diff --git a/[refs] b/[refs] index bf854c81ec35..c9949117ad2e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 73a0e405dce7d720808536b708f7c738b413b1a2 +refs/heads/master: 0d420f9d6111b3a2fb7d5dd0180456eed469055d diff --git a/trunk/CREDITS b/trunk/CREDITS index 85c7c70b7044..9bf714a1c7d9 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -24,11 +24,6 @@ S: C. Negri 6, bl. D3 S: Iasi 6600 S: Romania -N: Mark Adler -E: madler@alumni.caltech.edu -W: http://alumnus.caltech.edu/~madler/ -D: zlib decompression - N: Monalisa Agrawal E: magrawal@nortelnetworks.com D: Basic Interphase 5575 driver with UBR and ABR support. @@ -1578,8 +1573,12 @@ S: 160 00 Praha 6 S: Czech Republic N: Niels Kristian Bech Jensen -E: nkbj1970@hotmail.com +E: nkbj@image.dk +W: http://www.image.dk/~nkbj D: Miscellaneous kernel updates and fixes. +S: Dr. Holsts Vej 34, lejl. 164 +S: DK-8230 Åbyhøj +S: Denmark N: Michael K. Johnson E: johnsonm@redhat.com diff --git a/trunk/Documentation/ABI/README b/trunk/Documentation/ABI/README deleted file mode 100644 index 9feaf16f1617..000000000000 --- a/trunk/Documentation/ABI/README +++ /dev/null @@ -1,77 +0,0 @@ -This directory attempts to document the ABI between the Linux kernel and -userspace, and the relative stability of these interfaces. Due to the -everchanging nature of Linux, and the differing maturity levels, these -interfaces should be used by userspace programs in different ways. - -We have four different levels of ABI stability, as shown by the four -different subdirectories in this location. Interfaces may change levels -of stability according to the rules described below. - -The different levels of stability are: - - stable/ - This directory documents the interfaces that the developer has - defined to be stable. Userspace programs are free to use these - interfaces with no restrictions, and backward compatibility for - them will be guaranteed for at least 2 years. Most interfaces - (like syscalls) are expected to never change and always be - available. - - testing/ - This directory documents interfaces that are felt to be stable, - as the main development of this interface has been completed. - The interface can be changed to add new features, but the - current interface will not break by doing this, unless grave - errors or security problems are found in them. Userspace - programs can start to rely on these interfaces, but they must be - aware of changes that can occur before these interfaces move to - be marked stable. Programs that use these interfaces are - strongly encouraged to add their name to the description of - these interfaces, so that the kernel developers can easily - notify them if any changes occur (see the description of the - layout of the files below for details on how to do this.) - - obsolete/ - This directory documents interfaces that are still remaining in - the kernel, but are marked to be removed at some later point in - time. The description of the interface will document the reason - why it is obsolete and when it can be expected to be removed. - The file Documentation/feature-removal-schedule.txt may describe - some of these interfaces, giving a schedule for when they will - be removed. - - removed/ - This directory contains a list of the old interfaces that have - been removed from the kernel. - -Every file in these directories will contain the following information: - -What: Short description of the interface -Date: Date created -KernelVersion: Kernel version this feature first showed up in. -Contact: Primary contact for this interface (may be a mailing list) -Description: Long description of the interface and how to use it. -Users: All users of this interface who wish to be notified when - it changes. This is very important for interfaces in - the "testing" stage, so that kernel developers can work - with userspace developers to ensure that things do not - break in ways that are unacceptable. It is also - important to get feedback for these interfaces to make - sure they are working in a proper way and do not need to - be changed further. - - -How things move between levels: - -Interfaces in stable may move to obsolete, as long as the proper -notification is given. - -Interfaces may be removed from obsolete and the kernel as long as the -documented amount of time has gone by. - -Interfaces in the testing state can move to the stable state when the -developers feel they are finished. They cannot be removed from the -kernel tree without going through the obsolete state first. - -It's up to the developer to place their interfaces in the category they -wish for it to start out in. diff --git a/trunk/Documentation/ABI/obsolete/devfs b/trunk/Documentation/ABI/obsolete/devfs deleted file mode 100644 index b8b87399bc8f..000000000000 --- a/trunk/Documentation/ABI/obsolete/devfs +++ /dev/null @@ -1,13 +0,0 @@ -What: devfs -Date: July 2005 -Contact: Greg Kroah-Hartman -Description: - devfs has been unmaintained for a number of years, has unfixable - races, contains a naming policy within the kernel that is - against the LSB, and can be replaced by using udev. - The files fs/devfs/*, include/linux/devfs_fs*.h will be removed, - along with the the assorted devfs function calls throughout the - kernel tree. - -Users: - diff --git a/trunk/Documentation/ABI/stable/syscalls b/trunk/Documentation/ABI/stable/syscalls deleted file mode 100644 index c3ae3e7d6a0c..000000000000 --- a/trunk/Documentation/ABI/stable/syscalls +++ /dev/null @@ -1,10 +0,0 @@ -What: The kernel syscall interface -Description: - This interface matches much of the POSIX interface and is based - on it and other Unix based interfaces. It will only be added to - over time, and not have things removed from it. - - Note that this interface is different for every architecture - that Linux supports. Please see the architecture-specific - documentation for details on the syscall numbers that are to be - mapped to each syscall. diff --git a/trunk/Documentation/ABI/stable/sysfs-module b/trunk/Documentation/ABI/stable/sysfs-module deleted file mode 100644 index 75be43118335..000000000000 --- a/trunk/Documentation/ABI/stable/sysfs-module +++ /dev/null @@ -1,30 +0,0 @@ -What: /sys/module -Description: - The /sys/module tree consists of the following structure: - - /sys/module/MODULENAME - The name of the module that is in the kernel. This - module name will show up either if the module is built - directly into the kernel, or if it is loaded as a - dyanmic module. - - /sys/module/MODULENAME/parameters - This directory contains individual files that are each - individual parameters of the module that are able to be - changed at runtime. See the individual module - documentation as to the contents of these parameters and - what they accomplish. - - Note: The individual parameter names and values are not - considered stable, only the fact that they will be - placed in this location within sysfs. See the - individual driver documentation for details as to the - stability of the different parameters. - - /sys/module/MODULENAME/refcnt - If the module is able to be unloaded from the kernel, this file - will contain the current reference count of the module. - - Note: If the module is built into the kernel, or if the - CONFIG_MODULE_UNLOAD kernel configuration value is not enabled, - this file will not be present. diff --git a/trunk/Documentation/ABI/testing/sysfs-class b/trunk/Documentation/ABI/testing/sysfs-class deleted file mode 100644 index 4b0cb891e46e..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-class +++ /dev/null @@ -1,16 +0,0 @@ -What: /sys/class/ -Date: Febuary 2006 -Contact: Greg Kroah-Hartman -Description: - The /sys/class directory will consist of a group of - subdirectories describing individual classes of devices - in the kernel. The individual directories will consist - of either subdirectories, or symlinks to other - directories. - - All programs that use this directory tree must be able - to handle both subdirectories or symlinks in order to - work properly. - -Users: - udev diff --git a/trunk/Documentation/ABI/testing/sysfs-devices b/trunk/Documentation/ABI/testing/sysfs-devices deleted file mode 100644 index 6a25671ee5f6..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-devices +++ /dev/null @@ -1,25 +0,0 @@ -What: /sys/devices -Date: February 2006 -Contact: Greg Kroah-Hartman -Description: - The /sys/devices tree contains a snapshot of the - internal state of the kernel device tree. Devices will - be added and removed dynamically as the machine runs, - and between different kernel versions, the layout of the - devices within this tree will change. - - Please do not rely on the format of this tree because of - this. If a program wishes to find different things in - the tree, please use the /sys/class structure and rely - on the symlinks there to point to the proper location - within the /sys/devices tree of the individual devices. - Or rely on the uevent messages to notify programs of - devices being added and removed from this tree to find - the location of those devices. - - Note that sometimes not all devices along the directory - chain will have emitted uevent messages, so userspace - programs must be able to handle such occurrences. - -Users: - udev diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index 6d2412ec91ed..ce5d2c038cf5 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -155,83 +155,7 @@ problem, which is called the function-growth-hormone-imbalance syndrome. See next chapter. - Chapter 5: Typedefs - -Please don't use things like "vps_t". - -It's a _mistake_ to use typedef for structures and pointers. When you see a - - vps_t a; - -in the source, what does it mean? - -In contrast, if it says - - struct virtual_container *a; - -you can actually tell what "a" is. - -Lots of people think that typedefs "help readability". Not so. They are -useful only for: - - (a) totally opaque objects (where the typedef is actively used to _hide_ - what the object is). - - Example: "pte_t" etc. opaque objects that you can only access using - the proper accessor functions. - - NOTE! Opaqueness and "accessor functions" are not good in themselves. - The reason we have them for things like pte_t etc. is that there - really is absolutely _zero_ portably accessible information there. - - (b) Clear integer types, where the abstraction _helps_ avoid confusion - whether it is "int" or "long". - - u8/u16/u32 are perfectly fine typedefs, although they fit into - category (d) better than here. - - NOTE! Again - there needs to be a _reason_ for this. If something is - "unsigned long", then there's no reason to do - - typedef unsigned long myflags_t; - - but if there is a clear reason for why it under certain circumstances - might be an "unsigned int" and under other configurations might be - "unsigned long", then by all means go ahead and use a typedef. - - (c) when you use sparse to literally create a _new_ type for - type-checking. - - (d) New types which are identical to standard C99 types, in certain - exceptional circumstances. - - Although it would only take a short amount of time for the eyes and - brain to become accustomed to the standard types like 'uint32_t', - some people object to their use anyway. - - Therefore, the Linux-specific 'u8/u16/u32/u64' types and their - signed equivalents which are identical to standard types are - permitted -- although they are not mandatory in new code of your - own. - - When editing existing code which already uses one or the other set - of types, you should conform to the existing choices in that code. - - (e) Types safe for use in userspace. - - In certain structures which are visible to userspace, we cannot - require C99 types and cannot use the 'u32' form above. Thus, we - use __u32 and similar types in all structures which are shared - with userspace. - -Maybe there are other cases too, but the rule should basically be to NEVER -EVER use a typedef unless you can clearly match one of those rules. - -In general, a pointer, or a struct that has elements that can reasonably -be directly accessed should _never_ be a typedef. - - - Chapter 6: Functions + Chapter 5: Functions Functions should be short and sweet, and do just one thing. They should fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24, @@ -259,7 +183,7 @@ and it gets confused. You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now. - Chapter 7: Centralized exiting of functions + Chapter 6: Centralized exiting of functions Albeit deprecated by some people, the equivalent of the goto statement is used frequently by compilers in form of the unconditional jump instruction. @@ -296,7 +220,7 @@ out: return result; } - Chapter 8: Commenting + Chapter 7: Commenting Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to @@ -316,7 +240,7 @@ When commenting the kernel API functions, please use the kerneldoc format. See the files Documentation/kernel-doc-nano-HOWTO.txt and scripts/kernel-doc for details. - Chapter 9: You've made a mess of it + Chapter 8: You've made a mess of it That's OK, we all do. You've probably been told by your long-time Unix user helper that "GNU emacs" automatically formats the C sources for @@ -364,7 +288,7 @@ re-formatting you may want to take a look at the man page. But remember: "indent" is not a fix for bad programming. - Chapter 10: Configuration-files + Chapter 9: Configuration-files For configuration options (arch/xxx/Kconfig, and all the Kconfig files), somewhat different indentation is used. @@ -389,7 +313,7 @@ support for file-systems, for instance) should be denoted (DANGEROUS), other experimental options should be denoted (EXPERIMENTAL). - Chapter 11: Data structures + Chapter 10: Data structures Data structures that have visibility outside the single-threaded environment they are created and destroyed in should always have @@ -420,7 +344,7 @@ Remember: if another thread can find your data structure, and you don't have a reference count on it, you almost certainly have a bug. - Chapter 12: Macros, Enums and RTL + Chapter 11: Macros, Enums and RTL Names of macros defining constants and labels in enums are capitalized. @@ -475,7 +399,7 @@ The cpp manual deals with macros exhaustively. The gcc internals manual also covers RTL which is used frequently with assembly language in the kernel. - Chapter 13: Printing kernel messages + Chapter 12: Printing kernel messages Kernel developers like to be seen as literate. Do mind the spelling of kernel messages to make a good impression. Do not use crippled @@ -486,7 +410,7 @@ Kernel messages do not have to be terminated with a period. Printing numbers in parentheses (%d) adds no value and should be avoided. - Chapter 14: Allocating memory + Chapter 13: Allocating memory The kernel provides the following general purpose memory allocators: kmalloc(), kzalloc(), kcalloc(), and vmalloc(). Please refer to the API @@ -505,7 +429,7 @@ from void pointer to any other pointer type is guaranteed by the C programming language. - Chapter 15: The inline disease + Chapter 14: The inline disease There appears to be a common misperception that gcc has a magic "make me faster" speedup option called "inline". While the use of inlines can be @@ -533,7 +457,7 @@ something it would have done anyway. - Appendix I: References + Chapter 15: References The C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie. @@ -557,4 +481,4 @@ Kernel CodingStyle, by greg@kroah.com at OLS 2002: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ -- -Last updated on 30 April 2006. +Last updated on 30 December 2005 by a community effort on LKML. diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index 3630a0d7695f..ca02e04a906c 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -62,8 +62,6 @@ Internal Functions !Ikernel/exit.c !Ikernel/signal.c -!Iinclude/linux/kthread.h -!Ekernel/kthread.c Kernel objects manipulation @@ -116,33 +114,9 @@ X!Ilib/string.c - - Basic Kernel Library Functions - - - The Linux kernel provides more basic utility functions. - - - Bitmap Operations -!Elib/bitmap.c -!Ilib/bitmap.c - - - Command-line Parsing -!Elib/cmdline.c - - - CRC Functions -!Elib/crc16.c -!Elib/crc32.c -!Elib/crc-ccitt.c - - - Memory Management in Linux The Slab Cache -!Iinclude/linux/slab.h !Emm/slab.c User Space Memory Access @@ -306,13 +280,12 @@ X!Ekernel/module.c MTRR Handling !Earch/i386/kernel/cpu/mtrr/main.c - PCI Support Library !Edrivers/pci/pci.c !Edrivers/pci/pci-driver.c !Edrivers/pci/remove.c !Edrivers/pci/pci-acpi.c - !Edrivers/pci/msi.c @@ -341,13 +314,6 @@ X!Earch/i386/kernel/mca.c - - Firmware Interfaces - DMI Interfaces -!Edrivers/firmware/dmi_scan.c - - - The Device File System !Efs/devfs/base.c @@ -365,18 +331,6 @@ X!Earch/i386/kernel/mca.c !Esecurity/security.c - - Audit Interfaces -!Ekernel/audit.c -!Ikernel/auditsc.c -!Ikernel/auditfilter.c - - - - Accounting Framework -!Ikernel/acct.c - - Power Management !Ekernel/power/pm.c @@ -436,6 +390,7 @@ X!Edrivers/pnp/system.c + Block Devices !Eblock/ll_rw_blk.c @@ -446,14 +401,6 @@ X!Edrivers/pnp/system.c !Edrivers/char/misc.c - - Parallel Port Devices -!Iinclude/linux/parport.h -!Edrivers/parport/ieee1284.c -!Edrivers/parport/share.c -!Idrivers/parport/daisy.c - - Video4Linux !Edrivers/media/video/videodev.c diff --git a/trunk/Documentation/DocBook/kernel-locking.tmpl b/trunk/Documentation/DocBook/kernel-locking.tmpl index 644c3884fab9..158ffe9bfade 100644 --- a/trunk/Documentation/DocBook/kernel-locking.tmpl +++ b/trunk/Documentation/DocBook/kernel-locking.tmpl @@ -1590,7 +1590,7 @@ the amount of locking which needs to be done. Our final dilemma is this: when can we actually destroy the removed element? Remember, a reader might be stepping through - this element in the list right now: if we free this element and + this element in the list right now: it we free this element and the next pointer changes, the reader will jump off into garbage and crash. We need to wait until we know that all the readers who were traversing the list when we deleted the diff --git a/trunk/Documentation/DocBook/libata.tmpl b/trunk/Documentation/DocBook/libata.tmpl index e97c32314541..f869b03929db 100644 --- a/trunk/Documentation/DocBook/libata.tmpl +++ b/trunk/Documentation/DocBook/libata.tmpl @@ -169,22 +169,6 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); - PIO data read/write - -void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int); - - - -All bmdma-style drivers must implement this hook. This is the low-level -operation that actually copies the data bytes during a PIO data -transfer. -Typically the driver -will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or -ata_mmio_data_xfer(). - - - - ATA command execute void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); @@ -220,10 +204,11 @@ command. u8 (*check_status)(struct ata_port *ap); u8 (*check_altstatus)(struct ata_port *ap); +u8 (*check_err)(struct ata_port *ap); - Reads the Status/AltStatus ATA shadow register from + Reads the Status/AltStatus/Error ATA shadow register from hardware. On some hardware, reading the Status register has the side effect of clearing the interrupt condition. Most drivers for taskfile-based hardware use @@ -284,6 +269,23 @@ void (*set_mode) (struct ata_port *ap); + Reset ATA bus + +void (*phy_reset) (struct ata_port *ap); + + + + The very first step in the probe phase. Actions vary depending + on the bus type, typically. After waking up the device and probing + for device presence (PATA and SATA), typically a soft reset + (SRST) will be performed. Drivers typically use the helper + functions ata_bus_reset() or sata_phy_reset() for this hook. + Many SATA drivers use sata_phy_reset() or call it from within + their own phy_reset() functions. + + + + Control PCI IDE BMDMA engine void (*bmdma_setup) (struct ata_queued_cmd *qc); @@ -352,74 +354,16 @@ int (*qc_issue) (struct ata_queued_cmd *qc); - Exception and probe handling (EH) + Timeout (error) handling void (*eng_timeout) (struct ata_port *ap); -void (*phy_reset) (struct ata_port *ap); - - - -Deprecated. Use ->error_handler() instead. - - - -void (*freeze) (struct ata_port *ap); -void (*thaw) (struct ata_port *ap); - - - -ata_port_freeze() is called when HSM violations or some other -condition disrupts normal operation of the port. A frozen port -is not allowed to perform any operation until the port is -thawed, which usually follows a successful reset. - - - -The optional ->freeze() callback can be used for freezing the port -hardware-wise (e.g. mask interrupt and stop DMA engine). If a -port cannot be frozen hardware-wise, the interrupt handler -must ack and clear interrupts unconditionally while the port -is frozen. - - -The optional ->thaw() callback is called to perform the opposite of ->freeze(): -prepare the port for normal operation once again. Unmask interrupts, -start DMA engine, etc. - - - -void (*error_handler) (struct ata_port *ap); - - - -->error_handler() is a driver's hook into probe, hotplug, and recovery -and other exceptional conditions. The primary responsibility of an -implementation is to call ata_do_eh() or ata_bmdma_drive_eh() with a set -of EH hooks as arguments: - - - -'prereset' hook (may be NULL) is called during an EH reset, before any other actions -are taken. - - - -'postreset' hook (may be NULL) is called after the EH reset is performed. Based on -existing conditions, severity of the problem, and hardware capabilities, - - - -Either 'softreset' (may be NULL) or 'hardreset' (may be NULL) will be -called to perform the low-level EH reset. - - - -void (*post_internal_cmd) (struct ata_queued_cmd *qc); -Perform any hardware-specific actions necessary to finish processing -after executing a probe-time or EH-time command via ata_exec_internal(). +This is a high level error handling function, called from the +error handling thread, when a command times out. Most newer +hardware will implement its own error handling code here. IDE BMDMA +drivers may use the helper function ata_eng_timeout(). diff --git a/trunk/Documentation/RCU/checklist.txt b/trunk/Documentation/RCU/checklist.txt index 1d50cf0c905e..49e27cc19385 100644 --- a/trunk/Documentation/RCU/checklist.txt +++ b/trunk/Documentation/RCU/checklist.txt @@ -144,47 +144,9 @@ over a rather long period of time, but improvements are always welcome! whether the increased speed is worth it. 8. Although synchronize_rcu() is a bit slower than is call_rcu(), - it usually results in simpler code. So, unless update - performance is critically important or the updaters cannot block, - synchronize_rcu() should be used in preference to call_rcu(). - - An especially important property of the synchronize_rcu() - primitive is that it automatically self-limits: if grace periods - are delayed for whatever reason, then the synchronize_rcu() - primitive will correspondingly delay updates. In contrast, - code using call_rcu() should explicitly limit update rate in - cases where grace periods are delayed, as failing to do so can - result in excessive realtime latencies or even OOM conditions. - - Ways of gaining this self-limiting property when using call_rcu() - include: - - a. Keeping a count of the number of data-structure elements - used by the RCU-protected data structure, including those - waiting for a grace period to elapse. Enforce a limit - on this number, stalling updates as needed to allow - previously deferred frees to complete. - - Alternatively, limit only the number awaiting deferred - free rather than the total number of elements. - - b. Limiting update rate. For example, if updates occur only - once per hour, then no explicit rate limiting is required, - unless your system is already badly broken. The dcache - subsystem takes this approach -- updates are guarded - by a global lock, limiting their rate. - - c. Trusted update -- if updates can only be done manually by - superuser or some other trusted user, then it might not - be necessary to automatically limit them. The theory - here is that superuser already has lots of ways to crash - the machine. - - d. Use call_rcu_bh() rather than call_rcu(), in order to take - advantage of call_rcu_bh()'s faster grace periods. - - e. Periodically invoke synchronize_rcu(), permitting a limited - number of updates per grace period. + it usually results in simpler code. So, unless update performance + is important or the updaters cannot block, synchronize_rcu() + should be used in preference to call_rcu(). 9. All RCU list-traversal primitives, which include list_for_each_rcu(), list_for_each_entry_rcu(), diff --git a/trunk/Documentation/RCU/torture.txt b/trunk/Documentation/RCU/torture.txt index a4948591607d..e4c38152f7f7 100644 --- a/trunk/Documentation/RCU/torture.txt +++ b/trunk/Documentation/RCU/torture.txt @@ -7,7 +7,7 @@ The CONFIG_RCU_TORTURE_TEST config option is available for all RCU implementations. It creates an rcutorture kernel module that can be loaded to run a torture test. The test periodically outputs status messages via printk(), which can be examined via the dmesg -command (perhaps grepping for "torture"). The test is started +command (perhaps grepping for "rcutorture"). The test is started when the module is loaded, and stops when the module is unloaded. However, actually setting this config option to "y" results in the system @@ -35,19 +35,6 @@ stat_interval The number of seconds between output of torture be printed -only- when the module is unloaded, and this is the default. -shuffle_interval - The number of seconds to keep the test threads affinitied - to a particular subset of the CPUs. Used in conjunction - with test_no_idle_hz. - -test_no_idle_hz Whether or not to test the ability of RCU to operate in - a kernel that disables the scheduling-clock interrupt to - idle CPUs. Boolean parameter, "1" to test, "0" otherwise. - -torture_type The type of RCU to test: "rcu" for the rcu_read_lock() - API, "rcu_bh" for the rcu_read_lock_bh() API, and "srcu" - for the "srcu_read_lock()" API. - verbose Enable debug printk()s. Default is disabled. @@ -55,14 +42,14 @@ OUTPUT The statistics output is as follows: - rcu-torture: --- Start of test: nreaders=16 stat_interval=0 verbose=0 - rcu-torture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915 - rcu-torture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0 - rcu-torture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0 - rcu-torture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0 - rcu-torture: --- End of test + rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0 + rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915 + rcutorture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0 + rcutorture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0 + rcutorture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0 + rcutorture: --- End of test -The command "dmesg | grep torture:" will extract this information on +The command "dmesg | grep rcutorture:" will extract this information on most systems. On more esoteric configurations, it may be necessary to use other commands to access the output of the printk()s used by the RCU torture test. The printk()s use KERN_ALERT, so they should @@ -128,9 +115,8 @@ The following script may be used to torture RCU: modprobe rcutorture sleep 100 rmmod rcutorture - dmesg | grep torture: + dmesg | grep rcutorture: The output can be manually inspected for the error flag of "!!!". One could of course create a more elaborate script that automatically -checked for such errors. The "rmmod" command forces a "SUCCESS" or -"FAILURE" indication to be printk()ed. +checked for such errors. diff --git a/trunk/Documentation/RCU/whatisRCU.txt b/trunk/Documentation/RCU/whatisRCU.txt index 4f41a60e5111..07cb93b82ba9 100644 --- a/trunk/Documentation/RCU/whatisRCU.txt +++ b/trunk/Documentation/RCU/whatisRCU.txt @@ -184,17 +184,7 @@ synchronize_rcu() blocking, it registers a function and argument which are invoked after all ongoing RCU read-side critical sections have completed. This callback variant is particularly useful in situations where - it is illegal to block or where update-side performance is - critically important. - - However, the call_rcu() API should not be used lightly, as use - of the synchronize_rcu() API generally results in simpler code. - In addition, the synchronize_rcu() API has the nice property - of automatically limiting update rate should grace periods - be delayed. This property results in system resilience in face - of denial-of-service attacks. Code using call_rcu() should limit - update rate in order to gain this same sort of resilience. See - checklist.txt for some approaches to limiting the update rate. + it is illegal to block. rcu_assign_pointer() @@ -800,6 +790,7 @@ RCU pointer update: RCU grace period: + synchronize_kernel (deprecated) synchronize_net synchronize_sched synchronize_rcu diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist deleted file mode 100644 index 8230098da529..000000000000 --- a/trunk/Documentation/SubmitChecklist +++ /dev/null @@ -1,57 +0,0 @@ -Linux Kernel patch sumbittal checklist -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here are some basic things that developers should do if they -want to see their kernel patch submittals accepted quicker. - -These are all above and beyond the documentation that is provided -in Documentation/SubmittingPatches and elsewhere about submitting -Linux kernel patches. - - - -- Builds cleanly with applicable or modified CONFIG options =y, =m, and =n. - No gcc warnings/errors, no linker warnings/errors. - -- Passes allnoconfig, allmodconfig - -- Builds on multiple CPU arch-es by using local cross-compile tools - or something like PLM at OSDL. - -- ppc64 is a good architecture for cross-compilation checking because it - tends to use `unsigned long' for 64-bit quantities. - -- Matches kernel coding style(!) - -- Any new or modified CONFIG options don't muck up the config menu. - -- All new Kconfig options have help text. - -- Has been carefully reviewed with respect to relevant Kconfig - combinations. This is very hard to get right with testing -- - brainpower pays off here. - -- Check cleanly with sparse. - -- Use 'make checkstack' and 'make namespacecheck' and fix any - problems that they find. Note: checkstack does not point out - problems explicitly, but any one function that uses more than - 512 bytes on the stack is a candidate for change. - -- Include kernel-doc to document global kernel APIs. (Not required - for static functions, but OK there also.) Use 'make htmldocs' - or 'make mandocs' to check the kernel-doc and fix any issues. - -- Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, - CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, - CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEP all simultaneously - enabled. - -- Has been build- and runtime tested with and without CONFIG_SMP and - CONFIG_PREEMPT. - -- If the patch affects IO/Disk, etc: has been tested with and without - CONFIG_LBD. - - -2006-APR-27 diff --git a/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt b/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt index 3e46d2a31158..8c6ee684174c 100644 --- a/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt +++ b/trunk/Documentation/arm/Samsung-S3C24XX/Overview.txt @@ -7,13 +7,11 @@ Introduction ------------ The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported - by the 's3c2410' architecture of ARM Linux. Currently the S3C2410, - S3C2440 and S3C2442 devices are supported. + by the 's3c2410' architecture of ARM Linux. Currently the S3C2410 and + the S3C2440 are supported CPUs. Support for the S3C2400 series is in progress. - Support for the S3C2412 and S3C2413 CPUs is being merged. - Configuration ------------- @@ -45,18 +43,9 @@ Machines Samsung's own development board, geared for PDA work. - Samsung/Aiji SMDK2412 - - The S3C2412 version of the SMDK2440. - - Samsung/Aiji SMDK2413 - - The S3C2412 version of the SMDK2440. - Samsung/Meritech SMDK2440 - The S3C2440 compatible version of the SMDK2440, which has the - option of an S3C2440 or S3C2442 CPU module. + The S3C2440 compatible version of the SMDK2440 Thorcom VR1000 @@ -222,6 +211,24 @@ Port Contributors Lucas Correia Villa Real (S3C2400 port) +Document Changes +---------------- + + 05 Sep 2004 - BJD - Added Document Changes section + 05 Sep 2004 - BJD - Added Klaus Fetscher to list of contributors + 25 Oct 2004 - BJD - Added Dimitry Andric to list of contributors + 25 Oct 2004 - BJD - Updated the MTD from the 2.6.9 merge + 21 Jan 2005 - BJD - Added rx3715, added Shannon to contributors + 10 Feb 2005 - BJD - Added Guillaume Gourat to contributors + 02 Mar 2005 - BJD - Added SMDK2440 to list of machines + 06 Mar 2005 - BJD - Added Christer Weinigel + 08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction + 08 Mar 2005 - BJD - Added section on adding machines + 09 Sep 2005 - BJD - Added section on platform data + 11 Feb 2006 - BJD - Added I2C, RTC and Watchdog sections + 11 Feb 2006 - BJD - Added Osiris machine, and S3C2400 information + + Document Author --------------- diff --git a/trunk/Documentation/arm/Samsung-S3C24XX/S3C2412.txt b/trunk/Documentation/arm/Samsung-S3C24XX/S3C2412.txt deleted file mode 100644 index cb82a7fc7901..000000000000 --- a/trunk/Documentation/arm/Samsung-S3C24XX/S3C2412.txt +++ /dev/null @@ -1,120 +0,0 @@ - S3C2412 ARM Linux Overview - ========================== - -Introduction ------------- - - The S3C2412 is part of the S3C24XX range of ARM9 System-on-Chip CPUs - from Samsung. This part has an ARM926-EJS core, capable of running up - to 266MHz (see data-sheet for more information) - - -Clock ------ - - The core clock code provides a set of clocks to the drivers, and allows - for source selection and a number of other features. - - -Power ------ - - No support for suspend/resume to RAM in the current system. - - -DMA ---- - - No current support for DMA. - - -GPIO ----- - - There is support for setting the GPIO to input/output/special function - and reading or writing to them. - - -UART ----- - - The UART hardware is similar to the S3C2440, and is supported by the - s3c2410 driver in the drivers/serial directory. - - -NAND ----- - - The NAND hardware is similar to the S3C2440, and is supported by the - s3c2410 driver in the drivers/mtd/nand directory. - - -USB Host --------- - - The USB hardware is similar to the S3C2410, with extended clock source - control. The OHCI portion is supported by the ohci-s3c2410 driver, and - the clock control selection is supported by the core clock code. - - -USB Device ----------- - - No current support in the kernel - - -IRQs ----- - - All the standard, and external interrupt sources are supported. The - extra sub-sources are not yet supported. - - -RTC ---- - - The RTC hardware is similar to the S3C2410, and is supported by the - s3c2410-rtc driver. - - -Watchdog --------- - - The watchdog harware is the same as the S3C2410, and is supported by - the s3c2410_wdt driver. - - -MMC/SD/SDIO ------------ - - No current support for the MMC/SD/SDIO block. - -IIC ---- - - The IIC hardware is the same as the S3C2410, and is supported by the - i2c-s3c24xx driver. - - -IIS ---- - - No current support for the IIS interface. - - -SPI ---- - - No current support for the SPI interfaces. - - -ATA ---- - - No current support for the on-board ATA block. - - -Document Author ---------------- - -Ben Dooks, (c) 2006 Simtec Electronics diff --git a/trunk/Documentation/arm/Samsung-S3C24XX/S3C2413.txt b/trunk/Documentation/arm/Samsung-S3C24XX/S3C2413.txt deleted file mode 100644 index ab2a88858f12..000000000000 --- a/trunk/Documentation/arm/Samsung-S3C24XX/S3C2413.txt +++ /dev/null @@ -1,21 +0,0 @@ - S3C2413 ARM Linux Overview - ========================== - -Introduction ------------- - - The S3C2413 is an extended version of the S3C2412, with an camera - interface and mobile DDR memory support. See the S3C2412 support - documentation for more information. - - -Camera Interface ---------------- - - This block is currently not supported. - - -Document Author ---------------- - -Ben Dooks, (c) 2006 Simtec Electronics diff --git a/trunk/Documentation/atomic_ops.txt b/trunk/Documentation/atomic_ops.txt index 2a63d5662a93..23a1c2402bcc 100644 --- a/trunk/Documentation/atomic_ops.txt +++ b/trunk/Documentation/atomic_ops.txt @@ -157,13 +157,13 @@ For example, smp_mb__before_atomic_dec() can be used like so: smp_mb__before_atomic_dec(); atomic_dec(&obj->ref_count); -It makes sure that all memory operations preceding the atomic_dec() +It makes sure that all memory operations preceeding the atomic_dec() call are strongly ordered with respect to the atomic counter -operation. In the above example, it guarantees that the assignment of +operation. In the above example, it guarentees that the assignment of "1" to obj->dead will be globally visible to other cpus before the atomic counter decrement. -Without the explicit smp_mb__before_atomic_dec() call, the +Without the explicitl smp_mb__before_atomic_dec() call, the implementation could legally allow the atomic counter update visible to other cpus before the "obj->dead = 1;" assignment. @@ -173,11 +173,11 @@ ordering with respect to memory operations after an atomic_dec() call (smp_mb__{before,after}_atomic_inc()). A missing memory barrier in the cases where they are required by the -atomic_t implementation above can have disastrous results. Here is -an example, which follows a pattern occurring frequently in the Linux +atomic_t implementation above can have disasterous results. Here is +an example, which follows a pattern occuring frequently in the Linux kernel. It is the use of atomic counters to implement reference counting, and it works such that once the counter falls to zero it can -be guaranteed that no other entity can be accessing the object: +be guarenteed that no other entity can be accessing the object: static void obj_list_add(struct obj *obj) { @@ -291,9 +291,9 @@ to the size of an "unsigned long" C data type, and are least of that size. The endianness of the bits within each "unsigned long" are the native endianness of the cpu. - void set_bit(unsigned long nr, volatile unsigned long *addr); - void clear_bit(unsigned long nr, volatile unsigned long *addr); - void change_bit(unsigned long nr, volatile unsigned long *addr); + void set_bit(unsigned long nr, volatils unsigned long *addr); + void clear_bit(unsigned long nr, volatils unsigned long *addr); + void change_bit(unsigned long nr, volatils unsigned long *addr); These routines set, clear, and change, respectively, the bit number indicated by "nr" on the bit mask pointed to by "ADDR". @@ -301,9 +301,9 @@ indicated by "nr" on the bit mask pointed to by "ADDR". They must execute atomically, yet there are no implicit memory barrier semantics required of these interfaces. - int test_and_set_bit(unsigned long nr, volatile unsigned long *addr); - int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr); - int test_and_change_bit(unsigned long nr, volatile unsigned long *addr); + int test_and_set_bit(unsigned long nr, volatils unsigned long *addr); + int test_and_clear_bit(unsigned long nr, volatils unsigned long *addr); + int test_and_change_bit(unsigned long nr, volatils unsigned long *addr); Like the above, except that these routines return a boolean which indicates whether the changed bit was set _BEFORE_ the atomic bit @@ -335,7 +335,7 @@ subsequent memory operation is made visible. For example: /* ... */; obj->killed = 1; -The implementation of test_and_set_bit() must guarantee that +The implementation of test_and_set_bit() must guarentee that "obj->dead = 1;" is visible to cpus before the atomic memory operation done by test_and_set_bit() becomes visible. Likewise, the atomic memory operation done by test_and_set_bit() must become visible before @@ -474,7 +474,7 @@ Now, as far as memory barriers go, as long as spin_lock() strictly orders all subsequent memory operations (including the cas()) with respect to itself, things will be fine. -Said another way, _atomic_dec_and_lock() must guarantee that +Said another way, _atomic_dec_and_lock() must guarentee that a counter dropping to zero is never made visible before the spinlock being acquired. diff --git a/trunk/Documentation/console/console.txt b/trunk/Documentation/console/console.txt deleted file mode 100644 index d3e17447321c..000000000000 --- a/trunk/Documentation/console/console.txt +++ /dev/null @@ -1,144 +0,0 @@ -Console Drivers -=============== - -The linux kernel has 2 general types of console drivers. The first type is -assigned by the kernel to all the virtual consoles during the boot process. -This type will be called 'system driver', and only one system driver is allowed -to exist. The system driver is persistent and it can never be unloaded, though -it may become inactive. - -The second type has to be explicitly loaded and unloaded. This will be called -'modular driver' by this document. Multiple modular drivers can coexist at -any time with each driver sharing the console with other drivers including -the system driver. However, modular drivers cannot take over the console -that is currently occupied by another modular driver. (Exception: Drivers that -call take_over_console() will succeed in the takeover regardless of the type -of driver occupying the consoles.) They can only take over the console that is -occupied by the system driver. In the same token, if the modular driver is -released by the console, the system driver will take over. - -Modular drivers, from the programmer's point of view, has to call: - - take_over_console() - load and bind driver to console layer - give_up_console() - unbind and unload driver - -In newer kernels, the following are also available: - - register_con_driver() - unregister_con_driver() - -If sysfs is enabled, the contents of /sys/class/vtconsole can be -examined. This shows the console backends currently registered by the -system which are named vtcon where is an integer fro 0 to 15. Thus: - - ls /sys/class/vtconsole - . .. vtcon0 vtcon1 - -Each directory in /sys/class/vtconsole has 3 files: - - ls /sys/class/vtconsole/vtcon0 - . .. bind name uevent - -What do these files signify? - - 1. bind - this is a read/write file. It shows the status of the driver if - read, or acts to bind or unbind the driver to the virtual consoles - when written to. The possible values are: - - 0 - means the driver is not bound and if echo'ed, commands the driver - to unbind - - 1 - means the driver is bound and if echo'ed, commands the driver to - bind - - 2. name - read-only file. Shows the name of the driver in this format: - - cat /sys/class/vtconsole/vtcon0/name - (S) VGA+ - - '(S)' stands for a (S)ystem driver, ie, it cannot be directly - commanded to bind or unbind - - 'VGA+' is the name of the driver - - cat /sys/class/vtconsole/vtcon1/name - (M) frame buffer device - - In this case, '(M)' stands for a (M)odular driver, one that can be - directly commanded to bind or unbind. - - 3. uevent - ignore this file - -When unbinding, the modular driver is detached first, and then the system -driver takes over the consoles vacated by the driver. Binding, on the other -hand, will bind the driver to the consoles that are currently occupied by a -system driver. - -NOTE1: Binding and binding must be selected in Kconfig. It's under: - -Device Drivers -> Character devices -> Support for binding and unbinding -console drivers - -NOTE2: If any of the virtual consoles are in KD_GRAPHICS mode, then binding or -unbinding will not succeed. An example of an application that sets the console -to KD_GRAPHICS is X. - -How useful is this feature? This is very useful for console driver -developers. By unbinding the driver from the console layer, one can unload the -driver, make changes, recompile, reload and rebind the driver without any need -for rebooting the kernel. For regular users who may want to switch from -framebuffer console to VGA console and vice versa, this feature also makes -this possible. (NOTE NOTE NOTE: Please read fbcon.txt under Documentation/fb -for more details). - -Notes for developers: -===================== - -take_over_console() is now broken up into: - - register_con_driver() - bind_con_driver() - private function - -give_up_console() is a wrapper to unregister_con_driver(), and a driver must -be fully unbound for this call to succeed. con_is_bound() will check if the -driver is bound or not. - -Guidelines for console driver writers: -===================================== - -In order for binding to and unbinding from the console to properly work, -console drivers must follow these guidelines: - -1. All drivers, except system drivers, must call either register_con_driver() - or take_over_console(). register_con_driver() will just add the driver to - the console's internal list. It won't take over the - console. take_over_console(), as it name implies, will also take over (or - bind to) the console. - -2. All resources allocated during con->con_init() must be released in - con->con_deinit(). - -3. All resources allocated in con->con_startup() must be released when the - driver, which was previously bound, becomes unbound. The console layer - does not have a complementary call to con->con_startup() so it's up to the - driver to check when it's legal to release these resources. Calling - con_is_bound() in con->con_deinit() will help. If the call returned - false(), then it's safe to release the resources. This balance has to be - ensured because con->con_startup() can be called again when a request to - rebind the driver to the console arrives. - -4. Upon exit of the driver, ensure that the driver is totally unbound. If the - condition is satisfied, then the driver must call unregister_con_driver() - or give_up_console(). - -5. unregister_con_driver() can also be called on conditions which make it - impossible for the driver to service console requests. This can happen - with the framebuffer console that suddenly lost all of its drivers. - -The current crop of console drivers should still work correctly, but binding -and unbinding them may cause problems. With minimal fixes, these drivers can -be made to work correctly. - -========================== -Antonino Daplas - diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index 4aaf68fafebe..b369a8c46a73 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -3,7 +3,7 @@ Maintained by Torben Mathiasen - Last revised: 15 May 2006 + Last revised: 25 January 2005 This list is the Linux Device List, the official registry of allocated device numbers and /dev directory nodes for the Linux operating @@ -94,6 +94,7 @@ Your cooperation is appreciated. 9 = /dev/urandom Faster, less secure random number gen. 10 = /dev/aio Asyncronous I/O notification interface 11 = /dev/kmsg Writes to this come out as printk's + 12 = /dev/oldmem Access to crash dump from kexec kernel 1 block RAM disk 0 = /dev/ram0 First RAM disk 1 = /dev/ram1 Second RAM disk @@ -261,13 +262,13 @@ Your cooperation is appreciated. NOTE: These devices permit both read and write access. 7 block Loopback devices - 0 = /dev/loop0 First loop device - 1 = /dev/loop1 Second loop device + 0 = /dev/loop0 First loopback device + 1 = /dev/loop1 Second loopback device ... - The loop devices are used to mount filesystems not + The loopback devices are used to mount filesystems not associated with block devices. The binding to the - loop devices is handled by mount(8) or losetup(8). + loopback devices is handled by mount(8) or losetup(8). 8 block SCSI disk devices (0-15) 0 = /dev/sda First SCSI disk whole disk @@ -942,7 +943,7 @@ Your cooperation is appreciated. 240 = /dev/ftlp FTL on 16th Memory Technology Device Partitions are handled in the same way as for IDE - disks (see major number 3) except that the partition + disks (see major number 3) expect that the partition limit is 15 rather than 63 per disk (same as SCSI.) 45 char isdn4linux ISDN BRI driver @@ -1167,7 +1168,7 @@ Your cooperation is appreciated. The filename of the encrypted container and the passwords are sent via ioctls (using the sdmount tool) to the master node which then activates them via one of the - /dev/scramdisk/x nodes for loop mounting (all handled + /dev/scramdisk/x nodes for loopback mounting (all handled through the sdmount tool). Requested by: andy@scramdisklinux.org @@ -2537,32 +2538,18 @@ Your cooperation is appreciated. 0 = /dev/usb/lp0 First USB printer ... 15 = /dev/usb/lp15 16th USB printer + 16 = /dev/usb/mouse0 First USB mouse + ... + 31 = /dev/usb/mouse15 16th USB mouse + 32 = /dev/usb/ez0 First USB firmware loader + ... + 47 = /dev/usb/ez15 16th USB firmware loader 48 = /dev/usb/scanner0 First USB scanner ... 63 = /dev/usb/scanner15 16th USB scanner 64 = /dev/usb/rio500 Diamond Rio 500 65 = /dev/usb/usblcd USBLCD Interface (info@usblcd.de) 66 = /dev/usb/cpad0 Synaptics cPad (mouse/LCD) - 96 = /dev/usb/hiddev0 1st USB HID device - ... - 111 = /dev/usb/hiddev15 16th USB HID device - 112 = /dev/usb/auer0 1st auerswald ISDN device - ... - 127 = /dev/usb/auer15 16th auerswald ISDN device - 128 = /dev/usb/brlvgr0 First Braille Voyager device - ... - 131 = /dev/usb/brlvgr3 Fourth Braille Voyager device - 132 = /dev/usb/idmouse ID Mouse (fingerprint scanner) device - 133 = /dev/usb/sisusbvga1 First SiSUSB VGA device - ... - 140 = /dev/usb/sisusbvga8 Eigth SISUSB VGA device - 144 = /dev/usb/lcd USB LCD device - 160 = /dev/usb/legousbtower0 1st USB Legotower device - ... - 175 = /dev/usb/legousbtower15 16th USB Legotower device - 240 = /dev/usb/dabusb0 First daubusb device - ... - 243 = /dev/usb/dabusb3 Fourth dabusb device 180 block USB block devices 0 = /dev/uba First USB block device @@ -2723,17 +2710,6 @@ Your cooperation is appreciated. 1 = /dev/cpu/1/msr MSRs on CPU 1 ... -202 block Xen Virtual Block Device - 0 = /dev/xvda First Xen VBD whole disk - 16 = /dev/xvdb Second Xen VBD whole disk - 32 = /dev/xvdc Third Xen VBD whole disk - ... - 240 = /dev/xvdp Sixteenth Xen VBD whole disk - - Partitions are handled in the same way as for IDE - disks (see major number 3) except that the limit on - partitions is 15. - 203 char CPU CPUID information 0 = /dev/cpu/0/cpuid CPUID on CPU 0 1 = /dev/cpu/1/cpuid CPUID on CPU 1 @@ -2771,27 +2747,11 @@ Your cooperation is appreciated. 46 = /dev/ttyCPM0 PPC CPM (SCC or SMC) - port 0 ... 47 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 5 - 50 = /dev/ttyIOC0 Altix serial card - ... - 81 = /dev/ttyIOC31 Altix serial card - 82 = /dev/ttyVR0 NEC VR4100 series SIU - 83 = /dev/ttyVR1 NEC VR4100 series DSIU - 84 = /dev/ttyIOC84 Altix ioc4 serial card - ... - 115 = /dev/ttyIOC115 Altix ioc4 serial card - 116 = /dev/ttySIOC0 Altix ioc3 serial card - ... - 147 = /dev/ttySIOC31 Altix ioc3 serial card - 148 = /dev/ttyPSC0 PPC PSC - port 0 - ... - 153 = /dev/ttyPSC5 PPC PSC - port 5 - 154 = /dev/ttyAT0 ATMEL serial port 0 - ... - 169 = /dev/ttyAT15 ATMEL serial port 15 - 170 = /dev/ttyNX0 Hilscher netX serial port 0 + 50 = /dev/ttyIOC40 Altix serial card ... - 185 = /dev/ttyNX15 Hilscher netX serial port 15 - 186 = /dev/ttyJ0 JTAG1 DCC protocol based serial port emulation + 81 = /dev/ttyIOC431 Altix serial card + 82 = /dev/ttyVR0 NEC VR4100 series SIU + 83 = /dev/ttyVR1 NEC VR4100 series DSIU 205 char Low-density serial ports (alternate device) 0 = /dev/culu0 Callout device for ttyLU0 @@ -2826,8 +2786,8 @@ Your cooperation is appreciated. 50 = /dev/cuioc40 Callout device for ttyIOC40 ... 81 = /dev/cuioc431 Callout device for ttyIOC431 - 82 = /dev/cuvr0 Callout device for ttyVR0 - 83 = /dev/cuvr1 Callout device for ttyVR1 + 82 = /dev/cuvr0 Callout device for ttyVR0 + 83 = /dev/cuvr1 Callout device for ttyVR1 206 char OnStream SC-x0 tape devices @@ -2937,6 +2897,7 @@ Your cooperation is appreciated. ... 196 = /dev/dvb/adapter3/video0 first video decoder of fourth card + 216 char Bluetooth RFCOMM TTY devices 0 = /dev/rfcomm0 First Bluetooth RFCOMM TTY device 1 = /dev/rfcomm1 Second Bluetooth RFCOMM TTY device @@ -3041,43 +3002,12 @@ Your cooperation is appreciated. ioctl()'s can be used to rewind the tape regardless of the device used to access it. -231 char InfiniBand +231 char InfiniBand MAD 0 = /dev/infiniband/umad0 1 = /dev/infiniband/umad1 - ... - 63 = /dev/infiniband/umad63 63rd InfiniBandMad device - 64 = /dev/infiniband/issm0 First InfiniBand IsSM device - 65 = /dev/infiniband/issm1 Second InfiniBand IsSM device - ... - 127 = /dev/infiniband/issm63 63rd InfiniBand IsSM device - 128 = /dev/infiniband/uverbs0 First InfiniBand verbs device - 129 = /dev/infiniband/uverbs1 Second InfiniBand verbs device - ... - 159 = /dev/infiniband/uverbs31 31st InfiniBand verbs device - -232 char Biometric Devices - 0 = /dev/biometric/sensor0/fingerprint first fingerprint sensor on first device - 1 = /dev/biometric/sensor0/iris first iris sensor on first device - 2 = /dev/biometric/sensor0/retina first retina sensor on first device - 3 = /dev/biometric/sensor0/voiceprint first voiceprint sensor on first device - 4 = /dev/biometric/sensor0/facial first facial sensor on first device - 5 = /dev/biometric/sensor0/hand first hand sensor on first device - ... - 10 = /dev/biometric/sensor1/fingerprint first fingerprint sensor on second device - ... - 20 = /dev/biometric/sensor2/fingerprint first fingerprint sensor on third device - ... - -233 char PathScale InfiniPath interconnect - 0 = /dev/ipath Primary device for programs (any unit) - 1 = /dev/ipath0 Access specifically to unit 0 - 2 = /dev/ipath1 Access specifically to unit 1 - ... - 4 = /dev/ipath3 Access specifically to unit 3 - 129 = /dev/ipath_sma Device used by Subnet Management Agent - 130 = /dev/ipath_diag Device used by diagnostics programs + ... -234-239 UNASSIGNED +232-239 UNASSIGNED 240-254 char LOCAL/EXPERIMENTAL USE 240-254 block LOCAL/EXPERIMENTAL USE @@ -3091,28 +3021,6 @@ Your cooperation is appreciated. This major is reserved to assist the expansion to a larger number space. No device nodes with this major should ever be created on the filesystem. - (This is probaly not true anymore, but I'll leave it - for now /Torben) - ----LARGE MAJORS!!!!!--- - -256 char Equinox SST multi-port serial boards - 0 = /dev/ttyEQ0 First serial port on first Equinox SST board - 127 = /dev/ttyEQ127 Last serial port on first Equinox SST board - 128 = /dev/ttyEQ128 First serial port on second Equinox SST board - ... - 1027 = /dev/ttyEQ1027 Last serial port on eighth Equinox SST board - -256 block Resident Flash Disk Flash Translation Layer - 0 = /dev/rfda First RFD FTL layer - 16 = /dev/rfdb Second RFD FTL layer - ... - 240 = /dev/rfdp 16th RFD FTL layer - -257 char Phoenix Technologies Cryptographic Services Driver - 0 = /dev/ptlsec Crypto Services Driver - - **** ADDITIONAL /dev DIRECTORY ENTRIES diff --git a/trunk/Documentation/driver-model/overview.txt b/trunk/Documentation/driver-model/overview.txt index 2050c9ffc629..ac4a7a737e43 100644 --- a/trunk/Documentation/driver-model/overview.txt +++ b/trunk/Documentation/driver-model/overview.txt @@ -18,7 +18,7 @@ Traditional driver models implemented some sort of tree-like structure (sometimes just a list) for the devices they control. There wasn't any uniformity across the different bus types. -The current driver model provides a common, uniform data model for describing +The current driver model provides a comon, uniform data model for describing a bus and the devices that can appear under the bus. The unified bus model includes a set of common attributes which all busses carry, and a set of common callbacks, such as device discovery during bus probing, bus diff --git a/trunk/Documentation/fb/fbcon.txt b/trunk/Documentation/fb/fbcon.txt index f373df12ed4c..08dce0f631bf 100644 --- a/trunk/Documentation/fb/fbcon.txt +++ b/trunk/Documentation/fb/fbcon.txt @@ -135,10 +135,10 @@ C. Boot options The angle can be changed anytime afterwards by 'echoing' the same numbers to any one of the 2 attributes found in - /sys/class/graphics/fbcon + /sys/class/graphics/fb{x} - rotate - rotate the display of the active console - rotate_all - rotate the display of all consoles + con_rotate - rotate the display of the active console + con_rotate_all - rotate the display of all consoles Console rotation will only become available if Console Rotation Support is compiled in your kernel. @@ -148,177 +148,5 @@ C. Boot options Actually, the underlying fb driver is totally ignorant of console rotation. -C. Attaching, Detaching and Unloading - -Before going on on how to attach, detach and unload the framebuffer console, an -illustration of the dependencies may help. - -The console layer, as with most subsystems, needs a driver that interfaces with -the hardware. Thus, in a VGA console: - -console ---> VGA driver ---> hardware. - -Assuming the VGA driver can be unloaded, one must first unbind the VGA driver -from the console layer before unloading the driver. The VGA driver cannot be -unloaded if it is still bound to the console layer. (See -Documentation/console/console.txt for more information). - -This is more complicated in the case of the the framebuffer console (fbcon), -because fbcon is an intermediate layer between the console and the drivers: - -console ---> fbcon ---> fbdev drivers ---> hardware - -The fbdev drivers cannot be unloaded if it's bound to fbcon, and fbcon cannot -be unloaded if it's bound to the console layer. - -So to unload the fbdev drivers, one must first unbind fbcon from the console, -then unbind the fbdev drivers from fbcon. Fortunately, unbinding fbcon from -the console layer will automatically unbind framebuffer drivers from -fbcon. Thus, there is no need to explicitly unbind the fbdev drivers from -fbcon. - -So, how do we unbind fbcon from the console? Part of the answer is in -Documentation/console/console.txt. To summarize: - -Echo a value to the bind file that represents the framebuffer console -driver. So assuming vtcon1 represents fbcon, then: - -echo 1 > sys/class/vtconsole/vtcon1/bind - attach framebuffer console to - console layer -echo 0 > sys/class/vtconsole/vtcon1/bind - detach framebuffer console from - console layer - -If fbcon is detached from the console layer, your boot console driver (which is -usually VGA text mode) will take over. A few drivers (rivafb and i810fb) will -restore VGA text mode for you. With the rest, before detaching fbcon, you -must take a few additional steps to make sure that your VGA text mode is -restored properly. The following is one of the several methods that you can do: - -1. Download or install vbetool. This utility is included with most - distributions nowadays, and is usually part of the suspend/resume tool. - -2. In your kernel configuration, ensure that CONFIG_FRAMEBUFFER_CONSOLE is set - to 'y' or 'm'. Enable one or more of your favorite framebuffer drivers. - -3. Boot into text mode and as root run: - - vbetool vbestate save > - - The above command saves the register contents of your graphics - hardware to . You need to do this step only once as - the state file can be reused. - -4. If fbcon is compiled as a module, load fbcon by doing: - - modprobe fbcon - -5. Now to detach fbcon: - - vbetool vbestate restore < && \ - echo 0 > /sys/class/vtconsole/vtcon1/bind - -6. That's it, you're back to VGA mode. And if you compiled fbcon as a module, - you can unload it by 'rmmod fbcon' - -7. To reattach fbcon: - - echo 1 > /sys/class/vtconsole/vtcon1/bind - -8. Once fbcon is unbound, all drivers registered to the system will also -become unbound. This means that fbcon and individual framebuffer drivers -can be unloaded or reloaded at will. Reloading the drivers or fbcon will -automatically bind the console, fbcon and the drivers together. Unloading -all the drivers without unloading fbcon will make it impossible for the -console to bind fbcon. - -Notes for vesafb users: -======================= - -Unfortunately, if your bootline includes a vga=xxx parameter that sets the -hardware in graphics mode, such as when loading vesafb, vgacon will not load. -Instead, vgacon will replace the default boot console with dummycon, and you -won't get any display after detaching fbcon. Your machine is still alive, so -you can reattach vesafb. However, to reattach vesafb, you need to do one of -the following: - -Variation 1: - - a. Before detaching fbcon, do - - vbetool vbemode save > # do once for each vesafb mode, - # the file can be reused - - b. Detach fbcon as in step 5. - - c. Attach fbcon - - vbetool vbestate restore < && \ - echo 1 > /sys/class/vtconsole/vtcon1/bind - -Variation 2: - - a. Before detaching fbcon, do: - echo > /sys/class/tty/console/bind - - - vbetool vbemode get - - b. Take note of the mode number - - b. Detach fbcon as in step 5. - - c. Attach fbcon: - - vbetool vbemode set && \ - echo 1 > /sys/class/vtconsole/vtcon1/bind - -Samples: -======== - -Here are 2 sample bash scripts that you can use to bind or unbind the -framebuffer console driver if you are in an X86 box: - ---------------------------------------------------------------------------- -#!/bin/bash -# Unbind fbcon - -# Change this to where your actual vgastate file is located -# Or Use VGASTATE=$1 to indicate the state file at runtime -VGASTATE=/tmp/vgastate - -# path to vbetool -VBETOOL=/usr/local/bin - - -for (( i = 0; i < 16; i++)) -do - if test -x /sys/class/vtconsole/vtcon$i; then - if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \ - = 1 ]; then - if test -x $VBETOOL/vbetool; then - echo Unbinding vtcon$i - $VBETOOL/vbetool vbestate restore < $VGASTATE - echo 0 > /sys/class/vtconsole/vtcon$i/bind - fi - fi - fi -done - ---------------------------------------------------------------------------- -#!/bin/bash -# Bind fbcon - -for (( i = 0; i < 16; i++)) -do - if test -x /sys/class/vtconsole/vtcon$i; then - if [ `cat /sys/class/vtconsole/vtcon$i/name | grep -c "frame buffer"` \ - = 1 ]; then - echo Unbinding vtcon$i - echo 1 > /sys/class/vtconsole/vtcon$i/bind - fi - fi -done ---------------------------------------------------------------------------- - --- +--- Antonino Daplas diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 027285d0c26c..f7293297f326 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -33,6 +33,21 @@ Who: Adrian Bunk --------------------------- +What: RCU API moves to EXPORT_SYMBOL_GPL +When: April 2006 +Files: include/linux/rcupdate.h, kernel/rcupdate.c +Why: Outside of Linux, the only implementations of anything even + vaguely resembling RCU that I am aware of are in DYNIX/ptx, + VM/XA, Tornado, and K42. I do not expect anyone to port binary + drivers or kernel modules from any of these, since the first two + are owned by IBM and the last two are open-source research OSes. + So these will move to GPL after a grace period to allow + people, who might be using implementations that I am not aware + of, to adjust to this upcoming change. +Who: Paul E. McKenney + +--------------------------- + What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN When: November 2006 Why: Deprecated in favour of the new ioctl-based rawiso interface, which is diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index d31efbbdfe50..1045da582b9b 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -99,7 +99,7 @@ prototypes: int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct dentry *, struct kstatfs *); + int (*statfs) (struct super_block *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); @@ -142,16 +142,15 @@ see also dquot_operations section. --------------------------- file_system_type --------------------------- prototypes: - struct int (*get_sb) (struct file_system_type *, int, - const char *, void *, struct vfsmount *); + struct super_block *(*get_sb) (struct file_system_type *, int, + const char *, void *); void (*kill_sb) (struct super_block *); locking rules: may block BKL get_sb yes yes kill_sb yes yes -->get_sb() returns error or 0 with locked superblock attached to the vfsmount -(exclusive on ->s_umount). +->get_sb() returns error or a locked superblock (exclusive on ->s_umount). ->kill_sb() takes a write-locked superblock, does all shutdown work on it, unlocks and drops the reference. diff --git a/trunk/Documentation/filesystems/automount-support.txt b/trunk/Documentation/filesystems/automount-support.txt index 7cac200e2a85..58c65a1713e5 100644 --- a/trunk/Documentation/filesystems/automount-support.txt +++ b/trunk/Documentation/filesystems/automount-support.txt @@ -19,7 +19,7 @@ following procedure: (2) Have the follow_link() op do the following steps: - (a) Call vfs_kern_mount() to call the appropriate filesystem to set up a + (a) Call do_kern_mount() to call the appropriate filesystem to set up a superblock and gain a vfsmount structure representing it. (b) Copy the nameidata provided as an argument and substitute the dentry diff --git a/trunk/Documentation/filesystems/ext3.txt b/trunk/Documentation/filesystems/ext3.txt index 4aecc9bdb273..afb1335c05d6 100644 --- a/trunk/Documentation/filesystems/ext3.txt +++ b/trunk/Documentation/filesystems/ext3.txt @@ -113,14 +113,6 @@ noquota grpquota usrquota -bh (*) ext3 associates buffer heads to data pages to -nobh (a) cache disk block mapping information - (b) link pages into transaction to provide - ordering guarantees. - "bh" option forces use of buffer heads. - "nobh" option tries to avoid associating buffer - heads (supported only for "writeback" mode). - Specification ============= diff --git a/trunk/Documentation/filesystems/fuse.txt b/trunk/Documentation/filesystems/fuse.txt index a584f05403a4..33f74310d161 100644 --- a/trunk/Documentation/filesystems/fuse.txt +++ b/trunk/Documentation/filesystems/fuse.txt @@ -18,14 +18,6 @@ Non-privileged mount (or user mount): user. NOTE: this is not the same as mounts allowed with the "user" option in /etc/fstab, which is not discussed here. -Filesystem connection: - - A connection between the filesystem daemon and the kernel. The - connection exists until either the daemon dies, or the filesystem is - umounted. Note that detaching (or lazy umounting) the filesystem - does _not_ break the connection, in this case it will exist until - the last reference to the filesystem is released. - Mount owner: The user who does the mounting. @@ -94,20 +86,16 @@ Mount options The default is infinite. Note that the size of read requests is limited anyway to 32 pages (which is 128kbyte on i386). -Control filesystem -~~~~~~~~~~~~~~~~~~ - -There's a control filesystem for FUSE, which can be mounted by: +Sysfs +~~~~~ - mount -t fusectl none /sys/fs/fuse/connections +FUSE sets up the following hierarchy in sysfs: -Mounting it under the '/sys/fs/fuse/connections' directory makes it -backwards compatible with earlier versions. + /sys/fs/fuse/connections/N/ -Under the fuse control filesystem each connection has a directory -named by a unique number. +where N is an increasing number allocated to each new connection. -For each connection the following files exist within this directory: +For each connection the following attributes are defined: 'waiting' @@ -122,47 +110,7 @@ For each connection the following files exist within this directory: connection. This means that all waiting requests will be aborted an error returned for all aborted and new requests. -Only the owner of the mount may read or write these files. - -Interrupting filesystem operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If a process issuing a FUSE filesystem request is interrupted, the -following will happen: - - 1) If the request is not yet sent to userspace AND the signal is - fatal (SIGKILL or unhandled fatal signal), then the request is - dequeued and returns immediately. - - 2) If the request is not yet sent to userspace AND the signal is not - fatal, then an 'interrupted' flag is set for the request. When - the request has been successfully transfered to userspace and - this flag is set, an INTERRUPT request is queued. - - 3) If the request is already sent to userspace, then an INTERRUPT - request is queued. - -INTERRUPT requests take precedence over other requests, so the -userspace filesystem will receive queued INTERRUPTs before any others. - -The userspace filesystem may ignore the INTERRUPT requests entirely, -or may honor them by sending a reply to the _original_ request, with -the error set to EINTR. - -It is also possible that there's a race between processing the -original request and it's INTERRUPT request. There are two possibilities: - - 1) The INTERRUPT request is processed before the original request is - processed - - 2) The INTERRUPT request is processed after the original request has - been answered - -If the filesystem cannot find the original request, it should wait for -some timeout and/or a number of new requests to arrive, after which it -should reply to the INTERRUPT request with an EAGAIN error. In case -1) the INTERRUPT request will be requeued. In case 2) the INTERRUPT -reply will be ignored. +Only a privileged user may read or write these attributes. Aborting a filesystem connection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -191,8 +139,8 @@ the filesystem. There are several ways to do this: - Use forced umount (umount -f). Works in all cases but only if filesystem is still attached (it hasn't been lazy unmounted) - - Abort filesystem through the FUSE control filesystem. Most - powerful method, always works. + - Abort filesystem through the sysfs interface. Most powerful + method, always works. How do non-privileged mounts work? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -356,7 +304,25 @@ Scenario 1 - Simple deadlock | | for "file"] | | *DEADLOCK* -The solution for this is to allow the filesystem to be aborted. +The solution for this is to allow requests to be interrupted while +they are in userspace: + + | [interrupted by signal] | + | fuse_unlink() + | | [queue req on fc->pending] + | | [wake up fc->waitq] + | | [sleep on req->waitq] + +If the filesystem daemon was single threaded, this will stop here, +since there's no other thread to dequeue and execute the request. +In this case the solution is to kill the FUSE daemon as well. If +there are multiple serving threads, you just have to kill them as +long as any remain. + +Moral: a filesystem which deadlocks, can soon find itself dead. Scenario 2 - Tricky deadlock ---------------------------- @@ -389,14 +355,24 @@ but is caused by a pagefault. | | [lock page] | | * DEADLOCK * -Solution is basically the same as above. +Solution is again to let the the request be interrupted (not +elaborated further). + +An additional problem is that while the write buffer is being +copied to the request, the request must not be interrupted. This +is because the destination address of the copy may not be valid +after the request is interrupted. + +This is solved with doing the copy atomically, and allowing +interruption while the page(s) belonging to the write buffer are +faulted with get_user_pages(). The 'req->locked' flag indicates +when the copy is taking place, and interruption is delayed until +this flag is unset. -An additional problem is that while the write buffer is being copied -to the request, the request must not be interrupted/aborted. This is -because the destination address of the copy may not be valid after the -request has returned. +Scenario 3 - Tricky deadlock with asynchronous read +--------------------------------------------------- -This is solved with doing the copy atomically, and allowing abort -while the page(s) belonging to the write buffer are faulted with -get_user_pages(). The 'req->locked' flag indicates when the copy is -taking place, and abort is delayed until this flag is unset. +The same situation as above, except thread-1 will wait on page lock +and hence it will be uninterruptible as well. The solution is to +abort the connection with forced umount (if mount is attached) or +through the abort attribute in sysfs. diff --git a/trunk/Documentation/filesystems/porting b/trunk/Documentation/filesystems/porting index 5531694059ab..2f388460cbe7 100644 --- a/trunk/Documentation/filesystems/porting +++ b/trunk/Documentation/filesystems/porting @@ -50,11 +50,10 @@ Turn your foo_read_super() into a function that would return 0 in case of success and negative number in case of error (-EINVAL unless you have more informative error value to report). Call it foo_fill_super(). Now declare -int foo_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +struct super_block foo_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) { - return get_sb_bdev(fs_type, flags, dev_name, data, foo_fill_super, - mnt); + return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super); } (or similar with s/bdev/nodev/ or s/bdev/single/, depending on the kind of diff --git a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt index 25981e2e51be..60ab61e54e8a 100644 --- a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt +++ b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt @@ -70,13 +70,11 @@ tmpfs mounts. See Documentation/filesystems/tmpfs.txt for more information. What is rootfs? --------------- -Rootfs is a special instance of ramfs (or tmpfs, if that's enabled), which is -always present in 2.6 systems. You can't unmount rootfs for approximately the -same reason you can't kill the init process; rather than having special code -to check for and handle an empty list, it's smaller and simpler for the kernel -to just make sure certain lists can't become empty. +Rootfs is a special instance of ramfs, which is always present in 2.6 systems. +(It's used internally as the starting and stopping point for searches of the +kernel's doubly-linked list of mount points.) -Most systems just mount another filesystem over rootfs and ignore it. The +Most systems just mount another filesystem over it and ignore it. The amount of space an empty instance of ramfs takes up is tiny. What is initramfs? @@ -94,16 +92,14 @@ out of that. All this differs from the old initrd in several ways: - - The old initrd was always a separate file, while the initramfs archive is - linked into the linux kernel image. (The directory linux-*/usr is devoted - to generating this archive during the build.) + - The old initrd was a separate file, while the initramfs archive is linked + into the linux kernel image. (The directory linux-*/usr is devoted to + generating this archive during the build.) - The old initrd file was a gzipped filesystem image (in some file format, - such as ext2, that needed a driver built into the kernel), while the new + such as ext2, that had to be built into the kernel), while the new initramfs archive is a gzipped cpio archive (like tar only simpler, - see cpio(1) and Documentation/early-userspace/buffer-format.txt). The - kernel's cpio extraction code is not only extremely small, it's also - __init data that can be discarded during the boot process. + see cpio(1) and Documentation/early-userspace/buffer-format.txt). - The program run by the old initrd (which was called /initrd, not /init) did some setup and then returned to the kernel, while the init program from @@ -128,14 +124,13 @@ Populating initramfs: The 2.6 kernel build process always creates a gzipped cpio format initramfs archive and links it into the resulting kernel binary. By default, this -archive is empty (consuming 134 bytes on x86). - -The config option CONFIG_INITRAMFS_SOURCE (for some reason buried under -devices->block devices in menuconfig, and living in usr/Kconfig) can be used -to specify a source for the initramfs archive, which will automatically be -incorporated into the resulting binary. This option can point to an existing -gzipped cpio archive, a directory containing files to be archived, or a text -file specification such as the following example: +archive is empty (consuming 134 bytes on x86). The config option +CONFIG_INITRAMFS_SOURCE (for some reason buried under devices->block devices +in menuconfig, and living in usr/Kconfig) can be used to specify a source for +the initramfs archive, which will automatically be incorporated into the +resulting binary. This option can point to an existing gzipped cpio archive, a +directory containing files to be archived, or a text file specification such +as the following example: dir /dev 755 0 0 nod /dev/console 644 0 0 c 5 1 @@ -151,84 +146,23 @@ file specification such as the following example: Run "usr/gen_init_cpio" (after the kernel build) to get a usage message documenting the above file format. -One advantage of the configuration file is that root access is not required to +One advantage of the text file is that root access is not required to set permissions or create device nodes in the new archive. (Note that those two example "file" entries expect to find files named "init.sh" and "busybox" in a directory called "initramfs", under the linux-2.6.* directory. See Documentation/early-userspace/README for more details.) -The kernel does not depend on external cpio tools. If you specify a -directory instead of a configuration file, the kernel's build infrastructure -creates a configuration file from that directory (usr/Makefile calls -scripts/gen_initramfs_list.sh), and proceeds to package up that directory -using the config file (by feeding it to usr/gen_init_cpio, which is created -from usr/gen_init_cpio.c). The kernel's build-time cpio creation code is -entirely self-contained, and the kernel's boot-time extractor is also -(obviously) self-contained. - -The one thing you might need external cpio utilities installed for is creating -or extracting your own preprepared cpio files to feed to the kernel build -(instead of a config file or directory). - -The following command line can extract a cpio image (either by the above script -or by the kernel build) back into its component files: +The kernel does not depend on external cpio tools, gen_init_cpio is created +from usr/gen_init_cpio.c which is entirely self-contained, and the kernel's +boot-time extractor is also (obviously) self-contained. However, if you _do_ +happen to have cpio installed, the following command line can extract the +generated cpio image back into its component files: cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames -The following shell script can create a prebuilt cpio archive you can -use in place of the above config file: - - #!/bin/sh - - # Copyright 2006 Rob Landley and TimeSys Corporation. - # Licensed under GPL version 2 - - if [ $# -ne 2 ] - then - echo "usage: mkinitramfs directory imagename.cpio.gz" - exit 1 - fi - - if [ -d "$1" ] - then - echo "creating $2 from $1" - (cd "$1"; find . | cpio -o -H newc | gzip) > "$2" - else - echo "First argument must be a directory" - exit 1 - fi - -Note: The cpio man page contains some bad advice that will break your initramfs -archive if you follow it. It says "A typical way to generate the list -of filenames is with the find command; you should give find the -depth option -to minimize problems with permissions on directories that are unwritable or not -searchable." Don't do this when creating initramfs.cpio.gz images, it won't -work. The Linux kernel cpio extractor won't create files in a directory that -doesn't exist, so the directory entries must go before the files that go in -those directories. The above script gets them in the right order. - -External initramfs images: --------------------------- - -If the kernel has initrd support enabled, an external cpio.gz archive can also -be passed into a 2.6 kernel in place of an initrd. In this case, the kernel -will autodetect the type (initramfs, not initrd) and extract the external cpio -archive into rootfs before trying to run /init. - -This has the memory efficiency advantages of initramfs (no ramdisk block -device) but the separate packaging of initrd (which is nice if you have -non-GPL code you'd like to run from initramfs, without conflating it with -the GPL licensed Linux kernel binary). - -It can also be used to supplement the kernel's built-in initamfs image. The -files in the external archive will overwrite any conflicting files in -the built-in initramfs archive. Some distributors also prefer to customize -a single kernel image with task-specific initramfs images, without recompiling. - Contents of initramfs: ---------------------- -An initramfs archive is a complete self-contained root filesystem for Linux. If you don't already understand what shared libraries, devices, and paths you need to get a minimal root filesystem up and running, here are some references: @@ -242,36 +176,13 @@ code against, along with some related utilities. It is BSD licensed. I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net) myself. These are LGPL and GPL, respectively. (A self-contained initramfs -package is planned for the busybox 1.3 release.) +package is planned for the busybox 1.2 release.) In theory you could use glibc, but that's not well suited for small embedded uses like this. (A "hello world" program statically linked against glibc is over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do name lookups, even when otherwise statically linked.) -A good first step is to get initramfs to run a statically linked "hello world" -program as init, and test it under an emulator like qemu (www.qemu.org) or -User Mode Linux, like so: - - cat > hello.c << EOF - #include - #include - - int main(int argc, char *argv[]) - { - printf("Hello world!\n"); - sleep(999999999); - } - EOF - gcc -static hello2.c -o init - echo init | cpio -o -H newc | gzip > test.cpio.gz - # Testing external initramfs using the initrd loading mechanism. - qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero - -When debugging a normal root filesystem, it's nice to be able to boot with -"init=/bin/sh". The initramfs equivalent is "rdinit=/bin/sh", and it's -just as useful. - Why cpio rather than tar? ------------------------- @@ -330,7 +241,7 @@ the above threads) is: Future directions: ------------------ -Today (2.6.16), initramfs is always compiled in, but not always used. The +Today (2.6.14), initramfs is always compiled in, but not always used. The kernel falls back to legacy boot code that is reached only if initramfs does not contain an /init program. The fallback is legacy code, there to ensure a smooth transition and allowing early boot functionality to gradually move to @@ -347,9 +258,8 @@ and so on. This kind of complexity (which inevitably includes policy) is rightly handled in userspace. Both klibc and busybox/uClibc are working on simple initramfs -packages to drop into a kernel build. +packages to drop into a kernel build, and when standard solutions are ready +and widely deployed, the kernel's legacy early boot code will become obsolete +and a candidate for the feature removal schedule. -The klibc package has now been accepted into Andrew Morton's 2.6.17-mm tree. -The kernel's current early boot code (partition detection, etc) will probably -be migrated into a default initramfs, automatically created and used by the -kernel build. +But that's a while off yet. diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index 9d3aed628bc1..3a2e5520c1e3 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -113,8 +113,8 @@ members are defined: struct file_system_type { const char *name; int fs_flags; - struct int (*get_sb) (struct file_system_type *, int, - const char *, void *, struct vfsmount *); + struct super_block *(*get_sb) (struct file_system_type *, int, + const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; struct file_system_type * next; @@ -211,7 +211,7 @@ struct super_operations { int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct dentry *, struct kstatfs *); + int (*statfs) (struct super_block *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); diff --git a/trunk/Documentation/hwmon/abituguru b/trunk/Documentation/hwmon/abituguru deleted file mode 100644 index 69cdb527d58f..000000000000 --- a/trunk/Documentation/hwmon/abituguru +++ /dev/null @@ -1,59 +0,0 @@ -Kernel driver abituguru -======================= - -Supported chips: - * Abit uGuru (Hardware Monitor part only) - Prefix: 'abituguru' - Addresses scanned: ISA 0x0E0 - Datasheet: Not available, this driver is based on reverse engineering. - A "Datasheet" has been written based on the reverse engineering it - should be available in the same dir as this file under the name - abituguru-datasheet. - -Authors: - Hans de Goede , - (Initial reverse engineering done by Olle Sandberg - ) - - -Module Parameters ------------------ - -* force: bool Force detection. Note this parameter only causes the - detection to be skipped, if the uGuru can't be read - the module initialization (insmod) will still fail. -* fan_sensors: int Tell the driver how many fan speed sensors there are - on your motherboard. Default: 0 (autodetect). -* pwms: int Tell the driver how many fan speed controls (fan - pwms) your motherboard has. Default: 0 (autodetect). -* verbose: int How verbose should the driver be? (0-3): - 0 normal output - 1 + verbose error reporting - 2 + sensors type probing info\n" - 3 + retryable error reporting - Default: 2 (the driver is still in the testing phase) - -Notice if you need any of the first three options above please insmod the -driver with verbose set to 3 and mail me the output of: -dmesg | grep abituguru - - -Description ------------ - -This driver supports the hardware monitoring features of the Abit uGuru chip -found on Abit uGuru featuring motherboards (most modern Abit motherboards). - -The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit -claiming it is "a new microprocessor designed by the ABIT Engineers"). -Unfortunatly this doesn't help since the W83L950D is a generic -microcontroller with a custom Abit application running on it. - -Despite Abit not releasing any information regarding the uGuru, Olle -Sandberg has managed to reverse engineer the sensor part -of the uGuru. Without his work this driver would not have been possible. - -Known Issues ------------- - -The voltage and frequency control parts of the Abit uGuru are not supported. diff --git a/trunk/Documentation/hwmon/abituguru-datasheet b/trunk/Documentation/hwmon/abituguru-datasheet deleted file mode 100644 index aef5a9b36846..000000000000 --- a/trunk/Documentation/hwmon/abituguru-datasheet +++ /dev/null @@ -1,312 +0,0 @@ -uGuru datasheet -=============== - -First of all, what I know about uGuru is no fact based on any help, hints or -datasheet from Abit. The data I have got on uGuru have I assembled through -my weak knowledge in "backwards engineering". -And just for the record, you may have noticed uGuru isn't a chip developed by -Abit, as they claim it to be. It's realy just an microprocessor (uC) created by -Winbond (W83L950D). And no, reading the manual for this specific uC or -mailing Windbond for help won't give any usefull data about uGuru, as it is -the program inside the uC that is responding to calls. - -Olle Sandberg , 2005-05-25 - - -Original version by Olle Sandberg who did the heavy lifting of the initial -reverse engineering. This version has been almost fully rewritten for clarity -and extended with write support and info on more databanks, the write support -is once again reverse engineered by Olle the additional databanks have been -reverse engineered by me. I would like to express my thanks to Olle, this -document and the Linux driver could not have been written without his efforts. - -Note: because of the lack of specs only the sensors part of the uGuru is -described here and not the CPU / RAM / etc voltage & frequency control. - -Hans de Goede , 28-01-2006 - - -Detection -========= - -As far as known the uGuru is always placed at and using the (ISA) I/O-ports -0xE0 and 0xE4, so we don't have to scan any port-range, just check what the two -ports are holding for detection. We will refer to 0xE0 as CMD (command-port) -and 0xE4 as DATA because Abit refers to them with these names. - -If DATA holds 0x00 or 0x08 and CMD holds 0x00 or 0xAC an uGuru could be -present. We have to check for two different values at data-port, because -after a reboot uGuru will hold 0x00 here, but if the driver is removed and -later on attached again data-port will hold 0x08, more about this later. - -After wider testing of the Linux kernel driver some variants of the uGuru have -turned up which will hold 0x00 instead of 0xAC at the CMD port, thus we also -have to test CMD for two different values. On these uGuru's DATA will initally -hold 0x09 and will only hold 0x08 after reading CMD first, so CMD must be read -first! - -To be really sure an uGuru is present a test read of one or more register -sets should be done. - - -Reading / Writing -================= - -Addressing ----------- - -The uGuru has a number of different addressing levels. The first addressing -level we will call banks. A bank holds data for one or more sensors. The data -in a bank for a sensor is one or more bytes large. - -The number of bytes is fixed for a given bank, you should always read or write -that many bytes, reading / writing more will fail, the results when writing -less then the number of bytes for a given bank are undetermined. - -See below for all known bank addresses, numbers of sensors in that bank, -number of bytes data per sensor and contents/meaning of those bytes. - -Although both this document and the kernel driver have kept the sensor -terminoligy for the addressing within a bank this is not 100% correct, in -bank 0x24 for example the addressing within the bank selects a PWM output not -a sensor. - -Notice that some banks have both a read and a write address this is how the -uGuru determines if a read from or a write to the bank is taking place, thus -when reading you should always use the read address and when writing the -write address. The write address is always one (1) more then the read address. - - -uGuru ready ------------ - -Before you can read from or write to the uGuru you must first put the uGuru -in "ready" mode. - -To put the uGuru in ready mode first write 0x00 to DATA and then wait for DATA -to hold 0x09, DATA should read 0x09 within 250 read cycles. - -Next CMD _must_ be read and should hold 0xAC, usually CMD will hold 0xAC the -first read but sometimes it takes a while before CMD holds 0xAC and thus it -has to be read a number of times (max 50). - -After reading CMD, DATA should hold 0x08 which means that the uGuru is ready -for input. As above DATA will usually hold 0x08 the first read but not always. -This step can be skipped, but it is undetermined what happens if the uGuru has -not yet reported 0x08 at DATA and you proceed with writing a bank address. - - -Sending bank and sensor addresses to the uGuru ----------------------------------------------- - -First the uGuru must be in "ready" mode as described above, DATA should hold -0x08 indicating that the uGuru wants input, in this case the bank address. - -Next write the bank address to DATA. After the bank address has been written -wait for to DATA to hold 0x08 again indicating that it wants / is ready for -more input (max 250 reads). - -Once DATA holds 0x08 again write the sensor address to CMD. - - -Reading -------- - -First send the bank and sensor addresses as described above. -Then for each byte of data you want to read wait for DATA to hold 0x01 -which indicates that the uGuru is ready to be read (max 250 reads) and once -DATA holds 0x01 read the byte from CMD. - -Once all bytes have been read data will hold 0x09, but there is no reason to -test for this. Notice that the number of bytes is bank address dependent see -above and below. - -After completing a successfull read it is advised to put the uGuru back in -ready mode, so that it is ready for the next read / write cycle. This way -if your program / driver is unloaded and later loaded again the detection -algorithm described above will still work. - - - -Writing -------- - -First send the bank and sensor addresses as described above. -Then for each byte of data you want to write wait for DATA to hold 0x00 -which indicates that the uGuru is ready to be written (max 250 reads) and -once DATA holds 0x00 write the byte to CMD. - -Once all bytes have been written wait for DATA to hold 0x01 (max 250 reads) -don't ask why this is the way it is. - -Once DATA holds 0x01 read CMD it should hold 0xAC now. - -After completing a successfull write it is advised to put the uGuru back in -ready mode, so that it is ready for the next read / write cycle. This way -if your program / driver is unloaded and later loaded again the detection -algorithm described above will still work. - - -Gotchas -------- - -After wider testing of the Linux kernel driver some variants of the uGuru have -turned up which do not hold 0x08 at DATA within 250 reads after writing the -bank address. With these versions this happens quite frequent, using larger -timeouts doesn't help, they just go offline for a second or 2, doing some -internal callibration or whatever. Your code should be prepared to handle -this and in case of no response in this specific case just goto sleep for a -while and then retry. - - -Address Map -=========== - -Bank 0x20 Alarms (R) --------------------- -This bank contains 0 sensors, iow the sensor address is ignored (but must be -written) just use 0. Bank 0x20 contains 3 bytes: - -Byte 0: -This byte holds the alarm flags for sensor 0-7 of Sensor Bank1, with bit 0 -corresponding to sensor 0, 1 to 1, etc. - -Byte 1: -This byte holds the alarm flags for sensor 8-15 of Sensor Bank1, with bit 0 -corresponding to sensor 8, 1 to 9, etc. - -Byte 2: -This byte holds the alarm flags for sensor 0-5 of Sensor Bank2, with bit 0 -corresponding to sensor 0, 1 to 1, etc. - - -Bank 0x21 Sensor Bank1 Values / Readings (R) --------------------------------------------- -This bank contains 16 sensors, for each sensor it contains 1 byte. -So far the following sensors are known to be available on all motherboards: -Sensor 0 CPU temp -Sensor 1 SYS temp -Sensor 3 CPU core volt -Sensor 4 DDR volt -Sensor 10 DDR Vtt volt -Sensor 15 PWM temp - -Byte 0: -This byte holds the reading from the sensor. Sensors in Bank1 can be both -volt and temp sensors, this is motherboard specific. The uGuru however does -seem to know (be programmed with) what kindoff sensor is attached see Sensor -Bank1 Settings description. - -Volt sensors use a linear scale, a reading 0 corresponds with 0 volt and a -reading of 255 with 3494 mV. The sensors for higher voltages however are -connected through a division circuit. The currently known division circuits -in use result in ranges of: 0-4361mV, 0-6248mV or 0-14510mV. 3.3 volt sources -use the 0-4361mV range, 5 volt the 0-6248mV and 12 volt the 0-14510mV . - -Temp sensors also use a linear scale, a reading of 0 corresponds with 0 degree -Celsius and a reading of 255 with a reading of 255 degrees Celsius. - - -Bank 0x22 Sensor Bank1 Settings (R) -Bank 0x23 Sensor Bank1 Settings (W) ------------------------------------ - -This bank contains 16 sensors, for each sensor it contains 3 bytes. Each -set of 3 bytes contains the settings for the sensor with the same sensor -address in Bank 0x21 . - -Byte 0: -Alarm behaviour for the selected sensor. A 1 enables the described behaviour. -Bit 0: Give an alarm if measured temp is over the warning threshold (RW) * -Bit 1: Give an alarm if measured volt is over the max threshold (RW) ** -Bit 2: Give an alarm if measured volt is under the min threshold (RW) ** -Bit 3: Beep if alarm (RW) -Bit 4: 1 if alarm cause measured temp is over the warning threshold (R) -Bit 5: 1 if alarm cause measured volt is over the max threshold (R) -Bit 6: 1 if alarm cause measured volt is under the min threshold (R) -Bit 7: Volt sensor: Shutdown if alarm persist for more then 4 seconds (RW) - Temp sensor: Shutdown if temp is over the shutdown threshold (RW) - -* This bit is only honored/used by the uGuru if a temp sensor is connected -** This bit is only honored/used by the uGuru if a volt sensor is connected -Note with some trickery this can be used to find out what kinda sensor is -detected see the Linux kernel driver for an example with many comments on -how todo this. - -Byte 1: -Temp sensor: warning threshold (scale as bank 0x21) -Volt sensor: min threshold (scale as bank 0x21) - -Byte 2: -Temp sensor: shutdown threshold (scale as bank 0x21) -Volt sensor: max threshold (scale as bank 0x21) - - -Bank 0x24 PWM outputs for FAN's (R) -Bank 0x25 PWM outputs for FAN's (W) ------------------------------------ - -This bank contains 3 "sensors", for each sensor it contains 5 bytes. -Sensor 0 usually controls the CPU fan -Sensor 1 usually controls the NB (or chipset for single chip) fan -Sensor 2 usually controls the System fan - -Byte 0: -Flag 0x80 to enable control, Fan runs at 100% when disabled. -low nibble (temp)sensor address at bank 0x21 used for control. - -Byte 1: -0-255 = 0-12v (linear), specify voltage at which fan will rotate when under -low threshold temp (specified in byte 3) - -Byte 2: -0-255 = 0-12v (linear), specify voltage at which fan will rotate when above -high threshold temp (specified in byte 4) - -Byte 3: -Low threshold temp (scale as bank 0x21) - -byte 4: -High threshold temp (scale as bank 0x21) - - -Bank 0x26 Sensors Bank2 Values / Readings (R) ---------------------------------------------- - -This bank contains 6 sensors (AFAIK), for each sensor it contains 1 byte. -So far the following sensors are known to be available on all motherboards: -Sensor 0: CPU fan speed -Sensor 1: NB (or chipset for single chip) fan speed -Sensor 2: SYS fan speed - -Byte 0: -This byte holds the reading from the sensor. 0-255 = 0-15300 (linear) - - -Bank 0x27 Sensors Bank2 Settings (R) -Bank 0x28 Sensors Bank2 Settings (W) ------------------------------------- - -This bank contains 6 sensors (AFAIK), for each sensor it contains 2 bytes. - -Byte 0: -Alarm behaviour for the selected sensor. A 1 enables the described behaviour. -Bit 0: Give an alarm if measured rpm is under the min threshold (RW) -Bit 3: Beep if alarm (RW) -Bit 7: Shutdown if alarm persist for more then 4 seconds (RW) - -Byte 1: -min threshold (scale as bank 0x26) - - -Warning for the adventerous -=========================== - -A word of caution to those who want to experiment and see if they can figure -the voltage / clock programming out, I tried reading and only reading banks -0-0x30 with the reading code used for the sensor banks (0x20-0x28) and this -resulted in a _permanent_ reprogramming of the voltages, luckily I had the -sensors part configured so that it would shutdown my system on any out of spec -voltages which proprably safed my computer (after a reboot I managed to -immediatly enter the bios and reload the defaults). This probably means that -the read/write cycle for the non sensor part is different from the sensor part. diff --git a/trunk/Documentation/hwmon/lm70 b/trunk/Documentation/hwmon/lm70 deleted file mode 100644 index 2bdd3feebf53..000000000000 --- a/trunk/Documentation/hwmon/lm70 +++ /dev/null @@ -1,31 +0,0 @@ -Kernel driver lm70 -================== - -Supported chip: - * National Semiconductor LM70 - Datasheet: http://www.national.com/pf/LM/LM70.html - -Author: - Kaiwan N Billimoria - -Description ------------ - -This driver implements support for the National Semiconductor LM70 -temperature sensor. - -The LM70 temperature sensor chip supports a single temperature sensor. -It communicates with a host processor (or microcontroller) via an -SPI/Microwire Bus interface. - -Communication with the LM70 is simple: when the temperature is to be sensed, -the driver accesses the LM70 using SPI communication: 16 SCLK cycles -comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's -complement digital temperature (sent via the SIO line), is available in the -driver for interpretation. This driver makes use of the kernel's in-core -SPI support. - -Thanks to ---------- -Jean Delvare for mentoring the hwmon-side driver -development. diff --git a/trunk/Documentation/hwmon/lm83 b/trunk/Documentation/hwmon/lm83 index f7aad1489cb0..061d9ed8ff43 100644 --- a/trunk/Documentation/hwmon/lm83 +++ b/trunk/Documentation/hwmon/lm83 @@ -7,10 +7,6 @@ Supported chips: Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e Datasheet: Publicly available at the National Semiconductor website http://www.national.com/pf/LM/LM83.html - * National Semiconductor LM82 - Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the National Semiconductor website - http://www.national.com/pf/LM/LM82.html Author: Jean Delvare @@ -19,11 +15,10 @@ Description ----------- The LM83 is a digital temperature sensor. It senses its own temperature as -well as the temperature of up to three external diodes. The LM82 is -a stripped down version of the LM83 that only supports one external diode. -Both are compatible with many other devices such as the LM84 and all -other ADM1021 clones. The main difference between the LM83 and the LM84 -in that the later can only sense the temperature of one external diode. +well as the temperature of up to three external diodes. It is compatible +with many other devices such as the LM84 and all other ADM1021 clones. +The main difference between the LM83 and the LM84 in that the later can +only sense the temperature of one external diode. Using the adm1021 driver for a LM83 should work, but only two temperatures will be reported instead of four. @@ -35,16 +30,12 @@ contact us. Note that the LM90 can easily be misdetected as a LM83. Confirmed motherboards: SBS P014 - SBS PSL09 Unconfirmed motherboards: Gigabyte GA-8IK1100 Iwill MPX2 Soltek SL-75DRV5 -The LM82 is confirmed to have been found on most AMD Geode reference -designs and test platforms. - The driver has been successfully tested by Magnus Forsström, who I'd like to thank here. More testers will be of course welcome. diff --git a/trunk/Documentation/hwmon/smsc47m192 b/trunk/Documentation/hwmon/smsc47m192 deleted file mode 100644 index 45d6453cd435..000000000000 --- a/trunk/Documentation/hwmon/smsc47m192 +++ /dev/null @@ -1,102 +0,0 @@ -Kernel driver smsc47m192 -======================== - -Supported chips: - * SMSC LPC47M192 and LPC47M997 - Prefix: 'smsc47m192' - Addresses scanned: I2C 0x2c - 0x2d - Datasheet: The datasheet for LPC47M192 is publicly available from - http://www.smsc.com/ - The LPC47M997 is compatible for hardware monitoring. - -Author: Hartmut Rick - Special thanks to Jean Delvare for careful checking - of the code and many helpful comments and suggestions. - - -Description ------------ - -This driver implements support for the hardware sensor capabilities -of the SMSC LPC47M192 and LPC47M997 Super-I/O chips. - -These chips support 3 temperature channels and 8 voltage inputs -as well as CPU voltage VID input. - -They do also have fan monitoring and control capabilities, but the -these features are accessed via ISA bus and are not supported by this -driver. Use the 'smsc47m1' driver for fan monitoring and control. - -Voltages and temperatures are measured by an 8-bit ADC, the resolution -of the temperatures is 1 bit per degree C. -Voltages are scaled such that the nominal voltage corresponds to -192 counts, i.e. 3/4 of the full range. Thus the available range for -each voltage channel is 0V ... 255/192*(nominal voltage), the resolution -is 1 bit per (nominal voltage)/192. -Both voltage and temperature values are scaled by 1000, the sys files -show voltages in mV and temperatures in units of 0.001 degC. - -The +12V analog voltage input channel (in4_input) is multiplexed with -bit 4 of the encoded CPU voltage. This means that you either get -a +12V voltage measurement or a 5 bit CPU VID, but not both. -The default setting is to use the pin as 12V input, and use only 4 bit VID. -This driver assumes that the information in the configuration register -is correct, i.e. that the BIOS has updated the configuration if -the motherboard has this input wired to VID4. - -The temperature and voltage readings are updated once every 1.5 seconds. -Reading them more often repeats the same values. - - -sysfs interface ---------------- - -in0_input - +2.5V voltage input -in1_input - CPU voltage input (nominal 2.25V) -in2_input - +3.3V voltage input -in3_input - +5V voltage input -in4_input - +12V voltage input (may be missing if used as VID4) -in5_input - Vcc voltage input (nominal 3.3V) - This is the supply voltage of the sensor chip itself. -in6_input - +1.5V voltage input -in7_input - +1.8V voltage input - -in[0-7]_min, -in[0-7]_max - lower and upper alarm thresholds for in[0-7]_input reading - - All voltages are read and written in mV. - -in[0-7]_alarm - alarm flags for voltage inputs - These files read '1' in case of alarm, '0' otherwise. - -temp1_input - chip temperature measured by on-chip diode -temp[2-3]_input - temperature measured by external diodes (one of these would - typically be wired to the diode inside the CPU) - -temp[1-3]_min, -temp[1-3]_max - lower and upper alarm thresholds for temperatures - -temp[1-3]_offset - temperature offset registers - The chip adds the offsets stored in these registers to - the corresponding temperature readings. - Note that temp1 and temp2 offsets share the same register, - they cannot both be different from zero at the same time. - Writing a non-zero number to one of them will reset the other - offset to zero. - - All temperatures and offsets are read and written in - units of 0.001 degC. - -temp[1-3]_alarm - alarm flags for temperature inputs, '1' in case of alarm, - '0' otherwise. -temp[2-3]_input_fault - diode fault flags for temperature inputs 2 and 3. - A fault is detected if the two pins for the corresponding - sensor are open or shorted, or any of the two is shorted - to ground or Vcc. '1' indicates a diode fault. - -cpu0_vid - CPU voltage as received from the CPU - -vrm - CPU VID standard used for decoding CPU voltage - - The *_min, *_max, *_offset and vrm files can be read and - written, all others are read-only. diff --git a/trunk/Documentation/hwmon/sysfs-interface b/trunk/Documentation/hwmon/sysfs-interface index d1d390aaf620..a0d0ab24288e 100644 --- a/trunk/Documentation/hwmon/sysfs-interface +++ b/trunk/Documentation/hwmon/sysfs-interface @@ -3,15 +3,15 @@ Naming and data format standards for sysfs files The libsensors library offers an interface to the raw sensors data through the sysfs interface. See libsensors documentation and source for -further information. As of writing this document, libsensors -(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating +more further information. As of writing this document, libsensors +(from lm_sensors 2.8.3) is heavily chip-dependant. Adding or updating support for any given chip requires modifying the library's code. This is because libsensors was written for the procfs interface older kernel modules were using, which wasn't standardized enough. Recent versions of libsensors (from lm_sensors 2.8.2 and later) have support for the sysfs interface, though. -The new sysfs interface was designed to be as chip-independent as +The new sysfs interface was designed to be as chip-independant as possible. Note that motherboards vary widely in the connections to sensor chips. @@ -24,7 +24,7 @@ range using external resistors. Since the values of these resistors can change from motherboard to motherboard, the conversions cannot be hard coded into the driver and have to be done in user space. -For this reason, even if we aim at a chip-independent libsensors, it will +For this reason, even if we aim at a chip-independant libsensors, it will still require a configuration file (e.g. /etc/sensors.conf) for proper values conversion, labeling of inputs and hiding of unused inputs. @@ -39,16 +39,15 @@ If you are developing a userspace application please send us feedback on this standard. Note that this standard isn't completely established yet, so it is subject -to changes. If you are writing a new hardware monitoring driver those -features can't seem to fit in this interface, please contact us with your -extension proposal. Keep in mind that backward compatibility must be -preserved. +to changes, even important ones. One more reason to use the library instead +of accessing sysfs files directly. Each chip gets its own directory in the sysfs /sys/devices tree. To -find all sensor chips, it is easier to follow the device symlinks from -/sys/class/hwmon/hwmon*. +find all sensor chips, it is easier to follow the symlinks from +/sys/i2c/devices/ -All sysfs values are fixed point numbers. +All sysfs values are fixed point numbers. To get the true value of some +of the values, you should divide by the specified value. There is only one value per file, unlike the older /proc specification. The common scheme for files naming is: _. Usual @@ -70,40 +69,28 @@ to cause an alarm) is chip-dependent. ------------------------------------------------------------------------- -[0-*] denotes any positive number starting from 0 -[1-*] denotes any positive number starting from 1 -RO read only value -RW read/write value - -Read/write values may be read-only for some chips, depending on the -hardware implementation. - -All entries are optional, and should only be created in a given driver -if the chip has the feature. - ************ * Voltages * ************ -in[0-*]_min Voltage min value. +in[0-8]_min Voltage min value. Unit: millivolt - RW + Read/Write -in[0-*]_max Voltage max value. +in[0-8]_max Voltage max value. Unit: millivolt - RW + Read/Write -in[0-*]_input Voltage input value. +in[0-8]_input Voltage input value. Unit: millivolt - RO - Voltage measured on the chip pin. + Read only Actual voltage depends on the scaling resistors on the motherboard, as recommended in the chip datasheet. This varies by chip and by motherboard. Because of this variation, values are generally NOT scaled by the chip driver, and must be done by the application. However, some drivers (notably lm87 and via686a) - do scale, because of internal resistors built into a chip. + do scale, with various degrees of success. These drivers will output the actual voltage. Typical usage: @@ -117,72 +104,58 @@ in[0-*]_input Voltage input value. in7_* varies in8_* varies -cpu[0-*]_vid CPU core reference voltage. +cpu[0-1]_vid CPU core reference voltage. Unit: millivolt - RO + Read only. Not always correct. vrm Voltage Regulator Module version number. - RW (but changing it should no more be necessary) - Originally the VRM standard version multiplied by 10, but now - an arbitrary number, as not all standards have a version - number. + Read only. + Two digit number, first is major version, second is + minor version. Affects the way the driver calculates the CPU core reference voltage from the vid pins. -Also see the Alarms section for status flags associated with voltages. - ******** * Fans * ******** -fan[1-*]_min Fan minimum value +fan[1-3]_min Fan minimum value Unit: revolution/min (RPM) - RW + Read/Write. -fan[1-*]_input Fan input value. +fan[1-3]_input Fan input value. Unit: revolution/min (RPM) - RO + Read only. -fan[1-*]_div Fan divisor. +fan[1-3]_div Fan divisor. Integer value in powers of two (1, 2, 4, 8, 16, 32, 64, 128). - RW Some chips only support values 1, 2, 4 and 8. Note that this is actually an internal clock divisor, which affects the measurable speed range, not the read value. -Also see the Alarms section for status flags associated with fans. - - ******* * PWM * ******* -pwm[1-*] Pulse width modulation fan control. +pwm[1-3] Pulse width modulation fan control. Integer value in the range 0 to 255 - RW + Read/Write 255 is max or 100%. -pwm[1-*]_enable +pwm[1-3]_enable Switch PWM on and off. Not always present even if fan*_pwm is. - 0: turn off - 1: turn on in manual mode - 2+: turn on in automatic mode - Check individual chip documentation files for automatic mode details. - RW - -pwm[1-*]_mode - 0: DC mode - 1: PWM mode - RW + 0 to turn off + 1 to turn on in manual mode + 2 to turn on in automatic mode + Read/Write pwm[1-*]_auto_channels_temp Select which temperature channels affect this PWM output in auto mode. Bitfield, 1 is temp1, 2 is temp2, 4 is temp3 etc... Which values are possible depend on the chip used. - RW pwm[1-*]_auto_point[1-*]_pwm pwm[1-*]_auto_point[1-*]_temp @@ -190,7 +163,6 @@ pwm[1-*]_auto_point[1-*]_temp_hyst Define the PWM vs temperature curve. Number of trip points is chip-dependent. Use this for chips which associate trip points to PWM output channels. - RW OR @@ -200,57 +172,50 @@ temp[1-*]_auto_point[1-*]_temp_hyst Define the PWM vs temperature curve. Number of trip points is chip-dependent. Use this for chips which associate trip points to temperature channels. - RW **************** * Temperatures * **************** -temp[1-*]_type Sensor type selection. +temp[1-3]_type Sensor type selection. Integers 1 to 4 or thermistor Beta value (typically 3435) - RW + Read/Write. 1: PII/Celeron Diode 2: 3904 transistor 3: thermal diode 4: thermistor (default/unknown Beta) Not all types are supported by all chips -temp[1-*]_max Temperature max value. - Unit: millidegree Celsius (or millivolt, see below) - RW +temp[1-4]_max Temperature max value. + Unit: millidegree Celcius + Read/Write value. -temp[1-*]_min Temperature min value. - Unit: millidegree Celsius - RW +temp[1-3]_min Temperature min value. + Unit: millidegree Celcius + Read/Write value. -temp[1-*]_max_hyst +temp[1-3]_max_hyst Temperature hysteresis value for max limit. - Unit: millidegree Celsius + Unit: millidegree Celcius Must be reported as an absolute temperature, NOT a delta from the max value. - RW + Read/Write value. -temp[1-*]_input Temperature input value. - Unit: millidegree Celsius - RO +temp[1-4]_input Temperature input value. + Unit: millidegree Celcius + Read only value. -temp[1-*]_crit Temperature critical value, typically greater than +temp[1-4]_crit Temperature critical value, typically greater than corresponding temp_max values. - Unit: millidegree Celsius - RW + Unit: millidegree Celcius + Read/Write value. -temp[1-*]_crit_hyst +temp[1-2]_crit_hyst Temperature hysteresis value for critical limit. - Unit: millidegree Celsius + Unit: millidegree Celcius Must be reported as an absolute temperature, NOT a delta from the critical value. - RW - -temp[1-4]_offset - Temperature offset which is added to the temperature reading - by the chip. - Unit: millidegree Celsius Read/Write value. If there are multiple temperature sensors, temp1_* is @@ -260,17 +225,6 @@ temp[1-4]_offset itself, for example the thermal diode inside the CPU or a thermistor nearby. -Some chips measure temperature using external thermistors and an ADC, and -report the temperature measurement as a voltage. Converting this voltage -back to a temperature (or the other way around for limits) requires -mathematical functions not available in the kernel, so the conversion -must occur in user space. For these chips, all temp* files described -above should contain values expressed in millivolt instead of millidegree -Celsius. In other words, such temperature channels are handled as voltage -channels by the driver. - -Also see the Alarms section for status flags associated with temperatures. - ************ * Currents * @@ -279,88 +233,25 @@ Also see the Alarms section for status flags associated with temperatures. Note that no known chip provides current measurements as of writing, so this part is theoretical, so to say. -curr[1-*]_max Current max value +curr[1-n]_max Current max value Unit: milliampere - RW + Read/Write. -curr[1-*]_min Current min value. +curr[1-n]_min Current min value. Unit: milliampere - RW + Read/Write. -curr[1-*]_input Current input value +curr[1-n]_input Current input value Unit: milliampere - RO - + Read only. -********** -* Alarms * -********** -Each channel or limit may have an associated alarm file, containing a -boolean value. 1 means than an alarm condition exists, 0 means no alarm. - -Usually a given chip will either use channel-related alarms, or -limit-related alarms, not both. The driver should just reflect the hardware -implementation. - -in[0-*]_alarm -fan[1-*]_alarm -temp[1-*]_alarm - Channel alarm - 0: no alarm - 1: alarm - RO - -OR - -in[0-*]_min_alarm -in[0-*]_max_alarm -fan[1-*]_min_alarm -temp[1-*]_min_alarm -temp[1-*]_max_alarm -temp[1-*]_crit_alarm - Limit alarm - 0: no alarm - 1: alarm - RO - -Each input channel may have an associated fault file. This can be used -to notify open diodes, unconnected fans etc. where the hardware -supports it. When this boolean has value 1, the measurement for that -channel should not be trusted. - -in[0-*]_input_fault -fan[1-*]_input_fault -temp[1-*]_input_fault - Input fault condition - 0: no fault occured - 1: fault condition - RO - -Some chips also offer the possibility to get beeped when an alarm occurs: - -beep_enable Master beep enable - 0: no beeps - 1: beeps - RW - -in[0-*]_beep -fan[1-*]_beep -temp[1-*]_beep - Channel beep - 0: disable - 1: enable - RW - -In theory, a chip could provide per-limit beep masking, but no such chip -was seen so far. - -Old drivers provided a different, non-standard interface to alarms and -beeps. These interface files are deprecated, but will be kept around -for compatibility reasons: +********* +* Other * +********* alarms Alarm bitmask. - RO + Read only. Integer representation of one to four bytes. A '1' bit means an alarm. Chips should be programmed for 'comparator' mode so that @@ -368,26 +259,35 @@ alarms Alarm bitmask. if it is still valid. Generally a direct representation of a chip's internal alarm registers; there is no standard for the position - of individual bits. For this reason, the use of this - interface file for new drivers is discouraged. Use - individual *_alarm and *_fault files instead. + of individual bits. Bits are defined in kernel/include/sensors.h. -beep_mask Bitmask for beep. - Same format as 'alarms' with the same bit locations, - use discouraged for the same reason. Use individual - *_beep files instead. - RW +alarms_in Alarm bitmask relative to in (voltage) channels + Read only + A '1' bit means an alarm, LSB corresponds to in0 and so on + Prefered to 'alarms' for newer chips +alarms_fan Alarm bitmask relative to fan channels + Read only + A '1' bit means an alarm, LSB corresponds to fan1 and so on + Prefered to 'alarms' for newer chips -********* -* Other * -********* +alarms_temp Alarm bitmask relative to temp (temperature) channels + Read only + A '1' bit means an alarm, LSB corresponds to temp1 and so on + Prefered to 'alarms' for newer chips + +beep_enable Beep/interrupt enable + 0 to disable. + 1 to enable. + Read/Write + +beep_mask Bitmask for beep. + Same format as 'alarms' with the same bit locations. + Read/Write eeprom Raw EEPROM data in binary form. - RO + Read only. pec Enable or disable PEC (SMBus only) - 0: disable - 1: enable - RW + Read/Write diff --git a/trunk/Documentation/hwmon/userspace-tools b/trunk/Documentation/hwmon/userspace-tools index 19900a8fe679..2622aac65422 100644 --- a/trunk/Documentation/hwmon/userspace-tools +++ b/trunk/Documentation/hwmon/userspace-tools @@ -6,32 +6,31 @@ voltages, fans speed). They are often connected through an I2C bus, but some are also connected directly through the ISA bus. The kernel drivers make the data from the sensor chips available in the /sys -virtual filesystem. Userspace tools are then used to display the measured -values or configure the chips in a more friendly manner. +virtual filesystem. Userspace tools are then used to display or set or the +data in a more friendly manner. Lm-sensors ---------- -Core set of utilities that will allow you to obtain health information, +Core set of utilites that will allow you to obtain health information, setup monitoring limits etc. You can get them on their homepage http://www.lm-sensors.nu/ or as a package from your Linux distribution. If from website: -Get lm-sensors from project web site. Please note, you need only userspace -part, so compile with "make user" and install with "make user_install". +Get lmsensors from project web site. Please note, you need only userspace +part, so compile with "make user_install" target. General hints to get things working: 0) get lm-sensors userspace utils -1) compile all drivers in I2C and Hardware Monitoring sections as modules - in your kernel +1) compile all drivers in I2C section as modules in your kernel 2) run sensors-detect script, it will tell you what modules you need to load. 3) load them and run "sensors" command, you should see some results. 4) fix sensors.conf, labels, limits, fan divisors 5) if any more problems consult FAQ, or documentation -Other utilities ---------------- +Other utilites +-------------- If you want some graphical indicators of system health look for applications like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd, diff --git a/trunk/Documentation/hwmon/w83791d b/trunk/Documentation/hwmon/w83791d deleted file mode 100644 index 83a3836289c2..000000000000 --- a/trunk/Documentation/hwmon/w83791d +++ /dev/null @@ -1,113 +0,0 @@ -Kernel driver w83791d -===================== - -Supported chips: - * Winbond W83791D - Prefix: 'w83791d' - Addresses scanned: I2C 0x2c - 0x2f - Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf - -Author: Charles Spirakis - -This driver was derived from the w83781d.c and w83792d.c source files. - -Credits: - w83781d.c: - Frodo Looijaard , - Philip Edelbrock , - and Mark Studebaker - w83792d.c: - Chunhao Huang , - Rudolf Marek - -Module Parameters ------------------ - -* init boolean - (default 0) - Use 'init=1' to have the driver do extra software initializations. - The default behavior is to do the minimum initialization possible - and depend on the BIOS to properly setup the chip. If you know you - have a w83791d and you're having problems, try init=1 before trying - reset=1. - -* reset boolean - (default 0) - Use 'reset=1' to reset the chip (via index 0x40, bit 7). The default - behavior is no chip reset to preserve BIOS settings. - -* force_subclients=bus,caddr,saddr,saddr - This is used to force the i2c addresses for subclients of - a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b' - to force the subclients of chip 0x2f on bus 0 to i2c addresses - 0x4a and 0x4b. - - -Description ------------ - -This driver implements support for the Winbond W83791D chip. - -Detection of the chip can sometimes be foiled because it can be in an -internal state that allows no clean access (Bank with ID register is not -currently selected). If you know the address of the chip, use a 'force' -parameter; this will put it into a more well-behaved state first. - -The driver implements three temperature sensors, five fan rotation speed -sensors, and ten voltage sensors. - -Temperatures are measured in degrees Celsius and measurement resolution is 1 -degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when -the temperature gets higher than the Overtemperature Shutdown value; it stays -on until the temperature falls below the Hysteresis value. - -Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -triggered if the rotation speed has dropped below a programmable limit. Fan -readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3 -and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more -range or accuracy. - -Voltage sensors (also known as IN sensors) report their values in millivolts. -An alarm is triggered if the voltage has crossed a programmable minimum -or maximum limit. - -Alarms are provided as output from a "realtime status register". The -following bits are defined: - -bit - alarm on: -0 - Vcore -1 - VINR0 -2 - +3.3VIN -3 - 5VDD -4 - temp1 -5 - temp2 -6 - fan1 -7 - fan2 -8 - +12VIN -9 - -12VIN -10 - -5VIN -11 - fan3 -12 - chassis -13 - temp3 -14 - VINR1 -15 - reserved -16 - tart1 -17 - tart2 -18 - tart3 -19 - VSB -20 - VBAT -21 - fan4 -22 - fan5 -23 - reserved - -When an alarm goes off, you can be warned by a beeping signal through your -computer speaker. It is possible to enable all beeping globally, or only -the beeping for some alarms. - -The driver only reads the chip values each 3 seconds; reading them more -often will do no harm, but will return 'old' values. - -W83791D TODO: ---------------- -Provide a patch for per-file alarms as discussed on the mailing list -Provide a patch for smart-fan control (still need appropriate motherboard/fans) diff --git a/trunk/Documentation/i2c/busses/i2c-i801 b/trunk/Documentation/i2c/busses/i2c-i801 index e46c23458242..fd4b2712d570 100644 --- a/trunk/Documentation/i2c/busses/i2c-i801 +++ b/trunk/Documentation/i2c/busses/i2c-i801 @@ -21,7 +21,8 @@ Authors: Module Parameters ----------------- -None. +* force_addr: int + Forcibly enable the ICH at the given address. EXTREMELY DANGEROUS! Description diff --git a/trunk/Documentation/i2c/busses/i2c-nforce2 b/trunk/Documentation/i2c/busses/i2c-nforce2 index cd49c428a3ab..d751282d9b2a 100644 --- a/trunk/Documentation/i2c/busses/i2c-nforce2 +++ b/trunk/Documentation/i2c/busses/i2c-nforce2 @@ -7,8 +7,6 @@ Supported adapters: * nForce3 250Gb MCP 10de:00E4 * nForce4 MCP 10de:0052 * nForce4 MCP-04 10de:0034 - * nForce4 MCP51 10de:0264 - * nForce4 MCP55 10de:0368 Datasheet: not publically available, but seems to be similar to the AMD-8111 SMBus 2.0 adapter. diff --git a/trunk/Documentation/i2c/busses/i2c-ocores b/trunk/Documentation/i2c/busses/i2c-ocores deleted file mode 100644 index cfcebb10d14e..000000000000 --- a/trunk/Documentation/i2c/busses/i2c-ocores +++ /dev/null @@ -1,51 +0,0 @@ -Kernel driver i2c-ocores - -Supported adapters: - * OpenCores.org I2C controller by Richard Herveille (see datasheet link) - Datasheet: http://www.opencores.org/projects.cgi/web/i2c/overview - -Author: Peter Korsgaard - -Description ------------ - -i2c-ocores is an i2c bus driver for the OpenCores.org I2C controller -IP core by Richard Herveille. - -Usage ------ - -i2c-ocores uses the platform bus, so you need to provide a struct -platform_device with the base address and interrupt number. The -dev.platform_data of the device should also point to a struct -ocores_i2c_platform_data (see linux/i2c-ocores.h) describing the -distance between registers and the input clock speed. - -E.G. something like: - -static struct resource ocores_resources[] = { - [0] = { - .start = MYI2C_BASEADDR, - .end = MYI2C_BASEADDR + 8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MYI2C_IRQ, - .end = MYI2C_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct ocores_i2c_platform_data myi2c_data = { - .regstep = 2, /* two bytes between registers */ - .clock_khz = 50000, /* input clock of 50MHz */ -}; - -static struct platform_device myi2c = { - .name = "ocores-i2c", - .dev = { - .platform_data = &myi2c_data, - }, - .num_resources = ARRAY_SIZE(ocores_resources), - .resource = ocores_resources, -}; diff --git a/trunk/Documentation/i2c/busses/i2c-piix4 b/trunk/Documentation/i2c/busses/i2c-piix4 index 921476333235..a1c8f581afed 100644 --- a/trunk/Documentation/i2c/busses/i2c-piix4 +++ b/trunk/Documentation/i2c/busses/i2c-piix4 @@ -6,8 +6,6 @@ Supported adapters: Datasheet: Publicly available at the Intel website * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges Datasheet: Only available via NDA from ServerWorks - * ATI IXP southbridges IXP200, IXP300, IXP400 - Datasheet: Not publicly available * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge Datasheet: Publicly available at the SMSC website http://www.smsc.com @@ -23,6 +21,8 @@ Module Parameters Forcibly enable the PIIX4. DANGEROUS! * force_addr: int Forcibly enable the PIIX4 at the given address. EXTREMELY DANGEROUS! +* fix_hstcfg: int + Fix config register. Needed on some boards (Force CPCI735). Description @@ -63,36 +63,10 @@ The PIIX4E is just an new version of the PIIX4; it is supported as well. The PIIX/PIIX3 does not implement an SMBus or I2C bus, so you can't use this driver on those mainboards. -The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are +The ServerWorks Southbridges, the Intel 440MX, and the Victory766 are identical to the PIIX4 in I2C/SMBus support. -If you own Force CPCI735 motherboard or other OSB4 based systems you may need -to change the SMBus Interrupt Select register so the SMBus controller uses -the SMI mode. - -1) Use lspci command and locate the PCI device with the SMBus controller: - 00:0f.0 ISA bridge: ServerWorks OSB4 South Bridge (rev 4f) - The line may vary for different chipsets. Please consult the driver source - for all possible PCI ids (and lspci -n to match them). Lets assume the - device is located at 00:0f.0. -2) Now you just need to change the value in 0xD2 register. Get it first with - command: lspci -xxx -s 00:0f.0 - If the value is 0x3 then you need to change it to 0x1 - setpci -s 00:0f.0 d2.b=1 - -Please note that you don't need to do that in all cases, just when the SMBus is -not working properly. - - -Hardware-specific issues ------------------------- - -This driver will refuse to load on IBM systems with an Intel PIIX4 SMBus. -Some of these machines have an RFID EEPROM (24RF08) connected to the SMBus, -which can easily get corrupted due to a state machine bug. These are mostly -Thinkpad laptops, but desktop systems may also be affected. We have no list -of all affected systems, so the only safe solution was to prevent access to -the SMBus on all IBM systems (detected using DMI data.) - -For additional information, read: -http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/README.thinkpad +A few OSB4 southbridges are known to be misconfigured by the BIOS. In this +case, you have you use the fix_hstcfg module parameter. Do not use it +unless you know you have to, because in some cases it also breaks +configuration on southbridges that don't need it. diff --git a/trunk/Documentation/i2c/busses/scx200_acb b/trunk/Documentation/i2c/busses/scx200_acb index 7c07883d4dfc..f50e69981ec6 100644 --- a/trunk/Documentation/i2c/busses/scx200_acb +++ b/trunk/Documentation/i2c/busses/scx200_acb @@ -2,31 +2,14 @@ Kernel driver scx200_acb Author: Christer Weinigel -The driver supersedes the older, never merged driver named i2c-nscacb. - Module Parameters ----------------- -* base: up to 4 ints +* base: int Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices - By default the driver uses two base addresses 0x820 and 0x840. - If you want only one base address, specify the second as 0 so as to - override this default. - Description ----------- Enable the use of the ACCESS.bus controller on the Geode SCx200 and SC1100 processors and the CS5535 and CS5536 Geode companion devices. - -Device-specific notes ---------------------- - -The SC1100 WRAP boards are known to use base addresses 0x810 and 0x820. -If the scx200_acb driver is built into the kernel, add the following -parameter to your boot command line: - scx200_acb.base=0x810,0x820 -If the scx200_acb driver is built as a module, add the following line to -the file /etc/modprobe.conf instead: - options scx200_acb base=0x810,0x820 diff --git a/trunk/Documentation/ia64/aliasing.txt b/trunk/Documentation/ia64/aliasing.txt deleted file mode 100644 index 38f9a52d1820..000000000000 --- a/trunk/Documentation/ia64/aliasing.txt +++ /dev/null @@ -1,208 +0,0 @@ - MEMORY ATTRIBUTE ALIASING ON IA-64 - - Bjorn Helgaas - - May 4, 2006 - - -MEMORY ATTRIBUTES - - Itanium supports several attributes for virtual memory references. - The attribute is part of the virtual translation, i.e., it is - contained in the TLB entry. The ones of most interest to the Linux - kernel are: - - WB Write-back (cacheable) - UC Uncacheable - WC Write-coalescing - - System memory typically uses the WB attribute. The UC attribute is - used for memory-mapped I/O devices. The WC attribute is uncacheable - like UC is, but writes may be delayed and combined to increase - performance for things like frame buffers. - - The Itanium architecture requires that we avoid accessing the same - page with both a cacheable mapping and an uncacheable mapping[1]. - - The design of the chipset determines which attributes are supported - on which regions of the address space. For example, some chipsets - support either WB or UC access to main memory, while others support - only WB access. - -MEMORY MAP - - Platform firmware describes the physical memory map and the - supported attributes for each region. At boot-time, the kernel uses - the EFI GetMemoryMap() interface. ACPI can also describe memory - devices and the attributes they support, but Linux/ia64 currently - doesn't use this information. - - The kernel uses the efi_memmap table returned from GetMemoryMap() to - learn the attributes supported by each region of physical address - space. Unfortunately, this table does not completely describe the - address space because some machines omit some or all of the MMIO - regions from the map. - - The kernel maintains another table, kern_memmap, which describes the - memory Linux is actually using and the attribute for each region. - This contains only system memory; it does not contain MMIO space. - - The kern_memmap table typically contains only a subset of the system - memory described by the efi_memmap. Linux/ia64 can't use all memory - in the system because of constraints imposed by the identity mapping - scheme. - - The efi_memmap table is preserved unmodified because the original - boot-time information is required for kexec. - -KERNEL IDENTITY MAPPINGS - - Linux/ia64 identity mappings are done with large pages, currently - either 16MB or 64MB, referred to as "granules." Cacheable mappings - are speculative[2], so the processor can read any location in the - page at any time, independent of the programmer's intentions. This - means that to avoid attribute aliasing, Linux can create a cacheable - identity mapping only when the entire granule supports cacheable - access. - - Therefore, kern_memmap contains only full granule-sized regions that - can referenced safely by an identity mapping. - - Uncacheable mappings are not speculative, so the processor will - generate UC accesses only to locations explicitly referenced by - software. This allows UC identity mappings to cover granules that - are only partially populated, or populated with a combination of UC - and WB regions. - -USER MAPPINGS - - User mappings are typically done with 16K or 64K pages. The smaller - page size allows more flexibility because only 16K or 64K has to be - homogeneous with respect to memory attributes. - -POTENTIAL ATTRIBUTE ALIASING CASES - - There are several ways the kernel creates new mappings: - - mmap of /dev/mem - - This uses remap_pfn_range(), which creates user mappings. These - mappings may be either WB or UC. If the region being mapped - happens to be in kern_memmap, meaning that it may also be mapped - by a kernel identity mapping, the user mapping must use the same - attribute as the kernel mapping. - - If the region is not in kern_memmap, the user mapping should use - an attribute reported as being supported in the EFI memory map. - - Since the EFI memory map does not describe MMIO on some - machines, this should use an uncacheable mapping as a fallback. - - mmap of /sys/class/pci_bus/.../legacy_mem - - This is very similar to mmap of /dev/mem, except that legacy_mem - only allows mmap of the one megabyte "legacy MMIO" area for a - specific PCI bus. Typically this is the first megabyte of - physical address space, but it may be different on machines with - several VGA devices. - - "X" uses this to access VGA frame buffers. Using legacy_mem - rather than /dev/mem allows multiple instances of X to talk to - different VGA cards. - - The /dev/mem mmap constraints apply. - - However, since this is for mapping legacy MMIO space, WB access - does not make sense. This matters on machines without legacy - VGA support: these machines may have WB memory for the entire - first megabyte (or even the entire first granule). - - On these machines, we could mmap legacy_mem as WB, which would - be safe in terms of attribute aliasing, but X has no way of - knowing that it is accessing regular memory, not a frame buffer, - so the kernel should fail the mmap rather than doing it with WB. - - read/write of /dev/mem - - This uses copy_from_user(), which implicitly uses a kernel - identity mapping. This is obviously safe for things in - kern_memmap. - - There may be corner cases of things that are not in kern_memmap, - but could be accessed this way. For example, registers in MMIO - space are not in kern_memmap, but could be accessed with a UC - mapping. This would not cause attribute aliasing. But - registers typically can be accessed only with four-byte or - eight-byte accesses, and the copy_from_user() path doesn't allow - any control over the access size, so this would be dangerous. - - ioremap() - - This returns a kernel identity mapping for use inside the - kernel. - - If the region is in kern_memmap, we should use the attribute - specified there. Otherwise, if the EFI memory map reports that - the entire granule supports WB, we should use that (granules - that are partially reserved or occupied by firmware do not appear - in kern_memmap). Otherwise, we should use a UC mapping. - -PAST PROBLEM CASES - - mmap of various MMIO regions from /dev/mem by "X" on Intel platforms - - The EFI memory map may not report these MMIO regions. - - These must be allowed so that X will work. This means that - when the EFI memory map is incomplete, every /dev/mem mmap must - succeed. It may create either WB or UC user mappings, depending - on whether the region is in kern_memmap or the EFI memory map. - - mmap of 0x0-0xA0000 /dev/mem by "hwinfo" on HP sx1000 with VGA enabled - - See https://bugzilla.novell.com/show_bug.cgi?id=140858. - - The EFI memory map reports the following attributes: - 0x00000-0x9FFFF WB only - 0xA0000-0xBFFFF UC only (VGA frame buffer) - 0xC0000-0xFFFFF WB only - - This mmap is done with user pages, not kernel identity mappings, - so it is safe to use WB mappings. - - The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000, - which will use a granule-sized UC mapping covering 0-0xFFFFF. This - granule covers some WB-only memory, but since UC is non-speculative, - the processor will never generate an uncacheable reference to the - WB-only areas unless the driver explicitly touches them. - - mmap of 0x0-0xFFFFF legacy_mem by "X" - - If the EFI memory map reports this entire range as WB, there - is no VGA MMIO hole, and the mmap should fail or be done with - a WB mapping. - - There's no easy way for X to determine whether the 0xA0000-0xBFFFF - region is a frame buffer or just memory, so I think it's best to - just fail this mmap request rather than using a WB mapping. As - far as I know, there's no need to map legacy_mem with WB - mappings. - - Otherwise, a UC mapping of the entire region is probably safe. - The VGA hole means the region will not be in kern_memmap. The - HP sx1000 chipset doesn't support UC access to the memory surrounding - the VGA hole, but X doesn't need that area anyway and should not - reference it. - - mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled - - The EFI memory map reports the following attributes: - 0x00000-0xFFFFF WB only (no VGA MMIO hole) - - This is a special case of the previous case, and the mmap should - fail for the same reason as above. - -NOTES - - [1] SDM rev 2.2, vol 2, sec 4.4.1. - [2] SDM rev 2.2, vol 2, sec 4.4.6. diff --git a/trunk/Documentation/ioctl-number.txt b/trunk/Documentation/ioctl-number.txt index 1543802ef53e..171a44ebd939 100644 --- a/trunk/Documentation/ioctl-number.txt +++ b/trunk/Documentation/ioctl-number.txt @@ -85,9 +85,7 @@ Code Seq# Include File Comments 'C' all linux/soundcard.h 'D' all asm-s390/dasd.h -'E' all linux/input.h 'F' all linux/fb.h -'H' all linux/hiddev.h 'I' all linux/isdn.h 'J' 00-1F drivers/scsi/gdth_ioctl.h 'K' all linux/kd.h diff --git a/trunk/Documentation/isdn/README.gigaset b/trunk/Documentation/isdn/README.gigaset index fa0d4cca964a..85a64defd385 100644 --- a/trunk/Documentation/isdn/README.gigaset +++ b/trunk/Documentation/isdn/README.gigaset @@ -124,8 +124,7 @@ GigaSet 307x Device Driver You can use some configuration tool of your distribution to configure this "modem" or configure pppd/wvdial manually. There are some example ppp - configuration files and chat scripts in the gigaset-VERSION/ppp directory - in the driver packages from http://sourceforge.net/projects/gigaset307x/. + configuration files and chat scripts in the gigaset-VERSION/ppp directory. Please note that the USB drivers are not able to change the state of the control lines (the M105 driver can be configured to use some undocumented control requests, if you really need the control lines, though). This means @@ -165,8 +164,8 @@ GigaSet 307x Device Driver If you want both of these at once, you are out of luck. - You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode - setting (ttyGxy is ttyGU0 or ttyGB0). + You can also use /sys/module//parameters/cidmode for changing + the CID mode setting ( is usb_gigaset or bas_gigaset). 3. Troubleshooting diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index 14ef3868a328..a9c00facdf40 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -1123,14 +1123,6 @@ The top Makefile exports the following variables: $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may override this value on the command line if desired. - INSTALL_MOD_STRIP - - If this variable is specified, will cause modules to be stripped - after they are installed. If INSTALL_MOD_STRIP is '1', then the - default option --strip-debug will be used. Otherwise, - INSTALL_MOD_STRIP will used as the option(s) to the strip command. - - === 8 Makefile language The kernel Makefiles are designed to run with GNU Make. The Makefiles diff --git a/trunk/Documentation/kdump/gdbmacros.txt b/trunk/Documentation/kdump/gdbmacros.txt index 9b9b454b048a..dcf5580380ab 100644 --- a/trunk/Documentation/kdump/gdbmacros.txt +++ b/trunk/Documentation/kdump/gdbmacros.txt @@ -175,7 +175,7 @@ end document trapinfo Run info threads and lookup pid of thread #1 'trapinfo ' will tell you by which trap & possibly - address the kernel panicked. + addresthe kernel paniced. end diff --git a/trunk/Documentation/kdump/kdump.txt b/trunk/Documentation/kdump/kdump.txt index 08bafa8c1caa..212cf3c21abf 100644 --- a/trunk/Documentation/kdump/kdump.txt +++ b/trunk/Documentation/kdump/kdump.txt @@ -1,325 +1,155 @@ +Documentation for kdump - the kexec-based crash dumping solution ================================================================ -Documentation for Kdump - The kexec-based Crash Dumping Solution -================================================================ - -This document includes overview, setup and installation, and analysis -information. - -Overview -======== - -Kdump uses kexec to quickly boot to a dump-capture kernel whenever a -dump of the system kernel's memory needs to be taken (for example, when -the system panics). The system kernel's memory image is preserved across -the reboot and is accessible to the dump-capture kernel. - -You can use common Linux commands, such as cp and scp, to copy the -memory image to a dump file on the local disk, or across the network to -a remote system. - -Kdump and kexec are currently supported on the x86, x86_64, and ppc64 -architectures. - -When the system kernel boots, it reserves a small section of memory for -the dump-capture kernel. This ensures that ongoing Direct Memory Access -(DMA) from the system kernel does not corrupt the dump-capture kernel. -The kexec -p command loads the dump-capture kernel into this reserved -memory. - -On x86 machines, the first 640 KB of physical memory is needed to boot, -regardless of where the kernel loads. Therefore, kexec backs up this -region just before rebooting into the dump-capture kernel. - -All of the necessary information about the system kernel's core image is -encoded in the ELF format, and stored in a reserved area of memory -before a crash. The physical address of the start of the ELF header is -passed to the dump-capture kernel through the elfcorehdr= boot -parameter. - -With the dump-capture kernel, you can access the memory image, or "old -memory," in two ways: - -- Through a /dev/oldmem device interface. A capture utility can read the - device file and write out the memory in raw format. This is a raw dump - of memory. Analysis and capture tools must be intelligent enough to - determine where to look for the right information. - -- Through /proc/vmcore. This exports the dump as an ELF-format file that - you can write out using file copy commands such as cp or scp. Further, - you can use analysis tools such as the GNU Debugger (GDB) and the Crash - tool to debug the dump file. This method ensures that the dump pages are - correctly ordered. - - -Setup and Installation -====================== - -Install kexec-tools and the Kdump patch ---------------------------------------- - -1) Login as the root user. - -2) Download the kexec-tools user-space package from the following URL: - - http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz - -3) Unpack the tarball with the tar command, as follows: - - tar xvpzf kexec-tools-1.101.tar.gz - -4) Download the latest consolidated Kdump patch from the following URL: - - http://lse.sourceforge.net/kdump/ - - (This location is being used until all the user-space Kdump patches - are integrated with the kexec-tools package.) - -5) Change to the kexec-tools-1.101 directory, as follows: - - cd kexec-tools-1.101 - -6) Apply the consolidated patch to the kexec-tools-1.101 source tree - with the patch command, as follows. (Modify the path to the downloaded - patch as necessary.) - - patch -p1 < /path-to-kdump-patch/kexec-tools-1.101-kdump.patch - -7) Configure the package, as follows: - - ./configure - -8) Compile the package, as follows: - - make - -9) Install the package, as follows: - - make install - - -Download and build the system and dump-capture kernels ------------------------------------------------------- - -Download the mainline (vanilla) kernel source code (2.6.13-rc1 or newer) -from http://www.kernel.org. Two kernels must be built: a system kernel -and a dump-capture kernel. Use the following steps to configure these -kernels with the necessary kexec and Kdump features: - -System kernel -------------- - -1) Enable "kexec system call" in "Processor type and features." - - CONFIG_KEXEC=y - -2) Enable "sysfs file system support" in "Filesystem" -> "Pseudo - filesystems." This is usually enabled by default. - - CONFIG_SYSFS=y - - Note that "sysfs file system support" might not appear in the "Pseudo - filesystems" menu if "Configure standard kernel features (for small - systems)" is not enabled in "General Setup." In this case, check the - .config file itself to ensure that sysfs is turned on, as follows: - - grep 'CONFIG_SYSFS' .config - -3) Enable "Compile the kernel with debug info" in "Kernel hacking." - - CONFIG_DEBUG_INFO=Y - This causes the kernel to be built with debug symbols. The dump - analysis tools require a vmlinux with debug symbols in order to read - and analyze a dump file. +DESIGN +====== -4) Make and install the kernel and its modules. Update the boot loader - (such as grub, yaboot, or lilo) configuration files as necessary. +Kdump uses kexec to reboot to a second kernel whenever a dump needs to be +taken. This second kernel is booted with very little memory. The first kernel +reserves the section of memory that the second kernel uses. This ensures that +on-going DMA from the first kernel does not corrupt the second kernel. -5) Boot the system kernel with the boot parameter "crashkernel=Y@X", - where Y specifies how much memory to reserve for the dump-capture kernel - and X specifies the beginning of this reserved memory. For example, - "crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory - starting at physical address 0x01000000 for the dump-capture kernel. +All the necessary information about Core image is encoded in ELF format and +stored in reserved area of memory before crash. Physical address of start of +ELF header is passed to new kernel through command line parameter elfcorehdr=. - On x86 and x86_64, use "crashkernel=64M@16M". +On i386, the first 640 KB of physical memory is needed to boot, irrespective +of where the kernel loads. Hence, this region is backed up by kexec just before +rebooting into the new kernel. - On ppc64, use "crashkernel=128M@32M". +In the second kernel, "old memory" can be accessed in two ways. +- The first one is through a /dev/oldmem device interface. A capture utility + can read the device file and write out the memory in raw format. This is raw + dump of memory and analysis/capture tool should be intelligent enough to + determine where to look for the right information. ELF headers (elfcorehdr=) + can become handy here. -The dump-capture kernel ------------------------ +- The second interface is through /proc/vmcore. This exports the dump as an ELF + format file which can be written out using any file copy command + (cp, scp, etc). Further, gdb can be used to perform limited debugging on + the dump file. This method ensures methods ensure that there is correct + ordering of the dump pages (corresponding to the first 640 KB that has been + relocated). -1) Under "General setup," append "-kdump" to the current string in - "Local version." - -2) On x86, enable high memory support under "Processor type and - features": - - CONFIG_HIGHMEM64G=y - or - CONFIG_HIGHMEM4G - -3) On x86 and x86_64, disable symmetric multi-processing support - under "Processor type and features": - - CONFIG_SMP=n - (If CONFIG_SMP=y, then specify maxcpus=1 on the kernel command line - when loading the dump-capture kernel, see section "Load the Dump-capture - Kernel".) - -4) On ppc64, disable NUMA support and enable EMBEDDED support: - - CONFIG_NUMA=n - CONFIG_EMBEDDED=y - CONFIG_EEH=N for the dump-capture kernel - -5) Enable "kernel crash dumps" support under "Processor type and - features": - - CONFIG_CRASH_DUMP=y - -6) Use a suitable value for "Physical address where the kernel is - loaded" (under "Processor type and features"). This only appears when - "kernel crash dumps" is enabled. By default this value is 0x1000000 - (16MB). It should be the same as X in the "crashkernel=Y@X" boot - parameter discussed above. - - On x86 and x86_64, use "CONFIG_PHYSICAL_START=0x1000000". - - On ppc64 the value is automatically set at 32MB when - CONFIG_CRASH_DUMP is set. - -6) Optionally enable "/proc/vmcore support" under "Filesystems" -> - "Pseudo filesystems". - - CONFIG_PROC_VMCORE=y - (CONFIG_PROC_VMCORE is set by default when CONFIG_CRASH_DUMP is selected.) - -7) Make and install the kernel and its modules. DO NOT add this kernel - to the boot loader configuration files. - - -Load the Dump-capture Kernel -============================ - -After booting to the system kernel, load the dump-capture kernel using -the following command: - - kexec -p \ - --initrd= --args-linux \ - --append="root= init 1 irqpoll" - - -Notes on loading the dump-capture kernel: - -* must be a vmlinux image (that is, an - uncompressed ELF image). bzImage does not work at this time. - -* By default, the ELF headers are stored in ELF64 format to support - systems with more than 4GB memory. The --elf32-core-headers option can - be used to force the generation of ELF32 headers. This is necessary - because GDB currently cannot open vmcore files with ELF64 headers on - 32-bit systems. ELF32 headers can be used on non-PAE systems (that is, - less than 4GB of memory). - -* The "irqpoll" boot parameter reduces driver initialization failures - due to shared interrupts in the dump-capture kernel. - -* You must specify in the format corresponding to the root - device name in the output of mount command. - -* "init 1" boots the dump-capture kernel into single-user mode without - networking. If you want networking, use "init 3." - - -Kernel Panic -============ - -After successfully loading the dump-capture kernel as previously -described, the system will reboot into the dump-capture kernel if a -system crash is triggered. Trigger points are located in panic(), -die(), die_nmi() and in the sysrq handler (ALT-SysRq-c). - -The following conditions will execute a crash trigger point: - -If a hard lockup is detected and "NMI watchdog" is configured, the system -will boot into the dump-capture kernel ( die_nmi() ). - -If die() is called, and it happens to be a thread with pid 0 or 1, or die() -is called inside interrupt context or die() is called and panic_on_oops is set, -the system will boot into the dump-capture kernel. - -On powererpc systems when a soft-reset is generated, die() is called by all cpus and the system system will boot into the dump-capture kernel. - -For testing purposes, you can trigger a crash by using "ALT-SysRq-c", -"echo c > /proc/sysrq-trigger or write a module to force the panic. - -Write Out the Dump File -======================= +SETUP +===== -After the dump-capture kernel is booted, write out the dump file with -the following command: +1) Download the upstream kexec-tools userspace package from + http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz. + + Apply the latest consolidated kdump patch on top of kexec-tools-1.101 + from http://lse.sourceforge.net/kdump/. This arrangment has been made + till all the userspace patches supporting kdump are integrated with + upstream kexec-tools userspace. + +2) Download and build the appropriate (2.6.13-rc1 onwards) vanilla kernels. + Two kernels need to be built in order to get this feature working. + Following are the steps to properly configure the two kernels specific + to kexec and kdump features: + + A) First kernel or regular kernel: + ---------------------------------- + a) Enable "kexec system call" feature (in Processor type and features). + CONFIG_KEXEC=y + b) Enable "sysfs file system support" (in Pseudo filesystems). + CONFIG_SYSFS=y + c) make + d) Boot into first kernel with the command line parameter "crashkernel=Y@X". + Use appropriate values for X and Y. Y denotes how much memory to reserve + for the second kernel, and X denotes at what physical address the + reserved memory section starts. For example: "crashkernel=64M@16M". + + + B) Second kernel or dump capture kernel: + --------------------------------------- + a) For i386 architecture enable Highmem support + CONFIG_HIGHMEM=y + b) Enable "kernel crash dumps" feature (under "Processor type and features") + CONFIG_CRASH_DUMP=y + c) Make sure a suitable value for "Physical address where the kernel is + loaded" (under "Processor type and features"). By default this value + is 0x1000000 (16MB) and it should be same as X (See option d above), + e.g., 16 MB or 0x1000000. + CONFIG_PHYSICAL_START=0x1000000 + d) Enable "/proc/vmcore support" (Optional, under "Pseudo filesystems"). + CONFIG_PROC_VMCORE=y + +3) After booting to regular kernel or first kernel, load the second kernel + using the following command: + + kexec -p --args-linux --elf32-core-headers + --append="root= init 1 irqpoll maxcpus=1" + + Notes: + ====== + i) has to be a vmlinux image ie uncompressed elf image. + bzImage will not work, as of now. + ii) --args-linux has to be speicfied as if kexec it loading an elf image, + it needs to know that the arguments supplied are of linux type. + iii) By default ELF headers are stored in ELF64 format to support systems + with more than 4GB memory. Option --elf32-core-headers forces generation + of ELF32 headers. The reason for this option being, as of now gdb can + not open vmcore file with ELF64 headers on a 32 bit systems. So ELF32 + headers can be used if one has non-PAE systems and hence memory less + than 4GB. + iv) Specify "irqpoll" as command line parameter. This reduces driver + initialization failures in second kernel due to shared interrupts. + v) needs to be specified in a format corresponding to the root + device name in the output of mount command. + vi) If you have built the drivers required to mount root file system as + modules in , then, specify + --initrd=. + vii) Specify maxcpus=1 as, if during first kernel run, if panic happens on + non-boot cpus, second kernel doesn't seem to be boot up all the cpus. + The other option is to always built the second kernel without SMP + support ie CONFIG_SMP=n + +4) After successfully loading the second kernel as above, if a panic occurs + system reboots into the second kernel. A module can be written to force + the panic or "ALT-SysRq-c" can be used initiate a crash dump for testing + purposes. + +5) Once the second kernel has booted, write out the dump file using cp /proc/vmcore -You can also access dumped memory as a /dev/oldmem device for a linear -and raw view. To create the device, use the following command: + Dump memory can also be accessed as a /dev/oldmem device for a linear/raw + view. To create the device, type: - mknod /dev/oldmem c 1 12 + mknod /dev/oldmem c 1 12 -Use the dd command with suitable options for count, bs, and skip to -access specific portions of the dump. + Use "dd" with suitable options for count, bs and skip to access specific + portions of the dump. -To see the entire memory, use the following command: + Entire memory: dd if=/dev/oldmem of=oldmem.001 - dd if=/dev/oldmem of=oldmem.001 - -Analysis +ANALYSIS ======== +Limited analysis can be done using gdb on the dump file copied out of +/proc/vmcore. Use vmlinux built with -g and run -Before analyzing the dump image, you should reboot into a stable kernel. - -You can do limited analysis using GDB on the dump file copied out of -/proc/vmcore. Use the debug vmlinux built with -g and run the following -command: - - gdb vmlinux + gdb vmlinux -Stack trace for the task on processor 0, register display, and memory -display work fine. +Stack trace for the task on processor 0, register display, memory display +work fine. -Note: GDB cannot analyze core files generated in ELF64 format for x86. -On systems with a maximum of 4GB of memory, you can generate -ELF32-format headers using the --elf32-core-headers kernel option on the -dump kernel. +Note: gdb cannot analyse core files generated in ELF64 format for i386. -You can also use the Crash utility to analyze dump files in Kdump -format. Crash is available on Dave Anderson's site at the following URL: +Latest "crash" (crash-4.0-2.18) as available on Dave Anderson's site +http://people.redhat.com/~anderson/ works well with kdump format. - http://people.redhat.com/~anderson/ - - -To Do -===== -1) Provide a kernel pages filtering mechanism, so core file size is not - extreme on systems with huge memory banks. +TODO +==== +1) Provide a kernel pages filtering mechanism so that core file size is not + insane on systems having huge memory banks. +2) Relocatable kernel can help in maintaining multiple kernels for crashdump + and same kernel as the first kernel can be used to capture the dump. -2) Relocatable kernel can help in maintaining multiple kernels for - crash_dump, and the same kernel as the system kernel can be used to - capture the dump. - -Contact +CONTACT ======= - Vivek Goyal (vgoyal@in.ibm.com) Maneesh Soni (maneesh@in.ibm.com) - - -Trademark -========= - -Linux is a trademark of Linus Torvalds in the United States, other -countries, or both. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 0d189c93eeaf..a9d3a1794b23 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -61,7 +61,6 @@ parameter is applicable: MTD MTD support is enabled. NET Appropriate network support is enabled. NUMA NUMA support is enabled. - GENERIC_TIME The generic timeofday code is enabled. NFS Appropriate NFS support is enabled. OSS OSS sound support is enabled. PARIDE The ParIDE subsystem is enabled. @@ -148,9 +147,6 @@ running once the system is up. acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA Format: ,... - acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS - Format: To spoof as Windows 98: ="Microsoft Windows" - acpi_osi= [HW,ACPI] empty param disables _OSI acpi_serialize [HW,ACPI] force serialization of AML methods @@ -180,11 +176,6 @@ running once the system is up. override platform specific driver. See also Documentation/acpi-hotkey.txt. - acpi_pm_good [IA-32,X86-64] - Override the pmtimer bug detection: force the kernel - to assume that this machine's pmtimer latches its value - and always returns good values. - enable_timer_pin_1 [i386,x86-64] Enable PIN 1 of APIC timer Can be useful to work around chipset bugs @@ -347,11 +338,10 @@ running once the system is up. Value can be changed at runtime via /selinux/checkreqprot. - clock= [BUGS=IA-32, HW] gettimeofday clocksource override. - [Deprecated] - Forces specified clocksource (if avaliable) to be used - when calculating gettimeofday(). If specified - clocksource is not avalible, it defaults to PIT. + clock= [BUGS=IA-32,HW] gettimeofday timesource override. + Forces specified timesource (if avaliable) to be used + when calculating gettimeofday(). If specicified + timesource is not avalible, it defaults to PIT. Format: { pit | tsc | cyclone | pmtmr } disable_8254_timer @@ -1624,10 +1614,6 @@ running once the system is up. time Show timing data prefixed to each printk message line - clocksource= [GENERIC_TIME] Override the default clocksource - Override the default clocksource and use the clocksource - with the name specified. - tipar.timeout= [HW,PPT] Set communications timeout in tenths of a second (default 15). @@ -1669,10 +1655,6 @@ running once the system is up. usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. - vdso= [IA-32] - vdso=1: enable VDSO (default) - vdso=0: disable VDSO mapping - video= [FB] Frame buffer configuration See Documentation/fb/modedb.txt. diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index 61c0fad2fe2f..aaa01b0e3ee9 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -19,7 +19,6 @@ This document has the following sections: - Key overview - Key service overview - Key access permissions - - SELinux support - New procfs files - Userspace system call interface - Kernel services @@ -233,39 +232,6 @@ For changing the ownership, group ID or permissions mask, being the owner of the key or having the sysadmin capability is sufficient. -=============== -SELINUX SUPPORT -=============== - -The security class "key" has been added to SELinux so that mandatory access -controls can be applied to keys created within various contexts. This support -is preliminary, and is likely to change quite significantly in the near future. -Currently, all of the basic permissions explained above are provided in SELinux -as well; SELinux is simply invoked after all basic permission checks have been -performed. - -The value of the file /proc/self/attr/keycreate influences the labeling of -newly-created keys. If the contents of that file correspond to an SELinux -security context, then the key will be assigned that context. Otherwise, the -key will be assigned the current context of the task that invoked the key -creation request. Tasks must be granted explicit permission to assign a -particular context to newly-created keys, using the "create" permission in the -key security class. - -The default keyrings associated with users will be labeled with the default -context of the user if and only if the login programs have been instrumented to -properly initialize keycreate during the login process. Otherwise, they will -be labeled with the context of the login program itself. - -Note, however, that the default keyrings associated with the root user are -labeled with the default kernel context, since they are created early in the -boot process, before root has a chance to log in. - -The keyrings associated with new threads are each labeled with the context of -their associated thread, and both session and process keyrings are handled -similarly. - - ================ NEW PROCFS FILES ================ @@ -275,17 +241,9 @@ about the status of the key service: (*) /proc/keys - This lists the keys that are currently viewable by the task reading the - file, giving information about their type, description and permissions. - It is not possible to view the payload of the key this way, though some - information about it may be given. - - The only keys included in the list are those that grant View permission to - the reading process whether or not it possesses them. Note that LSM - security checks are still performed, and may further filter out keys that - the current process is not authorised to view. - - The contents of the file look like this: + This lists all the keys on the system, giving information about their + type, description and permissions. The payload of the key is not available + this way: SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4 @@ -313,7 +271,7 @@ about the status of the key service: (*) /proc/key-users This file lists the tracking data for each user that has at least one key - on the system. Such data includes quota information and statistics: + on the system. Such data includes quota information and statistics: [root@andromeda root]# cat /proc/key-users 0: 46 45/45 1/100 13/10000 @@ -977,16 +935,6 @@ The structure has a number of fields, some of which are mandatory: It is not safe to sleep in this method; the caller may hold spinlocks. - (*) void (*revoke)(struct key *key); - - This method is optional. It is called to discard part of the payload - data upon a key being revoked. The caller will have the key semaphore - write-locked. - - It is safe to sleep in this method, though care should be taken to avoid - a deadlock against the key semaphore. - - (*) void (*destroy)(struct key *key); This method is optional. It is called to discard the payload data on a key diff --git a/trunk/Documentation/md.txt b/trunk/Documentation/md.txt index 0668f9dc9d29..03a13c462cf2 100644 --- a/trunk/Documentation/md.txt +++ b/trunk/Documentation/md.txt @@ -200,17 +200,6 @@ All md devices contain: This can be written only while the array is being assembled, not after it is started. - layout - The "layout" for the array for the particular level. This is - simply a number that is interpretted differently by different - levels. It can be written while assembling an array. - - resync_start - The point at which resync should start. If no resync is needed, - this will be a very large number. At array creation it will - default to 0, though starting the array as 'clean' will - set it much larger. - new_dev This file can be written but not read. The value written should be a block device number as major:minor. e.g. 8:0 @@ -218,54 +207,6 @@ All md devices contain: available. It will then appear at md/dev-XXX (depending on the name of the device) and further configuration is then possible. - safe_mode_delay - When an md array has seen no write requests for a certain period - of time, it will be marked as 'clean'. When another write - request arrive, the array is marked as 'dirty' before the write - commenses. This is known as 'safe_mode'. - The 'certain period' is controlled by this file which stores the - period as a number of seconds. The default is 200msec (0.200). - Writing a value of 0 disables safemode. - - array_state - This file contains a single word which describes the current - state of the array. In many cases, the state can be set by - writing the word for the desired state, however some states - cannot be explicitly set, and some transitions are not allowed. - - clear - No devices, no size, no level - Writing is equivalent to STOP_ARRAY ioctl - inactive - May have some settings, but array is not active - all IO results in error - When written, doesn't tear down array, but just stops it - suspended (not supported yet) - All IO requests will block. The array can be reconfigured. - Writing this, if accepted, will block until array is quiessent - readonly - no resync can happen. no superblocks get written. - write requests fail - read-auto - like readonly, but behaves like 'clean' on a write request. - - clean - no pending writes, but otherwise active. - When written to inactive array, starts without resync - If a write request arrives then - if metadata is known, mark 'dirty' and switch to 'active'. - if not known, block and switch to write-pending - If written to an active array that has pending writes, then fails. - active - fully active: IO and resync can be happening. - When written to inactive array, starts with resync - - write-pending - clean, but writes are blocked waiting for 'active' to be written. - - active-idle - like active, but no writes have been seen for a while (safe_mode_delay). - - sync_speed_min sync_speed_max This are similar to /proc/sys/dev/raid/speed_limit_{min,max} @@ -309,18 +250,10 @@ Each directory contains: faulty - device has been kicked from active use due to a detected fault in_sync - device is a fully in-sync member of the array - writemostly - device will only be subject to read - requests if there are no other options. - This applies only to raid1 arrays. spare - device is working, but not a full member. This includes spares that are in the process of being recoverred to This list make grow in future. - This can be written to. - Writing "faulty" simulates a failure on the device. - Writing "remove" removes the device from the array. - Writing "writemostly" sets the writemostly flag. - Writing "-writemostly" clears the writemostly flag. errors An approximate count of read errors that have been detected on diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt index cf0d5416a4c3..4710845dbac4 100644 --- a/trunk/Documentation/memory-barriers.txt +++ b/trunk/Documentation/memory-barriers.txt @@ -262,14 +262,9 @@ What is required is some way of intervening to instruct the compiler and the CPU to restrict the order. Memory barriers are such interventions. They impose a perceived partial -ordering over the memory operations on either side of the barrier. - -Such enforcement is important because the CPUs and other devices in a system -can use a variety of tricks to improve performance - including reordering, -deferral and combination of memory operations; speculative loads; speculative -branch prediction and various types of caching. Memory barriers are used to -override or suppress these tricks, allowing the code to sanely control the -interaction of multiple CPUs and/or devices. +ordering between the memory operations specified on either side of the barrier. +They request that the sequence of memory events generated appears to other +parts of the system as if the barrier is effective on that CPU. VARIETIES OF MEMORY BARRIER @@ -287,7 +282,7 @@ Memory barriers come in four basic varieties: A write barrier is a partial ordering on stores only; it is not required to have any effect on loads. - A CPU can be viewed as committing a sequence of store operations to the + A CPU can be viewed as as commiting a sequence of store operations to the memory system as time progresses. All stores before a write barrier will occur in the sequence _before_ all the stores after the write barrier. @@ -418,7 +413,7 @@ There are certain things that the Linux kernel memory barriers do not guarantee: indirect effect will be the order in which the second CPU sees the effects of the first CPU's accesses occur, but see the next point: - (*) There is no guarantee that a CPU will see the correct order of effects + (*) There is no guarantee that the a CPU will see the correct order of effects from a second CPU's accesses, even _if_ the second CPU uses a memory barrier, unless the first CPU _also_ uses a matching memory barrier (see the subsection on "SMP Barrier Pairing"). @@ -466,8 +461,8 @@ Whilst this may seem like a failure of coherency or causality maintenance, it isn't, and this behaviour can be observed on certain real CPUs (such as the DEC Alpha). -To deal with this, a data dependency barrier or better must be inserted -between the address load and the data load: +To deal with this, a data dependency barrier must be inserted between the +address load and the data load: CPU 1 CPU 2 =============== =============== @@ -489,7 +484,7 @@ lines. The pointer P might be stored in an odd-numbered cache line, and the variable B might be stored in an even-numbered cache line. Then, if the even-numbered bank of the reading CPU's cache is extremely busy while the odd-numbered bank is idle, one can see the new value of the pointer P (&B), -but the old value of the variable B (2). +but the old value of the variable B (1). Another example of where data dependency barriers might by required is where a @@ -749,7 +744,7 @@ some effectively random order, despite the write barrier issued by CPU 1: : : -If, however, a read barrier were to be placed between the load of B and the +If, however, a read barrier were to be placed between the load of E and the load of A on CPU 2: CPU 1 CPU 2 @@ -1466,8 +1461,9 @@ instruction itself is complete. On a UP system - where this wouldn't be a problem - the smp_mb() is just a compiler barrier, thus making sure the compiler emits the instructions in the -right order without actually intervening in the CPU. Since there's only one -CPU, that CPU's dependency ordering logic will take care of everything else. +right order without actually intervening in the CPU. Since there there's only +one CPU, that CPU's dependency ordering logic will take care of everything +else. ATOMIC OPERATIONS @@ -1644,9 +1640,9 @@ functions: The PCI bus, amongst others, defines an I/O space concept - which on such CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O - space. However, it may also be mapped as a virtual I/O space in the CPU's - memory map, particularly on those CPUs that don't support alternate I/O - spaces. + space. However, it may also mapped as a virtual I/O space in the CPU's + memory map, particularly on those CPUs that don't support alternate + I/O spaces. Accesses to this space may be fully synchronous (as on i386), but intermediary bridges (such as the PCI host bridge) may not fully honour diff --git a/trunk/Documentation/networking/tuntap.txt b/trunk/Documentation/networking/tuntap.txt index 839cbb71388b..76750fb9151a 100644 --- a/trunk/Documentation/networking/tuntap.txt +++ b/trunk/Documentation/networking/tuntap.txt @@ -39,13 +39,10 @@ Copyright (C) 1999-2000 Maxim Krasnyansky mknod /dev/net/tun c 10 200 Set permissions: - e.g. chmod 0666 /dev/net/tun - There's no harm in allowing the device to be accessible by non-root users, - since CAP_NET_ADMIN is required for creating network devices or for - connecting to network devices which aren't owned by the user in question. - If you want to create persistent devices and give ownership of them to - unprivileged users, then you need the /dev/net/tun device to be usable by - those users. + e.g. chmod 0700 /dev/net/tun + if you want the device only accessible by root. Giving regular users the + right to assign network devices is NOT a good idea. Users could assign + bogus network interfaces to trick firewalls or administrators. Driver module autoloading diff --git a/trunk/Documentation/pci.txt b/trunk/Documentation/pci.txt index 3242e5c1ee9c..66bbbf1d1ef6 100644 --- a/trunk/Documentation/pci.txt +++ b/trunk/Documentation/pci.txt @@ -213,17 +213,9 @@ have been remapped by the kernel. See Documentation/IO-mapping.txt for how to access device memory. - The device driver needs to call pci_request_region() to make sure -no other device is already using the same resource. The driver is expected -to determine MMIO and IO Port resource availability _before_ calling -pci_enable_device(). Conversely, drivers should call pci_release_region() -_after_ calling pci_disable_device(). The idea is to prevent two devices -colliding on the same address range. - -Generic flavors of pci_request_region() are request_mem_region() -(for MMIO ranges) and request_region() (for IO Port ranges). -Use these for address resources that are not described by "normal" PCI -interfaces (e.g. BAR). + You still need to call request_region() for I/O regions and +request_mem_region() for memory regions to make sure nobody else is using the +same device. All interrupt handlers should be registered with SA_SHIRQ and use the devid to map IRQs to devices (remember that all PCI interrupts are shared). diff --git a/trunk/Documentation/pi-futex.txt b/trunk/Documentation/pi-futex.txt deleted file mode 100644 index 5d61dacd21f6..000000000000 --- a/trunk/Documentation/pi-futex.txt +++ /dev/null @@ -1,121 +0,0 @@ -Lightweight PI-futexes ----------------------- - -We are calling them lightweight for 3 reasons: - - - in the user-space fastpath a PI-enabled futex involves no kernel work - (or any other PI complexity) at all. No registration, no extra kernel - calls - just pure fast atomic ops in userspace. - - - even in the slowpath, the system call and scheduling pattern is very - similar to normal futexes. - - - the in-kernel PI implementation is streamlined around the mutex - abstraction, with strict rules that keep the implementation - relatively simple: only a single owner may own a lock (i.e. no - read-write lock support), only the owner may unlock a lock, no - recursive locking, etc. - -Priority Inheritance - why? ---------------------------- - -The short reply: user-space PI helps achieving/improving determinism for -user-space applications. In the best-case, it can help achieve -determinism and well-bound latencies. Even in the worst-case, PI will -improve the statistical distribution of locking related application -delays. - -The longer reply: ------------------ - -Firstly, sharing locks between multiple tasks is a common programming -technique that often cannot be replaced with lockless algorithms. As we -can see it in the kernel [which is a quite complex program in itself], -lockless structures are rather the exception than the norm - the current -ratio of lockless vs. locky code for shared data structures is somewhere -between 1:10 and 1:100. Lockless is hard, and the complexity of lockless -algorithms often endangers to ability to do robust reviews of said code. -I.e. critical RT apps often choose lock structures to protect critical -data structures, instead of lockless algorithms. Furthermore, there are -cases (like shared hardware, or other resource limits) where lockless -access is mathematically impossible. - -Media players (such as Jack) are an example of reasonable application -design with multiple tasks (with multiple priority levels) sharing -short-held locks: for example, a highprio audio playback thread is -combined with medium-prio construct-audio-data threads and low-prio -display-colory-stuff threads. Add video and decoding to the mix and -we've got even more priority levels. - -So once we accept that synchronization objects (locks) are an -unavoidable fact of life, and once we accept that multi-task userspace -apps have a very fair expectation of being able to use locks, we've got -to think about how to offer the option of a deterministic locking -implementation to user-space. - -Most of the technical counter-arguments against doing priority -inheritance only apply to kernel-space locks. But user-space locks are -different, there we cannot disable interrupts or make the task -non-preemptible in a critical section, so the 'use spinlocks' argument -does not apply (user-space spinlocks have the same priority inversion -problems as other user-space locking constructs). Fact is, pretty much -the only technique that currently enables good determinism for userspace -locks (such as futex-based pthread mutexes) is priority inheritance: - -Currently (without PI), if a high-prio and a low-prio task shares a lock -[this is a quite common scenario for most non-trivial RT applications], -even if all critical sections are coded carefully to be deterministic -(i.e. all critical sections are short in duration and only execute a -limited number of instructions), the kernel cannot guarantee any -deterministic execution of the high-prio task: any medium-priority task -could preempt the low-prio task while it holds the shared lock and -executes the critical section, and could delay it indefinitely. - -Implementation: ---------------- - -As mentioned before, the userspace fastpath of PI-enabled pthread -mutexes involves no kernel work at all - they behave quite similarly to -normal futex-based locks: a 0 value means unlocked, and a value==TID -means locked. (This is the same method as used by list-based robust -futexes.) Userspace uses atomic ops to lock/unlock these mutexes without -entering the kernel. - -To handle the slowpath, we have added two new futex ops: - - FUTEX_LOCK_PI - FUTEX_UNLOCK_PI - -If the lock-acquire fastpath fails, [i.e. an atomic transition from 0 to -TID fails], then FUTEX_LOCK_PI is called. The kernel does all the -remaining work: if there is no futex-queue attached to the futex address -yet then the code looks up the task that owns the futex [it has put its -own TID into the futex value], and attaches a 'PI state' structure to -the futex-queue. The pi_state includes an rt-mutex, which is a PI-aware, -kernel-based synchronization object. The 'other' task is made the owner -of the rt-mutex, and the FUTEX_WAITERS bit is atomically set in the -futex value. Then this task tries to lock the rt-mutex, on which it -blocks. Once it returns, it has the mutex acquired, and it sets the -futex value to its own TID and returns. Userspace has no other work to -perform - it now owns the lock, and futex value contains -FUTEX_WAITERS|TID. - -If the unlock side fastpath succeeds, [i.e. userspace manages to do a -TID -> 0 atomic transition of the futex value], then no kernel work is -triggered. - -If the unlock fastpath fails (because the FUTEX_WAITERS bit is set), -then FUTEX_UNLOCK_PI is called, and the kernel unlocks the futex on the -behalf of userspace - and it also unlocks the attached -pi_state->rt_mutex and thus wakes up any potential waiters. - -Note that under this approach, contrary to previous PI-futex approaches, -there is no prior 'registration' of a PI-futex. [which is not quite -possible anyway, due to existing ABI properties of pthread mutexes.] - -Also, under this scheme, 'robustness' and 'PI' are two orthogonal -properties of futexes, and all four combinations are possible: futex, -robust-futex, PI-futex, robust+PI-futex. - -More details about priority inheritance can be found in -Documentation/rtmutex.txt. diff --git a/trunk/Documentation/power/devices.txt b/trunk/Documentation/power/devices.txt index fba1e05c47c7..f987afe43e28 100644 --- a/trunk/Documentation/power/devices.txt +++ b/trunk/Documentation/power/devices.txt @@ -118,6 +118,96 @@ will fail. There is currently no way to know what states a device or driver supports a priori. This will change in the future. +pm_message_t meaning + +pm_message_t has two fields. event ("major"), and flags. If driver +does not know event code, it aborts the request, returning error. Some +drivers may need to deal with special cases based on the actual type +of suspend operation being done at the system level. This is why +there are flags. + +Event codes are: + +ON -- no need to do anything except special cases like broken +HW. + +# NOTIFICATION -- pretty much same as ON? + +FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from +scratch. That probably means stop accepting upstream requests, the +actual policy of what to do with them beeing specific to a given +driver. It's acceptable for a network driver to just drop packets +while a block driver is expected to block the queue so no request is +lost. (Use IDE as an example on how to do that). FREEZE requires no +power state change, and it's expected for drivers to be able to +quickly transition back to operating state. + +SUSPEND -- like FREEZE, but also put hardware into low-power state. If +there's need to distinguish several levels of sleep, additional flag +is probably best way to do that. + +Transitions are only from a resumed state to a suspended state, never +between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen, +FREEZE -> SUSPEND or SUSPEND -> FREEZE can not). + +All events are: + +[NOTE NOTE NOTE: If you are driver author, you should not care; you +should only look at event, and ignore flags.] + +#Prepare for suspend -- userland is still running but we are going to +#enter suspend state. This gives drivers chance to load firmware from +#disk and store it in memory, or do other activities taht require +#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these +#are forbiden once the suspend dance is started.. event = ON, flags = +#PREPARE_TO_SUSPEND + +Apm standby -- prepare for APM event. Quiesce devices to make life +easier for APM BIOS. event = FREEZE, flags = APM_STANDBY + +Apm suspend -- same as APM_STANDBY, but it we should probably avoid +spinning down disks. event = FREEZE, flags = APM_SUSPEND + +System halt, reboot -- quiesce devices to make life easier for BIOS. event += FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT + +System shutdown -- at least disks need to be spun down, or data may be +lost. Quiesce devices, just to make life easier for BIOS. event = +FREEZE, flags = SYSTEM_SHUTDOWN + +Kexec -- turn off DMAs and put hardware into some state where new +kernel can take over. event = FREEZE, flags = KEXEC + +Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake +may need to be enabled on some devices. This actually has at least 3 +subtypes, system can reboot, enter S4 and enter S5 at the end of +swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT, +SYSTEM_SHUTDOWN, SYSTEM_S4 + +Suspend to ram -- put devices into low power state. event = SUSPEND, +flags = SUSPEND_TO_RAM + +Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put +devices into low power mode, but you must be able to reinitialize +device from scratch in resume method. This has two flavors, its done +once on suspending kernel, once on resuming kernel. event = FREEZE, +flags = DURING_SUSPEND or DURING_RESUME + +Device detach requested from /sys -- deinitialize device; proably same as +SYSTEM_SHUTDOWN, I do not understand this one too much. probably event += FREEZE, flags = DEV_DETACH. + +#These are not really events sent: +# +#System fully on -- device is working normally; this is probably never +#passed to suspend() method... event = ON, flags = 0 +# +#Ready after resume -- userland is now running, again. Time to free any +#memory you ate during prepare to suspend... event = ON, flags = +#READY_AFTER_RESUME +# + + pm_message_t meaning pm_message_t has two fields. event ("major"), and flags. If driver diff --git a/trunk/Documentation/power/swsusp.txt b/trunk/Documentation/power/swsusp.txt index 823b2cf6e3dc..d7814a113ee1 100644 --- a/trunk/Documentation/power/swsusp.txt +++ b/trunk/Documentation/power/swsusp.txt @@ -18,11 +18,10 @@ Some warnings, first. * * (*) suspend/resume support is needed to make it safe. * - * If you have any filesystems on USB devices mounted before software suspend, + * If you have any filesystems on USB devices mounted before suspend, * they won't be accessible after resume and you may lose data, as though - * you have unplugged the USB devices with mounted filesystems on them; - * see the FAQ below for details. (This is not true for more traditional - * power states like "standby", which normally don't turn USB off.) + * you have unplugged the USB devices with mounted filesystems on them + * (see the FAQ below for details). You need to append resume=/dev/your_swap_partition to kernel command line. Then you suspend by @@ -205,7 +204,7 @@ Q: There don't seem to be any generally useful behavioral distinctions between SUSPEND and FREEZE. A: Doing SUSPEND when you are asked to do FREEZE is always correct, -but it may be unneccessarily slow. If you want your driver to stay simple, +but it may be unneccessarily slow. If you want USB to stay simple, slowness may not matter to you. It can always be fixed later. For devices like disk it does matter, you do not want to spindown for @@ -350,72 +349,25 @@ Q: How do I make suspend more verbose? A: If you want to see any non-error kernel messages on the virtual terminal the kernel switches to during suspend, you have to set the -kernel console loglevel to at least 4 (KERN_WARNING), for example by -doing - - # save the old loglevel - read LOGLEVEL DUMMY < /proc/sys/kernel/printk - # set the loglevel so we see the progress bar. - # if the level is higher than needed, we leave it alone. - if [ $LOGLEVEL -lt 5 ]; then - echo 5 > /proc/sys/kernel/printk - fi - - IMG_SZ=0 - read IMG_SZ < /sys/power/image_size - echo -n disk > /sys/power/state - RET=$? - # - # the logic here is: - # if image_size > 0 (without kernel support, IMG_SZ will be zero), - # then try again with image_size set to zero. - if [ $RET -ne 0 -a $IMG_SZ -ne 0 ]; then # try again with minimal image size - echo 0 > /sys/power/image_size - echo -n disk > /sys/power/state - RET=$? - fi - - # restore previous loglevel - echo $LOGLEVEL > /proc/sys/kernel/printk - exit $RET +kernel console loglevel to at least 5, for example by doing + + echo 5 > /proc/sys/kernel/printk Q: Is this true that if I have a mounted filesystem on a USB device and I suspend to disk, I can lose data unless the filesystem has been mounted with "sync"? -A: That's right ... if you disconnect that device, you may lose data. -In fact, even with "-o sync" you can lose data if your programs have -information in buffers they haven't written out to a disk you disconnect, -or if you disconnect before the device finished saving data you wrote. - -Software suspend normally powers down USB controllers, which is equivalent -to disconnecting all USB devices attached to your system. +A: That's right. It depends on your hardware, and it could be true even for +suspend-to-RAM. In fact, even with "-o sync" you can lose data if your +programs have information in buffers they haven't written out to disk. -Your system might well support low-power modes for its USB controllers -while the system is asleep, maintaining the connection, using true sleep -modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the -/sys/power/state file; write "standby" or "mem".) We've not seen any -hardware that can use these modes through software suspend, although in -theory some systems might support "platform" or "firmware" modes that -won't break the USB connections. +If you're lucky, your hardware will support low-power modes for USB +controllers while the system is asleep. Lots of hardware doesn't, +however. Shutting off the power to a USB controller is equivalent to +unplugging all the attached devices. Remember that it's always a bad idea to unplug a disk drive containing a -mounted filesystem. That's true even when your system is asleep! The -safest thing is to unmount all filesystems on removable media (such USB, -Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays) -before suspending; then remount them after resuming. - -Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were -compiled with the similar configuration files. Anyway I found that -suspend to disk (and resume) is much slower on 2.6.16 compared to -2.6.15. Any idea for why that might happen or how can I speed it up? - -A: This is because the size of the suspend image is now greater than -for 2.6.15 (by saving more data we can get more responsive system -after resume). - -There's the /sys/power/image_size knob that controls the size of the -image. If you set it to 0 (eg. by echo 0 > /sys/power/image_size as -root), the 2.6.15 behavior should be restored. If it is still too -slow, take a look at suspend.sf.net -- userland suspend is faster and -supports LZF compression to speed it up further. +mounted filesystem. With USB that's true even when your system is asleep! +The safest thing is to unmount all USB-based filesystems before suspending +and remount them after resuming. + diff --git a/trunk/Documentation/power/video.txt b/trunk/Documentation/power/video.txt index d859faa3a463..43a889f8f08d 100644 --- a/trunk/Documentation/power/video.txt +++ b/trunk/Documentation/power/video.txt @@ -90,7 +90,6 @@ Table of known working notebooks: Model hack (or "how to do it") ------------------------------------------------------------------------------ Acer Aspire 1406LC ole's late BIOS init (7), turn off DRI -Acer TM 230 s3_bios (2) Acer TM 242FX vbetool (6) Acer TM C110 video_post (8) Acer TM C300 vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8) @@ -116,7 +115,6 @@ Dell D610 vga=normal and X (possibly vbestate (6) too, but not tested) Dell Inspiron 4000 ??? (*) Dell Inspiron 500m ??? (*) Dell Inspiron 510m ??? -Dell Inspiron 5150 vbetool needed (6) Dell Inspiron 600m ??? (*) Dell Inspiron 8200 ??? (*) Dell Inspiron 8500 ??? (*) @@ -127,7 +125,6 @@ HP NX7000 ??? (*) HP Pavilion ZD7000 vbetool post needed, need open-source nv driver for X HP Omnibook XE3 athlon version none (1) HP Omnibook XE3GC none (1), video is S3 Savage/IX-MV -HP Omnibook XE3L-GF vbetool (6) HP Omnibook 5150 none (1), (S1 also works OK) IBM TP T20, model 2647-44G none (1), video is S3 Inc. 86C270-294 Savage/IX-MV, vesafb gets "interesting" but X work. IBM TP A31 / Type 2652-M5G s3_mode (3) [works ok with BIOS 1.04 2002-08-23, but not at all with BIOS 1.11 2004-11-05 :-(] @@ -160,7 +157,6 @@ Sony Vaio vgn-s260 X or boot-radeon can init it (5) Sony Vaio vgn-S580BH vga=normal, but suspend from X. Console will be blank unless you return to X. Sony Vaio vgn-FS115B s3_bios (2),s3_mode (4) Toshiba Libretto L5 none (1) -Toshiba Libretto 100CT/110CT vbetool (6) Toshiba Portege 3020CT s3_mode (3) Toshiba Satellite 4030CDT s3_mode (3) (S1 also works OK) Toshiba Satellite 4080XCDT s3_mode (3) (S1 also works OK) diff --git a/trunk/Documentation/robust-futexes.txt b/trunk/Documentation/robust-futexes.txt index 76e8064b8c3a..df82d75245a0 100644 --- a/trunk/Documentation/robust-futexes.txt +++ b/trunk/Documentation/robust-futexes.txt @@ -95,7 +95,7 @@ comparison. If the thread has registered a list, then normally the list is empty. If the thread/process crashed or terminated in some incorrect way then the list might be non-empty: in this case the kernel carefully walks the list [not trusting it], and marks all locks that are owned by -this thread with the FUTEX_OWNER_DIED bit, and wakes up one waiter (if +this thread with the FUTEX_OWNER_DEAD bit, and wakes up one waiter (if any). The list is guaranteed to be private and per-thread at do_exit() time, diff --git a/trunk/Documentation/rt-mutex-design.txt b/trunk/Documentation/rt-mutex-design.txt deleted file mode 100644 index c472ffacc2f6..000000000000 --- a/trunk/Documentation/rt-mutex-design.txt +++ /dev/null @@ -1,781 +0,0 @@ -# -# Copyright (c) 2006 Steven Rostedt -# Licensed under the GNU Free Documentation License, Version 1.2 -# - -RT-mutex implementation design ------------------------------- - -This document tries to describe the design of the rtmutex.c implementation. -It doesn't describe the reasons why rtmutex.c exists. For that please see -Documentation/rt-mutex.txt. Although this document does explain problems -that happen without this code, but that is in the concept to understand -what the code actually is doing. - -The goal of this document is to help others understand the priority -inheritance (PI) algorithm that is used, as well as reasons for the -decisions that were made to implement PI in the manner that was done. - - -Unbounded Priority Inversion ----------------------------- - -Priority inversion is when a lower priority process executes while a higher -priority process wants to run. This happens for several reasons, and -most of the time it can't be helped. Anytime a high priority process wants -to use a resource that a lower priority process has (a mutex for example), -the high priority process must wait until the lower priority process is done -with the resource. This is a priority inversion. What we want to prevent -is something called unbounded priority inversion. That is when the high -priority process is prevented from running by a lower priority process for -an undetermined amount of time. - -The classic example of unbounded priority inversion is were you have three -processes, let's call them processes A, B, and C, where A is the highest -priority process, C is the lowest, and B is in between. A tries to grab a lock -that C owns and must wait and lets C run to release the lock. But in the -meantime, B executes, and since B is of a higher priority than C, it preempts C, -but by doing so, it is in fact preempting A which is a higher priority process. -Now there's no way of knowing how long A will be sleeping waiting for C -to release the lock, because for all we know, B is a CPU hog and will -never give C a chance to release the lock. This is called unbounded priority -inversion. - -Here's a little ASCII art to show the problem. - - grab lock L1 (owned by C) - | -A ---+ - C preempted by B - | -C +----+ - -B +--------> - B now keeps A from running. - - -Priority Inheritance (PI) -------------------------- - -There are several ways to solve this issue, but other ways are out of scope -for this document. Here we only discuss PI. - -PI is where a process inherits the priority of another process if the other -process blocks on a lock owned by the current process. To make this easier -to understand, let's use the previous example, with processes A, B, and C again. - -This time, when A blocks on the lock owned by C, C would inherit the priority -of A. So now if B becomes runnable, it would not preempt C, since C now has -the high priority of A. As soon as C releases the lock, it loses its -inherited priority, and A then can continue with the resource that C had. - -Terminology ------------ - -Here I explain some terminology that is used in this document to help describe -the design that is used to implement PI. - -PI chain - The PI chain is an ordered series of locks and processes that cause - processes to inherit priorities from a previous process that is - blocked on one of its locks. This is described in more detail - later in this document. - -mutex - In this document, to differentiate from locks that implement - PI and spin locks that are used in the PI code, from now on - the PI locks will be called a mutex. - -lock - In this document from now on, I will use the term lock when - referring to spin locks that are used to protect parts of the PI - algorithm. These locks disable preemption for UP (when - CONFIG_PREEMPT is enabled) and on SMP prevents multiple CPUs from - entering critical sections simultaneously. - -spin lock - Same as lock above. - -waiter - A waiter is a struct that is stored on the stack of a blocked - process. Since the scope of the waiter is within the code for - a process being blocked on the mutex, it is fine to allocate - the waiter on the process's stack (local variable). This - structure holds a pointer to the task, as well as the mutex that - the task is blocked on. It also has the plist node structures to - place the task in the waiter_list of a mutex as well as the - pi_list of a mutex owner task (described below). - - waiter is sometimes used in reference to the task that is waiting - on a mutex. This is the same as waiter->task. - -waiters - A list of processes that are blocked on a mutex. - -top waiter - The highest priority process waiting on a specific mutex. - -top pi waiter - The highest priority process waiting on one of the mutexes - that a specific process owns. - -Note: task and process are used interchangeably in this document, mostly to - differentiate between two processes that are being described together. - - -PI chain --------- - -The PI chain is a list of processes and mutexes that may cause priority -inheritance to take place. Multiple chains may converge, but a chain -would never diverge, since a process can't be blocked on more than one -mutex at a time. - -Example: - - Process: A, B, C, D, E - Mutexes: L1, L2, L3, L4 - - A owns: L1 - B blocked on L1 - B owns L2 - C blocked on L2 - C owns L3 - D blocked on L3 - D owns L4 - E blocked on L4 - -The chain would be: - - E->L4->D->L3->C->L2->B->L1->A - -To show where two chains merge, we could add another process F and -another mutex L5 where B owns L5 and F is blocked on mutex L5. - -The chain for F would be: - - F->L5->B->L1->A - -Since a process may own more than one mutex, but never be blocked on more than -one, the chains merge. - -Here we show both chains: - - E->L4->D->L3->C->L2-+ - | - +->B->L1->A - | - F->L5-+ - -For PI to work, the processes at the right end of these chains (or we may -also call it the Top of the chain) must be equal to or higher in priority -than the processes to the left or below in the chain. - -Also since a mutex may have more than one process blocked on it, we can -have multiple chains merge at mutexes. If we add another process G that is -blocked on mutex L2: - - G->L2->B->L1->A - -And once again, to show how this can grow I will show the merging chains -again. - - E->L4->D->L3->C-+ - +->L2-+ - | | - G-+ +->B->L1->A - | - F->L5-+ - - -Plist ------ - -Before I go further and talk about how the PI chain is stored through lists -on both mutexes and processes, I'll explain the plist. This is similar to -the struct list_head functionality that is already in the kernel. -The implementation of plist is out of scope for this document, but it is -very important to understand what it does. - -There are a few differences between plist and list, the most important one -being that plist is a priority sorted linked list. This means that the -priorities of the plist are sorted, such that it takes O(1) to retrieve the -highest priority item in the list. Obviously this is useful to store processes -based on their priorities. - -Another difference, which is important for implementation, is that, unlike -list, the head of the list is a different element than the nodes of a list. -So the head of the list is declared as struct plist_head and nodes that will -be added to the list are declared as struct plist_node. - - -Mutex Waiter List ------------------ - -Every mutex keeps track of all the waiters that are blocked on itself. The mutex -has a plist to store these waiters by priority. This list is protected by -a spin lock that is located in the struct of the mutex. This lock is called -wait_lock. Since the modification of the waiter list is never done in -interrupt context, the wait_lock can be taken without disabling interrupts. - - -Task PI List ------------- - -To keep track of the PI chains, each process has its own PI list. This is -a list of all top waiters of the mutexes that are owned by the process. -Note that this list only holds the top waiters and not all waiters that are -blocked on mutexes owned by the process. - -The top of the task's PI list is always the highest priority task that -is waiting on a mutex that is owned by the task. So if the task has -inherited a priority, it will always be the priority of the task that is -at the top of this list. - -This list is stored in the task structure of a process as a plist called -pi_list. This list is protected by a spin lock also in the task structure, -called pi_lock. This lock may also be taken in interrupt context, so when -locking the pi_lock, interrupts must be disabled. - - -Depth of the PI Chain ---------------------- - -The maximum depth of the PI chain is not dynamic, and could actually be -defined. But is very complex to figure it out, since it depends on all -the nesting of mutexes. Let's look at the example where we have 3 mutexes, -L1, L2, and L3, and four separate functions func1, func2, func3 and func4. -The following shows a locking order of L1->L2->L3, but may not actually -be directly nested that way. - -void func1(void) -{ - mutex_lock(L1); - - /* do anything */ - - mutex_unlock(L1); -} - -void func2(void) -{ - mutex_lock(L1); - mutex_lock(L2); - - /* do something */ - - mutex_unlock(L2); - mutex_unlock(L1); -} - -void func3(void) -{ - mutex_lock(L2); - mutex_lock(L3); - - /* do something else */ - - mutex_unlock(L3); - mutex_unlock(L2); -} - -void func4(void) -{ - mutex_lock(L3); - - /* do something again */ - - mutex_unlock(L3); -} - -Now we add 4 processes that run each of these functions separately. -Processes A, B, C, and D which run functions func1, func2, func3 and func4 -respectively, and such that D runs first and A last. With D being preempted -in func4 in the "do something again" area, we have a locking that follows: - -D owns L3 - C blocked on L3 - C owns L2 - B blocked on L2 - B owns L1 - A blocked on L1 - -And thus we have the chain A->L1->B->L2->C->L3->D. - -This gives us a PI depth of 4 (four processes), but looking at any of the -functions individually, it seems as though they only have at most a locking -depth of two. So, although the locking depth is defined at compile time, -it still is very difficult to find the possibilities of that depth. - -Now since mutexes can be defined by user-land applications, we don't want a DOS -type of application that nests large amounts of mutexes to create a large -PI chain, and have the code holding spin locks while looking at a large -amount of data. So to prevent this, the implementation not only implements -a maximum lock depth, but also only holds at most two different locks at a -time, as it walks the PI chain. More about this below. - - -Mutex owner and flags ---------------------- - -The mutex structure contains a pointer to the owner of the mutex. If the -mutex is not owned, this owner is set to NULL. Since all architectures -have the task structure on at least a four byte alignment (and if this is -not true, the rtmutex.c code will be broken!), this allows for the two -least significant bits to be used as flags. This part is also described -in Documentation/rt-mutex.txt, but will also be briefly described here. - -Bit 0 is used as the "Pending Owner" flag. This is described later. -Bit 1 is used as the "Has Waiters" flags. This is also described later - in more detail, but is set whenever there are waiters on a mutex. - - -cmpxchg Tricks --------------- - -Some architectures implement an atomic cmpxchg (Compare and Exchange). This -is used (when applicable) to keep the fast path of grabbing and releasing -mutexes short. - -cmpxchg is basically the following function performed atomically: - -unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C) -{ - unsigned long T = *A; - if (*A == *B) { - *A = *C; - } - return T; -} -#define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c) - -This is really nice to have, since it allows you to only update a variable -if the variable is what you expect it to be. You know if it succeeded if -the return value (the old value of A) is equal to B. - -The macro rt_mutex_cmpxchg is used to try to lock and unlock mutexes. If -the architecture does not support CMPXCHG, then this macro is simply set -to fail every time. But if CMPXCHG is supported, then this will -help out extremely to keep the fast path short. - -The use of rt_mutex_cmpxchg with the flags in the owner field help optimize -the system for architectures that support it. This will also be explained -later in this document. - - -Priority adjustments --------------------- - -The implementation of the PI code in rtmutex.c has several places that a -process must adjust its priority. With the help of the pi_list of a -process this is rather easy to know what needs to be adjusted. - -The functions implementing the task adjustments are rt_mutex_adjust_prio, -__rt_mutex_adjust_prio (same as the former, but expects the task pi_lock -to already be taken), rt_mutex_get_prio, and rt_mutex_setprio. - -rt_mutex_getprio and rt_mutex_setprio are only used in __rt_mutex_adjust_prio. - -rt_mutex_getprio returns the priority that the task should have. Either the -task's own normal priority, or if a process of a higher priority is waiting on -a mutex owned by the task, then that higher priority should be returned. -Since the pi_list of a task holds an order by priority list of all the top -waiters of all the mutexes that the task owns, rt_mutex_getprio simply needs -to compare the top pi waiter to its own normal priority, and return the higher -priority back. - -(Note: if looking at the code, you will notice that the lower number of - prio is returned. This is because the prio field in the task structure - is an inverse order of the actual priority. So a "prio" of 5 is - of higher priority than a "prio" of 10.) - -__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the -result does not equal the task's current priority, then rt_mutex_setprio -is called to adjust the priority of the task to the new priority. -Note that rt_mutex_setprio is defined in kernel/sched.c to implement the -actual change in priority. - -It is interesting to note that __rt_mutex_adjust_prio can either increase -or decrease the priority of the task. In the case that a higher priority -process has just blocked on a mutex owned by the task, __rt_mutex_adjust_prio -would increase/boost the task's priority. But if a higher priority task -were for some reason to leave the mutex (timeout or signal), this same function -would decrease/unboost the priority of the task. That is because the pi_list -always contains the highest priority task that is waiting on a mutex owned -by the task, so we only need to compare the priority of that top pi waiter -to the normal priority of the given task. - - -High level overview of the PI chain walk ----------------------------------------- - -The PI chain walk is implemented by the function rt_mutex_adjust_prio_chain. - -The implementation has gone through several iterations, and has ended up -with what we believe is the best. It walks the PI chain by only grabbing -at most two locks at a time, and is very efficient. - -The rt_mutex_adjust_prio_chain can be used either to boost or lower process -priorities. - -rt_mutex_adjust_prio_chain is called with a task to be checked for PI -(de)boosting (the owner of a mutex that a process is blocking on), a flag to -check for deadlocking, the mutex that the task owns, and a pointer to a waiter -that is the process's waiter struct that is blocked on the mutex (although this -parameter may be NULL for deboosting). - -For this explanation, I will not mention deadlock detection. This explanation -will try to stay at a high level. - -When this function is called, there are no locks held. That also means -that the state of the owner and lock can change when entered into this function. - -Before this function is called, the task has already had rt_mutex_adjust_prio -performed on it. This means that the task is set to the priority that it -should be at, but the plist nodes of the task's waiter have not been updated -with the new priorities, and that this task may not be in the proper locations -in the pi_lists and wait_lists that the task is blocked on. This function -solves all that. - -A loop is entered, where task is the owner to be checked for PI changes that -was passed by parameter (for the first iteration). The pi_lock of this task is -taken to prevent any more changes to the pi_list of the task. This also -prevents new tasks from completing the blocking on a mutex that is owned by this -task. - -If the task is not blocked on a mutex then the loop is exited. We are at -the top of the PI chain. - -A check is now done to see if the original waiter (the process that is blocked -on the current mutex) is the top pi waiter of the task. That is, is this -waiter on the top of the task's pi_list. If it is not, it either means that -there is another process higher in priority that is blocked on one of the -mutexes that the task owns, or that the waiter has just woken up via a signal -or timeout and has left the PI chain. In either case, the loop is exited, since -we don't need to do any more changes to the priority of the current task, or any -task that owns a mutex that this current task is waiting on. A priority chain -walk is only needed when a new top pi waiter is made to a task. - -The next check sees if the task's waiter plist node has the priority equal to -the priority the task is set at. If they are equal, then we are done with -the loop. Remember that the function started with the priority of the -task adjusted, but the plist nodes that hold the task in other processes -pi_lists have not been adjusted. - -Next, we look at the mutex that the task is blocked on. The mutex's wait_lock -is taken. This is done by a spin_trylock, because the locking order of the -pi_lock and wait_lock goes in the opposite direction. If we fail to grab the -lock, the pi_lock is released, and we restart the loop. - -Now that we have both the pi_lock of the task as well as the wait_lock of -the mutex the task is blocked on, we update the task's waiter's plist node -that is located on the mutex's wait_list. - -Now we release the pi_lock of the task. - -Next the owner of the mutex has its pi_lock taken, so we can update the -task's entry in the owner's pi_list. If the task is the highest priority -process on the mutex's wait_list, then we remove the previous top waiter -from the owner's pi_list, and replace it with the task. - -Note: It is possible that the task was the current top waiter on the mutex, - in which case the task is not yet on the pi_list of the waiter. This - is OK, since plist_del does nothing if the plist node is not on any - list. - -If the task was not the top waiter of the mutex, but it was before we -did the priority updates, that means we are deboosting/lowering the -task. In this case, the task is removed from the pi_list of the owner, -and the new top waiter is added. - -Lastly, we unlock both the pi_lock of the task, as well as the mutex's -wait_lock, and continue the loop again. On the next iteration of the -loop, the previous owner of the mutex will be the task that will be -processed. - -Note: One might think that the owner of this mutex might have changed - since we just grab the mutex's wait_lock. And one could be right. - The important thing to remember is that the owner could not have - become the task that is being processed in the PI chain, since - we have taken that task's pi_lock at the beginning of the loop. - So as long as there is an owner of this mutex that is not the same - process as the tasked being worked on, we are OK. - - Looking closely at the code, one might be confused. The check for the - end of the PI chain is when the task isn't blocked on anything or the - task's waiter structure "task" element is NULL. This check is - protected only by the task's pi_lock. But the code to unlock the mutex - sets the task's waiter structure "task" element to NULL with only - the protection of the mutex's wait_lock, which was not taken yet. - Isn't this a race condition if the task becomes the new owner? - - The answer is No! The trick is the spin_trylock of the mutex's - wait_lock. If we fail that lock, we release the pi_lock of the - task and continue the loop, doing the end of PI chain check again. - - In the code to release the lock, the wait_lock of the mutex is held - the entire time, and it is not let go when we grab the pi_lock of the - new owner of the mutex. So if the switch of a new owner were to happen - after the check for end of the PI chain and the grabbing of the - wait_lock, the unlocking code would spin on the new owner's pi_lock - but never give up the wait_lock. So the PI chain loop is guaranteed to - fail the spin_trylock on the wait_lock, release the pi_lock, and - try again. - - If you don't quite understand the above, that's OK. You don't have to, - unless you really want to make a proof out of it ;) - - -Pending Owners and Lock stealing --------------------------------- - -One of the flags in the owner field of the mutex structure is "Pending Owner". -What this means is that an owner was chosen by the process releasing the -mutex, but that owner has yet to wake up and actually take the mutex. - -Why is this important? Why can't we just give the mutex to another process -and be done with it? - -The PI code is to help with real-time processes, and to let the highest -priority process run as long as possible with little latencies and delays. -If a high priority process owns a mutex that a lower priority process is -blocked on, when the mutex is released it would be given to the lower priority -process. What if the higher priority process wants to take that mutex again. -The high priority process would fail to take that mutex that it just gave up -and it would need to boost the lower priority process to run with full -latency of that critical section (since the low priority process just entered -it). - -There's no reason a high priority process that gives up a mutex should be -penalized if it tries to take that mutex again. If the new owner of the -mutex has not woken up yet, there's no reason that the higher priority process -could not take that mutex away. - -To solve this, we introduced Pending Ownership and Lock Stealing. When a -new process is given a mutex that it was blocked on, it is only given -pending ownership. This means that it's the new owner, unless a higher -priority process comes in and tries to grab that mutex. If a higher priority -process does come along and wants that mutex, we let the higher priority -process "steal" the mutex from the pending owner (only if it is still pending) -and continue with the mutex. - - -Taking of a mutex (The walk through) ------------------------------------- - -OK, now let's take a look at the detailed walk through of what happens when -taking a mutex. - -The first thing that is tried is the fast taking of the mutex. This is -done when we have CMPXCHG enabled (otherwise the fast taking automatically -fails). Only when the owner field of the mutex is NULL can the lock be -taken with the CMPXCHG and nothing else needs to be done. - -If there is contention on the lock, whether it is owned or pending owner -we go about the slow path (rt_mutex_slowlock). - -The slow path function is where the task's waiter structure is created on -the stack. This is because the waiter structure is only needed for the -scope of this function. The waiter structure holds the nodes to store -the task on the wait_list of the mutex, and if need be, the pi_list of -the owner. - -The wait_lock of the mutex is taken since the slow path of unlocking the -mutex also takes this lock. - -We then call try_to_take_rt_mutex. This is where the architecture that -does not implement CMPXCHG would always grab the lock (if there's no -contention). - -try_to_take_rt_mutex is used every time the task tries to grab a mutex in the -slow path. The first thing that is done here is an atomic setting of -the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the the mutex has no owner, there are no waiters and -the current task also won't have any waiters. But we don't have the lock -yet, so we assume we are going to be a waiter. The reason for this is to -play nice for those architectures that do have CMPXCHG. By setting this flag -now, the owner of the mutex can't release the mutex without going into the -slow unlock path, and it would then need to grab the wait_lock, which this -code currently holds. So setting the "Has Waiters" flag forces the owner -to synchronize with this code. - -Now that we know that we can't have any races with the owner releasing the -mutex, we check to see if we can take the ownership. This is done if the -mutex doesn't have a owner, or if we can steal the mutex from a pending -owner. Let's look at the situations we have here. - - 1) Has owner that is pending - ---------------------------- - - The mutex has a owner, but it hasn't woken up and the mutex flag - "Pending Owner" is set. The first check is to see if the owner isn't the - current task. This is because this function is also used for the pending - owner to grab the mutex. When a pending owner wakes up, it checks to see - if it can take the mutex, and this is done if the owner is already set to - itself. If so, we succeed and leave the function, clearing the "Pending - Owner" bit. - - If the pending owner is not current, we check to see if the current priority is - higher than the pending owner. If not, we fail the function and return. - - There's also something special about a pending owner. That is a pending owner - is never blocked on a mutex. So there is no PI chain to worry about. It also - means that if the mutex doesn't have any waiters, there's no accounting needed - to update the pending owner's pi_list, since we only worry about processes - blocked on the current mutex. - - If there are waiters on this mutex, and we just stole the ownership, we need - to take the top waiter, remove it from the pi_list of the pending owner, and - add it to the current pi_list. Note that at this moment, the pending owner - is no longer on the list of waiters. This is fine, since the pending owner - would add itself back when it realizes that it had the ownership stolen - from itself. When the pending owner tries to grab the mutex, it will fail - in try_to_take_rt_mutex if the owner field points to another process. - - 2) No owner - ----------- - - If there is no owner (or we successfully stole the lock), we set the owner - of the mutex to current, and set the flag of "Has Waiters" if the current - mutex actually has waiters, or we clear the flag if it doesn't. See, it was - OK that we set that flag early, since now it is cleared. - - 3) Failed to grab ownership - --------------------------- - - The most interesting case is when we fail to take ownership. This means that - there exists an owner, or there's a pending owner with equal or higher - priority than the current task. - -We'll continue on the failed case. - -If the mutex has a timeout, we set up a timer to go off to break us out -of this mutex if we failed to get it after a specified amount of time. - -Now we enter a loop that will continue to try to take ownership of the mutex, or -fail from a timeout or signal. - -Once again we try to take the mutex. This will usually fail the first time -in the loop, since it had just failed to get the mutex. But the second time -in the loop, this would likely succeed, since the task would likely be -the pending owner. - -If the mutex is TASK_INTERRUPTIBLE a check for signals and timeout is done -here. - -The waiter structure has a "task" field that points to the task that is blocked -on the mutex. This field can be NULL the first time it goes through the loop -or if the task is a pending owner and had it's mutex stolen. If the "task" -field is NULL then we need to set up the accounting for it. - -Task blocks on mutex --------------------- - -The accounting of a mutex and process is done with the waiter structure of -the process. The "task" field is set to the process, and the "lock" field -to the mutex. The plist nodes are initialized to the processes current -priority. - -Since the wait_lock was taken at the entry of the slow lock, we can safely -add the waiter to the wait_list. If the current process is the highest -priority process currently waiting on this mutex, then we remove the -previous top waiter process (if it exists) from the pi_list of the owner, -and add the current process to that list. Since the pi_list of the owner -has changed, we call rt_mutex_adjust_prio on the owner to see if the owner -should adjust its priority accordingly. - -If the owner is also blocked on a lock, and had its pi_list changed -(or deadlock checking is on), we unlock the wait_lock of the mutex and go ahead -and run rt_mutex_adjust_prio_chain on the owner, as described earlier. - -Now all locks are released, and if the current process is still blocked on a -mutex (waiter "task" field is not NULL), then we go to sleep (call schedule). - -Waking up in the loop ---------------------- - -The schedule can then wake up for a few reasons. - 1) we were given pending ownership of the mutex. - 2) we received a signal and was TASK_INTERRUPTIBLE - 3) we had a timeout and was TASK_INTERRUPTIBLE - -In any of these cases, we continue the loop and once again try to grab the -ownership of the mutex. If we succeed, we exit the loop, otherwise we continue -and on signal and timeout, will exit the loop, or if we had the mutex stolen -we just simply add ourselves back on the lists and go back to sleep. - -Note: For various reasons, because of timeout and signals, the steal mutex - algorithm needs to be careful. This is because the current process is - still on the wait_list. And because of dynamic changing of priorities, - especially on SCHED_OTHER tasks, the current process can be the - highest priority task on the wait_list. - -Failed to get mutex on Timeout or Signal ----------------------------------------- - -If a timeout or signal occurred, the waiter's "task" field would not be -NULL and the task needs to be taken off the wait_list of the mutex and perhaps -pi_list of the owner. If this process was a high priority process, then -the rt_mutex_adjust_prio_chain needs to be executed again on the owner, -but this time it will be lowering the priorities. - - -Unlocking the Mutex -------------------- - -The unlocking of a mutex also has a fast path for those architectures with -CMPXCHG. Since the taking of a mutex on contention always sets the -"Has Waiters" flag of the mutex's owner, we use this to know if we need to -take the slow path when unlocking the mutex. If the mutex doesn't have any -waiters, the owner field of the mutex would equal the current process and -the mutex can be unlocked by just replacing the owner field with NULL. - -If the owner field has the "Has Waiters" bit set (or CMPXCHG is not available), -the slow unlock path is taken. - -The first thing done in the slow unlock path is to take the wait_lock of the -mutex. This synchronizes the locking and unlocking of the mutex. - -A check is made to see if the mutex has waiters or not. On architectures that -do not have CMPXCHG, this is the location that the owner of the mutex will -determine if a waiter needs to be awoken or not. On architectures that -do have CMPXCHG, that check is done in the fast path, but it is still needed -in the slow path too. If a waiter of a mutex woke up because of a signal -or timeout between the time the owner failed the fast path CMPXCHG check and -the grabbing of the wait_lock, the mutex may not have any waiters, thus the -owner still needs to make this check. If there are no waiters than the mutex -owner field is set to NULL, the wait_lock is released and nothing more is -needed. - -If there are waiters, then we need to wake one up and give that waiter -pending ownership. - -On the wake up code, the pi_lock of the current owner is taken. The top -waiter of the lock is found and removed from the wait_list of the mutex -as well as the pi_list of the current owner. The task field of the new -pending owner's waiter structure is set to NULL, and the owner field of the -mutex is set to the new owner with the "Pending Owner" bit set, as well -as the "Has Waiters" bit if there still are other processes blocked on the -mutex. - -The pi_lock of the previous owner is released, and the new pending owner's -pi_lock is taken. Remember that this is the trick to prevent the race -condition in rt_mutex_adjust_prio_chain from adding itself as a waiter -on the mutex. - -We now clear the "pi_blocked_on" field of the new pending owner, and if -the mutex still has waiters pending, we add the new top waiter to the pi_list -of the pending owner. - -Finally we unlock the pi_lock of the pending owner and wake it up. - - -Contact -------- - -For updates on this document, please email Steven Rostedt - - -Credits -------- - -Author: Steven Rostedt - -Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and Randy Dunlap - -Updates -------- - -This document was originally written for 2.6.17-rc3-mm1 diff --git a/trunk/Documentation/rt-mutex.txt b/trunk/Documentation/rt-mutex.txt deleted file mode 100644 index 243393d882ee..000000000000 --- a/trunk/Documentation/rt-mutex.txt +++ /dev/null @@ -1,79 +0,0 @@ -RT-mutex subsystem with PI support ----------------------------------- - -RT-mutexes with priority inheritance are used to support PI-futexes, -which enable pthread_mutex_t priority inheritance attributes -(PTHREAD_PRIO_INHERIT). [See Documentation/pi-futex.txt for more details -about PI-futexes.] - -This technology was developed in the -rt tree and streamlined for -pthread_mutex support. - -Basic principles: ------------------ - -RT-mutexes extend the semantics of simple mutexes by the priority -inheritance protocol. - -A low priority owner of a rt-mutex inherits the priority of a higher -priority waiter until the rt-mutex is released. If the temporarily -boosted owner blocks on a rt-mutex itself it propagates the priority -boosting to the owner of the other rt_mutex it gets blocked on. The -priority boosting is immediately removed once the rt_mutex has been -unlocked. - -This approach allows us to shorten the block of high-prio tasks on -mutexes which protect shared resources. Priority inheritance is not a -magic bullet for poorly designed applications, but it allows -well-designed applications to use userspace locks in critical parts of -an high priority thread, without losing determinism. - -The enqueueing of the waiters into the rtmutex waiter list is done in -priority order. For same priorities FIFO order is chosen. For each -rtmutex, only the top priority waiter is enqueued into the owner's -priority waiters list. This list too queues in priority order. Whenever -the top priority waiter of a task changes (for example it timed out or -got a signal), the priority of the owner task is readjusted. [The -priority enqueueing is handled by "plists", see include/linux/plist.h -for more details.] - -RT-mutexes are optimized for fastpath operations and have no internal -locking overhead when locking an uncontended mutex or unlocking a mutex -without waiters. The optimized fastpath operations require cmpxchg -support. [If that is not available then the rt-mutex internal spinlock -is used] - -The state of the rt-mutex is tracked via the owner field of the rt-mutex -structure: - -rt_mutex->owner holds the task_struct pointer of the owner. Bit 0 and 1 -are used to keep track of the "owner is pending" and "rtmutex has -waiters" state. - - owner bit1 bit0 - NULL 0 0 mutex is free (fast acquire possible) - NULL 0 1 invalid state - NULL 1 0 Transitional state* - NULL 1 1 invalid state - taskpointer 0 0 mutex is held (fast release possible) - taskpointer 0 1 task is pending owner - taskpointer 1 0 mutex is held and has waiters - taskpointer 1 1 task is pending owner and mutex has waiters - -Pending-ownership handling is a performance optimization: -pending-ownership is assigned to the first (highest priority) waiter of -the mutex, when the mutex is released. The thread is woken up and once -it starts executing it can acquire the mutex. Until the mutex is taken -by it (bit 0 is cleared) a competing higher priority thread can "steal" -the mutex which puts the woken up thread back on the waiters list. - -The pending-ownership optimization is especially important for the -uninterrupted workflow of high-prio tasks which repeatedly -takes/releases locks that have lower-prio waiters. Without this -optimization the higher-prio thread would ping-pong to the lower-prio -task [because at unlock time we always assign a new owner]. - -(*) The "mutex has waiters" bit gets set to take the lock. If the lock -doesn't already have an owner, this bit is quickly cleared if there are -no waiters. So this is a transitional state to synchronize with looking -at the owner field of the mutex and the mutex owner releasing the lock. diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt index 2a58f985795a..95d17b3e2eee 100644 --- a/trunk/Documentation/rtc.txt +++ b/trunk/Documentation/rtc.txt @@ -44,10 +44,8 @@ normal timer interrupt, which is 100Hz. Programming and/or enabling interrupt frequencies greater than 64Hz is only allowed by root. This is perhaps a bit conservative, but we don't want an evil user generating lots of IRQs on a slow 386sx-16, where it might have -a negative impact on performance. This 64Hz limit can be changed by writing -a different value to /proc/sys/dev/rtc/max-user-freq. Note that the -interrupt handler is only a few lines of code to minimize any possibility -of this effect. +a negative impact on performance. Note that the interrupt handler is only +a few lines of code to minimize any possibility of this effect. Also, if the kernel time is synchronized with an external source, the kernel will write the time back to the CMOS clock every 11 minutes. In @@ -83,7 +81,6 @@ that will be using this driver. */ #include -#include #include #include #include diff --git a/trunk/Documentation/scsi/00-INDEX b/trunk/Documentation/scsi/00-INDEX index 12354830c6b0..e7da8c3a255b 100644 --- a/trunk/Documentation/scsi/00-INDEX +++ b/trunk/Documentation/scsi/00-INDEX @@ -30,6 +30,8 @@ aic7xxx.txt - info on driver for Adaptec controllers aic7xxx_old.txt - info on driver for Adaptec controllers, old generation +cpqfc.txt + - info on driver for Compaq Tachyon TS adapters dpti.txt - info on driver for DPT SmartRAID and Adaptec I2O RAID based adapters dtc3x80.txt diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid_sas b/trunk/Documentation/scsi/ChangeLog.megaraid_sas index 0a85a7e8120e..2dafa63bd370 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid_sas +++ b/trunk/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,16 +1,3 @@ - -1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro -2 Current Version : 00.00.02.04 -3 Older Version : 00.00.02.04 - -i. Remove superflous instance_lock - - gets rid of the otherwise superflous instance_lock and avoids an unsave - unsynchronized access in the error handler. - - - Christoph Hellwig - - 1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro 2 Current Version : 00.00.02.04 3 Older Version : 00.00.02.04 diff --git a/trunk/Documentation/scsi/aacraid.txt b/trunk/Documentation/scsi/aacraid.txt index be55670851a4..820fd0793502 100644 --- a/trunk/Documentation/scsi/aacraid.txt +++ b/trunk/Documentation/scsi/aacraid.txt @@ -24,10 +24,10 @@ Supported Cards/Chipsets 9005:0285:9005:0296 Adaptec 2240S (SabreExpress) 9005:0285:9005:0290 Adaptec 2410SA (Jaguar) 9005:0285:9005:0293 Adaptec 21610SA (Corsair-16) - 9005:0285:103c:3227 Adaptec 2610SA (Bearcat HP release) + 9005:0285:103c:3227 Adaptec 2610SA (Bearcat) 9005:0285:9005:0292 Adaptec 2810SA (Corsair-8) 9005:0285:9005:0294 Adaptec Prowler - 9005:0286:9005:029d Adaptec 2420SA (Intruder HP release) + 9005:0286:9005:029d Adaptec 2420SA (Intruder) 9005:0286:9005:029c Adaptec 2620SA (Intruder) 9005:0286:9005:029b Adaptec 2820SA (Intruder) 9005:0286:9005:02a7 Adaptec 2830SA (Skyray) @@ -38,7 +38,7 @@ Supported Cards/Chipsets 9005:0285:9005:0297 Adaptec 4005SAS (AvonPark) 9005:0285:9005:0299 Adaptec 4800SAS (Marauder-X) 9005:0285:9005:029a Adaptec 4805SAS (Marauder-E) - 9005:0286:9005:02a2 Adaptec 3800SAS (Hurricane44) + 9005:0286:9005:02a2 Adaptec 4810SAS (Hurricane) 1011:0046:9005:0364 Adaptec 5400S (Mustang) 1011:0046:9005:0365 Adaptec 5400S (Mustang) 9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware) @@ -72,7 +72,7 @@ Supported Cards/Chipsets 9005:0286:9005:02a1 ICP ICP9087MA (Lancer) 9005:0286:9005:02a4 ICP ICP9085LI (Marauder-X) 9005:0286:9005:02a5 ICP ICP5085BR (Marauder-E) - 9005:0286:9005:02a3 ICP ICP5445AU (Hurricane44) + 9005:0286:9005:02a3 ICP ICP5085AU (Hurricane) 9005:0286:9005:02a6 ICP ICP9067MA (Intruder-6) 9005:0286:9005:02a9 ICP ICP5087AU (Skyray) 9005:0286:9005:02aa ICP ICP5047AU (Skyray) diff --git a/trunk/Documentation/scsi/cpqfc.txt b/trunk/Documentation/scsi/cpqfc.txt new file mode 100644 index 000000000000..dd33e61c0645 --- /dev/null +++ b/trunk/Documentation/scsi/cpqfc.txt @@ -0,0 +1,272 @@ +Notes for CPQFCTS driver for Compaq Tachyon TS +Fibre Channel Host Bus Adapter, PCI 64-bit, 66MHz +for Linux (RH 6.1, 6.2 kernel 2.2.12-32, 2.2.14-5) +SMP tested +Tested in single and dual HBA configuration, 32 and 64bit busses, +33 and 66MHz. Only supports FC-AL. +SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc() + max of 128k bytes contiguous. + +Ver 2.5.4 Oct 03, 2002 + * fixed memcpy of sense buffer in ioctl to copy the smaller defined size +Ver 2.5.3 Aug 01, 2002 + * fix the passthru ioctl to handle the Scsi_Cmnd->request being a pointer +Ver 2.5.1 Jul 30, 2002 + * fix ioctl to pay attention to the specified LUN. +Ver 2.5.0 Nov 29, 2001 + * eliminated io_request_lock. This change makes the driver specific + to the 2.5.x kernels. + * silenced excessively noisy printks. + +Ver 2.1.2 July 23, 2002 + * initialize DumCmnd->lun in cpqfcTS_ioctl (used in fcFindLoggedInPorts as LUN index) + +Ver 2.1.1 Oct 18, 2001 + * reinitialize Cmnd->SCp.sent_command (used to identify commands as + passthrus) on calling scsi_done, since the scsi mid layer does not + use (or reinitialize) this field to prevent subsequent comands from + having it set incorrectly. + +Ver 2.1.0 Aug 27, 2001 + * Revise driver to use new kernel 2.4.x PCI DMA API, instead of + virt_to_bus(). (enables driver to work w/ ia64 systems with >2Gb RAM.) + Rework main scatter-gather code to handle cases where SG element + lengths are larger than 0x7FFFF bytes and use as many scatter + gather pages as necessary. (Steve Cameron) + * Makefile changes to bring cpqfc into line w/ rest of SCSI drivers + (thanks to Keith Owens) + +Ver 2.0.5 Aug 06, 2001 + * Reject non-existent luns in the driver rather than letting the + hardware do it. (some HW behaves differently than others in this area.) + * Changed Makefile to rely on "make dep" instead of explicit dependencies + * ifdef'ed out fibre channel analyzer triggering debug code + * fixed a jiffies wrapping issue + +Ver 2.0.4 Aug 01, 2001 + * Incorporated fix for target device reset from Steeleye + * Fixed passthrough ioctl so it doesn't hang. + * Fixed hang in launch_FCworker_thread() that occurred on some machines. + * Avoid problem when number of volumes in a single cabinet > 8 + +Ver 2.0.2 July 23, 2001 + Changed the semiphore changes so the driver would compile in 2.4.7. + This version is for 2.4.7 and beyond. + +Ver 2.0.1 May 7, 2001 + Merged version 1.3.6 fixes into version 2.0.0. + +Ver 2.0.0 May 7, 2001 + Fixed problem so spinlock is being initialized to UNLOCKED. + Fixed updated driver so it compiles in the 2.4 tree. + + Ver 1.3.6 Feb 27, 2001 + Added Target_Device_Reset function for SCSI error handling + Fixed problem with not reseting addressing mode after implicit logout + + +Ver 1.3.4 Sep 7, 2000 + Added Modinfo information + Fixed problem with statically linking the driver + +Ver 1.3.3, Aug 23, 2000 + Fixed device/function number in ioctl + +Ver 1.3.2, July 27, 2000 + Add include for Alpha compile on 2.2.14 kernel (cpq*i2c.c) + Change logic for different FCP-RSP sense_buffer location for HSG80 target + And search for Agilent Tachyon XL2 HBAs (not finished! - in test) + +Tested with +(storage): + Compaq RA-4x000, RAID firmware ver 2.40 - 2.54 + Seagate FC drives model ST39102FC, rev 0006 + Hitachi DK31CJ-72FC rev J8A8 + IBM DDYF-T18350R rev F60K + Compaq FC-SCSI bridge w/ DLT 35/70 Gb DLT (tape) +(servers): + Compaq PL-1850R + Compaq PL-6500 Xeon (400MHz) + Compaq PL-8500 (500MHz, 66MHz, 64bit PCI) + Compaq Alpha DS20 (RH 6.1) +(hubs): + Vixel Rapport 1000 (7-port "dumb") + Gadzoox Gibralter (12-port "dumb") + Gadzoox Capellix 2000, 3000 +(switches): + Brocade 2010, 2400, 2800, rev 2.0.3a (& later) + Gadzoox 3210 (Fabric blade beta) + Vixel 7100 (Fabric beta firmare - known hot plug issues) +using "qa_test" (esp. io_test script) suite modified from Unix tests. + +Installation: +make menuconfig + (select SCSI low-level, Compaq FC HBA) +make modules +make modules_install + +e.g. insmod -f cpqfc + +Due to Fabric/switch delays, driver requires 4 seconds +to initialize. If adapters are found, there will be a entries at +/proc/scsi/cpqfcTS/* + +sample contents of startup messages + +************************* + scsi_register allocating 3596 bytes for CPQFCHBA + ioremap'd Membase: c887e600 + HBA Tachyon RevId 1.2 +Allocating 119808 for 576 Exchanges @ c0dc0000 +Allocating 112904 for LinkQ @ c0c20000 (576 elements) +Allocating 110600 for TachSEST for 512 Exchanges + cpqfcTS: writing IMQ BASE 7C0000h PI 7C4000h + cpqfcTS: SEST c0e40000(virt): Wrote base E40000h @ c887e740 +cpqfcTS: New FC port 0000E8h WWN: 500507650642499D SCSI Chan/Trgt 0/0 +cpqfcTS: New FC port 0000EFh WWN: 50000E100000D5A6 SCSI Chan/Trgt 0/1 +cpqfcTS: New FC port 0000E4h WWN: 21000020370097BB SCSI Chan/Trgt 0/2 +cpqfcTS: New FC port 0000E2h WWN: 2100002037009946 SCSI Chan/Trgt 0/3 +cpqfcTS: New FC port 0000E1h WWN: 21000020370098FE SCSI Chan/Trgt 0/4 +cpqfcTS: New FC port 0000E0h WWN: 21000020370097B2 SCSI Chan/Trgt 0/5 +cpqfcTS: New FC port 0000DCh WWN: 2100002037006CC1 SCSI Chan/Trgt 0/6 +cpqfcTS: New FC port 0000DAh WWN: 21000020370059F6 SCSI Chan/Trgt 0/7 +cpqfcTS: New FC port 00000Fh WWN: 500805F1FADB0E20 SCSI Chan/Trgt 0/8 +cpqfcTS: New FC port 000008h WWN: 500805F1FADB0EBA SCSI Chan/Trgt 0/9 +cpqfcTS: New FC port 000004h WWN: 500805F1FADB1EB9 SCSI Chan/Trgt 0/10 +cpqfcTS: New FC port 000002h WWN: 500805F1FADB1ADE SCSI Chan/Trgt 0/11 +cpqfcTS: New FC port 000001h WWN: 500805F1FADBA2CA SCSI Chan/Trgt 0/12 +scsi4 : Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2: WWN 500508B200193F50 + on PCI bus 0 device 0xa0fc irq 5 IObaseL 0x3400, MEMBASE 0xc6ef8600 +PCI bus width 32 bits, bus speed 33 MHz +FCP-SCSI Driver v1.3.0 +GBIC detected: Short-wave. LPSM 0h Monitor +scsi : 5 hosts. + Vendor: IBM Model: DDYF-T18350R Rev: F60K + Type: Direct-Access ANSI SCSI revision: 03 +Detected scsi disk sdb at scsi4, channel 0, id 0, lun 0 + Vendor: HITACHI Model: DK31CJ-72FC Rev: J8A8 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdc at scsi4, channel 0, id 1, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdd at scsi4, channel 0, id 2, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sde at scsi4, channel 0, id 3, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdf at scsi4, channel 0, id 4, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdg at scsi4, channel 0, id 5, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdh at scsi4, channel 0, id 6, lun 0 + Vendor: SEAGATE Model: ST39102FC Rev: 0006 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdi at scsi4, channel 0, id 7, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdj at scsi4, channel 0, id 8, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdk at scsi4, channel 0, id 8, lun 1 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdl at scsi4, channel 0, id 9, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdm at scsi4, channel 0, id 9, lun 1 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdn at scsi4, channel 0, id 10, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdo at scsi4, channel 0, id 11, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdp at scsi4, channel 0, id 11, lun 1 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdq at scsi4, channel 0, id 12, lun 0 + Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54 + Type: Direct-Access ANSI SCSI revision: 02 +Detected scsi disk sdr at scsi4, channel 0, id 12, lun 1 +resize_dma_pool: unknown device type 12 +resize_dma_pool: unknown device type 12 +SCSI device sdb: hdwr sector= 512 bytes. Sectors= 35843670 [17501 MB] [17.5 GB] + sdb: sdb1 +SCSI device sdc: hdwr sector= 512 bytes. Sectors= 144410880 [70513 MB] [70.5 GB] + sdc: sdc1 +SCSI device sdd: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sdd: sdd1 +SCSI device sde: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sde: sde1 +SCSI device sdf: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sdf: sdf1 +SCSI device sdg: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sdg: sdg1 +SCSI device sdh: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sdh: sdh1 +SCSI device sdi: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB] + sdi: sdi1 +SCSI device sdj: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB] + sdj: sdj1 +SCSI device sdk: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB] + sdk: sdk1 +SCSI device sdl: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB] + sdl: sdl1 +SCSI device sdm: hdwr sector= 512 bytes. Sectors= 8380320 [4091 MB] [4.1 GB] + sdm: sdm1 +SCSI device sdn: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB] + sdn: sdn1 +SCSI device sdo: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB] + sdo: sdo1 +SCSI device sdp: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB] + sdp: sdp1 +SCSI device sdq: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB] + sdq: sdq1 +SCSI device sdr: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB] + sdr: sdr1 + +************************* + +If a GBIC of type Short-wave, Long-wave, or Copper is detected, it will +print out; otherwise, "none" is displayed. If the cabling is correct +and a loop circuit is completed, you should see "Monitor"; otherwise, +"LoopFail" (on open circuit) or some LPSM number/state with bit 3 set. + + +ERRATA: +1. Normally, Linux Scsi queries FC devices with INQUIRY strings. All LUNs +found according to INQUIRY should get READ commands at sector 0 to find +partition table, etc. Older kernels only query the first 4 devices. Some +Linux kernels only look for one LUN per target (i.e. FC device). + +2. Physically removing a device, or a malfunctioning system which hides a +device, leads to a 30-second timeout and subsequent _abort call. +In some process contexts, this will hang the kernel (crashing the system). +Single bit errors in frames and virtually all hot plugging events are +gracefully handled with internal driver timer and Abort processing. + +3. Some SCSI drives with error conditions will not handle the 7 second timeout +in this software driver, leading to infinite retries on timed out SCSI commands. +The 7 secs balances the need to quickly recover from lost frames (esp. on sequence +initiatives) and time needed by older/slower/error-state drives in responding. +This can be easily changed in "Exchanges[].timeOut". + +4. Due to the nature of FC soft addressing, there is no assurance that the +same LUNs (drives) will have the same path (e.g. /dev/sdb1) from one boot to +next. Dynamic soft address changes (i.e. 24-bit FC port_id) are +supported during run time (e.g. due to hot plug event) by the use of WWN to +SCSI Nexus (channel/target/LUN) mapping. + +5. Compaq RA4x00 firmware version 2.54 and later supports SSP (Selective +Storage Presentation), which maps LUNs to a WWN. If RA4x00 firmware prior +2.54 (e.g. older controller) is used, or the FC HBA is replaced (another WWN +is used), logical volumes on the RA4x00 will no longer be visible. + + +Send questions/comments to: +Amy Vanzant-Hodge (fibrechannel@compaq.com) + diff --git a/trunk/Documentation/scsi/hptiop.txt b/trunk/Documentation/scsi/hptiop.txt deleted file mode 100644 index d28a31247d4c..000000000000 --- a/trunk/Documentation/scsi/hptiop.txt +++ /dev/null @@ -1,92 +0,0 @@ -HIGHPOINT ROCKETRAID 3xxx RAID DRIVER (hptiop) - -Controller Register Map -------------------------- - -The controller IOP is accessed via PCI BAR0. - - BAR0 offset Register - 0x10 Inbound Message Register 0 - 0x14 Inbound Message Register 1 - 0x18 Outbound Message Register 0 - 0x1C Outbound Message Register 1 - 0x20 Inbound Doorbell Register - 0x24 Inbound Interrupt Status Register - 0x28 Inbound Interrupt Mask Register - 0x30 Outbound Interrupt Status Register - 0x34 Outbound Interrupt Mask Register - 0x40 Inbound Queue Port - 0x44 Outbound Queue Port - - -I/O Request Workflow ----------------------- - -All queued requests are handled via inbound/outbound queue port. -A request packet can be allocated in either IOP or host memory. - -To send a request to the controller: - - - Get a free request packet by reading the inbound queue port or - allocate a free request in host DMA coherent memory. - - The value returned from the inbound queue port is an offset - relative to the IOP BAR0. - - Requests allocated in host memory must be aligned on 32-bytes boundary. - - - Fill the packet. - - - Post the packet to IOP by writing it to inbound queue. For requests - allocated in IOP memory, write the offset to inbound queue port. For - requests allocated in host memory, write (0x80000000|(bus_addr>>5)) - to the inbound queue port. - - - The IOP process the request. When the request is completed, it - will be put into outbound queue. An outbound interrupt will be - generated. - - For requests allocated in IOP memory, the request offset is posted to - outbound queue. - - For requests allocated in host memory, (0x80000000|(bus_addr>>5)) - is posted to the outbound queue. If IOP_REQUEST_FLAG_OUTPUT_CONTEXT - flag is set in the request, the low 32-bit context value will be - posted instead. - - - The host read the outbound queue and complete the request. - - For requests allocated in IOP memory, the host driver free the request - by writing it to the outbound queue. - -Non-queued requests (reset/flush etc) can be sent via inbound message -register 0. An outbound message with the same value indicates the completion -of an inbound message. - - -User-level Interface ---------------------- - -The driver exposes following sysfs attributes: - - NAME R/W Description - driver-version R driver version string - firmware-version R firmware version string - -The driver registers char device "hptiop" to communicate with HighPoint RAID -management software. Its ioctl routine acts as a general binary interface -between the IOP firmware and HighPoint RAID management software. New management -functions can be implemented in application/firmware without modification -in driver code. - - ------------------------------------------------------------------------------ -Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - linux@highpoint-tech.com - http://www.highpoint-tech.com diff --git a/trunk/Documentation/scsi/ppa.txt b/trunk/Documentation/scsi/ppa.txt index 5d9223bc1bd5..0dac88d86d87 100644 --- a/trunk/Documentation/scsi/ppa.txt +++ b/trunk/Documentation/scsi/ppa.txt @@ -12,3 +12,5 @@ http://www.torque.net/parport/ Email list for Linux Parport linux-parport@torque.net +Email for problems with ZIP or ZIP Plus drivers +campbell@torque.net diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 87d76a5c73d0..0ee2c7dfc482 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -366,9 +366,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for C-Media CMI8338 and 8738 PCI sound cards. - mpu_port - 0x300,0x310,0x320,0x330 = legacy port, - 1 = integrated PCI port, - 0 = disable (default) + mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default) fm_port - 0x388 (default), 0 = disable (default) soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only) (default = 1) @@ -470,7 +468,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for multifunction CS5535 companion PCI device - The power-management is supported. + This module supports multiple cards. Module snd-dt019x ----------------- @@ -709,10 +707,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-hda-intel -------------------- - Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8), - ATI SB450, SB600, RS600, - VIA VT8251/VT8237A, - SIS966, ULI M5461 + Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450, + VIA VT8251/VT8237A model - force the model name position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) @@ -782,7 +778,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. AD1981 basic 3-jack (default) hp HP nx6320 - thinkpad Lenovo Thinkpad T60/X60/Z60 AD1986A 6stack 6-jack, separate surrounds (default) @@ -1638,7 +1633,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. About capture IBL, see the description of snd-vx222 module. - Note: snd-vxp440 driver is merged to snd-vxpocket driver since + Note: the driver is build only when CONFIG_ISA is set. + + Note2: snd-vxp440 driver is merged to snd-vxpocket driver since ALSA 1.0.10. The power-management is supported. @@ -1665,6 +1662,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Sound Core PDAudioCF sound card. + Note: the driver is build only when CONFIG_ISA is set. + The power-management is supported. diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 635cbb94357c..1faf76383bab 100644 --- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -4215,7 +4215,7 @@ struct _snd_pcm_runtime { @@ -4242,36 +4242,15 @@ struct _snd_pcm_runtime { - The 5th argument is bitflags for additional information. When the i/o port address above is a part of the PCI i/o region, the MPU401 i/o port might have been already allocated - (reserved) by the driver itself. In such a case, pass a bit flag - MPU401_INFO_INTEGRATED, + (reserved) by the driver itself. In such a case, pass non-zero + to the 5th argument + (integrated). Otherwise, pass 0 to it, and the mpu401-uart layer will allocate the i/o ports by itself. - - When the controller supports only the input or output MIDI stream, - pass MPU401_INFO_INPUT or - MPU401_INFO_OUTPUT bitflag, respectively. - Then the rawmidi instance is created as a single stream. - - - - MPU401_INFO_MMIO bitflag is used to change - the access method to MMIO (via readb and writeb) instead of - iob and outb. In this case, you have to pass the iomapped address - to snd_mpu401_uart_new(). - - - - When MPU401_INFO_TX_IRQ is set, the output - stream isn't checked in the default interrupt handler. The driver - needs to call snd_mpu401_uart_interrupt_tx() - by itself to start processing the output stream in irq handler. - - Usually, the port address corresponds to the command port and port + 1 corresponds to the data port. If not, you may change @@ -5354,7 +5333,7 @@ struct _snd_pcm_runtime { @@ -5415,12 +5394,29 @@ struct _snd_pcm_runtime { c.text.write_size = 256; entry->c.text.write = my_proc_write; ]]> + + The buffer size for read is set to 1024 implicitly by + snd_info_set_text_ops(). It should suffice + in most cases (the size will be aligned to + PAGE_SIZE anyway), but if you need to handle + very large text files, you can set it explicitly, too. + + + +c.text.read_size = 65536; +]]> + + + + For the write callback, you can use snd_info_get_line() to get a text line, and @@ -5566,7 +5562,7 @@ struct _snd_pcm_runtime { power status. Call snd_pcm_suspend_all() to suspend the running PCM streams. If AC97 codecs are used, call - snd_ac97_suspend() for each codec. + snd_ac97_resume() for each codec. Save the register values if necessary. Stop the hardware if necessary. Disable the PCI device by calling diff --git a/trunk/Documentation/sparc/sbus_drivers.txt b/trunk/Documentation/sparc/sbus_drivers.txt index 4b9351624f13..876195dc2aef 100644 --- a/trunk/Documentation/sparc/sbus_drivers.txt +++ b/trunk/Documentation/sparc/sbus_drivers.txt @@ -25,84 +25,42 @@ the bits necessary to run your device. The most commonly used members of this structure, and their typical usage, will be detailed below. - Here is a piece of skeleton code for perofming a device -probe in an SBUS driverunder Linux: + Here is how probing is performed by an SBUS driver +under Linux: - static int __devinit mydevice_probe_one(struct sbus_dev *sdev) + static void init_one_mydevice(struct sbus_dev *sdev) { - struct mysdevice *mp = kzalloc(sizeof(*mp), GFP_KERNEL); - - if (!mp) - return -ENODEV; - - ... - dev_set_drvdata(&sdev->ofdev.dev, mp); - return 0; ... } - static int __devinit mydevice_probe(struct of_device *dev, - const struct of_device_id *match) + static int mydevice_match(struct sbus_dev *sdev) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - return mydevice_probe_one(sdev); + if (some_criteria(sdev)) + return 1; + return 0; } - static int __devexit mydevice_remove(struct of_device *dev) + static void mydevice_probe(void) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct mydevice *mp = dev_get_drvdata(&dev->dev); - - return mydevice_remove_one(sdev, mp); - } - - static struct of_device_id mydevice_match[] = { - { - .name = "mydevice", - }, - {}, - }; - - MODULE_DEVICE_TABLE(of, mydevice_match); - - static struct of_platform_driver mydevice_driver = { - .name = "mydevice", - .match_table = mydevice_match, - .probe = mydevice_probe, - .remove = __devexit_p(mydevice_remove), - }; - - static int __init mydevice_init(void) - { - return of_register_driver(&mydevice_driver, &sbus_bus_type); - } + struct sbus_bus *sbus; + struct sbus_dev *sdev; - static void __exit mydevice_exit(void) - { - of_unregister_driver(&mydevice_driver); + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if (mydevice_match(sdev)) + init_one_mydevice(sdev); + } + } } - module_init(mydevice_init); - module_exit(mydevice_exit); - - The mydevice_match table is a series of entries which -describes what SBUS devices your driver is meant for. In the -simplest case you specify a string for the 'name' field. Every -SBUS device with a 'name' property matching your string will -be passed one-by-one to your .probe method. - - You should store away your device private state structure -pointer in the drvdata area so that you can retrieve it later on -in your .remove method. + All this does is walk through all SBUS devices in the +system, checks each to see if it is of the type which +your driver is written for, and if so it calls the init +routine to attach the device and prepare to drive it. - Any memory allocated, registers mapped, IRQs registered, -etc. must be undone by your .remove method so that all resources -of your device are relased by the time it returns. - - You should _NOT_ use the for_each_sbus(), for_each_sbusdev(), -and for_all_sbusdev() interfaces. They are deprecated, will be -removed, and no new driver should reference them ever. + "init_one_mydevice" might do things like allocate software +state structures, map in I/O registers, place the hardware +into an initialized state, etc. Mapping and Accessing I/O Registers @@ -305,3 +263,10 @@ discussed above and plus it handles both PCI and SBUS boards. Lance driver abuses consistent mappings for data transfer. It is a nifty trick which we do not particularly recommend... Just check it out and know that it's legal. + + Bad examples, do NOT use + + drivers/video/cgsix.c + This one uses result of sbus_ioremap as if it is an address. +This does NOT work on sparc64 and therefore is broken. We will +convert it at a later date. diff --git a/trunk/Documentation/sparse.txt b/trunk/Documentation/sparse.txt index 5a311c38dd1a..3f1c5464b1c9 100644 --- a/trunk/Documentation/sparse.txt +++ b/trunk/Documentation/sparse.txt @@ -1,6 +1,5 @@ Copyright 2004 Linus Torvalds Copyright 2004 Pavel Machek -Copyright 2006 Bob Copeland Using sparse for typechecking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -42,8 +41,15 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian vs cpu-endian vs whatever), and there the constant "0" really _is_ special. -Getting sparse -~~~~~~~~~~~~~~ +Use + + make C=[12] CF=-Wbitwise + +or you don't get any checking at all. + + +Where to get sparse +~~~~~~~~~~~~~~~~~~~ With git, you can just get it from @@ -51,7 +57,7 @@ With git, you can just get it from and DaveJ has tar-balls at - http://www.codemonkey.org.uk/projects/git-snapshots/sparse/ + http://www.codemonkey.org.uk/projects/git-snapshots/sparse/ Once you have it, just do @@ -59,20 +65,8 @@ Once you have it, just do make make install -as a regular user, and it will install sparse in your ~/bin directory. - -Using sparse -~~~~~~~~~~~~ - -Do a kernel make with "make C=1" to run sparse on all the C files that get -recompiled, or use "make C=2" to run sparse on the files whether they need to -be recompiled or not. The latter is a fast way to check the whole tree if you -have already built it. - -The optional make variable CF can be used to pass arguments to sparse. The -build system passes -Wbitwise to sparse automatically. To perform endianness -checks, you may define __CHECK_ENDIAN__: - - make C=2 CF="-D__CHECK_ENDIAN__" - -These checks are disabled by default as they generate a host of warnings. +as your regular user, and it will install sparse in your ~/bin directory. +After that, doing a kernel make with "make C=1" will run sparse on all the +C files that get recompiled, or with "make C=2" will run sparse on the +files whether they need to be recompiled or not (ie the latter is fast way +to check the whole tree if you have already built it). diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index 2dc246af4885..a46c10fcddfc 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -29,7 +29,6 @@ Currently, these files are in /proc/sys/vm: - drop-caches - zone_reclaim_mode - zone_reclaim_interval -- panic_on_oom ============================================================== @@ -179,15 +178,3 @@ Time is set in seconds and set by default to 30 seconds. Reduce the interval if undesired off node allocations occur. However, too frequent scans will have a negative impact onoff node allocation performance. -============================================================= - -panic_on_oom - -This enables or disables panic on out-of-memory feature. If this is set to 1, -the kernel panics when out-of-memory happens. If this is set to 0, the kernel -will kill some rogue process, called oom_killer. Usually, oom_killer can kill -rogue processes and system will survive. If you want to panic the system -rather than killing rogue processes, set this to 1. - -The default value is 0. - diff --git a/trunk/Documentation/sysrq.txt b/trunk/Documentation/sysrq.txt index e0188a23fd5e..ad0bedf678b3 100644 --- a/trunk/Documentation/sysrq.txt +++ b/trunk/Documentation/sysrq.txt @@ -115,9 +115,8 @@ trojan program is running at console and which could grab your password when you would try to login. It will kill all programs on given console and thus letting you make sure that the login prompt you see is actually the one from init, not some trojan program. -IMPORTANT: In its true form it is not a true SAK like the one in a :IMPORTANT -IMPORTANT: c2 compliant system, and it should not be mistaken as :IMPORTANT -IMPORTANT: such. :IMPORTANT +IMPORTANT:In its true form it is not a true SAK like the one in :IMPORTANT +IMPORTANT:c2 compliant systems, and it should be mistook as such. :IMPORTANT It seems other find it useful as (System Attention Key) which is useful when you want to exit a program that will not let you switch consoles. (For example, X or a svgalib program.) diff --git a/trunk/Documentation/tty.txt b/trunk/Documentation/tty.txt index dab56604745d..8ff7bc2a0811 100644 --- a/trunk/Documentation/tty.txt +++ b/trunk/Documentation/tty.txt @@ -80,6 +80,13 @@ receive_buf() - Hand buffers of bytes from the driver to the ldisc for processing. Semantics currently rather mysterious 8( +receive_room() - Can be called by the driver layer at any time when + the ldisc is opened. The ldisc must be able to + handle the reported amount of data at that instant. + Synchronization between active receive_buf and + receive_room calls is down to the driver not the + ldisc. Must not sleep. + write_wakeup() - May be called at any point between open and close. The TTY_DO_WRITE_WAKEUP flag indicates if a call is needed but always races versus calls. Thus the diff --git a/trunk/Documentation/usb/usbmon.txt b/trunk/Documentation/usb/usbmon.txt index e65ec828d7aa..63cb7edd177e 100644 --- a/trunk/Documentation/usb/usbmon.txt +++ b/trunk/Documentation/usb/usbmon.txt @@ -29,13 +29,14 @@ if usbmon is built into the kernel. # mount -t debugfs none_debugs /sys/kernel/debug # modprobe usbmon -# Verify that bus sockets are present. -# ls /sys/kernel/debug/usbmon +[root@lembas zaitcev]# ls /sys/kernel/debug/usbmon 1s 1t 2s 2t 3s 3t 4s 4t -# +[root@lembas zaitcev]# + +# ls /sys/kernel 2. Find which bus connects to the desired device @@ -75,7 +76,7 @@ that the file size is not excessive for your favourite editor. * Raw text data format -The '1t' type data consists of a stream of events, such as URB submission, +The '0t' type data consists of a stream of events, such as URB submission, URB callback, submission error. Every event is a text line, which consists of whitespace separated words. The number of position of words may depend on the event type, but there is a set of words, common for all types. @@ -96,25 +97,20 @@ Here is the list of words, from left to right: Zi Zo Isochronous input and output Ii Io Interrupt input and output Bi Bo Bulk input and output - Device address and Endpoint number are 3-digit and 2-digit (respectively) - decimal numbers, with leading zeroes. -- URB Status. In most cases, this field contains a number, sometimes negative, - which represents a "status" field of the URB. This field makes no sense for - submissions, but is present anyway to help scripts with parsing. When an - error occurs, the field contains the error code. In case of a submission of - a Control packet, this field contains a Setup Tag instead of an error code. - It is easy to tell whether the Setup Tag is present because it is never a - number. Thus if scripts find a number in this field, they proceed to read - Data Length. If they find something else, like a letter, they read the setup - packet before reading the Data Length. + Device address and Endpoint number are decimal numbers with leading zeroes + or 3 and 2 positions, correspondingly. +- URB Status. This field makes no sense for submissions, but is present + to help scripts with parsing. In error case, it contains the error code. + In case of a setup packet, it contains a Setup Tag. If scripts read a number + in this field, they proceed to read Data Length. Otherwise, they read + the setup packet before reading the Data Length. - Setup packet, if present, consists of 5 words: one of each for bmRequestType, bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. These words are safe to decode if Setup Tag was 's'. Otherwise, the setup packet was present, but not captured, and the fields contain filler. -- Data Length. For submissions, this is the requested length. For callbacks, - this is the actual length. +- Data Length. This is the actual length in the URB. - Data tag. The usbmon may not always capture data, even if length is nonzero. - The data words are present only if this tag is '='. + Only if tag is '=', the data words are present. - Data words follow, in big endian hexadecimal format. Notice that they are not machine words, but really just a byte stream split into words to make it easier to read. Thus, the last word may contain from one to four bytes. diff --git a/trunk/Documentation/video4linux/CARDLIST.bttv b/trunk/Documentation/video4linux/CARDLIST.bttv index 4efa4645885f..b72706c58a44 100644 --- a/trunk/Documentation/video4linux/CARDLIST.bttv +++ b/trunk/Documentation/video4linux/CARDLIST.bttv @@ -87,7 +87,7 @@ 86 -> Osprey 101/151 w/ svid 87 -> Osprey 200/201/250/251 88 -> Osprey 200/250 [0070:ff01] - 89 -> Osprey 210/220/230 + 89 -> Osprey 210/220 90 -> Osprey 500 [0070:ff02] 91 -> Osprey 540 [0070:ff04] 92 -> Osprey 2000 [0070:ff03] @@ -111,7 +111,7 @@ 110 -> IVC-100 [ff00:a132] 111 -> IVC-120G [ff00:a182,ff01:a182,ff02:a182,ff03:a182,ff04:a182,ff05:a182,ff06:a182,ff07:a182,ff08:a182,ff09:a182,ff0a:a182,ff0b:a182,ff0c:a182,ff0d:a182,ff0e:a182,ff0f:a182] 112 -> pcHDTV HD-2000 TV [7063:2000] -113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00,1822:0026] +113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00] 114 -> Winfast VC100 [107d:6607] 115 -> Teppro TEV-560/InterVision IV-560 116 -> SIMUS GVC1100 [aa6a:82b2] diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 6cb63ddf6163..3b39a91b24bd 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -15,7 +15,7 @@ 14 -> KWorld/VStream XPert DVB-T [17de:08a6] 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] 16 -> KWorld LTV883RF - 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810,18ac:d800] + 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810] 18 -> Hauppauge Nova-T DVB-T [0070:9002,0070:9001] 19 -> Conexant DVB-T reference design [14f1:0187] 20 -> Provideo PV259 [1540:2580] @@ -40,13 +40,8 @@ 39 -> KWorld DVB-S 100 [17de:08b2] 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] - 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025,1822:0019] + 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] 45 -> KWorld HardwareMpegTV XPert [17de:0840] 46 -> DViCO FusionHDTV DVB-T Hybrid [18ac:db40,18ac:db44] - 47 -> pcHDTV HD5500 HDTV [7063:5500] - 48 -> Kworld MCE 200 Deluxe [17de:0841] - 49 -> PixelView PlayTV P7000 [1554:4813] - 50 -> NPG Tech Real TV FM Top 10 [14f1:0842] - 51 -> WinFast DTV2000 H [107d:665e] diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index 9068b669f5ee..bca50903233f 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -93,4 +93,3 @@ 92 -> AVerMedia A169 B1 [1461:6360] 93 -> Medion 7134 Bridge #2 [16be:0005] 94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502] - 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner index 44134f04b82a..1bcdac67dd8c 100644 --- a/trunk/Documentation/video4linux/CARDLIST.tuner +++ b/trunk/Documentation/video4linux/CARDLIST.tuner @@ -62,7 +62,7 @@ tuner=60 - Thomson DTT 761X (ATSC/NTSC) tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF tuner=62 - Philips TEA5767HN FM Radio tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner -tuner=64 - LG TDVS-H06xF +tuner=64 - LG TDVS-H062F/TUA6034 tuner=65 - Ymec TVF66T5-B/DFF tuner=66 - LG TALN series tuner=67 - Philips TD1316 Hybrid Tuner @@ -71,4 +71,3 @@ tuner=69 - Tena TNF 5335 and similar models tuner=70 - Samsung TCPN 2121P30A tuner=71 - Xceive xc3028 tuner=72 - Thomson FE6600 -tuner=73 - Samsung TCPG 6121P30A diff --git a/trunk/Documentation/video4linux/CQcam.txt b/trunk/Documentation/video4linux/CQcam.txt index ade8651e2443..464e4cec94cb 100644 --- a/trunk/Documentation/video4linux/CQcam.txt +++ b/trunk/Documentation/video4linux/CQcam.txt @@ -185,10 +185,207 @@ this work is documented at the video4linux2 site listed below. 9.0 --- A sample program using v4lgrabber, -v4lgrab is a simple image grabber that will copy a frame from the +This program is a simple image grabber that will copy a frame from the first video device, /dev/video0 to standard output in portable pixmap -format (.ppm) To produce .jpg output, you can use it like this: -'v4lgrab | convert - c-qcam.jpg' +format (.ppm) Using this like: 'v4lgrab | convert - c-qcam.jpg' +produced this picture of me at + http://mug.sys.virginia.edu/~drf5n/extras/c-qcam.jpg + +-------------------- 8< ---------------- 8< ----------------------------- + +/* Simple Video4Linux image grabber. */ +/* + * Video4Linux Driver Test/Example Framegrabbing Program + * + * Compile with: + * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab + * Use as: + * v4lgrab >image.ppm + * + * Copyright (C) 1998-05-03, Phil Blundell + * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c + * with minor modifications (Dave Forrest, drf5n@virginia.edu). + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define FILE "/dev/video0" + +/* Stole this from tvset.c */ + +#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ +{ \ + switch (format) \ + { \ + case VIDEO_PALETTE_GREY: \ + switch (depth) \ + { \ + case 4: \ + case 6: \ + case 8: \ + (r) = (g) = (b) = (*buf++ << 8);\ + break; \ + \ + case 16: \ + (r) = (g) = (b) = \ + *((unsigned short *) buf); \ + buf += 2; \ + break; \ + } \ + break; \ + \ + \ + case VIDEO_PALETTE_RGB565: \ + { \ + unsigned short tmp = *(unsigned short *)buf; \ + (r) = tmp&0xF800; \ + (g) = (tmp<<5)&0xFC00; \ + (b) = (tmp<<11)&0xF800; \ + buf += 2; \ + } \ + break; \ + \ + case VIDEO_PALETTE_RGB555: \ + (r) = (buf[0]&0xF8)<<8; \ + (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ + (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ + buf += 2; \ + break; \ + \ + case VIDEO_PALETTE_RGB24: \ + (r) = buf[0] << 8; (g) = buf[1] << 8; \ + (b) = buf[2] << 8; \ + buf += 3; \ + break; \ + \ + default: \ + fprintf(stderr, \ + "Format %d not yet supported\n", \ + format); \ + } \ +} + +int get_brightness_adj(unsigned char *image, long size, int *brightness) { + long i, tot = 0; + for (i=0;i= 126 && (tot/(size*3)) <= 130); +} + +int main(int argc, char ** argv) +{ + int fd = open(FILE, O_RDONLY), f; + struct video_capability cap; + struct video_window win; + struct video_picture vpic; + + unsigned char *buffer, *src; + int bpp = 24, r, g, b; + unsigned int i, src_depth; + + if (fd < 0) { + perror(FILE); + exit(1); + } + + if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { + perror("VIDIOGCAP"); + fprintf(stderr, "(" FILE " not a video4linux device?)\n"); + close(fd); + exit(1); + } + + if (ioctl(fd, VIDIOCGWIN, &win) < 0) { + perror("VIDIOCGWIN"); + close(fd); + exit(1); + } + + if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) { + perror("VIDIOCGPICT"); + close(fd); + exit(1); + } + + if (cap.type & VID_TYPE_MONOCHROME) { + vpic.depth=8; + vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */ + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.depth=6; + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.depth=4; + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + close(fd); + exit(1); + } + } + } + } else { + vpic.depth=24; + vpic.palette=VIDEO_PALETTE_RGB24; + + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.palette=VIDEO_PALETTE_RGB565; + vpic.depth=16; + + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + vpic.palette=VIDEO_PALETTE_RGB555; + vpic.depth=15; + + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + return -1; + } + } + } + } + + buffer = malloc(win.width * win.height * bpp); + if (!buffer) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + do { + int newbright; + read(fd, buffer, win.width * win.height * bpp); + f = get_brightness_adj(buffer, win.width * win.height, &newbright); + if (f) { + vpic.brightness += (newbright << 8); + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + perror("VIDIOSPICT"); + break; + } + } + } while (f); + + fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height); + + src = buffer; + + for (i = 0; i < win.width * win.height; i++) { + READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b); + fputc(r>>8, stdout); + fputc(g>>8, stdout); + fputc(b>>8, stdout); + } + + close(fd); + return 0; +} +-------------------- 8< ---------------- 8< ----------------------------- 10.0 --- Other Information diff --git a/trunk/Documentation/video4linux/README.pvrusb2 b/trunk/Documentation/video4linux/README.pvrusb2 deleted file mode 100644 index c73a32c34528..000000000000 --- a/trunk/Documentation/video4linux/README.pvrusb2 +++ /dev/null @@ -1,212 +0,0 @@ - -$Id$ -Mike Isely - - pvrusb2 driver - -Background: - - This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which - is a USB 2.0 hosted TV Tuner. This driver is a work in progress. - Its history started with the reverse-engineering effort by Björn - Danielsson whose web page can be found here: - - http://pvrusb2.dax.nu/ - - From there Aurelien Alleaume began an effort to - create a video4linux compatible driver. I began with Aurelien's - last known snapshot and evolved the driver to the state it is in - here. - - More information on this driver can be found at: - - http://www.isely.net/pvrusb2.html - - - This driver has a strong separation of layers. They are very - roughly: - - 1a. Low level wire-protocol implementation with the device. - - 1b. I2C adaptor implementation and corresponding I2C client drivers - implemented elsewhere in V4L. - - 1c. High level hardware driver implementation which coordinates all - activities that ensure correct operation of the device. - - 2. A "context" layer which manages instancing of driver, setup, - tear-down, arbitration, and interaction with high level - interfaces appropriately as devices are hotplugged in the - system. - - 3. High level interfaces which glue the driver to various published - Linux APIs (V4L, sysfs, maybe DVB in the future). - - The most important shearing layer is between the top 2 layers. A - lot of work went into the driver to ensure that any kind of - conceivable API can be laid on top of the core driver. (Yes, the - driver internally leverages V4L to do its work but that really has - nothing to do with the API published by the driver to the outside - world.) The architecture allows for different APIs to - simultaneously access the driver. I have a strong sense of fairness - about APIs and also feel that it is a good design principle to keep - implementation and interface isolated from each other. Thus while - right now the V4L high level interface is the most complete, the - sysfs high level interface will work equally well for similar - functions, and there's no reason I see right now why it shouldn't be - possible to produce a DVB high level interface that can sit right - alongside V4L. - - NOTE: Complete documentation on the pvrusb2 driver is contained in - the html files within the doc directory; these are exactly the same - as what is on the web site at the time. Browse those files - (especially the FAQ) before asking questions. - - -Building - - To build these modules essentially amounts to just running "Make", - but you need the kernel source tree nearby and you will likely also - want to set a few controlling environment variables first in order - to link things up with that source tree. Please see the Makefile - here for comments that explain how to do that. - - -Source file list / functional overview: - - (Note: The term "module" used below generally refers to loosely - defined functional units within the pvrusb2 driver and bears no - relation to the Linux kernel's concept of a loadable module.) - - pvrusb2-audio.[ch] - This is glue logic that resides between this - driver and the msp3400.ko I2C client driver (which is found - elsewhere in V4L). - - pvrusb2-context.[ch] - This module implements the context for an - instance of the driver. Everything else eventually ties back to - or is otherwise instanced within the data structures implemented - here. Hotplugging is ultimately coordinated here. All high level - interfaces tie into the driver through this module. This module - helps arbitrate each interface's access to the actual driver core, - and is designed to allow concurrent access through multiple - instances of multiple interfaces (thus you can for example change - the tuner's frequency through sysfs while simultaneously streaming - video through V4L out to an instance of mplayer). - - pvrusb2-debug.h - This header defines a printk() wrapper and a mask - of debugging bit definitions for the various kinds of debug - messages that can be enabled within the driver. - - pvrusb2-debugifc.[ch] - This module implements a crude command line - oriented debug interface into the driver. Aside from being part - of the process for implementing manual firmware extraction (see - the pvrusb2 web site mentioned earlier), probably I'm the only one - who has ever used this. It is mainly a debugging aid. - - pvrusb2-eeprom.[ch] - This is glue logic that resides between this - driver the tveeprom.ko module, which is itself implemented - elsewhere in V4L. - - pvrusb2-encoder.[ch] - This module implements all protocol needed to - interact with the Conexant mpeg2 encoder chip within the pvrusb2 - device. It is a crude echo of corresponding logic in ivtv, - however the design goals (strict isolation) and physical layer - (proxy through USB instead of PCI) are enough different that this - implementation had to be completely different. - - pvrusb2-hdw-internal.h - This header defines the core data structure - in the driver used to track ALL internal state related to control - of the hardware. Nobody outside of the core hardware-handling - modules should have any business using this header. All external - access to the driver should be through one of the high level - interfaces (e.g. V4L, sysfs, etc), and in fact even those high - level interfaces are restricted to the API defined in - pvrusb2-hdw.h and NOT this header. - - pvrusb2-hdw.h - This header defines the full internal API for - controlling the hardware. High level interfaces (e.g. V4L, sysfs) - will work through here. - - pvrusb2-hdw.c - This module implements all the various bits of logic - that handle overall control of a specific pvrusb2 device. - (Policy, instantiation, and arbitration of pvrusb2 devices fall - within the jurisdiction of pvrusb-context not here). - - pvrusb2-i2c-chips-*.c - These modules implement the glue logic to - tie together and configure various I2C modules as they attach to - the I2C bus. There are two versions of this file. The "v4l2" - version is intended to be used in-tree alongside V4L, where we - implement just the logic that makes sense for a pure V4L - environment. The "all" version is intended for use outside of - V4L, where we might encounter other possibly "challenging" modules - from ivtv or older kernel snapshots (or even the support modules - in the standalone snapshot). - - pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1 - compatible commands to the I2C modules. It is here where state - changes inside the pvrusb2 driver are translated into V4L1 - commands that are in turn send to the various I2C modules. - - pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2 - compatible commands to the I2C modules. It is here where state - changes inside the pvrusb2 driver are translated into V4L2 - commands that are in turn send to the various I2C modules. - - pvrusb2-i2c-core.[ch] - This module provides an implementation of a - kernel-friendly I2C adaptor driver, through which other external - I2C client drivers (e.g. msp3400, tuner, lirc) may connect and - operate corresponding chips within the the pvrusb2 device. It is - through here that other V4L modules can reach into this driver to - operate specific pieces (and those modules are in turn driven by - glue logic which is coordinated by pvrusb2-hdw, doled out by - pvrusb2-context, and then ultimately made available to users - through one of the high level interfaces). - - pvrusb2-io.[ch] - This module implements a very low level ring of - transfer buffers, required in order to stream data from the - device. This module is *very* low level. It only operates the - buffers and makes no attempt to define any policy or mechanism for - how such buffers might be used. - - pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch] - to provide a streaming API usable by a read() system call style of - I/O. Right now this is the only layer on top of pvrusb2-io.[ch], - however the underlying architecture here was intended to allow for - other styles of I/O to be implemented with additonal modules, like - mmap()'ed buffers or something even more exotic. - - pvrusb2-main.c - This is the top level of the driver. Module level - and USB core entry points are here. This is our "main". - - pvrusb2-sysfs.[ch] - This is the high level interface which ties the - pvrusb2 driver into sysfs. Through this interface you can do - everything with the driver except actually stream data. - - pvrusb2-tuner.[ch] - This is glue logic that resides between this - driver and the tuner.ko I2C client driver (which is found - elsewhere in V4L). - - pvrusb2-util.h - This header defines some common macros used - throughout the driver. These macros are not really specific to - the driver, but they had to go somewhere. - - pvrusb2-v4l2.[ch] - This is the high level interface which ties the - pvrusb2 driver into video4linux. It is through here that V4L - applications can open and operate the driver in the usual V4L - ways. Note that **ALL** V4L functionality is published only - through here and nowhere else. - - pvrusb2-video-*.[ch] - This is glue logic that resides between this - driver and the saa711x.ko I2C client driver (which is found - elsewhere in V4L). Note that saa711x.ko used to be known as - saa7115.ko in ivtv. There are two versions of this; one is - selected depending on the particular saa711[5x].ko that is found. - - pvrusb2.h - This header contains compile time tunable parameters - (and at the moment the driver has very little that needs to be - tuned). - - - -Mike Isely - isely@pobox.com - diff --git a/trunk/Documentation/video4linux/Zoran b/trunk/Documentation/video4linux/Zoran index 040a2c841ae9..be9f21b84555 100644 --- a/trunk/Documentation/video4linux/Zoran +++ b/trunk/Documentation/video4linux/Zoran @@ -33,21 +33,6 @@ Inputs/outputs: Composite and S-video Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) Card number: 7 -AverMedia 6 Eyes AVS6EYES: -* Zoran zr36067 PCI controller -* Zoran zr36060 MJPEG codec -* Samsung ks0127 TV decoder -* Conexant bt866 TV encoder -Drivers to use: videodev, i2c-core, i2c-algo-bit, - videocodec, ks0127, bt866, zr36060, zr36067 -Inputs/outputs: Six physical inputs. 1-6 are composite, - 1-2, 3-4, 5-6 doubles as S-video, - 1-3 triples as component. - One composite output. -Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) -Card number: 8 -Not autodetected, card=8 is necessary. - Linux Media Labs LML33: * Zoran zr36067 PCI controller * Zoran zr36060 MJPEG codec @@ -207,10 +192,6 @@ Micronas vpx3220a TV decoder was introduced in 1996, is used in the DC30 and DC30+ and can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC 44, PAL 60, SECAM,NTSC Comb -Samsung ks0127 TV decoder -is used in the AVS6EYES card and -can handle: NTSC-M/N/44, PAL-M/N/B/G/H/I/D/K/L and SECAM - =========================== 1.2 What the TV encoder can do an what not @@ -240,10 +221,6 @@ ITT mse3000 TV encoder was introduced in 1991, is used in the DC10 old can generate: PAL , NTSC , SECAM -Conexant bt866 TV encoder -is used in AVS6EYES, and -can generate: NTSC/PAL, PAL­M, PAL­N - The adv717x, should be able to produce PAL N. But you find nothing PAL N specific in the registers. Seem that you have to reuse a other standard to generate PAL N, maybe it would work if you use the PAL M settings. diff --git a/trunk/Documentation/video4linux/bttv/CONTRIBUTORS b/trunk/Documentation/video4linux/bttv/CONTRIBUTORS index 8aad6dd93d6b..aef49db8847d 100644 --- a/trunk/Documentation/video4linux/bttv/CONTRIBUTORS +++ b/trunk/Documentation/video4linux/bttv/CONTRIBUTORS @@ -1,4 +1,4 @@ -Contributors to bttv: +Contributors to bttv: Michael Chu AverMedia fix and more flexible card recognition @@ -8,8 +8,8 @@ Alan Cox Chris Kleitsch Hardware I2C - -Gerd Knorr + +Gerd Knorr Radio card (ITT sound processor) bigfoot @@ -18,7 +18,7 @@ Ragnar Hojland Espinosa + many more (please mail me if you are missing in this list and would - like to be mentioned) + like to be mentioned) diff --git a/trunk/Documentation/video4linux/cx2341x/fw-calling.txt b/trunk/Documentation/video4linux/cx2341x/fw-calling.txt deleted file mode 100644 index 8d21181de537..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-calling.txt +++ /dev/null @@ -1,69 +0,0 @@ -This page describes how to make calls to the firmware api. - -How to call -=========== - -The preferred calling convention is known as the firmware mailbox. The -mailboxes are basically a fixed length array that serves as the call-stack. - -Firmware mailboxes can be located by searching the encoder and decoder memory -for a 16 byte signature. That signature will be located on a 256-byte boundary. - -Signature: -0x78, 0x56, 0x34, 0x12, 0x12, 0x78, 0x56, 0x34, -0x34, 0x12, 0x78, 0x56, 0x56, 0x34, 0x12, 0x78 - -The firmware implements 20 mailboxes of 20 32-bit words. The first 10 are -reserved for API calls. The second 10 are used by the firmware for event -notification. - - Index Name - ----- ---- - 0 Flags - 1 Command - 2 Return value - 3 Timeout - 4-19 Parameter/Result - - -The flags are defined in the following table. The direction is from the -perspective of the firmware. - - Bit Direction Purpose - --- --------- ------- - 2 O Firmware has processed the command. - 1 I Driver has finished setting the parameters. - 0 I Driver is using this mailbox. - - -The command is a 32-bit enumerator. The API specifics may be found in the -fw-*-api.txt documents. - -The return value is a 32-bit enumerator. Only two values are currently defined: -0=success and -1=command undefined. - -There are 16 parameters/results 32-bit fields. The driver populates these fields -with values for all the parameters required by the call. The driver overwrites -these fields with result values returned by the call. The API specifics may be -found in the fw-*-api.txt documents. - -The timeout value protects the card from a hung driver thread. If the driver -doesn't handle the completed call within the timeout specified, the firmware -will reset that mailbox. - -To make an API call, the driver iterates over each mailbox looking for the -first one available (bit 0 has been cleared). The driver sets that bit, fills -in the command enumerator, the timeout value and any required parameters. The -driver then sets the parameter ready bit (bit 1). The firmware scans the -mailboxes for pending commands, processes them, sets the result code, populates -the result value array with that call's return values and sets the call -complete bit (bit 2). Once bit 2 is set, the driver should retrieve the results -and clear all the flags. If the driver does not perform this task within the -time set in the timeout register, the firmware will reset that mailbox. - -Event notifications are sent from the firmware to the host. The host tells the -firmware which events it is interested in via an API call. That call tells the -firmware which notification mailbox to use. The firmware signals the host via -an interrupt. Only the 16 Results fields are used, the Flags, Command, Return -value and Timeout words are not used. - diff --git a/trunk/Documentation/video4linux/cx2341x/fw-decoder-api.txt b/trunk/Documentation/video4linux/cx2341x/fw-decoder-api.txt deleted file mode 100644 index 9df4fb3ea0f2..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-decoder-api.txt +++ /dev/null @@ -1,319 +0,0 @@ -Decoder firmware API description -================================ - -Note: this API is part of the decoder firmware, so it's cx23415 only. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_PING_FW -Enum 0/0x00 -Description - This API call does nothing. It may be used to check if the firmware - is responding. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_START_PLAYBACK -Enum 1/0x01 -Description - Begin or resume playback. -Param[0] - 0 based frame number in GOP to begin playback from. -Param[1] - Specifies the number of muted audio frames to play before normal - audio resumes. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_STOP_PLAYBACK -Enum 2/0x02 -Description - Ends playback and clears all decoder buffers. If PTS is not zero, - playback stops at specified PTS. -Param[0] - Display 0=last frame, 1=black -Param[1] - PTS low -Param[2] - PTS high - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_PLAYBACK_SPEED -Enum 3/0x03 -Description - Playback stream at speed other than normal. There are two modes of - operation: - Smooth: host transfers entire stream and firmware drops unused - frames. - Coarse: host drops frames based on indexing as required to achieve - desired speed. -Param[0] - Bitmap: - 0:7 0 normal - 1 fast only "1.5 times" - n nX fast, 1/nX slow - 30 Framedrop: - '0' during 1.5 times play, every other B frame is dropped - '1' during 1.5 times play, stream is unchanged (bitrate - must not exceed 8mbps) - 31 Speed: - '0' slow - '1' fast -Param[1] - Direction: 0=forward, 1=reverse -Param[2] - Picture mask: - 1=I frames - 3=I, P frames - 7=I, P, B frames -Param[3] - B frames per GOP (for reverse play only) -Param[4] - Mute audio: 0=disable, 1=enable -Param[5] - Display 0=frame, 1=field -Param[6] - Specifies the number of muted audio frames to play before normal audio - resumes. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_STEP_VIDEO -Enum 5/0x05 -Description - Each call to this API steps the playback to the next unit defined below - in the current playback direction. -Param[0] - 0=frame, 1=top field, 2=bottom field - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_DMA_BLOCK_SIZE -Enum 8/0x08 -Description - Set DMA transfer block size. Counterpart to API 0xC9 -Param[0] - DMA transfer block size in bytes. A different size may be specified - when issuing the DMA transfer command. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_GET_XFER_INFO -Enum 9/0x09 -Description - This API call may be used to detect an end of stream condtion. -Result[0] - Stream type -Result[1] - Address offset -Result[2] - Maximum bytes to transfer -Result[3] - Buffer fullness - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_GET_DMA_STATUS -Enum 10/0x0A -Description - Status of the last DMA transfer -Result[0] - Bit 1 set means transfer complete - Bit 2 set means DMA error - Bit 3 set means linked list error -Result[1] - DMA type: 0=MPEG, 1=OSD, 2=YUV - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SCHED_DMA_FROM_HOST -Enum 11/0x0B -Description - Setup DMA from host operation. Counterpart to API 0xCC -Param[0] - Memory address of link list -Param[1] - Total # of bytes to transfer -Param[2] - DMA type (0=MPEG, 1=OSD, 2=YUV) - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_PAUSE_PLAYBACK -Enum 13/0x0D -Description - Freeze playback immediately. In this mode, when internal buffers are - full, no more data will be accepted and data request IRQs will be - masked. -Param[0] - Display: 0=last frame, 1=black - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_HALT_FW -Enum 14/0x0E -Description - The firmware is halted and no further API calls are serviced until - the firmware is uploaded again. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_STANDARD -Enum 16/0x10 -Description - Selects display standard -Param[0] - 0=NTSC, 1=PAL - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_GET_VERSION -Enum 17/0x11 -Description - Returns decoder firmware version information -Result[0] - Version bitmask: - Bits 0:15 build - Bits 16:23 minor - Bits 24:31 major - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_STREAM_INPUT -Enum 20/0x14 -Description - Select decoder stream input port -Param[0] - 0=memory (default), 1=streaming - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_GET_TIMING_INFO -Enum 21/0x15 -Description - Returns timing information from start of playback -Result[0] - Frame count by decode order -Result[1] - Video PTS bits 0:31 by display order -Result[2] - Video PTS bit 32 by display order -Result[3] - SCR bits 0:31 by display order -Result[4] - SCR bit 32 by display order - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_AUDIO_MODE -Enum 22/0x16 -Description - Select audio mode -Param[0] - Dual mono mode action -Param[1] - Stereo mode action: - 0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_EVENT_NOTIFICATION -Enum 23/0x17 -Description - Setup firmware to notify the host about a particular event. - Counterpart to API 0xD5 -Param[0] - Event: 0=Audio mode change between stereo and dual channel -Param[1] - Notification 0=disabled, 1=enabled -Param[2] - Interrupt bit -Param[3] - Mailbox slot, -1 if no mailbox required. - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_DISPLAY_BUFFERS -Enum 24/0x18 -Description - Number of display buffers. To decode all frames in reverse playback you - must use nine buffers. -Param[0] - 0=six buffers, 1=nine buffers - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_EXTRACT_VBI -Enum 25/0x19 -Description - Extracts VBI data -Param[0] - 0=extract from extension & user data, 1=extract from private packets -Result[0] - VBI table location -Result[1] - VBI table size - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_DECODER_SOURCE -Enum 26/0x1A -Description - Selects decoder source. Ensure that the parameters passed to this - API match the encoder settings. -Param[0] - Mode: 0=MPEG from host, 1=YUV from encoder, 2=YUV from host -Param[1] - YUV picture width -Param[2] - YUV picture height -Param[3] - Bitmap: see Param[0] of API 0xBD - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_AUDIO_OUTPUT -Enum 27/0x1B -Description - Select audio output format -Param[0] - Bitmask: - 0:1 Data size: - '00' 16 bit - '01' 20 bit - '10' 24 bit - 2:7 Unused - 8:9 Mode: - '00' 2 channels - '01' 4 channels - '10' 6 channels - '11' 6 channels with one line data mode - (for left justified MSB first mode, 20 bit only) - 10:11 Unused - 12:13 Channel format: - '00' right justified MSB first mode - '01' left justified MSB first mode - '10' I2S mode - 14:15 Unused - 16:21 Right justify bit count - 22:31 Unused - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_AV_DELAY -Enum 28/0x1C -Description - Set audio/video delay in 90Khz ticks -Param[0] - 0=A/V in sync, negative=audio lags, positive=video lags - -------------------------------------------------------------------------------- - -Name CX2341X_DEC_SET_PREBUFFERING -Enum 30/0x1E -Description - Decoder prebuffering, when enabled up to 128KB are buffered for - streams <8mpbs or 640KB for streams >8mbps -Param[0] - 0=off, 1=on diff --git a/trunk/Documentation/video4linux/cx2341x/fw-dma.txt b/trunk/Documentation/video4linux/cx2341x/fw-dma.txt deleted file mode 100644 index 8123e262d5b6..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-dma.txt +++ /dev/null @@ -1,94 +0,0 @@ -This page describes the structures and procedures used by the cx2341x DMA -engine. - -Introduction -============ - -The cx2341x PCI interface is busmaster capable. This means it has a DMA -engine to efficiently transfer large volumes of data between the card and main -memory without requiring help from a CPU. Like most hardware, it must operate -on contiguous physical memory. This is difficult to come by in large quantities -on virtual memory machines. - -Therefore, it also supports a technique called "scatter-gather". The card can -transfer multiple buffers in one operation. Instead of allocating one large -contiguous buffer, the driver can allocate several smaller buffers. - -In practice, I've seen the average transfer to be roughly 80K, but transfers -above 128K were not uncommon, particularly at startup. The 128K figure is -important, because that is the largest block that the kernel can normally -allocate. Even still, 128K blocks are hard to come by, so the driver writer is -urged to choose a smaller block size and learn the scatter-gather technique. - -Mailbox #10 is reserved for DMA transfer information. - -Flow -==== - -This section describes, in general, the order of events when handling DMA -transfers. Detailed information follows this section. - -- The card raises the Encoder interrupt. -- The driver reads the transfer type, offset and size from Mailbox #10. -- The driver constructs the scatter-gather array from enough free dma buffers - to cover the size. -- The driver schedules the DMA transfer via the ScheduleDMAtoHost API call. -- The card raises the DMA Complete interrupt. -- The driver checks the DMA status register for any errors. -- The driver post-processes the newly transferred buffers. - -NOTE! It is possible that the Encoder and DMA Complete interrupts get raised -simultaneously. (End of the last, start of the next, etc.) - -Mailbox #10 -=========== - -The Flags, Command, Return Value and Timeout fields are ignored. - -Name: Mailbox #10 -Results[0]: Type: 0: MPEG. -Results[1]: Offset: The position relative to the card's memory space. -Results[2]: Size: The exact number of bytes to transfer. - -My speculation is that since the StartCapture API has a capture type of "RAW" -available, that the type field will have other values that correspond to YUV -and PCM data. - -Scatter-Gather Array -==================== - -The scatter-gather array is a contiguously allocated block of memory that -tells the card the source and destination of each data-block to transfer. -Card "addresses" are derived from the offset supplied by Mailbox #10. Host -addresses are the physical memory location of the target DMA buffer. - -Each S-G array element is a struct of three 32-bit words. The first word is -the source address, the second is the destination address. Both take up the -entire 32 bits. The lowest 16 bits of the third word is the transfer byte -count. The high-bit of the third word is the "last" flag. The last-flag tells -the card to raise the DMA_DONE interrupt. From hard personal experience, if -you forget to set this bit, the card will still "work" but the stream will -most likely get corrupted. - -The transfer count must be a multiple of 256. Therefore, the driver will need -to track how much data in the target buffer is valid and deal with it -accordingly. - -Array Element: - -- 32-bit Source Address -- 32-bit Destination Address -- 16-bit reserved (high bit is the last flag) -- 16-bit byte count - -DMA Transfer Status -=================== - -Register 0x0004 holds the DMA Transfer Status: - -Bit -4 Scatter-Gather array error -3 DMA write error -2 DMA read error -1 write completed -0 read completed diff --git a/trunk/Documentation/video4linux/cx2341x/fw-encoder-api.txt b/trunk/Documentation/video4linux/cx2341x/fw-encoder-api.txt deleted file mode 100644 index 001c68644b08..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-encoder-api.txt +++ /dev/null @@ -1,694 +0,0 @@ -Encoder firmware API description -================================ - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_PING_FW -Enum 128/0x80 -Description - Does nothing. Can be used to check if the firmware is responding. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_START_CAPTURE -Enum 129/0x81 -Description - Commences the capture of video, audio and/or VBI data. All encoding - parameters must be initialized prior to this API call. Captures frames - continuously or until a predefined number of frames have been captured. -Param[0] - Capture stream type: - 0=MPEG - 1=Raw - 2=Raw passthrough - 3=VBI - -Param[1] - Bitmask: - Bit 0 when set, captures YUV - Bit 1 when set, captures PCM audio - Bit 2 when set, captures VBI (same as param[0]=3) - Bit 3 when set, the capture destination is the decoder - (same as param[0]=2) - Bit 4 when set, the capture destination is the host - Note: this parameter is only meaningful for RAW capture type. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_STOP_CAPTURE -Enum 130/0x82 -Description - Ends a capture in progress -Param[0] - 0=stop at end of GOP (generates IRQ) - 1=stop immediate (no IRQ) -Param[1] - Stream type to stop, see param[0] of API 0x81 -Param[2] - Subtype, see param[1] of API 0x81 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_AUDIO_ID -Enum 137/0x89 -Description - Assigns the transport stream ID of the encoded audio stream -Param[0] - Audio Stream ID - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_VIDEO_ID -Enum 139/0x8B -Description - Set video transport stream ID -Param[0] - Video stream ID - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_PCR_ID -Enum 141/0x8D -Description - Assigns the transport stream ID for PCR packets -Param[0] - PCR Stream ID - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_FRAME_RATE -Enum 143/0x8F -Description - Set video frames per second. Change occurs at start of new GOP. -Param[0] - 0=30fps - 1=25fps - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_FRAME_SIZE -Enum 145/0x91 -Description - Select video stream encoding resolution. -Param[0] - Height in lines. Default 480 -Param[1] - Width in pixels. Default 720 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_BIT_RATE -Enum 149/0x95 -Description - Assign average video stream bitrate. Note on the last three params: - Param[3] and [4] seem to be always 0, param [5] doesn't seem to be used. -Param[0] - 0=variable bitrate, 1=constant bitrate -Param[1] - bitrate in bits per second -Param[2] - peak bitrate in bits per second, divided by 400 -Param[3] - Mux bitrate in bits per second, divided by 400. May be 0 (default). -Param[4] - Rate Control VBR Padding -Param[5] - VBV Buffer used by encoder - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_GOP_PROPERTIES -Enum 151/0x97 -Description - Setup the GOP structure -Param[0] - GOP size (maximum is 34) -Param[1] - Number of B frames between the I and P frame, plus 1. - For example: IBBPBBPBBPBB --> GOP size: 12, number of B frames: 2+1 = 3 - Note that GOP size must be a multiple of (B-frames + 1). - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_ASPECT_RATIO -Enum 153/0x99 -Description - Sets the encoding aspect ratio. Changes in the aspect ratio take effect - at the start of the next GOP. -Param[0] - '0000' forbidden - '0001' 1:1 square - '0010' 4:3 - '0011' 16:9 - '0100' 2.21:1 - '0101' reserved - .... - '1111' reserved - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_DNR_FILTER_MODE -Enum 155/0x9B -Description - Assign Dynamic Noise Reduction operating mode -Param[0] - Bit0: Spatial filter, set=auto, clear=manual - Bit1: Temporal filter, set=auto, clear=manual -Param[1] - Median filter: - 0=Disabled - 1=Horizontal - 2=Vertical - 3=Horiz/Vert - 4=Diagonal - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_DNR_FILTER_PROPS -Enum 157/0x9D -Description - These Dynamic Noise Reduction filter values are only meaningful when - the respective filter is set to "manual" (See API 0x9B) -Param[0] - Spatial filter: default 0, range 0:15 -Param[1] - Temporal filter: default 0, range 0:31 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_CORING_LEVELS -Enum 159/0x9F -Description - Assign Dynamic Noise Reduction median filter properties. -Param[0] - Threshold above which the luminance median filter is enabled. - Default: 0, range 0:255 -Param[1] - Threshold below which the luminance median filter is enabled. - Default: 255, range 0:255 -Param[2] - Threshold above which the chrominance median filter is enabled. - Default: 0, range 0:255 -Param[3] - Threshold below which the chrominance median filter is enabled. - Default: 255, range 0:255 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_SPATIAL_FILTER_TYPE -Enum 161/0xA1 -Description - Assign spatial prefilter parameters -Param[0] - Luminance filter - 0=Off - 1=1D Horizontal - 2=1D Vertical - 3=2D H/V Separable (default) - 4=2D Symmetric non-separable -Param[1] - Chrominance filter - 0=Off - 1=1D Horizontal (default) - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_3_2_PULLDOWN -Enum 177/0xB1 -Description - 3:2 pulldown properties -Param[0] - 0=enabled - 1=disabled - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_VBI_LINE -Enum 183/0xB7 -Description - Selects VBI line number. -Param[0] - Bits 0:4 line number - Bit 31 0=top_field, 1=bottom_field - Bits 0:31 all set specifies "all lines" -Param[1] - VBI line information features: 0=disabled, 1=enabled -Param[2] - Slicing: 0=None, 1=Closed Caption - Almost certainly not implemented. Set to 0. -Param[3] - Luminance samples in this line. - Almost certainly not implemented. Set to 0. -Param[4] - Chrominance samples in this line - Almost certainly not implemented. Set to 0. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_STREAM_TYPE -Enum 185/0xB9 -Description - Assign stream type - Note: Transport stream is not working in recent firmwares. - And in older firmwares the timestamps in the TS seem to be - unreliable. -Param[0] - 0=Program stream - 1=Transport stream - 2=MPEG1 stream - 3=PES A/V stream - 5=PES Video stream - 7=PES Audio stream - 10=DVD stream - 11=VCD stream - 12=SVCD stream - 13=DVD_S1 stream - 14=DVD_S2 stream - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_OUTPUT_PORT -Enum 187/0xBB -Description - Assign stream output port. Normally 0 when the data is copied through - the PCI bus (DMA), and 1 when the data is streamed to another chip - (pvrusb and cx88-blackbird). -Param[0] - 0=Memory (default) - 1=Streaming - 2=Serial -Param[1] - Unknown, but leaving this to 0 seems to work best. Indications are that - this might have to do with USB support, although passing anything but 0 - onl breaks things. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_AUDIO_PROPERTIES -Enum 189/0xBD -Description - Set audio stream properties, may be called while encoding is in progress. - Note: all bitfields are consistent with ISO11172 documentation except - bits 2:3 which ISO docs define as: - '11' Layer I - '10' Layer II - '01' Layer III - '00' Undefined - This discrepancy may indicate a possible error in the documentation. - Testing indicated that only Layer II is actually working, and that - the minimum bitrate should be 192 kbps. -Param[0] - Bitmask: - 0:1 '00' 44.1Khz - '01' 48Khz - '10' 32Khz - '11' reserved - - 2:3 '01'=Layer I - '10'=Layer II - - 4:7 Bitrate: - Index | Layer I | Layer II - ------+-------------+------------ - '0000' | free format | free format - '0001' | 32 kbit/s | 32 kbit/s - '0010' | 64 kbit/s | 48 kbit/s - '0011' | 96 kbit/s | 56 kbit/s - '0100' | 128 kbit/s | 64 kbit/s - '0101' | 160 kbit/s | 80 kbit/s - '0110' | 192 kbit/s | 96 kbit/s - '0111' | 224 kbit/s | 112 kbit/s - '1000' | 256 kbit/s | 128 kbit/s - '1001' | 288 kbit/s | 160 kbit/s - '1010' | 320 kbit/s | 192 kbit/s - '1011' | 352 kbit/s | 224 kbit/s - '1100' | 384 kbit/s | 256 kbit/s - '1101' | 416 kbit/s | 320 kbit/s - '1110' | 448 kbit/s | 384 kbit/s - Note: For Layer II, not all combinations of total bitrate - and mode are allowed. See ISO11172-3 3-Annex B, Table 3-B.2 - - 8:9 '00'=Stereo - '01'=JointStereo - '10'=Dual - '11'=Mono - Note: testing seems to indicate that Mono and possibly - JointStereo are not working (default to stereo). - Dual does work, though. - - 10:11 Mode Extension used in joint_stereo mode. - In Layer I and II they indicate which subbands are in - intensity_stereo. All other subbands are coded in stereo. - '00' subbands 4-31 in intensity_stereo, bound==4 - '01' subbands 8-31 in intensity_stereo, bound==8 - '10' subbands 12-31 in intensity_stereo, bound==12 - '11' subbands 16-31 in intensity_stereo, bound==16 - - 12:13 Emphasis: - '00' None - '01' 50/15uS - '10' reserved - '11' CCITT J.17 - - 14 CRC: - '0' off - '1' on - - 15 Copyright: - '0' off - '1' on - - 16 Generation: - '0' copy - '1' original - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_HALT_FW -Enum 195/0xC3 -Description - The firmware is halted and no further API calls are serviced until the - firmware is uploaded again. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_GET_VERSION -Enum 196/0xC4 -Description - Returns the version of the encoder firmware. -Result[0] - Version bitmask: - Bits 0:15 build - Bits 16:23 minor - Bits 24:31 major - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_GOP_CLOSURE -Enum 197/0xC5 -Description - Assigns the GOP open/close property. -Param[0] - 0=Open - 1=Closed - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_GET_SEQ_END -Enum 198/0xC6 -Description - Obtains the sequence end code of the encoder's buffer. When a capture - is started a number of interrupts are still generated, the last of - which will have Result[0] set to 1 and Result[1] will contain the size - of the buffer. -Result[0] - State of the transfer (1 if last buffer) -Result[1] - If Result[0] is 1, this contains the size of the last buffer, undefined - otherwise. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_PGM_INDEX_INFO -Enum 199/0xC7 -Description - Sets the Program Index Information. -Param[0] - Picture Mask: - 0=No index capture - 1=I frames - 3=I,P frames - 7=I,P,B frames -Param[1] - Elements requested (up to 400) -Result[0] - Offset in SDF memory of the table. -Result[1] - Number of allocated elements up to a maximum of Param[1] - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_VBI_CONFIG -Enum 200/0xC8 -Description - Configure VBI settings -Param[0] - Bitmap: - 0 Mode '0' Sliced, '1' Raw - 1:3 Insertion: - '000' insert in extension & user data - '001' insert in private packets - '010' separate stream and user data - '111' separate stream and private data - 8:15 Stream ID (normally 0xBD) -Param[1] - Frames per interrupt (max 8). Only valid in raw mode. -Param[2] - Total raw VBI frames. Only valid in raw mode. -Param[3] - Start codes -Param[4] - Stop codes -Param[5] - Lines per frame -Param[6] - Byte per line -Result[0] - Observed frames per interrupt in raw mode only. Rage 1 to Param[1] -Result[1] - Observed number of frames in raw mode. Range 1 to Param[2] -Result[2] - Memory offset to start or raw VBI data - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_DMA_BLOCK_SIZE -Enum 201/0xC9 -Description - Set DMA transfer block size -Param[0] - DMA transfer block size in bytes or frames. When unit is bytes, - supported block sizes are 2^7, 2^8 and 2^9 bytes. -Param[1] - Unit: 0=bytes, 1=frames - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_GET_PREV_DMA_INFO_MB_10 -Enum 202/0xCA -Description - Returns information on the previous DMA transfer in conjunction with - bit 27 of the interrupt mask. Uses mailbox 10. -Result[0] - Type of stream -Result[1] - Address Offset -Result[2] - Maximum size of transfer - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 -Enum 203/0xCB -Description - Returns information on the previous DMA transfer in conjunction with - bit 27 of the interrupt mask. Uses mailbox 9. -Result[0] - Status bits: - Bit 0 set indicates transfer complete - Bit 2 set indicates transfer error - Bit 4 set indicates linked list error -Result[1] - DMA type -Result[2] - Presentation Time Stamp bits 0..31 -Result[3] - Presentation Time Stamp bit 32 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SCHED_DMA_TO_HOST -Enum 204/0xCC -Description - Setup DMA to host operation -Param[0] - Memory address of link list -Param[1] - Length of link list (wtf: what units ???) -Param[2] - DMA type (0=MPEG) - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_INITIALIZE_INPUT -Enum 205/0xCD -Description - Initializes the video input - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_FRAME_DROP_RATE -Enum 208/0xD0 -Description - For each frame captured, skip specified number of frames. -Param[0] - Number of frames to skip - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_PAUSE_ENCODER -Enum 210/0xD2 -Description - During a pause condition, all frames are dropped instead of being encoded. -Param[0] - 0=Pause encoding - 1=Continue encoding - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_REFRESH_INPUT -Enum 211/0xD3 -Description - Refreshes the video input - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_COPYRIGHT -Enum 212/0xD4 -Description - Sets stream copyright property -Param[0] - 0=Stream is not copyrighted - 1=Stream is copyrighted - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_EVENT_NOTIFICATION -Enum 213/0xD5 -Description - Setup firmware to notify the host about a particular event. Host must - unmask the interrupt bit. -Param[0] - Event (0=refresh encoder input) -Param[1] - Notification 0=disabled 1=enabled -Param[2] - Interrupt bit -Param[3] - Mailbox slot, -1 if no mailbox required. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_NUM_VSYNC_LINES -Enum 214/0xD6 -Description - Depending on the analog video decoder used, this assigns the number - of lines for field 1 and 2. -Param[0] - Field 1 number of lines: - 0x00EF for SAA7114 - 0x00F0 for SAA7115 - 0x0105 for Micronas -Param[1] - Field 2 number of lines: - 0x00EF for SAA7114 - 0x00F0 for SAA7115 - 0x0106 for Micronas - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_SET_PLACEHOLDER -Enum 215/0xD7 -Description - Provides a mechanism of inserting custom user data in the MPEG stream. -Param[0] - 0=extension & user data - 1=private packet with stream ID 0xBD -Param[1] - Rate at which to insert data, in units of frames (for private packet) - or GOPs (for ext. & user data) -Param[2] - Number of data DWORDs (below) to insert -Param[3] - Custom data 0 -Param[4] - Custom data 1 -Param[5] - Custom data 2 -Param[6] - Custom data 3 -Param[7] - Custom data 4 -Param[8] - Custom data 5 -Param[9] - Custom data 6 -Param[10] - Custom data 7 -Param[11] - Custom data 8 - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_MUTE_VIDEO -Enum 217/0xD9 -Description - Video muting -Param[0] - Bit usage: - 0 '0'=video not muted - '1'=video muted, creates frames with the YUV color defined below - 1:7 Unused - 8:15 V chrominance information - 16:23 U chrominance information - 24:31 Y luminance information - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_MUTE_AUDIO -Enum 218/0xDA -Description - Audio muting -Param[0] - 0=audio not muted - 1=audio muted (produces silent mpeg audio stream) - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_UNKNOWN -Enum 219/0xDB -Description - Unknown API, it's used by Hauppauge though. -Param[0] - 0 This is the value Hauppauge uses, Unknown what it means. - -------------------------------------------------------------------------------- - -Name CX2341X_ENC_MISC -Enum 220/0xDC -Description - Miscellaneous actions. Not known for 100% what it does. It's really a - sort of ioctl call. The first parameter is a command number, the second - the value. -Param[0] - Command number: - 1=set initial SCR value when starting encoding. - 2=set quality mode (apparently some test setting). - 3=setup advanced VIM protection handling (supposedly only for the cx23416 - for raw YUV). - Actually it looks like this should be 0 for saa7114/5 based card and 1 - for cx25840 based cards. - 4=generate artificial PTS timestamps - 5=USB flush mode - 6=something to do with the quantization matrix - 7=set navigation pack insertion for DVD - 8=enable scene change detection (seems to be a failure) - 9=set history parameters of the video input module - 10=set input field order of VIM - 11=set quantization matrix - 12=reset audio interface - 13=set audio volume delay - 14=set audio delay - -Param[1] - Command value. diff --git a/trunk/Documentation/video4linux/cx2341x/fw-memory.txt b/trunk/Documentation/video4linux/cx2341x/fw-memory.txt deleted file mode 100644 index ef0aad3f88fc..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-memory.txt +++ /dev/null @@ -1,141 +0,0 @@ -This document describes the cx2341x memory map and documents some of the register -space. - -Warning! This information was figured out from searching through the memory and -registers, this information may not be correct and is certainly not complete, and -was not derived from anything more than searching through the memory space with -commands like: - - ivtvctl -O min=0x02000000,max=0x020000ff - -So take this as is, I'm always searching for more stuff, it's a large -register space :-). - -Memory Map -========== - -The cx2341x exposes its entire 64M memory space to the PCI host via the PCI BAR0 -(Base Address Register 0). The addresses here are offsets relative to the -address held in BAR0. - -0x00000000-0x00ffffff Encoder memory space -0x00000000-0x0003ffff Encode.rom - ???-??? MPEG buffer(s) - ???-??? Raw video capture buffer(s) - ???-??? Raw audio capture buffer(s) - ???-??? Display buffers (6 or 9) - -0x01000000-0x01ffffff Decoder memory space -0x01000000-0x0103ffff Decode.rom - ???-??? MPEG buffers(s) -0x0114b000-0x0115afff Audio.rom (deprecated?) - -0x02000000-0x0200ffff Register Space - -Registers -========= - -The registers occupy the 64k space starting at the 0x02000000 offset from BAR0. -All of these registers are 32 bits wide. - -DMA Registers 0x000-0xff: - - 0x00 - Control: - 0=reset/cancel, 1=read, 2=write, 4=stop - 0x04 - DMA status: - 1=read busy, 2=write busy, 4=read error, 8=write error, 16=link list error - 0x08 - pci DMA pointer for read link list - 0x0c - pci DMA pointer for write link list - 0x10 - read/write DMA enable: - 1=read enable, 2=write enable - 0x14 - always 0xffffffff, if set any lower instability occurs, 0x00 crashes - 0x18 - ?? - 0x1c - always 0x20 or 32, smaller values slow down DMA transactions - 0x20 - always value of 0x780a010a - 0x24-0x3c - usually just random values??? - 0x40 - Interrupt status - 0x44 - Write a bit here and shows up in Interrupt status 0x40 - 0x48 - Interrupt Mask - 0x4C - always value of 0xfffdffff, - if changed to 0xffffffff DMA write interrupts break. - 0x50 - always 0xffffffff - 0x54 - always 0xffffffff (0x4c, 0x50, 0x54 seem like interrupt masks, are - 3 processors on chip, Java ones, VPU, SPU, APU, maybe these are the - interrupt masks???). - 0x60-0x7C - random values - 0x80 - first write linked list reg, for Encoder Memory addr - 0x84 - first write linked list reg, for pci memory addr - 0x88 - first write linked list reg, for length of buffer in memory addr - (|0x80000000 or this for last link) - 0x8c-0xcc - rest of write linked list reg, 8 sets of 3 total, DMA goes here - from linked list addr in reg 0x0c, firmware must push through or - something. - 0xe0 - first (and only) read linked list reg, for pci memory addr - 0xe4 - first (and only) read linked list reg, for Decoder memory addr - 0xe8 - first (and only) read linked list reg, for length of buffer - 0xec-0xff - Nothing seems to be in these registers, 0xec-f4 are 0x00000000. - -Memory locations for Encoder Buffers 0x700-0x7ff: - -These registers show offsets of memory locations pertaining to each -buffer area used for encoding, have to shift them by <<1 first. - -0x07F8: Encoder SDRAM refresh -0x07FC: Encoder SDRAM pre-charge - -Memory locations for Decoder Buffers 0x800-0x8ff: - -These registers show offsets of memory locations pertaining to each -buffer area used for decoding, have to shift them by <<1 first. - -0x08F8: Decoder SDRAM refresh -0x08FC: Decoder SDRAM pre-charge - -Other memory locations: - -0x2800: Video Display Module control -0x2D00: AO (audio output?) control -0x2D24: Bytes Flushed -0x7000: LSB I2C write clock bit (inverted) -0x7004: LSB I2C write data bit (inverted) -0x7008: LSB I2C read clock bit -0x700c: LSB I2C read data bit -0x9008: GPIO get input state -0x900c: GPIO set output state -0x9020: GPIO direction (Bit7 (GPIO 0..7) - 0:input, 1:output) -0x9050: SPU control -0x9054: Reset HW blocks -0x9058: VPU control -0xA018: Bit6: interrupt pending? -0xA064: APU command - - -Interrupt Status Register -========================= - -The definition of the bits in the interrupt status register 0x0040, and the -interrupt mask 0x0048. If a bit is cleared in the mask, then we want our ISR to -execute. - -Bit -31 Encoder Start Capture -30 Encoder EOS -29 Encoder VBI capture -28 Encoder Video Input Module reset event -27 Encoder DMA complete -26 -25 Decoder copy protect detection event -24 Decoder audio mode change detection event -23 -22 Decoder data request -21 Decoder I-Frame? done -20 Decoder DMA complete -19 Decoder VBI re-insertion -18 Decoder DMA err (linked-list bad) - -Missing -Encoder API call completed -Decoder API call completed -Encoder API post(?) -Decoder API post(?) -Decoder VTRACE event diff --git a/trunk/Documentation/video4linux/cx2341x/fw-osd-api.txt b/trunk/Documentation/video4linux/cx2341x/fw-osd-api.txt deleted file mode 100644 index da98ae30a37a..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-osd-api.txt +++ /dev/null @@ -1,342 +0,0 @@ -OSD firmware API description -============================ - -Note: this API is part of the decoder firmware, so it's cx23415 only. - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_FRAMEBUFFER -Enum 65/0x41 -Description - Return base and length of contiguous OSD memory. -Result[0] - OSD base address -Result[1] - OSD length - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_PIXEL_FORMAT -Enum 66/0x42 -Description - Query OSD format -Result[0] - 0=8bit index, 4=AlphaRGB 8:8:8:8 - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_PIXEL_FORMAT -Enum 67/0x43 -Description - Assign pixel format -Param[0] - 0=8bit index, 4=AlphaRGB 8:8:8:8 - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_STATE -Enum 68/0x44 -Description - Query OSD state -Result[0] - Bit 0 0=off, 1=on - Bits 1:2 alpha control - Bits 3:5 pixel format - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_STATE -Enum 69/0x45 -Description - OSD switch -Param[0] - 0=off, 1=on - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_OSD_COORDS -Enum 70/0x46 -Description - Retrieve coordinates of OSD area blended with video -Result[0] - OSD buffer address -Result[1] - Stride in pixels -Result[2] - Lines in OSD buffer -Result[3] - Horizontal offset in buffer -Result[4] - Vertical offset in buffer - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_OSD_COORDS -Enum 71/0x47 -Description - Assign the coordinates of the OSD area to blend with video -Param[0] - buffer address -Param[1] - buffer stride in pixels -Param[2] - lines in buffer -Param[3] - horizontal offset -Param[4] - vertical offset - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_SCREEN_COORDS -Enum 72/0x48 -Description - Retrieve OSD screen area coordinates -Result[0] - top left horizontal offset -Result[1] - top left vertical offset -Result[2] - bottom right hotizontal offset -Result[3] - bottom right vertical offset - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_SCREEN_COORDS -Enum 73/0x49 -Description - Assign the coordinates of the screen area to blend with video -Param[0] - top left horizontal offset -Param[1] - top left vertical offset -Param[2] - bottom left horizontal offset -Param[3] - bottom left vertical offset - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_GLOBAL_ALPHA -Enum 74/0x4A -Description - Retrieve OSD global alpha -Result[0] - global alpha: 0=off, 1=on -Result[1] - bits 0:7 global alpha - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_GLOBAL_ALPHA -Enum 75/0x4B -Description - Update global alpha -Param[0] - global alpha: 0=off, 1=on -Param[1] - global alpha (8 bits) -Param[2] - local alpha: 0=on, 1=off - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_BLEND_COORDS -Enum 78/0x4C -Description - Move start of blending area within display buffer -Param[0] - horizontal offset in buffer -Param[1] - vertical offset in buffer - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_FLICKER_STATE -Enum 79/0x4F -Description - Retrieve flicker reduction module state -Result[0] - flicker state: 0=off, 1=on - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_FLICKER_STATE -Enum 80/0x50 -Description - Set flicker reduction module state -Param[0] - State: 0=off, 1=on - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_BLT_COPY -Enum 82/0x52 -Description - BLT copy -Param[0] -'0000' zero -'0001' ~destination AND ~source -'0010' ~destination AND source -'0011' ~destination -'0100' destination AND ~source -'0101' ~source -'0110' destination XOR source -'0111' ~destination OR ~source -'1000' ~destination AND ~source -'1001' destination XNOR source -'1010' source -'1011' ~destination OR source -'1100' destination -'1101' destination OR ~source -'1110' destination OR source -'1111' one - -Param[1] - Resulting alpha blending - '01' source_alpha - '10' destination_alpha - '11' source_alpha*destination_alpha+1 - (zero if both source and destination alpha are zero) -Param[2] - '00' output_pixel = source_pixel - - '01' if source_alpha=0: - output_pixel = destination_pixel - if 256 > source_alpha > 1: - output_pixel = ((source_alpha + 1)*source_pixel + - (255 - source_alpha)*destination_pixel)/256 - - '10' if destination_alpha=0: - output_pixel = source_pixel - if 255 > destination_alpha > 0: - output_pixel = ((255 - destination_alpha)*source_pixel + - (destination_alpha + 1)*destination_pixel)/256 - - '11' if source_alpha=0: - source_temp = 0 - if source_alpha=255: - source_temp = source_pixel*256 - if 255 > source_alpha > 0: - source_temp = source_pixel*(source_alpha + 1) - if destination_alpha=0: - destination_temp = 0 - if destination_alpha=255: - destination_temp = destination_pixel*256 - if 255 > destination_alpha > 0: - destination_temp = destination_pixel*(destination_alpha + 1) - output_pixel = (source_temp + destination_temp)/256 -Param[3] - width -Param[4] - height -Param[5] - destination pixel mask -Param[6] - destination rectangle start address -Param[7] - destination stride in dwords -Param[8] - source stride in dwords -Param[9] - source rectangle start address - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_BLT_FILL -Enum 83/0x53 -Description - BLT fill color -Param[0] - Same as Param[0] on API 0x52 -Param[1] - Same as Param[1] on API 0x52 -Param[2] - Same as Param[2] on API 0x52 -Param[3] - width -Param[4] - height -Param[5] - destination pixel mask -Param[6] - destination rectangle start address -Param[7] - destination stride in dwords -Param[8] - color fill value - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_BLT_TEXT -Enum 84/0x54 -Description - BLT for 8 bit alpha text source -Param[0] - Same as Param[0] on API 0x52 -Param[1] - Same as Param[1] on API 0x52 -Param[2] - Same as Param[2] on API 0x52 -Param[3] - width -Param[4] - height -Param[5] - destination pixel mask -Param[6] - destination rectangle start address -Param[7] - destination stride in dwords -Param[8] - source stride in dwords -Param[9] - source rectangle start address -Param[10] - color fill value - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_FRAMEBUFFER_WINDOW -Enum 86/0x56 -Description - Positions the main output window on the screen. The coordinates must be - such that the entire window fits on the screen. -Param[0] - window width -Param[1] - window height -Param[2] - top left window corner horizontal offset -Param[3] - top left window corner vertical offset - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_CHROMA_KEY -Enum 96/0x60 -Description - Chroma key switch and color -Param[0] - state: 0=off, 1=on -Param[1] - color - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_GET_ALPHA_CONTENT_INDEX -Enum 97/0x61 -Description - Retrieve alpha content index -Result[0] - alpha content index, Range 0:15 - -------------------------------------------------------------------------------- - -Name CX2341X_OSD_SET_ALPHA_CONTENT_INDEX -Enum 98/0x62 -Description - Assign alpha content index -Param[0] - alpha content index, range 0:15 diff --git a/trunk/Documentation/video4linux/cx2341x/fw-upload.txt b/trunk/Documentation/video4linux/cx2341x/fw-upload.txt deleted file mode 100644 index 60c502ce3215..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/fw-upload.txt +++ /dev/null @@ -1,49 +0,0 @@ -This document describes how to upload the cx2341x firmware to the card. - -How to find -=========== - -See the web pages of the various projects that uses this chip for information -on how to obtain the firmware. - -The firmware stored in a Windows driver can be detected as follows: - -- Each firmware image is 256k bytes. -- The 1st 32-bit word of the Encoder image is 0x0000da7 -- The 1st 32-bit word of the Decoder image is 0x00003a7 -- The 2nd 32-bit word of both images is 0xaa55bb66 - -How to load -=========== - -- Issue the FWapi command to stop the encoder if it is running. Wait for the - command to complete. -- Issue the FWapi command to stop the decoder if it is running. Wait for the - command to complete. -- Issue the I2C command to the digitizer to stop emitting VSYNC events. -- Issue the FWapi command to halt the encoder's firmware. -- Sleep for 10ms. -- Issue the FWapi command to halt the decoder's firmware. -- Sleep for 10ms. -- Write 0x00000000 to register 0x2800 to stop the Video Display Module. -- Write 0x00000005 to register 0x2D00 to stop the AO (audio output?). -- Write 0x00000000 to register 0xA064 to ping? the APU. -- Write 0xFFFFFFFE to register 0x9058 to stop the VPU. -- Write 0xFFFFFFFF to register 0x9054 to reset the HW blocks. -- Write 0x00000001 to register 0x9050 to stop the SPU. -- Sleep for 10ms. -- Write 0x0000001A to register 0x07FC to init the Encoder SDRAM's pre-charge. -- Write 0x80000640 to register 0x07F8 to init the Encoder SDRAM's refresh to 1us. -- Write 0x0000001A to register 0x08FC to init the Decoder SDRAM's pre-charge. -- Write 0x80000640 to register 0x08F8 to init the Decoder SDRAM's refresh to 1us. -- Sleep for 512ms. (600ms is recommended) -- Transfer the encoder's firmware image to offset 0 in Encoder memory space. -- Transfer the decoder's firmware image to offset 0 in Decoder memory space. -- Use a read-modify-write operation to Clear bit 0 of register 0x9050 to - re-enable the SPU. -- Sleep for 1 second. -- Use a read-modify-write operation to Clear bits 3 and 0 of register 0x9058 - to re-enable the VPU. -- Sleep for 1 second. -- Issue status API commands to both firmware images to verify. - diff --git a/trunk/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt b/trunk/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt deleted file mode 100644 index 93fec32a1188..000000000000 --- a/trunk/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt +++ /dev/null @@ -1,54 +0,0 @@ -The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting. - -GPIO0 GPIO1 - 0 0 TV Audio - 1 0 FM radio - 0 1 Line-In - 1 1 Mono tuner bypass or CD passthru (tuner specific) - -GPIO 16(i believe) is tied to the IR port (if present). - ------------------------------------------------------------------------------------- - ->From the data sheet: - Register 24'h20004 PCI Interrupt Status - bit [18] IR_SMP_INT Set when 32 input samples have been collected over - gpio[16] pin into GP_SAMPLE register. - -What's missing from the data sheet: - -Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5 -compat remote) -set register 0x35C050 to 0xa80a80 - -enable sampling -set register 0x35C054 to 0x5 - -Of course, enable the IRQ bit 18 in the interrupt mask register .(and -provide for a handler) - -GP_SAMPLE register is at 0x35C058 - -Bits are then right shifted into the GP_SAMPLE register at the specified -rate; you get an interrupt when a full DWORD is recieved. -You need to recover the actual RC5 bits out of the (oversampled) IR sensor -bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data) An -actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment. - -I'm pretty sure when no IR signal is present the receiver is always in a -marking state(1); but stray light, etc can cause intermittent noise values -as well. Remember, this is a free running sample of the IR receiver state -over time, so don't assume any sample starts at any particular place. - -http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf -This data sheet (google search) seems to have a lovely description of the -RC5 basics - -http://users.pandora.be/nenya/electronics/rc5/ and more data - -http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt -and even a reference to how to decode a bi-phase data stream. - -http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm -still more info - diff --git a/trunk/Documentation/video4linux/et61x251.txt b/trunk/Documentation/video4linux/et61x251.txt index cd584f20a997..29340282ab5f 100644 --- a/trunk/Documentation/video4linux/et61x251.txt +++ b/trunk/Documentation/video4linux/et61x251.txt @@ -1,9 +1,9 @@ - ET61X[12]51 PC Camera Controllers - Driver for Linux - ================================= + ET61X[12]51 PC Camera Controllers + Driver for Linux + ================================= - - Documentation - + - Documentation - Index @@ -156,46 +156,46 @@ Name: video_nr Type: short array (min = 0, max = 64) Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: - -1 = use next available - n = use minor number n - You can specify up to 64 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - registered camera and use auto for the first one and for every - other camera. + -1 = use next available + n = use minor number n + You can specify up to 64 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + registered camera and use auto for the first one and for every + other camera. Default: -1 ------------------------------------------------------------------------------- Name: force_munmap Type: bool array (min = 0, max = 64) Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory - before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not - all the applications support this feature. This parameter is - specific for each detected camera. - 0 = do not force memory unmapping - 1 = force memory unmapping (save memory) + before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not + all the applications support this feature. This parameter is + specific for each detected camera. + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- Name: frame_timeout Type: uint array (min = 0, max = 64) Syntax: Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. + specific for each detected camera. This parameter can be + changed at runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- Name: debug Type: ushort Syntax: Description: Debugging information level, from 0 to 3: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = more verbose messages - Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations - about the hardware being detected. This module parameter can be - changed at runtime thanks to the /sys filesystem interface. + 0 = none (use carefully) + 1 = critical errors + 2 = significant informations + 3 = more verbose messages + Level 3 is useful for testing only, when only one device + is used at the same time. It also shows some more informations + about the hardware being detected. This module parameter can be + changed at runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- diff --git a/trunk/Documentation/video4linux/ibmcam.txt b/trunk/Documentation/video4linux/ibmcam.txt index 397a94eb77b8..4a40a2e99451 100644 --- a/trunk/Documentation/video4linux/ibmcam.txt +++ b/trunk/Documentation/video4linux/ibmcam.txt @@ -21,7 +21,7 @@ Internal interface: Video For Linux (V4L) Supported controls: - by V4L: Contrast, Brightness, Color, Hue - by driver options: frame rate, lighting conditions, video format, - default picture settings, sharpness. + default picture settings, sharpness. SUPPORTED CAMERAS: @@ -191,66 +191,66 @@ init_model2_sat Integer 0..255 [0x34] init_model2_sat=65 init_model2_yb Integer 0..255 [0xa0] init_model2_yb=200 debug You don't need this option unless you are a developer. - If you are a developer then you will see in the code - what values do what. 0=off. + If you are a developer then you will see in the code + what values do what. 0=off. flags This is a bit mask, and you can combine any number of - bits to produce what you want. Usually you don't want - any of extra features this option provides: - - FLAGS_RETRY_VIDIOCSYNC 1 This bit allows to retry failed - VIDIOCSYNC ioctls without failing. - Will work with xawtv, will not - with xrealproducer. Default is - not set. - FLAGS_MONOCHROME 2 Activates monochrome (b/w) mode. - FLAGS_DISPLAY_HINTS 4 Shows colored pixels which have - magic meaning to developers. - FLAGS_OVERLAY_STATS 8 Shows tiny numbers on screen, - useful only for debugging. - FLAGS_FORCE_TESTPATTERN 16 Shows blue screen with numbers. - FLAGS_SEPARATE_FRAMES 32 Shows each frame separately, as - it was received from the camera. - Default (not set) is to mix the - preceding frame in to compensate - for occasional loss of Isoc data - on high frame rates. - FLAGS_CLEAN_FRAMES 64 Forces "cleanup" of each frame - prior to use; relevant only if - FLAGS_SEPARATE_FRAMES is set. - Default is not to clean frames, - this is a little faster but may - produce flicker if frame rate is - too high and Isoc data gets lost. - FLAGS_NO_DECODING 128 This flag turns the video stream - decoder off, and dumps the raw - Isoc data from the camera into - the reading process. Useful to - developers, but not to users. + bits to produce what you want. Usually you don't want + any of extra features this option provides: + + FLAGS_RETRY_VIDIOCSYNC 1 This bit allows to retry failed + VIDIOCSYNC ioctls without failing. + Will work with xawtv, will not + with xrealproducer. Default is + not set. + FLAGS_MONOCHROME 2 Activates monochrome (b/w) mode. + FLAGS_DISPLAY_HINTS 4 Shows colored pixels which have + magic meaning to developers. + FLAGS_OVERLAY_STATS 8 Shows tiny numbers on screen, + useful only for debugging. + FLAGS_FORCE_TESTPATTERN 16 Shows blue screen with numbers. + FLAGS_SEPARATE_FRAMES 32 Shows each frame separately, as + it was received from the camera. + Default (not set) is to mix the + preceding frame in to compensate + for occasional loss of Isoc data + on high frame rates. + FLAGS_CLEAN_FRAMES 64 Forces "cleanup" of each frame + prior to use; relevant only if + FLAGS_SEPARATE_FRAMES is set. + Default is not to clean frames, + this is a little faster but may + produce flicker if frame rate is + too high and Isoc data gets lost. + FLAGS_NO_DECODING 128 This flag turns the video stream + decoder off, and dumps the raw + Isoc data from the camera into + the reading process. Useful to + developers, but not to users. framerate This setting controls frame rate of the camera. This is - an approximate setting (in terms of "worst" ... "best") - because camera changes frame rate depending on amount - of light available. Setting 0 is slowest, 6 is fastest. - Beware - fast settings are very demanding and may not - work well with all video sizes. Be conservative. + an approximate setting (in terms of "worst" ... "best") + because camera changes frame rate depending on amount + of light available. Setting 0 is slowest, 6 is fastest. + Beware - fast settings are very demanding and may not + work well with all video sizes. Be conservative. hue_correction This highly optional setting allows to adjust the - hue of the image in a way slightly different from - what usual "hue" control does. Both controls affect - YUV colorspace: regular "hue" control adjusts only - U component, and this "hue_correction" option similarly - adjusts only V component. However usually it is enough - to tweak only U or V to compensate for colored light or - color temperature; this option simply allows more - complicated correction when and if it is necessary. + hue of the image in a way slightly different from + what usual "hue" control does. Both controls affect + YUV colorspace: regular "hue" control adjusts only + U component, and this "hue_correction" option similarly + adjusts only V component. However usually it is enough + to tweak only U or V to compensate for colored light or + color temperature; this option simply allows more + complicated correction when and if it is necessary. init_brightness These settings specify _initial_ values which will be init_contrast used to set up the camera. If your V4L application has init_color its own controls to adjust the picture then these init_hue controls will be used too. These options allow you to - preconfigure the camera when it gets connected, before - any V4L application connects to it. Good for webcams. + preconfigure the camera when it gets connected, before + any V4L application connects to it. Good for webcams. init_model2_rg These initial settings alter color balance of the init_model2_rg2 camera on hardware level. All four settings may be used @@ -258,47 +258,47 @@ init_model2_sat to tune the camera to specific lighting conditions. These init_model2_yb settings only apply to Model 2 cameras. lighting This option selects one of three hardware-defined - photosensitivity settings of the camera. 0=bright light, - 1=Medium (default), 2=Low light. This setting affects - frame rate: the dimmer the lighting the lower the frame - rate (because longer exposition time is needed). The - Model 2 cameras allow values more than 2 for this option, - thus enabling extremely high sensitivity at cost of frame - rate, color saturation and imaging sensor noise. + photosensitivity settings of the camera. 0=bright light, + 1=Medium (default), 2=Low light. This setting affects + frame rate: the dimmer the lighting the lower the frame + rate (because longer exposition time is needed). The + Model 2 cameras allow values more than 2 for this option, + thus enabling extremely high sensitivity at cost of frame + rate, color saturation and imaging sensor noise. sharpness This option controls smoothing (noise reduction) - made by camera. Setting 0 is most smooth, setting 6 - is most sharp. Be aware that CMOS sensor used in the - camera is pretty noisy, so if you choose 6 you will - be greeted with "snowy" image. Default is 4. Model 2 - cameras do not support this feature. + made by camera. Setting 0 is most smooth, setting 6 + is most sharp. Be aware that CMOS sensor used in the + camera is pretty noisy, so if you choose 6 you will + be greeted with "snowy" image. Default is 4. Model 2 + cameras do not support this feature. size This setting chooses one of several image sizes that are - supported by this driver. Cameras may support more, but - it's difficult to reverse-engineer all formats. - Following video sizes are supported: - - size=0 128x96 (Model 1 only) - size=1 160x120 - size=2 176x144 - size=3 320x240 (Model 2 only) - size=4 352x240 (Model 2 only) - size=5 352x288 - size=6 640x480 (Model 3 only) - - The 352x288 is the native size of the Model 1 sensor - array, so it's the best resolution the camera can - yield. The best resolution of Model 2 is 176x144, and - larger images are produced by stretching the bitmap. - Model 3 has sensor with 640x480 grid, and it works too, - but the frame rate will be exceptionally low (1-2 FPS); - it may be still OK for some applications, like security. - Choose the image size you need. The smaller image can - support faster frame rate. Default is 352x288. + supported by this driver. Cameras may support more, but + it's difficult to reverse-engineer all formats. + Following video sizes are supported: + + size=0 128x96 (Model 1 only) + size=1 160x120 + size=2 176x144 + size=3 320x240 (Model 2 only) + size=4 352x240 (Model 2 only) + size=5 352x288 + size=6 640x480 (Model 3 only) + + The 352x288 is the native size of the Model 1 sensor + array, so it's the best resolution the camera can + yield. The best resolution of Model 2 is 176x144, and + larger images are produced by stretching the bitmap. + Model 3 has sensor with 640x480 grid, and it works too, + but the frame rate will be exceptionally low (1-2 FPS); + it may be still OK for some applications, like security. + Choose the image size you need. The smaller image can + support faster frame rate. Default is 352x288. For more information and the Troubleshooting FAQ visit this URL: - http://www.linux-usb.org/ibmcam/ + http://www.linux-usb.org/ibmcam/ WHAT NEEDS TO BE DONE: diff --git a/trunk/Documentation/video4linux/ov511.txt b/trunk/Documentation/video4linux/ov511.txt index 79af610d4ba5..142741e3c578 100644 --- a/trunk/Documentation/video4linux/ov511.txt +++ b/trunk/Documentation/video4linux/ov511.txt @@ -81,7 +81,7 @@ MODULE PARAMETERS: TYPE: integer (Boolean) DEFAULT: 1 DESC: Brightness is normally under automatic control and can't be set - manually by the video app. Set to 0 for manual control. + manually by the video app. Set to 0 for manual control. NAME: autogain TYPE: integer (Boolean) @@ -97,13 +97,13 @@ MODULE PARAMETERS: TYPE: integer (0-6) DEFAULT: 3 DESC: Sets the threshold for printing debug messages. The higher the value, - the more is printed. The levels are cumulative, and are as follows: - 0=no debug messages - 1=init/detection/unload and other significant messages - 2=some warning messages - 3=config/control function calls - 4=most function calls and data parsing messages - 5=highly repetitive mesgs + the more is printed. The levels are cumulative, and are as follows: + 0=no debug messages + 1=init/detection/unload and other significant messages + 2=some warning messages + 3=config/control function calls + 4=most function calls and data parsing messages + 5=highly repetitive mesgs NAME: snapshot TYPE: integer (Boolean) @@ -116,24 +116,24 @@ MODULE PARAMETERS: TYPE: integer (1-4 for OV511, 1-31 for OV511+) DEFAULT: 1 DESC: Number of cameras allowed to stream simultaneously on a single bus. - Values higher than 1 reduce the data rate of each camera, allowing two - or more to be used at once. If you have a complicated setup involving - both OV511 and OV511+ cameras, trial-and-error may be necessary for - finding the optimum setting. + Values higher than 1 reduce the data rate of each camera, allowing two + or more to be used at once. If you have a complicated setup involving + both OV511 and OV511+ cameras, trial-and-error may be necessary for + finding the optimum setting. NAME: compress TYPE: integer (Boolean) DEFAULT: 0 DESC: Set this to 1 to turn on the camera's compression engine. This can - potentially increase the frame rate at the expense of quality, if you - have a fast CPU. You must load the proper compression module for your - camera before starting your application (ov511_decomp or ov518_decomp). + potentially increase the frame rate at the expense of quality, if you + have a fast CPU. You must load the proper compression module for your + camera before starting your application (ov511_decomp or ov518_decomp). NAME: testpat TYPE: integer (Boolean) DEFAULT: 0 DESC: This configures the camera's sensor to transmit a colored test-pattern - instead of an image. This does not work correctly yet. + instead of an image. This does not work correctly yet. NAME: dumppix TYPE: integer (0-2) diff --git a/trunk/Documentation/video4linux/sn9c102.txt b/trunk/Documentation/video4linux/sn9c102.txt index 1d20895b4354..142920bc011f 100644 --- a/trunk/Documentation/video4linux/sn9c102.txt +++ b/trunk/Documentation/video4linux/sn9c102.txt @@ -1,9 +1,9 @@ - SN9C10x PC Camera Controllers - Driver for Linux - ============================= + SN9C10x PC Camera Controllers + Driver for Linux + ============================= - - Documentation - + - Documentation - Index @@ -176,46 +176,46 @@ Name: video_nr Type: short array (min = 0, max = 64) Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: - -1 = use next available - n = use minor number n - You can specify up to 64 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - recognized camera and use auto for the first one and for every - other camera. + -1 = use next available + n = use minor number n + You can specify up to 64 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + recognized camera and use auto for the first one and for every + other camera. Default: -1 ------------------------------------------------------------------------------- Name: force_munmap Type: bool array (min = 0, max = 64) Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory - before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not - all the applications support this feature. This parameter is - specific for each detected camera. - 0 = do not force memory unmapping - 1 = force memory unmapping (save memory) + before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not + all the applications support this feature. This parameter is + specific for each detected camera. + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- Name: frame_timeout Type: uint array (min = 0, max = 64) Syntax: Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. + specific for each detected camera. This parameter can be + changed at runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- Name: debug Type: ushort Syntax: Description: Debugging information level, from 0 to 3: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = more verbose messages - Level 3 is useful for testing only, when only one device - is used. It also shows some more informations about the - hardware being detected. This parameter can be changed at - runtime thanks to the /sys filesystem interface. + 0 = none (use carefully) + 1 = critical errors + 2 = significant informations + 3 = more verbose messages + Level 3 is useful for testing only, when only one device + is used. It also shows some more informations about the + hardware being detected. This parameter can be changed at + runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- @@ -280,24 +280,24 @@ Byte # Value Description 0x04 0xC4 Frame synchronisation pattern. 0x05 0x96 Frame synchronisation pattern. 0x06 0xXX Unknown meaning. The exact value depends on the chip; - possible values are 0x00, 0x01 and 0x20. + possible values are 0x00, 0x01 and 0x20. 0x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a - frame counter, u is unknown, zz is a size indicator - (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for - "compression enabled" (1 = yes, 0 = no). + frame counter, u is unknown, zz is a size indicator + (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for + "compression enabled" (1 = yes, 0 = no). 0x08 0xXX Brightness sum inside Auto-Exposure area (low-byte). 0x09 0xXX Brightness sum inside Auto-Exposure area (high-byte). - For a pure white image, this number will be equal to 500 - times the area of the specified AE area. For images - that are not pure white, the value scales down according - to relative whiteness. + For a pure white image, this number will be equal to 500 + times the area of the specified AE area. For images + that are not pure white, the value scales down according + to relative whiteness. 0x0A 0xXX Brightness sum outside Auto-Exposure area (low-byte). 0x0B 0xXX Brightness sum outside Auto-Exposure area (high-byte). - For a pure white image, this number will be equal to 125 - times the area outside of the specified AE area. For - images that are not pure white, the value scales down - according to relative whiteness. - according to relative whiteness. + For a pure white image, this number will be equal to 125 + times the area outside of the specified AE area. For + images that are not pure white, the value scales down + according to relative whiteness. + according to relative whiteness. The following bytes are used by the SN9C103 bridge only: diff --git a/trunk/Documentation/video4linux/v4lgrab.c b/trunk/Documentation/video4linux/v4lgrab.c deleted file mode 100644 index 079b628481cf..000000000000 --- a/trunk/Documentation/video4linux/v4lgrab.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Simple Video4Linux image grabber. */ -/* - * Video4Linux Driver Test/Example Framegrabbing Program - * - * Compile with: - * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab - * Use as: - * v4lgrab >image.ppm - * - * Copyright (C) 1998-05-03, Phil Blundell - * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c - * with minor modifications (Dave Forrest, drf5n@virginia.edu). - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define FILE "/dev/video0" - -/* Stole this from tvset.c */ - -#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ -{ \ - switch (format) \ - { \ - case VIDEO_PALETTE_GREY: \ - switch (depth) \ - { \ - case 4: \ - case 6: \ - case 8: \ - (r) = (g) = (b) = (*buf++ << 8);\ - break; \ - \ - case 16: \ - (r) = (g) = (b) = \ - *((unsigned short *) buf); \ - buf += 2; \ - break; \ - } \ - break; \ - \ - \ - case VIDEO_PALETTE_RGB565: \ - { \ - unsigned short tmp = *(unsigned short *)buf; \ - (r) = tmp&0xF800; \ - (g) = (tmp<<5)&0xFC00; \ - (b) = (tmp<<11)&0xF800; \ - buf += 2; \ - } \ - break; \ - \ - case VIDEO_PALETTE_RGB555: \ - (r) = (buf[0]&0xF8)<<8; \ - (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ - (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ - buf += 2; \ - break; \ - \ - case VIDEO_PALETTE_RGB24: \ - (r) = buf[0] << 8; (g) = buf[1] << 8; \ - (b) = buf[2] << 8; \ - buf += 3; \ - break; \ - \ - default: \ - fprintf(stderr, \ - "Format %d not yet supported\n", \ - format); \ - } \ -} - -int get_brightness_adj(unsigned char *image, long size, int *brightness) { - long i, tot = 0; - for (i=0;i= 126 && (tot/(size*3)) <= 130); -} - -int main(int argc, char ** argv) -{ - int fd = open(FILE, O_RDONLY), f; - struct video_capability cap; - struct video_window win; - struct video_picture vpic; - - unsigned char *buffer, *src; - int bpp = 24, r, g, b; - unsigned int i, src_depth; - - if (fd < 0) { - perror(FILE); - exit(1); - } - - if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { - perror("VIDIOGCAP"); - fprintf(stderr, "(" FILE " not a video4linux device?)\n"); - close(fd); - exit(1); - } - - if (ioctl(fd, VIDIOCGWIN, &win) < 0) { - perror("VIDIOCGWIN"); - close(fd); - exit(1); - } - - if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) { - perror("VIDIOCGPICT"); - close(fd); - exit(1); - } - - if (cap.type & VID_TYPE_MONOCHROME) { - vpic.depth=8; - vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */ - if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - vpic.depth=6; - if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - vpic.depth=4; - if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - fprintf(stderr, "Unable to find a supported capture format.\n"); - close(fd); - exit(1); - } - } - } - } else { - vpic.depth=24; - vpic.palette=VIDEO_PALETTE_RGB24; - - if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { - vpic.palette=VIDEO_PALETTE_RGB565; - vpic.depth=16; - - if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - vpic.palette=VIDEO_PALETTE_RGB555; - vpic.depth=15; - - if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - fprintf(stderr, "Unable to find a supported capture format.\n"); - return -1; - } - } - } - } - - buffer = malloc(win.width * win.height * bpp); - if (!buffer) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - - do { - int newbright; - read(fd, buffer, win.width * win.height * bpp); - f = get_brightness_adj(buffer, win.width * win.height, &newbright); - if (f) { - vpic.brightness += (newbright << 8); - if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { - perror("VIDIOSPICT"); - break; - } - } - } while (f); - - fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height); - - src = buffer; - - for (i = 0; i < win.width * win.height; i++) { - READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b); - fputc(r>>8, stdout); - fputc(g>>8, stdout); - fputc(b>>8, stdout); - } - - close(fd); - return 0; -} diff --git a/trunk/Documentation/video4linux/w9968cf.txt b/trunk/Documentation/video4linux/w9968cf.txt index 0d53ce774b01..3b704f2aae6d 100644 --- a/trunk/Documentation/video4linux/w9968cf.txt +++ b/trunk/Documentation/video4linux/w9968cf.txt @@ -1,9 +1,9 @@ - W996[87]CF JPEG USB Dual Mode Camera Chip - Driver for Linux 2.6 (basic version) - ========================================= + W996[87]CF JPEG USB Dual Mode Camera Chip + Driver for Linux 2.6 (basic version) + ========================================= - - Documentation - + - Documentation - Index @@ -188,57 +188,57 @@ Name: ovmod_load Type: bool Syntax: <0|1> Description: Automatic 'ovcamchip' module loading: 0 disabled, 1 enabled. - If enabled, 'insmod' searches for the required 'ovcamchip' - module in the system, according to its configuration, and - loads that module automatically. This action is performed as - once soon as the 'w9968cf' module is loaded into memory. + If enabled, 'insmod' searches for the required 'ovcamchip' + module in the system, according to its configuration, and + loads that module automatically. This action is performed as + once soon as the 'w9968cf' module is loaded into memory. Default: 1 Note: The kernel must be compiled with the CONFIG_KMOD option - enabled for the 'ovcamchip' module to be loaded and for - this parameter to be present. + enabled for the 'ovcamchip' module to be loaded and for + this parameter to be present. ------------------------------------------------------------------------------- Name: simcams Type: int Syntax: Description: Number of cameras allowed to stream simultaneously. - n may vary from 0 to 32. + n may vary from 0 to 32. Default: 32 ------------------------------------------------------------------------------- Name: video_nr Type: int array (min = 0, max = 32) Syntax: <-1|n[,...]> Description: Specify V4L minor mode number. - -1 = use next available - n = use minor number n - You can specify up to 32 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - recognized camera and use auto for the first one and for every - other camera. + -1 = use next available + n = use minor number n + You can specify up to 32 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + recognized camera and use auto for the first one and for every + other camera. Default: -1 ------------------------------------------------------------------------------- Name: packet_size Type: int array (min = 0, max = 32) Syntax: Description: Specify the maximum data payload size in bytes for alternate - settings, for each device. n is scaled between 63 and 1023. + settings, for each device. n is scaled between 63 and 1023. Default: 1023 ------------------------------------------------------------------------------- Name: max_buffers Type: int array (min = 0, max = 32) Syntax: Description: For advanced users. - Specify the maximum number of video frame buffers to allocate - for each device, from 2 to 32. + Specify the maximum number of video frame buffers to allocate + for each device, from 2 to 32. Default: 2 ------------------------------------------------------------------------------- Name: double_buffer Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Hardware double buffering: 0 disabled, 1 enabled. - It should be enabled if you want smooth video output: if you - obtain out of sync. video, disable it, or try to - decrease the 'clockdiv' module parameter value. + It should be enabled if you want smooth video output: if you + obtain out of sync. video, disable it, or try to + decrease the 'clockdiv' module parameter value. Default: 1 for every device. ------------------------------------------------------------------------------- Name: clamping @@ -251,9 +251,9 @@ Name: filter_type Type: int array (min = 0, max = 32) Syntax: <0|1|2[,...]> Description: Video filter type. - 0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter. - The filter is used to reduce noise and aliasing artifacts - produced by the CCD or CMOS image sensor. + 0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter. + The filter is used to reduce noise and aliasing artifacts + produced by the CCD or CMOS image sensor. Default: 0 for every device. ------------------------------------------------------------------------------- Name: largeview @@ -266,9 +266,9 @@ Name: upscaling Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Software scaling (for non-compressed video only): - 0 disabled, 1 enabled. - Disable it if you have a slow CPU or you don't have enough - memory. + 0 disabled, 1 enabled. + Disable it if you have a slow CPU or you don't have enough + memory. Default: 0 for every device. Note: If 'w9968cf-vpp' is not present, this parameter is set to 0. ------------------------------------------------------------------------------- @@ -276,36 +276,36 @@ Name: decompression Type: int array (min = 0, max = 32) Syntax: <0|1|2[,...]> Description: Software video decompression: - 0 = disables decompression - (doesn't allow formats needing decompression). - 1 = forces decompression - (allows formats needing decompression only). - 2 = allows any permitted formats. - Formats supporting (de)compressed video are YUV422P and - YUV420P/YUV420 in any resolutions where width and height are - multiples of 16. + 0 = disables decompression + (doesn't allow formats needing decompression). + 1 = forces decompression + (allows formats needing decompression only). + 2 = allows any permitted formats. + Formats supporting (de)compressed video are YUV422P and + YUV420P/YUV420 in any resolutions where width and height are + multiples of 16. Default: 2 for every device. Note: If 'w9968cf-vpp' is not present, forcing decompression is not - allowed; in this case this parameter is set to 2. + allowed; in this case this parameter is set to 2. ------------------------------------------------------------------------------- Name: force_palette Type: int array (min = 0, max = 32) Syntax: <0|9|10|13|15|8|7|1|6|3|4|5[,...]> Description: Force picture palette. - In order: - 0 = Off - allows any of the following formats: - 9 = UYVY 16 bpp - Original video, compression disabled - 10 = YUV420 12 bpp - Original video, compression enabled - 13 = YUV422P 16 bpp - Original video, compression enabled - 15 = YUV420P 12 bpp - Original video, compression enabled - 8 = YUVY 16 bpp - Software conversion from UYVY - 7 = YUV422 16 bpp - Software conversion from UYVY - 1 = GREY 8 bpp - Software conversion from UYVY - 6 = RGB555 16 bpp - Software conversion from UYVY - 3 = RGB565 16 bpp - Software conversion from UYVY - 4 = RGB24 24 bpp - Software conversion from UYVY - 5 = RGB32 32 bpp - Software conversion from UYVY - When not 0, this parameter will override 'decompression'. + In order: + 0 = Off - allows any of the following formats: + 9 = UYVY 16 bpp - Original video, compression disabled + 10 = YUV420 12 bpp - Original video, compression enabled + 13 = YUV422P 16 bpp - Original video, compression enabled + 15 = YUV420P 12 bpp - Original video, compression enabled + 8 = YUVY 16 bpp - Software conversion from UYVY + 7 = YUV422 16 bpp - Software conversion from UYVY + 1 = GREY 8 bpp - Software conversion from UYVY + 6 = RGB555 16 bpp - Software conversion from UYVY + 3 = RGB565 16 bpp - Software conversion from UYVY + 4 = RGB24 24 bpp - Software conversion from UYVY + 5 = RGB32 32 bpp - Software conversion from UYVY + When not 0, this parameter will override 'decompression'. Default: 0 for every device. Initial palette is 9 (UYVY). Note: If 'w9968cf-vpp' is not present, this parameter is set to 9. ------------------------------------------------------------------------------- @@ -313,77 +313,77 @@ Name: force_rgb Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Read RGB video data instead of BGR: - 1 = use RGB component ordering. - 0 = use BGR component ordering. - This parameter has effect when using RGBX palettes only. + 1 = use RGB component ordering. + 0 = use BGR component ordering. + This parameter has effect when using RGBX palettes only. Default: 0 for every device. ------------------------------------------------------------------------------- Name: autobright Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Image sensor automatically changes brightness: - 0 = no, 1 = yes + 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: autoexp Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Image sensor automatically changes exposure: - 0 = no, 1 = yes + 0 = no, 1 = yes Default: 1 for every device. ------------------------------------------------------------------------------- Name: lightfreq Type: int array (min = 0, max = 32) Syntax: <50|60[,...]> Description: Light frequency in Hz: - 50 for European and Asian lighting, 60 for American lighting. + 50 for European and Asian lighting, 60 for American lighting. Default: 50 for every device. ------------------------------------------------------------------------------- Name: bandingfilter Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Banding filter to reduce effects of fluorescent - lighting: - 0 disabled, 1 enabled. - This filter tries to reduce the pattern of horizontal - light/dark bands caused by some (usually fluorescent) lighting. + lighting: + 0 disabled, 1 enabled. + This filter tries to reduce the pattern of horizontal + light/dark bands caused by some (usually fluorescent) lighting. Default: 0 for every device. ------------------------------------------------------------------------------- Name: clockdiv Type: int array (min = 0, max = 32) Syntax: <-1|n[,...]> Description: Force pixel clock divisor to a specific value (for experts): - n may vary from 0 to 127. - -1 for automatic value. - See also the 'double_buffer' module parameter. + n may vary from 0 to 127. + -1 for automatic value. + See also the 'double_buffer' module parameter. Default: -1 for every device. ------------------------------------------------------------------------------- Name: backlight Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Objects are lit from behind: - 0 = no, 1 = yes + 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: mirror Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: Reverse image horizontally: - 0 = no, 1 = yes + 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: monochrome Type: bool array (min = 0, max = 32) Syntax: <0|1[,...]> Description: The image sensor is monochrome: - 0 = no, 1 = yes + 0 = no, 1 = yes Default: 0 for every device. ------------------------------------------------------------------------------- Name: brightness Type: long array (min = 0, max = 32) Syntax: Description: Set picture brightness (0-65535). - This parameter has no effect if 'autobright' is enabled. + This parameter has no effect if 'autobright' is enabled. Default: 31000 for every device. ------------------------------------------------------------------------------- Name: hue @@ -414,23 +414,23 @@ Name: debug Type: int Syntax: Description: Debugging information level, from 0 to 6: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = configuration or general messages - 4 = warnings - 5 = called functions - 6 = function internals - Level 5 and 6 are useful for testing only, when only one - device is used. + 0 = none (use carefully) + 1 = critical errors + 2 = significant informations + 3 = configuration or general messages + 4 = warnings + 5 = called functions + 6 = function internals + Level 5 and 6 are useful for testing only, when only one + device is used. Default: 2 ------------------------------------------------------------------------------- Name: specific_debug Type: bool Syntax: <0|1> Description: Enable or disable specific debugging messages: - 0 = print messages concerning every level <= 'debug' level. - 1 = print messages concerning the level indicated by 'debug'. + 0 = print messages concerning every level <= 'debug' level. + 1 = print messages concerning the level indicated by 'debug'. Default: 0 ------------------------------------------------------------------------------- diff --git a/trunk/Documentation/video4linux/zc0301.txt b/trunk/Documentation/video4linux/zc0301.txt index f406f5e80046..f55262c6733b 100644 --- a/trunk/Documentation/video4linux/zc0301.txt +++ b/trunk/Documentation/video4linux/zc0301.txt @@ -1,9 +1,9 @@ - ZC0301 and ZC0301P Image Processor and Control Chip - Driver for Linux - =================================================== + ZC0301 Image Processor and Control Chip + Driver for Linux + ======================================= - - Documentation - + - Documentation - Index @@ -51,13 +51,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 4. Overview and features ======================== -This driver supports the video interface of the devices mounting the ZC0301 or -ZC0301P Image Processors and Control Chips. +This driver supports the video interface of the devices mounting the ZC0301 +Image Processor and Control Chip. The driver relies on the Video4Linux2 and USB core modules. It has been designed to run properly on SMP systems as well. -The latest version of the ZC0301[P] driver can be found at the following URL: +The latest version of the ZC0301 driver can be found at the following URL: http://www.linux-projects.org/ Some of the features of the driver are: @@ -117,7 +117,7 @@ supported by the USB Audio driver thanks to the ALSA API: And finally: - # V4L USB devices + # USB Multimedia devices # CONFIG_USB_ZC0301=m @@ -146,46 +146,46 @@ Name: video_nr Type: short array (min = 0, max = 64) Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: - -1 = use next available - n = use minor number n - You can specify up to 64 cameras this way. - For example: - video_nr=-1,2,-1 would assign minor number 2 to the second - registered camera and use auto for the first one and for every - other camera. + -1 = use next available + n = use minor number n + You can specify up to 64 cameras this way. + For example: + video_nr=-1,2,-1 would assign minor number 2 to the second + registered camera and use auto for the first one and for every + other camera. Default: -1 ------------------------------------------------------------------------------- Name: force_munmap Type: bool array (min = 0, max = 64) Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory - before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not - all the applications support this feature. This parameter is - specific for each detected camera. - 0 = do not force memory unmapping - 1 = force memory unmapping (save memory) + before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not + all the applications support this feature. This parameter is + specific for each detected camera. + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- Name: frame_timeout Type: uint array (min = 0, max = 64) Syntax: Description: Timeout for a video frame in seconds. This parameter is - specific for each detected camera. This parameter can be - changed at runtime thanks to the /sys filesystem interface. + specific for each detected camera. This parameter can be + changed at runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- Name: debug Type: ushort Syntax: Description: Debugging information level, from 0 to 3: - 0 = none (use carefully) - 1 = critical errors - 2 = significant informations - 3 = more verbose messages - Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations - about the hardware being detected. This module parameter can be - changed at runtime thanks to the /sys filesystem interface. + 0 = none (use carefully) + 1 = critical errors + 2 = significant informations + 3 = more verbose messages + Level 3 is useful for testing only, when only one device + is used at the same time. It also shows some more informations + about the hardware being detected. This module parameter can be + changed at runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- @@ -204,25 +204,11 @@ Vendor ID Product ID 0x041e 0x4017 0x041e 0x401c 0x041e 0x401e -0x041e 0x401f -0x041e 0x4022 0x041e 0x4034 0x041e 0x4035 -0x041e 0x4036 -0x041e 0x403a -0x0458 0x7007 -0x0458 0x700C -0x0458 0x700f -0x046d 0x08ae -0x055f 0xd003 -0x055f 0xd004 0x046d 0x08ae 0x0ac8 0x0301 -0x0ac8 0x301b -0x0ac8 0x303b -0x10fd 0x0128 0x10fd 0x8050 -0x10fd 0x804e The list above does not imply that all those devices work with this driver: up until now only the ones that mount the following image sensors are supported; @@ -231,7 +217,6 @@ kernel messages will always tell you whether this is the case: Model Manufacturer ----- ------------ PAS202BCB PixArt Imaging, Inc. -PB-0330 Photobit Corporation 9. Notes for V4L2 application developers @@ -265,6 +250,5 @@ the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. been taken from the documentation of the ZC030x Video4Linux1 driver written by Andrew Birkett ; - The initialization values of the ZC0301 controller connected to the PAS202BCB - and PB-0330 image sensors have been taken from the SPCA5XX driver maintained - by Michel Xhaard ; -- Stanislav Lechev donated one camera. + image sensor have been taken from the SPCA5XX driver maintained by + Michel Xhaard . diff --git a/trunk/Documentation/vm/page_migration b/trunk/Documentation/vm/page_migration index 99f89aa10169..0dd4ef30c361 100644 --- a/trunk/Documentation/vm/page_migration +++ b/trunk/Documentation/vm/page_migration @@ -26,13 +26,8 @@ a process are located. See also the numa_maps manpage in the numactl package. Manual migration is useful if for example the scheduler has relocated a process to a processor on a distant node. A batch scheduler or an administrator may detect the situation and move the pages of the process -nearer to the new processor. The kernel itself does only provide -manual page migration support. Automatic page migration may be implemented -through user space processes that move pages. A special function call -"move_pages" allows the moving of individual pages within a process. -A NUMA profiler may f.e. obtain a log showing frequent off node -accesses and may use the result to move pages to more advantageous -locations. +nearer to the new processor. At some point in the future we may have +some mechanism in the scheduler that will automatically move the pages. Larger installations usually partition the system using cpusets into sections of nodes. Paul Jackson has equipped cpusets with the ability to @@ -67,14 +62,22 @@ A. In kernel use of migrate_pages() It also prevents the swapper or other scans to encounter the page. -2. We need to have a function of type new_page_t that can be - passed to migrate_pages(). This function should figure out - how to allocate the correct new page given the old page. +2. Generate a list of newly allocates page. These pages will contain the + contents of the pages from the first list after page migration is + complete. 3. The migrate_pages() function is called which attempts - to do the migration. It will call the function to allocate - the new page for each page that is considered for - moving. + to do the migration. It returns the moved pages in the + list specified as the third parameter and the failed + migrations in the fourth parameter. The first parameter + will contain the pages that could still be retried. + +4. The leftover pages of various types are returned + to the LRU using putback_to_lru_pages() or otherwise + disposed of. The pages will still have the refcount as + increased by isolate_lru_pages() if putback_to_lru_pages() is not + used! The kernel may want to handle the various cases of failures in + different ways. B. How migrate_pages() works ---------------------------- @@ -90,58 +93,83 @@ Steps: 2. Insure that writeback is complete. -3. Prep the new page that we want to move to. It is locked +3. Make sure that the page has assigned swap cache entry if + it is an anonyous page. The swap cache reference is necessary + to preserve the information contain in the page table maps while + page migration occurs. + +4. Prep the new page that we want to move to. It is locked and set to not being uptodate so that all accesses to the new page immediately lock while the move is in progress. -4. The new page is prepped with some settings from the old page so that - accesses to the new page will discover a page with the correct settings. - -5. All the page table references to the page are converted - to migration entries or dropped (nonlinear vmas). - This decrease the mapcount of a page. If the resulting - mapcount is not zero then we do not migrate the page. - All user space processes that attempt to access the page - will now wait on the page lock. +5. All the page table references to the page are either dropped (file + backed pages) or converted to swap references (anonymous pages). + This should decrease the reference count. 6. The radix tree lock is taken. This will cause all processes trying - to access the page via the mapping to block on the radix tree spinlock. + to reestablish a pte to block on the radix tree spinlock. 7. The refcount of the page is examined and we back out if references remain otherwise we know that we are the only one referencing this page. 8. The radix tree is checked and if it does not contain the pointer to this - page then we back out because someone else modified the radix tree. + page then we back out because someone else modified the mapping first. + +9. The mapping is checked. If the mapping is gone then a truncate action may + be in progress and we back out. + +10. The new page is prepped with some settings from the old page so that + accesses to the new page will be discovered to have the correct settings. -9. The radix tree is changed to point to the new page. +11. The radix tree is changed to point to the new page. -10. The reference count of the old page is dropped because the radix tree - reference is gone. A reference to the new page is established because - the new page is referenced to by the radix tree. +12. The reference count of the old page is dropped because the radix tree + reference is gone. -11. The radix tree lock is dropped. With that lookups in the mapping - become possible again. Processes will move from spinning on the tree_lock - to sleeping on the locked new page. +13. The radix tree lock is dropped. With that lookups become possible again + and other processes will move from spinning on the tree lock to sleeping on + the locked new page. -12. The page contents are copied to the new page. +14. The page contents are copied to the new page. -13. The remaining page flags are copied to the new page. +15. The remaining page flags are copied to the new page. -14. The old page flags are cleared to indicate that the page does - not provide any information anymore. +16. The old page flags are cleared to indicate that the page does + not use any information anymore. -15. Queued up writeback on the new page is triggered. +17. Queued up writeback on the new page is triggered. -16. If migration entries were page then replace them with real ptes. Doing - so will enable access for user space processes not already waiting for - the page lock. +18. If swap pte's were generated for the page then replace them with real + ptes. This will reenable access for processes not blocked by the page lock. 19. The page locks are dropped from the old and new page. - Processes waiting on the page lock will redo their page faults - and will reach the new page. + Processes waiting on the page lock can continue. 20. The new page is moved to the LRU and can be scanned by the swapper etc again. -Christoph Lameter, May 8, 2006. +TODO list +--------- + +- Page migration requires the use of swap handles to preserve the + information of the anonymous page table entries. This means that swap + space is reserved but never used. The maximum number of swap handles used + is determined by CHUNK_SIZE (see mm/mempolicy.c) per ongoing migration. + Reservation of pages could be avoided by having a special type of swap + handle that does not require swap space and that would only track the page + references. Something like that was proposed by Marcelo Tosatti in the + past (search for migration cache on lkml or linux-mm@kvack.org). + +- Page migration unmaps ptes for file backed pages and requires page + faults to reestablish these ptes. This could be optimized by somehow + recording the references before migration and then reestablish them later. + However, there are several locking challenges that have to be overcome + before this is possible. + +- Page migration generates read ptes for anonymous pages. Dirty page + faults are required to make the pages writable again. It may be possible + to generate a pte marked dirty if it is known that the page is dirty and + that this process has the only reference to that page. + +Christoph Lameter, March 8, 2006. diff --git a/trunk/Documentation/w1/masters/ds2490 b/trunk/Documentation/w1/masters/ds2490 deleted file mode 100644 index 44a4918bd7f2..000000000000 --- a/trunk/Documentation/w1/masters/ds2490 +++ /dev/null @@ -1,18 +0,0 @@ -Kernel driver ds2490 -==================== - -Supported chips: - * Maxim DS2490 based - -Author: Evgeniy Polyakov - - -Description ------------ - -The Maixm/Dallas Semiconductor DS2490 is a chip -which allows to build USB <-> W1 bridges. - -DS9490(R) is a USB <-> W1 bus master device -which has 0x81 family ID integrated chip and DS2490 -low-level operational chip. diff --git a/trunk/Documentation/w1/w1.generic b/trunk/Documentation/w1/w1.generic index 4c6509dd4789..f937fbe1cacb 100644 --- a/trunk/Documentation/w1/w1.generic +++ b/trunk/Documentation/w1/w1.generic @@ -27,19 +27,8 @@ When a w1 master driver registers with the w1 subsystem, the following occurs: When a device is found on the bus, w1 core checks if driver for it's family is loaded. If so, the family driver is attached to the slave. -If there is no driver for the family, default one is assigned, which allows to perform -almost any kind of operations. Each logical operation is a transaction -in nature, which can contain several (two or one) low-level operations. -Let's see how one can read EEPROM context: -1. one must write control buffer, i.e. buffer containing command byte -and two byte address. At this step bus is reset and appropriate device -is selected using either W1_SKIP_ROM or W1_MATCH_ROM command. -Then provided control buffer is being written to the wire. -2. reading. This will issue reading eeprom response. - -It is possible that between 1. and 2. w1 master thread will reset bus for searching -and slave device will be even removed, but in this case 0xff will -be read, since no device was selected. +If there is no driver for the family, a simple sysfs entry is created +for the slave device. W1 device families @@ -100,5 +89,4 @@ driver - (standard) symlink to the w1 driver name - the device name, usually the same as the directory name w1_slave - (optional) a binary file whose meaning depends on the family driver -rw - (optional) created for slave devices which do not have - appropriate family driver. Allows to read/write binary data. + diff --git a/trunk/Documentation/w1/w1.netlink b/trunk/Documentation/w1/w1.netlink deleted file mode 100644 index 3640c7c87d45..000000000000 --- a/trunk/Documentation/w1/w1.netlink +++ /dev/null @@ -1,98 +0,0 @@ -Userspace communication protocol over connector [1]. - - -Message types. -============= - -There are three types of messages between w1 core and userspace: -1. Events. They are generated each time new master or slave device found - either due to automatic or requested search. -2. Userspace commands. Includes read/write and search/alarm search comamnds. -3. Replies to userspace commands. - - -Protocol. -======== - -[struct cn_msg] - connector header. It's length field is equal to size of the attached data. -[struct w1_netlink_msg] - w1 netlink header. - __u8 type - message type. - W1_SLAVE_ADD/W1_SLAVE_REMOVE - slave add/remove events. - W1_MASTER_ADD/W1_MASTER_REMOVE - master add/remove events. - W1_MASTER_CMD - userspace command for bus master device (search/alarm search). - W1_SLAVE_CMD - userspace command for slave device (read/write/ search/alarm search - for bus master device where given slave device found). - __u8 res - reserved - __u16 len - size of attached to this header data. - union { - __u8 id; - slave unique device id - struct w1_mst { - __u32 id; - master's id. - __u32 res; - reserved - } mst; - } id; - -[strucrt w1_netlink_cmd] - command for gived master or slave device. - __u8 cmd - command opcode. - W1_CMD_READ - read command. - W1_CMD_WRITE - write command. - W1_CMD_SEARCH - search command. - W1_CMD_ALARM_SEARCH - alarm search command. - __u8 res - reserved - __u16 len - length of data for this command. - For read command data must be allocated like for write command. - __u8 data[0] - data for this command. - - -Each connector message can include one or more w1_netlink_msg with zero of more attached w1_netlink_cmd messages. - -For event messages there are no w1_netlink_cmd embedded structures, only connector header -and w1_netlink_msg strucutre with "len" field being zero and filled type (one of event types) -and id - either 8 bytes of slave unique id in host order, or master's id, which is assigned -to bus master device when it is added to w1 core. - -Currently replies to userspace commands are only generated for read command request. -One reply is generated exactly for one w1_netlink_cmd read request. -Replies are not combined when sent - i.e. typical reply messages looks like the following: -[cn_msg][w1_netlink_msg][w1_netlink_cmd] -cn_msg.len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd) + cmd->len; -w1_netlink_msg.len = sizeof(struct w1_netlink_cmd) + cmd->len; -w1_netlink_cmd.len = cmd->len; - - -Operation steps in w1 core when new command is received. -======================================================= - -When new message (w1_netlink_msg) is received w1 core detects if it is master of slave request, -according to w1_netlink_msg.type field. -Then master or slave device is searched for. -When found, master device (requested or those one on where slave device is found) is locked. -If slave command is requested, then reset/select procedure is started to select given device. - -Then all requested in w1_netlink_msg operations are performed one by one. -If command requires reply (like read command) it is sent on command completion. - -When all commands (w1_netlink_cmd) are processed muster device is unlocked -and next w1_netlink_msg header processing started. - - -Connector [1] specific documentation. -==================================== - -Each connector message includes two u32 fields as "address". -w1 uses CN_W1_IDX and CN_W1_VAL defined in include/linux/connector.h header. -Each message also includes sequence and acknowledge numbers. -Sequence number for event messages is appropriate bus master sequence number increased with -each event message sent "through" this master. -Sequence number for userspace requests is set by userspace application. -Sequence number for reply is the same as was in request, and -acknowledge number is set to seq+1. - - -Additional documantion, source code examples. -============================================ - -1. Documentation/connector -2. http://tservice.net.ru/~s0mbre/archive/w1 -This archive includes userspace application w1d.c which -uses read/write/search commands for all master/slave devices found on the bus. diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 6887d44d2661..f2cd6ef53ff3 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -205,27 +205,6 @@ IOMMU pages Prereserve that many 128K pages for the software IO bounce buffering. force Force all IO through the software TLB. - calgary=[64k,128k,256k,512k,1M,2M,4M,8M] - calgary=[translate_empty_slots] - calgary=[disable=] - - 64k,...,8M - Set the size of each PCI slot's translation table - when using the Calgary IOMMU. This is the size of the translation - table itself in main memory. The smallest table, 64k, covers an IO - space of 32MB; the largest, 8MB table, can cover an IO space of - 4GB. Normally the kernel will make the right choice by itself. - - translate_empty_slots - Enable translation even on slots that have - no devices attached to them, in case a device will be hotplugged - in the future. - - disable= - Disable translation on a given PHB. For - example, the built-in graphics adapter resides on the first bridge - (PCI bus number 0); if translation (isolation) is enabled on this - bridge, X servers that access the hardware directly from user - space might stop working. Use this option if you have devices that - are accessed from userspace directly on some PCI host bridge. - Debugging oops=panic Always panic on oopses. Default is to just kill the process, diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 31a13720f23c..ce37c4b1ef94 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -181,12 +181,6 @@ M: bcrl@kvack.org L: linux-aio@kvack.org S: Supported -ABIT UGURU HARDWARE MONITOR DRIVER -P: Hans de Goede -M: j.w.r.degoede@hhs.nl -L: lm-sensors@lm-sensors.org -S: Maintained - ACENIC DRIVER P: Jes Sorensen M: jes@trained-monkey.org @@ -574,12 +568,6 @@ L: linuxppc-dev@ozlabs.org W: http://www.penguinppc.org/ppc64/ S: Supported -BROADCOM B44 10/100 ETHERNET DRIVER -P: Gary Zambrano -M: zambrano@broadcom.com -L: netdev@vger.kernel.org -S: Supported - BROADCOM BNX2 GIGABIT ETHERNET DRIVER P: Michael Chan M: mchan@broadcom.com @@ -1118,11 +1106,6 @@ L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.nu/ S: Maintained -HARDWARE RANDOM NUMBER GENERATOR CORE -P: Michael Buesch -M: mb@bu3sch.de -S: Maintained - HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER P: Robert Love M: rlove@rlove.org @@ -1164,12 +1147,6 @@ L: linux-hams@vger.kernel.org W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/ S: Maintained -HIGHPOINT ROCKETRAID 3xxx RAID DRIVER -P: HighPoint Linux Team -M: linux@highpoint-tech.com -W: http://www.highpoint-tech.com -S: Supported - HIPPI P: Jes Sorensen M: jes@trained-monkey.org @@ -1401,8 +1378,7 @@ S: Supported INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS P: Dmitry Torokhov -M: dmitry.torokhov@gmail.com -M: dtor@mail.ru +M: dtor_core@ameritech.net L: linux-input@atrey.karlin.mff.cuni.cz L: linux-joystick@atrey.karlin.mff.cuni.cz T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git @@ -1442,11 +1418,6 @@ P: Tigran Aivazian M: tigran@veritas.com S: Maintained -INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT -P: Deepak Saxena -M: dsaxena@plexity.net -S: Maintained - INTEL PRO/100 ETHERNET SUPPORT P: John Ronciak M: john.ronciak@intel.com @@ -2080,12 +2051,6 @@ M: adaplas@pol.net L: linux-fbdev-devel@lists.sourceforge.net S: Maintained -OPENCORES I2C BUS DRIVER -P: Peter Korsgaard -M: jacmet@sunsite.dk -L: lm-sensors@lm-sensors.org -S: Maintained - ORACLE CLUSTER FILESYSTEM 2 (OCFS2) P: Mark Fasheh M: mark.fasheh@oracle.com @@ -2557,6 +2522,12 @@ M: thomas@winischhofer.net W: http://www.winischhofer.at/linuxsisusbvga.shtml S: Maintained +SMSC47M1 HARDWARE MONITOR DRIVER +P: Jean Delvare +M: khali@linux-fr.org +L: lm-sensors@lm-sensors.org +S: Odd Fixes + SMB FILESYSTEM P: Urban Widmark M: urban@teststation.com @@ -2736,11 +2707,6 @@ P: Christoph Hellwig M: hch@infradead.org S: Maintained -TI OMAP RANDOM NUMBER GENERATOR SUPPORT -P: Deepak Saxena -M: dsaxena@plexity.net -S: Maintained - TI PARALLEL LINK CABLE DRIVER P: Romain Lievin M: roms@lpg.ticalc.org @@ -3174,6 +3140,12 @@ L: wbsd-devel@list.drzeus.cx W: http://projects.drzeus.cx/wbsd S: Maintained +W83L785TS HARDWARE MONITOR DRIVER +P: Jean Delvare +M: khali@linux-fr.org +L: lm-sensors@lm-sensors.org +S: Odd Fixes + WATCHDOG DEVICE DRIVERS P: Wim Van Sebroeck M: wim@iguana.be @@ -3213,7 +3185,7 @@ XFS FILESYSTEM P: Silicon Graphics Inc M: xfs-masters@oss.sgi.com M: nathans@sgi.com -L: xfs@oss.sgi.com +L: linux-xfs@oss.sgi.com W: http://oss.sgi.com/projects/xfs S: Supported diff --git a/trunk/Makefile b/trunk/Makefile index e9560c6f8156..1700d3f6ea22 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -71,7 +71,7 @@ endif # In both cases the working directory must be the root of the kernel src. # 1) O= # Use "make O=dir/to/store/output/files/" -# +# # 2) Set KBUILD_OUTPUT # Set the environment variable KBUILD_OUTPUT to point to the directory # where the output files shall be placed. @@ -178,20 +178,18 @@ CROSS_COMPILE ?= # Architecture as present in compile.h UTS_MACHINE := $(ARCH) -KCONFIG_CONFIG ?= .config - # SHELL used by kbuild CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ else echo sh; fi ; fi) -HOSTCC = gcc -HOSTCXX = g++ -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -HOSTCXXFLAGS = -O2 +HOSTCC = gcc +HOSTCXX = g++ +HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCXXFLAGS = -O2 -# Decide whether to build built-in, modular, or both. -# Normally, just do built-in. +# Decide whether to build built-in, modular, or both. +# Normally, just do built-in. KBUILD_MODULES := KBUILD_BUILTIN := 1 @@ -199,7 +197,7 @@ KBUILD_BUILTIN := 1 # If we have only "make modules", don't compile built-in objects. # When we're building modules with modversions, we need to consider # the built-in objects during the descend as well, in order to -# make sure the checksums are up to date before we record them. +# make sure the checksums are uptodate before we record them. ifeq ($(MAKECMDGOALS),modules) KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) @@ -232,7 +230,7 @@ export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD # # If $(quiet) is empty, the whole command will be printed. # If it is set to "quiet_", only the short version will be printed. -# If it is set to "silent_", nothing will be printed at all, since +# If it is set to "silent_", nothing wil be printed at all, since # the variable $(silent_cmd_cc_o_c) doesn't exist. # # A simple variant is to prefix commands with $(Q) - that's useful @@ -267,9 +265,10 @@ MAKEFLAGS += --include-dir=$(srctree) # We need some generic definitions include $(srctree)/scripts/Kbuild.include -# Do not use make's built-in rules and variables -# This increases performance and avoid hard-to-debug behavour -MAKEFLAGS += -rR +# For maximum performance (+ possibly random breakage, uncomment +# the following) + +#MAKEFLAGS += -rR # Make variables (CC, etc...) @@ -306,21 +305,21 @@ LINUXINCLUDE := -Iinclude \ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) -CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -fno-common -AFLAGS := -D__ASSEMBLY__ +CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common +AFLAGS := -D__ASSEMBLY__ -# Read KERNELRELEASE from include/config/kernel.release (if it exists) -KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) +# Read KERNELRELEASE from .kernelrelease (if it exists) +KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null) KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) -export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION -export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC -export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE -export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS +export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \ + ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \ + CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \ + HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS -export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE +export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE # When compiling out-of-tree modules, put MODVERDIR in the module @@ -358,13 +357,12 @@ endif # catch them early, and hand them over to scripts/kconfig/Makefile # It is allowed to specify more targets when calling make, including # mixing *config targets and build targets. -# For example 'make oldconfig all'. +# For example 'make oldconfig all'. # Detect when mixed targets is specified, and make a second invocation # of make so .config is not included in this case either (for *config). no-dot-config-targets := clean mrproper distclean \ - cscope TAGS tags help %docs check% \ - kernelrelease kernelversion + cscope TAGS tags help %docs check% config-targets := 0 mixed-targets := 0 @@ -406,8 +404,9 @@ include $(srctree)/arch/$(ARCH)/Makefile export KBUILD_DEFCONFIG config %config: scripts_basic outputmakefile FORCE - $(Q)mkdir -p include/linux include/config + $(Q)mkdir -p include/linux $(Q)$(MAKE) $(build)=scripts/kconfig $@ + $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease else # =========================================================================== @@ -417,11 +416,13 @@ else ifeq ($(KBUILD_EXTMOD),) # Additional helpers built in scripts/ # Carefully list dependencies so we do not try to build scripts twice -# in parallel +# in parrallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf +scripts: scripts_basic include/config/MARKER $(Q)$(MAKE) $(build)=$(@) +scripts_basic: include/linux/autoconf.h + # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ drivers-y := drivers/ sound/ @@ -435,32 +436,31 @@ ifeq ($(dot-config),1) # Read in dependencies to all Kconfig* files, make sure to run # oldconfig if changes are detected. --include include/config/auto.conf.cmd --include include/config/auto.conf +-include .kconfig.d +include .config + +# If .config needs to be updated, it will be done via the dependency +# that autoconf has on .config. # To avoid any implicit rule to kick in, define an empty command -$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; +.config .kconfig.d: ; -# If .config is newer than include/config/auto.conf, someone tinkered +# If .config is newer than include/linux/autoconf.h, someone tinkered # with it and forgot to run make oldconfig. -# if auto.conf.cmd is missing then we are probably in a cleaned tree so +# If kconfig.d is missing then we are probarly in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd -ifeq ($(KBUILD_EXTMOD),) +include/linux/autoconf.h: .kconfig.d .config + $(Q)mkdir -p include/linux $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig -else - $(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it) -endif - else # Dummy target needed, because used as prerequisite -include/config/auto.conf: ; +include/linux/autoconf.h: ; endif # The all: target is the default when no target is given on the # command line. # This allow a user to issue only 'make' to build a kernel including modules -# Defaults vmlinux but it is usually overridden in the arch makefile +# Defaults vmlinux but it is usually overriden in the arch makefile all: vmlinux ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE @@ -492,11 +492,11 @@ CHECKFLAGS += $(NOSTDINC_FLAGS) # warn about C99 declaration after statement CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) -# disable pointer signed / unsigned warnings in gcc 4.0 +# disable pointer signedness warnings in gcc 4.0 CFLAGS += $(call cc-option,-Wno-pointer-sign,) # Default kernel image to build when no specific target is given. -# KBUILD_IMAGE may be overruled on the command line or +# KBUILD_IMAGE may be overruled on the commandline or # set in the environment # Also any assignments in arch/$(ARCH)/Makefile take precedence over # this default value @@ -510,29 +510,12 @@ export INSTALL_PATH ?= /boot # # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory # relocations required by build roots. This is not defined in the -# makefile but the argument can be passed to make if needed. +# makefile but the arguement can be passed to make if needed. # MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB -# -# INSTALL_MOD_STRIP, if defined, will cause modules to be -# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then -# the default option --strip-debug will be used. Otherwise, -# INSTALL_MOD_STRIP will used as the options to the strip command. - -ifdef INSTALL_MOD_STRIP -ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $STRIP) --strip-debug -else -mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) -endif # INSTALL_MOD_STRIP=1 -else -mod_strip_cmd = true -endif # INSTALL_MOD_STRIP -export mod_strip_cmd - ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ @@ -556,7 +539,7 @@ libs-y := $(libs-y1) $(libs-y2) # Build vmlinux # --------------------------------------------------------------------------- -# vmlinux is built from the objects selected by $(vmlinux-init) and +# vmlinux is build from the objects selected by $(vmlinux-init) and # $(vmlinux-main). Most are built-in.o files from top-level directories # in the kernel tree, others are specified in arch/$(ARCH)Makefile. # Ordering when linking is important, and $(vmlinux-init) must be first. @@ -607,7 +590,7 @@ quiet_cmd_vmlinux_version = GEN .version $(MAKE) $(build)=init # Generate System.map -quiet_cmd_sysmap = SYSMAP +quiet_cmd_sysmap = SYSMAP cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap # Link of vmlinux @@ -736,7 +719,7 @@ $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ # Build the kernel release string -# The KERNELRELEASE is stored in a file named include/config/kernel.release +# The KERNELRELEASE is stored in a file named .kernelrelease # to be used when executing for example make install or make modules_install # # Take the contents of any files called localversion* and the config @@ -754,10 +737,10 @@ _localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f))) localver = $(subst $(space),, \ $(shell cat /dev/null $(_localver)) \ $(patsubst "%",%,$(CONFIG_LOCALVERSION))) - + # If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called # and if the SCM is know a tag from the SCM is appended. -# The appended tag is determined by the SCM used. +# The appended tag is determinded by the SCM used. # # Currently, only git is supported. # Other SCMs can edit scripts/setlocalversion and add the appropriate @@ -770,9 +753,9 @@ endif localver-full = $(localver)$(localver-auto) -# Store (new) KERNELRELASE string in include/config/kernel.release +# Store (new) KERNELRELASE string in .kernelrelease kernelrelease = $(KERNELVERSION)$(localver-full) -include/config/kernel.release: include/config/auto.conf FORCE +.kernelrelease: FORCE $(Q)rm -f $@ $(Q)echo $(kernelrelease) > $@ @@ -793,10 +776,10 @@ PHONY += prepare-all # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) # 2) Create the include2 directory, used for the second asm symlink -prepare3: include/config/kernel.release +prepare3: .kernelrelease ifneq ($(KBUILD_SRC),) @echo ' Using $(srctree) as source for kernel' - $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ + $(Q)if [ -f $(srctree)/.config ]; then \ echo " $(srctree) is not clean, please run 'make mrproper'";\ echo " in the '$(srctree)' directory.";\ /bin/false; \ @@ -809,7 +792,7 @@ endif prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/asm \ - include/config/auto.conf + include/config/MARKER ifneq ($(KBUILD_MODULES),) $(Q)mkdir -p $(MODVERDIR) $(Q)rm -f $(MODVERDIR)/* @@ -823,20 +806,27 @@ prepare0: archprepare FORCE # All the preparing.. prepare prepare-all: prepare0 -# Leave this as default for preprocessing vmlinux.lds.S, which is now -# done in arch/$(ARCH)/kernel/Makefile +# Leave this as default for preprocessing vmlinux.lds.S, which is now +# done in arch/$(ARCH)/kernel/Makefile export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) -# FIXME: The asm symlink changes when $(ARCH) changes. That's -# hard to detect, but I suppose "make mrproper" is a good idea -# before switching between archs anyway. +# FIXME: The asm symlink changes when $(ARCH) changes. That's +# hard to detect, but I suppose "make mrproper" is a good idea +# before switching between archs anyway. include/asm: @echo ' SYMLINK $@ -> include/asm-$(ARCH)' $(Q)if [ ! -d include ]; then mkdir -p include; fi; @ln -fsn asm-$(ARCH) $@ +# Split autoconf.h into include/linux/config/* + +include/config/MARKER: scripts/basic/split-include include/linux/autoconf.h + @echo ' SPLIT include/linux/autoconf.h -> include/config/*' + @scripts/basic/split-include include/linux/autoconf.h include/config + @touch $@ + # Generate some files # --------------------------------------------------------------------------- @@ -856,7 +846,7 @@ define filechk_version.h ) endef -include/linux/version.h: $(srctree)/Makefile include/config/kernel.release FORCE +include/linux/version.h: $(srctree)/Makefile .config .kernelrelease FORCE $(call filechk,version.h) # --------------------------------------------------------------------------- @@ -870,7 +860,7 @@ depend dep: ifdef CONFIG_MODULES -# By default, build modules as well +# By default, build modules as well all: modules @@ -952,7 +942,7 @@ CLEAN_FILES += vmlinux System.map \ MRPROPER_DIRS += include/config include2 MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ - Module.symvers tags TAGS cscope* + .kernelrelease Module.symvers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules # @@ -968,9 +958,8 @@ clean: archclean $(clean-dirs) $(call cmd,rmdirs) $(call cmd,rmfiles) @find . $(RCS_FIND_IGNORE) \ - \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ - -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ - -o -name '*.symtypes' \) \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -993,9 +982,9 @@ PHONY += distclean distclean: mrproper @find $(srctree) $(RCS_FIND_IGNORE) \ - \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ + \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ - -o -name '.*.rej' -o -size 0 \ + -o -name '.*.rej' -o -size 0 \ -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ -type f -print | xargs rm -f @@ -1005,9 +994,9 @@ distclean: mrproper # rpm target kept for backward compatibility package-dir := $(srctree)/scripts/package -%pkg: include/config/kernel.release FORCE +%pkg: FORCE $(Q)$(MAKE) $(build)=$(package-dir) $@ -rpm: include/config/kernel.release FORCE +rpm: FORCE $(Q)$(MAKE) $(build)=$(package-dir) $@ @@ -1088,7 +1077,7 @@ else # KBUILD_EXTMOD # make M=dir modules Make all modules in specified dir # make M=dir Same as 'make M=dir modules' # make M=dir modules_install -# Install the modules built in the module directory +# Install the modules build in the module directory # Assumes install directory is already created # We are always building modules @@ -1147,7 +1136,7 @@ clean: rm-dirs := $(MODVERDIR) clean: $(clean-dirs) $(call cmd,rmdirs) @find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \ - \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -type f -print | xargs rm -f @@ -1186,41 +1175,31 @@ else ALLINCLUDE_ARCHS := $(ARCH) endif else -#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour. +#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) endif ALLSOURCE_ARCHS := $(ARCH) -define find-sources - ( find $(__srctree) $(RCS_FIND_IGNORE) \ +define all-sources + ( find $(__srctree) $(RCS_FIND_IGNORE) \ \( -name include -o -name arch \) -prune -o \ - -name $1 -print; \ + -name '*.[chS]' -print; \ for ARCH in $(ALLSOURCE_ARCHS) ; do \ find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \ - -name $1 -print; \ + -name '*.[chS]' -print; \ done ; \ find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \ - -name $1 -print; \ + -name '*.[chS]' -print; \ find $(__srctree)include $(RCS_FIND_IGNORE) \ \( -name config -o -name 'asm-*' \) -prune \ - -o -name $1 -print; \ + -o -name '*.[chS]' -print; \ for ARCH in $(ALLINCLUDE_ARCHS) ; do \ find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \ - -name $1 -print; \ + -name '*.[chS]' -print; \ done ; \ find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ - -name $1 -print ) -endef - -define all-sources - $(call find-sources,'*.[chS]') -endef -define all-kconfigs - $(call find-sources,'Kconfig*') -endef -define all-defconfigs - $(call find-sources,'defconfig') + -name '*.[chS]' -print ) endef quiet_cmd_cscope-file = FILELST cscope.files @@ -1240,13 +1219,7 @@ define cmd_TAGS echo "-I __initdata,__exitdata,__acquires,__releases \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ --extra=+f --c-kinds=+px"`; \ - $(all-sources) | xargs etags $$ETAGSF -a; \ - if test "x$$ETAGSF" = x; then \ - $(all-kconfigs) | xargs etags -a \ - --regex='/^config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \ - $(all-defconfigs) | xargs etags -a \ - --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \ - fi + $(all-sources) | xargs etags $$ETAGSF -a endef TAGS: FORCE @@ -1286,14 +1259,14 @@ namespacecheck: endif #ifeq ($(config-targets),1) endif #ifeq ($(mixed-targets),1) -PHONY += checkstack kernelrelease kernelversion +PHONY += checkstack checkstack: $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ $(PERL) $(src)/scripts/checkstack.pl $(ARCH) kernelrelease: - $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \ - $(error kernelrelease not valid - run 'make prepare' to update it)) + $(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \ + $(error kernelrelease not valid - run 'make *config' to update it)) kernelversion: @echo $(KERNELVERSION) @@ -1328,8 +1301,6 @@ endif $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) %.o: %.S prepare scripts FORCE $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.symtypes: %.c prepare scripts FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) # Modules / %/: prepare scripts FORCE diff --git a/trunk/arch/alpha/kernel/alpha_ksyms.c b/trunk/arch/alpha/kernel/alpha_ksyms.c index d3848c5b0d2b..2b245ad731ee 100644 --- a/trunk/arch/alpha/kernel/alpha_ksyms.c +++ b/trunk/arch/alpha/kernel/alpha_ksyms.c @@ -53,6 +53,10 @@ extern void __divqu (void); extern void __remqu (void); EXPORT_SYMBOL(alpha_mv); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(disable_irq_nosync); +EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(screen_info); EXPORT_SYMBOL(perf_irq); EXPORT_SYMBOL(callback_getenv); @@ -64,13 +68,19 @@ EXPORT_SYMBOL(alpha_using_srm); /* platform dependent support */ EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(__memsetw); @@ -112,9 +122,11 @@ EXPORT_SYMBOL(alpha_write_fp_reg_s); /* In-kernel system calls. */ EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(sys_open); EXPORT_SYMBOL(sys_dup); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_read); EXPORT_SYMBOL(sys_lseek); EXPORT_SYMBOL(execve); EXPORT_SYMBOL(sys_setsid); diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index e15dcf4f3dcd..31afe3d91ac6 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -244,7 +244,7 @@ do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer, unsigned long bufsiz) { struct kstatfs linux_stat; - int error = vfs_statfs(dentry, &linux_stat); + int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat); if (!error) error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); return error; diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 254c507a608c..558b83368559 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -481,7 +481,7 @@ register_cpus(void) struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; - register_cpu(p, i); + register_cpu(p, i, NULL); } return 0; } diff --git a/trunk/arch/alpha/kernel/signal.c b/trunk/arch/alpha/kernel/signal.c index 741da0945dc4..2e45e8604e32 100644 --- a/trunk/arch/alpha/kernel/signal.c +++ b/trunk/arch/alpha/kernel/signal.c @@ -375,7 +375,7 @@ do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs, static inline void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) { - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void __user *)((sp - frame_size) & -32ul); diff --git a/trunk/arch/alpha/oprofile/common.c b/trunk/arch/alpha/oprofile/common.c index 9fc0eeb4f0ab..ba788cfdc3c6 100644 --- a/trunk/arch/alpha/oprofile/common.c +++ b/trunk/arch/alpha/oprofile/common.c @@ -112,7 +112,7 @@ op_axp_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[4]; + char buf[3]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 3d1a3fb7d5fc..1b7e5c2e90ef 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -253,7 +253,7 @@ config ARCH_SA1100 Support for StrongARM 11x0 based boards. config ARCH_S3C2410 - bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442" + bool "Samsung S3C2410" help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (), the IPAQ 1940 or @@ -372,7 +372,7 @@ config ISA_DMA_API bool config PCI - bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX + bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index a3bbaaf480b9..282b14e2f464 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -177,7 +177,7 @@ boot := arch/arm/boot # them changed. We use .arch to indicate when they were updated # last, otherwise make uses the target directory mtime. -include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf +include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/MARKER @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-arm diff --git a/trunk/arch/arm/boot/compressed/head-at91rm9200.S b/trunk/arch/arm/boot/compressed/head-at91rm9200.S index d68b9acd826e..57a3b163b2cb 100644 --- a/trunk/arch/arm/boot/compressed/head-at91rm9200.S +++ b/trunk/arch/arm/boot/compressed/head-at91rm9200.S @@ -61,12 +61,6 @@ cmp r7, r3 beq 99f - @ Ajeco 1ARM : 1075 - mov r3, #(MACH_TYPE_ONEARM & 0xff) - orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00) - cmp r7, r3 - beq 99f - @ Unknown board, use the AT91RM9200DK board @ mov r7, #MACH_TYPE_AT91RM9200 mov r7, #(MACH_TYPE_AT91RM9200DK & 0xff) diff --git a/trunk/arch/arm/boot/compressed/ll_char_wr.S b/trunk/arch/arm/boot/compressed/ll_char_wr.S index 8517c8606b4a..d7bbd9da2fca 100644 --- a/trunk/arch/arm/boot/compressed/ll_char_wr.S +++ b/trunk/arch/arm/boot/compressed/ll_char_wr.S @@ -77,7 +77,7 @@ Lrow4bpplp: subne r1, r1, #1 ldrneb r7, [r6, r1] bne Lrow4bpplp - ldmfd sp!, {r4 - r7, pc} + LOADREGS(fd, sp!, {r4 - r7, pc}) @ @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) @@ -105,7 +105,7 @@ Lrow8bpplp: subne r1, r1, #1 ldrneb r7, [r6, r1] bne Lrow8bpplp - ldmfd sp!, {r4 - r7, pc} + LOADREGS(fd, sp!, {r4 - r7, pc}) @ @ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc) @@ -127,7 +127,7 @@ Lrow1bpp: strb r7, [r0], r5 mov r7, r7, lsr #8 strb r7, [r0], r5 - ldmfd sp!, {r4 - r7, pc} + LOADREGS(fd, sp!, {r4 - r7, pc}) .bss ENTRY(con_charconvtable) diff --git a/trunk/arch/arm/common/Makefile b/trunk/arch/arm/common/Makefile index e1289a256ce5..847e3e6356c6 100644 --- a/trunk/arch/arm/common/Makefile +++ b/trunk/arch/arm/common/Makefile @@ -16,4 +16,3 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_ARCH_IXP2000) += uengine.o -obj-$(CONFIG_ARCH_IXP23XX) += uengine.o diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 5b7c26395b44..7971d0dc6892 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -77,8 +77,6 @@ struct dmabounce_device_info { #endif struct dmabounce_pool small; struct dmabounce_pool large; - - rwlock_t lock; }; static LIST_HEAD(dmabounce_devs); @@ -118,7 +116,6 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr, struct safe_buffer *buf; struct dmabounce_pool *pool; struct device *dev = device_info->dev; - unsigned long flags; dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", __func__, ptr, size, dir); @@ -166,12 +163,8 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr, print_alloc_stats(device_info); #endif - write_lock_irqsave(&device_info->lock, flags); - list_add(&buf->node, &device_info->safe_buffers); - write_unlock_irqrestore(&device_info->lock, flags); - return buf; } @@ -179,32 +172,22 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr, static inline struct safe_buffer * find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr) { - struct safe_buffer *b = NULL; - unsigned long flags; - - read_lock_irqsave(&device_info->lock, flags); + struct safe_buffer *b; list_for_each_entry(b, &device_info->safe_buffers, node) if (b->safe_dma_addr == safe_dma_addr) - break; + return b; - read_unlock_irqrestore(&device_info->lock, flags); - return b; + return NULL; } static inline void free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf) { - unsigned long flags; - dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf); - write_lock_irqsave(&device_info->lock, flags); - list_del(&buf->node); - write_unlock_irqrestore(&device_info->lock, flags); - if (buf->pool) dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr); else @@ -413,6 +396,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) { + unsigned long flags; dma_addr_t dma_addr; dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", @@ -420,8 +404,12 @@ dma_map_single(struct device *dev, void *ptr, size_t size, BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + dma_addr = map_single(dev, ptr, size, dir); + local_irq_restore(flags); + return dma_addr; } @@ -436,18 +424,25 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { + unsigned long flags; + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, (void *) dma_addr, size, dir); BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + unmap_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); } int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { + unsigned long flags; int i; dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", @@ -455,6 +450,8 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + for (i = 0; i < nents; i++, sg++) { struct page *page = sg->page; unsigned int offset = sg->offset; @@ -465,6 +462,8 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, map_single(dev, ptr, length, dir); } + local_irq_restore(flags); + return nents; } @@ -472,6 +471,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { + unsigned long flags; int i; dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", @@ -479,38 +479,55 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; unsigned int length = sg->length; unmap_single(dev, dma_addr, length, dir); } + + local_irq_restore(flags); } void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { + unsigned long flags; + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, (void *) dma_addr, size, dir); + local_irq_save(flags); + sync_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); } void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { + unsigned long flags; + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, (void *) dma_addr, size, dir); + local_irq_save(flags); + sync_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); } void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { + unsigned long flags; int i; dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", @@ -518,18 +535,23 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; unsigned int length = sg->length; sync_single(dev, dma_addr, length, dir); } + + local_irq_restore(flags); } void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { + unsigned long flags; int i; dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", @@ -537,12 +559,16 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, BUG_ON(dir == DMA_NONE); + local_irq_save(flags); + for (i = 0; i < nents; i++, sg++) { dma_addr_t dma_addr = sg->dma_address; unsigned int length = sg->length; sync_single(dev, dma_addr, length, dir); } + + local_irq_restore(flags); } static int @@ -596,7 +622,6 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, device_info->dev = dev; INIT_LIST_HEAD(&device_info->safe_buffers); - rwlock_init(&device_info->lock); #ifdef STATS device_info->total_allocs = 0; diff --git a/trunk/arch/arm/common/locomo.c b/trunk/arch/arm/common/locomo.c index 0dafba3a701d..a7dc1370695b 100644 --- a/trunk/arch/arm/common/locomo.c +++ b/trunk/arch/arm/common/locomo.c @@ -629,6 +629,21 @@ static int locomo_resume(struct platform_device *dev) #endif +#define LCM_ALC_EN 0x8000 + +void frontlight_set(struct locomo *lchip, int duty, int vr, int bpwf) +{ + unsigned long flags; + + spin_lock_irqsave(&lchip->lock, flags); + locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + udelay(100); + locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); + locomo_writel(bpwf | LCM_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + spin_unlock_irqrestore(&lchip->lock, flags); +} + + /** * locomo_probe - probe for a single LoCoMo chip. * @phys_addr: physical address of device. @@ -683,10 +698,14 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) , lchip->base + LOCOMO_GPD); locomo_writel(0, lchip->base + LOCOMO_GIE); - /* Frontlight */ + /* FrontLight */ locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); + /* Same constants can be used for collie and poodle + (depending on CONFIG options in original sharp code)? */ + frontlight_set(lchip, 163, 0, 148); + /* Longtime timer */ locomo_writel(0, lchip->base + LOCOMO_LTINT); /* SPI */ @@ -1043,30 +1062,6 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int spin_unlock_irqrestore(&lchip->lock, flags); } -/* - * Frontlight control - */ - -static struct locomo *locomo_chip_driver(struct locomo_dev *ldev); - -void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf) -{ - unsigned long flags; - struct locomo *lchip = locomo_chip_driver(dev); - - if (vr) - locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1); - else - locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); - - spin_lock_irqsave(&lchip->lock, flags); - locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); - udelay(100); - locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); - locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); - spin_unlock_irqrestore(&lchip->lock, flags); -} - /* * LoCoMo "Register Access Bus." * diff --git a/trunk/arch/arm/common/uengine.c b/trunk/arch/arm/common/uengine.c index dfca596a9a27..a1310b71004e 100644 --- a/trunk/arch/arm/common/uengine.c +++ b/trunk/arch/arm/common/uengine.c @@ -18,26 +18,10 @@ #include #include #include -#include +#include #include #include -#if defined(CONFIG_ARCH_IXP2000) -#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE -#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID -#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL -#define IXP_RESET1 IXP2000_RESET1 -#else -#if defined(CONFIG_ARCH_IXP23XX) -#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE -#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID -#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL -#define IXP_RESET1 IXP23XX_RESET1 -#else -#error unknown platform -#endif -#endif - #define USTORE_ADDRESS 0x000 #define USTORE_DATA_LOWER 0x004 #define USTORE_DATA_UPPER 0x008 @@ -59,7 +43,7 @@ u32 ixp2000_uengine_mask; static void *ixp2000_uengine_csr_area(int uengine) { - return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10); + return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10); } /* @@ -107,13 +91,8 @@ EXPORT_SYMBOL(ixp2000_uengine_csr_write); void ixp2000_uengine_reset(u32 uengine_mask) { - u32 value; - - value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask; - - uengine_mask &= ixp2000_uengine_mask; - ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask); - ixp2000_reg_wrb(IXP_RESET1, value); + ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask); + ixp2000_reg_wrb(IXP2000_RESET1, 0); } EXPORT_SYMBOL(ixp2000_uengine_reset); @@ -256,12 +235,11 @@ static int check_ixp_type(struct ixp2000_uengine_code *c) u32 product_id; u32 rev; - product_id = ixp2000_reg_read(IXP_PRODUCT_ID); + product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID); if (((product_id >> 16) & 0x1f) != 0) return 0; switch ((product_id >> 8) & 0xff) { -#ifdef CONFIG_ARCH_IXP2000 case 0: /* IXP2800 */ if (!(c->cpu_model_bitmask & 4)) return 0; @@ -276,14 +254,6 @@ static int check_ixp_type(struct ixp2000_uengine_code *c) if (!(c->cpu_model_bitmask & 2)) return 0; break; -#endif - -#ifdef CONFIG_ARCH_IXP23XX - case 4: /* IXP23xx */ - if (!(c->cpu_model_bitmask & 0x3f0)) - return 0; - break; -#endif default: return 0; @@ -462,8 +432,7 @@ static int __init ixp2000_uengine_init(void) /* * Determine number of microengines present. */ - switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) { -#ifdef CONFIG_ARCH_IXP2000 + switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) { case 0: /* IXP2800 */ case 1: /* IXP2850 */ ixp2000_uengine_mask = 0x00ff00ff; @@ -472,17 +441,10 @@ static int __init ixp2000_uengine_init(void) case 2: /* IXP2400 */ ixp2000_uengine_mask = 0x000f000f; break; -#endif - -#ifdef CONFIG_ARCH_IXP23XX - case 4: /* IXP23xx */ - ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf; - break; -#endif default: printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n", - (unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID)); + (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID)); ixp2000_uengine_mask = 0x00000000; break; } @@ -495,15 +457,15 @@ static int __init ixp2000_uengine_init(void) /* * Synchronise timestamp counters across all microengines. */ - value = ixp2000_reg_read(IXP_MISC_CONTROL); - ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80); + value = ixp2000_reg_read(IXP2000_MISC_CONTROL); + ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80); for (uengine = 0; uengine < 32; uengine++) { if (ixp2000_uengine_mask & (1 << uengine)) { ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); } } - ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80); + ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80); return 0; } diff --git a/trunk/arch/arm/configs/lpd270_defconfig b/trunk/arch/arm/configs/lpd270_defconfig deleted file mode 100644 index d08bbe59483a..000000000000 --- a/trunk/arch/arm/configs/lpd270_defconfig +++ /dev/null @@ -1,963 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git2 -# Wed Jun 21 22:20:18 2006 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_MTD_XIP=y -CONFIG_VECTORS_BASE=0xffff0000 - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91RM9200 is not set -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set -CONFIG_ARCH_PXA=y -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set - -# -# Intel PXA2xx Implementations -# -# CONFIG_ARCH_LUBBOCK is not set -CONFIG_MACH_LOGICPD_PXA270=y -# CONFIG_MACH_MAINSTONE is not set -# CONFIG_ARCH_PXA_IDP is not set -# CONFIG_PXA_SHARPSL is not set -CONFIG_PXA27x=y -CONFIG_IWMMXT=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_APM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -# CONFIG_PACKET is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -# CONFIG_MTD_CFI_I1 is not set -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_SHARP_SL is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_SMC91X=y -# CONFIG_DM9000 is not set -# CONFIG_SMC911X is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_MACMODES is not set -CONFIG_FB_FIRMWARE_EDID=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_PXA=y -# CONFIG_FB_PXA_PARAMETERS is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -CONFIG_SND_AC97_CODEC=y -CONFIG_SND_AC97_BUS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ALSA ARM devices -# -CONFIG_SND_PXA2XX_PCM=y -CONFIG_SND_PXA2XX_AC97=y - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_VFAT_FS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/arm/configs/onearm_defconfig b/trunk/arch/arm/configs/onearm_defconfig deleted file mode 100644 index 5401c01caefe..000000000000 --- a/trunk/arch/arm/configs/onearm_defconfig +++ /dev/null @@ -1,1053 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git10 -# Mon Jun 26 13:45:44 2006 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -CONFIG_ARCH_AT91RM9200=y -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set - -# -# AT91RM9200 Implementations -# - -# -# AT91RM9200 Board Type -# -CONFIG_MACH_ONEARM=y -# CONFIG_ARCH_AT91RM9200DK is not set -# CONFIG_MACH_AT91RM9200EK is not set -# CONFIG_MACH_CSB337 is not set -# CONFIG_MACH_CSB637 is not set -# CONFIG_MACH_CARMEVA is not set -# CONFIG_MACH_KB9200 is not set -# CONFIG_MACH_ATEB9200 is not set -# CONFIG_MACH_KAFA is not set - -# -# AT91RM9200 Feature Selections -# -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y - -# -# PC-card bridges -# -CONFIG_AT91_CF=y - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 -CONFIG_LEDS=y -CONFIG_LEDS_TIMER=y -# CONFIG_LEDS_CPU is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set -# CONFIG_APM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x0 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=0 -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_IMPA7 is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_ARM_AT91_ETHER=y -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_AT91=y -CONFIG_SERIAL_AT91_CONSOLE=y -# CONFIG_SERIAL_AT91_TTYAT is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y -CONFIG_USB_DEBUG=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -CONFIG_USB_GADGET_AT91=y -CONFIG_USB_AT91=y -# CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_GADGET_DUALSPEED is not set -# CONFIG_USB_ZERO 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 - -# -# MMC/SD Card support -# -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=y -CONFIG_MMC_AT91RM9200=y - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig index f20814e6f497..e17661380096 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git9 -# Sun Jun 25 23:56:32 2006 +# Linux kernel version: 2.6.17 +# Tue Jun 20 18:57:01 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -49,6 +49,7 @@ CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set +CONFIG_OBSOLETE_INTERMODULE=y # # Loadable module support @@ -80,26 +81,18 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # System Type # -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91RM9200 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -107,6 +100,14 @@ CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_NETX is not set # # S3C24XX Implementations @@ -122,14 +123,11 @@ CONFIG_ARCH_SMDK2410=y CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_SMDK2440_CPU2442=y -CONFIG_MACH_SMDK2413=y CONFIG_MACH_VR1000=y CONFIG_MACH_RX3715=y CONFIG_MACH_OTOM=y CONFIG_MACH_NEXCODER_2440=y -CONFIG_S3C2410_CLOCK=y CONFIG_CPU_S3C2410=y -CONFIG_CPU_S3C2412=y CONFIG_CPU_S3C244X=y CONFIG_CPU_S3C2440=y CONFIG_CPU_S3C2442=y @@ -155,11 +153,8 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 # CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y -CONFIG_CPU_ARM926T=y CONFIG_CPU_32v4=y -CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_ABRT_EV5TJ=y CONFIG_CPU_CACHE_V4WT=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y @@ -172,7 +167,6 @@ CONFIG_CPU_TLB_V4WBI=y # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set -# CONFIG_CPU_CACHE_ROUND_ROBIN is not set # # Bus support @@ -220,7 +214,6 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" CONFIG_FPE_NWFPE=y # CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set -# CONFIG_VFP is not set # # Userspace binary formats @@ -249,8 +242,6 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -269,8 +260,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -278,7 +267,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -333,7 +321,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -421,12 +408,10 @@ CONFIG_MTD_BAST_MAXSIZE=4 # CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_S3C2410=y # CONFIG_MTD_NAND_S3C2410_DEBUG is not set # CONFIG_MTD_NAND_S3C2410_HWECC is not set -# CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -440,8 +425,8 @@ CONFIG_MTD_NAND_S3C2410=y # CONFIG_PARPORT=y # CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_ARC is not set # CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_AX88796 is not set CONFIG_PARPORT_1284=y # @@ -750,7 +735,6 @@ CONFIG_I2C_ALGOBIT=m # # CONFIG_I2C_ELEKTOR is not set CONFIG_I2C_ISA=m -# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set CONFIG_I2C_S3C2410=y @@ -781,13 +765,13 @@ CONFIG_SENSORS_EEPROM=m # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y CONFIG_HWMON_VID=m -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -815,10 +799,8 @@ CONFIG_SENSORS_LM85=m # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set @@ -863,7 +845,6 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set CONFIG_FB_FIRMWARE_EDID=y -# CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_S1D13XXX is not set @@ -995,12 +976,10 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1045,7 +1024,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index 302fc1401547..de606dfa8db9 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -702,6 +702,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, /* * Mark this as IO */ + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (remap_pfn_range(vma, vma->vm_start, phys, diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 86c92523a346..ab8e600c18c8 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -20,7 +20,6 @@ #include #include #include -#include #include "entry-header.S" @@ -561,8 +560,10 @@ ENTRY(__switch_to) add ip, r1, #TI_CPU_SAVE ldr r3, [r2, #TI_TP_VALUE] stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack -#ifdef CONFIG_MMU - ldr r6, [r2, #TI_CPU_DOMAIN] +#ifndef CONFIG_MMU + add r2, r2, #TI_CPU_DOMAIN +#else + ldr r6, [r2, #TI_CPU_DOMAIN]! #endif #if __LINUX_ARM_ARCH__ >= 6 #ifdef CONFIG_CPU_32v6K @@ -584,20 +585,21 @@ ENTRY(__switch_to) #ifdef CONFIG_MMU mcr p15, 0, r6, c3, c0, 0 @ Set domain register #endif +#ifdef CONFIG_VFP + @ Always disable VFP so we can lazily save/restore the old + @ state. This occurs in the context of the previous thread. + VFPFMRX r4, FPEXC + bic r4, r4, #FPEXC_ENABLE + VFPFMXR FPEXC, r4 +#endif #if defined(CONFIG_IWMMXT) bl iwmmxt_task_switch #elif defined(CONFIG_CPU_XSCALE) - add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra + add r4, r2, #40 @ cpu_context_save->extra ldmib r4, {r4, r5} mar acc0, r4, r5 #endif - mov r5, r0 - add r4, r2, #TI_CPU_SAVE - ldr r0, =thread_notify_head - mov r1, #THREAD_NOTIFY_SWITCH - bl atomic_notifier_call_chain - mov r0, r5 - ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously + ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously __INIT diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 75af6d6e2f28..b5bcebca1cd6 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -340,7 +340,7 @@ sys_mmap2: streq r5, [sp, #4] beq do_mmap2 mov r0, #-EINVAL - mov pc, lr + RETINSTR(mov,pc, lr) #else str r5, [sp, #4] b do_mmap2 diff --git a/trunk/arch/arm/kernel/head-nommu.S b/trunk/arch/arm/kernel/head-nommu.S index 2af7e44218af..adf62e5eaad7 100644 --- a/trunk/arch/arm/kernel/head-nommu.S +++ b/trunk/arch/arm/kernel/head-nommu.S @@ -39,7 +39,7 @@ __INIT .type stext, %function ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 330b9476c398..04f7344e356a 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -71,7 +71,7 @@ __INIT .type stext, %function ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid @@ -104,7 +104,7 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type movs r10, r5 @ invalid processor? diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index ec20f8935e8b..bcc19fbb32df 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -52,7 +52,7 @@ */ #define MAX_IRQ_CNT 100000 -static int noirqdebug __read_mostly; +static int noirqdebug; static volatile unsigned long irq_err_count; static DEFINE_SPINLOCK(irq_controller_lock); static LIST_HEAD(irq_pending); @@ -81,7 +81,7 @@ irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs) void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { - irq_err_count++; + irq_err_count += 1; printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); } diff --git a/trunk/arch/arm/kernel/iwmmxt.S b/trunk/arch/arm/kernel/iwmmxt.S index a3bae95e536c..24c7b0477a09 100644 --- a/trunk/arch/arm/kernel/iwmmxt.S +++ b/trunk/arch/arm/kernel/iwmmxt.S @@ -273,7 +273,7 @@ ENTRY(iwmmxt_task_restore) * * r0 = previous task_struct pointer (must be preserved) * r1 = previous thread_info pointer - * r2 = next thread_info pointer (must be preserved) + * r2 = next thread_info.cpu_domain pointer (must be preserved) * * Called only from __switch_to with task preemption disabled. * No need to care about preserving r4 and above. @@ -285,7 +285,7 @@ ENTRY(iwmmxt_task_switch) bne 1f @ yes: block them for next task ldr r5, =concan_owner - add r6, r2, #TI_IWMMXT_STATE @ get next task Concan save area + add r6, r2, #(TI_IWMMXT_STATE - TI_CPU_DOMAIN) @ get next task Concan save area ldr r5, [r5] @ get current Concan owner teq r5, r6 @ next task owns it? movne pc, lr @ no: leave Concan disabled diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index e1c77ee885a7..17c38dbf2f3c 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -339,9 +338,13 @@ void exit_thread(void) { } -ATOMIC_NOTIFIER_HEAD(thread_notify_head); +static void default_fp_init(union fp_state *fp) +{ + memset(fp, 0, sizeof(union fp_state)); +} -EXPORT_SYMBOL_GPL(thread_notify_head); +void (*fp_init)(union fp_state *) = default_fp_init; +EXPORT_SYMBOL(fp_init); void flush_thread(void) { @@ -350,21 +353,22 @@ void flush_thread(void) memset(thread->used_cp, 0, sizeof(thread->used_cp)); memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); - memset(&thread->fpstate, 0, sizeof(union fp_state)); - - thread_notify(THREAD_NOTIFY_FLUSH, thread); #if defined(CONFIG_IWMMXT) iwmmxt_task_release(thread); +#endif + fp_init(&thread->fpstate); +#if defined(CONFIG_VFP) + vfp_flush_thread(&thread->vfpstate); #endif } void release_thread(struct task_struct *dead_task) { - struct thread_info *thread = task_thread_info(dead_task); - - thread_notify(THREAD_NOTIFY_RELEASE, thread); +#if defined(CONFIG_VFP) + vfp_release_thread(&task_thread_info(dead_task)->vfpstate); +#endif #if defined(CONFIG_IWMMXT) - iwmmxt_task_release(thread); + iwmmxt_task_release(task_thread_info(dead_task)); #endif } diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 093ccba0503c..9fc9af88c60c 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -808,7 +808,7 @@ static int __init topology_init(void) int cpu; for_each_possible_cpu(cpu) - register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); + register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); return 0; } diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 1ce05ec086c6..a0cd0a90a10d 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -134,6 +134,17 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, #ifdef CONFIG_IWMMXT +/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */ +#define IWMMXT_STORAGE_SIZE (0x98 + 8) +#define IWMMXT_MAGIC0 0x12ef842a +#define IWMMXT_MAGIC1 0x1c07ca71 + +struct iwmmxt_sigframe { + unsigned long magic0; + unsigned long magic1; + unsigned long storage[0x98/4]; +}; + static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) { char kbuf[sizeof(*frame) + 8]; @@ -141,8 +152,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) /* the iWMMXt context must be 64 bit aligned */ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); - kframe->magic = IWMMXT_MAGIC; - kframe->size = IWMMXT_STORAGE_SIZE; + kframe->magic0 = IWMMXT_MAGIC0; + kframe->magic1 = IWMMXT_MAGIC1; iwmmxt_task_copy(current_thread_info(), &kframe->storage); return __copy_to_user(frame, kframe, sizeof(*frame)); } @@ -156,8 +167,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); if (__copy_from_user(kframe, frame, sizeof(*frame))) return -1; - if (kframe->magic != IWMMXT_MAGIC || - kframe->size != IWMMXT_STORAGE_SIZE) + if (kframe->magic0 != IWMMXT_MAGIC0 || + kframe->magic1 != IWMMXT_MAGIC1) return -1; iwmmxt_task_restore(current_thread_info(), &kframe->storage); return 0; @@ -165,62 +176,71 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) #endif +/* + * Auxiliary signal frame. This saves stuff like FP state. + * The layout of this structure is not part of the user ABI. + */ +struct aux_sigframe { +#ifdef CONFIG_IWMMXT + struct iwmmxt_sigframe iwmmxt; +#endif +#ifdef CONFIG_VFP + union vfp_state vfp; +#endif +}; + /* * Do a signal return; undo the signal stack. These are aligned to 64-bit. */ struct sigframe { - struct ucontext uc; + struct sigcontext sc; + unsigned long extramask[_NSIG_WORDS-1]; unsigned long retcode[2]; + struct aux_sigframe aux __attribute__((aligned(8))); }; struct rt_sigframe { + struct siginfo __user *pinfo; + void __user *puc; struct siginfo info; - struct sigframe sig; + struct ucontext uc; + unsigned long retcode[2]; + struct aux_sigframe aux __attribute__((aligned(8))); }; -static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, + struct aux_sigframe __user *aux) { - struct aux_sigframe __user *aux; - sigset_t set; - int err; - - err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (err == 0) { - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } + int err = 0; - __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); - __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); - __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); - __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); - __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); - __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); - __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); - __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); - __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); - __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); - __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); - __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); - __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); - __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); - __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); - __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); - __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); + __get_user_error(regs->ARM_r0, &sc->arm_r0, err); + __get_user_error(regs->ARM_r1, &sc->arm_r1, err); + __get_user_error(regs->ARM_r2, &sc->arm_r2, err); + __get_user_error(regs->ARM_r3, &sc->arm_r3, err); + __get_user_error(regs->ARM_r4, &sc->arm_r4, err); + __get_user_error(regs->ARM_r5, &sc->arm_r5, err); + __get_user_error(regs->ARM_r6, &sc->arm_r6, err); + __get_user_error(regs->ARM_r7, &sc->arm_r7, err); + __get_user_error(regs->ARM_r8, &sc->arm_r8, err); + __get_user_error(regs->ARM_r9, &sc->arm_r9, err); + __get_user_error(regs->ARM_r10, &sc->arm_r10, err); + __get_user_error(regs->ARM_fp, &sc->arm_fp, err); + __get_user_error(regs->ARM_ip, &sc->arm_ip, err); + __get_user_error(regs->ARM_sp, &sc->arm_sp, err); + __get_user_error(regs->ARM_lr, &sc->arm_lr, err); + __get_user_error(regs->ARM_pc, &sc->arm_pc, err); + __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); err |= !valid_user_regs(regs); - aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= restore_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP // if (err == 0) -// err |= vfp_restore_state(&sf->aux.vfp); +// err |= vfp_restore_state(&aux->vfp); #endif return err; @@ -229,6 +249,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) asmlinkage int sys_sigreturn(struct pt_regs *regs) { struct sigframe __user *frame; + sigset_t set; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; @@ -245,8 +266,19 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) goto badframe; + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; - if (restore_sigframe(regs, frame)) + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->sc, &frame->aux)) goto badframe; /* Send SIGTRAP if we're single-stepping */ @@ -265,6 +297,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; + sigset_t set; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; @@ -281,11 +314,19 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; - if (restore_sigframe(regs, &frame->sig)) + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux)) goto badframe; - if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) goto badframe; /* Send SIGTRAP if we're single-stepping */ @@ -302,46 +343,42 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) } static int -setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) +setup_sigcontext(struct sigcontext __user *sc, struct aux_sigframe __user *aux, + struct pt_regs *regs, unsigned long mask) { - struct aux_sigframe __user *aux; int err = 0; - __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); - __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); - __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); - __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); - __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); - __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); - __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); - __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); - __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); - __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); - __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); - __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); - __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); - __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); - __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); - __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); - __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); - - __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err); - __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err); - __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err); - __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); - - err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); - - aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; + __put_user_error(regs->ARM_r0, &sc->arm_r0, err); + __put_user_error(regs->ARM_r1, &sc->arm_r1, err); + __put_user_error(regs->ARM_r2, &sc->arm_r2, err); + __put_user_error(regs->ARM_r3, &sc->arm_r3, err); + __put_user_error(regs->ARM_r4, &sc->arm_r4, err); + __put_user_error(regs->ARM_r5, &sc->arm_r5, err); + __put_user_error(regs->ARM_r6, &sc->arm_r6, err); + __put_user_error(regs->ARM_r7, &sc->arm_r7, err); + __put_user_error(regs->ARM_r8, &sc->arm_r8, err); + __put_user_error(regs->ARM_r9, &sc->arm_r9, err); + __put_user_error(regs->ARM_r10, &sc->arm_r10, err); + __put_user_error(regs->ARM_fp, &sc->arm_fp, err); + __put_user_error(regs->ARM_ip, &sc->arm_ip, err); + __put_user_error(regs->ARM_sp, &sc->arm_sp, err); + __put_user_error(regs->ARM_lr, &sc->arm_lr, err); + __put_user_error(regs->ARM_pc, &sc->arm_pc, err); + __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); + + __put_user_error(current->thread.trap_no, &sc->trap_no, err); + __put_user_error(current->thread.error_code, &sc->error_code, err); + __put_user_error(current->thread.address, &sc->fault_address, err); + __put_user_error(mask, &sc->oldmask, err); + #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= preserve_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP // if (err == 0) -// err |= vfp_save_state(&sf->aux.vfp); +// err |= vfp_save_state(&aux->vfp); #endif - __put_user_error(0, &aux->end_magic, err); return err; } @@ -450,12 +487,13 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg if (!frame) return 1; - /* - * Set uc.uc_flags to a value which sc.trap_no would never have. - */ - __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); + err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } - err |= setup_sigframe(frame, regs, set); if (err == 0) err = setup_return(regs, ka, frame->retcode, frame, usig); @@ -473,20 +511,25 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, if (!frame) return 1; + __put_user_error(&frame->info, &frame->pinfo, err); + __put_user_error(&frame->uc, &frame->puc, err); err |= copy_siginfo_to_user(&frame->info, info); - __put_user_error(0, &frame->sig.uc.uc_flags, err); - __put_user_error(NULL, &frame->sig.uc.uc_link, err); + __put_user_error(0, &frame->uc.uc_flags, err); + __put_user_error(NULL, &frame->uc.uc_link, err); memset(&stack, 0, sizeof(stack)); stack.ss_sp = (void __user *)current->sas_ss_sp; stack.ss_flags = sas_ss_flags(regs->ARM_sp); stack.ss_size = current->sas_ss_size; - err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack)); + err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); + + err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux, + regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - err |= setup_sigframe(&frame->sig, regs, set); if (err == 0) - err = setup_return(regs, ka, frame->sig.retcode, frame, usig); + err = setup_return(regs, ka, frame->retcode, frame, usig); if (err == 0) { /* @@ -495,7 +538,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, * -- Peter Maydell 2000-12-06 */ regs->ARM_r1 = (unsigned long)&frame->info; - regs->ARM_r2 = (unsigned long)&frame->sig.uc; + regs->ARM_r2 = (unsigned long)&frame->uc; } return err; @@ -622,33 +665,17 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) if (syscall) { if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { if (thumb_mode(regs)) { - regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; + regs->ARM_r7 = __NR_restart_syscall; regs->ARM_pc -= 2; } else { -#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) - regs->ARM_r7 = __NR_restart_syscall; - regs->ARM_pc -= 4; -#else u32 __user *usp; - u32 swival = __NR_restart_syscall; regs->ARM_sp -= 12; usp = (u32 __user *)regs->ARM_sp; - /* - * Either we supports OABI only, or we have - * EABI with the OABI compat layer enabled. - * In the later case we don't know if user - * space is EABI or not, and if not we must - * not clobber r7. Always using the OABI - * syscall solves that issue and works for - * all those cases. - */ - swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE; - put_user(regs->ARM_pc, &usp[0]); /* swi __NR_restart_syscall */ - put_user(0xef000000 | swival, &usp[1]); + put_user(0xef000000 | __NR_restart_syscall, &usp[1]); /* ldr pc, [sp], #12 */ put_user(0xe49df00c, &usp[2]); @@ -656,7 +683,6 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) (unsigned long)(usp + 3)); regs->ARM_pc = regs->ARM_sp + 4; -#endif } } if (regs->ARM_r0 == -ERESTARTNOHAND || diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 058b80d72aa1..16153c86c3f8 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -41,7 +41,7 @@ ENTRY(c_backtrace) movne r0, #0 movs frame, r0 1: moveq r0, #-2 - ldmeqfd sp!, {r4 - r8, pc} + LOADREGS(eqfd, sp!, {r4 - r8, pc}) 2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction ldr r0, [sp], #4 @@ -85,7 +85,7 @@ ENTRY(c_backtrace) * A zero next framepointer means we're done. */ teq next, #0 - ldmeqfd sp!, {r4 - r8, pc} + LOADREGS(eqfd, sp!, {r4 - r8, pc}) /* * The next framepointer must be above the @@ -104,7 +104,7 @@ ENTRY(c_backtrace) 1007: ldr r0, =.Lbad mov r1, frame bl printk - ldmfd sp!, {r4 - r8, pc} + LOADREGS(fd, sp!, {r4 - r8, pc}) .ltorg .previous @@ -145,7 +145,7 @@ ENTRY(c_backtrace) adrne r0, .Lcr blne printk mov r0, stack - ldmfd sp!, {instr, reg, stack, r7, r8, pc} + LOADREGS(fd, sp!, {instr, reg, stack, r7, r8, pc}) .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" diff --git a/trunk/arch/arm/lib/clear_user.S b/trunk/arch/arm/lib/clear_user.S index ea435ae2e4a5..7ff9f831b3f9 100644 --- a/trunk/arch/arm/lib/clear_user.S +++ b/trunk/arch/arm/lib/clear_user.S @@ -43,10 +43,10 @@ USER( strnebt r2, [r0], #1) tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 USER( strnebt r2, [r0], #1) mov r0, #0 - ldmfd sp!, {r1, pc} + LOADREGS(fd,sp!, {r1, pc}) .section .fixup,"ax" .align 0 -9001: ldmfd sp!, {r0, pc} +9001: LOADREGS(fd,sp!, {r0, pc}) .previous diff --git a/trunk/arch/arm/lib/copy_page.S b/trunk/arch/arm/lib/copy_page.S index 666c99cc0744..68117968482b 100644 --- a/trunk/arch/arm/lib/copy_page.S +++ b/trunk/arch/arm/lib/copy_page.S @@ -43,4 +43,4 @@ ENTRY(copy_page) bgt 1b @ 1 PLD( ldmeqia r1!, {r3, r4, ip, lr} ) PLD( beq 2b ) - ldmfd sp!, {r4, pc} @ 3 + LOADREGS(fd, sp!, {r4, pc}) @ 3 diff --git a/trunk/arch/arm/lib/csumipv6.S b/trunk/arch/arm/lib/csumipv6.S index 9621469beec1..7065a20ee8ad 100644 --- a/trunk/arch/arm/lib/csumipv6.S +++ b/trunk/arch/arm/lib/csumipv6.S @@ -28,5 +28,5 @@ ENTRY(__csum_ipv6_magic) adcs r0, r0, r3 adcs r0, r0, r2 adcs r0, r0, #0 - ldmfd sp!, {pc} + LOADREGS(fd, sp!, {pc}) diff --git a/trunk/arch/arm/lib/delay.S b/trunk/arch/arm/lib/delay.S index 930a70259220..9183b06c0e2f 100644 --- a/trunk/arch/arm/lib/delay.S +++ b/trunk/arch/arm/lib/delay.S @@ -31,7 +31,7 @@ ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 mov r2, r2, lsr #10 @ max = 0x00007fff mul r0, r2, r0 @ max = 2^32-1 movs r0, r0, lsr #6 - moveq pc, lr + RETINSTR(moveq,pc,lr) /* * loops = r0 * HZ * loops_per_jiffy / 1000000 @@ -43,20 +43,20 @@ ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 ENTRY(__delay) subs r0, r0, #1 #if 0 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 - movls pc, lr + RETINSTR(movls,pc,lr) subs r0, r0, #1 #endif bhi __delay - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/ecard.S b/trunk/arch/arm/lib/ecard.S index c55aaa2a2088..fb7b602a6f76 100644 --- a/trunk/arch/arm/lib/ecard.S +++ b/trunk/arch/arm/lib/ecard.S @@ -29,7 +29,7 @@ ENTRY(ecard_loader_read) CPSR2SPSR(r0) mov lr, pc mov pc, r2 - ldmfd sp!, {r4 - r12, pc} + LOADREGS(fd, sp!, {r4 - r12, pc}) @ Purpose: call an expansion card loader to reset the card @ Proto : void read_loader(int card_base, char *loader); @@ -41,5 +41,5 @@ ENTRY(ecard_loader_reset) CPSR2SPSR(r0) mov lr, pc add pc, r1, #8 - ldmfd sp!, {r4 - r12, pc} + LOADREGS(fd, sp!, {r4 - r12, pc}) diff --git a/trunk/arch/arm/lib/findbit.S b/trunk/arch/arm/lib/findbit.S index a5ca0248aa4e..6f8e27a58c78 100644 --- a/trunk/arch/arm/lib/findbit.S +++ b/trunk/arch/arm/lib/findbit.S @@ -32,7 +32,7 @@ ENTRY(_find_first_zero_bit_le) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - mov pc, lr + RETINSTR(mov,pc,lr) /* * Purpose : Find next 'zero' bit @@ -66,7 +66,7 @@ ENTRY(_find_first_bit_le) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - mov pc, lr + RETINSTR(mov,pc,lr) /* * Purpose : Find next 'one' bit @@ -98,7 +98,7 @@ ENTRY(_find_first_zero_bit_be) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - mov pc, lr + RETINSTR(mov,pc,lr) ENTRY(_find_next_zero_bit_be) teq r1, #0 @@ -126,7 +126,7 @@ ENTRY(_find_first_bit_be) 2: cmp r2, r1 @ any more? blo 1b 3: mov r0, r1 @ no free bits - mov pc, lr + RETINSTR(mov,pc,lr) ENTRY(_find_next_bit_be) teq r1, #0 @@ -164,5 +164,5 @@ ENTRY(_find_next_bit_be) addeq r2, r2, #1 mov r0, r2 #endif - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/io-readsb.S b/trunk/arch/arm/lib/io-readsb.S index fb966ad0276f..d3d8de71a2c8 100644 --- a/trunk/arch/arm/lib/io-readsb.S +++ b/trunk/arch/arm/lib/io-readsb.S @@ -72,7 +72,7 @@ ENTRY(__raw_readsb) bpl .Linsb_16_lp tst r2, #15 - ldmeqfd sp!, {r4 - r6, pc} + LOADREGS(eqfd, sp!, {r4 - r6, pc}) .Linsb_no_16: tst r2, #8 beq .Linsb_no_8 @@ -109,7 +109,7 @@ ENTRY(__raw_readsb) str r3, [r1], #4 .Linsb_no_4: ands r2, r2, #3 - ldmeqfd sp!, {r4 - r6, pc} + LOADREGS(eqfd, sp!, {r4 - r6, pc}) cmp r2, #2 ldrb r3, [r0] @@ -119,4 +119,4 @@ ENTRY(__raw_readsb) ldrgtb r3, [r0] strgtb r3, [r1] - ldmfd sp!, {r4 - r6, pc} + LOADREGS(fd, sp!, {r4 - r6, pc}) diff --git a/trunk/arch/arm/lib/io-readsw-armv3.S b/trunk/arch/arm/lib/io-readsw-armv3.S index 4ef904185142..146d47c15455 100644 --- a/trunk/arch/arm/lib/io-readsw-armv3.S +++ b/trunk/arch/arm/lib/io-readsw-armv3.S @@ -28,7 +28,7 @@ strb r3, [r1], #1 subs r2, r2, #1 - moveq pc, lr + RETINSTR(moveq, pc, lr) ENTRY(__raw_readsw) teq r2, #0 @ do we have to check for the zero len? @@ -69,7 +69,7 @@ ENTRY(__raw_readsw) bpl .Linsw_8_lp tst r2, #7 - ldmeqfd sp!, {r4, r5, r6, pc} + LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) .Lno_insw_8: tst r2, #4 beq .Lno_insw_4 @@ -102,6 +102,6 @@ ENTRY(__raw_readsw) movne r3, r3, lsr #8 strneb r3, [r1] - ldmfd sp!, {r4, r5, r6, pc} + LOADREGS(fd, sp!, {r4, r5, r6, pc}) diff --git a/trunk/arch/arm/lib/io-writesb.S b/trunk/arch/arm/lib/io-writesb.S index 7eba2b6cc69f..08209fc640ea 100644 --- a/trunk/arch/arm/lib/io-writesb.S +++ b/trunk/arch/arm/lib/io-writesb.S @@ -64,7 +64,7 @@ ENTRY(__raw_writesb) bpl .Loutsb_16_lp tst r2, #15 - ldmeqfd sp!, {r4, r5, pc} + LOADREGS(eqfd, sp!, {r4, r5, pc}) .Loutsb_no_16: tst r2, #8 beq .Loutsb_no_8 @@ -80,7 +80,7 @@ ENTRY(__raw_writesb) outword r3 .Loutsb_no_4: ands r2, r2, #3 - ldmeqfd sp!, {r4, r5, pc} + LOADREGS(eqfd, sp!, {r4, r5, pc}) cmp r2, #2 ldrb r3, [r1], #1 @@ -90,4 +90,4 @@ ENTRY(__raw_writesb) ldrgtb r3, [r1] strgtb r3, [r0] - ldmfd sp!, {r4, r5, pc} + LOADREGS(fd, sp!, {r4, r5, pc}) diff --git a/trunk/arch/arm/lib/io-writesw-armv3.S b/trunk/arch/arm/lib/io-writesw-armv3.S index 1607a29f49b7..52d62b481295 100644 --- a/trunk/arch/arm/lib/io-writesw-armv3.S +++ b/trunk/arch/arm/lib/io-writesw-armv3.S @@ -29,7 +29,7 @@ orr r3, r3, r3, lsl #16 str r3, [r0] subs r2, r2, #1 - moveq pc, lr + RETINSTR(moveq, pc, lr) ENTRY(__raw_writesw) teq r2, #0 @ do we have to check for the zero len? @@ -80,7 +80,7 @@ ENTRY(__raw_writesw) bpl .Loutsw_8_lp tst r2, #7 - ldmeqfd sp!, {r4, r5, r6, pc} + LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) .Lno_outsw_8: tst r2, #4 beq .Lno_outsw_4 @@ -124,4 +124,4 @@ ENTRY(__raw_writesw) orrne ip, ip, ip, lsr #16 strne ip, [r0] - ldmfd sp!, {r4, r5, r6, pc} + LOADREGS(fd, sp!, {r4, r5, r6, pc}) diff --git a/trunk/arch/arm/lib/memchr.S b/trunk/arch/arm/lib/memchr.S index e7ab1ea8ebaa..ac34fe55d21a 100644 --- a/trunk/arch/arm/lib/memchr.S +++ b/trunk/arch/arm/lib/memchr.S @@ -22,4 +22,4 @@ ENTRY(memchr) bne 1b sub r0, r0, #1 2: movne r0, #0 - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/memset.S b/trunk/arch/arm/lib/memset.S index 95b110b07a89..a1795f599937 100644 --- a/trunk/arch/arm/lib/memset.S +++ b/trunk/arch/arm/lib/memset.S @@ -53,7 +53,7 @@ ENTRY(memset) stmgeia r0!, {r1, r3, ip, lr} stmgeia r0!, {r1, r3, ip, lr} bgt 2b - ldmeqfd sp!, {pc} @ Now <64 bytes to go. + LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go. /* * No need to correct the count; we're only testing bits from now on */ @@ -77,4 +77,4 @@ ENTRY(memset) strneb r1, [r0], #1 tst r2, #1 strneb r1, [r0], #1 - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/memzero.S b/trunk/arch/arm/lib/memzero.S index abf2508e8221..51ccc60160fd 100644 --- a/trunk/arch/arm/lib/memzero.S +++ b/trunk/arch/arm/lib/memzero.S @@ -53,7 +53,7 @@ ENTRY(__memzero) stmgeia r0!, {r2, r3, ip, lr} @ 4 stmgeia r0!, {r2, r3, ip, lr} @ 4 bgt 3b @ 1 - ldmeqfd sp!, {pc} @ 1/2 quick exit + LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit /* * No need to correct the count; we're only testing bits from now on */ @@ -77,4 +77,4 @@ ENTRY(__memzero) strneb r2, [r0], #1 @ 1 tst r1, #1 @ 1 a byte left over strneb r2, [r0], #1 @ 1 - mov pc, lr @ 1 + RETINSTR(mov,pc,lr) @ 1 diff --git a/trunk/arch/arm/lib/strchr.S b/trunk/arch/arm/lib/strchr.S index 9f18d6fdee6a..5b9b493733fc 100644 --- a/trunk/arch/arm/lib/strchr.S +++ b/trunk/arch/arm/lib/strchr.S @@ -23,4 +23,4 @@ ENTRY(strchr) teq r2, r1 movne r0, #0 subeq r0, r0, #1 - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/strncpy_from_user.S b/trunk/arch/arm/lib/strncpy_from_user.S index 35649f04fcac..629cc8775276 100644 --- a/trunk/arch/arm/lib/strncpy_from_user.S +++ b/trunk/arch/arm/lib/strncpy_from_user.S @@ -21,6 +21,7 @@ * -EFAULT on exception, or "len" if we fill the whole buffer */ ENTRY(__arch_strncpy_from_user) + save_lr mov ip, r1 1: subs r2, r2, #1 USER( ldrplbt r3, [r1], #1) @@ -30,13 +31,13 @@ USER( ldrplbt r3, [r1], #1) bne 1b sub r1, r1, #1 @ take NUL character out of count 2: sub r0, r1, ip - mov pc, lr + restore_pc .section .fixup,"ax" .align 0 9001: mov r3, #0 strb r3, [r0, #0] @ null terminate mov r0, #-EFAULT - mov pc, lr + restore_pc .previous diff --git a/trunk/arch/arm/lib/strnlen_user.S b/trunk/arch/arm/lib/strnlen_user.S index 3668a15991ef..67bcd8268128 100644 --- a/trunk/arch/arm/lib/strnlen_user.S +++ b/trunk/arch/arm/lib/strnlen_user.S @@ -21,6 +21,7 @@ * or zero on exception, or n + 1 if too long */ ENTRY(__arch_strnlen_user) + save_lr mov r2, r0 1: USER( ldrbt r3, [r0], #1) @@ -30,10 +31,10 @@ USER( ldrbt r3, [r0], #1) bne 1b add r0, r0, #1 2: sub r0, r0, r2 - mov pc, lr + restore_pc .section .fixup,"ax" .align 0 9001: mov r0, #0 - mov pc, lr + restore_pc .previous diff --git a/trunk/arch/arm/lib/strrchr.S b/trunk/arch/arm/lib/strrchr.S index 538df220aa48..fa923f026f15 100644 --- a/trunk/arch/arm/lib/strrchr.S +++ b/trunk/arch/arm/lib/strrchr.S @@ -22,4 +22,4 @@ ENTRY(strrchr) teq r2, #0 bne 1b mov r0, r3 - mov pc, lr + RETINSTR(mov,pc,lr) diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S index 1f1545d737be..0cc450f863b6 100644 --- a/trunk/arch/arm/lib/uaccess.S +++ b/trunk/arch/arm/lib/uaccess.S @@ -105,7 +105,7 @@ USER( strgtbt r3, [r0], #1) @ May fault movs ip, r2 bne .Lc2u_nowords .Lc2u_finished: mov r0, #0 - ldmfd sp!, {r2, r4 - r7, pc} + LOADREGS(fd,sp!,{r2, r4 - r7, pc}) .Lc2u_src_not_aligned: bic r1, r1, #3 @@ -280,7 +280,7 @@ USER( strgtbt r3, [r0], #1) @ May fault .section .fixup,"ax" .align 0 -9001: ldmfd sp!, {r0, r4 - r7, pc} +9001: LOADREGS(fd,sp!, {r0, r4 - r7, pc}) .previous /* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); @@ -369,7 +369,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault bne .Lcfu_nowords .Lcfu_finished: mov r0, #0 add sp, sp, #8 - ldmfd sp!, {r4 - r7, pc} + LOADREGS(fd,sp!,{r4 - r7, pc}) .Lcfu_src_not_aligned: bic r1, r1, #3 @@ -556,6 +556,6 @@ USER( ldrgtbt r3, [r1], #1) @ May fault movne r1, r4 blne __memzero mov r0, r4 - ldmfd sp!, {r4 - r7, pc} + LOADREGS(fd,sp!, {r4 - r7, pc}) .previous diff --git a/trunk/arch/arm/mach-at91rm9200/Kconfig b/trunk/arch/arm/mach-at91rm9200/Kconfig index 70d402f76ce5..1ab5b7828318 100644 --- a/trunk/arch/arm/mach-at91rm9200/Kconfig +++ b/trunk/arch/arm/mach-at91rm9200/Kconfig @@ -4,12 +4,6 @@ menu "AT91RM9200 Implementations" comment "AT91RM9200 Board Type" -config MACH_ONEARM - bool "Ajeco 1ARM Single Board Computer" - depends on ARCH_AT91RM9200 - help - Select this if you are using Ajeco's 1ARM Single Board Computer - config ARCH_AT91RM9200DK bool "Atmel AT91RM9200-DK Development board" depends on ARCH_AT91RM9200 diff --git a/trunk/arch/arm/mach-at91rm9200/Makefile b/trunk/arch/arm/mach-at91rm9200/Makefile index 82db957322df..81ebc6684ad2 100644 --- a/trunk/arch/arm/mach-at91rm9200/Makefile +++ b/trunk/arch/arm/mach-at91rm9200/Makefile @@ -10,7 +10,6 @@ obj- := obj-$(CONFIG_PM) += pm.o # Board-specific support -obj-$(CONFIG_MACH_ONEARM) += board-1arm.o obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o obj-$(CONFIG_MACH_CSB337) += board-csb337.o diff --git a/trunk/arch/arm/mach-at91rm9200/board-1arm.c b/trunk/arch/arm/mach-at91rm9200/board-1arm.c deleted file mode 100644 index dc79e0992af7..000000000000 --- a/trunk/arch/arm/mach-at91rm9200/board-1arm.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * linux/arch/arm/mach-at91rm9200/board-1arm.c - * - * Copyright (C) 2005 SAN People - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "generic.h" - -static void __init onearm_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(PQFP_GPIO_BANKS); -} - -/* - * Serial port configuration. - * 0 .. 3 = USART0 .. USART3 - * 4 = DBGU - */ -static struct at91_uart_config __initdata onearm_uart_config = { - .console_tty = 0, /* ttyS0 */ - .nr_tty = 3, - .tty_map = { 4, 0, 1, -1, -1 }, /* ttyS0, ..., ttyS4 */ -}; - -static void __init onearm_map_io(void) -{ - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); - - /* Setup the serial ports and console */ - at91_init_serial(&onearm_uart_config); -} - -static struct at91_eth_data __initdata onearm_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata onearm_usbh_data = { - .ports = 1, -}; - -static struct at91_udc_data __initdata onearm_udc_data = { - .vbus_pin = AT91_PIN_PC2, - .pullup_pin = AT91_PIN_PC3, -}; - -static void __init onearm_board_init(void) -{ - /* Serial */ - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&onearm_eth_data); - /* USB Host */ - at91_add_device_usbh(&onearm_usbh_data); - /* USB Device */ - at91_add_device_udc(&onearm_udc_data); -} - -MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") - /* Maintainer: Lennert Buytenhek */ - .phys_io = AT91_BASE_SYS, - .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, - .boot_params = AT91_SDRAM_BASE + 0x100, - .timer = &at91rm9200_timer, - .map_io = onearm_map_io, - .init_irq = onearm_init_irq, - .init_machine = onearm_board_init, -MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/Makefile b/trunk/arch/arm/mach-ep93xx/Makefile index 05a48a21038e..5393af989e94 100644 --- a/trunk/arch/arm/mach-ep93xx/Makefile +++ b/trunk/arch/arm/mach-ep93xx/Makefile @@ -1,7 +1,7 @@ # # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o obj-m := obj-n := obj- := diff --git a/trunk/arch/arm/mach-ep93xx/clock.c b/trunk/arch/arm/mach-ep93xx/clock.c deleted file mode 100644 index 08ad782c1649..000000000000 --- a/trunk/arch/arm/mach-ep93xx/clock.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * arch/arm/mach-ep93xx/clock.c - * Clock control for Cirrus EP93xx chips. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct clk { - char *name; - unsigned long rate; - int users; - u32 enable_reg; - u32 enable_mask; -}; - -static struct clk clk_pll1 = { - .name = "pll1", -}; -static struct clk clk_f = { - .name = "fclk", -}; -static struct clk clk_h = { - .name = "hclk", -}; -static struct clk clk_p = { - .name = "pclk", -}; -static struct clk clk_pll2 = { - .name = "pll2", -}; -static struct clk clk_usb_host = { - .name = "usb_host", - .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL, - .enable_mask = EP93XX_SYSCON_CLOCK_USH_EN, -}; - - -static struct clk *clocks[] = { - &clk_pll1, - &clk_f, - &clk_h, - &clk_p, - &clk_pll2, - &clk_usb_host, -}; - -struct clk *clk_get(struct device *dev, const char *id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(clocks); i++) { - if (!strcmp(clocks[i]->name, id)) - return clocks[i]; - } - - return ERR_PTR(-ENOENT); -} - -int clk_enable(struct clk *clk) -{ - if (!clk->users++ && clk->enable_reg) { - u32 value; - - value = __raw_readl(clk->enable_reg); - __raw_writel(value | clk->enable_mask, clk->enable_reg); - } - - return 0; -} - -void clk_disable(struct clk *clk) -{ - if (!--clk->users && clk->enable_reg) { - u32 value; - - value = __raw_readl(clk->enable_reg); - __raw_writel(value & ~clk->enable_mask, clk->enable_reg); - } -} - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} - -void clk_put(struct clk *clk) -{ -} - - - -static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; -static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; -static char pclk_divisors[] = { 1, 2, 4, 8 }; - -/* - * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS - */ -static unsigned long calc_pll_rate(u32 config_word) -{ - unsigned long long rate; - int i; - - rate = 14745600; - rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ - rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ - do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ - for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */ - rate >>= 1; - - return (unsigned long)rate; -} - -void ep93xx_clock_init(void) -{ - u32 value; - - value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); - if (!(value & 0x00800000)) { /* PLL1 bypassed? */ - clk_pll1.rate = 14745600; - } else { - clk_pll1.rate = calc_pll_rate(value); - } - clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7]; - clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7]; - clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3]; - - value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); - if (!(value & 0x00080000)) { /* PLL2 bypassed? */ - clk_pll2.rate = 14745600; - } else if (value & 0x00040000) { /* PLL2 enabled? */ - clk_pll2.rate = calc_pll_rate(value); - } else { - clk_pll2.rate = 0; - } - clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1); - - printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n", - clk_pll1.rate / 1000000, clk_pll2.rate / 1000000); - printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", - clk_f.rate / 1000000, clk_h.rate / 1000000, - clk_p.rate / 1000000); -} diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index 1fe73c0a9d01..dcd417625389 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -103,8 +103,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) write_seqlock(&xtime_lock); __raw_writel(1, EP93XX_TIMER1_CLEAR); - while ((signed long) - (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) + while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time >= TIMER4_TICKS_PER_JIFFY) { last_jiffy_time += TIMER4_TICKS_PER_JIFFY; timer_tick(regs); @@ -125,7 +124,7 @@ static void __init ep93xx_timer_init(void) { /* Enable periodic HZ timer. */ __raw_writel(0x48, EP93XX_TIMER1_CONTROL); - __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD); + __raw_writel((508000 / HZ) - 1, EP93XX_TIMER1_LOAD); __raw_writel(0xc8, EP93XX_TIMER1_CONTROL); /* Enable lost jiffy timer. */ @@ -433,37 +432,10 @@ static struct platform_device ep93xx_rtc_device = { }; -static struct resource ep93xx_ohci_resources[] = { - [0] = { - .start = EP93XX_USB_PHYS_BASE, - .end = EP93XX_USB_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_EP93XX_USB, - .end = IRQ_EP93XX_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device ep93xx_ohci_device = { - .name = "ep93xx-ohci", - .id = -1, - .dev = { - .dma_mask = (void *)0xffffffff, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(ep93xx_ohci_resources), - .resource = ep93xx_ohci_resources, -}; - - void __init ep93xx_init_devices(void) { unsigned int v; - ep93xx_clock_init(); - /* * Disallow access to MaverickCrunch initially. */ @@ -477,5 +449,4 @@ void __init ep93xx_init_devices(void) amba_device_register(&uart3_device, &iomem_resource); platform_device_register(&ep93xx_rtc_device); - platform_device_register(&ep93xx_ohci_device); } diff --git a/trunk/arch/arm/mach-ep93xx/gesbc9312.c b/trunk/arch/arm/mach-ep93xx/gesbc9312.c index 47cc6c8b7c79..d18fcb1a2f1b 100644 --- a/trunk/arch/arm/mach-ep93xx/gesbc9312.c +++ b/trunk/arch/arm/mach-ep93xx/gesbc9312.c @@ -16,38 +16,16 @@ #include #include #include -#include #include -#include #include #include #include #include -static struct physmap_flash_data gesbc9312_flash_data = { - .width = 4, -}; - -static struct resource gesbc9312_flash_resource = { - .start = 0x60000000, - .end = 0x60800000, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device gesbc9312_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &gesbc9312_flash_data, - }, - .num_resources = 1, - .resource = &gesbc9312_flash_resource, -}; - static void __init gesbc9312_init_machine(void) { ep93xx_init_devices(); - platform_device_register(&gesbc9312_flash); + physmap_configure(0x60000000, 0x00800000, 4, NULL); } MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx") diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index 6e5a56cd5ae8..e24566b88a78 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -112,26 +111,6 @@ static void __init ts72xx_map_io(void) } } -static struct physmap_flash_data ts72xx_flash_data = { - .width = 1, -}; - -static struct resource ts72xx_flash_resource = { - .start = TS72XX_NOR_PHYS_BASE, - .end = TS72XX_NOR_PHYS_BASE + 0x01000000, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ts72xx_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ts72xx_flash_data, - }, - .num_resources = 1, - .resource = &ts72xx_flash_resource, -}; - static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); @@ -162,7 +141,7 @@ static void __init ts72xx_init_machine(void) { ep93xx_init_devices(); if (board_is_ts7200()) - platform_device_register(&ts72xx_flash); + physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL); platform_device_register(&ts72xx_rtc_device); } diff --git a/trunk/arch/arm/mach-imx/dma.c b/trunk/arch/arm/mach-imx/dma.c index 36578871ecc8..4ca51dcf13ac 100644 --- a/trunk/arch/arm/mach-imx/dma.c +++ b/trunk/arch/arm/mach-imx/dma.c @@ -15,9 +15,6 @@ * Changed to support scatter gather DMA * by taking Russell's code from RiscPC * - * 2006-05-31 Pavel Pisa - * Corrected error handling code. - * */ #undef DEBUG @@ -280,7 +277,7 @@ imx_dma_setup_sg(imx_dmach_t dma_ch, int imx_dma_setup_handlers(imx_dmach_t dma_ch, void (*irq_handler) (int, void *, struct pt_regs *), - void (*err_handler) (int, void *, struct pt_regs *, int), + void (*err_handler) (int, void *, struct pt_regs *), void *data) { struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch]; @@ -466,53 +463,43 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) int i, disr = DISR; struct imx_dma_channel *channel; unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; - int errcode; - DISR = disr & err_mask; + DISR = disr; for (i = 0; i < IMX_DMA_CHANNELS; i++) { - if(!(err_mask & (1 << i))) - continue; channel = &imx_dma_channels[i]; - errcode = 0; + + if ((err_mask & 1 << i) && channel->name + && channel->err_handler) { + channel->err_handler(i, channel->data, regs); + continue; + } + + imx_dma_channels[i].sg = NULL; if (DBTOSR & (1 << i)) { - DBTOSR = (1 << i); - errcode |= IMX_DMA_ERR_BURST; + printk(KERN_WARNING + "Burst timeout on channel %d (%s)\n", + i, channel->name); + DBTOSR |= (1 << i); } if (DRTOSR & (1 << i)) { - DRTOSR = (1 << i); - errcode |= IMX_DMA_ERR_REQUEST; + printk(KERN_WARNING + "Request timeout on channel %d (%s)\n", + i, channel->name); + DRTOSR |= (1 << i); } if (DSESR & (1 << i)) { - DSESR = (1 << i); - errcode |= IMX_DMA_ERR_TRANSFER; + printk(KERN_WARNING + "Transfer timeout on channel %d (%s)\n", + i, channel->name); + DSESR |= (1 << i); } if (DBOSR & (1 << i)) { - DBOSR = (1 << i); - errcode |= IMX_DMA_ERR_BUFFER; + printk(KERN_WARNING + "Buffer overflow timeout on channel %d (%s)\n", + i, channel->name); + DBOSR |= (1 << i); } - - /* - * The cleaning of @sg field would be questionable - * there, because its value can help to compute - * remaining/transfered bytes count in the handler - */ - /*imx_dma_channels[i].sg = NULL;*/ - - if (channel->name && channel->err_handler) { - channel->err_handler(i, channel->data, regs, errcode); - continue; - } - - imx_dma_channels[i].sg = NULL; - - printk(KERN_WARNING - "DMA timeout on channel %d (%s) -%s%s%s%s\n", - i, channel->name, - errcode&IMX_DMA_ERR_BURST? " burst":"", - errcode&IMX_DMA_ERR_REQUEST? " request":"", - errcode&IMX_DMA_ERR_TRANSFER? " transfer":"", - errcode&IMX_DMA_ERR_BUFFER? " buffer":""); } return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-ixp2000/core.c b/trunk/arch/arm/mach-ixp2000/core.c index ebe4391dd7f9..6e8d504aca55 100644 --- a/trunk/arch/arm/mach-ixp2000/core.c +++ b/trunk/arch/arm/mach-ixp2000/core.c @@ -211,8 +211,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* clear timer 1 */ ixp2000_reg_wrb(IXP2000_T1_CLR, 1); - while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr) - >= ticks_per_jiffy) { + while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { timer_tick(regs); next_jiffy_time -= ticks_per_jiffy; } @@ -302,7 +301,6 @@ void gpio_line_config(int line, int direction) } local_irq_restore(flags); } -EXPORT_SYMBOL(gpio_line_config); /************************************************************************* diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c index 051e3d70026e..affd1d5d7440 100644 --- a/trunk/arch/arm/mach-ixp23xx/core.c +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -334,7 +334,7 @@ void __init ixp23xx_init_irq(void) /************************************************************************* * Timer-tick functions for IXP23xx *************************************************************************/ -#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC) +#define CLOCK_TICKS_PER_USEC CLOCK_TICK_RATE / (USEC_PER_SEC) static unsigned long next_jiffy_time; @@ -353,7 +353,7 @@ ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Clear Pending Interrupt by writing '1' to it */ *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND; - while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) { + while ((*IXP23XX_TIMER_CONT - next_jiffy_time) > LATCH) { timer_tick(regs); next_jiffy_time += LATCH; } @@ -439,6 +439,5 @@ static struct platform_device *ixp23xx_devices[] __initdata = { void __init ixp23xx_sys_init(void) { - *IXP23XX_EXP_UNIT_FUSE |= 0xf; platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices)); } diff --git a/trunk/arch/arm/mach-ixp23xx/espresso.c b/trunk/arch/arm/mach-ixp23xx/espresso.c index dc5e489c70bc..bf688c128630 100644 --- a/trunk/arch/arm/mach-ixp23xx/espresso.c +++ b/trunk/arch/arm/mach-ixp23xx/espresso.c @@ -53,29 +53,9 @@ static int __init espresso_pci_init(void) }; subsys_initcall(espresso_pci_init); -static struct physmap_flash_data espresso_flash_data = { - .width = 2, -}; - -static struct resource espresso_flash_resource = { - .start = 0x90000000, - .end = 0x92000000, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device espresso_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &espresso_flash_data, - }, - .num_resources = 1, - .resource = &espresso_flash_resource, -}; - static void __init espresso_init(void) { - platform_device_register(&espresso_flash); + physmap_configure(0x90000000, 0x02000000, 2, NULL); /* * Mark flash as writeable. diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index 535b334ee045..00146c35daac 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -298,29 +298,9 @@ static void __init ixdp2351_map_io(void) iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc)); } -static struct physmap_flash_data ixdp2351_flash_data = { - .width = 1, -}; - -static struct resource ixdp2351_flash_resource = { - .start = 0x90000000, - .end = 0x94000000, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ixdp2351_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ixdp2351_flash_data, - }, - .num_resources = 1, - .resource = &ixdp2351_flash_resource, -}; - static void __init ixdp2351_init(void) { - platform_device_register(&ixdp2351_flash); + physmap_configure(0x90000000, 0x04000000, 1, NULL); /* * Mark flash as writeable diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c index b9f5d13fcfe1..43c14e740794 100644 --- a/trunk/arch/arm/mach-ixp23xx/roadrunner.c +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -137,29 +137,9 @@ static int __init roadrunner_pci_init(void) subsys_initcall(roadrunner_pci_init); -static struct physmap_flash_data roadrunner_flash_data = { - .width = 2, -}; - -static struct resource roadrunner_flash_resource = { - .start = 0x90000000, - .end = 0x94000000, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device roadrunner_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &roadrunner_flash_data, - }, - .num_resources = 1, - .resource = &roadrunner_flash_resource, -}; - static void __init roadrunner_init(void) { - platform_device_register(&roadrunner_flash); + physmap_configure(0x90000000, 0x04000000, 2, NULL); /* * Mark flash as writeable diff --git a/trunk/arch/arm/mach-ixp4xx/Kconfig b/trunk/arch/arm/mach-ixp4xx/Kconfig index 57f23b465392..3b23f43cb160 100644 --- a/trunk/arch/arm/mach-ixp4xx/Kconfig +++ b/trunk/arch/arm/mach-ixp4xx/Kconfig @@ -35,6 +35,7 @@ config ARCH_ADI_COYOTE config ARCH_IXDP425 bool "IXDP425" + select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP425 Development Platform (Also known as Richfield). @@ -42,6 +43,7 @@ config ARCH_IXDP425 config MACH_IXDPG425 bool "IXDPG425" + select PCI help Say 'Y' here if you want your kernel to support Intel's IXDPG425 Development Platform (Also known as Montajade). @@ -49,6 +51,7 @@ config MACH_IXDPG425 config MACH_IXDP465 bool "IXDP465" + select PCI help Say 'Y' here if you want your kernel to support Intel's IXDP465 Development Platform (Also known as BMP). diff --git a/trunk/arch/arm/mach-ixp4xx/Makefile b/trunk/arch/arm/mach-ixp4xx/Makefile index 640315d8b96a..5a4aaa0e0a09 100644 --- a/trunk/arch/arm/mach-ixp4xx/Makefile +++ b/trunk/arch/arm/mach-ixp4xx/Makefile @@ -2,23 +2,13 @@ # Makefile for the linux kernel. # -obj-pci-y := -obj-pci-n := - -obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o -obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o -obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o -obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o -obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o -obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o - obj-y += common.o -obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o -obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o -obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o -obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o -obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o -obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o +obj-$(CONFIG_PCI) += common-pci.o +obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o +obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o +obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o +obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o +obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o +obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o -obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index bf25a76e9bdf..00b761ff0f9c 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -276,7 +276,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs /* * Catch up with the real idea of time */ - while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) { + while ((*IXP4XX_OSTS - last_jiffy_time) > LATCH) { timer_tick(regs); last_jiffy_time += LATCH; } diff --git a/trunk/arch/arm/mach-ixp4xx/nas100d-power.c b/trunk/arch/arm/mach-ixp4xx/nas100d-power.c index a3745ed37f9f..99d333d7ebdd 100644 --- a/trunk/arch/arm/mach-ixp4xx/nas100d-power.c +++ b/trunk/arch/arm/mach-ixp4xx/nas100d-power.c @@ -20,10 +20,11 @@ #include #include #include -#include #include +extern void ctrl_alt_del(void); + static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs) { /* Signal init to do the ctrlaltdel action, this will bypass init if diff --git a/trunk/arch/arm/mach-ixp4xx/nas100d-setup.c b/trunk/arch/arm/mach-ixp4xx/nas100d-setup.c index 9a31444d9214..a3b4c6ac5708 100644 --- a/trunk/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -38,36 +37,6 @@ static struct platform_device nas100d_flash = { .resource = &nas100d_flash_resource, }; -#ifdef CONFIG_LEDS_IXP4XX -static struct resource nas100d_led_resources[] = { - { - .name = "wlan", /* green led */ - .start = 0, - .end = 0, - .flags = IXP4XX_GPIO_LOW, - }, - { - .name = "ready", /* blue power led (off is flashing!) */ - .start = 15, - .end = 15, - .flags = IXP4XX_GPIO_LOW, - }, - { - .name = "disk", /* yellow led */ - .start = 3, - .end = 3, - .flags = IXP4XX_GPIO_LOW, - }, -}; - -static struct platform_device nas100d_leds = { - .name = "IXP4XX-GPIO-LED", - .id = -1, - .num_resources = ARRAY_SIZE(nas100d_led_resources), - .resource = nas100d_led_resources, -}; -#endif - static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = { .sda_pin = NAS100D_SDA_PIN, .scl_pin = NAS100D_SCL_PIN, @@ -126,9 +95,7 @@ static struct platform_device nas100d_uart = { static struct platform_device *nas100d_devices[] __initdata = { &nas100d_i2c_controller, &nas100d_flash, -#ifdef CONFIG_LEDS_IXP4XX - &nas100d_leds, -#endif + &nas100d_uart, }; static void nas100d_power_off(void) @@ -155,12 +122,6 @@ static void __init nas100d_init(void) pm_power_off = nas100d_power_off; - /* This is only useful on a modified machine, but it is valuable - * to have it first in order to see debug messages, and so that - * it does *not* get removed if platform_add_devices fails! - */ - (void)platform_device_register(&nas100d_uart); - platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices)); } diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-power.c b/trunk/arch/arm/mach-ixp4xx/nslu2-power.c index 6d38e97142cc..d80c362bc539 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-power.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-power.c @@ -20,10 +20,11 @@ #include #include #include -#include #include +extern void ctrl_alt_del(void); + static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs) { /* Signal init to do the ctrlaltdel action, this will bypass init if diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c b/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c index 749a337494d3..55411f21d838 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -7,7 +7,6 @@ * Copyright (C) 2003-2004 MontaVista Software, Inc. * * Author: Mark Rakes - * Author: Rod Whitby * Maintainers: http://www.nslu2-linux.org/ * * Fixed missing init_time in MACHINE_START kas11 10/22/04 @@ -17,7 +16,6 @@ #include #include #include -#include #include #include @@ -45,42 +43,6 @@ static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = { .scl_pin = NSLU2_SCL_PIN, }; -#ifdef CONFIG_LEDS_IXP4XX -static struct resource nslu2_led_resources[] = { - { - .name = "ready", /* green led */ - .start = NSLU2_LED_GRN, - .end = NSLU2_LED_GRN, - .flags = IXP4XX_GPIO_HIGH, - }, - { - .name = "status", /* red led */ - .start = NSLU2_LED_RED, - .end = NSLU2_LED_RED, - .flags = IXP4XX_GPIO_HIGH, - }, - { - .name = "disk-1", - .start = NSLU2_LED_DISK1, - .end = NSLU2_LED_DISK1, - .flags = IXP4XX_GPIO_LOW, - }, - { - .name = "disk-2", - .start = NSLU2_LED_DISK2, - .end = NSLU2_LED_DISK2, - .flags = IXP4XX_GPIO_LOW, - }, -}; - -static struct platform_device nslu2_leds = { - .name = "IXP4XX-GPIO-LED", - .id = -1, - .num_resources = ARRAY_SIZE(nslu2_led_resources), - .resource = nslu2_led_resources, -}; -#endif - static struct platform_device nslu2_i2c_controller = { .name = "IXP4XX-I2C", .id = 0, @@ -140,10 +102,8 @@ static struct platform_device nslu2_uart = { static struct platform_device *nslu2_devices[] __initdata = { &nslu2_i2c_controller, &nslu2_flash, + &nslu2_uart, &nslu2_beeper, -#ifdef CONFIG_LEDS_IXP4XX - &nslu2_leds, -#endif }; static void nslu2_power_off(void) @@ -167,12 +127,6 @@ static void __init nslu2_init(void) pm_power_off = nslu2_power_off; - /* This is only useful on a modified machine, but it is valuable - * to have it first in order to see debug messages, and so that - * it does *not* get removed if platform_add_devices fails! - */ - (void)platform_device_register(&nslu2_uart); - platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices)); } diff --git a/trunk/arch/arm/mach-omap1/board-ams-delta.c b/trunk/arch/arm/mach-omap1/board-ams-delta.c index 73df32aac4c4..6178f046f128 100644 --- a/trunk/arch/arm/mach-omap1/board-ams-delta.c +++ b/trunk/arch/arm/mach-omap1/board-ams-delta.c @@ -84,15 +84,6 @@ static struct omap_board_config_kernel ams_delta_config[] = { { OMAP_TAG_UART, &ams_delta_uart_config }, }; -static struct platform_device ams_delta_led_device = { - .name = "ams-delta-led", - .id = -1 -}; - -static struct platform_device *ams_delta_devices[] __initdata = { - &ams_delta_led_device, -}; - static void __init ams_delta_init(void) { iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); @@ -103,8 +94,6 @@ static void __init ams_delta_init(void) /* Clear latch2 (NAND, LCD, modem enable) */ ams_delta_latch2_write(~0, 0); - - platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); } static void __init ams_delta_map_io(void) diff --git a/trunk/arch/arm/mach-pnx4008/clock.c b/trunk/arch/arm/mach-pnx4008/clock.c index f582ed2ec43c..285b22f631e9 100644 --- a/trunk/arch/arm/mach-pnx4008/clock.c +++ b/trunk/arch/arm/mach-pnx4008/clock.c @@ -767,54 +767,6 @@ static struct clk *onchip_clks[] = { &uart6_ck, }; -static int local_clk_enable(struct clk *clk) -{ - int ret = 0; - - if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate - && clk->user_rate) - ret = clk->set_rate(clk, clk->user_rate); - return ret; -} - -static void local_clk_disable(struct clk *clk) -{ - if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) - clk->set_rate(clk, 0); -} - -static void local_clk_unuse(struct clk *clk) -{ - if (clk->usecount > 0 && !(--clk->usecount)) { - local_clk_disable(clk); - if (clk->parent) - local_clk_unuse(clk->parent); - } -} - -static int local_clk_use(struct clk *clk) -{ - int ret = 0; - if (clk->usecount++ == 0) { - if (clk->parent) - ret = local_clk_use(clk->parent); - - if (ret != 0) { - clk->usecount--; - goto out; - } - - ret = local_clk_enable(clk); - - if (ret != 0 && clk->parent) { - local_clk_unuse(clk->parent); - clk->usecount--; - } - } -out: - return ret; -} - static int local_set_rate(struct clk *clk, u32 rate) { int ret = -EINVAL; @@ -895,12 +847,28 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); +static int local_clk_enable(struct clk *clk) +{ + int ret = 0; + + if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate + && clk->user_rate) + ret = clk->set_rate(clk, clk->user_rate); + return ret; +} + +static void local_clk_disable(struct clk *clk) +{ + if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) + clk->set_rate(clk, 0); +} + int clk_enable(struct clk *clk) { int ret = 0; clock_lock(); - ret = local_clk_use(clk); + ret = local_clk_enable(clk); clock_unlock(); return ret; } @@ -910,12 +878,71 @@ EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { clock_lock(); - local_clk_unuse(clk); + local_clk_disable(clk); clock_unlock(); } EXPORT_SYMBOL(clk_disable); +static void local_clk_unuse(struct clk *clk) +{ + if (clk->usecount > 0 && !(--clk->usecount)) { + local_clk_disable(clk); + if (clk->parent) + local_clk_unuse(clk->parent); + } +} + +static int local_clk_use(struct clk *clk) +{ + int ret = 0; + if (clk->usecount++ == 0) { + if (clk->parent) + ret = local_clk_use(clk->parent); + + if (ret != 0) { + clk->usecount--; + goto out; + } + + ret = local_clk_enable(clk); + + if (ret != 0 && clk->parent) { + local_clk_unuse(clk->parent); + clk->usecount--; + } + } +out: + return ret; +} + +/* The main purpose of clk_use ans clk_unuse functions + * is to control switching 13MHz oscillator and PLL1 (13'MHz), + * so that they are disabled whenever none of PLL2-5 is using them. + * Although in theory these functions should work with any clock, + * please use them only on PLL2 - PLL5 to avoid confusion. + */ +int clk_use(struct clk *clk) +{ + int ret = 0; + + clock_lock(); + ret = local_clk_use(clk); + clock_unlock(); + return ret; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ + + clock_lock(); + local_clk_unuse(clk); + clock_unlock(); +} + +EXPORT_SYMBOL(clk_unuse); + long clk_round_rate(struct clk *clk, unsigned long rate) { long ret; @@ -968,7 +995,7 @@ static int __init clk_init(void) __FUNCTION__, (*clkp)->name, (*clkp)->rate); } - local_clk_use(&ck_pll4); + clk_use(&ck_pll4); /* if ck_13MHz is not used, disable it. */ if (ck_13MHz.usecount == 0) diff --git a/trunk/arch/arm/mach-pnx4008/serial.c b/trunk/arch/arm/mach-pnx4008/serial.c index 95a1b3f964a2..10322384e45d 100644 --- a/trunk/arch/arm/mach-pnx4008/serial.c +++ b/trunk/arch/arm/mach-pnx4008/serial.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include diff --git a/trunk/arch/arm/mach-pxa/sleep.S b/trunk/arch/arm/mach-pxa/sleep.S index 0650bed3b96e..c9862688ff3d 100644 --- a/trunk/arch/arm/mach-pxa/sleep.S +++ b/trunk/arch/arm/mach-pxa/sleep.S @@ -189,7 +189,7 @@ ENTRY(pxa_cpu_suspend) .data .align 5 ENTRY(pxa_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off + mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC @ set SVC, irqs off msr cpsr_c, r0 ldr r0, sleep_save_sp @ stack phys addr diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig index b4171dd43df0..0c334136db7c 100644 --- a/trunk/arch/arm/mach-s3c2410/Kconfig +++ b/trunk/arch/arm/mach-s3c2410/Kconfig @@ -71,22 +71,16 @@ config ARCH_S3C2440 Say Y here if you are using the SMDK2440. config SMDK2440_CPU2440 - bool "SMDK2440 with S3C2440 CPU module" + bool "SMDK2440 with S3C2440 cpu module" depends on ARCH_S3C2440 default y if ARCH_S3C2440 select CPU_S3C2440 config SMDK2440_CPU2442 - bool "SMDM2440 with S3C2442 CPU module" + bool "SMDM2440 with S3C2442 cpu module" depends on ARCH_S3C2440 select CPU_S3C2442 -config MACH_SMDK2413 - bool "SMDK2413" - select CPU_S3C2412 - select MACH_SMDK - help - Say Y here if you are using an SMDK2413 config MACH_VR1000 bool "Thorcom VR1000" @@ -120,33 +114,13 @@ config MACH_NEXCODER_2440 endmenu -config S3C2410_CLOCK - bool - help - Clock code for the S3C2410, and similar processors - config CPU_S3C2410 bool depends on ARCH_S3C2410 - select S3C2410_CLOCK help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. -# internal node to signify if we are only dealing with an S3C2412 - -config CPU_S3C2412_ONLY - bool - depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ - !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412 - default y if CPU_S3C2412 - -config CPU_S3C2412 - bool - depends on ARCH_S3C2410 - help - Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line - config CPU_S3C244X bool depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) @@ -156,7 +130,6 @@ config CPU_S3C244X config CPU_S3C2440 bool depends on ARCH_S3C2410 - select S3C2410_CLOCK select CPU_S3C244X help Support for S3C2440 Samsung Mobile CPU based systems. @@ -164,7 +137,6 @@ config CPU_S3C2440 config CPU_S3C2442 bool depends on ARCH_S3C2420 - select S3C2410_CLOCK select CPU_S3C244X help Support for S3C2442 Samsung Mobile CPU based systems. diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile index 0c7938645df6..5e09355cd4f4 100644 --- a/trunk/arch/arm/mach-s3c2410/Makefile +++ b/trunk/arch/arm/mach-s3c2410/Makefile @@ -24,20 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o -# S3C2412 support -obj-$(CONFIG_CPU_S3C2412) += s3c2412.o -obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o - -# # S3C244X support obj-$(CONFIG_CPU_S3C244X) += s3c244x.o obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o -# Clock control - -obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o - # S3C2440 support obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o @@ -62,7 +53,6 @@ obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o obj-$(CONFIG_ARCH_H1940) += mach-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o -obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o diff --git a/trunk/arch/arm/mach-s3c2410/clock.c b/trunk/arch/arm/mach-s3c2410/clock.c index e13fb6778890..99d174612b53 100644 --- a/trunk/arch/arm/mach-s3c2410/clock.c +++ b/trunk/arch/arm/mach-s3c2410/clock.c @@ -3,7 +3,7 @@ * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks * - * S3C24XX Core clock control support + * S3C2410 Clock control support * * Based on, and code from linux/arch/arm/mach-versatile/clock.c ** @@ -56,6 +56,25 @@ static LIST_HEAD(clocks); DEFINE_MUTEX(clocks_mutex); +/* old functions */ + +void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) +{ + unsigned long clkcon; + + clkcon = __raw_readl(S3C2410_CLKCON); + + if (enable) + clkcon |= clocks; + else + clkcon &= ~clocks; + + /* ensure none of the special function bits set */ + clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3); + + __raw_writel(clkcon, S3C2410_CLKCON); +} + /* enable and disable calls for use with the clk struct */ static int clk_null_enable(struct clk *clk, int enable) @@ -63,6 +82,12 @@ static int clk_null_enable(struct clk *clk, int enable) return 0; } +int s3c24xx_clkcon_enable(struct clk *clk, int enable) +{ + s3c24xx_clk_enable(clk->ctrlbit, enable); + return 0; +} + /* Clock API calls */ struct clk *clk_get(struct device *dev, const char *id) @@ -148,11 +173,8 @@ unsigned long clk_get_rate(struct clk *clk) if (clk->rate != 0) return clk->rate; - if (clk->get_rate != NULL) - return (clk->get_rate)(clk); - - if (clk->parent != NULL) - return clk_get_rate(clk->parent); + while (clk->parent != NULL && clk->rate == 0) + clk = clk->parent; return clk->rate; } @@ -211,9 +233,31 @@ EXPORT_SYMBOL(clk_set_rate); EXPORT_SYMBOL(clk_get_parent); EXPORT_SYMBOL(clk_set_parent); +/* base clock enable */ + +static int s3c24xx_upll_enable(struct clk *clk, int enable) +{ + unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); + unsigned long orig = clkslow; + + if (enable) + clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF; + else + clkslow |= S3C2410_CLKSLOW_UCLK_OFF; + + __raw_writel(clkslow, S3C2410_CLKSLOW); + + /* if we started the UPLL, then allow to settle */ + + if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF)) + udelay(200); + + return 0; +} + /* base clocks */ -struct clk clk_xtal = { +static struct clk clk_xtal = { .name = "xtal", .id = -1, .rate = 0, @@ -221,27 +265,23 @@ struct clk clk_xtal = { .ctrlbit = 0, }; -struct clk clk_mpll = { - .name = "mpll", - .id = -1, -}; - -struct clk clk_upll = { +static struct clk clk_upll = { .name = "upll", .id = -1, .parent = NULL, + .enable = s3c24xx_upll_enable, .ctrlbit = 0, }; -struct clk clk_f = { +static struct clk clk_f = { .name = "fclk", .id = -1, .rate = 0, - .parent = &clk_mpll, + .parent = NULL, .ctrlbit = 0, }; -struct clk clk_h = { +static struct clk clk_h = { .name = "hclk", .id = -1, .rate = 0, @@ -249,7 +289,7 @@ struct clk clk_h = { .ctrlbit = 0, }; -struct clk clk_p = { +static struct clk clk_p = { .name = "pclk", .id = -1, .rate = 0, @@ -268,14 +308,14 @@ struct clk clk_usb_bus = { static int s3c24xx_dclk_enable(struct clk *clk, int enable) { - unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON); + unsigned long dclkcon = __raw_readl(S3C2410_DCLKCON); if (enable) dclkcon |= clk->ctrlbit; else dclkcon &= ~clk->ctrlbit; - __raw_writel(dclkcon, S3C24XX_DCLKCON); + __raw_writel(dclkcon, S3C2410_DCLKCON); return 0; } @@ -294,7 +334,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent) clk->parent = parent; - dclkcon = __raw_readl(S3C24XX_DCLKCON); + dclkcon = __raw_readl(S3C2410_DCLKCON); if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) { if (uclk) @@ -308,7 +348,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent) dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK; } - __raw_writel(dclkcon, S3C24XX_DCLKCON); + __raw_writel(dclkcon, S3C2410_DCLKCON); return 0; } @@ -386,6 +426,108 @@ struct clk s3c24xx_uclk = { .id = -1, }; + +/* standard clock definitions */ + +static struct clk init_clocks[] = { + { + .name = "nand", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_NAND, + }, { + .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_LCDC, + }, { + .name = "usb-host", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBH, + }, { + .name = "usb-device", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBD, + }, { + .name = "timers", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_PWMT, + }, { + .name = "sdi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SDI, + }, { + .name = "uart", + .id = 0, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART0, + }, { + .name = "uart", + .id = 1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART1, + }, { + .name = "uart", + .id = 2, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART2, + }, { + .name = "gpio", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_GPIO, + }, { + .name = "rtc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_RTC, + }, { + .name = "adc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_ADC, + }, { + .name = "i2c", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIC, + }, { + .name = "iis", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIS, + }, { + .name = "spi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SPI, + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_p, + .ctrlbit = 0, + } +}; + /* initialise the clock system */ int s3c24xx_register_clock(struct clk *clk) @@ -395,6 +537,14 @@ int s3c24xx_register_clock(struct clk *clk) if (clk->enable == NULL) clk->enable = clk_null_enable; + /* if this is a standard clock, set the usage state */ + + if (clk->ctrlbit && clk->enable == s3c24xx_clkcon_enable) { + unsigned long clkcon = __raw_readl(S3C2410_CLKCON); + + clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0; + } + /* add to the list of available clocks */ mutex_lock(&clocks_mutex); @@ -411,18 +561,44 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, unsigned long hclk, unsigned long pclk) { - printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n"); + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); + unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); + struct clk *clkp = init_clocks; + int ptr; + int ret; + + printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n"); /* initialise the main system clocks */ clk_xtal.rate = xtal; - clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal); + clk_upll.rate = s3c2410_get_pll(upllcon, xtal); - clk_mpll.rate = fclk; clk_h.rate = hclk; clk_p.rate = pclk; clk_f.rate = fclk; + /* We must be careful disabling the clocks we are not intending to + * be using at boot time, as subsytems such as the LCD which do + * their own DMA requests to the bus can cause the system to lockup + * if they where in the middle of requesting bus access. + * + * Disabling the LCD clock if the LCD is active is very dangerous, + * and therefore the bootloader should be careful to not enable + * the LCD clock if it is not needed. + */ + + mutex_lock(&clocks_mutex); + + s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); + + mutex_unlock(&clocks_mutex); + /* assume uart clocks are correctly setup */ /* register our clocks */ @@ -430,9 +606,6 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, if (s3c24xx_register_clock(&clk_xtal) < 0) printk(KERN_ERR "failed to register master xtal\n"); - if (s3c24xx_register_clock(&clk_mpll) < 0) - printk(KERN_ERR "failed to register mpll clock\n"); - if (s3c24xx_register_clock(&clk_upll) < 0) printk(KERN_ERR "failed to register upll clock\n"); @@ -445,5 +618,27 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, if (s3c24xx_register_clock(&clk_p) < 0) printk(KERN_ERR "failed to register cpu pclk\n"); + + if (s3c24xx_register_clock(&clk_usb_bus) < 0) + printk(KERN_ERR "failed to register usb bus clock\n"); + + /* register clocks from clock array */ + + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + /* show the clock-slow value */ + + printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n", + print_mhz(xtal / ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))), + (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast", + (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on", + (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on"); + return 0; } diff --git a/trunk/arch/arm/mach-s3c2410/clock.h b/trunk/arch/arm/mach-s3c2410/clock.h index 7f0ea03e1d49..01bb458bf8eb 100644 --- a/trunk/arch/arm/mach-s3c2410/clock.h +++ b/trunk/arch/arm/mach-s3c2410/clock.h @@ -22,7 +22,6 @@ struct clk { int (*enable)(struct clk *, int enable); int (*set_rate)(struct clk *c, unsigned long rate); - unsigned long (*get_rate)(struct clk *c); unsigned long (*round_rate)(struct clk *c, unsigned long rate); int (*set_parent)(struct clk *c, struct clk *parent); }; @@ -37,15 +36,6 @@ extern struct clk s3c24xx_uclk; extern struct clk clk_usb_bus; -/* core clock support */ - -extern struct clk clk_f; -extern struct clk clk_h; -extern struct clk clk_p; -extern struct clk clk_mpll; -extern struct clk clk_upll; -extern struct clk clk_xtal; - /* exports for arch/arm/mach-s3c2410 * * Please DO NOT use these outside of arch/arm/mach-s3c2410 @@ -53,8 +43,7 @@ extern struct clk clk_xtal; extern struct mutex clocks_mutex; -extern int s3c2410_clkcon_enable(struct clk *clk, int enable); - +extern int s3c24xx_clkcon_enable(struct clk *clk, int enable); extern int s3c24xx_register_clock(struct clk *clk); extern int s3c24xx_setup_clocks(unsigned long xtal, diff --git a/trunk/arch/arm/mach-s3c2410/cpu.c b/trunk/arch/arm/mach-s3c2410/cpu.c index 1c3c6adae6c4..52842e6e86e6 100644 --- a/trunk/arch/arm/mach-s3c2410/cpu.c +++ b/trunk/arch/arm/mach-s3c2410/cpu.c @@ -44,7 +44,6 @@ #include "clock.h" #include "s3c2400.h" #include "s3c2410.h" -#include "s3c2412.h" #include "s3c244x.h" #include "s3c2440.h" #include "s3c2442.h" @@ -63,7 +62,6 @@ struct cpu_table { static const char name_s3c2400[] = "S3C2400"; static const char name_s3c2410[] = "S3C2410"; -static const char name_s3c2412[] = "S3C2412"; static const char name_s3c2440[] = "S3C2440"; static const char name_s3c2442[] = "S3C2442"; static const char name_s3c2410a[] = "S3C2410A"; @@ -115,15 +113,6 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s3c2442_init, .name = name_s3c2442 }, - { - .idcode = 0x32412001, - .idmask = 0xffffffff, - .map_io = s3c2412_map_io, - .init_clocks = s3c2412_init_clocks, - .init_uarts = s3c2412_init_uarts, - .init = s3c2412_init, - .name = name_s3c2412, - }, { .idcode = 0x0, /* S3C2400 doesn't have an idcode */ .idmask = 0xffffffff, @@ -182,24 +171,6 @@ void s3c24xx_set_board(struct s3c24xx_board *b) static struct cpu_table *cpu; -static unsigned long s3c24xx_read_idcode_v5(void) -{ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) - return __raw_readl(S3C2412_GSTATUS1); -#else - return 1UL; /* don't look like an 2400 */ -#endif -} - -static unsigned long s3c24xx_read_idcode_v4(void) -{ -#ifndef CONFIG_CPU_S3C2400 - return __raw_readl(S3C2410_GSTATUS1); -#else - return 0UL; -#endif -} - void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) { unsigned long idcode = 0x0; @@ -207,11 +178,9 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) /* initialise the io descriptors we need for initialisation */ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); - if (cpu_architecture() >= CPU_ARCH_ARMv5) { - idcode = s3c24xx_read_idcode_v5(); - } else { - idcode = s3c24xx_read_idcode_v4(); - } +#ifndef CONFIG_CPU_S3C2400 + idcode = __raw_readl(S3C2410_GSTATUS1); +#endif cpu = s3c_lookup_cpu(idcode); diff --git a/trunk/arch/arm/mach-s3c2410/cpu.h b/trunk/arch/arm/mach-s3c2410/cpu.h index b0ed9d2d141b..40862899b2f1 100644 --- a/trunk/arch/arm/mach-s3c2410/cpu.h +++ b/trunk/arch/arm/mach-s3c2410/cpu.h @@ -73,7 +73,5 @@ extern struct sys_timer s3c24xx_timer; /* system device classes */ -extern struct sysdev_class s3c2410_sysclass; -extern struct sysdev_class s3c2412_sysclass; extern struct sysdev_class s3c2440_sysclass; extern struct sysdev_class s3c2442_sysclass; diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c index 6822dc7f7799..66d8c068e940 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -191,9 +191,13 @@ static struct irqchip s3c_irq_chip = { .ack = s3c_irq_ack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .set_wake = s3c_irq_wake }; +/* S3C2410_EINTMASK + * S3C2410_EINTPEND + */ + static void s3c_irqext_mask(unsigned int irqno) { @@ -201,9 +205,9 @@ s3c_irqext_mask(unsigned int irqno) irqno -= EXTINT_OFF; - mask = __raw_readl(S3C24XX_EINTMASK); + mask = __raw_readl(S3C2410_EINTMASK); mask |= ( 1UL << irqno); - __raw_writel(mask, S3C24XX_EINTMASK); + __raw_writel(mask, S3C2410_EINTMASK); if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { /* check to see if all need masking */ @@ -228,11 +232,11 @@ s3c_irqext_ack(unsigned int irqno) bit = 1UL << (irqno - EXTINT_OFF); - mask = __raw_readl(S3C24XX_EINTMASK); + mask = __raw_readl(S3C2410_EINTMASK); - __raw_writel(bit, S3C24XX_EINTPEND); + __raw_writel(bit, S3C2410_EINTPEND); - req = __raw_readl(S3C24XX_EINTPEND); + req = __raw_readl(S3C2410_EINTPEND); req &= ~mask; /* not sure if we should be acking the parent irq... */ @@ -253,9 +257,9 @@ s3c_irqext_unmask(unsigned int irqno) irqno -= EXTINT_OFF; - mask = __raw_readl(S3C24XX_EINTMASK); + mask = __raw_readl(S3C2410_EINTMASK); mask &= ~( 1UL << irqno); - __raw_writel(mask, S3C24XX_EINTMASK); + __raw_writel(mask, S3C2410_EINTMASK); s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); } @@ -271,28 +275,28 @@ s3c_irqext_type(unsigned int irq, unsigned int type) if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) { gpcon_reg = S3C2410_GPFCON; - extint_reg = S3C24XX_EXTINT0; + extint_reg = S3C2410_EXTINT0; gpcon_offset = (irq - IRQ_EINT0) * 2; extint_offset = (irq - IRQ_EINT0) * 4; } else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7)) { gpcon_reg = S3C2410_GPFCON; - extint_reg = S3C24XX_EXTINT0; + extint_reg = S3C2410_EXTINT0; gpcon_offset = (irq - (EXTINT_OFF)) * 2; extint_offset = (irq - (EXTINT_OFF)) * 4; } else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15)) { gpcon_reg = S3C2410_GPGCON; - extint_reg = S3C24XX_EXTINT1; + extint_reg = S3C2410_EXTINT1; gpcon_offset = (irq - IRQ_EINT8) * 2; extint_offset = (irq - IRQ_EINT8) * 4; } else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23)) { gpcon_reg = S3C2410_GPGCON; - extint_reg = S3C24XX_EXTINT2; + extint_reg = S3C2410_EXTINT2; gpcon_offset = (irq - IRQ_EINT8) * 2; extint_offset = (irq - IRQ_EINT16) * 4; } else @@ -568,23 +572,6 @@ s3c_irq_demux_uart2(unsigned int irq, s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); } -static void -s3c_irq_demux_extint(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) -{ - unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); - unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); - - eintpnd &= ~eintmsk; - - if (eintpnd) { - irq = fls(eintpnd); - irq += (IRQ_EINT4 - (4 + 1)); - - desc_handle_irq(irq, irq_desc + irq, regs); - } -} /* s3c24xx_init_irq * @@ -604,12 +591,12 @@ void __init s3c24xx_init_irq(void) last = 0; for (i = 0; i < 4; i++) { - pend = __raw_readl(S3C24XX_EINTPEND); + pend = __raw_readl(S3C2410_EINTPEND); if (pend == 0 || pend == last) break; - __raw_writel(pend, S3C24XX_EINTPEND); + __raw_writel(pend, S3C2410_EINTPEND); printk("irq: clearing pending ext status %08x\n", (int)pend); last = pend; } @@ -643,14 +630,12 @@ void __init s3c24xx_init_irq(void) irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); - for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) { + for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) { /* set all the s3c2410 internal irqs */ switch (irqno) { /* deal with the special IRQs (cascaded) */ - case IRQ_EINT4t7: - case IRQ_EINT8t23: case IRQ_UART0: case IRQ_UART1: case IRQ_UART2: @@ -674,14 +659,12 @@ void __init s3c24xx_init_irq(void) /* setup the cascade irq handlers */ - set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); - set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); - set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); + /* external interrupts */ for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2413.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2413.c deleted file mode 100644 index b7ef7d3c54a9..000000000000 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2413.c +++ /dev/null @@ -1,126 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the - * loans of SMDK2413 to work with. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -//#include -#include -#include -#include - -#include -#include - -#include "s3c2410.h" -#include "s3c2412.h" -#include "clock.h" -#include "devs.h" -#include "cpu.h" - -#include "common-smdk.h" - -static struct map_desc smdk2413_iodesc[] __initdata = { -}; - -static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - [1] = { - .hwport = 1, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - /* IR port */ - [2] = { - .hwport = 2, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x43, - .ufcon = 0x51, - } -}; - -static struct platform_device *smdk2413_devices[] __initdata = { - &s3c_device_usb, - //&s3c_device_lcd, - &s3c_device_wdt, - &s3c_device_i2c, - &s3c_device_iis, -}; - -static struct s3c24xx_board smdk2413_board __initdata = { - .devices = smdk2413_devices, - .devices_count = ARRAY_SIZE(smdk2413_devices) -}; - -static void __init smdk2413_fixup(struct machine_desc *desc, - struct tag *tags, char **cmdline, - struct meminfo *mi) -{ - if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) { - mi->nr_banks=1; - mi->bank[0].start = 0x30000000; - mi->bank[0].size = SZ_64M; - mi->bank[0].node = 0; - } -} - -static void __init smdk2413_map_io(void) -{ - s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc)); - s3c24xx_init_clocks(12000000); - s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs)); - s3c24xx_set_board(&smdk2413_board); -} - -static void __init smdk2413_machine_init(void) -{ - smdk_machine_init(); -} - -MACHINE_START(S3C2413, "SMDK2413") - /* Maintainer: Ben Dooks */ - .phys_io = S3C2410_PA_UART, - .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, - .boot_params = S3C2410_SDRAM_PA + 0x100, - - .fixup = smdk2413_fixup, - .init_irq = s3c24xx_init_irq, - .map_io = smdk2413_map_io, - .init_machine = smdk2413_machine_init, - .timer = &s3c24xx_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2410/pm-simtec.c b/trunk/arch/arm/mach-s3c2410/pm-simtec.c index 7b244566a436..4c7ccef6c207 100644 --- a/trunk/arch/arm/mach-s3c2410/pm-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/pm-simtec.c @@ -48,8 +48,7 @@ static __init int pm_simtec_init(void) /* check which machine we are running on */ - if (!machine_is_bast() && !machine_is_vr1000() && - !machine_is_anubis() && !machine_is_osiris()) + if (!machine_is_bast() && !machine_is_vr1000() && !machine_is_anubis()) return 0; printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c b/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c deleted file mode 100644 index 99718663318e..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-clock.c +++ /dev/null @@ -1,271 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/clock.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410,S3C2440,S3C2442 Clock control support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "clock.h" -#include "cpu.h" - -int s3c2410_clkcon_enable(struct clk *clk, int enable) -{ - unsigned int clocks = clk->ctrlbit; - unsigned long clkcon; - - clkcon = __raw_readl(S3C2410_CLKCON); - - if (enable) - clkcon |= clocks; - else - clkcon &= ~clocks; - - /* ensure none of the special function bits set */ - clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); - - __raw_writel(clkcon, S3C2410_CLKCON); - - return 0; -} - -static int s3c2410_upll_enable(struct clk *clk, int enable) -{ - unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); - unsigned long orig = clkslow; - - if (enable) - clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF; - else - clkslow |= S3C2410_CLKSLOW_UCLK_OFF; - - __raw_writel(clkslow, S3C2410_CLKSLOW); - - /* if we started the UPLL, then allow to settle */ - - if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF)) - udelay(200); - - return 0; -} - -/* standard clock definitions */ - -static struct clk init_clocks_disable[] = { - { - .name = "nand", - .id = -1, - .parent = &clk_h, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_NAND, - }, { - .name = "sdi", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_SDI, - }, { - .name = "adc", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_ADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_IIC, - }, { - .name = "iis", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_IIS, - }, { - .name = "spi", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_SPI, - } -}; - -static struct clk init_clocks[] = { - { - .name = "lcd", - .id = -1, - .parent = &clk_h, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_LCDC, - }, { - .name = "gpio", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_GPIO, - }, { - .name = "usb-host", - .id = -1, - .parent = &clk_h, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_USBH, - }, { - .name = "usb-device", - .id = -1, - .parent = &clk_h, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_USBD, - }, { - .name = "timers", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_PWMT, - }, { - .name = "uart", - .id = 0, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_UART2, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_p, - .enable = s3c2410_clkcon_enable, - .ctrlbit = S3C2410_CLKCON_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_p, - .ctrlbit = 0, - }, { - .name = "usb-bus-host", - .id = -1, - .parent = &clk_usb_bus, - }, { - .name = "usb-bus-gadget", - .id = -1, - .parent = &clk_usb_bus, - }, -}; - -/* s3c2410_baseclk_add() - * - * Add all the clocks used by the s3c2410 or compatible CPUs - * such as the S3C2440 and S3C2442. - * - * We cannot use a system device as we are needed before any - * of the init-calls that initialise the devices are actually - * done. -*/ - -int __init s3c2410_baseclk_add(void) -{ - unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW); - unsigned long clkcon = __raw_readl(S3C2410_CLKCON); - struct clk *clkp; - struct clk *xtal; - int ret; - int ptr; - - clk_upll.enable = s3c2410_upll_enable; - - if (s3c24xx_register_clock(&clk_usb_bus) < 0) - printk(KERN_ERR "failed to register usb bus clock\n"); - - /* register clocks from clock array */ - - clkp = init_clocks; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { - /* ensure that we note the clock state */ - - clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0; - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } - - /* We must be careful disabling the clocks we are not intending to - * be using at boot time, as subsytems such as the LCD which do - * their own DMA requests to the bus can cause the system to lockup - * if they where in the middle of requesting bus access. - * - * Disabling the LCD clock if the LCD is active is very dangerous, - * and therefore the bootloader should be careful to not enable - * the LCD clock if it is not needed. - */ - - /* install (and disable) the clocks we do not need immediately */ - - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - - s3c2410_clkcon_enable(clkp, 0); - } - - /* show the clock-slow value */ - - xtal = clk_get(NULL, "xtal"); - - printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n", - print_mhz(clk_get_rate(xtal) / - ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))), - (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast", - (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on", - (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on"); - - return 0; -} diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c b/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c index 471a71490010..d5e1caea1d23 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-gpio.c @@ -18,6 +18,9 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Changelog + * 15-Jan-2006 LCVR Splitted from gpio.c */ #include @@ -35,7 +38,7 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, unsigned int config) { - void __iomem *reg = S3C24XX_EINFLT0; + void __iomem *reg = S3C2410_EINFLT0; unsigned long flags; unsigned long val; @@ -44,7 +47,7 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, config &= 0xff; - pin -= S3C2410_GPG8; + pin -= S3C2410_GPG8_EINT16; reg += pin & ~3; local_irq_save(flags); @@ -58,10 +61,10 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, /* update filter enable */ - val = __raw_readl(S3C24XX_EXTINT2); + val = __raw_readl(S3C2410_EXTINT2); val &= ~(1 << ((pin * 4) + 3)); val |= on << ((pin * 4) + 3); - __raw_writel(val, S3C24XX_EXTINT2); + __raw_writel(val, S3C2410_EXTINT2); local_irq_restore(flags); @@ -72,7 +75,7 @@ EXPORT_SYMBOL(s3c2410_gpio_irqfilter); int s3c2410_gpio_getirq(unsigned int pin) { - if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15) + if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) return -1; /* not valid interrupts */ if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410.c b/trunk/arch/arm/mach-s3c2410/s3c2410.c index a110cff9cf6b..0852e87a79c4 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -109,33 +108,11 @@ void __init s3c2410_init_clocks(int xtal) */ s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); - s3c2410_baseclk_add(); } -struct sysdev_class s3c2410_sysclass = { - set_kset_name("s3c2410-core"), -}; - -static struct sys_device s3c2410_sysdev = { - .cls = &s3c2410_sysclass, -}; - -/* need to register class before we actually register the device, and - * we also need to ensure that it has been initialised before any of the - * drivers even try to use it (even if not on an s3c2440 based system) - * as a driver which may support both 2410 and 2440 may try and use it. -*/ - -static int __init s3c2410_core_init(void) -{ - return sysdev_class_register(&s3c2410_sysclass); -} - -core_initcall(s3c2410_core_init); - int __init s3c2410_init(void) { printk("S3C2410: Initialising architecture\n"); - return sysdev_register(&s3c2410_sysdev); + return 0; } diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410.h b/trunk/arch/arm/mach-s3c2410/s3c2410.h index 73f1a2474a61..4d5312a48209 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.h +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.h @@ -29,8 +29,6 @@ extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s3c2410_init_clocks(int xtal); -extern int s3c2410_baseclk_add(void); - #else #define s3c2410_init_clocks NULL #define s3c2410_init_uarts NULL diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412-clock.c b/trunk/arch/arm/mach-s3c2410/s3c2412-clock.c deleted file mode 100644 index c95ed3e18580..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2412-clock.c +++ /dev/null @@ -1,711 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2412,S3C2413 Clock control support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "clock.h" -#include "cpu.h" - -/* We currently have to assume that the system is running - * from the XTPll input, and that all ***REFCLKs are being - * fed from it, as we cannot read the state of OM[4] from - * software. - * - * It would be possible for each board initialisation to - * set the correct muxing at initialisation -*/ - -int s3c2412_clkcon_enable(struct clk *clk, int enable) -{ - unsigned int clocks = clk->ctrlbit; - unsigned long clkcon; - - clkcon = __raw_readl(S3C2410_CLKCON); - - if (enable) - clkcon |= clocks; - else - clkcon &= ~clocks; - - __raw_writel(clkcon, S3C2410_CLKCON); - - return 0; -} - -static int s3c2412_upll_enable(struct clk *clk, int enable) -{ - unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); - unsigned long orig = upllcon; - - if (!enable) - upllcon |= S3C2412_PLLCON_OFF; - else - upllcon &= ~S3C2412_PLLCON_OFF; - - __raw_writel(upllcon, S3C2410_UPLLCON); - - /* allow ~150uS for the PLL to settle and lock */ - - if (enable && (orig & S3C2412_PLLCON_OFF)) - udelay(150); - - return 0; -} - -/* clock selections */ - -/* CPU EXTCLK input */ -static struct clk clk_ext = { - .name = "extclk", - .id = -1, -}; - -static struct clk clk_erefclk = { - .name = "erefclk", - .id = -1, -}; - -static struct clk clk_urefclk = { - .name = "urefclk", - .id = -1, -}; - -static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_urefclk) - clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL; - else if (parent == &clk_upll) - clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} - -static struct clk clk_usysclk = { - .name = "usysclk", - .id = -1, - .parent = &clk_xtal, - .set_parent = s3c2412_setparent_usysclk, -}; - -static struct clk clk_mrefclk = { - .name = "mrefclk", - .parent = &clk_xtal, - .id = -1, -}; - -static struct clk clk_mdivclk = { - .name = "mdivclk", - .parent = &clk_xtal, - .id = -1, -}; - -static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_usysclk) - clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK; - else if (parent == &clk_h) - clksrc |= S3C2412_CLKSRC_USBCLK_HCLK; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} - -static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - return parent_rate; - - div = parent_rate / rate; - if (div > 2) - div = 2; - - return parent_rate / div; -} - -static unsigned long s3c2412_getrate_usbsrc(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2410_CLKDIVN); - - return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1); -} - -static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); - - rate = s3c2412_roundrate_usbsrc(clk, rate); - - if ((parent_rate / rate) == 2) - clkdivn |= S3C2412_CLKDIVN_USB48DIV; - else - clkdivn &= ~S3C2412_CLKDIVN_USB48DIV; - - __raw_writel(clkdivn, S3C2410_CLKDIVN); - return 0; -} - -static struct clk clk_usbsrc = { - .name = "usbsrc", - .id = -1, - .get_rate = s3c2412_getrate_usbsrc, - .set_rate = s3c2412_setrate_usbsrc, - .round_rate = s3c2412_roundrate_usbsrc, - .set_parent = s3c2412_setparent_usbsrc, -}; - -static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_mdivclk) - clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; - else if (parent == &clk_upll) - clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} - -static struct clk clk_msysclk = { - .name = "msysclk", - .id = -1, - .set_parent = s3c2412_setparent_msysclk, -}; - -/* these next clocks have an divider immediately after them, - * so we can register them with their divider and leave out the - * intermediate clock stage -*/ -static unsigned long s3c2412_roundrate_clksrc(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - return parent_rate; - - /* note, we remove the +/- 1 calculations as they cancel out */ - - div = (rate / parent_rate); - - if (div < 1) - div = 1; - else if (div > 16) - div = 16; - - return parent_rate / div; -} - -static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_erefclk) - clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL; - else if (parent == &clk_mpll) - clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} - -static unsigned long s3c2412_getrate_uart(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2410_CLKDIVN); - - div &= S3C2412_CLKDIVN_UARTDIV_MASK; - div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); - - rate = s3c2412_roundrate_clksrc(clk, rate); - - clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK; - clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT; - - __raw_writel(clkdivn, S3C2410_CLKDIVN); - return 0; -} - -static struct clk clk_uart = { - .name = "uartclk", - .id = -1, - .get_rate = s3c2412_getrate_uart, - .set_rate = s3c2412_setrate_uart, - .set_parent = s3c2412_setparent_uart, - .round_rate = s3c2412_roundrate_clksrc, -}; - -static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_erefclk) - clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL; - else if (parent == &clk_mpll) - clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} - -static unsigned long s3c2412_getrate_i2s(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2410_CLKDIVN); - - div &= S3C2412_CLKDIVN_I2SDIV_MASK; - div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); - - rate = s3c2412_roundrate_clksrc(clk, rate); - - clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK; - clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT; - - __raw_writel(clkdivn, S3C2410_CLKDIVN); - return 0; -} - -static struct clk clk_i2s = { - .name = "i2sclk", - .id = -1, - .get_rate = s3c2412_getrate_i2s, - .set_rate = s3c2412_setrate_i2s, - .set_parent = s3c2412_setparent_i2s, - .round_rate = s3c2412_roundrate_clksrc, -}; - -static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - - if (parent == &clk_usysclk) - clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK; - else if (parent == &clk_h) - clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK; - else - return -EINVAL; - - clk->parent = parent; - - __raw_writel(clksrc, S3C2412_CLKSRC); - return 0; -} -static unsigned long s3c2412_getrate_cam(struct clk *clk) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long div = __raw_readl(S3C2410_CLKDIVN); - - div &= S3C2412_CLKDIVN_CAMDIV_MASK; - div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT; - - return parent_rate / (div + 1); -} - -static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); - - rate = s3c2412_roundrate_clksrc(clk, rate); - - clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK; - clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT; - - __raw_writel(clkdivn, S3C2410_CLKDIVN); - return 0; -} - -static struct clk clk_cam = { - .name = "camif-upll", /* same as 2440 name */ - .id = -1, - .get_rate = s3c2412_getrate_cam, - .set_rate = s3c2412_setrate_cam, - .set_parent = s3c2412_setparent_cam, - .round_rate = s3c2412_roundrate_clksrc, -}; - -/* standard clock definitions */ - -static struct clk init_clocks_disable[] = { - { - .name = "nand", - .id = -1, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_NAND, - }, { - .name = "sdi", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_SDI, - }, { - .name = "adc", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_ADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_IIC, - }, { - .name = "iis", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_IIS, - }, { - .name = "spi", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_SPI, - } -}; - -static struct clk init_clocks[] = { - { - .name = "dma", - .id = 0, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_DMA0, - }, { - .name = "dma", - .id = 1, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_DMA1, - }, { - .name = "dma", - .id = 2, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_DMA2, - }, { - .name = "dma", - .id = 3, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_DMA3, - }, { - .name = "lcd", - .id = -1, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_LCDC, - }, { - .name = "gpio", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_GPIO, - }, { - .name = "usb-host", - .id = -1, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_USBH, - }, { - .name = "usb-device", - .id = -1, - .parent = &clk_h, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_USBD, - }, { - .name = "timers", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_PWMT, - }, { - .name = "uart", - .id = 0, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_UART2, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_p, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_p, - .ctrlbit = 0, - }, { - .name = "usb-bus-gadget", - .id = -1, - .parent = &clk_usb_bus, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_USB_DEV48, - }, { - .name = "usb-bus-host", - .id = -1, - .parent = &clk_usb_bus, - .enable = s3c2412_clkcon_enable, - .ctrlbit = S3C2412_CLKCON_USB_HOST48, - } -}; - -/* clocks to add where we need to check their parentage */ - -struct clk_init { - struct clk *clk; - unsigned int bit; - struct clk *src_0; - struct clk *src_1; -}; - -struct clk_init clks_src[] __initdata = { - { - .clk = &clk_usysclk, - .bit = S3C2412_CLKSRC_USBCLK_HCLK, - .src_0 = &clk_urefclk, - .src_1 = &clk_upll, - }, { - .clk = &clk_i2s, - .bit = S3C2412_CLKSRC_I2SCLK_MPLL, - .src_0 = &clk_erefclk, - .src_1 = &clk_mpll, - }, { - .clk = &clk_cam, - .bit = S3C2412_CLKSRC_CAMCLK_HCLK, - .src_0 = &clk_usysclk, - .src_1 = &clk_h, - }, { - .clk = &clk_msysclk, - .bit = S3C2412_CLKSRC_MSYSCLK_MPLL, - .src_0 = &clk_mdivclk, - .src_1 = &clk_mpll, - }, { - .clk = &clk_uart, - .bit = S3C2412_CLKSRC_UARTCLK_MPLL, - .src_0 = &clk_erefclk, - .src_1 = &clk_mpll, - }, { - .clk = &clk_usbsrc, - .bit = S3C2412_CLKSRC_USBCLK_HCLK, - .src_0 = &clk_usysclk, - .src_1 = &clk_h, - }, -}; - -/* s3c2412_clk_initparents - * - * Initialise the parents for the clocks that we get at start-time -*/ - -static void __init s3c2412_clk_initparents(void) -{ - unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); - struct clk_init *cip = clks_src; - struct clk *src; - int ptr; - int ret; - - for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) { - ret = s3c24xx_register_clock(cip->clk); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - cip->clk->name, ret); - } - - src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0; - - printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name); - clk_set_parent(cip->clk, src); - } -} - -/* clocks to add straight away */ - -struct clk *clks[] __initdata = { - &clk_ext, - &clk_usb_bus, - &clk_erefclk, - &clk_urefclk, - &clk_mrefclk, -}; - -int __init s3c2412_baseclk_add(void) -{ - unsigned long clkcon = __raw_readl(S3C2410_CLKCON); - struct clk *clkp; - int ret; - int ptr; - - clk_upll.enable = s3c2412_upll_enable; - clk_usb_bus.parent = &clk_usbsrc; - clk_usb_bus.rate = 0x0; - - s3c2412_clk_initparents(); - - for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { - clkp = clks[ptr]; - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } - - /* ensure usb bus clock is within correct rate of 48MHz */ - - if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { - printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n"); - - /* for the moment, let's use the UPLL, and see if we can - * get 48MHz */ - - clk_set_parent(&clk_usysclk, &clk_upll); - clk_set_parent(&clk_usbsrc, &clk_usysclk); - clk_set_rate(&clk_usbsrc, 48*1000*1000); - } - - printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", - (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on", - print_mhz(clk_get_rate(&clk_upll)), - print_mhz(clk_get_rate(&clk_usb_bus))); - - /* register clocks from clock array */ - - clkp = init_clocks; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { - /* ensure that we note the clock state */ - - clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0; - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } - - /* We must be careful disabling the clocks we are not intending to - * be using at boot time, as subsytems such as the LCD which do - * their own DMA requests to the bus can cause the system to lockup - * if they where in the middle of requesting bus access. - * - * Disabling the LCD clock if the LCD is active is very dangerous, - * and therefore the bootloader should be careful to not enable - * the LCD clock if it is not needed. - */ - - /* install (and disable) the clocks we do not need immediately */ - - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - - s3c2412_clkcon_enable(clkp, 0); - } - - return 0; -} diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412.c b/trunk/arch/arm/mach-s3c2410/s3c2412.c deleted file mode 100644 index e24ffd5e478b..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2412.c +++ /dev/null @@ -1,195 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2412.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * http://armlinux.simtec.co.uk/. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Modifications: - * 16-May-2003 BJD Created initial version - * 16-Aug-2003 BJD Fixed header files and copyright, added URL - * 05-Sep-2003 BJD Moved to kernel v2.6 - * 18-Jan-2004 BJD Added serial port configuration - * 21-Aug-2004 BJD Added new struct s3c2410_board handler - * 28-Sep-2004 BJD Updates for new serial port bits - * 04-Nov-2004 BJD Updated UART configuration process - * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate - * 13-Aug-2005 DA Removed UART from initial I/O mappings -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "s3c2412.h" -#include "cpu.h" -#include "devs.h" -#include "clock.h" -#include "pm.h" - -#ifndef CONFIG_CPU_S3C2412_ONLY -void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; -#endif - -/* Initial IO mappings */ - -static struct map_desc s3c2412_iodesc[] __initdata = { - IODESC_ENT(CLKPWR), - IODESC_ENT(LCD), - IODESC_ENT(TIMER), - IODESC_ENT(ADC), - IODESC_ENT(WATCHDOG), -}; - -/* uart registration process */ - -void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no); - - /* rename devices that are s3c2412/s3c2413 specific */ - s3c_device_sdi.name = "s3c2412-sdi"; - s3c_device_nand.name = "s3c2412-nand"; -} - -/* s3c2412_map_io - * - * register the standard cpu IO areas, and any passed in from the - * machine specific initialisation. -*/ - -void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) -{ - /* move base of IO */ - - s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; - - /* register our io-tables */ - - iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); - iotable_init(mach_desc, mach_size); -} - -void __init s3c2412_init_clocks(int xtal) -{ - unsigned long tmp; - unsigned long fclk; - unsigned long hclk; - unsigned long pclk; - - /* now we've got our machine bits initialised, work out what - * clocks we've got */ - - fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2); - - tmp = __raw_readl(S3C2410_CLKDIVN); - - /* work out clock scalings */ - - hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1); - hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1); - pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1); - - /* print brieft summary of clocks, etc */ - - printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", - print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); - - /* initialise the clocks here, to allow other things like the - * console to use them - */ - - s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); - s3c2412_baseclk_add(); -} - -/* need to register class before we actually register the device, and - * we also need to ensure that it has been initialised before any of the - * drivers even try to use it (even if not on an s3c2412 based system) - * as a driver which may support both 2410 and 2440 may try and use it. -*/ - -#ifdef CONFIG_PM -static struct sleep_save s3c2412_sleep[] = { - SAVE_ITEM(S3C2412_DSC0), - SAVE_ITEM(S3C2412_DSC1), - SAVE_ITEM(S3C2413_GPJDAT), - SAVE_ITEM(S3C2413_GPJCON), - SAVE_ITEM(S3C2413_GPJUP), - - /* save the sleep configuration anyway, just in case these - * get damaged during wakeup */ - - SAVE_ITEM(S3C2412_GPBSLPCON), - SAVE_ITEM(S3C2412_GPCSLPCON), - SAVE_ITEM(S3C2412_GPDSLPCON), - SAVE_ITEM(S3C2412_GPESLPCON), - SAVE_ITEM(S3C2412_GPFSLPCON), - SAVE_ITEM(S3C2412_GPGSLPCON), - SAVE_ITEM(S3C2412_GPHSLPCON), - SAVE_ITEM(S3C2413_GPJSLPCON), -}; - -static int s3c2412_suspend(struct sys_device *dev, pm_message_t state) -{ - s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -static int s3c2412_resume(struct sys_device *dev) -{ - s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -#else -#define s3c2412_suspend NULL -#define s3c2412_resume NULL -#endif - -struct sysdev_class s3c2412_sysclass = { - set_kset_name("s3c2412-core"), - .suspend = s3c2412_suspend, - .resume = s3c2412_resume -}; - -static int __init s3c2412_core_init(void) -{ - return sysdev_class_register(&s3c2412_sysclass); -} - -core_initcall(s3c2412_core_init); - -static struct sys_device s3c2412_sysdev = { - .cls = &s3c2412_sysclass, -}; - -int __init s3c2412_init(void) -{ - printk("S3C2412: Initialising architecture\n"); - - return sysdev_register(&s3c2412_sysdev); -} diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412.h b/trunk/arch/arm/mach-s3c2410/s3c2412.h deleted file mode 100644 index c6e56032a6e7..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2412.h +++ /dev/null @@ -1,29 +0,0 @@ -/* arch/arm/mach-s3c2410/s3c2412.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * Header file for s3c2412 cpu support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifdef CONFIG_CPU_S3C2412 - -extern int s3c2412_init(void); - -extern void s3c2412_map_io(struct map_desc *mach_desc, int size); - -extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -extern void s3c2412_init_clocks(int xtal); - -extern int s3c2412_baseclk_add(void); -#else -#define s3c2412_init_clocks NULL -#define s3c2412_init_uarts NULL -#define s3c2412_map_io NULL -#define s3c2412_init NULL -#endif diff --git a/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c b/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c index 15796864d010..d7a30ed6c327 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -91,7 +91,7 @@ static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate) static struct clk s3c2440_clk_cam = { .name = "camif", .id = -1, - .enable = s3c2410_clkcon_enable, + .enable = s3c24xx_clkcon_enable, .ctrlbit = S3C2440_CLKCON_CAMERA, }; @@ -105,7 +105,7 @@ static struct clk s3c2440_clk_cam_upll = { static struct clk s3c2440_clk_ac97 = { .name = "ac97", .id = -1, - .enable = s3c2410_clkcon_enable, + .enable = s3c24xx_clkcon_enable, .ctrlbit = S3C2440_CLKCON_CAMERA, }; diff --git a/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c b/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c index d9f54b5cab7f..5b7b301eb522 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2442-clock.c @@ -102,7 +102,7 @@ static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate) static struct clk s3c2442_clk_cam = { .name = "camif", .id = -1, - .enable = s3c2410_clkcon_enable, + .enable = s3c24xx_clkcon_enable, .ctrlbit = S3C2440_CLKCON_CAMERA, }; diff --git a/trunk/arch/arm/mach-s3c2410/s3c244x.c b/trunk/arch/arm/mach-s3c2410/s3c244x.c index 838bc525e836..96852a7000db 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x.c @@ -34,7 +34,6 @@ #include #include -#include "s3c2410.h" #include "s3c2440.h" #include "s3c244x.h" #include "clock.h" @@ -119,7 +118,6 @@ void __init s3c244x_init_clocks(int xtal) */ s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); - s3c2410_baseclk_add(); } #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-s3c2410/sleep.S b/trunk/arch/arm/mach-s3c2410/sleep.S index dc27167f4d59..5f6761ed96b2 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -128,7 +128,7 @@ s3c2410_sleep_save_phys: */ ENTRY(s3c2410_cpu_resume) - mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC msr cpsr_c, r0 @@ load UART to allow us to print the two characters for diff --git a/trunk/arch/arm/mach-sa1100/sleep.S b/trunk/arch/arm/mach-sa1100/sleep.S index 5a84062f92af..2fa1e289d177 100644 --- a/trunk/arch/arm/mach-sa1100/sleep.S +++ b/trunk/arch/arm/mach-sa1100/sleep.S @@ -177,7 +177,7 @@ sa1110_sdram_controller_fix: .data .align 5 ENTRY(sa1100_cpu_resume) - mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + mov r0, #PSR_F_BIT | PSR_I_BIT | MODE_SVC msr cpsr_c, r0 @ set SVC, irqs off ldr r0, sleep_save_sp @ stack phys addr diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index ecf5e232a6fc..4221d054a1e9 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -61,9 +61,9 @@ config CPU_ARM720T # ARM920T config CPU_ARM920T - bool "Support ARM920T processor" - depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 - default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200 + bool "Support ARM920T processor" if !ARCH_S3C2410 + depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 + default y if ARCH_S3C2410 || ARCH_AT91RM9200 select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT @@ -121,8 +121,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT diff --git a/trunk/arch/arm/mm/copypage-v3.S b/trunk/arch/arm/mm/copypage-v3.S index 2ee394b11bcb..3c58ebbf0359 100644 --- a/trunk/arch/arm/mm/copypage-v3.S +++ b/trunk/arch/arm/mm/copypage-v3.S @@ -35,7 +35,7 @@ ENTRY(v3_copy_user_page) stmia r0!, {r3, r4, ip, lr} @ 4 ldmneia r1!, {r3, r4, ip, lr} @ 4 bne 1b @ 1 - ldmfd sp!, {r4, pc} @ 3 + LOADREGS(fd, sp!, {r4, pc}) @ 3 .align 5 /* diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 09b1a41a6de8..ee6f15298735 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -29,6 +29,38 @@ #define TTB_RGN_WT (2 << 3) #define TTB_RGN_WB (3 << 3) + .macro cpsie, flags + .ifc \flags, f + .long 0xf1080040 + .exitm + .endif + .ifc \flags, i + .long 0xf1080080 + .exitm + .endif + .ifc \flags, if + .long 0xf10800c0 + .exitm + .endif + .err + .endm + + .macro cpsid, flags + .ifc \flags, f + .long 0xf10c0040 + .exitm + .endif + .ifc \flags, i + .long 0xf10c0080 + .exitm + .endif + .ifc \flags, if + .long 0xf10c00c0 + .exitm + .endif + .err + .endm + ENTRY(cpu_v6_proc_init) mov pc, lr diff --git a/trunk/arch/arm/nwfpe/entry26.S b/trunk/arch/arm/nwfpe/entry26.S index 3e6fb5d21d64..51940a96d6a6 100644 --- a/trunk/arch/arm/nwfpe/entry26.S +++ b/trunk/arch/arm/nwfpe/entry26.S @@ -26,7 +26,7 @@ It is called from the kernel with code similar to this: mov fp, #0 - teqp pc, #PSR_I_BIT | SVC_MODE + teqp pc, #PSR_I_BIT | MODE_SVC ldr r4, .LC2 ldr pc, [r4] @ Call FP module USR entry point diff --git a/trunk/arch/arm/nwfpe/fpmodule.c b/trunk/arch/arm/nwfpe/fpmodule.c index 7d977d23f026..2dfe1ac42ee8 100644 --- a/trunk/arch/arm/nwfpe/fpmodule.c +++ b/trunk/arch/arm/nwfpe/fpmodule.c @@ -33,8 +33,7 @@ #include #include #include - -#include +/* XXX */ #include "softfloat.h" #include "fpopcode.h" @@ -57,28 +56,16 @@ void fp_send_sig(unsigned long sig, struct task_struct *p, int priv); extern char fpe_type[]; #endif -static int nwfpe_notify(struct notifier_block *self, unsigned long cmd, void *v) -{ - struct thread_info *thread = v; - - if (cmd == THREAD_NOTIFY_FLUSH) - nwfpe_init_fpa(&thread->fpstate); - - return NOTIFY_DONE; -} - -static struct notifier_block nwfpe_notifier_block = { - .notifier_call = nwfpe_notify, -}; - /* kernel function prototypes required */ void fp_setup(void); /* external declarations for saved kernel symbols */ extern void (*kern_fp_enter)(void); +extern void (*fp_init)(union fp_state *); /* Original value of fp_enter from kernel before patched by fpe_init. */ static void (*orig_fp_enter)(void); +static void (*orig_fp_init)(union fp_state *); /* forward declarations */ extern void nwfpe_enter(void); @@ -101,20 +88,20 @@ static int __init fpe_init(void) printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" NWFPE_BITS " precision)\n"); - thread_register_notifier(&nwfpe_notifier_block); - /* Save pointer to the old FP handler and then patch ourselves in */ orig_fp_enter = kern_fp_enter; + orig_fp_init = fp_init; kern_fp_enter = nwfpe_enter; + fp_init = nwfpe_init_fpa; return 0; } static void __exit fpe_exit(void) { - thread_unregister_notifier(&nwfpe_notifier_block); /* Restore the values we saved earlier. */ kern_fp_enter = orig_fp_enter; + fp_init = orig_fp_init; } /* diff --git a/trunk/arch/arm/plat-omap/timer32k.c b/trunk/arch/arm/plat-omap/timer32k.c index 3461a6c9665c..b2a943bf11ef 100644 --- a/trunk/arch/arm/plat-omap/timer32k.c +++ b/trunk/arch/arm/plat-omap/timer32k.c @@ -210,8 +210,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, now = omap_32k_sync_timer_read(); - while ((signed long)(now - omap_32k_last_tick) - >= OMAP_32K_TICKS_PER_HZ) { + while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; timer_tick(regs); } diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index e1372a25311d..6d7de9c0412f 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Jun 26 22:26:08 2006 +# Last update: Mon May 8 20:11:05 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -566,8 +566,8 @@ switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 ens_cmu MACH_ENS_CMU ENS_CMU 550 mm6_sdb MACH_MM6_SDB MM6_SDB 551 saturn MACH_SATURN SATURN 552 -i30030evb MACH_I30030EVB I30030EVB 553 -mxc27530evb MACH_MXC27530EVB MXC27530EVB 554 +i30030evb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 +mxc27530evb MACH_SCMA11EVB SCMA11EVB 554 smdk2800 MACH_SMDK2800 SMDK2800 555 mtwilson MACH_MTWILSON MTWILSON 556 ziti MACH_ZITI ZITI 557 @@ -647,7 +647,7 @@ sendt MACH_SENDT SENDT 630 mx2jazz MACH_MX2JAZZ MX2JAZZ 631 multiio MACH_MULTIIO MULTIIO 632 hrdisplay MACH_HRDISPLAY HRDISPLAY 633 -mxc27530ads MACH_MXC27530ADS MXC27530ADS 634 +mxc27530ads MACH_SCMA11BB SCMA11BB 634 trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 @@ -721,7 +721,7 @@ gp32 MACH_GP32 GP32 706 gem MACH_GEM GEM 707 i858 MACH_I858 I858 708 hx2750 MACH_HX2750 HX2750 709 -mxc91131evb MACH_MXC91131EVB MXC91131EVB 710 +mxc91131evb MACH_ZEUSEVB ZEUSEVB 710 p700 MACH_P700 P700 711 cpe MACH_CPE CPE 712 spitz MACH_SPITZ SPITZ 713 @@ -802,7 +802,7 @@ cpuat91 MACH_CPUAT91 CPUAT91 787 rea9200 MACH_REA9200 REA9200 788 acts_pune_sa1110 MACH_ACTS_PUNE_SA1110 ACTS_PUNE_SA1110 789 ixp425 MACH_IXP425 IXP425 790 -i30030ads MACH_I30030ADS I30030ADS 791 +i30030ads MACH_ARGONPLUSODYSSEY ARGONPLUSODYSSEY 791 perch MACH_PERCH PERCH 792 eis05r1 MACH_EIS05R1 EIS05R1 793 pepperpad MACH_PEPPERPAD PEPPERPAD 794 @@ -930,7 +930,7 @@ netclient MACH_NETCLIENT NETCLIENT 916 xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917 xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 -mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 +mxc30030evb MACH_ARGONLVEVB ARGONLVEVB 920 rea_2d MACH_REA_2D REA_2D 921 eti3e524 MACH_TI3E524 TI3E524 922 ateb9200 MACH_ATEB9200 ATEB9200 923 @@ -986,7 +986,7 @@ redfox MACH_REDFOX REDFOX 972 mysh_ep9315_1 MACH_MYSH_EP9315_1 MYSH_EP9315_1 973 tpf106 MACH_TPF106 TPF106 974 at91rm9200kg MACH_AT91RM9200KG AT91RM9200KG 975 -rcmt2 MACH_SLEDB SLEDB 976 +racemt2 MACH_SLEDB SLEDB 976 ontrack MACH_ONTRACK ONTRACK 977 pm1200 MACH_PM1200 PM1200 978 ess24562 MACH_ESS24XXX ESS24XXX 979 @@ -1022,7 +1022,7 @@ smdk2440 MACH_SMDK2440 SMDK2440 1008 smdk2412 MACH_SMDK2412 SMDK2412 1009 webbox MACH_WEBBOX WEBBOX 1010 cwwndp MACH_CWWNDP CWWNDP 1011 -i839 MACH_DRAGON DRAGON 1012 +dragon MACH_DRAGON DRAGON 1012 opendo_cpu_board MACH_OPENDO_CPU_BOARD OPENDO_CPU_BOARD 1013 ccm2200 MACH_CCM2200 CCM2200 1014 etwarm MACH_ETWARM ETWARM 1015 @@ -1040,56 +1040,3 @@ edg79524 MACH_EDG79524 EDG79524 1026 ai2410 MACH_AI2410 AI2410 1027 ixp465 MACH_IXP465 IXP465 1028 balloon3 MACH_BALLOON3 BALLOON3 1029 -heins MACH_HEINS HEINS 1030 -mpluseva MACH_MPLUSEVA MPLUSEVA 1031 -rt042 MACH_RT042 RT042 1032 -cwiem MACH_CWIEM CWIEM 1033 -cm_x270 MACH_CM_X270 CM_X270 1034 -cm_x255 MACH_CM_X255 CM_X255 1035 -esh_at91 MACH_ESH_AT91 ESH_AT91 1036 -sandgate3 MACH_SANDGATE3 SANDGATE3 1037 -primo MACH_PRIMO PRIMO 1038 -gemstone MACH_GEMSTONE GEMSTONE 1039 -pronghorn_metro MACH_PRONGHORNMETRO PRONGHORNMETRO 1040 -sidewinder MACH_SIDEWINDER SIDEWINDER 1041 -picomod1 MACH_PICOMOD1 PICOMOD1 1042 -sg590 MACH_SG590 SG590 1043 -akai9307 MACH_AKAI9307 AKAI9307 1044 -fontaine MACH_FONTAINE FONTAINE 1045 -wombat MACH_WOMBAT WOMBAT 1046 -acq300 MACH_ACQ300 ACQ300 1047 -mod_270 MACH_MOD_270 MOD_270 1048 -vmc_vc0820 MACH_VC0820 VC0820 1049 -ani_aim MACH_ANI_AIM ANI_AIM 1050 -jellyfish MACH_JELLYFISH JELLYFISH 1051 -amanita MACH_AMANITA AMANITA 1052 -vlink MACH_VLINK VLINK 1053 -dexflex MACH_DEXFLEX DEXFLEX 1054 -eigen_ttq MACH_EIGEN_TTQ EIGEN_TTQ 1055 -arcom_titan MACH_ARCOM_TITAN ARCOM_TITAN 1056 -tabla MACH_TABLA TABLA 1057 -mdirac3 MACH_MDIRAC3 MDIRAC3 1058 -mrhfbp2 MACH_MRHFBP2 MRHFBP2 1059 -at91rm9200rb MACH_AT91RM9200RB AT91RM9200RB 1060 -ani_apm MACH_ANI_APM ANI_APM 1061 -ella1 MACH_ELLA1 ELLA1 1062 -inhand_pxa27x MACH_INHAND_PXA27X INHAND_PXA27X 1063 -inhand_pxa25x MACH_INHAND_PXA25X INHAND_PXA25X 1064 -empos_xm MACH_EMPOS_XM EMPOS_XM 1065 -empos MACH_EMPOS EMPOS 1066 -empos_tiny MACH_EMPOS_TINY EMPOS_TINY 1067 -empos_sm MACH_EMPOS_SM EMPOS_SM 1068 -egret MACH_EGRET EGRET 1069 -ostrich MACH_OSTRICH OSTRICH 1070 -n50 MACH_N50 N50 1071 -ecbat91 MACH_ECBAT91 ECBAT91 1072 -stareast MACH_STAREAST STAREAST 1073 -dspg_dw MACH_DSPG_DW DSPG_DW 1074 -onearm MACH_ONEARM ONEARM 1075 -mrg110_6 MACH_MRG110_6 MRG110_6 1076 -wrt300nv2 MACH_WRT300NV2 WRT300NV2 1077 -xm_bulverde MACH_XM_BULVERDE XM_BULVERDE 1078 -msm6100 MACH_MSM6100 MSM6100 1079 -eti_b1 MACH_ETI_B1 ETI_B1 1080 -za9l_series MACH_ZILOG_ZA9L ZILOG_ZA9L 1081 -bit2440 MACH_BIT2440 BIT2440 1082 diff --git a/trunk/arch/arm/vfp/Makefile b/trunk/arch/arm/vfp/Makefile index 7e136e77971a..afabac31dd1d 100644 --- a/trunk/arch/arm/vfp/Makefile +++ b/trunk/arch/arm/vfp/Makefile @@ -7,9 +7,6 @@ # EXTRA_CFLAGS := -DDEBUG # EXTRA_AFLAGS := -DDEBUG -AFLAGS :=$(AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp) -LDFLAGS +=--no-warn-mismatch - obj-y += vfp.o -vfp-$(CONFIG_VFP) += vfpmodule.o entry.o vfphw.o vfpsingle.o vfpdouble.o +vfp-$(CONFIG_VFP) += entry.o vfpmodule.o vfphw.o vfpsingle.o vfpdouble.o diff --git a/trunk/arch/arm/vfp/vfphw.S b/trunk/arch/arm/vfp/vfphw.S index eb683cd77163..a3f65b47aea9 100644 --- a/trunk/arch/arm/vfp/vfphw.S +++ b/trunk/arch/arm/vfp/vfphw.S @@ -192,7 +192,7 @@ vfp_get_double: add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - fmrrd r0, r1, d\dr + mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr mov pc, lr .endr @@ -206,6 +206,6 @@ vfp_put_double: add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - fmdrr d\dr, r1, r2 + mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr mov pc, lr .endr diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 2476f4c2e760..03486be04193 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -15,8 +15,6 @@ #include #include #include - -#include #include #include "vfpinstr.h" @@ -38,54 +36,37 @@ union vfp_state *last_VFP_context; */ unsigned int VFP_arch; -static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) +/* + * Per-thread VFP initialisation. + */ +void vfp_flush_thread(union vfp_state *vfp) { - struct thread_info *thread = v; - union vfp_state *vfp = &thread->vfpstate; - - switch (cmd) { - case THREAD_NOTIFY_FLUSH: - /* - * Per-thread VFP initialisation. - */ - memset(vfp, 0, sizeof(union vfp_state)); - - vfp->hard.fpexc = FPEXC_ENABLE; - vfp->hard.fpscr = FPSCR_ROUND_NEAREST; + memset(vfp, 0, sizeof(union vfp_state)); - /* - * Disable VFP to ensure we initialise it first. - */ - fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + vfp->hard.fpexc = FPEXC_ENABLE; + vfp->hard.fpscr = FPSCR_ROUND_NEAREST; - /* - * FALLTHROUGH: Ensure we don't try to overwrite our newly - * initialised state information on the first fault. - */ - - case THREAD_NOTIFY_RELEASE: - /* - * Per-thread VFP cleanup. - */ - if (last_VFP_context == vfp) - last_VFP_context = NULL; - break; - - case THREAD_NOTIFY_SWITCH: - /* - * Always disable VFP so we can lazily save/restore the - * old state. - */ - fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - break; - } + /* + * Disable VFP to ensure we initialise it first. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - return NOTIFY_DONE; + /* + * Ensure we don't try to overwrite our newly initialised + * state information on the first fault. + */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; } -static struct notifier_block vfp_notifier_block = { - .notifier_call = vfp_notifier, -}; +/* + * Per-thread VFP cleanup. + */ +void vfp_release_thread(union vfp_state *vfp) +{ + if (last_VFP_context == vfp) + last_VFP_context = NULL; +} /* * Raise a SIGFPE for the current process. @@ -300,8 +281,6 @@ static int __init vfp_init(void) (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); vfp_vector = vfp_support_entry; - - thread_register_notifier(&vfp_notifier_block); } return 0; } diff --git a/trunk/arch/cris/arch-v32/drivers/pci/bios.c b/trunk/arch/cris/arch-v32/drivers/pci/bios.c index 1e9d062103ae..24bc149889b6 100644 --- a/trunk/arch/cris/arch-v32/drivers/pci/bios.c +++ b/trunk/arch/cris/arch-v32/drivers/pci/bios.c @@ -27,6 +27,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, /* Leave vm_pgoff as-is, the PCI space address is the physical * address on this platform. */ + vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO); + prot = pgprot_val(vma->vm_page_prot); vma->vm_page_prot = __pgprot(prot); diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index 81d94e41a189..a9b59527a741 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -1474,7 +1474,7 @@ sys_call_table: .long sys_mknodat .long sys_fchownat .long sys_futimesat - .long sys_fstatat64 /* 300 */ + .long sys_newfstatat /* 300 */ .long sys_unlinkat .long sys_renameat .long sys_linkat diff --git a/trunk/arch/frv/kernel/frv_ksyms.c b/trunk/arch/frv/kernel/frv_ksyms.c index dee637fffda5..0f273a7aca5a 100644 --- a/trunk/arch/frv/kernel/frv_ksyms.c +++ b/trunk/arch/frv/kernel/frv_ksyms.c @@ -26,6 +26,16 @@ extern long __memset_user(void *dst, const void *src, size_t count); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); + EXPORT_SYMBOL(ip_fast_csum); #if 0 @@ -34,6 +44,8 @@ EXPORT_SYMBOL(local_bh_count); #endif EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(__res_bus_clock_speed_HZ); EXPORT_SYMBOL(__page_offset); EXPORT_SYMBOL(__memcpy_user); @@ -50,12 +62,18 @@ EXPORT_SYMBOL(memory_end); EXPORT_SYMBOL(__debug_bug_trap); +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); + /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, their interface isn't gonna change any time soon now, so it's OK to leave it out of version control. */ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memscan); +EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__outsl_ns); EXPORT_SYMBOL(__insl_ns); diff --git a/trunk/arch/frv/kernel/irq-routing.c b/trunk/arch/frv/kernel/irq-routing.c index b90b70a761d1..d4776d1f4e82 100644 --- a/trunk/arch/frv/kernel/irq-routing.c +++ b/trunk/arch/frv/kernel/irq-routing.c @@ -112,7 +112,7 @@ struct irq_source frv_cpuuart[2] = { #define __CPUUART(X, A) \ [X] = { \ .muxname = "uart", \ - .muxdata = (volatile void __iomem *)(unsigned long)A,\ + .muxdata = (volatile void __iomem *) A, \ .irqmask = 1 << IRQ_CPU_UART##X, \ .doirq = frv_cpuuart_doirq, \ } @@ -136,7 +136,7 @@ struct irq_source frv_cpudma[8] = { #define __CPUDMA(X, A) \ [X] = { \ .muxname = "dma", \ - .muxdata = (volatile void __iomem *)(unsigned long)A,\ + .muxdata = (volatile void __iomem *) A, \ .irqmask = 1 << IRQ_CPU_DMA##X, \ .doirq = frv_cpudma_doirq, \ } @@ -164,7 +164,7 @@ struct irq_source frv_cputimer[3] = { #define __CPUTIMER(X) \ [X] = { \ .muxname = "timer", \ - .muxdata = NULL, \ + .muxdata = 0, \ .irqmask = 1 << IRQ_CPU_TIMER##X, \ .doirq = frv_cputimer_doirq, \ } @@ -187,7 +187,7 @@ struct irq_source frv_cpuexternal[8] = { #define __CPUEXTERNAL(X) \ [X] = { \ .muxname = "ext", \ - .muxdata = NULL, \ + .muxdata = 0, \ .irqmask = 1 << IRQ_CPU_EXTERNAL##X, \ .doirq = frv_cpuexternal_doirq, \ } diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index 8b112b361914..11fa326a8f62 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -625,7 +625,7 @@ static struct proc_dir_entry * irq_dir [NR_IRQS]; #define HEX_DIGITS 8 -static unsigned int parse_hex_value (const char __user *buffer, +static unsigned int parse_hex_value (const char *buffer, unsigned long count, unsigned long *ret) { unsigned char hexnum [HEX_DIGITS]; @@ -672,7 +672,7 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, return sprintf (page, "%08lx\n", *mask); } -static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer, +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { unsigned long *mask = (unsigned long *) data, full_count = count, err; @@ -711,7 +711,7 @@ void init_irq_proc (void) int i; /* create /proc/irq */ - root_irq_dir = proc_mkdir("irq", NULL); + root_irq_dir = proc_mkdir("irq", 0); /* create /proc/irq/prof_cpu_mask */ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); diff --git a/trunk/arch/frv/kernel/pm.c b/trunk/arch/frv/kernel/pm.c index 43ce28a13a5d..f0b8fff3e733 100644 --- a/trunk/arch/frv/kernel/pm.c +++ b/trunk/arch/frv/kernel/pm.c @@ -137,7 +137,7 @@ unsigned long sleep_phys_sp(void *sp) #define CTL_PM_P0 4 #define CTL_PM_CM 5 -static int user_atoi(char __user *ubuf, size_t len) +static int user_atoi(char *ubuf, size_t len) { char buf[16]; unsigned long ret; @@ -159,7 +159,7 @@ static int user_atoi(char __user *ubuf, size_t len) * Send us to sleep. */ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *fpos) + void *buffer, size_t *lenp, loff_t *fpos) { int retval, mode; @@ -215,7 +215,7 @@ static int try_set_cmode(int new_cmode) static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *fpos) + void *buffer, size_t *lenp, loff_t *fpos) { int new_cmode; @@ -227,9 +227,9 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_cmode(new_cmode)?:*lenp; } -static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) +static int cmode_sysctl(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) { if (oldval && oldlenp) { size_t oldlen; @@ -240,7 +240,7 @@ static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, if (oldlen != sizeof(int)) return -EINVAL; - if (put_user(clock_cmode_current, (unsigned __user *)oldval) || + if (put_user(clock_cmode_current, (unsigned int *)oldval) || put_user(sizeof(int), oldlenp)) return -EFAULT; } @@ -250,7 +250,7 @@ static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, if (newlen != sizeof(int)) return -EINVAL; - if (get_user(new_cmode, (int __user *)newval)) + if (get_user(new_cmode, (int *)newval)) return -EFAULT; return try_set_cmode(new_cmode)?:1; @@ -318,7 +318,7 @@ static int try_set_cm(int new_cm) } static int p0_procctl(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *fpos) + void *buffer, size_t *lenp, loff_t *fpos) { int new_p0; @@ -330,9 +330,9 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_p0(new_p0)?:*lenp; } -static int p0_sysctl(ctl_table *table, int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) +static int p0_sysctl(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) { if (oldval && oldlenp) { size_t oldlen; @@ -343,7 +343,7 @@ static int p0_sysctl(ctl_table *table, int __user *name, int nlen, if (oldlen != sizeof(int)) return -EINVAL; - if (put_user(clock_p0_current, (unsigned __user *)oldval) || + if (put_user(clock_p0_current, (unsigned int *)oldval) || put_user(sizeof(int), oldlenp)) return -EFAULT; } @@ -353,7 +353,7 @@ static int p0_sysctl(ctl_table *table, int __user *name, int nlen, if (newlen != sizeof(int)) return -EINVAL; - if (get_user(new_p0, (int __user *)newval)) + if (get_user(new_p0, (int *)newval)) return -EFAULT; return try_set_p0(new_p0)?:1; @@ -362,7 +362,7 @@ static int p0_sysctl(ctl_table *table, int __user *name, int nlen, } static int cm_procctl(ctl_table *ctl, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *fpos) + void *buffer, size_t *lenp, loff_t *fpos) { int new_cm; @@ -374,9 +374,9 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp, return try_set_cm(new_cm)?:*lenp; } -static int cm_sysctl(ctl_table *table, int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) +static int cm_sysctl(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) { if (oldval && oldlenp) { size_t oldlen; @@ -387,7 +387,7 @@ static int cm_sysctl(ctl_table *table, int __user *name, int nlen, if (oldlen != sizeof(int)) return -EINVAL; - if (put_user(clock_cm_current, (unsigned __user *)oldval) || + if (put_user(clock_cm_current, (unsigned int *)oldval) || put_user(sizeof(int), oldlenp)) return -EFAULT; } @@ -397,7 +397,7 @@ static int cm_sysctl(ctl_table *table, int __user *name, int nlen, if (newlen != sizeof(int)) return -EINVAL; - if (get_user(new_cm, (int __user *)newval)) + if (get_user(new_cm, (int *)newval)) return -EFAULT; return try_set_cm(new_cm)?:1; diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 489e6c489cbe..0fff8a61ef2a 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -246,7 +246,7 @@ int copy_thread(int nr, unsigned long clone_flags, /* * sys_execve() executes a new program. */ -asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp) +asmlinkage int sys_execve(char *name, char **argv, char **envp) { int error; char * filename; diff --git a/trunk/arch/frv/kernel/setup.c b/trunk/arch/frv/kernel/setup.c index 1f7d65f29e78..5908deae9607 100644 --- a/trunk/arch/frv/kernel/setup.c +++ b/trunk/arch/frv/kernel/setup.c @@ -814,7 +814,7 @@ void __init setup_arch(char **cmdline_p) * - by now the stack is part of the init task */ printk("Memory %08lx-%08lx\n", memory_start, memory_end); - BUG_ON(memory_start == memory_end); + if (memory_start == memory_end) BUG(); init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; diff --git a/trunk/arch/frv/kernel/signal.c b/trunk/arch/frv/kernel/signal.c index b8a5882b8625..679c1d5cc958 100644 --- a/trunk/arch/frv/kernel/signal.c +++ b/trunk/arch/frv/kernel/signal.c @@ -98,7 +98,7 @@ int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) struct sigframe { - __sigrestore_t pretcode; + void (*pretcode)(void); int sig; struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; @@ -107,10 +107,10 @@ struct sigframe struct rt_sigframe { - __sigrestore_t pretcode; + void (*pretcode)(void); int sig; - struct siginfo __user *pinfo; - void __user *puc; + struct siginfo *pinfo; + void *puc; struct siginfo info; struct ucontext uc; uint32_t retcode[2]; @@ -233,7 +233,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (! sas_ss_flags(sp)) + if (! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; } @@ -284,7 +284,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) * setlos #__NR_sigreturn,gr7 * tira gr0,0 */ - if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || + if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) || __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || __put_user(0xc0700000, &frame->retcode[1])) goto give_sigsegv; @@ -300,7 +300,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) if (get_personality & FDPIC_FUNCPTRS) { struct fdpic_func_descriptor __user *funcptr = - (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; + (struct fdpic_func_descriptor *) ka->sa.sa_handler; __get_user(__frame->pc, &funcptr->text); __get_user(__frame->gr15, &funcptr->GOT); } else { @@ -359,8 +359,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Create the ucontext. */ if (__put_user(0, &frame->uc.uc_flags) || - __put_user(NULL, &frame->uc.uc_link) || - __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || + __put_user(0, &frame->uc.uc_link) || + __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) || __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) goto give_sigsegv; @@ -382,7 +382,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * setlos #__NR_sigreturn,gr7 * tira gr0,0 */ - if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || + if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) || __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || __put_user(0xc0700000, &frame->retcode[1])) goto give_sigsegv; @@ -398,7 +398,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, __frame->gr9 = (unsigned long) &frame->info; if (get_personality & FDPIC_FUNCPTRS) { - struct fdpic_func_descriptor __user *funcptr = + struct fdpic_func_descriptor *funcptr = (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; __get_user(__frame->pc, &funcptr->text); __get_user(__frame->gr15, &funcptr->GOT); diff --git a/trunk/arch/frv/kernel/sys_frv.c b/trunk/arch/frv/kernel/sys_frv.c index c4d4348c9e8e..931aa6d895e3 100644 --- a/trunk/arch/frv/kernel/sys_frv.c +++ b/trunk/arch/frv/kernel/sys_frv.c @@ -32,7 +32,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage long sys_pipe(unsigned long __user * fildes) +asmlinkage long sys_pipe(unsigned long * fildes) { int fd[2]; int error; diff --git a/trunk/arch/frv/kernel/sysctl.c b/trunk/arch/frv/kernel/sysctl.c index b908863d6593..408b0f382b42 100644 --- a/trunk/arch/frv/kernel/sysctl.c +++ b/trunk/arch/frv/kernel/sysctl.c @@ -49,7 +49,7 @@ static void frv_change_dcache_mode(unsigned long newmode) * handle requests to dynamically switch the write caching mode delivered by /proc */ static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { unsigned long hsr0; char buff[8]; @@ -123,7 +123,7 @@ static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp, */ #ifdef CONFIG_MMU static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { pid_t pid; char buff[16], *p; diff --git a/trunk/arch/frv/kernel/uaccess.c b/trunk/arch/frv/kernel/uaccess.c index 9fb771a20df3..9b751c0f0e84 100644 --- a/trunk/arch/frv/kernel/uaccess.c +++ b/trunk/arch/frv/kernel/uaccess.c @@ -17,7 +17,7 @@ /* * copy a null terminated string from userspace */ -long strncpy_from_user(char *dst, const char __user *src, long count) +long strncpy_from_user(char *dst, const char *src, long count) { unsigned long max; char *p, ch; @@ -70,9 +70,9 @@ EXPORT_SYMBOL(strncpy_from_user); * * Return 0 on exception, a value greater than N if too long */ -long strnlen_user(const char __user *src, long count) +long strnlen_user(const char *src, long count) { - const char __user *p; + const char *p; long err = 0; char ch; diff --git a/trunk/arch/frv/mb93090-mb00/pci-irq.c b/trunk/arch/frv/mb93090-mb00/pci-irq.c index 45ae39d84b69..c4a1144c98b0 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-irq.c +++ b/trunk/arch/frv/mb93090-mb00/pci-irq.c @@ -32,11 +32,11 @@ */ static const uint8_t __initdata pci_bus0_irq_routing[32][4] = { - [0 ] = { IRQ_FPGA_MB86943_PCI_INTA }, - [16] = { IRQ_FPGA_RTL8029_INTA }, - [17] = { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB }, - [18] = { IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA }, - [19] = { IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD }, + [0 ] { IRQ_FPGA_MB86943_PCI_INTA }, + [16] { IRQ_FPGA_RTL8029_INTA }, + [17] { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB }, + [18] { IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA }, + [19] { IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD }, }; void __init pcibios_irq_init(void) diff --git a/trunk/arch/frv/mm/kmap.c b/trunk/arch/frv/mm/kmap.c index 40b62c5c2951..c54f18e65ea6 100644 --- a/trunk/arch/frv/mm/kmap.c +++ b/trunk/arch/frv/mm/kmap.c @@ -31,15 +31,15 @@ * Map some physical address range into the kernel address space. */ -void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) { - return (void __iomem *)physaddr; + return (void *)physaddr; } /* * Unmap a ioremap()ed region again */ -void iounmap(void volatile __iomem *addr) +void iounmap(void *addr) { } diff --git a/trunk/arch/h8300/kernel/signal.c b/trunk/arch/h8300/kernel/signal.c index 7787f70a05bb..f13d5e82d4b9 100644 --- a/trunk/arch/h8300/kernel/signal.c +++ b/trunk/arch/h8300/kernel/signal.c @@ -307,7 +307,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) + if (!on_sig_stack(usp)) usp = current->sas_ss_sp + current->sas_ss_size; } return (void *)((usp - frame_size) & -8UL); diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 3bb221db164a..8dfa3054f10f 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -14,10 +14,6 @@ config X86_32 486, 586, Pentiums, and various instruction-set-compatible chips by AMD, Cyrix, and others. -config GENERIC_TIME - bool - default y - config SEMAPHORE_SLEEPERS bool default y @@ -177,12 +173,6 @@ config ACPI_SRAT bool default y depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) - select ACPI_NUMA - -config HAVE_ARCH_PARSE_SRAT - bool - default y - depends on ACPI_SRAT config X86_SUMMIT_NUMA bool @@ -233,7 +223,8 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on X86_HT + depends on SMP + default off help SMT scheduler support improves the CPU scheduler's decision making when dealing with Intel Pentium 4 chips with HyperThreading at a @@ -242,7 +233,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on X86_HT + depends on SMP default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -328,15 +319,6 @@ config X86_MCE_P4THERMAL Enabling this feature will cause a message to be printed when the P4 enters thermal throttling. -config VM86 - default y - bool "Enable VM86 support" if EMBEDDED - help - This option is required by programs like DOSEMU to run 16-bit legacy - code on X86 processors. It also may be needed by software like - XFree86 to initialize some video cards via BIOS. Disabling this - option saves about 6k. - config TOSHIBA tristate "Toshiba Laptop support" ---help--- @@ -734,7 +716,7 @@ config KEXEC help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot - but it is independent of the system firmware. And like a reboot + but it is indepedent of the system firmware. And like a reboot you can start any kernel with it, not just Linux. The name comes from the similiarity to the exec system call. @@ -780,17 +762,6 @@ config HOTPLUG_CPU enable suspend on SMP systems. CPUs can be controlled through /sys/devices/system/cpu. -config COMPAT_VDSO - bool "Compat VDSO support" - default y - help - Map the VDSO to the predictable old-style address too. - ---help--- - Say N here if you are running a sufficiently recent glibc - version (2.3.3 or later), to remove the high-mapped - VDSO mapping and to exclusively use the randomized VDSO. - - If unsure, say Y. endmenu @@ -1070,27 +1041,13 @@ config SCx200 tristate "NatSemi SCx200 support" depends on !X86_VOYAGER help - This provides basic support for National Semiconductor's - (now AMD's) Geode processors. The driver probes for the - PCI-IDs of several on-chip devices, so its a good dependency - for other scx200_* drivers. - - If compiled as a module, the driver is named scx200. + This provides basic support for the National Semiconductor SCx200 + processor. Right now this is just a driver for the GPIO pins. -config SCx200HR_TIMER - tristate "NatSemi SCx200 27MHz High-Resolution Timer Support" - depends on SCx200 && GENERIC_TIME - default y - help - This driver provides a clocksource built upon the on-chip - 27MHz high-resolution timer. Its also a workaround for - NSC Geode SC-1100's buggy TSC, which loses time when the - processor goes idle (as is done by the scheduler). The - other workaround is idle=poll boot option. + If you don't know what to do here, say N. -config K8_NB - def_bool y - depends on AGP_AMD64 + This support is also available as a module. If compiled as a + module, it will be called scx200. source "drivers/pcmcia/Kconfig" diff --git a/trunk/arch/i386/Kconfig.cpu b/trunk/arch/i386/Kconfig.cpu index 21c9a4e71104..eb130482ba18 100644 --- a/trunk/arch/i386/Kconfig.cpu +++ b/trunk/arch/i386/Kconfig.cpu @@ -41,7 +41,7 @@ config M386 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - - "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above). + - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). If you don't know what to do, choose "386". diff --git a/trunk/arch/i386/boot/Makefile b/trunk/arch/i386/boot/Makefile index e97946626064..33e55476381b 100644 --- a/trunk/arch/i386/boot/Makefile +++ b/trunk/arch/i386/boot/Makefile @@ -109,13 +109,8 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf isoimage: $(BOOTIMAGE) -rm -rf $(obj)/isoimage mkdir $(obj)/isoimage - for i in lib lib64 share end ; do \ - if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ - cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ - break ; \ - fi ; \ - if [ $$i = end ] ; then exit 1 ; fi ; \ - done + cp `echo /usr/lib*/syslinux/isolinux.bin | awk '{ print $1; }'` \ + $(obj)/isoimage cp $(BOOTIMAGE) $(obj)/isoimage/linux echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg if [ -f '$(FDINITRD)' ] ; then \ diff --git a/trunk/arch/i386/boot/compressed/misc.c b/trunk/arch/i386/boot/compressed/misc.c index b2ccd543410d..f19f3a7492a5 100644 --- a/trunk/arch/i386/boot/compressed/misc.c +++ b/trunk/arch/i386/boot/compressed/misc.c @@ -24,6 +24,14 @@ #undef memset #undef memcpy + +/* + * Why do we do this? Don't ask me.. + * + * Incomprehensible are the ways of bootloaders. + */ +static void* memset(void *, int, size_t); +static void* memcpy(void *, __const void *, size_t); #define memzero(s, n) memset ((s), 0, (n)) typedef unsigned char uch; @@ -85,7 +93,7 @@ static unsigned char *real_mode; /* Pointer to real-mode data */ #endif #define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) -extern unsigned char input_data[]; +extern char input_data[]; extern int input_len; static long bytes_out = 0; @@ -95,9 +103,6 @@ static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); -static void *memset(void *s, int c, unsigned n); -static void *memcpy(void *dest, const void *src, unsigned n); - static void putstr(const char *); extern int end; @@ -200,7 +205,7 @@ static void putstr(const char *s) outb_p(0xff & (pos >> 1), vidport+1); } -static void* memset(void* s, int c, unsigned n) +static void* memset(void* s, int c, size_t n) { int i; char *ss = (char*)s; @@ -209,13 +214,14 @@ static void* memset(void* s, int c, unsigned n) return s; } -static void* memcpy(void* dest, const void* src, unsigned n) +static void* memcpy(void* __dest, __const void* __src, + size_t __n) { int i; - char *d = (char *)dest, *s = (char *)src; + char *d = (char *)__dest, *s = (char *)__src; - for (i=0;i RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif - output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ + output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; } @@ -318,9 +324,11 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) #ifdef STANDARD_MEMORY_BIOS_CALL if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < + (3*1024)) + error("Less than 4MB of memory"); #endif - mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; + mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; low_buffer_size = low_buffer_end - LOW_BUFFER_START; diff --git a/trunk/arch/i386/boot/video.S b/trunk/arch/i386/boot/video.S index 8c2a6faeeae5..c9343c3a8082 100644 --- a/trunk/arch/i386/boot/video.S +++ b/trunk/arch/i386/boot/video.S @@ -1929,7 +1929,7 @@ skip10: movb %ah, %al ret store_edid: -#ifdef CONFIG_FIRMWARE_EDID +#ifdef CONFIG_FB_FIRMWARE_EDID pushw %es # just save all registers pushw %ax pushw %bx @@ -1947,22 +1947,6 @@ store_edid: rep stosl - pushw %es # save ES - xorw %di, %di # Report Capability - pushw %di - popw %es # ES:DI must be 0:0 - movw $0x4f15, %ax - xorw %bx, %bx - xorw %cx, %cx - int $0x10 - popw %es # restore ES - - cmpb $0x00, %ah # call successful - jne no_edid - - cmpb $0x4f, %al # function supported - jne no_edid - movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx @@ -1970,7 +1954,6 @@ store_edid: movw $0x140, %di int $0x10 -no_edid: popw %di # restore all registers popw %dx popw %cx diff --git a/trunk/arch/i386/crypto/aes-i586-asm.S b/trunk/arch/i386/crypto/aes-i586-asm.S index f942f0c8f630..911b15377f2e 100644 --- a/trunk/arch/i386/crypto/aes-i586-asm.S +++ b/trunk/arch/i386/crypto/aes-i586-asm.S @@ -36,19 +36,22 @@ .file "aes-i586-asm.S" .text -#include - +// aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])// +// aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])// + #define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) -/* offsets to parameters with one register pushed onto stack */ -#define tfm 8 -#define out_blk 12 -#define in_blk 16 +// offsets to parameters with one register pushed onto stack + +#define in_blk 8 // input byte array address parameter +#define out_blk 12 // output byte array address parameter +#define ctx 16 // AES context structure + +// offsets in context structure -/* offsets in crypto_tfm structure */ -#define ekey (crypto_tfm_ctx_offset + 0) -#define nrnd (crypto_tfm_ctx_offset + 256) -#define dkey (crypto_tfm_ctx_offset + 260) +#define ekey 0 // encryption key schedule base address +#define nrnd 256 // number of rounds +#define dkey 260 // decryption key schedule base address // register mapping for encrypt and decrypt subroutines @@ -217,7 +220,6 @@ do_col (table, r5,r0,r1,r4, r2,r3); /* idx=r5 */ // AES (Rijndael) Encryption Subroutine -/* void aes_enc_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */ .global aes_enc_blk @@ -228,7 +230,7 @@ aes_enc_blk: push %ebp - mov tfm(%esp),%ebp + mov ctx(%esp),%ebp // pointer to context // CAUTION: the order and the values used in these assigns // rely on the register mappings @@ -293,7 +295,6 @@ aes_enc_blk: ret // AES (Rijndael) Decryption Subroutine -/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */ .global aes_dec_blk @@ -304,7 +305,7 @@ aes_enc_blk: aes_dec_blk: push %ebp - mov tfm(%esp),%ebp + mov ctx(%esp),%ebp // pointer to context // CAUTION: the order and the values used in these assigns // rely on the register mappings diff --git a/trunk/arch/i386/crypto/aes.c b/trunk/arch/i386/crypto/aes.c index d3806daa3de3..a50397b1d5c7 100644 --- a/trunk/arch/i386/crypto/aes.c +++ b/trunk/arch/i386/crypto/aes.c @@ -45,8 +45,8 @@ #include #include -asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); -asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); +asmlinkage void aes_enc_blk(const u8 *src, u8 *dst, void *ctx); +asmlinkage void aes_dec_blk(const u8 *src, u8 *dst, void *ctx); #define AES_MIN_KEY_SIZE 16 #define AES_MAX_KEY_SIZE 32 @@ -378,12 +378,12 @@ static void gen_tabs(void) k[8*(i)+11] = ss[3]; \ } -static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int +aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) { int i; u32 ss[8]; - struct aes_ctx *ctx = crypto_tfm_ctx(tfm); + struct aes_ctx *ctx = ctx_arg; const __le32 *key = (const __le32 *)in_key; /* encryption schedule */ @@ -464,16 +464,16 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, return 0; } -static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static inline void aes_encrypt(void *ctx, u8 *dst, const u8 *src) { - aes_enc_blk(tfm, dst, src); + aes_enc_blk(src, dst, ctx); } - -static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static inline void aes_decrypt(void *ctx, u8 *dst, const u8 *src) { - aes_dec_blk(tfm, dst, src); + aes_dec_blk(src, dst, ctx); } + static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_driver_name = "aes-i586", diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 5e70c2fb273a..96fb8a020af2 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -7,9 +7,10 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o bootflag.o \ - quirks.o i8237.o topology.o alternative.o i8253.o tsc.o + quirks.o i8237.o topology.o alternative.o obj-y += cpu/ +obj-y += timers/ obj-y += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o @@ -36,8 +37,6 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_HPET_TIMER) += hpet.o -obj-$(CONFIG_K8_NB) += k8.o EXTRA_AFLAGS := -traditional @@ -77,6 +76,3 @@ SYSCFLAGS_vsyscall-syms.o = -r $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE $(call if_changed,syscall) - -k8-y += ../../x86_64/kernel/k8.o - diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index 97ca17189af5..40e5aba3ad3d 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -202,8 +202,6 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) if (mcfg->config[i].base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); - kfree(pci_mmcfg_config); - pci_mmcfg_config_num = 0; return -ENODEV; } } @@ -217,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) { struct acpi_table_madt *madt = NULL; - if (!phys_addr || !size || !cpu_has_apic) + if (!phys_addr || !size) return -EINVAL; madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); @@ -623,9 +621,9 @@ extern u32 pmtmr_ioport; static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) { - struct fadt_descriptor *fadt = NULL; + struct fadt_descriptor_rev2 *fadt = NULL; - fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size); + fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); if (!fadt) { printk(KERN_WARNING PREFIX "Unable to map FADT\n"); return 0; @@ -756,7 +754,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } - if (!cpu_has_apic) + if (!cpu_has_apic) return -ENODEV; /* diff --git a/trunk/arch/i386/kernel/acpi/processor.c b/trunk/arch/i386/kernel/acpi/processor.c index b54fded49834..9f4cc02717ec 100644 --- a/trunk/arch/i386/kernel/acpi/processor.c +++ b/trunk/arch/i386/kernel/acpi/processor.c @@ -47,7 +47,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) buf[2] = ACPI_PDC_C_CAPABILITY_SMP; if (cpu_has(c, X86_FEATURE_EST)) - buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; + buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; diff --git a/trunk/arch/i386/kernel/acpi/sleep.c b/trunk/arch/i386/kernel/acpi/sleep.c index 4ee83577bf61..1cb2b186a3af 100644 --- a/trunk/arch/i386/kernel/acpi/sleep.c +++ b/trunk/arch/i386/kernel/acpi/sleep.c @@ -8,17 +8,30 @@ #include #include #include -#include - #include +#include /* address in low memory of the wakeup routine. */ unsigned long acpi_wakeup_address = 0; unsigned long acpi_video_flags; extern char wakeup_start, wakeup_end; +extern void zap_low_mappings(void); + extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); +static void init_low_mapping(pgd_t * pgd, int pgd_limit) +{ + int pgd_ofs = 0; + + while ((pgd_ofs < pgd_limit) + && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { + set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD)); + pgd_ofs++, pgd++; + } + flush_tlb_all(); +} + /** * acpi_save_state_mem - save kernel state * @@ -29,6 +42,7 @@ int acpi_save_state_mem(void) { if (!acpi_wakeup_address) return 1; + init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); memcpy((void *)acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); acpi_copy_wakeup_routine(acpi_wakeup_address); @@ -41,6 +55,7 @@ int acpi_save_state_mem(void) */ void acpi_restore_state_mem(void) { + zap_low_mappings(); } /** diff --git a/trunk/arch/i386/kernel/acpi/wakeup.S b/trunk/arch/i386/kernel/acpi/wakeup.S index 9f408eee4e6f..7c74fe0dc93c 100644 --- a/trunk/arch/i386/kernel/acpi/wakeup.S +++ b/trunk/arch/i386/kernel/acpi/wakeup.S @@ -56,7 +56,7 @@ wakeup_code: 1: # set up page table - movl $swsusp_pg_dir-__PAGE_OFFSET, %eax + movl $swapper_pg_dir-__PAGE_OFFSET, %eax movl %eax, %cr3 testl $1, real_efer_save_restore - wakeup_code @@ -265,6 +265,11 @@ ENTRY(acpi_copy_wakeup_routine) movl $0x12345678, saved_magic ret +.data +ALIGN +ENTRY(saved_magic) .long 0 +ENTRY(saved_eip) .long 0 + save_registers: leal 4(%esp), %eax movl %eax, saved_context_esp @@ -299,11 +304,7 @@ ret_point: call restore_processor_state ret -.data ALIGN -ENTRY(saved_magic) .long 0 -ENTRY(saved_eip) .long 0 - # saved registers saved_gdt: .long 0,0 saved_idt: .long 0,0 diff --git a/trunk/arch/i386/kernel/alternative.c b/trunk/arch/i386/kernel/alternative.c index 50eb0e03777e..5cbd6f99fb2a 100644 --- a/trunk/arch/i386/kernel/alternative.c +++ b/trunk/arch/i386/kernel/alternative.c @@ -4,41 +4,27 @@ #include #include -static int no_replacement = 0; -static int smp_alt_once = 0; -static int debug_alternative = 0; - -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 1; -} -static int __init bootonly(char *str) -{ - smp_alt_once = 1; - return 1; -} -static int __init debug_alt(char *str) -{ - debug_alternative = 1; - return 1; -} - -__setup("noreplacement", noreplacement_setup); -__setup("smp-alt-boot", bootonly); -__setup("debug-alternative", debug_alt); - -#define DPRINTK(fmt, args...) if (debug_alternative) \ - printk(KERN_DEBUG fmt, args) +#define DEBUG 0 +#if DEBUG +# define DPRINTK(fmt, args...) printk(fmt, args) +#else +# define DPRINTK(fmt, args...) +#endif -#ifdef GENERIC_NOP1 /* Use inline assembly to define this because the nops are defined as inline assembly strings in the include files and we cannot get them easily into strings. */ asm("\t.data\nintelnops: " GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 GENERIC_NOP7 GENERIC_NOP8); -extern unsigned char intelnops[]; +asm("\t.data\nk8nops: " + K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 + K8_NOP7 K8_NOP8); +asm("\t.data\nk7nops: " + K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 + K7_NOP7 K7_NOP8); + +extern unsigned char intelnops[], k8nops[], k7nops[]; static unsigned char *intel_nops[ASM_NOP_MAX+1] = { NULL, intelnops, @@ -50,13 +36,6 @@ static unsigned char *intel_nops[ASM_NOP_MAX+1] = { intelnops + 1 + 2 + 3 + 4 + 5 + 6, intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; -#endif - -#ifdef K8_NOP1 -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); -extern unsigned char k8nops[]; static unsigned char *k8_nops[ASM_NOP_MAX+1] = { NULL, k8nops, @@ -68,13 +47,6 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = { k8nops + 1 + 2 + 3 + 4 + 5 + 6, k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; -#endif - -#ifdef K7_NOP1 -asm("\t.data\nk7nops: " - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 - K7_NOP7 K7_NOP8); -extern unsigned char k7nops[]; static unsigned char *k7_nops[ASM_NOP_MAX+1] = { NULL, k7nops, @@ -86,18 +58,6 @@ static unsigned char *k7_nops[ASM_NOP_MAX+1] = { k7nops + 1 + 2 + 3 + 4 + 5 + 6, k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, }; -#endif - -#ifdef CONFIG_X86_64 - -extern char __vsyscall_0; -static inline unsigned char** find_nop_table(void) -{ - return k8_nops; -} - -#else /* CONFIG_X86_64 */ - static struct nop { int cpuid; unsigned char **noptable; @@ -107,6 +67,14 @@ static struct nop { { -1, NULL } }; + +extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; +extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; +extern u8 *__smp_locks[], *__smp_locks_end[]; + +extern u8 __smp_alt_begin[], __smp_alt_end[]; + + static unsigned char** find_nop_table(void) { unsigned char **noptable = intel_nops; @@ -121,14 +89,6 @@ static unsigned char** find_nop_table(void) return noptable; } -#endif /* CONFIG_X86_64 */ - -extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; -extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; -extern u8 *__smp_locks[], *__smp_locks_end[]; - -extern u8 __smp_alt_begin[], __smp_alt_end[]; - /* Replace instructions with better alternatives for this CPU type. This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where @@ -139,7 +99,6 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { unsigned char **noptable = find_nop_table(); struct alt_instr *a; - u8 *instr; int diff, i, k; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); @@ -147,16 +106,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) BUG_ON(a->replacementlen > a->instrlen); if (!boot_cpu_has(a->cpuid)) continue; - instr = a->instr; -#ifdef CONFIG_X86_64 - /* vsyscall code is not mapped yet. resolve it manually. */ - if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { - instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0)); - DPRINTK("%s: vsyscall fixup: %p => %p\n", - __FUNCTION__, a->instr, instr); - } -#endif - memcpy(instr, a->replacement, a->replacementlen); + memcpy(a->instr, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; /* Pad the rest with nops */ for (i = a->replacementlen; diff > 0; diff -= k, i += k) { @@ -236,6 +186,14 @@ struct smp_alt_module { static LIST_HEAD(smp_alt_modules); static DEFINE_SPINLOCK(smp_alt); +static int smp_alt_once = 0; +static int __init bootonly(char *str) +{ + smp_alt_once = 1; + return 1; +} +__setup("smp-alt-boot", bootonly); + void alternatives_smp_module_add(struct module *mod, char *name, void *locks, void *locks_end, void *text, void *text_end) @@ -243,9 +201,6 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; - if (no_replacement) - return; - if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -280,7 +235,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; spin_lock_irqsave(&smp_alt, flags); @@ -301,7 +256,7 @@ void alternatives_smp_switch(int smp) struct smp_alt_module *mod; unsigned long flags; - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); @@ -330,13 +285,6 @@ void alternatives_smp_switch(int smp) void __init alternative_instructions(void) { - if (no_replacement) { - printk(KERN_INFO "(SMP-)alternatives turned off\n"); - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - return; - } apply_alternatives(__alt_instructions, __alt_instructions_end); /* switch to patch-once-at-boottime-only mode and free the diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 7ce09492fc0c..3d4b2f3d116a 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -63,7 +62,7 @@ int apic_verbosity; static void apic_pm_activate(void); -static int modern_apic(void) +int modern_apic(void) { unsigned int lvr, version; /* AMD systems use old APIC versions, so check the CPU */ @@ -114,7 +113,7 @@ void __init apic_intr_init(void) } /* Using APIC to generate smp_local_timer_interrupt? */ -int using_apic_timer __read_mostly = 0; +int using_apic_timer = 0; static int enabled_via_apicbase; @@ -157,7 +156,7 @@ void clear_local_APIC(void) maxlvt = get_maxlvt(); /* - * Masking an LVT entry can trigger a local APIC error + * Masking an LVT entry on a P6 can trigger a local APIC error * if the vector is zero. Mask LVTERR first to prevent this. */ if (maxlvt >= 3) { @@ -1118,18 +1117,7 @@ void disable_APIC_timer(void) unsigned long v; v = apic_read(APIC_LVTT); - /* - * When an illegal vector value (0-15) is written to an LVT - * entry and delivery mode is Fixed, the APIC may signal an - * illegal vector error, with out regard to whether the mask - * bit is set or whether an interrupt is actually seen on input. - * - * Boot sequence might call this function when the LVTT has - * '0' vector value. So make sure vector field is set to - * valid value. - */ - v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); - apic_write_around(APIC_LVTT, v); + apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); } } diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index 7c5729d1fd06..df0e1745f189 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -374,14 +374,14 @@ static struct { unsigned short segment; } apm_bios_entry; static int clock_slowed; -static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; -static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; +static int idle_threshold = DEFAULT_IDLE_THRESHOLD; +static int idle_period = DEFAULT_IDLE_PERIOD; static int set_pm_idle; static int suspends_pending; static int standbys_pending; static int ignore_sys_suspend; static int ignore_normal_resume; -static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; +static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; #ifdef CONFIG_APM_RTC_IS_GMT # define clock_cmos_diff 0 @@ -390,8 +390,8 @@ static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; static long clock_cmos_diff; static int got_clock_diff; #endif -static int debug __read_mostly; -static int smp __read_mostly; +static int debug; +static int smp; static int apm_disabled = -1; #ifdef CONFIG_SMP static int power_off; @@ -403,8 +403,8 @@ static int realmode_power_off = 1; #else static int realmode_power_off; #endif -static int exit_kapmd __read_mostly; -static int kapmd_running __read_mostly; +static int exit_kapmd; +static int kapmd_running; #ifdef CONFIG_APM_ALLOW_INTS static int allow_ints = 1; #else @@ -416,15 +416,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static struct apm_user * user_list; static DEFINE_SPINLOCK(user_list_lock); -static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; +static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; -static const char driver_version[] = "1.16ac"; /* no spaces */ +static char driver_version[] = "1.16ac"; /* no spaces */ /* * APM event names taken from the APM 1.2 specification. These are * the message codes that the BIOS uses to tell us about events */ -static const char * const apm_event_name[] = { +static char * apm_event_name[] = { "system standby", "system suspend", "normal resume", @@ -616,7 +616,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, * @ecx_in: ECX register value for BIOS call * @eax: EAX register on return from the BIOS call * - * Make a BIOS call that returns one value only, or just status. + * Make a BIOS call that does only returns one value, or just status. * If there is an error, then the error code is returned in AH * (bits 8-15 of eax) and this function returns non-zero. This is * used for simpler BIOS operations. This call may hold interrupts @@ -764,9 +764,9 @@ static int apm_do_idle(void) int idled = 0; int polling; - polling = !!(current_thread_info()->status & TS_POLLING); + polling = test_thread_flag(TIF_POLLING_NRFLAG); if (polling) { - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); } if (!need_resched()) { @@ -774,7 +774,7 @@ static int apm_do_idle(void) ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); } if (polling) - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); if (!idled) return 0; @@ -822,7 +822,7 @@ static void apm_do_busy(void) #define IDLE_CALC_LIMIT (HZ * 100) #define IDLE_LEAKY_MAX 16 -static void (*original_pm_idle)(void) __read_mostly; +static void (*original_pm_idle)(void); /** * apm_cpu_idle - cpu idling for APM capable Linux @@ -1063,8 +1063,7 @@ static int apm_engage_power_management(u_short device, int enable) static int apm_console_blank(int blank) { - int error = APM_NOT_ENGAGED; /* silence gcc */ - int i; + int error, i; u_short state; static const u_short dev[3] = { 0x100, 0x1FF, 0x101 }; @@ -1105,8 +1104,7 @@ static int queue_empty(struct apm_user *as) static apm_event_t get_queued_event(struct apm_user *as) { - if (++as->event_tail >= APM_MAX_EVENTS) - as->event_tail = 0; + as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; return as->events[as->event_tail]; } @@ -1120,16 +1118,13 @@ static void queue_event(apm_event_t event, struct apm_user *sender) for (as = user_list; as != NULL; as = as->next) { if ((as == sender) || (!as->reader)) continue; - if (++as->event_head >= APM_MAX_EVENTS) - as->event_head = 0; - + as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; if (as->event_head == as->event_tail) { static int notified; if (notified++ == 0) printk(KERN_ERR "apm: an event queue overflowed\n"); - if (++as->event_tail >= APM_MAX_EVENTS) - as->event_tail = 0; + as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; } as->events[as->event_head] = event; if ((!as->suser) || (!as->writer)) @@ -1287,7 +1282,7 @@ static void standby(void) static apm_event_t get_event(void) { int error; - apm_event_t event = APM_NO_EVENTS; /* silence gcc */ + apm_event_t event; apm_eventinfo_t info; static int notified; diff --git a/trunk/arch/i386/kernel/asm-offsets.c b/trunk/arch/i386/kernel/asm-offsets.c index c80271f8f084..36d66e2077d0 100644 --- a/trunk/arch/i386/kernel/asm-offsets.c +++ b/trunk/arch/i386/kernel/asm-offsets.c @@ -4,7 +4,6 @@ * to extract and format the required data. */ -#include #include #include #include @@ -14,7 +13,6 @@ #include #include #include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -55,7 +53,6 @@ void foo(void) OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); - OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); @@ -71,7 +68,5 @@ void foo(void) sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(VDSO_PRELINK, VDSO_PRELINK); - - OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); + DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); } diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index e6a2d6b80cda..786d1a57048b 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -224,26 +224,22 @@ static void __init init_amd(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_HT /* - * On a AMD multi core setup the lower bits of the APIC id - * distingush the cores. + * On a AMD dual core setup the lower bits of the APIC id + * distingush the cores. Assumes number of cores is a power + * of two. */ if (c->x86_max_cores > 1) { int cpu = smp_processor_id(); - unsigned bits = (cpuid_ecx(0x80000008) >> 12) & 0xf; - - if (bits == 0) { - while ((1 << bits) < c->x86_max_cores) - bits++; - } - c->cpu_core_id = c->phys_proc_id & ((1<phys_proc_id >>= bits; + unsigned bits = 0; + while ((1 << bits) < c->x86_max_cores) + bits++; + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<>= bits; printk(KERN_INFO "CPU %d(%d) -> Core %d\n", - cpu, c->x86_max_cores, c->cpu_core_id); + cpu, c->x86_max_cores, cpu_core_id[cpu]); } #endif - if (cpuid_eax(0x80000000) >= 0x80000006) - num_cache_leaves = 3; } static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 70c87de582c7..a06a49075f10 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #ifdef CONFIG_X86_LOCAL_APIC #include #include @@ -294,7 +292,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_mask = tfms & 15; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); #else c->apicid = (ebx >> 24) & 0xFF; @@ -319,7 +317,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) early_intel_workaround(c); #ifdef CONFIG_X86_HT - c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; + phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; #endif } @@ -477,9 +475,11 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; int index_msb, core_bits; + int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); + if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; @@ -490,17 +490,16 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) } else if (smp_num_siblings > 1 ) { if (smp_num_siblings > NR_CPUS) { - printk(KERN_WARNING "CPU: Unsupported number of the " - "siblings %d", smp_num_siblings); + printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); smp_num_siblings = 1; return; } index_msb = get_count_order(smp_num_siblings); - c->phys_proc_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); + phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - c->phys_proc_id); + phys_proc_id[cpu]); smp_num_siblings = smp_num_siblings / c->x86_max_cores; @@ -508,12 +507,12 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) core_bits = get_count_order(c->x86_max_cores); - c->cpu_core_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & + cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & ((1 << core_bits) - 1); if (c->x86_max_cores > 1) printk(KERN_INFO "CPU: Processor Core ID: %d\n", - c->cpu_core_id); + cpu_core_id[cpu]); } } #endif @@ -612,12 +611,6 @@ void __cpuinit cpu_init(void) set_in_cr4(X86_CR4_TSD); } - /* The CPU hotplug case */ - if (cpu_gdt_descr->address) { - gdt = (struct desc_struct *)cpu_gdt_descr->address; - memset(gdt, 0, PAGE_SIZE); - goto old_gdt; - } /* * This is a horrible hack to allocate the GDT. The problem * is that cpu_init() is called really early for the boot CPU @@ -636,7 +629,7 @@ void __cpuinit cpu_init(void) local_irq_enable(); } } -old_gdt: + /* * Initialize the per-CPU GDT with the boot GDT, * and set up the GDT descriptor: diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 5fd65325b81a..1a7bdcef1926 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -48,13 +48,12 @@ MODULE_LICENSE("GPL"); struct cpufreq_acpi_io { - struct acpi_processor_performance *acpi_data; + struct acpi_processor_performance acpi_data; struct cpufreq_frequency_table *freq_table; unsigned int resume; }; static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; -static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; static struct cpufreq_driver acpi_cpufreq_driver; @@ -105,43 +104,64 @@ acpi_processor_set_performance ( { u16 port = 0; u8 bit_width = 0; - int i = 0; - int ret = 0; + int ret; u32 value = 0; + int i = 0; + struct cpufreq_freqs cpufreq_freqs; + cpumask_t saved_mask; int retval; - struct acpi_processor_performance *perf; dprintk("acpi_processor_set_performance\n"); - retval = 0; - perf = data->acpi_data; - if (state == perf->state) { + /* + * TBD: Use something other than set_cpus_allowed. + * As set_cpus_allowed is a bit racy, + * with any other set_cpus_allowed for this process. + */ + saved_mask = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (smp_processor_id() != cpu) { + return (-EAGAIN); + } + + if (state == data->acpi_data.state) { if (unlikely(data->resume)) { dprintk("Called after resume, resetting to P%d\n", state); data->resume = 0; } else { dprintk("Already at target state (P%d)\n", state); - return (retval); + retval = 0; + goto migrate_end; } } - dprintk("Transitioning from P%d to P%d\n", perf->state, state); + dprintk("Transitioning from P%d to P%d\n", + data->acpi_data.state, state); + + /* cpufreq frequency struct */ + cpufreq_freqs.cpu = cpu; + cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency; + cpufreq_freqs.new = data->freq_table[state].frequency; + + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); /* * First we write the target state's 'control' value to the * control_register. */ - port = perf->control_register.address; - bit_width = perf->control_register.bit_width; - value = (u32) perf->states[state].control; + port = data->acpi_data.control_register.address; + bit_width = data->acpi_data.control_register.bit_width; + value = (u32) data->acpi_data.states[state].control; dprintk("Writing 0x%08x to port 0x%04x\n", value, port); ret = acpi_processor_write_port(port, bit_width, value); if (ret) { dprintk("Invalid port width 0x%04x\n", bit_width); - return (ret); + retval = ret; + goto migrate_end; } /* @@ -157,35 +177,48 @@ acpi_processor_set_performance ( * before giving up. */ - port = perf->status_register.address; - bit_width = perf->status_register.bit_width; + port = data->acpi_data.status_register.address; + bit_width = data->acpi_data.status_register.bit_width; dprintk("Looking for 0x%08x from port 0x%04x\n", - (u32) perf->states[state].status, port); + (u32) data->acpi_data.states[state].status, port); - for (i = 0; i < 100; i++) { + for (i=0; i<100; i++) { ret = acpi_processor_read_port(port, bit_width, &value); if (ret) { dprintk("Invalid port width 0x%04x\n", bit_width); - return (ret); + retval = ret; + goto migrate_end; } - if (value == (u32) perf->states[state].status) + if (value == (u32) data->acpi_data.states[state].status) break; udelay(10); } } else { - value = (u32) perf->states[state].status; + value = (u32) data->acpi_data.states[state].status; } - if (unlikely(value != (u32) perf->states[state].status)) { + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + + if (unlikely(value != (u32) data->acpi_data.states[state].status)) { + unsigned int tmp = cpufreq_freqs.new; + cpufreq_freqs.new = cpufreq_freqs.old; + cpufreq_freqs.old = tmp; + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); printk(KERN_WARNING "acpi-cpufreq: Transition failed\n"); retval = -ENODEV; - return (retval); + goto migrate_end; } dprintk("Transition successful after %d microseconds\n", i * 10); - perf->state = state; + data->acpi_data.state = state; + + retval = 0; +migrate_end: + set_cpus_allowed(current, saved_mask); return (retval); } @@ -197,17 +230,8 @@ acpi_cpufreq_target ( unsigned int relation) { struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; - struct acpi_processor_performance *perf; - struct cpufreq_freqs freqs; - cpumask_t online_policy_cpus; - cpumask_t saved_mask; - cpumask_t set_mask; - cpumask_t covered_cpus; - unsigned int cur_state = 0; unsigned int next_state = 0; unsigned int result = 0; - unsigned int j; - unsigned int tmp; dprintk("acpi_cpufreq_setpolicy\n"); @@ -216,95 +240,11 @@ acpi_cpufreq_target ( target_freq, relation, &next_state); - if (unlikely(result)) + if (result) return (result); - perf = data->acpi_data; - cur_state = perf->state; - freqs.old = data->freq_table[cur_state].frequency; - freqs.new = data->freq_table[next_state].frequency; - -#ifdef CONFIG_HOTPLUG_CPU - /* cpufreq holds the hotplug lock, so we are safe from here on */ - cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); -#else - online_policy_cpus = policy->cpus; -#endif - - for_each_cpu_mask(j, online_policy_cpus) { - freqs.cpu = j; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - /* - * We need to call driver->target() on all or any CPU in - * policy->cpus, depending on policy->shared_type. - */ - saved_mask = current->cpus_allowed; - cpus_clear(covered_cpus); - for_each_cpu_mask(j, online_policy_cpus) { - /* - * Support for SMP systems. - * Make sure we are running on CPU that wants to change freq - */ - cpus_clear(set_mask); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - cpus_or(set_mask, set_mask, online_policy_cpus); - else - cpu_set(j, set_mask); - - set_cpus_allowed(current, set_mask); - if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { - dprintk("couldn't limit to CPUs in this domain\n"); - result = -EAGAIN; - break; - } - - result = acpi_processor_set_performance (data, j, next_state); - if (result) { - result = -EAGAIN; - break; - } - - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - break; - - cpu_set(j, covered_cpus); - } - - for_each_cpu_mask(j, online_policy_cpus) { - freqs.cpu = j; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } + result = acpi_processor_set_performance (data, policy->cpu, next_state); - if (unlikely(result)) { - /* - * We have failed halfway through the frequency change. - * We have sent callbacks to online_policy_cpus and - * acpi_processor_set_performance() has been called on - * coverd_cpus. Best effort undo.. - */ - - if (!cpus_empty(covered_cpus)) { - for_each_cpu_mask(j, covered_cpus) { - policy->cpu = j; - acpi_processor_set_performance (data, - j, - cur_state); - } - } - - tmp = freqs.new; - freqs.new = freqs.old; - freqs.old = tmp; - for_each_cpu_mask(j, online_policy_cpus) { - freqs.cpu = j; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - } - - set_cpus_allowed(current, saved_mask); return (result); } @@ -330,65 +270,30 @@ acpi_cpufreq_guess_freq ( struct cpufreq_acpi_io *data, unsigned int cpu) { - struct acpi_processor_performance *perf = data->acpi_data; - if (cpu_khz) { /* search the closest match to cpu_khz */ unsigned int i; unsigned long freq; - unsigned long freqn = perf->states[0].core_frequency * 1000; + unsigned long freqn = data->acpi_data.states[0].core_frequency * 1000; - for (i = 0; i < (perf->state_count - 1); i++) { + for (i=0; i < (data->acpi_data.state_count - 1); i++) { freq = freqn; - freqn = perf->states[i+1].core_frequency * 1000; + freqn = data->acpi_data.states[i+1].core_frequency * 1000; if ((2 * cpu_khz) > (freqn + freq)) { - perf->state = i; + data->acpi_data.state = i; return (freq); } } - perf->state = perf->state_count - 1; + data->acpi_data.state = data->acpi_data.state_count - 1; return (freqn); - } else { + } else /* assume CPU is at P0... */ - perf->state = 0; - return perf->states[0].core_frequency * 1000; - } + data->acpi_data.state = 0; + return data->acpi_data.states[0].core_frequency * 1000; + } -/* - * acpi_cpufreq_early_init - initialize ACPI P-States library - * - * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c) - * in order to determine correct frequency and voltage pairings. We can - * do _PDC and _PSD and find out the processor dependency for the - * actual init that will happen later... - */ -static int acpi_cpufreq_early_init_acpi(void) -{ - struct acpi_processor_performance *data; - unsigned int i, j; - - dprintk("acpi_cpufreq_early_init\n"); - - for_each_possible_cpu(i) { - data = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!data) { - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } - return (-ENOMEM); - } - acpi_perf_data[i] = data; - } - - /* Do initialization in ACPI core */ - acpi_processor_preregister_performance(acpi_perf_data); - return 0; -} - static int acpi_cpufreq_cpu_init ( struct cpufreq_policy *policy) @@ -398,51 +303,41 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; - struct acpi_processor_performance *perf; dprintk("acpi_cpufreq_cpu_init\n"); - if (!acpi_perf_data[cpu]) - return (-ENODEV); - data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) return (-ENOMEM); - data->acpi_data = acpi_perf_data[cpu]; acpi_io_data[cpu] = data; - result = acpi_processor_register_performance(data->acpi_data, cpu); + result = acpi_processor_register_performance(&data->acpi_data, cpu); if (result) goto err_free; - perf = data->acpi_data; - policy->cpus = perf->shared_cpu_map; - policy->shared_type = perf->shared_type; - if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; } /* capability check */ - if (perf->state_count <= 1) { + if (data->acpi_data.state_count <= 1) { dprintk("No P-States\n"); result = -ENODEV; goto err_unreg; } - - if ((perf->control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || - (perf->status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { + if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || + (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { dprintk("Unsupported address space [%d, %d]\n", - (u32) (perf->control_register.space_id), - (u32) (perf->status_register.space_id)); + (u32) (data->acpi_data.control_register.space_id), + (u32) (data->acpi_data.status_register.space_id)); result = -ENODEV; goto err_unreg; } /* alloc freq_table */ - data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (perf->state_count + 1), GFP_KERNEL); + data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL); if (!data->freq_table) { result = -ENOMEM; goto err_unreg; @@ -450,9 +345,9 @@ acpi_cpufreq_cpu_init ( /* detect transition latency */ policy->cpuinfo.transition_latency = 0; - for (i=0; istate_count; i++) { - if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) - policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; + for (i=0; iacpi_data.state_count; i++) { + if ((data->acpi_data.states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) + policy->cpuinfo.transition_latency = data->acpi_data.states[i].transition_latency * 1000; } policy->governor = CPUFREQ_DEFAULT_GOVERNOR; @@ -460,11 +355,11 @@ acpi_cpufreq_cpu_init ( policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); /* table init */ - for (i=0; i<=perf->state_count; i++) + for (i=0; i<=data->acpi_data.state_count; i++) { data->freq_table[i].index = i; - if (istate_count) - data->freq_table[i].frequency = perf->states[i].core_frequency * 1000; + if (iacpi_data.state_count) + data->freq_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; else data->freq_table[i].frequency = CPUFREQ_TABLE_END; } @@ -479,12 +374,12 @@ acpi_cpufreq_cpu_init ( printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n", cpu); - for (i = 0; i < perf->state_count; i++) + for (i = 0; i < data->acpi_data.state_count; i++) dprintk(" %cP%d: %d MHz, %d mW, %d uS\n", - (i == perf->state?'*':' '), i, - (u32) perf->states[i].core_frequency, - (u32) perf->states[i].power, - (u32) perf->states[i].transition_latency); + (i == data->acpi_data.state?'*':' '), i, + (u32) data->acpi_data.states[i].core_frequency, + (u32) data->acpi_data.states[i].power, + (u32) data->acpi_data.states[i].transition_latency); cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); @@ -499,7 +394,7 @@ acpi_cpufreq_cpu_init ( err_freqfree: kfree(data->freq_table); err_unreg: - acpi_processor_unregister_performance(perf, cpu); + acpi_processor_unregister_performance(&data->acpi_data, cpu); err_free: kfree(data); acpi_io_data[cpu] = NULL; @@ -520,7 +415,7 @@ acpi_cpufreq_cpu_exit ( if (data) { cpufreq_frequency_table_put_attr(policy->cpu); acpi_io_data[policy->cpu] = NULL; - acpi_processor_unregister_performance(data->acpi_data, policy->cpu); + acpi_processor_unregister_performance(&data->acpi_data, policy->cpu); kfree(data); } @@ -567,10 +462,7 @@ acpi_cpufreq_init (void) dprintk("acpi_cpufreq_init\n"); - result = acpi_cpufreq_early_init_acpi(); - - if (!result) - result = cpufreq_register_driver(&acpi_cpufreq_driver); + result = cpufreq_register_driver(&acpi_cpufreq_driver); return (result); } @@ -579,15 +471,10 @@ acpi_cpufreq_init (void) static void __exit acpi_cpufreq_exit (void) { - unsigned int i; dprintk("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); - for_each_possible_cpu(i) { - kfree(acpi_perf_data[i]); - acpi_perf_data[i] = NULL; - } return; } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 2d6491672559..b4277f58f40c 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -120,7 +120,7 @@ static int pending_bit_stuck(void) { u32 lo, hi; - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) return 0; rdmsr(MSR_FIDVID_STATUS, lo, hi); @@ -136,7 +136,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) u32 lo, hi; u32 i = 0; - if (cpu_family == CPU_HW_PSTATE) { + if (cpu_family) { rdmsr(MSR_PSTATE_STATUS, lo, hi); i = lo & HW_PSTATE_MASK; rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); @@ -598,7 +598,7 @@ static void print_basics(struct powernow_k8_data *data) int j; for (j = 0; j < data->numps; j++) { if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { - if (cpu_family == CPU_HW_PSTATE) { + if (cpu_family) { printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, (data->powernow_table[j].index & 0xff0000) >> 16, data->powernow_table[j].frequency/1000); @@ -758,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data) #ifdef CONFIG_X86_POWERNOW_K8_ACPI static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { - if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) + if (!data->acpi_data.state_count || cpu_family) return; data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; @@ -801,7 +801,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) goto err_out; } - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) ret_val = fill_powernow_table_pstate(data, powernow_table); else ret_val = fill_powernow_table_fidvid(data, powernow_table); @@ -885,8 +885,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf u32 vid; if (data->exttype) { - fid = data->acpi_data.states[i].status & EXT_FID_MASK; - vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; + fid = data->acpi_data.states[i].status & FID_MASK; + vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; } else { fid = data->acpi_data.states[i].control & FID_MASK; vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; @@ -1082,7 +1082,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi if (query_current_values_with_pending_wait(data)) goto err_out; - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) dprintk("targ: curr fid 0x%x, did 0x%x\n", data->currfid, data->currvid); else { @@ -1103,7 +1103,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi powernow_k8_acpi_pst_values(data, newstate); - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) ret = transition_frequency_pstate(data, newstate); else ret = transition_frequency_fidvid(data, newstate); @@ -1115,7 +1115,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi } mutex_unlock(&fidvid_mutex); - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); else pol->cur = find_khz_freq_from_fid(data->currfid); @@ -1163,7 +1163,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. */ - if (num_online_cpus() != 1) { + if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); kfree(data); return -ENODEV; @@ -1197,14 +1197,14 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) if (query_current_values_with_pending_wait(data)) goto err_out; - if (cpu_family == CPU_OPTERON) + if (!cpu_family) fidvid_msr_init(); /* run on any CPU again */ set_cpus_allowed(current, oldmask); pol->governor = CPUFREQ_DEFAULT_GOVERNOR; - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) pol->cpus = cpumask_of_cpu(pol->cpu); else pol->cpus = cpu_core_map[pol->cpu]; @@ -1215,7 +1215,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) + (3 * (1 << data->irt) * 10)) * 1000; - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); else pol->cur = find_khz_freq_from_fid(data->currfid); @@ -1232,7 +1232,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); - if (cpu_family == CPU_HW_PSTATE) + if (cpu_family) dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", data->currfid, data->currdid); else diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 0fb2a3001ba5..bf8ad9e43da3 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -169,9 +169,7 @@ struct powernow_k8_data { #define MVS_MASK 3 #define VST_MASK 0x7f #define VID_MASK 0x1f -#define FID_MASK 0x1f -#define EXT_VID_MASK 0x3f -#define EXT_FID_MASK 0x3f +#define FID_MASK 0x3f /* diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index f7e4356f6820..ce54ff12c15d 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -2,15 +2,19 @@ * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium * M (part of the Centrino chipset). * - * Since the original Pentium M, most new Intel CPUs support Enhanced - * SpeedStep. - * * Despite the "SpeedStep" in the name, this is almost entirely unlike * traditional SpeedStep. * * Modelled on speedstep.c * * Copyright (C) 2003 Jeremy Fitzhardinge + * + * WARNING WARNING WARNING + * + * This driver manipulates the PERF_CTL MSR, which is only somewhat + * documented. While it seems to work on my laptop, it has not been + * tested anywhere else, and it may not work for you, do strange + * things or simply crash. */ #include @@ -32,7 +36,7 @@ #include #define PFX "speedstep-centrino: " -#define MAINTAINER "cpufreq@lists.linux.org.uk" +#define MAINTAINER "Jeremy Fitzhardinge " #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) @@ -347,36 +351,7 @@ static unsigned int get_cur_freq(unsigned int cpu) #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI -static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; - -/* - * centrino_cpu_early_init_acpi - Do the preregistering with ACPI P-States - * library - * - * Before doing the actual init, we need to do _PSD related setup whenever - * supported by the BIOS. These are handled by this early_init routine. - */ -static int centrino_cpu_early_init_acpi(void) -{ - unsigned int i, j; - struct acpi_processor_performance *data; - - for_each_possible_cpu(i) { - data = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!data) { - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } - return (-ENOMEM); - } - acpi_perf_data[i] = data; - } - - acpi_processor_preregister_performance(acpi_perf_data); - return 0; -} +static struct acpi_processor_performance p; /* * centrino_cpu_init_acpi - register with ACPI P-States library @@ -390,51 +365,46 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) unsigned long cur_freq; int result = 0, i; unsigned int cpu = policy->cpu; - struct acpi_processor_performance *p; - - p = acpi_perf_data[cpu]; /* register with ACPI core */ - if (acpi_processor_register_performance(p, cpu)) { - dprintk(PFX "obtaining ACPI data failed\n"); + if (acpi_processor_register_performance(&p, cpu)) { + dprintk("obtaining ACPI data failed\n"); return -EIO; } - policy->cpus = p->shared_cpu_map; - policy->shared_type = p->shared_type; /* verify the acpi_data */ - if (p->state_count <= 1) { + if (p.state_count <= 1) { dprintk("No P-States\n"); result = -ENODEV; goto err_unreg; } - if ((p->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || - (p->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { + if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || + (p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { dprintk("Invalid control/status registers (%x - %x)\n", - p->control_register.space_id, p->status_register.space_id); + p.control_register.space_id, p.status_register.space_id); result = -EIO; goto err_unreg; } - for (i=0; istate_count; i++) { - if (p->states[i].control != p->states[i].status) { + for (i=0; istates[i].control, p->states[i].status); + p.states[i].control, p.states[i].status); result = -EINVAL; goto err_unreg; } - if (!p->states[i].core_frequency) { + if (!p.states[i].core_frequency) { dprintk("Zero core frequency for state %u\n", i); result = -EINVAL; goto err_unreg; } - if (p->states[i].core_frequency > p->states[0].core_frequency) { + if (p.states[i].core_frequency > p.states[0].core_frequency) { dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i, - p->states[i].core_frequency, p->states[0].core_frequency); - p->states[i].core_frequency = 0; + p.states[i].core_frequency, p.states[0].core_frequency); + p.states[i].core_frequency = 0; continue; } } @@ -446,26 +416,26 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) } centrino_model[cpu]->model_name=NULL; - centrino_model[cpu]->max_freq = p->states[0].core_frequency * 1000; + centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) * - (p->state_count + 1), GFP_KERNEL); + (p.state_count + 1), GFP_KERNEL); if (!centrino_model[cpu]->op_points) { result = -ENOMEM; goto err_kfree; } - for (i=0; istate_count; i++) { - centrino_model[cpu]->op_points[i].index = p->states[i].control; - centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000; + for (i=0; iop_points[i].index = p.states[i].control; + centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000; dprintk("adding state %i with frequency %u and control value %04x\n", i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index); } - centrino_model[cpu]->op_points[p->state_count].frequency = CPUFREQ_TABLE_END; + centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END; cur_freq = get_cur_freq(cpu); - for (i=0; istate_count; i++) { - if (!p->states[i].core_frequency) { + for (i=0; iop_points[i].frequency = CPUFREQ_ENTRY_INVALID; continue; @@ -481,7 +451,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) } if (cur_freq == centrino_model[cpu]->op_points[i].frequency) - p->state = i; + p.state = i; } /* notify BIOS that we exist */ @@ -494,13 +464,12 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) err_kfree: kfree(centrino_model[cpu]); err_unreg: - acpi_processor_unregister_performance(p, cpu); - dprintk(PFX "invalid ACPI data\n"); + acpi_processor_unregister_performance(&p, cpu); + dprintk("invalid ACPI data\n"); return (result); } #else static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; } -static inline int centrino_cpu_early_init_acpi(void) { return 0; } #endif static int centrino_cpu_init(struct cpufreq_policy *policy) @@ -586,15 +555,10 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI if (!centrino_model[cpu]->model_name) { - static struct acpi_processor_performance *p; - - if (acpi_perf_data[cpu]) { - p = acpi_perf_data[cpu]; - dprintk("unregistering and freeing ACPI data\n"); - acpi_processor_unregister_performance(p, cpu); - kfree(centrino_model[cpu]->op_points); - kfree(centrino_model[cpu]); - } + dprintk("unregistering and freeing ACPI data\n"); + acpi_processor_unregister_performance(&p, cpu); + kfree(centrino_model[cpu]->op_points); + kfree(centrino_model[cpu]); } #endif @@ -628,128 +592,63 @@ static int centrino_target (struct cpufreq_policy *policy, unsigned int relation) { unsigned int newstate = 0; - unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; + unsigned int msr, oldmsr, h, cpu = policy->cpu; struct cpufreq_freqs freqs; - cpumask_t online_policy_cpus; cpumask_t saved_mask; - cpumask_t set_mask; - cpumask_t covered_cpus; - int retval = 0; - unsigned int j, k, first_cpu, tmp; + int retval; - if (unlikely(centrino_model[cpu] == NULL)) + if (centrino_model[cpu] == NULL) return -ENODEV; - if (unlikely(cpufreq_frequency_table_target(policy, - centrino_model[cpu]->op_points, - target_freq, - relation, - &newstate))) { - return -EINVAL; + /* + * Support for SMP systems. + * Make sure we are running on the CPU that wants to change frequency + */ + saved_mask = current->cpus_allowed; + set_cpus_allowed(current, policy->cpus); + if (!cpu_isset(smp_processor_id(), policy->cpus)) { + dprintk("couldn't limit to CPUs in this domain\n"); + return(-EAGAIN); } -#ifdef CONFIG_HOTPLUG_CPU - /* cpufreq holds the hotplug lock, so we are safe from here on */ - cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); -#else - online_policy_cpus = policy->cpus; -#endif + if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq, + relation, &newstate)) { + retval = -EINVAL; + goto migrate_end; + } - saved_mask = current->cpus_allowed; - first_cpu = 1; - cpus_clear(covered_cpus); - for_each_cpu_mask(j, online_policy_cpus) { - /* - * Support for SMP systems. - * Make sure we are running on CPU that wants to change freq - */ - cpus_clear(set_mask); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - cpus_or(set_mask, set_mask, online_policy_cpus); - else - cpu_set(j, set_mask); - - set_cpus_allowed(current, set_mask); - if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { - dprintk("couldn't limit to CPUs in this domain\n"); - retval = -EAGAIN; - if (first_cpu) { - /* We haven't started the transition yet. */ - goto migrate_end; - } - break; - } + msr = centrino_model[cpu]->op_points[newstate].index; + rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); - msr = centrino_model[cpu]->op_points[newstate].index; - - if (first_cpu) { - rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); - if (msr == (oldmsr & 0xffff)) { - dprintk("no change needed - msr was and needs " - "to be %x\n", oldmsr); - retval = 0; - goto migrate_end; - } - - freqs.old = extract_clock(oldmsr, cpu, 0); - freqs.new = extract_clock(msr, cpu, 0); - - dprintk("target=%dkHz old=%d new=%d msr=%04x\n", - target_freq, freqs.old, freqs.new, msr); - - for_each_cpu_mask(k, online_policy_cpus) { - freqs.cpu = k; - cpufreq_notify_transition(&freqs, - CPUFREQ_PRECHANGE); - } - - first_cpu = 0; - /* all but 16 LSB are reserved, treat them with care */ - oldmsr &= ~0xffff; - msr &= 0xffff; - oldmsr |= msr; - } + if (msr == (oldmsr & 0xffff)) { + retval = 0; + dprintk("no change needed - msr was and needs to be %x\n", oldmsr); + goto migrate_end; + } - wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - break; + freqs.cpu = cpu; + freqs.old = extract_clock(oldmsr, cpu, 0); + freqs.new = extract_clock(msr, cpu, 0); - cpu_set(j, covered_cpus); - } + dprintk("target=%dkHz old=%d new=%d msr=%04x\n", + target_freq, freqs.old, freqs.new, msr); - for_each_cpu_mask(k, online_policy_cpus) { - freqs.cpu = k; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - if (unlikely(retval)) { - /* - * We have failed halfway through the frequency change. - * We have sent callbacks to policy->cpus and - * MSRs have already been written on coverd_cpus. - * Best effort undo.. - */ + /* all but 16 LSB are "reserved", so treat them with + care */ + oldmsr &= ~0xffff; + msr &= 0xffff; + oldmsr |= msr; - if (!cpus_empty(covered_cpus)) { - for_each_cpu_mask(j, covered_cpus) { - set_cpus_allowed(current, cpumask_of_cpu(j)); - wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); - } - } + wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); - tmp = freqs.new; - freqs.new = freqs.old; - freqs.old = tmp; - for_each_cpu_mask(j, online_policy_cpus) { - freqs.cpu = j; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - } + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + retval = 0; migrate_end: set_cpus_allowed(current, saved_mask); - return 0; + return (retval); } static struct freq_attr* centrino_attr[] = { @@ -791,25 +690,12 @@ static int __init centrino_init(void) if (!cpu_has(cpu, X86_FEATURE_EST)) return -ENODEV; - centrino_cpu_early_init_acpi(); - return cpufreq_register_driver(¢rino_driver); } static void __exit centrino_exit(void) { -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - unsigned int j; -#endif - cpufreq_unregister_driver(¢rino_driver); - -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } -#endif } MODULE_AUTHOR ("Jeremy Fitzhardinge "); diff --git a/trunk/arch/i386/kernel/cpu/cyrix.c b/trunk/arch/i386/kernel/cpu/cyrix.c index f03b7f94c304..00f2e058797c 100644 --- a/trunk/arch/i386/kernel/cpu/cyrix.c +++ b/trunk/arch/i386/kernel/cpu/cyrix.c @@ -184,7 +184,7 @@ static void __init geode_configure(void) #ifdef CONFIG_PCI -static struct pci_device_id __initdata cyrix_55x0[] = { +static struct pci_device_id cyrix_55x0[] = { { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, { }, @@ -272,15 +272,14 @@ static void __init init_cyrix(struct cpuinfo_x86 *c) printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); isa_dma_bridge_buggy = 2; - - +#endif + c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ + /* * The 5510/5520 companion chips have a funky PIT. */ if (pci_dev_present(cyrix_55x0)) pit_latch_buggy = 1; -#endif - c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ /* GXm supports extended cpuid levels 'ala' AMD */ if (c->cpuid_level == 2) { @@ -354,7 +353,7 @@ static void __init init_nsc(struct cpuinfo_x86 *c) * This function only handles the GX processor, and kicks every * thing else to the Cyrix init function above - that should * cover any processors that might have been branded differently - * after NSC acquired Cyrix. + * after NSC aquired Cyrix. * * If this breaks your GX1 horribly, please e-mail * info-linux@ldcmail.amd.com to tell us. diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index 10afc645c540..5386b29bb5a5 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -122,12 +122,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) select_idle_routine(c); l2 = init_intel_cacheinfo(c); - if (c->cpuid_level > 9 ) { - unsigned eax = cpuid_eax(10); - /* Check for version and the number of counters */ - if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) - set_bit(X86_FEATURE_ARCH_PERFMON, c->x86_capability); - } /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) diff --git a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c index e9f0b928b0a9..c8547a6fa7e6 100644 --- a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -4,7 +4,6 @@ * Changes: * Venkatesh Pallipadi : Adding cache identification through cpuid(4) * Ashok Raj : Work with CPU hotplug infrastructure. - * Andi Kleen : CPUID4 emulation on AMD. */ #include @@ -131,111 +130,25 @@ struct _cpuid4_info { cpumask_t shared_cpu_map; }; -unsigned short num_cache_leaves; - -/* AMD doesn't have CPUID4. Emulate it here to report the same - information to the user. This makes some assumptions about the machine: - No L3, L2 not shared, no SMT etc. that is currently true on AMD CPUs. - - In theory the TLBs could be reported as fake type (they are in "dummy"). - Maybe later */ -union l1_cache { - struct { - unsigned line_size : 8; - unsigned lines_per_tag : 8; - unsigned assoc : 8; - unsigned size_in_kb : 8; - }; - unsigned val; -}; - -union l2_cache { - struct { - unsigned line_size : 8; - unsigned lines_per_tag : 4; - unsigned assoc : 4; - unsigned size_in_kb : 16; - }; - unsigned val; -}; - -static const unsigned short assocs[] = { - [1] = 1, [2] = 2, [4] = 4, [6] = 8, - [8] = 16, - [0xf] = 0xffff // ?? - }; -static const unsigned char levels[] = { 1, 1, 2 }; -static const unsigned char types[] = { 1, 2, 3 }; - -static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, - union _cpuid4_leaf_ebx *ebx, - union _cpuid4_leaf_ecx *ecx) -{ - unsigned dummy; - unsigned line_size, lines_per_tag, assoc, size_in_kb; - union l1_cache l1i, l1d; - union l2_cache l2; - - eax->full = 0; - ebx->full = 0; - ecx->full = 0; - - cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val); - cpuid(0x80000006, &dummy, &dummy, &l2.val, &dummy); - - if (leaf > 2 || !l1d.val || !l1i.val || !l2.val) - return; - - eax->split.is_self_initializing = 1; - eax->split.type = types[leaf]; - eax->split.level = levels[leaf]; - eax->split.num_threads_sharing = 0; - eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; - - if (leaf <= 1) { - union l1_cache *l1 = leaf == 0 ? &l1d : &l1i; - assoc = l1->assoc; - line_size = l1->line_size; - lines_per_tag = l1->lines_per_tag; - size_in_kb = l1->size_in_kb; - } else { - assoc = l2.assoc; - line_size = l2.line_size; - lines_per_tag = l2.lines_per_tag; - /* cpu_data has errata corrections for K7 applied */ - size_in_kb = current_cpu_data.x86_cache_size; - } - - if (assoc == 0xf) - eax->split.is_fully_associative = 1; - ebx->split.coherency_line_size = line_size - 1; - ebx->split.ways_of_associativity = assocs[assoc] - 1; - ebx->split.physical_line_partition = lines_per_tag - 1; - ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / - (ebx->split.ways_of_associativity + 1) - 1; -} +static unsigned short num_cache_leaves; static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) { - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; - unsigned edx; + unsigned int eax, ebx, ecx, edx; + union _cpuid4_leaf_eax cache_eax; - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) - amd_cpuid4(index, &eax, &ebx, &ecx); - else - cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); - if (eax.split.type == CACHE_TYPE_NULL) + cpuid_count(4, index, &eax, &ebx, &ecx, &edx); + cache_eax.full = eax; + if (cache_eax.split.type == CACHE_TYPE_NULL) return -EIO; /* better error ? */ - this_leaf->eax = eax; - this_leaf->ebx = ebx; - this_leaf->ecx = ecx; - this_leaf->size = (ecx.split.number_of_sets + 1) * - (ebx.split.coherency_line_size + 1) * - (ebx.split.physical_line_partition + 1) * - (ebx.split.ways_of_associativity + 1); + this_leaf->eax.full = eax; + this_leaf->ebx.full = ebx; + this_leaf->ecx.full = ecx; + this_leaf->size = (this_leaf->ecx.split.number_of_sets + 1) * + (this_leaf->ebx.split.coherency_line_size + 1) * + (this_leaf->ebx.split.physical_line_partition + 1) * + (this_leaf->ebx.split.ways_of_associativity + 1); return 0; } @@ -261,7 +174,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); #endif @@ -383,14 +296,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) if (new_l2) { l2 = new_l2; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP cpu_llc_id[cpu] = l2_id; #endif } if (new_l3) { l3 = new_l3; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP cpu_llc_id[cpu] = l3_id; #endif } @@ -729,7 +642,7 @@ static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) return; } -static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, +static int cacheinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -747,7 +660,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = +static struct notifier_block cacheinfo_cpu_notifier = { .notifier_call = cacheinfo_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index f54a15268ed7..f94cdb7aca50 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -18,7 +18,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) * applications want to get the raw CPUID data, they should access * /dev/cpu//cpuid instead. */ - static const char * const x86_cap_flags[] = { + static char *x86_cap_flags[] = { /* Intel-defined */ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", @@ -52,7 +52,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* VIA/Cyrix/Centaur-defined */ NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", - "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -62,7 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; - static const char * const x86_power_flags[] = { + static char *x86_power_flags[] = { "ts", /* temperature sensor */ "fid", /* frequency id control */ "vid", /* voltage id control */ @@ -109,9 +109,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); #ifdef CONFIG_X86_HT if (c->x86_max_cores * smp_num_siblings > 1) { - seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); + seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]); seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n])); - seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); + seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } #endif diff --git a/trunk/arch/i386/kernel/cpuid.c b/trunk/arch/i386/kernel/cpuid.c index f6dfa9fb675c..1d9a4abcdfc7 100644 --- a/trunk/arch/i386/kernel/cpuid.c +++ b/trunk/arch/i386/kernel/cpuid.c @@ -183,7 +183,7 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier = +static struct notifier_block cpuid_class_cpu_notifier = { .notifier_call = cpuid_class_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 48f0f62f781c..2b0cfce24a61 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -114,15 +114,19 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ halt(); - for (;;) - cpu_relax(); + for(;;); return 1; } +/* + * By using the NMI code instead of a vector we just sneak thru the + * word generator coming out with just what we want. AND it does + * not matter if clustered_apic_mode is set or not. + */ static void smp_send_nmi_allbutself(void) { - send_IPI_allbutself(NMI_VECTOR); + send_IPI_allbutself(APIC_DM_NMI); } static void nmi_shootdown_cpus(void) @@ -158,7 +162,7 @@ static void nmi_shootdown_cpus(void) void machine_crash_shutdown(struct pt_regs *regs) { /* This function is only called after the system - * has panicked or is otherwise in a critical state. + * has paniced or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * diff --git a/trunk/arch/i386/kernel/doublefault.c b/trunk/arch/i386/kernel/doublefault.c index b4d14c2eb345..5edb1d379add 100644 --- a/trunk/arch/i386/kernel/doublefault.c +++ b/trunk/arch/i386/kernel/doublefault.c @@ -44,8 +44,7 @@ static void doublefault_fn(void) } } - for (;;) - cpu_relax(); + for (;;) /* nothing */; } struct tss_struct doublefault_tss __cacheline_aligned = { diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index fbdb933251b6..cfc683f153b9 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -48,7 +48,6 @@ #include #include #include -#include #include "irq_vectors.h" #define nr_syscalls ((syscall_table_size)/4) @@ -83,76 +82,34 @@ VM_MASK = 0x00020000 #define resume_kernel restore_nocheck #endif -#ifdef CONFIG_VM86 -#define resume_userspace_sig check_userspace -#else -#define resume_userspace_sig resume_userspace -#endif - #define SAVE_ALL \ cld; \ pushl %es; \ - CFI_ADJUST_CFA_OFFSET 4;\ - /*CFI_REL_OFFSET es, 0;*/\ pushl %ds; \ - CFI_ADJUST_CFA_OFFSET 4;\ - /*CFI_REL_OFFSET ds, 0;*/\ pushl %eax; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET eax, 0;\ pushl %ebp; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET ebp, 0;\ pushl %edi; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET edi, 0;\ pushl %esi; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET esi, 0;\ pushl %edx; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET edx, 0;\ pushl %ecx; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET ecx, 0;\ pushl %ebx; \ - CFI_ADJUST_CFA_OFFSET 4;\ - CFI_REL_OFFSET ebx, 0;\ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; #define RESTORE_INT_REGS \ popl %ebx; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE ebx;\ popl %ecx; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE ecx;\ popl %edx; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE edx;\ popl %esi; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE esi;\ popl %edi; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE edi;\ popl %ebp; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE ebp;\ - popl %eax; \ - CFI_ADJUST_CFA_OFFSET -4;\ - CFI_RESTORE eax + popl %eax #define RESTORE_REGS \ RESTORE_INT_REGS; \ 1: popl %ds; \ - CFI_ADJUST_CFA_OFFSET -4;\ - /*CFI_RESTORE ds;*/\ 2: popl %es; \ - CFI_ADJUST_CFA_OFFSET -4;\ - /*CFI_RESTORE es;*/\ .section .fixup,"ax"; \ 3: movl $0,(%esp); \ jmp 1b; \ @@ -165,43 +122,13 @@ VM_MASK = 0x00020000 .long 2b,4b; \ .previous -#define RING0_INT_FRAME \ - CFI_STARTPROC simple;\ - CFI_DEF_CFA esp, 3*4;\ - /*CFI_OFFSET cs, -2*4;*/\ - CFI_OFFSET eip, -3*4 - -#define RING0_EC_FRAME \ - CFI_STARTPROC simple;\ - CFI_DEF_CFA esp, 4*4;\ - /*CFI_OFFSET cs, -2*4;*/\ - CFI_OFFSET eip, -3*4 - -#define RING0_PTREGS_FRAME \ - CFI_STARTPROC simple;\ - CFI_DEF_CFA esp, OLDESP-EBX;\ - /*CFI_OFFSET cs, CS-OLDESP;*/\ - CFI_OFFSET eip, EIP-OLDESP;\ - /*CFI_OFFSET es, ES-OLDESP;*/\ - /*CFI_OFFSET ds, DS-OLDESP;*/\ - CFI_OFFSET eax, EAX-OLDESP;\ - CFI_OFFSET ebp, EBP-OLDESP;\ - CFI_OFFSET edi, EDI-OLDESP;\ - CFI_OFFSET esi, ESI-OLDESP;\ - CFI_OFFSET edx, EDX-OLDESP;\ - CFI_OFFSET ecx, ECX-OLDESP;\ - CFI_OFFSET ebx, EBX-OLDESP ENTRY(ret_from_fork) - CFI_STARTPROC pushl %eax - CFI_ADJUST_CFA_OFFSET -4 call schedule_tail GET_THREAD_INFO(%ebp) popl %eax - CFI_ADJUST_CFA_OFFSET -4 jmp syscall_exit - CFI_ENDPROC /* * Return to user mode is not as complex as all this looks, @@ -212,12 +139,10 @@ ENTRY(ret_from_fork) # userspace resumption stub bypassing syscall exit tracing ALIGN - RING0_PTREGS_FRAME ret_from_exception: preempt_stop ret_from_intr: GET_THREAD_INFO(%ebp) -check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al testl $(VM_MASK | 3), %eax @@ -246,38 +171,20 @@ need_resched: call preempt_schedule_irq jmp need_resched #endif - CFI_ENDPROC /* SYSENTER_RETURN points to after the "sysenter" instruction in the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ # sysenter call handler stub ENTRY(sysenter_entry) - CFI_STARTPROC simple - CFI_DEF_CFA esp, 0 - CFI_REGISTER esp, ebp movl TSS_sysenter_esp0(%esp),%esp sysenter_past_esp: sti pushl $(__USER_DS) - CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET ss, 0*/ pushl %ebp - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esp, 0 pushfl - CFI_ADJUST_CFA_OFFSET 4 pushl $(__USER_CS) - CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET cs, 0*/ - /* - * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. - */ - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET eip, 0 + pushl $SYSENTER_RETURN /* * Load the potential sixth argument from user stack. @@ -292,7 +199,6 @@ sysenter_past_esp: .previous pushl %eax - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) @@ -313,14 +219,11 @@ sysenter_past_esp: xorl %ebp,%ebp sti sysexit - CFI_ENDPROC # system call handler stub ENTRY(system_call) - RING0_INT_FRAME # can't unwind into user space anyway pushl %eax # save orig_eax - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) testl $TF_MASK,EFLAGS(%esp) @@ -353,12 +256,10 @@ restore_all: movb CS(%esp), %al andl $(VM_MASK | (4 << 8) | 3), %eax cmpl $((4 << 8) | 3), %eax - CFI_REMEMBER_STATE je ldt_ss # returning to user-space with LDT SS restore_nocheck: RESTORE_REGS addl $4, %esp - CFI_ADJUST_CFA_OFFSET -4 1: iret .section .fixup,"ax" iret_exc: @@ -372,7 +273,6 @@ iret_exc: .long 1b,iret_exc .previous - CFI_RESTORE_STATE ldt_ss: larl OLDSS(%esp), %eax jnz restore_nocheck @@ -385,13 +285,11 @@ ldt_ss: * CPUs, which we can try to work around to make * dosemu and wine happy. */ subl $8, %esp # reserve space for switch16 pointer - CFI_ADJUST_CFA_OFFSET 8 cli movl %esp, %eax /* Set up the 16bit stack frame with switch32 pointer on top, * and a switch16 pointer on top of the current frame. */ call setup_x86_bogus_stack - CFI_ADJUST_CFA_OFFSET -8 # frame has moved RESTORE_REGS lss 20+4(%esp), %esp # switch to 16bit stack 1: iret @@ -399,11 +297,9 @@ ldt_ss: .align 4 .long 1b,iret_exc .previous - CFI_ENDPROC # perform work that needs to be done immediately before resumption ALIGN - RING0_PTREGS_FRAME # can't unwind into user space anyway work_pending: testb $_TIF_NEED_RESCHED, %cl jz work_notifysig @@ -427,20 +323,18 @@ work_notifysig: # deal with pending signals and # vm86-space xorl %edx, %edx call do_notify_resume - jmp resume_userspace_sig + jmp resume_userspace ALIGN work_notifysig_v86: #ifdef CONFIG_VM86 pushl %ecx # save ti_flags for do_notify_resume - CFI_ADJUST_CFA_OFFSET 4 call save_v86_state # %eax contains pt_regs pointer popl %ecx - CFI_ADJUST_CFA_OFFSET -4 movl %eax, %esp xorl %edx, %edx call do_notify_resume - jmp resume_userspace_sig + jmp resume_userspace #endif # perform syscall exit tracing @@ -469,21 +363,19 @@ syscall_exit_work: movl $1, %edx call do_syscall_trace jmp resume_userspace - CFI_ENDPROC - RING0_INT_FRAME # can't unwind into user space anyway + ALIGN syscall_fault: pushl %eax # save orig_eax - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) movl $-EFAULT,EAX(%esp) jmp resume_userspace + ALIGN syscall_badsys: movl $-ENOSYS,EAX(%esp) jmp resume_userspace - CFI_ENDPROC #define FIXUP_ESPFIX_STACK \ movl %esp, %eax; \ @@ -495,21 +387,16 @@ syscall_badsys: movl %eax, %esp; #define UNWIND_ESPFIX_STACK \ pushl %eax; \ - CFI_ADJUST_CFA_OFFSET 4; \ movl %ss, %eax; \ /* see if on 16bit stack */ \ cmpw $__ESPFIX_SS, %ax; \ - je 28f; \ -27: popl %eax; \ - CFI_ADJUST_CFA_OFFSET -4; \ -.section .fixup,"ax"; \ -28: movl $__KERNEL_DS, %eax; \ - movl %eax, %ds; \ - movl %eax, %es; \ + jne 28f; \ + movl $__KERNEL_DS, %edx; \ + movl %edx, %ds; \ + movl %edx, %es; \ /* switch to 32bit stack */ \ - FIXUP_ESPFIX_STACK; \ - jmp 27b; \ -.previous + FIXUP_ESPFIX_STACK \ +28: popl %eax; /* * Build the entry stubs and pointer table with @@ -521,14 +408,9 @@ ENTRY(interrupt) vector=0 ENTRY(irq_entries_start) - RING0_INT_FRAME .rept NR_IRQS ALIGN - .if vector - CFI_ADJUST_CFA_OFFSET -4 - .endif -1: pushl $~(vector) - CFI_ADJUST_CFA_OFFSET 4 +1: pushl $vector-256 jmp common_interrupt .data .long 1b @@ -542,99 +424,60 @@ common_interrupt: movl %esp,%eax call do_IRQ jmp ret_from_intr - CFI_ENDPROC #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ - RING0_INT_FRAME; \ - pushl $~(nr); \ - CFI_ADJUST_CFA_OFFSET 4; \ - SAVE_ALL; \ + pushl $nr-256; \ + SAVE_ALL \ movl %esp,%eax; \ call smp_/**/name; \ - jmp ret_from_intr; \ - CFI_ENDPROC + jmp ret_from_intr; /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" ENTRY(divide_error) - RING0_INT_FRAME pushl $0 # no error code - CFI_ADJUST_CFA_OFFSET 4 pushl $do_divide_error - CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: pushl %ds - CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET ds, 0*/ pushl %eax - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET eax, 0 xorl %eax, %eax pushl %ebp - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebp, 0 pushl %edi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edi, 0 pushl %esi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esi, 0 pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx, 0 decl %eax # eax = -1 pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx, 0 pushl %ebx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebx, 0 cld pushl %es - CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET es, 0*/ UNWIND_ESPFIX_STACK popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - /*CFI_REGISTER es, ecx*/ movl ES(%esp), %edi # get the function address movl ORIG_EAX(%esp), %edx # get the error code movl %eax, ORIG_EAX(%esp) movl %ecx, ES(%esp) - /*CFI_REL_OFFSET es, ES*/ movl $(__USER_DS), %ecx movl %ecx, %ds movl %ecx, %es movl %esp,%eax # pt_regs pointer call *%edi jmp ret_from_exception - CFI_ENDPROC ENTRY(coprocessor_error) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_coprocessor_error - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(simd_coprocessor_error) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_simd_coprocessor_error - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(device_not_available) - RING0_INT_FRAME pushl $-1 # mark this as an int - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL movl %cr0, %eax testl $0x4, %eax # EM (math emulation bit) @@ -644,12 +487,9 @@ ENTRY(device_not_available) jmp ret_from_exception device_not_available_emulate: pushl $0 # temporary storage for ORIG_EIP - CFI_ADJUST_CFA_OFFSET 4 call math_emulate addl $4, %esp - CFI_ADJUST_CFA_OFFSET -4 jmp ret_from_exception - CFI_ENDPROC /* * Debug traps and NMI can happen at the one SYSENTER instruction @@ -674,19 +514,16 @@ label: \ pushl $sysenter_past_esp KPROBE_ENTRY(debug) - RING0_INT_FRAME cmpl $sysenter_entry,(%esp) jne debug_stack_correct FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) debug_stack_correct: pushl $-1 # mark this as an int - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # error code 0 movl %esp,%eax # pt_regs pointer call do_debug jmp ret_from_exception - CFI_ENDPROC .previous .text /* * NMI is doubly nasty. It can happen _while_ we're handling @@ -697,18 +534,14 @@ debug_stack_correct: * fault happened on the sysenter path. */ ENTRY(nmi) - RING0_INT_FRAME pushl %eax - CFI_ADJUST_CFA_OFFSET 4 movl %ss, %eax cmpw $__ESPFIX_SS, %ax popl %eax - CFI_ADJUST_CFA_OFFSET -4 je nmi_16bit_stack cmpl $sysenter_entry,(%esp) je nmi_stack_fixup pushl %eax - CFI_ADJUST_CFA_OFFSET 4 movl %esp,%eax /* Do not access memory above the end of our stack page, * it might not exist. @@ -716,19 +549,16 @@ ENTRY(nmi) andl $(THREAD_SIZE-1),%eax cmpl $(THREAD_SIZE-20),%eax popl %eax - CFI_ADJUST_CFA_OFFSET -4 jae nmi_stack_correct cmpl $sysenter_entry,12(%esp) je nmi_debug_stack_check nmi_stack_correct: pushl %eax - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_nmi jmp restore_all - CFI_ENDPROC nmi_stack_fixup: FIX_STACK(12,nmi_stack_correct, 1) @@ -744,177 +574,94 @@ nmi_debug_stack_check: jmp nmi_stack_correct nmi_16bit_stack: - RING0_INT_FRAME /* create the pointer to lss back */ pushl %ss - CFI_ADJUST_CFA_OFFSET 4 pushl %esp - CFI_ADJUST_CFA_OFFSET 4 movzwl %sp, %esp addw $4, (%esp) /* copy the iret frame of 12 bytes */ .rept 3 pushl 16(%esp) - CFI_ADJUST_CFA_OFFSET 4 .endr pushl %eax - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL FIXUP_ESPFIX_STACK # %eax == %esp - CFI_ADJUST_CFA_OFFSET -20 # the frame has now moved xorl %edx,%edx # zero error code call do_nmi RESTORE_REGS lss 12+4(%esp), %esp # back to 16bit stack 1: iret - CFI_ENDPROC .section __ex_table,"a" .align 4 .long 1b,iret_exc .previous KPROBE_ENTRY(int3) - RING0_INT_FRAME pushl $-1 # mark this as an int - CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # zero error code movl %esp,%eax # pt_regs pointer call do_int3 jmp ret_from_exception - CFI_ENDPROC .previous .text ENTRY(overflow) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_overflow - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(bounds) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_bounds - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(invalid_op) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_invalid_op - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(coprocessor_segment_overrun) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_coprocessor_segment_overrun - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(invalid_TSS) - RING0_EC_FRAME pushl $do_invalid_TSS - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(segment_not_present) - RING0_EC_FRAME pushl $do_segment_not_present - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC ENTRY(stack_segment) - RING0_EC_FRAME pushl $do_stack_segment - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC KPROBE_ENTRY(general_protection) - RING0_EC_FRAME pushl $do_general_protection - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC .previous .text ENTRY(alignment_check) - RING0_EC_FRAME pushl $do_alignment_check - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC KPROBE_ENTRY(page_fault) - RING0_EC_FRAME pushl $do_page_fault - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC .previous .text #ifdef CONFIG_X86_MCE ENTRY(machine_check) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl machine_check_vector - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC #endif ENTRY(spurious_interrupt_bug) - RING0_INT_FRAME pushl $0 - CFI_ADJUST_CFA_OFFSET 4 pushl $do_spurious_interrupt_bug - CFI_ADJUST_CFA_OFFSET 4 jmp error_code - CFI_ENDPROC - -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movl 4(%esp), %edx - movl (%esp), %ecx - leal 4(%esp), %eax - movl %ebx, EBX(%edx) - xorl %ebx, %ebx - movl %ebx, ECX(%edx) - movl %ebx, EDX(%edx) - movl %esi, ESI(%edx) - movl %edi, EDI(%edx) - movl %ebp, EBP(%edx) - movl %ebx, EAX(%edx) - movl $__USER_DS, DS(%edx) - movl $__USER_DS, ES(%edx) - movl %ebx, ORIG_EAX(%edx) - movl %ecx, EIP(%edx) - movl 12(%esp), %ecx - movl $__KERNEL_CS, CS(%edx) - movl %ebx, EFLAGS(%edx) - movl %eax, OLDESP(%edx) - movl 8(%esp), %eax - movl %ecx, 8(%esp) - movl EBX(%edx), %ebx - movl $__KERNEL_DS, OLDSS(%edx) - jmpl *%eax - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif .section .rodata,"a" #include "syscall_table.S" diff --git a/trunk/arch/i386/kernel/hpet.c b/trunk/arch/i386/kernel/hpet.c deleted file mode 100644 index c6737c35815d..000000000000 --- a/trunk/arch/i386/kernel/hpet.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#define HPET_MASK CLOCKSOURCE_MASK(32) -#define HPET_SHIFT 22 - -/* FSEC = 10^-15 NSEC = 10^-9 */ -#define FSEC_PER_NSEC 1000000 - -static void *hpet_ptr; - -static cycle_t read_hpet(void) -{ - return (cycle_t)readl(hpet_ptr); -} - -static struct clocksource clocksource_hpet = { - .name = "hpet", - .rating = 250, - .read = read_hpet, - .mask = HPET_MASK, - .mult = 0, /* set below */ - .shift = HPET_SHIFT, - .is_continuous = 1, -}; - -static int __init init_hpet_clocksource(void) -{ - unsigned long hpet_period; - void __iomem* hpet_base; - u64 tmp; - - if (!hpet_address) - return -ENODEV; - - /* calculate the hpet address: */ - hpet_base = - (void __iomem*)ioremap_nocache(hpet_address, HPET_MMAP_SIZE); - hpet_ptr = hpet_base + HPET_COUNTER; - - /* calculate the frequency: */ - hpet_period = readl(hpet_base + HPET_PERIOD); - - /* - * hpet period is in femto seconds per cycle - * so we need to convert this to ns/cyc units - * aproximated by mult/2^shift - * - * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift - * fsec/cyc * 1ns/1000000fsec * 2^shift = mult - * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult - * (fsec/cyc << shift)/1000000 = mult - * (hpet_period << shift)/FSEC_PER_NSEC = mult - */ - tmp = (u64)hpet_period << HPET_SHIFT; - do_div(tmp, FSEC_PER_NSEC); - clocksource_hpet.mult = (u32)tmp; - - return clocksource_register(&clocksource_hpet); -} - -module_init(init_hpet_clocksource); diff --git a/trunk/arch/i386/kernel/i387.c b/trunk/arch/i386/kernel/i387.c index c4351972d9af..d75524758daf 100644 --- a/trunk/arch/i386/kernel/i387.c +++ b/trunk/arch/i386/kernel/i387.c @@ -25,7 +25,7 @@ #define HAVE_HWFP 1 #endif -static unsigned long mxcsr_feature_mask __read_mostly = 0xffffffff; +static unsigned long mxcsr_feature_mask = 0xffffffff; void mxcsr_feature_mask_init(void) { diff --git a/trunk/arch/i386/kernel/i8253.c b/trunk/arch/i386/kernel/i8253.c deleted file mode 100644 index 477b24daff53..000000000000 --- a/trunk/arch/i386/kernel/i8253.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * i8253.c 8253/PIT functions - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "io_ports.h" - -DEFINE_SPINLOCK(i8253_lock); -EXPORT_SYMBOL(i8253_lock); - -void setup_pit_timer(void) -{ - unsigned long flags; - - spin_lock_irqsave(&i8253_lock, flags); - outb_p(0x34,PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ - udelay(10); - outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ - udelay(10); - outb(LATCH >> 8 , PIT_CH0); /* MSB */ - spin_unlock_irqrestore(&i8253_lock, flags); -} - -/* - * Since the PIT overflows every tick, its not very useful - * to just read by itself. So use jiffies to emulate a free - * running counter: - */ -static cycle_t pit_read(void) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - spin_lock_irqsave(&i8253_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb_p(PIT_CH0) << 8; - - /* VIA686a test code... reset the latch if count > max + 1 */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; - } - - /* - * It's possible for count to appear to go the wrong way for a - * couple of reasons: - * - * 1. The timer counter underflows, but we haven't handled the - * resulting interrupt and incremented jiffies yet. - * 2. Hardware problem with the timer, not giving us continuous time, - * the counter does small "jumps" upwards on some Pentium systems, - * (see c't 95/10 page 335 for Neptun bug.) - * - * Previous attempts to handle these cases intelligently were - * buggy, so we just do the simple thing now. - */ - if (count > old_count && jifs == old_jifs) { - count = old_count; - } - old_count = count; - old_jifs = jifs; - - spin_unlock_irqrestore(&i8253_lock, flags); - - count = (LATCH - 1) - count; - - return (cycle_t)(jifs * LATCH) + count; -} - -static struct clocksource clocksource_pit = { - .name = "pit", - .rating = 110, - .read = pit_read, - .mask = CLOCKSOURCE_MASK(32), - .mult = 0, - .shift = 20, -}; - -static int __init init_pit_clocksource(void) -{ - if (num_possible_cpus() > 4) /* PIT does not scale! */ - return 0; - - clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); - return clocksource_register(&clocksource_pit); -} -module_init(init_pit_clocksource); diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index c1a42feba286..323ef8ab3244 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -175,7 +175,7 @@ static void mask_and_ack_8259A(unsigned int irq) * Lightweight spurious IRQ detection. We do not want * to overdo spurious IRQ handling - it's usually a sign * of hardware problems, so we only do the checks we can - * do without slowing down good hardware unnecessarily. + * do without slowing down good hardware unnecesserily. * * Note that IRQ7 and IRQ15 (the two spurious IRQs * usually resulting from the 8259A-1|2 PICs) occur @@ -271,8 +271,8 @@ static int i8259A_shutdown(struct sys_device *dev) * the kernel initialization code can get it * out of. */ - outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ - outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ + outb(0xff, 0x21); /* mask all of 8259A-1 */ + outb(0xff, 0xA1); /* mask all of 8259A-1 */ return 0; } diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index 72ae414e4d49..d70f2ade5cde 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -38,7 +38,6 @@ #include #include #include -#include #include @@ -51,7 +50,6 @@ atomic_t irq_mis_count; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); int timer_over_8254 __initdata = 1; @@ -269,7 +267,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) # include /* kmalloc() */ # include /* time_after() */ -#ifdef CONFIG_BALANCED_IRQ_DEBUG +# ifdef CONFIG_BALANCED_IRQ_DEBUG # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) # define Dprintk(x...) do { TDprintk(x); } while (0) # else @@ -277,15 +275,10 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) # define Dprintk(x...) # endif -#define IRQBALANCE_CHECK_ARCH -999 -#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) -#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) -#define BALANCED_IRQ_MORE_DELTA (HZ/10) -#define BALANCED_IRQ_LESS_DELTA (HZ) -static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH; -static int physical_balance __read_mostly; -static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; +#define IRQBALANCE_CHECK_ARCH -999 +static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; +static int physical_balance = 0; static struct irq_cpu_info { unsigned long * last_irq; @@ -304,14 +297,12 @@ static struct irq_cpu_info { #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) -static cpumask_t balance_irq_affinity[NR_IRQS] = { - [0 ... NR_IRQS-1] = CPU_MASK_ALL -}; +#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) +#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) +#define BALANCED_IRQ_MORE_DELTA (HZ/10) +#define BALANCED_IRQ_LESS_DELTA (HZ) -void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) -{ - balance_irq_affinity[irq] = mask; -} +static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; static unsigned long move(int curr_cpu, cpumask_t allowed_mask, unsigned long now, int direction) @@ -349,7 +340,7 @@ static inline void balance_irq(int cpu, int irq) if (irqbalance_disabled) return; - cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); + cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); new_cpu = move(cpu, allowed_mask, now, 1); if (cpu != new_cpu) { set_pending_irq(irq, cpumask_of_cpu(new_cpu)); @@ -538,9 +529,7 @@ static void do_irq_balance(void) } } - cpus_and(allowed_mask, - cpu_online_map, - balance_irq_affinity[selected_irq]); + cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); target_cpu_mask = cpumask_of_cpu(min_loaded); cpus_and(tmp, target_cpu_mask, allowed_mask); @@ -1163,17 +1152,10 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; int assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - unsigned long flags; - int vector; - - BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); - spin_lock_irqsave(&vector_lock, flags); - - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { - spin_unlock_irqrestore(&vector_lock, flags); + BUG_ON(irq >= NR_IRQ_VECTORS); + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); - } next: current_vector += 8; if (current_vector == SYSCALL_VECTOR) @@ -1181,21 +1163,16 @@ int assign_irq_vector(int irq) if (current_vector >= FIRST_SYSTEM_VECTOR) { offset++; - if (!(offset%8)) { - spin_unlock_irqrestore(&vector_lock, flags); + if (!(offset%8)) return -ENOSPC; - } current_vector = FIRST_DEVICE_VECTOR + offset; } - vector = current_vector; - vector_irq[vector] = irq; + vector_irq[current_vector] = irq; if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = vector; + IO_APIC_VECTOR(irq) = current_vector; - spin_unlock_irqrestore(&vector_lock, flags); - - return vector; + return current_vector; } static struct hw_interrupt_type ioapic_level_type; @@ -1207,14 +1184,21 @@ static struct hw_interrupt_type ioapic_edge_type; static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - unsigned idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; - - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[idx].handler = &ioapic_level_type; - else - irq_desc[idx].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[idx]); + if (use_pci_vector() && !platform_legacy_irq(irq)) { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[vector].handler = &ioapic_level_type; + else + irq_desc[vector].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[vector]); + } else { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[irq].handler = &ioapic_level_type; + else + irq_desc[irq].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[irq]); + } } static void __init setup_IO_APIC_irqs(void) diff --git a/trunk/arch/i386/kernel/irq.c b/trunk/arch/i386/kernel/irq.c index c703bc7b0880..f3a9c78c4a24 100644 --- a/trunk/arch/i386/kernel/irq.c +++ b/trunk/arch/i386/kernel/irq.c @@ -42,8 +42,8 @@ union irq_ctx { u32 stack[THREAD_SIZE/sizeof(u32)]; }; -static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; -static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; +static union irq_ctx *hardirq_ctx[NR_CPUS]; +static union irq_ctx *softirq_ctx[NR_CPUS]; #endif /* @@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; */ fastcall unsigned int do_IRQ(struct pt_regs *regs) { - /* high bit used in ret_from_ code */ - int irq = ~regs->orig_eax; + /* high bits used in ret_from_ code */ + int irq = regs->orig_eax & 0xff; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; @@ -95,14 +95,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) irqctx->tinfo.task = curctx->tinfo.task; irqctx->tinfo.previous_esp = current_stack_pointer; - /* - * Copy the softirq bits in preempt_count so that the - * softirq checks work in the hardirq context. - */ - irqctx->tinfo.preempt_count = - (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | - (curctx->tinfo.preempt_count & SOFTIRQ_MASK); - asm volatile( " xchgl %%ebx,%%esp \n" " call __do_IRQ \n" @@ -227,7 +219,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); for_each_online_cpu(j) - seq_printf(p, "CPU%-8d",j); + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); } diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index 727e419ad78a..38806f427849 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -57,85 +57,34 @@ static __always_inline void set_jmp_op(void *from, void *to) /* * returns non-zero if opcodes can be boosted. */ -static __always_inline int can_boost(kprobe_opcode_t *opcodes) +static __always_inline int can_boost(kprobe_opcode_t opcode) { -#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ - (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ - (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \ - (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \ - (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \ - << (row % 32)) - /* - * Undefined/reserved opcodes, conditional jump, Opcode Extension - * Groups, and some special opcodes can not be boost. - */ - static const unsigned long twobyte_is_boostable[256 / 32] = { - /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ - /* ------------------------------- */ - W(0x00, 0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0)| /* 00 */ - W(0x10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 10 */ - W(0x20, 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0)| /* 20 */ - W(0x30, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 30 */ - W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 40 */ - W(0x50, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 50 */ - W(0x60, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1)| /* 60 */ - W(0x70, 0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1), /* 70 */ - W(0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 80 */ - W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 90 */ - W(0xa0, 1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,1)| /* a0 */ - W(0xb0, 1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1), /* b0 */ - W(0xc0, 1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1)| /* c0 */ - W(0xd0, 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1), /* d0 */ - W(0xe0, 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1)| /* e0 */ - W(0xf0, 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0) /* f0 */ - /* ------------------------------- */ - /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ - }; -#undef W - kprobe_opcode_t opcode; - kprobe_opcode_t *orig_opcodes = opcodes; -retry: - if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) - return 0; - opcode = *(opcodes++); - - /* 2nd-byte opcode */ - if (opcode == 0x0f) { - if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) - return 0; - return test_bit(*opcodes, twobyte_is_boostable); - } - - switch (opcode & 0xf0) { - case 0x60: - if (0x63 < opcode && opcode < 0x67) - goto retry; /* prefixes */ - /* can't boost Address-size override and bound */ - return (opcode != 0x62 && opcode != 0x67); + switch (opcode & 0xf0 ) { case 0x70: return 0; /* can't boost conditional jump */ + case 0x90: + /* can't boost call and pushf */ + return opcode != 0x9a && opcode != 0x9c; case 0xc0: - /* can't boost software-interruptions */ - return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; + /* can't boost undefined opcodes and soft-interruptions */ + return (0xc1 < opcode && opcode < 0xc6) || + (0xc7 < opcode && opcode < 0xcc) || opcode == 0xcf; case 0xd0: /* can boost AA* and XLAT */ return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); case 0xe0: - /* can boost in/out and absolute jmps */ - return ((opcode & 0x04) || opcode == 0xea); + /* can boost in/out and (may be) jmps */ + return (0xe3 < opcode && opcode != 0xe8); case 0xf0: - if ((opcode & 0x0c) == 0 && opcode != 0xf1) - goto retry; /* lock/rep(ne) prefix */ /* clear and set flags can be boost */ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); default: - if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) - goto retry; /* prefixes */ - /* can't boost CS override and call */ - return (opcode != 0x2e && opcode != 0x9a); + /* currently, can't boost 2 bytes opcodes */ + return opcode != 0x0f; } } + /* * returns non-zero if opcode modifies the interrupt flag. */ @@ -160,7 +109,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = *p->addr; - if (can_boost(p->addr)) { + if (can_boost(p->opcode)) { p->ainsn.boostable = 0; } else { p->ainsn.boostable = -1; @@ -259,9 +208,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) struct kprobe_ctlblk *kcb; #ifdef CONFIG_PREEMPT unsigned pre_preempt_count = preempt_count(); -#else - unsigned pre_preempt_count = 1; -#endif +#endif /* CONFIG_PREEMPT */ addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); @@ -338,14 +285,22 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) /* handler has already set things up, so skip ss setup */ return 1; -ss_probe: - if (pre_preempt_count && p->ainsn.boostable == 1 && !p->post_handler){ + if (p->ainsn.boostable == 1 && +#ifdef CONFIG_PREEMPT + !(pre_preempt_count) && /* + * This enables booster when the direct + * execution path aren't preempted. + */ +#endif /* CONFIG_PREEMPT */ + !p->post_handler && !p->break_handler ) { /* Boost up -- we can execute copied instructions directly */ reset_current_kprobe(); regs->eip = (unsigned long)p->ainsn.insn; preempt_enable_no_resched(); return 1; } + +ss_probe: prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1; @@ -652,7 +607,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; - if (args->regs && user_mode_vm(args->regs)) + if (args->regs && user_mode(args->regs)) return ret; switch (val) { diff --git a/trunk/arch/i386/kernel/machine_kexec.c b/trunk/arch/i386/kernel/machine_kexec.c index 511abe52a94e..f73d7374a2ba 100644 --- a/trunk/arch/i386/kernel/machine_kexec.c +++ b/trunk/arch/i386/kernel/machine_kexec.c @@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( unsigned long start_address, unsigned int has_pae) ATTRIB_NORET; -extern const unsigned char relocate_new_kernel[]; +const extern unsigned char relocate_new_kernel[]; extern void relocate_new_kernel_end(void); -extern const unsigned int relocate_new_kernel_size; +const extern unsigned int relocate_new_kernel_size; /* * A architecture hook called to validate the diff --git a/trunk/arch/i386/kernel/microcode.c b/trunk/arch/i386/kernel/microcode.c index 0a865889b2a9..e7c138f66c5a 100644 --- a/trunk/arch/i386/kernel/microcode.c +++ b/trunk/arch/i386/kernel/microcode.c @@ -91,10 +91,7 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); MODULE_AUTHOR("Tigran Aivazian "); MODULE_LICENSE("GPL"); -static int verbose; -module_param(verbose, int, 0644); - -#define MICROCODE_VERSION "1.14a" +#define MICROCODE_VERSION "1.14" #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ #define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ @@ -125,15 +122,14 @@ static unsigned int user_buffer_size; /* it's size */ typedef enum mc_error_code { MC_SUCCESS = 0, - MC_IGNORED = 1, - MC_NOTFOUND = 2, - MC_MARKED = 3, - MC_ALLOCATED = 4, + MC_NOTFOUND = 1, + MC_MARKED = 2, + MC_ALLOCATED = 3, } mc_error_code_t; static struct ucode_cpu_info { unsigned int sig; - unsigned int pf, orig_pf; + unsigned int pf; unsigned int rev; unsigned int cksum; mc_error_code_t err; @@ -168,7 +164,6 @@ static void collect_cpu_info (void *unused) rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); uci->pf = 1 << ((val[1] >> 18) & 7); } - uci->orig_pf = uci->pf; } wrmsr(MSR_IA32_UCODE_REV, 0, 0); @@ -202,34 +197,21 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he pr_debug(" Checksum 0x%x\n", cksum); if (mc_header->rev < uci->rev) { - if (uci->err == MC_NOTFOUND) { - uci->err = MC_IGNORED; - uci->cksum = mc_header->rev; - } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev) - uci->cksum = mc_header->rev; + printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" + " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + goto out; } else if (mc_header->rev == uci->rev) { - if (uci->err < MC_MARKED) { - /* notify the caller of success on this cpu */ - uci->err = MC_SUCCESS; - } - } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) { - pr_debug("microcode: CPU%d found a matching microcode update with " - " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); - uci->cksum = cksum; - uci->pf = pf; /* keep the original mc pf for cksum calculation */ - uci->err = MC_MARKED; /* found the match */ - for_each_online_cpu(cpu_num) { - if (ucode_cpu_info + cpu_num != uci - && ucode_cpu_info[cpu_num].mc == uci->mc) { - uci->mc = NULL; - break; - } - } - if (uci->mc != NULL) { - vfree(uci->mc); - uci->mc = NULL; - } + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + goto out; } + + pr_debug("microcode: CPU%d found a matching microcode update with " + " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + uci->cksum = cksum; + uci->pf = pf; /* keep the original mc pf for cksum calculation */ + uci->err = MC_MARKED; /* found the match */ +out: return; } @@ -271,8 +253,10 @@ static int find_matching_ucodes (void) for_each_online_cpu(cpu_num) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; - if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) + if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf)) mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); } @@ -311,8 +295,9 @@ static int find_matching_ucodes (void) } for_each_online_cpu(cpu_num) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - - if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) { + if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ + continue; + if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) { mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); } } @@ -383,13 +368,6 @@ static void do_update_one (void * unused) struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; if (uci->mc == NULL) { - if (verbose) { - if (uci->err == MC_SUCCESS) - printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", - cpu_num, uci->rev); - else - printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); - } return; } @@ -448,9 +426,6 @@ static int do_microcode_update (void) ucode_cpu_info[j].mc = NULL; } } - if (ucode_cpu_info[i].err == MC_IGNORED && verbose) - printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision" - " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev); } out: return error; diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index d022cb8fd725..7a328230e540 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -266,7 +266,7 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long acti return NOTIFY_OK; } -static struct notifier_block __cpuinitdata msr_class_cpu_notifier = +static struct notifier_block msr_class_cpu_notifier = { .notifier_call = msr_class_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index a76e93146585..d43b498ec745 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -14,17 +14,21 @@ */ #include +#include #include +#include +#include #include +#include +#include #include #include #include #include -#include #include +#include #include -#include #include "mach_traps.h" @@ -96,9 +100,6 @@ int nmi_active; (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when * the CPU is idle. To make sure the NMI watchdog really ticks on all @@ -211,8 +212,6 @@ static int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); -static void disable_intel_arch_watchdog(void); - static void disable_lapic_nmi_watchdog(void) { if (nmi_active <= 0) @@ -222,10 +221,6 @@ static void disable_lapic_nmi_watchdog(void) wrmsr(MSR_K7_EVNTSEL0, 0, 0); break; case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - disable_intel_arch_watchdog(); - break; - } switch (boot_cpu_data.x86) { case 6: if (boot_cpu_data.x86_model > 0xd) @@ -454,53 +449,6 @@ static int setup_p4_watchdog(void) return 1; } -static void disable_intel_arch_watchdog(void) -{ - unsigned ebx; - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebp indicates event present. - */ - ebx = cpuid_ebx(10); - if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); -} - -static int setup_intel_arch_watchdog(void) -{ - unsigned int evntsel; - unsigned ebx; - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebp indicates event present. - */ - ebx = cpuid_ebx(10); - if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return 0; - - nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - - clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); - clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); - - evntsel = ARCH_PERFMON_EVENTSEL_INT - | ARCH_PERFMON_EVENTSEL_OS - | ARCH_PERFMON_EVENTSEL_USR - | ARCH_PERFMON_NMI_EVENT_SEL - | ARCH_PERFMON_NMI_EVENT_UMASK; - - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); - write_watchdog_counter("INTEL_ARCH_PERFCTR0"); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); - return 1; -} - void setup_apic_nmi_watchdog (void) { switch (boot_cpu_data.x86_vendor) { @@ -510,11 +458,6 @@ void setup_apic_nmi_watchdog (void) setup_k7_watchdog(); break; case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } switch (boot_cpu_data.x86) { case 6: if (boot_cpu_data.x86_model > 0xd) @@ -618,8 +561,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); } - else if (nmi_perfctr_msr == MSR_P6_PERFCTR0 || - nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + else if (nmi_perfctr_msr == MSR_P6_PERFCTR0) { /* Only P6 based Pentium M need to re-unmask * the apic vector but it doesn't hurt * other P6 variant */ diff --git a/trunk/arch/i386/kernel/numaq.c b/trunk/arch/i386/kernel/numaq.c index 0caf14652bad..5f5b075f860a 100644 --- a/trunk/arch/i386/kernel/numaq.c +++ b/trunk/arch/i386/kernel/numaq.c @@ -79,12 +79,10 @@ int __init get_memcfg_numaq(void) return 1; } -static int __init numaq_tsc_disable(void) +static int __init numaq_dsc_disable(void) { - if (num_online_nodes() > 1) { - printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); - tsc_disable = 1; - } + printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); + tsc_disable = 1; return 0; } -arch_initcall(numaq_tsc_disable); +core_initcall(numaq_dsc_disable); diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 6946b06e2784..6259afea46d1 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -102,7 +102,7 @@ void default_idle(void) local_irq_enable(); if (!hlt_counter && boot_cpu_data.hlt_works_ok) { - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); while (!need_resched()) { local_irq_disable(); @@ -111,7 +111,7 @@ void default_idle(void) else local_irq_enable(); } - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); } else { while (!need_resched()) cpu_relax(); @@ -174,7 +174,7 @@ void cpu_idle(void) { int cpu = smp_processor_id(); - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); /* endless idle loop with no priority at all */ while (1) { @@ -312,7 +312,7 @@ void show_regs(struct pt_regs * regs) cr3 = read_cr3(); cr4 = read_cr4_safe(); printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); - show_trace(NULL, regs, ®s->esp); + show_trace(NULL, ®s->esp); } /* diff --git a/trunk/arch/i386/kernel/scx200.c b/trunk/arch/i386/kernel/scx200.c index 9bf590cefc7d..321f5fd26e75 100644 --- a/trunk/arch/i386/kernel/scx200.c +++ b/trunk/arch/i386/kernel/scx200.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -46,19 +45,11 @@ static struct pci_driver scx200_pci_driver = { .probe = scx200_probe, }; -static DEFINE_MUTEX(scx200_gpio_config_lock); - -static void __devinit scx200_init_shadow(void) -{ - int bank; - - /* read the current values driven on the GPIO signals */ - for (bank = 0; bank < 2; ++bank) - scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); -} +static DEFINE_SPINLOCK(scx200_gpio_config_lock); static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + int bank; unsigned base; if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE || @@ -72,7 +63,10 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ } scx200_gpio_base = base; - scx200_init_shadow(); + + /* read the current values driven on the GPIO signals */ + for (bank = 0; bank < 2; ++bank) + scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); } else { /* find the base of the Configuration Block */ @@ -93,11 +87,12 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ return 0; } -u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits) +u32 scx200_gpio_configure(int index, u32 mask, u32 bits) { u32 config, new_config; + unsigned long flags; - mutex_lock(&scx200_gpio_config_lock); + spin_lock_irqsave(&scx200_gpio_config_lock, flags); outl(index, scx200_gpio_base + 0x20); config = inl(scx200_gpio_base + 0x24); @@ -105,11 +100,45 @@ u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits) new_config = (config & mask) | bits; outl(new_config, scx200_gpio_base + 0x24); - mutex_unlock(&scx200_gpio_config_lock); + spin_unlock_irqrestore(&scx200_gpio_config_lock, flags); return config; } +#if 0 +void scx200_gpio_dump(unsigned index) +{ + u32 config = scx200_gpio_configure(index, ~0, 0); + printk(KERN_DEBUG "GPIO%02u: 0x%08lx", index, (unsigned long)config); + + if (config & 1) + printk(" OE"); /* output enabled */ + else + printk(" TS"); /* tristate */ + if (config & 2) + printk(" PP"); /* push pull */ + else + printk(" OD"); /* open drain */ + if (config & 4) + printk(" PUE"); /* pull up enabled */ + else + printk(" PUD"); /* pull up disabled */ + if (config & 8) + printk(" LOCKED"); /* locked */ + if (config & 16) + printk(" LEVEL"); /* level input */ + else + printk(" EDGE"); /* edge input */ + if (config & 32) + printk(" HI"); /* trigger on rising edge */ + else + printk(" LO"); /* trigger on falling edge */ + if (config & 64) + printk(" DEBOUNCE"); /* debounce */ + printk("\n"); +} +#endif /* 0 */ + static int __init scx200_init(void) { printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n"); @@ -130,3 +159,10 @@ EXPORT_SYMBOL(scx200_gpio_base); EXPORT_SYMBOL(scx200_gpio_shadow); EXPORT_SYMBOL(scx200_gpio_configure); EXPORT_SYMBOL(scx200_cb_base); + +/* + Local variables: + compile-command: "make -k -C ../../.. SUBDIRS=arch/i386/kernel modules" + c-basic-offset: 8 + End: +*/ diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 4a65040cc624..dd6b0e3386ce 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include "setup_arch_pre.h" #include /* Forward Declaration. */ @@ -410,8 +410,8 @@ static void __init limit_regions(unsigned long long size) } } -void __init add_memory_region(unsigned long long start, - unsigned long long size, int type) +static void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) { int x; @@ -474,7 +474,7 @@ static struct change_member *change_point[2*E820MAX] __initdata; static struct e820entry *overlap_list[E820MAX] __initdata; static struct e820entry new_bios[E820MAX] __initdata; -int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) +static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) { struct change_member *change_tmp; unsigned long current_type, last_type; @@ -643,7 +643,7 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) * thinkpad 560x, for example, does not cooperate with the memory * detection code.) */ -int __init copy_e820_map(struct e820entry * biosmap, int nr_map) +static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) { /* Only one memory region (or negative)? Ignore it */ if (nr_map < 2) @@ -701,6 +701,12 @@ static inline void copy_edd(void) } #endif +/* + * Do NOT EVER look at the BIOS memory size location. + * It does not work on many machines. + */ +#define LOWMEMSIZE() (0x9f000) + static void __init parse_cmdline_early (char ** cmdline_p) { char c = ' ', *to = command_line, *from = saved_command_line; @@ -1417,6 +1423,8 @@ static void __init register_memory(void) pci_mem_start, gapstart, gapsize); } +static char * __init machine_specific_memory_setup(void); + #ifdef CONFIG_MCA static void set_mca_bus(int x) { @@ -1575,7 +1583,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif - tsc_init(); } static __init int add_pcspkr(void) @@ -1595,6 +1602,7 @@ static __init int add_pcspkr(void) } device_initcall(add_pcspkr); +#include "setup_arch_post.h" /* * Local Variables: * mode:c diff --git a/trunk/arch/i386/kernel/signal.c b/trunk/arch/i386/kernel/signal.c index 43002cfb40c4..5c352c3a9e7f 100644 --- a/trunk/arch/i386/kernel/signal.c +++ b/trunk/arch/i386/kernel/signal.c @@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, goto give_sigsegv; } - restorer = (void *)VDSO_SYM(&__kernel_sigreturn); + restorer = &__kernel_sigreturn; if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; @@ -447,7 +447,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, goto give_sigsegv; /* Set up to return from userspace. */ - restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); + restorer = &__kernel_rt_sigreturn; if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; err |= __put_user(restorer, &frame->pretcode); diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index c10789d7a9d3..d134e9643a58 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -114,17 +114,7 @@ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_m static inline int __prepare_ICR (unsigned int shortcut, int vector) { - unsigned int icr = shortcut | APIC_DEST_LOGICAL; - - switch (vector) { - default: - icr |= APIC_DM_FIXED | vector; - break; - case NMI_VECTOR: - icr |= APIC_DM_NMI; - break; - } - return icr; + return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL; } static inline int __prepare_ICR2 (unsigned int mask) diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 89e7315e539c..825b2b4ca721 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -67,6 +66,12 @@ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); #endif +/* Package ID of each logical CPU */ +int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; + +/* Core ID of each logical CPU */ +int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; + /* Last level cache ID of each logical CPU */ int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; @@ -252,7 +257,7 @@ static void __init synchronize_tsc_bp (void) * all APs synchronize but they loop on '== num_cpus' */ while (atomic_read(&tsc_count_start) != num_booting_cpus()-1) - cpu_relax(); + mb(); atomic_set(&tsc_count_stop, 0); wmb(); /* @@ -271,7 +276,7 @@ static void __init synchronize_tsc_bp (void) * Wait for all APs to leave the synchronization point: */ while (atomic_read(&tsc_count_stop) != num_booting_cpus()-1) - cpu_relax(); + mb(); atomic_set(&tsc_count_start, 0); wmb(); atomic_inc(&tsc_count_stop); @@ -328,21 +333,19 @@ static void __init synchronize_tsc_ap (void) * this gets called, so we first wait for the BP to * finish SMP initialization: */ - while (!atomic_read(&tsc_start_flag)) - cpu_relax(); + while (!atomic_read(&tsc_start_flag)) mb(); for (i = 0; i < NR_LOOPS; i++) { atomic_inc(&tsc_count_start); while (atomic_read(&tsc_count_start) != num_booting_cpus()) - cpu_relax(); + mb(); rdtscll(tsc_values[smp_processor_id()]); if (i == NR_LOOPS-1) write_tsc(0, 0); atomic_inc(&tsc_count_stop); - while (atomic_read(&tsc_count_stop) != num_booting_cpus()) - cpu_relax(); + while (atomic_read(&tsc_count_stop) != num_booting_cpus()) mb(); } } #undef NR_LOOPS @@ -448,12 +451,10 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * And for power savings, we return cpu_core_map + * TBD: when power saving sched policy is added, we will return + * cpu_core_map when power saving policy is enabled */ - if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; - else - return c->llc_shared_map; + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ @@ -469,8 +470,8 @@ set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu_mask(i, cpu_sibling_setup_map) { - if (c[cpu].phys_proc_id == c[i].phys_proc_id && - c[cpu].cpu_core_id == c[i].cpu_core_id) { + if (phys_proc_id[cpu] == phys_proc_id[i] && + cpu_core_id[cpu] == cpu_core_id[i]) { cpu_set(i, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[i]); cpu_set(i, cpu_core_map[cpu]); @@ -497,7 +498,7 @@ set_cpu_sibling_map(int cpu) cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } - if (c[cpu].phys_proc_id == c[i].phys_proc_id) { + if (phys_proc_id[cpu] == phys_proc_id[i]) { cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); /* @@ -1052,7 +1053,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); apicid = x86_cpu_to_apicid[cpu]; if (apicid == BAD_APICID) { @@ -1060,18 +1060,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) goto exit; } - /* - * the CPU isn't initialized at boot time, allocate gdt table here. - * cpu_init will initialize it - */ - if (!cpu_gdt_descr->address) { - cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); - if (!cpu_gdt_descr->address) - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); - ret = -ENOMEM; - goto exit; - } - info.complete = &done; info.apicid = apicid; info.cpu = cpu; @@ -1349,8 +1337,8 @@ remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_map[sibling]); cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); - c[cpu].phys_proc_id = 0; - c[cpu].cpu_core_id = 0; + phys_proc_id[cpu] = BAD_APICID; + cpu_core_id[cpu] = BAD_APICID; cpu_clear(cpu, cpu_sibling_setup_map); } @@ -1445,7 +1433,7 @@ int __devinit __cpu_up(unsigned int cpu) /* Unleash the CPU! */ cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) - cpu_relax(); + mb(); return 0; } diff --git a/trunk/arch/i386/kernel/srat.c b/trunk/arch/i386/kernel/srat.c index 989c85255dbe..52b3ed5d2cb5 100644 --- a/trunk/arch/i386/kernel/srat.c +++ b/trunk/arch/i386/kernel/srat.c @@ -39,6 +39,7 @@ #define NODE_ARRAY_OFFSET(x) ((x) % 8) /* 8 bits/char */ #define BMAP_SET(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit)) #define BMAP_TEST(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit))) +#define MAX_PXM_DOMAINS 256 /* 1 byte and no promises about values */ /* bitmap length; _PXM is at most 255 */ #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ @@ -212,11 +213,19 @@ static __init void node_read_chunk(int nid, struct node_memory_chunk_s *memory_c node_end_pfn[nid] = memory_chunk->end_pfn; } +static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ + +int pxm_to_node(int pxm) +{ + return pxm_to_nid_map[pxm]; +} + /* Parse the ACPI Static Resource Affinity Table */ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) { u8 *start, *end, *p; int i, j, nid; + u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */ start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ p = start; @@ -226,6 +235,10 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); memset(zholes_size, 0, sizeof(zholes_size)); + /* -1 in these maps means not available */ + memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); + memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); + num_memory_chunks = 0; while (p < end) { switch (*p) { @@ -265,7 +278,9 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (BMAP_TEST(pxm_bitmap, i)) { - int nid = acpi_map_pxm_to_node(i); + nid = num_online_nodes(); + pxm_to_nid_map[i] = nid; + nid_to_pxm_map[nid] = i; node_set_online(nid); } } @@ -273,7 +288,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) /* set cnode id in memory chunk structure */ for (i = 0; i < num_memory_chunks; i++) - node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm); + node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm]; printk("pxm bitmap: "); for (i = 0; i < sizeof(pxm_bitmap); i++) { diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index dd63d4775398..af56987f69b0 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -316,4 +316,3 @@ ENTRY(sys_call_table) .long sys_sync_file_range .long sys_tee /* 315 */ .long sys_vmsplice - .long sys_move_pages diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index c60419dee018..0bada1870bdf 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -2,8 +2,6 @@ * linux/arch/i386/kernel/sysenter.c * * (C) Copyright 2002 Linus Torvalds - * Portions based on the vdso-randomization code from exec-shield: - * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar * * This file contains the needed initializations to support sysenter. */ @@ -15,31 +13,12 @@ #include #include #include -#include -#include #include #include #include #include -/* - * Should the kernel map a VDSO page into processes and pass its - * address down to glibc upon exec()? - */ -unsigned int __read_mostly vdso_enabled = 1; - -EXPORT_SYMBOL_GPL(vdso_enabled); - -static int __init vdso_setup(char *s) -{ - vdso_enabled = simple_strtoul(s, NULL, 0); - - return 1; -} - -__setup("vdso=", vdso_setup); - extern asmlinkage void sysenter_entry(void); void enable_sep_cpu(void) @@ -66,122 +45,23 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; -static void *syscall_page; int __init sysenter_setup(void) { - syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); + void *page = (void *)get_zeroed_page(GFP_ATOMIC); -#ifdef CONFIG_COMPAT_VDSO - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); - printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); -#else - /* - * In the non-compat case the ELF coredumping code needs the fixmap: - */ - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); -#endif + __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC); if (!boot_cpu_has(X86_FEATURE_SEP)) { - memcpy(syscall_page, + memcpy(page, &vsyscall_int80_start, &vsyscall_int80_end - &vsyscall_int80_start); return 0; } - memcpy(syscall_page, + memcpy(page, &vsyscall_sysenter_start, &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } - -static struct page *syscall_nopage(struct vm_area_struct *vma, - unsigned long adr, int *type) -{ - struct page *p = virt_to_page(adr - vma->vm_start + syscall_page); - get_page(p); - return p; -} - -/* Prevent VMA merging */ -static void syscall_vma_close(struct vm_area_struct *vma) -{ -} - -static struct vm_operations_struct syscall_vm_ops = { - .close = syscall_vma_close, - .nopage = syscall_nopage, -}; - -/* Defined in vsyscall-sysenter.S */ -extern void SYSENTER_RETURN; - -/* Setup a VMA at program startup for the vsyscall page */ -int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) -{ - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret; - - down_write(&mm->mmap_sem); - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; - } - - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); - if (!vma) { - ret = -ENOMEM; - goto up_fail; - } - - vma->vm_start = addr; - vma->vm_end = addr + PAGE_SIZE; - /* MAYWRITE to allow gdb to COW and set breakpoints */ - vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; - vma->vm_flags |= mm->def_flags; - vma->vm_page_prot = protection_map[vma->vm_flags & 7]; - vma->vm_ops = &syscall_vm_ops; - vma->vm_mm = mm; - - ret = insert_vm_struct(mm, vma); - if (ret) - goto free_vma; - - current->mm->context.vdso = (void *)addr; - current_thread_info()->sysenter_return = - (void *)VDSO_SYM(&SYSENTER_RETURN); - mm->total_vm++; -up_fail: - up_write(&mm->mmap_sem); - return ret; - -free_vma: - kmem_cache_free(vm_area_cachep, vma); - return ret; -} - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) - return "[vdso]"; - return NULL; -} - -struct vm_area_struct *get_gate_vma(struct task_struct *tsk) -{ - return NULL; -} - -int in_gate_area(struct task_struct *task, unsigned long addr) -{ - return 0; -} - -int in_gate_area_no_task(unsigned long addr) -{ - return 0; -} diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 5f43d0410122..9d3074759856 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -82,6 +82,13 @@ extern unsigned long wall_jiffies; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); +#include + +DEFINE_SPINLOCK(i8253_lock); +EXPORT_SYMBOL(i8253_lock); + +struct timer_opts *cur_timer __read_mostly = &timer_none; + /* * This is a special lock that is owned by the CPU and holds the index * register we are working with. It is required for NMI access to the @@ -111,19 +118,99 @@ void rtc_cmos_write(unsigned char val, unsigned char addr) } EXPORT_SYMBOL(rtc_cmos_write); +/* + * This version of gettimeofday has microsecond resolution + * and better than microsecond precision on fast x86 machines with TSC. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long seq; + unsigned long usec, sec; + unsigned long max_ntp_tick; + + do { + unsigned long lost; + + seq = read_seqbegin(&xtime_lock); + + usec = cur_timer->get_offset(); + lost = jiffies - wall_jiffies; + + /* + * If time_adjust is negative then NTP is slowing the clock + * so make sure not to go into next possible interval. + * Better to lose some accuracy than have time go backwards.. + */ + if (unlikely(time_adjust < 0)) { + max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; + usec = min(usec, max_ntp_tick); + + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * (USEC_PER_SEC / HZ); + + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; + + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! + */ + nsec -= cur_timer->get_offset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; + + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); + + ntp_clear(); + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + return 0; +} + +EXPORT_SYMBOL(do_settimeofday); + static int set_rtc_mmss(unsigned long nowtime) { int retval; - unsigned long flags; + + WARN_ON(irqs_disabled()); /* gets recalled with irq locally disabled */ - /* XXX - does irqsave resolve this? -johnstul */ - spin_lock_irqsave(&rtc_lock, flags); + spin_lock_irq(&rtc_lock); if (efi_enabled) retval = efi_set_rtc_mmss(nowtime); else retval = mach_set_rtc_mmss(nowtime); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irq(&rtc_lock); return retval; } @@ -131,6 +218,16 @@ static int set_rtc_mmss(unsigned long nowtime) int timer_ack; +/* monotonic_clock(): returns # of nanoseconds passed since time_init() + * Note: This function is required to return accurate + * time even in the absence of multiple timer ticks. + */ +unsigned long long monotonic_clock(void) +{ + return cur_timer->monotonic_clock(); +} +EXPORT_SYMBOL(monotonic_clock); + #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) unsigned long profile_pc(struct pt_regs *regs) { @@ -145,21 +242,11 @@ EXPORT_SYMBOL(profile_pc); #endif /* - * This is the same as the above, except we _also_ save the current - * Time Stamp Counter value at the time of the timer interrupt, so that - * we later on can estimate the time of day more exactly. + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick */ -irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static inline void do_timer_interrupt(int irq, struct pt_regs *regs) { - /* - * Here we are in the timer irq handler. We just have irqs locally - * disabled but we don't know if the timer_bh is running on the other - * CPU. We need to avoid to SMP race with it. NOTE: we don' t need - * the irq version of write_lock because as just said we have irq - * locally disabled. -arca - */ - write_seqlock(&xtime_lock); - #ifdef CONFIG_X86_IO_APIC if (timer_ack) { /* @@ -192,6 +279,27 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) irq = inb_p( 0x61 ); /* read the current state */ outb_p( irq|0x80, 0x61 ); /* reset the IRQ */ } +} + +/* + * This is the same as the above, except we _also_ save the current + * Time Stamp Counter value at the time of the timer interrupt, so that + * we later on can estimate the time of day more exactly. + */ +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_seqlock(&xtime_lock); + + cur_timer->mark_offset(); + + do_timer_interrupt(irq, regs); write_sequnlock(&xtime_lock); @@ -272,6 +380,7 @@ void notify_arch_cmos_timer(void) static long clock_cmos_diff, sleep_start; +static struct timer_opts *last_timer; static int timer_suspend(struct sys_device *dev, pm_message_t state) { /* @@ -280,6 +389,10 @@ static int timer_suspend(struct sys_device *dev, pm_message_t state) clock_cmos_diff = -get_cmos_time(); clock_cmos_diff += get_seconds(); sleep_start = get_cmos_time(); + last_timer = cur_timer; + cur_timer = &timer_none; + if (last_timer->suspend) + last_timer->suspend(state); return 0; } @@ -302,6 +415,10 @@ static int timer_resume(struct sys_device *dev) jiffies_64 += sleep_length; wall_jiffies += sleep_length; write_sequnlock_irqrestore(&xtime_lock, flags); + if (last_timer->resume) + last_timer->resume(); + cur_timer = last_timer; + last_timer = NULL; touch_softlockup_watchdog(); return 0; } @@ -343,6 +460,9 @@ static void __init hpet_time_init(void) printk("Using HPET for base-timer\n"); } + cur_timer = select_timer(); + printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); + time_init_hook(); } #endif @@ -364,5 +484,8 @@ void __init time_init(void) set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); + cur_timer = select_timer(); + printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); + time_init_hook(); } diff --git a/trunk/arch/i386/kernel/timers/Makefile b/trunk/arch/i386/kernel/timers/Makefile new file mode 100644 index 000000000000..8fa12be658dd --- /dev/null +++ b/trunk/arch/i386/kernel/timers/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for x86 timers +# + +obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o common.o + +obj-$(CONFIG_X86_CYCLONE_TIMER) += timer_cyclone.o +obj-$(CONFIG_HPET_TIMER) += timer_hpet.o +obj-$(CONFIG_X86_PM_TIMER) += timer_pm.o diff --git a/trunk/arch/i386/kernel/timers/common.c b/trunk/arch/i386/kernel/timers/common.c new file mode 100644 index 000000000000..8163fe0cf1f0 --- /dev/null +++ b/trunk/arch/i386/kernel/timers/common.c @@ -0,0 +1,172 @@ +/* + * Common functions used across the timers go here + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mach_timer.h" + +/* ------ Calibrate the TSC ------- + * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). + * Too much 64-bit arithmetic here to do this cleanly in C, and for + * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2) + * output busy loop as low as possible. We avoid reading the CTC registers + * directly because of the awkward 8-bit access mechanism of the 82C54 + * device. + */ + +#define CALIBRATE_TIME (5 * 1000020/HZ) + +unsigned long calibrate_tsc(void) +{ + mach_prepare_counter(); + + { + unsigned long startlow, starthigh; + unsigned long endlow, endhigh; + unsigned long count; + + rdtsc(startlow,starthigh); + mach_countup(&count); + rdtsc(endlow,endhigh); + + + /* Error: ECTCNEVERSET */ + if (count <= 1) + goto bad_ctc; + + /* 64-bit subtract - gcc just messes up with long longs */ + __asm__("subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (endlow), "=d" (endhigh) + :"g" (startlow), "g" (starthigh), + "0" (endlow), "1" (endhigh)); + + /* Error: ECPUTOOFAST */ + if (endhigh) + goto bad_ctc; + + /* Error: ECPUTOOSLOW */ + if (endlow <= CALIBRATE_TIME) + goto bad_ctc; + + __asm__("divl %2" + :"=a" (endlow), "=d" (endhigh) + :"r" (endlow), "0" (0), "1" (CALIBRATE_TIME)); + + return endlow; + } + + /* + * The CTC wasn't reliable: we got a hit on the very first read, + * or the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ +bad_ctc: + return 0; +} + +#ifdef CONFIG_HPET_TIMER +/* ------ Calibrate the TSC using HPET ------- + * Return 2^32 * (1 / (TSC clocks per usec)) for getting the CPU freq. + * Second output is parameter 1 (when non NULL) + * Set 2^32 * (1 / (tsc per HPET clk)) for delay_hpet(). + * calibrate_tsc() calibrates the processor TSC by comparing + * it to the HPET timer of known frequency. + * Too much 64-bit arithmetic here to do this cleanly in C + */ +#define CALIBRATE_CNT_HPET (5 * hpet_tick) +#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) + +unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) +{ + unsigned long tsc_startlow, tsc_starthigh; + unsigned long tsc_endlow, tsc_endhigh; + unsigned long hpet_start, hpet_end; + unsigned long result, remain; + + hpet_start = hpet_readl(HPET_COUNTER); + rdtsc(tsc_startlow, tsc_starthigh); + do { + hpet_end = hpet_readl(HPET_COUNTER); + } while ((hpet_end - hpet_start) < CALIBRATE_CNT_HPET); + rdtsc(tsc_endlow, tsc_endhigh); + + /* 64-bit subtract - gcc just messes up with long longs */ + __asm__("subl %2,%0\n\t" + "sbbl %3,%1" + :"=a" (tsc_endlow), "=d" (tsc_endhigh) + :"g" (tsc_startlow), "g" (tsc_starthigh), + "0" (tsc_endlow), "1" (tsc_endhigh)); + + /* Error: ECPUTOOFAST */ + if (tsc_endhigh) + goto bad_calibration; + + /* Error: ECPUTOOSLOW */ + if (tsc_endlow <= CALIBRATE_TIME_HPET) + goto bad_calibration; + + ASM_DIV64_REG(result, remain, tsc_endlow, 0, CALIBRATE_TIME_HPET); + if (remain > (tsc_endlow >> 1)) + result++; /* rounding the result */ + + if (tsc_hpet_quotient_ptr) { + unsigned long tsc_hpet_quotient; + + ASM_DIV64_REG(tsc_hpet_quotient, remain, tsc_endlow, 0, + CALIBRATE_CNT_HPET); + if (remain > (tsc_endlow >> 1)) + tsc_hpet_quotient++; /* rounding the result */ + *tsc_hpet_quotient_ptr = tsc_hpet_quotient; + } + + return result; +bad_calibration: + /* + * the CPU was so fast/slow that the quotient wouldn't fit in + * 32 bits.. + */ + return 0; +} +#endif + + +unsigned long read_timer_tsc(void) +{ + unsigned long retval; + rdtscl(retval); + return retval; +} + + +/* calculate cpu_khz */ +void init_cpu_khz(void) +{ + if (cpu_has_tsc) { + unsigned long tsc_quotient = calibrate_tsc(); + if (tsc_quotient) { + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000; + __asm__("divl %2" + :"=a" (cpu_khz), "=d" (edx) + :"r" (tsc_quotient), + "0" (eax), "1" (edx)); + printk("Detected %u.%03u MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + } + } + } +} + diff --git a/trunk/arch/i386/kernel/timers/timer.c b/trunk/arch/i386/kernel/timers/timer.c new file mode 100644 index 000000000000..7e39ed8e33f8 --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#ifdef CONFIG_HPET_TIMER +/* + * HPET memory read is slower than tsc reads, but is more dependable as it + * always runs at constant frequency and reduces complexity due to + * cpufreq. So, we prefer HPET timer to tsc based one. Also, we cannot use + * timer_pit when HPET is active. So, we default to timer_tsc. + */ +#endif +/* list of timers, ordered by preference, NULL terminated */ +static struct init_timer_opts* __initdata timers[] = { +#ifdef CONFIG_X86_CYCLONE_TIMER + &timer_cyclone_init, +#endif +#ifdef CONFIG_HPET_TIMER + &timer_hpet_init, +#endif +#ifdef CONFIG_X86_PM_TIMER + &timer_pmtmr_init, +#endif + &timer_tsc_init, + &timer_pit_init, + NULL, +}; + +static char clock_override[10] __initdata; + +static int __init clock_setup(char* str) +{ + if (str) + strlcpy(clock_override, str, sizeof(clock_override)); + return 1; +} +__setup("clock=", clock_setup); + + +/* The chosen timesource has been found to be bad. + * Fall back to a known good timesource (the PIT) + */ +void clock_fallback(void) +{ + cur_timer = &timer_pit; +} + +/* iterates through the list of timers, returning the first + * one that initializes successfully. + */ +struct timer_opts* __init select_timer(void) +{ + int i = 0; + + /* find most preferred working timer */ + while (timers[i]) { + if (timers[i]->init) + if (timers[i]->init(clock_override) == 0) + return timers[i]->opts; + ++i; + } + + panic("select_timer: Cannot find a suitable timer\n"); + return NULL; +} + +int read_current_timer(unsigned long *timer_val) +{ + if (cur_timer->read_timer) { + *timer_val = cur_timer->read_timer(); + return 0; + } + return -1; +} diff --git a/trunk/arch/i386/kernel/timers/timer_cyclone.c b/trunk/arch/i386/kernel/timers/timer_cyclone.c new file mode 100644 index 000000000000..13892a65c941 --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_cyclone.c @@ -0,0 +1,259 @@ +/* Cyclone-timer: + * This code implements timer_ops for the cyclone counter found + * on IBM x440, x360, and other Summit based systems. + * + * Copyright (C) 2002 IBM, John Stultz (johnstul@us.ibm.com) + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "io_ports.h" + +/* Number of usecs that the last interrupt was delayed */ +static int delay_at_last_interrupt; + +#define CYCLONE_CBAR_ADDR 0xFEB00CD0 +#define CYCLONE_PMCC_OFFSET 0x51A0 +#define CYCLONE_MPMC_OFFSET 0x51D0 +#define CYCLONE_MPCS_OFFSET 0x51A8 +#define CYCLONE_TIMER_FREQ 100000000 +#define CYCLONE_TIMER_MASK (((u64)1<<40)-1) /* 40 bit mask */ +int use_cyclone = 0; + +static u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ +static u32 last_cyclone_low; +static u32 last_cyclone_high; +static unsigned long long monotonic_base; +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; + +/* helper macro to atomically read both cyclone counter registers */ +#define read_cyclone_counter(low,high) \ + do{ \ + high = cyclone_timer[1]; low = cyclone_timer[0]; \ + } while (high != cyclone_timer[1]); + + +static void mark_offset_cyclone(void) +{ + unsigned long lost, delay; + unsigned long delta = last_cyclone_low; + int count; + unsigned long long this_offset, last_offset; + + write_seqlock(&monotonic_lock); + last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + + spin_lock(&i8253_lock); + read_cyclone_counter(last_cyclone_low,last_cyclone_high); + + /* read values for delay_at_last_interrupt */ + outb_p(0x00, 0x43); /* latch the count ASAP */ + + count = inb_p(0x40); /* read the latched count */ + count |= inb(0x40) << 8; + + /* + * VIA686a test code... reset the latch if count > max + 1 + * from timer_pit.c - cjb + */ + if (count > LATCH) { + outb_p(0x34, PIT_MODE); + outb_p(LATCH & 0xff, PIT_CH0); + outb(LATCH >> 8, PIT_CH0); + count = LATCH - 1; + } + spin_unlock(&i8253_lock); + + /* lost tick compensation */ + delta = last_cyclone_low - delta; + delta /= (CYCLONE_TIMER_FREQ/1000000); + delta += delay_at_last_interrupt; + lost = delta/(1000000/HZ); + delay = delta%(1000000/HZ); + if (lost >= 2) + jiffies_64 += lost-1; + + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + monotonic_base += (this_offset - last_offset) & CYCLONE_TIMER_MASK; + write_sequnlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ + count = ((LATCH-1) - count) * TICK_SIZE; + delay_at_last_interrupt = (count + LATCH/2) / LATCH; + + + /* catch corner case where tick rollover occured + * between cyclone and pit reads (as noted when + * usec delta is > 90% # of usecs/tick) + */ + if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) + jiffies_64++; +} + +static unsigned long get_offset_cyclone(void) +{ + u32 offset; + + if(!cyclone_timer) + return delay_at_last_interrupt; + + /* Read the cyclone timer */ + offset = cyclone_timer[0]; + + /* .. relative to previous jiffy */ + offset = offset - last_cyclone_low; + + /* convert cyclone ticks to microseconds */ + /* XXX slow, can we speed this up? */ + offset = offset/(CYCLONE_TIMER_FREQ/1000000); + + /* our adjusted time offset in microseconds */ + return delay_at_last_interrupt + offset; +} + +static unsigned long long monotonic_clock_cyclone(void) +{ + u32 now_low, now_high; + unsigned long long last_offset, this_offset, base; + unsigned long long ret; + unsigned seq; + + /* atomically read monotonic base & last_offset */ + do { + seq = read_seqbegin(&monotonic_lock); + last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low; + base = monotonic_base; + } while (read_seqretry(&monotonic_lock, seq)); + + + /* Read the cyclone counter */ + read_cyclone_counter(now_low,now_high); + this_offset = ((unsigned long long)now_high<<32)|now_low; + + /* convert to nanoseconds */ + ret = base + ((this_offset - last_offset)&CYCLONE_TIMER_MASK); + return ret * (1000000000 / CYCLONE_TIMER_FREQ); +} + +static int __init init_cyclone(char* override) +{ + u32* reg; + u32 base; /* saved cyclone base address */ + u32 pageaddr; /* page that contains cyclone_timer register */ + u32 offset; /* offset from pageaddr to cyclone_timer register */ + int i; + + /* check clock override */ + if (override[0] && strncmp(override,"cyclone",7)) + return -ENODEV; + + /*make sure we're on a summit box*/ + if(!use_cyclone) return -ENODEV; + + printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); + + /* find base address */ + pageaddr = (CYCLONE_CBAR_ADDR)&PAGE_MASK; + offset = (CYCLONE_CBAR_ADDR)&(~PAGE_MASK); + set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); + reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); + if(!reg){ + printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); + return -ENODEV; + } + base = *reg; + if(!base){ + printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); + return -ENODEV; + } + + /* setup PMCC */ + pageaddr = (base + CYCLONE_PMCC_OFFSET)&PAGE_MASK; + offset = (base + CYCLONE_PMCC_OFFSET)&(~PAGE_MASK); + set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); + reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); + if(!reg){ + printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); + return -ENODEV; + } + reg[0] = 0x00000001; + + /* setup MPCS */ + pageaddr = (base + CYCLONE_MPCS_OFFSET)&PAGE_MASK; + offset = (base + CYCLONE_MPCS_OFFSET)&(~PAGE_MASK); + set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); + reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); + if(!reg){ + printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); + return -ENODEV; + } + reg[0] = 0x00000001; + + /* map in cyclone_timer */ + pageaddr = (base + CYCLONE_MPMC_OFFSET)&PAGE_MASK; + offset = (base + CYCLONE_MPMC_OFFSET)&(~PAGE_MASK); + set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); + cyclone_timer = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); + if(!cyclone_timer){ + printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); + return -ENODEV; + } + + /*quick test to make sure its ticking*/ + for(i=0; i<3; i++){ + u32 old = cyclone_timer[0]; + int stall = 100; + while(stall--) barrier(); + if(cyclone_timer[0] == old){ + printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); + cyclone_timer = 0; + return -ENODEV; + } + } + + init_cpu_khz(); + + /* Everything looks good! */ + return 0; +} + + +static void delay_cyclone(unsigned long loops) +{ + unsigned long bclock, now; + if(!cyclone_timer) + return; + bclock = cyclone_timer[0]; + do { + rep_nop(); + now = cyclone_timer[0]; + } while ((now-bclock) < loops); +} +/************************************************************/ + +/* cyclone timer_opts struct */ +static struct timer_opts timer_cyclone = { + .name = "cyclone", + .mark_offset = mark_offset_cyclone, + .get_offset = get_offset_cyclone, + .monotonic_clock = monotonic_clock_cyclone, + .delay = delay_cyclone, +}; + +struct init_timer_opts __initdata timer_cyclone_init = { + .init = init_cyclone, + .opts = &timer_cyclone, +}; diff --git a/trunk/arch/i386/kernel/timers/timer_hpet.c b/trunk/arch/i386/kernel/timers/timer_hpet.c new file mode 100644 index 000000000000..17a6fe7166e7 --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_hpet.c @@ -0,0 +1,217 @@ +/* + * This code largely moved from arch/i386/kernel/time.c. + * See comments there for proper credits. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "io_ports.h" +#include "mach_timer.h" +#include + +static unsigned long hpet_usec_quotient __read_mostly; /* convert hpet clks to usec */ +static unsigned long tsc_hpet_quotient __read_mostly; /* convert tsc to hpet clks */ +static unsigned long hpet_last; /* hpet counter value at last tick*/ +static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ +static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ +static unsigned long long monotonic_base; +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; + +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_khz * 10^3)) + * ns = cycles * (10^6 / cpu_khz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^6 * SC / cpu_khz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * + * We can use khz divisor instead of mhz to keep a better percision, since + * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. + * (mathieu.desnoyers@polymtl.ca) + * + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale __read_mostly; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_khz) +{ + cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +static unsigned long long monotonic_clock_hpet(void) +{ + unsigned long long last_offset, this_offset, base; + unsigned seq; + + /* atomically read monotonic base & last_offset */ + do { + seq = read_seqbegin(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + base = monotonic_base; + } while (read_seqretry(&monotonic_lock, seq)); + + /* Read the Time Stamp Counter */ + rdtscll(this_offset); + + /* return the value in ns */ + return base + cycles_2_ns(this_offset - last_offset); +} + +static unsigned long get_offset_hpet(void) +{ + register unsigned long eax, edx; + + eax = hpet_readl(HPET_COUNTER); + eax -= hpet_last; /* hpet delta */ + eax = min(hpet_tick, eax); + /* + * Time offset = (hpet delta) * ( usecs per HPET clock ) + * = (hpet delta) * ( usecs per tick / HPET clocks per tick) + * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) + * + * Where, + * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick + * + * Using a mull instead of a divl saves some cycles in critical path. + */ + ASM_MUL64_REG(eax, edx, hpet_usec_quotient, eax); + + /* our adjusted time offset in microseconds */ + return edx; +} + +static void mark_offset_hpet(void) +{ + unsigned long long this_offset, last_offset; + unsigned long offset; + + write_seqlock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + rdtsc(last_tsc_low, last_tsc_high); + + if (hpet_use_timer) + offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + else + offset = hpet_readl(HPET_COUNTER); + if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) { + int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1; + jiffies_64 += lost_ticks; + } + hpet_last = offset; + + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_sequnlock(&monotonic_lock); +} + +static void delay_hpet(unsigned long loops) +{ + unsigned long hpet_start, hpet_end; + unsigned long eax; + + /* loops is the number of cpu cycles. Convert it to hpet clocks */ + ASM_MUL64_REG(eax, loops, tsc_hpet_quotient, loops); + + hpet_start = hpet_readl(HPET_COUNTER); + do { + rep_nop(); + hpet_end = hpet_readl(HPET_COUNTER); + } while ((hpet_end - hpet_start) < (loops)); +} + +static struct timer_opts timer_hpet; + +static int __init init_hpet(char* override) +{ + unsigned long result, remain; + + /* check clock override */ + if (override[0] && strncmp(override,"hpet",4)) + return -ENODEV; + + if (!is_hpet_enabled()) + return -ENODEV; + + printk("Using HPET for gettimeofday\n"); + if (cpu_has_tsc) { + unsigned long tsc_quotient = calibrate_tsc_hpet(&tsc_hpet_quotient); + if (tsc_quotient) { + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000; + ASM_DIV64_REG(cpu_khz, edx, tsc_quotient, + eax, edx); + printk("Detected %u.%03u MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + } + set_cyc2ns_scale(cpu_khz); + } + /* set this only when cpu_has_tsc */ + timer_hpet.read_timer = read_timer_tsc; + } + + /* + * Math to calculate hpet to usec multiplier + * Look for the comments at get_offset_hpet() + */ + ASM_DIV64_REG(result, remain, hpet_tick, 0, KERNEL_TICK_USEC); + if (remain > (hpet_tick >> 1)) + result++; /* rounding the result */ + hpet_usec_quotient = result; + + return 0; +} + +static int hpet_resume(void) +{ + write_seqlock(&monotonic_lock); + /* Assume this is the last mark offset time */ + rdtsc(last_tsc_low, last_tsc_high); + + if (hpet_use_timer) + hpet_last = hpet_readl(HPET_T0_CMP) - hpet_tick; + else + hpet_last = hpet_readl(HPET_COUNTER); + write_sequnlock(&monotonic_lock); + return 0; +} +/************************************************************/ + +/* tsc timer_opts struct */ +static struct timer_opts timer_hpet __read_mostly = { + .name = "hpet", + .mark_offset = mark_offset_hpet, + .get_offset = get_offset_hpet, + .monotonic_clock = monotonic_clock_hpet, + .delay = delay_hpet, + .resume = hpet_resume, +}; + +struct init_timer_opts __initdata timer_hpet_init = { + .init = init_hpet, + .opts = &timer_hpet, +}; diff --git a/trunk/arch/i386/kernel/timers/timer_none.c b/trunk/arch/i386/kernel/timers/timer_none.c new file mode 100644 index 000000000000..4ea2f414dbbd --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_none.c @@ -0,0 +1,39 @@ +#include +#include + +static void mark_offset_none(void) +{ + /* nothing needed */ +} + +static unsigned long get_offset_none(void) +{ + return 0; +} + +static unsigned long long monotonic_clock_none(void) +{ + return 0; +} + +static void delay_none(unsigned long loops) +{ + int d0; + __asm__ __volatile__( + "\tjmp 1f\n" + ".align 16\n" + "1:\tjmp 2f\n" + ".align 16\n" + "2:\tdecl %0\n\tjns 2b" + :"=&a" (d0) + :"0" (loops)); +} + +/* none timer_opts struct */ +struct timer_opts timer_none = { + .name = "none", + .mark_offset = mark_offset_none, + .get_offset = get_offset_none, + .monotonic_clock = monotonic_clock_none, + .delay = delay_none, +}; diff --git a/trunk/arch/i386/kernel/timers/timer_pit.c b/trunk/arch/i386/kernel/timers/timer_pit.c new file mode 100644 index 000000000000..b9b6bd56b9ba --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_pit.c @@ -0,0 +1,177 @@ +/* + * This code largely moved from arch/i386/kernel/time.c. + * See comments there for proper credits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "do_timer.h" +#include "io_ports.h" + +static int count_p; /* counter in get_offset_pit() */ + +static int __init init_pit(char* override) +{ + /* check clock override */ + if (override[0] && strncmp(override,"pit",3)) + printk(KERN_ERR "Warning: clock= override failed. Defaulting " + "to PIT\n"); + init_cpu_khz(); + count_p = LATCH; + return 0; +} + +static void mark_offset_pit(void) +{ + /* nothing needed */ +} + +static unsigned long long monotonic_clock_pit(void) +{ + return 0; +} + +static void delay_pit(unsigned long loops) +{ + int d0; + __asm__ __volatile__( + "\tjmp 1f\n" + ".align 16\n" + "1:\tjmp 2f\n" + ".align 16\n" + "2:\tdecl %0\n\tjns 2b" + :"=&a" (d0) + :"0" (loops)); +} + + +/* This function must be called with xtime_lock held. + * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs + * + * However, the pc-audio speaker driver changes the divisor so that + * it gets interrupted rather more often - it loads 64 into the + * counter rather than 11932! This has an adverse impact on + * do_gettimeoffset() -- it stops working! What is also not + * good is that the interval that our timer function gets called + * is no longer 10.0002 ms, but 9.9767 ms. To get around this + * would require using a different timing source. Maybe someone + * could use the RTC - I know that this can interrupt at frequencies + * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix + * it so that at startup, the timer code in sched.c would select + * using either the RTC or the 8253 timer. The decision would be + * based on whether there was any other device around that needed + * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, + * and then do some jiggery to have a version of do_timer that + * advanced the clock by 1/1024 s. Every time that reached over 1/100 + * of a second, then do all the old code. If the time was kept correct + * then do_gettimeoffset could just return 0 - there is no low order + * divider that can be accessed. + * + * Ideally, you would be able to use the RTC for the speaker driver, + * but it appears that the speaker driver really needs interrupt more + * often than every 120 us or so. + * + * Anyway, this needs more thought.... pjsg (1993-08-28) + * + * If you are really that interested, you should be reading + * comp.protocols.time.ntp! + */ + +static unsigned long get_offset_pit(void) +{ + int count; + unsigned long flags; + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have xtime_lock. + */ + unsigned long jiffies_t; + + spin_lock_irqsave(&i8253_lock, flags); + /* timer count may underflow right here */ + outb_p(0x00, PIT_MODE); /* latch the count ASAP */ + + count = inb_p(PIT_CH0); /* read the latched count */ + + /* + * We do this guaranteed double memory access instead of a _p + * postfix in the previous port access. Wheee, hackady hack + */ + jiffies_t = jiffies; + + count |= inb_p(PIT_CH0) << 8; + + /* VIA686a test code... reset the latch if count > max + 1 */ + if (count > LATCH) { + outb_p(0x34, PIT_MODE); + outb_p(LATCH & 0xff, PIT_CH0); + outb(LATCH >> 8, PIT_CH0); + count = LATCH - 1; + } + + /* + * avoiding timer inconsistencies (they are rare, but they happen)... + * there are two kinds of problems that must be avoided here: + * 1. the timer counter underflows + * 2. hardware problem with the timer, not giving us continuous time, + * the counter does small "jumps" upwards on some Pentium systems, + * (see c't 95/10 page 335 for Neptun bug.) + */ + + if( jiffies_t == jiffies_p ) { + if( count > count_p ) { + /* the nutcase */ + count = do_timer_overflow(count); + } + } else + jiffies_p = jiffies_t; + + count_p = count; + + spin_unlock_irqrestore(&i8253_lock, flags); + + count = ((LATCH-1) - count) * TICK_SIZE; + count = (count + LATCH/2) / LATCH; + + return count; +} + + +/* tsc timer_opts struct */ +struct timer_opts timer_pit = { + .name = "pit", + .mark_offset = mark_offset_pit, + .get_offset = get_offset_pit, + .monotonic_clock = monotonic_clock_pit, + .delay = delay_pit, +}; + +struct init_timer_opts __initdata timer_pit_init = { + .init = init_pit, + .opts = &timer_pit, +}; + +void setup_pit_timer(void) +{ + unsigned long flags; + + spin_lock_irqsave(&i8253_lock, flags); + outb_p(0x34,PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ + udelay(10); + outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ + udelay(10); + outb(LATCH >> 8 , PIT_CH0); /* MSB */ + spin_unlock_irqrestore(&i8253_lock, flags); +} diff --git a/trunk/arch/i386/kernel/timers/timer_pm.c b/trunk/arch/i386/kernel/timers/timer_pm.c new file mode 100644 index 000000000000..144e94a04933 --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_pm.c @@ -0,0 +1,342 @@ +/* + * (C) Dominik Brodowski 2003 + * + * Driver to use the Power Management Timer (PMTMR) available in some + * southbridges as primary timing source for the Linux kernel. + * + * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, + * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. + * + * This file is licensed under the GPL v2. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mach_timer.h" + +/* Number of PMTMR ticks expected during calibration run */ +#define PMTMR_TICKS_PER_SEC 3579545 +#define PMTMR_EXPECTED_RATE \ + ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10)) + + +/* The I/O port the PMTMR resides at. + * The location is detected during setup_arch(), + * in arch/i386/acpi/boot.c */ +u32 pmtmr_ioport = 0; + + +/* value of the Power timer at last timer interrupt */ +static u32 offset_tick; +static u32 offset_delay; + +static unsigned long long monotonic_base; +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; + +#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ + +static int pmtmr_need_workaround __read_mostly = 1; + +/*helper function to safely read acpi pm timesource*/ +static inline u32 read_pmtmr(void) +{ + if (pmtmr_need_workaround) { + u32 v1, v2, v3; + + /* It has been reported that because of various broken + * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time + * source is not latched, so you must read it multiple + * times to insure a safe value is read. + */ + do { + v1 = inl(pmtmr_ioport); + v2 = inl(pmtmr_ioport); + v3 = inl(pmtmr_ioport); + } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) + || (v3 > v1 && v3 < v2)); + + /* mask the output to 24 bits */ + return v2 & ACPI_PM_MASK; + } + + return inl(pmtmr_ioport) & ACPI_PM_MASK; +} + + +/* + * Some boards have the PMTMR running way too fast. We check + * the PMTMR rate against PIT channel 2 to catch these cases. + */ +static int verify_pmtmr_rate(void) +{ + u32 value1, value2; + unsigned long count, delta; + + mach_prepare_counter(); + value1 = read_pmtmr(); + mach_countup(&count); + value2 = read_pmtmr(); + delta = (value2 - value1) & ACPI_PM_MASK; + + /* Check that the PMTMR delta is within 5% of what we expect */ + if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || + delta > (PMTMR_EXPECTED_RATE * 21) / 20) { + printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE); + return -1; + } + + return 0; +} + + +static int init_pmtmr(char* override) +{ + u32 value1, value2; + unsigned int i; + + if (override[0] && strncmp(override,"pmtmr",5)) + return -ENODEV; + + if (!pmtmr_ioport) + return -ENODEV; + + /* we use the TSC for delay_pmtmr, so make sure it exists */ + if (!cpu_has_tsc) + return -ENODEV; + + /* "verify" this timing source */ + value1 = read_pmtmr(); + for (i = 0; i < 10000; i++) { + value2 = read_pmtmr(); + if (value2 == value1) + continue; + if (value2 > value1) + goto pm_good; + if ((value2 < value1) && ((value2) < 0xFFF)) + goto pm_good; + printk(KERN_INFO "PM-Timer had inconsistent results: 0x%#x, 0x%#x - aborting.\n", value1, value2); + return -EINVAL; + } + printk(KERN_INFO "PM-Timer had no reasonable result: 0x%#x - aborting.\n", value1); + return -ENODEV; + +pm_good: + if (verify_pmtmr_rate() != 0) + return -ENODEV; + + init_cpu_khz(); + return 0; +} + +static inline u32 cyc2us(u32 cycles) +{ + /* The Power Management Timer ticks at 3.579545 ticks per microsecond. + * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%] + * + * Even with HZ = 100, delta is at maximum 35796 ticks, so it can + * easily be multiplied with 286 (=0x11E) without having to fear + * u32 overflows. + */ + cycles *= 286; + return (cycles >> 10); +} + +/* + * this gets called during each timer interrupt + * - Called while holding the writer xtime_lock + */ +static void mark_offset_pmtmr(void) +{ + u32 lost, delta, last_offset; + static int first_run = 1; + last_offset = offset_tick; + + write_seqlock(&monotonic_lock); + + offset_tick = read_pmtmr(); + + /* calculate tick interval */ + delta = (offset_tick - last_offset) & ACPI_PM_MASK; + + /* convert to usecs */ + delta = cyc2us(delta); + + /* update the monotonic base value */ + monotonic_base += delta * NSEC_PER_USEC; + write_sequnlock(&monotonic_lock); + + /* convert to ticks */ + delta += offset_delay; + lost = delta / (USEC_PER_SEC / HZ); + offset_delay = delta % (USEC_PER_SEC / HZ); + + + /* compensate for lost ticks */ + if (lost >= 2) + jiffies_64 += lost - 1; + + /* don't calculate delay for first run, + or if we've got less then a tick */ + if (first_run || (lost < 1)) { + first_run = 0; + offset_delay = 0; + } +} + +static int pmtmr_resume(void) +{ + write_seqlock(&monotonic_lock); + /* Assume this is the last mark offset time */ + offset_tick = read_pmtmr(); + write_sequnlock(&monotonic_lock); + return 0; +} + +static unsigned long long monotonic_clock_pmtmr(void) +{ + u32 last_offset, this_offset; + unsigned long long base, ret; + unsigned seq; + + + /* atomically read monotonic base & last_offset */ + do { + seq = read_seqbegin(&monotonic_lock); + last_offset = offset_tick; + base = monotonic_base; + } while (read_seqretry(&monotonic_lock, seq)); + + /* Read the pmtmr */ + this_offset = read_pmtmr(); + + /* convert to nanoseconds */ + ret = (this_offset - last_offset) & ACPI_PM_MASK; + ret = base + (cyc2us(ret) * NSEC_PER_USEC); + return ret; +} + +static void delay_pmtmr(unsigned long loops) +{ + unsigned long bclock, now; + + rdtscl(bclock); + do + { + rep_nop(); + rdtscl(now); + } while ((now-bclock) < loops); +} + + +/* + * get the offset (in microseconds) from the last call to mark_offset() + * - Called holding a reader xtime_lock + */ +static unsigned long get_offset_pmtmr(void) +{ + u32 now, offset, delta = 0; + + offset = offset_tick; + now = read_pmtmr(); + delta = (now - offset)&ACPI_PM_MASK; + + return (unsigned long) offset_delay + cyc2us(delta); +} + + +/* acpi timer_opts struct */ +static struct timer_opts timer_pmtmr = { + .name = "pmtmr", + .mark_offset = mark_offset_pmtmr, + .get_offset = get_offset_pmtmr, + .monotonic_clock = monotonic_clock_pmtmr, + .delay = delay_pmtmr, + .read_timer = read_timer_tsc, + .resume = pmtmr_resume, +}; + +struct init_timer_opts __initdata timer_pmtmr_init = { + .init = init_pmtmr, + .opts = &timer_pmtmr, +}; + +#ifdef CONFIG_PCI +/* + * PIIX4 Errata: + * + * The power management timer may return improper results when read. + * Although the timer value settles properly after incrementing, + * while incrementing there is a 3 ns window every 69.8 ns where the + * timer value is indeterminate (a 4.2% chance that the data will be + * incorrect when read). As a result, the ACPI free running count up + * timer specification is violated due to erroneous reads. + */ +static int __init pmtmr_bug_check(void) +{ + static struct pci_device_id gray_list[] __initdata = { + /* these chipsets may have bug. */ + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82801DB_0) }, + { }, + }; + struct pci_dev *dev; + int pmtmr_has_bug = 0; + u8 rev; + + if (cur_timer != &timer_pmtmr || !pmtmr_need_workaround) + return 0; + + dev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, NULL); + if (dev) { + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); + /* the bug has been fixed in PIIX4M */ + if (rev < 3) { + printk(KERN_WARNING "* Found PM-Timer Bug on this " + "chipset. Due to workarounds for a bug,\n" + "* this time source is slow. Consider trying " + "other time sources (clock=)\n"); + pmtmr_has_bug = 1; + } + pci_dev_put(dev); + } + + if (pci_dev_present(gray_list)) { + printk(KERN_WARNING "* This chipset may have PM-Timer Bug. Due" + " to workarounds for a bug,\n" + "* this time source is slow. If you are sure your timer" + " does not have\n" + "* this bug, please use \"pmtmr_good\" to disable the " + "workaround\n"); + pmtmr_has_bug = 1; + } + + if (!pmtmr_has_bug) + pmtmr_need_workaround = 0; + + return 0; +} +device_initcall(pmtmr_bug_check); +#endif + +static int __init pmtr_good_setup(char *__str) +{ + pmtmr_need_workaround = 0; + return 1; +} +__setup("pmtmr_good", pmtr_good_setup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dominik Brodowski "); +MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86"); diff --git a/trunk/arch/i386/kernel/timers/timer_tsc.c b/trunk/arch/i386/kernel/timers/timer_tsc.c new file mode 100644 index 000000000000..f1187ddb0d0f --- /dev/null +++ b/trunk/arch/i386/kernel/timers/timer_tsc.c @@ -0,0 +1,617 @@ +/* + * This code largely moved from arch/i386/kernel/time.c. + * See comments there for proper credits. + * + * 2004-06-25 Jesper Juhl + * moved mark_offset_tsc below cpufreq_delayed_get to avoid gcc 3.4 + * failing to inline. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +/* processor.h for distable_tsc flag */ +#include + +#include "io_ports.h" +#include "mach_timer.h" + +#include +#include + +#ifdef CONFIG_HPET_TIMER +static unsigned long hpet_usec_quotient; +static unsigned long hpet_last; +static struct timer_opts timer_tsc; +#endif + +static inline void cpufreq_delayed_get(void); + +int tsc_disable __devinitdata = 0; + +static int use_tsc; +/* Number of usecs that the last interrupt was delayed */ +static int delay_at_last_interrupt; + +static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ +static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ +static unsigned long long monotonic_base; +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; + +/* Avoid compensating for lost ticks before TSCs are synched */ +static int detect_lost_ticks; +static int __init start_lost_tick_compensation(void) +{ + detect_lost_ticks = 1; + return 0; +} +late_initcall(start_lost_tick_compensation); + +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_khz * 10^3)) + * ns = cycles * (10^6 / cpu_khz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^6 * SC / cpu_khz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * + * We can use khz divisor instead of mhz to keep a better percision, since + * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. + * (mathieu.desnoyers@polymtl.ca) + * + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale __read_mostly; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_khz) +{ + cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +static int count2; /* counter for mark_offset_tsc() */ + +/* Cached *multiplier* to convert TSC counts to microseconds. + * (see the equation below). + * Equal to 2^32 * (1 / (clocks per usec) ). + * Initialized in time_init. + */ +static unsigned long fast_gettimeoffset_quotient; + +static unsigned long get_offset_tsc(void) +{ + register unsigned long eax, edx; + + /* Read the Time Stamp Counter */ + + rdtsc(eax,edx); + + /* .. relative to previous jiffy (32 bits is enough) */ + eax -= last_tsc_low; /* tsc_low delta */ + + /* + * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient + * = (tsc_low delta) * (usecs_per_clock) + * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) + * + * Using a mull instead of a divl saves up to 31 clock cycles + * in the critical path. + */ + + __asm__("mull %2" + :"=a" (eax), "=d" (edx) + :"rm" (fast_gettimeoffset_quotient), + "0" (eax)); + + /* our adjusted time offset in microseconds */ + return delay_at_last_interrupt + edx; +} + +static unsigned long long monotonic_clock_tsc(void) +{ + unsigned long long last_offset, this_offset, base; + unsigned seq; + + /* atomically read monotonic base & last_offset */ + do { + seq = read_seqbegin(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + base = monotonic_base; + } while (read_seqretry(&monotonic_lock, seq)); + + /* Read the Time Stamp Counter */ + rdtscll(this_offset); + + /* return the value in ns */ + return base + cycles_2_ns(this_offset - last_offset); +} + +/* + * Scheduler clock - returns current time in nanosec units. + */ +unsigned long long sched_clock(void) +{ + unsigned long long this_offset; + + /* + * In the NUMA case we dont use the TSC as they are not + * synchronized across all CPUs. + */ +#ifndef CONFIG_NUMA + if (!use_tsc) +#endif + /* no locking but a rare wrong value is not a big deal */ + return jiffies_64 * (1000000000 / HZ); + + /* Read the Time Stamp Counter */ + rdtscll(this_offset); + + /* return the value in ns */ + return cycles_2_ns(this_offset); +} + +static void delay_tsc(unsigned long loops) +{ + unsigned long bclock, now; + + rdtscl(bclock); + do + { + rep_nop(); + rdtscl(now); + } while ((now-bclock) < loops); +} + +#ifdef CONFIG_HPET_TIMER +static void mark_offset_tsc_hpet(void) +{ + unsigned long long this_offset, last_offset; + unsigned long offset, temp, hpet_current; + + write_seqlock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + /* + * It is important that these two operations happen almost at + * the same time. We do the RDTSC stuff first, since it's + * faster. To avoid any inconsistencies, we need interrupts + * disabled locally. + */ + /* + * Interrupts are just disabled locally since the timer irq + * has the SA_INTERRUPT flag set. -arca + */ + /* read Pentium cycle counter */ + + hpet_current = hpet_readl(HPET_COUNTER); + rdtsc(last_tsc_low, last_tsc_high); + + /* lost tick compensation */ + offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) + && detect_lost_ticks) { + int lost_ticks = (offset - hpet_last) / hpet_tick; + jiffies_64 += lost_ticks; + } + hpet_last = hpet_current; + + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_sequnlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ + /* + * Time offset = (hpet delta) * ( usecs per HPET clock ) + * = (hpet delta) * ( usecs per tick / HPET clocks per tick) + * = (hpet delta) * ( hpet_usec_quotient ) / (2^32) + * Where, + * hpet_usec_quotient = (2^32 * usecs per tick)/HPET clocks per tick + */ + delay_at_last_interrupt = hpet_current - offset; + ASM_MUL64_REG(temp, delay_at_last_interrupt, + hpet_usec_quotient, delay_at_last_interrupt); +} +#endif + + +#ifdef CONFIG_CPU_FREQ +#include + +static unsigned int cpufreq_delayed_issched = 0; +static unsigned int cpufreq_init = 0; +static struct work_struct cpufreq_delayed_get_work; + +static void handle_cpufreq_delayed_get(void *v) +{ + unsigned int cpu; + for_each_online_cpu(cpu) { + cpufreq_get(cpu); + } + cpufreq_delayed_issched = 0; +} + +/* if we notice lost ticks, schedule a call to cpufreq_get() as it tries + * to verify the CPU frequency the timing core thinks the CPU is running + * at is still correct. + */ +static inline void cpufreq_delayed_get(void) +{ + if (cpufreq_init && !cpufreq_delayed_issched) { + cpufreq_delayed_issched = 1; + printk(KERN_DEBUG "Losing some ticks... checking if CPU frequency changed.\n"); + schedule_work(&cpufreq_delayed_get_work); + } +} + +/* If the CPU frequency is scaled, TSC-based delays will need a different + * loops_per_jiffy value to function properly. + */ + +static unsigned int ref_freq = 0; +static unsigned long loops_per_jiffy_ref = 0; + +#ifndef CONFIG_SMP +static unsigned long fast_gettimeoffset_ref = 0; +static unsigned int cpu_khz_ref = 0; +#endif + +static int +time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct cpufreq_freqs *freq = data; + + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_seqlock_irq(&xtime_lock); + if (!ref_freq) { + if (!freq->old){ + ref_freq = freq->new; + goto end; + } + ref_freq = freq->old; + loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; +#ifndef CONFIG_SMP + fast_gettimeoffset_ref = fast_gettimeoffset_quotient; + cpu_khz_ref = cpu_khz; +#endif + } + + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || + (val == CPUFREQ_RESUMECHANGE)) { + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) + cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); +#ifndef CONFIG_SMP + if (cpu_khz) + cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); + if (use_tsc) { + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { + fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq); + set_cyc2ns_scale(cpu_khz); + } + } +#endif + } + +end: + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_sequnlock_irq(&xtime_lock); + + return 0; +} + +static struct notifier_block time_cpufreq_notifier_block = { + .notifier_call = time_cpufreq_notifier +}; + + +static int __init cpufreq_tsc(void) +{ + int ret; + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); + ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + if (!ret) + cpufreq_init = 1; + return ret; +} +core_initcall(cpufreq_tsc); + +#else /* CONFIG_CPU_FREQ */ +static inline void cpufreq_delayed_get(void) { return; } +#endif + +int recalibrate_cpu_khz(void) +{ +#ifndef CONFIG_SMP + unsigned int cpu_khz_old = cpu_khz; + + if (cpu_has_tsc) { + local_irq_disable(); + init_cpu_khz(); + local_irq_enable(); + cpu_data[0].loops_per_jiffy = + cpufreq_scale(cpu_data[0].loops_per_jiffy, + cpu_khz_old, + cpu_khz); + return 0; + } else + return -ENODEV; +#else + return -ENODEV; +#endif +} +EXPORT_SYMBOL(recalibrate_cpu_khz); + +static void mark_offset_tsc(void) +{ + unsigned long lost,delay; + unsigned long delta = last_tsc_low; + int count; + int countmp; + static int count1 = 0; + unsigned long long this_offset, last_offset; + static int lost_count = 0; + + write_seqlock(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + /* + * It is important that these two operations happen almost at + * the same time. We do the RDTSC stuff first, since it's + * faster. To avoid any inconsistencies, we need interrupts + * disabled locally. + */ + + /* + * Interrupts are just disabled locally since the timer irq + * has the SA_INTERRUPT flag set. -arca + */ + + /* read Pentium cycle counter */ + + rdtsc(last_tsc_low, last_tsc_high); + + spin_lock(&i8253_lock); + outb_p(0x00, PIT_MODE); /* latch the count ASAP */ + + count = inb_p(PIT_CH0); /* read the latched count */ + count |= inb(PIT_CH0) << 8; + + /* + * VIA686a test code... reset the latch if count > max + 1 + * from timer_pit.c - cjb + */ + if (count > LATCH) { + outb_p(0x34, PIT_MODE); + outb_p(LATCH & 0xff, PIT_CH0); + outb(LATCH >> 8, PIT_CH0); + count = LATCH - 1; + } + + spin_unlock(&i8253_lock); + + if (pit_latch_buggy) { + /* get center value of last 3 time lutch */ + if ((count2 >= count && count >= count1) + || (count1 >= count && count >= count2)) { + count2 = count1; count1 = count; + } else if ((count1 >= count2 && count2 >= count) + || (count >= count2 && count2 >= count1)) { + countmp = count;count = count2; + count2 = count1;count1 = countmp; + } else { + count2 = count1; count1 = count; count = count1; + } + } + + /* lost tick compensation */ + delta = last_tsc_low - delta; + { + register unsigned long eax, edx; + eax = delta; + __asm__("mull %2" + :"=a" (eax), "=d" (edx) + :"rm" (fast_gettimeoffset_quotient), + "0" (eax)); + delta = edx; + } + delta += delay_at_last_interrupt; + lost = delta/(1000000/HZ); + delay = delta%(1000000/HZ); + if (lost >= 2 && detect_lost_ticks) { + jiffies_64 += lost-1; + + /* sanity check to ensure we're not always losing ticks */ + if (lost_count++ > 100) { + printk(KERN_WARNING "Losing too many ticks!\n"); + printk(KERN_WARNING "TSC cannot be used as a timesource. \n"); + printk(KERN_WARNING "Possible reasons for this are:\n"); + printk(KERN_WARNING " You're running with Speedstep,\n"); + printk(KERN_WARNING " You don't have DMA enabled for your hard disk (see hdparm),\n"); + printk(KERN_WARNING " Incorrect TSC synchronization on an SMP system (see dmesg).\n"); + printk(KERN_WARNING "Falling back to a sane timesource now.\n"); + + clock_fallback(); + } + /* ... but give the TSC a fair chance */ + if (lost_count > 25) + cpufreq_delayed_get(); + } else + lost_count = 0; + /* update the monotonic base value */ + this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + monotonic_base += cycles_2_ns(this_offset - last_offset); + write_sequnlock(&monotonic_lock); + + /* calculate delay_at_last_interrupt */ + count = ((LATCH-1) - count) * TICK_SIZE; + delay_at_last_interrupt = (count + LATCH/2) / LATCH; + + /* catch corner case where tick rollover occured + * between tsc and pit reads (as noted when + * usec delta is > 90% # of usecs/tick) + */ + if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ)) + jiffies_64++; +} + +static int __init init_tsc(char* override) +{ + + /* check clock override */ + if (override[0] && strncmp(override,"tsc",3)) { +#ifdef CONFIG_HPET_TIMER + if (is_hpet_enabled()) { + printk(KERN_ERR "Warning: clock= override failed. Defaulting to tsc\n"); + } else +#endif + { + return -ENODEV; + } + } + + /* + * If we have APM enabled or the CPU clock speed is variable + * (CPU stops clock on HLT or slows clock to save power) + * then the TSC timestamps may diverge by up to 1 jiffy from + * 'real time' but nothing will break. + * The most frequent case is that the CPU is "woken" from a halt + * state by the timer interrupt itself, so we get 0 error. In the + * rare cases where a driver would "wake" the CPU and request a + * timestamp, the maximum error is < 1 jiffy. But timestamps are + * still perfectly ordered. + * Note that the TSC counter will be reset if APM suspends + * to disk; this won't break the kernel, though, 'cuz we're + * smart. See arch/i386/kernel/apm.c. + */ + /* + * Firstly we have to do a CPU check for chips with + * a potentially buggy TSC. At this point we haven't run + * the ident/bugs checks so we must run this hook as it + * may turn off the TSC flag. + * + * NOTE: this doesn't yet handle SMP 486 machines where only + * some CPU's have a TSC. Thats never worked and nobody has + * moaned if you have the only one in the world - you fix it! + */ + + count2 = LATCH; /* initialize counter for mark_offset_tsc() */ + + if (cpu_has_tsc) { + unsigned long tsc_quotient; +#ifdef CONFIG_HPET_TIMER + if (is_hpet_enabled() && hpet_use_timer) { + unsigned long result, remain; + printk("Using TSC for gettimeofday\n"); + tsc_quotient = calibrate_tsc_hpet(NULL); + timer_tsc.mark_offset = &mark_offset_tsc_hpet; + /* + * Math to calculate hpet to usec multiplier + * Look for the comments at get_offset_tsc_hpet() + */ + ASM_DIV64_REG(result, remain, hpet_tick, + 0, KERNEL_TICK_USEC); + if (remain > (hpet_tick >> 1)) + result++; /* rounding the result */ + + hpet_usec_quotient = result; + } else +#endif + { + tsc_quotient = calibrate_tsc(); + } + + if (tsc_quotient) { + fast_gettimeoffset_quotient = tsc_quotient; + use_tsc = 1; + /* + * We could be more selective here I suspect + * and just enable this for the next intel chips ? + */ + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000; + __asm__("divl %2" + :"=a" (cpu_khz), "=d" (edx) + :"r" (tsc_quotient), + "0" (eax), "1" (edx)); + printk("Detected %u.%03u MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + } + set_cyc2ns_scale(cpu_khz); + return 0; + } + } + return -ENODEV; +} + +static int tsc_resume(void) +{ + write_seqlock(&monotonic_lock); + /* Assume this is the last mark offset time */ + rdtsc(last_tsc_low, last_tsc_high); +#ifdef CONFIG_HPET_TIMER + if (is_hpet_enabled() && hpet_use_timer) + hpet_last = hpet_readl(HPET_COUNTER); +#endif + write_sequnlock(&monotonic_lock); + return 0; +} + +#ifndef CONFIG_X86_TSC +/* disable flag for tsc. Takes effect by clearing the TSC cpu flag + * in cpu/common.c */ +static int __init tsc_setup(char *str) +{ + tsc_disable = 1; + return 1; +} +#else +static int __init tsc_setup(char *str) +{ + printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " + "cannot disable TSC.\n"); + return 1; +} +#endif +__setup("notsc", tsc_setup); + + + +/************************************************************/ + +/* tsc timer_opts struct */ +static struct timer_opts timer_tsc = { + .name = "tsc", + .mark_offset = mark_offset_tsc, + .get_offset = get_offset_tsc, + .monotonic_clock = monotonic_clock_tsc, + .delay = delay_tsc, + .read_timer = read_timer_tsc, + .resume = tsc_resume, +}; + +struct init_timer_opts __initdata timer_tsc_init = { + .init = init_tsc, + .opts = &timer_tsc, +}; diff --git a/trunk/arch/i386/kernel/topology.c b/trunk/arch/i386/kernel/topology.c index e2e281d4bcc8..296355292c7c 100644 --- a/trunk/arch/i386/kernel/topology.c +++ b/trunk/arch/i386/kernel/topology.c @@ -32,8 +32,15 @@ static struct i386_cpu cpu_devices[NR_CPUS]; -int arch_register_cpu(int num) -{ +int arch_register_cpu(int num){ + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + if (node_online(node)) + parent = &node_devices[node].node; +#endif /* CONFIG_NUMA */ + /* * CPU0 cannot be offlined due to several * restrictions and assumptions in kernel. This basically @@ -43,13 +50,21 @@ int arch_register_cpu(int num) if (!num) cpu_devices[num].cpu.no_control = 1; - return register_cpu(&cpu_devices[num].cpu, num); + return register_cpu(&cpu_devices[num].cpu, num, parent); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - return unregister_cpu(&cpu_devices[num].cpu); + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + if (node_online(node)) + parent = &node_devices[node].node; +#endif /* CONFIG_NUMA */ + + return unregister_cpu(&cpu_devices[num].cpu, parent); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -59,13 +74,16 @@ EXPORT_SYMBOL(arch_unregister_cpu); #ifdef CONFIG_NUMA #include +#include + +struct i386_node node_devices[MAX_NUMNODES]; static int __init topology_init(void) { int i; for_each_online_node(i) - register_one_node(i); + arch_register_node(i); for_each_present_cpu(i) arch_register_cpu(i); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 78464097470a..0e498369f35e 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -28,7 +28,6 @@ #include #include #include -#include #ifdef CONFIG_EISA #include @@ -48,7 +47,7 @@ #include #include #include -#include + #include #include #include @@ -93,7 +92,6 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; -static int call_trace = 1; ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -151,12 +149,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, while (valid_stack_ptr(tinfo, (void *)ebp)) { addr = *(unsigned long *)(ebp + 4); printed = print_addr_and_symbol(addr, log_lvl, printed); - /* - * break out of recursive entries (such as - * end_of_stack_stop_unwind_function): - */ - if (ebp == *(unsigned long *)ebp) - break; ebp = *(unsigned long *)ebp; } #else @@ -172,23 +164,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return ebp; } -static asmlinkage int show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) -{ - int n = 0; - int printed = 0; /* nr of entries already printed on current line */ - - while (unwind(info) == 0 && UNW_PC(info)) { - ++n; - printed = print_addr_and_symbol(UNW_PC(info), log_lvl, printed); - if (arch_unw_user_mode(info)) - break; - } - if (printed) - printk("\n"); - return n; -} - -static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +static void show_trace_log_lvl(struct task_struct *task, unsigned long *stack, char *log_lvl) { unsigned long ebp; @@ -196,26 +172,6 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (!task) task = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - - if (regs) { - if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = show_trace_unwind(&info, log_lvl); - } else if (task == current) - unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); - else { - if (unwind_init_blocked(&info, task) == 0) - unw_ret = show_trace_unwind(&info, log_lvl); - } - if (unw_ret > 0) { - if (call_trace > 0) - return; - printk("%sLegacy call trace:\n", log_lvl); - } - } - if (task == current) { /* Grab ebp right from our regs */ asm ("movl %%ebp, %0" : "=r" (ebp) : ); @@ -236,13 +192,13 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, } } -void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) +void show_trace(struct task_struct *task, unsigned long * stack) { - show_trace_log_lvl(task, regs, stack, ""); + show_trace_log_lvl(task, stack, ""); } -static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *esp, char *log_lvl) +static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, + char *log_lvl) { unsigned long *stack; int i; @@ -263,13 +219,13 @@ static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, printk("%08lx ", *stack++); } printk("\n%sCall Trace:\n", log_lvl); - show_trace_log_lvl(task, regs, esp, log_lvl); + show_trace_log_lvl(task, esp, log_lvl); } void show_stack(struct task_struct *task, unsigned long *esp) { printk(" "); - show_stack_log_lvl(task, NULL, esp, ""); + show_stack_log_lvl(task, esp, ""); } /* @@ -279,7 +235,7 @@ void dump_stack(void) { unsigned long stack; - show_trace(current, NULL, &stack); + show_trace(current, &stack); } EXPORT_SYMBOL(dump_stack); @@ -312,9 +268,8 @@ void show_registers(struct pt_regs *regs) regs->esi, regs->edi, regs->ebp, esp); printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, ss); - printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", - TASK_COMM_LEN, current->comm, current->pid, - current_thread_info(), current, current->thread_info); + printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", + current->comm, current->pid, current_thread_info(), current); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -323,7 +278,7 @@ void show_registers(struct pt_regs *regs) u8 __user *eip; printk("\n" KERN_EMERG "Stack: "); - show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); + show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG); printk(KERN_EMERG "Code: "); @@ -1253,15 +1208,3 @@ static int __init kstack_setup(char *s) return 1; } __setup("kstack=", kstack_setup); - -static int __init call_trace_setup(char *s) -{ - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "new") == 0) - call_trace = 1; - return 1; -} -__setup("call_trace=", call_trace_setup); diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c deleted file mode 100644 index 7e0d8dab2075..000000000000 --- a/trunk/arch/i386/kernel/tsc.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * This code largely moved from arch/i386/kernel/timer/timer_tsc.c - * which was originally moved from arch/i386/kernel/time.c. - * See comments there for proper credits. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mach_timer.h" - -/* - * On some systems the TSC frequency does not - * change with the cpu frequency. So we need - * an extra value to store the TSC freq - */ -unsigned int tsc_khz; - -int tsc_disable __cpuinitdata = 0; - -#ifdef CONFIG_X86_TSC -static int __init tsc_setup(char *str) -{ - printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC.\n"); - return 1; -} -#else -/* - * disable flag for tsc. Takes effect by clearing the TSC cpu flag - * in cpu/common.c - */ -static int __init tsc_setup(char *str) -{ - tsc_disable = 1; - - return 1; -} -#endif - -__setup("notsc", tsc_setup); - -/* - * code to mark and check if the TSC is unstable - * due to cpufreq or due to unsynced TSCs - */ -static int tsc_unstable; - -static inline int check_tsc_unstable(void) -{ - return tsc_unstable; -} - -void mark_tsc_unstable(void) -{ - tsc_unstable = 1; -} -EXPORT_SYMBOL_GPL(mark_tsc_unstable); - -/* Accellerators for sched_clock() - * convert from cycles(64bits) => nanoseconds (64bits) - * basic equation: - * ns = cycles / (freq / ns_per_sec) - * ns = cycles * (ns_per_sec / freq) - * ns = cycles * (10^9 / (cpu_khz * 10^3)) - * ns = cycles * (10^6 / cpu_khz) - * - * Then we use scaling math (suggested by george@mvista.com) to get: - * ns = cycles * (10^6 * SC / cpu_khz) / SC - * ns = cycles * cyc2ns_scale / SC - * - * And since SC is a constant power of two, we can convert the div - * into a shift. - * - * We can use khz divisor instead of mhz to keep a better percision, since - * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - * (mathieu.desnoyers@polymtl.ca) - * - * -johnstul@us.ibm.com "math is hard, lets go shopping!" - */ -static unsigned long cyc2ns_scale __read_mostly; - -#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ - -static inline void set_cyc2ns_scale(unsigned long cpu_khz) -{ - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; -} - -static inline unsigned long long cycles_2_ns(unsigned long long cyc) -{ - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; -} - -/* - * Scheduler clock - returns current time in nanosec units. - */ -unsigned long long sched_clock(void) -{ - unsigned long long this_offset; - - /* - * in the NUMA case we dont use the TSC as they are not - * synchronized across all CPUs. - */ -#ifndef CONFIG_NUMA - if (!cpu_khz || check_tsc_unstable()) -#endif - /* no locking but a rare wrong value is not a big deal */ - return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); - - /* read the Time Stamp Counter: */ - rdtscll(this_offset); - - /* return the value in ns */ - return cycles_2_ns(this_offset); -} - -static unsigned long calculate_cpu_khz(void) -{ - unsigned long long start, end; - unsigned long count; - u64 delta64; - int i; - unsigned long flags; - - local_irq_save(flags); - - /* run 3 times to ensure the cache is warm */ - for (i = 0; i < 3; i++) { - mach_prepare_counter(); - rdtscll(start); - mach_countup(&count); - rdtscll(end); - } - /* - * Error: ECTCNEVERSET - * The CTC wasn't reliable: we got a hit on the very first read, - * or the CPU was so fast/slow that the quotient wouldn't fit in - * 32 bits.. - */ - if (count <= 1) - goto err; - - delta64 = end - start; - - /* cpu freq too fast: */ - if (delta64 > (1ULL<<32)) - goto err; - - /* cpu freq too slow: */ - if (delta64 <= CALIBRATE_TIME_MSEC) - goto err; - - delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ - do_div(delta64,CALIBRATE_TIME_MSEC); - - local_irq_restore(flags); - return (unsigned long)delta64; -err: - local_irq_restore(flags); - return 0; -} - -int recalibrate_cpu_khz(void) -{ -#ifndef CONFIG_SMP - unsigned long cpu_khz_old = cpu_khz; - - if (cpu_has_tsc) { - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; - cpu_data[0].loops_per_jiffy = - cpufreq_scale(cpu_data[0].loops_per_jiffy, - cpu_khz_old, cpu_khz); - return 0; - } else - return -ENODEV; -#else - return -ENODEV; -#endif -} - -EXPORT_SYMBOL(recalibrate_cpu_khz); - -void tsc_init(void) -{ - if (!cpu_has_tsc || tsc_disable) - return; - - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; - - if (!cpu_khz) - return; - - printk("Detected %lu.%03lu MHz processor.\n", - (unsigned long)cpu_khz / 1000, - (unsigned long)cpu_khz % 1000); - - set_cyc2ns_scale(cpu_khz); - use_tsc_delay(); -} - -#ifdef CONFIG_CPU_FREQ - -static unsigned int cpufreq_delayed_issched = 0; -static unsigned int cpufreq_init = 0; -static struct work_struct cpufreq_delayed_get_work; - -static void handle_cpufreq_delayed_get(void *v) -{ - unsigned int cpu; - - for_each_online_cpu(cpu) - cpufreq_get(cpu); - - cpufreq_delayed_issched = 0; -} - -/* - * if we notice cpufreq oddness, schedule a call to cpufreq_get() as it tries - * to verify the CPU frequency the timing core thinks the CPU is running - * at is still correct. - */ -static inline void cpufreq_delayed_get(void) -{ - if (cpufreq_init && !cpufreq_delayed_issched) { - cpufreq_delayed_issched = 1; - printk(KERN_DEBUG "Checking if CPU frequency changed.\n"); - schedule_work(&cpufreq_delayed_get_work); - } -} - -/* - * if the CPU frequency is scaled, TSC-based delays will need a different - * loops_per_jiffy value to function properly. - */ -static unsigned int ref_freq = 0; -static unsigned long loops_per_jiffy_ref = 0; -static unsigned long cpu_khz_ref = 0; - -static int -time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) -{ - struct cpufreq_freqs *freq = data; - - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_seqlock_irq(&xtime_lock); - - if (!ref_freq) { - if (!freq->old){ - ref_freq = freq->new; - goto end; - } - ref_freq = freq->old; - loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; - cpu_khz_ref = cpu_khz; - } - - if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || - (val == CPUFREQ_RESUMECHANGE)) { - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - cpu_data[freq->cpu].loops_per_jiffy = - cpufreq_scale(loops_per_jiffy_ref, - ref_freq, freq->new); - - if (cpu_khz) { - - if (num_online_cpus() == 1) - cpu_khz = cpufreq_scale(cpu_khz_ref, - ref_freq, freq->new); - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { - tsc_khz = cpu_khz; - set_cyc2ns_scale(cpu_khz); - /* - * TSC based sched_clock turns - * to junk w/ cpufreq - */ - mark_tsc_unstable(); - } - } - } -end: - if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) - write_sequnlock_irq(&xtime_lock); - - return 0; -} - -static struct notifier_block time_cpufreq_notifier_block = { - .notifier_call = time_cpufreq_notifier -}; - -static int __init cpufreq_tsc(void) -{ - int ret; - - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); - ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - if (!ret) - cpufreq_init = 1; - - return ret; -} - -core_initcall(cpufreq_tsc); - -#endif - -/* clock source code */ - -static unsigned long current_tsc_khz = 0; -static int tsc_update_callback(void); - -static cycle_t read_tsc(void) -{ - cycle_t ret; - - rdtscll(ret); - - return ret; -} - -static struct clocksource clocksource_tsc = { - .name = "tsc", - .rating = 300, - .read = read_tsc, - .mask = CLOCKSOURCE_MASK(64), - .mult = 0, /* to be set */ - .shift = 22, - .update_callback = tsc_update_callback, - .is_continuous = 1, -}; - -static int tsc_update_callback(void) -{ - int change = 0; - - /* check to see if we should switch to the safe clocksource: */ - if (clocksource_tsc.rating != 50 && check_tsc_unstable()) { - clocksource_tsc.rating = 50; - clocksource_reselect(); - change = 1; - } - - /* only update if tsc_khz has changed: */ - if (current_tsc_khz != tsc_khz) { - current_tsc_khz = tsc_khz; - clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz, - clocksource_tsc.shift); - change = 1; - } - - return change; -} - -static int __init dmi_mark_tsc_unstable(struct dmi_system_id *d) -{ - printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", - d->ident); - mark_tsc_unstable(); - return 0; -} - -/* List of systems that have known TSC problems */ -static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { - { - .callback = dmi_mark_tsc_unstable, - .ident = "IBM Thinkpad 380XD", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), - }, - }, - {} -}; - -#define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */ -static struct timer_list verify_tsc_freq_timer; - -/* XXX - Probably should add locking */ -static void verify_tsc_freq(unsigned long unused) -{ - static u64 last_tsc; - static unsigned long last_jiffies; - - u64 now_tsc, interval_tsc; - unsigned long now_jiffies, interval_jiffies; - - - if (check_tsc_unstable()) - return; - - rdtscll(now_tsc); - now_jiffies = jiffies; - - if (!last_jiffies) { - goto out; - } - - interval_jiffies = now_jiffies - last_jiffies; - interval_tsc = now_tsc - last_tsc; - interval_tsc *= HZ; - do_div(interval_tsc, cpu_khz*1000); - - if (interval_tsc < (interval_jiffies * 3 / 4)) { - printk("TSC appears to be running slowly. " - "Marking it as unstable\n"); - mark_tsc_unstable(); - return; - } - -out: - last_tsc = now_tsc; - last_jiffies = now_jiffies; - /* set us up to go off on the next interval: */ - mod_timer(&verify_tsc_freq_timer, - jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL)); -} - -/* - * Make an educated guess if the TSC is trustworthy and synchronized - * over all CPUs. - */ -static __init int unsynchronized_tsc(void) -{ - /* - * Intel systems are normally all synchronized. - * Exceptions must mark TSC as unstable: - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - return 0; - - /* assume multi socket systems are not synchronized: */ - return num_possible_cpus() > 1; -} - -static int __init init_tsc_clocksource(void) -{ - - if (cpu_has_tsc && tsc_khz && !tsc_disable) { - /* check blacklist */ - dmi_check_system(bad_tsc_dmi_table); - - if (unsynchronized_tsc()) /* mark unstable if unsynced */ - mark_tsc_unstable(); - current_tsc_khz = tsc_khz; - clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz, - clocksource_tsc.shift); - /* lower the rating if we already know its unstable: */ - if (check_tsc_unstable()) - clocksource_tsc.rating = 50; - - init_timer(&verify_tsc_freq_timer); - verify_tsc_freq_timer.function = verify_tsc_freq; - verify_tsc_freq_timer.expires = - jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL); - add_timer(&verify_tsc_freq_timer); - - return clocksource_register(&clocksource_tsc); - } - - return 0; -} - -module_init(init_tsc_clocksource); diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index 2d4f1386e2b1..8831303a473f 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -37,13 +37,6 @@ SECTIONS RODATA - . = ALIGN(4); - __tracedata_start = .; - .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { - *(.tracedata) - } - __tracedata_end = .; - /* writeable */ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ *(.data) @@ -71,15 +64,6 @@ SECTIONS .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } _edata = .; /* End of data section */ -#ifdef CONFIG_STACK_UNWIND - . = ALIGN(4); - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { - __start_unwind = .; - *(.eh_frame) - __end_unwind = .; - } -#endif - . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) diff --git a/trunk/arch/i386/kernel/vsyscall-sysenter.S b/trunk/arch/i386/kernel/vsyscall-sysenter.S index 1a36d26e15eb..3b62baa6a371 100644 --- a/trunk/arch/i386/kernel/vsyscall-sysenter.S +++ b/trunk/arch/i386/kernel/vsyscall-sysenter.S @@ -42,10 +42,10 @@ __kernel_vsyscall: /* 7: align return point with nop's to make disassembly easier */ .space 7,0x90 - /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ + /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */ jmp .Lenter_kernel /* 16: System call normal return point is here! */ - .globl SYSENTER_RETURN /* Symbol used by sysenter.c */ + .globl SYSENTER_RETURN /* Symbol used by entry.S. */ SYSENTER_RETURN: pop %ebp .Lpop_ebp: diff --git a/trunk/arch/i386/kernel/vsyscall.lds.S b/trunk/arch/i386/kernel/vsyscall.lds.S index e26975fc68b6..98699ca6e52d 100644 --- a/trunk/arch/i386/kernel/vsyscall.lds.S +++ b/trunk/arch/i386/kernel/vsyscall.lds.S @@ -7,7 +7,7 @@ SECTIONS { - . = VDSO_PRELINK + SIZEOF_HEADERS; + . = VSYSCALL_BASE + SIZEOF_HEADERS; .hash : { *(.hash) } :text .dynsym : { *(.dynsym) } @@ -20,7 +20,7 @@ SECTIONS For the layouts to match, we need to skip more than enough space for the dynamic symbol table et al. If this amount is insufficient, ld -shared will barf. Just increase it here. */ - . = VDSO_PRELINK + 0x400; + . = VSYSCALL_BASE + 0x400; .text : { *(.text) } :text =0x90909090 .note : { *(.note.*) } :text :note diff --git a/trunk/arch/i386/lib/delay.c b/trunk/arch/i386/lib/delay.c index 3c0714c4b669..c49a6acbee56 100644 --- a/trunk/arch/i386/lib/delay.c +++ b/trunk/arch/i386/lib/delay.c @@ -10,92 +10,43 @@ * we have to worry about. */ -#include #include #include #include - +#include #include #include #include #ifdef CONFIG_SMP -# include +#include #endif -/* simple loop based delay: */ -static void delay_loop(unsigned long loops) -{ - int d0; - - __asm__ __volatile__( - "\tjmp 1f\n" - ".align 16\n" - "1:\tjmp 2f\n" - ".align 16\n" - "2:\tdecl %0\n\tjns 2b" - :"=&a" (d0) - :"0" (loops)); -} - -/* TSC based delay: */ -static void delay_tsc(unsigned long loops) -{ - unsigned long bclock, now; - - rdtscl(bclock); - do { - rep_nop(); - rdtscl(now); - } while ((now-bclock) < loops); -} - -/* - * Since we calibrate only once at boot, this - * function should be set once at boot and not changed - */ -static void (*delay_fn)(unsigned long) = delay_loop; - -void use_tsc_delay(void) -{ - delay_fn = delay_tsc; -} - -int read_current_timer(unsigned long *timer_val) -{ - if (delay_fn == delay_tsc) { - rdtscl(*timer_val); - return 0; - } - return -1; -} +extern struct timer_opts* timer; void __delay(unsigned long loops) { - delay_fn(loops); + cur_timer->delay(loops); } inline void __const_udelay(unsigned long xloops) { int d0; - xloops *= 4; __asm__("mull %0" :"=d" (xloops), "=&a" (d0) - :"1" (xloops), "0" - (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))); - - __delay(++xloops); + :"1" (xloops),"0" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))); + __delay(++xloops); } void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ } void __ndelay(unsigned long nsecs) { - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } EXPORT_SYMBOL(__delay); diff --git a/trunk/arch/i386/lib/usercopy.c b/trunk/arch/i386/lib/usercopy.c index c5aa65f7c02a..4cf981d70f45 100644 --- a/trunk/arch/i386/lib/usercopy.c +++ b/trunk/arch/i386/lib/usercopy.c @@ -425,212 +425,15 @@ __copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size) : "eax", "edx", "memory"); return size; } - -/* - * Non Temporal Hint version of __copy_user_zeroing_intel. It is cache aware. - * hyoshiok@miraclelinux.com - */ - -static unsigned long __copy_user_zeroing_intel_nocache(void *to, - const void __user *from, unsigned long size) -{ - int d0, d1; - - __asm__ __volatile__( - " .align 2,0x90\n" - "0: movl 32(%4), %%eax\n" - " cmpl $67, %0\n" - " jbe 2f\n" - "1: movl 64(%4), %%eax\n" - " .align 2,0x90\n" - "2: movl 0(%4), %%eax\n" - "21: movl 4(%4), %%edx\n" - " movnti %%eax, 0(%3)\n" - " movnti %%edx, 4(%3)\n" - "3: movl 8(%4), %%eax\n" - "31: movl 12(%4),%%edx\n" - " movnti %%eax, 8(%3)\n" - " movnti %%edx, 12(%3)\n" - "4: movl 16(%4), %%eax\n" - "41: movl 20(%4), %%edx\n" - " movnti %%eax, 16(%3)\n" - " movnti %%edx, 20(%3)\n" - "10: movl 24(%4), %%eax\n" - "51: movl 28(%4), %%edx\n" - " movnti %%eax, 24(%3)\n" - " movnti %%edx, 28(%3)\n" - "11: movl 32(%4), %%eax\n" - "61: movl 36(%4), %%edx\n" - " movnti %%eax, 32(%3)\n" - " movnti %%edx, 36(%3)\n" - "12: movl 40(%4), %%eax\n" - "71: movl 44(%4), %%edx\n" - " movnti %%eax, 40(%3)\n" - " movnti %%edx, 44(%3)\n" - "13: movl 48(%4), %%eax\n" - "81: movl 52(%4), %%edx\n" - " movnti %%eax, 48(%3)\n" - " movnti %%edx, 52(%3)\n" - "14: movl 56(%4), %%eax\n" - "91: movl 60(%4), %%edx\n" - " movnti %%eax, 56(%3)\n" - " movnti %%edx, 60(%3)\n" - " addl $-64, %0\n" - " addl $64, %4\n" - " addl $64, %3\n" - " cmpl $63, %0\n" - " ja 0b\n" - " sfence \n" - "5: movl %0, %%eax\n" - " shrl $2, %0\n" - " andl $3, %%eax\n" - " cld\n" - "6: rep; movsl\n" - " movl %%eax,%0\n" - "7: rep; movsb\n" - "8:\n" - ".section .fixup,\"ax\"\n" - "9: lea 0(%%eax,%0,4),%0\n" - "16: pushl %0\n" - " pushl %%eax\n" - " xorl %%eax,%%eax\n" - " rep; stosb\n" - " popl %%eax\n" - " popl %0\n" - " jmp 8b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,16b\n" - " .long 1b,16b\n" - " .long 2b,16b\n" - " .long 21b,16b\n" - " .long 3b,16b\n" - " .long 31b,16b\n" - " .long 4b,16b\n" - " .long 41b,16b\n" - " .long 10b,16b\n" - " .long 51b,16b\n" - " .long 11b,16b\n" - " .long 61b,16b\n" - " .long 12b,16b\n" - " .long 71b,16b\n" - " .long 13b,16b\n" - " .long 81b,16b\n" - " .long 14b,16b\n" - " .long 91b,16b\n" - " .long 6b,9b\n" - " .long 7b,16b\n" - ".previous" - : "=&c"(size), "=&D" (d0), "=&S" (d1) - : "1"(to), "2"(from), "0"(size) - : "eax", "edx", "memory"); - return size; -} - -static unsigned long __copy_user_intel_nocache(void *to, - const void __user *from, unsigned long size) -{ - int d0, d1; - - __asm__ __volatile__( - " .align 2,0x90\n" - "0: movl 32(%4), %%eax\n" - " cmpl $67, %0\n" - " jbe 2f\n" - "1: movl 64(%4), %%eax\n" - " .align 2,0x90\n" - "2: movl 0(%4), %%eax\n" - "21: movl 4(%4), %%edx\n" - " movnti %%eax, 0(%3)\n" - " movnti %%edx, 4(%3)\n" - "3: movl 8(%4), %%eax\n" - "31: movl 12(%4),%%edx\n" - " movnti %%eax, 8(%3)\n" - " movnti %%edx, 12(%3)\n" - "4: movl 16(%4), %%eax\n" - "41: movl 20(%4), %%edx\n" - " movnti %%eax, 16(%3)\n" - " movnti %%edx, 20(%3)\n" - "10: movl 24(%4), %%eax\n" - "51: movl 28(%4), %%edx\n" - " movnti %%eax, 24(%3)\n" - " movnti %%edx, 28(%3)\n" - "11: movl 32(%4), %%eax\n" - "61: movl 36(%4), %%edx\n" - " movnti %%eax, 32(%3)\n" - " movnti %%edx, 36(%3)\n" - "12: movl 40(%4), %%eax\n" - "71: movl 44(%4), %%edx\n" - " movnti %%eax, 40(%3)\n" - " movnti %%edx, 44(%3)\n" - "13: movl 48(%4), %%eax\n" - "81: movl 52(%4), %%edx\n" - " movnti %%eax, 48(%3)\n" - " movnti %%edx, 52(%3)\n" - "14: movl 56(%4), %%eax\n" - "91: movl 60(%4), %%edx\n" - " movnti %%eax, 56(%3)\n" - " movnti %%edx, 60(%3)\n" - " addl $-64, %0\n" - " addl $64, %4\n" - " addl $64, %3\n" - " cmpl $63, %0\n" - " ja 0b\n" - " sfence \n" - "5: movl %0, %%eax\n" - " shrl $2, %0\n" - " andl $3, %%eax\n" - " cld\n" - "6: rep; movsl\n" - " movl %%eax,%0\n" - "7: rep; movsb\n" - "8:\n" - ".section .fixup,\"ax\"\n" - "9: lea 0(%%eax,%0,4),%0\n" - "16: jmp 8b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,16b\n" - " .long 1b,16b\n" - " .long 2b,16b\n" - " .long 21b,16b\n" - " .long 3b,16b\n" - " .long 31b,16b\n" - " .long 4b,16b\n" - " .long 41b,16b\n" - " .long 10b,16b\n" - " .long 51b,16b\n" - " .long 11b,16b\n" - " .long 61b,16b\n" - " .long 12b,16b\n" - " .long 71b,16b\n" - " .long 13b,16b\n" - " .long 81b,16b\n" - " .long 14b,16b\n" - " .long 91b,16b\n" - " .long 6b,9b\n" - " .long 7b,16b\n" - ".previous" - : "=&c"(size), "=&D" (d0), "=&S" (d1) - : "1"(to), "2"(from), "0"(size) - : "eax", "edx", "memory"); - return size; -} - #else - /* * Leave these declared but undefined. They should not be any references to * them */ -unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, - unsigned long size); -unsigned long __copy_user_intel(void __user *to, const void *from, - unsigned long size); -unsigned long __copy_user_zeroing_intel_nocache(void *to, - const void __user *from, unsigned long size); +unsigned long +__copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size); +unsigned long +__copy_user_intel(void __user *to, const void *from, unsigned long size); #endif /* CONFIG_X86_INTEL_USERCOPY */ /* Generic arbitrary sized copy. */ @@ -712,8 +515,8 @@ do { \ : "memory"); \ } while (0) -unsigned long __copy_to_user_ll(void __user *to, const void *from, - unsigned long n) + +unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n) { BUG_ON((long) n < 0); #ifndef CONFIG_X86_WP_WORKS_OK @@ -773,8 +576,8 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, } EXPORT_SYMBOL(__copy_to_user_ll); -unsigned long __copy_from_user_ll(void *to, const void __user *from, - unsigned long n) +unsigned long +__copy_from_user_ll(void *to, const void __user *from, unsigned long n) { BUG_ON((long)n < 0); if (movsl_is_ok(to, from, n)) @@ -785,49 +588,6 @@ unsigned long __copy_from_user_ll(void *to, const void __user *from, } EXPORT_SYMBOL(__copy_from_user_ll); -unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, - unsigned long n) -{ - BUG_ON((long)n < 0); - if (movsl_is_ok(to, from, n)) - __copy_user(to, from, n); - else - n = __copy_user_intel((void __user *)to, - (const void *)from, n); - return n; -} -EXPORT_SYMBOL(__copy_from_user_ll_nozero); - -unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, - unsigned long n) -{ - BUG_ON((long)n < 0); -#ifdef CONFIG_X86_INTEL_USERCOPY - if ( n > 64 && cpu_has_xmm2) - n = __copy_user_zeroing_intel_nocache(to, from, n); - else - __copy_user_zeroing(to, from, n); -#else - __copy_user_zeroing(to, from, n); -#endif - return n; -} - -unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, - unsigned long n) -{ - BUG_ON((long)n < 0); -#ifdef CONFIG_X86_INTEL_USERCOPY - if ( n > 64 && cpu_has_xmm2) - n = __copy_user_intel_nocache(to, from, n); - else - __copy_user(to, from, n); -#else - __copy_user(to, from, n); -#endif - return n; -} - /** * copy_to_user: - Copy a block of data into user space. * @to: Destination address, in user space. diff --git a/trunk/arch/i386/mach-default/setup.c b/trunk/arch/i386/mach-default/setup.c index 004837c58793..b4a7455c6993 100644 --- a/trunk/arch/i386/mach-default/setup.c +++ b/trunk/arch/i386/mach-default/setup.c @@ -8,8 +8,6 @@ #include #include #include -#include -#include #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) @@ -132,44 +130,3 @@ static int __init print_ipi_mode(void) } late_initcall(print_ipi_mode); - -/** - * machine_specific_memory_setup - Hook for machine specific memory setup. - * - * Description: - * This is included late in kernel/setup.c so that it can make - * use of all of the static functions. - **/ - -char * __init machine_specific_memory_setup(void) -{ - char *who; - - - who = "BIOS-e820"; - - /* - * Try to copy the BIOS-supplied E820-map. - * - * Otherwise fake a memory map; one section from 0k->640k, - * the next section from 1mb->appropriate_mem_k - */ - sanitize_e820_map(E820_MAP, &E820_MAP_NR); - if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { - unsigned long mem_size; - - /* compare results from other methods and take the greater */ - if (ALT_MEM_K < EXT_MEM_K) { - mem_size = EXT_MEM_K; - who = "BIOS-88"; - } else { - mem_size = ALT_MEM_K; - who = "BIOS-e801"; - } - - e820.nr_map = 0; - add_memory_region(0, LOWMEMSIZE(), E820_RAM); - add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); - } - return who; -} diff --git a/trunk/arch/i386/mach-visws/setup.c b/trunk/arch/i386/mach-visws/setup.c index 8a9e1a6f745d..07fac7e749c7 100644 --- a/trunk/arch/i386/mach-visws/setup.c +++ b/trunk/arch/i386/mach-visws/setup.c @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include "cobalt.h" #include "piix4.h" @@ -135,50 +133,3 @@ void __init time_init_hook(void) /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ setup_irq(0, &irq0); } - -/* Hook for machine specific memory setup. */ - -#define MB (1024 * 1024) - -static unsigned long sgivwfb_mem_phys; -static unsigned long sgivwfb_mem_size; - -long long mem_size __initdata = 0; - -char * __init machine_specific_memory_setup(void) -{ - long long gfx_mem_size = 8 * MB; - - mem_size = ALT_MEM_K; - - if (!mem_size) { - printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); - mem_size = 128 * MB; - } - - /* - * this hardcodes the graphics memory to 8 MB - * it really should be sized dynamically (or at least - * set as a boot param) - */ - if (!sgivwfb_mem_size) { - printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); - sgivwfb_mem_size = 8 * MB; - } - - /* - * Trim to nearest MB - */ - sgivwfb_mem_size &= ~((1 << 20) - 1); - sgivwfb_mem_phys = mem_size - gfx_mem_size; - - add_memory_region(0, LOWMEMSIZE(), E820_RAM); - add_memory_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); - add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); - - return "PROM"; - - /* Remove gcc warnings */ - (void) sanitize_e820_map(NULL, NULL); - (void) copy_e820_map(NULL, 0); -} diff --git a/trunk/arch/i386/mach-voyager/setup.c b/trunk/arch/i386/mach-voyager/setup.c index defc6ebbd565..7d8a3acb9441 100644 --- a/trunk/arch/i386/mach-voyager/setup.c +++ b/trunk/arch/i386/mach-voyager/setup.c @@ -5,11 +5,8 @@ #include #include #include +#include #include -#include -#include -#include -#include void __init pre_intr_init_hook(void) { @@ -27,7 +24,8 @@ void __init intr_init_hook(void) smp_intr_init(); #endif - setup_irq(2, &irq2); + if (!acpi_ioapic) + setup_irq(2, &irq2); } void __init pre_setup_arch_hook(void) @@ -47,74 +45,3 @@ void __init time_init_hook(void) { setup_irq(0, &irq0); } - -/* Hook for machine specific memory setup. */ - -char * __init machine_specific_memory_setup(void) -{ - char *who; - - who = "NOT VOYAGER"; - - if(voyager_level == 5) { - __u32 addr, length; - int i; - - who = "Voyager-SUS"; - - e820.nr_map = 0; - for(i=0; voyager_memory_detect(i, &addr, &length); i++) { - add_memory_region(addr, length, E820_RAM); - } - return who; - } else if(voyager_level == 4) { - __u32 tom; - __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; - /* select the DINO config space */ - outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); - /* Read DINO top of memory register */ - tom = ((inb(catbase + 0x4) & 0xf0) << 16) - + ((inb(catbase + 0x5) & 0x7f) << 24); - - if(inb(catbase) != VOYAGER_DINO) { - printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); - tom = (EXT_MEM_K)<<10; - } - who = "Voyager-TOM"; - add_memory_region(0, 0x9f000, E820_RAM); - /* map from 1M to top of memory */ - add_memory_region(1*1024*1024, tom - 1*1024*1024, E820_RAM); - /* FIXME: Should check the ASICs to see if I need to - * take out the 8M window. Just do it at the moment - * */ - add_memory_region(8*1024*1024, 8*1024*1024, E820_RESERVED); - return who; - } - - who = "BIOS-e820"; - - /* - * Try to copy the BIOS-supplied E820-map. - * - * Otherwise fake a memory map; one section from 0k->640k, - * the next section from 1mb->appropriate_mem_k - */ - sanitize_e820_map(E820_MAP, &E820_MAP_NR); - if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { - unsigned long mem_size; - - /* compare results from other methods and take the greater */ - if (ALT_MEM_K < EXT_MEM_K) { - mem_size = EXT_MEM_K; - who = "BIOS-88"; - } else { - mem_size = ALT_MEM_K; - who = "BIOS-e801"; - } - - e820.nr_map = 0; - add_memory_region(0, LOWMEMSIZE(), E820_RAM); - add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); - } - return who; -} diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 8242af9ebc6f..70e560a1b79a 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -661,7 +661,6 @@ do_boot_cpu(__u8 cpu) print_cpu_info(&cpu_data[cpu]); wmb(); cpu_set(cpu, cpu_callout_map); - cpu_set(cpu, cpu_present_map); } else { printk("CPU%d FAILED TO BOOT: ", cpu); @@ -1913,7 +1912,6 @@ void __devinit smp_prepare_boot_cpu(void) cpu_set(smp_processor_id(), cpu_online_map); cpu_set(smp_processor_id(), cpu_callout_map); cpu_set(smp_processor_id(), cpu_possible_map); - cpu_set(smp_processor_id(), cpu_present_map); } int __devinit diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index 6ee7faaf2c1b..7f0fcf219a26 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -30,40 +30,6 @@ extern void die(const char *,struct pt_regs *,long); -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); -int register_page_fault_notifier(struct notifier_block *nb) -{ - vmalloc_sync_all(); - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif - - /* * Unlock any spinlocks which will prevent us from getting the * message out @@ -111,15 +77,12 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, unsigned seg = regs->xcs & 0xffff; u32 seg_ar, seg_limit, base, *desc; - /* Unlikely, but must come before segment checks. */ - if (unlikely(regs->eflags & VM_MASK)) { - base = seg << 4; - *eip_limit = base + 0xffff; - return base + (eip & 0xffff); - } - /* The standard kernel/user address space limit. */ *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; + + /* Unlikely, but must come before segment checks. */ + if (unlikely((regs->eflags & VM_MASK) != 0)) + return eip + (seg << 4); /* By far the most common cases. */ if (likely(seg == __USER_CS || seg == __KERNEL_CS)) @@ -358,7 +321,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, if (unlikely(address >= TASK_SIZE)) { if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) return; - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; /* @@ -368,7 +331,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; @@ -417,12 +380,12 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area; if (error_code & 4) { /* - * Accessing the stack below %esp is always a bug. - * The large cushion allows instructions like enter - * and pusha to work. ("enter $65535,$31" pushes - * 32 pointers and then decrements %esp by 65535.) + * accessing the stack below %esp is always a bug. + * The "+ 32" is there due to some instructions (like + * pusha) doing post-decrement on the stack and that + * doesn't show up until later.. */ - if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp) + if (address + 32 < regs->esp) goto bad_area; } if (expand_stack(vma, address)) diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index f84b16e007ff..3df1371d4520 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -23,14 +23,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include @@ -386,7 +384,7 @@ static void __init pagetable_init (void) #endif } -#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) +#ifdef CONFIG_SOFTWARE_SUSPEND /* * Swap suspend & friends need this for resume because things like the intel-agp * driver might have split up a kernel 4MB mapping. @@ -655,7 +653,7 @@ void __init mem_init(void) */ #ifdef CONFIG_MEMORY_HOTPLUG #ifndef CONFIG_NEED_MULTIPLE_NODES -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { struct pglist_data *pgdata = &contig_page_data; struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; @@ -754,7 +752,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); free_page(addr); totalram_pages++; } diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index 353a836ed63c..92c3d9f0e731 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -209,19 +209,19 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) } void global_flush_tlb(void) -{ - struct list_head l; +{ + LIST_HEAD(l); struct page *pg, *next; BUG_ON(irqs_disabled()); spin_lock_irq(&cpa_lock); - list_replace_init(&df_list, &l); + list_splice_init(&df_list, &l); spin_unlock_irq(&cpa_lock); flush_map(); list_for_each_entry_safe(pg, next, &l, lru) __free_page(pg); -} +} #ifdef CONFIG_DEBUG_PAGEALLOC void kernel_map_pages(struct page *page, int numpages, int enable) @@ -229,8 +229,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) if (PageHighMem(page)) return; if (!enable) - debug_check_no_locks_freed(page_address(page), - numpages * PAGE_SIZE); + mutex_debug_check_no_locks_freed(page_address(page), + numpages * PAGE_SIZE); /* the return value is ignored - the calls cannot fail, * large pages are disabled at boot time. diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c index fa8a37bcb391..ec0fd3cfa774 100644 --- a/trunk/arch/i386/oprofile/nmi_int.c +++ b/trunk/arch/i386/oprofile/nmi_int.c @@ -281,9 +281,9 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry * dir; - char buf[4]; + char buf[2]; - snprintf(buf, sizeof(buf), "%d", i); + snprintf(buf, 2, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); diff --git a/trunk/arch/i386/oprofile/op_model_athlon.c b/trunk/arch/i386/oprofile/op_model_athlon.c index 693bdea4a52b..3ad9a72a5036 100644 --- a/trunk/arch/i386/oprofile/op_model_athlon.c +++ b/trunk/arch/i386/oprofile/op_model_athlon.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "op_x86_model.h" #include "op_counter.h" diff --git a/trunk/arch/i386/oprofile/op_model_p4.c b/trunk/arch/i386/oprofile/op_model_p4.c index 7c61d357b82b..ac8a066035c2 100644 --- a/trunk/arch/i386/oprofile/op_model_p4.c +++ b/trunk/arch/i386/oprofile/op_model_p4.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "op_x86_model.h" #include "op_counter.h" diff --git a/trunk/arch/i386/oprofile/op_model_ppro.c b/trunk/arch/i386/oprofile/op_model_ppro.c index 5c3ab4b027ad..d719015fc044 100644 --- a/trunk/arch/i386/oprofile/op_model_ppro.c +++ b/trunk/arch/i386/oprofile/op_model_ppro.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "op_x86_model.h" #include "op_counter.h" diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c index c624b61e1104..dbece776c5b2 100644 --- a/trunk/arch/i386/pci/common.c +++ b/trunk/arch/i386/pci/common.c @@ -288,7 +288,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - pcibios_disable_resources(dev); if (pcibios_disable_irq) pcibios_disable_irq(dev); } diff --git a/trunk/arch/i386/pci/i386.c b/trunk/arch/i386/pci/i386.c index a151f7a99f5e..ed2c8c899bd3 100644 --- a/trunk/arch/i386/pci/i386.c +++ b/trunk/arch/i386/pci/i386.c @@ -242,15 +242,6 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) return 0; } -void pcibios_disable_resources(struct pci_dev *dev) -{ - u16 cmd; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(dev, PCI_COMMAND, cmd); -} - /* * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. @@ -285,6 +276,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, /* Leave vm_pgoff as-is, the PCI space address is the physical * address on this platform. */ + vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO); + prot = pgprot_val(vma->vm_page_prot); if (boot_cpu_data.x86 > 3) prot |= _PAGE_PCD | _PAGE_PWT; diff --git a/trunk/arch/i386/pci/irq.c b/trunk/arch/i386/pci/irq.c index 8ce69508f3c7..06dab00aaadc 100644 --- a/trunk/arch/i386/pci/irq.c +++ b/trunk/arch/i386/pci/irq.c @@ -198,14 +198,14 @@ static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigne */ static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; + static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; return irqmap[read_config_nybble(router, 0x48, pirq-1)]; } static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; + static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; unsigned int val = irqmap[irq]; if (val) { @@ -256,13 +256,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i */ static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; return read_config_nybble(router, 0x55, pirqmap[pirq-1]); } static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); return 1; } @@ -274,13 +274,13 @@ static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq */ static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; return read_config_nybble(router,0x43, pirqmap[pirq-1]); } static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); return 1; } @@ -505,7 +505,7 @@ static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) { - static struct pci_device_id __initdata pirq_440gx[] = { + static struct pci_device_id pirq_440gx[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, { }, @@ -880,7 +880,6 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) { DBG(" -> got IRQ %d\n", irq); msg = "Found"; - eisa_set_level_irq(irq); } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { DBG(" -> assigning IRQ %d", newirq); if (r->set(pirq_router_dev, dev, pirq, newirq)) { diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index e545b0992c48..6b1ea0c9a570 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -15,9 +15,7 @@ #include #include "pci.h" -/* aperture is up to 256MB but BIOS may reserve less */ -#define MMCONFIG_APER_MIN (2 * 1024*1024) -#define MMCONFIG_APER_MAX (256 * 1024*1024) +#define MMCONFIG_APER_SIZE (256*1024*1024) /* Assume systems with more busses have correct MCFG */ #define MAX_CHECK_BUS 16 @@ -199,10 +197,9 @@ void __init pci_mmcfg_init(void) return; if (!e820_all_mapped(pci_mmcfg_config[0].base_address, - pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", - pci_mmcfg_config[0].base_address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } diff --git a/trunk/arch/i386/pci/pcbios.c b/trunk/arch/i386/pci/pcbios.c index ed1512a175ab..1eec0868f4b3 100644 --- a/trunk/arch/i386/pci/pcbios.c +++ b/trunk/arch/i386/pci/pcbios.c @@ -371,7 +371,8 @@ void __devinit pcibios_sort(void) list_for_each(ln, &pci_devices) { d = pci_dev_g(ln); if (d->bus->number == bus && d->devfn == devfn) { - list_move_tail(&d->global_list, &sorted_devices); + list_del(&d->global_list); + list_add_tail(&d->global_list, &sorted_devices); if (d == dev) found = 1; break; @@ -389,7 +390,8 @@ void __devinit pcibios_sort(void) if (!found) { printk(KERN_WARNING "PCI: Device %s not found by BIOS\n", pci_name(dev)); - list_move_tail(&dev->global_list, &sorted_devices); + list_del(&dev->global_list); + list_add_tail(&dev->global_list, &sorted_devices); } } list_splice(&sorted_devices, &pci_devices); diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h index 12bf3d8dda29..12035e29108b 100644 --- a/trunk/arch/i386/pci/pci.h +++ b/trunk/arch/i386/pci/pci.h @@ -35,7 +35,6 @@ extern unsigned int pcibios_max_latency; void pcibios_resource_survey(void); int pcibios_enable_resources(struct pci_dev *, int); -void pcibios_disable_resources(struct pci_dev *); /* pci-pc.c */ diff --git a/trunk/arch/i386/power/cpu.c b/trunk/arch/i386/power/cpu.c index e6517915fe3e..79b2370c7fac 100644 --- a/trunk/arch/i386/power/cpu.c +++ b/trunk/arch/i386/power/cpu.c @@ -10,8 +10,6 @@ #include #include #include -#include -#include static struct saved_context saved_context; diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index a56df7bf022d..0f3076a820c3 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -77,7 +77,6 @@ choice config IA64_GENERIC bool "generic" select ACPI - select PCI select NUMA select ACPI_NUMA help @@ -274,6 +273,7 @@ config HOTPLUG_CPU config SCHED_SMT bool "SMT scheduler support" depends on SMP + default off help Improves the CPU scheduler's decision making when dealing with Intel IA64 chips with MultiThreading at a cost of slightly increased @@ -374,10 +374,6 @@ config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y depends on NEED_MULTIPLE_NODES -config HAVE_ARCH_NODEDATA_EXTENSION - def_bool y - depends on NUMA - config IA32_SUPPORT bool "Support for Linux/x86 binaries" help @@ -453,8 +449,6 @@ config PCI_DOMAINS bool default PCI -source "drivers/pci/pcie/Kconfig" - source "drivers/pci/Kconfig" source "drivers/pci/hotplug/Kconfig" diff --git a/trunk/arch/ia64/Makefile b/trunk/arch/ia64/Makefile index 21033ed83307..80ea7506fa1a 100644 --- a/trunk/arch/ia64/Makefile +++ b/trunk/arch/ia64/Makefile @@ -71,8 +71,6 @@ all: compressed unwcheck compressed: vmlinux.gz -vmlinuz: vmlinux.gz - vmlinux.gz: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c index 5825ddee58d6..bdccd0b1eb60 100644 --- a/trunk/arch/ia64/hp/common/sba_iommu.c +++ b/trunk/arch/ia64/hp/common/sba_iommu.c @@ -1958,7 +1958,7 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) if (pxm < 0) return; - node = pxm_to_node(pxm); + node = pxm_to_nid_map[pxm]; if (node >= MAX_NUMNODES || !node_online(node)) return; @@ -1999,7 +1999,7 @@ acpi_sba_ioc_add(struct acpi_device *device) if (!iovp_shift) iovp_shift = min(PAGE_SHIFT, 16); } - kfree(dev_info); + ACPI_MEM_FREE(dev_info); /* * default anything not caught above or specified on cmdline to 4k diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index ca16d9556bde..58c93a30348c 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -68,6 +68,8 @@ EXPORT_SYMBOL(pm_power_off); unsigned char acpi_kbd_controller_present = 1; unsigned char acpi_legacy_devices; +static unsigned int __initdata acpi_madt_rev; + unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; @@ -241,8 +243,6 @@ acpi_parse_iosapic(acpi_table_entry_header * header, const unsigned long end) return iosapic_init(iosapic->address, iosapic->global_irq_base); } -static unsigned int __initdata acpi_madt_rev; - static int __init acpi_parse_plat_int_src(acpi_table_entry_header * header, const unsigned long end) @@ -415,6 +415,9 @@ static int __initdata srat_num_cpus; /* number of cpus */ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN]; #define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag)) #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) +/* maps to convert between proximity domain and logical node ID */ +int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS]; +int __initdata nid_to_pxm_map[MAX_NUMNODES]; static struct acpi_table_slit __initdata *slit_table; static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa) @@ -530,17 +533,22 @@ void __init acpi_numa_arch_fixup(void) * MCD - This can probably be dropped now. No need for pxm ID to node ID * mapping with sparse node numbering iff MAX_PXM_DOMAINS <= MAX_NUMNODES. */ + /* calculate total number of nodes in system from PXM bitmap */ + memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); + memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); nodes_clear(node_online_map); for (i = 0; i < MAX_PXM_DOMAINS; i++) { if (pxm_bit_test(i)) { - int nid = acpi_map_pxm_to_node(i); + int nid = num_online_nodes(); + pxm_to_nid_map[i] = nid; + nid_to_pxm_map[nid] = i; node_set_online(nid); } } /* set logical node id in memory chunk structure */ for (i = 0; i < num_node_memblks; i++) - node_memblk[i].nid = pxm_to_node(node_memblk[i].nid); + node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid]; /* assign memory bank numbers for each chunk on each node */ for_each_online_node(i) { @@ -554,7 +562,7 @@ void __init acpi_numa_arch_fixup(void) /* set logical node id in cpu structure */ for (i = 0; i < srat_num_cpus; i++) - node_cpuid[i].nid = pxm_to_node(node_cpuid[i].nid); + node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid]; printk(KERN_INFO "Number of logical nodes in system = %d\n", num_online_nodes()); @@ -567,11 +575,11 @@ void __init acpi_numa_arch_fixup(void) for (i = 0; i < slit_table->localities; i++) { if (!pxm_bit_test(i)) continue; - node_from = pxm_to_node(i); + node_from = pxm_to_nid_map[i]; for (j = 0; j < slit_table->localities; j++) { if (!pxm_bit_test(j)) continue; - node_to = pxm_to_node(j); + node_to = pxm_to_nid_map[j]; node_distance(node_from, node_to) = slit_table->entry[i * slit_table->localities + j]; } @@ -618,7 +626,7 @@ EXPORT_SYMBOL(acpi_unregister_gsi); static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; - struct fadt_descriptor *fadt; + struct fadt_descriptor_rev2 *fadt; if (!phys_addr || !size) return -EINVAL; @@ -627,7 +635,7 @@ static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ - fadt = (struct fadt_descriptor *)fadt_header; + fadt = (struct fadt_descriptor_rev2 *)fadt_header; if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) acpi_kbd_controller_present = 0; @@ -777,9 +785,9 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid) /* * Assuming that the container driver would have set the proximity - * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag + * domain and would have initialized pxm_to_nid_map[pxm_id] && pxm_flag */ - node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id); + node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_nid_map[pxm_id]; node_cpuid[cpu].phys_id = physid; #endif @@ -958,7 +966,7 @@ acpi_map_iosapic(acpi_handle handle, u32 depth, void *context, void **ret) if (pxm < 0) return AE_OK; - node = pxm_to_node(pxm); + node = pxm_to_nid_map[pxm]; if (node >= MAX_NUMNODES || !node_online(node) || cpus_empty(node_to_cpumask(node))) diff --git a/trunk/arch/ia64/kernel/asm-offsets.c b/trunk/arch/ia64/kernel/asm-offsets.c index 16e7b6600ae6..77225659e968 100644 --- a/trunk/arch/ia64/kernel/asm-offsets.c +++ b/trunk/arch/ia64/kernel/asm-offsets.c @@ -217,24 +217,16 @@ void foo(void) DEFINE(IA64_MCA_CPU_INIT_STACK_OFFSET, offsetof (struct ia64_mca_cpu, init_stack)); BLANK(); + DEFINE(IA64_SAL_OS_STATE_COMMON_OFFSET, + offsetof (struct ia64_sal_os_state, sal_ra)); DEFINE(IA64_SAL_OS_STATE_OS_GP_OFFSET, offsetof (struct ia64_sal_os_state, os_gp)); - DEFINE(IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET, - offsetof (struct ia64_sal_os_state, proc_state_param)); - DEFINE(IA64_SAL_OS_STATE_SAL_RA_OFFSET, - offsetof (struct ia64_sal_os_state, sal_ra)); - DEFINE(IA64_SAL_OS_STATE_SAL_GP_OFFSET, - offsetof (struct ia64_sal_os_state, sal_gp)); DEFINE(IA64_SAL_OS_STATE_PAL_MIN_STATE_OFFSET, offsetof (struct ia64_sal_os_state, pal_min_state)); - DEFINE(IA64_SAL_OS_STATE_OS_STATUS_OFFSET, - offsetof (struct ia64_sal_os_state, os_status)); - DEFINE(IA64_SAL_OS_STATE_CONTEXT_OFFSET, - offsetof (struct ia64_sal_os_state, context)); + DEFINE(IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET, + offsetof (struct ia64_sal_os_state, proc_state_param)); DEFINE(IA64_SAL_OS_STATE_SIZE, sizeof (struct ia64_sal_os_state)); - BLANK(); - DEFINE(IA64_PMSA_GR_OFFSET, offsetof (struct pal_min_state_area_s, pmsa_gr)); DEFINE(IA64_PMSA_BANK1_GR_OFFSET, diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index c33d0ba7e300..12cfedce73b1 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -8,8 +8,6 @@ * Copyright (C) 1999-2003 Hewlett-Packard Co. * David Mosberger-Tang * Stephane Eranian - * (c) Copyright 2006 Hewlett-Packard Development Company, L.P. - * Bjorn Helgaas * * All EFI Runtime Services are not implemented yet as EFI only * supports physical mode addressing on SoftSDV. This is to be fixed @@ -624,20 +622,28 @@ efi_get_iobase (void) return 0; } -static struct kern_memdesc * -kern_memory_descriptor (unsigned long phys_addr) +static efi_memory_desc_t * +efi_memory_descriptor (unsigned long phys_addr) { - struct kern_memdesc *md; + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; - for (md = kern_memmap; md->start != ~0UL; md++) { - if (phys_addr - md->start < (md->num_pages << EFI_PAGE_SHIFT)) + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md; } return 0; } -static efi_memory_desc_t * -efi_memory_descriptor (unsigned long phys_addr) +static int +efi_memmap_has_mmio (void) { void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; @@ -650,8 +656,8 @@ efi_memory_descriptor (unsigned long phys_addr) for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) - return md; + if (md->type == EFI_MEMORY_MAPPED_IO) + return 1; } return 0; } @@ -677,125 +683,71 @@ efi_mem_attributes (unsigned long phys_addr) } EXPORT_SYMBOL(efi_mem_attributes); -u64 -efi_mem_attribute (unsigned long phys_addr, unsigned long size) +/* + * Determines whether the memory at phys_addr supports the desired + * attribute (WB, UC, etc). If this returns 1, the caller can safely + * access size bytes at phys_addr with the specified attribute. + */ +int +efi_mem_attribute_range (unsigned long phys_addr, unsigned long size, u64 attr) { unsigned long end = phys_addr + size; efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); - u64 attr; - - if (!md) - return 0; - - /* - * EFI_MEMORY_RUNTIME is not a memory attribute; it just tells - * the kernel that firmware needs this region mapped. - */ - attr = md->attribute & ~EFI_MEMORY_RUNTIME; - do { - unsigned long md_end = efi_md_end(md); - - if (end <= md_end) - return attr; - - md = efi_memory_descriptor(md_end); - if (!md || (md->attribute & ~EFI_MEMORY_RUNTIME) != attr) - return 0; - } while (md); - return 0; -} - -u64 -kern_mem_attribute (unsigned long phys_addr, unsigned long size) -{ - unsigned long end = phys_addr + size; - struct kern_memdesc *md; - u64 attr; /* - * This is a hack for ioremap calls before we set up kern_memmap. - * Maybe we should do efi_memmap_init() earlier instead. + * Some firmware doesn't report MMIO regions in the EFI memory + * map. The Intel BigSur (a.k.a. HP i2000) has this problem. + * On those platforms, we have to assume UC is valid everywhere. */ - if (!kern_memmap) { - attr = efi_mem_attribute(phys_addr, size); - if (attr & EFI_MEMORY_WB) - return EFI_MEMORY_WB; + if (!md || (md->attribute & attr) != attr) { + if (attr == EFI_MEMORY_UC && !efi_memmap_has_mmio()) + return 1; return 0; } - md = kern_memory_descriptor(phys_addr); - if (!md) - return 0; - - attr = md->attribute; do { - unsigned long md_end = kmd_end(md); + unsigned long md_end = efi_md_end(md); if (end <= md_end) - return attr; + return 1; - md = kern_memory_descriptor(md_end); - if (!md || md->attribute != attr) + md = efi_memory_descriptor(md_end); + if (!md || (md->attribute & attr) != attr) return 0; } while (md); return 0; } -EXPORT_SYMBOL(kern_mem_attribute); +/* + * For /dev/mem, we only allow read & write system calls to access + * write-back memory, because read & write don't allow the user to + * control access size. + */ int valid_phys_addr_range (unsigned long phys_addr, unsigned long size) { - u64 attr; - - /* - * /dev/mem reads and writes use copy_to_user(), which implicitly - * uses a granule-sized kernel identity mapping. It's really - * only safe to do this for regions in kern_memmap. For more - * details, see Documentation/ia64/aliasing.txt. - */ - attr = kern_mem_attribute(phys_addr, size); - if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC) - return 1; - return 0; + return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB); } +/* + * We allow mmap of anything in the EFI memory map that supports + * either write-back or uncacheable access. For uncacheable regions, + * the supported access sizes are system-dependent, and the user is + * responsible for using the correct size. + * + * Note that this doesn't currently allow access to hot-added memory, + * because that doesn't appear in the boot-time EFI memory map. + */ int valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long size) { - /* - * MMIO regions are often missing from the EFI memory map. - * We must allow mmap of them for programs like X, so we - * currently can't do any useful validation. - */ - return 1; -} - -pgprot_t -phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, - pgprot_t vma_prot) -{ - unsigned long phys_addr = pfn << PAGE_SHIFT; - u64 attr; - - /* - * For /dev/mem mmap, we use user mappings, but if the region is - * in kern_memmap (and hence may be covered by a kernel mapping), - * we must use the same attribute as the kernel mapping. - */ - attr = kern_mem_attribute(phys_addr, size); - if (attr & EFI_MEMORY_WB) - return pgprot_cacheable(vma_prot); - else if (attr & EFI_MEMORY_UC) - return pgprot_noncached(vma_prot); + if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB)) + return 1; - /* - * Some chipsets don't support UC access to memory. If - * WB is supported, we prefer that. - */ - if (efi_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) - return pgprot_cacheable(vma_prot); + if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC)) + return 1; - return pgprot_noncached(vma_prot); + return 0; } int __init diff --git a/trunk/arch/ia64/kernel/efi_stub.S b/trunk/arch/ia64/kernel/efi_stub.S index a56e161d7515..5a7fe70212a9 100644 --- a/trunk/arch/ia64/kernel/efi_stub.S +++ b/trunk/arch/ia64/kernel/efi_stub.S @@ -61,7 +61,7 @@ GLOBAL_ENTRY(efi_call_phys) or loc3=loc3,r17 mov b6=r2 ;; - andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared + andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared br.call.sptk.many rp=ia64_switch_mode_phys .ret0: mov out4=in5 mov out0=in1 diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index 32c999f58d12..bcb80ca5cf40 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1584,7 +1584,7 @@ sys_call_table: data8 sys_keyctl data8 sys_ioprio_set data8 sys_ioprio_get // 1275 - data8 sys_move_pages + data8 sys_ni_syscall data8 sys_inotify_init data8 sys_inotify_add_watch data8 sys_inotify_rm_watch diff --git a/trunk/arch/ia64/kernel/entry.h b/trunk/arch/ia64/kernel/entry.h index ebc3dfb88826..78eeb0793419 100644 --- a/trunk/arch/ia64/kernel/entry.h +++ b/trunk/arch/ia64/kernel/entry.h @@ -23,7 +23,6 @@ #define PT(f) (IA64_PT_REGS_##f##_OFFSET) #define SW(f) (IA64_SWITCH_STACK_##f##_OFFSET) -#define SOS(f) (IA64_SAL_OS_STATE_##f##_OFFSET) #define PT_REGS_SAVES(off) \ .unwabi 3, 'i'; \ diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index ef9a2b49307a..6c4d59fd0364 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -46,10 +46,6 @@ #define IRQ_DEBUG 0 -/* These can be overridden in platform_irq_init */ -int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR; -int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR; - /* default base addr of IPI table */ void __iomem *ipi_base_addr = ((void __iomem *) (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); @@ -64,7 +60,7 @@ __u8 isa_irq_to_vector_map[16] = { }; EXPORT_SYMBOL(isa_irq_to_vector_map); -static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)]; +static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; int assign_irq_vector (int irq) @@ -93,19 +89,6 @@ free_irq_vector (int vector) printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); } -int -reserve_irq_vector (int vector) -{ - int pos; - - if (vector < IA64_FIRST_DEVICE_VECTOR || - vector > IA64_LAST_DEVICE_VECTOR) - return -EINVAL; - - pos = vector - IA64_FIRST_DEVICE_VECTOR; - return test_and_set_bit(pos, ia64_vector_mask); -} - #ifdef CONFIG_SMP # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) #else diff --git a/trunk/arch/ia64/kernel/mca_asm.S b/trunk/arch/ia64/kernel/mca_asm.S index c1bd1feffab0..6dff024cd62b 100644 --- a/trunk/arch/ia64/kernel/mca_asm.S +++ b/trunk/arch/ia64/kernel/mca_asm.S @@ -159,7 +159,7 @@ ia64_os_mca_spin: GET_IA64_MCA_DATA(r2) // Using MCA stack, struct ia64_sal_os_state, variable proc_state_param ;; - add r3=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET+SOS(PROC_STATE_PARAM), r2 + add r3=IA64_MCA_CPU_MCA_STACK_OFFSET+MCA_SOS_OFFSET+IA64_SAL_OS_STATE_PROC_STATE_PARAM_OFFSET, r2 ;; ld8 r18=[r3] // Get processor state parameter on existing PALE_CHECK. ;; @@ -479,11 +479,9 @@ ia64_state_save: st8 [temp2]=r11,16 // rv_rc mov r11=cr.iipa ;; - st8 [temp1]=r18 // proc_state_param - st8 [temp2]=r19 // monarch + st8 [temp1]=r18,16 // proc_state_param + st8 [temp2]=r19,16 // monarch mov r6=IA64_KR(CURRENT) - add temp1=SOS(SAL_RA), regs - add temp2=SOS(SAL_GP), regs ;; st8 [temp1]=r12,16 // sal_ra st8 [temp2]=r10,16 // sal_gp @@ -505,14 +503,12 @@ ia64_state_save: st8 [temp2]=r11,16 // cr.iipa mov r12=cr.iim ;; - st8 [temp1]=r12 // cr.iim + st8 [temp1]=r12,16 // cr.iim (p1) mov r12=IA64_MCA_COLD_BOOT (p2) mov r12=IA64_INIT_WARM_BOOT mov r6=cr.iha - add temp1=SOS(OS_STATUS), regs ;; - st8 [temp2]=r6 // cr.iha - add temp2=SOS(CONTEXT), regs + st8 [temp2]=r6,16 // cr.iha st8 [temp1]=r12 // os_status, default is cold boot mov r6=IA64_MCA_SAME_CONTEXT ;; @@ -824,8 +820,8 @@ ia64_state_restore: // Restore the SAL to OS state. The previous code left regs at pt_regs. add regs=MCA_SOS_OFFSET-MCA_PT_REGS_OFFSET, regs ;; - add temp1=SOS(SAL_RA), regs - add temp2=SOS(SAL_GP), regs + add temp1=IA64_SAL_OS_STATE_COMMON_OFFSET, regs + add temp2=IA64_SAL_OS_STATE_COMMON_OFFSET+8, regs ;; ld8 r12=[temp1],16 // sal_ra ld8 r9=[temp2],16 // sal_gp @@ -846,10 +842,8 @@ ia64_state_restore: ;; mov cr.itir=temp3 mov cr.iipa=temp4 - ld8 temp3=[temp1] // cr.iim - ld8 temp4=[temp2] // cr.iha - add temp1=SOS(OS_STATUS), regs - add temp2=SOS(CONTEXT), regs + ld8 temp3=[temp1],16 // cr.iim + ld8 temp4=[temp2],16 // cr.iha ;; mov cr.iim=temp3 mov cr.iha=temp4 @@ -922,7 +916,7 @@ ia64_state_restore: ia64_new_stack: add regs=MCA_PT_REGS_OFFSET, r3 - add temp2=MCA_SOS_OFFSET+SOS(PAL_MIN_STATE), r3 + add temp2=MCA_SOS_OFFSET+IA64_SAL_OS_STATE_PAL_MIN_STATE_OFFSET, r3 mov b0=r2 // save return address GET_IA64_MCA_DATA(temp1) invala @@ -1026,7 +1020,7 @@ ia64_old_stack: ia64_set_kernel_registers: add temp3=MCA_SP_OFFSET, r3 - add temp4=MCA_SOS_OFFSET+SOS(OS_GP), r3 + add temp4=MCA_SOS_OFFSET+IA64_SAL_OS_STATE_OS_GP_OFFSET, r3 mov b0=r2 // save return address GET_IA64_MCA_DATA(temp1) ;; diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 303a9afcf2a1..859fb37ff49b 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -959,7 +959,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } -static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, +static int palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -978,7 +978,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata palinfo_cpu_notifier = +static struct notifier_block palinfo_cpu_notifier = { .notifier_call = palinfo_cpu_callback, .priority = 0, diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 6d7bc8ff7b3a..077f21216b65 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -532,6 +532,7 @@ static ctl_table pfm_sysctl_root[] = { static struct ctl_table_header *pfm_sysctl_header; static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); +static int pfm_flush(struct file *filp); #define pfm_get_cpu_var(v) __ia64_per_cpu_var(v) #define pfm_get_cpu_data(a,b) per_cpu(a, b) @@ -594,11 +595,10 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, } -static int -pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, - struct vfsmount *mnt) +static struct super_block * +pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt); + return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC); } static struct file_system_type pfm_fs_type = { @@ -1773,7 +1773,7 @@ pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx) * When caller is self-monitoring, the context is unloaded. */ static int -pfm_flush(struct file *filp, fl_owner_t id) +pfm_flush(struct file *filp) { pfm_context_t *ctx; struct task_struct *task; diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index b045c279136c..355d57970ba3 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -272,9 +272,9 @@ cpu_idle (void) /* endless idle loop with no priority at all */ while (1) { if (can_do_pal_halt) - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); else - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); if (!need_resched()) { void (*idle)(void); diff --git a/trunk/arch/ia64/kernel/sal.c b/trunk/arch/ia64/kernel/sal.c index 77fa65903d94..056f7a6eedc7 100644 --- a/trunk/arch/ia64/kernel/sal.c +++ b/trunk/arch/ia64/kernel/sal.c @@ -227,7 +227,7 @@ static int sal_cache_flush_drops_interrupts; static void __init check_sal_cache_flush (void) { - unsigned long flags; + unsigned long flags, itv; int cpu; u64 vector; @@ -238,6 +238,9 @@ check_sal_cache_flush (void) * Schedule a timer interrupt, wait until it's reported, and see if * SAL_CACHE_FLUSH drops it. */ + itv = ia64_get_itv(); + BUG_ON((itv & (1 << 16)) == 0); + ia64_set_itv(IA64_TIMER_VECTOR); ia64_set_itm(ia64_get_itc() + 1000); @@ -257,6 +260,7 @@ check_sal_cache_flush (void) ia64_eoi(); } + ia64_set_itv(itv); local_irq_restore(flags); put_cpu(); } diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index 9065f0f01ba3..663a186ad194 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -572,7 +572,7 @@ static struct file_operations salinfo_data_fops = { }; #ifdef CONFIG_HOTPLUG_CPU -static int __devinit +static int salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { unsigned int i, cpu = (unsigned long)hcpu; @@ -673,7 +673,9 @@ salinfo_init(void) salinfo_timer.function = &salinfo_timeout; add_timer(&salinfo_timer); - register_hotcpu_notifier(&salinfo_cpu_notifier); +#ifdef CONFIG_HOTPLUG_CPU + register_cpu_notifier(&salinfo_cpu_notifier); +#endif return 0; } diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index 6dba2d63f24d..e4dfda1eb7dd 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -260,7 +260,6 @@ reserve_memory (void) n++; num_rsvd_regions = n; - BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n); sort_regions(rsvd_region, num_rsvd_regions); } diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 5511d9c6c701..4f3a16b37f8f 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -26,10 +26,19 @@ #include #include +#ifdef CONFIG_NUMA +static struct node *sysfs_nodes; +#endif static struct ia64_cpu *sysfs_cpus; int arch_register_cpu(int num) { + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + parent = &sysfs_nodes[cpu_to_node(num)]; +#endif /* CONFIG_NUMA */ + #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* * If CPEI cannot be re-targetted, and this is @@ -39,14 +48,21 @@ int arch_register_cpu(int num) sysfs_cpus[num].cpu.no_control = 1; #endif - return register_cpu(&sysfs_cpus[num].cpu, num); + return register_cpu(&sysfs_cpus[num].cpu, num, parent); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - return unregister_cpu(&sysfs_cpus[num].cpu); + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + parent = &sysfs_nodes[node]; +#endif /* CONFIG_NUMA */ + + return unregister_cpu(&sysfs_cpus[num].cpu, parent); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -58,11 +74,17 @@ static int __init topology_init(void) int i, err = 0; #ifdef CONFIG_NUMA + sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); + if (!sysfs_nodes) { + err = -ENOMEM; + goto out; + } + /* * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */ for_each_online_node(i) { - if ((err = register_one_node(i))) + if ((err = register_node(&sysfs_nodes[i], i, 0))) goto out; } #endif @@ -144,7 +166,7 @@ static void cache_shared_cpu_map_setup( unsigned int cpu, num_shared = (int) csi.num_shared; do { - for_each_possible_cpu(j) + for_each_cpu(j) if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id && cpu_data(j)->core_id == csi.log1_cid && cpu_data(j)->thread_id == csi.log1_tid) @@ -404,7 +426,7 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev) * When a cpu is hot-plugged, do a check and initiate * cache kobject if necessary */ -static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, +static int cache_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -422,7 +444,7 @@ static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cache_cpu_notifier = +static struct notifier_block cache_cpu_notifier = { .notifier_call = cache_cpu_callback }; diff --git a/trunk/arch/ia64/kernel/uncached.c b/trunk/arch/ia64/kernel/uncached.c index 5f03b9e524dd..fcd2bad0286f 100644 --- a/trunk/arch/ia64/kernel/uncached.c +++ b/trunk/arch/ia64/kernel/uncached.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -29,8 +29,15 @@ #include #include +#define DEBUG 0 -extern void __init efi_memmap_walk_uc(efi_freemem_callback_t, void *); +#if DEBUG +#define dprintk printk +#else +#define dprintk(x...) do { } while (0) +#endif + +void __init efi_memmap_walk_uc (efi_freemem_callback_t callback); #define MAX_UNCACHED_GRANULES 5 static int allocated_granules; @@ -53,7 +60,6 @@ static void uncached_ipi_visibility(void *data) static void uncached_ipi_mc_drain(void *data) { int status; - status = ia64_pal_mc_drain(); if (status) printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on " @@ -61,35 +67,30 @@ static void uncached_ipi_mc_drain(void *data) } -/* - * Add a new chunk of uncached memory pages to the specified pool. - * - * @pool: pool to add new chunk of uncached memory to - * @nid: node id of node to allocate memory from, or -1 - * - * This is accomplished by first allocating a granule of cached memory pages - * and then converting them to uncached memory pages. - */ -static int uncached_add_chunk(struct gen_pool *pool, int nid) +static unsigned long +uncached_get_new_chunk(struct gen_pool *poolp) { struct page *page; + void *tmp; int status, i; - unsigned long c_addr, uc_addr; + unsigned long addr, node; if (allocated_granules >= MAX_UNCACHED_GRANULES) - return -1; - - /* attempt to allocate a granule's worth of cached memory pages */ + return 0; - page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO, + node = poolp->private; + page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, IA64_GRANULE_SHIFT-PAGE_SHIFT); - if (!page) - return -1; - /* convert the memory pages from cached to uncached */ + dprintk(KERN_INFO "get_new_chunk page %p, addr %lx\n", + page, (unsigned long)(page-vmem_map) << PAGE_SHIFT); - c_addr = (unsigned long)page_address(page); - uc_addr = c_addr - PAGE_OFFSET + __IA64_UNCACHED_OFFSET; + /* + * Do magic if no mem on local node! XXX + */ + if (!page) + return 0; + tmp = page_address(page); /* * There's a small race here where it's possible for someone to @@ -99,90 +100,76 @@ static int uncached_add_chunk(struct gen_pool *pool, int nid) for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++) SetPageUncached(&page[i]); - flush_tlb_kernel_range(uc_addr, uc_adddr + IA64_GRANULE_SIZE); + flush_tlb_kernel_range(tmp, tmp + IA64_GRANULE_SIZE); status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); + + dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n", + status, raw_smp_processor_id()); + if (!status) { status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1); if (status) - goto failed; + printk(KERN_WARNING "smp_call_function failed for " + "uncached_ipi_visibility! (%i)\n", status); } - preempt_disable(); - if (ia64_platform_is("sn2")) - sn_flush_all_caches(uc_addr, IA64_GRANULE_SIZE); + sn_flush_all_caches((unsigned long)tmp, IA64_GRANULE_SIZE); else - flush_icache_range(uc_addr, uc_addr + IA64_GRANULE_SIZE); - - /* flush the just introduced uncached translation from the TLB */ - local_flush_tlb_all(); - - preempt_enable(); + flush_icache_range((unsigned long)tmp, + (unsigned long)tmp+IA64_GRANULE_SIZE); ia64_pal_mc_drain(); status = smp_call_function(uncached_ipi_mc_drain, NULL, 0, 1); if (status) - goto failed; + printk(KERN_WARNING "smp_call_function failed for " + "uncached_ipi_mc_drain! (%i)\n", status); - /* - * The chunk of memory pages has been converted to uncached so now we - * can add it to the pool. - */ - status = gen_pool_add(pool, uc_addr, IA64_GRANULE_SIZE, nid); - if (status) - goto failed; + addr = (unsigned long)tmp - PAGE_OFFSET + __IA64_UNCACHED_OFFSET; allocated_granules++; - return 0; - - /* failed to convert or add the chunk so give it back to the kernel */ -failed: - for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++) - ClearPageUncached(&page[i]); - - free_pages(c_addr, IA64_GRANULE_SHIFT-PAGE_SHIFT); - return -1; + return addr; } /* * uncached_alloc_page * - * @starting_nid: node id of node to start with, or -1 - * * Allocate 1 uncached page. Allocates on the requested node. If no * uncached pages are available on the requested node, roundrobin starting - * with the next higher node. + * with higher nodes. */ -unsigned long uncached_alloc_page(int starting_nid) +unsigned long +uncached_alloc_page(int nid) { - unsigned long uc_addr; - struct gen_pool *pool; - int nid; + unsigned long maddr; - if (unlikely(starting_nid >= MAX_NUMNODES)) - return 0; + maddr = gen_pool_alloc(uncached_pool[nid], PAGE_SIZE); - if (starting_nid < 0) - starting_nid = numa_node_id(); - nid = starting_nid; + dprintk(KERN_DEBUG "uncached_alloc_page returns %lx on node %i\n", + maddr, nid); - do { - if (!node_online(nid)) - continue; - pool = uncached_pool[nid]; - if (pool == NULL) - continue; - do { - uc_addr = gen_pool_alloc(pool, PAGE_SIZE); - if (uc_addr != 0) - return uc_addr; - } while (uncached_add_chunk(pool, nid) == 0); - - } while ((nid = (nid + 1) % MAX_NUMNODES) != starting_nid); + /* + * If no memory is availble on our local node, try the + * remaining nodes in the system. + */ + if (!maddr) { + int i; + + for (i = MAX_NUMNODES - 1; i >= 0; i--) { + if (i == nid || !node_online(i)) + continue; + maddr = gen_pool_alloc(uncached_pool[i], PAGE_SIZE); + dprintk(KERN_DEBUG "uncached_alloc_page alternate search " + "returns %lx on node %i\n", maddr, i); + if (maddr) { + break; + } + } + } - return 0; + return maddr; } EXPORT_SYMBOL(uncached_alloc_page); @@ -190,22 +177,21 @@ EXPORT_SYMBOL(uncached_alloc_page); /* * uncached_free_page * - * @uc_addr: uncached address of page to free - * * Free a single uncached page. */ -void uncached_free_page(unsigned long uc_addr) +void +uncached_free_page(unsigned long maddr) { - int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET); - struct gen_pool *pool = uncached_pool[nid]; + int node; + + node = paddr_to_nid(maddr - __IA64_UNCACHED_OFFSET); - if (unlikely(pool == NULL)) - return; + dprintk(KERN_DEBUG "uncached_free_page(%lx) on node %i\n", maddr, node); - if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET) - panic("uncached_free_page invalid address %lx\n", uc_addr); + if ((maddr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET) + panic("uncached_free_page invalid address %lx\n", maddr); - gen_pool_free(pool, uc_addr, PAGE_SIZE); + gen_pool_free(uncached_pool[node], maddr, PAGE_SIZE); } EXPORT_SYMBOL(uncached_free_page); @@ -213,39 +199,43 @@ EXPORT_SYMBOL(uncached_free_page); /* * uncached_build_memmap, * - * @uc_start: uncached starting address of a chunk of uncached memory - * @uc_end: uncached ending address of a chunk of uncached memory - * @arg: ignored, (NULL argument passed in on call to efi_memmap_walk_uc()) - * * Called at boot time to build a map of pages that can be used for * memory special operations. */ -static int __init uncached_build_memmap(unsigned long uc_start, - unsigned long uc_end, void *arg) +static int __init +uncached_build_memmap(unsigned long start, unsigned long end, void *arg) { - int nid = paddr_to_nid(uc_start - __IA64_UNCACHED_OFFSET); - struct gen_pool *pool = uncached_pool[nid]; - size_t size = uc_end - uc_start; + long length = end - start; + int node; + + dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); touch_softlockup_watchdog(); + memset((char *)start, 0, length); - if (pool != NULL) { - memset((char *)uc_start, 0, size); - (void) gen_pool_add(pool, uc_start, size, nid); + node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET); + + for (; start < end ; start += PAGE_SIZE) { + dprintk(KERN_INFO "sticking %lx into the pool!\n", start); + gen_pool_free(uncached_pool[node], start, PAGE_SIZE); } + return 0; } -static int __init uncached_init(void) -{ - int nid; +static int __init uncached_init(void) { + int i; - for_each_online_node(nid) { - uncached_pool[nid] = gen_pool_create(PAGE_SHIFT, nid); + for (i = 0; i < MAX_NUMNODES; i++) { + if (!node_online(i)) + continue; + uncached_pool[i] = gen_pool_create(0, IA64_GRANULE_SHIFT, + &uncached_get_new_chunk, i); } - efi_memmap_walk_uc(uncached_build_memmap, NULL); + efi_memmap_walk_uc(uncached_build_memmap); + return 0; } diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 525b082eb661..b6bcc9fa3603 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -33,6 +33,7 @@ */ struct early_node_data { struct ia64_node_data *node_data; + pg_data_t *pgdat; unsigned long pernode_addr; unsigned long pernode_size; struct bootmem_data bootmem_data; @@ -45,8 +46,6 @@ struct early_node_data { static struct early_node_data mem_data[MAX_NUMNODES] __initdata; static nodemask_t memory_less_mask __initdata; -static pg_data_t *pgdat_list[MAX_NUMNODES]; - /* * To prevent cache aliasing effects, align per-node structures so that they * start at addresses that are strided by node number. @@ -100,7 +99,7 @@ static int __init build_node_maps(unsigned long start, unsigned long len, * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been * called yet. Note that node 0 will also count all non-existent cpus. */ -static int __meminit early_nr_cpus_node(int node) +static int __init early_nr_cpus_node(int node) { int cpu, n = 0; @@ -115,7 +114,7 @@ static int __meminit early_nr_cpus_node(int node) * compute_pernodesize - compute size of pernode data * @node: the node id. */ -static unsigned long __meminit compute_pernodesize(int node) +static unsigned long __init compute_pernodesize(int node) { unsigned long pernodesize = 0, cpus; @@ -176,13 +175,13 @@ static void __init fill_pernode(int node, unsigned long pernode, pernode += PERCPU_PAGE_SIZE * cpus; pernode += node * L1_CACHE_BYTES; - pgdat_list[node] = __va(pernode); + mem_data[node].pgdat = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); mem_data[node].node_data = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - pgdat_list[node]->bdata = bdp; + mem_data[node].pgdat->bdata = bdp; pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); cpu_data = per_cpu_node_setup(cpu_data, node); @@ -269,7 +268,7 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, static int __init free_node_bootmem(unsigned long start, unsigned long len, int node) { - free_bootmem_node(pgdat_list[node], start, len); + free_bootmem_node(mem_data[node].pgdat, start, len); return 0; } @@ -288,7 +287,7 @@ static void __init reserve_pernode_space(void) int node; for_each_online_node(node) { - pg_data_t *pdp = pgdat_list[node]; + pg_data_t *pdp = mem_data[node].pgdat; if (node_isset(node, memory_less_mask)) continue; @@ -308,17 +307,6 @@ static void __init reserve_pernode_space(void) } } -static void __meminit scatter_node_data(void) -{ - pg_data_t **dst; - int node; - - for_each_online_node(node) { - dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs; - memcpy(dst, pgdat_list, sizeof(pgdat_list)); - } -} - /** * initialize_pernode_data - fixup per-cpu & per-node pointers * @@ -329,10 +317,17 @@ static void __meminit scatter_node_data(void) */ static void __init initialize_pernode_data(void) { + pg_data_t *pgdat_list[MAX_NUMNODES]; int cpu, node; - scatter_node_data(); + for_each_online_node(node) + pgdat_list[node] = mem_data[node].pgdat; + /* Copy the pg_data_t list to each node and init the node field */ + for_each_online_node(node) { + memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, + sizeof(pgdat_list)); + } #ifdef CONFIG_SMP /* Set the node_data pointer for each per-cpu struct */ for (cpu = 0; cpu < NR_CPUS; cpu++) { @@ -377,7 +372,7 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize) if (bestnode == -1) bestnode = anynode; - ptr = __alloc_bootmem_node(pgdat_list[bestnode], pernodesize, + ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); return ptr; @@ -481,7 +476,7 @@ void __init find_memory(void) pernodesize = mem_data[node].pernode_size; map = pernode + pernodesize; - init_bootmem_node(pgdat_list[node], + init_bootmem_node(mem_data[node].pgdat, map>>PAGE_SHIFT, bdp->node_boot_start>>PAGE_SHIFT, bdp->node_low_pfn); @@ -791,21 +786,3 @@ void __init paging_init(void) zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } - -pg_data_t *arch_alloc_nodedata(int nid) -{ - unsigned long size = compute_pernodesize(nid); - - return kzalloc(size, GFP_KERNEL); -} - -void arch_free_nodedata(pg_data_t *pgdat) -{ - kfree(pgdat); -} - -void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) -{ - pgdat_list[update_node] = update_pgdat; - scatter_node_data(); -} diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c index 14ef7cceb208..d98ec49570b8 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -19,40 +19,6 @@ extern void die (char *, struct pt_regs *, long); -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif - /* * Return TRUE if ADDRESS points at a page in the kernel's mapped segment * (inside region 5, on ia64) and that page is present. @@ -118,7 +84,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re /* * This is to handle the kprobes on user space access instructions */ - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, SIGSEGV) == NOTIFY_STOP) return; diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 38306e98f04b..cafa8776a53d 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -652,7 +652,7 @@ void online_page(struct page *page) num_physpages++; } -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { pg_data_t *pgdat; struct zone *zone; @@ -660,7 +660,7 @@ int arch_add_memory(int nid, u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - pgdat = NODE_DATA(nid); + pgdat = NODE_DATA(0); zone = pgdat->node_zones + ZONE_NORMAL; ret = __add_pages(zone, start_pfn, nr_pages); @@ -676,5 +676,4 @@ int remove_memory(u64 start, u64 size) { return -EINVAL; } -EXPORT_SYMBOL_GPL(remove_memory); #endif diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c index 07bd02b6c372..643ccc6960ce 100644 --- a/trunk/arch/ia64/mm/ioremap.c +++ b/trunk/arch/ia64/mm/ioremap.c @@ -11,7 +11,6 @@ #include #include #include -#include static inline void __iomem * __ioremap (unsigned long offset, unsigned long size) @@ -22,29 +21,16 @@ __ioremap (unsigned long offset, unsigned long size) void __iomem * ioremap (unsigned long offset, unsigned long size) { - u64 attr; - unsigned long gran_base, gran_size; - - /* - * For things in kern_memmap, we must use the same attribute - * as the rest of the kernel. For more details, see - * Documentation/ia64/aliasing.txt. - */ - attr = kern_mem_attribute(offset, size); - if (attr & EFI_MEMORY_WB) + if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) return phys_to_virt(offset); - else if (attr & EFI_MEMORY_UC) + + if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) return __ioremap(offset, size); /* - * Some chipsets don't support UC access to memory. If - * WB is supported for the whole granule, we prefer that. + * Someday this should check ACPI resources so we + * can do the right thing for hot-plugged regions. */ - gran_base = GRANULEROUNDDOWN(offset); - gran_size = GRANULEROUNDUP(offset + size) - gran_base; - if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) - return phys_to_virt(offset); - return __ioremap(offset, size); } EXPORT_SYMBOL(ioremap); @@ -52,9 +38,6 @@ EXPORT_SYMBOL(ioremap); void __iomem * ioremap_nocache (unsigned long offset, unsigned long size) { - if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) - return 0; - return __ioremap(offset, size); } EXPORT_SYMBOL(ioremap_nocache); diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 77375a55da31..ab829a22f8a4 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -352,7 +352,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) pxm = acpi_get_pxm(controller->acpi_handle); #ifdef CONFIG_NUMA if (pxm >= 0) - controller->node = pxm_to_node(pxm); + controller->node = pxm_to_nid_map[pxm]; #endif acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, @@ -602,6 +602,8 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, * Leave vm_pgoff as-is, the PCI space address is the physical * address on this platform. */ + vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO); + if (write_combine && efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); @@ -643,30 +645,18 @@ char *ia64_pci_get_legacy_mem(struct pci_bus *bus) int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma) { - unsigned long size = vma->vm_end - vma->vm_start; - pgprot_t prot; char *addr; - /* - * Avoid attribute aliasing. See Documentation/ia64/aliasing.txt - * for more details. - */ - if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size)) - return -EINVAL; - prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, - vma->vm_page_prot); - if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot))) - return -EINVAL; - addr = pci_get_legacy_mem(bus); if (IS_ERR(addr)) return PTR_ERR(addr); vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT; - vma->vm_page_prot = prot; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO); if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - size, vma->vm_page_prot)) + vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index dc09a6a28a37..5101ac462643 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -58,7 +58,7 @@ static int max_pcibus_number = 255; /* Default highest pci bus number */ */ static dma_addr_t -sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) +sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size) { return 0; } @@ -457,6 +457,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) pcidev_info->pdi_sn_irq_info = NULL; kfree(sn_irq_info); } + + /* + * MSI currently not supported on altix. Remove this when + * the MSI abstraction patches are integrated into the kernel + * (sometime after 2.6.16 releases) + */ + dev->no_msi = 1; } /* diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 677c6c0fd661..c265e02f5036 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -26,11 +26,11 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); int sn_force_interrupt_flag = 1; extern int sn_ioif_inited; -struct list_head **sn_irq_lh; -static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */ +static struct list_head **sn_irq_lh; +static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ -u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, - struct sn_irq_info *sn_irq_info, +static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, + u64 sn_irq_info, int req_irq, nasid_t req_nasid, int req_slice) { @@ -40,13 +40,12 @@ u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, (u64) SAL_INTR_ALLOC, (u64) local_nasid, - (u64) local_widget, __pa(sn_irq_info), (u64) req_irq, + (u64) local_widget, (u64) sn_irq_info, (u64) req_irq, (u64) req_nasid, (u64) req_slice); - return ret_stuff.status; } -void sn_intr_free(nasid_t local_nasid, int local_widget, +static inline void sn_intr_free(nasid_t local_nasid, int local_widget, struct sn_irq_info *sn_irq_info) { struct ia64_sal_retval ret_stuff; @@ -113,91 +112,73 @@ static void sn_end_irq(unsigned int irq) static void sn_irq_info_free(struct rcu_head *head); -struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, - nasid_t nasid, int slice) +static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) { - int vector; - int cpuphys; - int64_t bridge; - int local_widget, status; - nasid_t local_nasid; - struct sn_irq_info *new_irq_info; - struct sn_pcibus_provider *pci_provider; - - new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); - if (new_irq_info == NULL) - return NULL; - - memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); + struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; + int cpuid, cpuphys; - bridge = (u64) new_irq_info->irq_bridge; - if (!bridge) { - kfree(new_irq_info); - return NULL; /* irq is not a device interrupt */ - } + cpuid = first_cpu(mask); + cpuphys = cpu_physical_id(cpuid); - local_nasid = NASID_GET(bridge); + list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, + sn_irq_lh[irq], list) { + u64 bridge; + int local_widget, status; + nasid_t local_nasid; + struct sn_irq_info *new_irq_info; + struct sn_pcibus_provider *pci_provider; + + new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); + if (new_irq_info == NULL) + break; + memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); + + bridge = (u64) new_irq_info->irq_bridge; + if (!bridge) { + kfree(new_irq_info); + break; /* irq is not a device interrupt */ + } - if (local_nasid & 1) - local_widget = TIO_SWIN_WIDGETNUM(bridge); - else - local_widget = SWIN_WIDGETNUM(bridge); + local_nasid = NASID_GET(bridge); - vector = sn_irq_info->irq_irq; - /* Free the old PROM new_irq_info structure */ - sn_intr_free(local_nasid, local_widget, new_irq_info); - /* Update kernels new_irq_info with new target info */ - unregister_intr_pda(new_irq_info); + if (local_nasid & 1) + local_widget = TIO_SWIN_WIDGETNUM(bridge); + else + local_widget = SWIN_WIDGETNUM(bridge); - /* allocate a new PROM new_irq_info struct */ - status = sn_intr_alloc(local_nasid, local_widget, - new_irq_info, vector, - nasid, slice); + /* Free the old PROM new_irq_info structure */ + sn_intr_free(local_nasid, local_widget, new_irq_info); + /* Update kernels new_irq_info with new target info */ + unregister_intr_pda(new_irq_info); - /* SAL call failed */ - if (status) { - kfree(new_irq_info); - return NULL; - } + /* allocate a new PROM new_irq_info struct */ + status = sn_intr_alloc(local_nasid, local_widget, + __pa(new_irq_info), irq, + cpuid_to_nasid(cpuid), + cpuid_to_slice(cpuid)); - cpuphys = nasid_slice_to_cpuid(nasid, slice); - new_irq_info->irq_cpuid = cpuphys; - register_intr_pda(new_irq_info); + /* SAL call failed */ + if (status) { + kfree(new_irq_info); + break; + } - pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; + new_irq_info->irq_cpuid = cpuid; + register_intr_pda(new_irq_info); - /* - * If this represents a line interrupt, target it. If it's - * an msi (irq_int_bit < 0), it's already targeted. - */ - if (new_irq_info->irq_int_bit >= 0 && - pci_provider && pci_provider->target_interrupt) - (pci_provider->target_interrupt)(new_irq_info); + pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; + if (pci_provider && pci_provider->target_interrupt) + (pci_provider->target_interrupt)(new_irq_info); - spin_lock(&sn_irq_info_lock); - list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); - spin_unlock(&sn_irq_info_lock); - call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + spin_lock(&sn_irq_info_lock); + list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); + spin_unlock(&sn_irq_info_lock); + call_rcu(&sn_irq_info->rcu, sn_irq_info_free); #ifdef CONFIG_SMP - set_irq_affinity_info((vector & 0xff), cpuphys, 0); + set_irq_affinity_info((irq & 0xff), cpuphys, 0); #endif - - return new_irq_info; -} - -static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) -{ - struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; - nasid_t nasid; - int slice; - - nasid = cpuid_to_nasid(first_cpu(mask)); - slice = cpuid_to_slice(first_cpu(mask)); - - list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, - sn_irq_lh[irq], list) - (void)sn_retarget_vector(sn_irq_info, nasid, slice); + } } struct hw_interrupt_type irq_type_sn = { @@ -221,9 +202,6 @@ void sn_irq_init(void) int i; irq_desc_t *base_desc = irq_desc; - ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; - ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; - for (i = 0; i < NR_IRQS; i++) { if (base_desc[i].handler == &no_irq_type) { base_desc[i].handler = &irq_type_sn; @@ -307,7 +285,6 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) /* link it into the sn_irq[irq] list */ spin_lock(&sn_irq_info_lock); list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); - reserve_irq_vector(sn_irq_info->irq_irq); spin_unlock(&sn_irq_info_lock); register_intr_pda(sn_irq_info); @@ -333,11 +310,8 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) spin_lock(&sn_irq_info_lock); list_del_rcu(&sn_irq_info->list); spin_unlock(&sn_irq_info_lock); - if (list_empty(sn_irq_lh[sn_irq_info->irq_irq])) - free_irq_vector(sn_irq_info->irq_irq); call_rcu(&sn_irq_info->rcu, sn_irq_info_free); pci_dev_put(pci_dev); - } static inline void diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 93577abae36d..30988dfbddff 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -139,7 +139,7 @@ static int __init pxm_to_nasid(int pxm) int i; int nid; - nid = pxm_to_node(pxm); + nid = pxm_to_nid_map[pxm]; for (i = 0; i < num_node_memblks; i++) { if (node_memblk[i].nid == nid) { return NASID_GET(node_memblk[i].start_paddr); @@ -704,7 +704,7 @@ void __init build_cnode_tables(void) * cnode == node for all C & M bricks. */ for_each_online_node(node) { - nasid = pxm_to_nasid(node_to_pxm(node)); + nasid = pxm_to_nasid(nid_to_pxm_map[node]); sn_cnodeid_to_nasid[node] = nasid; physical_node_map[nasid] = node; } diff --git a/trunk/arch/ia64/sn/kernel/sn2/cache.c b/trunk/arch/ia64/sn/kernel/sn2/cache.c index 2862cb33026d..bc3cfa17cd0f 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/cache.c +++ b/trunk/arch/ia64/sn/kernel/sn2/cache.c @@ -3,12 +3,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2003, 2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. * */ #include #include -#include /** * sn_flush_all_caches - flush a range of address from all caches (incl. L4) @@ -18,24 +17,18 @@ * Flush a range of addresses from all caches including L4. * All addresses fully or partially contained within * @flush_addr to @flush_addr + @bytes are flushed - * from all caches. + * from the all caches. */ void sn_flush_all_caches(long flush_addr, long bytes) { - unsigned long addr = flush_addr; - - /* SHub1 requires a cached address */ - if (is_shub1() && (addr & RGN_BITS) == RGN_BASE(RGN_UNCACHED)) - addr = (addr - RGN_BASE(RGN_UNCACHED)) + RGN_BASE(RGN_KERNEL); - - flush_icache_range(addr, addr + bytes); + flush_icache_range(flush_addr, flush_addr+bytes); /* * The last call may have returned before the caches * were actually flushed, so we call it again to make * sure. */ - flush_icache_range(addr, addr + bytes); + flush_icache_range(flush_addr, flush_addr+bytes); mb(); } EXPORT_SYMBOL(sn_flush_all_caches); diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 9a8a29339d2d..739c948dc504 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -51,8 +51,6 @@ static nasid_t sn_hwperf_master_nasid = INVALID_NASID; static int sn_hwperf_init(void); static DECLARE_MUTEX(sn_hwperf_init_mutex); -#define cnode_possible(n) ((n) < num_cnodes) - static int sn_hwperf_enum_objects(int *nobj, struct sn_hwperf_object_info **ret) { int e; @@ -129,14 +127,14 @@ static int sn_hwperf_geoid_to_cnode(char *location) } } - return cnode_possible(cnode) ? cnode : -1; + return node_possible(cnode) ? cnode : -1; } static int sn_hwperf_obj_to_cnode(struct sn_hwperf_object_info * obj) { if (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj)) BUG(); - if (SN_HWPERF_FOREIGN(obj)) + if (!obj->sn_hwp_this_part) return -1; return sn_hwperf_geoid_to_cnode(obj->location); } @@ -201,12 +199,12 @@ static void print_pci_topology(struct seq_file *s) static inline int sn_hwperf_has_cpus(cnodeid_t node) { - return node < MAX_NUMNODES && node_online(node) && nr_cpus_node(node); + return node_online(node) && nr_cpus_node(node); } static inline int sn_hwperf_has_mem(cnodeid_t node) { - return node < MAX_NUMNODES && node_online(node) && NODE_DATA(node)->node_present_pages; + return node_online(node) && NODE_DATA(node)->node_present_pages; } static struct sn_hwperf_object_info * @@ -239,7 +237,7 @@ static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objb int found_mem = 0; int found_cpu = 0; - if (!cnode_possible(node)) + if (!node_possible(node)) return -EINVAL; if (sn_hwperf_has_cpus(node)) { @@ -444,7 +442,7 @@ static int sn_topology_show(struct seq_file *s, void *d) seq_printf(s, "%s %d %s %s asic %s", slabname, ordinal, obj->location, obj->sn_hwp_this_part ? "local" : "shared", obj->name); - if (ordinal < 0 || (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj))) + if (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj)) seq_putc(s, '\n'); else { cnodeid_t near_mem = -1; @@ -470,24 +468,22 @@ static int sn_topology_show(struct seq_file *s, void *d) /* * CPUs on this node, if any */ - if (!SN_HWPERF_IS_IONODE(obj)) { - cpumask = node_to_cpumask(ordinal); - for_each_online_cpu(i) { - if (cpu_isset(i, cpumask)) { - slice = 'a' + cpuid_to_slice(i); - c = cpu_data(i); - seq_printf(s, "cpu %d %s%c local" - " freq %luMHz, arch ia64", - i, obj->location, slice, - c->proc_freq / 1000000); - for_each_online_cpu(j) { - seq_printf(s, j ? ":%d" : ", dist %d", - node_distance( - cpu_to_node(i), - cpu_to_node(j))); - } - seq_putc(s, '\n'); + cpumask = node_to_cpumask(ordinal); + for_each_online_cpu(i) { + if (cpu_isset(i, cpumask)) { + slice = 'a' + cpuid_to_slice(i); + c = cpu_data(i); + seq_printf(s, "cpu %d %s%c local" + " freq %luMHz, arch ia64", + i, obj->location, slice, + c->proc_freq / 1000000); + for_each_online_cpu(j) { + seq_printf(s, j ? ":%d" : ", dist %d", + node_distance( + cpu_to_node(i), + cpu_to_node(j))); } + seq_putc(s, '\n'); } } } @@ -527,7 +523,7 @@ static int sn_topology_show(struct seq_file *s, void *d) if (obj->sn_hwp_this_part && p->sn_hwp_this_part) /* both ends local to this partition */ seq_puts(s, " local"); - else if (SN_HWPERF_FOREIGN(p)) + else if (!obj->sn_hwp_this_part && !p->sn_hwp_this_part) /* both ends of the link in foreign partiton */ seq_puts(s, " foreign"); else @@ -780,7 +776,7 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg) case SN_HWPERF_GET_NODE_NASID: if (a.sz != sizeof(u64) || - (node = a.arg) < 0 || !cnode_possible(node)) { + (node = a.arg) < 0 || !node_possible(node)) { r = -EINVAL; goto error; } diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index 7a291a271511..b4b84c269210 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -113,8 +113,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, * resources. */ - *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size, - SN_DMA_ADDR_PHYS); + *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size); if (!*dma_handle) { printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); free_pages((unsigned long)cpuaddr, get_order(size)); @@ -177,7 +176,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, BUG_ON(dev->bus != &pci_bus_type); phys_addr = __pa(cpu_addr); - dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); + dma_addr = provider->dma_map(pdev, phys_addr, size); if (!dma_addr) { printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); return 0; @@ -261,8 +260,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, for (i = 0; i < nhwentries; i++, sg++) { phys_addr = SG_ENT_PHYS_ADDRESS(sg); sg->dma_address = provider->dma_map(pdev, - phys_addr, sg->length, - SN_DMA_ADDR_PHYS); + phys_addr, sg->length); if (!sg->dma_address) { printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index a86c7b945962..9f86bb6519aa 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -41,7 +41,7 @@ extern int sn_ioif_inited; static dma_addr_t pcibr_dmamap_ate32(struct pcidev_info *info, - u64 paddr, size_t req_size, u64 flags, int dma_flags) + u64 paddr, size_t req_size, u64 flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; @@ -81,12 +81,9 @@ pcibr_dmamap_ate32(struct pcidev_info *info, if (IS_PCIX(pcibus_info)) ate_flags &= ~(PCI32_ATE_PREF); - if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS)) - xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : - PHYS_TO_TIODMA(paddr); - else - xio_addr = paddr; - + xio_addr = + IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : + PHYS_TO_TIODMA(paddr); offset = IOPGOFF(xio_addr); ate = ate_flags | (xio_addr - offset); @@ -94,13 +91,6 @@ pcibr_dmamap_ate32(struct pcidev_info *info, if (IS_PIC_SOFT(pcibus_info)) { ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT); } - - /* - * If we're mapping for MSI, set the MSI bit in the ATE - */ - if (dma_flags & SN_DMA_MSI) - ate |= PCI32_ATE_MSI; - ate_write(pcibus_info, ate_index, ate_count, ate); /* @@ -115,27 +105,20 @@ pcibr_dmamap_ate32(struct pcidev_info *info, if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR) ATE_SWAP_ON(pci_addr); - return pci_addr; } static dma_addr_t pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, - u64 dma_attributes, int dma_flags) + u64 dma_attributes) { struct pcibus_info *pcibus_info = (struct pcibus_info *) ((info->pdi_host_pcidev_info)->pdi_pcibus_info); u64 pci_addr; /* Translate to Crosstalk View of Physical Address */ - if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) - pci_addr = IS_PIC_SOFT(pcibus_info) ? - PHYS_TO_DMA(paddr) : - PHYS_TO_TIODMA(paddr) | dma_attributes; - else - pci_addr = IS_PIC_SOFT(pcibus_info) ? - paddr : - paddr | dma_attributes; + pci_addr = (IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : + PHYS_TO_TIODMA(paddr)) | dma_attributes; /* Handle Bus mode */ if (IS_PCIX(pcibus_info)) @@ -147,9 +130,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, ((u64) pcibus_info-> pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT); } else - pci_addr |= (dma_flags & SN_DMA_MSI) ? - TIOCP_PCI64_CMDTYPE_MSI : - TIOCP_PCI64_CMDTYPE_MEM; + pci_addr |= TIOCP_PCI64_CMDTYPE_MEM; /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */ if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn)) @@ -160,7 +141,7 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr, static dma_addr_t pcibr_dmatrans_direct32(struct pcidev_info * info, - u64 paddr, size_t req_size, u64 flags, int dma_flags) + u64 paddr, size_t req_size, u64 flags) { struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> @@ -175,14 +156,8 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, return 0; } - if (dma_flags & SN_DMA_MSI) - return 0; - - if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) - xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : - PHYS_TO_TIODMA(paddr); - else - xio_addr = paddr; + xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) : + PHYS_TO_TIODMA(paddr); xio_base = pcibus_info->pbi_dir_xbase; offset = xio_addr - xio_base; @@ -352,7 +327,7 @@ void sn_dma_flush(u64 addr) */ dma_addr_t -pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_flags) +pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size) { dma_addr_t dma_handle; struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); @@ -369,11 +344,11 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int */ dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, - PCI64_ATTR_PREF, dma_flags); + PCI64_ATTR_PREF); } else { /* Handle 32-63 bit cards via direct mapping */ dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr, - size, 0, dma_flags); + size, 0); if (!dma_handle) { /* * It is a 32 bit card and we cannot do direct mapping, @@ -381,8 +356,7 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int */ dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr, - size, PCI32_ATE_PREF, - dma_flags); + size, PCI32_ATE_PREF); } } @@ -391,18 +365,18 @@ pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_addr_t pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr, - size_t size, int dma_flags) + size_t size) { dma_addr_t dma_handle; struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); if (hwdev->dev.coherent_dma_mask == ~0UL) { dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr, - PCI64_ATTR_BAR, dma_flags); + PCI64_ATTR_BAR); } else { dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info, phys_addr, size, - PCI32_ATE_BAR, dma_flags); + PCI32_ATE_BAR); } return dma_handle; diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index 20de72791b97..be0176912968 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -515,16 +515,10 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * use the GART mapped mode. */ static u64 -tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) +tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count) { u64 mapaddr; - /* - * Not supported for now ... - */ - if (dma_flags & SN_DMA_MSI) - return 0; - /* * If card is 64 or 48 bit addresable, use a direct mapping. 32 * bit direct is so restrictive w.r.t. where the memory resides that diff --git a/trunk/arch/ia64/sn/pci/tioce_provider.c b/trunk/arch/ia64/sn/pci/tioce_provider.c index 2d7948567ebc..833295624e5d 100644 --- a/trunk/arch/ia64/sn/pci/tioce_provider.c +++ b/trunk/arch/ia64/sn/pci/tioce_provider.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. */ #include @@ -170,8 +170,7 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1) #define ATE_VALID(ate) ((ate) & (1UL << 63)) -#define ATE_MAKE(addr, ps, msi) \ - (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0)) +#define ATE_MAKE(addr, ps) (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63)) /* * Flavors of ate-based mapping supported by tioce_alloc_map() @@ -197,17 +196,15 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr) * * 63 - must be 1 to indicate d64 mode to CE hardware * 62 - barrier bit ... controlled with tioce_dma_barrier() - * 61 - msi bit ... specified through dma_flags + * 61 - 0 since this is not an MSI transaction * 60:54 - reserved, MBZ */ static u64 -tioce_dma_d64(unsigned long ct_addr, int dma_flags) +tioce_dma_d64(unsigned long ct_addr) { u64 bus_addr; bus_addr = ct_addr | (1UL << 63); - if (dma_flags & SN_DMA_MSI) - bus_addr |= (1UL << 61); return bus_addr; } @@ -264,7 +261,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base, */ static u64 tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, - u64 ct_addr, int len, int dma_flags) + u64 ct_addr, int len) { int i; int j; @@ -273,7 +270,6 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, int entries; int nates; u64 pagesize; - int msi_capable, msi_wanted; u64 *ate_shadow; u64 *ate_reg; u64 addr; @@ -295,7 +291,6 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, ate_reg = ce_mmr->ce_ure_ate3240; pagesize = ce_kern->ce_ate3240_pagesize; bus_base = TIOCE_M32_MIN; - msi_capable = 1; break; case TIOCE_ATE_M40: first = 0; @@ -304,7 +299,6 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, ate_reg = ce_mmr->ce_ure_ate40; pagesize = MB(64); bus_base = TIOCE_M40_MIN; - msi_capable = 0; break; case TIOCE_ATE_M40S: /* @@ -317,16 +311,11 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, ate_reg = ce_mmr->ce_ure_ate3240; pagesize = GB(16); bus_base = TIOCE_M40S_MIN; - msi_capable = 0; break; default: return 0; } - msi_wanted = dma_flags & SN_DMA_MSI; - if (msi_wanted && !msi_capable) - return 0; - nates = ATE_NPAGES(ct_addr, len, pagesize); if (nates > entries) return 0; @@ -355,7 +344,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, for (j = 0; j < nates; j++) { u64 ate; - ate = ATE_MAKE(addr, pagesize, msi_wanted); + ate = ATE_MAKE(addr, pagesize); ate_shadow[i + j] = ate; tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate); addr += pagesize; @@ -382,7 +371,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info. */ static u64 -tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags) +tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr) { int dma_ok; int port; @@ -392,9 +381,6 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags) u64 ct_lower; dma_addr_t bus_addr; - if (dma_flags & SN_DMA_MSI) - return 0; - ct_upper = ct_addr & ~0x3fffffffUL; ct_lower = ct_addr & 0x3fffffffUL; @@ -521,7 +507,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) */ static u64 tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, - int barrier, int dma_flags) + int barrier) { unsigned long flags; u64 ct_addr; @@ -537,18 +523,15 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, if (dma_mask < 0x7fffffffUL) return 0; - if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) - ct_addr = PHYS_TO_TIODMA(paddr); - else - ct_addr = paddr; + ct_addr = PHYS_TO_TIODMA(paddr); /* * If the device can generate 64 bit addresses, create a D64 map. + * Since this should never fail, bypass the rest of the checks. */ if (dma_mask == ~0UL) { - mapaddr = tioce_dma_d64(ct_addr, dma_flags); - if (mapaddr) - goto dma_map_done; + mapaddr = tioce_dma_d64(ct_addr); + goto dma_map_done; } pcidev_to_tioce(pdev, NULL, &ce_kern, &port); @@ -591,22 +574,18 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, if (byte_count > MB(64)) { mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, - port, ct_addr, byte_count, - dma_flags); + port, ct_addr, byte_count); if (!mapaddr) mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, - ct_addr, byte_count, - dma_flags); + ct_addr, byte_count); } else { mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1, - ct_addr, byte_count, - dma_flags); + ct_addr, byte_count); if (!mapaddr) mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S, - port, ct_addr, byte_count, - dma_flags); + port, ct_addr, byte_count); } } @@ -614,7 +593,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, * 32-bit direct is the next mode to try */ if (!mapaddr && dma_mask >= 0xffffffffUL) - mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags); + mapaddr = tioce_dma_d32(pdev, ct_addr); /* * Last resort, try 32-bit ATE-based map. @@ -622,7 +601,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, if (!mapaddr) mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr, - byte_count, dma_flags); + byte_count); spin_unlock_irqrestore(&ce_kern->ce_lock, flags); @@ -643,9 +622,9 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, * in the address. */ static u64 -tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) +tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count) { - return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags); + return tioce_do_dma_map(pdev, paddr, byte_count, 0); } /** @@ -657,9 +636,9 @@ tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) * Simply call tioce_do_dma_map() to create a map with the barrier bit set * in the address. */ static u64 -tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) +tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count) { - return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags); + return tioce_do_dma_map(pdev, paddr, byte_count, 1); } /** @@ -717,7 +696,7 @@ tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit) while (ate_index <= last_ate) { u64 ate; - ate = ATE_MAKE(0xdeadbeef, ps, 0); + ate = ATE_MAKE(0xdeadbeef, ps); ce_kern->ce_ate3240_shadow[ate_index] = ate; tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index], ate); @@ -1023,7 +1002,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL); tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias, ~0ULL); - tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, 0ULL); + tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, ~0ULL); if (request_irq(SGI_PCIASIC_ERROR, tioce_error_intr_handler, diff --git a/trunk/arch/m32r/kernel/setup.c b/trunk/arch/m32r/kernel/setup.c index 1ff483c8a4c9..3cd3c2988a48 100644 --- a/trunk/arch/m32r/kernel/setup.c +++ b/trunk/arch/m32r/kernel/setup.c @@ -275,7 +275,7 @@ static int __init topology_init(void) int i; for_each_present_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); return 0; } diff --git a/trunk/arch/m68k/amiga/amiga_ksyms.c b/trunk/arch/m68k/amiga/amiga_ksyms.c index 8f2e0587ae2f..b7bd84c73ea7 100644 --- a/trunk/arch/m68k/amiga/amiga_ksyms.c +++ b/trunk/arch/m68k/amiga/amiga_ksyms.c @@ -23,6 +23,8 @@ EXPORT_SYMBOL(amiga_chip_avail); EXPORT_SYMBOL(amiga_chip_size); EXPORT_SYMBOL(amiga_audio_period); EXPORT_SYMBOL(amiga_audio_min_period); +EXPORT_SYMBOL(amiga_do_irq); +EXPORT_SYMBOL(amiga_do_irq_list); #ifdef CONFIG_AMIGA_PCMCIA EXPORT_SYMBOL(pcmcia_reset); diff --git a/trunk/arch/m68k/amiga/amiints.c b/trunk/arch/m68k/amiga/amiints.c index f9403f4640a1..b0aa61bf8700 100644 --- a/trunk/arch/m68k/amiga/amiints.c +++ b/trunk/arch/m68k/amiga/amiints.c @@ -35,30 +35,61 @@ * /Jes */ +#include +#include +#include +#include #include -#include #include +#include +#include #include #include #include #include #include -static void amiga_enable_irq(unsigned int irq); -static void amiga_disable_irq(unsigned int irq); -static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp); -static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp); -static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp); -static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp); - -static struct irq_controller amiga_irq_controller = { - .name = "amiga", - .lock = SPIN_LOCK_UNLOCKED, - .enable = amiga_enable_irq, - .disable = amiga_disable_irq, +extern int cia_request_irq(struct ciabase *base,int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id); +extern void cia_init_IRQ(struct ciabase *base); +extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); + +/* irq node variables for amiga interrupt sources */ +static irq_node_t *ami_irq_list[AMI_STD_IRQS]; + +static unsigned short amiga_intena_vals[AMI_STD_IRQS] = { + [IRQ_AMIGA_VERTB] = IF_VERTB, + [IRQ_AMIGA_COPPER] = IF_COPER, + [IRQ_AMIGA_AUD0] = IF_AUD0, + [IRQ_AMIGA_AUD1] = IF_AUD1, + [IRQ_AMIGA_AUD2] = IF_AUD2, + [IRQ_AMIGA_AUD3] = IF_AUD3, + [IRQ_AMIGA_BLIT] = IF_BLIT, + [IRQ_AMIGA_DSKSYN] = IF_DSKSYN, + [IRQ_AMIGA_DSKBLK] = IF_DSKBLK, + [IRQ_AMIGA_RBF] = IF_RBF, + [IRQ_AMIGA_TBE] = IF_TBE, + [IRQ_AMIGA_SOFT] = IF_SOFT, + [IRQ_AMIGA_PORTS] = IF_PORTS, + [IRQ_AMIGA_EXTER] = IF_EXTER +}; +static const unsigned char ami_servers[AMI_STD_IRQS] = { + [IRQ_AMIGA_VERTB] = 1, + [IRQ_AMIGA_PORTS] = 1, + [IRQ_AMIGA_EXTER] = 1 }; +static short ami_ablecount[AMI_IRQS]; + +static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp) +{ + num_spurious += 1; + return IRQ_NONE; +} + /* * void amiga_init_IRQ(void) * @@ -72,12 +103,23 @@ static struct irq_controller amiga_irq_controller = { void __init amiga_init_IRQ(void) { - request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL); - request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL); - request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL); - request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL); + int i; - m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); + /* initialize handlers */ + for (i = 0; i < AMI_STD_IRQS; i++) { + if (ami_servers[i]) { + ami_irq_list[i] = NULL; + } else { + ami_irq_list[i] = new_irq_node(); + ami_irq_list[i]->handler = ami_badint; + ami_irq_list[i]->flags = 0; + ami_irq_list[i]->dev_id = NULL; + ami_irq_list[i]->devname = NULL; + ami_irq_list[i]->next = NULL; + } + } + for (i = 0; i < AMI_IRQS; i++) + ami_ablecount[i] = 0; /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) @@ -92,21 +134,249 @@ void __init amiga_init_IRQ(void) cia_init_IRQ(&ciab_base); } +static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) +{ + unsigned long flags; + irq_node_t *cur; + + if (!node->dev_id) + printk("%s: Warning: dev_id of %s is zero\n", + __FUNCTION__, node->devname); + + local_irq_save(flags); + + cur = *list; + + if (node->flags & SA_INTERRUPT) { + if (node->flags & SA_SHIRQ) + return -EBUSY; + /* + * There should never be more than one + */ + while (cur && cur->flags & SA_INTERRUPT) { + list = &cur->next; + cur = cur->next; + } + } else { + while (cur) { + list = &cur->next; + cur = cur->next; + } + } + + node->next = cur; + *list = node; + + local_irq_restore(flags); + return 0; +} + +static inline void amiga_delete_irq(irq_node_t **list, void *dev_id) +{ + unsigned long flags; + irq_node_t *node; + + local_irq_save(flags); + + for (node = *list; node; list = &node->next, node = *list) { + if (node->dev_id == dev_id) { + *list = node->next; + /* Mark it as free. */ + node->handler = NULL; + local_irq_restore(flags); + return; + } + } + local_irq_restore(flags); + printk ("%s: tried to remove invalid irq\n", __FUNCTION__); +} + +/* + * amiga_request_irq : add an interrupt service routine for a particular + * machine specific interrupt source. + * If the addition was successful, it returns 0. + */ + +int amiga_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + irq_node_t *node; + int error = 0; + + if (irq >= AMI_IRQS) { + printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, + irq, devname); + return -ENXIO; + } + + if (irq >= IRQ_AMIGA_AUTO) + return cpu_request_irq(irq - IRQ_AMIGA_AUTO, handler, + flags, devname, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) + return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, + handler, flags, devname, dev_id); + + if (irq >= IRQ_AMIGA_CIAA) + return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, + handler, flags, devname, dev_id); + + /* + * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared, + * we could add a check here for the SA_SHIRQ flag but all drivers + * should be aware of sharing anyway. + */ + if (ami_servers[irq]) { + if (!(node = new_irq_node())) + return -ENOMEM; + node->handler = handler; + node->flags = flags; + node->dev_id = dev_id; + node->devname = devname; + node->next = NULL; + error = amiga_insert_irq(&ami_irq_list[irq], node); + } else { + ami_irq_list[irq]->handler = handler; + ami_irq_list[irq]->flags = flags; + ami_irq_list[irq]->dev_id = dev_id; + ami_irq_list[irq]->devname = devname; + } + + /* enable the interrupt */ + if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) + amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; + + return error; +} + +void amiga_free_irq(unsigned int irq, void *dev_id) +{ + if (irq >= AMI_IRQS) { + printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); + return; + } + + if (irq >= IRQ_AMIGA_AUTO) + cpu_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); + + if (irq >= IRQ_AMIGA_CIAB) { + cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); + return; + } + + if (irq >= IRQ_AMIGA_CIAA) { + cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); + return; + } + + if (ami_servers[irq]) { + amiga_delete_irq(&ami_irq_list[irq], dev_id); + /* if server list empty, disable the interrupt */ + if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) + amiga_custom.intena = amiga_intena_vals[irq]; + } else { + if (ami_irq_list[irq]->dev_id != dev_id) + printk("%s: removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, ami_irq_list[irq]->devname); + ami_irq_list[irq]->handler = ami_badint; + ami_irq_list[irq]->flags = 0; + ami_irq_list[irq]->dev_id = NULL; + ami_irq_list[irq]->devname = NULL; + amiga_custom.intena = amiga_intena_vals[irq]; + } +} + /* * Enable/disable a particular machine specific interrupt source. * Note that this may affect other interrupts in case of a shared interrupt. * This function should only be called for a _very_ short time to change some * internal data, that may not be changed by the interrupt at the same time. + * ami_(enable|disable)_irq calls may also be nested. */ -static void amiga_enable_irq(unsigned int irq) +void amiga_enable_irq(unsigned int irq) +{ + if (irq >= AMI_IRQS) { + printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); + return; + } + + if (--ami_ablecount[irq]) + return; + + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO){ + printk("%s: Trying to enable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { + cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB))); + cia_able_irq(&ciab_base, CIA_ICR_SETCLR | + (1 << (irq - IRQ_AMIGA_CIAB))); + return; + } + + if (irq >= IRQ_AMIGA_CIAA) { + cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); + cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | + (1 << (irq - IRQ_AMIGA_CIAA))); + return; + } + + /* enable the interrupt */ + amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; +} + +void amiga_disable_irq(unsigned int irq) +{ + if (irq >= AMI_IRQS) { + printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); + return; + } + + if (ami_ablecount[irq]++) + return; + + /* No action for auto-vector interrupts */ + if (irq >= IRQ_AMIGA_AUTO) { + printk("%s: Trying to disable auto-vector IRQ %i\n", + __FUNCTION__, irq - IRQ_AMIGA_AUTO); + return; + } + + if (irq >= IRQ_AMIGA_CIAB) { + cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); + return; + } + + if (irq >= IRQ_AMIGA_CIAA) { + cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); + return; + } + + /* disable the interrupt */ + amiga_custom.intena = amiga_intena_vals[irq]; +} + +inline void amiga_do_irq(int irq, struct pt_regs *fp) { - amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); + kstat_cpu(0).irqs[SYS_IRQS + irq]++; + ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); } -static void amiga_disable_irq(unsigned int irq) +void amiga_do_irq_list(int irq, struct pt_regs *fp) { - amiga_custom.intena = 1 << (irq - IRQ_USER); + irq_node_t *node; + + kstat_cpu(0).irqs[SYS_IRQS + irq]++; + + amiga_custom.intreq = amiga_intena_vals[irq]; + + for (node = ami_irq_list[irq]; node; node = node->next) + node->handler(irq, node->dev_id, fp); } /* @@ -120,19 +390,19 @@ static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { amiga_custom.intreq = IF_TBE; - m68k_handle_int(IRQ_AMIGA_TBE, fp); + amiga_do_irq(IRQ_AMIGA_TBE, fp); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { amiga_custom.intreq = IF_DSKBLK; - m68k_handle_int(IRQ_AMIGA_DSKBLK, fp); + amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { amiga_custom.intreq = IF_SOFT; - m68k_handle_int(IRQ_AMIGA_SOFT, fp); + amiga_do_irq(IRQ_AMIGA_SOFT, fp); } return IRQ_HANDLED; } @@ -144,20 +414,18 @@ static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) /* if a blitter interrupt */ if (ints & IF_BLIT) { amiga_custom.intreq = IF_BLIT; - m68k_handle_int(IRQ_AMIGA_BLIT, fp); + amiga_do_irq(IRQ_AMIGA_BLIT, fp); } /* if a copper interrupt */ if (ints & IF_COPER) { amiga_custom.intreq = IF_COPER; - m68k_handle_int(IRQ_AMIGA_COPPER, fp); + amiga_do_irq(IRQ_AMIGA_COPPER, fp); } /* if a vertical blank interrupt */ - if (ints & IF_VERTB) { - amiga_custom.intreq = IF_VERTB; - m68k_handle_int(IRQ_AMIGA_VERTB, fp); - } + if (ints & IF_VERTB) + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); return IRQ_HANDLED; } @@ -168,25 +436,25 @@ static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) /* if audio 0 interrupt */ if (ints & IF_AUD0) { amiga_custom.intreq = IF_AUD0; - m68k_handle_int(IRQ_AMIGA_AUD0, fp); + amiga_do_irq(IRQ_AMIGA_AUD0, fp); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { amiga_custom.intreq = IF_AUD1; - m68k_handle_int(IRQ_AMIGA_AUD1, fp); + amiga_do_irq(IRQ_AMIGA_AUD1, fp); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { amiga_custom.intreq = IF_AUD2; - m68k_handle_int(IRQ_AMIGA_AUD2, fp); + amiga_do_irq(IRQ_AMIGA_AUD2, fp); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { amiga_custom.intreq = IF_AUD3; - m68k_handle_int(IRQ_AMIGA_AUD3, fp); + amiga_do_irq(IRQ_AMIGA_AUD3, fp); } return IRQ_HANDLED; } @@ -198,13 +466,55 @@ static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ - m68k_handle_int(IRQ_AMIGA_RBF, fp); + amiga_do_irq(IRQ_AMIGA_RBF, fp); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { amiga_custom.intreq = IF_DSKSYN; - m68k_handle_int(IRQ_AMIGA_DSKSYN, fp); + amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } return IRQ_HANDLED; } + +static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) +{ + panic ("level 7 interrupt received\n"); +} + +irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { + [0] = ami_badint, + [1] = ami_int1, + [2] = ami_badint, + [3] = ami_int3, + [4] = ami_int4, + [5] = ami_int5, + [6] = ami_badint, + [7] = ami_int7 +}; + +int show_amiga_interrupts(struct seq_file *p, void *v) +{ + int i; + irq_node_t *node; + + for (i = 0; i < AMI_STD_IRQS; i++) { + if (!(node = ami_irq_list[i])) + continue; + seq_printf(p, "ami %2d: %10u ", i, + kstat_cpu(0).irqs[SYS_IRQS + i]); + do { + if (node->flags & SA_INTERRUPT) + seq_puts(p, "F "); + else + seq_puts(p, " "); + seq_printf(p, "%s\n", node->devname); + if ((node = node->next)) + seq_puts(p, " "); + } while (node); + } + + cia_get_irq_list(&ciaa_base, p); + cia_get_irq_list(&ciab_base, p); + return 0; +} diff --git a/trunk/arch/m68k/amiga/cia.c b/trunk/arch/m68k/amiga/cia.c index 0956e45399e5..9476eb9440f5 100644 --- a/trunk/arch/m68k/amiga/cia.c +++ b/trunk/arch/m68k/amiga/cia.c @@ -29,18 +29,21 @@ struct ciabase { unsigned short int_mask; int handler_irq, cia_irq, server_irq; char *name; + irq_handler_t irq_list[CIA_IRQS]; } ciaa_base = { .cia = &ciaa, .int_mask = IF_PORTS, - .handler_irq = IRQ_AMIGA_PORTS, + .handler_irq = IRQ_AMIGA_AUTO_2, .cia_irq = IRQ_AMIGA_CIAA, - .name = "CIAA" + .server_irq = IRQ_AMIGA_PORTS, + .name = "CIAA handler" }, ciab_base = { .cia = &ciab, .int_mask = IF_EXTER, - .handler_irq = IRQ_AMIGA_EXTER, + .handler_irq = IRQ_AMIGA_AUTO_6, .cia_irq = IRQ_AMIGA_CIAB, - .name = "CIAB" + .server_irq = IRQ_AMIGA_EXTER, + .name = "CIAB handler" }; /* @@ -63,11 +66,13 @@ unsigned char cia_set_irq(struct ciabase *base, unsigned char mask) /* * Enable or disable CIA interrupts, return old interrupt mask, + * interrupts will only be enabled if a handler exists */ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) { - unsigned char old; + unsigned char old, tmp; + int i; old = base->icr_mask; base->icr_data |= base->cia->icr; @@ -77,104 +82,99 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) else base->icr_mask &= ~mask; base->icr_mask &= CIA_ICR_ALL; + for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) { + if ((tmp & base->icr_mask) && !base->irq_list[i].handler) { + base->icr_mask &= ~tmp; + base->cia->icr = tmp; + } + } if (base->icr_data & base->icr_mask) amiga_custom.intreq = IF_SETCLR | base->int_mask; return old; } +int cia_request_irq(struct ciabase *base, unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + unsigned char mask; + + base->irq_list[irq].handler = handler; + base->irq_list[irq].flags = flags; + base->irq_list[irq].dev_id = dev_id; + base->irq_list[irq].devname = devname; + + /* enable the interrupt */ + mask = 1 << irq; + cia_set_irq(base, mask); + cia_able_irq(base, CIA_ICR_SETCLR | mask); + return 0; +} + +void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id) +{ + if (base->irq_list[irq].dev_id != dev_id) + printk("%s: removing probably wrong IRQ %i from %s\n", + __FUNCTION__, base->cia_irq + irq, + base->irq_list[irq].devname); + + base->irq_list[irq].handler = NULL; + base->irq_list[irq].flags = 0; + + cia_able_irq(base, 1 << irq); +} + static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) { struct ciabase *base = (struct ciabase *)dev_id; - int mach_irq; + int mach_irq, i; unsigned char ints; mach_irq = base->cia_irq; + irq = SYS_IRQS + mach_irq; ints = cia_set_irq(base, CIA_ICR_ALL); amiga_custom.intreq = base->int_mask; - for (; ints; mach_irq++, ints >>= 1) { - if (ints & 1) - m68k_handle_int(mach_irq, fp); + for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) { + if (ints & 1) { + kstat_cpu(0).irqs[irq]++; + base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp); + } + ints >>= 1; } + amiga_do_irq_list(base->server_irq, fp); return IRQ_HANDLED; } -static void cia_enable_irq(unsigned int irq) +void __init cia_init_IRQ(struct ciabase *base) { - unsigned char mask; + int i; - if (irq >= IRQ_AMIGA_CIAB) { - mask = 1 << (irq - IRQ_AMIGA_CIAB); - cia_set_irq(&ciab_base, mask); - cia_able_irq(&ciab_base, CIA_ICR_SETCLR | mask); - } else { - mask = 1 << (irq - IRQ_AMIGA_CIAA); - cia_set_irq(&ciaa_base, mask); - cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | mask); + /* init isr handlers */ + for (i = 0; i < CIA_IRQS; i++) { + base->irq_list[i].handler = NULL; + base->irq_list[i].flags = 0; } -} - -static void cia_disable_irq(unsigned int irq) -{ - if (irq >= IRQ_AMIGA_CIAB) - cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); - else - cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); -} -static struct irq_controller cia_irq_controller = { - .name = "cia", - .lock = SPIN_LOCK_UNLOCKED, - .enable = cia_enable_irq, - .disable = cia_disable_irq, -}; + /* clear any pending interrupt and turn off all interrupts */ + cia_set_irq(base, CIA_ICR_ALL); + cia_able_irq(base, CIA_ICR_ALL); -/* - * Override auto irq 2 & 6 and use them as general chain - * for external interrupts, we link the CIA interrupt sources - * into this chain. - */ + /* install CIA handler */ + request_irq(base->handler_irq, cia_handler, 0, base->name, base); -static void auto_enable_irq(unsigned int irq) -{ - switch (irq) { - case IRQ_AUTO_2: - amiga_custom.intena = IF_SETCLR | IF_PORTS; - break; - case IRQ_AUTO_6: - amiga_custom.intena = IF_SETCLR | IF_EXTER; - break; - } + amiga_custom.intena = IF_SETCLR | base->int_mask; } -static void auto_disable_irq(unsigned int irq) +int cia_get_irq_list(struct ciabase *base, struct seq_file *p) { - switch (irq) { - case IRQ_AUTO_2: - amiga_custom.intena = IF_PORTS; - break; - case IRQ_AUTO_6: - amiga_custom.intena = IF_EXTER; - break; + int i, j; + + j = base->cia_irq; + for (i = 0; i < CIA_IRQS; i++) { + seq_printf(p, "cia %2d: %10d ", j + i, + kstat_cpu(0).irqs[SYS_IRQS + j + i]); + seq_puts(p, " "); + seq_printf(p, "%s\n", base->irq_list[i].devname); } -} - -static struct irq_controller auto_irq_controller = { - .name = "auto", - .lock = SPIN_LOCK_UNLOCKED, - .enable = auto_enable_irq, - .disable = auto_disable_irq, -}; - -void __init cia_init_IRQ(struct ciabase *base) -{ - m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); - - /* clear any pending interrupt and turn off all interrupts */ - cia_set_irq(base, CIA_ICR_ALL); - cia_able_irq(base, CIA_ICR_ALL); - - /* override auto int and install CIA handler */ - m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); - m68k_irq_startup(base->handler_irq); - request_irq(base->handler_irq, cia_handler, SA_SHIRQ, base->name, base); + return 0; } diff --git a/trunk/arch/m68k/amiga/config.c b/trunk/arch/m68k/amiga/config.c index b5b8a416a07a..12e3706fe02c 100644 --- a/trunk/arch/m68k/amiga/config.c +++ b/trunk/arch/m68k/amiga/config.c @@ -87,8 +87,17 @@ extern char m68k_debug_device[]; static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); /* amiga specific irq functions */ extern void amiga_init_IRQ (void); +extern irqreturn_t (*amiga_default_handler[]) (int, void *, struct pt_regs *); +extern int amiga_request_irq (unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, + void *dev_id); +extern void amiga_free_irq (unsigned int irq, void *dev_id); +extern void amiga_enable_irq (unsigned int); +extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); +extern int show_amiga_interrupts (struct seq_file *, void *); /* amiga specific timer functions */ static unsigned long amiga_gettimeoffset (void); static int a3000_hwclk (int, struct rtc_time *); @@ -383,8 +392,14 @@ void __init config_amiga(void) mach_sched_init = amiga_sched_init; mach_init_IRQ = amiga_init_IRQ; + mach_default_handler = &amiga_default_handler; + mach_request_irq = amiga_request_irq; + mach_free_irq = amiga_free_irq; + enable_irq = amiga_enable_irq; + disable_irq = amiga_disable_irq; mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; + mach_get_irq_list = show_amiga_interrupts; mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_hwclk = a3000_hwclk; diff --git a/trunk/arch/m68k/apollo/Makefile b/trunk/arch/m68k/apollo/Makefile index 76a057962c38..39264f3b6ad6 100644 --- a/trunk/arch/m68k/apollo/Makefile +++ b/trunk/arch/m68k/apollo/Makefile @@ -2,4 +2,4 @@ # Makefile for Linux arch/m68k/amiga source directory # -obj-y := config.o dn_ints.o +obj-y := config.o dn_ints.o dma.o diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index 99c70978aafa..d401962d9b25 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -28,6 +28,11 @@ u_long apollo_model; extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *)); extern void dn_init_IRQ(void); +extern int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); +extern void dn_free_irq(unsigned int irq, void *dev_id); +extern void dn_enable_irq(unsigned int); +extern void dn_disable_irq(unsigned int); +extern int show_dn_interrupts(struct seq_file *, void *); extern unsigned long dn_gettimeoffset(void); extern int dn_dummy_hwclk(int, struct rtc_time *); extern int dn_dummy_set_clock_mmss(unsigned long); @@ -35,11 +40,13 @@ extern void dn_dummy_reset(void); extern void dn_dummy_waitbut(void); extern struct fb_info *dn_fb_init(long *); extern void dn_dummy_debug_init(void); +extern void dn_dummy_video_setup(char *,int *); extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp); #ifdef CONFIG_HEARTBEAT static void dn_heartbeat(int on); #endif static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *); +static irqreturn_t (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL; static void dn_get_model(char *model); static const char *apollo_models[] = { [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)", @@ -157,10 +164,17 @@ void config_apollo(void) { mach_sched_init=dn_sched_init; /* */ mach_init_IRQ=dn_init_IRQ; + mach_default_handler=NULL; + mach_request_irq = dn_request_irq; + mach_free_irq = dn_free_irq; + enable_irq = dn_enable_irq; + disable_irq = dn_disable_irq; + mach_get_irq_list = show_dn_interrupts; mach_gettimeoffset = dn_gettimeoffset; mach_max_dma_address = 0xffffffff; mach_hwclk = dn_dummy_hwclk; /* */ mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ + mach_process_int = dn_process_int; mach_reset = dn_dummy_reset; /* */ #ifdef CONFIG_HEARTBEAT mach_heartbeat = dn_heartbeat; @@ -175,13 +189,11 @@ void config_apollo(void) { } -irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) -{ - irqreturn_t (*timer_handler)(int, void *, struct pt_regs *) = dev_id; +irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) { volatile unsigned char x; - timer_handler(irq, dev_id, fp); + sched_timer_handler(irq,dev_id,fp); x=*(volatile unsigned char *)(timer+3); x=*(volatile unsigned char *)(timer+5); @@ -205,7 +217,9 @@ void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); #endif - request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine); + sched_timer_handler=timer_routine; + request_irq(0,dn_timer_int,0,NULL,NULL); + } unsigned long dn_gettimeoffset(void) { diff --git a/trunk/arch/m68k/apollo/dn_ints.c b/trunk/arch/m68k/apollo/dn_ints.c index 9fe07803797b..a31259359a12 100644 --- a/trunk/arch/m68k/apollo/dn_ints.c +++ b/trunk/arch/m68k/apollo/dn_ints.c @@ -1,44 +1,125 @@ -#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include #include +#include -void dn_process_int(unsigned int irq, struct pt_regs *fp) +static irq_handler_t dn_irqs[16]; + +irqreturn_t dn_process_int(int irq, struct pt_regs *fp) { - m68k_handle_int(irq, fp); + irqreturn_t res = IRQ_NONE; + + if(dn_irqs[irq-160].handler) { + res = dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp); + } else { + printk("spurious irq %d occurred\n",irq); + } + + *(volatile unsigned char *)(pica)=0x20; + *(volatile unsigned char *)(picb)=0x20; - *(volatile unsigned char *)(pica)=0x20; - *(volatile unsigned char *)(picb)=0x20; + return res; } -int apollo_irq_startup(unsigned int irq) -{ - if (irq < 8) - *(volatile unsigned char *)(pica+1) &= ~(1 << irq); - else - *(volatile unsigned char *)(picb+1) &= ~(1 << (irq - 8)); - return 0; +void dn_init_IRQ(void) { + + int i; + + for(i=0;i<16;i++) { + dn_irqs[i].handler=NULL; + dn_irqs[i].flags=IRQ_FLG_STD; + dn_irqs[i].dev_id=NULL; + dn_irqs[i].devname=NULL; + } + } -void apollo_irq_shutdown(unsigned int irq) -{ - if (irq < 8) - *(volatile unsigned char *)(pica+1) |= (1 << irq); - else - *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); +int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { + + if((irq<0) || (irq>15)) { + printk("Trying to request invalid IRQ\n"); + return -ENXIO; + } + + if(!dn_irqs[irq].handler) { + dn_irqs[irq].handler=handler; + dn_irqs[irq].flags=IRQ_FLG_STD; + dn_irqs[irq].dev_id=dev_id; + dn_irqs[irq].devname=devname; + if(irq<8) + *(volatile unsigned char *)(pica+1)&=~(1<15)) { + printk("Trying to free invalid IRQ\n"); + return ; + } + + if(irq<8) + *(volatile unsigned char *)(pica+1)|=(1< 0 && \ @@ -295,14 +301,6 @@ __asm__ (__ALIGN_STR "\n" ); for (;;); } -#endif - -/* - * Bitmap for free interrupt vector numbers - * (new vectors starting from 0x70 can be allocated by - * atari_register_vme_int()) - */ -static int free_vme_vec_bitmap; /* GK: * HBL IRQ handler for Falcon. Nobody needs it :-) @@ -315,33 +313,12 @@ __ALIGN_STR "\n\t" "orw #0x200,%sp@\n\t" /* set saved ipl to 2 */ "rte"); -extern void atari_microwire_cmd(int cmd); - -extern int atari_SCC_reset_done; - -static int atari_startup_irq(unsigned int irq) -{ - m68k_irq_startup(irq); - atari_turnon_irq(irq); - atari_enable_irq(irq); - return 0; -} +/* Defined in entry.S; only increments 'num_spurious' */ +asmlinkage void bad_interrupt(void); -static void atari_shutdown_irq(unsigned int irq) -{ - atari_disable_irq(irq); - atari_turnoff_irq(irq); - m68k_irq_shutdown(irq); -} +extern void atari_microwire_cmd( int cmd ); -static struct irq_controller atari_irq_controller = { - .name = "atari", - .lock = SPIN_LOCK_UNLOCKED, - .startup = atari_startup_irq, - .shutdown = atari_shutdown_irq, - .enable = atari_enable_irq, - .disable = atari_disable_irq, -}; +extern int atari_SCC_reset_done; /* * void atari_init_IRQ (void) @@ -356,8 +333,12 @@ static struct irq_controller atari_irq_controller = { void __init atari_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER, 192, NULL); - m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); + int i; + + /* initialize the vector table */ + for (i = 0; i < NUM_INT_SOURCES; ++i) { + vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_interrupt; + } /* Initialize the MFP(s) */ @@ -397,7 +378,8 @@ void __init atari_init_IRQ(void) * enabled in VME mask */ tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ - } else { + } + else { /* If no SCU and no Hades, the HSYNC interrupt needs to be * disabled this way. (Else _inthandler in kernel/sys_call.S * gets overruns) @@ -422,6 +404,184 @@ void __init atari_init_IRQ(void) } +static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp ) +{ + irq_node_t *node; + + for (node = (irq_node_t *)dev_id; node; node = node->next) + node->handler(irq, node->dev_id, fp); + return IRQ_HANDLED; +} + + +/* + * atari_request_irq : add an interrupt service routine for a particular + * machine specific interrupt source. + * If the addition was successful, it returns 0. + */ + +int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + int vector; + unsigned long oflags = flags; + + /* + * The following is a hack to make some PCI card drivers work, + * which set the SA_SHIRQ flag. + */ + + flags &= ~SA_SHIRQ; + + if (flags == SA_INTERRUPT) { + printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n", + __FUNCTION__, devname); + flags = IRQ_TYPE_SLOW; + } + if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) { + printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n", + __FUNCTION__, flags, oflags, devname); + return -EINVAL; + } + if (!IS_VALID_INTNO(irq)) { + printk ("%s: Unknown irq %d requested from %s\n", + __FUNCTION__, irq, devname); + return -ENXIO; + } + vector = IRQ_SOURCE_TO_VECTOR(irq); + + /* + * Check type/source combination: slow ints are (currently) + * only possible for MFP-interrupts. + */ + if (flags == IRQ_TYPE_SLOW && + (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) { + printk ("%s: Slow irq requested for non-MFP source %d from %s\n", + __FUNCTION__, irq, devname); + return -EINVAL; + } + + if (vectors[vector] == bad_interrupt) { + /* int has no handler yet */ + irq_handler[irq].handler = handler; + irq_handler[irq].dev_id = dev_id; + irq_param[irq].flags = flags; + irq_param[irq].devname = devname; + vectors[vector] = + (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] : + (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler : + atari_prio_irq_handler; + /* If MFP int, also enable and umask it */ + atari_turnon_irq(irq); + atari_enable_irq(irq); + + return 0; + } + else if (irq_param[irq].flags == flags) { + /* old handler is of same type -> handlers can be chained */ + irq_node_t *node; + unsigned long flags; + + local_irq_save(flags); + + if (irq_handler[irq].handler != atari_call_irq_list) { + /* Only one handler yet, make a node for this first one */ + if (!(node = new_irq_node())) + return -ENOMEM; + node->handler = irq_handler[irq].handler; + node->dev_id = irq_handler[irq].dev_id; + node->devname = irq_param[irq].devname; + node->next = NULL; + + irq_handler[irq].handler = atari_call_irq_list; + irq_handler[irq].dev_id = node; + irq_param[irq].devname = "chained"; + } + + if (!(node = new_irq_node())) + return -ENOMEM; + node->handler = handler; + node->dev_id = dev_id; + node->devname = devname; + /* new handlers are put in front of the queue */ + node->next = irq_handler[irq].dev_id; + irq_handler[irq].dev_id = node; + + local_irq_restore(flags); + return 0; + } else { + printk ("%s: Irq %d allocated by other type int (call from %s)\n", + __FUNCTION__, irq, devname); + return -EBUSY; + } +} + +void atari_free_irq(unsigned int irq, void *dev_id) +{ + unsigned long flags; + int vector; + irq_node_t **list, *node; + + if (!IS_VALID_INTNO(irq)) { + printk("%s: Unknown irq %d\n", __FUNCTION__, irq); + return; + } + + vector = IRQ_SOURCE_TO_VECTOR(irq); + if (vectors[vector] == bad_interrupt) + goto not_found; + + local_irq_save(flags); + + if (irq_handler[irq].handler != atari_call_irq_list) { + /* It's the only handler for the interrupt */ + if (irq_handler[irq].dev_id != dev_id) { + local_irq_restore(flags); + goto not_found; + } + irq_handler[irq].handler = NULL; + irq_handler[irq].dev_id = NULL; + irq_param[irq].devname = NULL; + vectors[vector] = bad_interrupt; + /* If MFP int, also disable it */ + atari_disable_irq(irq); + atari_turnoff_irq(irq); + + local_irq_restore(flags); + return; + } + + /* The interrupt is chained, find the irq on the list */ + for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) { + if ((*list)->dev_id == dev_id) break; + } + if (!*list) { + local_irq_restore(flags); + goto not_found; + } + + (*list)->handler = NULL; /* Mark it as free for reallocation */ + *list = (*list)->next; + + /* If there's now only one handler, unchain the interrupt, i.e. plug in + * the handler directly again and omit atari_call_irq_list */ + node = (irq_node_t *)irq_handler[irq].dev_id; + if (node && !node->next) { + irq_handler[irq].handler = node->handler; + irq_handler[irq].dev_id = node->dev_id; + irq_param[irq].devname = node->devname; + node->handler = NULL; /* Mark it as free for reallocation */ + } + + local_irq_restore(flags); + return; + +not_found: + printk("%s: tried to remove invalid irq\n", __FUNCTION__); + return; +} + + /* * atari_register_vme_int() returns the number of a free interrupt vector for * hardware with a programmable int vector (probably a VME board). @@ -431,24 +591,58 @@ unsigned long atari_register_vme_int(void) { int i; - for (i = 0; i < 32; i++) - if ((free_vme_vec_bitmap & (1 << i)) == 0) + for(i = 0; i < 32; i++) + if((free_vme_vec_bitmap & (1 << i)) == 0) break; - if (i == 16) + if(i == 16) return 0; free_vme_vec_bitmap |= 1 << i; - return VME_SOURCE_BASE + i; + return (VME_SOURCE_BASE + i); } void atari_unregister_vme_int(unsigned long irq) { - if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { + if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { irq -= VME_SOURCE_BASE; free_vme_vec_bitmap &= ~(1 << irq); } } +int show_atari_interrupts(struct seq_file *p, void *v) +{ + int i; + + for (i = 0; i < NUM_INT_SOURCES; ++i) { + if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt) + continue; + if (i < STMFP_SOURCE_BASE) + seq_printf(p, "auto %2d: %10u ", + i, kstat_cpu(0).irqs[i]); + else + seq_printf(p, "vec $%02x: %10u ", + IRQ_SOURCE_TO_VECTOR(i), + kstat_cpu(0).irqs[i]); + + if (irq_handler[i].handler != atari_call_irq_list) { + seq_printf(p, "%s\n", irq_param[i].devname); + } + else { + irq_node_t *n; + for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) { + seq_printf(p, "%s\n", n->devname); + if (n->next) + seq_puts(p, " " ); + } + } + } + if (num_spurious) + seq_printf(p, "spurio.: %10u\n", num_spurious); + + return 0; +} + + diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index 727289acad7e..1012b08e5522 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -57,6 +57,12 @@ static int atari_get_hardware_list(char *buffer); /* atari specific irq functions */ extern void atari_init_IRQ (void); +extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +extern void atari_free_irq (unsigned int irq, void *dev_id); +extern void atari_enable_irq (unsigned int); +extern void atari_disable_irq (unsigned int); +extern int show_atari_interrupts (struct seq_file *, void *); extern void atari_mksound( unsigned int count, unsigned int ticks ); #ifdef CONFIG_HEARTBEAT static void atari_heartbeat( int on ); @@ -226,8 +232,13 @@ void __init config_atari(void) mach_sched_init = atari_sched_init; mach_init_IRQ = atari_init_IRQ; + mach_request_irq = atari_request_irq; + mach_free_irq = atari_free_irq; + enable_irq = atari_enable_irq; + disable_irq = atari_disable_irq; mach_get_model = atari_get_model; mach_get_hardware_list = atari_get_hardware_list; + mach_get_irq_list = show_atari_interrupts; mach_gettimeoffset = atari_gettimeoffset; mach_reset = atari_reset; mach_max_dma_address = 0xffffff; diff --git a/trunk/arch/m68k/bvme6000/Makefile b/trunk/arch/m68k/bvme6000/Makefile index d8174004fe2f..2348e6ceed1e 100644 --- a/trunk/arch/m68k/bvme6000/Makefile +++ b/trunk/arch/m68k/bvme6000/Makefile @@ -2,4 +2,4 @@ # Makefile for Linux arch/m68k/bvme6000 source directory # -obj-y := config.o rtc.o +obj-y := config.o bvmeints.o rtc.o diff --git a/trunk/arch/m68k/bvme6000/bvmeints.c b/trunk/arch/m68k/bvme6000/bvmeints.c new file mode 100644 index 000000000000..298a8df02664 --- /dev/null +++ b/trunk/arch/m68k/bvme6000/bvmeints.c @@ -0,0 +1,160 @@ +/* + * arch/m68k/bvme6000/bvmeints.c + * + * Copyright (C) 1997 Richard Hirst [richard@sleepie.demon.co.uk] + * + * based on amiints.c -- Amiga Linux interrupt handling code + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp); + +/* + * This should ideally be 4 elements only, for speed. + */ + +static struct { + irqreturn_t (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + unsigned count; +} irq_tab[256]; + +/* + * void bvme6000_init_IRQ (void) + * + * Parameters: None + * + * Returns: Nothing + * + * This function is called during kernel startup to initialize + * the bvme6000 IRQ handling routines. + */ + +void bvme6000_init_IRQ (void) +{ + int i; + + for (i = 0; i < 256; i++) { + irq_tab[i].handler = bvme6000_defhand; + irq_tab[i].flags = IRQ_FLG_STD; + irq_tab[i].dev_id = NULL; + irq_tab[i].devname = NULL; + irq_tab[i].count = 0; + } +} + +int bvme6000_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + if (irq > 255) { + printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + return -ENXIO; + } +#if 0 + /* Nothing special about auto-vectored devices for the BVME6000, + * but treat it specially to avoid changes elsewhere. + */ + + if (irq >= VEC_INT1 && irq <= VEC_INT7) + return cpu_request_irq(irq - VEC_SPUR, handler, flags, + devname, dev_id); +#endif + if (!(irq_tab[irq].flags & IRQ_FLG_STD)) { + if (irq_tab[irq].flags & IRQ_FLG_LOCK) { + printk("%s: IRQ %d from %s is not replaceable\n", + __FUNCTION__, irq, irq_tab[irq].devname); + return -EBUSY; + } + if (flags & IRQ_FLG_REPLACE) { + printk("%s: %s can't replace IRQ %d from %s\n", + __FUNCTION__, devname, irq, irq_tab[irq].devname); + return -EBUSY; + } + } + irq_tab[irq].handler = handler; + irq_tab[irq].flags = flags; + irq_tab[irq].dev_id = dev_id; + irq_tab[irq].devname = devname; + return 0; +} + +void bvme6000_free_irq(unsigned int irq, void *dev_id) +{ + if (irq > 255) { + printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); + return; + } +#if 0 + if (irq >= VEC_INT1 && irq <= VEC_INT7) { + cpu_free_irq(irq - VEC_SPUR, dev_id); + return; + } +#endif + if (irq_tab[irq].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_tab[irq].devname); + + irq_tab[irq].handler = bvme6000_defhand; + irq_tab[irq].flags = IRQ_FLG_STD; + irq_tab[irq].dev_id = NULL; + irq_tab[irq].devname = NULL; +} + +irqreturn_t bvme6000_process_int (unsigned long vec, struct pt_regs *fp) +{ + if (vec > 255) { + printk ("bvme6000_process_int: Illegal vector %ld", vec); + return IRQ_NONE; + } else { + irq_tab[vec].count++; + irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp); + return IRQ_HANDLED; + } +} + +int show_bvme6000_interrupts(struct seq_file *p, void *v) +{ + int i; + + for (i = 0; i < 256; i++) { + if (irq_tab[i].count) + seq_printf(p, "Vec 0x%02x: %8d %s\n", + i, irq_tab[i].count, + irq_tab[i].devname ? irq_tab[i].devname : "free"); + } + return 0; +} + + +static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp) +{ + printk ("Unknown interrupt 0x%02x\n", irq); + return IRQ_NONE; +} + +void bvme6000_enable_irq (unsigned int irq) +{ +} + + +void bvme6000_disable_irq (unsigned int irq) +{ +} + diff --git a/trunk/arch/m68k/bvme6000/config.c b/trunk/arch/m68k/bvme6000/config.c index d1e916ae55a8..c90cb5fcc8ef 100644 --- a/trunk/arch/m68k/bvme6000/config.c +++ b/trunk/arch/m68k/bvme6000/config.c @@ -36,8 +36,15 @@ #include #include +extern irqreturn_t bvme6000_process_int (int level, struct pt_regs *regs); +extern void bvme6000_init_IRQ (void); +extern void bvme6000_free_irq (unsigned int, void *); +extern int show_bvme6000_interrupts(struct seq_file *, void *); +extern void bvme6000_enable_irq (unsigned int); +extern void bvme6000_disable_irq (unsigned int); static void bvme6000_get_model(char *model); static int bvme6000_get_hardware_list(char *buffer); +extern int bvme6000_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long bvme6000_gettimeoffset (void); extern int bvme6000_hwclk (int, struct rtc_time *); @@ -93,14 +100,6 @@ static int bvme6000_get_hardware_list(char *buffer) return 0; } -/* - * This function is called during kernel startup to initialize - * the bvme6000 IRQ handling routines. - */ -static void bvme6000_init_IRQ(void) -{ - m68k_setup_user_interrupt(VEC_USER, 192, NULL); -} void __init config_bvme6000(void) { @@ -128,6 +127,12 @@ void __init config_bvme6000(void) mach_hwclk = bvme6000_hwclk; mach_set_clock_mmss = bvme6000_set_clock_mmss; mach_reset = bvme6000_reset; + mach_free_irq = bvme6000_free_irq; + mach_process_int = bvme6000_process_int; + mach_get_irq_list = show_bvme6000_interrupts; + mach_request_irq = bvme6000_request_irq; + enable_irq = bvme6000_enable_irq; + disable_irq = bvme6000_disable_irq; mach_get_model = bvme6000_get_model; mach_get_hardware_list = bvme6000_get_hardware_list; diff --git a/trunk/arch/m68k/hp300/Makefile b/trunk/arch/m68k/hp300/Makefile index 288b9c67c9bf..89b6317899e3 100644 --- a/trunk/arch/m68k/hp300/Makefile +++ b/trunk/arch/m68k/hp300/Makefile @@ -2,4 +2,4 @@ # Makefile for Linux arch/m68k/hp300 source directory # -obj-y := ksyms.o config.o time.o reboot.o +obj-y := ksyms.o config.o ints.o time.o reboot.o diff --git a/trunk/arch/m68k/hp300/config.c b/trunk/arch/m68k/hp300/config.c index 2ef271cd818b..6d129eef370f 100644 --- a/trunk/arch/m68k/hp300/config.c +++ b/trunk/arch/m68k/hp300/config.c @@ -21,6 +21,7 @@ #include #include +#include "ints.h" #include "time.h" unsigned long hp300_model; @@ -63,6 +64,8 @@ static char *hp300_models[] __initdata = { static char hp300_model_name[13] = "HP9000/"; extern void hp300_reset(void); +extern irqreturn_t (*hp300_default_handler[])(int, void *, struct pt_regs *); +extern int show_hp300_interrupts(struct seq_file *, void *); #ifdef CONFIG_SERIAL_8250_CONSOLE extern int hp300_setup_serial_console(void) __init; #endif @@ -242,16 +245,16 @@ static unsigned int hp300_get_ss(void) hp300_rtc_read(RTC_REG_SEC2); } -static void __init hp300_init_IRQ(void) -{ -} - void __init config_hp300(void) { mach_sched_init = hp300_sched_init; mach_init_IRQ = hp300_init_IRQ; + mach_request_irq = hp300_request_irq; + mach_free_irq = hp300_free_irq; mach_get_model = hp300_get_model; + mach_get_irq_list = show_hp300_interrupts; mach_gettimeoffset = hp300_gettimeoffset; + mach_default_handler = &hp300_default_handler; mach_hwclk = hp300_hwclk; mach_get_ss = hp300_get_ss; mach_reset = hp300_reset; diff --git a/trunk/arch/m68k/hp300/ints.c b/trunk/arch/m68k/hp300/ints.c new file mode 100644 index 000000000000..0c5bb403e893 --- /dev/null +++ b/trunk/arch/m68k/hp300/ints.c @@ -0,0 +1,175 @@ +/* + * linux/arch/m68k/hp300/ints.c + * + * Copyright (C) 1998 Philip Blundell + * + * This file contains the HP300-specific interrupt handling. + * We only use the autovector interrupts, and therefore we need to + * maintain lists of devices sharing each ipl. + * [ipl list code added by Peter Maydell 06/1998] + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ints.h" + +/* Each ipl has a linked list of interrupt service routines. + * Service routines are added via hp300_request_irq() and removed + * via hp300_free_irq(). The device driver should set IRQ_FLG_FAST + * if it needs to be serviced early (eg FIFOless UARTs); this will + * cause it to be added at the front of the queue rather than + * the back. + * Currently IRQ_FLG_SLOW and flags=0 are treated identically; if + * we needed three levels of priority we could distinguish them + * but this strikes me as mildly ugly... + */ + +/* we start with no entries in any list */ +static irq_node_t *hp300_irq_list[HP300_NUM_IRQS]; + +static spinlock_t irqlist_lock; + +/* This handler receives all interrupts, dispatching them to the registered handlers */ +static irqreturn_t hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp) +{ + irq_node_t *t; + /* We just give every handler on the chain an opportunity to handle + * the interrupt, in priority order. + */ + for(t = hp300_irq_list[irq]; t; t=t->next) + t->handler(irq, t->dev_id, fp); + /* We could put in some accounting routines, checks for stray interrupts, + * etc, in here. Note that currently we can't tell whether or not + * a handler handles the interrupt, though. + */ + return IRQ_HANDLED; +} + +static irqreturn_t hp300_badint(int irq, void *dev_id, struct pt_regs *fp) +{ + num_spurious += 1; + return IRQ_NONE; +} + +irqreturn_t (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { + [0] = hp300_badint, + [1] = hp300_int_handler, + [2] = hp300_int_handler, + [3] = hp300_int_handler, + [4] = hp300_int_handler, + [5] = hp300_int_handler, + [6] = hp300_int_handler, + [7] = hp300_int_handler +}; + +/* dev_id had better be unique to each handler because it's the only way we have + * to distinguish handlers when removing them... + * + * It would be pretty easy to support IRQ_FLG_LOCK (handler is not replacable) + * and IRQ_FLG_REPLACE (handler replaces existing one with this dev_id) + * if we wanted to. IRQ_FLG_FAST is needed for devices where interrupt latency + * matters (eg the dreaded FIFOless UART...) + */ +int hp300_request_irq(unsigned int irq, + irqreturn_t (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + irq_node_t *t, *n = new_irq_node(); + + if (!n) /* oops, no free nodes */ + return -ENOMEM; + + spin_lock_irqsave(&irqlist_lock, flags); + + if (!hp300_irq_list[irq]) { + /* no list yet */ + hp300_irq_list[irq] = n; + n->next = NULL; + } else if (flags & IRQ_FLG_FAST) { + /* insert at head of list */ + n->next = hp300_irq_list[irq]; + hp300_irq_list[irq] = n; + } else { + /* insert at end of list */ + for(t = hp300_irq_list[irq]; t->next; t = t->next) + /* do nothing */; + n->next = NULL; + t->next = n; + } + + /* Fill in n appropriately */ + n->handler = handler; + n->flags = flags; + n->dev_id = dev_id; + n->devname = devname; + spin_unlock_irqrestore(&irqlist_lock, flags); + return 0; +} + +void hp300_free_irq(unsigned int irq, void *dev_id) +{ + irq_node_t *t; + unsigned long flags; + + spin_lock_irqsave(&irqlist_lock, flags); + + t = hp300_irq_list[irq]; + if (!t) /* no handlers at all for that IRQ */ + { + printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq); + spin_unlock_irqrestore(&irqlist_lock, flags); + return; + } + + if (t->dev_id == dev_id) + { /* removing first handler on chain */ + t->flags = IRQ_FLG_STD; /* we probably don't really need these */ + t->dev_id = NULL; + t->devname = NULL; + t->handler = NULL; /* frees this irq_node_t */ + hp300_irq_list[irq] = t->next; + spin_unlock_irqrestore(&irqlist_lock, flags); + return; + } + + /* OK, must be removing from middle of the chain */ + + for (t = hp300_irq_list[irq]; t->next && t->next->dev_id != dev_id; t = t->next) + /* do nothing */; + if (!t->next) + { + printk(KERN_ERR "hp300_free_irq: attempt to remove nonexistent handler for IRQ %d\n", irq); + spin_unlock_irqrestore(&irqlist_lock, flags); + return; + } + /* remove the entry after t: */ + t->next->flags = IRQ_FLG_STD; + t->next->dev_id = NULL; + t->next->devname = NULL; + t->next->handler = NULL; + t->next = t->next->next; + + spin_unlock_irqrestore(&irqlist_lock, flags); +} + +int show_hp300_interrupts(struct seq_file *p, void *v) +{ + return 0; +} + +void __init hp300_init_IRQ(void) +{ + spin_lock_init(&irqlist_lock); +} diff --git a/trunk/arch/m68k/hp300/ints.h b/trunk/arch/m68k/hp300/ints.h new file mode 100644 index 000000000000..8cfabe2f3840 --- /dev/null +++ b/trunk/arch/m68k/hp300/ints.h @@ -0,0 +1,9 @@ +extern void hp300_init_IRQ(void); +extern void (*hp300_handlers[8])(int, void *, struct pt_regs *); +extern void hp300_free_irq(unsigned int irq, void *dev_id); +extern int hp300_request_irq(unsigned int irq, + irqreturn_t (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); + +/* number of interrupts, includes 0 (what's that?) */ +#define HP300_NUM_IRQS 8 diff --git a/trunk/arch/m68k/hp300/time.c b/trunk/arch/m68k/hp300/time.c index 7df05662b277..8da5b1b31e61 100644 --- a/trunk/arch/m68k/hp300/time.c +++ b/trunk/arch/m68k/hp300/time.c @@ -18,6 +18,7 @@ #include #include #include +#include "ints.h" /* Clock hardware definitions */ @@ -70,7 +71,7 @@ void __init hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs * asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); - request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); + cpu_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */ diff --git a/trunk/arch/m68k/kernel/Makefile b/trunk/arch/m68k/kernel/Makefile index dae609797dc0..458925c471a1 100644 --- a/trunk/arch/m68k/kernel/Makefile +++ b/trunk/arch/m68k/kernel/Makefile @@ -9,8 +9,8 @@ else endif extra-y += vmlinux.lds -obj-y := entry.o process.o traps.o ints.o dma.o signal.o ptrace.o \ - sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o +obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ + sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_MODULES) += module.o diff --git a/trunk/arch/m68k/kernel/dma.c b/trunk/arch/m68k/kernel/dma.c deleted file mode 100644 index fc449f8b2045..000000000000 --- a/trunk/arch/m68k/kernel/dma.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#undef DEBUG - -#include -#include -#include -#include - -#include -#include - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *handle, int flag) -{ - struct page *page, **map; - pgprot_t pgprot; - void *addr; - int i, order; - - pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); - - size = PAGE_ALIGN(size); - order = get_order(size); - - page = alloc_pages(flag, order); - if (!page) - return NULL; - - *handle = page_to_phys(page); - map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); - if (!map) { - __free_pages(page, order); - return NULL; - } - split_page(page, order); - - order = 1 << order; - size >>= PAGE_SHIFT; - map[0] = page; - for (i = 1; i < size; i++) - map[i] = page + i; - for (; i < order; i++) - __free_page(page + i); - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); - if (CPU_IS_040_OR_060) - pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; - else - pgprot_val(pgprot) |= _PAGE_NOCACHE030; - addr = vmap(map, size, flag, pgprot); - kfree(map); - - return addr; -} -EXPORT_SYMBOL(dma_alloc_coherent); - -void dma_free_coherent(struct device *dev, size_t size, - void *addr, dma_addr_t handle) -{ - pr_debug("dma_free_coherent: %p, %x\n", addr, handle); - vfree(addr); -} -EXPORT_SYMBOL(dma_free_coherent); - -inline void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, - enum dma_data_direction dir) -{ - switch (dir) { - case DMA_TO_DEVICE: - cache_push(handle, size); - break; - case DMA_FROM_DEVICE: - cache_clear(handle, size); - break; - default: - if (printk_ratelimit()) - printk("dma_sync_single_for_device: unsupported dir %u\n", dir); - break; - } -} -EXPORT_SYMBOL(dma_sync_single_for_device); - -void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - int i; - - for (i = 0; i < nents; sg++, i++) - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); -} -EXPORT_SYMBOL(dma_sync_sg_for_device); - -dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, - enum dma_data_direction dir) -{ - dma_addr_t handle = virt_to_bus(addr); - - dma_sync_single_for_device(dev, handle, size, dir); - return handle; -} -EXPORT_SYMBOL(dma_map_single); - -dma_addr_t dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir) -{ - dma_addr_t handle = page_to_phys(page) + offset; - - dma_sync_single_for_device(dev, handle, size, dir); - return handle; -} -EXPORT_SYMBOL(dma_map_page); - -int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - int i; - - for (i = 0; i < nents; sg++, i++) { - sg->dma_address = page_to_phys(sg->page) + sg->offset; - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); - } - return nents; -} -EXPORT_SYMBOL(dma_map_sg); diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S index 449b62b30f45..320fde05dc63 100644 --- a/trunk/arch/m68k/kernel/entry.S +++ b/trunk/arch/m68k/kernel/entry.S @@ -45,11 +45,9 @@ #include .globl system_call, buserr, trap, resume -.globl sys_call_table +.globl inthandler, sys_call_table .globl sys_fork, sys_clone, sys_vfork .globl ret_from_interrupt, bad_interrupt -.globl auto_irqhandler_fixup -.globl user_irqvec_fixup, user_irqhandler_fixup .text ENTRY(buserr) @@ -193,29 +191,65 @@ do_delayed_trace: jbra resume_userspace -/* This is the main interrupt handler for autovector interrupts */ +#if 0 +#ifdef CONFIG_AMIGA +ami_inthandler: + addql #1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT + SAVE_ALL_INT + GET_CURRENT(%d0) -ENTRY(auto_inthandler) + bfextu %sp@(PT_VECTOR){#4,#12},%d0 + movel %d0,%a0 + addql #1,%a0@(kstat+STAT_IRQ-VECOFF(VEC_SPUR)) + movel %a0@(autoirq_list-VECOFF(VEC_SPUR)),%a0 + +| amiga vector int handler get the req mask instead of irq vector + lea CUSTOMBASE,%a1 + movew %a1@(C_INTREQR),%d0 + andw %a1@(C_INTENAR),%d0 + +| prepare stack (push frame pointer, dev_id & req mask) + pea %sp@ + movel %a0@(IRQ_DEVID),%sp@- + movel %d0,%sp@- + pea %pc@(ret_from_interrupt:w) + jbra @(IRQ_HANDLER,%a0)@(0) + +ENTRY(nmi_handler) + rte +#endif +#endif + +/* +** This is the main interrupt handler, responsible for calling process_int() +*/ +inthandler: SAVE_ALL_INT GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) | put exception # in d0 - bfextu %sp@(PT_VECTOR){#4,#10},%d0 - subw #VEC_SPUR,%d0 + bfextu %sp@(PT_VECTOR){#4,#10},%d0 movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack -auto_irqhandler_fixup = . + 2 - jsr m68k_handle_int | process the IRQ - addql #8,%sp | pop parameters off stack +#if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD) + btstb #4,0xff000000 | Q40 floppy needs very special treatment ... + jbeq 1f + btstb #3,0xff000004 + jbeq 1f + jbsr floppy_hardint + jbra 3f +1: +#endif + jbsr process_int | process the IRQ +3: addql #8,%sp | pop parameters off stack ret_from_interrupt: - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) - jeq ret_from_last_interrupt -2: RESTORE_ALL - - ALIGN -ret_from_last_interrupt: + subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) + jeq 1f +2: + RESTORE_ALL +1: moveq #(~ALLOWINT>>8)&0xff,%d0 andb %sp@(PT_SR),%d0 jne 2b @@ -226,42 +260,12 @@ ret_from_last_interrupt: pea ret_from_exception jra do_softirq -/* Handler for user defined interrupt vectors */ - -ENTRY(user_inthandler) - SAVE_ALL_INT - GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) - | put exception # in d0 - bfextu %sp@(PT_VECTOR){#4,#10},%d0 -user_irqvec_fixup = . + 2 - subw #VEC_USER,%d0 - - movel %sp,%sp@- - movel %d0,%sp@- | put vector # on stack -user_irqhandler_fixup = . + 2 - jsr m68k_handle_int | process the IRQ - addql #8,%sp | pop parameters off stack - - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL /* Handler for uninitialized and spurious interrupts */ -ENTRY(bad_inthandler) - SAVE_ALL_INT - GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) - - movel %sp,%sp@- - jsr handle_badint - addql #4,%sp - - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL - +bad_interrupt: + addql #1,num_spurious + rte ENTRY(sys_fork) SAVE_SWITCH_STACK diff --git a/trunk/arch/m68k/kernel/ints.c b/trunk/arch/m68k/kernel/ints.c index 5a8344b93547..514d323ad536 100644 --- a/trunk/arch/m68k/kernel/ints.c +++ b/trunk/arch/m68k/kernel/ints.c @@ -39,40 +39,47 @@ #include #include #include -#include #ifdef CONFIG_Q40 #include #endif -extern u32 auto_irqhandler_fixup[]; -extern u32 user_irqhandler_fixup[]; -extern u16 user_irqvec_fixup[]; - /* table for system interrupt handlers */ -static struct irq_node *irq_list[NR_IRQS]; -static struct irq_controller *irq_controller[NR_IRQS]; -static int irq_depth[NR_IRQS]; - -static int m68k_first_user_vec; - -static struct irq_controller auto_irq_controller = { - .name = "auto", - .lock = SPIN_LOCK_UNLOCKED, - .startup = m68k_irq_startup, - .shutdown = m68k_irq_shutdown, +static irq_handler_t irq_list[SYS_IRQS]; + +static const char *default_names[SYS_IRQS] = { + [0] = "spurious int", + [1] = "int1 handler", + [2] = "int2 handler", + [3] = "int3 handler", + [4] = "int4 handler", + [5] = "int5 handler", + [6] = "int6 handler", + [7] = "int7 handler" }; -static struct irq_controller user_irq_controller = { - .name = "user", - .lock = SPIN_LOCK_UNLOCKED, - .startup = m68k_irq_startup, - .shutdown = m68k_irq_shutdown, -}; +/* The number of spurious interrupts */ +volatile unsigned int num_spurious; #define NUM_IRQ_NODES 100 static irq_node_t nodes[NUM_IRQ_NODES]; +static void dummy_enable_irq(unsigned int irq); +static void dummy_disable_irq(unsigned int irq); +static int dummy_request_irq(unsigned int irq, + irqreturn_t (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +static void dummy_free_irq(unsigned int irq, void *dev_id); + +void (*enable_irq) (unsigned int) = dummy_enable_irq; +void (*disable_irq) (unsigned int) = dummy_disable_irq; + +int (*mach_request_irq) (unsigned int, irqreturn_t (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *) = dummy_request_irq; +void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; + +void init_irq_proc(void); + /* * void init_IRQ(void) * @@ -88,76 +95,18 @@ void __init init_IRQ(void) { int i; - /* assembly irq entry code relies on this... */ - if (HARDIRQ_MASK != 0x00ff0000) { - extern void hardirq_mask_is_broken(void); - hardirq_mask_is_broken(); + for (i = 0; i < SYS_IRQS; i++) { + if (mach_default_handler) + irq_list[i].handler = (*mach_default_handler)[i]; + irq_list[i].flags = 0; + irq_list[i].dev_id = NULL; + irq_list[i].devname = default_names[i]; } - for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) - irq_controller[i] = &auto_irq_controller; - - mach_init_IRQ(); -} - -/** - * m68k_setup_auto_interrupt - * @handler: called from auto vector interrupts - * - * setup the handler to be called from auto vector interrupts instead of the - * standard m68k_handle_int(), it will be called with irq numbers in the range - * from IRQ_AUTO_1 - IRQ_AUTO_7. - */ -void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) -{ - if (handler) - *auto_irqhandler_fixup = (u32)handler; - flush_icache(); -} - -/** - * m68k_setup_user_interrupt - * @vec: first user vector interrupt to handle - * @cnt: number of active user vector interrupts - * @handler: called from user vector interrupts - * - * setup user vector interrupts, this includes activating the specified range - * of interrupts, only then these interrupts can be requested (note: this is - * different from auto vector interrupts). An optional handler can be installed - * to be called instead of the default m68k_handle_int(), it will be called - * with irq numbers starting from IRQ_USER. - */ -void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)) -{ - int i; - - m68k_first_user_vec = vec; - for (i = 0; i < cnt; i++) - irq_controller[IRQ_USER + i] = &user_irq_controller; - *user_irqvec_fixup = vec - IRQ_USER; - if (handler) - *user_irqhandler_fixup = (u32)handler; - flush_icache(); -} - -/** - * m68k_setup_irq_controller - * @contr: irq controller which controls specified irq - * @irq: first irq to be managed by the controller - * - * Change the controller for the specified range of irq, which will be used to - * manage these irq. auto/user irq already have a default controller, which can - * be changed as well, but the controller probably should use m68k_irq_startup/ - * m68k_irq_shutdown. - */ -void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, - unsigned int cnt) -{ - int i; + for (i = 0; i < NUM_IRQ_NODES; i++) + nodes[i].handler = NULL; - for (i = 0; i < cnt; i++) - irq_controller[irq + i] = contr; + mach_init_IRQ (); } irq_node_t *new_irq_node(void) @@ -165,183 +114,84 @@ irq_node_t *new_irq_node(void) irq_node_t *node; short i; - for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { - if (!node->handler) { - memset(node, 0, sizeof(*node)); + for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) + if (!node->handler) return node; - } - } printk ("new_irq_node: out of nodes\n"); return NULL; } -int setup_irq(unsigned int irq, struct irq_node *node) -{ - struct irq_controller *contr; - struct irq_node **prev; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { - printk("%s: Incorrect IRQ %d from %s\n", - __FUNCTION__, irq, node->devname); - return -ENXIO; - } - - spin_lock_irqsave(&contr->lock, flags); - - prev = irq_list + irq; - if (*prev) { - /* Can't share interrupts unless both agree to */ - if (!((*prev)->flags & node->flags & SA_SHIRQ)) { - spin_unlock_irqrestore(&contr->lock, flags); - return -EBUSY; - } - while (*prev) - prev = &(*prev)->next; - } - - if (!irq_list[irq]) { - if (contr->startup) - contr->startup(irq); - else - contr->enable(irq); - } - node->next = NULL; - *prev = node; - - spin_unlock_irqrestore(&contr->lock, flags); - - return 0; -} - +/* + * We will keep these functions until I have convinced Linus to move + * the declaration of them from include/linux/sched.h to + * include/asm/irq.h. + */ int request_irq(unsigned int irq, irqreturn_t (*handler) (int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { - struct irq_node *node; - int res; - - node = new_irq_node(); - if (!node) - return -ENOMEM; - - node->handler = handler; - node->flags = flags; - node->dev_id = dev_id; - node->devname = devname; - - res = setup_irq(irq, node); - if (res) - node->handler = NULL; - - return res; + return mach_request_irq(irq, handler, flags, devname, dev_id); } EXPORT_SYMBOL(request_irq); void free_irq(unsigned int irq, void *dev_id) { - struct irq_controller *contr; - struct irq_node **p, *node; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { - printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); - return; - } - - spin_lock_irqsave(&contr->lock, flags); - - p = irq_list + irq; - while ((node = *p)) { - if (node->dev_id == dev_id) - break; - p = &node->next; - } - - if (node) { - *p = node->next; - node->handler = NULL; - } else - printk("%s: Removing probably wrong IRQ %d\n", - __FUNCTION__, irq); - - if (!irq_list[irq]) { - if (contr->shutdown) - contr->shutdown(irq); - else - contr->disable(irq); - } - - spin_unlock_irqrestore(&contr->lock, flags); + mach_free_irq(irq, dev_id); } EXPORT_SYMBOL(free_irq); -void enable_irq(unsigned int irq) +int cpu_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) { - struct irq_controller *contr; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { - printk("%s: Incorrect IRQ %d\n", - __FUNCTION__, irq); - return; + if (irq < IRQ1 || irq > IRQ7) { + printk("%s: Incorrect IRQ %d from %s\n", + __FUNCTION__, irq, devname); + return -ENXIO; } - spin_lock_irqsave(&contr->lock, flags); - if (irq_depth[irq]) { - if (!--irq_depth[irq]) { - if (contr->enable) - contr->enable(irq); +#if 0 + if (!(irq_list[irq].flags & IRQ_FLG_STD)) { + if (irq_list[irq].flags & IRQ_FLG_LOCK) { + printk("%s: IRQ %d from %s is not replaceable\n", + __FUNCTION__, irq, irq_list[irq].devname); + return -EBUSY; } - } else - WARN_ON(1); - spin_unlock_irqrestore(&contr->lock, flags); -} + if (!(flags & IRQ_FLG_REPLACE)) { + printk("%s: %s can't replace IRQ %d from %s\n", + __FUNCTION__, devname, irq, irq_list[irq].devname); + return -EBUSY; + } + } +#endif -EXPORT_SYMBOL(enable_irq); + irq_list[irq].handler = handler; + irq_list[irq].flags = flags; + irq_list[irq].dev_id = dev_id; + irq_list[irq].devname = devname; + return 0; +} -void disable_irq(unsigned int irq) +void cpu_free_irq(unsigned int irq, void *dev_id) { - struct irq_controller *contr; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { - printk("%s: Incorrect IRQ %d\n", - __FUNCTION__, irq); + if (irq < IRQ1 || irq > IRQ7) { + printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); return; } - spin_lock_irqsave(&contr->lock, flags); - if (!irq_depth[irq]++) { - if (contr->disable) - contr->disable(irq); - } - spin_unlock_irqrestore(&contr->lock, flags); -} + if (irq_list[irq].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_list[irq].devname); -EXPORT_SYMBOL(disable_irq); - -int m68k_irq_startup(unsigned int irq) -{ - if (irq <= IRQ_AUTO_7) - vectors[VEC_SPUR + irq] = auto_inthandler; - else - vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler; - return 0; + irq_list[irq].handler = (*mach_default_handler)[irq]; + irq_list[irq].flags = 0; + irq_list[irq].dev_id = NULL; + irq_list[irq].devname = default_names[irq]; } -void m68k_irq_shutdown(unsigned int irq) -{ - if (irq <= IRQ_AUTO_7) - vectors[VEC_SPUR + irq] = bad_inthandler; - else - vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; -} - - /* * Do we need these probe functions on the m68k? * @@ -369,50 +219,58 @@ int probe_irq_off (unsigned long irqs) EXPORT_SYMBOL(probe_irq_off); -unsigned int irq_canonicalize(unsigned int irq) +static void dummy_enable_irq(unsigned int irq) { -#ifdef CONFIG_Q40 - if (MACH_IS_Q40 && irq == 11) - irq = 10; -#endif - return irq; + printk("calling uninitialized enable_irq()\n"); } -EXPORT_SYMBOL(irq_canonicalize); +static void dummy_disable_irq(unsigned int irq) +{ + printk("calling uninitialized disable_irq()\n"); +} -asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) +static int dummy_request_irq(unsigned int irq, + irqreturn_t (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) { - struct irq_node *node; - - kstat_cpu(0).irqs[irq]++; - node = irq_list[irq]; - do { - node->handler(irq, node->dev_id, regs); - node = node->next; - } while (node); + printk("calling uninitialized request_irq()\n"); + return 0; } -asmlinkage void handle_badint(struct pt_regs *regs) +static void dummy_free_irq(unsigned int irq, void *dev_id) { - kstat_cpu(0).irqs[0]++; - printk("unexpected interrupt from %u\n", regs->vector); + printk("calling uninitialized disable_irq()\n"); +} + +asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) +{ + if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) { + vec -= VEC_SPUR; + kstat_cpu(0).irqs[vec]++; + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + } else { + if (mach_process_int) + mach_process_int(vec, fp); + else + panic("Can't process interrupt vector %ld\n", vec); + return; + } } int show_interrupts(struct seq_file *p, void *v) { - struct irq_controller *contr; - struct irq_node *node; int i = *(loff_t *) v; /* autovector interrupts */ - if (irq_list[i]) { - contr = irq_controller[i]; - node = irq_list[i]; - seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); - while ((node = node->next)) - seq_printf(p, ", %s", node->devname); - seq_puts(p, "\n"); - } + if (i < SYS_IRQS) { + if (mach_default_handler) { + seq_printf(p, "auto %2d: %10u ", i, + i ? kstat_cpu(0).irqs[i] : num_spurious); + seq_puts(p, " "); + seq_printf(p, "%s\n", irq_list[i].devname); + } + } else if (i == SYS_IRQS) + mach_get_irq_list(p, v); return 0; } diff --git a/trunk/arch/m68k/kernel/m68k_ksyms.c b/trunk/arch/m68k/kernel/m68k_ksyms.c index 1f5e1b5aeda4..5b7952ea2bae 100644 --- a/trunk/arch/m68k/kernel/m68k_ksyms.c +++ b/trunk/arch/m68k/kernel/m68k_ksyms.c @@ -57,6 +57,8 @@ EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); #ifdef CONFIG_VME EXPORT_SYMBOL(vme_brdtype); diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 214a95f9f3ac..750d5b3c971f 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -68,8 +68,11 @@ char m68k_debug_device[6] = ""; void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; /* machine dependent irq functions */ void (*mach_init_IRQ) (void) __initdata = NULL; +irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); void (*mach_get_model) (char *model); int (*mach_get_hardware_list) (char *buffer); +int (*mach_get_irq_list) (struct seq_file *, void *); +irqreturn_t (*mach_process_int) (int, struct pt_regs *); /* machine dependent timer functions */ unsigned long (*mach_gettimeoffset) (void); int (*mach_hwclk) (int, struct rtc_time*); diff --git a/trunk/arch/m68k/kernel/signal.c b/trunk/arch/m68k/kernel/signal.c index f9af893cd289..866917bfa028 100644 --- a/trunk/arch/m68k/kernel/signal.c +++ b/trunk/arch/m68k/kernel/signal.c @@ -763,7 +763,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) + if (!on_sig_stack(usp)) usp = current->sas_ss_sp + current->sas_ss_size; } return (void __user *)((usp - frame_size) & -8UL); diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index e86de7b061cd..cdf58fbb3e73 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -45,6 +45,7 @@ asmlinkage void system_call(void); asmlinkage void buserr(void); asmlinkage void trap(void); +asmlinkage void inthandler(void); asmlinkage void nmihandler(void); #ifdef CONFIG_M68KFPU_EMU asmlinkage void fpu_emu(void); @@ -52,7 +53,51 @@ asmlinkage void fpu_emu(void); e_vector vectors[256] = { [VEC_BUSERR] = buserr, + [VEC_ADDRERR] = trap, + [VEC_ILLEGAL] = trap, + [VEC_ZERODIV] = trap, + [VEC_CHK] = trap, + [VEC_TRAP] = trap, + [VEC_PRIV] = trap, + [VEC_TRACE] = trap, + [VEC_LINE10] = trap, + [VEC_LINE11] = trap, + [VEC_RESV12] = trap, + [VEC_COPROC] = trap, + [VEC_FORMAT] = trap, + [VEC_UNINT] = trap, + [VEC_RESV16] = trap, + [VEC_RESV17] = trap, + [VEC_RESV18] = trap, + [VEC_RESV19] = trap, + [VEC_RESV20] = trap, + [VEC_RESV21] = trap, + [VEC_RESV22] = trap, + [VEC_RESV23] = trap, + [VEC_SPUR] = inthandler, + [VEC_INT1] = inthandler, + [VEC_INT2] = inthandler, + [VEC_INT3] = inthandler, + [VEC_INT4] = inthandler, + [VEC_INT5] = inthandler, + [VEC_INT6] = inthandler, + [VEC_INT7] = inthandler, [VEC_SYS] = system_call, + [VEC_TRAP1] = trap, + [VEC_TRAP2] = trap, + [VEC_TRAP3] = trap, + [VEC_TRAP4] = trap, + [VEC_TRAP5] = trap, + [VEC_TRAP6] = trap, + [VEC_TRAP7] = trap, + [VEC_TRAP8] = trap, + [VEC_TRAP9] = trap, + [VEC_TRAP10] = trap, + [VEC_TRAP11] = trap, + [VEC_TRAP12] = trap, + [VEC_TRAP13] = trap, + [VEC_TRAP14] = trap, + [VEC_TRAP15] = trap, }; /* nmi handler for the Amiga */ @@ -69,7 +114,7 @@ void __init base_trap_init(void) if(MACH_IS_SUN3X) { extern e_vector *sun3x_prom_vbr; - __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); + __asm__ volatile ("movec %%vbr, %0" : "=r" ((void*)sun3x_prom_vbr)); } /* setup the exception vector table */ @@ -87,15 +132,12 @@ void __init trap_init (void) { int i; - for (i = VEC_SPUR; i <= VEC_INT7; i++) - vectors[i] = bad_inthandler; - - for (i = 0; i < VEC_USER; i++) + for (i = 48; i < 64; i++) if (!vectors[i]) vectors[i] = trap; - for (i = VEC_USER; i < 256; i++) - vectors[i] = bad_inthandler; + for (i = 64; i < 256; i++) + vectors[i] = inthandler; #ifdef CONFIG_M68KFPU_EMU if (FPU_IS_EMU) @@ -885,94 +927,71 @@ void show_trace(unsigned long *stack) void show_registers(struct pt_regs *regs) { struct frame *fp = (struct frame *)regs; - mm_segment_t old_fs = get_fs(); - u16 c, *cp; unsigned long addr; int i; - print_modules(); - printk("PC: [<%08lx>]",regs->pc); - print_symbol(" %s", regs->pc); - printk("\nSR: %04x SP: %p a2: %08lx\n", - regs->sr, regs, regs->a2); - printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", - regs->d0, regs->d1, regs->d2, regs->d3); - printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", - regs->d4, regs->d5, regs->a0, regs->a1); - - printk("Process %s (pid: %d, task=%p)\n", - current->comm, current->pid, current); addr = (unsigned long)&fp->un; - printk("Frame format=%X ", regs->format); - switch (regs->format) { + printk("Frame format=%X ", fp->ptregs.format); + switch (fp->ptregs.format) { case 0x2: - printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); - addr += sizeof(fp->un.fmt2); - break; + printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); + addr += sizeof(fp->un.fmt2); + break; case 0x3: - printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); - addr += sizeof(fp->un.fmt3); - break; + printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); + addr += sizeof(fp->un.fmt3); + break; case 0x4: - printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" - : "eff addr=%08lx pc=%08lx\n"), - fp->un.fmt4.effaddr, fp->un.fmt4.pc); - addr += sizeof(fp->un.fmt4); - break; + printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" + : "eff addr=%08lx pc=%08lx\n"), + fp->un.fmt4.effaddr, fp->un.fmt4.pc); + addr += sizeof(fp->un.fmt4); + break; case 0x7: - printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", - fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); - printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", - fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); - printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", - fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); - printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", - fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); - printk("push data: %08lx %08lx %08lx %08lx\n", - fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, - fp->un.fmt7.pd3); - addr += sizeof(fp->un.fmt7); - break; + printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", + fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); + printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", + fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); + printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", + fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); + printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", + fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); + printk("push data: %08lx %08lx %08lx %08lx\n", + fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, + fp->un.fmt7.pd3); + addr += sizeof(fp->un.fmt7); + break; case 0x9: - printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); - addr += sizeof(fp->un.fmt9); - break; + printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); + addr += sizeof(fp->un.fmt9); + break; case 0xa: - printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", - fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, - fp->un.fmta.daddr, fp->un.fmta.dobuf); - addr += sizeof(fp->un.fmta); - break; + printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", + fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, + fp->un.fmta.daddr, fp->un.fmta.dobuf); + addr += sizeof(fp->un.fmta); + break; case 0xb: - printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", - fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, - fp->un.fmtb.daddr, fp->un.fmtb.dobuf); - printk("baddr=%08lx dibuf=%08lx ver=%x\n", - fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); - addr += sizeof(fp->un.fmtb); - break; + printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", + fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, + fp->un.fmtb.daddr, fp->un.fmtb.dobuf); + printk("baddr=%08lx dibuf=%08lx ver=%x\n", + fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); + addr += sizeof(fp->un.fmtb); + break; default: - printk("\n"); + printk("\n"); } show_stack(NULL, (unsigned long *)addr); - printk("Code:"); - set_fs(KERNEL_DS); - cp = (u16 *)regs->pc; - for (i = -8; i < 16; i++) { - if (get_user(c, cp + i) && i >= 0) { - printk(" Bad PC value."); - break; - } - printk(i ? " %04x" : " <%04x>", c); - } - set_fs(old_fs); + printk("Code: "); + for (i = 0; i < 10; i++) + printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]); printk ("\n"); } void show_stack(struct task_struct *task, unsigned long *stack) { - unsigned long *p; unsigned long *endstack; int i; @@ -985,13 +1004,12 @@ void show_stack(struct task_struct *task, unsigned long *stack) endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); printk("Stack from %08lx:", (unsigned long)stack); - p = stack; for (i = 0; i < kstack_depth_to_print; i++) { - if (p + 1 > endstack) + if (stack + 1 > endstack) break; if (i % 8 == 0) printk("\n "); - printk(" %08lx", *p++); + printk(" %08lx", *stack++); } printk("\n"); show_trace(stack); @@ -1170,7 +1188,19 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) console_verbose(); printk("%s: %08x\n",str,nr); - show_registers(fp); + print_modules(); + printk("PC: [<%08lx>]",fp->pc); + print_symbol(" %s\n", fp->pc); + printk("\nSR: %04x SP: %p a2: %08lx\n", + fp->sr, fp, fp->a2); + printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", + fp->d0, fp->d1, fp->d2, fp->d3); + printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", + fp->d4, fp->d5, fp->a0, fp->a1); + + printk("Process %s (pid: %d, stackpage=%08lx)\n", + current->comm, current->pid, PAGE_SIZE+(unsigned long)current); + show_stack(NULL, (unsigned long *)fp); do_exit(SIGSEGV); } diff --git a/trunk/arch/m68k/lib/Makefile b/trunk/arch/m68k/lib/Makefile index 6bbf19f96007..ebe51a513817 100644 --- a/trunk/arch/m68k/lib/Makefile +++ b/trunk/arch/m68k/lib/Makefile @@ -4,5 +4,5 @@ EXTRA_AFLAGS := -traditional -lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - checksum.o string.o semaphore.o uaccess.o +lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ + checksum.o string.o semaphore.o diff --git a/trunk/arch/m68k/lib/uaccess.c b/trunk/arch/m68k/lib/uaccess.c deleted file mode 100644 index 1bc188c0d983..000000000000 --- a/trunk/arch/m68k/lib/uaccess.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#include -#include - -unsigned long __generic_copy_from_user(void *to, const void __user *from, - unsigned long n) -{ - unsigned long tmp, res; - - asm volatile ("\n" - " tst.l %0\n" - " jeq 2f\n" - "1: moves.l (%1)+,%3\n" - " move.l %3,(%2)+\n" - " subq.l #1,%0\n" - " jne 1b\n" - "2: btst #1,%5\n" - " jeq 4f\n" - "3: moves.w (%1)+,%3\n" - " move.w %3,(%2)+\n" - "4: btst #0,%5\n" - " jeq 6f\n" - "5: moves.b (%1)+,%3\n" - " move.b %3,(%2)+\n" - "6:\n" - " .section .fixup,\"ax\"\n" - " .even\n" - "10: move.l %0,%3\n" - "7: clr.l (%2)+\n" - " subq.l #1,%3\n" - " jne 7b\n" - " lsl.l #2,%0\n" - " btst #1,%5\n" - " jeq 8f\n" - "30: clr.w (%2)+\n" - " addq.l #2,%0\n" - "8: btst #0,%5\n" - " jeq 6b\n" - "50: clr.b (%2)+\n" - " addq.l #1,%0\n" - " jra 6b\n" - " .previous\n" - "\n" - " .section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,10b\n" - " .long 3b,30b\n" - " .long 5b,50b\n" - " .previous" - : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp) - : "0" (n / 4), "d" (n & 3)); - - return res; -} -EXPORT_SYMBOL(__generic_copy_from_user); - -unsigned long __generic_copy_to_user(void __user *to, const void *from, - unsigned long n) -{ - unsigned long tmp, res; - - asm volatile ("\n" - " tst.l %0\n" - " jeq 4f\n" - "1: move.l (%1)+,%3\n" - "2: moves.l %3,(%2)+\n" - "3: subq.l #1,%0\n" - " jne 1b\n" - "4: btst #1,%5\n" - " jeq 6f\n" - " move.w (%1)+,%3\n" - "5: moves.w %3,(%2)+\n" - "6: btst #0,%5\n" - " jeq 8f\n" - " move.b (%1)+,%3\n" - "7: moves.b %3,(%2)+\n" - "8:\n" - " .section .fixup,\"ax\"\n" - " .even\n" - "20: lsl.l #2,%0\n" - "50: add.l %5,%0\n" - " jra 7b\n" - " .previous\n" - "\n" - " .section __ex_table,\"a\"\n" - " .align 4\n" - " .long 2b,20b\n" - " .long 3b,20b\n" - " .long 5b,50b\n" - " .long 6b,50b\n" - " .long 7b,50b\n" - " .long 8b,50b\n" - " .previous" - : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp) - : "0" (n / 4), "d" (n & 3)); - - return res; -} -EXPORT_SYMBOL(__generic_copy_to_user); - -/* - * Copy a null terminated string from userspace. - */ -long strncpy_from_user(char *dst, const char __user *src, long count) -{ - long res; - char c; - - if (count <= 0) - return count; - - asm volatile ("\n" - "1: moves.b (%2)+,%4\n" - " move.b %4,(%1)+\n" - " jeq 2f\n" - " subq.l #1,%3\n" - " jne 1b\n" - "2: sub.l %3,%0\n" - "3:\n" - " .section .fixup,\"ax\"\n" - " .even\n" - "10: move.l %5,%0\n" - " jra 3b\n" - " .previous\n" - "\n" - " .section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,10b\n" - " .previous" - : "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c) - : "i" (-EFAULT), "0" (count)); - - return res; -} -EXPORT_SYMBOL(strncpy_from_user); - -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - */ -long strnlen_user(const char __user *src, long n) -{ - char c; - long res; - - asm volatile ("\n" - "1: subq.l #1,%1\n" - " jmi 3f\n" - "2: moves.b (%0)+,%2\n" - " tst.b %2\n" - " jne 1b\n" - " jra 4f\n" - "\n" - "3: addq.l #1,%0\n" - "4: sub.l %4,%0\n" - "5:\n" - " .section .fixup,\"ax\"\n" - " .even\n" - "20: sub.l %0,%0\n" - " jra 5b\n" - " .previous\n" - "\n" - " .section __ex_table,\"a\"\n" - " .align 4\n" - " .long 2b,20b\n" - " .previous\n" - : "=&a" (res), "+d" (n), "=&d" (c) - : "0" (src), "r" (src)); - - return res; -} -EXPORT_SYMBOL(strnlen_user); - -/* - * Zero Userspace - */ - -unsigned long clear_user(void __user *to, unsigned long n) -{ - unsigned long res; - - asm volatile ("\n" - " tst.l %0\n" - " jeq 3f\n" - "1: moves.l %2,(%1)+\n" - "2: subq.l #1,%0\n" - " jne 1b\n" - "3: btst #1,%4\n" - " jeq 5f\n" - "4: moves.w %2,(%1)+\n" - "5: btst #0,%4\n" - " jeq 7f\n" - "6: moves.b %2,(%1)\n" - "7:\n" - " .section .fixup,\"ax\"\n" - " .even\n" - "10: lsl.l #2,%0\n" - "40: add.l %4,%0\n" - " jra 7b\n" - " .previous\n" - "\n" - " .section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,10b\n" - " .long 2b,10b\n" - " .long 4b,40b\n" - " .long 5b,40b\n" - " .long 6b,40b\n" - " .long 7b,40b\n" - " .previous" - : "=d" (res), "+a" (to) - : "r" (0), "0" (n / 4), "d" (n & 3)); - - return res; -} -EXPORT_SYMBOL(clear_user); diff --git a/trunk/arch/m68k/mac/baboon.c b/trunk/arch/m68k/mac/baboon.c index 6eaa881793d1..b19b7dd9bd21 100644 --- a/trunk/arch/m68k/mac/baboon.c +++ b/trunk/arch/m68k/mac/baboon.c @@ -81,7 +81,7 @@ irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { if (events & irq_bit/* & baboon_active*/) { baboon_active &= ~irq_bit; - m68k_handle_int(IRQ_BABOON_0 + i, regs); + mac_do_irq_list(IRQ_BABOON_0 + i, regs); baboon_active |= irq_bit; baboon->mb_ifr &= ~irq_bit; } diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 5a9990e436bb..14f8d3f4e195 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -89,11 +89,38 @@ extern void mac_debugging_long(int, long); static void mac_get_model(char *str); +void mac_bang(int irq, void *vector, struct pt_regs *p) +{ + printk(KERN_INFO "Resetting ...\n"); + mac_reset(); +} + static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) { via_init_clock(vector); } +#if 0 +void mac_waitbut (void) +{ + ; +} +#endif + +extern irqreturn_t mac_default_handler(int, void *, struct pt_regs *); + +irqreturn_t (*mac_handlers[8])(int, void *, struct pt_regs *)= +{ + mac_default_handler, + mac_default_handler, + mac_default_handler, + mac_default_handler, + mac_default_handler, + mac_default_handler, + mac_default_handler, + mac_default_handler +}; + /* * Parse a Macintosh-specific record in the bootinfo */ @@ -169,7 +196,13 @@ void __init config_mac(void) mach_sched_init = mac_sched_init; mach_init_IRQ = mac_init_IRQ; + mach_request_irq = mac_request_irq; + mach_free_irq = mac_free_irq; + enable_irq = mac_enable_irq; + disable_irq = mac_disable_irq; mach_get_model = mac_get_model; + mach_default_handler = &mac_handlers; + mach_get_irq_list = show_mac_interrupts; mach_gettimeoffset = mac_gettimeoffset; #warning move to adb/via init #if 0 diff --git a/trunk/arch/m68k/mac/iop.c b/trunk/arch/m68k/mac/iop.c index 4c8ece7e64a3..9179a3798407 100644 --- a/trunk/arch/m68k/mac/iop.c +++ b/trunk/arch/m68k/mac/iop.c @@ -317,7 +317,7 @@ void __init iop_register_interrupts(void) { if (iop_ism_present) { if (oss_present) { - request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, + cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, IRQ_FLG_LOCK, "ISM IOP", (void *) IOP_NUM_ISM); oss_irq_enable(IRQ_MAC_ADB); diff --git a/trunk/arch/m68k/mac/macints.c b/trunk/arch/m68k/mac/macints.c index 694b14bb0de1..1809601ad903 100644 --- a/trunk/arch/m68k/mac/macints.c +++ b/trunk/arch/m68k/mac/macints.c @@ -137,6 +137,14 @@ #define DEBUG_SPURIOUS #define SHUTUP_SONIC +/* + * The mac_irq_list array is an array of linked lists of irq_node_t nodes. + * Each node contains one handler to be called whenever the interrupt + * occurs, with fast handlers listed before slow handlers. + */ + +irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; + /* SCC interrupt mask */ static int scc_mask; @@ -201,37 +209,34 @@ extern int baboon_irq_pending(int); * SCC interrupt routines */ -static void scc_irq_enable(unsigned int); -static void scc_irq_disable(unsigned int); +static void scc_irq_enable(int); +static void scc_irq_disable(int); /* * console_loglevel determines NMI handler function */ +extern irqreturn_t mac_bang(int, void *, struct pt_regs *); irqreturn_t mac_nmi_handler(int, void *, struct pt_regs *); irqreturn_t mac_debug_handler(int, void *, struct pt_regs *); /* #define DEBUG_MACINTS */ -static void mac_enable_irq(unsigned int irq); -static void mac_disable_irq(unsigned int irq); - -static struct irq_controller mac_irq_controller = { - .name = "mac", - .lock = SPIN_LOCK_UNLOCKED, - .enable = mac_enable_irq, - .disable = mac_disable_irq, -}; - void mac_init_IRQ(void) { + int i; + #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif + /* Initialize the IRQ handler lists. Initially each list is empty, */ + + for (i = 0; i < NUM_MAC_SOURCES; i++) { + mac_irq_list[i] = NULL; + } + scc_mask = 0; - m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, - NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ #ifdef SHUTUP_SONIC printk("Killing onboard sonic... "); @@ -248,22 +253,119 @@ void mac_init_IRQ(void) * at levels 1-7. Most of the work is done elsewhere. */ - if (oss_present) + if (oss_present) { oss_register_interrupts(); - else + } else { via_register_interrupts(); - if (psc_present) - psc_register_interrupts(); - if (baboon_present) - baboon_register_interrupts(); + } + if (psc_present) psc_register_interrupts(); + if (baboon_present) baboon_register_interrupts(); iop_register_interrupts(); - request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI", + cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", mac_nmi_handler); #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Done!\n"); #endif } +/* + * Routines to work with irq_node_t's on linked lists lifted from + * the Amiga code written by Roman Zippel. + */ + +static inline void mac_insert_irq(irq_node_t **list, irq_node_t *node) +{ + unsigned long flags; + irq_node_t *cur; + + if (!node->dev_id) + printk("%s: Warning: dev_id of %s is zero\n", + __FUNCTION__, node->devname); + + local_irq_save(flags); + + cur = *list; + + if (node->flags & IRQ_FLG_FAST) { + node->flags &= ~IRQ_FLG_SLOW; + while (cur && cur->flags & IRQ_FLG_FAST) { + list = &cur->next; + cur = cur->next; + } + } else if (node->flags & IRQ_FLG_SLOW) { + while (cur) { + list = &cur->next; + cur = cur->next; + } + } else { + while (cur && !(cur->flags & IRQ_FLG_SLOW)) { + list = &cur->next; + cur = cur->next; + } + } + + node->next = cur; + *list = node; + + local_irq_restore(flags); +} + +static inline void mac_delete_irq(irq_node_t **list, void *dev_id) +{ + unsigned long flags; + irq_node_t *node; + + local_irq_save(flags); + + for (node = *list; node; list = &node->next, node = *list) { + if (node->dev_id == dev_id) { + *list = node->next; + /* Mark it as free. */ + node->handler = NULL; + local_irq_restore(flags); + return; + } + } + local_irq_restore(flags); + printk ("%s: tried to remove invalid irq\n", __FUNCTION__); +} + +/* + * Call all the handlers for a given interrupt. Fast handlers are called + * first followed by slow handlers. + * + * This code taken from the original Amiga code written by Roman Zippel. + */ + +void mac_do_irq_list(int irq, struct pt_regs *fp) +{ + irq_node_t *node, *slow_nodes; + unsigned long flags; + + kstat_cpu(0).irqs[irq]++; + +#ifdef DEBUG_SPURIOUS + if (!mac_irq_list[irq] && (console_loglevel > 7)) { + printk("mac_do_irq_list: spurious interrupt %d!\n", irq); + return; + } +#endif + + /* serve first fast and normal handlers */ + for (node = mac_irq_list[irq]; + node && (!(node->flags & IRQ_FLG_SLOW)); + node = node->next) + node->handler(irq, node->dev_id, fp); + if (!node) return; + local_save_flags(flags); + local_irq_restore((flags & ~0x0700) | (fp->sr & 0x0700)); + /* if slow handlers exists, serve them now */ + slow_nodes = node; + for (; node; node = node->next) { + node->handler(irq, node->dev_id, fp); + } +} + /* * mac_enable_irq - enable an interrupt source * mac_disable_irq - disable an interrupt source @@ -273,124 +375,276 @@ void mac_init_IRQ(void) * These routines are just dispatchers to the VIA/OSS/PSC routines. */ -static void mac_enable_irq(unsigned int irq) +void mac_enable_irq (unsigned int irq) { - int irq_src = IRQ_SRC(irq); + int irq_src = IRQ_SRC(irq); switch(irq_src) { - case 1: - via_irq_enable(irq); - break; - case 2: - case 7: - if (oss_present) - oss_irq_enable(irq); - else - via_irq_enable(irq); - break; - case 3: - case 4: - case 5: - case 6: - if (psc_present) - psc_irq_enable(irq); - else if (oss_present) - oss_irq_enable(irq); - else if (irq_src == 4) - scc_irq_enable(irq); - break; - case 8: - if (baboon_present) - baboon_irq_enable(irq); - break; + case 1: via_irq_enable(irq); + break; + case 2: + case 7: if (oss_present) { + oss_irq_enable(irq); + } else { + via_irq_enable(irq); + } + break; + case 3: + case 4: + case 5: + case 6: if (psc_present) { + psc_irq_enable(irq); + } else if (oss_present) { + oss_irq_enable(irq); + } else if (irq_src == 4) { + scc_irq_enable(irq); + } + break; + case 8: if (baboon_present) { + baboon_irq_enable(irq); + } + break; } } -static void mac_disable_irq(unsigned int irq) +void mac_disable_irq (unsigned int irq) { - int irq_src = IRQ_SRC(irq); + int irq_src = IRQ_SRC(irq); switch(irq_src) { - case 1: - via_irq_disable(irq); - break; - case 2: - case 7: - if (oss_present) - oss_irq_disable(irq); - else - via_irq_disable(irq); - break; - case 3: - case 4: - case 5: - case 6: - if (psc_present) - psc_irq_disable(irq); - else if (oss_present) - oss_irq_disable(irq); - else if (irq_src == 4) - scc_irq_disable(irq); - break; - case 8: - if (baboon_present) - baboon_irq_disable(irq); - break; + case 1: via_irq_disable(irq); + break; + case 2: + case 7: if (oss_present) { + oss_irq_disable(irq); + } else { + via_irq_disable(irq); + } + break; + case 3: + case 4: + case 5: + case 6: if (psc_present) { + psc_irq_disable(irq); + } else if (oss_present) { + oss_irq_disable(irq); + } else if (irq_src == 4) { + scc_irq_disable(irq); + } + break; + case 8: if (baboon_present) { + baboon_irq_disable(irq); + } + break; } } -void mac_clear_irq(unsigned int irq) +void mac_clear_irq( unsigned int irq ) { switch(IRQ_SRC(irq)) { - case 1: - via_irq_clear(irq); - break; - case 2: - case 7: - if (oss_present) - oss_irq_clear(irq); - else - via_irq_clear(irq); - break; - case 3: - case 4: - case 5: - case 6: - if (psc_present) - psc_irq_clear(irq); - else if (oss_present) - oss_irq_clear(irq); - break; - case 8: - if (baboon_present) - baboon_irq_clear(irq); - break; + case 1: via_irq_clear(irq); + break; + case 2: + case 7: if (oss_present) { + oss_irq_clear(irq); + } else { + via_irq_clear(irq); + } + break; + case 3: + case 4: + case 5: + case 6: if (psc_present) { + psc_irq_clear(irq); + } else if (oss_present) { + oss_irq_clear(irq); + } + break; + case 8: if (baboon_present) { + baboon_irq_clear(irq); + } + break; } } -int mac_irq_pending(unsigned int irq) +int mac_irq_pending( unsigned int irq ) { switch(IRQ_SRC(irq)) { - case 1: - return via_irq_pending(irq); - case 2: - case 7: - if (oss_present) - return oss_irq_pending(irq); - else - return via_irq_pending(irq); - case 3: - case 4: - case 5: - case 6: - if (psc_present) - return psc_irq_pending(irq); - else if (oss_present) - return oss_irq_pending(irq); + case 1: return via_irq_pending(irq); + case 2: + case 7: if (oss_present) { + return oss_irq_pending(irq); + } else { + return via_irq_pending(irq); + } + case 3: + case 4: + case 5: + case 6: if (psc_present) { + return psc_irq_pending(irq); + } else if (oss_present) { + return oss_irq_pending(irq); + } + } + return 0; +} + +/* + * Add an interrupt service routine to an interrupt source. + * Returns 0 on success. + * + * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a + * non-PSC machine). We should return -EINVAL in those cases. + */ + +int mac_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + irq_node_t *node; + +#ifdef DEBUG_MACINTS + printk ("%s: irq %d requested for %s\n", __FUNCTION__, irq, devname); +#endif + + if (irq < VIA1_SOURCE_BASE) { + return cpu_request_irq(irq, handler, flags, devname, dev_id); } + + if (irq >= NUM_MAC_SOURCES) { + printk ("%s: unknown irq %d requested by %s\n", + __FUNCTION__, irq, devname); + } + + /* Get a node and stick it onto the right list */ + + if (!(node = new_irq_node())) return -ENOMEM; + + node->handler = handler; + node->flags = flags; + node->dev_id = dev_id; + node->devname = devname; + node->next = NULL; + mac_insert_irq(&mac_irq_list[irq], node); + + /* Now enable the IRQ source */ + + mac_enable_irq(irq); + return 0; } +/* + * Removes an interrupt service routine from an interrupt source. + */ + +void mac_free_irq(unsigned int irq, void *dev_id) +{ +#ifdef DEBUG_MACINTS + printk ("%s: irq %d freed by %p\n", __FUNCTION__, irq, dev_id); +#endif + + if (irq < VIA1_SOURCE_BASE) { + cpu_free_irq(irq, dev_id); + return; + } + + if (irq >= NUM_MAC_SOURCES) { + printk ("%s: unknown irq %d freed\n", + __FUNCTION__, irq); + return; + } + + mac_delete_irq(&mac_irq_list[irq], dev_id); + + /* If the list for this interrupt is */ + /* empty then disable the source. */ + + if (!mac_irq_list[irq]) { + mac_disable_irq(irq); + } +} + +/* + * Generate a pretty listing for /proc/interrupts + * + * By the time we're called the autovector interrupt list has already been + * generated, so we just need to do the machspec interrupts. + * + * 990506 (jmt) - rewritten to handle chained machspec interrupt handlers. + * Also removed display of num_spurious it is already + * displayed for us as autovector irq 0. + */ + +int show_mac_interrupts(struct seq_file *p, void *v) +{ + int i; + irq_node_t *node; + char *base; + + /* Don't do Nubus interrupts in this loop; we do them separately */ + /* below so that we can print slot numbers instead of IRQ numbers */ + + for (i = VIA1_SOURCE_BASE ; i < NUM_MAC_SOURCES ; ++i) { + + /* Nonexistant interrupt or nothing registered; skip it. */ + + if ((node = mac_irq_list[i]) == NULL) continue; + if (node->flags & IRQ_FLG_STD) continue; + + base = ""; + switch(IRQ_SRC(i)) { + case 1: base = "via1"; + break; + case 2: if (oss_present) { + base = "oss"; + } else { + base = "via2"; + } + break; + case 3: + case 4: + case 5: + case 6: if (psc_present) { + base = "psc"; + } else if (oss_present) { + base = "oss"; + } else { + if (IRQ_SRC(i) == 4) base = "scc"; + } + break; + case 7: base = "nbus"; + break; + case 8: base = "bbn"; + break; + } + seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]); + + do { + if (node->flags & IRQ_FLG_FAST) { + seq_puts(p, "F "); + } else if (node->flags & IRQ_FLG_SLOW) { + seq_puts(p, "S "); + } else { + seq_puts(p, " "); + } + seq_printf(p, "%s\n", node->devname); + if ((node = node->next)) { + seq_puts(p, " "); + } + } while(node); + + } + return 0; +} + +void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) +{ +#ifdef DEBUG_SPURIOUS + printk("Unexpected IRQ %d on device %p\n", irq, dev_id); +#endif +} + static int num_debug[8]; irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) @@ -430,7 +684,7 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) while (nmi_hold == 1) udelay(1000); - if (console_loglevel >= 8) { + if ( console_loglevel >= 8 ) { #if 0 show_state(); printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); @@ -459,16 +713,14 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) * done in hardware (only the PSC can do that.) */ -static void scc_irq_enable(unsigned int irq) -{ - int irq_idx = IRQ_IDX(irq); +static void scc_irq_enable(int irq) { + int irq_idx = IRQ_IDX(irq); scc_mask |= (1 << irq_idx); } -static void scc_irq_disable(unsigned int irq) -{ - int irq_idx = IRQ_IDX(irq); +static void scc_irq_disable(int irq) { + int irq_idx = IRQ_IDX(irq); scc_mask &= ~(1 << irq_idx); } @@ -503,8 +755,6 @@ void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs) /* and since they're autovector interrupts they */ /* pretty much kill the system. */ - if (reg & 0x38) - m68k_handle_int(IRQ_SCCA, regs); - if (reg & 0x07) - m68k_handle_int(IRQ_SCCB, regs); + if (reg & 0x38) mac_do_irq_list(IRQ_SCCA, regs); + if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs); } diff --git a/trunk/arch/m68k/mac/oss.c b/trunk/arch/m68k/mac/oss.c index 63e04365191f..333547692724 100644 --- a/trunk/arch/m68k/mac/oss.c +++ b/trunk/arch/m68k/mac/oss.c @@ -67,15 +67,15 @@ void __init oss_init(void) void __init oss_register_interrupts(void) { - request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, "scsi", (void *) oss); - request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); - request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, "nubus", (void *) oss); - request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, "sound", (void *) oss); - request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, + cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, "via1", (void *) via1); } @@ -113,7 +113,7 @@ irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs) oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; - m68k_handle_int(IRQ_MAC_SCSI, regs); + mac_do_irq_list(IRQ_MAC_SCSI, regs); oss->irq_pending &= ~OSS_IP_SCSI; oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { @@ -146,7 +146,7 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; - m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); + mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); oss->irq_pending &= ~irq_bit; oss->irq_level[i] = OSS_IRQLEV_NUBUS; } diff --git a/trunk/arch/m68k/mac/psc.c b/trunk/arch/m68k/mac/psc.c index e26218091755..e72384e43a1e 100644 --- a/trunk/arch/m68k/mac/psc.c +++ b/trunk/arch/m68k/mac/psc.c @@ -117,10 +117,10 @@ void __init psc_init(void) void __init psc_register_interrupts(void) { - request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30); - request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40); - request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50); - request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60); + cpu_request_irq(3, psc_irq, IRQ_FLG_LOCK, "psc3", (void *) 0x30); + cpu_request_irq(4, psc_irq, IRQ_FLG_LOCK, "psc4", (void *) 0x40); + cpu_request_irq(5, psc_irq, IRQ_FLG_LOCK, "psc5", (void *) 0x50); + cpu_request_irq(6, psc_irq, IRQ_FLG_LOCK, "psc6", (void *) 0x60); } /* @@ -149,7 +149,7 @@ irqreturn_t psc_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { if (events & irq_bit) { psc_write_byte(pIER, irq_bit); - m68k_handle_int(base_irq + i, regs); + mac_do_irq_list(base_irq + i, regs); psc_write_byte(pIFR, irq_bit); psc_write_byte(pIER, irq_bit | 0x80); } diff --git a/trunk/arch/m68k/mac/via.c b/trunk/arch/m68k/mac/via.c index c4aa345d544e..cd528bf7b43f 100644 --- a/trunk/arch/m68k/mac/via.c +++ b/trunk/arch/m68k/mac/via.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -70,6 +71,7 @@ void via_irq_enable(int irq); void via_irq_disable(int irq); void via_irq_clear(int irq); +extern irqreturn_t mac_bang(int, void *, struct pt_regs *); extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *); extern int oss_present; @@ -210,6 +212,11 @@ void __init via_init(void) break; } #else + /* The alernate IRQ mapping seems to just not work. Anyone with a */ + /* supported machine is welcome to take a stab at fixing it. It */ + /* _should_ work on the following Quadras: 610,650,700,800,900,950 */ + /* - 1999-06-12 (jmt) */ + via_alt_mapping = 0; #endif @@ -253,21 +260,27 @@ void __init via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *)) void __init via_register_interrupts(void) { if (via_alt_mapping) { - request_irq(IRQ_AUTO_1, via1_irq, + cpu_request_irq(IRQ_AUTO_1, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", (void *) via1); - request_irq(IRQ_AUTO_6, via1_irq, + cpu_request_irq(IRQ_AUTO_6, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", (void *) via1); } else { - request_irq(IRQ_AUTO_1, via1_irq, + cpu_request_irq(IRQ_AUTO_1, via1_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", (void *) via1); +#if 0 /* interferes with serial on some machines */ + if (!psc_present) { + cpu_request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK, + "Off Switch", mac_bang); + } +#endif } - request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, + cpu_request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, "via2", (void *) via2); if (!psc_present) { - request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, + cpu_request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, "scc", mac_scc_dispatch); } request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, @@ -424,7 +437,7 @@ irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { via1[vIER] = irq_bit; - m68k_handle_int(VIA1_SOURCE_BASE + i, regs); + mac_do_irq_list(VIA1_SOURCE_BASE + i, regs); via1[vIFR] = irq_bit; via1[vIER] = irq_bit | 0x80; } @@ -439,7 +452,7 @@ irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs) /* No, it won't be set. that's why we're doing this. */ via_irq_disable(IRQ_MAC_NUBUS); via_irq_clear(IRQ_MAC_NUBUS); - m68k_handle_int(IRQ_MAC_NUBUS, regs); + mac_do_irq_list(IRQ_MAC_NUBUS, regs); via_irq_enable(IRQ_MAC_NUBUS); } #endif @@ -458,8 +471,8 @@ irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { via2[gIER] = irq_bit; + mac_do_irq_list(VIA2_SOURCE_BASE + i, regs); via2[gIFR] = irq_bit | rbv_clear; - m68k_handle_int(VIA2_SOURCE_BASE + i, regs); via2[gIER] = irq_bit | 0x80; } return IRQ_HANDLED; @@ -481,7 +494,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { if (events & irq_bit) { via_irq_disable(NUBUS_SOURCE_BASE + i); - m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); + mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); via_irq_enable(NUBUS_SOURCE_BASE + i); } } @@ -516,7 +529,6 @@ void via_irq_enable(int irq) { } via2[gIER] = irq_bit | 0x80; } else if (irq_src == 7) { - nubus_active |= irq_bit; if (rbv_present) { /* enable the slot interrupt. SIER works like IER. */ via2[rSIER] = IER_SET_BIT(irq_idx); @@ -538,6 +550,7 @@ void via_irq_enable(int irq) { } } } + nubus_active |= irq_bit; } } diff --git a/trunk/arch/m68k/mm/kmap.c b/trunk/arch/m68k/mm/kmap.c index 43ffab048724..85ad19a0ac79 100644 --- a/trunk/arch/m68k/mm/kmap.c +++ b/trunk/arch/m68k/mm/kmap.c @@ -259,15 +259,13 @@ void __iounmap(void *addr, unsigned long size) if (CPU_IS_020_OR_030) { int pmd_off = (virtaddr/PTRTREESIZE) & 15; - int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; - if (pmd_type == _PAGE_PRESENT) { + if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { pmd_dir->pmd[pmd_off] = 0; virtaddr += PTRTREESIZE; size -= PTRTREESIZE; continue; - } else if (pmd_type == 0) - continue; + } } if (pmd_bad(*pmd_dir)) { diff --git a/trunk/arch/m68k/mm/memory.c b/trunk/arch/m68k/mm/memory.c index a226668f20c3..d6d582a5abb0 100644 --- a/trunk/arch/m68k/mm/memory.c +++ b/trunk/arch/m68k/mm/memory.c @@ -94,7 +94,8 @@ pmd_t *get_pointer_table (void) PD_MARKBITS(dp) = mask & ~tmp; if (!PD_MARKBITS(dp)) { /* move to end of list */ - list_move_tail(dp, &ptable_list); + list_del(dp); + list_add_tail(dp, &ptable_list); } return (pmd_t *) (page_address(PD_PAGE(dp)) + off); } @@ -122,7 +123,8 @@ int free_pointer_table (pmd_t *ptable) * move this descriptor to the front of the list, since * it has one or more free tables. */ - list_move(dp, &ptable_list); + list_del(dp); + list_add(dp, &ptable_list); } return 0; } diff --git a/trunk/arch/m68k/mm/motorola.c b/trunk/arch/m68k/mm/motorola.c index bdb11103694b..afb57eeafdcb 100644 --- a/trunk/arch/m68k/mm/motorola.c +++ b/trunk/arch/m68k/mm/motorola.c @@ -203,7 +203,7 @@ void __init paging_init(void) { int chunk; unsigned long mem_avail = 0; - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long zones_size[3] = { 0, }; #ifdef DEBUG { @@ -257,12 +257,12 @@ void __init paging_init(void) #ifdef DEBUG printk ("before free_area_init\n"); #endif - zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ? - (mach_max_dma_address+1) : (unsigned long)high_memory); - zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0]; + zones_size[0] = (mach_max_dma_address < (unsigned long)high_memory ? + (mach_max_dma_address+1) : (unsigned long)high_memory); + zones_size[1] = (unsigned long)high_memory - zones_size[0]; - zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT; - zones_size[ZONE_NORMAL] >>= PAGE_SHIFT; + zones_size[0] = (zones_size[0] - PAGE_OFFSET) >> PAGE_SHIFT; + zones_size[1] >>= PAGE_SHIFT; free_area_init(zones_size); } diff --git a/trunk/arch/m68k/mm/sun3mmu.c b/trunk/arch/m68k/mm/sun3mmu.c index ac6640ade0b1..a47be196a47c 100644 --- a/trunk/arch/m68k/mm/sun3mmu.c +++ b/trunk/arch/m68k/mm/sun3mmu.c @@ -46,7 +46,7 @@ void __init paging_init(void) unsigned long address; unsigned long next_pgtable; unsigned long bootmem_end; - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long zones_size[3] = {0, 0, 0}; unsigned long size; @@ -92,7 +92,8 @@ void __init paging_init(void) current->mm = NULL; /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ - zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; + zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; + zones_size[1] = 0; free_area_init(zones_size); diff --git a/trunk/arch/m68k/mvme147/147ints.c b/trunk/arch/m68k/mvme147/147ints.c new file mode 100644 index 000000000000..69a744ee35a3 --- /dev/null +++ b/trunk/arch/m68k/mvme147/147ints.c @@ -0,0 +1,145 @@ +/* + * arch/m68k/mvme147/147ints.c + * + * Copyright (C) 1997 Richard Hirst [richard@sleepie.demon.co.uk] + * + * based on amiints.c -- Amiga Linux interrupt handling code + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static irqreturn_t mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp); + +/* + * This should ideally be 4 elements only, for speed. + */ + +static struct { + irqreturn_t (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + unsigned count; +} irq_tab[256]; + +/* + * void mvme147_init_IRQ (void) + * + * Parameters: None + * + * Returns: Nothing + * + * This function is called during kernel startup to initialize + * the mvme147 IRQ handling routines. + */ + +void mvme147_init_IRQ (void) +{ + int i; + + for (i = 0; i < 256; i++) { + irq_tab[i].handler = mvme147_defhand; + irq_tab[i].flags = IRQ_FLG_STD; + irq_tab[i].dev_id = NULL; + irq_tab[i].devname = NULL; + irq_tab[i].count = 0; + } +} + +int mvme147_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + if (irq > 255) { + printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + return -ENXIO; + } + if (!(irq_tab[irq].flags & IRQ_FLG_STD)) { + if (irq_tab[irq].flags & IRQ_FLG_LOCK) { + printk("%s: IRQ %d from %s is not replaceable\n", + __FUNCTION__, irq, irq_tab[irq].devname); + return -EBUSY; + } + if (flags & IRQ_FLG_REPLACE) { + printk("%s: %s can't replace IRQ %d from %s\n", + __FUNCTION__, devname, irq, irq_tab[irq].devname); + return -EBUSY; + } + } + irq_tab[irq].handler = handler; + irq_tab[irq].flags = flags; + irq_tab[irq].dev_id = dev_id; + irq_tab[irq].devname = devname; + return 0; +} + +void mvme147_free_irq(unsigned int irq, void *dev_id) +{ + if (irq > 255) { + printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); + return; + } + if (irq_tab[irq].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_tab[irq].devname); + + irq_tab[irq].handler = mvme147_defhand; + irq_tab[irq].flags = IRQ_FLG_STD; + irq_tab[irq].dev_id = NULL; + irq_tab[irq].devname = NULL; +} + +irqreturn_t mvme147_process_int (unsigned long vec, struct pt_regs *fp) +{ + if (vec > 255) { + printk ("mvme147_process_int: Illegal vector %ld\n", vec); + return IRQ_NONE; + } else { + irq_tab[vec].count++; + irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp); + return IRQ_HANDLED; + } +} + +int show_mvme147_interrupts (struct seq_file *p, void *v) +{ + int i; + + for (i = 0; i < 256; i++) { + if (irq_tab[i].count) + seq_printf(p, "Vec 0x%02x: %8d %s\n", + i, irq_tab[i].count, + irq_tab[i].devname ? irq_tab[i].devname : "free"); + } + return 0; +} + + +static irqreturn_t mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp) +{ + printk ("Unknown interrupt 0x%02x\n", irq); + return IRQ_NONE; +} + +void mvme147_enable_irq (unsigned int irq) +{ +} + + +void mvme147_disable_irq (unsigned int irq) +{ +} + diff --git a/trunk/arch/m68k/mvme147/Makefile b/trunk/arch/m68k/mvme147/Makefile index a36d38dbfbbc..f0153ed3efa5 100644 --- a/trunk/arch/m68k/mvme147/Makefile +++ b/trunk/arch/m68k/mvme147/Makefile @@ -2,4 +2,4 @@ # Makefile for Linux arch/m68k/mvme147 source directory # -obj-y := config.o +obj-y := config.o 147ints.o diff --git a/trunk/arch/m68k/mvme147/config.c b/trunk/arch/m68k/mvme147/config.c index 0cd0e5bddcee..0fcf9720c2fe 100644 --- a/trunk/arch/m68k/mvme147/config.c +++ b/trunk/arch/m68k/mvme147/config.c @@ -36,8 +36,15 @@ #include +extern irqreturn_t mvme147_process_int (int level, struct pt_regs *regs); +extern void mvme147_init_IRQ (void); +extern void mvme147_free_irq (unsigned int, void *); +extern int show_mvme147_interrupts (struct seq_file *, void *); +extern void mvme147_enable_irq (unsigned int); +extern void mvme147_disable_irq (unsigned int); static void mvme147_get_model(char *model); static int mvme147_get_hardware_list(char *buffer); +extern int mvme147_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long mvme147_gettimeoffset (void); extern int mvme147_hwclk (int, struct rtc_time *); @@ -84,15 +91,6 @@ static int mvme147_get_hardware_list(char *buffer) return 0; } -/* - * This function is called during kernel startup to initialize - * the mvme147 IRQ handling routines. - */ - -void mvme147_init_IRQ(void) -{ - m68k_setup_user_interrupt(VEC_USER, 192, NULL); -} void __init config_mvme147(void) { @@ -103,6 +101,12 @@ void __init config_mvme147(void) mach_hwclk = mvme147_hwclk; mach_set_clock_mmss = mvme147_set_clock_mmss; mach_reset = mvme147_reset; + mach_free_irq = mvme147_free_irq; + mach_process_int = mvme147_process_int; + mach_get_irq_list = show_mvme147_interrupts; + mach_request_irq = mvme147_request_irq; + enable_irq = mvme147_enable_irq; + disable_irq = mvme147_disable_irq; mach_get_model = mvme147_get_model; mach_get_hardware_list = mvme147_get_hardware_list; diff --git a/trunk/arch/m68k/mvme16x/16xints.c b/trunk/arch/m68k/mvme16x/16xints.c new file mode 100644 index 000000000000..793ef735b59c --- /dev/null +++ b/trunk/arch/m68k/mvme16x/16xints.c @@ -0,0 +1,149 @@ +/* + * arch/m68k/mvme16x/16xints.c + * + * Copyright (C) 1995 Richard Hirst [richard@sleepie.demon.co.uk] + * + * based on amiints.c -- Amiga Linux interrupt handling code + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp); + +/* + * This should ideally be 4 elements only, for speed. + */ + +static struct { + irqreturn_t (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + unsigned count; +} irq_tab[192]; + +/* + * void mvme16x_init_IRQ (void) + * + * Parameters: None + * + * Returns: Nothing + * + * This function is called during kernel startup to initialize + * the mvme16x IRQ handling routines. Should probably ensure + * that the base vectors for the VMEChip2 and PCCChip2 are valid. + */ + +void mvme16x_init_IRQ (void) +{ + int i; + + for (i = 0; i < 192; i++) { + irq_tab[i].handler = mvme16x_defhand; + irq_tab[i].flags = IRQ_FLG_STD; + irq_tab[i].dev_id = NULL; + irq_tab[i].devname = NULL; + irq_tab[i].count = 0; + } +} + +int mvme16x_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + if (irq < 64 || irq > 255) { + printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + return -ENXIO; + } + + if (!(irq_tab[irq-64].flags & IRQ_FLG_STD)) { + if (irq_tab[irq-64].flags & IRQ_FLG_LOCK) { + printk("%s: IRQ %d from %s is not replaceable\n", + __FUNCTION__, irq, irq_tab[irq-64].devname); + return -EBUSY; + } + if (flags & IRQ_FLG_REPLACE) { + printk("%s: %s can't replace IRQ %d from %s\n", + __FUNCTION__, devname, irq, irq_tab[irq-64].devname); + return -EBUSY; + } + } + irq_tab[irq-64].handler = handler; + irq_tab[irq-64].flags = flags; + irq_tab[irq-64].dev_id = dev_id; + irq_tab[irq-64].devname = devname; + return 0; +} + +void mvme16x_free_irq(unsigned int irq, void *dev_id) +{ + if (irq < 64 || irq > 255) { + printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); + return; + } + + if (irq_tab[irq-64].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_tab[irq-64].devname); + + irq_tab[irq-64].handler = mvme16x_defhand; + irq_tab[irq-64].flags = IRQ_FLG_STD; + irq_tab[irq-64].dev_id = NULL; + irq_tab[irq-64].devname = NULL; +} + +irqreturn_t mvme16x_process_int (unsigned long vec, struct pt_regs *fp) +{ + if (vec < 64 || vec > 255) { + printk ("mvme16x_process_int: Illegal vector %ld", vec); + return IRQ_NONE; + } else { + irq_tab[vec-64].count++; + irq_tab[vec-64].handler(vec, irq_tab[vec-64].dev_id, fp); + return IRQ_HANDLED; + } +} + +int show_mvme16x_interrupts (struct seq_file *p, void *v) +{ + int i; + + for (i = 0; i < 192; i++) { + if (irq_tab[i].count) + seq_printf(p, "Vec 0x%02x: %8d %s\n", + i+64, irq_tab[i].count, + irq_tab[i].devname ? irq_tab[i].devname : "free"); + } + return 0; +} + + +static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp) +{ + printk ("Unknown interrupt 0x%02x\n", irq); + return IRQ_NONE; +} + + +void mvme16x_enable_irq (unsigned int irq) +{ +} + + +void mvme16x_disable_irq (unsigned int irq) +{ +} + + diff --git a/trunk/arch/m68k/mvme16x/Makefile b/trunk/arch/m68k/mvme16x/Makefile index 950e82f21640..5129f56b64a3 100644 --- a/trunk/arch/m68k/mvme16x/Makefile +++ b/trunk/arch/m68k/mvme16x/Makefile @@ -2,4 +2,4 @@ # Makefile for Linux arch/m68k/mvme16x source directory # -obj-y := config.o rtc.o mvme16x_ksyms.o +obj-y := config.o 16xints.o rtc.o mvme16x_ksyms.o diff --git a/trunk/arch/m68k/mvme16x/config.c b/trunk/arch/m68k/mvme16x/config.c index ce2727ed1bc0..26ce81c1337d 100644 --- a/trunk/arch/m68k/mvme16x/config.c +++ b/trunk/arch/m68k/mvme16x/config.c @@ -40,8 +40,15 @@ extern t_bdid mvme_bdid; static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; +extern irqreturn_t mvme16x_process_int (int level, struct pt_regs *regs); +extern void mvme16x_init_IRQ (void); +extern void mvme16x_free_irq (unsigned int, void *); +extern int show_mvme16x_interrupts (struct seq_file *, void *); +extern void mvme16x_enable_irq (unsigned int); +extern void mvme16x_disable_irq (unsigned int); static void mvme16x_get_model(char *model); static int mvme16x_get_hardware_list(char *buffer); +extern int mvme16x_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long mvme16x_gettimeoffset (void); extern int mvme16x_hwclk (int, struct rtc_time *); @@ -113,16 +120,6 @@ static int mvme16x_get_hardware_list(char *buffer) return (len); } -/* - * This function is called during kernel startup to initialize - * the mvme16x IRQ handling routines. Should probably ensure - * that the base vectors for the VMEChip2 and PCCChip2 are valid. - */ - -static void mvme16x_init_IRQ (void) -{ - m68k_setup_user_interrupt(VEC_USER, 192, NULL); -} #define pcc2chip ((volatile u_char *)0xfff42000) #define PccSCCMICR 0x1d @@ -141,6 +138,12 @@ void __init config_mvme16x(void) mach_hwclk = mvme16x_hwclk; mach_set_clock_mmss = mvme16x_set_clock_mmss; mach_reset = mvme16x_reset; + mach_free_irq = mvme16x_free_irq; + mach_process_int = mvme16x_process_int; + mach_get_irq_list = show_mvme16x_interrupts; + mach_request_irq = mvme16x_request_irq; + enable_irq = mvme16x_enable_irq; + disable_irq = mvme16x_disable_irq; mach_get_model = mvme16x_get_model; mach_get_hardware_list = mvme16x_get_hardware_list; diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index efa52d302d67..5e0f9b04d45e 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -37,9 +37,15 @@ #include extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); +extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ extern void q40_init_IRQ (void); +extern void q40_free_irq (unsigned int, void *); +extern int show_q40_interrupts (struct seq_file *, void *); +extern void q40_enable_irq (unsigned int); +extern void q40_disable_irq (unsigned int); static void q40_get_model(char *model); static int q40_get_hardware_list(char *buffer); +extern int q40_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern unsigned long q40_gettimeoffset (void); @@ -169,6 +175,13 @@ void __init config_q40(void) mach_set_clock_mmss = q40_set_clock_mmss; mach_reset = q40_reset; + mach_free_irq = q40_free_irq; + mach_process_int = q40_process_int; + mach_get_irq_list = show_q40_interrupts; + mach_request_irq = q40_request_irq; + enable_irq = q40_enable_irq; + disable_irq = q40_disable_irq; + mach_default_handler = &q40_default_handler; mach_get_model = q40_get_model; mach_get_hardware_list = q40_get_hardware_list; diff --git a/trunk/arch/m68k/q40/q40ints.c b/trunk/arch/m68k/q40/q40ints.c index 472f41c4158b..f8ecc2664fe6 100644 --- a/trunk/arch/m68k/q40/q40ints.c +++ b/trunk/arch/m68k/q40/q40ints.c @@ -14,8 +14,13 @@ #include #include #include +#include +#include +#include #include +#include +#include #include #include #include @@ -34,37 +39,29 @@ * */ -static void q40_irq_handler(unsigned int, struct pt_regs *fp); -static void q40_enable_irq(unsigned int); -static void q40_disable_irq(unsigned int); +extern int ints_inited; -unsigned short q40_ablecount[35]; -unsigned short q40_state[35]; -static int q40_irq_startup(unsigned int irq) -{ - /* test for ISA ints not implemented by HW */ - switch (irq) { - case 1: case 2: case 8: case 9: - case 11: case 12: case 13: - printk("%s: ISA IRQ %d not implemented by HW\n", __FUNCTION__, irq); - return -ENXIO; - } - return 0; -} +irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp); -static void q40_irq_shutdown(unsigned int irq) -{ -} -static struct irq_controller q40_irq_controller = { - .name = "q40", - .lock = SPIN_LOCK_UNLOCKED, - .startup = q40_irq_startup, - .shutdown = q40_irq_shutdown, - .enable = q40_enable_irq, - .disable = q40_disable_irq, -}; +static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp); +static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs); + + +#define DEVNAME_SIZE 24 + +static struct q40_irq_node { + irqreturn_t (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + /* struct q40_irq_node *next;*/ + char devname[DEVNAME_SIZE]; + unsigned count; + unsigned short state; +} irq_tab[Q40_IRQ_MAX+1]; + +short unsigned q40_ablecount[Q40_IRQ_MAX+1]; /* * void q40_init_IRQ (void) @@ -77,29 +74,139 @@ static struct irq_controller q40_irq_controller = { * the q40 IRQ handling routines. */ -static int disabled; +static int disabled=0; -void q40_init_IRQ(void) +void q40_init_IRQ (void) { - m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); + int i; - /* setup handler for ISA ints */ - m68k_setup_auto_interrupt(q40_irq_handler); + disabled=0; + for (i = 0; i <= Q40_IRQ_MAX; i++) { + irq_tab[i].handler = q40_defhand; + irq_tab[i].flags = 0; + irq_tab[i].dev_id = NULL; + /* irq_tab[i].next = NULL;*/ + irq_tab[i].devname[0] = 0; + irq_tab[i].count = 0; + irq_tab[i].state =0; + q40_ablecount[i]=0; /* all enabled */ + } - m68k_irq_startup(IRQ_AUTO_2); - m68k_irq_startup(IRQ_AUTO_4); + /* setup handler for ISA ints */ + cpu_request_irq(IRQ2, q40_irq2_handler, 0, "q40 ISA and master chip", + NULL); /* now enable some ints.. */ - master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ + master_outb(1,EXT_ENABLE_REG); /* ISA IRQ 5-15 */ /* make sure keyboard IRQ is disabled */ - master_outb(0, KEY_IRQ_ENABLE_REG); + master_outb(0,KEY_IRQ_ENABLE_REG); } +int q40_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + /*printk("q40_request_irq %d, %s\n",irq,devname);*/ + + if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) { + printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); + return -ENXIO; + } + + /* test for ISA ints not implemented by HW */ + switch (irq) + { + case 1: case 2: case 8: case 9: + case 12: case 13: + printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname); + return -ENXIO; + case 11: + printk("warning IRQ 10 and 11 not distinguishable\n"); + irq=10; + default: + ; + } + + if (irq Q40_IRQ_MAX || (irq>15 && irq<32)) { + printk("%s: Incorrect IRQ %d, dev_id %x \n", __FUNCTION__, irq, (unsigned)dev_id); + return; + } + + /* test for ISA ints not implemented by HW */ + switch (irq) + { + case 1: case 2: case 8: case 9: + case 12: case 13: + printk("%s: ISA IRQ %d from %x invalid\n", __FUNCTION__, irq, (unsigned)dev_id); + return; + case 11: irq=10; + default: + ; + } + + if (irqpc, fp->d0, fp->orig_d0, fp->d1, fp->d2); + printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG)); + return IRQ_HANDLED; +} /* * this stuff doesn't really belong here.. - */ +*/ int ql_ticks; /* 200Hz ticks since last jiffie */ static int sound_ticks; @@ -108,53 +215,54 @@ static int sound_ticks; void q40_mksound(unsigned int hz, unsigned int ticks) { - /* for now ignore hz, except that hz==0 switches off sound */ - /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ - if (hz == 0) { - if (sound_ticks) - sound_ticks = 1; - - *DAC_LEFT = 128; - *DAC_RIGHT = 128; - - return; - } - /* sound itself is done in q40_timer_int */ - if (sound_ticks == 0) - sound_ticks = 1000; /* pretty long beep */ - sound_ticks = ticks << 1; + /* for now ignore hz, except that hz==0 switches off sound */ + /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ + if (hz==0) + { + if (sound_ticks) + sound_ticks=1; + + *DAC_LEFT=128; + *DAC_RIGHT=128; + + return; + } + /* sound itself is done in q40_timer_int */ + if (sound_ticks == 0) sound_ticks=1000; /* pretty long beep */ + sound_ticks=ticks<<1; } static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *); static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs) { - ql_ticks = ql_ticks ? 0 : 1; - if (sound_ticks) { - unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL; - sound_ticks--; - *DAC_LEFT=sval; - *DAC_RIGHT=sval; - } - - if (!ql_ticks) - q40_timer_routine(irq, dev, regs); - return IRQ_HANDLED; + ql_ticks = ql_ticks ? 0 : 1; + if (sound_ticks) + { + unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL; + sound_ticks--; + *DAC_LEFT=sval; + *DAC_RIGHT=sval; + } + + if (!ql_ticks) + q40_timer_routine(irq, dev, regs); + return IRQ_HANDLED; } void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) { - int timer_irq; + int timer_irq; - q40_timer_routine = timer_routine; - timer_irq = Q40_IRQ_FRAME; + q40_timer_routine = timer_routine; + timer_irq=Q40_IRQ_FRAME; - if (request_irq(timer_irq, q40_timer_int, 0, + if (request_irq(timer_irq, q40_timer_int, 0, "timer", q40_timer_int)) - panic("Couldn't register timer int"); + panic ("Couldn't register timer int"); - master_outb(-1, FRAME_CLEAR_REG); - master_outb( 1, FRAME_RATE_REG); + master_outb(-1,FRAME_CLEAR_REG); + master_outb( 1,FRAME_RATE_REG); } @@ -200,132 +308,169 @@ static int mext_disabled=0; /* ext irq disabled by master chip? */ static int aliased_irq=0; /* how many times inside handler ?*/ -/* got interrupt, dispatch to ISA or keyboard/timer IRQs */ -static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) +/* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */ +irqreturn_t q40_irq2_handler (int vec, void *devname, struct pt_regs *fp) { - unsigned mir, mer; - int i; + unsigned mir, mer; + int irq,i; //repeat: - mir = master_inb(IIRQ_REG); -#ifdef CONFIG_BLK_DEV_FD - if ((mir & Q40_IRQ_EXT_MASK) && - (master_inb(EIRQ_REG) & Q40_IRQ6_MASK)) { - floppy_hardint(); - return; - } -#endif - switch (irq) { - case 4: - case 6: - m68k_handle_int(Q40_IRQ_SAMPLE, fp); - return; - } - if (mir & Q40_IRQ_FRAME_MASK) { - m68k_handle_int(Q40_IRQ_FRAME, fp); - master_outb(-1, FRAME_CLEAR_REG); - } - if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { - mer = master_inb(EIRQ_REG); - for (i = 0; eirqs[i].mask; i++) { - if (mer & eirqs[i].mask) { - irq = eirqs[i].irq; + mir=master_inb(IIRQ_REG); + if (mir&Q40_IRQ_FRAME_MASK) { + irq_tab[Q40_IRQ_FRAME].count++; + irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp); + master_outb(-1,FRAME_CLEAR_REG); + } + if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) { + mer=master_inb(EIRQ_REG); + for (i=0; eirqs[i].mask; i++) { + if (mer&(eirqs[i].mask)) { + irq=eirqs[i].irq; /* * There is a little mess wrt which IRQ really caused this irq request. The * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they * are read - which is long after the request came in. In theory IRQs should * not just go away but they occassionally do */ - if (irq > 4 && irq <= 15 && mext_disabled) { - /*aliased_irq++;*/ - goto iirq; - } - if (q40_state[irq] & IRQ_INPROGRESS) { - /* some handlers do local_irq_enable() for irq latency reasons, */ - /* however reentering an active irq handler is not permitted */ + if (irq>4 && irq<=15 && mext_disabled) { + /*aliased_irq++;*/ + goto iirq; + } + if (irq_tab[irq].handler == q40_defhand ) { + printk("handler for IRQ %d not defined\n",irq); + continue; /* ignore uninited INTs :-( */ + } + if ( irq_tab[irq].state & IRQ_INPROGRESS ) { + /* some handlers do local_irq_enable() for irq latency reasons, */ + /* however reentering an active irq handler is not permitted */ #ifdef IP_USE_DISABLE - /* in theory this is the better way to do it because it still */ - /* lets through eg the serial irqs, unfortunately it crashes */ - disable_irq(irq); - disabled = 1; + /* in theory this is the better way to do it because it still */ + /* lets through eg the serial irqs, unfortunately it crashes */ + disable_irq(irq); + disabled=1; #else - /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n", - irq, disabled ? "already" : "not yet"); */ - fp->sr = (((fp->sr) & (~0x700))+0x200); - disabled = 1; + /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */ + fp->sr = (((fp->sr) & (~0x700))+0x200); + disabled=1; #endif - goto iirq; - } - q40_state[irq] |= IRQ_INPROGRESS; - m68k_handle_int(irq, fp); - q40_state[irq] &= ~IRQ_INPROGRESS; - - /* naively enable everything, if that fails than */ - /* this function will be reentered immediately thus */ - /* getting another chance to disable the IRQ */ - - if (disabled) { + goto iirq; + } + irq_tab[irq].count++; + irq_tab[irq].state |= IRQ_INPROGRESS; + irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp); + irq_tab[irq].state &= ~IRQ_INPROGRESS; + + /* naively enable everything, if that fails than */ + /* this function will be reentered immediately thus */ + /* getting another chance to disable the IRQ */ + + if ( disabled ) { #ifdef IP_USE_DISABLE - if (irq > 4) { - disabled = 0; - enable_irq(irq); - } + if (irq>4){ + disabled=0; + enable_irq(irq);} #else - disabled = 0; - /*printk("reenabling irq %d\n", irq); */ + disabled=0; + /*printk("reenabling irq %d\n",irq); */ #endif - } + } // used to do 'goto repeat;' here, this delayed bh processing too long - return; - } - } - if (mer && ccleirq > 0 && !aliased_irq) { - printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer); - ccleirq--; - } - } + return IRQ_HANDLED; + } + } + if (mer && ccleirq>0 && !aliased_irq) + printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--; + } iirq: - mir = master_inb(IIRQ_REG); - /* should test whether keyboard irq is really enabled, doing it in defhand */ - if (mir & Q40_IRQ_KEYB_MASK) - m68k_handle_int(Q40_IRQ_KEYBOARD, fp); - - return; + mir=master_inb(IIRQ_REG); + /* should test whether keyboard irq is really enabled, doing it in defhand */ + if (mir&Q40_IRQ_KEYB_MASK) { + irq_tab[Q40_IRQ_KEYBOARD].count++; + irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp); + } + return IRQ_HANDLED; } -void q40_enable_irq(unsigned int irq) +int show_q40_interrupts (struct seq_file *p, void *v) { - if (irq >= 5 && irq <= 15) { - mext_disabled--; - if (mext_disabled > 0) - printk("q40_enable_irq : nested disable/enable\n"); - if (mext_disabled == 0) - master_outb(1, EXT_ENABLE_REG); + int i; + + for (i = 0; i <= Q40_IRQ_MAX; i++) { + if (irq_tab[i].count) + seq_printf(p, "%sIRQ %02d: %8d %s%s\n", + (i<=15) ? "ISA-" : " " , + i, irq_tab[i].count, + irq_tab[i].devname[0] ? irq_tab[i].devname : "?", + irq_tab[i].handler == q40_defhand ? + " (now unassigned)" : ""); } + return 0; } -void q40_disable_irq(unsigned int irq) +static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp) { - /* disable ISA iqs : only do something if the driver has been - * verified to be Q40 "compatible" - right now IDE, NE2K - * Any driver should not attempt to sleep across disable_irq !! - */ - - if (irq >= 5 && irq <= 15) { - master_outb(0, EXT_ENABLE_REG); - mext_disabled++; - if (mext_disabled > 1) - printk("disable_irq nesting count %d\n",mext_disabled); - } + if (irq!=Q40_IRQ_KEYBOARD) + printk ("Unknown q40 interrupt %d\n", irq); + else master_outb(-1,KEYBOARD_UNLOCK_REG); + return IRQ_NONE; +} +static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs) +{ + printk ("Uninitialised interrupt level %d\n", lev); + return IRQ_NONE; +} + +irqreturn_t (*q40_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { + [0] = default_handler, + [1] = default_handler, + [2] = default_handler, + [3] = default_handler, + [4] = default_handler, + [5] = default_handler, + [6] = default_handler, + [7] = default_handler +}; + + +void q40_enable_irq (unsigned int irq) +{ + if ( irq>=5 && irq<=15 ) + { + mext_disabled--; + if (mext_disabled>0) + printk("q40_enable_irq : nested disable/enable\n"); + if (mext_disabled==0) + master_outb(1,EXT_ENABLE_REG); + } } -unsigned long q40_probe_irq_on(void) + +void q40_disable_irq (unsigned int irq) { - printk("irq probing not working - reconfigure the driver to avoid this\n"); - return -1; + /* disable ISA iqs : only do something if the driver has been + * verified to be Q40 "compatible" - right now IDE, NE2K + * Any driver should not attempt to sleep across disable_irq !! + */ + + if ( irq>=5 && irq<=15 ) { + master_outb(0,EXT_ENABLE_REG); + mext_disabled++; + if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled); + } } -int q40_probe_irq_off(unsigned long irqs) + +unsigned long q40_probe_irq_on (void) { - return -1; + printk("irq probing not working - reconfigure the driver to avoid this\n"); + return -1; } +int q40_probe_irq_off (unsigned long irqs) +{ + return -1; +} +/* + * Local variables: + * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040 -c -o q40ints.o q40ints.c" + * End: + */ diff --git a/trunk/arch/m68k/sun3/config.c b/trunk/arch/m68k/sun3/config.c index 553c304aa2c5..f1ca0dfbaa67 100644 --- a/trunk/arch/m68k/sun3/config.c +++ b/trunk/arch/m68k/sun3/config.c @@ -36,6 +36,7 @@ extern char _text, _end; char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; extern unsigned long sun3_gettimeoffset(void); +extern int show_sun3_interrupts (struct seq_file *, void *); extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); extern void sun3_get_model (char* model); extern void idprom_init (void); @@ -146,6 +147,13 @@ void __init config_sun3(void) mach_sched_init = sun3_sched_init; mach_init_IRQ = sun3_init_IRQ; + mach_default_handler = &sun3_default_handler; + mach_request_irq = sun3_request_irq; + mach_free_irq = sun3_free_irq; + enable_irq = sun3_enable_irq; + disable_irq = sun3_disable_irq; + mach_process_int = sun3_process_int; + mach_get_irq_list = show_sun3_interrupts; mach_reset = sun3_reboot; mach_gettimeoffset = sun3_gettimeoffset; mach_get_model = sun3_get_model; diff --git a/trunk/arch/m68k/sun3/sun3dvma.c b/trunk/arch/m68k/sun3/sun3dvma.c index 97c7bfde8ae8..f04a1d25f1a2 100644 --- a/trunk/arch/m68k/sun3/sun3dvma.c +++ b/trunk/arch/m68k/sun3/sun3dvma.c @@ -119,7 +119,8 @@ static inline int refill(void) if(hole->end == prev->start) { hole->size += prev->size; hole->end = prev->end; - list_move(&(prev->list), &hole_cache); + list_del(&(prev->list)); + list_add(&(prev->list), &hole_cache); ret++; } @@ -181,7 +182,8 @@ static inline unsigned long get_baddr(int len, unsigned long align) #endif return hole->end; } else if(hole->size == newlen) { - list_move(&(hole->list), &hole_cache); + list_del(&(hole->list)); + list_add(&(hole->list), &hole_cache); dvma_entry_use(hole->start) = newlen; #ifdef DVMA_DEBUG dvma_allocs++; diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index 0912435e9e90..e62a033cd493 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -19,6 +19,7 @@ #include extern void sun3_leds (unsigned char); +static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp); void sun3_disable_interrupts(void) { @@ -39,30 +40,48 @@ int led_pattern[8] = { volatile unsigned char* sun3_intreg; +void sun3_insert_irq(irq_node_t **list, irq_node_t *node) +{ +} + +void sun3_delete_irq(irq_node_t **list, void *dev_id) +{ +} + void sun3_enable_irq(unsigned int irq) { - *sun3_intreg |= (1 << irq); + *sun3_intreg |= (1<= 64) && (irq <= 255)) { + int vec; + + vec = irq - 64; + if(sun3_vechandler[vec] != NULL) { + printk("sun3_request_irq: request for vec %d -- already taken!\n", irq); + return 1; + } + + sun3_vechandler[vec] = handler; + vec_ids[vec] = dev_id; + vec_names[vec] = devname; + vec_ints[vec] = 0; + + return 0; + } + } + + printk("sun3_request_irq: invalid irq %d\n", irq); + return 1; + +} + +void sun3_free_irq(unsigned int irq, void *dev_id) { - *sun3_intreg = 1; - m68k_setup_auto_interrupt(sun3_inthandle); - m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); - m68k_setup_user_interrupt(VEC_USER, 192, NULL); + if(irq < SYS_IRQS) { + if(sun3_inthandler[irq] == NULL) + panic("sun3_free_int: attempt to free unused irq %d\n", irq); + if(dev_ids[irq] != dev_id) + panic("sun3_free_int: incorrect dev_id for irq %d\n", irq); + + sun3_inthandler[irq] = NULL; + return; + } else if((irq >= 64) && (irq <= 255)) { + int vec; + + vec = irq - 64; + if(sun3_vechandler[vec] == NULL) + panic("sun3_free_int: attempt to free unused vector %d\n", irq); + if(vec_ids[irq] != dev_id) + panic("sun3_free_int: incorrect dev_id for vec %d\n", irq); + + sun3_vechandler[vec] = NULL; + return; + } else { + panic("sun3_free_irq: invalid irq %d\n", irq); + } +} + +irqreturn_t sun3_process_int(int irq, struct pt_regs *regs) +{ + + if((irq >= 64) && (irq <= 255)) { + int vec; + + vec = irq - 64; + if(sun3_vechandler[vec] == NULL) + panic ("bad interrupt vector %d received\n",irq); - request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL); - request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL); - request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL); + vec_ints[vec]++; + return sun3_vechandler[vec](irq, vec_ids[vec], regs); + } else { + panic("sun3_process_int: unable to handle interrupt vector %d\n", + irq); + } } diff --git a/trunk/arch/m68k/sun3x/config.c b/trunk/arch/m68k/sun3x/config.c index 52fb17408869..0920f5d33606 100644 --- a/trunk/arch/m68k/sun3x/config.c +++ b/trunk/arch/m68k/sun3x/config.c @@ -52,10 +52,17 @@ void __init config_sun3x(void) sun3x_prom_init(); + mach_get_irq_list = show_sun3_interrupts; mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */ + mach_default_handler = &sun3_default_handler; mach_sched_init = sun3x_sched_init; mach_init_IRQ = sun3_init_IRQ; + enable_irq = sun3_enable_irq; + disable_irq = sun3_disable_irq; + mach_request_irq = sun3_request_irq; + mach_free_irq = sun3_free_irq; + mach_process_int = sun3_process_int; mach_gettimeoffset = sun3x_gettimeoffset; mach_reset = sun3x_reboot; diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index 8b6e723eb82b..3cde6822ead1 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -5,7 +5,7 @@ mainmenu "uClinux/68k (w/o MMU) Kernel Configuration" -config M68K +config M68KNOMMU bool default y @@ -119,11 +119,6 @@ config M5307 help Motorola ColdFire 5307 processor support. -config M532x - bool "MCF532x" - help - Freescale (Motorola) ColdFire 532x processor support. - config M5407 bool "MCF5407" help @@ -138,43 +133,125 @@ config M527x config COLDFIRE bool - depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407) + depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407) default y -config CLOCK_SET - bool "Enable setting the CPU clock frequency" - default n +choice + prompt "CPU CLOCK Frequency" + default AUTO + +config CLOCK_AUTO + bool "AUTO" + ---help--- + Define the CPU clock frequency in use. On many boards you don't + really need to know, so you can select the AUTO option. On some + boards you need to know the real clock frequency to determine other + system timing (for example baud rate dividors, etc). Some processors + have an internal PLL and you can select a frequency to run at. + You need to know a little about the internals of your processor to + set this. If in doubt choose the AUTO option. + +config CLOCK_11MHz + bool "11MHz" + help + Select a 11MHz CPU clock frequency. + +config CLOCK_16MHz + bool "16MHz" + help + Select a 16MHz CPU clock frequency. + +config CLOCK_20MHz + bool "20MHz" + help + Select a 20MHz CPU clock frequency. + +config CLOCK_24MHz + bool "24MHz" + help + Select a 24MHz CPU clock frequency. + +config CLOCK_25MHz + bool "25MHz" + help + Select a 25MHz CPU clock frequency. + +config CLOCK_33MHz + bool "33MHz" + help + Select a 33MHz CPU clock frequency. + +config CLOCK_40MHz + bool "40MHz" + help + Select a 40MHz CPU clock frequency. + +config CLOCK_45MHz + bool "45MHz" + help + Select a 45MHz CPU clock frequency. + +config CLOCK_48MHz + bool "48MHz" + help + Select a 48MHz CPU clock frequency. + +config CLOCK_50MHz + bool "50MHz" + help + Select a 50MHz CPU clock frequency. + +config CLOCK_54MHz + bool "54MHz" + help + Select a 54MHz CPU clock frequency. + +config CLOCK_60MHz + bool "60MHz" + help + Select a 60MHz CPU clock frequency. + +config CLOCK_62_5MHz + bool "62.5MHz" + help + Select a 62.5MHz CPU clock frequency. + +config CLOCK_64MHz + bool "64MHz" + help + Select a 64MHz CPU clock frequency. + +config CLOCK_66MHz + bool "66MHz" + help + Select a 66MHz CPU clock frequency. + +config CLOCK_70MHz + bool "70MHz" + help + Select a 70MHz CPU clock frequency. + +config CLOCK_100MHz + bool "100MHz" + help + Select a 100MHz CPU clock frequency. + +config CLOCK_140MHz + bool "140MHz" help - On some CPU's you do not need to know what the core CPU clock - frequency is. On these you can disable clock setting. On some - traditional 68K parts, and on all ColdFire parts you need to set - the appropriate CPU clock frequency. On these devices many of the - onboard peripherals derive their timing from the master CPU clock - frequency. - -config CLOCK_FREQ - int "Set the core clock frequency" - default "66666666" - depends on CLOCK_SET - help - Define the CPU clock frequency in use. This is the core clock - frequency, it may or may not be the same as the external clock - crystal fitted to your board. Some processors have an internal - PLL and can have their frequency programmed at run time, others - use internal dividers. In gernal the kernel won't setup a PLL - if it is fitted (there are some expections). This value will be - specific to the exact CPU that you are using. - -config CLOCK_DIV - int "Set the core/bus clock divide ratio" - default "1" - depends on CLOCK_SET - help - On many SoC style CPUs the master CPU clock is also used to drive - on-chip peripherals. The clock that is distributed to these - peripherals is sometimes a fixed ratio of the master clock - frequency. If so then set this to the divider ration of the - master clock to the peripheral clock. If not sure then select 1. + Select a 140MHz CPU clock frequency. + +config CLOCK_150MHz + bool "150MHz" + help + Select a 150MHz CPU clock frequency. + +config CLOCK_166MHz + bool "166MHz" + help + Select a 166MHz CPU clock frequency. + +endchoice config OLDMASK bool "Old mask 5307 (1H55J) silicon" @@ -300,12 +377,6 @@ config COBRA5272 help Support for the senTec COBRA5272 board. -config AVNET5282 - bool "Avnet 5282 board support" - depends on M528x - help - Support for the Avnet 5282 board. - config M5282EVB bool "Motorola M5282EVB board support" depends on M528x @@ -348,18 +419,6 @@ config SECUREEDGEMP3 help Support for the SnapGear SecureEdge/MP3 platform. -config M5329EVB - bool "Freescale (Motorola) M5329EVB board support" - depends on M532x - help - Support for the Freescale (Motorola) M5329EVB board. - -config COBRA5329 - bool "senTec COBRA5329 board support" - depends on M532x - help - Support for the senTec COBRA5329 board. - config M5407C3 bool "Motorola M5407C3 board support" depends on M5407 @@ -428,7 +487,7 @@ config ARNEWSH config FREESCALE bool default y - depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5329EVB || M5407C3) + depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3) config HW_FEITH bool @@ -449,11 +508,6 @@ config SNEHA bool default y depends on CPU16B - -config AVNET - bool - default y - depends on (AVNET5282) config LARGE_ALLOCS bool "Allow allocating large blocks (> 1MB) of memory" @@ -472,46 +526,38 @@ config 4KSTACKS running more threads on a system and also reduces the pressure on the VM subsystem for higher order allocations. -comment "RAM configuration" +choice + prompt "RAM size" + default AUTO + +config RAMAUTO + bool "AUTO" + ---help--- + Configure the RAM size on your platform. Many platforms can auto + detect this, on those choose the AUTO option. Otherwise set the + RAM size you intend using. -config RAMBASE - hex "Address of the base of RAM" - default "0" +config RAM4MB + bool "4MiB" help - Define the address that RAM starts at. On many platforms this is - 0, the base of the address space. And this is the default. Some - platforms choose to setup their RAM at other addresses within the - processor address space. + Set RAM size to be 4MiB. -config RAMSIZE - hex "Size of RAM (in bytes)" - default "0x400000" +config RAM8MB + bool "8MiB" help - Define the size of the system RAM. If you select 0 then the - kernel will try to probe the RAM size at runtime. This is not - supported on all CPU types. + Set RAM size to be 8MiB. -config VECTORBASE - hex "Address of the base of system vectors" - default "0" +config RAM16MB + bool "16MiB" help - Define the address of the the system vectors. Commonly this is - put at the start of RAM, but it doesn't have to be. On ColdFire - platforms this address is programmed into the VBR register, thus - actually setting the address to use. + Set RAM size to be 16MiB. -config KERNELBASE - hex "Address of the base of kernel code" - default "0x400" +config RAM32MB + bool "32MiB" help - Typically on m68k systems the kernel will not start at the base - of RAM, but usually some small offset from it. Define the start - address of the kernel here. The most common setup will have the - processor vectors at the base of RAM and then the start of the - kernel. On some platforms some RAM is reserved for boot loaders - and the kernel starts after that. The 0x400 default was based on - a system with the RAM based at address 0, and leaving enough room - for the theoretical maximum number of 256 vectors. + Set RAM size to be 32MiB. + +endchoice choice prompt "RAM bus width" @@ -519,7 +565,7 @@ choice config RAMAUTOBIT bool "AUTO" - help + ---help--- Select the physical RAM data bus size. Not needed on most platforms, so you can generally choose AUTO. @@ -553,9 +599,7 @@ config RAMKERNEL config ROMKERNEL bool "ROM" help - The kernel will be resident in FLASH/ROM when running. This is - often referred to as Execute-in-Place (XIP), since the kernel - code executes from the position it is stored in the FLASH/ROM. + The kernel will be resident in FLASH/ROM when running. endchoice diff --git a/trunk/arch/m68knommu/Makefile b/trunk/arch/m68knommu/Makefile index 8951793fd8d4..6f880cbff1c8 100644 --- a/trunk/arch/m68knommu/Makefile +++ b/trunk/arch/m68knommu/Makefile @@ -21,7 +21,6 @@ platform-$(CONFIG_M527x) := 527x platform-$(CONFIG_M5272) := 5272 platform-$(CONFIG_M528x) := 528x platform-$(CONFIG_M5307) := 5307 -platform-$(CONFIG_M532x) := 532x platform-$(CONFIG_M5407) := 5407 PLATFORM := $(platform-y) @@ -45,7 +44,6 @@ board-$(CONFIG_senTec) := senTec board-$(CONFIG_SNEHA) := SNEHA board-$(CONFIG_M5208EVB) := M5208EVB board-$(CONFIG_MOD5272) := MOD5272 -board-$(CONFIG_AVNET) := AVNET BOARD := $(board-y) model-$(CONFIG_RAMKERNEL) := ram @@ -67,7 +65,6 @@ cpuclass-$(CONFIG_M527x) := 5307 cpuclass-$(CONFIG_M5272) := 5307 cpuclass-$(CONFIG_M528x) := 5307 cpuclass-$(CONFIG_M5307) := 5307 -cpuclass-$(CONFIG_M532x) := 5307 cpuclass-$(CONFIG_M5407) := 5307 cpuclass-$(CONFIG_M68328) := 68328 cpuclass-$(CONFIG_M68EZ328) := 68328 @@ -84,17 +81,16 @@ export PLATFORM BOARD MODEL CPUCLASS # # Some CFLAG additions based on specific CPU type. # -cflags-$(CONFIG_M5206) := -m5200 -cflags-$(CONFIG_M5206e) := -m5200 -cflags-$(CONFIG_M520x) := -m5307 -cflags-$(CONFIG_M523x) := -m5307 -cflags-$(CONFIG_M5249) := -m5200 -cflags-$(CONFIG_M527x) := -m5307 -cflags-$(CONFIG_M5272) := -m5307 -cflags-$(CONFIG_M528x) := -m5307 -cflags-$(CONFIG_M5307) := -m5307 -cflags-$(CONFIG_M532x) := -m5307 -cflags-$(CONFIG_M5407) := -m5200 +cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M520x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5272) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M528x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5307) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5407) := -m5200 -Wa,-S -Wa,-m5200 cflags-$(CONFIG_M68328) := -m68000 cflags-$(CONFIG_M68EZ328) := -m68000 cflags-$(CONFIG_M68VZ328) := -m68000 diff --git a/trunk/arch/m68knommu/defconfig b/trunk/arch/m68knommu/defconfig index 3891de09ac23..2d59ba1a79ba 100644 --- a/trunk/arch/m68knommu/defconfig +++ b/trunk/arch/m68knommu/defconfig @@ -1,22 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Tue Jun 27 12:57:06 2006 +# Linux kernel version: 2.6.13-uc0 +# Wed Aug 31 15:03:26 2005 # -CONFIG_M68K=y +CONFIG_M68KNOMMU=y # CONFIG_MMU is not set # CONFIG_FPU is not set +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_TIME_LOW_RES=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -24,54 +23,32 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_SYSCTL is not set # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +# CONFIG_KOBJECT_UEVENT is not set # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set -CONFIG_SLAB=y -CONFIG_TINY_SHMEM=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support # # CONFIG_MODULES is not set -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - # # Processor type and features # @@ -81,7 +58,6 @@ CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_M68360 is not set # CONFIG_M5206 is not set # CONFIG_M5206e is not set -# CONFIG_M520x is not set # CONFIG_M523x is not set # CONFIG_M5249 is not set # CONFIG_M5271 is not set @@ -89,12 +65,29 @@ CONFIG_M5272=y # CONFIG_M5275 is not set # CONFIG_M528x is not set # CONFIG_M5307 is not set -# CONFIG_M532x is not set # CONFIG_M5407 is not set CONFIG_COLDFIRE=y -CONFIG_CLOCK_SET=y -CONFIG_CLOCK_FREQ=66666666 -CONFIG_CLOCK_DIV=1 +# CONFIG_CLOCK_AUTO is not set +# CONFIG_CLOCK_11MHz is not set +# CONFIG_CLOCK_16MHz is not set +# CONFIG_CLOCK_20MHz is not set +# CONFIG_CLOCK_24MHz is not set +# CONFIG_CLOCK_25MHz is not set +# CONFIG_CLOCK_33MHz is not set +# CONFIG_CLOCK_40MHz is not set +# CONFIG_CLOCK_45MHz is not set +# CONFIG_CLOCK_48MHz is not set +# CONFIG_CLOCK_50MHz is not set +# CONFIG_CLOCK_54MHz is not set +# CONFIG_CLOCK_60MHz is not set +# CONFIG_CLOCK_62_5MHz is not set +# CONFIG_CLOCK_64MHz is not set +CONFIG_CLOCK_66MHz=y +# CONFIG_CLOCK_70MHz is not set +# CONFIG_CLOCK_100MHz is not set +# CONFIG_CLOCK_140MHz is not set +# CONFIG_CLOCK_150MHz is not set +# CONFIG_CLOCK_166MHz is not set # # Platform @@ -109,14 +102,11 @@ CONFIG_M5272C3=y CONFIG_FREESCALE=y # CONFIG_LARGE_ALLOCS is not set CONFIG_4KSTACKS=y - -# -# RAM configuration -# -CONFIG_RAMBASE=0x0 -CONFIG_RAMSIZE=0x800000 -CONFIG_VECTORBASE=0x0 -CONFIG_KERNELBASE=0x20000 +CONFIG_RAMAUTO=y +# CONFIG_RAM4MB is not set +# CONFIG_RAM8MB is not set +# CONFIG_RAM16MB is not set +# CONFIG_RAM32MB is not set CONFIG_RAMAUTOBIT=y # CONFIG_RAM8BIT is not set # CONFIG_RAM16BIT is not set @@ -129,8 +119,6 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -152,7 +140,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_BINFMT_FLAT=y # CONFIG_BINFMT_ZFLAT is not set # CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set # @@ -168,7 +155,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -185,30 +171,18 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_INET_DIAG is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - # # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -221,11 +195,8 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -234,7 +205,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set # # Device Drivers @@ -247,11 +217,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - # # Memory Technology Devices (MTD) # @@ -270,7 +235,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -290,13 +254,13 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_SNAPGEARuC is not set # CONFIG_MTD_PLATRAM is not set # @@ -305,6 +269,7 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -319,11 +284,6 @@ CONFIG_MTD_UCLINUX=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -336,6 +296,7 @@ CONFIG_MTD_UCLINUX=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -343,7 +304,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set # CONFIG_ATA_OVER_ETH is not set # @@ -354,7 +324,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # SCSI device support # -# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -384,16 +353,14 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# -# PHY device support -# -# CONFIG_PHYLIB is not set - # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NE2000 is not set +# CONFIG_NET_PCI is not set CONFIG_FEC=y # CONFIG_FEC2 is not set @@ -425,7 +392,6 @@ CONFIG_PPP=y # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -459,6 +425,8 @@ CONFIG_PPP=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_LEDMAN is not set +# CONFIG_RESETSWITCH is not set # # Serial drivers @@ -482,6 +450,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_MCFWATCHDOG is not set +# CONFIG_RTC is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -494,19 +464,14 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set +# CONFIG_MCF_QSPI is not set +# CONFIG_M41T11M6 is not set # # I2C support # # CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# CONFIG_I2C_SENSOR is not set # # Dallas's 1-wire bus @@ -517,7 +482,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # Hardware Monitoring support # # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # # Misc devices @@ -527,7 +491,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -539,6 +502,11 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_FB is not set +# +# SPI support +# +# CONFIG_SPI is not set + # # Sound # @@ -549,11 +517,6 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# # # USB Gadget Support @@ -565,32 +528,14 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_MMC is not set -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - # # File systems # @@ -598,11 +543,15 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y # CONFIG_INOTIFY is not set @@ -610,7 +559,6 @@ CONFIG_ROMFS_FS=y # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -633,7 +581,6 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -664,7 +611,6 @@ CONFIG_RAMFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -681,12 +627,8 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set # CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set # CONFIG_BOOTPARAM is not set @@ -713,6 +655,5 @@ CONFIG_LOG_BUF_SHIFT=14 # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/m68knommu/kernel/setup.c b/trunk/arch/m68knommu/kernel/setup.c index 99d038e9ab31..93120b9bfff1 100644 --- a/trunk/arch/m68knommu/kernel/setup.c +++ b/trunk/arch/m68knommu/kernel/setup.c @@ -42,6 +42,7 @@ #include #endif +unsigned long rom_length; unsigned long memory_start; unsigned long memory_end; @@ -55,29 +56,29 @@ static void dummy_waitbut(void) { } -void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); -void (*mach_tick)( void ); +void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) = NULL; +void (*mach_tick)( void ) = NULL; /* machine dependent keyboard functions */ -int (*mach_keyb_init) (void); -int (*mach_kbdrate) (struct kbd_repeat *); -void (*mach_kbd_leds) (unsigned int); +int (*mach_keyb_init) (void) = NULL; +int (*mach_kbdrate) (struct kbd_repeat *) = NULL; +void (*mach_kbd_leds) (unsigned int) = NULL; /* machine dependent irq functions */ -void (*mach_init_IRQ) (void); -irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); -int (*mach_get_irq_list) (struct seq_file *, void *); -void (*mach_process_int) (int irq, struct pt_regs *fp); +void (*mach_init_IRQ) (void) = NULL; +irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; +int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; +void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL; void (*mach_trap_init) (void); /* machine dependent timer functions */ -unsigned long (*mach_gettimeoffset) (void); -void (*mach_gettod) (int*, int*, int*, int*, int*, int*); -int (*mach_hwclk) (int, struct hwclk_time*); -int (*mach_set_clock_mmss) (unsigned long); -void (*mach_mksound)( unsigned int count, unsigned int ticks ); -void (*mach_reset)( void ); +unsigned long (*mach_gettimeoffset) (void) = NULL; +void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL; +int (*mach_hwclk) (int, struct hwclk_time*) = NULL; +int (*mach_set_clock_mmss) (unsigned long) = NULL; +void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL; +void (*mach_reset)( void ) = NULL; void (*waitbut)(void) = dummy_waitbut; -void (*mach_debug_init)(void); -void (*mach_halt)( void ); -void (*mach_power_off)( void ); +void (*mach_debug_init)(void) = NULL; +void (*mach_halt)( void ) = NULL; +void (*mach_power_off)( void ) = NULL; #ifdef CONFIG_M68000 @@ -128,9 +129,6 @@ void (*mach_power_off)( void ); #if defined(CONFIG_M5307) #define CPU "COLDFIRE(m5307)" #endif -#if defined(CONFIG_M532x) - #define CPU "COLDFIRE(m532x)" -#endif #if defined(CONFIG_M5407) #define CPU "COLDFIRE(m5407)" #endif @@ -269,6 +267,34 @@ void setup_arch(char **cmdline_p) paging_init(); } +int get_cpuinfo(char * buffer) +{ + char *cpu, *mmu, *fpu; + u_long clockfreq; + + cpu = CPU; + mmu = "none"; + fpu = "none"; + +#ifdef CONFIG_COLDFIRE + clockfreq = (loops_per_jiffy*HZ)*3; +#else + clockfreq = (loops_per_jiffy*HZ)*16; +#endif + + return(sprintf(buffer, "CPU:\t\t%s\n" + "MMU:\t\t%s\n" + "FPU:\t\t%s\n" + "Clocking:\t%lu.%1luMHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, mmu, fpu, + clockfreq/1000000,(clockfreq/100000)%10, + (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, + (loops_per_jiffy*HZ))); + +} + /* * Get CPU information for use by the procfs. */ diff --git a/trunk/arch/m68knommu/kernel/signal.c b/trunk/arch/m68knommu/kernel/signal.c index 437f8c6c14a0..e1b3aa39e270 100644 --- a/trunk/arch/m68knommu/kernel/signal.c +++ b/trunk/arch/m68knommu/kernel/signal.c @@ -553,7 +553,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) + if (!on_sig_stack(usp)) usp = current->sas_ss_sp + current->sas_ss_size; } return (void *)((usp - frame_size) & -8UL); @@ -608,7 +608,7 @@ static void setup_frame (int sig, struct k_sigaction *ka, if (regs->stkadj) { struct pt_regs *tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); -#if defined(DEBUG) +#if DEBUG printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); #endif /* This must be copied with decreasing addresses to @@ -678,7 +678,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, if (regs->stkadj) { struct pt_regs *tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); -#if defined(DEBUG) +#if DEBUG printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); #endif /* This must be copied with decreasing addresses to diff --git a/trunk/arch/m68knommu/kernel/traps.c b/trunk/arch/m68knommu/kernel/traps.c index 44ff74e643b1..5bc068462864 100644 --- a/trunk/arch/m68knommu/kernel/traps.c +++ b/trunk/arch/m68knommu/kernel/traps.c @@ -93,12 +93,12 @@ asmlinkage void buserr_c(struct frame *fp) if (user_mode(&fp->ptregs)) current->thread.esp0 = (unsigned long) fp; -#if defined(DEBUG) +#if DEBUG printk (KERN_DEBUG "*** Bus Error *** Format is %x\n", fp->ptregs.format); #endif die_if_kernel("bad frame format",&fp->ptregs,0); -#if defined(DEBUG) +#if DEBUG printk(KERN_DEBUG "Unknown SIGSEGV - 4\n"); #endif force_sig(SIGSEGV, current); diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 6a2f0c693254..a331cc90797c 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -1,7 +1,7 @@ /* * vmlinux.lds.S -- master linker script for m68knommu arch * - * (C) Copyright 2002-2006, Greg Ungerer + * (C) Copyright 2002-2004, Greg Ungerer * * This ends up looking compilcated, because of the number of * address variations for ram and rom/flash layouts. The real @@ -22,7 +22,13 @@ #define ROM_START 0x10c10400 #define ROM_LENGTH 0xfec00 #define ROM_END 0x10d00000 -#define DATA_ADDR CONFIG_KERNELBASE +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x10000400 +#define RAM_LENGTH 0xffc00 +#define RAM_END 0x10100000 +#define _ramend _ram_end_notused +#define DATA_ADDR RAM_START #endif /* @@ -35,6 +41,11 @@ #define ROM_START 0x10c10400 #define ROM_LENGTH 0x1efc00 #define ROM_END 0x10e00000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020400 +#define RAM_LENGTH 0x7dfc00 +#define RAM_END 0x00800000 #endif #ifdef CONFIG_ROMKERNEL #define ROMVEC_START 0x10c10000 @@ -42,6 +53,11 @@ #define ROM_START 0x10c10400 #define ROM_LENGTH 0x1efc00 #define ROM_END 0x10e00000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020000 +#define RAM_LENGTH 0x600000 +#define RAM_END 0x00800000 #endif #ifdef CONFIG_HIMEMKERNEL #define ROMVEC_START 0x00600000 @@ -49,28 +65,141 @@ #define ROM_START 0x00600400 #define ROM_LENGTH 0x1efc00 #define ROM_END 0x007f0000 +#define RAMVEC_START 0x00000000 +#define RAMVEC_LENGTH 0x400 +#define RAM_START 0x00020000 +#define RAM_LENGTH 0x5e0000 +#define RAM_END 0x00600000 #endif #endif +#ifdef CONFIG_DRAGEN2 +#define RAM_START 0x10000 +#define RAM_LENGTH 0x7f0000 +#endif + #ifdef CONFIG_UCQUICC #define ROMVEC_START 0x00000000 #define ROMVEC_LENGTH 0x404 #define ROM_START 0x00000404 #define ROM_LENGTH 0x1ff6fc #define ROM_END 0x00200000 +#define RAMVEC_START 0x00200000 +#define RAMVEC_LENGTH 0x404 +#define RAM_START 0x00200404 +#define RAM_LENGTH 0x1ff6fc +#define RAM_END 0x00400000 +#endif + +/* + * The standard Arnewsh 5206 board only has 1MiB of ram. Not normally + * enough to be useful. Assume the user has fitted something larger, + * at least 4MiB in size. No point in not letting the kernel completely + * link, it will be obvious if it is too big when they go to load it. + */ +#if defined(CONFIG_ARN5206) +#define RAM_START 0x10000 +#define RAM_LENGTH 0x3f0000 +#endif + +/* + * The Motorola 5206eLITE board only has 1MiB of static RAM. + */ +#if defined(CONFIG_ELITE) +#define RAM_START 0x30020000 +#define RAM_LENGTH 0xe0000 +#endif + +/* + * All the Motorola eval boards have the same basic arrangement. + * The end of RAM will vary depending on how much ram is fitted, + * but this isn't important here, we assume at least 4MiB. + */ +#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \ + defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \ + defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) || \ + defined(CONFIG_M5271EVB) || defined(CONFIG_M5275EVB) || \ + defined(CONFIG_M5235EVB) +#define RAM_START 0x20000 +#define RAM_LENGTH 0x3e0000 +#endif + +/* + * The Freescale 5208EVB board has 32MB of RAM. + */ +#if defined(CONFIG_M5208EVB) +#define RAM_START 0x40020000 +#define RAM_LENGTH 0x01fe0000 +#endif + +/* + * The senTec COBRA5272 board has nearly the same memory layout as + * the M5272C3. We assume 16MiB ram. + */ +#if defined(CONFIG_COBRA5272) +#define RAM_START 0x20000 +#define RAM_LENGTH 0xfe0000 +#endif + +#if defined(CONFIG_M5282EVB) +#define RAM_START 0x10000 +#define RAM_LENGTH 0x3f0000 +#endif + +/* + * The senTec COBRA5282 board has the same memory layout as the M5282EVB. + */ +#if defined(CONFIG_COBRA5282) +#define RAM_START 0x10000 +#define RAM_LENGTH 0x3f0000 +#endif + + +/* + * The EMAC SoM-5282EM module. + */ +#if defined(CONFIG_SOM5282EM) +#define RAM_START 0x10000 +#define RAM_LENGTH 0xff0000 +#endif + + +/* + * These flash boot boards use all of ram for operation. Again the + * actual memory size is not important here, assume at least 4MiB. + * They currently have no support for running in flash. + */ +#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ + defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ + defined(CONFIG_HW_FEITH) +#define RAM_START 0x400 +#define RAM_LENGTH 0x3ffc00 +#endif + +/* + * Sneha Boards mimimun memory + * The end of RAM will vary depending on how much ram is fitted, + * but this isn't important here, we assume at least 4MiB. + */ +#if defined(CONFIG_CPU16B) +#define RAM_START 0x20000 +#define RAM_LENGTH 0x3e0000 +#endif + +#if defined(CONFIG_MOD5272) +#define RAM_START 0x02000000 +#define RAM_LENGTH 0x00800000 +#define RAMVEC_START 0x20000000 +#define RAMVEC_LENGTH 0x00000400 #endif #if defined(CONFIG_RAMKERNEL) -#define RAM_START CONFIG_KERNELBASE -#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE) #define TEXT ram #define DATA ram #define INIT ram #define BSS ram #endif #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) -#define RAM_START CONFIG_RAMBASE -#define RAM_LENGTH CONFIG_RAMSIZE #define TEXT rom #define DATA ram #define INIT ram @@ -86,7 +215,13 @@ OUTPUT_ARCH(m68k) ENTRY(_start) MEMORY { +#ifdef RAMVEC_START + ramvec : ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH +#endif ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH +#ifdef RAM_END + eram : ORIGIN = RAM_END, LENGTH = 0 +#endif #ifdef ROM_START romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH @@ -173,6 +308,12 @@ SECTIONS { __rom_end = . ; } > erom #endif +#ifdef RAMVEC_START + . = RAMVEC_START ; + .ramvec : { + __ramvec = .; + } > ramvec +#endif .data DATA_ADDR : { . = ALIGN(4); @@ -232,5 +373,12 @@ SECTIONS { _ebss = . ; } > BSS +#ifdef RAM_END + . = RAM_END ; + .eram : { + __ramend = . ; + _ramend = . ; + } > eram +#endif } diff --git a/trunk/arch/m68knommu/mm/init.c b/trunk/arch/m68knommu/mm/init.c index 70d1653be3da..d79503fe6e42 100644 --- a/trunk/arch/m68knommu/mm/init.c +++ b/trunk/arch/m68knommu/mm/init.c @@ -63,6 +63,8 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; +extern unsigned long rom_length; + void show_mem(void) { unsigned long i; @@ -176,9 +178,11 @@ void mem_init(void) initk = (&__init_begin - &__init_end) >> 10; tmp = nr_free_pages() << PAGE_SHIFT; - printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n", + printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", tmp >> 10, len >> 10, + (rom_length > 0) ? ((rom_length >> 10) - codek) : 0, + rom_length >> 10, codek, datak ); diff --git a/trunk/arch/m68knommu/platform/5307/Makefile b/trunk/arch/m68knommu/platform/5307/Makefile index 2fd37dcc309b..8d1619dc1ea6 100644 --- a/trunk/arch/m68knommu/platform/5307/Makefile +++ b/trunk/arch/m68knommu/platform/5307/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_M5249) += timers.o obj-$(CONFIG_M527x) += pit.o obj-$(CONFIG_M5272) += timers.o obj-$(CONFIG_M5307) += config.o timers.o -obj-$(CONFIG_M532x) += timers.o obj-$(CONFIG_M528x) += pit.o obj-$(CONFIG_M5407) += timers.o diff --git a/trunk/arch/m68knommu/platform/5307/entry.S b/trunk/arch/m68knommu/platform/5307/entry.S index 9ddf5476ef8f..89b180d4ed6a 100644 --- a/trunk/arch/m68knommu/platform/5307/entry.S +++ b/trunk/arch/m68knommu/platform/5307/entry.S @@ -4,8 +4,8 @@ * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) * Copyright (C) 1998 D. Jeff Dionne , * Kenneth Albanowski , - * Copyright (C) 2000 Lineo Inc. (www.lineo.com) - * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com) + * Copyright (C) 2000 Lineo Inc. (www.lineo.com) + * Copyright (C) 2004 Macq Electronique SA. (www.macqel.com) * * Based on: * @@ -56,27 +56,32 @@ sw_usp: .globl inthandler .globl fasthandler -enosys: - mov.l #sys_ni_syscall,%d3 - bra 1f - ENTRY(system_call) SAVE_ALL move #0x2000,%sr /* enable intrs again */ - cmpl #NR_syscalls,%d0 - jcc enosys + movel #-LENOSYS,%d2 + movel %d2,PT_D0(%sp) /* default return value in d0 */ + /* original D0 is in orig_d0 */ + movel %d0,%d2 + + /* save top of frame */ + pea %sp@ + jbsr set_esp0 + addql #4,%sp + + cmpl #NR_syscalls,%d2 + jcc ret_from_exception lea sys_call_table,%a0 - lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */ - movel %a0@(%d0),%d3 - jeq enosys + lsll #2,%d2 /* movel %a0@(%d2:l:4),%d3 */ + movel %a0@(%d2),%d3 + jeq ret_from_exception + lsrl #2,%d2 -1: movel %sp,%d2 /* get thread_info pointer */ andl #-THREAD_SIZE,%d2 /* at start of kernel stack */ movel %d2,%a0 - movel %sp,%a0@(THREAD_ESP0) /* save top of frame */ - btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) + btst #TIF_SYSCALL_TRACE,%a0@(TI_FLAGS) bnes 1f movel %d3,%a0 @@ -121,8 +126,8 @@ Luser_return: jne Lwork_to_do /* still work to do */ Lreturn: - move #0x2700,%sr /* disable intrs */ - movel sw_usp,%a0 /* get usp */ + move #0x2700,%sr /* disable intrs */ + movel sw_usp,%a0 /* get usp */ movel %sp@(PT_PC),%a0@- /* copy exception program counter */ movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ moveml %sp@,%d1-%d5/%a0-%a2 @@ -165,7 +170,7 @@ ENTRY(inthandler) movel %d0,%sp@(PT_ORIG_D0) addql #1,local_irq_count - movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ + movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ andl #0x03fc,%d0 /* mask out vector only */ leal per_cpu__kstat+STAT_IRQ,%a0 @@ -179,7 +184,7 @@ ENTRY(inthandler) movel %sp,%sp@- /* push regs arg onto stack */ movel %a0@(8),%sp@- /* push devid arg */ - movel %d0,%sp@- /* push vector # on stack */ + movel %d0,%sp@- /* push vector # on stack */ movel %a0@,%a0 /* get function to call */ jbsr %a0@ /* call vector handler */ @@ -196,7 +201,7 @@ ENTRY(inthandler) ENTRY(fasthandler) SAVE_LOCAL - movew %sp@(PT_FORMATVEC),%d0 + movew %sp@(PT_FORMATVEC),%d0 andl #0x03fc,%d0 /* mask out vector only */ leal per_cpu__kstat+STAT_IRQ,%a0 @@ -205,7 +210,7 @@ ENTRY(fasthandler) movel %sp,%sp@- /* push regs arg onto stack */ clrl %sp@- /* push devid arg */ lsrl #2,%d0 /* calculate real vector # */ - movel %d0,%sp@- /* push vector # on stack */ + movel %d0,%sp@- /* push vector # on stack */ lsll #4,%d0 /* adjust for array offset */ lea irq_list,%a0 @@ -260,3 +265,4 @@ ENTRY(resume) movew %a1@(TASK_THREAD+THREAD_SR),%d0 /* restore thread status reg */ movew %d0, %sr rts + diff --git a/trunk/arch/m68knommu/platform/5307/head.S b/trunk/arch/m68knommu/platform/5307/head.S index 1d9eb301d7ac..c30c462b99b1 100644 --- a/trunk/arch/m68knommu/platform/5307/head.S +++ b/trunk/arch/m68knommu/platform/5307/head.S @@ -3,7 +3,7 @@ /* * head.S -- common startup code for ColdFire CPUs. * - * (C) Copyright 1999-2006, Greg Ungerer . + * (C) Copyright 1999-2004, Greg Ungerer (gerg@snapgear.com). */ /*****************************************************************************/ @@ -19,15 +19,47 @@ /*****************************************************************************/ /* - * If we don't have a fixed memory size, then lets build in code + * Define fixed memory sizes. Configuration of a fixed memory size + * overrides everything else. If the user defined a size we just + * blindly use it (they know what they are doing right :-) + */ +#if defined(CONFIG_RAM32MB) +#define MEM_SIZE 0x02000000 /* memory size 32Mb */ +#elif defined(CONFIG_RAM16MB) +#define MEM_SIZE 0x01000000 /* memory size 16Mb */ +#elif defined(CONFIG_RAM8MB) +#define MEM_SIZE 0x00800000 /* memory size 8Mb */ +#elif defined(CONFIG_RAM4MB) +#define MEM_SIZE 0x00400000 /* memory size 4Mb */ +#elif defined(CONFIG_RAM1MB) +#define MEM_SIZE 0x00100000 /* memory size 1Mb */ +#endif + +/* + * Memory size exceptions for special cases. Some boards may be set + * for auto memory sizing, but we can't do it that way for some reason. + * For example the 5206eLITE board has static RAM, and auto-detecting + * the SDRAM will do you no good at all. Same goes for the MOD5272. + */ +#ifdef CONFIG_RAMAUTO +#if defined(CONFIG_M5206eLITE) +#define MEM_SIZE 0x00100000 /* 1MiB default memory */ +#endif +#if defined(CONFIG_MOD5272) +#define MEM_SIZE 0x00800000 /* 8MiB default memory */ +#endif +#endif /* CONFIG_RAMAUTO */ + + +/* + * If we don't have a fixed memory size now, then lets build in code * to auto detect the DRAM size. Obviously this is the prefered - * method, and should work for most boards. It won't work for those - * that do not have their RAM starting at address 0, and it only - * works on SDRAM (not boards fitted with SRAM). + * method, and should work for most boards (it won't work for those + * that do not have their RAM starting at address 0). */ -#if CONFIG_RAMSIZE != 0 +#if defined(MEM_SIZE) .macro GET_MEM_SIZE - movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */ + movel #MEM_SIZE,%d0 /* hard coded memory size */ .endm #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ @@ -66,7 +98,37 @@ .endm #else -#error "ERROR: I don't know how to probe your boards memory size?" +#error "ERROR: I don't know how to determine your boards memory size?" +#endif + + +/* + * Most ColdFire boards have their DRAM starting at address 0. + * Notable exception is the 5206eLITE board, another is the MOD5272. + */ +#if defined(CONFIG_M5206eLITE) +#define MEM_BASE 0x30000000 +#endif +#if defined(CONFIG_MOD5272) +#define MEM_BASE 0x02000000 +#define VBR_BASE 0x20000000 /* vectors in SRAM */ +#endif +#if defined(CONFIG_M5208EVB) +#define MEM_BASE 0x40000000 +#endif + +#ifndef MEM_BASE +#define MEM_BASE 0x00000000 /* memory base at address 0 */ +#endif + +/* + * The default location for the vectors is at the base of RAM. + * Some boards might like to use internal SRAM or something like + * that. If no board specific header defines an alternative then + * use the base of RAM. + */ +#ifndef VBR_BASE +#define VBR_BASE MEM_BASE /* vector address */ #endif /*****************************************************************************/ @@ -129,11 +191,11 @@ _start: * Create basic memory configuration. Set VBR accordingly, * and size memory. */ - movel #CONFIG_VECTORBASE,%a7 + movel #VBR_BASE,%a7 movec %a7,%VBR /* set vectors addr */ movel %a7,_ramvec - movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */ + movel #MEM_BASE,%a7 /* mark the base of RAM */ movel %a7,_rambase GET_MEM_SIZE /* macro code determines size */ diff --git a/trunk/arch/m68knommu/platform/5307/pit.c b/trunk/arch/m68knommu/platform/5307/pit.c index ef174748825f..323f2677e49d 100644 --- a/trunk/arch/m68knommu/platform/5307/pit.c +++ b/trunk/arch/m68knommu/platform/5307/pit.c @@ -1,11 +1,11 @@ /***************************************************************************/ /* - * pit.c -- Freescale ColdFire PIT timer. Currently this type of - * hardware timer only exists in the Freescale ColdFire + * pit.c -- Motorola ColdFire PIT timer. Currently this type of + * hardware timer only exists in the Motorola ColdFire * 5270/5271, 5282 and other CPUs. * - * Copyright (C) 1999-2006, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) * */ @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -26,20 +25,13 @@ /***************************************************************************/ -/* - * By default use timer1 as the system clock timer. - */ -#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a)) - -/***************************************************************************/ - void coldfire_pit_tick(void) { - unsigned short pcsr; + volatile struct mcfpit *tp; /* Reset the ColdFire timer */ - pcsr = __raw_readw(TA(MCFPIT_PCSR)); - __raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR)); + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); + tp->pcsr |= MCFPIT_PCSR_PIF; } /***************************************************************************/ @@ -48,6 +40,7 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { volatile unsigned char *icrp; volatile unsigned long *imrp; + volatile struct mcfpit *tp; request_irq(MCFINT_VECBASE + MCFINT_PIT1, handler, SA_INTERRUPT, "ColdFire Timer", NULL); @@ -60,23 +53,27 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) *imrp &= ~MCFPIT_IMR_IBIT; /* Set up PIT timer 1 as poll clock */ - __raw_writew(MCFPIT_PCSR_DISABLE, TA(MCFPIT_PCSR)); - __raw_writew(((MCF_CLK / 2) / 64) / HZ, TA(MCFPIT_PMR)); - __raw_writew(MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | - MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64, TA(MCFPIT_PCSR)); + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); + tp->pcsr = MCFPIT_PCSR_DISABLE; + + tp->pmr = ((MCF_CLK / 2) / 64) / HZ; + tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | + MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64; } /***************************************************************************/ unsigned long coldfire_pit_offset(void) { + volatile struct mcfpit *tp; volatile unsigned long *ipr; unsigned long pmr, pcntr, offset; + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR); - pmr = __raw_readw(TA(MCFPIT_PMR)); - pcntr = __raw_readw(TA(MCFPIT_PCNTR)); + pmr = *(&tp->pmr); + pcntr = *(&tp->pcntr); /* * If we are still in the first half of the upcount and a diff --git a/trunk/arch/m68knommu/platform/5307/timers.c b/trunk/arch/m68knommu/platform/5307/timers.c index 83b8b89dfa09..ef49596aa09c 100644 --- a/trunk/arch/m68knommu/platform/5307/timers.c +++ b/trunk/arch/m68knommu/platform/5307/timers.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -24,11 +23,6 @@ /***************************************************************************/ -/* - * By default use timer1 as the system clock timer. - */ -#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a)) - /* * Default the timer and vector to use for ColdFire. Some ColdFire * CPU's and some boards may want different. Their sub-architecture @@ -38,6 +32,8 @@ unsigned int mcf_timervector = 29; unsigned int mcf_profilevector = 31; unsigned int mcf_timerlevel = 5; +static volatile struct mcftimer *mcf_timerp; + /* * These provide the underlying interrupt vector support. * Unfortunately it is a little different on each ColdFire. @@ -50,17 +46,20 @@ extern int mcf_timerirqpending(int timer); void coldfire_tick(void) { /* Reset the ColdFire timer */ - __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER)); + mcf_timerp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; } /***************************************************************************/ void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { - __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); - __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); - __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | - MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); + /* Set up an internal TIMER as poll clock */ + mcf_timerp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE1); + mcf_timerp->tmr = MCFTIMER_TMR_DISABLE; + + mcf_timerp->trr = (unsigned short) ((MCF_BUSCLK / 16) / HZ); + mcf_timerp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | + MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL); mcf_settimericr(1, mcf_timerlevel); @@ -76,8 +75,13 @@ unsigned long coldfire_timer_offset(void) { unsigned long trr, tcn, offset; - tcn = __raw_readw(TA(MCFTIMER_TCN)); - trr = __raw_readw(TA(MCFTIMER_TRR)); + /* + * The change to pointer and de-reference is to force the compiler + * to read the registers with a single 16bit access. Otherwise it + * does some crazy 8bit read combining. + */ + tcn = *(&mcf_timerp->tcn); + trr = *(&mcf_timerp->trr); offset = (tcn * (1000000 / HZ)) / trr; /* Check if we just wrapped the counters and maybe missed a tick */ @@ -90,24 +94,22 @@ unsigned long coldfire_timer_offset(void) #ifdef CONFIG_HIGHPROFILE /***************************************************************************/ -/* - * By default use timer2 as the profiler clock timer. - */ -#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a)) - /* * Choose a reasonably fast profile timer. Make it an odd value to * try and get good coverage of kernal operations. */ #define PROFILEHZ 1013 +static volatile struct mcftimer *mcf_proftp; + /* * Use the other timer to provide high accuracy profiling info. */ + void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) { /* Reset ColdFire timer2 */ - __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); + mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; if (current->pid) profile_tick(CPU_PROFILING, regs); } @@ -119,11 +121,12 @@ void coldfire_profile_init(void) printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); /* Set up TIMER 2 as high speed profile clock */ - __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); + mcf_proftp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE2); + mcf_proftp->tmr = MCFTIMER_TMR_DISABLE; - __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); - __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | - MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); + mcf_proftp->trr = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ); + mcf_proftp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | + MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; request_irq(mcf_profilevector, coldfire_profile_tick, (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL); diff --git a/trunk/arch/m68knommu/platform/532x/Makefile b/trunk/arch/m68knommu/platform/532x/Makefile deleted file mode 100644 index 12301803b9eb..000000000000 --- a/trunk/arch/m68knommu/platform/532x/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Makefile for the m68knommu linux kernel. -# - -# -# If you want to play with the HW breakpoints then you will -# need to add define this, which will give you a stack backtrace -# on the console port whenever a DBG interrupt occurs. You have to -# set up you HW breakpoints to trigger a DBG interrupt: -# -# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT -# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT -# - -ifdef CONFIG_FULLDEBUG -AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 -endif - -#obj-y := config.o usb-mcf532x.o spi-mcf532x.o -obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/532x/config.c b/trunk/arch/m68knommu/platform/532x/config.c deleted file mode 100644 index ceef9bc181ea..000000000000 --- a/trunk/arch/m68knommu/platform/532x/config.c +++ /dev/null @@ -1,486 +0,0 @@ -/***************************************************************************/ - -/* - * linux/arch/m68knommu/platform/532x/config.c - * - * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) - * Copyright (C) 2000, Lineo (www.lineo.com) - * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com - * Copyright Freescale Semiconductor, Inc 2006 - * Copyright (c) 2006, emlix, Sebastian Hess - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -/***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/***************************************************************************/ - -void coldfire_tick(void); -void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); -unsigned long coldfire_timer_offset(void); -void coldfire_trap_init(void); -void coldfire_reset(void); - -extern unsigned int mcf_timervector; -extern unsigned int mcf_profilevector; -extern unsigned int mcf_timerlevel; - -/***************************************************************************/ - -/* - * DMA channel base address table. - */ -unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { }; -unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; - -/***************************************************************************/ - -void mcf_settimericr(unsigned int timer, unsigned int level) -{ - volatile unsigned char *icrp; - unsigned int icr; - unsigned char irq; - - if (timer <= 2) { - switch (timer) { - case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break; - default: irq = 32; icr = MCFSIM_ICR_TIMER1; break; - } - - icrp = (volatile unsigned char *) (MCF_MBAR + icr); - *icrp = level; - mcf_enable_irq0(irq); - } -} - -/***************************************************************************/ - -int mcf_timerirqpending(int timer) -{ - unsigned int imr = 0; - - switch (timer) { - case 1: imr = 0x1; break; - case 2: imr = 0x2; break; - default: break; - } - return (mcf_getiprh() & imr); -} - -/***************************************************************************/ - -void config_BSP(char *commandp, int size) -{ - mcf_setimr(MCFSIM_IMR_MASKALL); - -#if defined(CONFIG_BOOTPARAM) - strncpy(commandp, CONFIG_BOOTPARAM_STRING, size); - commandp[size-1] = 0; -#else - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0x4000, 4); - if(strncmp(commandp, "kcl ", 4) == 0){ - memcpy(commandp, (char *) 0x4004, size); - commandp[size-1] = 0; - } else { - memset(commandp, 0, size); - } -#endif - - mcf_timervector = 64+32; - mcf_profilevector = 64+33; - mach_sched_init = coldfire_timer_init; - mach_tick = coldfire_tick; - mach_gettimeoffset = coldfire_timer_offset; - mach_trap_init = coldfire_trap_init; - mach_reset = coldfire_reset; - -#ifdef MCF_BDM_DISABLE - /* - * Disable the BDM clocking. This also turns off most of the rest of - * the BDM device. This is good for EMC reasons. This option is not - * incompatible with the memory protection option. - */ - wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK); -#endif -} - -/***************************************************************************/ -/* Board initialization */ - -/********************************************************************/ -/* - * PLL min/max specifications - */ -#define MAX_FVCO 500000 /* KHz */ -#define MAX_FSYS 80000 /* KHz */ -#define MIN_FSYS 58333 /* KHz */ -#define FREF 16000 /* KHz */ - - -#define MAX_MFD 135 /* Multiplier */ -#define MIN_MFD 88 /* Multiplier */ -#define BUSDIV 6 /* Divider */ - -/* - * Low Power Divider specifications - */ -#define MIN_LPD (1 << 0) /* Divider (not encoded) */ -#define MAX_LPD (1 << 15) /* Divider (not encoded) */ -#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */ - -#define SYS_CLK_KHZ 80000 -#define SYSTEM_PERIOD 12.5 -/* - * SDRAM Timing Parameters - */ -#define SDRAM_BL 8 /* # of beats in a burst */ -#define SDRAM_TWR 2 /* in clocks */ -#define SDRAM_CASL 2.5 /* CASL in clocks */ -#define SDRAM_TRCD 2 /* in clocks */ -#define SDRAM_TRP 2 /* in clocks */ -#define SDRAM_TRFC 7 /* in clocks */ -#define SDRAM_TREFI 7800 /* in ns */ - -#define EXT_SRAM_ADDRESS (0xC0000000) -#define FLASH_ADDRESS (0x00000000) -#define SDRAM_ADDRESS (0x40000000) - -#define NAND_FLASH_ADDRESS (0xD0000000) - -int sys_clk_khz = 0; -int sys_clk_mhz = 0; - -void wtm_init(void); -void scm_init(void); -void gpio_init(void); -void fbcs_init(void); -void sdramc_init(void); -int clock_pll (int fsys, int flags); -int clock_limp (int); -int clock_exit_limp (void); -int get_sys_clock (void); - -asmlinkage void __init sysinit(void) -{ - sys_clk_khz = clock_pll(0, 0); - sys_clk_mhz = sys_clk_khz/1000; - - wtm_init(); - scm_init(); - gpio_init(); - fbcs_init(); - sdramc_init(); -} - -void wtm_init(void) -{ - /* Disable watchdog timer */ - MCF_WTM_WCR = 0; -} - -#define MCF_SCM_BCR_GBW (0x00000100) -#define MCF_SCM_BCR_GBR (0x00000200) - -void scm_init(void) -{ - /* All masters are trusted */ - MCF_SCM_MPR = 0x77777777; - - /* Allow supervisor/user, read/write, and trusted/untrusted - access to all slaves */ - MCF_SCM_PACRA = 0; - MCF_SCM_PACRB = 0; - MCF_SCM_PACRC = 0; - MCF_SCM_PACRD = 0; - MCF_SCM_PACRE = 0; - MCF_SCM_PACRF = 0; - - /* Enable bursts */ - MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW); -} - - -void fbcs_init(void) -{ - MCF_GPIO_PAR_CS = 0x0000003E; - - /* Latch chip select */ - MCF_FBCS1_CSAR = 0x10080000; - - MCF_FBCS1_CSCR = 0x002A3780; - MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V); - - /* Initialize latch to drive signals to inactive states */ - *((u16 *)(0x10080000)) = 0xFFFF; - - /* External SRAM */ - MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS; - MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16 - | MCF_FBCS_CSCR_AA - | MCF_FBCS_CSCR_SBM - | MCF_FBCS_CSCR_WS(1)); - MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K - | MCF_FBCS_CSMR_V); - - /* Boot Flash connected to FBCS0 */ - MCF_FBCS0_CSAR = FLASH_ADDRESS; - MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16 - | MCF_FBCS_CSCR_BEM - | MCF_FBCS_CSCR_AA - | MCF_FBCS_CSCR_SBM - | MCF_FBCS_CSCR_WS(7)); - MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M - | MCF_FBCS_CSMR_V); -} - -void sdramc_init(void) -{ - /* - * Check to see if the SDRAM has already been initialized - * by a run control tool - */ - if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) { - /* SDRAM chip select initialization */ - - /* Initialize SDRAM chip select */ - MCF_SDRAMC_SDCS0 = (0 - | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) - | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE)); - - /* - * Basic configuration and initialization - */ - MCF_SDRAMC_SDCFG1 = (0 - | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 )) - | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) - | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2)) - | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5)) - | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5)) - | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5)) - | MCF_SDRAMC_SDCFG1_WTLAT(3)); - MCF_SDRAMC_SDCFG2 = (0 - | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1) - | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR) - | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5)) - | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1)); - - - /* - * Precharge and enable write to SDMR - */ - MCF_SDRAMC_SDCR = (0 - | MCF_SDRAMC_SDCR_MODE_EN - | MCF_SDRAMC_SDCR_CKE - | MCF_SDRAMC_SDCR_DDR - | MCF_SDRAMC_SDCR_MUX(1) - | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5)) - | MCF_SDRAMC_SDCR_PS_16 - | MCF_SDRAMC_SDCR_IPALL); - - /* - * Write extended mode register - */ - MCF_SDRAMC_SDMR = (0 - | MCF_SDRAMC_SDMR_BNKAD_LEMR - | MCF_SDRAMC_SDMR_AD(0x0) - | MCF_SDRAMC_SDMR_CMD); - - /* - * Write mode register and reset DLL - */ - MCF_SDRAMC_SDMR = (0 - | MCF_SDRAMC_SDMR_BNKAD_LMR - | MCF_SDRAMC_SDMR_AD(0x163) - | MCF_SDRAMC_SDMR_CMD); - - /* - * Execute a PALL command - */ - MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL; - - /* - * Perform two REF cycles - */ - MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF; - MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF; - - /* - * Write mode register and clear reset DLL - */ - MCF_SDRAMC_SDMR = (0 - | MCF_SDRAMC_SDMR_BNKAD_LMR - | MCF_SDRAMC_SDMR_AD(0x063) - | MCF_SDRAMC_SDMR_CMD); - - /* - * Enable auto refresh and lock SDMR - */ - MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN; - MCF_SDRAMC_SDCR |= (0 - | MCF_SDRAMC_SDCR_REF - | MCF_SDRAMC_SDCR_DQS_OE(0xC)); - } -} - -void gpio_init(void) -{ - /* Enable UART0 pins */ - MCF_GPIO_PAR_UART = ( 0 - | MCF_GPIO_PAR_UART_PAR_URXD0 - | MCF_GPIO_PAR_UART_PAR_UTXD0); - - /* Initialize TIN3 as a GPIO output to enable the write - half of the latch */ - MCF_GPIO_PAR_TIMER = 0x00; - MCF_GPIO_PDDR_TIMER = 0x08; - MCF_GPIO_PCLRR_TIMER = 0x0; - -} - -int clock_pll(int fsys, int flags) -{ - int fref, temp, fout, mfd; - u32 i; - - fref = FREF; - - if (fsys == 0) { - /* Return current PLL output */ - mfd = MCF_PLL_PFDR; - - return (fref * mfd / (BUSDIV * 4)); - } - - /* Check bounds of requested system clock */ - if (fsys > MAX_FSYS) - fsys = MAX_FSYS; - if (fsys < MIN_FSYS) - fsys = MIN_FSYS; - - /* Multiplying by 100 when calculating the temp value, - and then dividing by 100 to calculate the mfd allows - for exact values without needing to include floating - point libraries. */ - temp = 100 * fsys / fref; - mfd = 4 * BUSDIV * temp / 100; - - /* Determine the output frequency for selected values */ - fout = (fref * mfd / (BUSDIV * 4)); - - /* - * Check to see if the SDRAM has already been initialized. - * If it has then the SDRAM needs to be put into self refresh - * mode before reprogramming the PLL. - */ - if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF) - /* Put SDRAM into self refresh mode */ - MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE; - - /* - * Initialize the PLL to generate the new system clock frequency. - * The device must be put into LIMP mode to reprogram the PLL. - */ - - /* Enter LIMP mode */ - clock_limp(DEFAULT_LPD); - - /* Reprogram PLL for desired fsys */ - MCF_PLL_PODR = (0 - | MCF_PLL_PODR_CPUDIV(BUSDIV/3) - | MCF_PLL_PODR_BUSDIV(BUSDIV)); - - MCF_PLL_PFDR = mfd; - - /* Exit LIMP mode */ - clock_exit_limp(); - - /* - * Return the SDRAM to normal operation if it is in use. - */ - if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF) - /* Exit self refresh mode */ - MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE; - - /* Errata - workaround for SDRAM opeartion after exiting LIMP mode */ - MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH; - - /* wait for DQS logic to relock */ - for (i = 0; i < 0x200; i++) - ; - - return fout; -} - -int clock_limp(int div) -{ - u32 temp; - - /* Check bounds of divider */ - if (div < MIN_LPD) - div = MIN_LPD; - if (div > MAX_LPD) - div = MAX_LPD; - - /* Save of the current value of the SSIDIV so we don't - overwrite the value*/ - temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF)); - - /* Apply the divider to the system clock */ - MCF_CCM_CDR = ( 0 - | MCF_CCM_CDR_LPDIV(div) - | MCF_CCM_CDR_SSIDIV(temp)); - - MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP; - - return (FREF/(3*(1 << div))); -} - -int clock_exit_limp(void) -{ - int fout; - - /* Exit LIMP mode */ - MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP); - - /* Wait for PLL to lock */ - while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK)) - ; - - fout = get_sys_clock(); - - return fout; -} - -int get_sys_clock(void) -{ - int divider; - - /* Test to see if device is in LIMP mode */ - if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) { - divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF); - return (FREF/(2 << divider)); - } - else - return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4)); -} diff --git a/trunk/arch/m68knommu/platform/68328/head-pilot.S b/trunk/arch/m68knommu/platform/68328/head-pilot.S index 46b3604f999c..c46775fe04be 100644 --- a/trunk/arch/m68knommu/platform/68328/head-pilot.S +++ b/trunk/arch/m68knommu/platform/68328/head-pilot.S @@ -21,6 +21,7 @@ .global _start .global _rambase +.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -120,7 +121,7 @@ L0: DBG_PUTC('B') /* Copy command line from beginning of RAM (+16) to end of bss */ - movel #CONFIG_VECTORBASE, %d7 + movel #__ramvec, %d7 addl #16, %d7 moveal %d7, %a0 moveal #_ebss, %a1 diff --git a/trunk/arch/m68knommu/platform/68328/head-ram.S b/trunk/arch/m68knommu/platform/68328/head-ram.S index e8dc9241ff96..6bdc9bce43f2 100644 --- a/trunk/arch/m68knommu/platform/68328/head-ram.S +++ b/trunk/arch/m68knommu/platform/68328/head-ram.S @@ -1,7 +1,10 @@ #include .global __main + .global __ram_start + .global __ram_end .global __rom_start + .global __rom_end .global _rambase .global _ramstart @@ -9,7 +12,6 @@ .global splash_bits .global _start .global _stext - .global _edata #define DEBUG #define ROM_OFFSET 0x10C00000 @@ -71,7 +73,7 @@ pclp1: #ifdef CONFIG_RELOCATE /* Copy me to RAM */ moveal #__rom_start, %a0 - moveal #_stext, %a1 + moveal #__ram_start, %a1 moveal #_edata, %a2 /* Copy %a0 to %a1 until %a1 == %a2 */ diff --git a/trunk/arch/m68knommu/platform/68328/head-rom.S b/trunk/arch/m68knommu/platform/68328/head-rom.S index 234430b9551c..2b448a297011 100644 --- a/trunk/arch/m68knommu/platform/68328/head-rom.S +++ b/trunk/arch/m68knommu/platform/68328/head-rom.S @@ -28,8 +28,6 @@ _ramstart: _ramend: .long 0 -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #ifdef CONFIG_INIT_LCD splash_bits: #include "bootlogo.rh" @@ -50,7 +48,7 @@ _stext: movew #0x2700,%sr moveb #0x81, 0xfffffA27 /* LCKCON */ movew #0xff00, 0xfffff412 /* LCD pins */ #endif - moveal #RAMEND-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp + moveal #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp movew #32767, %d0 /* PLL settle wait loop */ 1: subq #1, %d0 bne 1b @@ -75,13 +73,13 @@ _stext: movew #0x2700,%sr bhi 1b movel #_sdata, %d0 - movel %d0, _rambase - movel #_ebss, %d0 - movel %d0, _ramstart - movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 - movel %d0, _ramend - movel #CONFIG_VECTORBASE, %d0 - movel %d0, _ramvec + movel %d0, _rambase + movel #_ebss, %d0 + movel %d0, _ramstart + movel #__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0 + movel %d0, _ramend + movel #__ramvec, %d0 + movel %d0, _ramvec /* * load the current task pointer and stack diff --git a/trunk/arch/m68knommu/platform/68360/head-ram.S b/trunk/arch/m68knommu/platform/68360/head-ram.S index f497713a4ec7..a5c639a51eef 100644 --- a/trunk/arch/m68knommu/platform/68360/head-ram.S +++ b/trunk/arch/m68knommu/platform/68360/head-ram.S @@ -18,6 +18,7 @@ .global _start .global _rambase +.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -25,8 +26,6 @@ .global _quicc_base .global _periph_base -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -104,7 +103,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #RAMEND, %sp /*set up stack at the end of DRAM:*/ + movea.l #__ramend, %sp /*set up stack at the end of DRAM:*/ set_mbar_register: moveq.l #0x07, %d1 /* Setup MBAR */ @@ -164,7 +163,7 @@ configure_memory_controller: move.l %d0, GMR configure_chip_select_0: - move.l #RAMEND, %d0 + move.l #__ramend, %d0 subi.l #__ramstart, %d0 subq.l #0x01, %d0 eori.l #SIM_OR_MASK, %d0 @@ -235,10 +234,16 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #RAMEND, %d0 + move.l #__ramend, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from RAMEND.*/ + move.l %d0, _ramend /* Different from __ramend.*/ +store_flash_size: + /* Set rom size information */ + move.l #__rom_end, %d0 + sub.l #__rom_start, %d0 + move.l %d0, rom_length + pea 0 pea env pea %sp@(4) @@ -281,7 +286,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long RAMEND /* Reset: Initial Stack Pointer - 0. */ + .long __ramend /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/trunk/arch/m68knommu/platform/68360/head-rom.S b/trunk/arch/m68knommu/platform/68360/head-rom.S index 2d28c3e19a88..0da357a4cfee 100644 --- a/trunk/arch/m68knommu/platform/68360/head-rom.S +++ b/trunk/arch/m68knommu/platform/68360/head-rom.S @@ -18,6 +18,7 @@ .global _start .global _rambase +.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -25,8 +26,6 @@ .global _quicc_base .global _periph_base -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -116,7 +115,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #RAMEND, %sp /* set up stack at the end of DRAM:*/ + movea.l #__ramend, %sp /* set up stack at the end of DRAM:*/ set_mbar_register: @@ -246,10 +245,16 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #RAMEND, %d0 + move.l #__ramend, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from RAMEND.*/ + move.l %d0, _ramend /* Different from __ramend.*/ +store_flash_size: + /* Set rom size information */ + move.l #__rom_end, %d0 + sub.l #__rom_start, %d0 + move.l %d0, rom_length + pea 0 pea env pea %sp@(4) @@ -293,7 +298,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long RAMEND /* Reset: Initial Stack Pointer - 0. */ + .long __ramend /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 676e868d26fb..a9bf6cc3abd1 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -541,6 +540,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set, #define IRIX_P_PGID 2 #define IRIX_P_ALL 7 +extern int getrusage(struct task_struct *, int, struct rusage __user *); + #define W_EXITED 1 #define W_TRAPPED 2 #define W_STOPPED 4 diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 2d2fdf77e308..a0ac0e5f61ad 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -497,7 +497,7 @@ einval: li v0, -EINVAL sys sys_sched_get_priority_min 1 sys sys_sched_rr_get_interval 2 /* 4165 */ sys sys_nanosleep, 2 - sys sys_mremap, 5 + sys sys_mremap, 4 sys sys_accept 3 sys sys_bind 3 sys sys_connect 3 /* 4170 */ diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 9096a5ea4229..298f82fe8440 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -446,7 +446,7 @@ static int __init topology_init(void) int ret; for_each_present_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 70cf09afdf56..2e8e52c135e6 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -367,7 +367,7 @@ void mipsmt_prepare_cpus(void) dvpe(); dmt(); - spin_lock_init(&freeIPIq.lock); + freeIPIq.lock = SPIN_LOCK_UNLOCKED; /* * We probably don't have as many VPEs as we do SMP "CPUs", @@ -375,7 +375,7 @@ void mipsmt_prepare_cpus(void) */ for (i=0; i #include #include -#include #include #include @@ -236,6 +235,7 @@ asmlinkage int irix_prctl(unsigned option, ...) #undef DEBUG_PROCGRPS extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt); +extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru); extern char *prom_getenv(char *name); extern long prom_setenv(char *name, char *value); @@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __user *path, if (error) goto out; - error = vfs_statfs(nd.dentry, &kbuf); + error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); if (error) goto dput_and_out; @@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); if (error) goto out_f; @@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf) error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.dentry, &kbuf); + error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); if (error) goto dput_and_out; @@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); if (error) goto out_f; @@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user * error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.dentry, &kbuf); + error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); if (error) goto dput_and_out; @@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); if (error) goto out_f; diff --git a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c index 8bd9b844fa9e..e5eceed1beff 100644 --- a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c @@ -59,7 +59,7 @@ void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) * bit_num - Indicates which bit number in the cause register * * Outputs : - * 1 if successful, 0 if failure + * 1 if succesful, 0 if failure */ int enable_galileo_irq(int int_cause, int bit_num) { @@ -83,7 +83,7 @@ int enable_galileo_irq(int int_cause, int bit_num) * bit_num - Indicates which bit number in the cause register * * Outputs : - * 1 if successful, 0 if failure + * 1 if succesful, 0 if failure */ int disable_galileo_irq(int int_cause, int bit_num) { diff --git a/trunk/arch/mips/oprofile/common.c b/trunk/arch/mips/oprofile/common.c index 65eb55400d77..c31e4cff64e0 100644 --- a/trunk/arch/mips/oprofile/common.c +++ b/trunk/arch/mips/oprofile/common.c @@ -38,7 +38,7 @@ static int op_mips_create_files(struct super_block * sb, struct dentry * root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[4]; + char buf[3]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/trunk/arch/mips/sgi-ip22/ip22-reset.c b/trunk/arch/mips/sgi-ip22/ip22-reset.c index 8134220ed600..a9c58e067b53 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-reset.c +++ b/trunk/arch/mips/sgi-ip22/ip22-reset.c @@ -34,7 +34,7 @@ #define POWERDOWN_TIMEOUT 120 /* - * Blink frequency during reboot grace period and when panicked. + * Blink frequency during reboot grace period and when paniced. */ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) diff --git a/trunk/arch/mips/sgi-ip32/ip32-reset.c b/trunk/arch/mips/sgi-ip32/ip32-reset.c index 79ddb4605659..ab9d9cef089e 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-reset.c +++ b/trunk/arch/mips/sgi-ip32/ip32-reset.c @@ -28,13 +28,13 @@ #define POWERDOWN_TIMEOUT 120 /* - * Blink frequency during reboot grace period and when panicked. + * Blink frequency during reboot grace period and when paniced. */ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) static struct timer_list power_timer, blink_timer, debounce_timer; -static int has_panicked, shuting_down; +static int has_paniced, shuting_down; static void ip32_machine_restart(char *command) __attribute__((noreturn)); static void ip32_machine_halt(void) __attribute__((noreturn)); @@ -109,7 +109,7 @@ static void debounce(unsigned long data) } CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); - if (has_panicked) + if (has_paniced) ip32_machine_restart(NULL); enable_irq(MACEISA_RTC_IRQ); @@ -117,7 +117,7 @@ static void debounce(unsigned long data) static inline void ip32_power_button(void) { - if (has_panicked) + if (has_paniced) return; if (shuting_down || kill_proc(1, SIGINT, 1)) { @@ -161,9 +161,9 @@ static int panic_event(struct notifier_block *this, unsigned long event, { unsigned long led; - if (has_panicked) + if (has_paniced) return NOTIFY_DONE; - has_panicked = 1; + has_paniced = 1; /* turn off the green LED */ led = mace->perif.ctrl.misc | MACEISA_LED_GREEN; diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index cb69727027ae..05273ccced0e 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf) s = user_get_super(dev); if (s == NULL) goto out; - err = vfs_statfs(s->s_root, &sbuf); + err = vfs_statfs(s, &sbuf); drop_super(s); if (err) goto out; @@ -186,12 +186,12 @@ struct hpux_statfs { int16_t f_pad; }; -static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf) +static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf) { struct kstatfs st; int retval; - retval = vfs_statfs(dentry, &st); + retval = vfs_statfs(sb, &st); if (retval) return retval; @@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char __user *path, error = user_path_walk(path, &nd); if (!error) { struct hpux_statfs tmp; - error = vfs_statfs_hpux(nd.dentry, &tmp); + error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; path_release(&nd); @@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf) file = fget(fd); if (!file) goto out; - error = vfs_statfs_hpux(file->f_dentry, &tmp); + error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index cc38edfd90c5..05767e83cf2d 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -248,7 +248,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n", (unsigned long)ka, sp, frame_size); - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp; /* Stacks grow up! */ DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp); diff --git a/trunk/arch/parisc/kernel/topology.c b/trunk/arch/parisc/kernel/topology.c index 068b20d822e7..3ba040050e4c 100644 --- a/trunk/arch/parisc/kernel/topology.c +++ b/trunk/arch/parisc/kernel/topology.c @@ -26,10 +26,11 @@ static struct cpu cpu_devices[NR_CPUS] __read_mostly; static int __init topology_init(void) { + struct node *parent = NULL; int num; for_each_present_cpu(num) { - register_cpu(&cpu_devices[num], num); + register_cpu(&cpu_devices[num], num, parent); } return 0; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index e922a88b2bad..6729c98b66f9 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -45,10 +45,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_FIND_NEXT_BIT - bool - default y - config PPC bool default y @@ -141,15 +137,6 @@ config PPC_85xx select FSL_SOC select 85xx -config PPC_86xx - bool "Freescale 86xx" - select 6xx - select FSL_SOC - select PPC_FPU - select ALTIVEC - help - The Freescale E600 SoCs have 74xx cores. - config 40x bool "AMCC 40x" @@ -349,7 +336,7 @@ endchoice config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 - bool "IBM pSeries & new (POWER5-based) iSeries" + bool " IBM pSeries & new (POWER5-based) iSeries" select PPC_I8259 select PPC_RTAS select RTAS_ERROR_LOGGING @@ -357,7 +344,7 @@ config PPC_PSERIES default y config PPC_CHRP - bool "Common Hardware Reference Platform (CHRP) based machines" + bool " Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 select PPC_I8259 select PPC_INDIRECT_PCI @@ -367,7 +354,7 @@ config PPC_CHRP default y config PPC_PMAC - bool "Apple PowerMac based machines" + bool " Apple PowerMac based machines" depends on PPC_MULTIPLATFORM select PPC_INDIRECT_PCI if PPC32 select PPC_MPC106 if PPC32 @@ -383,7 +370,7 @@ config PPC_PMAC64 default y config PPC_PREP - bool "PowerPC Reference Platform (PReP) based machines" + bool " PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 && BROKEN select PPC_I8259 select PPC_INDIRECT_PCI @@ -392,7 +379,7 @@ config PPC_PREP config PPC_MAPLE depends on PPC_MULTIPLATFORM && PPC64 - bool "Maple 970FX Evaluation Board" + bool " Maple 970FX Evaluation Board" select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -404,18 +391,8 @@ config PPC_MAPLE For more informations, refer to config PPC_CELL - bool - default n - -config PPC_CELL_NATIVE - bool - select PPC_CELL - default n - -config PPC_IBM_CELL_BLADE - bool " IBM Cell Blade" + bool " Cell Broadband Processor Architecture" depends on PPC_MULTIPLATFORM && PPC64 - select PPC_CELL_NATIVE select PPC_RTAS select MMIO_NVRAM select PPC_UDBG_16550 @@ -462,6 +439,11 @@ config MPIC_BROKEN_U3 depends on PPC_MAPLE default y +config CELL_IIC + depends on PPC_CELL + bool + default y + config IBMVIO depends on PPC_PSERIES || PPC_ISERIES bool @@ -563,7 +545,6 @@ source arch/powerpc/platforms/embedded6xx/Kconfig source arch/powerpc/platforms/4xx/Kconfig source arch/powerpc/platforms/83xx/Kconfig source arch/powerpc/platforms/85xx/Kconfig -source arch/powerpc/platforms/86xx/Kconfig source arch/powerpc/platforms/8xx/Kconfig source arch/powerpc/platforms/cell/Kconfig @@ -718,6 +699,7 @@ config PPC_64K_PAGES config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" depends on PPC64 && SMP + default off help SMT scheduler support improves the CPU scheduler's decision making when dealing with POWER5 cpus at a cost of slightly increased @@ -794,7 +776,6 @@ config GENERIC_ISA_DMA config PPC_I8259 bool - default y if MPC8641_HPCN default n config PPC_INDIRECT_PCI @@ -817,8 +798,8 @@ config MCA bool config PCI - bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) - default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx + bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) + default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS default PCI_QSPAN if !4xx && !CPM2 && 8xx help @@ -846,12 +827,12 @@ config PCI_8260 default y config 8260_PCI9 - bool "Enable workaround for MPC826x erratum PCI 9" + bool " Enable workaround for MPC826x erratum PCI 9" depends on PCI_8260 && !ADS8272 default y choice - prompt "IDMA channel for PCI 9 workaround" + prompt " IDMA channel for PCI 9 workaround" depends on 8260_PCI9 config 8260_PCI9_IDMA1 @@ -868,8 +849,6 @@ config 8260_PCI9_IDMA4 endchoice -source "drivers/pci/pcie/Kconfig" - source "drivers/pci/Kconfig" source "drivers/pcmcia/Kconfig" diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index c69006ae8246..8d48e9e7162a 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -110,16 +110,13 @@ config SERIAL_TEXT_DEBUG depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ PPC_GEN550 || PPC_MPC52xx -config PPC_EARLY_DEBUG - bool "Early debugging (dangerous)" - choice - prompt "Early debugging console" - depends on PPC_EARLY_DEBUG + prompt "Early debugging (dangerous)" + bool + optional help - Use the selected console for early debugging. Careful, if you - enable debugging for the wrong type of machine your kernel - _will not boot_. + Enable early debugging. Careful, if you enable debugging for the + wrong type of machine your kernel _will not boot_. config PPC_EARLY_DEBUG_LPAR bool "LPAR HV Console" diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 01667d1d571d..ed5b26aa8be3 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -108,6 +108,7 @@ ifeq ($(CONFIG_6xx),y) CFLAGS += -mcpu=powerpc endif +cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge cpu-as-$(CONFIG_4xx) += -Wa,-m405 cpu-as-$(CONFIG_6xx) += -Wa,-maltivec cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index d961bfeed05f..840ae595a617 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -29,8 +29,8 @@ OBJCOPYFLAGS := contents,alloc,load,readonly,data OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment -zlib := inffast.c inflate.c inftrees.c -zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c +zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) diff --git a/trunk/arch/powerpc/boot/main.c b/trunk/arch/powerpc/boot/main.c index b66634c9ea34..816446f0e497 100644 --- a/trunk/arch/powerpc/boot/main.c +++ b/trunk/arch/powerpc/boot/main.c @@ -33,14 +33,6 @@ extern char _vmlinux_end[]; extern char _initrd_start[]; extern char _initrd_end[]; -/* A buffer that may be edited by tools operating on a zImage binary so as to - * edit the command line passed to vmlinux (by setting /chosen/bootargs). - * The buffer is put in it's own section so that tools may locate it easier. - */ -static char builtin_cmdline[512] - __attribute__((section("__builtin_cmdline"))); - - struct addr_range { unsigned long addr; unsigned long size; @@ -212,23 +204,6 @@ static int is_elf32(void *hdr) return 1; } -void export_cmdline(void* chosen_handle) -{ - int len; - char cmdline[2] = { 0, 0 }; - - if (builtin_cmdline[0] == 0) - return; - - len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline)); - if (len > 0 && cmdline[0] != 0) - return; - - setprop(chosen_handle, "bootargs", builtin_cmdline, - strlen(builtin_cmdline) + 1); -} - - void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) { int len; @@ -314,8 +289,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); } - export_cmdline(chosen_handle); - /* Skip over the ELF header */ #ifdef DEBUG printf("... skipping 0x%lx bytes of ELF header\n\r", diff --git a/trunk/arch/powerpc/boot/prom.h b/trunk/arch/powerpc/boot/prom.h index a57b184c564f..3e2ddd4a5a81 100644 --- a/trunk/arch/powerpc/boot/prom.h +++ b/trunk/arch/powerpc/boot/prom.h @@ -31,11 +31,4 @@ static inline int getprop(void *phandle, const char *name, return call_prom("getprop", 4, 1, phandle, name, buf, buflen); } - -static inline int setprop(void *phandle, const char *name, - void *buf, int buflen) -{ - return call_prom("setprop", 4, 1, phandle, name, buf, buflen); -} - #endif /* _PPC_BOOT_PROM_H_ */ diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index b8b8d4675dc0..dbe421dc3c11 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Mon Jun 19 17:23:03 2006 +# Linux kernel version: 2.6.16 +# Thu Mar 23 20:48:09 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -11,7 +11,6 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -56,7 +55,7 @@ CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_CPUSETS=y +# CONFIG_CPUSETS is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -117,15 +116,13 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set CONFIG_PPC_CELL=y -CONFIG_PPC_CELL_NATIVE=y -CONFIG_PPC_IBM_CELL_BLADE=y -CONFIG_PPC_SYSTEMSIM=y # CONFIG_U3_DART is not set CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERROR_LOGGING is not set CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=y CONFIG_MMIO_NVRAM=y +CONFIG_CELL_IIC=y # CONFIG_PPC_MPC106 is not set # CONFIG_PPC_970_NAP is not set # CONFIG_CPU_FREQ is not set @@ -135,9 +132,7 @@ CONFIG_MMIO_NVRAM=y # Cell Broadband Engine options # CONFIG_SPU_FS=m -CONFIG_SPU_BASE=y CONFIG_SPUFS_MMAP=y -CONFIG_CBE_RAS=y # # Kernel options @@ -157,24 +152,20 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=4 +# CONFIG_NUMA is not set CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y -CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y -CONFIG_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y @@ -191,7 +182,6 @@ CONFIG_GENERIC_ISA_DMA=y # CONFIG_PPC_INDIRECT_PCI is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_PCIEPORTBUS=y # CONFIG_PCI_DEBUG is not set # @@ -486,7 +476,7 @@ CONFIG_DM_MULTIPATH=m # CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set -CONFIG_BONDING=y +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set @@ -634,7 +624,6 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_N_HDLC is not set # CONFIG_SPECIALIX is not set # CONFIG_SX is not set -# CONFIG_RIO is not set # CONFIG_STALDRV is not set # @@ -777,7 +766,6 @@ CONFIG_I2C_ALGOBIT=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1066,7 +1054,11 @@ CONFIG_DEBUGGER=y # CONFIG_XMON is not set CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set # # Security options diff --git a/trunk/arch/powerpc/configs/mpc85xx_cds_defconfig b/trunk/arch/powerpc/configs/mpc85xx_cds_defconfig deleted file mode 100644 index 9bb022a523fe..000000000000 --- a/trunk/arch/powerpc/configs/mpc85xx_cds_defconfig +++ /dev/null @@ -1,846 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Sun Apr 2 11:23:42 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -CONFIG_PPC_85xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_85xx=y -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_MPIC=y -# CONFIG_WANT_EARLY_SERIAL is not set - -# -# Platform support -# -# CONFIG_MPC8540_ADS is not set -CONFIG_MPC85xx_CDS=y -CONFIG_MPC8540=y -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_MATH_EMULATION=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -# CONFIG_BLK_DEV_IDEDISK is not set -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_DEBUGGER is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig b/trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig deleted file mode 100644 index d7a30f9bc535..000000000000 --- a/trunk/arch/powerpc/configs/mpc8641_hpcn_defconfig +++ /dev/null @@ -1,921 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Fri Jun 16 10:47:09 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -CONFIG_PPC_86xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_6xx=y -CONFIG_PPC_FPU=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -# CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_CPUSETS is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -# CONFIG_SLAB is not set -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_SLOB=y - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_MPIC=y -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Platform Support -# -CONFIG_MPC8641_HPCN=y -CONFIG_MPC8641=y - -# -# Kernel options -# -CONFIG_HIGHMEM=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_IRQ_ALL_CPUS is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -CONFIG_VITESSE_PHY=y - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_GFAR_NAPI is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_CHARDEV is not set - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -CONFIG_LDM_PARTITION=y -# CONFIG_LDM_DEBUG is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_DEBUGGER is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/pmac32_defconfig b/trunk/arch/powerpc/configs/pmac32_defconfig index addc79381c3b..57a027971d67 100644 --- a/trunk/arch/powerpc/configs/pmac32_defconfig +++ b/trunk/arch/powerpc/configs/pmac32_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc5 -# Mon May 29 14:47:49 2006 +# Linux kernel version: 2.6.16-rc6 +# Wed Mar 15 16:21:32 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -9,7 +9,6 @@ CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y @@ -28,11 +27,11 @@ CONFIG_CLASSIC32=y # CONFIG_PPC_52xx is not set # CONFIG_PPC_82xx is not set # CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_8xx is not set # CONFIG_E200 is not set +# CONFIG_E500 is not set CONFIG_6xx=y CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y @@ -60,7 +59,6 @@ CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_EMBEDDED is not set @@ -75,6 +73,10 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -86,6 +88,7 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -94,8 +97,6 @@ CONFIG_KMOD=y # Block layer # CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_LSF=y # # IO Schedulers @@ -123,7 +124,6 @@ CONFIG_MPIC=y # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set CONFIG_PPC_MPC106=y -# CONFIG_PPC_970_NAP is not set CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set @@ -182,6 +182,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_PPC_INDIRECT_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set # @@ -238,9 +239,7 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y +# CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -251,10 +250,9 @@ CONFIG_IP_FIB_HASH=y # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y @@ -266,8 +264,6 @@ CONFIG_TCP_CONG_BIC=y # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -282,15 +278,12 @@ CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m @@ -312,15 +305,15 @@ CONFIG_IP_NF_NETBIOS_NS=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_PPTP=m -CONFIG_IP_NF_H323=m # CONFIG_IP_NF_QUEUE is not set CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_AH_ESP=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m CONFIG_IP_NF_MATCH_ADDRTYPE=m @@ -342,7 +335,6 @@ CONFIG_IP_NF_NAT_FTP=m CONFIG_IP_NF_NAT_TFTP=m CONFIG_IP_NF_NAT_AMANDA=m CONFIG_IP_NF_NAT_PPTP=m -CONFIG_IP_NF_NAT_H323=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m @@ -358,12 +350,10 @@ CONFIG_IP_NF_ARP_MANGLE=m # CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m -CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # -CONFIG_IP_DCCP_CCID2=m CONFIG_IP_DCCP_CCID3=m CONFIG_IP_DCCP_TFRC_LIB=m @@ -371,6 +361,7 @@ CONFIG_IP_DCCP_TFRC_LIB=m # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set +# CONFIG_IP_DCCP_UNLOAD_HACK is not set # # SCTP Configuration (EXPERIMENTAL) @@ -486,8 +477,6 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m -# CONFIG_IEEE80211_SOFTMAC is not set -CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -673,8 +662,9 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -704,17 +694,16 @@ CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m +# CONFIG_MD_RAID10 is not set CONFIG_MD_RAID5=m -CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set # CONFIG_DM_MULTIPATH is not set # @@ -751,7 +740,7 @@ CONFIG_IEEE1394_OHCI1394=m CONFIG_IEEE1394_VIDEO1394=m CONFIG_IEEE1394_SBP2=m # CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_ETH1394=m CONFIG_IEEE1394_DV1394=m CONFIG_IEEE1394_RAWIO=m @@ -780,10 +769,10 @@ CONFIG_THERM_ADT746X=m # Network device support # CONFIG_NETDEVICES=y -CONFIG_DUMMY=m +# CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set -CONFIG_TUN=m +# CONFIG_TUN is not set # # ARCnet devices @@ -868,7 +857,6 @@ CONFIG_PCNET32=y # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y -# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) @@ -1004,7 +992,6 @@ CONFIG_HW_CONSOLE=y # Serial drivers # CONFIG_SERIAL_8250=m -CONFIG_SERIAL_8250_PCI=m # CONFIG_SERIAL_8250_CS is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 @@ -1040,7 +1027,6 @@ CONFIG_GEN_RTC=y # Ftape, the floppy tape device driver # CONFIG_AGP=m -# CONFIG_AGP_VIA is not set CONFIG_AGP_UNINORTH=m CONFIG_DRM=m # CONFIG_DRM_TDFX is not set @@ -1095,6 +1081,7 @@ CONFIG_I2C_POWERMAC=y # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -1113,8 +1100,10 @@ CONFIG_I2C_POWERMAC=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_M41T00 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1141,17 +1130,19 @@ CONFIG_I2C_POWERMAC=y # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -1161,7 +1152,6 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MACMODES=y -CONFIG_FB_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -1185,6 +1175,7 @@ CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_FB_MATROX_G is not set # CONFIG_FB_MATROX_I2C is not set # CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=y CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set @@ -1243,11 +1234,9 @@ CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -1264,7 +1253,6 @@ CONFIG_SND_DUMMY=m # PCI devices # # CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALS300 is not set # CONFIG_SND_ALS4000 is not set # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set @@ -1297,7 +1285,6 @@ CONFIG_SND_DUMMY=m # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set # CONFIG_SND_PCXHR is not set -# CONFIG_SND_RIPTIDE is not set # CONFIG_SND_RME32 is not set # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set @@ -1323,8 +1310,6 @@ CONFIG_SND_USB_AUDIO=m # # PCMCIA devices # -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_PDAUDIOCF is not set # # Open Sound System @@ -1336,7 +1321,6 @@ CONFIG_SND_USB_AUDIO=m # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -1352,9 +1336,7 @@ CONFIG_USB_DYNAMIC_MINORS=y # # USB Host Controller Drivers # -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_SPLIT_ISO=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1365,6 +1347,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # # USB Device Class drivers # +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m @@ -1375,17 +1358,7 @@ CONFIG_USB_PRINTER=m # # may also be needed; see USB_STORAGE Help for more information # -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1401,7 +1374,9 @@ CONFIG_USB_HIDINPUT_POWERBOOK=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1415,6 +1390,15 @@ CONFIG_USB_APPLETOUCH=y # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + # # USB Network Adapters # @@ -1445,7 +1429,6 @@ CONFIG_USB_SERIAL=m # CONFIG_USB_SERIAL_GENERIC is not set # CONFIG_USB_SERIAL_AIRPRIME is not set # CONFIG_USB_SERIAL_ANYDATA is not set -# CONFIG_USB_SERIAL_ARK3116 is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set @@ -1453,7 +1436,6 @@ CONFIG_USB_SERIAL=m # 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=m CONFIG_USB_SERIAL_IPAQ=m # CONFIG_USB_SERIAL_IR is not set @@ -1478,7 +1460,6 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # 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_NAVMAN is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set @@ -1503,7 +1484,6 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1521,19 +1501,6 @@ CONFIG_USB_EZUSB=y # # CONFIG_MMC is not set -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # @@ -1543,11 +1510,6 @@ CONFIG_USB_EZUSB=y # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - # # File systems # @@ -1556,14 +1518,14 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set @@ -1572,7 +1534,7 @@ CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m +# CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m # @@ -1604,6 +1566,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +CONFIG_RELAYFS_FS=m # CONFIG_CONFIGFS_FS is not set # @@ -1627,24 +1590,17 @@ CONFIG_HFSPLUS_FS=m # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_TCP=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_ACL_SUPPORT=y +CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set @@ -1725,7 +1681,7 @@ CONFIG_NLS_UTF8=m CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC32=y -CONFIG_LIBCRC32C=m +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_TEXTSEARCH=y @@ -1779,29 +1735,29 @@ CONFIG_BOOTX_TEXT=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig index 31708ad4574e..58e68ce09b0f 100644 --- a/trunk/arch/powerpc/configs/pseries_defconfig +++ b/trunk/arch/powerpc/configs/pseries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc4 -# Sun May 28 07:26:56 2006 +# Linux kernel version: 2.6.17-rc1 +# Wed Apr 19 11:48:00 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -11,7 +11,6 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -127,9 +126,8 @@ CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m # CONFIG_MMIO_NVRAM is not set CONFIG_IBMVIO=y -CONFIG_IBMEBUS=y +# CONFIG_IBMEBUS is not set # CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_WANT_EARLY_SERIAL is not set @@ -145,7 +143,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m +# CONFIG_BINFMT_MISC is not set CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_IOMMU_VMERGE=y CONFIG_HOTPLUG_CPU=y @@ -157,7 +155,6 @@ CONFIG_EEH=y CONFIG_SCANLOG=m CONFIG_LPARCFG=y CONFIG_NUMA=y -CONFIG_NODES_SHIFT=4 CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y @@ -470,7 +467,7 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -502,18 +499,13 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA_FC=m -CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y -CONFIG_SCSI_QLA21XX=m -CONFIG_SCSI_QLA22XX=m -CONFIG_SCSI_QLA2300=m -CONFIG_SCSI_QLA2322=m -CONFIG_SCSI_QLA24XX=m +# CONFIG_SCSI_QLA_FC is not set CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -529,7 +521,7 @@ CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y CONFIG_MD_RAID10=m CONFIG_MD_RAID5=y -CONFIG_MD_RAID5_RESHAPE=y +# CONFIG_MD_RAID5_RESHAPE is not set CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m @@ -772,7 +764,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_ICOM=m -CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -781,7 +773,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_TIPAR is not set CONFIG_HVC_DRIVER=y CONFIG_HVC_CONSOLE=y -CONFIG_HVC_RTAS=y +# CONFIG_HVC_RTAS is not set CONFIG_HVCS=m # @@ -1039,7 +1031,9 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1110,26 +1104,17 @@ CONFIG_USB_MON=y # # CONFIG_NEW_LEDS is not set -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # CONFIG_INFINIBAND=m -CONFIG_INFINIBAND_USER_MAD=m -CONFIG_INFINIBAND_USER_ACCESS=m +# CONFIG_INFINIBAND_USER_MAD is not set +# CONFIG_INFINIBAND_USER_ACCESS is not set CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -CONFIG_INFINIBAND_IPOIB_DEBUG=y -# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set -CONFIG_INFINIBAND_SRP=m +# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +# CONFIG_INFINIBAND_SRP is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1174,15 +1159,15 @@ CONFIG_XFS_EXPORT=y CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set -CONFIG_OCFS2_FS=m +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m +CONFIG_AUTOFS_FS=m +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -1214,7 +1199,7 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1332,7 +1317,7 @@ CONFIG_ZLIB_DEFLATE=m # CONFIG_PROFILING=y CONFIG_OPROFILE=y -CONFIG_KPROBES=y +# CONFIG_KPROBES is not set # # Kernel hacking @@ -1344,7 +1329,7 @@ CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1354,13 +1339,17 @@ CONFIG_DEBUG_FS=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUGGER=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set # # Security options diff --git a/trunk/arch/powerpc/kernel/align.c b/trunk/arch/powerpc/kernel/align.c index 4734b5de599d..faaec9c6f78f 100644 --- a/trunk/arch/powerpc/kernel/align.c +++ b/trunk/arch/powerpc/kernel/align.c @@ -35,19 +35,17 @@ struct aligninfo { #define INVALID { 0, 0 } -/* Bits in the flags field */ -#define LD 0 /* load */ -#define ST 1 /* store */ -#define SE 2 /* sign-extend value */ -#define F 4 /* to/from fp regs */ -#define U 8 /* update index register */ -#define M 0x10 /* multiple load/store */ -#define SW 0x20 /* byte swap */ -#define S 0x40 /* single-precision fp or... */ -#define SX 0x40 /* ... byte count in XER */ +#define LD 1 /* load */ +#define ST 2 /* store */ +#define SE 4 /* sign-extend value */ +#define F 8 /* to/from fp regs */ +#define U 0x10 /* update index register */ +#define M 0x20 /* multiple load/store */ +#define SW 0x40 /* byte swap int or ... */ +#define S 0x40 /* ... single-precision fp */ +#define SX 0x40 /* byte count in XER */ #define HARD 0x80 /* string, stwcx. */ -/* DSISR bits reported for a DCBZ instruction: */ #define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ #define SWAP(a, b) (t = (a), (a) = (b), (b) = t) @@ -258,16 +256,12 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) #define REG_BYTE(rp, i) *((u8 *)(rp) + (i)) #endif -#define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) - static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, unsigned int reg, unsigned int nb, - unsigned int flags, unsigned int instr, - unsigned long swiz) + unsigned int flags, unsigned int instr) { unsigned long *rptr; - unsigned int nb0, i, bswiz; - unsigned long p; + unsigned int nb0, i; /* * We do not try to emulate 8 bytes multiple as they aren't really @@ -286,12 +280,9 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, if (nb == 0) return 1; } else { - unsigned long pc = regs->nip ^ (swiz & 4); - - if (__get_user(instr, (unsigned int __user *)pc)) + if (__get_user(instr, + (unsigned int __user *)regs->nip)) return -EFAULT; - if (swiz == 0 && (flags & SW)) - instr = cpu_to_le32(instr); nb = (instr >> 11) & 0x1f; if (nb == 0) nb = 32; @@ -309,10 +300,7 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, return -EFAULT; /* bad address */ rptr = ®s->gpr[reg]; - p = (unsigned long) addr; - bswiz = (flags & SW)? 3: 0; - - if (!(flags & ST)) { + if (flags & LD) { /* * This zeroes the top 4 bytes of the affected registers * in 64-bit mode, and also zeroes out any remaining @@ -323,28 +311,26 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, memset(®s->gpr[0], 0, ((nb0 + 3) / 4) * sizeof(unsigned long)); - for (i = 0; i < nb; ++i, ++p) - if (__get_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p))) + for (i = 0; i < nb; ++i) + if (__get_user(REG_BYTE(rptr, i), addr + i)) return -EFAULT; if (nb0 > 0) { rptr = ®s->gpr[0]; addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__get_user(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) + for (i = 0; i < nb0; ++i) + if (__get_user(REG_BYTE(rptr, i), addr + i)) return -EFAULT; } } else { - for (i = 0; i < nb; ++i, ++p) - if (__put_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p))) + for (i = 0; i < nb; ++i) + if (__put_user(REG_BYTE(rptr, i), addr + i)) return -EFAULT; if (nb0 > 0) { rptr = ®s->gpr[0]; addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__put_user(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) + for (i = 0; i < nb0; ++i) + if (__put_user(REG_BYTE(rptr, i), addr + i)) return -EFAULT; } } @@ -366,7 +352,7 @@ int fix_alignment(struct pt_regs *regs) unsigned int reg, areg; unsigned int dsisr; unsigned char __user *addr; - unsigned long p, swiz; + unsigned char __user *p; int ret, t; union { u64 ll; @@ -394,15 +380,11 @@ int fix_alignment(struct pt_regs *regs) * let's make one up from the instruction */ if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { - unsigned long pc = regs->nip; - - if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE)) - pc ^= 4; - if (unlikely(__get_user(instr, (unsigned int __user *)pc))) + unsigned int real_instr; + if (unlikely(__get_user(real_instr, + (unsigned int __user *)regs->nip))) return -EFAULT; - if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) - instr = cpu_to_le32(instr); - dsisr = make_dsisr(instr); + dsisr = make_dsisr(real_instr); } /* extract the operation and registers from the dsisr */ @@ -415,24 +397,6 @@ int fix_alignment(struct pt_regs *regs) nb = aligninfo[instr].len; flags = aligninfo[instr].flags; - /* Byteswap little endian loads and stores */ - swiz = 0; - if (regs->msr & MSR_LE) { - flags ^= SW; - /* - * So-called "PowerPC little endian" mode works by - * swizzling addresses rather than by actually doing - * any byte-swapping. To emulate this, we XOR each - * byte address with 7. We also byte-swap, because - * the processor's address swizzling depends on the - * operand size (it xors the address with 7 for bytes, - * 6 for halfwords, 4 for words, 0 for doublewords) but - * we will xor with 7 and load/store each byte separately. - */ - if (cpu_has_feature(CPU_FTR_PPC_LE)) - swiz = 7; - } - /* DAR has the operand effective address */ addr = (unsigned char __user *)regs->dar; @@ -448,8 +412,7 @@ int fix_alignment(struct pt_regs *regs) * function */ if (flags & M) - return emulate_multiple(regs, addr, reg, nb, - flags, instr, swiz); + return emulate_multiple(regs, addr, reg, nb, flags, instr); /* Verify the address of the operand */ if (unlikely(user_mode(regs) && @@ -468,71 +431,51 @@ int fix_alignment(struct pt_regs *regs) /* If we are loading, get the data from user space, else * get it from register values */ - if (!(flags & ST)) { + if (flags & LD) { data.ll = 0; ret = 0; - p = (unsigned long) addr; + p = addr; switch (nb) { case 8: - ret |= __get_user(data.v[0], SWIZ_PTR(p++)); - ret |= __get_user(data.v[1], SWIZ_PTR(p++)); - ret |= __get_user(data.v[2], SWIZ_PTR(p++)); - ret |= __get_user(data.v[3], SWIZ_PTR(p++)); + ret |= __get_user(data.v[0], p++); + ret |= __get_user(data.v[1], p++); + ret |= __get_user(data.v[2], p++); + ret |= __get_user(data.v[3], p++); case 4: - ret |= __get_user(data.v[4], SWIZ_PTR(p++)); - ret |= __get_user(data.v[5], SWIZ_PTR(p++)); + ret |= __get_user(data.v[4], p++); + ret |= __get_user(data.v[5], p++); case 2: - ret |= __get_user(data.v[6], SWIZ_PTR(p++)); - ret |= __get_user(data.v[7], SWIZ_PTR(p++)); + ret |= __get_user(data.v[6], p++); + ret |= __get_user(data.v[7], p++); if (unlikely(ret)) return -EFAULT; } - } else if (flags & F) { + } else if (flags & F) data.dd = current->thread.fpr[reg]; - if (flags & S) { - /* Single-precision FP store requires conversion... */ -#ifdef CONFIG_PPC_FPU - preempt_disable(); - enable_kernel_fp(); - cvt_df(&data.dd, (float *)&data.v[4], ¤t->thread); - preempt_enable(); -#else - return 0; -#endif - } - } else + else data.ll = regs->gpr[reg]; - if (flags & SW) { - switch (nb) { - case 8: - SWAP(data.v[0], data.v[7]); - SWAP(data.v[1], data.v[6]); - SWAP(data.v[2], data.v[5]); - SWAP(data.v[3], data.v[4]); - break; - case 4: - SWAP(data.v[4], data.v[7]); - SWAP(data.v[5], data.v[6]); - break; - case 2: - SWAP(data.v[6], data.v[7]); - break; - } - } - - /* Perform other misc operations like sign extension + /* Perform other misc operations like sign extension, byteswap, * or floating point single precision conversion */ - switch (flags & ~(U|SW)) { + switch (flags & ~U) { case LD+SE: /* sign extend */ if ( nb == 2 ) data.ll = data.x16.low16; else /* nb must be 4 */ data.ll = data.x32.low32; break; + case LD+S: /* byte-swap */ + case ST+S: + if (nb == 2) { + SWAP(data.v[6], data.v[7]); + } else { + SWAP(data.v[4], data.v[7]); + SWAP(data.v[5], data.v[6]); + } + break; - /* Single-precision FP load requires conversion... */ + /* Single-precision FP load and store require conversions... */ case LD+F+S: #ifdef CONFIG_PPC_FPU preempt_disable(); @@ -541,6 +484,16 @@ int fix_alignment(struct pt_regs *regs) preempt_enable(); #else return 0; +#endif + break; + case ST+F+S: +#ifdef CONFIG_PPC_FPU + preempt_disable(); + enable_kernel_fp(); + cvt_df(&data.dd, (float *)&data.v[4], ¤t->thread); + preempt_enable(); +#else + return 0; #endif break; } @@ -548,19 +501,19 @@ int fix_alignment(struct pt_regs *regs) /* Store result to memory or update registers */ if (flags & ST) { ret = 0; - p = (unsigned long) addr; + p = addr; switch (nb) { case 8: - ret |= __put_user(data.v[0], SWIZ_PTR(p++)); - ret |= __put_user(data.v[1], SWIZ_PTR(p++)); - ret |= __put_user(data.v[2], SWIZ_PTR(p++)); - ret |= __put_user(data.v[3], SWIZ_PTR(p++)); + ret |= __put_user(data.v[0], p++); + ret |= __put_user(data.v[1], p++); + ret |= __put_user(data.v[2], p++); + ret |= __put_user(data.v[3], p++); case 4: - ret |= __put_user(data.v[4], SWIZ_PTR(p++)); - ret |= __put_user(data.v[5], SWIZ_PTR(p++)); + ret |= __put_user(data.v[4], p++); + ret |= __put_user(data.v[5], p++); case 2: - ret |= __put_user(data.v[6], SWIZ_PTR(p++)); - ret |= __put_user(data.v[7], SWIZ_PTR(p++)); + ret |= __put_user(data.v[6], p++); + ret |= __put_user(data.v[7], p++); } if (unlikely(ret)) return -EFAULT; diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index ff2940548929..8f85c5e8a55a 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -122,8 +122,9 @@ int main(void) DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); - DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp)); - DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp)); +#ifdef CONFIG_PPC_64K_PAGES + DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir)); +#endif #ifdef CONFIG_HUGETLB_PAGE DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); diff --git a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S b/trunk/arch/powerpc/kernel/cpu_setup_6xx.S index 365381fcb27c..55ed7716636f 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_6xx.S @@ -210,11 +210,9 @@ setup_745x_specifics: * the firmware. If any, we disable NAP capability as * it's known to be bogus on rev 2.1 and earlier */ -BEGIN_FTR_SECTION mfspr r11,SPRN_L3CR andis. r11,r11,L3CR_L3E@h beq 1f -END_FTR_SECTION_IFSET(CPU_FTR_L3CR) lwz r6,CPU_SPEC_FEATURES(r5) andi. r0,r6,CPU_FTR_L3_DISABLE_NAP beq 1f diff --git a/trunk/arch/powerpc/kernel/cpu_setup_power4.S b/trunk/arch/powerpc/kernel/cpu_setup_power4.S index 271418308d53..b61d86e7ceb6 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_power4.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_power4.S @@ -73,6 +73,23 @@ _GLOBAL(__970_cpu_preinit) isync blr +_GLOBAL(__setup_cpu_power4) + blr + +_GLOBAL(__setup_cpu_be) + /* Set large page sizes LP=0: 16MB, LP=1: 64KB */ + addi r3, 0, 0 + ori r3, r3, HID6_LB + sldi r3, r3, 32 + nor r3, r3, r3 + mfspr r4, SPRN_HID6 + and r4, r4, r3 + addi r3, 0, 0x02000 + sldi r3, r3, 32 + or r4, r4, r3 + mtspr SPRN_HID6, r4 + blr + _GLOBAL(__setup_cpu_ppc970) mfspr r0,SPRN_HID0 li r11,5 /* clear DOZE and SLEEP */ diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 1c114880dc05..3f7182db9ed5 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -30,7 +30,11 @@ EXPORT_SYMBOL(cur_cpu_spec); * part of the cputable though. That has to be fixed for both ppc32 * and ppc64 */ -#ifdef CONFIG_PPC32 +#ifdef CONFIG_PPC64 +extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); +#else extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); @@ -54,8 +58,7 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); #define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) #define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\ - PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ - PPC_FEATURE_TRUE_LE) + PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ PPC_FEATURE_BOOKE) @@ -75,10 +78,11 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00400000, .cpu_name = "POWER3 (630)", .cpu_features = CPU_FTRS_POWER3, - .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/power3", .oprofile_type = PPC_OPROFILE_RS64, .platform = "power3", @@ -88,10 +92,11 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00410000, .cpu_name = "POWER3 (630+)", .cpu_features = CPU_FTRS_POWER3, - .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER_PPC64, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/power3", .oprofile_type = PPC_OPROFILE_RS64, .platform = "power3", @@ -105,6 +110,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -118,6 +124,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -131,6 +138,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -144,6 +152,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", .oprofile_type = PPC_OPROFILE_RS64, .platform = "rs64", @@ -157,6 +166,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power4", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "power4", @@ -170,6 +180,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, + .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power4", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "power4", @@ -189,11 +200,17 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, +#endif /* CONFIG_PPC64 */ +#if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) { /* PPC970FX */ .pvr_mask = 0xffff0000, .pvr_value = 0x003c0000, .cpu_name = "PPC970FX", +#ifdef CONFIG_PPC32 + .cpu_features = CPU_FTRS_970_32, +#else .cpu_features = CPU_FTRS_PPC970, +#endif .cpu_user_features = COMMON_USER_POWER4 | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, @@ -204,6 +221,8 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, +#endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ +#ifdef CONFIG_PPC64 { /* PPC970MP */ .pvr_mask = 0xffff0000, .pvr_value = 0x00440000, @@ -213,7 +232,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 128, .dcache_bsize = 128, - .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, @@ -228,13 +246,9 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power5", .oprofile_type = PPC_OPROFILE_POWER4, - /* SIHV / SIPR bits are implemented on POWER4+ (GQ) - * and above but only works on POWER5 and above - */ - .oprofile_mmcra_sihv = MMCRA_SIHV, - .oprofile_mmcra_sipr = MMCRA_SIPR, .platform = "power5", }, { /* Power5 GS */ @@ -246,10 +260,9 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power5+", .oprofile_type = PPC_OPROFILE_POWER4, - .oprofile_mmcra_sihv = MMCRA_SIHV, - .oprofile_mmcra_sipr = MMCRA_SIPR, .platform = "power5+", }, { /* Power6 */ @@ -260,13 +273,10 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER_POWER6, .icache_bsize = 128, .dcache_bsize = 128, - .num_pmcs = 8, + .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power6", .oprofile_type = PPC_OPROFILE_POWER4, - .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, - .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, - .oprofile_mmcra_clear = POWER6_MMCRA_THRM | - POWER6_MMCRA_OTHER, .platform = "power6", }, { /* Cell Broadband Engine */ @@ -279,6 +289,7 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_SMT, .icache_bsize = 128, .dcache_bsize = 128, + .cpu_setup = __setup_cpu_be, .platform = "ppc-cell-be", }, { /* default match */ @@ -290,6 +301,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, + .cpu_setup = __setup_cpu_power4, .platform = "power4", } #endif /* CONFIG_PPC64 */ @@ -311,7 +323,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00030000, .cpu_name = "603", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -322,7 +334,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00060000, .cpu_name = "603e", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -333,7 +345,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00070000, .cpu_name = "603ev", .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -344,7 +356,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00040000, .cpu_name = "604", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 2, @@ -356,7 +368,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00090000, .cpu_name = "604e", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -368,7 +380,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00090000, .cpu_name = "604r", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -380,7 +392,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000a0000, .cpu_name = "604ev", .cpu_features = CPU_FTRS_604, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -392,7 +404,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00084202, .cpu_name = "740/750", .cpu_features = CPU_FTRS_740_NOTAU, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -404,7 +416,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00080100, .cpu_name = "750CX", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -416,7 +428,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00082200, .cpu_name = "750CX", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -428,7 +440,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00082210, .cpu_name = "750CXe", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -440,7 +452,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00083214, .cpu_name = "750CXe", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -452,7 +464,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00083000, .cpu_name = "745/755", .cpu_features = CPU_FTRS_750, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -464,7 +476,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000100, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX1, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -476,7 +488,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000200, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX2, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -488,7 +500,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70000000, .cpu_name = "750FX", .cpu_features = CPU_FTRS_750FX, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -500,7 +512,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x70020000, .cpu_name = "750GX", .cpu_features = CPU_FTRS_750GX, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -512,7 +524,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x00080000, .cpu_name = "740/750", .cpu_features = CPU_FTRS_740, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -524,8 +536,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000c1101, .cpu_name = "7400 (1.1)", .cpu_features = CPU_FTRS_7400_NOTAU, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -537,8 +548,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x000c0000, .cpu_name = "7400", .cpu_features = CPU_FTRS_7400, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -550,8 +560,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x800c0000, .cpu_name = "7410", .cpu_features = CPU_FTRS_7400, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, @@ -563,8 +572,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000200, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_20, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -578,8 +586,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000201, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_21, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -593,8 +600,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80000000, .cpu_name = "7450", .cpu_features = CPU_FTRS_7450_23, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -608,8 +614,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010100, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455_1, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -623,8 +628,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010200, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455_20, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -638,8 +642,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80010000, .cpu_name = "7455", .cpu_features = CPU_FTRS_7455, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -653,8 +656,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020100, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447_10, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -668,8 +670,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020101, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447_10, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -683,7 +684,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80020000, .cpu_name = "7447/7457", .cpu_features = CPU_FTRS_7447, - .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -697,8 +698,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80030000, .cpu_name = "7447A", .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -712,8 +712,7 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x80040000, .cpu_name = "7448", .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_USER | - PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, + .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, @@ -722,18 +721,6 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_G4, .platform = "ppc7450", }, - { /* 8641 */ - .pvr_mask = 0xffffffff, - .pvr_value = 0x80040010, - .cpu_name = "8641", - .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 32, - .dcache_bsize = 32, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x - }, - { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, .pvr_value = 0x00810000, diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index e253a45dcf10..778f22fd85d2 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -175,11 +174,9 @@ static void crash_kexec_prepare_cpus(void) void default_machine_crash_shutdown(struct pt_regs *regs) { - unsigned int irq; - /* * This function is only called after the system - * has panicked or is otherwise in a critical state. + * has paniced or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * @@ -189,16 +186,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs) */ local_irq_disable(); - for_each_irq(irq) { - struct irq_desc *desc = irq_descp(irq); - - if (desc->status & IRQ_INPROGRESS) - desc->handler->end(irq); - - if (!(desc->status & IRQ_DISABLED)) - desc->handler->disable(irq); - } - if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); diff --git a/trunk/arch/powerpc/kernel/crash_dump.c b/trunk/arch/powerpc/kernel/crash_dump.c index 371973be8d71..764d07329716 100644 --- a/trunk/arch/powerpc/kernel/crash_dump.c +++ b/trunk/arch/powerpc/kernel/crash_dump.c @@ -25,11 +25,6 @@ #define DBG(fmt...) #endif -void reserve_kdump_trampoline(void) -{ - lmb_reserve(0, KDUMP_RESERVE_LIMIT); -} - static void __init create_trampoline(unsigned long addr) { /* The maximum range of a single instruction branch, is the current @@ -44,11 +39,11 @@ static void __init create_trampoline(unsigned long addr) create_branch(addr + 4, addr + PHYSICAL_START, 0); } -void __init setup_kdump_trampoline(void) +void __init kdump_setup(void) { unsigned long i; - DBG(" -> setup_kdump_trampoline()\n"); + DBG(" -> kdump_setup()\n"); for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) { create_trampoline(i); @@ -57,7 +52,7 @@ void __init setup_kdump_trampoline(void) create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START); create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START); - DBG(" <- setup_kdump_trampoline()\n"); + DBG(" <- kdump_setup()\n"); } #ifdef CONFIG_PROC_VMCORE diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 221062c960c9..19ad5c6b1818 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -57,7 +57,6 @@ system_call_common: beq- 1f ld r1,PACAKSAVE(r13) 1: std r10,0(r1) - crclr so std r11,_NIP(r1) std r12,_MSR(r1) std r0,GPR0(r1) @@ -76,6 +75,7 @@ system_call_common: std r11,GPR11(r1) std r11,GPR12(r1) std r9,GPR13(r1) + crclr so mfcr r9 mflr r10 li r11,0xc01 diff --git a/trunk/arch/powerpc/kernel/fpu.S b/trunk/arch/powerpc/kernel/fpu.S index 01f71200c603..340730fb8c91 100644 --- a/trunk/arch/powerpc/kernel/fpu.S +++ b/trunk/arch/powerpc/kernel/fpu.S @@ -72,7 +72,7 @@ _GLOBAL(load_up_fpu) std r12,_MSR(r1) #endif lfd fr0,THREAD_FPSCR(r5) - MTFSF_L(fr0) + mtfsf 0xff,fr0 REST_32FPRS(0, r5) #ifndef CONFIG_SMP subi r4,r5,THREAD @@ -127,7 +127,7 @@ _GLOBAL(giveup_fpu) _GLOBAL(cvt_fd) lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ - MTFSF_L(0) + mtfsf 0xff,0 lfs 0,0(r3) stfd 0,0(r4) mffs 0 @@ -136,7 +136,7 @@ _GLOBAL(cvt_fd) _GLOBAL(cvt_df) lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ - MTFSF_L(0) + mtfsf 0xff,0 lfd 0,0(r3) stfs 0,0(r4) mffs 0 diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index b25b25902d15..a0579e859b21 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -973,13 +973,6 @@ __secondary_start_gemini: b __secondary_start #endif /* CONFIG_GEMINI */ - .globl __secondary_start_mpc86xx -__secondary_start_mpc86xx: - mfspr r3, SPRN_PIR - stw r3, __secondary_hold_acknowledge@l(0) - mr r24, r3 /* cpu # */ - b __secondary_start - .globl __secondary_start_pmac_0 __secondary_start_pmac_0: /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ @@ -1095,12 +1088,7 @@ load_up_mmu: LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) -BEGIN_FTR_SECTION - LOAD_BAT(4,r3,r4,r5) - LOAD_BAT(5,r3,r4,r5) - LOAD_BAT(6,r3,r4,r5) - LOAD_BAT(7,r3,r4,r5) -END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) + blr /* diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 831acbdf2592..b7d140430a41 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -316,21 +316,6 @@ label##_pSeries: \ mtspr SPRN_SPRG1,r13; /* save r13 */ \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) -#define HSTD_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r20; /* save r20 */ \ - mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR0,r20; \ - mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR1,r20; \ - mfspr r20,SPRN_SPRG1; /* restore r20 */ \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) - - #define STD_EXCEPTION_ISERIES(n, label, area) \ .globl label##_iSeries; \ label##_iSeries: \ @@ -559,17 +544,8 @@ system_call_pSeries: STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable) -#ifdef CONFIG_CBE_RAS - HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error) -#endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) -#ifdef CONFIG_CBE_RAS - HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance) -#endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1700, altivec_assist) -#ifdef CONFIG_CBE_RAS - HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal) -#endif /* CONFIG_CBE_RAS */ . = 0x3000 @@ -851,11 +827,6 @@ machine_check_common: #else STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception) #endif -#ifdef CONFIG_CBE_RAS - STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception) - STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception) - STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) -#endif /* CONFIG_CBE_RAS */ /* * Here we have detected that the kernel stack pointer is bad. diff --git a/trunk/arch/powerpc/kernel/iomap.c b/trunk/arch/powerpc/kernel/iomap.c index a13a93dfc655..fd8214caedee 100644 --- a/trunk/arch/powerpc/kernel/iomap.c +++ b/trunk/arch/powerpc/kernel/iomap.c @@ -106,6 +106,8 @@ EXPORT_SYMBOL(iowrite32_rep); void __iomem *ioport_map(unsigned long port, unsigned int len) { + if (!_IO_IS_VALID(port)) + return NULL; return (void __iomem *) (port+pci_io_base); } diff --git a/trunk/arch/powerpc/kernel/iommu.c b/trunk/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..4eba60a32890 100644 --- a/trunk/arch/powerpc/kernel/iommu.c +++ b/trunk/arch/powerpc/kernel/iommu.c @@ -418,11 +418,10 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, * Build a iommu_table structure. This contains a bit map which * is used to manage allocation of the tce space. */ -struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) +struct iommu_table *iommu_init_table(struct iommu_table *tbl) { unsigned long sz; static int welcomed = 0; - struct page *page; /* Set aside 1/4 of the table for large allocations. */ tbl->it_halfpoint = tbl->it_size * 3 / 4; @@ -430,10 +429,10 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) /* number of bytes needed for the bitmap */ sz = (tbl->it_size + 7) >> 3; - page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); - if (!page) + tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz)); + if (!tbl->it_map) panic("iommu_init_table: Can't allocate %ld bytes\n", sz); - tbl->it_map = page_address(page); + memset(tbl->it_map, 0, sz); tbl->it_hint = 0; @@ -537,12 +536,11 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, * to the dma address (mapping) of the first page. */ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, - dma_addr_t *dma_handle, unsigned long mask, gfp_t flag, int node) + dma_addr_t *dma_handle, unsigned long mask, gfp_t flag) { void *ret = NULL; dma_addr_t mapping; unsigned int npages, order; - struct page *page; size = PAGE_ALIGN(size); npages = size >> PAGE_SHIFT; @@ -562,10 +560,9 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, return NULL; /* Alloc enough pages (and possibly more) */ - page = alloc_pages_node(node, flag, order); - if (!page) + ret = (void *)__get_free_pages(flag, order); + if (!ret) return NULL; - ret = page_address(page); memset(ret, 0, size); /* Set up tces to cover the allocated range */ @@ -573,9 +570,9 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, mask >> PAGE_SHIFT, order); if (mapping == DMA_ERROR_CODE) { free_pages((unsigned long)ret, order); - return NULL; - } - *dma_handle = mapping; + ret = NULL; + } else + *dma_handle = mapping; return ret; } diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 40d4c14fde8f..57d560c68897 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include @@ -380,8 +379,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) #endif /* CONFIG_PPC64 */ #ifdef CONFIG_IRQSTACKS -struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; -struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; +struct thread_info *softirq_ctx[NR_CPUS]; +struct thread_info *hardirq_ctx[NR_CPUS]; void irq_ctx_init(void) { @@ -437,30 +436,6 @@ void do_softirq(void) } EXPORT_SYMBOL(do_softirq); -#ifdef CONFIG_PCI_MSI -int pci_enable_msi(struct pci_dev * pdev) -{ - if (ppc_md.enable_msi) - return ppc_md.enable_msi(pdev); - else - return -1; -} - -void pci_disable_msi(struct pci_dev * pdev) -{ - if (ppc_md.disable_msi) - ppc_md.disable_msi(pdev); -} - -void pci_scan_msi_device(struct pci_dev *dev) {} -int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;} -void pci_disable_msix(struct pci_dev *dev) {} -void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} -void disable_msi_mode(struct pci_dev *dev, int pos, int type) {} -void pci_no_msi(void) {} - -#endif - #ifdef CONFIG_PPC64 static int __init setup_noirqdistrib(char *str) { diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..2cbde865d4f5 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -521,10 +521,10 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, current_weight = (resource >> 5 * 8) & 0xFF; - pr_debug("%s: current_entitled = %lu, current_weight = %u\n", + pr_debug("%s: current_entitled = %lu, current_weight = %lu\n", __FUNCTION__, current_entitled, current_weight); - pr_debug("%s: new_entitled = %lu, new_weight = %u\n", + pr_debug("%s: new_entitled = %lu, new_weight = %lu\n", __FUNCTION__, *new_entitled_ptr, *new_weight_ptr); retval = plpar_hcall_norets(H_SET_PPP, *new_entitled_ptr, diff --git a/trunk/arch/powerpc/kernel/machine_kexec_32.c b/trunk/arch/powerpc/kernel/machine_kexec_32.c index cbaa34196797..443606134dff 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec_32.c +++ b/trunk/arch/powerpc/kernel/machine_kexec_32.c @@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( */ void default_machine_kexec(struct kimage *image) { - extern const unsigned char relocate_new_kernel[]; - extern const unsigned int relocate_new_kernel_size; + const extern unsigned char relocate_new_kernel[]; + const extern unsigned int relocate_new_kernel_size; unsigned long page_list; unsigned long reboot_code_buffer, reboot_code_buffer_phys; relocate_new_kernel_t rnk; diff --git a/trunk/arch/powerpc/kernel/machine_kexec_64.c b/trunk/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..ee166c586642 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec_64.c +++ b/trunk/arch/powerpc/kernel/machine_kexec_64.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include /* _end */ #include @@ -336,105 +335,7 @@ static void __init export_htab_values(void) of_node_put(node); } -static struct property crashk_base_prop = { - .name = "linux,crashkernel-base", - .length = sizeof(unsigned long), - .value = (unsigned char *)&crashk_res.start, -}; - -static unsigned long crashk_size; - -static struct property crashk_size_prop = { - .name = "linux,crashkernel-size", - .length = sizeof(unsigned long), - .value = (unsigned char *)&crashk_size, -}; - -static void __init export_crashk_values(void) -{ - struct device_node *node; - struct property *prop; - - node = of_find_node_by_path("/chosen"); - if (!node) - return; - - /* There might be existing crash kernel properties, but we can't - * be sure what's in them, so remove them. */ - prop = of_find_property(node, "linux,crashkernel-base", NULL); - if (prop) - prom_remove_property(node, prop); - - prop = of_find_property(node, "linux,crashkernel-size", NULL); - if (prop) - prom_remove_property(node, prop); - - if (crashk_res.start != 0) { - prom_add_property(node, &crashk_base_prop); - crashk_size = crashk_res.end - crashk_res.start + 1; - prom_add_property(node, &crashk_size_prop); - } - - of_node_put(node); -} - void __init kexec_setup(void) { export_htab_values(); - export_crashk_values(); -} - -static int __init early_parse_crashk(char *p) -{ - unsigned long size; - - if (!p) - return 1; - - size = memparse(p, &p); - - if (*p == '@') - crashk_res.start = memparse(p + 1, &p); - else - crashk_res.start = KDUMP_KERNELBASE; - - crashk_res.end = crashk_res.start + size - 1; - - return 0; -} -early_param("crashkernel", early_parse_crashk); - -void __init reserve_crashkernel(void) -{ - unsigned long size; - - if (crashk_res.start == 0) - return; - - /* We might have got these values via the command line or the - * device tree, either way sanitise them now. */ - - size = crashk_res.end - crashk_res.start + 1; - - if (crashk_res.start != KDUMP_KERNELBASE) - printk("Crash kernel location must be 0x%x\n", - KDUMP_KERNELBASE); - - crashk_res.start = KDUMP_KERNELBASE; - size = PAGE_ALIGN(size); - crashk_res.end = crashk_res.start + size - 1; - - /* Crash kernel trumps memory limit */ - if (memory_limit && memory_limit <= crashk_res.end) { - memory_limit = crashk_res.end + 1; - printk("Adjusted memory limit for crashkernel, now 0x%lx\n", - memory_limit); - } - - lmb_reserve(crashk_res.start, size); -} - -int overlaps_crashkernel(unsigned long start, unsigned long size) -{ - return (start + size) > crashk_res.start && start <= crashk_res.end; } diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..be982023409e 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -216,7 +216,7 @@ _GLOBAL(call_setup_cpu) lwz r4,0(r4) add r4,r4,r3 lwz r5,CPU_SPEC_SETUP(r4) - cmpwi 0,r5,0 + cmpi 0,r5,0 add r5,r5,r3 beqlr mtctr r5 diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index e8883d42c43c..2778cce058e2 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -482,9 +482,7 @@ _GLOBAL(identify_cpu) sub r0,r3,r5 std r0,0(r4) ld r4,CPU_SPEC_SETUP(r3) - cmpdi 0,r4,0 add r4,r4,r5 - beqlr ld r4,0(r4) add r4,r4,r5 mtctr r4 @@ -770,6 +768,9 @@ _GLOBAL(giveup_altivec) #endif /* CONFIG_ALTIVEC */ +_GLOBAL(__setup_cpu_power3) + blr + _GLOBAL(execve) li r0,__NR_execve sc diff --git a/trunk/arch/powerpc/kernel/nvram_64.c b/trunk/arch/powerpc/kernel/nvram_64.c index 6960f090991e..ada50aa5b600 100644 --- a/trunk/arch/powerpc/kernel/nvram_64.c +++ b/trunk/arch/powerpc/kernel/nvram_64.c @@ -204,7 +204,7 @@ static void nvram_print_partitions(char * label) printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); list_for_each(p, &nvram_part->partition) { tmp_part = list_entry(p, struct nvram_partition, partition); - printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%s\n", + printk(KERN_WARNING "%d \t%02x\t%02x\t%d\t%s\n", tmp_part->index, tmp_part->header.signature, tmp_part->header.checksum, tmp_part->header.length, tmp_part->header.name); diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index b5431ccf1147..b129d2e4b759 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -1113,10 +1113,9 @@ check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga) int i; int rc = 0; -#define push_end(res, mask) do { \ - BUG_ON((mask+1) & mask); \ - res->end = (res->end + mask) | mask; \ -} while (0) +#define push_end(res, size) do { unsigned long __sz = (size) ; \ + res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \ + } while (0) list_for_each_entry(dev, &bus->devices, bus_list) { u16 class = dev->class >> 8; @@ -1654,6 +1653,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; vma->vm_pgoff = offset >> PAGE_SHIFT; + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, vma->vm_page_prot, mmap_state, write_combine); diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 247937dd8b73..4c4449be81ce 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -42,6 +42,14 @@ unsigned long pci_probe_only = 1; int pci_assign_all_buses = 0; +/* + * legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch + * devices we don't have access to. + */ +unsigned long io_page_mask; + +EXPORT_SYMBOL(io_page_mask); + #ifdef CONFIG_PPC_MULTIPLATFORM static void fixup_resource(struct resource *res, struct pci_dev *dev); static void do_bus_setup(struct pci_bus *bus); @@ -227,10 +235,8 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev) pci_setup_pci_controller(phb); phb->arch_data = dev; phb->is_dynamic = mem_init_done; - if (dev) { - PHB_SET_NODE(phb, of_node_to_nid(dev)); + if (dev) add_linux_pci_domain(dev, phb); - } return phb; } @@ -390,7 +396,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->current_state = 4; /* unknown power state */ - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + if (!strcmp(type, "pci")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; @@ -599,7 +605,7 @@ static int __init pcibios_init(void) iSeries_pcibios_init(); #endif - printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); + printk("PCI: Probing PCI hardware\n"); /* Scan all of the recorded PCI controllers. */ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { @@ -624,14 +630,14 @@ static int __init pcibios_init(void) /* Cache the location of the ISA bridge (if we have one) */ ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); if (ppc64_isabridge_dev != NULL) - printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); + printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); #ifdef CONFIG_PPC_MULTIPLATFORM /* map in PCI I/O space */ phbs_remap_io(); #endif - printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); + printk("PCI: Probing PCI hardware done\n"); return 0; } @@ -798,7 +804,7 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, + printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, prot); return __pgprot(prot); @@ -877,6 +883,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; vma->vm_pgoff = offset >> PAGE_SHIFT; + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, vma->vm_page_prot, mmap_state, write_combine); @@ -887,8 +894,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return ret; } -static ssize_t pci_show_devspec(struct device *dev, - struct device_attribute *attr, char *buf) +#ifdef CONFIG_PPC_MULTIPLATFORM +static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pdev; struct device_node *np; @@ -900,10 +907,13 @@ static ssize_t pci_show_devspec(struct device *dev, return sprintf(buf, "%s", np->full_name); } static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); +#endif /* CONFIG_PPC_MULTIPLATFORM */ void pcibios_add_platform_entries(struct pci_dev *pdev) { +#ifdef CONFIG_PPC_MULTIPLATFORM device_create_file(&pdev->dev, &dev_attr_devspec); +#endif /* CONFIG_PPC_MULTIPLATFORM */ } #ifdef CONFIG_PPC_MULTIPLATFORM @@ -1094,6 +1104,8 @@ void __init pci_setup_phb_io(struct pci_controller *hose, int primary) pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys, hose->io_base_virt); of_node_put(isa_dn); + /* Allow all IO */ + io_page_mask = -1; } } @@ -1200,7 +1212,7 @@ int remap_bus_range(struct pci_bus *bus) return 1; if (start_phys == 0) return 1; - printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); + printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); if (__ioremap_explicit(start_phys, start_virt, size, _PAGE_NO_CACHE | _PAGE_GUARDED)) return 1; @@ -1220,13 +1232,27 @@ static void phbs_remap_io(void) static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long offset; + unsigned long start, end, mask, offset; if (res->flags & IORESOURCE_IO) { offset = (unsigned long)hose->io_base_virt - pci_io_base; - res->start += offset; - res->end += offset; + start = res->start += offset; + end = res->end += offset; + + /* Need to allow IO access to pages that are in the + ISA range */ + if (start < MAX_ISA_PORT) { + if (end > MAX_ISA_PORT) + end = MAX_ISA_PORT; + + start >>= PAGE_SHIFT; + end >>= PAGE_SHIFT; + + /* get the range of pages for the map */ + mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1); + io_page_mask |= mask; + } } else if (res->flags & IORESOURCE_MEM) { res->start += hose->pci_mem_offset; res->end += hose->pci_mem_offset; @@ -1416,12 +1442,3 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, return -EOPNOTSUPP; } - -#ifdef CONFIG_NUMA -int pcibus_to_node(struct pci_bus *bus) -{ - struct pci_controller *phb = pci_bus_to_host(bus); - return phb->node; -} -EXPORT_SYMBOL(pcibus_to_node); -#endif diff --git a/trunk/arch/powerpc/kernel/pci_direct_iommu.c b/trunk/arch/powerpc/kernel/pci_direct_iommu.c index 72ce082ce738..e1a32f802c0b 100644 --- a/trunk/arch/powerpc/kernel/pci_direct_iommu.c +++ b/trunk/arch/powerpc/kernel/pci_direct_iommu.c @@ -82,17 +82,13 @@ static int pci_direct_dma_supported(struct device *dev, u64 mask) return mask < 0x100000000ull; } -static struct dma_mapping_ops pci_direct_ops = { - .alloc_coherent = pci_direct_alloc_coherent, - .free_coherent = pci_direct_free_coherent, - .map_single = pci_direct_map_single, - .unmap_single = pci_direct_unmap_single, - .map_sg = pci_direct_map_sg, - .unmap_sg = pci_direct_unmap_sg, - .dma_supported = pci_direct_dma_supported, -}; - void __init pci_direct_iommu_init(void) { - pci_dma_ops = pci_direct_ops; + pci_dma_ops.alloc_coherent = pci_direct_alloc_coherent; + pci_dma_ops.free_coherent = pci_direct_free_coherent; + pci_dma_ops.map_single = pci_direct_map_single; + pci_dma_ops.unmap_single = pci_direct_unmap_single; + pci_dma_ops.map_sg = pci_direct_map_sg; + pci_dma_ops.unmap_sg = pci_direct_unmap_sg; + pci_dma_ops.dma_supported = pci_direct_dma_supported; } diff --git a/trunk/arch/powerpc/kernel/pci_dn.c b/trunk/arch/powerpc/kernel/pci_dn.c index 1c18953514c3..12c4c9e9bbc7 100644 --- a/trunk/arch/powerpc/kernel/pci_dn.c +++ b/trunk/arch/powerpc/kernel/pci_dn.c @@ -31,7 +31,6 @@ #include #include #include -#include /* * Traverse_func that inits the PCI fields of the device node. @@ -60,11 +59,6 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) pdn->busno = (regs[0] >> 16) & 0xff; pdn->devfn = (regs[0] >> 8) & 0xff; } - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL); - if (busp) - pdn->bussubno = *busp; - } pdn->pci_ext_config_space = (type && *type == 1); return NULL; diff --git a/trunk/arch/powerpc/kernel/pci_iommu.c b/trunk/arch/powerpc/kernel/pci_iommu.c index 0688b2534acb..c1d95e14bbed 100644 --- a/trunk/arch/powerpc/kernel/pci_iommu.c +++ b/trunk/arch/powerpc/kernel/pci_iommu.c @@ -44,16 +44,16 @@ */ #define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) -static inline struct iommu_table *device_to_table(struct device *hwdev) +static inline struct iommu_table *devnode_table(struct device *dev) { struct pci_dev *pdev; - if (!hwdev) { + if (!dev) { pdev = ppc64_isabridge_dev; if (!pdev) return NULL; } else - pdev = to_pci_dev(hwdev); + pdev = to_pci_dev(dev); return PCI_DN(PCI_GET_DN(pdev))->iommu_table; } @@ -85,15 +85,14 @@ static inline unsigned long device_to_mask(struct device *hwdev) static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle, - device_to_mask(hwdev), flag, - pcibus_to_node(to_pci_dev(hwdev)->bus)); + return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle, + device_to_mask(hwdev), flag); } static void pci_iommu_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle); + iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle); } /* Creates TCEs for a user provided buffer. The user buffer must be @@ -105,7 +104,7 @@ static void pci_iommu_free_coherent(struct device *hwdev, size_t size, static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, size_t size, enum dma_data_direction direction) { - return iommu_map_single(device_to_table(hwdev), vaddr, size, + return iommu_map_single(devnode_table(hwdev), vaddr, size, device_to_mask(hwdev), direction); } @@ -113,27 +112,27 @@ static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction); + iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction); } static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { - return iommu_map_sg(pdev, device_to_table(pdev), sglist, + return iommu_map_sg(pdev, devnode_table(pdev), sglist, nelems, device_to_mask(pdev), direction); } static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { - iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction); + iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction); } /* We support DMA to/from any memory page via the iommu */ static int pci_iommu_dma_supported(struct device *dev, u64 mask) { - struct iommu_table *tbl = device_to_table(dev); + struct iommu_table *tbl = devnode_table(dev); if (!tbl || tbl->it_offset > mask) { printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n"); @@ -148,17 +147,13 @@ static int pci_iommu_dma_supported(struct device *dev, u64 mask) return 1; } -struct dma_mapping_ops pci_iommu_ops = { - .alloc_coherent = pci_iommu_alloc_coherent, - .free_coherent = pci_iommu_free_coherent, - .map_single = pci_iommu_map_single, - .unmap_single = pci_iommu_unmap_single, - .map_sg = pci_iommu_map_sg, - .unmap_sg = pci_iommu_unmap_sg, - .dma_supported = pci_iommu_dma_supported, -}; - void pci_iommu_init(void) { - pci_dma_ops = pci_iommu_ops; + pci_dma_ops.alloc_coherent = pci_iommu_alloc_coherent; + pci_dma_ops.free_coherent = pci_iommu_free_coherent; + pci_dma_ops.map_single = pci_iommu_map_single; + pci_dma_ops.unmap_single = pci_iommu_unmap_single; + pci_dma_ops.map_sg = pci_iommu_map_sg; + pci_dma_ops.unmap_sg = pci_iommu_unmap_sg; + pci_dma_ops.dma_supported = pci_iommu_dma_supported; } diff --git a/trunk/arch/powerpc/kernel/proc_ppc64.c b/trunk/arch/powerpc/kernel/proc_ppc64.c index 2ab8f2be911e..3c2cf661f6d9 100644 --- a/trunk/arch/powerpc/kernel/proc_ppc64.c +++ b/trunk/arch/powerpc/kernel/proc_ppc64.c @@ -52,7 +52,7 @@ static int __init proc_ppc64_create(void) if (!root) return 1; - if (!of_find_node_by_path("/rtas")) + if (!machine_is(pseries) && !machine_is(cell)) return 0; if (!proc_mkdir("rtas", root)) @@ -115,6 +115,8 @@ static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) { struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + vma->vm_flags |= VM_SHM | VM_LOCKED; + if ((vma->vm_end - vma->vm_start) > dp->size) return -EINVAL; diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index e4732459c485..2dd47d2dd998 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -708,61 +708,6 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) return put_user(val, (unsigned int __user *) adr); } -int set_endian(struct task_struct *tsk, unsigned int val) -{ - struct pt_regs *regs = tsk->thread.regs; - - if ((val == PR_ENDIAN_LITTLE && !cpu_has_feature(CPU_FTR_REAL_LE)) || - (val == PR_ENDIAN_PPC_LITTLE && !cpu_has_feature(CPU_FTR_PPC_LE))) - return -EINVAL; - - if (regs == NULL) - return -EINVAL; - - if (val == PR_ENDIAN_BIG) - regs->msr &= ~MSR_LE; - else if (val == PR_ENDIAN_LITTLE || val == PR_ENDIAN_PPC_LITTLE) - regs->msr |= MSR_LE; - else - return -EINVAL; - - return 0; -} - -int get_endian(struct task_struct *tsk, unsigned long adr) -{ - struct pt_regs *regs = tsk->thread.regs; - unsigned int val; - - if (!cpu_has_feature(CPU_FTR_PPC_LE) && - !cpu_has_feature(CPU_FTR_REAL_LE)) - return -EINVAL; - - if (regs == NULL) - return -EINVAL; - - if (regs->msr & MSR_LE) { - if (cpu_has_feature(CPU_FTR_REAL_LE)) - val = PR_ENDIAN_LITTLE; - else - val = PR_ENDIAN_PPC_LITTLE; - } else - val = PR_ENDIAN_BIG; - - return put_user(val, (unsigned int __user *)adr); -} - -int set_unalign_ctl(struct task_struct *tsk, unsigned int val) -{ - tsk->thread.align_ctl = val; - return 0; -} - -int get_unalign_ctl(struct task_struct *tsk, unsigned long adr) -{ - return put_user(tsk->thread.align_ctl, (unsigned int __user *)adr); -} - #define TRUNC_PTR(x) ((typeof(x))(((unsigned long)(x)) & 0xffffffff)) int sys_clone(unsigned long clone_flags, unsigned long usp, diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 483455c5bb02..9a07f97f0712 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -50,7 +50,6 @@ #include #include #include -#include #ifdef DEBUG #define DBG(fmt...) printk(KERN_ERR fmt) @@ -837,42 +836,6 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, return mem; } -static int __init early_parse_mem(char *p) -{ - if (!p) - return 1; - - memory_limit = PAGE_ALIGN(memparse(p, &p)); - DBG("memory limit = 0x%lx\n", memory_limit); - - return 0; -} -early_param("mem", early_parse_mem); - -/* - * The device tree may be allocated below our memory limit, or inside the - * crash kernel region for kdump. If so, move it out now. - */ -static void move_device_tree(void) -{ - unsigned long start, size; - void *p; - - DBG("-> move_device_tree\n"); - - start = __pa(initial_boot_params); - size = initial_boot_params->totalsize; - - if ((memory_limit && (start + size) > memory_limit) || - overlaps_crashkernel(start, size)) { - p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size)); - memcpy(p, initial_boot_params, size); - initial_boot_params = (struct boot_param_header *)p; - DBG("Moved device tree to 0x%p\n", p); - } - - DBG("<- move_device_tree\n"); -} /** * unflattens the device-tree passed by the firmware, creating the @@ -948,10 +911,7 @@ static struct ibm_pa_feature { {CPU_FTR_CTRL, 0, 0, 3, 0}, {CPU_FTR_NOEXECUTE, 0, 0, 6, 0}, {CPU_FTR_NODSISRALIGN, 0, 1, 1, 1}, -#if 0 - /* put this back once we know how to test if firmware does 64k IO */ {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, -#endif }; static void __init check_cpu_pa_features(unsigned long node) @@ -1110,7 +1070,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, iommu_force_on = 1; #endif - /* mem=x on the command line is the preferred mechanism */ lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL); if (lprop) memory_limit = *lprop; @@ -1164,6 +1123,17 @@ static int __init early_init_dt_scan_chosen(unsigned long node, DBG("Command line is: %s\n", cmd_line); + if (strstr(cmd_line, "mem=")) { + char *p, *q; + + for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { + q = p + 4; + if (p > cmd_line && p[-1] != ' ') + continue; + memory_limit = memparse(q, &q); + } + } + /* break now */ return 1; } @@ -1267,17 +1237,9 @@ static void __init early_reserve_mem(void) { u64 base, size; u64 *reserve_map; - unsigned long self_base; - unsigned long self_size; reserve_map = (u64 *)(((unsigned long)initial_boot_params) + initial_boot_params->off_mem_rsvmap); - - /* before we do anything, lets reserve the dt blob */ - self_base = __pa((unsigned long)initial_boot_params); - self_size = initial_boot_params->totalsize; - lmb_reserve(self_base, self_size); - #ifdef CONFIG_PPC32 /* * Handle the case where we might be booting from an old kexec @@ -1292,9 +1254,6 @@ static void __init early_reserve_mem(void) size_32 = *(reserve_map_32++); if (size_32 == 0) break; - /* skip if the reservation is for the blob */ - if (base_32 == self_base && size_32 == self_size) - continue; DBG("reserving: %x -> %x\n", base_32, size_32); lmb_reserve(base_32, size_32); } @@ -1306,9 +1265,6 @@ static void __init early_reserve_mem(void) size = *(reserve_map++); if (size == 0) break; - /* skip if the reservation is for the blob */ - if (base == self_base && size == self_size) - continue; DBG("reserving: %llx -> %llx\n", base, size); lmb_reserve(base, size); } @@ -1336,25 +1292,17 @@ void __init early_init_devtree(void *params) lmb_init(); of_scan_flat_dt(early_init_dt_scan_root, NULL); of_scan_flat_dt(early_init_dt_scan_memory, NULL); - - /* Save command line for /proc/cmdline and then parse parameters */ - strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); - parse_early_param(); - - /* Reserve LMB regions used by kernel, initrd, dt, etc... */ - lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); - reserve_kdump_trampoline(); - reserve_crashkernel(); - early_reserve_mem(); - lmb_enforce_memory_limit(memory_limit); lmb_analyze(); DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); - /* We may need to relocate the flat tree, do it now. - * FIXME .. and the initrd too? */ - move_device_tree(); + /* Reserve LMB regions used by kernel, initrd, dt, etc... */ + lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); +#ifdef CONFIG_CRASH_DUMP + lmb_reserve(0, KDUMP_RESERVE_LIMIT); +#endif + early_reserve_mem(); DBG("Scanning CPUs ...\n"); @@ -2105,46 +2053,29 @@ int prom_update_property(struct device_node *np, return 0; } - -/* Find the device node for a given logical cpu number, also returns the cpu - * local thread number (index in ibm,interrupt-server#s) if relevant and - * asked for (non NULL) - */ -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) +#ifdef CONFIG_KEXEC +/* We may have allocated the flat device tree inside the crash kernel region + * in prom_init. If so we need to move it out into regular memory. */ +void kdump_move_device_tree(void) { - int hardid; - struct device_node *np; + unsigned long start, end; + struct boot_param_header *new; - hardid = get_hard_smp_processor_id(cpu); + start = __pa((unsigned long)initial_boot_params); + end = start + initial_boot_params->totalsize; - for_each_node_by_type(np, "cpu") { - u32 *intserv; - unsigned int plen, t; + if (end < crashk_res.start || start > crashk_res.end) + return; - /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist - * fallback to "reg" property and assume no threads - */ - intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", - &plen); - if (intserv == NULL) { - u32 *reg = (u32 *)get_property(np, "reg", NULL); - if (reg == NULL) - continue; - if (*reg == hardid) { - if (thread) - *thread = 0; - return np; - } - } else { - plen /= sizeof(u32); - for (t = 0; t < plen; t++) { - if (hardid == intserv[t]) { - if (thread) - *thread = t; - return np; - } - } - } - } - return NULL; + new = (struct boot_param_header*) + __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE)); + + memcpy(new, initial_boot_params, initial_boot_params->totalsize); + + initial_boot_params = new; + + DBG("Flat device tree blob moved to %p\n", initial_boot_params); + + /* XXX should we unreserve the old DT? */ } +#endif /* CONFIG_KEXEC */ diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 8c28eb0cbdac..f70bd090dacd 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -194,12 +194,19 @@ static int __initdata of_platform; static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; +static unsigned long __initdata prom_memory_limit; + static unsigned long __initdata alloc_top; static unsigned long __initdata alloc_top_high; static unsigned long __initdata alloc_bottom; static unsigned long __initdata rmo_top; static unsigned long __initdata ram_top; +#ifdef CONFIG_KEXEC +static unsigned long __initdata prom_crashk_base; +static unsigned long __initdata prom_crashk_size; +#endif + static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; static int __initdata mem_reserve_cnt; @@ -567,7 +574,7 @@ static void __init early_cmdline_parse(void) if ((long)_prom->chosen > 0) l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1); #ifdef CONFIG_CMDLINE - if (l <= 0 || p[0] == '\0') /* dbl check */ + if (l == 0) /* dbl check */ strlcpy(RELOC(prom_cmd_line), RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line)); #endif /* CONFIG_CMDLINE */ @@ -586,6 +593,45 @@ static void __init early_cmdline_parse(void) RELOC(iommu_force_on) = 1; } #endif + + opt = strstr(RELOC(prom_cmd_line), RELOC("mem=")); + if (opt) { + opt += 4; + RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt); +#ifdef CONFIG_PPC64 + /* Align to 16 MB == size of ppc64 large page */ + RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); +#endif + } + +#ifdef CONFIG_KEXEC + /* + * crashkernel=size@addr specifies the location to reserve for + * crash kernel. + */ + opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); + if (opt) { + opt += 12; + RELOC(prom_crashk_size) = + prom_memparse(opt, (const char **)&opt); + + if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != + RELOC(prom_crashk_size)) { + prom_printf("Warning: crashkernel size is not " + "aligned to 16MB\n"); + } + + /* + * At present, the crash kernel always run at 32MB. + * Just ignore whatever user passed. + */ + RELOC(prom_crashk_base) = 0x2000000; + if (*opt == '@') { + prom_printf("Warning: PPC64 kdump kernel always runs " + "at 32 MB\n"); + } + } +#endif } #ifdef CONFIG_PPC_PSERIES @@ -1069,6 +1115,29 @@ static void __init prom_init_mem(void) RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end)); } + /* + * If prom_memory_limit is set we reduce the upper limits *except* for + * alloc_top_high. This must be the real top of RAM so we can put + * TCE's up there. + */ + + RELOC(alloc_top_high) = RELOC(ram_top); + + if (RELOC(prom_memory_limit)) { + if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) { + prom_printf("Ignoring mem=%x <= alloc_bottom.\n", + RELOC(prom_memory_limit)); + RELOC(prom_memory_limit) = 0; + } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) { + prom_printf("Ignoring mem=%x >= ram_top.\n", + RELOC(prom_memory_limit)); + RELOC(prom_memory_limit) = 0; + } else { + RELOC(ram_top) = RELOC(prom_memory_limit); + RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit)); + } + } + /* * Setup our top alloc point, that is top of RMO or top of * segment 0 when running non-LPAR. @@ -1081,14 +1150,20 @@ static void __init prom_init_mem(void) RELOC(rmo_top) = RELOC(ram_top); RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top)); RELOC(alloc_top) = RELOC(rmo_top); - RELOC(alloc_top_high) = RELOC(ram_top); prom_printf("memory layout at init:\n"); + prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); prom_printf(" ram_top : %x\n", RELOC(ram_top)); +#ifdef CONFIG_KEXEC + if (RELOC(prom_crashk_base)) { + prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base)); + prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size)); + } +#endif } @@ -1274,10 +1349,16 @@ static void __init prom_initialize_tce_table(void) reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom); - /* These are only really needed if there is a memory limit in - * effect, but we don't know so export them always. */ - RELOC(prom_tce_alloc_start) = local_alloc_bottom; - RELOC(prom_tce_alloc_end) = local_alloc_top; + if (RELOC(prom_memory_limit)) { + /* + * We align the start to a 16MB boundary so we can map + * the TCE area using large pages if possible. + * The end should be the top of RAM so no need to align it. + */ + RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, + 0x1000000); + RELOC(prom_tce_alloc_end) = local_alloc_top; + } /* Flag the first invalid entry */ prom_debug("ending prom_initialize_tce_table\n"); @@ -1960,7 +2041,11 @@ static void __init flatten_device_tree(void) /* Version 16 is not backward compatible */ hdr->last_comp_version = 0x10; - /* Copy the reserve map in */ + /* Reserve the whole thing and copy the reserve map in, we + * also bump mem_reserve_cnt to cause further reservations to + * fail since it's too late. + */ + reserve_mem(RELOC(dt_header_start), hdr->totalsize); memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map)); #ifdef DEBUG_PROM @@ -1973,9 +2058,6 @@ static void __init flatten_device_tree(void) RELOC(mem_reserve_map)[i].size); } #endif - /* Bump mem_reserve_cnt to cause further reservations to fail - * since it's too late. - */ RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE; prom_printf("Device tree strings 0x%x -> 0x%x\n", @@ -2198,6 +2280,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_mem(); +#ifdef CONFIG_KEXEC + if (RELOC(prom_crashk_base)) + reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size)); +#endif /* * Determine which cpu is actually running right _now_ */ @@ -2231,6 +2317,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, /* * Fill in some infos for use by the kernel later on */ + if (RELOC(prom_memory_limit)) + prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit", + &RELOC(prom_memory_limit), + sizeof(prom_memory_limit)); #ifdef CONFIG_PPC64 if (RELOC(ppc64_iommu_off)) prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", @@ -2250,6 +2340,16 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, } #endif +#ifdef CONFIG_KEXEC + if (RELOC(prom_crashk_base)) { + prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base", + PTRRELOC(&prom_crashk_base), + sizeof(RELOC(prom_crashk_base))); + prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size", + PTRRELOC(&prom_crashk_size), + sizeof(RELOC(prom_crashk_size))); + } +#endif /* * Fixup any known bugs in the device-tree */ diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c index 45df420383cc..3934c227549b 100644 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ b/trunk/arch/powerpc/kernel/prom_parse.c @@ -548,28 +548,3 @@ int of_pci_address_to_resource(struct device_node *dev, int bar, return __of_address_to_resource(dev, addrp, size, flags, r); } EXPORT_SYMBOL_GPL(of_pci_address_to_resource); - -void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, - unsigned long *busno, unsigned long *phys, unsigned long *size) -{ - u32 *dma_window, cells; - unsigned char *prop; - - dma_window = (u32 *)dma_window_prop; - - /* busno is always one cell */ - *busno = *(dma_window++); - - prop = get_property(dn, "ibm,#dma-address-cells", NULL); - if (!prop) - prop = get_property(dn, "#address-cells", NULL); - - cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn); - *phys = of_read_addr(dma_window, cells); - - dma_window += cells; - - prop = get_property(dn, "ibm,#dma-size-cells", NULL); - cells = prop ? *(u32 *)prop : prom_n_size_cells(dn); - *size = of_read_addr(dma_window, cells); -} diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index 5563e2e7d89c..4a677d1bd4ef 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -404,6 +404,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = ptrace_detach(child, data); break; +#ifdef CONFIG_PPC64 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ int i; unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; @@ -467,6 +468,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } break; } +#endif /* CONFIG_PPC64 */ #ifdef CONFIG_ALTIVEC case PTRACE_GETVRREGS: diff --git a/trunk/arch/powerpc/kernel/rtas-rtc.c b/trunk/arch/powerpc/kernel/rtas-rtc.c index 77578c093dda..34d073fb6091 100644 --- a/trunk/arch/powerpc/kernel/rtas-rtc.c +++ b/trunk/arch/powerpc/kernel/rtas-rtc.c @@ -14,20 +14,19 @@ unsigned long __init rtas_get_boot_time(void) { int ret[8]; - int error; - unsigned int wait_time; + int error, wait_time; u64 max_wait_tb; max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); - - wait_time = rtas_busy_delay_time(error); - if (wait_time) { + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { + wait_time = rtas_extended_busy_delay_time(error); /* This is boot time so we spin. */ udelay(wait_time*1000); + error = RTAS_CLOCK_BUSY; } - } while (wait_time && (get_tb() < max_wait_tb)); + } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); if (error != 0 && printk_ratelimit()) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", @@ -45,25 +44,24 @@ unsigned long __init rtas_get_boot_time(void) void rtas_get_rtc_time(struct rtc_time *rtc_tm) { int ret[8]; - int error; - unsigned int wait_time; + int error, wait_time; u64 max_wait_tb; max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); - - wait_time = rtas_busy_delay_time(error); - if (wait_time) { + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { if (in_interrupt() && printk_ratelimit()) { memset(rtc_tm, 0, sizeof(struct rtc_time)); printk(KERN_WARNING "error: reading clock" " would delay interrupt\n"); return; /* delay not allowed */ } + wait_time = rtas_extended_busy_delay_time(error); msleep(wait_time); + error = RTAS_CLOCK_BUSY; } - } while (wait_time && (get_tb() < max_wait_tb)); + } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); if (error != 0 && printk_ratelimit()) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", @@ -90,14 +88,14 @@ int rtas_set_rtc_time(struct rtc_time *tm) tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, 0); - - wait_time = rtas_busy_delay_time(error); - if (wait_time) { + if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { if (in_interrupt()) return 1; /* probably decrementer */ + wait_time = rtas_extended_busy_delay_time(error); msleep(wait_time); + error = RTAS_CLOCK_BUSY; } - } while (wait_time && (get_tb() < max_wait_tb)); + } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); if (error != 0 && printk_ratelimit()) printk(KERN_WARNING "error: setting the clock failed (%d)\n", diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 17dc79198515..0112318213ab 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -370,36 +370,24 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) return ret; } -/* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status - * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. +/* Given an RTAS status code of 990n compute the hinted delay of 10^n + * (last digit) milliseconds. For now we bound at n=5 (100 sec). */ -unsigned int rtas_busy_delay_time(int status) +unsigned int rtas_extended_busy_delay_time(int status) { - int order; - unsigned int ms = 0; - - if (status == RTAS_BUSY) { - ms = 1; - } else if (status >= 9900 && status <= 9905) { - order = status - 9900; - for (ms = 1; order > 0; order--) - ms *= 10; - } + int order = status - 9900; + unsigned long ms; - return ms; -} + if (order < 0) + order = 0; /* RTC depends on this for -2 clock busy */ + else if (order > 5) + order = 5; /* bound */ -/* For an RTAS busy status code, perform the hinted delay. */ -unsigned int rtas_busy_delay(int status) -{ - unsigned int ms; + /* Use microseconds for reasonable accuracy */ + for (ms = 1; order > 0; order--) + ms *= 10; - might_sleep(); - ms = rtas_busy_delay_time(status); - if (ms) - msleep(ms); - - return ms; + return ms; } int rtas_error_rc(int rtas_rc) @@ -450,14 +438,22 @@ int rtas_get_power_level(int powerdomain, int *level) int rtas_set_power_level(int powerdomain, int level, int *setlevel) { int token = rtas_token("set-power-level"); + unsigned int wait_time; int rc; if (token == RTAS_UNKNOWN_SERVICE) return -ENOENT; - do { + while (1) { rc = rtas_call(token, 2, 2, setlevel, powerdomain, level); - } while (rtas_busy_delay(rc)); + if (rc == RTAS_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } if (rc < 0) return rtas_error_rc(rc); @@ -467,14 +463,22 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) int rtas_get_sensor(int sensor, int index, int *state) { int token = rtas_token("get-sensor-state"); + unsigned int wait_time; int rc; if (token == RTAS_UNKNOWN_SERVICE) return -ENOENT; - do { + while (1) { rc = rtas_call(token, 2, 2, state, sensor, index); - } while (rtas_busy_delay(rc)); + if (rc == RTAS_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } if (rc < 0) return rtas_error_rc(rc); @@ -484,14 +488,23 @@ int rtas_get_sensor(int sensor, int index, int *state) int rtas_set_indicator(int indicator, int index, int new_value) { int token = rtas_token("set-indicator"); + unsigned int wait_time; int rc; if (token == RTAS_UNKNOWN_SERVICE) return -ENOENT; - do { + while (1) { rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); - } while (rtas_busy_delay(rc)); + if (rc == RTAS_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } + else + break; + } if (rc < 0) return rtas_error_rc(rc); @@ -542,11 +555,13 @@ void rtas_os_term(char *str) do { status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL, __pa(rtas_os_term_buf)); - } while (rtas_busy_delay(status)); - if (status != 0) - printk(KERN_EMERG "ibm,os-term call failed %d\n", + if (status == RTAS_BUSY) + udelay(1); + else if (status != 0) + printk(KERN_EMERG "ibm,os-term call failed %d\n", status); + } while (status == RTAS_BUSY); } static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; @@ -593,31 +608,9 @@ static void rtas_percpu_suspend_me(void *info) static int rtas_ibm_suspend_me(struct rtas_args *args) { int i; - long state; - long rc; - unsigned long dummy; struct rtas_suspend_me_data data; - /* Make sure the state is valid */ - rc = plpar_hcall(H_VASI_STATE, - ((u64)args->args[0] << 32) | args->args[1], - 0, 0, 0, - &state, &dummy, &dummy); - - if (rc) { - printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); - return rc; - } else if (state == H_VASI_ENABLED) { - args->args[args->nargs] = RTAS_NOT_SUSPENDABLE; - return 0; - } else if (state != H_VASI_SUSPENDING) { - printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n", - state); - args->args[args->nargs] = -1; - return 0; - } - data.waiting = 1; data.args = args; @@ -796,8 +789,7 @@ EXPORT_SYMBOL(rtas_token); EXPORT_SYMBOL(rtas_call); EXPORT_SYMBOL(rtas_data_buf); EXPORT_SYMBOL(rtas_data_buf_lock); -EXPORT_SYMBOL(rtas_busy_delay_time); -EXPORT_SYMBOL(rtas_busy_delay); +EXPORT_SYMBOL(rtas_extended_busy_delay_time); EXPORT_SYMBOL(rtas_get_sensor); EXPORT_SYMBOL(rtas_get_power_level); EXPORT_SYMBOL(rtas_set_power_level); diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 1442b63a75da..aaf384c3f04a 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -365,12 +365,20 @@ static int rtas_excl_release(struct inode *inode, struct file *file) static void manage_flash(struct rtas_manage_flash_t *args_buf) { + unsigned int wait_time; s32 rc; - do { + while (1) { rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1, NULL, args_buf->op); - } while (rtas_busy_delay(rc)); + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } args_buf->status = rc; } @@ -443,18 +451,27 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf, static void validate_flash(struct rtas_validate_flash_t *args_buf) { int token = rtas_token("ibm,validate-flash-image"); + unsigned int wait_time; int update_results; s32 rc; rc = 0; - do { + while(1) { spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); rc = rtas_call(token, 2, 2, &update_results, (u32) __pa(rtas_data_buf), args_buf->buf_size); memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); - } while (rtas_busy_delay(rc)); + + if (rc == RTAS_RC_BUSY) + udelay(1); + else if (rtas_is_extended_busy(rc)) { + wait_time = rtas_extended_busy_delay_time(rc); + udelay(wait_time * 1000); + } else + break; + } args_buf->status = rc; args_buf->update_results = update_results; diff --git a/trunk/arch/powerpc/kernel/rtas_pci.c b/trunk/arch/powerpc/kernel/rtas_pci.c index 6eb7e49b394a..57b539a03fa9 100644 --- a/trunk/arch/powerpc/kernel/rtas_pci.c +++ b/trunk/arch/powerpc/kernel/rtas_pci.c @@ -313,9 +313,7 @@ unsigned long __init find_and_init_phbs(void) for (node = of_get_next_child(root, NULL); node != NULL; node = of_get_next_child(root, node)) { - - if (node->type == NULL || (strcmp(node->type, "pci") != 0 && - strcmp(node->type, "pciex") != 0)) + if (node->type == NULL || strcmp(node->type, "pci") != 0) continue; phb = pcibios_alloc_controller(node); diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index bd328123af75..684ab1d49c65 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -443,7 +443,6 @@ void __init smp_setup_cpu_maps(void) } #endif /* CONFIG_SMP */ -int __initdata do_early_xmon; #ifdef CONFIG_XMON static int __init early_xmon(char *p) { @@ -457,7 +456,7 @@ static int __init early_xmon(char *p) return 0; } xmon_init(1); - do_early_xmon = 1; + debugger(NULL); return 0; } @@ -525,20 +524,3 @@ int check_legacy_ioport(unsigned long base_port) return ppc_md.check_legacy_ioport(base_port); } EXPORT_SYMBOL(check_legacy_ioport); - -static int ppc_panic_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - ppc_md.panic(ptr); /* May not return */ - return NOTIFY_DONE; -} - -static struct notifier_block ppc_panic_block = { - .notifier_call = ppc_panic_event, - .priority = INT_MIN /* may not return; must be done last */ -}; - -void __init setup_panic(void) -{ - atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block); -} diff --git a/trunk/arch/powerpc/kernel/setup.h b/trunk/arch/powerpc/kernel/setup.h index 4c67ad7fae08..2ebba755272e 100644 --- a/trunk/arch/powerpc/kernel/setup.h +++ b/trunk/arch/powerpc/kernel/setup.h @@ -2,8 +2,5 @@ #define _POWERPC_KERNEL_SETUP_H void check_for_initrd(void); -void do_init_bootmem(void); -void setup_panic(void); -extern int do_early_xmon; #endif /* _POWERPC_KERNEL_SETUP_H */ diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index 0932a62a1c96..69ac25701344 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -131,6 +131,12 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr)); + /* Check default command line */ +#ifdef CONFIG_CMDLINE + if (cmd_line[0] == 0) + strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); +#endif /* CONFIG_CMDLINE */ + probe_machine(); #ifdef CONFIG_6xx @@ -215,7 +221,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ if (ppc_md.init != NULL) { @@ -229,7 +235,7 @@ arch_initcall(ppc_init); /* Warning, IO base is not yet inited */ void __init setup_arch(char **cmdline_p) { - *cmdline_p = cmd_line; + extern void do_init_bootmem(void); /* so udelay does something sensible, assume <= 1000 bogomips */ loops_per_jiffy = 500000000 / HZ; @@ -279,16 +285,16 @@ void __init setup_arch(char **cmdline_p) /* reboot on panic */ panic_timeout = 180; - if (ppc_md.panic) - setup_panic(); - init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; init_mm.brk = klimit; - if (do_early_xmon) - debugger(NULL); + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); + *cmdline_p = cmd_line; + + parse_early_param(); /* set up the bootmem stuff with available memory */ do_init_bootmem(); diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..4467c49903b6 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -100,6 +100,12 @@ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ +static int ppc64_panic_event(struct notifier_block *, unsigned long, void *); +static struct notifier_block ppc64_panic_block = { + .notifier_call = ppc64_panic_event, + .priority = INT_MIN /* may not return; must be done last */ +}; + #ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -193,7 +199,9 @@ void __init early_setup(unsigned long dt_ptr) /* Probe the machine type */ probe_machine(); - setup_kdump_trampoline(); +#ifdef CONFIG_CRASH_DUMP + kdump_setup(); +#endif DBG("Found, Initializing memory management...\n"); @@ -345,6 +353,9 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); +#ifdef CONFIG_KEXEC + kdump_move_device_tree(); +#endif /* * Unflatten the device-tree passed by prom_init or kexec */ @@ -409,8 +420,10 @@ void __init setup_system(void) */ register_early_udbg_console(); - if (do_early_xmon) - debugger(NULL); + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); + + parse_early_param(); check_smt_enabled(); smp_setup_cpu_maps(); @@ -443,6 +456,13 @@ void __init setup_system(void) DBG(" <- setup_system()\n"); } +static int ppc64_panic_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + ppc_md.panic((char *)ptr); /* May not return */ + return NOTIFY_DONE; +} + #ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { @@ -497,6 +517,8 @@ static void __init emergency_stack_init(void) */ void __init setup_arch(char **cmdline_p) { + extern void do_init_bootmem(void); + ppc64_boot_msg(0x12, "Setup Arch"); *cmdline_p = cmd_line; @@ -513,7 +535,8 @@ void __init setup_arch(char **cmdline_p) panic_timeout = 180; if (ppc_md.panic) - setup_panic(); + atomic_notifier_chain_register(&panic_notifier_list, + &ppc64_panic_block); init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) _etext; diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index d73b25e22fca..8fdeca2d4597 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -419,7 +419,9 @@ static long restore_user_regs(struct pt_regs *regs, { long err; unsigned int save_r2 = 0; +#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) unsigned long msr; +#endif /* * restore general registers but not including MSR or SOFTE. Also @@ -428,16 +430,11 @@ static long restore_user_regs(struct pt_regs *regs, if (!sig) save_r2 = (unsigned int)regs->gpr[2]; err = restore_general_regs(regs, sr); - err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); if (!sig) regs->gpr[2] = (unsigned long) save_r2; if (err) return 1; - /* if doing signal return, restore the previous little-endian mode */ - if (sig) - regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); - /* * Do this before updating the thread state in * current->thread.fpr/vr/evr. That way, if we get preempted @@ -458,7 +455,7 @@ static long restore_user_regs(struct pt_regs *regs, /* force the process to reload the altivec registers from current->thread when it next does altivec instructions */ regs->msr &= ~MSR_VEC; - if (msr & MSR_VEC) { + if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) { /* restore altivec registers from the stack */ if (__copy_from_user(current->thread.vr, &sr->mc_vregs, sizeof(sr->mc_vregs))) @@ -475,7 +472,7 @@ static long restore_user_regs(struct pt_regs *regs, /* force the process to reload the spe registers from current->thread when it next does spe instructions */ regs->msr &= ~MSR_SPE; - if (msr & MSR_SPE) { + if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { /* restore spe registers from the stack */ if (__copy_from_user(current->thread.evr, &sr->mc_vregs, ELF_NEVRREG * sizeof(u32))) @@ -760,10 +757,10 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, /* Save user registers on the stack */ frame = &rt_sf->uc.uc_mcontext; - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) { + if (vdso32_rt_sigtramp && current->thread.vdso_base) { if (save_user_regs(regs, frame, 0)) goto badframe; - regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp; + regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; } else { if (save_user_regs(regs, frame, __NR_rt_sigreturn)) goto badframe; @@ -780,8 +777,6 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, regs->gpr[5] = (unsigned long) &rt_sf->uc; regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; - /* enter the signal handler in big-endian mode */ - regs->msr &= ~MSR_LE; regs->trap = 0; return 1; @@ -1043,10 +1038,10 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, || __put_user(sig, &sc->signal)) goto badframe; - if (vdso32_sigtramp && current->mm->context.vdso_base) { + if (vdso32_sigtramp && current->thread.vdso_base) { if (save_user_regs(regs, &frame->mctx, 0)) goto badframe; - regs->link = current->mm->context.vdso_base + vdso32_sigtramp; + regs->link = current->thread.vdso_base + vdso32_sigtramp; } else { if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) goto badframe; @@ -1061,8 +1056,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, regs->gpr[3] = sig; regs->gpr[4] = (unsigned long) sc; regs->nip = (unsigned long) ka->sa.sa_handler; - /* enter the signal handler in big-endian mode */ - regs->msr &= ~MSR_LE; regs->trap = 0; return 1; diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 6e75d7ab6d4d..c2db642f4cdd 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -141,7 +141,9 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, unsigned long err = 0; unsigned long save_r13 = 0; elf_greg_t *gregs = (elf_greg_t *)regs; +#ifdef CONFIG_ALTIVEC unsigned long msr; +#endif int i; /* If this is not a signal return, we preserve the TLS in r13 */ @@ -152,12 +154,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __copy_from_user(regs, &sc->gp_regs, PT_MSR*sizeof(unsigned long)); - /* get MSR separately, transfer the LE bit if doing signal return */ - err |= __get_user(msr, &sc->gp_regs[PT_MSR]); - if (sig) - regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); - - /* skip SOFTE */ + /* skip MSR and SOFTE */ for (i = PT_MSR+1; i <= PT_RESULT; i++) { if (i == PT_SOFTE) continue; @@ -182,6 +179,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, #ifdef CONFIG_ALTIVEC err |= __get_user(v_regs, &sc->v_regs); + err |= __get_user(msr, &sc->gp_regs[PT_MSR]); if (err) return err; if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128))) @@ -398,8 +396,8 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, current->thread.fpscr.val = 0; /* Set up to return from userspace. */ - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { - regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp; + if (vdso64_rt_sigtramp && current->thread.vdso_base) { + regs->link = current->thread.vdso_base + vdso64_rt_sigtramp; } else { err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); if (err) @@ -414,8 +412,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, /* Set up "regs" so we "return" to the signal handler. */ err |= get_user(regs->nip, &funct_desc_ptr->entry); - /* enter the signal handler in big-endian mode */ - regs->msr &= ~MSR_LE; regs->gpr[1] = newsp; err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); regs->gpr[3] = signr; diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index c5d179d4f818..530f7dba0bd2 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -492,7 +492,7 @@ int __devinit __cpu_up(unsigned int cpu) * -- Cort */ if (system_state < SYSTEM_RUNNING) - for (c = 50000; c && !cpu_callin_map[cpu]; c--) + for (c = 5000; c && !cpu_callin_map[cpu]; c--) udelay(100); #ifdef CONFIG_HOTPLUG_CPU else diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 4662b580efa1..5bc2585c8036 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -279,7 +279,7 @@ static void unregister_cpu_online(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __devinit sysfs_cpu_notify(struct notifier_block *self, +static int sysfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned int)(long)hcpu; @@ -297,19 +297,30 @@ static int __devinit sysfs_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __devinitdata sysfs_cpu_nb = { +static struct notifier_block sysfs_cpu_nb = { .notifier_call = sysfs_cpu_notify, }; /* NUMA stuff */ #ifdef CONFIG_NUMA +static struct node node_devices[MAX_NUMNODES]; + static void register_nodes(void) { int i; - for (i = 0; i < MAX_NUMNODES; i++) - register_one_node(i); + for (i = 0; i < MAX_NUMNODES; i++) { + if (node_online(i)) { + int p_node = parent_node(i); + struct node *parent = NULL; + + if (p_node != i) + parent = &node_devices[p_node]; + + register_node(&node_devices[i], i, parent); + } + } } int sysfs_add_device_to_node(struct sys_device *dev, int nid) @@ -348,13 +359,23 @@ static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); static int __init topology_init(void) { int cpu; + struct node *parent = NULL; register_nodes(); + register_cpu_notifier(&sysfs_cpu_nb); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); +#ifdef CONFIG_NUMA + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; +#endif /* * For now, we just see if the system supports making * the RTAS calls for CPU hotplug. But, there may be a @@ -366,7 +387,7 @@ static int __init topology_init(void) c->no_control = 1; if (cpu_online(cpu) || (c->no_control == 0)) { - register_cpu(c, cpu); + register_cpu(c, cpu, parent); sysdev_create_file(&c->sysdev, &attr_physical_id); } diff --git a/trunk/arch/powerpc/kernel/systbl.S b/trunk/arch/powerpc/kernel/systbl.S index ee75ccf1a802..26ed1f5ef16e 100644 --- a/trunk/arch/powerpc/kernel/systbl.S +++ b/trunk/arch/powerpc/kernel/systbl.S @@ -32,10 +32,6 @@ #define SYS32ONLY(func) .long sys_##func #define SYSX(f, f3264, f32) .long f32 #endif -#define SYSCALL_SPU(func) SYSCALL(func) -#define COMPAT_SYS_SPU(func) COMPAT_SYS(func) -#define PPC_SYS_SPU(func) PPC_SYS(func) -#define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) #ifdef CONFIG_PPC64 #define sys_sigpending sys_ni_syscall @@ -43,4 +39,309 @@ #endif _GLOBAL(sys_call_table) -#include +SYSCALL(restart_syscall) +SYSCALL(exit) +PPC_SYS(fork) +SYSCALL(read) +SYSCALL(write) +COMPAT_SYS(open) +SYSCALL(close) +COMPAT_SYS(waitpid) +COMPAT_SYS(creat) +SYSCALL(link) +SYSCALL(unlink) +COMPAT_SYS(execve) +SYSCALL(chdir) +COMPAT_SYS(time) +SYSCALL(mknod) +SYSCALL(chmod) +SYSCALL(lchown) +SYSCALL(ni_syscall) +OLDSYS(stat) +SYSX(sys_lseek,ppc32_lseek,sys_lseek) +SYSCALL(getpid) +COMPAT_SYS(mount) +SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount) +SYSCALL(setuid) +SYSCALL(getuid) +COMPAT_SYS(stime) +COMPAT_SYS(ptrace) +SYSCALL(alarm) +OLDSYS(fstat) +COMPAT_SYS(pause) +COMPAT_SYS(utime) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +COMPAT_SYS(access) +COMPAT_SYS(nice) +SYSCALL(ni_syscall) +SYSCALL(sync) +COMPAT_SYS(kill) +SYSCALL(rename) +COMPAT_SYS(mkdir) +SYSCALL(rmdir) +SYSCALL(dup) +SYSCALL(pipe) +COMPAT_SYS(times) +SYSCALL(ni_syscall) +SYSCALL(brk) +SYSCALL(setgid) +SYSCALL(getgid) +SYSCALL(signal) +SYSCALL(geteuid) +SYSCALL(getegid) +SYSCALL(acct) +SYSCALL(umount) +SYSCALL(ni_syscall) +COMPAT_SYS(ioctl) +COMPAT_SYS(fcntl) +SYSCALL(ni_syscall) +COMPAT_SYS(setpgid) +SYSCALL(ni_syscall) +SYSX(sys_ni_syscall,sys_olduname, sys_olduname) +COMPAT_SYS(umask) +SYSCALL(chroot) +SYSCALL(ustat) +SYSCALL(dup2) +SYSCALL(getppid) +SYSCALL(getpgrp) +SYSCALL(setsid) +SYS32ONLY(sigaction) +SYSCALL(sgetmask) +COMPAT_SYS(ssetmask) +SYSCALL(setreuid) +SYSCALL(setregid) +SYS32ONLY(sigsuspend) +COMPAT_SYS(sigpending) +COMPAT_SYS(sethostname) +COMPAT_SYS(setrlimit) +COMPAT_SYS(old_getrlimit) +COMPAT_SYS(getrusage) +COMPAT_SYS(gettimeofday) +COMPAT_SYS(settimeofday) +COMPAT_SYS(getgroups) +COMPAT_SYS(setgroups) +SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select) +SYSCALL(symlink) +OLDSYS(lstat) +COMPAT_SYS(readlink) +SYSCALL(uselib) +SYSCALL(swapon) +SYSCALL(reboot) +SYSX(sys_ni_syscall,old32_readdir,old_readdir) +SYSCALL(mmap) +SYSCALL(munmap) +SYSCALL(truncate) +SYSCALL(ftruncate) +SYSCALL(fchmod) +SYSCALL(fchown) +COMPAT_SYS(getpriority) +COMPAT_SYS(setpriority) +SYSCALL(ni_syscall) +COMPAT_SYS(statfs) +COMPAT_SYS(fstatfs) +SYSCALL(ni_syscall) +COMPAT_SYS(socketcall) +COMPAT_SYS(syslog) +COMPAT_SYS(setitimer) +COMPAT_SYS(getitimer) +COMPAT_SYS(newstat) +COMPAT_SYS(newlstat) +COMPAT_SYS(newfstat) +SYSX(sys_ni_syscall,sys_uname,sys_uname) +SYSCALL(ni_syscall) +SYSCALL(vhangup) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +COMPAT_SYS(wait4) +SYSCALL(swapoff) +COMPAT_SYS(sysinfo) +COMPAT_SYS(ipc) +SYSCALL(fsync) +SYS32ONLY(sigreturn) +PPC_SYS(clone) +COMPAT_SYS(setdomainname) +PPC_SYS(newuname) +SYSCALL(ni_syscall) +COMPAT_SYS(adjtimex) +SYSCALL(mprotect) +SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask) +SYSCALL(ni_syscall) +SYSCALL(init_module) +SYSCALL(delete_module) +SYSCALL(ni_syscall) +SYSCALL(quotactl) +COMPAT_SYS(getpgid) +SYSCALL(fchdir) +SYSCALL(bdflush) +COMPAT_SYS(sysfs) +SYSX(ppc64_personality,ppc64_personality,sys_personality) +SYSCALL(ni_syscall) +SYSCALL(setfsuid) +SYSCALL(setfsgid) +SYSCALL(llseek) +COMPAT_SYS(getdents) +SYSX(sys_select,ppc32_select,ppc_select) +SYSCALL(flock) +SYSCALL(msync) +COMPAT_SYS(readv) +COMPAT_SYS(writev) +COMPAT_SYS(getsid) +SYSCALL(fdatasync) +COMPAT_SYS(sysctl) +SYSCALL(mlock) +SYSCALL(munlock) +SYSCALL(mlockall) +SYSCALL(munlockall) +COMPAT_SYS(sched_setparam) +COMPAT_SYS(sched_getparam) +COMPAT_SYS(sched_setscheduler) +COMPAT_SYS(sched_getscheduler) +SYSCALL(sched_yield) +COMPAT_SYS(sched_get_priority_max) +COMPAT_SYS(sched_get_priority_min) +COMPAT_SYS(sched_rr_get_interval) +COMPAT_SYS(nanosleep) +SYSCALL(mremap) +SYSCALL(setresuid) +SYSCALL(getresuid) +SYSCALL(ni_syscall) +SYSCALL(poll) +COMPAT_SYS(nfsservctl) +SYSCALL(setresgid) +SYSCALL(getresgid) +COMPAT_SYS(prctl) +COMPAT_SYS(rt_sigreturn) +COMPAT_SYS(rt_sigaction) +COMPAT_SYS(rt_sigprocmask) +COMPAT_SYS(rt_sigpending) +COMPAT_SYS(rt_sigtimedwait) +COMPAT_SYS(rt_sigqueueinfo) +COMPAT_SYS(rt_sigsuspend) +COMPAT_SYS(pread64) +COMPAT_SYS(pwrite64) +SYSCALL(chown) +SYSCALL(getcwd) +SYSCALL(capget) +SYSCALL(capset) +COMPAT_SYS(sigaltstack) +SYSX(sys_sendfile64,compat_sys_sendfile,sys_sendfile) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +PPC_SYS(vfork) +COMPAT_SYS(getrlimit) +COMPAT_SYS(readahead) +SYS32ONLY(mmap2) +SYS32ONLY(truncate64) +SYS32ONLY(ftruncate64) +SYSX(sys_ni_syscall,sys_stat64,sys_stat64) +SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64) +SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64) +SYSCALL(pciconfig_read) +SYSCALL(pciconfig_write) +SYSCALL(pciconfig_iobase) +SYSCALL(ni_syscall) +SYSCALL(getdents64) +SYSCALL(pivot_root) +SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64) +SYSCALL(madvise) +SYSCALL(mincore) +SYSCALL(gettid) +SYSCALL(tkill) +SYSCALL(setxattr) +SYSCALL(lsetxattr) +SYSCALL(fsetxattr) +SYSCALL(getxattr) +SYSCALL(lgetxattr) +SYSCALL(fgetxattr) +SYSCALL(listxattr) +SYSCALL(llistxattr) +SYSCALL(flistxattr) +SYSCALL(removexattr) +SYSCALL(lremovexattr) +SYSCALL(fremovexattr) +COMPAT_SYS(futex) +COMPAT_SYS(sched_setaffinity) +COMPAT_SYS(sched_getaffinity) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +SYS32ONLY(sendfile64) +COMPAT_SYS(io_setup) +SYSCALL(io_destroy) +COMPAT_SYS(io_getevents) +COMPAT_SYS(io_submit) +SYSCALL(io_cancel) +SYSCALL(set_tid_address) +SYSX(sys_fadvise64,ppc32_fadvise64,sys_fadvise64) +SYSCALL(exit_group) +SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie) +SYSCALL(epoll_create) +SYSCALL(epoll_ctl) +SYSCALL(epoll_wait) +SYSCALL(remap_file_pages) +SYSX(sys_timer_create,compat_sys_timer_create,sys_timer_create) +COMPAT_SYS(timer_settime) +COMPAT_SYS(timer_gettime) +SYSCALL(timer_getoverrun) +SYSCALL(timer_delete) +COMPAT_SYS(clock_settime) +COMPAT_SYS(clock_gettime) +COMPAT_SYS(clock_getres) +COMPAT_SYS(clock_nanosleep) +SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) +COMPAT_SYS(tgkill) +COMPAT_SYS(utimes) +COMPAT_SYS(statfs64) +COMPAT_SYS(fstatfs64) +SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) +PPC_SYS(rtas) +OLDSYS(debug_setcontext) +SYSCALL(ni_syscall) +SYSCALL(ni_syscall) +COMPAT_SYS(mbind) +COMPAT_SYS(get_mempolicy) +COMPAT_SYS(set_mempolicy) +COMPAT_SYS(mq_open) +SYSCALL(mq_unlink) +COMPAT_SYS(mq_timedsend) +COMPAT_SYS(mq_timedreceive) +COMPAT_SYS(mq_notify) +COMPAT_SYS(mq_getsetattr) +COMPAT_SYS(kexec_load) +COMPAT_SYS(add_key) +COMPAT_SYS(request_key) +COMPAT_SYS(keyctl) +COMPAT_SYS(waitid) +COMPAT_SYS(ioprio_set) +COMPAT_SYS(ioprio_get) +SYSCALL(inotify_init) +SYSCALL(inotify_add_watch) +SYSCALL(inotify_rm_watch) +SYSCALL(spu_run) +SYSCALL(spu_create) +COMPAT_SYS(pselect6) +COMPAT_SYS(ppoll) +SYSCALL(unshare) +SYSCALL(splice) +SYSCALL(tee) +SYSCALL(vmsplice) +COMPAT_SYS(openat) +SYSCALL(mkdirat) +SYSCALL(mknodat) +SYSCALL(fchownat) +COMPAT_SYS(futimesat) +SYSX(sys_newfstatat, sys_fstatat64, sys_fstatat64) +SYSCALL(unlinkat) +SYSCALL(renameat) +SYSCALL(linkat) +SYSCALL(symlinkat) +SYSCALL(readlinkat) +SYSCALL(fchmodat) +SYSCALL(faccessat) +COMPAT_SYS(get_robust_list) +COMPAT_SYS(set_robust_list) + +/* + * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c + * as well when appropriate. + */ diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 7dd5dab789a1..24e3ad756de0 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -76,6 +76,7 @@ /* keep track of when we need to update the rtc */ time_t last_rtc_update; +extern int piranha_simulator; #ifdef CONFIG_PPC_ISERIES unsigned long iSeries_recal_titan = 0; unsigned long iSeries_recal_tb = 0; @@ -102,7 +103,7 @@ EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ u64 tb_to_xs; unsigned tb_to_us; -#define TICKLEN_SCALE TICK_LENGTH_SHIFT +#define TICKLEN_SCALE (SHIFT_SCALE - 10) u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ u64 ticklen_to_xs; /* 0.64 fraction */ @@ -857,50 +858,42 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); -static int __init get_freq(char *name, int cells, unsigned long *val) +void __init generic_calibrate_decr(void) { struct device_node *cpu; unsigned int *fp; - int found = 0; + int node_found; - /* The cpu node should have timebase and clock frequency properties */ + /* + * The cpu node should have a timebase-frequency property + * to tell us the rate at which the decrementer counts. + */ cpu = of_find_node_by_type(NULL, "cpu"); + ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */ + node_found = 0; if (cpu) { - fp = (unsigned int *)get_property(cpu, name, NULL); + fp = (unsigned int *)get_property(cpu, "timebase-frequency", + NULL); if (fp) { - found = 1; - *val = 0; - while (cells--) - *val = (*val << 32) | *fp++; + node_found = 1; + ppc_tb_freq = *fp; } - - of_node_put(cpu); } - - return found; -} - -void __init generic_calibrate_decr(void) -{ - ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */ - - if (!get_freq("ibm,extended-timebase-frequency", 2, &ppc_tb_freq) && - !get_freq("timebase-frequency", 1, &ppc_tb_freq)) { - + if (!node_found) printk(KERN_ERR "WARNING: Estimating decrementer frequency " "(not found)\n"); - } - ppc_proc_freq = DEFAULT_PROC_FREQ; /* hardcoded default */ - - if (!get_freq("ibm,extended-clock-frequency", 2, &ppc_proc_freq) && - !get_freq("clock-frequency", 1, &ppc_proc_freq)) { - - printk(KERN_ERR "WARNING: Estimating processor frequency " - "(not found)\n"); + ppc_proc_freq = DEFAULT_PROC_FREQ; + node_found = 0; + if (cpu) { + fp = (unsigned int *)get_property(cpu, "clock-frequency", + NULL); + if (fp) { + node_found = 1; + ppc_proc_freq = *fp; + } } - #ifdef CONFIG_BOOKE /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); @@ -912,6 +905,11 @@ void __init generic_calibrate_decr(void) /* Enable decrementer interrupt */ mtspr(SPRN_TCR, TCR_DIE); #endif + if (!node_found) + printk(KERN_ERR "WARNING: Estimating processor frequency " + "(not found)\n"); + + of_node_put(cpu); } unsigned long get_boot_time(void) @@ -947,9 +945,9 @@ void __init time_init(void) } else { /* Normal PowerPC with timebase register */ ppc_md.calibrate_decr(); - printk(KERN_DEBUG "time_init: decrementer frequency = %lu.%.6lu MHz\n", + printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n", ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); - printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", + printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n", ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); tb_last_stamp = tb_last_jiffy = get_tb(); } @@ -1012,7 +1010,10 @@ void __init time_init(void) tb_to_ns_scale = scale; tb_to_ns_shift = shift; - tm = get_boot_time(); +#ifdef CONFIG_PPC_ISERIES + if (!piranha_simulator) +#endif + tm = get_boot_time(); write_seqlock_irqsave(&xtime_lock, flags); diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 52f5659534f4..064a52564692 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -106,18 +105,10 @@ int die(const char *str, struct pt_regs *regs, long err) spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - if (machine_is(powermac) && pmac_backlight) { - struct backlight_properties *props; - - down(&pmac_backlight->sem); - props = pmac_backlight->props; - props->brightness = props->max_brightness; - props->power = FB_BLANK_UNBLANK; - props->update_status(pmac_backlight); - up(&pmac_backlight->sem); + if (machine_is(powermac)) { + set_backlight_enable(1); + set_backlight_level(BACKLIGHT_MAX); } - mutex_unlock(&pmac_backlight_mutex); #endif printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT @@ -667,7 +658,7 @@ static int emulate_instruction(struct pt_regs *regs) u32 instword; u32 rd; - if (!user_mode(regs) || (regs->msr & MSR_LE)) + if (!user_mode(regs)) return -EINVAL; CHECK_FULL_REGS(regs); @@ -814,11 +805,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs) { - int fixed = 0; + int fixed; - /* we don't implement logging of alignment exceptions */ - if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) - fixed = fix_alignment(regs); + fixed = fix_alignment(regs); if (fixed == 1) { regs->nip += 4; /* skip over emulated instruction */ diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..3774e80094f5 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -142,14 +141,12 @@ static int early_console_initialized; void __init disable_early_printk(void) { +#if 1 if (!early_console_initialized) return; - if (strstr(saved_command_line, "udbg-immortal")) { - printk(KERN_INFO "early console immortal !\n"); - return; - } unregister_console(&udbg_console); early_console_initialized = 0; +#endif } /* called by setup_system */ diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index bc3e15be3087..573afb68d69e 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -223,7 +223,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, struct vm_area_struct *vma; unsigned long vdso_pages; unsigned long vdso_base; - int rc; #ifdef CONFIG_PPC64 if (test_thread_flag(TIF_32BIT)) { @@ -238,13 +237,20 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, vdso_base = VDSO32_MBASE; #endif - current->mm->context.vdso_base = 0; + current->thread.vdso_base = 0; /* vDSO has a problem and was disabled, just don't "enable" it for the * process */ if (vdso_pages == 0) return 0; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + if (vma == NULL) + return -ENOMEM; + + memset(vma, 0, sizeof(*vma)); + /* Add a page to the vdso size for the data page */ vdso_pages ++; @@ -253,23 +259,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, * at vdso_base which is the "natural" base for it, but we might fail * and end up putting it elsewhere. */ - down_write(&mm->mmap_sem); vdso_base = get_unmapped_area(NULL, vdso_base, vdso_pages << PAGE_SHIFT, 0, 0); - if (IS_ERR_VALUE(vdso_base)) { - rc = vdso_base; - goto fail_mmapsem; + if (vdso_base & ~PAGE_MASK) { + kmem_cache_free(vm_area_cachep, vma); + return (int)vdso_base; } + current->thread.vdso_base = vdso_base; - /* Allocate a VMA structure and fill it up */ - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); - if (vma == NULL) { - rc = -ENOMEM; - goto fail_mmapsem; - } vma->vm_mm = mm; - vma->vm_start = vdso_base; + vma->vm_start = current->thread.vdso_base; vma->vm_end = vma->vm_start + (vdso_pages << PAGE_SHIFT); /* @@ -282,38 +282,23 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, * It's fine to use that for setting breakpoints in the vDSO code * pages though */ - vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC; + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; vma->vm_ops = &vdso_vmops; - /* Insert new VMA */ - rc = insert_vm_struct(mm, vma); - if (rc) - goto fail_vma; - - /* Put vDSO base into mm struct and account for memory usage */ - current->mm->context.vdso_base = vdso_base; + down_write(&mm->mmap_sem); + if (insert_vm_struct(mm, vma)) { + up_write(&mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return -ENOMEM; + } mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; up_write(&mm->mmap_sem); - return 0; - fail_vma: - kmem_cache_free(vm_area_cachep, vma); - fail_mmapsem: - up_write(&mm->mmap_sem); - return rc; -} - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base) - return "[vdso]"; - return NULL; + return 0; } - - static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname, unsigned long *size) { diff --git a/trunk/arch/powerpc/kernel/vector.S b/trunk/arch/powerpc/kernel/vector.S index 9416b4ab92ec..66b3d03c5fa5 100644 --- a/trunk/arch/powerpc/kernel/vector.S +++ b/trunk/arch/powerpc/kernel/vector.S @@ -53,12 +53,12 @@ fpenable: stfd fr31,8(r1) LDCONST(fr1, fpzero) mffs fr31 - MTFSF_L(fr1) + mtfsf 0xff,fr1 blr fpdisable: mtlr r12 - MTFSF_L(fr31) + mtfsf 0xff,fr31 lfd fr31,8(r1) lfd fr1,16(r1) lfd fr0,24(r1) diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index cdf5867838a6..971020cf3f7d 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -13,116 +13,27 @@ * 2 of the License, or (at your option) any later version. */ -#include -#include #include #include #include #include #include -#include - #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct subsystem devices_subsys; /* needed for vio_find_name() */ - -static struct vio_dev vio_bus_device = { /* fake "parent" device */ + +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *, const struct vio_dev *); + +struct vio_dev vio_bus_device = { /* fake "parent" device */ .name = vio_bus_device.dev.bus_id, .type = "", .dev.bus_id = "vio", .dev.bus = &vio_bus_type, }; -#ifdef CONFIG_PPC_ISERIES -struct device *iSeries_vio_dev = &vio_bus_device.dev; -EXPORT_SYMBOL(iSeries_vio_dev); - -static struct iommu_table veth_iommu_table; -static struct iommu_table vio_iommu_table; - -static void __init iommu_vio_init(void) -{ - iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); - veth_iommu_table.it_size /= 2; - vio_iommu_table = veth_iommu_table; - vio_iommu_table.it_offset += veth_iommu_table.it_size; - - if (!iommu_init_table(&veth_iommu_table, -1)) - printk("Virtual Bus VETH TCE table failed.\n"); - if (!iommu_init_table(&vio_iommu_table, -1)) - printk("Virtual Bus VIO TCE table failed.\n"); -} -#endif - -static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) -{ -#ifdef CONFIG_PPC_ISERIES - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - if (strcmp(dev->type, "network") == 0) - return &veth_iommu_table; - return &vio_iommu_table; - } else -#endif - { - unsigned char *dma_window; - struct iommu_table *tbl; - unsigned long offset, size; - - dma_window = get_property(dev->dev.platform_data, - "ibm,my-dma-window", NULL); - if (!dma_window) - return NULL; - - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); - - of_parse_dma_window(dev->dev.platform_data, dma_window, - &tbl->it_index, &offset, &size); - - /* TCE table size - measured in tce entries */ - tbl->it_size = size >> PAGE_SHIFT; - /* offset for VIO should always be 0 */ - tbl->it_offset = offset >> PAGE_SHIFT; - tbl->it_busno = 0; - tbl->it_type = TCE_VB; - - return iommu_init_table(tbl, -1); - } -} - -/** - * vio_match_device: - Tell if a VIO device has a matching - * VIO device id structure. - * @ids: array of VIO device id structures to search in - * @dev: the VIO device structure to match against - * - * Used by a driver to check whether a VIO device present in the - * system is in its list of supported devices. Returns the matching - * vio_device_id structure or NULL if there is no match. - */ -static const struct vio_device_id *vio_match_device( - const struct vio_device_id *ids, const struct vio_dev *dev) -{ - while (ids->type[0] != '\0') { - if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && - device_is_compatible(dev->dev.platform_data, ids->compat)) - return ids; - ids++; - } - return NULL; -} +static struct vio_bus_ops vio_bus_ops; /* * Convert from struct device to struct vio_dev and pass to driver. @@ -195,110 +106,35 @@ void vio_unregister_driver(struct vio_driver *viodrv) } EXPORT_SYMBOL(vio_unregister_driver); -/* vio_dev refcount hit 0 */ -static void __devinit vio_dev_release(struct device *dev) -{ - if (dev->platform_data) { - /* XXX free TCE table */ - of_node_put(dev->platform_data); - } - kfree(to_vio_dev(dev)); -} - /** - * vio_register_device_node: - Register a new vio device. - * @of_node: The OF node for this device. + * vio_match_device: - Tell if a VIO device has a matching + * VIO device id structure. + * @ids: array of VIO device id structures to search in + * @dev: the VIO device structure to match against * - * Creates and initializes a vio_dev structure from the data in - * of_node (dev.platform_data) and adds it to the list of virtual devices. - * Returns a pointer to the created vio_dev or NULL if node has - * NULL device_type or compatible fields. + * Used by a driver to check whether a VIO device present in the + * system is in its list of supported devices. Returns the matching + * vio_device_id structure or NULL if there is no match. */ -struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *ids, const struct vio_dev *dev) { - struct vio_dev *viodev; - unsigned int *unit_address; - unsigned int *irq_p; - - /* we need the 'device_type' property, in order to match with drivers */ - if (of_node->type == NULL) { - printk(KERN_WARNING "%s: node %s missing 'device_type'\n", - __FUNCTION__, - of_node->name ? of_node->name : ""); - return NULL; - } - - unit_address = (unsigned int *)get_property(of_node, "reg", NULL); - if (unit_address == NULL) { - printk(KERN_WARNING "%s: node %s missing 'reg'\n", - __FUNCTION__, - of_node->name ? of_node->name : ""); - return NULL; - } - - /* allocate a vio_dev for this node */ - viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); - if (viodev == NULL) - return NULL; - - viodev->dev.platform_data = of_node_get(of_node); - - viodev->irq = NO_IRQ; - irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL); - if (irq_p) { - int virq = virt_irq_create_mapping(*irq_p); - if (virq == NO_IRQ) { - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", of_node->full_name); - } else - viodev->irq = irq_offset_up(virq); - } - - snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); - viodev->name = of_node->name; - viodev->type = of_node->type; - viodev->unit_address = *unit_address; - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - unit_address = (unsigned int *)get_property(of_node, - "linux,unit_address", NULL); - if (unit_address != NULL) - viodev->unit_address = *unit_address; - } - viodev->iommu_table = vio_build_iommu_table(viodev); - - /* init generic 'struct device' fields: */ - viodev->dev.parent = &vio_bus_device.dev; - viodev->dev.bus = &vio_bus_type; - viodev->dev.release = vio_dev_release; - - /* register with generic device framework */ - if (device_register(&viodev->dev)) { - printk(KERN_ERR "%s: failed to register device %s\n", - __FUNCTION__, viodev->dev.bus_id); - /* XXX free TCE table */ - kfree(viodev); - return NULL; + while (ids->type[0] != '\0') { + if (vio_bus_ops.match(ids, dev)) + return ids; + ids++; } - - return viodev; + return NULL; } -EXPORT_SYMBOL(vio_register_device_node); /** * vio_bus_init: - Initialize the virtual IO bus */ -static int __init vio_bus_init(void) +int __init vio_bus_init(struct vio_bus_ops *ops) { int err; - struct device_node *node_vroot; -#ifdef CONFIG_PPC_ISERIES - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - iommu_vio_init(); - vio_bus_device.iommu_table = &vio_iommu_table; - iSeries_vio_dev = &vio_bus_device.dev; - } -#endif + vio_bus_ops = *ops; err = bus_register(&vio_bus_type); if (err) { @@ -317,48 +153,47 @@ static int __init vio_bus_init(void) return err; } - node_vroot = find_devices("vdevice"); - if (node_vroot) { - struct device_node *of_node; - - /* - * Create struct vio_devices for each virtual device in - * the device tree. Drivers will associate with them later. - */ - for (of_node = node_vroot->child; of_node != NULL; - of_node = of_node->sibling) { - printk(KERN_DEBUG "%s: processing %p\n", - __FUNCTION__, of_node); - vio_register_device_node(of_node); - } - } - return 0; } -__initcall(vio_bus_init); -static ssize_t name_show(struct device *dev, +/* vio_dev refcount hit 0 */ +static void __devinit vio_dev_release(struct device *dev) +{ + if (vio_bus_ops.release_device) + vio_bus_ops.release_device(dev); + kfree(to_vio_dev(dev)); +} + +static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", to_vio_dev(dev)->name); } +DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL); -static ssize_t devspec_show(struct device *dev, - struct device_attribute *attr, char *buf) +struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev) { - struct device_node *of_node = dev->platform_data; + /* init generic 'struct device' fields: */ + viodev->dev.parent = &vio_bus_device.dev; + viodev->dev.bus = &vio_bus_type; + viodev->dev.release = vio_dev_release; - return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); -} + /* register with generic device framework */ + if (device_register(&viodev->dev)) { + printk(KERN_ERR "%s: failed to register device %s\n", + __FUNCTION__, viodev->dev.bus_id); + return NULL; + } + device_create_file(&viodev->dev, &dev_attr_name); -static struct device_attribute vio_dev_attrs[] = { - __ATTR_RO(name), - __ATTR_RO(devspec), - __ATTR_NULL -}; + return viodev; +} void __devinit vio_unregister_device(struct vio_dev *viodev) { + if (vio_bus_ops.unregister_device) + vio_bus_ops.unregister_device(viodev); + device_remove_file(&viodev->dev, &dev_attr_name); device_unregister(&viodev->dev); } EXPORT_SYMBOL(vio_unregister_device); @@ -394,7 +229,7 @@ static void *vio_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, - dma_handle, ~0ul, flag, -1); + dma_handle, ~0ul, flag); } static void vio_free_coherent(struct device *dev, size_t size, @@ -432,23 +267,22 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { const struct vio_dev *vio_dev = to_vio_dev(dev); - struct device_node *dn = dev->platform_data; char *cp; int length; if (!num_envp) return -ENOMEM; - if (!dn) + if (!vio_dev->dev.platform_data) return -ENODEV; - cp = (char *)get_property(dn, "compatible", &length); + cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length); if (!cp) return -ENODEV; envp[0] = buffer; length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s", vio_dev->type, cp); - if ((buffer_size - length) <= 0) + if (buffer_size - length <= 0) return -ENOMEM; envp[1] = NULL; return 0; @@ -456,81 +290,9 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, struct bus_type vio_bus_type = { .name = "vio", - .dev_attrs = vio_dev_attrs, .uevent = vio_hotplug, .match = vio_bus_match, .probe = vio_bus_probe, .remove = vio_bus_remove, .shutdown = vio_bus_shutdown, }; - -/** - * vio_get_attribute: - get attribute for virtual device - * @vdev: The vio device to get property. - * @which: The property/attribute to be extracted. - * @length: Pointer to length of returned data size (unused if NULL). - * - * Calls prom.c's get_property() to return the value of the - * attribute specified by @which -*/ -const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) -{ - return get_property(vdev->dev.platform_data, which, length); -} -EXPORT_SYMBOL(vio_get_attribute); - -#ifdef CONFIG_PPC_PSERIES -/* vio_find_name() - internal because only vio.c knows how we formatted the - * kobject name - * XXX once vio_bus_type.devices is actually used as a kset in - * drivers/base/bus.c, this function should be removed in favor of - * "device_find(kobj_name, &vio_bus_type)" - */ -static struct vio_dev *vio_find_name(const char *kobj_name) -{ - struct kobject *found; - - found = kset_find_obj(&devices_subsys.kset, kobj_name); - if (!found) - return NULL; - - return to_vio_dev(container_of(found, struct device, kobj)); -} - -/** - * vio_find_node - find an already-registered vio_dev - * @vnode: device_node of the virtual device we're looking for - */ -struct vio_dev *vio_find_node(struct device_node *vnode) -{ - uint32_t *unit_address; - char kobj_name[BUS_ID_SIZE]; - - /* construct the kobject name from the device node */ - unit_address = (uint32_t *)get_property(vnode, "reg", NULL); - if (!unit_address) - return NULL; - snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); - - return vio_find_name(kobj_name); -} -EXPORT_SYMBOL(vio_find_node); - -int vio_enable_interrupts(struct vio_dev *dev) -{ - int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE); - if (rc != H_SUCCESS) - printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc); - return rc; -} -EXPORT_SYMBOL(vio_enable_interrupts); - -int vio_disable_interrupts(struct vio_dev *dev) -{ - int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE); - if (rc != H_SUCCESS) - printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc); - return rc; -} -EXPORT_SYMBOL(vio_disable_interrupts); -#endif /* CONFIG_PPC_PSERIES */ diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index 8b25953dc4f0..fe79c2584cb0 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -93,11 +93,6 @@ SECTIONS __ptov_table_begin = .; *(.ptov_fixup); __ptov_table_end = .; -#ifdef CONFIG_PPC_ISERIES - __dt_strings_start = .; - *(.dt_strings); - __dt_strings_end = .; -#endif } . = ALIGN(16); diff --git a/trunk/arch/powerpc/lib/Makefile b/trunk/arch/powerpc/lib/Makefile index ff7096458249..34f5c2e074c9 100644 --- a/trunk/arch/powerpc/lib/Makefile +++ b/trunk/arch/powerpc/lib/Makefile @@ -2,15 +2,12 @@ # Makefile for ppc-specific library files.. # -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif - ifeq ($(CONFIG_PPC_MERGE),y) obj-y := string.o strcase.o obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o endif +obj-y += bitops.o obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ memcpy_64.o usercopy_64.o mem_64.o string.o \ strcase.o diff --git a/trunk/arch/powerpc/lib/bitops.c b/trunk/arch/powerpc/lib/bitops.c new file mode 100644 index 000000000000..f68ad71a0187 --- /dev/null +++ b/trunk/arch/powerpc/lib/bitops.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include + +/** + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + const unsigned long *p = addr + BITOP_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG-1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset %= BITS_PER_LONG; + if (offset) { + tmp = *(p++); + tmp &= (~0UL << offset); + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG-1)) { + if ((tmp = *(p++))) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= (~0UL >> (BITS_PER_LONG - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} +EXPORT_SYMBOL(find_next_bit); + +/* + * This implementation of find_{first,next}_zero_bit was stolen from + * Linus' asm-alpha/bitops.h. + */ +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + const unsigned long *p = addr + BITOP_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG-1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset %= BITS_PER_LONG; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (BITS_PER_LONG - offset); + if (size < BITS_PER_LONG) + goto found_first; + if (~tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG-1)) { + if (~(tmp = *(p++))) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ffz(tmp); +} +EXPORT_SYMBOL(find_next_zero_bit); + +static inline unsigned int ext2_ilog2(unsigned int x) +{ + int lz; + + asm("cntlzw %0,%1": "=r"(lz):"r"(x)); + return 31 - lz; +} + +static inline unsigned int ext2_ffz(unsigned int x) +{ + u32 rc; + if ((x = ~x) == 0) + return 32; + rc = ext2_ilog2(x & -x); + return rc; +} + +unsigned long find_next_zero_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5); + unsigned int result = offset & ~31; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31; + if (offset) { + tmp = cpu_to_le32p(p++); + tmp |= ~0U >> (32 - offset); /* bug or feature ? */ + if (size < 32) + goto found_first; + if (tmp != ~0) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = cpu_to_le32p(p++)) != ~0) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = cpu_to_le32p(p); +found_first: + tmp |= ~0 << size; + if (tmp == ~0) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ext2_ffz(tmp); +} +EXPORT_SYMBOL(find_next_zero_le_bit); diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index a0a9e1e0061e..fdbba4206d59 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -40,40 +40,6 @@ #include #include -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif - /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. @@ -176,7 +142,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code & ESR_DST; #endif /* CONFIG_4xx || CONFIG_BOOKE */ - if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code, + if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return 0; diff --git a/trunk/arch/powerpc/mm/hash_low_32.S b/trunk/arch/powerpc/mm/hash_low_32.S index 94255beeecd3..ea469eefa146 100644 --- a/trunk/arch/powerpc/mm/hash_low_32.S +++ b/trunk/arch/powerpc/mm/hash_low_32.S @@ -74,6 +74,12 @@ _GLOBAL(hash_page_sync) */ .text _GLOBAL(hash_page) +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + MTMSRD(r0) + isync +#endif tophys(r7,0) /* gets -KERNELBASE into r7 */ #ifdef CONFIG_SMP addis r8,r7,mmu_hash_lock@h @@ -279,6 +285,7 @@ Hash_base = 0xc0180000 Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) +#ifndef CONFIG_PPC64BRIDGE /* defines for the PTE format for 32-bit PPCs */ #define PTE_SIZE 8 #define PTEG_SIZE 64 @@ -292,6 +299,21 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) #define SET_V(r) oris r,r,PTE_V@h #define CLR_V(r,t) rlwinm r,r,0,1,31 +#else +/* defines for the PTE format for 64-bit PPCs */ +#define PTE_SIZE 16 +#define PTEG_SIZE 128 +#define LG_PTEG_SIZE 7 +#define LDPTEu ldu +#define STPTE std +#define CMPPTE cmpd +#define PTE_H 2 +#define PTE_V 1 +#define TST_V(r) andi. r,r,PTE_V +#define SET_V(r) ori r,r,PTE_V +#define CLR_V(r,t) li t,PTE_V; andc r,r,t +#endif /* CONFIG_PPC64BRIDGE */ + #define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) #define HASH_RIGHT 31-LG_PTEG_SIZE @@ -309,8 +331,14 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r5) /* set V (valid) bit */ /* Get the address of the primary PTE group in the hash table (r3) */ @@ -488,8 +516,14 @@ _GLOBAL(flush_hash_pages) add r3,r3,r0 /* note code below trims to 24 bits */ /* Construct the high word of the PPC-style PTE (r11) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r11,r3,12 /* shift vsid into position */ + rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r11) /* set V (valid) bit */ #ifdef CONFIG_SMP diff --git a/trunk/arch/powerpc/mm/hash_low_64.S b/trunk/arch/powerpc/mm/hash_low_64.S index 52e914238959..e0d02c4a2615 100644 --- a/trunk/arch/powerpc/mm/hash_low_64.S +++ b/trunk/arch/powerpc/mm/hash_low_64.S @@ -136,7 +136,6 @@ _GLOBAL(__hash_page_4K) and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ andc r0,r30,r0 /* r0 = pte & ~r0 */ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */ /* We eventually do the icache sync here (maybe inline that * code rather than call a C function...) @@ -369,7 +368,6 @@ _GLOBAL(__hash_page_4K) rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ or r30,r30,r31 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE - oris r30,r30,_PAGE_COMBO@h /* Write the linux PTE atomically (setting busy) */ stdcx. r30,0,r6 bne- 1b @@ -402,7 +400,6 @@ _GLOBAL(__hash_page_4K) and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ andc r0,r30,r0 /* r0 = pte & ~r0 */ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */ /* We eventually do the icache sync here (maybe inline that * code rather than call a C function...) @@ -429,14 +426,6 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) andi. r0,r31,_PAGE_HASHPTE li r26,0 /* Default hidx */ beq htab_insert_pte - - /* - * Check if the pte was already inserted into the hash table - * as a 64k HW page, and invalidate the 64k HPTE if so. - */ - andis. r0,r31,_PAGE_COMBO@h - beq htab_inval_old_hpte - ld r6,STK_PARM(r6)(r1) ori r26,r6,0x8000 /* Load the hidx mask */ ld r26,0(r26) @@ -507,19 +496,6 @@ _GLOBAL(htab_call_hpte_remove) /* Try all again */ b htab_insert_pte - /* - * Call out to C code to invalidate an 64k HW HPTE that is - * useless now that the segment has been switched to 4k pages. - */ -htab_inval_old_hpte: - mr r3,r29 /* virtual addr */ - mr r4,r31 /* PTE.pte */ - li r5,0 /* PTE.hidx */ - li r6,MMU_PAGE_64K /* psize */ - ld r7,STK_PARM(r8)(r1) /* local */ - bl .flush_hash_page - b htab_insert_pte - htab_bail_ok: li r3,0 b htab_bail @@ -660,12 +636,6 @@ _GLOBAL(__hash_page_64K) * is changing this PTE anyway and might hash it. */ bne- ht64_bail_ok -BEGIN_FTR_SECTION - /* Check if PTE has the cache-inhibit bit set */ - andi. r0,r31,_PAGE_NO_CACHE - /* If so, bail out and refault as a 4k page */ - bne- ht64_bail_ok -END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) /* Prepare new PTE value (turn access RW into DIRTY, then * add BUSY,HASHPTE and ACCESSED) */ @@ -701,7 +671,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/ andc r0,r30,r0 /* r0 = pte & ~r0 */ rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */ - ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */ /* We eventually do the icache sync here (maybe inline that * code rather than call a C function...) diff --git a/trunk/arch/powerpc/mm/hash_native_64.c b/trunk/arch/powerpc/mm/hash_native_64.c index a0f3cbd00d39..994856e55b7c 100644 --- a/trunk/arch/powerpc/mm/hash_native_64.c +++ b/trunk/arch/powerpc/mm/hash_native_64.c @@ -238,7 +238,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, DBG_LOW(" -> hit\n"); /* Update the HPTE */ hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | - (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); + (newpp & (HPTE_R_PP | HPTE_R_N)); native_unlock_hpte(hptep); } diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index d03fd2b4445e..c006d9039633 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -92,15 +92,10 @@ unsigned long htab_size_bytes; unsigned long htab_hash_mask; int mmu_linear_psize = MMU_PAGE_4K; int mmu_virtual_psize = MMU_PAGE_4K; -int mmu_vmalloc_psize = MMU_PAGE_4K; -int mmu_io_psize = MMU_PAGE_4K; #ifdef CONFIG_HUGETLB_PAGE int mmu_huge_psize = MMU_PAGE_16M; unsigned int HPAGE_SHIFT; #endif -#ifdef CONFIG_PPC_64K_PAGES -int mmu_ci_restrictions; -#endif /* There are definitions of page sizes arrays to be used when none * is provided by the firmware. @@ -313,31 +308,20 @@ static void __init htab_init_page_sizes(void) else if (mmu_psize_defs[MMU_PAGE_1M].shift) mmu_linear_psize = MMU_PAGE_1M; -#ifdef CONFIG_PPC_64K_PAGES /* * Pick a size for the ordinary pages. Default is 4K, we support - * 64K for user mappings and vmalloc if supported by the processor. - * We only use 64k for ioremap if the processor - * (and firmware) support cache-inhibited large pages. - * If not, we use 4k and set mmu_ci_restrictions so that - * hash_page knows to switch processes that use cache-inhibited - * mappings to 4k pages. + * 64K if cache inhibited large pages are supported by the + * processor */ - if (mmu_psize_defs[MMU_PAGE_64K].shift) { +#ifdef CONFIG_PPC_64K_PAGES + if (mmu_psize_defs[MMU_PAGE_64K].shift && + cpu_has_feature(CPU_FTR_CI_LARGE_PAGE)) mmu_virtual_psize = MMU_PAGE_64K; - mmu_vmalloc_psize = MMU_PAGE_64K; - if (cpu_has_feature(CPU_FTR_CI_LARGE_PAGE)) - mmu_io_psize = MMU_PAGE_64K; - else - mmu_ci_restrictions = 1; - } #endif - printk(KERN_DEBUG "Page orders: linear mapping = %d, " - "virtual = %d, io = %d\n", + printk(KERN_INFO "Page orders: linear mapping = %d, others = %d\n", mmu_psize_defs[mmu_linear_psize].shift, - mmu_psize_defs[mmu_virtual_psize].shift, - mmu_psize_defs[mmu_io_psize].shift); + mmu_psize_defs[mmu_virtual_psize].shift); #ifdef CONFIG_HUGETLB_PAGE /* Init large page size. Currently, we pick 16M or 1M depending @@ -572,7 +556,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) pte_t *ptep; cpumask_t tmp; int rc, user_region = 0, local = 0; - int psize; DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", ea, access, trap); @@ -592,15 +575,10 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) return 1; } vsid = get_vsid(mm->context.id, ea); - psize = mm->context.user_psize; break; case VMALLOC_REGION_ID: mm = &init_mm; vsid = get_kernel_vsid(ea); - if (ea < VMALLOC_END) - psize = mmu_vmalloc_psize; - else - psize = mmu_io_psize; break; default: /* Not a valid range @@ -651,40 +629,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) #ifndef CONFIG_PPC_64K_PAGES rc = __hash_page_4K(ea, access, vsid, ptep, trap, local); #else - if (mmu_ci_restrictions) { - /* If this PTE is non-cacheable, switch to 4k */ - if (psize == MMU_PAGE_64K && - (pte_val(*ptep) & _PAGE_NO_CACHE)) { - if (user_region) { - psize = MMU_PAGE_4K; - mm->context.user_psize = MMU_PAGE_4K; - mm->context.sllp = SLB_VSID_USER | - mmu_psize_defs[MMU_PAGE_4K].sllp; - } else if (ea < VMALLOC_END) { - /* - * some driver did a non-cacheable mapping - * in vmalloc space, so switch vmalloc - * to 4k pages - */ - printk(KERN_ALERT "Reducing vmalloc segment " - "to 4kB pages because of " - "non-cacheable mapping\n"); - psize = mmu_vmalloc_psize = MMU_PAGE_4K; - } - } - if (user_region) { - if (psize != get_paca()->context.user_psize) { - get_paca()->context = mm->context; - slb_flush_and_rebolt(); - } - } else if (get_paca()->vmalloc_sllp != - mmu_psize_defs[mmu_vmalloc_psize].sllp) { - get_paca()->vmalloc_sllp = - mmu_psize_defs[mmu_vmalloc_psize].sllp; - slb_flush_and_rebolt(); - } - } - if (psize == MMU_PAGE_64K) + if (mmu_virtual_psize == MMU_PAGE_64K) rc = __hash_page_64K(ea, access, vsid, ptep, trap, local); else rc = __hash_page_4K(ea, access, vsid, ptep, trap, local); @@ -736,18 +681,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, #ifndef CONFIG_PPC_64K_PAGES __hash_page_4K(ea, access, vsid, ptep, trap, local); #else - if (mmu_ci_restrictions) { - /* If this PTE is non-cacheable, switch to 4k */ - if (mm->context.user_psize == MMU_PAGE_64K && - (pte_val(*ptep) & _PAGE_NO_CACHE)) { - mm->context.user_psize = MMU_PAGE_4K; - mm->context.sllp = SLB_VSID_USER | - mmu_psize_defs[MMU_PAGE_4K].sllp; - get_paca()->context = mm->context; - slb_flush_and_rebolt(); - } - } - if (mm->context.user_psize == MMU_PAGE_64K) + if (mmu_virtual_psize == MMU_PAGE_64K) __hash_page_64K(ea, access, vsid, ptep, trap, local); else __hash_page_4K(ea, access, vsid, ptep, trap, local); diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index d454caada265..9e30f968c184 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ void free_initmem(void) addr = (unsigned long)__init_begin; for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); diff --git a/trunk/arch/powerpc/mm/lmb.c b/trunk/arch/powerpc/mm/lmb.c index 8b6f522655a6..417d58518558 100644 --- a/trunk/arch/powerpc/mm/lmb.c +++ b/trunk/arch/powerpc/mm/lmb.c @@ -89,23 +89,18 @@ static long __init lmb_regions_adjacent(struct lmb_region *rgn, return lmb_addrs_adjacent(base1, size1, base2, size2); } -static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r) -{ - unsigned long i; - - for (i = r; i < rgn->cnt - 1; i++) { - rgn->region[i].base = rgn->region[i + 1].base; - rgn->region[i].size = rgn->region[i + 1].size; - } - rgn->cnt--; -} - /* Assumption: base addr of region 1 < base addr of region 2 */ static void __init lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2) { + unsigned long i; + rgn->region[r1].size += rgn->region[r2].size; - lmb_remove_region(rgn, r2); + for (i=r2; i < rgn->cnt-1; i++) { + rgn->region[i].base = rgn->region[i+1].base; + rgn->region[i].size = rgn->region[i+1].size; + } + rgn->cnt--; } /* This routine called with relocation disabled. */ @@ -299,16 +294,17 @@ unsigned long __init lmb_end_of_DRAM(void) return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); } -/* You must call lmb_analyze() after this. */ +/* + * Truncate the lmb list to memory_limit if it's set + * You must call lmb_analyze() after this. + */ void __init lmb_enforce_memory_limit(unsigned long memory_limit) { unsigned long i, limit; - struct lmb_property *p; if (! memory_limit) return; - /* Truncate the lmb regions to satisfy the memory limit. */ limit = memory_limit; for (i = 0; i < lmb.memory.cnt; i++) { if (limit > lmb.memory.region[i].size) { @@ -320,21 +316,4 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit) lmb.memory.cnt = i + 1; break; } - - lmb.rmo_size = lmb.memory.region[0].size; - - /* And truncate any reserves above the limit also. */ - for (i = 0; i < lmb.reserved.cnt; i++) { - p = &lmb.reserved.region[i]; - - if (p->base > memory_limit) - p->size = 0; - else if ((p->base + p->size) > memory_limit) - p->size = memory_limit - p->base; - - if (p->size == 0) { - lmb_remove_region(&lmb.reserved, i); - i--; - } - } } diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 089d939a0b3e..741dd8802d49 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -114,20 +114,15 @@ void online_page(struct page *page) num_physpages++; } -#ifdef CONFIG_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return hot_add_scn_to_nid(start); -} -#endif - -int __devinit arch_add_memory(int nid, u64 start, u64 size) +int __devinit add_memory(u64 start, u64 size) { struct pglist_data *pgdata; struct zone *zone; + int nid; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + nid = hot_add_scn_to_nid(start); pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); @@ -304,9 +299,9 @@ void __init paging_init(void) kmap_prot = PAGE_KERNEL; #endif /* CONFIG_HIGHMEM */ - printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", + printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", top_of_ram, total_ram); - printk(KERN_DEBUG "Memory hole size: %ldMB\n", + printk(KERN_INFO "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); /* * All pages are DMA-able so we put them all in the DMA zone. @@ -385,7 +380,7 @@ void __init mem_init(void) totalhigh_pages++; } totalram_pages += totalhigh_pages; - printk(KERN_DEBUG "High memory: %luk\n", + printk(KERN_INFO "High memory: %luk\n", totalhigh_pages << (PAGE_SHIFT-10)); } #endif /* CONFIG_HIGHMEM */ diff --git a/trunk/arch/powerpc/mm/mmu_context_32.c b/trunk/arch/powerpc/mm/mmu_context_32.c index e326e4249e1a..a8816e0f6a86 100644 --- a/trunk/arch/powerpc/mm/mmu_context_32.c +++ b/trunk/arch/powerpc/mm/mmu_context_32.c @@ -30,7 +30,7 @@ #include #include -unsigned long next_mmu_context; +mm_context_t next_mmu_context; unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; #ifdef FEW_CONTEXTS atomic_t nr_free_contexts; diff --git a/trunk/arch/powerpc/mm/mmu_context_64.c b/trunk/arch/powerpc/mm/mmu_context_64.c index 65d18dca266f..714a84dd8d5d 100644 --- a/trunk/arch/powerpc/mm/mmu_context_64.c +++ b/trunk/arch/powerpc/mm/mmu_context_64.c @@ -49,9 +49,6 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) } mm->context.id = index; - mm->context.user_psize = mmu_virtual_psize; - mm->context.sllp = SLB_VSID_USER | - mmu_psize_defs[mmu_virtual_psize].sllp; return 0; } diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index fbe23933f731..092355f37399 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -334,7 +334,7 @@ static int __cpuinit numa_setup_cpu(unsigned long lcpu) return nid; } -static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, +static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -487,9 +487,9 @@ static void __init setup_nonnuma(void) unsigned long total_ram = lmb_phys_mem_size(); unsigned int i; - printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", + printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", top_of_ram, total_ram); - printk(KERN_DEBUG "Memory hole size: %ldMB\n", + printk(KERN_INFO "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); for (i = 0; i < lmb.memory.cnt; ++i) @@ -507,7 +507,7 @@ void __init dump_numa_cpu_topology(void) return; for_each_online_node(node) { - printk(KERN_DEBUG "Node %d CPUs:", node); + printk(KERN_INFO "Node %d CPUs:", node); count = 0; /* @@ -543,7 +543,7 @@ static void __init dump_numa_memory_topology(void) for_each_online_node(node) { unsigned long i; - printk(KERN_DEBUG "Node %d Memory:", node); + printk(KERN_INFO "Node %d Memory:", node); count = 0; @@ -609,15 +609,14 @@ static void __init *careful_allocation(int nid, unsigned long size, return (void *)ret; } -static struct notifier_block __cpuinitdata ppc64_numa_nb = { - .notifier_call = cpu_numa_callback, - .priority = 1 /* Must run before sched domains notifier. */ -}; - void __init do_init_bootmem(void) { int nid; unsigned int i; + static struct notifier_block ppc64_numa_nb = { + .notifier_call = cpu_numa_callback, + .priority = 1 /* Must run before sched domains notifier. */ + }; min_low_pfn = 0; max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/mm/ppc_mmu_32.c b/trunk/arch/powerpc/mm/ppc_mmu_32.c index 2ed43a493b31..ed7fcfe5fd37 100644 --- a/trunk/arch/powerpc/mm/ppc_mmu_32.c +++ b/trunk/arch/powerpc/mm/ppc_mmu_32.c @@ -42,14 +42,18 @@ unsigned long _SDR1; union ubat { /* BAT register values to be loaded */ BAT bat; +#ifdef CONFIG_PPC64BRIDGE + u64 word[2]; +#else u32 word[2]; -} BATS[8][2]; /* 8 pairs of IBAT, DBAT */ +#endif +} BATS[4][2]; /* 4 pairs of IBAT, DBAT */ struct batrange { /* stores address ranges mapped by BATs */ unsigned long start; unsigned long limit; unsigned long phys; -} bat_addrs[8]; +} bat_addrs[4]; /* * Return PA for this VA if it is mapped by a BAT, or 0 @@ -186,7 +190,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, return; pmd = pmd_offset(pgd_offset(mm, ea), ea); if (!pmd_none(*pmd)) - add_hash_page(mm->context.id, ea, pmd_val(*pmd)); + add_hash_page(mm->context, ea, pmd_val(*pmd)); } /* @@ -216,9 +220,15 @@ void __init MMU_init_hw(void) if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); +#ifdef CONFIG_PPC64BRIDGE +#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ +#define SDR1_LOW_BITS (lg_n_hpteg - 11) +#define MIN_N_HPTEG 2048 /* min 256kB hash table */ +#else #define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ #define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) #define MIN_N_HPTEG 1024 /* min 64kB hash table */ +#endif /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. diff --git a/trunk/arch/powerpc/mm/slb.c b/trunk/arch/powerpc/mm/slb.c index 6a8bf6c6000e..ffc8ed4de62d 100644 --- a/trunk/arch/powerpc/mm/slb.c +++ b/trunk/arch/powerpc/mm/slb.c @@ -60,19 +60,19 @@ static inline void create_slbe(unsigned long ea, unsigned long flags, : "memory" ); } -void slb_flush_and_rebolt(void) +static void slb_flush_and_rebolt(void) { /* If you change this make sure you change SLB_NUM_BOLTED * appropriately too. */ - unsigned long linear_llp, vmalloc_llp, lflags, vflags; + unsigned long linear_llp, virtual_llp, lflags, vflags; unsigned long ksp_esid_data; WARN_ON(!irqs_disabled()); linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; - vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; + virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp; lflags = SLB_VSID_KERNEL | linear_llp; - vflags = SLB_VSID_KERNEL | vmalloc_llp; + vflags = SLB_VSID_KERNEL | virtual_llp; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) @@ -122,6 +122,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) get_paca()->slb_cache_ptr = 0; get_paca()->context = mm->context; +#ifdef CONFIG_PPC_64K_PAGES + get_paca()->pgdir = mm->pgd; +#endif /* CONFIG_PPC_64K_PAGES */ /* * preload some userspace segments into the SLB. @@ -164,10 +167,11 @@ static inline void patch_slb_encoding(unsigned int *insn_addr, void slb_initialize(void) { - unsigned long linear_llp, vmalloc_llp, io_llp; + unsigned long linear_llp, virtual_llp; static int slb_encoding_inited; extern unsigned int *slb_miss_kernel_load_linear; - extern unsigned int *slb_miss_kernel_load_io; + extern unsigned int *slb_miss_kernel_load_virtual; + extern unsigned int *slb_miss_user_load_normal; #ifdef CONFIG_HUGETLB_PAGE extern unsigned int *slb_miss_user_load_huge; unsigned long huge_llp; @@ -177,19 +181,18 @@ void slb_initialize(void) /* Prepare our SLB miss handler based on our page size */ linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; - io_llp = mmu_psize_defs[mmu_io_psize].sllp; - vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; - get_paca()->vmalloc_sllp = SLB_VSID_KERNEL | vmalloc_llp; - + virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp; if (!slb_encoding_inited) { slb_encoding_inited = 1; patch_slb_encoding(slb_miss_kernel_load_linear, SLB_VSID_KERNEL | linear_llp); - patch_slb_encoding(slb_miss_kernel_load_io, - SLB_VSID_KERNEL | io_llp); + patch_slb_encoding(slb_miss_kernel_load_virtual, + SLB_VSID_KERNEL | virtual_llp); + patch_slb_encoding(slb_miss_user_load_normal, + SLB_VSID_USER | virtual_llp); DBG("SLB: linear LLP = %04x\n", linear_llp); - DBG("SLB: io LLP = %04x\n", io_llp); + DBG("SLB: virtual LLP = %04x\n", virtual_llp); #ifdef CONFIG_HUGETLB_PAGE patch_slb_encoding(slb_miss_user_load_huge, SLB_VSID_USER | huge_llp); @@ -204,7 +207,7 @@ void slb_initialize(void) unsigned long lflags, vflags; lflags = SLB_VSID_KERNEL | linear_llp; - vflags = SLB_VSID_KERNEL | vmalloc_llp; + vflags = SLB_VSID_KERNEL | virtual_llp; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ asm volatile("isync":::"memory"); @@ -212,6 +215,7 @@ void slb_initialize(void) asm volatile("isync; slbia; isync":::"memory"); create_slbe(PAGE_OFFSET, lflags, 0); + /* VMALLOC space has 4K pages always for now */ create_slbe(VMALLOC_START, vflags, 1); /* We don't bolt the stack for the time being - we're in boot, diff --git a/trunk/arch/powerpc/mm/slb_low.S b/trunk/arch/powerpc/mm/slb_low.S index 8548dcf8ef8b..abfaabf667bf 100644 --- a/trunk/arch/powerpc/mm/slb_low.S +++ b/trunk/arch/powerpc/mm/slb_low.S @@ -59,19 +59,10 @@ _GLOBAL(slb_miss_kernel_load_linear) li r11,0 b slb_finish_load -1: /* vmalloc/ioremap mapping encoding bits, the "li" instructions below +1: /* vmalloc/ioremap mapping encoding bits, the "li" instruction below * will be patched by the kernel at boot */ -BEGIN_FTR_SECTION - /* check whether this is in vmalloc or ioremap space */ - clrldi r11,r10,48 - cmpldi r11,(VMALLOC_SIZE >> 28) - 1 - bgt 5f - lhz r11,PACAVMALLOCSLLP(r13) - b slb_finish_load -5: -END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) -_GLOBAL(slb_miss_kernel_load_io) +_GLOBAL(slb_miss_kernel_load_virtual) li r11,0 b slb_finish_load @@ -105,7 +96,9 @@ _GLOBAL(slb_miss_user_load_huge) 1: #endif /* CONFIG_HUGETLB_PAGE */ - lhz r11,PACACONTEXTSLLP(r13) +_GLOBAL(slb_miss_user_load_normal) + li r11,0 + 2: ld r9,PACACONTEXTID(r13) rldimi r10,r9,USER_ESID_BITS,0 diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 691320c90b78..4a9291d9fef8 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -200,6 +200,10 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) __get_cpu_var(stab_cache_ptr) = 0; +#ifdef CONFIG_PPC_64K_PAGES + get_paca()->pgdir = mm->pgd; +#endif /* CONFIG_PPC_64K_PAGES */ + /* Now preload some entries for the new task */ if (test_tsk_thread_flag(tsk, TIF_32BIT)) unmapped_base = TASK_UNMAPPED_BASE_USER32; diff --git a/trunk/arch/powerpc/mm/tlb_32.c b/trunk/arch/powerpc/mm/tlb_32.c index 02eb23e036d5..ad580f3742e5 100644 --- a/trunk/arch/powerpc/mm/tlb_32.c +++ b/trunk/arch/powerpc/mm/tlb_32.c @@ -42,7 +42,7 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) if (Hash != 0) { ptephys = __pa(ptep) & PAGE_MASK; - flush_hash_pages(mm->context.id, addr, ptephys, 1); + flush_hash_pages(mm->context, addr, ptephys, 1); } } @@ -102,7 +102,7 @@ static void flush_range(struct mm_struct *mm, unsigned long start, pmd_t *pmd; unsigned long pmd_end; int count; - unsigned int ctx = mm->context.id; + unsigned int ctx = mm->context; if (Hash == 0) { _tlbia(); @@ -172,7 +172,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr); if (!pmd_none(*pmd)) - flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); + flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1); FINISH_FLUSH; } diff --git a/trunk/arch/powerpc/mm/tlb_64.c b/trunk/arch/powerpc/mm/tlb_64.c index e7449b068c82..f734b11566c2 100644 --- a/trunk/arch/powerpc/mm/tlb_64.c +++ b/trunk/arch/powerpc/mm/tlb_64.c @@ -131,7 +131,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, { struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); unsigned long vsid; - unsigned int psize; + unsigned int psize = mmu_virtual_psize; int i; i = batch->index; @@ -148,8 +148,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, #else BUG(); #endif - } else - psize = pte_pagesize_index(pte); + } /* * This can happen when we are in the middle of a TLB batch and diff --git a/trunk/arch/powerpc/oprofile/Kconfig b/trunk/arch/powerpc/oprofile/Kconfig index eb2dece76a54..d03c0e5ca870 100644 --- a/trunk/arch/powerpc/oprofile/Kconfig +++ b/trunk/arch/powerpc/oprofile/Kconfig @@ -1,4 +1,5 @@ config PROFILING + depends on !PPC_ISERIES bool "Profiling support (EXPERIMENTAL)" help Say Y here to enable the extended profiling support mechanisms used diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index 3145d610b5b0..f5f9859a8338 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -1,7 +1,3 @@ -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif - obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index fd0bbbe7a4de..5b1de7e8041e 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -22,7 +22,6 @@ #include #include #include -#include static struct op_powerpc_model *model; @@ -94,7 +93,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; - char buf[4]; + char buf[3]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); @@ -131,9 +130,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) if (!cur_cpu_spec->oprofile_cpu_type) return -ENODEV; - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return -ENODEV; - switch (cur_cpu_spec->oprofile_type) { #ifdef CONFIG_PPC64 case PPC_OPROFILE_RS64: @@ -166,7 +162,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->stop = op_powerpc_stop; ops->backtrace = op_powerpc_backtrace; - printk(KERN_DEBUG "oprofile: using %s performance monitoring.\n", + printk(KERN_INFO "oprofile: using %s performance monitoring.\n", ops->cpu_type); return 0; diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 506f6b79f893..4c2beab1fdc1 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -24,6 +24,10 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int oprofile_running; +static int mmcra_has_sihv; +/* Unfortunately these bits vary between CPUs */ +static unsigned long mmcra_sihv = MMCRA_SIHV; +static unsigned long mmcra_sipr = MMCRA_SIPR; /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ static u32 mmcr0_val; @@ -36,6 +40,16 @@ static void power4_reg_setup(struct op_counter_config *ctr, { int i; + /* + * SIHV / SIPR bits are only implemented on POWER4+ (GQ) and above. + * However we disable it on all POWER4 until we verify it works + * (I was seeing some strange behaviour last time I tried). + * + * It has been verified to work on POWER5 so we enable it there. + */ + if (cpu_has_feature(CPU_FTR_MMCRA_SIHV)) + mmcra_has_sihv = 1; + /* * The performance counter event settings are given in the mmcr0, * mmcr1 and mmcra values passed from the user in the @@ -188,19 +202,18 @@ static unsigned long get_pc(struct pt_regs *regs) unsigned long mmcra; /* Cant do much about it */ - if (!cur_cpu_spec->oprofile_mmcra_sihv) + if (!mmcra_has_sihv) return pc; mmcra = mfspr(SPRN_MMCRA); /* Were we in the hypervisor? */ - if (firmware_has_feature(FW_FEATURE_LPAR) && - (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) + if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv)) /* function descriptor madness */ return *((unsigned long *)hypervisor_bucket); /* We were in userspace, nothing to do */ - if (mmcra & cur_cpu_spec->oprofile_mmcra_sipr) + if (mmcra & mmcra_sipr) return pc; #ifdef CONFIG_PPC_RTAS @@ -222,14 +235,15 @@ static unsigned long get_pc(struct pt_regs *regs) return pc; } -static int get_kernel(unsigned long pc, unsigned long mmcra) +static int get_kernel(unsigned long pc) { int is_kernel; - if (!cur_cpu_spec->oprofile_mmcra_sihv) { + if (!mmcra_has_sihv) { is_kernel = is_kernel_addr(pc); } else { - is_kernel = ((mmcra & cur_cpu_spec->oprofile_mmcra_sipr) == 0); + unsigned long mmcra = mfspr(SPRN_MMCRA); + is_kernel = ((mmcra & mmcra_sipr) == 0); } return is_kernel; @@ -243,12 +257,9 @@ static void power4_handle_interrupt(struct pt_regs *regs, int val; int i; unsigned int mmcr0; - unsigned long mmcra; - - mmcra = mfspr(SPRN_MMCRA); pc = get_pc(regs); - is_kernel = get_kernel(pc, mmcra); + is_kernel = get_kernel(pc); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); @@ -276,10 +287,6 @@ static void power4_handle_interrupt(struct pt_regs *regs, */ mmcr0 &= ~MMCR0_PMAO; - /* Clear the appropriate bits in the MMCRA */ - mmcra &= ~cur_cpu_spec->oprofile_mmcra_clear; - mtspr(SPRN_MMCRA, mmcra); - /* * now clear the freeze bit, counting will not start until we * rfid from this exception, because only at that point will diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index 454fc53289ab..06e371282f57 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -11,20 +11,13 @@ config MPC8540_ADS help This option enables support for the MPC 8540 ADS board -config MPC85xx_CDS - bool "Freescale MPC85xx CDS" - select DEFAULT_UIMAGE - select PPC_I8259 if PCI - help - This option enables support for the MPC85xx CDS board - endchoice config MPC8540 bool select PPC_UDBG_16550 select PPC_INDIRECT_PCI - default y if MPC8540_ADS || MPC85xx_CDS + default y if MPC8540_ADS config PPC_INDIRECT_PCI_BE bool diff --git a/trunk/arch/powerpc/platforms/85xx/Makefile b/trunk/arch/powerpc/platforms/85xx/Makefile index 7615aa59c78b..ffc4139cb214 100644 --- a/trunk/arch/powerpc/platforms/85xx/Makefile +++ b/trunk/arch/powerpc/platforms/85xx/Makefile @@ -3,4 +3,3 @@ # obj-$(CONFIG_PPC_85xx) += misc.o pci.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o -obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c deleted file mode 100644 index 18e6e11f7020..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * MPC85xx setup and early boot code plus other random bits. - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2005 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "mpc85xx.h" - -#ifndef CONFIG_PCI -unsigned long isa_io_base = 0; -unsigned long isa_mem_base = 0; -#endif - -static int cds_pci_slot = 2; -static volatile u8 *cadmus; - -/* - * Internal interrupts are all Level Sensitive, and Positive Polarity - * - * Note: Likely, this table and the following function should be - * obtained and derived from the OF Device Tree. - */ -static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { - MPC85XX_INTERNAL_IRQ_SENSES, -#if defined(CONFIG_PCI) - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */ -#else - 0x0, /* External 0: */ - 0x0, /* External 1: */ - 0x0, /* External 2: */ - 0x0, /* External 3: */ -#endif - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ - 0x0, /* External 6: */ - 0x0, /* External 7: */ - 0x0, /* External 8: */ - 0x0, /* External 9: */ - 0x0, /* External 10: */ -#ifdef CONFIG_PCI - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */ -#else - 0x0, /* External 11: */ -#endif -}; - - -#ifdef CONFIG_PCI -/* - * interrupt routing - */ -int -mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - - if (!hose->index) - { - /* Handle PCI1 interrupts */ - char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - - /* Note IRQ assignment for slots is based on which slot the elysium is - * in -- in this setup elysium is in slot #2 (this PIRQA as first - * interrupt on slot */ - { - { 0, 1, 2, 3 }, /* 16 - PMC */ - { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ - { 0, 1, 2, 3 }, /* 18 - Slot 1 */ - { 1, 2, 3, 0 }, /* 19 - Slot 2 */ - { 2, 3, 0, 1 }, /* 20 - Slot 3 */ - { 3, 0, 1, 2 }, /* 21 - Slot 4 */ - }; - - const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; - int i, j; - - for (i = 0; i < 6; i++) - for (j = 0; j < 4; j++) - pci_irq_table[i][j] = - ((pci_irq_table[i][j] + 5 - - cds_pci_slot) & 0x3) + PIRQ0A; - - return PCI_IRQ_TABLE_LOOKUP; - } else { - /* Handle PCI2 interrupts (if we have one) */ - char pci_irq_table[][4] = - { - /* - * We only have one slot and one interrupt - * going to PIRQA - PIRQD */ - { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */ - }; - - const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4; - - return PCI_IRQ_TABLE_LOOKUP; - } -} - -#define ARCADIA_HOST_BRIDGE_IDSEL 17 -#define ARCADIA_2ND_BRIDGE_IDSEL 3 - -extern int mpc85xx_pci2_busno; - -int -mpc85xx_exclude_device(u_char bus, u_char devfn) -{ - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (mpc85xx_pci2_busno) - if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - /* We explicitly do not go past the Tundra 320 Bridge */ - if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) - return PCIBIOS_DEVICE_NOT_FOUND; - else - return PCIBIOS_SUCCESSFUL; -} - -void __init -mpc85xx_cds_pcibios_fixup(void) -{ - struct pci_dev *dev; - u_char c; - - if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_82C586_1, NULL))) { - /* - * U-Boot does not set the enable bits - * for the IDE device. Force them on here. - */ - pci_read_config_byte(dev, 0x40, &c); - c |= 0x03; /* IDE: Chip Enable Bits */ - pci_write_config_byte(dev, 0x40, c); - - /* - * Since only primary interface works, force the - * IDE function to standard primary IDE interrupt - * w/ 8259 offset - */ - dev->irq = 14; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - pci_dev_put(dev); - } - - /* - * Force legacy USB interrupt routing - */ - if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_82C586_2, NULL))) { - dev->irq = 10; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); - pci_dev_put(dev); - } - - if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_82C586_2, dev))) { - dev->irq = 11; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); - pci_dev_put(dev); - } -} -#endif /* CONFIG_PCI */ - -void __init mpc85xx_cds_pic_init(void) -{ - struct mpic *mpic1; - phys_addr_t OpenPIC_PAddr; - - /* Determine the Physical Address of the OpenPIC regs */ - OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; - - mpic1 = mpic_alloc(OpenPIC_PAddr, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, - mpc85xx_cds_openpic_initsenses, - sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC "); - BUG_ON(mpic1 == NULL); - mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); - mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); - mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); - mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); - mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); - mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); - mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); - mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); - - /* dummy mappings to get to 48 */ - mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); - mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); - mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); - mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); - - /* External ints */ - mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); - mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); - mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); - - mpic_init(mpic1); - -#ifdef CONFIG_PCI - mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL); - - i8259_init(0,0); -#endif -} - - -/* - * Setup the architecture - */ -static void __init -mpc85xx_cds_setup_arch(void) -{ - struct device_node *cpu; -#ifdef CONFIG_PCI - struct device_node *np; -#endif - - if (ppc_md.progress) - ppc_md.progress("mpc85xx_cds_setup_arch()", 0); - - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu != 0) { - unsigned int *fp; - - fp = (int *)get_property(cpu, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 500000000 / HZ; - of_node_put(cpu); - } - - cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE); - cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1; - - if (ppc_md.progress) { - char buf[40]; - snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n", - cadmus[CM_VER], cds_pci_slot); - ppc_md.progress(buf, 0); - } - -#ifdef CONFIG_PCI - for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) - add_bridge(np); - - ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc85xx_map_irq; - ppc_md.pci_exclude_device = mpc85xx_exclude_device; -#endif - -#ifdef CONFIG_ROOT_NFS - ROOT_DEV = Root_NFS; -#else - ROOT_DEV = Root_HDA1; -#endif -} - - -void -mpc85xx_cds_show_cpuinfo(struct seq_file *m) -{ - uint pvid, svid, phid1; - uint memsize = total_memory; - - pvid = mfspr(SPRN_PVR); - svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); - seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]); - seq_printf(m, "PVR\t\t: 0x%x\n", pvid); - seq_printf(m, "SVR\t\t: 0x%x\n", svid); - - /* Display cpu Pll setting */ - phid1 = mfspr(SPRN_HID1); - seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -} - - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init mpc85xx_cds_probe(void) -{ - /* We always match for now, eventually we should look at - * the flat dev tree to ensure this is the board we are - * supposed to run on - */ - return 1; -} - -define_machine(mpc85xx_cds) { - .name = "MPC85xx CDS", - .probe = mpc85xx_cds_probe, - .setup_arch = mpc85xx_cds_setup_arch, - .init_IRQ = mpc85xx_cds_pic_init, - .show_cpuinfo = mpc85xx_cds_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = mpc85xx_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.h deleted file mode 100644 index 671f54ff185a..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * arch/ppc/platforms/85xx/mpc85xx_cds_common.h - * - * MPC85xx CDS board definitions - * - * Maintainer: Kumar Gala - * - * Copyright 2004 Freescale Semiconductor, Inc - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#ifndef __MACH_MPC85XX_CDS_H__ -#define __MACH_MPC85XX_CDS_H__ - -/* CADMUS info */ -#define CADMUS_BASE (0xf8004000) -#define CADMUS_SIZE (256) -#define CM_VER (0) -#define CM_CSR (1) -#define CM_RST (2) - -/* CDS NVRAM/RTC */ -#define CDS_RTC_ADDR (0xf8000000) -#define CDS_RTC_SIZE (8 * 1024) - -/* PCI interrupt controller */ -#define PIRQ0A MPC85xx_IRQ_EXT0 -#define PIRQ0B MPC85xx_IRQ_EXT1 -#define PIRQ0C MPC85xx_IRQ_EXT2 -#define PIRQ0D MPC85xx_IRQ_EXT3 -#define PIRQ1A MPC85xx_IRQ_EXT11 - -#define NR_8259_INTS 16 -#define CPM_IRQ_OFFSET NR_8259_INTS - -#define MPC85xx_OPENPIC_IRQ_OFFSET 80 - -#endif /* __MACH_MPC85XX_CDS_H__ */ diff --git a/trunk/arch/powerpc/platforms/86xx/Kconfig b/trunk/arch/powerpc/platforms/86xx/Kconfig deleted file mode 100644 index 3a87863d2876..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/Kconfig +++ /dev/null @@ -1,36 +0,0 @@ -menu "Platform Support" - depends on PPC_86xx - -choice - prompt "Machine Type" - default MPC8641_HPCN - -config MPC8641_HPCN - bool "Freescale MPC8641 HPCN" - help - This option enables support for the MPC8641 HPCN board. - -endchoice - - -config MPC8641 - bool - select PPC_INDIRECT_PCI - select PPC_UDBG_16550 - default y if MPC8641_HPCN - -config MPIC - bool - default y - -config PPC_INDIRECT_PCI_BE - bool - depends on PPC_86xx - default y - -config PPC_STD_MMU - bool - depends on PPC_86xx - default y - -endmenu diff --git a/trunk/arch/powerpc/platforms/86xx/Makefile b/trunk/arch/powerpc/platforms/86xx/Makefile deleted file mode 100644 index 7be796c5d5c9..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the PowerPC 86xx linux kernel. -# - - -ifeq ($(CONFIG_PPC_86xx),y) -obj-$(CONFIG_SMP) += mpc86xx_smp.o -endif -obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o -obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h deleted file mode 100644 index 5042253758b7..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * MPC8641 HPCN board definitions - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Author: Xianghua Xiao - */ - -#ifndef __MPC8641_HPCN_H__ -#define __MPC8641_HPCN_H__ - -#include -#include - -/* PCI interrupt controller */ -#define PIRQA 3 -#define PIRQB 4 -#define PIRQC 5 -#define PIRQD 6 -#define PIRQ7 7 -#define PIRQE 9 -#define PIRQF 10 -#define PIRQG 11 -#define PIRQH 12 - -/* PCI-Express memory map */ -#define MPC86XX_PCIE_LOWER_IO 0x00000000 -#define MPC86XX_PCIE_UPPER_IO 0x00ffffff - -#define MPC86XX_PCIE_LOWER_MEM 0x80000000 -#define MPC86XX_PCIE_UPPER_MEM 0x9fffffff - -#define MPC86XX_PCIE_IO_BASE 0xe2000000 -#define MPC86XX_PCIE_MEM_OFFSET 0x00000000 - -#define MPC86XX_PCIE_IO_SIZE 0x01000000 - -#define PCIE1_CFG_ADDR_OFFSET (0x8000) -#define PCIE1_CFG_DATA_OFFSET (0x8004) - -#define PCIE2_CFG_ADDR_OFFSET (0x9000) -#define PCIE2_CFG_DATA_OFFSET (0x9004) - -#define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET -#define MPC86xx_PCIE_SIZE (0x1000) - -#define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ - -#endif /* __MPC8641_HPCN_H__ */ diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx.h b/trunk/arch/powerpc/platforms/86xx/mpc86xx.h deleted file mode 100644 index e3c9e4f417d3..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __MPC86XX_H__ -#define __MPC86XX_H__ - -/* - * Declaration for the various functions exported by the - * mpc86xx_* files. Mostly for use by mpc86xx_setup(). - */ - -extern int __init add_bridge(struct device_node *dev); - -extern void __init setup_indirect_pcie(struct pci_controller *hose, - u32 cfg_addr, u32 cfg_data); -extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, - void __iomem *cfg_addr, - void __iomem *cfg_data); - -extern void __init mpc86xx_smp_init(void); - -#endif /* __MPC86XX_H__ */ diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c deleted file mode 100644 index 483c21df181e..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * MPC86xx HPCN board specific routines - * - * Recode: ZHANG WEI - * Initial author: Xianghua Xiao - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "mpc86xx.h" - -#ifndef CONFIG_PCI -unsigned long isa_io_base = 0; -unsigned long isa_mem_base = 0; -unsigned long pci_dram_offset = 0; -#endif - - -/* - * Internal interrupts are all Level Sensitive, and Positive Polarity - */ - -static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */ - 0x0, /* External 0: */ - 0x0, /* External 1: */ - 0x0, /* External 2: */ - 0x0, /* External 3: */ - 0x0, /* External 4: */ - 0x0, /* External 5: */ - 0x0, /* External 6: */ - 0x0, /* External 7: */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */ - 0x0, /* External 11: */ - 0x0, - 0x0, - 0x0, - 0x0, -}; - - -void __init -mpc86xx_hpcn_init_irq(void) -{ - struct mpic *mpic1; - phys_addr_t openpic_paddr; - - /* Determine the Physical Address of the OpenPIC regs */ - openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; - - /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(openpic_paddr, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250, - mpc86xx_hpcn_openpic_initsenses, - sizeof(mpc86xx_hpcn_openpic_initsenses), - " MPIC "); - BUG_ON(mpic1 == NULL); - - /* 48 Internal Interrupts */ - mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200); - mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400); - mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600); - - /* 16 External interrupts */ - mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000); - - mpic_init(mpic1); - -#ifdef CONFIG_PCI - mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL); - i8259_init(0, I8259_OFFSET); -#endif -} - - - -#ifdef CONFIG_PCI -/* - * interrupt routing - */ - -int -mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - static char pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */ - {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */ - {0, 0, 0, 0}, /* IDSEL 19 */ - {0, 0, 0, 0}, /* IDSEL 20 */ - {0, 0, 0, 0}, /* IDSEL 21 */ - {0, 0, 0, 0}, /* IDSEL 22 */ - {0, 0, 0, 0}, /* IDSEL 23 */ - {0, 0, 0, 0}, /* IDSEL 24 */ - {0, 0, 0, 0}, /* IDSEL 25 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/ - {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */ - {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */ - {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */ - {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/ - {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */ - }; - - const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; -} - - -int -mpc86xx_exclude_device(u_char bus, u_char devfn) -{ -#if !defined(CONFIG_PCI) - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; -#endif - - return PCIBIOS_SUCCESSFUL; -} -#endif /* CONFIG_PCI */ - - -static void __init -mpc86xx_hpcn_setup_arch(void) -{ - struct device_node *np; - - if (ppc_md.progress) - ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0); - - np = of_find_node_by_type(NULL, "cpu"); - if (np != 0) { - unsigned int *fp; - - fp = (int *)get_property(np, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(np); - } - -#ifdef CONFIG_PCI - for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) - add_bridge(np); - - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc86xx_map_irq; - ppc_md.pci_exclude_device = mpc86xx_exclude_device; -#endif - - printk("MPC86xx HPCN board from Freescale Semiconductor\n"); - -#ifdef CONFIG_ROOT_NFS - ROOT_DEV = Root_NFS; -#else - ROOT_DEV = Root_HDA1; -#endif - -#ifdef CONFIG_SMP - mpc86xx_smp_init(); -#endif -} - - -void -mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) -{ - struct device_node *root; - uint memsize = total_memory; - const char *model = ""; - uint svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); - - root = of_find_node_by_path("/"); - if (root) - model = get_property(root, "model", NULL); - seq_printf(m, "Machine\t\t: %s\n", model); - of_node_put(root); - - seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); -} - - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init mpc86xx_hpcn_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "mpc86xx")) - return 1; /* Looks good */ - - return 0; -} - - -void -mpc86xx_restart(char *cmd) -{ - void __iomem *rstcr; - - rstcr = ioremap(get_immrbase() + MPC86XX_RSTCR_OFFSET, 0x100); - - local_irq_disable(); - - /* Assert reset request to Reset Control Register */ - out_be32(rstcr, 0x2); - - /* not reached */ -} - - -long __init -mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - - -define_machine(mpc86xx_hpcn) { - .name = "MPC86xx HPCN", - .probe = mpc86xx_hpcn_probe, - .setup_arch = mpc86xx_hpcn_setup_arch, - .init_IRQ = mpc86xx_hpcn_init_irq, - .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = mpc86xx_restart, - .time_init = mpc86xx_time_init, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_pcie.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_pcie.c deleted file mode 100644 index a2f4f730213e..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_pcie.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Support for indirect PCI bridges. - * - * Copyright (C) 1998 Gabriel Paubert. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * "Temporary" MPC8548 Errata file - - * The standard indirect_pci code should work with future silicon versions. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mpc86xx.h" - -#define PCI_CFG_OUT out_be32 - -/* ERRATA PCI-Ex 14 PCIE Controller timeout */ -#define PCIE_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff) - - -static int -indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 *val) -{ - struct pci_controller *hose = bus->sysdata; - volatile void __iomem *cfg_data; - u32 temp; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* Possible artifact of CDCpp50937 needs further investigation */ - if (devfn != 0x0 && bus->number == 0xff) - return PCIBIOS_DEVICE_NOT_FOUND; - - PCIE_FIX; - if (bus->number == 0xff) { - PCI_CFG_OUT(hose->cfg_addr, - (0x80000000 | ((offset & 0xf00) << 16) | - ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) ))); - } else { - PCI_CFG_OUT(hose->cfg_addr, - (0x80000001 | ((offset & 0xf00) << 16) | - ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) ))); - } - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ - cfg_data = hose->cfg_data; - PCIE_FIX; - temp = in_le32(cfg_data); - switch (len) { - case 1: - *val = (temp >> (((offset & 3))*8)) & 0xff; - break; - case 2: - *val = (temp >> (((offset & 3))*8)) & 0xffff; - break; - default: - *val = temp; - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 val) -{ - struct pci_controller *hose = bus->sysdata; - volatile void __iomem *cfg_data; - u32 temp; - - if (ppc_md.pci_exclude_device) - if (ppc_md.pci_exclude_device(bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - - /* Possible artifact of CDCpp50937 needs further investigation */ - if (devfn != 0x0 && bus->number == 0xff) - return PCIBIOS_DEVICE_NOT_FOUND; - - PCIE_FIX; - if (bus->number == 0xff) { - PCI_CFG_OUT(hose->cfg_addr, - (0x80000000 | ((offset & 0xf00) << 16) | - ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) ))); - } else { - PCI_CFG_OUT(hose->cfg_addr, - (0x80000001 | ((offset & 0xf00) << 16) | - ((bus->number - hose->bus_offset) << 16) - | (devfn << 8) | ((offset & 0xfc) ))); - } - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ - cfg_data = hose->cfg_data; - switch (len) { - case 1: - PCIE_FIX; - temp = in_le32(cfg_data); - temp = (temp & ~(0xff << ((offset & 3) * 8))) | - (val << ((offset & 3) * 8)); - PCIE_FIX; - out_le32(cfg_data, temp); - break; - case 2: - PCIE_FIX; - temp = in_le32(cfg_data); - temp = (temp & ~(0xffff << ((offset & 3) * 8))); - temp |= (val << ((offset & 3) * 8)) ; - PCIE_FIX; - out_le32(cfg_data, temp); - break; - default: - PCIE_FIX; - out_le32(cfg_data, val); - break; - } - PCIE_FIX; - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops indirect_pcie_ops = { - indirect_read_config_pcie, - indirect_write_config_pcie -}; - -void __init -setup_indirect_pcie_nomap(struct pci_controller* hose, void __iomem * cfg_addr, - void __iomem * cfg_data) -{ - hose->cfg_addr = cfg_addr; - hose->cfg_data = cfg_data; - hose->ops = &indirect_pcie_ops; -} - -void __init -setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) -{ - unsigned long base = cfg_addr & PAGE_MASK; - void __iomem *mbase, *addr, *data; - - mbase = ioremap(base, PAGE_SIZE); - addr = mbase + (cfg_addr & ~PAGE_MASK); - if ((cfg_data & PAGE_MASK) != base) - mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); - data = mbase + (cfg_data & ~PAGE_MASK); - setup_indirect_pcie_nomap(hose, addr, data); -} diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c deleted file mode 100644 index 944ec4b71416..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Author: Xianghua Xiao - * Zhang Wei - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "mpc86xx.h" - -extern void __secondary_start_mpc86xx(void); -extern unsigned long __secondary_hold_acknowledge; - - -static void __init -smp_86xx_release_core(int nr) -{ - void *mcm_vaddr; - unsigned long vaddr, pcr; - - if (nr < 0 || nr >= NR_CPUS) - return; - - /* - * Startup Core #nr. - */ - mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, - MPC86xx_MCM_SIZE); - vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; - pcr = in_be32((volatile unsigned *)vaddr); - pcr |= 1 << (nr + 24); - out_be32((volatile unsigned *)vaddr, pcr); -} - - -static void __init -smp_86xx_kick_cpu(int nr) -{ - unsigned int save_vector; - unsigned long target, flags; - int n = 0; - volatile unsigned int *vector - = (volatile unsigned int *)(KERNELBASE + 0x100); - - if (nr < 0 || nr >= NR_CPUS) - return; - - pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr); - - local_irq_save(flags); - local_irq_disable(); - - /* Save reset vector */ - save_vector = *vector; - - /* Setup fake reset vector to call __secondary_start_mpc86xx. */ - target = (unsigned long) __secondary_start_mpc86xx; - create_branch((unsigned long)vector, target, BRANCH_SET_LINK); - - /* Kick that CPU */ - smp_86xx_release_core(nr); - - /* Wait a bit for the CPU to take the exception. */ - while ((__secondary_hold_acknowledge != nr) && (n++, n < 1000)) - mdelay(1); - - /* Restore the exception vector */ - *vector = save_vector; - flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); - - local_irq_restore(flags); - - pr_debug("wait CPU #%d for %d msecs.\n", nr, n); -} - - -static void __init -smp_86xx_setup_cpu(int cpu_nr) -{ - mpic_setup_this_cpu(); -} - - -struct smp_ops_t smp_86xx_ops = { - .message_pass = smp_mpic_message_pass, - .probe = smp_mpic_probe, - .kick_cpu = smp_86xx_kick_cpu, - .setup_cpu = smp_86xx_setup_cpu, - .take_timebase = smp_generic_take_timebase, - .give_timebase = smp_generic_give_timebase, -}; - - -void __init -mpc86xx_smp_init(void) -{ - smp_ops = &smp_86xx_ops; -} diff --git a/trunk/arch/powerpc/platforms/86xx/pci.c b/trunk/arch/powerpc/platforms/86xx/pci.c deleted file mode 100644 index 5180df7c75bc..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/pci.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * MPC86XX pci setup code - * - * Recode: ZHANG WEI - * Initial author: Xianghua Xiao - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "mpc86xx.h" - -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) -#else -#define DBG(fmt, args...) -#endif - -struct pcie_outbound_window_regs { - uint pexotar; /* 0x.0 - PCI Express outbound translation address register */ - uint pexotear; /* 0x.4 - PCI Express outbound translation extended address register */ - uint pexowbar; /* 0x.8 - PCI Express outbound window base address register */ - char res1[4]; - uint pexowar; /* 0x.10 - PCI Express outbound window attributes register */ - char res2[12]; -}; - -struct pcie_inbound_window_regs { - uint pexitar; /* 0x.0 - PCI Express inbound translation address register */ - char res1[4]; - uint pexiwbar; /* 0x.8 - PCI Express inbound window base address register */ - uint pexiwbear; /* 0x.c - PCI Express inbound window base extended address register */ - uint pexiwar; /* 0x.10 - PCI Express inbound window attributes register */ - char res2[12]; -}; - -static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource *rsrc) -{ - volatile struct ccsr_pex *pcie; - volatile struct pcie_outbound_window_regs *pcieow; - volatile struct pcie_inbound_window_regs *pcieiw; - int i = 0; - - DBG("PCIE memory map start 0x%x, size 0x%x\n", rsrc->start, - rsrc->end - rsrc->start + 1); - pcie = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); - - /* Disable all windows (except pexowar0 since its ignored) */ - pcie->pexowar1 = 0; - pcie->pexowar2 = 0; - pcie->pexowar3 = 0; - pcie->pexowar4 = 0; - pcie->pexiwar1 = 0; - pcie->pexiwar2 = 0; - pcie->pexiwar3 = 0; - - pcieow = (struct pcie_outbound_window_regs *)&pcie->pexotar1; - pcieiw = (struct pcie_inbound_window_regs *)&pcie->pexitar1; - - /* Setup outbound MEM window */ - for(i = 0; i < 3; i++) - if (hose->mem_resources[i].flags & IORESOURCE_MEM){ - DBG("PCIE MEM resource start 0x%08x, size 0x%08x.\n", - hose->mem_resources[i].start, - hose->mem_resources[i].end - - hose->mem_resources[i].start + 1); - pcieow->pexotar = (hose->mem_resources[i].start) >> 12 - & 0x000fffff; - pcieow->pexotear = 0; - pcieow->pexowbar = (hose->mem_resources[i].start) >> 12 - & 0x000fffff; - /* Enable, Mem R/W */ - pcieow->pexowar = 0x80044000 | - (__ilog2(hose->mem_resources[i].end - - hose->mem_resources[i].start + 1) - - 1); - pcieow++; - } - - /* Setup outbound IO window */ - if (hose->io_resource.flags & IORESOURCE_IO){ - DBG("PCIE IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n", - hose->io_resource.start, - hose->io_resource.end - hose->io_resource.start + 1, - hose->io_base_phys); - pcieow->pexotar = (hose->io_resource.start) >> 12 & 0x000fffff; - pcieow->pexotear = 0; - pcieow->pexowbar = (hose->io_base_phys) >> 12 & 0x000fffff; - /* Enable, IO R/W */ - pcieow->pexowar = 0x80088000 | (__ilog2(hose->io_resource.end - - hose->io_resource.start + 1) - 1); - } - - /* Setup 2G inbound Memory Window @ 0 */ - pcieiw->pexitar = 0x00000000; - pcieiw->pexiwbar = 0x00000000; - /* Enable, Prefetch, Local Mem, Snoop R/W, 2G */ - pcieiw->pexiwar = 0xa0f5501e; -} - -static void __init -mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) -{ - volatile struct ccsr_pex *pcie; - u16 cmd; - unsigned int temps; - - DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", - pcie_offset, pcie_size); - - pcie = ioremap(pcie_offset, pcie_size); - - early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY - | PCI_COMMAND_IO; - early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd); - - early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); - - /* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */ - early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps); - temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16); - early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); -} - -int __init add_bridge(struct device_node *dev) -{ - int len; - struct pci_controller *hose; - struct resource rsrc; - int *bus_range; - int has_address = 0; - int primary = 0; - - DBG("Adding PCIE host bridge %s\n", dev->full_name); - - /* Fetch host bridge registers address */ - has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); - - /* Get bus range if any */ - bus_range = (int *) get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); - - hose = pcibios_alloc_controller(); - if (!hose) - return -ENOMEM; - hose->arch_data = dev; - hose->set_cfg_type = 1; - - /* last_busno = 0xfe cause by MPC8641 PCIE bug */ - hose->first_busno = bus_range ? bus_range[0] : 0x0; - hose->last_busno = bus_range ? bus_range[1] : 0xfe; - - setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4); - - /* Setup the PCIE host controller. */ - mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1); - - if ((rsrc.start & 0xfffff) == 0x8000) - primary = 1; - - printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. " - "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); - - DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", - hose, hose->cfg_addr, hose->cfg_data); - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(hose, dev, primary); - - /* Setup PEX window registers */ - setup_pcie_atmu(hose, &rsrc); - - return 0; -} - -static void __devinit quirk_ali1575(struct pci_dev *dev) -{ - unsigned short temp; - - /* - * ALI1575 interrupts route table setup: - * - * IRQ pin IRQ# - * PIRQA ---- 3 - * PIRQB ---- 4 - * PIRQC ---- 5 - * PIRQD ---- 6 - * PIRQE ---- 9 - * PIRQF ---- 10 - * PIRQG ---- 11 - * PIRQH ---- 12 - * - * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD - * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA - */ - pci_write_config_dword(dev, 0x48, 0xb9317542); - - /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x86, 0x0c); - - /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x87, 0x0d); - - /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ - pci_write_config_byte(dev, 0x88, 0x0f); - - /* USB 2.0 controller, interrupt: PIRQ7 */ - pci_write_config_byte(dev, 0x74, 0x06); - - /* Audio controller, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x8a, 0x0c); - - /* Modem controller, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x8b, 0x0d); - - /* HD audio controller, interrupt: PIRQG */ - pci_write_config_byte(dev, 0x8c, 0x0e); - - /* Serial ATA interrupt: PIRQD */ - pci_write_config_byte(dev, 0x8d, 0x0b); - - /* SMB interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8e, 0x0f); - - /* PMU ACPI SCI interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8f, 0x0f); - - /* Primary PATA IDE IRQ: 14 - * Secondary PATA IDE IRQ: 15 - */ - pci_write_config_byte(dev, 0x44, 0x3d); - pci_write_config_byte(dev, 0x75, 0x0f); - - /* Set IRQ14 and IRQ15 to legacy IRQs */ - pci_read_config_word(dev, 0x46, &temp); - temp |= 0xc000; - pci_write_config_word(dev, 0x46, temp); - - /* Set i8259 interrupt trigger - * IRQ 3: Level - * IRQ 4: Level - * IRQ 5: Level - * IRQ 6: Level - * IRQ 7: Level - * IRQ 9: Level - * IRQ 10: Level - * IRQ 11: Level - * IRQ 12: Level - * IRQ 14: Edge - * IRQ 15: Edge - */ - outb(0xfa, 0x4d0); - outb(0x1e, 0x4d1); -} - -static void __devinit quirk_uli5288(struct pci_dev *dev) -{ - unsigned char c; - - pci_read_config_byte(dev,0x83,&c); - c |= 0x80; - pci_write_config_byte(dev, 0x83, c); - - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x0a, 0x06); - - pci_read_config_byte(dev,0x83,&c); - c &= 0x7f; - pci_write_config_byte(dev, 0x83, c); - - pci_read_config_byte(dev,0x84,&c); - c |= 0x01; - pci_write_config_byte(dev, 0x84, c); -} - -static void __devinit quirk_uli5229(struct pci_dev *dev) -{ - unsigned short temp; - pci_write_config_word(dev, 0x04, 0x0405); - pci_read_config_word(dev, 0x4a, &temp); - temp |= 0x1000; - pci_write_config_word(dev, 0x4a, temp); -} - -static void __devinit early_uli5249(struct pci_dev *dev) -{ - unsigned char temp; - pci_write_config_word(dev, 0x04, 0x0007); - pci_read_config_byte(dev, 0x7c, &temp); - pci_write_config_byte(dev, 0x7c, 0x80); - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x7c, temp); - dev->class |= 0x1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); diff --git a/trunk/arch/powerpc/platforms/Makefile b/trunk/arch/powerpc/platforms/Makefile index 292863694562..c4f6b0d2d140 100644 --- a/trunk/arch/powerpc/platforms/Makefile +++ b/trunk/arch/powerpc/platforms/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_83xx) += 83xx/ obj-$(CONFIG_PPC_85xx) += 85xx/ -obj-$(CONFIG_PPC_86xx) += 86xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9a..6a02d51086c8 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -5,24 +5,15 @@ config SPU_FS tristate "SPU file system" default m depends on PPC_CELL - select SPU_BASE help The SPU file system is used to access Synergistic Processing Units on machines implementing the Broadband Processor Architecture. -config SPU_BASE - bool - default n - config SPUFS_MMAP bool depends on SPU_FS && SPARSEMEM select MEMORY_HOTPLUG default y -config CBE_RAS - bool "RAS features for bare metal Cell BE" - default y - endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index c89cdd67383b..e570bad06394 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -1,15 +1,16 @@ -obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ - cbe_regs.o spider-pic.o pervasive.o -obj-$(CONFIG_CBE_RAS) += ras.o +obj-y += interrupt.o iommu.o setup.o spider-pic.o +obj-y += pervasive.o -ifeq ($(CONFIG_SMP),y) -obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o -endif +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ + +spu-base-y += spu_base.o spu_priv1.o # needed only when building loadable spufs.ko -spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o -spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o +spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o +obj-y += $(spufs-modular-m) + +# always needed in kernel +spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o +obj-y += $(spufs-builtin-y) $(spufs-builtin-m) -obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ - $(spufs-modular-m) \ - $(spu-priv1-y) spufs/ diff --git a/trunk/arch/powerpc/platforms/cell/cbe_regs.c b/trunk/arch/powerpc/platforms/cell/cbe_regs.c deleted file mode 100644 index ce696c1cca75..000000000000 --- a/trunk/arch/powerpc/platforms/cell/cbe_regs.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * cbe_regs.c - * - * Accessor routines for the various MMIO register blocks of the CBE - * - * (c) 2006 Benjamin Herrenschmidt , IBM Corp. - */ - - -#include -#include -#include - -#include -#include -#include -#include - -#include "cbe_regs.h" - -#define MAX_CBE 2 - -/* - * Current implementation uses "cpu" nodes. We build our own mapping - * array of cpu numbers to cpu nodes locally for now to allow interrupt - * time code to have a fast path rather than call of_get_cpu_node(). If - * we implement cpu hotplug, we'll have to install an appropriate norifier - * in order to release references to the cpu going away - */ -static struct cbe_regs_map -{ - struct device_node *cpu_node; - struct cbe_pmd_regs __iomem *pmd_regs; - struct cbe_iic_regs __iomem *iic_regs; -} cbe_regs_maps[MAX_CBE]; -static int cbe_regs_map_count; - -static struct cbe_thread_map -{ - struct device_node *cpu_node; - struct cbe_regs_map *regs; -} cbe_thread_map[NR_CPUS]; - -static struct cbe_regs_map *cbe_find_map(struct device_node *np) -{ - int i; - - for (i = 0; i < cbe_regs_map_count; i++) - if (cbe_regs_maps[i].cpu_node == np) - return &cbe_regs_maps[i]; - return NULL; -} - -struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) -{ - struct cbe_regs_map *map = cbe_find_map(np); - if (map == NULL) - return NULL; - return map->pmd_regs; -} - -struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) -{ - struct cbe_regs_map *map = cbe_thread_map[cpu].regs; - if (map == NULL) - return NULL; - return map->pmd_regs; -} - - -struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) -{ - struct cbe_regs_map *map = cbe_find_map(np); - if (map == NULL) - return NULL; - return map->iic_regs; -} -struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) -{ - struct cbe_regs_map *map = cbe_thread_map[cpu].regs; - if (map == NULL) - return NULL; - return map->iic_regs; -} - -void __init cbe_regs_init(void) -{ - int i; - struct device_node *cpu; - - /* Build local fast map of CPUs */ - for_each_possible_cpu(i) - cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL); - - /* Find maps for each device tree CPU */ - for_each_node_by_type(cpu, "cpu") { - struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; - - /* That hack must die die die ! */ - struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *prop; - - - if (cbe_regs_map_count > MAX_CBE) { - printk(KERN_ERR "cbe_regs: More BE chips than supported" - "!\n"); - cbe_regs_map_count--; - return; - } - map->cpu_node = cpu; - for_each_possible_cpu(i) - if (cbe_thread_map[i].cpu_node == cpu) - cbe_thread_map[i].regs = map; - - prop = (struct address_prop *)get_property(cpu, "pervasive", - NULL); - if (prop != NULL) - map->pmd_regs = ioremap(prop->address, prop->len); - - prop = (struct address_prop *)get_property(cpu, "iic", - NULL); - if (prop != NULL) - map->iic_regs = ioremap(prop->address, prop->len); - } -} - diff --git a/trunk/arch/powerpc/platforms/cell/cbe_regs.h b/trunk/arch/powerpc/platforms/cell/cbe_regs.h deleted file mode 100644 index e76e4a6af5bc..000000000000 --- a/trunk/arch/powerpc/platforms/cell/cbe_regs.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * cbe_regs.h - * - * This file is intended to hold the various register definitions for CBE - * on-chip system devices (memory controller, IO controller, etc...) - * - * (c) 2006 Benjamin Herrenschmidt , IBM Corp. - */ - -#ifndef CBE_REGS_H -#define CBE_REGS_H - -/* - * - * Some HID register definitions - * - */ - -/* CBE specific HID0 bits */ -#define HID0_CBE_THERM_WAKEUP 0x0000020000000000ul -#define HID0_CBE_SYSERR_WAKEUP 0x0000008000000000ul -#define HID0_CBE_THERM_INT_EN 0x0000000400000000ul -#define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul - - -/* - * - * Pervasive unit register definitions - * - */ - -struct cbe_pmd_regs { - u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ - - /* Thermal Sensor Registers */ - u64 ts_ctsr1; /* 0x0800 */ - u64 ts_ctsr2; /* 0x0808 */ - u64 ts_mtsr1; /* 0x0810 */ - u64 ts_mtsr2; /* 0x0818 */ - u64 ts_itr1; /* 0x0820 */ - u64 ts_itr2; /* 0x0828 */ - u64 ts_gitr; /* 0x0830 */ - u64 ts_isr; /* 0x0838 */ - u64 ts_imr; /* 0x0840 */ - u64 tm_cr1; /* 0x0848 */ - u64 tm_cr2; /* 0x0850 */ - u64 tm_simr; /* 0x0858 */ - u64 tm_tpr; /* 0x0860 */ - u64 tm_str1; /* 0x0868 */ - u64 tm_str2; /* 0x0870 */ - u64 tm_tsr; /* 0x0878 */ - - /* Power Management */ - u64 pm_control; /* 0x0880 */ -#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000 - u64 pm_status; /* 0x0888 */ - - /* Time Base Register */ - u64 tbr; /* 0x0890 */ - - u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */ - - /* Fault Isolation Registers */ - u64 checkstop_fir; /* 0x0c00 */ - u64 recoverable_fir; - u64 spec_att_mchk_fir; - u64 fir_mode_reg; - u64 fir_enable_mask; - - u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ -}; - -extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); -extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu); - -/* - * - * IIC unit register definitions - * - */ - -struct cbe_iic_pending_bits { - u32 data; - u8 flags; - u8 class; - u8 source; - u8 prio; -}; - -#define CBE_IIC_IRQ_VALID 0x80 -#define CBE_IIC_IRQ_IPI 0x40 - -struct cbe_iic_thread_regs { - struct cbe_iic_pending_bits pending; - struct cbe_iic_pending_bits pending_destr; - u64 generate; - u64 prio; -}; - -struct cbe_iic_regs { - u8 pad_0x0000_0x0400[0x0400 - 0x0000]; /* 0x0000 */ - - /* IIC interrupt registers */ - struct cbe_iic_thread_regs thread[2]; /* 0x0400 */ - u64 iic_ir; /* 0x0440 */ - u64 iic_is; /* 0x0448 */ - - u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */ - - /* IOC FIR */ - u64 ioc_fir_reset; /* 0x0500 */ - u64 ioc_fir_set; - u64 ioc_checkstop_enable; - u64 ioc_fir_error_mask; - u64 ioc_syserr_enable; - u64 ioc_fir; - - u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */ -}; - -extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np); -extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu); - - -/* Init this module early */ -extern void cbe_regs_init(void); - - -#endif /* CBE_REGS_H */ diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 1bbf822b4efc..978be1c30c1b 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -33,10 +33,29 @@ #include #include "interrupt.h" -#include "cbe_regs.h" + +struct iic_pending_bits { + u32 data; + u8 flags; + u8 class; + u8 source; + u8 prio; +}; + +enum iic_pending_flags { + IIC_VALID = 0x80, + IIC_IPI = 0x40, +}; + +struct iic_regs { + struct iic_pending_bits pending; + struct iic_pending_bits pending_destr; + u64 generate; + u64 prio; +}; struct iic { - struct cbe_iic_thread_regs __iomem *regs; + struct iic_regs __iomem *regs; u8 target_id; }; @@ -96,7 +115,7 @@ static struct hw_interrupt_type iic_pic = { .end = iic_end, }; -static int iic_external_get_irq(struct cbe_iic_pending_bits pending) +static int iic_external_get_irq(struct iic_pending_bits pending) { int irq; unsigned char node, unit; @@ -117,7 +136,8 @@ static int iic_external_get_irq(struct cbe_iic_pending_bits pending) * One of these units can be connected * to an external interrupt controller. */ - if (pending.class != 2) + if (pending.prio > 0x3f || + pending.class != 2) break; irq = IIC_EXT_OFFSET + spider_get_irq(node) @@ -148,15 +168,15 @@ int iic_get_irq(struct pt_regs *regs) { struct iic *iic; int irq; - struct cbe_iic_pending_bits pending; + struct iic_pending_bits pending; iic = &__get_cpu_var(iic); *(unsigned long *) &pending = in_be64((unsigned long __iomem *) &iic->regs->pending_destr); irq = -1; - if (pending.flags & CBE_IIC_IRQ_VALID) { - if (pending.flags & CBE_IIC_IRQ_IPI) { + if (pending.flags & IIC_VALID) { + if (pending.flags & IIC_IPI) { irq = IIC_IPI_OFFSET + (pending.prio >> 4); /* if (irq > 0x80) @@ -180,7 +200,7 @@ static int setup_iic_hardcoded(void) unsigned long regs; struct iic *iic; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { iic = &per_cpu(iic, cpu); nodeid = cpu/2; @@ -206,7 +226,7 @@ static int setup_iic_hardcoded(void) regs += 0x20; printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); - iic->regs = ioremap(regs, sizeof(struct cbe_iic_thread_regs)); + iic->regs = ioremap(regs, sizeof(struct iic_regs)); iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); } @@ -247,12 +267,12 @@ static int setup_iic(void) } iic = &per_cpu(iic, np[0]); - iic->regs = ioremap(regs[0], sizeof(struct cbe_iic_thread_regs)); + iic->regs = ioremap(regs[0], sizeof(struct iic_regs)); iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); iic = &per_cpu(iic, np[1]); - iic->regs = ioremap(regs[2], sizeof(struct cbe_iic_thread_regs)); + iic->regs = ioremap(regs[2], sizeof(struct iic_regs)); iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index a35004e14c69..a49ceb799a8e 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -473,16 +473,6 @@ static int cell_dma_supported(struct device *dev, u64 mask) return mask < 0x100000000ull; } -static struct dma_mapping_ops cell_iommu_ops = { - .alloc_coherent = cell_alloc_coherent, - .free_coherent = cell_free_coherent, - .map_single = cell_map_single, - .unmap_single = cell_unmap_single, - .map_sg = cell_map_sg, - .unmap_sg = cell_unmap_sg, - .dma_supported = cell_dma_supported, -}; - void cell_init_iommu(void) { int setup_bus = 0; @@ -508,5 +498,11 @@ void cell_init_iommu(void) } } - pci_dma_ops = cell_iommu_ops; + pci_dma_ops.alloc_coherent = cell_alloc_coherent; + pci_dma_ops.free_coherent = cell_free_coherent; + pci_dma_ops.map_single = cell_map_single; + pci_dma_ops.unmap_single = cell_unmap_single; + pci_dma_ops.map_sg = cell_map_sg; + pci_dma_ops.unmap_sg = cell_unmap_sg; + pci_dma_ops.dma_supported = cell_dma_supported; } diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index 695ac4e1617e..7eed8c624517 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -37,28 +37,36 @@ #include #include "pervasive.h" -#include "cbe_regs.h" static DEFINE_SPINLOCK(cbe_pervasive_lock); +struct cbe_pervasive { + struct pmd_regs __iomem *regs; + unsigned int thread; +}; + +/* can't use per_cpu from setup_arch */ +static struct cbe_pervasive cbe_pervasive[NR_CPUS]; static void __init cbe_enable_pause_zero(void) { unsigned long thread_switch_control; unsigned long temp_register; - struct cbe_pmd_regs __iomem *pregs; + struct cbe_pervasive *p; + int thread; spin_lock_irq(&cbe_pervasive_lock); - pregs = cbe_get_cpu_pmd_regs(smp_processor_id()); - if (pregs == NULL) + p = &cbe_pervasive[smp_processor_id()]; + + if (!cbe_pervasive->regs) goto out; pr_debug("Power Management: CPU %d\n", smp_processor_id()); /* Enable Pause(0) control bit */ - temp_register = in_be64(&pregs->pm_control); + temp_register = in_be64(&p->regs->pm_control); - out_be64(&pregs->pm_control, - temp_register | CBE_PMD_PAUSE_ZERO_CONTROL); + out_be64(&p->regs->pm_control, + temp_register|PMD_PAUSE_ZERO_CONTROL); /* Enable DEC and EE interrupt request */ thread_switch_control = mfspr(SPRN_TSC_CELL); @@ -67,16 +75,25 @@ static void __init cbe_enable_pause_zero(void) switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { case CTRL_CT0: thread_switch_control |= TSC_CELL_DEC_ENABLE_0; + thread = 0; break; case CTRL_CT1: thread_switch_control |= TSC_CELL_DEC_ENABLE_1; + thread = 1; break; default: printk(KERN_WARNING "%s: unknown configuration\n", __FUNCTION__); + thread = -1; break; } + if (p->thread != thread) + printk(KERN_WARNING "%s: device tree inconsistant, " + "cpu %i: %d/%d\n", __FUNCTION__, + smp_processor_id(), + p->thread, thread); + mtspr(SPRN_TSC_CELL, thread_switch_control); out: @@ -87,11 +104,6 @@ static void cbe_idle(void) { unsigned long ctrl; - /* Why do we do that on every idle ? Couldn't that be done once for - * all or do we lose the state some way ? Also, the pm_control - * register setting, that can't be set once at boot ? We really want - * to move that away in order to implement a simple powersave - */ cbe_enable_pause_zero(); while (1) { @@ -140,15 +152,8 @@ static int cbe_system_reset_exception(struct pt_regs *regs) timer_interrupt(regs); break; case SRR1_WAKEMT: + /* no action required */ break; -#ifdef CONFIG_CBE_RAS - case SRR1_WAKESYSERR: - cbe_system_error_exception(regs); - break; - case SRR1_WAKETHERM: - cbe_thermal_exception(regs); - break; -#endif /* CONFIG_CBE_RAS */ default: /* do system reset */ return 0; @@ -157,11 +162,68 @@ static int cbe_system_reset_exception(struct pt_regs *regs) return 1; } -void __init cbe_pervasive_init(void) +static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p) +{ + struct device_node *node; + unsigned int *int_servers; + char *addr; + unsigned long real_address; + unsigned int size; + + struct pmd_regs __iomem *pmd_mmio_area; + int hardid, thread; + int proplen; + + pmd_mmio_area = NULL; + hardid = get_hard_smp_processor_id(cpu); + for (node = NULL; (node = of_find_node_by_type(node, "cpu"));) { + int_servers = (void *) get_property(node, + "ibm,ppc-interrupt-server#s", &proplen); + if (!int_servers) { + printk(KERN_WARNING "%s misses " + "ibm,ppc-interrupt-server#s property", + node->full_name); + continue; + } + for (thread = 0; thread < proplen / sizeof (int); thread++) { + if (hardid == int_servers[thread]) { + addr = get_property(node, "pervasive", NULL); + goto found; + } + } + } + + printk(KERN_WARNING "%s: CPU %d not found\n", __FUNCTION__, cpu); + return -EINVAL; + +found: + real_address = *(unsigned long*) addr; + addr += sizeof (unsigned long); + size = *(unsigned int*) addr; + + pr_debug("pervasive area for CPU %d at %lx, size %x\n", + cpu, real_address, size); + p->regs = ioremap(real_address, size); + p->thread = thread; + return 0; +} + +void __init cell_pervasive_init(void) { + struct cbe_pervasive *p; + int cpu; + int ret; + if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) return; + for_each_possible_cpu(cpu) { + p = &cbe_pervasive[cpu]; + ret = cbe_find_pmd_mmio(cpu, p); + if (ret) + return; + } + ppc_md.idle_loop = cbe_idle; ppc_md.system_reset_exception = cbe_system_reset_exception; } diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.h b/trunk/arch/powerpc/platforms/cell/pervasive.h index 7b50947f8044..da1fb85ca3e8 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.h +++ b/trunk/arch/powerpc/platforms/cell/pervasive.h @@ -25,9 +25,38 @@ #ifndef PERVASIVE_H #define PERVASIVE_H -extern void cbe_pervasive_init(void); -extern void cbe_system_error_exception(struct pt_regs *regs); -extern void cbe_maintenance_exception(struct pt_regs *regs); -extern void cbe_thermal_exception(struct pt_regs *regs); +struct pmd_regs { + u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ + + /* Thermal Sensor Registers */ + u64 ts_ctsr1; /* 0x0800 */ + u64 ts_ctsr2; /* 0x0808 */ + u64 ts_mtsr1; /* 0x0810 */ + u64 ts_mtsr2; /* 0x0818 */ + u64 ts_itr1; /* 0x0820 */ + u64 ts_itr2; /* 0x0828 */ + u64 ts_gitr; /* 0x0830 */ + u64 ts_isr; /* 0x0838 */ + u64 ts_imr; /* 0x0840 */ + u64 tm_cr1; /* 0x0848 */ + u64 tm_cr2; /* 0x0850 */ + u64 tm_simr; /* 0x0858 */ + u64 tm_tpr; /* 0x0860 */ + u64 tm_str1; /* 0x0868 */ + u64 tm_str2; /* 0x0870 */ + u64 tm_tsr; /* 0x0878 */ + + /* Power Management */ + u64 pm_control; /* 0x0880 */ +#define PMD_PAUSE_ZERO_CONTROL 0x10000 + u64 pm_status; /* 0x0888 */ + + /* Time Base Register */ + u64 tbr; /* 0x0890 */ + + u8 pad_0x0898_0x1000 [0x1000 - 0x0898]; /* 0x0898 */ +}; + +void __init cell_pervasive_init(void); #endif diff --git a/trunk/arch/powerpc/platforms/cell/ras.c b/trunk/arch/powerpc/platforms/cell/ras.c deleted file mode 100644 index 033ad6e2827b..000000000000 --- a/trunk/arch/powerpc/platforms/cell/ras.c +++ /dev/null @@ -1,112 +0,0 @@ -#define DEBUG - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ras.h" -#include "cbe_regs.h" - - -static void dump_fir(int cpu) -{ - struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu); - struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu); - - if (pregs == NULL) - return; - - /* Todo: do some nicer parsing of bits and based on them go down - * to other sub-units FIRs and not only IIC - */ - printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n", - in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n", - in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n", - in_be64(&pregs->spec_att_mchk_fir)); - - if (iregs == NULL) - return; - printk(KERN_ERR "IOC FIR : 0x%016lx\n", - in_be64(&iregs->ioc_fir)); - -} - -void cbe_system_error_exception(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu); - dump_fir(cpu); - dump_stack(); -} - -void cbe_maintenance_exception(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - /* - * Nothing implemented for the maintenance interrupt at this point - */ - - printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu); - dump_stack(); -} - -void cbe_thermal_exception(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - /* - * Nothing implemented for the thermal interrupt at this point - */ - - printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu); - dump_stack(); -} - -static int cbe_machine_check_handler(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu); - dump_fir(cpu); - - /* No recovery from this code now, lets continue */ - return 0; -} - -void __init cbe_ras_init(void) -{ - unsigned long hid0; - - /* - * Enable System Error & thermal interrupts and wakeup conditions - */ - - hid0 = mfspr(SPRN_HID0); - hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP | - HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP; - mtspr(SPRN_HID0, hid0); - mb(); - - /* - * Install machine check handler. Leave setting of precise mode to - * what the firmware did for now - */ - ppc_md.machine_check_exception = cbe_machine_check_handler; - mb(); - - /* - * For now, we assume that IOC_FIR is already set to forward some - * error conditions to the System Error handler. If that is not true - * then it will have to be fixed up here. - */ -} diff --git a/trunk/arch/powerpc/platforms/cell/ras.h b/trunk/arch/powerpc/platforms/cell/ras.h deleted file mode 100644 index eb7ee54c82a0..000000000000 --- a/trunk/arch/powerpc/platforms/cell/ras.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RAS_H -#define RAS_H - -extern void cbe_system_error_exception(struct pt_regs *regs); -extern void cbe_maintenance_exception(struct pt_regs *regs); -extern void cbe_thermal_exception(struct pt_regs *regs); -extern void cbe_ras_init(void); - -#endif /* RAS_H */ diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index 3d1831d331e5..fd3e5609e3e0 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -49,13 +49,10 @@ #include #include #include -#include #include "interrupt.h" #include "iommu.h" -#include "cbe_regs.h" #include "pervasive.h" -#include "ras.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -84,15 +81,6 @@ static void __init cell_setup_arch(void) { ppc_md.init_IRQ = iic_init_IRQ; ppc_md.get_irq = iic_get_irq; -#ifdef CONFIG_SPU_BASE - spu_priv1_ops = &spu_priv1_mmio_ops; -#endif - - cbe_regs_init(); - -#ifdef CONFIG_CBE_RAS - cbe_ras_init(); -#endif #ifdef CONFIG_SMP smp_init_cell(); @@ -110,7 +98,7 @@ static void __init cell_setup_arch(void) init_pci_config_tokens(); find_and_init_phbs(); spider_init_IRQ(); - cbe_pervasive_init(); + cell_pervasive_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2c..ad141fe8d52d 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -34,15 +34,10 @@ #include #include #include -#include #include #include "interrupt.h" -const struct spu_priv1_ops *spu_priv1_ops; - -EXPORT_SYMBOL_GPL(spu_priv1_ops); - static int __spu_trap_invalid_dma(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); @@ -76,7 +71,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) { struct spu_priv2 __iomem *priv2 = spu->priv2; struct mm_struct *mm = spu->mm; - u64 esid, vsid, llp; + u64 esid, vsid; pr_debug("%s\n", __FUNCTION__); @@ -96,14 +91,9 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) } esid = (ea & ESID_MASK) | SLB_ESID_V; -#ifdef CONFIG_HUGETLB_PAGE + vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | SLB_VSID_USER; if (in_hugepage_area(mm->context, ea)) - llp = mmu_psize_defs[mmu_huge_psize].sllp; - else -#endif - llp = mmu_psize_defs[mmu_virtual_psize].sllp; - vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | - SLB_VSID_USER | llp; + vsid |= SLB_VSID_L; out_be64(&priv2->slb_index_W, spu->slb_replace); out_be64(&priv2->slb_vsid_RW, vsid); @@ -140,7 +130,57 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) spu->dar = ea; spu->dsisr = dsisr; mb(); - spu->stop_callback(spu); + if (spu->stop_callback) + spu->stop_callback(spu); + return 0; +} + +static int __spu_trap_mailbox(struct spu *spu) +{ + if (spu->ibox_callback) + spu->ibox_callback(spu); + + /* atomically disable SPU mailbox interrupts */ + spin_lock(&spu->register_lock); + spu_int_mask_and(spu, 2, ~0x1); + spin_unlock(&spu->register_lock); + return 0; +} + +static int __spu_trap_stop(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + spu->stop_code = in_be32(&spu->problem->spu_status_R); + if (spu->stop_callback) + spu->stop_callback(spu); + return 0; +} + +static int __spu_trap_halt(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + spu->stop_code = in_be32(&spu->problem->spu_status_R); + if (spu->stop_callback) + spu->stop_callback(spu); + return 0; +} + +static int __spu_trap_tag_group(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + spu->mfc_callback(spu); + return 0; +} + +static int __spu_trap_spubox(struct spu *spu) +{ + if (spu->wbox_callback) + spu->wbox_callback(spu); + + /* atomically disable SPU mailbox interrupts */ + spin_lock(&spu->register_lock); + spu_int_mask_and(spu, 2, ~0x10); + spin_unlock(&spu->register_lock); return 0; } @@ -151,7 +191,8 @@ spu_irq_class_0(int irq, void *data, struct pt_regs *regs) spu = data; spu->class_0_pending = 1; - spu->stop_callback(spu); + if (spu->stop_callback) + spu->stop_callback(spu); return IRQ_HANDLED; } @@ -229,38 +270,29 @@ spu_irq_class_2(int irq, void *data, struct pt_regs *regs) unsigned long mask; spu = data; - spin_lock(&spu->register_lock); stat = spu_int_stat_get(spu, 2); mask = spu_int_mask_get(spu, 2); - /* ignore interrupts we're not waiting for */ - stat &= mask; - /* - * mailbox interrupts (0x1 and 0x10) are level triggered. - * mask them now before acknowledging. - */ - if (stat & 0x11) - spu_int_mask_and(spu, 2, ~(stat & 0x11)); - /* acknowledge all interrupts before the callbacks */ - spu_int_stat_clear(spu, 2, stat); - spin_unlock(&spu->register_lock); pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); + stat &= mask; + if (stat & 1) /* PPC core mailbox */ - spu->ibox_callback(spu); + __spu_trap_mailbox(spu); if (stat & 2) /* SPU stop-and-signal */ - spu->stop_callback(spu); + __spu_trap_stop(spu); if (stat & 4) /* SPU halted */ - spu->stop_callback(spu); + __spu_trap_halt(spu); if (stat & 8) /* DMA tag group complete */ - spu->mfc_callback(spu); + __spu_trap_tag_group(spu); if (stat & 0x10) /* SPU mailbox threshold */ - spu->wbox_callback(spu); + __spu_trap_spubox(spu); + spu_int_stat_clear(spu, 2, stat); return stat ? IRQ_HANDLED : IRQ_NONE; } @@ -480,6 +512,14 @@ int spu_irq_class_1_bottom(struct spu *spu) return ret; } +void spu_irq_setaffinity(struct spu *spu, int cpu) +{ + u64 target = iic_get_target_id(cpu); + u64 route = target << 48 | target << 32 | target << 16; + spu_int_route_set(spu, route); +} +EXPORT_SYMBOL_GPL(spu_irq_setaffinity); + static int __init find_spu_node_id(struct device_node *spe) { unsigned int *id; @@ -609,46 +649,6 @@ static int __init spu_map_device(struct spu *spu, struct device_node *node) return ret; } -struct sysdev_class spu_sysdev_class = { - set_kset_name("spu") -}; - -static ssize_t spu_show_isrc(struct sys_device *sysdev, char *buf) -{ - struct spu *spu = container_of(sysdev, struct spu, sysdev); - return sprintf(buf, "%d\n", spu->isrc); - -} -static SYSDEV_ATTR(isrc, 0400, spu_show_isrc, NULL); - -extern int attach_sysdev_to_node(struct sys_device *dev, int nid); - -static int spu_create_sysdev(struct spu *spu) -{ - int ret; - - spu->sysdev.id = spu->number; - spu->sysdev.cls = &spu_sysdev_class; - ret = sysdev_register(&spu->sysdev); - if (ret) { - printk(KERN_ERR "Can't register SPU %d with sysfs\n", - spu->number); - return ret; - } - - sysdev_create_file(&spu->sysdev, &attr_isrc); - sysfs_add_device_to_node(&spu->sysdev, spu->nid); - - return 0; -} - -static void spu_destroy_sysdev(struct spu *spu) -{ - sysdev_remove_file(&spu->sysdev, &attr_isrc); - sysfs_remove_device_from_node(&spu->sysdev, spu->nid); - sysdev_unregister(&spu->sysdev); -} - static int __init create_spu(struct device_node *spe) { struct spu *spu; @@ -656,7 +656,7 @@ static int __init create_spu(struct device_node *spe) static int number; ret = -ENOMEM; - spu = kzalloc(sizeof (*spu), GFP_KERNEL); + spu = kmalloc(sizeof (*spu), GFP_KERNEL); if (!spu) goto out; @@ -668,20 +668,33 @@ static int __init create_spu(struct device_node *spe) spu->nid = of_node_to_nid(spe); if (spu->nid == -1) spu->nid = 0; + + spu->stop_code = 0; + spu->slb_replace = 0; + spu->mm = NULL; + spu->ctx = NULL; + spu->rq = NULL; + spu->pid = 0; + spu->class_0_pending = 0; + spu->flags = 0UL; + spu->dar = 0UL; + spu->dsisr = 0UL; spin_lock_init(&spu->register_lock); + spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); spu_mfc_sr1_set(spu, 0x33); - mutex_lock(&spu_mutex); + spu->ibox_callback = NULL; + spu->wbox_callback = NULL; + spu->stop_callback = NULL; + spu->mfc_callback = NULL; + + mutex_lock(&spu_mutex); spu->number = number++; ret = spu_request_irqs(spu); if (ret) goto out_unmap; - ret = spu_create_sysdev(spu); - if (ret) - goto out_free_irqs; - list_add(&spu->list, &spu_list); mutex_unlock(&spu_mutex); @@ -690,9 +703,6 @@ static int __init create_spu(struct device_node *spe) spu->problem, spu->priv1, spu->priv2, spu->number); goto out; -out_free_irqs: - spu_free_irqs(spu); - out_unmap: mutex_unlock(&spu_mutex); spu_unmap(spu); @@ -706,7 +716,6 @@ static void destroy_spu(struct spu *spu) { list_del_init(&spu->list); - spu_destroy_sysdev(spu); spu_free_irqs(spu); spu_unmap(spu); kfree(spu); @@ -719,7 +728,6 @@ static void cleanup_spu_base(void) list_for_each_entry_safe(spu, tmp, &spu_list, list) destroy_spu(spu); mutex_unlock(&spu_mutex); - sysdev_class_unregister(&spu_sysdev_class); } module_exit(cleanup_spu_base); @@ -728,11 +736,6 @@ static int __init init_spu_base(void) struct device_node *node; int ret; - /* create sysdev class for spus */ - ret = sysdev_class_register(&spu_sysdev_class); - if (ret) - return ret; - ret = -ENODEV; for (node = of_find_node_by_type(NULL, "spe"); node; node = of_find_node_by_type(node, "spe")) { diff --git a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c index 47ec3be3edcd..b47fcc5ddb78 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c @@ -34,19 +34,307 @@ */ void *spu_syscall_table[] = { -#define SYSCALL(func) sys_ni_syscall, -#define COMPAT_SYS(func) sys_ni_syscall, -#define PPC_SYS(func) sys_ni_syscall, -#define OLDSYS(func) sys_ni_syscall, -#define SYS32ONLY(func) sys_ni_syscall, -#define SYSX(f, f3264, f32) sys_ni_syscall, - -#define SYSCALL_SPU(func) sys_##func, -#define COMPAT_SYS_SPU(func) sys_##func, -#define PPC_SYS_SPU(func) ppc_##func, -#define SYSX_SPU(f, f3264, f32) f, - -#include + [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */ + [__NR_exit] sys_ni_syscall, /* sys_exit */ + [__NR_fork] sys_ni_syscall, /* ppc_fork */ + [__NR_read] sys_read, + [__NR_write] sys_write, + [__NR_open] sys_open, + [__NR_close] sys_close, + [__NR_waitpid] sys_waitpid, + [__NR_creat] sys_creat, + [__NR_link] sys_link, + [__NR_unlink] sys_unlink, + [__NR_execve] sys_ni_syscall, /* sys_execve */ + [__NR_chdir] sys_chdir, + [__NR_time] sys_time, + [__NR_mknod] sys_mknod, + [__NR_chmod] sys_chmod, + [__NR_lchown] sys_lchown, + [__NR_break] sys_ni_syscall, + [__NR_oldstat] sys_ni_syscall, + [__NR_lseek] sys_lseek, + [__NR_getpid] sys_getpid, + [__NR_mount] sys_ni_syscall, /* sys_mount */ + [__NR_umount] sys_ni_syscall, + [__NR_setuid] sys_setuid, + [__NR_getuid] sys_getuid, + [__NR_stime] sys_stime, + [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */ + [__NR_alarm] sys_alarm, + [__NR_oldfstat] sys_ni_syscall, + [__NR_pause] sys_ni_syscall, /* sys_pause */ + [__NR_utime] sys_ni_syscall, /* sys_utime */ + [__NR_stty] sys_ni_syscall, + [__NR_gtty] sys_ni_syscall, + [__NR_access] sys_access, + [__NR_nice] sys_nice, + [__NR_ftime] sys_ni_syscall, + [__NR_sync] sys_sync, + [__NR_kill] sys_kill, + [__NR_rename] sys_rename, + [__NR_mkdir] sys_mkdir, + [__NR_rmdir] sys_rmdir, + [__NR_dup] sys_dup, + [__NR_pipe] sys_pipe, + [__NR_times] sys_times, + [__NR_prof] sys_ni_syscall, + [__NR_brk] sys_brk, + [__NR_setgid] sys_setgid, + [__NR_getgid] sys_getgid, + [__NR_signal] sys_ni_syscall, /* sys_signal */ + [__NR_geteuid] sys_geteuid, + [__NR_getegid] sys_getegid, + [__NR_acct] sys_ni_syscall, /* sys_acct */ + [__NR_umount2] sys_ni_syscall, /* sys_umount */ + [__NR_lock] sys_ni_syscall, + [__NR_ioctl] sys_ioctl, + [__NR_fcntl] sys_fcntl, + [__NR_mpx] sys_ni_syscall, + [__NR_setpgid] sys_setpgid, + [__NR_ulimit] sys_ni_syscall, + [__NR_oldolduname] sys_ni_syscall, + [__NR_umask] sys_umask, + [__NR_chroot] sys_chroot, + [__NR_ustat] sys_ni_syscall, /* sys_ustat */ + [__NR_dup2] sys_dup2, + [__NR_getppid] sys_getppid, + [__NR_getpgrp] sys_getpgrp, + [__NR_setsid] sys_setsid, + [__NR_sigaction] sys_ni_syscall, + [__NR_sgetmask] sys_sgetmask, + [__NR_ssetmask] sys_ssetmask, + [__NR_setreuid] sys_setreuid, + [__NR_setregid] sys_setregid, + [__NR_sigsuspend] sys_ni_syscall, + [__NR_sigpending] sys_ni_syscall, + [__NR_sethostname] sys_sethostname, + [__NR_setrlimit] sys_setrlimit, + [__NR_getrlimit] sys_ni_syscall, + [__NR_getrusage] sys_getrusage, + [__NR_gettimeofday] sys_gettimeofday, + [__NR_settimeofday] sys_settimeofday, + [__NR_getgroups] sys_getgroups, + [__NR_setgroups] sys_setgroups, + [__NR_select] sys_ni_syscall, + [__NR_symlink] sys_symlink, + [__NR_oldlstat] sys_ni_syscall, + [__NR_readlink] sys_readlink, + [__NR_uselib] sys_ni_syscall, /* sys_uselib */ + [__NR_swapon] sys_ni_syscall, /* sys_swapon */ + [__NR_reboot] sys_ni_syscall, /* sys_reboot */ + [__NR_readdir] sys_ni_syscall, + [__NR_mmap] sys_mmap, + [__NR_munmap] sys_munmap, + [__NR_truncate] sys_truncate, + [__NR_ftruncate] sys_ftruncate, + [__NR_fchmod] sys_fchmod, + [__NR_fchown] sys_fchown, + [__NR_getpriority] sys_getpriority, + [__NR_setpriority] sys_setpriority, + [__NR_profil] sys_ni_syscall, + [__NR_statfs] sys_ni_syscall, /* sys_statfs */ + [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */ + [__NR_ioperm] sys_ni_syscall, + [__NR_socketcall] sys_socketcall, + [__NR_syslog] sys_syslog, + [__NR_setitimer] sys_setitimer, + [__NR_getitimer] sys_getitimer, + [__NR_stat] sys_newstat, + [__NR_lstat] sys_newlstat, + [__NR_fstat] sys_newfstat, + [__NR_olduname] sys_ni_syscall, + [__NR_iopl] sys_ni_syscall, + [__NR_vhangup] sys_vhangup, + [__NR_idle] sys_ni_syscall, + [__NR_vm86] sys_ni_syscall, + [__NR_wait4] sys_wait4, + [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */ + [__NR_sysinfo] sys_sysinfo, + [__NR_ipc] sys_ni_syscall, /* sys_ipc */ + [__NR_fsync] sys_fsync, + [__NR_sigreturn] sys_ni_syscall, + [__NR_clone] sys_ni_syscall, /* ppc_clone */ + [__NR_setdomainname] sys_setdomainname, + [__NR_uname] ppc_newuname, + [__NR_modify_ldt] sys_ni_syscall, + [__NR_adjtimex] sys_adjtimex, + [__NR_mprotect] sys_mprotect, + [__NR_sigprocmask] sys_ni_syscall, + [__NR_create_module] sys_ni_syscall, + [__NR_init_module] sys_ni_syscall, /* sys_init_module */ + [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */ + [__NR_get_kernel_syms] sys_ni_syscall, + [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */ + [__NR_getpgid] sys_getpgid, + [__NR_fchdir] sys_fchdir, + [__NR_bdflush] sys_bdflush, + [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */ + [__NR_personality] ppc64_personality, + [__NR_afs_syscall] sys_ni_syscall, + [__NR_setfsuid] sys_setfsuid, + [__NR_setfsgid] sys_setfsgid, + [__NR__llseek] sys_llseek, + [__NR_getdents] sys_getdents, + [__NR__newselect] sys_select, + [__NR_flock] sys_flock, + [__NR_msync] sys_msync, + [__NR_readv] sys_readv, + [__NR_writev] sys_writev, + [__NR_getsid] sys_getsid, + [__NR_fdatasync] sys_fdatasync, + [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */ + [__NR_mlock] sys_mlock, + [__NR_munlock] sys_munlock, + [__NR_mlockall] sys_mlockall, + [__NR_munlockall] sys_munlockall, + [__NR_sched_setparam] sys_sched_setparam, + [__NR_sched_getparam] sys_sched_getparam, + [__NR_sched_setscheduler] sys_sched_setscheduler, + [__NR_sched_getscheduler] sys_sched_getscheduler, + [__NR_sched_yield] sys_sched_yield, + [__NR_sched_get_priority_max] sys_sched_get_priority_max, + [__NR_sched_get_priority_min] sys_sched_get_priority_min, + [__NR_sched_rr_get_interval] sys_sched_rr_get_interval, + [__NR_nanosleep] sys_nanosleep, + [__NR_mremap] sys_mremap, + [__NR_setresuid] sys_setresuid, + [__NR_getresuid] sys_getresuid, + [__NR_query_module] sys_ni_syscall, + [__NR_poll] sys_poll, + [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */ + [__NR_setresgid] sys_setresgid, + [__NR_getresgid] sys_getresgid, + [__NR_prctl] sys_prctl, + [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */ + [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */ + [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */ + [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */ + [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */ + [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */ + [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */ + [__NR_pread64] sys_pread64, + [__NR_pwrite64] sys_pwrite64, + [__NR_chown] sys_chown, + [__NR_getcwd] sys_getcwd, + [__NR_capget] sys_capget, + [__NR_capset] sys_capset, + [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */ + [__NR_sendfile] sys_sendfile64, + [__NR_getpmsg] sys_ni_syscall, + [__NR_putpmsg] sys_ni_syscall, + [__NR_vfork] sys_ni_syscall, /* ppc_vfork */ + [__NR_ugetrlimit] sys_getrlimit, + [__NR_readahead] sys_readahead, + [192] sys_ni_syscall, + [193] sys_ni_syscall, + [194] sys_ni_syscall, + [195] sys_ni_syscall, + [196] sys_ni_syscall, + [197] sys_ni_syscall, + [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */ + [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */ + [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */ + [__NR_multiplexer] sys_ni_syscall, + [__NR_getdents64] sys_getdents64, + [__NR_pivot_root] sys_pivot_root, + [204] sys_ni_syscall, + [__NR_madvise] sys_madvise, + [__NR_mincore] sys_mincore, + [__NR_gettid] sys_gettid, + [__NR_tkill] sys_tkill, + [__NR_setxattr] sys_setxattr, + [__NR_lsetxattr] sys_lsetxattr, + [__NR_fsetxattr] sys_fsetxattr, + [__NR_getxattr] sys_getxattr, + [__NR_lgetxattr] sys_lgetxattr, + [__NR_fgetxattr] sys_fgetxattr, + [__NR_listxattr] sys_listxattr, + [__NR_llistxattr] sys_llistxattr, + [__NR_flistxattr] sys_flistxattr, + [__NR_removexattr] sys_removexattr, + [__NR_lremovexattr] sys_lremovexattr, + [__NR_fremovexattr] sys_fremovexattr, + [__NR_futex] sys_futex, + [__NR_sched_setaffinity] sys_sched_setaffinity, + [__NR_sched_getaffinity] sys_sched_getaffinity, + [224] sys_ni_syscall, + [__NR_tuxcall] sys_ni_syscall, + [226] sys_ni_syscall, + [__NR_io_setup] sys_io_setup, + [__NR_io_destroy] sys_io_destroy, + [__NR_io_getevents] sys_io_getevents, + [__NR_io_submit] sys_io_submit, + [__NR_io_cancel] sys_io_cancel, + [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */ + [__NR_fadvise64] sys_fadvise64, + [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */ + [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */ + [__NR_epoll_create] sys_epoll_create, + [__NR_epoll_ctl] sys_epoll_ctl, + [__NR_epoll_wait] sys_epoll_wait, + [__NR_remap_file_pages] sys_remap_file_pages, + [__NR_timer_create] sys_timer_create, + [__NR_timer_settime] sys_timer_settime, + [__NR_timer_gettime] sys_timer_gettime, + [__NR_timer_getoverrun] sys_timer_getoverrun, + [__NR_timer_delete] sys_timer_delete, + [__NR_clock_settime] sys_clock_settime, + [__NR_clock_gettime] sys_clock_gettime, + [__NR_clock_getres] sys_clock_getres, + [__NR_clock_nanosleep] sys_clock_nanosleep, + [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */ + [__NR_tgkill] sys_tgkill, + [__NR_utimes] sys_utimes, + [__NR_statfs64] sys_statfs64, + [__NR_fstatfs64] sys_fstatfs64, + [254] sys_ni_syscall, + [__NR_rtas] ppc_rtas, + [256] sys_ni_syscall, + [257] sys_ni_syscall, + [258] sys_ni_syscall, + [__NR_mbind] sys_ni_syscall, /* sys_mbind */ + [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */ + [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */ + [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */ + [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */ + [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */ + [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */ + [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */ + [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */ + [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */ + [__NR_add_key] sys_ni_syscall, /* sys_add_key */ + [__NR_request_key] sys_ni_syscall, /* sys_request_key */ + [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */ + [__NR_waitid] sys_ni_syscall, /* sys_waitid */ + [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */ + [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */ + [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */ + [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */ + [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */ + [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */ + [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */ + [__NR_pselect6] sys_ni_syscall, /* sys_pselect */ + [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ + [__NR_unshare] sys_unshare, + [__NR_splice] sys_splice, + [__NR_tee] sys_tee, + [__NR_vmsplice] sys_vmsplice, + [__NR_openat] sys_openat, + [__NR_mkdirat] sys_mkdirat, + [__NR_mknodat] sys_mknodat, + [__NR_fchownat] sys_fchownat, + [__NR_futimesat] sys_futimesat, + [__NR_newfstatat] sys_newfstatat, + [__NR_unlinkat] sys_unlinkat, + [__NR_renameat] sys_renameat, + [__NR_linkat] sys_linkat, + [__NR_symlinkat] sys_symlinkat, + [__NR_readlinkat] sys_readlinkat, + [__NR_fchmodat] sys_fchmodat, + [__NR_faccessat] sys_faccessat, + [__NR_get_robust_list] sys_get_robust_list, + [__NR_set_robust_list] sys_set_robust_list, }; long spu_sys_callback(struct spu_syscall_block *s) diff --git a/trunk/arch/powerpc/platforms/cell/spu_priv1.c b/trunk/arch/powerpc/platforms/cell/spu_priv1.c new file mode 100644 index 000000000000..b2656421c7b5 --- /dev/null +++ b/trunk/arch/powerpc/platforms/cell/spu_priv1.c @@ -0,0 +1,133 @@ +/* + * access to SPU privileged registers + */ +#include + +#include +#include + +void spu_int_mask_and(struct spu *spu, int class, u64 mask) +{ + u64 old_mask; + + old_mask = in_be64(&spu->priv1->int_mask_RW[class]); + out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); +} +EXPORT_SYMBOL_GPL(spu_int_mask_and); + +void spu_int_mask_or(struct spu *spu, int class, u64 mask) +{ + u64 old_mask; + + old_mask = in_be64(&spu->priv1->int_mask_RW[class]); + out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); +} +EXPORT_SYMBOL_GPL(spu_int_mask_or); + +void spu_int_mask_set(struct spu *spu, int class, u64 mask) +{ + out_be64(&spu->priv1->int_mask_RW[class], mask); +} +EXPORT_SYMBOL_GPL(spu_int_mask_set); + +u64 spu_int_mask_get(struct spu *spu, int class) +{ + return in_be64(&spu->priv1->int_mask_RW[class]); +} +EXPORT_SYMBOL_GPL(spu_int_mask_get); + +void spu_int_stat_clear(struct spu *spu, int class, u64 stat) +{ + out_be64(&spu->priv1->int_stat_RW[class], stat); +} +EXPORT_SYMBOL_GPL(spu_int_stat_clear); + +u64 spu_int_stat_get(struct spu *spu, int class) +{ + return in_be64(&spu->priv1->int_stat_RW[class]); +} +EXPORT_SYMBOL_GPL(spu_int_stat_get); + +void spu_int_route_set(struct spu *spu, u64 route) +{ + out_be64(&spu->priv1->int_route_RW, route); +} +EXPORT_SYMBOL_GPL(spu_int_route_set); + +u64 spu_mfc_dar_get(struct spu *spu) +{ + return in_be64(&spu->priv1->mfc_dar_RW); +} +EXPORT_SYMBOL_GPL(spu_mfc_dar_get); + +u64 spu_mfc_dsisr_get(struct spu *spu) +{ + return in_be64(&spu->priv1->mfc_dsisr_RW); +} +EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get); + +void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr) +{ + out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); +} +EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set); + +void spu_mfc_sdr_set(struct spu *spu, u64 sdr) +{ + out_be64(&spu->priv1->mfc_sdr_RW, sdr); +} +EXPORT_SYMBOL_GPL(spu_mfc_sdr_set); + +void spu_mfc_sr1_set(struct spu *spu, u64 sr1) +{ + out_be64(&spu->priv1->mfc_sr1_RW, sr1); +} +EXPORT_SYMBOL_GPL(spu_mfc_sr1_set); + +u64 spu_mfc_sr1_get(struct spu *spu) +{ + return in_be64(&spu->priv1->mfc_sr1_RW); +} +EXPORT_SYMBOL_GPL(spu_mfc_sr1_get); + +void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id) +{ + out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); +} +EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set); + +u64 spu_mfc_tclass_id_get(struct spu *spu) +{ + return in_be64(&spu->priv1->mfc_tclass_id_RW); +} +EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get); + +void spu_tlb_invalidate(struct spu *spu) +{ + out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); +} +EXPORT_SYMBOL_GPL(spu_tlb_invalidate); + +void spu_resource_allocation_groupID_set(struct spu *spu, u64 id) +{ + out_be64(&spu->priv1->resource_allocation_groupID_RW, id); +} +EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set); + +u64 spu_resource_allocation_groupID_get(struct spu *spu) +{ + return in_be64(&spu->priv1->resource_allocation_groupID_RW); +} +EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get); + +void spu_resource_allocation_enable_set(struct spu *spu, u64 enable) +{ + out_be64(&spu->priv1->resource_allocation_enable_RW, enable); +} +EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set); + +u64 spu_resource_allocation_enable_get(struct spu *spu) +{ + return in_be64(&spu->priv1->resource_allocation_enable_RW); +} +EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get); diff --git a/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c deleted file mode 100644 index 71b69f0a1a48..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * spu hypervisor abstraction for direct hardware access. - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * Copyright 2006 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include - -#include "interrupt.h" - -static void int_mask_and(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); -} - -static void int_mask_or(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); -} - -static void int_mask_set(struct spu *spu, int class, u64 mask) -{ - out_be64(&spu->priv1->int_mask_RW[class], mask); -} - -static u64 int_mask_get(struct spu *spu, int class) -{ - return in_be64(&spu->priv1->int_mask_RW[class]); -} - -static void int_stat_clear(struct spu *spu, int class, u64 stat) -{ - out_be64(&spu->priv1->int_stat_RW[class], stat); -} - -static u64 int_stat_get(struct spu *spu, int class) -{ - return in_be64(&spu->priv1->int_stat_RW[class]); -} - -static void cpu_affinity_set(struct spu *spu, int cpu) -{ - u64 target = iic_get_target_id(cpu); - u64 route = target << 48 | target << 32 | target << 16; - out_be64(&spu->priv1->int_route_RW, route); -} - -static u64 mfc_dar_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_dar_RW); -} - -static u64 mfc_dsisr_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_dsisr_RW); -} - -static void mfc_dsisr_set(struct spu *spu, u64 dsisr) -{ - out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); -} - -static void mfc_sdr_set(struct spu *spu, u64 sdr) -{ - out_be64(&spu->priv1->mfc_sdr_RW, sdr); -} - -static void mfc_sr1_set(struct spu *spu, u64 sr1) -{ - out_be64(&spu->priv1->mfc_sr1_RW, sr1); -} - -static u64 mfc_sr1_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_sr1_RW); -} - -static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) -{ - out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); -} - -static u64 mfc_tclass_id_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_tclass_id_RW); -} - -static void tlb_invalidate(struct spu *spu) -{ - out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); -} - -static void resource_allocation_groupID_set(struct spu *spu, u64 id) -{ - out_be64(&spu->priv1->resource_allocation_groupID_RW, id); -} - -static u64 resource_allocation_groupID_get(struct spu *spu) -{ - return in_be64(&spu->priv1->resource_allocation_groupID_RW); -} - -static void resource_allocation_enable_set(struct spu *spu, u64 enable) -{ - out_be64(&spu->priv1->resource_allocation_enable_RW, enable); -} - -static u64 resource_allocation_enable_get(struct spu *spu) -{ - return in_be64(&spu->priv1->resource_allocation_enable_RW); -} - -const struct spu_priv1_ops spu_priv1_mmio_ops = -{ - .int_mask_and = int_mask_and, - .int_mask_or = int_mask_or, - .int_mask_set = int_mask_set, - .int_mask_get = int_mask_get, - .int_stat_clear = int_stat_clear, - .int_stat_get = int_stat_get, - .cpu_affinity_set = cpu_affinity_set, - .mfc_dar_get = mfc_dar_get, - .mfc_dsisr_get = mfc_dsisr_get, - .mfc_dsisr_set = mfc_dsisr_set, - .mfc_sdr_set = mfc_sdr_set, - .mfc_sr1_set = mfc_sr1_set, - .mfc_sr1_get = mfc_sr1_get, - .mfc_tclass_id_set = mfc_tclass_id_set, - .mfc_tclass_id_get = mfc_tclass_id_get, - .tlb_invalidate = tlb_invalidate, - .resource_allocation_groupID_set = resource_allocation_groupID_set, - .resource_allocation_groupID_get = resource_allocation_groupID_get, - .resource_allocation_enable_set = resource_allocation_enable_set, - .resource_allocation_enable_get = resource_allocation_enable_get, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/Makefile b/trunk/arch/powerpc/platforms/cell/spufs/Makefile index bb5dc634272c..a7cddf40e3d9 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/Makefile +++ b/trunk/arch/powerpc/platforms/cell/spufs/Makefile @@ -1,7 +1,5 @@ -obj-y += switch.o - obj-$(CONFIG_SPU_FS) += spufs.o -spufs-y += inode.o file.o context.o syscalls.o +spufs-y += inode.o file.o context.o switch.o syscalls.o spufs-y += sched.o backing_ops.o hw_ops.o run.o # Rules to build switch.o with the help of SPU tool chain @@ -10,14 +8,11 @@ SPU_CC := $(SPU_CROSS)gcc SPU_AS := $(SPU_CROSS)gcc SPU_LD := $(SPU_CROSS)ld SPU_OBJCOPY := $(SPU_CROSS)objcopy -SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ -SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ +SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -I$(objtree)/include2 +SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -I$(objtree)/include2 SPU_LDFLAGS := -N -Ttext=0x0 $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h -clean-files := spu_save_dump.h spu_restore_dump.h # Compile SPU files cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $< @@ -50,8 +45,7 @@ cmd_hexdump = ( \ echo " * Hex-dump auto generated from $*.c." ; \ echo " * Do not edit!" ; \ echo " */" ; \ - echo "static unsigned int $*_code[] " \ - "__attribute__((__aligned__(128))) = {" ; \ + echo "static unsigned int $*_code[] __page_aligned = {" ; \ hexdump -v -e '"0x" 4/1 "%02x" "," "\n"' $< ; \ echo "};" ; \ ) > $@ diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index 36439c5e9f2d..8bb33abfad17 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -30,7 +30,7 @@ struct spu_context *alloc_spu_context(void) { struct spu_context *ctx; - ctx = kzalloc(sizeof *ctx, GFP_KERNEL); + ctx = kmalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) goto out; /* Binding to physical processor deferred @@ -48,7 +48,17 @@ struct spu_context *alloc_spu_context(void) init_waitqueue_head(&ctx->wbox_wq); init_waitqueue_head(&ctx->stop_wq); init_waitqueue_head(&ctx->mfc_wq); + ctx->ibox_fasync = NULL; + ctx->wbox_fasync = NULL; + ctx->mfc_fasync = NULL; + ctx->mfc = NULL; + ctx->tagwait = 0; ctx->state = SPU_STATE_SAVED; + ctx->local_store = NULL; + ctx->cntl = NULL; + ctx->signal1 = NULL; + ctx->signal2 = NULL; + ctx->spu = NULL; ctx->ops = &spu_backing_ops; ctx->owner = get_task_mm(current); goto out; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 7854a380dce2..366185e92667 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -824,55 +824,6 @@ static u64 spufs_signal2_type_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu"); -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x0000); -} - -static struct vm_operations_struct spufs_mss_mmap_vmops = { - .nopage = spufs_mss_mmap_nopage, -}; - -/* - * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. - * Mapping this area requires that the application have CAP_SYS_RAWIO, - * as these registers require special care when read/writing. - */ -static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_mss_mmap_vmops; - return 0; -} -#endif - -static int spufs_mss_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - - file->private_data = i->i_ctx; - return nonseekable_open(inode, file); -} - -static struct file_operations spufs_mss_fops = { - .open = spufs_mss_open, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_mss_mmap, -#endif -}; - - #ifdef CONFIG_SPUFS_MMAP static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) @@ -1150,7 +1101,7 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) return mask; } -static int spufs_mfc_flush(struct file *file, fl_owner_t id) +static int spufs_mfc_flush(struct file *file) { struct spu_context *ctx = file->private_data; int ret; @@ -1176,7 +1127,7 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id) static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, int datasync) { - return spufs_mfc_flush(file, NULL); + return spufs_mfc_flush(file); } static int spufs_mfc_fasync(int fd, struct file *file, int on) @@ -1328,22 +1279,6 @@ static u64 spufs_srr0_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, "%llx\n") -static u64 spufs_id_get(void *data) -{ - struct spu_context *ctx = data; - u64 num; - - spu_acquire(ctx); - if (ctx->state == SPU_STATE_RUNNABLE) - num = ctx->spu->number; - else - num = (unsigned int)-1; - spu_release(ctx); - - return num; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n") - struct tree_descr spufs_dir_contents[] = { { "mem", &spufs_mem_fops, 0666, }, { "regs", &spufs_regs_fops, 0666, }, @@ -1357,7 +1292,6 @@ struct tree_descr spufs_dir_contents[] = { { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, - { "mss", &spufs_mss_fops, 0666, }, { "mfc", &spufs_mfc_fops, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, { "npc", &spufs_npc_ops, 0666, }, @@ -1367,6 +1301,5 @@ struct tree_descr spufs_dir_contents[] = { { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, { "srr0", &spufs_srr0_ops, 0666, }, - { "phys-id", &spufs_id_ops, 0666, }, {}, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c index ede2cac46b6d..a13a8b5a014d 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -32,7 +32,6 @@ #include #include -#include #include #include #include "spufs.h" diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 7b4572805db9..d9554199afa7 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -157,12 +157,20 @@ static void spufs_prune_dir(struct dentry *dir) mutex_unlock(&dir->d_inode->i_mutex); } -/* Caller must hold root->i_mutex */ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) { + struct spu_context *ctx; + /* remove all entries */ + mutex_lock(&root->i_mutex); spufs_prune_dir(dir_dentry); + mutex_unlock(&root->i_mutex); + + /* We have to give up the mm_struct */ + ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; + spu_forget(ctx); + /* XXX Do we need to hold i_mutex here ? */ return simple_rmdir(root, dir_dentry); } @@ -191,23 +199,16 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, static int spufs_dir_close(struct inode *inode, struct file *file) { - struct spu_context *ctx; struct inode *dir; struct dentry *dentry; int ret; dentry = file->f_dentry; dir = dentry->d_parent->d_inode; - ctx = SPUFS_I(dentry->d_inode)->i_ctx; - mutex_lock(&dir->i_mutex); ret = spufs_rmdir(dir, dentry); - mutex_unlock(&dir->i_mutex); WARN_ON(ret); - /* We have to give up the mm_struct */ - spu_forget(ctx); - return dcache_dir_close(inode, file); } @@ -304,10 +305,6 @@ long spufs_create_thread(struct nameidata *nd, nd->dentry != nd->dentry->d_sb->s_root) goto out; - /* all flags are reserved */ - if (flags) - goto out; - dentry = lookup_create(nd, 1); ret = PTR_ERR(dentry); if (IS_ERR(dentry)) @@ -327,13 +324,8 @@ long spufs_create_thread(struct nameidata *nd, * in error path of *_open(). */ ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); - if (ret < 0) { - WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry)); - mutex_unlock(&nd->dentry->d_inode->i_mutex); - spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); - dput(dentry); - goto out; - } + if (ret < 0) + spufs_rmdir(nd->dentry->d_inode, dentry); out_dput: dput(dentry); @@ -436,11 +428,11 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) return spufs_create_root(sb, data); } -static int +static struct super_block * spufs_get_sb(struct file_system_type *fstype, int flags, - const char *name, void *data, struct vfsmount *mnt) + const char *name, void *data) { - return get_sb_single(fstype, flags, data, spufs_fill_super, mnt); + return get_sb_single(fstype, flags, data, spufs_fill_super); } static struct file_system_type spufs_type = { diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index 3dcc5d8d66b9..bf652cd77000 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -43,7 +43,6 @@ #include #include #include -#include #include "spufs.h" #define SPU_MIN_TIMESLICE (100 * HZ / 1000) @@ -364,7 +363,7 @@ int spu_activate(struct spu_context *ctx, u64 flags) * We're likely to wait for interrupts on the same * CPU that we are now on, so send them here. */ - spu_cpu_affinity_set(spu, raw_smp_processor_id()); + spu_irq_setaffinity(spu, raw_smp_processor_id()); put_active_spu(spu); return 0; } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped index 15183d209b58..1b2355ff7036 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped +++ b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped @@ -3,901 +3,229 @@ * Hex-dump auto generated from spu_restore.c. * Do not edit! */ -static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { -0x40800000, -0x409ff801, -0x24000080, -0x24fd8081, -0x1cd80081, -0x33001180, -0x42030003, -0x33800284, -0x1c010204, -0x40200000, -0x40200000, -0x40200000, -0x34000190, -0x34004191, -0x34008192, -0x3400c193, -0x141fc205, -0x23fffd84, -0x1c100183, -0x217ffa85, -0x3080a000, -0x3080a201, -0x3080a402, -0x3080a603, -0x3080a804, -0x3080aa05, -0x3080ac06, -0x3080ae07, -0x3080b008, -0x3080b209, -0x3080b40a, -0x3080b60b, -0x3080b80c, -0x3080ba0d, -0x3080bc0e, -0x3080be0f, -0x00003ffc, -0x00000000, -0x00000000, -0x00000000, -0x01a00182, -0x3ec00083, -0xb0a14103, -0x01a00204, -0x3ec10082, -0x4202800e, -0x04000703, -0xb0a14202, -0x21a00803, -0x3fbf028d, -0x3f20068d, -0x3fbe0682, -0x3fe30102, -0x21a00882, -0x3f82028f, -0x3fe3078f, -0x3fbf0784, -0x3f200204, -0x3fbe0204, -0x3fe30204, -0x04000203, -0x21a00903, -0x40848002, -0x21a00982, -0x40800003, -0x21a00a03, -0x40802002, -0x21a00a82, -0x21a00083, -0x40800082, -0x21a00b02, -0x10002818, -0x42a00002, -0x32800007, -0x4207000c, -0x18008208, -0x40a0000b, -0x4080020a, -0x40800709, -0x00200000, -0x42070002, -0x3ac30384, -0x1cffc489, -0x00200000, -0x18008383, -0x38830382, -0x4cffc486, -0x3ac28185, -0xb0408584, -0x28830382, -0x1c020387, -0x38828182, -0xb0408405, -0x1802c408, -0x28828182, -0x217ff886, -0x04000583, -0x21a00803, -0x3fbe0682, -0x3fe30102, -0x04000106, -0x21a00886, -0x04000603, -0x21a00903, -0x40803c02, -0x21a00982, -0x40800003, -0x04000184, -0x21a00a04, -0x40802202, -0x21a00a82, -0x42028005, -0x34208702, -0x21002282, -0x21a00804, -0x21a00886, -0x3fbf0782, -0x3f200102, -0x3fbe0102, -0x3fe30102, -0x21a00902, -0x40804003, -0x21a00983, -0x21a00a04, -0x40805a02, -0x21a00a82, -0x40800083, -0x21a00b83, -0x01a00c02, -0x01a00d83, -0x3420c282, -0x21a00e02, -0x34210283, -0x21a00f03, -0x34200284, -0x77400200, -0x3421c282, -0x21a00702, -0x34218283, -0x21a00083, -0x34214282, -0x21a00b02, -0x4200480c, -0x00200000, -0x1c010286, -0x34220284, -0x34220302, -0x0f608203, -0x5c024204, -0x3b81810b, -0x42013c02, -0x00200000, -0x18008185, -0x38808183, -0x3b814182, -0x21004e84, -0x4020007f, -0x35000100, -0x000004e0, -0x000002a0, -0x000002e8, -0x00000428, -0x00000360, -0x000002e8, -0x000004a0, -0x00000468, -0x000003c8, -0x00000360, -0x409ffe02, -0x30801203, -0x40800204, -0x3ec40085, -0x10009c09, -0x3ac10606, -0xb060c105, -0x4020007f, -0x4020007f, -0x20801203, -0x38810602, -0xb0408586, -0x28810602, -0x32004180, -0x34204702, -0x21a00382, -0x4020007f, -0x327fdc80, -0x409ffe02, -0x30801203, -0x40800204, -0x3ec40087, -0x40800405, -0x00200000, -0x40800606, -0x3ac10608, -0x3ac14609, -0x3ac1860a, -0xb060c107, -0x20801203, -0x41004003, -0x38810602, -0x4020007f, -0xb0408188, -0x4020007f, -0x28810602, -0x41201002, -0x38814603, -0x10009c09, -0xb060c109, -0x4020007f, -0x28814603, -0x41193f83, -0x38818602, -0x60ffc003, -0xb040818a, -0x28818602, -0x32003080, -0x409ffe02, -0x30801203, -0x40800204, -0x3ec40087, -0x41201008, -0x10009c14, -0x40800405, -0x3ac10609, -0x40800606, -0x3ac1460a, -0xb060c107, -0x3ac1860b, -0x20801203, -0x38810602, -0xb0408409, -0x28810602, -0x38814603, -0xb060c40a, -0x4020007f, -0x28814603, -0x41193f83, -0x38818602, -0x60ffc003, -0xb040818b, -0x28818602, -0x32002380, -0x409ffe02, -0x30801204, -0x40800205, -0x3ec40083, -0x40800406, -0x3ac14607, -0x3ac18608, -0xb0810103, -0x41004002, -0x20801204, -0x4020007f, -0x38814603, -0x10009c0b, -0xb060c107, -0x4020007f, -0x4020007f, -0x28814603, -0x38818602, -0x4020007f, -0x4020007f, -0xb0408588, -0x28818602, -0x4020007f, -0x32001780, -0x409ffe02, -0x1000640e, -0x40800204, -0x30801203, -0x40800405, -0x3ec40087, -0x40800606, -0x3ac10608, -0x3ac14609, -0x3ac1860a, -0xb060c107, -0x20801203, -0x413d8003, -0x38810602, -0x4020007f, -0x327fd780, -0x409ffe02, -0x10007f0c, -0x40800205, -0x30801204, -0x40800406, -0x3ec40083, -0x3ac14607, -0x3ac18608, -0xb0810103, -0x413d8002, -0x20801204, -0x38814603, -0x4020007f, -0x327feb80, -0x409ffe02, -0x30801203, -0x40800204, -0x3ec40087, -0x40800405, -0x1000650a, -0x40800606, -0x3ac10608, -0x3ac14609, -0x3ac1860a, -0xb060c107, -0x20801203, -0x38810602, -0xb0408588, -0x4020007f, -0x327fc980, -0x00400000, -0x40800003, -0x4020007f, -0x35000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, +static unsigned int spu_restore_code[] __page_aligned = { +0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, +0x1cd80081, 0x33001180, 0x42030003, 0x33800284, +0x1c010204, 0x40200000, 0x40200000, 0x40200000, +0x34000190, 0x34004191, 0x34008192, 0x3400c193, +0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffa85, +0x3080a000, 0x3080a201, 0x3080a402, 0x3080a603, +0x3080a804, 0x3080aa05, 0x3080ac06, 0x3080ae07, +0x3080b008, 0x3080b209, 0x3080b40a, 0x3080b60b, +0x3080b80c, 0x3080ba0d, 0x3080bc0e, 0x3080be0f, +0x00003ffc, 0x00000000, 0x00000000, 0x00000000, +0x01a00182, 0x3ec00083, 0xb0a14103, 0x01a00204, +0x3ec10082, 0x4202800e, 0x04000703, 0xb0a14202, +0x21a00803, 0x3fbf028d, 0x3f20068d, 0x3fbe0682, +0x3fe30102, 0x21a00882, 0x3f82028f, 0x3fe3078f, +0x3fbf0784, 0x3f200204, 0x3fbe0204, 0x3fe30204, +0x04000203, 0x21a00903, 0x40848002, 0x21a00982, +0x40800003, 0x21a00a03, 0x40802002, 0x21a00a82, +0x21a00083, 0x40800082, 0x21a00b02, 0x10002818, +0x40a80002, 0x32800007, 0x4207000c, 0x18008208, +0x40a0000b, 0x4080020a, 0x40800709, 0x00200000, +0x42070002, 0x3ac30384, 0x1cffc489, 0x00200000, +0x18008383, 0x38830382, 0x4cffc486, 0x3ac28185, +0xb0408584, 0x28830382, 0x1c020387, 0x38828182, +0xb0408405, 0x1802c408, 0x28828182, 0x217ff886, +0x04000583, 0x21a00803, 0x3fbe0682, 0x3fe30102, +0x04000106, 0x21a00886, 0x04000603, 0x21a00903, +0x40803c02, 0x21a00982, 0x40800003, 0x04000184, +0x21a00a04, 0x40802202, 0x21a00a82, 0x42028005, +0x34208702, 0x21002282, 0x21a00804, 0x21a00886, +0x3fbf0782, 0x3f200102, 0x3fbe0102, 0x3fe30102, +0x21a00902, 0x40804003, 0x21a00983, 0x21a00a04, +0x40805a02, 0x21a00a82, 0x40800083, 0x21a00b83, +0x01a00c02, 0x01a00d83, 0x3420c282, 0x21a00e02, +0x34210283, 0x21a00f03, 0x34200284, 0x77400200, +0x3421c282, 0x21a00702, 0x34218283, 0x21a00083, +0x34214282, 0x21a00b02, 0x4200480c, 0x00200000, +0x1c010286, 0x34220284, 0x34220302, 0x0f608203, +0x5c024204, 0x3b81810b, 0x42013c02, 0x00200000, +0x18008185, 0x38808183, 0x3b814182, 0x21004e84, +0x4020007f, 0x35000100, 0x000004e0, 0x000002a0, +0x000002e8, 0x00000428, 0x00000360, 0x000002e8, +0x000004a0, 0x00000468, 0x000003c8, 0x00000360, +0x409ffe02, 0x30801203, 0x40800204, 0x3ec40085, +0x10009c09, 0x3ac10606, 0xb060c105, 0x4020007f, +0x4020007f, 0x20801203, 0x38810602, 0xb0408586, +0x28810602, 0x32004180, 0x34204702, 0x21a00382, +0x4020007f, 0x327fdc80, 0x409ffe02, 0x30801203, +0x40800204, 0x3ec40087, 0x40800405, 0x00200000, +0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, +0xb060c107, 0x20801203, 0x41004003, 0x38810602, +0x4020007f, 0xb0408188, 0x4020007f, 0x28810602, +0x41201002, 0x38814603, 0x10009c09, 0xb060c109, +0x4020007f, 0x28814603, 0x41193f83, 0x38818602, +0x60ffc003, 0xb040818a, 0x28818602, 0x32003080, +0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, +0x41201008, 0x10009c14, 0x40800405, 0x3ac10609, +0x40800606, 0x3ac1460a, 0xb060c107, 0x3ac1860b, +0x20801203, 0x38810602, 0xb0408409, 0x28810602, +0x38814603, 0xb060c40a, 0x4020007f, 0x28814603, +0x41193f83, 0x38818602, 0x60ffc003, 0xb040818b, +0x28818602, 0x32002380, 0x409ffe02, 0x30801204, +0x40800205, 0x3ec40083, 0x40800406, 0x3ac14607, +0x3ac18608, 0xb0810103, 0x41004002, 0x20801204, +0x4020007f, 0x38814603, 0x10009c0b, 0xb060c107, +0x4020007f, 0x4020007f, 0x28814603, 0x38818602, +0x4020007f, 0x4020007f, 0xb0408588, 0x28818602, +0x4020007f, 0x32001780, 0x409ffe02, 0x1000640e, +0x40800204, 0x30801203, 0x40800405, 0x3ec40087, +0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, +0xb060c107, 0x20801203, 0x413d8003, 0x38810602, +0x4020007f, 0x327fd780, 0x409ffe02, 0x10007f0c, +0x40800205, 0x30801204, 0x40800406, 0x3ec40083, +0x3ac14607, 0x3ac18608, 0xb0810103, 0x413d8002, +0x20801204, 0x38814603, 0x4020007f, 0x327feb80, +0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, +0x40800405, 0x1000650a, 0x40800606, 0x3ac10608, +0x3ac14609, 0x3ac1860a, 0xb060c107, 0x20801203, +0x38810602, 0xb0408588, 0x4020007f, 0x327fc980, +0x00400000, 0x40800003, 0x4020007f, 0x35000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped b/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped index b9f81ac8a632..39e54003f1df 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped +++ b/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped @@ -3,741 +3,189 @@ * Hex-dump auto generated from spu_save.c. * Do not edit! */ -static unsigned int spu_save_code[] __attribute__((__aligned__(128))) = { -0x20805000, -0x20805201, -0x20805402, -0x20805603, -0x20805804, -0x20805a05, -0x20805c06, -0x20805e07, -0x20806008, -0x20806209, -0x2080640a, -0x2080660b, -0x2080680c, -0x20806a0d, -0x20806c0e, -0x20806e0f, -0x4201c003, -0x33800184, -0x1c010204, -0x40200000, -0x24000190, -0x24004191, -0x24008192, -0x2400c193, -0x141fc205, -0x23fffd84, -0x1c100183, -0x217ffb85, -0x40800000, -0x409ff801, -0x24000080, -0x24fd8081, -0x1cd80081, -0x33000180, -0x00000000, -0x00000000, -0x01a00182, -0x3ec00083, -0xb1c38103, -0x01a00204, -0x3ec10082, -0x4201400d, -0xb1c38202, -0x01a00583, -0x34218682, -0x3ed80684, -0xb0408184, -0x24218682, -0x01a00603, -0x00200000, -0x34214682, -0x3ed40684, -0xb0408184, -0x40800003, -0x24214682, -0x21a00083, -0x40800082, -0x21a00b02, -0x4020007f, -0x1000251e, -0x42a00002, -0x32800008, -0x4205c00c, -0x00200000, -0x40a0000b, -0x3f82070f, -0x4080020a, -0x40800709, -0x3fe3078f, -0x3fbf0783, -0x3f200183, -0x3fbe0183, -0x3fe30187, -0x18008387, -0x4205c002, -0x3ac30404, -0x1cffc489, -0x00200000, -0x18008403, -0x38830402, -0x4cffc486, -0x3ac28185, -0xb0408584, -0x28830402, -0x1c020408, -0x38828182, -0xb0408385, -0x1802c387, -0x28828182, -0x217ff886, -0x04000582, -0x32800007, -0x21a00802, -0x3fbf0705, -0x3f200285, -0x3fbe0285, -0x3fe30285, -0x21a00885, -0x04000603, -0x21a00903, -0x40803c02, -0x21a00982, -0x04000386, -0x21a00a06, -0x40801202, -0x21a00a82, -0x73000003, -0x24200683, -0x01a00404, -0x00200000, -0x34204682, -0x3ec40683, -0xb0408203, -0x24204682, -0x01a00783, -0x00200000, -0x3421c682, -0x3edc0684, -0xb0408184, -0x2421c682, -0x21a00806, -0x21a00885, -0x3fbf0784, -0x3f200204, -0x3fbe0204, -0x3fe30204, -0x21a00904, -0x40804002, -0x21a00982, -0x21a00a06, -0x40805a02, -0x21a00a82, -0x04000683, -0x21a00803, -0x21a00885, -0x21a00904, -0x40848002, -0x21a00982, -0x21a00a06, -0x40801002, -0x21a00a82, -0x21a00a06, -0x40806602, -0x00200000, -0x35800009, -0x21a00a82, -0x40800083, -0x21a00b83, -0x01a00c02, -0x01a00d83, -0x00003ffb, -0x40800003, -0x4020007f, -0x35000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, +static unsigned int spu_save_code[] __page_aligned = { +0x20805000, 0x20805201, 0x20805402, 0x20805603, +0x20805804, 0x20805a05, 0x20805c06, 0x20805e07, +0x20806008, 0x20806209, 0x2080640a, 0x2080660b, +0x2080680c, 0x20806a0d, 0x20806c0e, 0x20806e0f, +0x4201c003, 0x33800184, 0x1c010204, 0x40200000, +0x24000190, 0x24004191, 0x24008192, 0x2400c193, +0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffb85, +0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, +0x1cd80081, 0x33000180, 0x00000000, 0x00000000, +0x01a00182, 0x3ec00083, 0xb1c38103, 0x01a00204, +0x3ec10082, 0x4201400d, 0xb1c38202, 0x01a00583, +0x34218682, 0x3ed80684, 0xb0408184, 0x24218682, +0x01a00603, 0x00200000, 0x34214682, 0x3ed40684, +0xb0408184, 0x40800003, 0x24214682, 0x21a00083, +0x40800082, 0x21a00b02, 0x4020007f, 0x1000251e, +0x40a80002, 0x32800008, 0x4205c00c, 0x00200000, +0x40a0000b, 0x3f82070f, 0x4080020a, 0x40800709, +0x3fe3078f, 0x3fbf0783, 0x3f200183, 0x3fbe0183, +0x3fe30187, 0x18008387, 0x4205c002, 0x3ac30404, +0x1cffc489, 0x00200000, 0x18008403, 0x38830402, +0x4cffc486, 0x3ac28185, 0xb0408584, 0x28830402, +0x1c020408, 0x38828182, 0xb0408385, 0x1802c387, +0x28828182, 0x217ff886, 0x04000582, 0x32800007, +0x21a00802, 0x3fbf0705, 0x3f200285, 0x3fbe0285, +0x3fe30285, 0x21a00885, 0x04000603, 0x21a00903, +0x40803c02, 0x21a00982, 0x04000386, 0x21a00a06, +0x40801202, 0x21a00a82, 0x73000003, 0x24200683, +0x01a00404, 0x00200000, 0x34204682, 0x3ec40683, +0xb0408203, 0x24204682, 0x01a00783, 0x00200000, +0x3421c682, 0x3edc0684, 0xb0408184, 0x2421c682, +0x21a00806, 0x21a00885, 0x3fbf0784, 0x3f200204, +0x3fbe0204, 0x3fe30204, 0x21a00904, 0x40804002, +0x21a00982, 0x21a00a06, 0x40805a02, 0x21a00a82, +0x04000683, 0x21a00803, 0x21a00885, 0x21a00904, +0x40848002, 0x21a00982, 0x21a00a06, 0x40801002, +0x21a00a82, 0x21a00a06, 0x40806602, 0x00200000, +0x35800009, 0x21a00a82, 0x40800083, 0x21a00b83, +0x01a00c02, 0x01a00d83, 0x00003ffb, 0x40800003, +0x4020007f, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44a..1726bfe38ee0 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -46,7 +46,6 @@ #include #include -#include #include #include @@ -623,17 +622,12 @@ static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu) static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; int i; /* Save, Step 42: + * Save the following CH: [0,1,3,4,24,25,27] */ - - /* Save CH 1, without channel count */ - out_be64(&priv2->spu_chnlcntptr_RW, 1); - csa->spu_chnldata_RW[1] = in_be64(&priv2->spu_chnldata_RW); - - /* Save the following CH: [0,3,4,24,25,27] */ for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); @@ -724,15 +718,13 @@ static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) static inline void get_kernel_slb(u64 ea, u64 slb[2]) { - u64 llp; - - if (REGION_ID(ea) == KERNEL_REGION_ID) - llp = mmu_psize_defs[mmu_linear_psize].sllp; - else - llp = mmu_psize_defs[mmu_virtual_psize].sllp; - slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | - SLB_VSID_KERNEL | llp; + slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; slb[1] = (ea & ESID_MASK) | SLB_ESID_V; + + /* Large pages are used for kernel text/data, but not vmalloc. */ + if (cpu_has_feature(CPU_FTR_16M_PAGE) + && REGION_ID(ea) == KERNEL_REGION_ID) + slb[0] |= SLB_VSID_L; } static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) @@ -1111,18 +1103,13 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; u64 idx; int i; /* Restore, Step 20: + * Reset the following CH: [0,1,3,4,24,25,27] */ - - /* Reset CH 1 */ - out_be64(&priv2->spu_chnlcntptr_RW, 1); - out_be64(&priv2->spu_chnldata_RW, 0UL); - - /* Reset the following CH: [0,3,4,24,25,27] */ for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); @@ -1583,17 +1570,12 @@ static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; int i; /* Restore, Step 59: + * Restore the following CH: [0,1,3,4,24,25,27] */ - - /* Restore CH 1 without count */ - out_be64(&priv2->spu_chnlcntptr_RW, 1); - out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[1]); - - /* Restore the following CH: [0,3,4,24,25,27] */ for (i = 0; i < 7; i++) { idx = ch_indices[i]; out_be64(&priv2->spu_chnlcntptr_RW, idx); @@ -2092,7 +2074,6 @@ int spu_save(struct spu_state *prev, struct spu *spu) } return rc; } -EXPORT_SYMBOL_GPL(spu_save); /** * spu_restore - SPU context restore, with harvest and locking. @@ -2100,7 +2081,7 @@ EXPORT_SYMBOL_GPL(spu_save); * @spu: pointer to SPU iomem structure. * * Perform harvest + restore, as we may not be coming - * from a previous successful save operation, and the + * from a previous succesful save operation, and the * hardware state is unknown. */ int spu_restore(struct spu_state *new, struct spu *spu) @@ -2109,6 +2090,7 @@ int spu_restore(struct spu_state *new, struct spu *spu) acquire_spu_lock(spu); harvest(NULL, spu); + spu->stop_code = 0; spu->dar = 0; spu->dsisr = 0; spu->slb_replace = 0; @@ -2121,7 +2103,6 @@ int spu_restore(struct spu_state *new, struct spu *spu) } return rc; } -EXPORT_SYMBOL_GPL(spu_restore); /** * spu_harvest - SPU harvest (reset) operation @@ -2144,7 +2125,6 @@ static void init_prob(struct spu_state *csa) csa->spu_chnlcnt_RW[28] = 1; csa->spu_chnlcnt_RW[30] = 1; csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP; - csa->prob.mb_stat_R = 0x000400; } static void init_priv1(struct spu_state *csa) @@ -2203,7 +2183,7 @@ void spu_init_csa(struct spu_state *csa) memset(lscsa, 0, sizeof(struct spu_lscsa)); csa->lscsa = lscsa; - spin_lock_init(&csa->register_lock); + csa->register_lock = SPIN_LOCK_UNLOCKED; /* Set LS pages reserved to allow for user-space mapping. */ for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) @@ -2213,7 +2193,6 @@ void spu_init_csa(struct spu_state *csa) init_priv1(csa); init_priv2(csa); } -EXPORT_SYMBOL_GPL(spu_init_csa); void spu_fini_csa(struct spu_state *csa) { @@ -2224,4 +2203,3 @@ void spu_fini_csa(struct spu_state *csa) vfree(csa->lscsa); } -EXPORT_SYMBOL_GPL(spu_fini_csa); diff --git a/trunk/arch/powerpc/platforms/iseries/Makefile b/trunk/arch/powerpc/platforms/iseries/Makefile index dee4eb4d8bec..ce8c0b943fa0 100644 --- a/trunk/arch/powerpc/platforms/iseries/Makefile +++ b/trunk/arch/powerpc/platforms/iseries/Makefile @@ -1,11 +1,9 @@ EXTRA_CFLAGS += -mno-minimal-toc -obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ +obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o misc.o irq.o obj-$(CONFIG_PCI) += pci.o vpdinfo.o +obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_VIOPATH) += viopath.o obj-$(CONFIG_MODULES) += ksyms.o - -$(obj)/dt_mod.o: $(obj)/dt.o - @$(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings $(obj)/dt.o $(obj)/dt_mod.o diff --git a/trunk/arch/powerpc/platforms/iseries/call_pci.h b/trunk/arch/powerpc/platforms/iseries/call_pci.h index dbdf69850ed9..59d4e0ad5cf3 100644 --- a/trunk/arch/powerpc/platforms/iseries/call_pci.h +++ b/trunk/arch/powerpc/platforms/iseries/call_pci.h @@ -145,25 +145,6 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, return retVal.rc; } -static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, u32 *value) -{ - struct HvCallPci_DsaAddr dsa; - struct HvCallPci_LoadReturn retVal; - - *((u64*)&dsa) = 0; - - dsa.busNumber = busNumber; - dsa.subBusNumber = subBusNumber; - dsa.deviceId = deviceId; - - HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0); - - *value = retVal.value; - - return retVal.rc; -} - static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u8 value) { diff --git a/trunk/arch/powerpc/platforms/iseries/dt.c b/trunk/arch/powerpc/platforms/iseries/dt.c deleted file mode 100644 index d3444aabe76e..000000000000 --- a/trunk/arch/powerpc/platforms/iseries/dt.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation - * - * Description: - * This file contains all the routines to build a flattened device - * tree for a legacy iSeries machine. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* ETH_ALEN */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "processor_vpd.h" -#include "call_hpt.h" -#include "call_pci.h" -#include "pci.h" - -#ifdef DEBUG -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -/* - * These are created by the linker script at the start and end - * of the section containing all the strings from this file. - */ -extern char __dt_strings_start[]; -extern char __dt_strings_end[]; - -struct iseries_flat_dt { - struct boot_param_header header; - u64 reserve_map[2]; -}; - -static void * __initdata dt_data; - -/* - * Putting these strings here keeps them out of the section - * that we rename to .dt_strings using objcopy and capture - * for the strings blob of the flattened device tree. - */ -static char __initdata device_type_cpu[] = "cpu"; -static char __initdata device_type_memory[] = "memory"; -static char __initdata device_type_serial[] = "serial"; -static char __initdata device_type_network[] = "network"; -static char __initdata device_type_block[] = "block"; -static char __initdata device_type_byte[] = "byte"; -static char __initdata device_type_pci[] = "pci"; -static char __initdata device_type_vdevice[] = "vdevice"; -static char __initdata device_type_vscsi[] = "vscsi"; - -static struct iseries_flat_dt * __init dt_init(void) -{ - struct iseries_flat_dt *dt; - unsigned long str_len; - - str_len = __dt_strings_end - __dt_strings_start; - dt = (struct iseries_flat_dt *)ALIGN(klimit, 8); - dt->header.off_mem_rsvmap = - offsetof(struct iseries_flat_dt, reserve_map); - dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8); - dt->header.off_dt_struct = dt->header.off_dt_strings - + ALIGN(str_len, 8); - dt_data = (void *)((unsigned long)dt + dt->header.off_dt_struct); - dt->header.dt_strings_size = str_len; - - /* There is no notion of hardware cpu id on iSeries */ - dt->header.boot_cpuid_phys = smp_processor_id(); - - memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start, - str_len); - - dt->header.magic = OF_DT_HEADER; - dt->header.version = 0x10; - dt->header.last_comp_version = 0x10; - - dt->reserve_map[0] = 0; - dt->reserve_map[1] = 0; - - return dt; -} - -static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value) -{ - *((u32 *)dt_data) = value; - dt_data += sizeof(u32); -} - -#ifdef notyet -static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value) -{ - *((u64 *)dt_data) = value; - dt_data += sizeof(u64); -} -#endif - -static void __init dt_push_bytes(struct iseries_flat_dt *dt, const char *data, - int len) -{ - memcpy(dt_data, data, len); - dt_data += ALIGN(len, 4); -} - -static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name) -{ - dt_push_u32(dt, OF_DT_BEGIN_NODE); - dt_push_bytes(dt, name, strlen(name) + 1); -} - -#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) - -static void __init dt_prop(struct iseries_flat_dt *dt, const char *name, - const void *data, int len) -{ - unsigned long offset; - - dt_push_u32(dt, OF_DT_PROP); - - /* Length of the data */ - dt_push_u32(dt, len); - - offset = name - __dt_strings_start; - - /* The offset of the properties name in the string blob. */ - dt_push_u32(dt, (u32)offset); - - /* The actual data. */ - dt_push_bytes(dt, data, len); -} - -static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name, - const char *data) -{ - dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ -} - -static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name, - u32 data) -{ - dt_prop(dt, name, &data, sizeof(u32)); -} - -#ifdef notyet -static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, - u64 data) -{ - dt_prop(dt, name, &data, sizeof(u64)); -} -#endif - -static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, - const char *name, u64 *data, int n) -{ - dt_prop(dt, name, data, sizeof(u64) * n); -} - -static void __init dt_prop_u32_list(struct iseries_flat_dt *dt, - const char *name, u32 *data, int n) -{ - dt_prop(dt, name, data, sizeof(u32) * n); -} - -#ifdef notyet -static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name) -{ - dt_prop(dt, name, NULL, 0); -} -#endif - -static void __init dt_cpus(struct iseries_flat_dt *dt) -{ - unsigned char buf[32]; - unsigned char *p; - unsigned int i, index; - struct IoHriProcessorVpd *d; - u32 pft_size[2]; - - /* yuck */ - snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); - p = strchr(buf, ' '); - if (!p) p = buf + strlen(buf); - - dt_start_node(dt, "cpus"); - dt_prop_u32(dt, "#address-cells", 1); - dt_prop_u32(dt, "#size-cells", 0); - - pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */ - pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); - - for (i = 0; i < NR_CPUS; i++) { - if (lppaca[i].dyn_proc_status >= 2) - continue; - - snprintf(p, 32 - (p - buf), "@%d", i); - dt_start_node(dt, buf); - - dt_prop_str(dt, "device_type", device_type_cpu); - - index = lppaca[i].dyn_hv_phys_proc_index; - d = &xIoHriProcessorVpd[index]; - - dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); - dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); - - dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); - dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); - - /* magic conversions to Hz copied from old code */ - dt_prop_u32(dt, "clock-frequency", - ((1UL << 34) * 1000000) / d->xProcFreq); - dt_prop_u32(dt, "timebase-frequency", - ((1UL << 32) * 1000000) / d->xTimeBaseFreq); - - dt_prop_u32(dt, "reg", i); - - dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2); - - dt_end_node(dt); - } - - dt_end_node(dt); -} - -static void __init dt_model(struct iseries_flat_dt *dt) -{ - char buf[16] = "IBM,"; - - /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ - strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); - strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); - buf[11] = '\0'; - dt_prop_str(dt, "system-id", buf); - - /* "IBM," + machineType[0:4] */ - strne2a(buf + 4, xItExtVpdPanel.machineType, 4); - buf[8] = '\0'; - dt_prop_str(dt, "model", buf); - - dt_prop_str(dt, "compatible", "IBM,iSeries"); -} - -static void __init dt_do_vdevice(struct iseries_flat_dt *dt, - const char *name, u32 reg, int unit, - const char *type, const char *compat, int end) -{ - char buf[32]; - - snprintf(buf, 32, "%s@%08x", name, reg + ((unit >= 0) ? unit : 0)); - dt_start_node(dt, buf); - dt_prop_str(dt, "device_type", type); - if (compat) - dt_prop_str(dt, "compatible", compat); - dt_prop_u32(dt, "reg", reg + ((unit >= 0) ? unit : 0)); - if (unit >= 0) - dt_prop_u32(dt, "linux,unit_address", unit); - if (end) - dt_end_node(dt); -} - -static void __init dt_vdevices(struct iseries_flat_dt *dt) -{ - u32 reg = 0; - HvLpIndexMap vlan_map; - int i; - - dt_start_node(dt, "vdevice"); - dt_prop_str(dt, "device_type", device_type_vdevice); - dt_prop_str(dt, "compatible", "IBM,iSeries-vdevice"); - dt_prop_u32(dt, "#address-cells", 1); - dt_prop_u32(dt, "#size-cells", 0); - - dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1); - reg++; - - dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi, - "IBM,v-scsi", 1); - reg++; - - vlan_map = HvLpConfig_getVirtualLanIndexMap(); - for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { - unsigned char mac_addr[ETH_ALEN]; - - if ((vlan_map & (0x8000 >> i)) == 0) - continue; - dt_do_vdevice(dt, "l-lan", reg, i, device_type_network, - "IBM,iSeries-l-lan", 0); - mac_addr[0] = 0x02; - mac_addr[1] = 0x01; - mac_addr[2] = 0xff; - mac_addr[3] = i; - mac_addr[4] = 0xff; - mac_addr[5] = HvLpConfig_getLpIndex_outline(); - dt_prop(dt, "local-mac-address", (char *)mac_addr, ETH_ALEN); - dt_prop(dt, "mac-address", (char *)mac_addr, ETH_ALEN); - dt_prop_u32(dt, "max-frame-size", 9000); - dt_prop_u32(dt, "address-bits", 48); - - dt_end_node(dt); - } - reg += HVMAXARCHITECTEDVIRTUALLANS; - - for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) - dt_do_vdevice(dt, "viodasd", reg, i, device_type_block, - "IBM,iSeries-viodasd", 1); - reg += HVMAXARCHITECTEDVIRTUALDISKS; - - for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) - dt_do_vdevice(dt, "viocd", reg, i, device_type_block, - "IBM,iSeries-viocd", 1); - reg += HVMAXARCHITECTEDVIRTUALCDROMS; - - for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) - dt_do_vdevice(dt, "viotape", reg, i, device_type_byte, - "IBM,iSeries-viotape", 1); - - dt_end_node(dt); -} - -struct pci_class_name { - u16 code; - const char *name; - const char *type; -}; - -static struct pci_class_name __initdata pci_class_name[] = { - { PCI_CLASS_NETWORK_ETHERNET, "ethernet", device_type_network }, -}; - -static struct pci_class_name * __init dt_find_pci_class_name(u16 class_code) -{ - struct pci_class_name *cp; - - for (cp = pci_class_name; - cp < &pci_class_name[ARRAY_SIZE(pci_class_name)]; cp++) - if (cp->code == class_code) - return cp; - return NULL; -} - -/* - * This assumes that the node slot is always on the primary bus! - */ -static void __init scan_bridge_slot(struct iseries_flat_dt *dt, - HvBusNumber bus, struct HvCallPci_BridgeInfo *bridge_info) -{ - HvSubBusNumber sub_bus = bridge_info->subBusNumber; - u16 vendor_id; - u16 device_id; - u32 class_id; - int err; - char buf[32]; - u32 reg[5]; - int id_sel = ISERIES_GET_DEVICE_FROM_SUBBUS(sub_bus); - int function = ISERIES_GET_FUNCTION_FROM_SUBBUS(sub_bus); - HvAgentId eads_id_sel = ISERIES_PCI_AGENTID(id_sel, function); - u8 devfn; - struct pci_class_name *cp; - - /* - * Connect all functions of any device found. - */ - for (id_sel = 1; id_sel <= bridge_info->maxAgents; id_sel++) { - for (function = 0; function < 8; function++) { - HvAgentId agent_id = ISERIES_PCI_AGENTID(id_sel, - function); - err = HvCallXm_connectBusUnit(bus, sub_bus, - agent_id, 0); - if (err) { - if (err != 0x302) - DBG("connectBusUnit(%x, %x, %x) %x\n", - bus, sub_bus, agent_id, err); - continue; - } - - err = HvCallPci_configLoad16(bus, sub_bus, agent_id, - PCI_VENDOR_ID, &vendor_id); - if (err) { - DBG("ReadVendor(%x, %x, %x) %x\n", - bus, sub_bus, agent_id, err); - continue; - } - err = HvCallPci_configLoad16(bus, sub_bus, agent_id, - PCI_DEVICE_ID, &device_id); - if (err) { - DBG("ReadDevice(%x, %x, %x) %x\n", - bus, sub_bus, agent_id, err); - continue; - } - err = HvCallPci_configLoad32(bus, sub_bus, agent_id, - PCI_CLASS_REVISION , &class_id); - if (err) { - DBG("ReadClass(%x, %x, %x) %x\n", - bus, sub_bus, agent_id, err); - continue; - } - - devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(eads_id_sel), - function); - cp = dt_find_pci_class_name(class_id >> 16); - if (cp && cp->name) - strncpy(buf, cp->name, sizeof(buf) - 1); - else - snprintf(buf, sizeof(buf), "pci%x,%x", - vendor_id, device_id); - buf[sizeof(buf) - 1] = '\0'; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "@%x", PCI_SLOT(devfn)); - buf[sizeof(buf) - 1] = '\0'; - if (function != 0) - snprintf(buf + strlen(buf), - sizeof(buf) - strlen(buf), - ",%x", function); - dt_start_node(dt, buf); - reg[0] = (bus << 16) | (devfn << 8); - reg[1] = 0; - reg[2] = 0; - reg[3] = 0; - reg[4] = 0; - dt_prop_u32_list(dt, "reg", reg, 5); - if (cp && (cp->type || cp->name)) - dt_prop_str(dt, "device_type", - cp->type ? cp->type : cp->name); - dt_prop_u32(dt, "vendor-id", vendor_id); - dt_prop_u32(dt, "device-id", device_id); - dt_prop_u32(dt, "class-code", class_id >> 8); - dt_prop_u32(dt, "revision-id", class_id & 0xff); - dt_prop_u32(dt, "linux,subbus", sub_bus); - dt_prop_u32(dt, "linux,agent-id", agent_id); - dt_prop_u32(dt, "linux,logical-slot-number", - bridge_info->logicalSlotNumber); - dt_end_node(dt); - - } - } -} - -static void __init scan_bridge(struct iseries_flat_dt *dt, HvBusNumber bus, - HvSubBusNumber sub_bus, int id_sel) -{ - struct HvCallPci_BridgeInfo bridge_info; - HvAgentId agent_id; - int function; - int ret; - - /* Note: hvSubBus and irq is always be 0 at this level! */ - for (function = 0; function < 8; ++function) { - agent_id = ISERIES_PCI_AGENTID(id_sel, function); - ret = HvCallXm_connectBusUnit(bus, sub_bus, agent_id, 0); - if (ret != 0) { - if (ret != 0xb) - DBG("connectBusUnit(%x, %x, %x) %x\n", - bus, sub_bus, agent_id, ret); - continue; - } - DBG("found device at bus %d idsel %d func %d (AgentId %x)\n", - bus, id_sel, function, agent_id); - ret = HvCallPci_getBusUnitInfo(bus, sub_bus, agent_id, - iseries_hv_addr(&bridge_info), - sizeof(struct HvCallPci_BridgeInfo)); - if (ret != 0) - continue; - DBG("bridge info: type %x subbus %x " - "maxAgents %x maxsubbus %x logslot %x\n", - bridge_info.busUnitInfo.deviceType, - bridge_info.subBusNumber, - bridge_info.maxAgents, - bridge_info.maxSubBusNumber, - bridge_info.logicalSlotNumber); - if (bridge_info.busUnitInfo.deviceType == - HvCallPci_BridgeDevice) - scan_bridge_slot(dt, bus, &bridge_info); - else - DBG("PCI: Invalid Bridge Configuration(0x%02X)", - bridge_info.busUnitInfo.deviceType); - } -} - -static void __init scan_phb(struct iseries_flat_dt *dt, HvBusNumber bus) -{ - struct HvCallPci_DeviceInfo dev_info; - const HvSubBusNumber sub_bus = 0; /* EADs is always 0. */ - int err; - int id_sel; - const int max_agents = 8; - - /* - * Probe for EADs Bridges - */ - for (id_sel = 1; id_sel < max_agents; ++id_sel) { - err = HvCallPci_getDeviceInfo(bus, sub_bus, id_sel, - iseries_hv_addr(&dev_info), - sizeof(struct HvCallPci_DeviceInfo)); - if (err) { - if (err != 0x302) - DBG("getDeviceInfo(%x, %x, %x) %x\n", - bus, sub_bus, id_sel, err); - continue; - } - if (dev_info.deviceType != HvCallPci_NodeDevice) { - DBG("PCI: Invalid System Configuration" - "(0x%02X) for bus 0x%02x id 0x%02x.\n", - dev_info.deviceType, bus, id_sel); - continue; - } - scan_bridge(dt, bus, sub_bus, id_sel); - } -} - -static void __init dt_pci_devices(struct iseries_flat_dt *dt) -{ - HvBusNumber bus; - char buf[32]; - u32 buses[2]; - int phb_num = 0; - - /* Check all possible buses. */ - for (bus = 0; bus < 256; bus++) { - int err = HvCallXm_testBus(bus); - - if (err) { - /* - * Check for Unexpected Return code, a clue that - * something has gone wrong. - */ - if (err != 0x0301) - DBG("Unexpected Return on Probe(0x%02X) " - "0x%04X\n", bus, err); - continue; - } - DBG("bus %d appears to exist\n", bus); - snprintf(buf, 32, "pci@%d", phb_num); - dt_start_node(dt, buf); - dt_prop_str(dt, "device_type", device_type_pci); - dt_prop_str(dt, "compatible", "IBM,iSeries-Logical-PHB"); - dt_prop_u32(dt, "#address-cells", 3); - dt_prop_u32(dt, "#size-cells", 2); - buses[0] = buses[1] = bus; - dt_prop_u32_list(dt, "bus-range", buses, 2); - scan_phb(dt, bus); - dt_end_node(dt); - phb_num++; - } -} - -static void dt_finish(struct iseries_flat_dt *dt) -{ - dt_push_u32(dt, OF_DT_END); - dt->header.totalsize = (unsigned long)dt_data - (unsigned long)dt; - klimit = ALIGN((unsigned long)dt_data, 8); -} - -void * __init build_flat_dt(unsigned long phys_mem_size) -{ - struct iseries_flat_dt *iseries_dt; - u64 tmp[2]; - - iseries_dt = dt_init(); - - dt_start_node(iseries_dt, ""); - - dt_prop_u32(iseries_dt, "#address-cells", 2); - dt_prop_u32(iseries_dt, "#size-cells", 2); - dt_model(iseries_dt); - - /* /memory */ - dt_start_node(iseries_dt, "memory@0"); - dt_prop_str(iseries_dt, "device_type", device_type_memory); - tmp[0] = 0; - tmp[1] = phys_mem_size; - dt_prop_u64_list(iseries_dt, "reg", tmp, 2); - dt_end_node(iseries_dt); - - /* /chosen */ - dt_start_node(iseries_dt, "chosen"); - dt_prop_str(iseries_dt, "bootargs", cmd_line); - dt_end_node(iseries_dt); - - dt_cpus(iseries_dt); - - dt_vdevices(iseries_dt); - dt_pci_devices(iseries_dt); - - dt_end_node(iseries_dt); - - dt_finish(iseries_dt); - - return iseries_dt; -} diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.c b/trunk/arch/powerpc/platforms/iseries/iommu.c index e3bd2015f2c9..bea0b703f409 100644 --- a/trunk/arch/powerpc/platforms/iseries/iommu.c +++ b/trunk/arch/powerpc/platforms/iseries/iommu.c @@ -4,7 +4,6 @@ * Rewrite, cleanup: * * Copyright (C) 2004 Olof Johansson , IBM Corporation - * Copyright (C) 2006 Olof Johansson * * Dynamic DMA mapping support, iSeries-specific parts. * @@ -32,37 +31,42 @@ #include #include #include -#include #include #include -#include + +#include "iommu.h" + +extern struct list_head iSeries_Global_Device_List; + static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, unsigned long uaddr, enum dma_data_direction direction) { u64 rc; - u64 tce, rpn; + union tce_entry tce; index <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; while (npages--) { - rpn = virt_to_abs(uaddr) >> TCE_SHIFT; - tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; + tce.te_word = 0; + tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT; if (tbl->it_type == TCE_VB) { /* Virtual Bus */ - tce |= TCE_VALID|TCE_ALLIO; + tce.te_bits.tb_valid = 1; + tce.te_bits.tb_allio = 1; if (direction != DMA_TO_DEVICE) - tce |= TCE_VB_WRITE; + tce.te_bits.tb_rdwr = 1; } else { /* PCI Bus */ - tce |= TCE_PCI_READ; /* Read allowed */ + tce.te_bits.tb_rdwr = 1; /* Read allowed */ if (direction != DMA_TO_DEVICE) - tce |= TCE_PCI_WRITE; + tce.te_bits.tb_pciwr = 1; } - rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); + rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, + tce.te_word); if (rc) panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc); @@ -120,7 +124,7 @@ void iommu_table_getparms_iSeries(unsigned long busno, /* itc_size is in pages worth of table, it_size is in # of entries */ tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / - TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; + sizeof(union tce_entry)) >> TCE_PAGE_FACTOR; tbl->it_busno = parms->itc_busno; tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; tbl->it_index = parms->itc_index; @@ -138,15 +142,10 @@ void iommu_table_getparms_iSeries(unsigned long busno, */ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { - struct device_node *node; + struct pci_dn *pdn; - for (node = NULL; (node = of_find_all_nodes(node)); ) { - struct pci_dn *pdn = PCI_DN(node); - struct iommu_table *it; - - if (pdn == NULL) - continue; - it = pdn->iommu_table; + list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { + struct iommu_table *it = pdn->iommu_table; if ((it != NULL) && (it->it_type == TCE_PCI) && (it->it_offset == tbl->it_offset) && @@ -162,18 +161,15 @@ void iommu_devnode_init_iSeries(struct device_node *dn) { struct iommu_table *tbl; struct pci_dn *pdn = PCI_DN(dn); - u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); - - BUG_ON(lsn == NULL); tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); + iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl); /* Look for existing tce table */ pdn->iommu_table = iommu_table_find(tbl); if (pdn->iommu_table == NULL) - pdn->iommu_table = iommu_init_table(tbl, -1); + pdn->iommu_table = iommu_init_table(tbl); else kfree(tbl); } diff --git a/trunk/include/asm-powerpc/iseries/iommu.h b/trunk/arch/powerpc/platforms/iseries/iommu.h similarity index 90% rename from trunk/include/asm-powerpc/iseries/iommu.h rename to trunk/arch/powerpc/platforms/iseries/iommu.h index 0edbfe10cb37..cb5658fbe657 100644 --- a/trunk/include/asm-powerpc/iseries/iommu.h +++ b/trunk/arch/powerpc/platforms/iseries/iommu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_ISERIES_IOMMU_H -#define _ASM_POWERPC_ISERIES_IOMMU_H +#ifndef _PLATFORMS_ISERIES_IOMMU_H +#define _PLATFORMS_ISERIES_IOMMU_H /* * Copyright (C) 2005 Stephen Rothwell, IBM Corporation @@ -32,4 +32,4 @@ extern void iommu_table_getparms_iSeries(unsigned long busno, unsigned char slotno, unsigned char virtbus, struct iommu_table *tbl); -#endif /* _ASM_POWERPC_ISERIES_IOMMU_H */ +#endif /* _PLATFORMS_ISERIES_IOMMU_H */ diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 62bbbcf5ded3..be3fbfc24e6c 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -42,7 +42,6 @@ #include #include "irq.h" -#include "pci.h" #include "call_pci.h" #if defined(CONFIG_SMP) @@ -313,12 +312,12 @@ static hw_irq_controller iSeries_IRQ_handler = { * Note that sub_bus is always 0 (at the moment at least). */ int __init iSeries_allocate_IRQ(HvBusNumber bus, - HvSubBusNumber sub_bus, u32 bsubbus) + HvSubBusNumber sub_bus, HvAgentId dev_id) { int virtirq; unsigned int realirq; - u8 idsel = ISERIES_GET_DEVICE_FROM_SUBBUS(bsubbus); - u8 function = ISERIES_GET_FUNCTION_FROM_SUBBUS(bsubbus); + u8 idsel = (dev_id >> 4); + u8 function = dev_id & 7; realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) + function; diff --git a/trunk/arch/powerpc/platforms/iseries/irq.h b/trunk/arch/powerpc/platforms/iseries/irq.h index 188aa808abd7..b9c801ba5a47 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.h +++ b/trunk/arch/powerpc/platforms/iseries/irq.h @@ -2,7 +2,7 @@ #define _ISERIES_IRQ_H extern void iSeries_init_IRQ(void); -extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32); +extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); extern void iSeries_activate_IRQs(void); extern int iSeries_get_irq(struct pt_regs *); diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index 1a2c2a50f922..d771b8ee857d 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -45,6 +45,7 @@ #include "setup.h" +extern int piranha_simulator; static int mf_initialized; /* @@ -657,7 +658,7 @@ static void mf_clear_src(void) void __init mf_display_progress(u16 value) { - if (!mf_initialized) + if (piranha_simulator || !mf_initialized) return; if (0xFFFF == value) @@ -1294,6 +1295,9 @@ __initcall(mf_proc_init); */ void iSeries_get_rtc_time(struct rtc_time *rtc_tm) { + if (piranha_simulator) + return; + mf_get_rtc(rtc_tm); rtc_tm->tm_mon--; } @@ -1312,6 +1316,9 @@ unsigned long iSeries_get_boot_time(void) { struct rtc_time tm; + if (piranha_simulator) + return 0; + mf_get_boot_rtc(&tm); return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); diff --git a/trunk/arch/powerpc/platforms/iseries/pci.c b/trunk/arch/powerpc/platforms/iseries/pci.c index 35bcc98111f5..a19833b880e4 100644 --- a/trunk/arch/powerpc/platforms/iseries/pci.c +++ b/trunk/arch/powerpc/platforms/iseries/pci.c @@ -37,18 +37,36 @@ #include #include -#include #include #include "irq.h" #include "pci.h" #include "call_pci.h" +#include "iommu.h" + +extern unsigned long io_page_mask; /* * Forward declares of prototypes. */ static struct device_node *find_Device_Node(int bus, int devfn); +static void scan_PHB_slots(struct pci_controller *Phb); +static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel); +static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info); + +LIST_HEAD(iSeries_Global_Device_List); + +static int DeviceCount; + +/* Counters and control flags. */ +static long Pci_Io_Read_Count; +static long Pci_Io_Write_Count; +#if 0 +static long Pci_Cfg_Read_Count; +static long Pci_Cfg_Write_Count; +#endif +static long Pci_Error_Count; static int Pci_Retry_Max = 3; /* Only retry 3 times */ static int Pci_Error_Flag = 1; /* Set Retry Error on. */ @@ -63,18 +81,40 @@ static struct pci_ops iSeries_pci_ops; #define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL #define BASE_IO_MEMORY 0xE000000000000000UL -static unsigned long max_io_memory = BASE_IO_MEMORY; +static unsigned long max_io_memory = 0xE000000000000000UL; static long current_iomm_table_entry; /* * Lookup Tables. */ -static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; -static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; +static struct device_node **iomm_table; +static u8 *iobar_table; -static const char pci_io_text[] = "iSeries PCI I/O"; +/* + * Static and Global variables + */ +static char *pci_io_text = "iSeries PCI I/O"; static DEFINE_SPINLOCK(iomm_table_lock); +/* + * iomm_table_initialize + * + * Allocates and initalizes the Address Translation Table and Bar + * Tables to get them ready for use. Must be called before any + * I/O space is handed out to the device BARs. + */ +static void iomm_table_initialize(void) +{ + spin_lock(&iomm_table_lock); + iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES, + GFP_KERNEL); + iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES, + GFP_KERNEL); + spin_unlock(&iomm_table_lock); + if ((iomm_table == NULL) || (iobar_table == NULL)) + panic("PCI: I/O tables allocation failed.\n"); +} + /* * iomm_table_allocate_entry * @@ -102,8 +142,9 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) */ spin_lock(&iomm_table_lock); bar_res->name = pci_io_text; - bar_res->start = BASE_IO_MEMORY + + bar_res->start = IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; + bar_res->start += BASE_IO_MEMORY; bar_res->end = bar_res->start + bar_size - 1; /* * Allocate the number of table entries needed for BAR. @@ -115,7 +156,7 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) ++current_iomm_table_entry; } max_io_memory = BASE_IO_MEMORY + - IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; + (IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry); spin_unlock(&iomm_table_lock); } @@ -132,10 +173,13 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) */ static void allocate_device_bars(struct pci_dev *dev) { + struct resource *bar_res; int bar_num; - for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) + for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) { + bar_res = &dev->resource[bar_num]; iomm_table_allocate_entry(dev, bar_num); + } } /* @@ -155,7 +199,34 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, } /* - * iSeries_pcibios_init + * build_device_node(u16 Bus, int SubBus, u8 DevFn) + */ +static struct device_node *build_device_node(HvBusNumber Bus, + HvSubBusNumber SubBus, int AgentId, int Function) +{ + struct device_node *node; + struct pci_dn *pdn; + + node = kmalloc(sizeof(struct device_node), GFP_KERNEL); + if (node == NULL) + return NULL; + memset(node, 0, sizeof(struct device_node)); + pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + if (pdn == NULL) { + kfree(node); + return NULL; + } + node->data = pdn; + pdn->node = node; + list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List); + pdn->busno = Bus; + pdn->bussubno = SubBus; + pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); + return node; +} + +/* + * unsigned long __init find_and_init_phbs(void) * * Description: * This function checks for all possible system PCI host bridges that connect @@ -163,42 +234,50 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, * ownership status. A pci_controller is built for any bus which is partially * owned or fully owned by this guest partition. */ -void iSeries_pcibios_init(void) +unsigned long __init find_and_init_phbs(void) { struct pci_controller *phb; - struct device_node *root = of_find_node_by_path("/"); - struct device_node *node = NULL; + HvBusNumber bus; - if (root == NULL) { - printk(KERN_CRIT "iSeries_pcibios_init: can't find root " - "of device tree\n"); - return; - } - while ((node = of_get_next_child(root, node)) != NULL) { - HvBusNumber bus; - u32 *busp; - - if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) - continue; - - busp = (u32 *)get_property(node, "bus-range", NULL); - if (busp == NULL) - continue; - bus = *busp; - printk("bus %d appears to exist\n", bus); - phb = pcibios_alloc_controller(node); - if (phb == NULL) - continue; - - phb->pci_mem_offset = phb->local_number = bus; - phb->first_busno = bus; - phb->last_busno = bus; - phb->ops = &iSeries_pci_ops; - } + /* Check all possible buses. */ + for (bus = 0; bus < 256; bus++) { + int ret = HvCallXm_testBus(bus); + if (ret == 0) { + printk("bus %d appears to exist\n", bus); + + phb = pcibios_alloc_controller(NULL); + if (phb == NULL) + return -ENOMEM; - of_node_put(root); + phb->pci_mem_offset = phb->local_number = bus; + phb->first_busno = bus; + phb->last_busno = bus; + phb->ops = &iSeries_pci_ops; - pci_devs_phb_init(); + /* Find and connect the devices. */ + scan_PHB_slots(phb); + } + /* + * Check for Unexpected Return code, a clue that something + * has gone wrong. + */ + else if (ret != 0x0301) + printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X", + bus, ret); + } + return 0; +} + +/* + * iSeries_pcibios_init + * + * Chance to initialize and structures or variable before PCI Bus walk. + */ +void iSeries_pcibios_init(void) +{ + iomm_table_initialize(); + find_and_init_phbs(); + io_page_mask = -1; } /* @@ -220,34 +299,6 @@ void __init iSeries_pci_final_fixup(void) pdev->bus->number, pdev->devfn, node); if (node != NULL) { - struct pci_dn *pdn = PCI_DN(node); - u32 *agent; - - agent = (u32 *)get_property(node, "linux,agent-id", - NULL); - if ((pdn != NULL) && (agent != NULL)) { - u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, - pdn->bussubno); - int err; - - err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno, - *agent, irq); - if (err) - pci_Log_Error("Connect Bus Unit", - pdn->busno, pdn->bussubno, *agent, err); - else { - err = HvCallPci_configStore8(pdn->busno, pdn->bussubno, - *agent, - PCI_INTERRUPT_LINE, - irq); - if (err) - pci_Log_Error("PciCfgStore Irq Failed!", - pdn->busno, pdn->bussubno, *agent, err); - } - if (!err) - pdev->irq = irq; - } - ++DeviceCount; pdev->sysdata = (void *)node; PCI_DN(node)->pcidev = pdev; @@ -257,6 +308,7 @@ void __init iSeries_pci_final_fixup(void) } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); + pdev->irq = PCI_DN(node)->Irq; } iSeries_activate_IRQs(); mf_display_src(0xC9000200); @@ -270,6 +322,148 @@ void pcibios_fixup_resources(struct pci_dev *pdev) { } +/* + * Loop through each node function to find usable EADs bridges. + */ +static void scan_PHB_slots(struct pci_controller *Phb) +{ + struct HvCallPci_DeviceInfo *DevInfo; + HvBusNumber bus = Phb->local_number; /* System Bus */ + const HvSubBusNumber SubBus = 0; /* EADs is always 0. */ + int HvRc = 0; + int IdSel; + const int MaxAgents = 8; + + DevInfo = (struct HvCallPci_DeviceInfo*) + kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL); + if (DevInfo == NULL) + return; + + /* + * Probe for EADs Bridges + */ + for (IdSel = 1; IdSel < MaxAgents; ++IdSel) { + HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, + iseries_hv_addr(DevInfo), + sizeof(struct HvCallPci_DeviceInfo)); + if (HvRc == 0) { + if (DevInfo->deviceType == HvCallPci_NodeDevice) + scan_EADS_bridge(bus, SubBus, IdSel); + else + printk("PCI: Invalid System Configuration(0x%02X)" + " for bus 0x%02x id 0x%02x.\n", + DevInfo->deviceType, bus, IdSel); + } + else + pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc); + } + kfree(DevInfo); +} + +static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, + int IdSel) +{ + struct HvCallPci_BridgeInfo *BridgeInfo; + HvAgentId AgentId; + int Function; + int HvRc; + + BridgeInfo = (struct HvCallPci_BridgeInfo *) + kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL); + if (BridgeInfo == NULL) + return; + + /* Note: hvSubBus and irq is always be 0 at this level! */ + for (Function = 0; Function < 8; ++Function) { + AgentId = ISERIES_PCI_AGENTID(IdSel, Function); + HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0); + if (HvRc == 0) { + printk("found device at bus %d idsel %d func %d (AgentId %x)\n", + bus, IdSel, Function, AgentId); + /* Connect EADs: 0x18.00.12 = 0x00 */ + HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, + iseries_hv_addr(BridgeInfo), + sizeof(struct HvCallPci_BridgeInfo)); + if (HvRc == 0) { + printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n", + BridgeInfo->busUnitInfo.deviceType, + BridgeInfo->subBusNumber, + BridgeInfo->maxAgents, + BridgeInfo->maxSubBusNumber, + BridgeInfo->logicalSlotNumber); + if (BridgeInfo->busUnitInfo.deviceType == + HvCallPci_BridgeDevice) { + /* Scan_Bridge_Slot...: 0x18.00.12 */ + scan_bridge_slot(bus, BridgeInfo); + } else + printk("PCI: Invalid Bridge Configuration(0x%02X)", + BridgeInfo->busUnitInfo.deviceType); + } + } else if (HvRc != 0x000B) + pci_Log_Error("EADs Connect", + bus, SubBus, AgentId, HvRc); + } + kfree(BridgeInfo); +} + +/* + * This assumes that the node slot is always on the primary bus! + */ +static int scan_bridge_slot(HvBusNumber Bus, + struct HvCallPci_BridgeInfo *BridgeInfo) +{ + struct device_node *node; + HvSubBusNumber SubBus = BridgeInfo->subBusNumber; + u16 VendorId = 0; + int HvRc = 0; + u8 Irq = 0; + int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus); + int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus); + HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function); + + /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */ + Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel); + + /* + * Connect all functions of any device found. + */ + for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { + for (Function = 0; Function < 8; ++Function) { + HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function); + HvRc = HvCallXm_connectBusUnit(Bus, SubBus, + AgentId, Irq); + if (HvRc != 0) { + pci_Log_Error("Connect Bus Unit", + Bus, SubBus, AgentId, HvRc); + continue; + } + + HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, + PCI_VENDOR_ID, &VendorId); + if (HvRc != 0) { + pci_Log_Error("Read Vendor", + Bus, SubBus, AgentId, HvRc); + continue; + } + printk("read vendor ID: %x\n", VendorId); + + /* FoundDevice: 0x18.28.10 = 0x12AE */ + HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, + PCI_INTERRUPT_LINE, Irq); + if (HvRc != 0) + pci_Log_Error("PciCfgStore Irq Failed!", + Bus, SubBus, AgentId, HvRc); + + ++DeviceCount; + node = build_device_node(Bus, SubBus, EADsIdSel, Function); + PCI_DN(node)->Irq = Irq; + PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber; + + } /* for (Function = 0; Function < 8; ++Function) */ + } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ + return HvRc; +} + /* * I/0 Memory copy MUST use mmio commands on iSeries * To do; For performance, include the hv call directly @@ -315,13 +509,11 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio); */ static struct device_node *find_Device_Node(int bus, int devfn) { - struct device_node *node; - - for (node = NULL; (node = of_find_all_nodes(node)); ) { - struct pci_dn *pdn = PCI_DN(node); + struct pci_dn *pdn; - if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn)) - return node; + list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { + if ((bus == pdn->busno) && (devfn == pdn->devfn)) + return pdn->node; } return NULL; } @@ -433,6 +625,7 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, if (ret != 0) { struct pci_dn *pdn = PCI_DN(DevNode); + ++Pci_Error_Count; (*retry)++; printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", TextHdr, pdn->busno, pdn->devfn, @@ -514,6 +707,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) return 0xff; } do { + ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); @@ -543,6 +737,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) return 0xffff; } do { + ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, BarOffset, 0); } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); @@ -573,6 +768,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) return 0xffffffff; } do { + ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, BarOffset, 0); } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); @@ -610,6 +806,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) return; } do { + ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); } @@ -637,6 +834,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) return; } do { + ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); } @@ -664,6 +862,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) return; } do { + ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); } diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 617c724c4590..a6fd9bedb074 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,9 @@ extern void iSeries_pci_final_fixup(void); static void iSeries_pci_final_fixup(void) { } #endif +/* Global Variables */ +int piranha_simulator; + extern int rd_size; /* Defined in drivers/block/rd.c */ extern unsigned long embedded_sysmap_start; extern unsigned long embedded_sysmap_end; @@ -87,6 +91,8 @@ extern unsigned long embedded_sysmap_end; extern unsigned long iSeries_recal_tb; extern unsigned long iSeries_recal_titan; +static unsigned long cmd_mem_limit; + struct MemoryBlock { unsigned long absStart; unsigned long absEnd; @@ -334,6 +340,8 @@ static void __init iSeries_init_early(void) #ifdef CONFIG_SMP smp_init_iSeries(); #endif + if (itLpNaca.xPirEnvironMode == 0) + piranha_simulator = 1; /* Associate Lp Event Queue 0 with processor 0 */ HvCallEvent_setLpEventQueueInterruptProc(0, 0); @@ -528,10 +536,10 @@ static void __init iSeries_setup_arch(void) { if (get_lppaca()->shared_proc) { ppc_md.idle_loop = iseries_shared_idle; - printk(KERN_DEBUG "Using shared processor idle loop\n"); + printk(KERN_INFO "Using shared processor idle loop\n"); } else { ppc_md.idle_loop = iseries_dedicated_idle; - printk(KERN_DEBUG "Using dedicated idle loop\n"); + printk(KERN_INFO "Using dedicated idle loop\n"); } /* Setup the Lp Event Queue */ @@ -706,6 +714,243 @@ define_machine(iseries) { /* XXX Implement enable_pmcs for iSeries */ }; +struct blob { + unsigned char data[PAGE_SIZE]; + unsigned long next; +}; + +struct iseries_flat_dt { + struct boot_param_header header; + u64 reserve_map[2]; + struct blob dt; + struct blob strings; +}; + +struct iseries_flat_dt iseries_dt; + +void dt_init(struct iseries_flat_dt *dt) +{ + dt->header.off_mem_rsvmap = + offsetof(struct iseries_flat_dt, reserve_map); + dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt); + dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings); + dt->header.totalsize = sizeof(struct iseries_flat_dt); + dt->header.dt_strings_size = sizeof(struct blob); + + /* There is no notion of hardware cpu id on iSeries */ + dt->header.boot_cpuid_phys = smp_processor_id(); + + dt->dt.next = (unsigned long)&dt->dt.data; + dt->strings.next = (unsigned long)&dt->strings.data; + + dt->header.magic = OF_DT_HEADER; + dt->header.version = 0x10; + dt->header.last_comp_version = 0x10; + + dt->reserve_map[0] = 0; + dt->reserve_map[1] = 0; +} + +void dt_check_blob(struct blob *b) +{ + if (b->next >= (unsigned long)&b->next) { + DBG("Ran out of space in flat device tree blob!\n"); + BUG(); + } +} + +void dt_push_u32(struct iseries_flat_dt *dt, u32 value) +{ + *((u32*)dt->dt.next) = value; + dt->dt.next += sizeof(u32); + + dt_check_blob(&dt->dt); +} + +void dt_push_u64(struct iseries_flat_dt *dt, u64 value) +{ + *((u64*)dt->dt.next) = value; + dt->dt.next += sizeof(u64); + + dt_check_blob(&dt->dt); +} + +unsigned long dt_push_bytes(struct blob *blob, char *data, int len) +{ + unsigned long start = blob->next - (unsigned long)blob->data; + + memcpy((char *)blob->next, data, len); + blob->next = _ALIGN(blob->next + len, 4); + + dt_check_blob(blob); + + return start; +} + +void dt_start_node(struct iseries_flat_dt *dt, char *name) +{ + dt_push_u32(dt, OF_DT_BEGIN_NODE); + dt_push_bytes(&dt->dt, name, strlen(name) + 1); +} + +#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) + +void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len) +{ + unsigned long offset; + + dt_push_u32(dt, OF_DT_PROP); + + /* Length of the data */ + dt_push_u32(dt, len); + + /* Put the property name in the string blob. */ + offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1); + + /* The offset of the properties name in the string blob. */ + dt_push_u32(dt, (u32)offset); + + /* The actual data. */ + dt_push_bytes(&dt->dt, data, len); +} + +void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data) +{ + dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ +} + +void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u32)); +} + +void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u64)); +} + +void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n) +{ + dt_prop(dt, name, (char *)data, sizeof(u64) * n); +} + +void dt_prop_u32_list(struct iseries_flat_dt *dt, char *name, u32 *data, int n) +{ + dt_prop(dt, name, (char *)data, sizeof(u32) * n); +} + +void dt_prop_empty(struct iseries_flat_dt *dt, char *name) +{ + dt_prop(dt, name, NULL, 0); +} + +void dt_cpus(struct iseries_flat_dt *dt) +{ + unsigned char buf[32]; + unsigned char *p; + unsigned int i, index; + struct IoHriProcessorVpd *d; + u32 pft_size[2]; + + /* yuck */ + snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); + p = strchr(buf, ' '); + if (!p) p = buf + strlen(buf); + + dt_start_node(dt, "cpus"); + dt_prop_u32(dt, "#address-cells", 1); + dt_prop_u32(dt, "#size-cells", 0); + + pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */ + pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); + + for (i = 0; i < NR_CPUS; i++) { + if (lppaca[i].dyn_proc_status >= 2) + continue; + + snprintf(p, 32 - (p - buf), "@%d", i); + dt_start_node(dt, buf); + + dt_prop_str(dt, "device_type", "cpu"); + + index = lppaca[i].dyn_hv_phys_proc_index; + d = &xIoHriProcessorVpd[index]; + + dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); + dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); + + dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); + dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); + + /* magic conversions to Hz copied from old code */ + dt_prop_u32(dt, "clock-frequency", + ((1UL << 34) * 1000000) / d->xProcFreq); + dt_prop_u32(dt, "timebase-frequency", + ((1UL << 32) * 1000000) / d->xTimeBaseFreq); + + dt_prop_u32(dt, "reg", i); + + dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2); + + dt_end_node(dt); + } + + dt_end_node(dt); +} + +void dt_model(struct iseries_flat_dt *dt) +{ + char buf[16] = "IBM,"; + + /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ + strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); + strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); + buf[11] = '\0'; + dt_prop_str(dt, "system-id", buf); + + /* "IBM," + machineType[0:4] */ + strne2a(buf + 4, xItExtVpdPanel.machineType, 4); + buf[8] = '\0'; + dt_prop_str(dt, "model", buf); + + dt_prop_str(dt, "compatible", "IBM,iSeries"); +} + +void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) +{ + u64 tmp[2]; + + dt_init(dt); + + dt_start_node(dt, ""); + + dt_prop_u32(dt, "#address-cells", 2); + dt_prop_u32(dt, "#size-cells", 2); + dt_model(dt); + + /* /memory */ + dt_start_node(dt, "memory@0"); + dt_prop_str(dt, "name", "memory"); + dt_prop_str(dt, "device_type", "memory"); + tmp[0] = 0; + tmp[1] = phys_mem_size; + dt_prop_u64_list(dt, "reg", tmp, 2); + dt_end_node(dt); + + /* /chosen */ + dt_start_node(dt, "chosen"); + dt_prop_str(dt, "bootargs", cmd_line); + if (cmd_mem_limit) + dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); + dt_end_node(dt); + + dt_cpus(dt); + + dt_end_node(dt); + + dt_push_u32(dt, OF_DT_END); +} + void * __init iSeries_early_setup(void) { unsigned long phys_mem_size; @@ -720,8 +965,28 @@ void * __init iSeries_early_setup(void) iSeries_get_cmdline(); - return (void *) __pa(build_flat_dt(phys_mem_size)); + /* Save unparsed command line copy for /proc/cmdline */ + strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); + + /* Parse early parameters, in particular mem=x */ + parse_early_param(); + + build_flat_dt(&iseries_dt, phys_mem_size); + + return (void *) __pa(&iseries_dt); +} + +/* + * On iSeries we just parse the mem=X option from the command line. + * On pSeries it's a bit more complicated, see prom_init_mem() + */ +static int __init early_parsemem(char *p) +{ + if (p) + cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE); + return 0; } +early_param("mem", early_parsemem); static void hvputc(char c) { diff --git a/trunk/arch/powerpc/platforms/iseries/setup.h b/trunk/arch/powerpc/platforms/iseries/setup.h index 0a47ac53c959..5213044ec411 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.h +++ b/trunk/arch/powerpc/platforms/iseries/setup.h @@ -21,6 +21,4 @@ extern unsigned long iSeries_get_boot_time(void); extern int iSeries_set_rtc_time(struct rtc_time *tm); extern void iSeries_get_rtc_time(struct rtc_time *tm); -extern void *build_flat_dt(unsigned long phys_mem_size); - #endif /* __ISERIES_SETUP_H__ */ diff --git a/trunk/arch/powerpc/platforms/iseries/vio.c b/trunk/arch/powerpc/platforms/iseries/vio.c new file mode 100644 index 000000000000..ad36ab0639f0 --- /dev/null +++ b/trunk/arch/powerpc/platforms/iseries/vio.c @@ -0,0 +1,131 @@ +/* + * IBM PowerPC iSeries Virtual I/O Infrastructure Support. + * + * Copyright (c) 2005 Stephen Rothwell, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iommu.h" + +struct device *iSeries_vio_dev = &vio_bus_device.dev; +EXPORT_SYMBOL(iSeries_vio_dev); + +static struct iommu_table veth_iommu_table; +static struct iommu_table vio_iommu_table; + +static void __init iommu_vio_init(void) +{ + iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); + veth_iommu_table.it_size /= 2; + vio_iommu_table = veth_iommu_table; + vio_iommu_table.it_offset += veth_iommu_table.it_size; + + if (!iommu_init_table(&veth_iommu_table)) + printk("Virtual Bus VETH TCE table failed.\n"); + if (!iommu_init_table(&vio_iommu_table)) + printk("Virtual Bus VIO TCE table failed.\n"); +} + +/** + * vio_register_device_iseries: - Register a new iSeries vio device. + * @voidev: The device to register. + */ +static struct vio_dev *__init vio_register_device_iseries(char *type, + uint32_t unit_num) +{ + struct vio_dev *viodev; + + /* allocate a vio_dev for this device */ + viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); + if (!viodev) + return NULL; + memset(viodev, 0, sizeof(struct vio_dev)); + + snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num); + + viodev->name = viodev->dev.bus_id; + viodev->type = type; + viodev->unit_address = unit_num; + viodev->iommu_table = &vio_iommu_table; + if (vio_register_device(viodev) == NULL) { + kfree(viodev); + return NULL; + } + return viodev; +} + +void __init probe_bus_iseries(void) +{ + HvLpIndexMap vlan_map; + struct vio_dev *viodev; + int i; + + /* there is only one of each of these */ + vio_register_device_iseries("viocons", 0); + vio_register_device_iseries("vscsi", 0); + + vlan_map = HvLpConfig_getVirtualLanIndexMap(); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { + if ((vlan_map & (0x8000 >> i)) == 0) + continue; + viodev = vio_register_device_iseries("vlan", i); + /* veth is special and has it own iommu_table */ + viodev->iommu_table = &veth_iommu_table; + } + for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) + vio_register_device_iseries("viodasd", i); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) + vio_register_device_iseries("viocd", i); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) + vio_register_device_iseries("viotape", i); +} + +/** + * vio_match_device_iseries: - Tell if a iSeries VIO device matches a + * vio_device_id + */ +static int vio_match_device_iseries(const struct vio_device_id *id, + const struct vio_dev *dev) +{ + return strncmp(dev->type, id->type, strlen(id->type)) == 0; +} + +static struct vio_bus_ops vio_bus_ops_iseries = { + .match = vio_match_device_iseries, +}; + +/** + * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus + */ +static int __init vio_bus_init_iseries(void) +{ + int err; + + err = vio_bus_init(&vio_bus_ops_iseries); + if (err == 0) { + iommu_vio_init(); + vio_bus_device.iommu_table = &vio_iommu_table; + iSeries_vio_dev = &vio_bus_device.dev; + probe_bus_iseries(); + } + return err; +} + +__initcall(vio_bus_init_iseries); diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index 9a4efc0c3b29..85d6c93659cc 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -437,6 +437,9 @@ void __init maple_pci_init(void) /* Tell pci.c to not change any resource allocations. */ pci_probe_only = 1; + + /* Allow all IO */ + io_page_mask = -1; } int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index a0505ea48a86..24c0aef4ea39 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -189,7 +189,7 @@ void __init maple_setup_arch(void) conswitchp = &dummy_con; #endif - printk(KERN_DEBUG "Using native/NAP idle loop\n"); + printk(KERN_INFO "Using native/NAP idle loop\n"); } /* diff --git a/trunk/arch/powerpc/platforms/powermac/backlight.c b/trunk/arch/powerpc/platforms/powermac/backlight.c index 498b042e1837..8be2f7d071f0 100644 --- a/trunk/arch/powerpc/platforms/powermac/backlight.c +++ b/trunk/arch/powerpc/platforms/powermac/backlight.c @@ -3,148 +3,200 @@ * Contains support for the backlight. * * Copyright (C) 2000 Benjamin Herrenschmidt - * Copyright (C) 2006 Michael Hanselmann * */ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include -#define OLD_BACKLIGHT_MAX 15 +#include +#include -/* Protect the pmac_backlight variable */ -DEFINE_MUTEX(pmac_backlight_mutex); +static struct backlight_controller *backlighter; +static void* backlighter_data; +static int backlight_autosave; +static int backlight_level = BACKLIGHT_MAX; +static int backlight_enabled = 1; +static int backlight_req_level = -1; +static int backlight_req_enable = -1; -/* Main backlight storage - * - * Backlight drivers in this variable are required to have the "props" - * attribute set and to have an update_status function. - * - * We can only store one backlight here, but since Apple laptops have only one - * internal display, it doesn't matter. Other backlight drivers can be used - * independently. - * - * Lock ordering: - * pmac_backlight_mutex (global, main backlight) - * pmac_backlight->sem (backlight class) - */ -struct backlight_device *pmac_backlight; +static void backlight_callback(void *); +static DECLARE_WORK(backlight_work, backlight_callback, NULL); -int pmac_has_backlight_type(const char *type) +void register_backlight_controller(struct backlight_controller *ctrler, + void *data, char *type) { - struct device_node* bk_node = find_devices("backlight"); - + struct device_node* bk_node; + char *prop; + int valid = 0; + + /* There's already a matching controller, bail out */ + if (backlighter != NULL) + return; + + bk_node = find_devices("backlight"); + +#ifdef CONFIG_ADB_PMU + /* Special case for the old PowerBook since I can't test on it */ + backlight_autosave = machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500"); + if ((backlight_autosave + || machine_is_compatible("AAPL,PowerBook1998") + || machine_is_compatible("PowerBook1,1")) + && !strcmp(type, "pmu")) + valid = 1; +#endif if (bk_node) { - char *prop = get_property(bk_node, "backlight-control", NULL); - if (prop && strncmp(prop, type, strlen(type)) == 0) - return 1; + prop = get_property(bk_node, "backlight-control", NULL); + if (prop && !strncmp(prop, type, strlen(type))) + valid = 1; + } + if (!valid) + return; + backlighter = ctrler; + backlighter_data = data; + + if (bk_node && !backlight_autosave) + prop = get_property(bk_node, "bklt", NULL); + else + prop = NULL; + if (prop) { + backlight_level = ((*prop)+1) >> 1; + if (backlight_level > BACKLIGHT_MAX) + backlight_level = BACKLIGHT_MAX; } - return 0; +#ifdef CONFIG_ADB_PMU + if (backlight_autosave) { + struct adb_request req; + pmu_request(&req, NULL, 2, 0xd9, 0); + while (!req.complete) + pmu_poll(); + backlight_level = req.reply[0] >> 4; + } +#endif + acquire_console_sem(); + if (!backlighter->set_enable(1, backlight_level, data)) + backlight_enabled = 1; + release_console_sem(); + + printk(KERN_INFO "Registered \"%s\" backlight controller," + "level: %d/15\n", type, backlight_level); } +EXPORT_SYMBOL(register_backlight_controller); -int pmac_backlight_curve_lookup(struct fb_info *info, int value) +void unregister_backlight_controller(struct backlight_controller + *ctrler, void *data) { - int level = (FB_BACKLIGHT_LEVELS - 1); - - if (info && info->bl_dev) { - int i, max = 0; - - /* Look for biggest value */ - for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) - max = max((int)info->bl_curve[i], max); - - /* Look for nearest value */ - for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) { - int diff = abs(info->bl_curve[i] - value); - if (diff < max) { - max = diff; - level = i; - } - } - - } - - return level; + /* We keep the current backlight level (for now) */ + if (ctrler == backlighter && data == backlighter_data) + backlighter = NULL; } +EXPORT_SYMBOL(unregister_backlight_controller); -static void pmac_backlight_key(int direction) +static int __set_backlight_enable(int enable) { - mutex_lock(&pmac_backlight_mutex); - if (pmac_backlight) { - struct backlight_properties *props; - int brightness; - - down(&pmac_backlight->sem); - props = pmac_backlight->props; - - brightness = props->brightness + - ((direction?-1:1) * (props->max_brightness / 15)); - - if (brightness < 0) - brightness = 0; - else if (brightness > props->max_brightness) - brightness = props->max_brightness; - - props->brightness = brightness; - props->update_status(pmac_backlight); - - up(&pmac_backlight->sem); - } - mutex_unlock(&pmac_backlight_mutex); + int rc; + + if (!backlighter) + return -ENODEV; + acquire_console_sem(); + rc = backlighter->set_enable(enable, backlight_level, + backlighter_data); + if (!rc) + backlight_enabled = enable; + release_console_sem(); + return rc; } - -void pmac_backlight_key_up() +int set_backlight_enable(int enable) { - pmac_backlight_key(0); + if (!backlighter) + return -ENODEV; + backlight_req_enable = enable; + schedule_work(&backlight_work); + return 0; } -void pmac_backlight_key_down() +EXPORT_SYMBOL(set_backlight_enable); + +int get_backlight_enable(void) { - pmac_backlight_key(1); + if (!backlighter) + return -ENODEV; + return backlight_enabled; } +EXPORT_SYMBOL(get_backlight_enable); -int pmac_backlight_set_legacy_brightness(int brightness) +static int __set_backlight_level(int level) { - int error = -ENXIO; - - mutex_lock(&pmac_backlight_mutex); - if (pmac_backlight) { - struct backlight_properties *props; - - down(&pmac_backlight->sem); - props = pmac_backlight->props; - props->brightness = brightness * - props->max_brightness / OLD_BACKLIGHT_MAX; - props->update_status(pmac_backlight); - up(&pmac_backlight->sem); - - error = 0; + int rc = 0; + + if (!backlighter) + return -ENODEV; + if (level < BACKLIGHT_MIN) + level = BACKLIGHT_OFF; + if (level > BACKLIGHT_MAX) + level = BACKLIGHT_MAX; + acquire_console_sem(); + if (backlight_enabled) + rc = backlighter->set_level(level, backlighter_data); + if (!rc) + backlight_level = level; + release_console_sem(); + if (!rc && !backlight_autosave) { + level <<=1; + if (level & 0x10) + level |= 0x01; + // -- todo: save to property "bklt" } - mutex_unlock(&pmac_backlight_mutex); - - return error; + return rc; } - -int pmac_backlight_get_legacy_brightness() +int set_backlight_level(int level) { - int result = -ENXIO; + if (!backlighter) + return -ENODEV; + backlight_req_level = level; + schedule_work(&backlight_work); + return 0; +} - mutex_lock(&pmac_backlight_mutex); - if (pmac_backlight) { - struct backlight_properties *props; +EXPORT_SYMBOL(set_backlight_level); - down(&pmac_backlight->sem); - props = pmac_backlight->props; - result = props->brightness * - OLD_BACKLIGHT_MAX / props->max_brightness; - up(&pmac_backlight->sem); - } - mutex_unlock(&pmac_backlight_mutex); +int get_backlight_level(void) +{ + if (!backlighter) + return -ENODEV; + return backlight_level; +} +EXPORT_SYMBOL(get_backlight_level); - return result; +static void backlight_callback(void *dummy) +{ + int level, enable; + + do { + level = backlight_req_level; + enable = backlight_req_enable; + mb(); + + if (level >= 0) + __set_backlight_level(level); + if (enable >= 0) + __set_backlight_enable(enable); + } while(cmpxchg(&backlight_req_level, level, -1) != level || + cmpxchg(&backlight_req_enable, enable, -1) != enable); } diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c index af2a8f9f1222..cfd6527a0d7e 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -314,7 +314,7 @@ static int pmu_set_cpu_speed(int low_speed) _set_L3CR(save_l3cr); /* Restore userland MMU context */ - set_context(current->active_mm->context.id, current->active_mm->pgd); + set_context(current->active_mm->context, current->active_mm->pgd); #ifdef DEBUG_FREQ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index 85e00cb0006e..a5063cd675c5 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -2510,7 +2510,7 @@ static int __init probe_motherboard(void) if (get_property(np, "flush-on-lock", NULL)) break; powersave_nap = 1; - printk(KERN_DEBUG "Processor NAP mode on idle enabled.\n"); + printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); break; } diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index 80035853467b..ea179afea632 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -1068,6 +1068,9 @@ void __init pmac_pci_init(void) /* Tell pci.c to not use the common resource allocation mechanism */ pci_probe_only = 1; + /* Allow all IO */ + io_page_mask = -1; + #else /* CONFIG_PPC64 */ init_p2pbridge(); fixup_nec_usb2(); diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c b/trunk/arch/powerpc/platforms/powermac/pfunc_core.c index 93e7505debc5..f08173b0f065 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_core.c @@ -546,7 +546,7 @@ struct pmf_device { }; static LIST_HEAD(pmf_devices); -static DEFINE_SPINLOCK(pmf_lock); +static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) @@ -871,17 +871,10 @@ int pmf_register_irq_client(struct device_node *target, spin_unlock_irqrestore(&pmf_lock, flags); if (func == NULL) return -ENODEV; - - /* guard against manipulations of list */ mutex_lock(&pmf_irq_mutex); if (list_empty(&func->irq_clients)) func->dev->handlers->irq_enable(func); - - /* guard against pmf_do_irq while changing list */ - spin_lock_irqsave(&pmf_lock, flags); list_add(&client->link, &func->irq_clients); - spin_unlock_irqrestore(&pmf_lock, flags); - client->func = func; mutex_unlock(&pmf_irq_mutex); @@ -892,19 +885,12 @@ EXPORT_SYMBOL_GPL(pmf_register_irq_client); void pmf_unregister_irq_client(struct pmf_irq_client *client) { struct pmf_function *func = client->func; - unsigned long flags; BUG_ON(func == NULL); - /* guard against manipulations of list */ mutex_lock(&pmf_irq_mutex); client->func = NULL; - - /* guard against pmf_do_irq while changing list */ - spin_lock_irqsave(&pmf_lock, flags); list_del(&client->link); - spin_unlock_irqrestore(&pmf_lock, flags); - if (list_empty(&func->irq_clients)) func->dev->handlers->irq_disable(func); mutex_unlock(&pmf_irq_mutex); diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bdc..b9200fb07815 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -458,7 +458,7 @@ static int pmac_pm_finish(suspend_state_t state) printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); /* Restore userland MMU context */ - set_context(current->active_mm->context.id, current->active_mm->pgd); + set_context(current->active_mm->context, current->active_mm->pgd); return 0; } diff --git a/trunk/arch/powerpc/platforms/pseries/Makefile b/trunk/arch/powerpc/platforms/pseries/Makefile index e5e0ff466904..930898635c9f 100644 --- a/trunk/arch/powerpc/platforms/pseries/Makefile +++ b/trunk/arch/powerpc/platforms/pseries/Makefile @@ -1,11 +1,8 @@ -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif - obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ firmware.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c index c37a8497c60f..d4a402c5866c 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c @@ -287,7 +287,7 @@ void pci_addr_cache_remove_device(struct pci_dev *dev) * find the pci device that corresponds to a given address. * This routine scans all pci busses to build the cache. * Must be run late in boot process, after the pci controllers - * have been scanned for devices (after all device resources are known). + * have been scaned for devices (after all device resources are known). */ void __init pci_addr_cache_build(void) { @@ -304,8 +304,6 @@ void __init pci_addr_cache_build(void) pci_addr_cache_insert_device(dev); dn = pci_device_to_OF_node(dev); - if (!dn) - continue; pci_dev_get (dev); /* matching put is in eeh_remove_device() */ PCI_DN(dn)->pcidev = dev; } diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index 0ec9a5445b95..1fba695e32e8 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -23,8 +23,9 @@ * */ #include -#include #include +#include +#include #include #include #include @@ -201,11 +202,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) { - int cnt, rc; - - /* pcibios will clear the counter; save the value */ - cnt = pe_dn->eeh_freeze_count; - + int rc; if (bus) pcibios_remove_pci_devices(bus); @@ -244,7 +241,6 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) ssleep (5); pcibios_add_pci_devices(bus); } - pe_dn->eeh_freeze_count = cnt; return 0; } @@ -254,29 +250,23 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) */ #define MAX_WAIT_FOR_RECOVERY 15 -struct pci_dn * handle_eeh_events (struct eeh_event *event) +void handle_eeh_events (struct eeh_event *event) { struct device_node *frozen_dn; struct pci_dn *frozen_pdn; struct pci_bus *frozen_bus; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; - const char *location, *pci_str, *drv_str; + const char *pci_str, *drv_str; frozen_dn = find_device_pe(event->dn); frozen_bus = pcibios_find_pci_bus(frozen_dn); if (!frozen_dn) { - - location = (char *) get_property(event->dn, "ibm,loc-code", NULL); - 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)); - return NULL; + printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n", + pci_name(event->dev)); + return; } - location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL); - location = location ? location : "unknown"; /* There are two different styles for coming up with the PE. * In the old style, it was the highest EEH-capable device @@ -288,10 +278,9 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) frozen_bus = pcibios_find_pci_bus (frozen_dn->parent); if (!frozen_bus) { - printk(KERN_ERR "EEH: Cannot find PCI bus " - "for location=%s dn=%s\n", - location, frozen_dn->full_name); - return NULL; + printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n", + frozen_dn->full_name); + return; } #if 0 @@ -325,9 +314,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); printk(KERN_WARNING - "EEH: This PCI device has failed %d times since last reboot: " - "location=%s driver=%s pci addr=%s\n", - frozen_pdn->eeh_freeze_count, location, drv_str, pci_str); + "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", + frozen_pdn->eeh_freeze_count, drv_str, pci_str); /* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs @@ -367,7 +355,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) /* Tell all device drivers that they can resume operations */ pci_walk_bus(frozen_bus, eeh_report_resume, NULL); - return frozen_pdn; + return; excess_failures: /* @@ -376,18 +364,17 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) * due to actual, failed cards. */ printk(KERN_ERR - "EEH: PCI device at location=%s driver=%s pci addr=%s \n" - "has failed %d times and has been permanently disabled. \n" - "Please try reseating this device or replacing it.\n", - location, drv_str, pci_str, frozen_pdn->eeh_freeze_count); + "EEH: PCI device %s - %s has failed %d times \n" + "and has been permanently disabled. Please try reseating\n" + "this device or replacing it.\n", + drv_str, pci_str, frozen_pdn->eeh_freeze_count); goto perm_error; hard_fail: printk(KERN_ERR - "EEH: Unable to recover from failure of PCI device " - "at location=%s driver=%s pci addr=%s \n" + "EEH: Unable to recover from failure of PCI device %s - %s\n" "Please try reseating this device or replacing it.\n", - location, drv_str, pci_str); + drv_str, pci_str); perm_error: eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); @@ -397,8 +384,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) /* Shut down the device drivers for good. */ pcibios_remove_pci_devices(frozen_bus); - - return NULL; } /* ---------- end of file ---------- */ diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c index 45ccc687e57c..40020c65c89e 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c @@ -18,7 +18,6 @@ * Copyright (c) 2005 Linas Vepstas */ -#include #include #include #include @@ -35,7 +34,7 @@ */ /* EEH event workqueue setup. */ -static DEFINE_SPINLOCK(eeh_eventlist_lock); +static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED; LIST_HEAD(eeh_eventlist); static void eeh_thread_launcher(void *); DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); @@ -57,43 +56,38 @@ static int eeh_event_handler(void * dummy) { unsigned long flags; struct eeh_event *event; - struct pci_dn *pdn; daemonize ("eehd"); - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irqsave(&eeh_eventlist_lock, flags); - event = NULL; + while (1) { + set_current_state(TASK_INTERRUPTIBLE); - /* Unqueue the event, get ready to process. */ - if (!list_empty(&eeh_eventlist)) { - event = list_entry(eeh_eventlist.next, struct eeh_event, list); - list_del(&event->list); - } - spin_unlock_irqrestore(&eeh_eventlist_lock, flags); + spin_lock_irqsave(&eeh_eventlist_lock, flags); + event = NULL; - if (event == NULL) - return 0; + /* Unqueue the event, get ready to process. */ + if (!list_empty(&eeh_eventlist)) { + event = list_entry(eeh_eventlist.next, struct eeh_event, list); + list_del(&event->list); + } + spin_unlock_irqrestore(&eeh_eventlist_lock, flags); - /* Serialize processing of EEH events */ - mutex_lock(&eeh_event_mutex); - eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); + if (event == NULL) + break; - printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", - pci_name(event->dev)); + /* Serialize processing of EEH events */ + mutex_lock(&eeh_event_mutex); + eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); - pdn = handle_eeh_events(event); + printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", + pci_name(event->dev)); - eeh_clear_slot(event->dn, EEH_MODE_RECOVERING); - pci_dev_put(event->dev); - kfree(event); - mutex_unlock(&eeh_event_mutex); + handle_eeh_events(event); - /* If there are no new errors after an hour, clear the counter. */ - if (pdn && pdn->eeh_freeze_count>0) { - msleep_interruptible (3600*1000); - if (pdn->eeh_freeze_count>0) - pdn->eeh_freeze_count--; + eeh_clear_slot(event->dn, EEH_MODE_RECOVERING); + pci_dev_put(event->dev); + kfree(event); + mutex_unlock(&eeh_event_mutex); } return 0; diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9d..2643078433f0 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -1,24 +1,23 @@ /* * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * - * Rewrite, cleanup: + * Rewrite, cleanup: * * Copyright (C) 2004 Olof Johansson , IBM Corporation - * Copyright (C) 2006 Olof Johansson * * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. * - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -50,46 +49,52 @@ #define DBG(fmt...) -static void tce_build_pSeries(struct iommu_table *tbl, long index, - long npages, unsigned long uaddr, +static void tce_build_pSeries(struct iommu_table *tbl, long index, + long npages, unsigned long uaddr, enum dma_data_direction direction) { - u64 proto_tce; - u64 *tcep; - u64 rpn; + union tce_entry t; + union tce_entry *tp; index <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; - proto_tce = TCE_PCI_READ; // Read allowed + t.te_word = 0; + t.te_rdwr = 1; // Read allowed if (direction != DMA_TO_DEVICE) - proto_tce |= TCE_PCI_WRITE; + t.te_pciwr = 1; - tcep = ((u64 *)tbl->it_base) + index; + tp = ((union tce_entry *)tbl->it_base) + index; while (npages--) { /* can't move this out since we might cross LMB boundary */ - rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; - *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; + t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; + + tp->te_word = t.te_word; uaddr += TCE_PAGE_SIZE; - tcep++; + tp++; } } static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) { - u64 *tcep; + union tce_entry t; + union tce_entry *tp; npages <<= TCE_PAGE_FACTOR; index <<= TCE_PAGE_FACTOR; - tcep = ((u64 *)tbl->it_base) + index; - - while (npages--) - *(tcep++) = 0; + t.te_word = 0; + tp = ((union tce_entry *)tbl->it_base) + index; + + while (npages--) { + tp->te_word = t.te_word; + + tp++; + } } @@ -98,44 +103,43 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, enum dma_data_direction direction) { u64 rc; - u64 proto_tce, tce; - u64 rpn; + union tce_entry tce; tcenum <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; - rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; - proto_tce = TCE_PCI_READ; + tce.te_word = 0; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; + tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) - proto_tce |= TCE_PCI_WRITE; + tce.te_pciwr = 1; while (npages--) { - tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; - rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce); - + rc = plpar_tce_put((u64)tbl->it_index, + (u64)tcenum << 12, + tce.te_word ); + if (rc && printk_ratelimit()) { printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); printk("\tindex = 0x%lx\n", (u64)tbl->it_index); printk("\ttcenum = 0x%lx\n", (u64)tcenum); - printk("\ttce val = 0x%lx\n", tce ); + printk("\ttce val = 0x%lx\n", tce.te_word ); show_stack(current, (unsigned long *)__get_SP()); } - + tcenum++; - rpn++; + tce.te_rpn++; } } -static DEFINE_PER_CPU(u64 *, tce_page) = NULL; +static DEFINE_PER_CPU(void *, tce_page) = NULL; static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, enum dma_data_direction direction) { u64 rc; - u64 proto_tce; - u64 *tcep; - u64 rpn; + union tce_entry tce, *tcep; long l, limit; if (TCE_PAGE_FACTOR == 0 && npages == 1) @@ -148,7 +152,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, * from iommu_alloc{,_sg}() */ if (!tcep) { - tcep = (u64 *)__get_free_page(GFP_ATOMIC); + tcep = (void *)__get_free_page(GFP_ATOMIC); /* If allocation fails, fall back to the loop implementation */ if (!tcep) return tce_build_pSeriesLP(tbl, tcenum, npages, @@ -159,10 +163,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, tcenum <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; - rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; - proto_tce = TCE_PCI_READ; + tce.te_word = 0; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; + tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) - proto_tce |= TCE_PCI_WRITE; + tce.te_pciwr = 1; /* We can map max one pageful of TCEs at a time */ do { @@ -170,11 +175,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, * Set up the page with TCE data, looping through and setting * the values. */ - limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE); + limit = min_t(long, npages, 4096/sizeof(union tce_entry)); for (l = 0; l < limit; l++) { - tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; - rpn++; + tcep[l] = tce; + tce.te_rpn++; } rc = plpar_tce_put_indirect((u64)tbl->it_index, @@ -190,7 +195,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); printk("\tindex = 0x%lx\n", (u64)tbl->it_index); printk("\tnpages = 0x%lx\n", (u64)npages); - printk("\ttce[0] val = 0x%lx\n", tcep[0]); + printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word); show_stack(current, (unsigned long *)__get_SP()); } } @@ -198,17 +203,23 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) { u64 rc; + union tce_entry tce; tcenum <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; + tce.te_word = 0; + while (npages--) { - rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); + rc = plpar_tce_put((u64)tbl->it_index, + (u64)tcenum << 12, + tce.te_word); if (rc && printk_ratelimit()) { printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); printk("\tindex = 0x%lx\n", (u64)tbl->it_index); printk("\ttcenum = 0x%lx\n", (u64)tcenum); + printk("\ttce val = 0x%lx\n", tce.te_word ); show_stack(current, (unsigned long *)__get_SP()); } @@ -220,24 +231,31 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) { u64 rc; + union tce_entry tce; tcenum <<= TCE_PAGE_FACTOR; npages <<= TCE_PAGE_FACTOR; - rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); + tce.te_word = 0; + + rc = plpar_tce_stuff((u64)tbl->it_index, + (u64)tcenum << 12, + tce.te_word, + npages); if (rc && printk_ratelimit()) { printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); printk("\trc = %ld\n", rc); printk("\tindex = 0x%lx\n", (u64)tbl->it_index); printk("\tnpages = 0x%lx\n", (u64)npages); + printk("\ttce val = 0x%lx\n", tce.te_word ); show_stack(current, (unsigned long *)__get_SP()); } } static void iommu_table_setparms(struct pci_controller *phb, struct device_node *dn, - struct iommu_table *tbl) + struct iommu_table *tbl) { struct device_node *node; unsigned long *basep; @@ -257,16 +275,16 @@ static void iommu_table_setparms(struct pci_controller *phb, memset((void *)tbl->it_base, 0, *sizep); tbl->it_busno = phb->bus->number; - + /* Units of tce entries */ tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; - + /* Test if we are going over 2GB of DMA space */ if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); - panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); + panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); } - + phb->dma_window_base_cur += phb->dma_window_size; /* Set the tce table size - measured in entries */ @@ -281,22 +299,30 @@ static void iommu_table_setparms(struct pci_controller *phb, * iommu_table_setparms_lpar * * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. + * + * ToDo: properly interpret the ibm,dma-window property. The definition is: + * logical-bus-number (1 word) + * phys-address (#address-cells words) + * size (#cell-size words) + * + * Currently we hard code these sizes (more or less). */ static void iommu_table_setparms_lpar(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl, - unsigned char *dma_window) + unsigned int *dma_window) { - unsigned long offset, size; - tbl->it_busno = PCI_DN(dn)->bussubno; - of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size); + /* TODO: Parse field size properties properly. */ + tbl->it_size = (((unsigned long)dma_window[4] << 32) | + (unsigned long)dma_window[5]) >> PAGE_SHIFT; + tbl->it_offset = (((unsigned long)dma_window[2] << 32) | + (unsigned long)dma_window[3]) >> PAGE_SHIFT; tbl->it_base = 0; + tbl->it_index = dma_window[0]; tbl->it_blocksize = 16; tbl->it_type = TCE_PCI; - tbl->it_offset = offset >> PAGE_SHIFT; - tbl->it_size = size >> PAGE_SHIFT; } static void iommu_bus_setup_pSeries(struct pci_bus *bus) @@ -331,9 +357,13 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) if (isa_dn_orig) of_node_put(isa_dn_orig); - /* Count number of direct PCI children of the PHB. */ + /* Count number of direct PCI children of the PHB. + * All PCI device nodes have class-code property, so it's + * an easy way to find them. + */ for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) - children++; + if (get_property(tmp, "class-code", NULL)) + children++; DBG("Children: %d\n", children); @@ -364,11 +394,10 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) pci->phb->dma_window_size = 0x8000000ul; pci->phb->dma_window_base_cur = 0x8000000ul; - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - pci->phb->node); + tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_setparms(pci->phb, dn, tbl); - pci->iommu_table = iommu_init_table(tbl, pci->phb->node); + pci->iommu_table = iommu_init_table(tbl); /* Divide the rest (1.75GB) among the children */ pci->phb->dma_window_size = 0x80000000ul; @@ -385,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) struct iommu_table *tbl; struct device_node *dn, *pdn; struct pci_dn *ppci; - unsigned char *dma_window = NULL; + unsigned int *dma_window = NULL; DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); @@ -393,7 +422,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { - dma_window = get_property(pdn, "ibm,dma-window", NULL); + dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); if (dma_window != NULL) break; } @@ -411,12 +440,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) ppci->bussubno = bus->number; - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - ppci->phb->node); - + tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), + GFP_KERNEL); + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); - ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); + ppci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) @@ -439,11 +468,9 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) */ if (!dev->bus->self) { DBG(" --> first child, no bridge. Allocating iommu table.\n"); - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - PCI_DN(dn)->phb->node); + tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); - PCI_DN(dn)->iommu_table = iommu_init_table(tbl, - PCI_DN(dn)->phb->node); + PCI_DN(mydn)->iommu_table = iommu_init_table(tbl); return; } @@ -489,7 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; struct iommu_table *tbl; - unsigned char *dma_window = NULL; + int *dma_window = NULL; struct pci_dn *pci; DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); @@ -504,7 +531,8 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { - dma_window = get_property(pdn, "ibm,dma-window", NULL); + dma_window = (unsigned int *) + get_property(pdn, "ibm,dma-window", NULL); if (dma_window) break; } @@ -525,12 +553,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) /* iommu_table_setparms_lpar needs bussubno. */ pci->bussubno = pci->phb->bus->number; - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - pci->phb->node); + tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), + GFP_KERNEL); iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); - pci->iommu_table = iommu_init_table(tbl, pci->phb->node); + pci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) diff --git a/trunk/arch/powerpc/platforms/pseries/rtasd.c b/trunk/arch/powerpc/platforms/pseries/rtasd.c index 2e4e04042d85..e0000ce769e5 100644 --- a/trunk/arch/powerpc/platforms/pseries/rtasd.c +++ b/trunk/arch/powerpc/platforms/pseries/rtasd.c @@ -348,7 +348,7 @@ static int enable_surveillance(int timeout) return 0; if (error == -EINVAL) { - printk(KERN_DEBUG "rtasd: surveillance not supported\n"); + printk(KERN_INFO "rtasd: surveillance not supported\n"); return 0; } @@ -440,7 +440,7 @@ static int rtasd(void *unused) goto error; } - printk(KERN_DEBUG "RTAS daemon started\n"); + printk(KERN_INFO "RTAS daemon started\n"); DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); @@ -487,7 +487,7 @@ static int __init rtas_init(void) /* No RTAS */ if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { - printk(KERN_DEBUG "rtasd: no event-scan on system\n"); + printk(KERN_INFO "rtasd: no event-scan on system\n"); return -ENODEV; } diff --git a/trunk/arch/powerpc/platforms/pseries/scanlog.c b/trunk/arch/powerpc/platforms/pseries/scanlog.c index 77a5bb1d9c30..50643496eb63 100644 --- a/trunk/arch/powerpc/platforms/pseries/scanlog.c +++ b/trunk/arch/powerpc/platforms/pseries/scanlog.c @@ -107,9 +107,9 @@ static ssize_t scanlog_read(struct file *file, char __user *buf, /* Break to sleep default time */ break; default: - /* Assume extended busy */ - wait_time = rtas_busy_delay_time(status); - if (!wait_time) { + if (status > 9900 && status <= 9905) { + wait_time = rtas_extended_busy_delay_time(status); + } else { printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); return -EIO; } diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 1e28518c6121..3ba87835757e 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -235,14 +235,14 @@ static void __init pSeries_setup_arch(void) if (firmware_has_feature(FW_FEATURE_SPLPAR)) { vpa_init(boot_cpuid); if (get_lppaca()->shared_proc) { - printk(KERN_DEBUG "Using shared processor idle loop\n"); + printk(KERN_INFO "Using shared processor idle loop\n"); ppc_md.power_save = pseries_shared_idle_sleep; } else { - printk(KERN_DEBUG "Using dedicated idle loop\n"); + printk(KERN_INFO "Using dedicated idle loop\n"); ppc_md.power_save = pseries_dedicated_idle_sleep; } } else { - printk(KERN_DEBUG "Using default idle loop\n"); + printk(KERN_INFO "Using default idle loop\n"); } if (firmware_has_feature(FW_FEATURE_LPAR)) diff --git a/trunk/arch/powerpc/platforms/pseries/vio.c b/trunk/arch/powerpc/platforms/pseries/vio.c new file mode 100644 index 000000000000..8e53e04ada8b --- /dev/null +++ b/trunk/arch/powerpc/platforms/pseries/vio.c @@ -0,0 +1,274 @@ +/* + * IBM PowerPC pSeries Virtual I/O Infrastructure Support. + * + * Copyright (c) 2003-2005 IBM Corp. + * Dave Engebretsen engebret@us.ibm.com + * Santiago Leon santil@us.ibm.com + * Hollis Blanchard + * Stephen Rothwell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct subsystem devices_subsys; /* needed for vio_find_name() */ + +static void probe_bus_pseries(void) +{ + struct device_node *node_vroot, *of_node; + + node_vroot = find_devices("vdevice"); + if ((node_vroot == NULL) || (node_vroot->child == NULL)) + /* this machine doesn't do virtual IO, and that's ok */ + return; + + /* + * Create struct vio_devices for each virtual device in the device tree. + * Drivers will associate with them later. + */ + for (of_node = node_vroot->child; of_node != NULL; + of_node = of_node->sibling) { + printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); + vio_register_device_node(of_node); + } +} + +/** + * vio_match_device_pseries: - Tell if a pSeries VIO device matches a + * vio_device_id + */ +static int vio_match_device_pseries(const struct vio_device_id *id, + const struct vio_dev *dev) +{ + return (strncmp(dev->type, id->type, strlen(id->type)) == 0) && + device_is_compatible(dev->dev.platform_data, id->compat); +} + +static void vio_release_device_pseries(struct device *dev) +{ + /* XXX free TCE table */ + of_node_put(dev->platform_data); +} + +static ssize_t viodev_show_devspec(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct device_node *of_node = dev->platform_data; + + return sprintf(buf, "%s\n", of_node->full_name); +} +DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); + +static void vio_unregister_device_pseries(struct vio_dev *viodev) +{ + device_remove_file(&viodev->dev, &dev_attr_devspec); +} + +static struct vio_bus_ops vio_bus_ops_pseries = { + .match = vio_match_device_pseries, + .unregister_device = vio_unregister_device_pseries, + .release_device = vio_release_device_pseries, +}; + +/** + * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus + */ +static int __init vio_bus_init_pseries(void) +{ + int err; + + err = vio_bus_init(&vio_bus_ops_pseries); + if (err == 0) + probe_bus_pseries(); + return err; +} + +__initcall(vio_bus_init_pseries); + +/** + * vio_build_iommu_table: - gets the dma information from OF and + * builds the TCE tree. + * @dev: the virtual device. + * + * Returns a pointer to the built tce tree, or NULL if it can't + * find property. +*/ +static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) +{ + unsigned int *dma_window; + struct iommu_table *newTceTable; + unsigned long offset; + int dma_window_property_size; + + dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size); + if(!dma_window) { + return NULL; + } + + newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL); + + /* There should be some code to extract the phys-encoded offset + using prom_n_addr_cells(). However, according to a comment + on earlier versions, it's always zero, so we don't bother */ + offset = dma_window[1] >> PAGE_SHIFT; + + /* TCE table size - measured in tce entries */ + newTceTable->it_size = dma_window[4] >> PAGE_SHIFT; + /* offset for VIO should always be 0 */ + newTceTable->it_offset = offset; + newTceTable->it_busno = 0; + newTceTable->it_index = (unsigned long)dma_window[0]; + newTceTable->it_type = TCE_VB; + + return iommu_init_table(newTceTable); +} + +/** + * vio_register_device_node: - Register a new vio device. + * @of_node: The OF node for this device. + * + * Creates and initializes a vio_dev structure from the data in + * of_node (dev.platform_data) and adds it to the list of virtual devices. + * Returns a pointer to the created vio_dev or NULL if node has + * NULL device_type or compatible fields. + */ +struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) +{ + struct vio_dev *viodev; + unsigned int *unit_address; + unsigned int *irq_p; + + /* we need the 'device_type' property, in order to match with drivers */ + if ((NULL == of_node->type)) { + printk(KERN_WARNING + "%s: node %s missing 'device_type'\n", __FUNCTION__, + of_node->name ? of_node->name : ""); + return NULL; + } + + unit_address = (unsigned int *)get_property(of_node, "reg", NULL); + if (!unit_address) { + printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, + of_node->name ? of_node->name : ""); + return NULL; + } + + /* allocate a vio_dev for this node */ + viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); + if (!viodev) { + return NULL; + } + memset(viodev, 0, sizeof(struct vio_dev)); + + viodev->dev.platform_data = of_node_get(of_node); + + viodev->irq = NO_IRQ; + irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL); + if (irq_p) { + int virq = virt_irq_create_mapping(*irq_p); + if (virq == NO_IRQ) { + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", of_node->full_name); + } else + viodev->irq = irq_offset_up(virq); + } + + snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); + viodev->name = of_node->name; + viodev->type = of_node->type; + viodev->unit_address = *unit_address; + viodev->iommu_table = vio_build_iommu_table(viodev); + + /* register with generic device framework */ + if (vio_register_device(viodev) == NULL) { + /* XXX free TCE table */ + kfree(viodev); + return NULL; + } + device_create_file(&viodev->dev, &dev_attr_devspec); + + return viodev; +} +EXPORT_SYMBOL(vio_register_device_node); + +/** + * vio_get_attribute: - get attribute for virtual device + * @vdev: The vio device to get property. + * @which: The property/attribute to be extracted. + * @length: Pointer to length of returned data size (unused if NULL). + * + * Calls prom.c's get_property() to return the value of the + * attribute specified by the preprocessor constant @which +*/ +const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) +{ + return get_property(vdev->dev.platform_data, (char*)which, length); +} +EXPORT_SYMBOL(vio_get_attribute); + +/* vio_find_name() - internal because only vio.c knows how we formatted the + * kobject name + * XXX once vio_bus_type.devices is actually used as a kset in + * drivers/base/bus.c, this function should be removed in favor of + * "device_find(kobj_name, &vio_bus_type)" + */ +static struct vio_dev *vio_find_name(const char *kobj_name) +{ + struct kobject *found; + + found = kset_find_obj(&devices_subsys.kset, kobj_name); + if (!found) + return NULL; + + return to_vio_dev(container_of(found, struct device, kobj)); +} + +/** + * vio_find_node - find an already-registered vio_dev + * @vnode: device_node of the virtual device we're looking for + */ +struct vio_dev *vio_find_node(struct device_node *vnode) +{ + uint32_t *unit_address; + char kobj_name[BUS_ID_SIZE]; + + /* construct the kobject name from the device node */ + unit_address = (uint32_t *)get_property(vnode, "reg", NULL); + if (!unit_address) + return NULL; + snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); + + return vio_find_name(kobj_name); +} +EXPORT_SYMBOL(vio_find_node); + +int vio_enable_interrupts(struct vio_dev *dev) +{ + int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE); + if (rc != H_SUCCESS) + printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc); + return rc; +} +EXPORT_SYMBOL(vio_enable_interrupts); + +int vio_disable_interrupts(struct vio_dev *dev) +{ + int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE); + if (rc != H_SUCCESS) + printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc); + return rc; +} +EXPORT_SYMBOL(vio_disable_interrupts); diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index b14f9b5c114e..2d60ea30fed6 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -522,7 +522,7 @@ void xics_init_IRQ(void) np = of_find_node_by_type(NULL, "interrupt-controller"); if (!np) { - printk(KERN_DEBUG "xics: no ISA interrupt controller\n"); + printk(KERN_WARNING "xics: no ISA interrupt controller\n"); xics_irq_8259_cascade_real = -1; xics_irq_8259_cascade = -1; } else { @@ -641,26 +641,23 @@ void xics_teardown_cpu(int secondary) ops->cppr_info(cpu, 0x00); iosync(); - /* Clear IPI */ - ops->qirr_info(cpu, 0xff); - - /* - * we need to EOI the IPI if we got here from kexec down IPI - * - * probably need to check all the other interrupts too - * should we be flagging idle loop instead? - * or creating some task to be scheduled? - */ - ops->xirr_info_set(cpu, XICS_IPI); - /* * Some machines need to have at least one cpu in the GIQ, * so leave the master cpu in the group. */ - if (secondary) + if (secondary) { + /* + * we need to EOI the IPI if we got here from kexec down IPI + * + * probably need to check all the other interrupts too + * should we be flagging idle loop instead? + * or creating some task to be scheduled? + */ + ops->xirr_info_set(cpu, XICS_IPI); rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); + } } #ifdef CONFIG_HOTPLUG_CPU diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index cef95b023730..4c2b356774ea 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -1,7 +1,3 @@ -ifeq ($(CONFIG_PPC64),y) -EXTRA_CFLAGS += -mno-minimal-toc -endif - obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index 6232091cc72b..38087bd6e3cf 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -246,7 +246,7 @@ static void iommu_table_dart_setup(void) iommu_table_dart.it_base = (unsigned long)dart_vbase; iommu_table_dart.it_index = 0; iommu_table_dart.it_blocksize = 1; - iommu_init_table(&iommu_table_dart, -1); + iommu_init_table(&iommu_table_dart); /* Reserve the last page of the DART to avoid possible prefetch * past the DART mapped area diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 71a3275935ec..ceb584682fa3 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -372,7 +372,7 @@ static int __init fsl_usb_of_init(void) { struct device_node *np; unsigned int i; - struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL; + struct platform_device *usb_dev; int ret; for (np = NULL, i = 0; @@ -393,15 +393,15 @@ static int __init fsl_usb_of_init(void) r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; - usb_dev_mph = - platform_device_register_simple("fsl-ehci", i, r, 2); - if (IS_ERR(usb_dev_mph)) { - ret = PTR_ERR(usb_dev_mph); + usb_dev = + platform_device_register_simple("fsl-usb2-mph", i, r, 2); + if (IS_ERR(usb_dev)) { + ret = PTR_ERR(usb_dev); goto err; } - usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL; - usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask; + usb_dev->dev.coherent_dma_mask = 0xffffffffUL; + usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; usb_data.operating_mode = FSL_USB2_MPH_HOST; @@ -417,14 +417,31 @@ static int __init fsl_usb_of_init(void) usb_data.phy_mode = determine_usb_phy(prop); ret = - platform_device_add_data(usb_dev_mph, &usb_data, + platform_device_add_data(usb_dev, &usb_data, sizeof(struct fsl_usb2_platform_data)); if (ret) - goto unreg_mph; + goto unreg; } - for (np = NULL; + return 0; + +unreg: + platform_device_unregister(usb_dev); +err: + return ret; +} + +arch_initcall(fsl_usb_of_init); + +static int __init fsl_usb_dr_of_init(void) +{ + struct device_node *np; + unsigned int i; + struct platform_device *usb_dev; + int ret; + + for (np = NULL, i = 0; (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL; i++) { struct resource r[2]; @@ -436,21 +453,21 @@ static int __init fsl_usb_of_init(void) ret = of_address_to_resource(np, 0, &r[0]); if (ret) - goto unreg_mph; + goto err; r[1].start = np->intrs[0].line; r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; - usb_dev_dr = - platform_device_register_simple("fsl-ehci", i, r, 2); - if (IS_ERR(usb_dev_dr)) { - ret = PTR_ERR(usb_dev_dr); + usb_dev = + platform_device_register_simple("fsl-usb2-dr", i, r, 2); + if (IS_ERR(usb_dev)) { + ret = PTR_ERR(usb_dev); goto err; } - usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL; - usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask; + usb_dev->dev.coherent_dma_mask = 0xffffffffUL; + usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; usb_data.operating_mode = FSL_USB2_DR_HOST; @@ -458,22 +475,19 @@ static int __init fsl_usb_of_init(void) usb_data.phy_mode = determine_usb_phy(prop); ret = - platform_device_add_data(usb_dev_dr, &usb_data, + platform_device_add_data(usb_dev, &usb_data, sizeof(struct fsl_usb2_platform_data)); if (ret) - goto unreg_dr; + goto unreg; } + return 0; -unreg_dr: - if (usb_dev_dr) - platform_device_unregister(usb_dev_dr); -unreg_mph: - if (usb_dev_mph) - platform_device_unregister(usb_dev_mph); +unreg: + platform_device_unregister(usb_dev); err: return ret; } -arch_initcall(fsl_usb_of_init); +arch_initcall(fsl_usb_dr_of_init); diff --git a/trunk/arch/powerpc/sysdev/mmio_nvram.c b/trunk/arch/powerpc/sysdev/mmio_nvram.c index 615350d46b52..74e0d31a3559 100644 --- a/trunk/arch/powerpc/sysdev/mmio_nvram.c +++ b/trunk/arch/powerpc/sysdev/mmio_nvram.c @@ -32,7 +32,7 @@ static void __iomem *mmio_nvram_start; static long mmio_nvram_len; -static DEFINE_SPINLOCK(mmio_nvram_lock); +static spinlock_t mmio_nvram_lock = SPIN_LOCK_UNLOCKED; static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index) { diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index bffe50d02c99..7dcdfcb3c984 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -829,27 +829,7 @@ void __init mpic_init(struct mpic *mpic) mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); } -void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) -{ - u32 v; - - v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); - v &= ~MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO_MASK; - v |= MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO(clock_ratio); - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); -} -void __init mpic_set_serial_int(struct mpic *mpic, int enable) -{ - u32 v; - - v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); - if (enable) - v |= MPIC_GREG_GLOBAL_CONF_1_SIE; - else - v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); -} void mpic_irq_set_priority(unsigned int irq, unsigned int pri) { diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index 0741df8c41b7..4735b41c113c 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif #include #include #include diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index b55de4f42aec..e9a8f5d1dfcd 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -40,10 +40,6 @@ config GENERIC_NVRAM bool default y -config GENERIC_FIND_NEXT_BIT - bool - default y - config SCHED_NO_NO_OMIT_FRAME_POINTER bool default y diff --git a/trunk/arch/ppc/boot/lib/Makefile b/trunk/arch/ppc/boot/lib/Makefile index 2f995f712ec5..80c84d562fa4 100644 --- a/trunk/arch/ppc/boot/lib/Makefile +++ b/trunk/arch/ppc/boot/lib/Makefile @@ -5,7 +5,7 @@ CFLAGS_kbd.o := -Idrivers/char CFLAGS_vreset.o := -Iarch/ppc/boot/include -zlib := inffast.c inflate.c inftrees.c +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c lib-y += $(zlib:.c=.o) div64.o lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o diff --git a/trunk/arch/ppc/kernel/machine_kexec.c b/trunk/arch/ppc/kernel/machine_kexec.c index a469ba438cbe..84d65a87191e 100644 --- a/trunk/arch/ppc/kernel/machine_kexec.c +++ b/trunk/arch/ppc/kernel/machine_kexec.c @@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( unsigned long reboot_code_buffer, unsigned long start_address) ATTRIB_NORET; -extern const unsigned char relocate_new_kernel[]; -extern const unsigned int relocate_new_kernel_size; +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; void machine_shutdown(void) { diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c index d20accf9650d..809673a36f7a 100644 --- a/trunk/arch/ppc/kernel/pci.c +++ b/trunk/arch/ppc/kernel/pci.c @@ -1032,6 +1032,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; vma->vm_pgoff = offset >> PAGE_SHIFT; + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, vma->vm_page_prot, mmap_state, write_combine); diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 4b4607d89bfa..1f79e84ab464 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -475,7 +475,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ if (ppc_md.init != NULL) { diff --git a/trunk/arch/ppc/mm/init.c b/trunk/arch/ppc/mm/init.c index c9bd184a295a..386e000bcb73 100644 --- a/trunk/arch/ppc/mm/init.c +++ b/trunk/arch/ppc/mm/init.c @@ -583,7 +583,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_offset(pgd_offset(mm, address), address); if (!pmd_none(*pmd)) - add_hash_page(mm->context.id, address, pmd_val(*pmd)); + add_hash_page(mm->context, address, pmd_val(*pmd)); } #endif } diff --git a/trunk/arch/ppc/mm/mmu_context.c b/trunk/arch/ppc/mm/mmu_context.c index 8784f3715032..b4a4b3f02a1c 100644 --- a/trunk/arch/ppc/mm/mmu_context.c +++ b/trunk/arch/ppc/mm/mmu_context.c @@ -30,7 +30,7 @@ #include #include -unsigned long next_mmu_context; +mm_context_t next_mmu_context; unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; #ifdef FEW_CONTEXTS atomic_t nr_free_contexts; diff --git a/trunk/arch/ppc/mm/tlb.c b/trunk/arch/ppc/mm/tlb.c index 606b023196a2..6c3dc3c44c86 100644 --- a/trunk/arch/ppc/mm/tlb.c +++ b/trunk/arch/ppc/mm/tlb.c @@ -42,7 +42,7 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) if (Hash != 0) { ptephys = __pa(ptep) & PAGE_MASK; - flush_hash_pages(mm->context.id, addr, ptephys, 1); + flush_hash_pages(mm->context, addr, ptephys, 1); } } @@ -102,7 +102,7 @@ static void flush_range(struct mm_struct *mm, unsigned long start, pmd_t *pmd; unsigned long pmd_end; int count; - unsigned int ctx = mm->context.id; + unsigned int ctx = mm->context; if (Hash == 0) { _tlbia(); @@ -166,7 +166,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr); if (!pmd_none(*pmd)) - flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); + flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1); FINISH_FLUSH; } diff --git a/trunk/arch/ppc/platforms/4xx/Kconfig b/trunk/arch/ppc/platforms/4xx/Kconfig index 293bd489e7d9..174ddbc9758b 100644 --- a/trunk/arch/ppc/platforms/4xx/Kconfig +++ b/trunk/arch/ppc/platforms/4xx/Kconfig @@ -183,7 +183,7 @@ config IBM_EMAC4 config BIOS_FIXUP bool - depends on BUBINGA || EP405 || SYCAMORE || WALNUT || CPCI405 + depends on BUBINGA || EP405 || SYCAMORE || WALNUT default y # OAK doesn't exist but wanted to keep this around for any future 403GCX boards diff --git a/trunk/arch/ppc/platforms/4xx/cpci405.c b/trunk/arch/ppc/platforms/4xx/cpci405.c index 970b69831e6f..6571e39fbe48 100644 --- a/trunk/arch/ppc/platforms/4xx/cpci405.c +++ b/trunk/arch/ppc/platforms/4xx/cpci405.c @@ -1,12 +1,10 @@ /* * Board setup routines for the esd CPCI-405 cPCI Board. * - * Copyright 2001-2006 esd electronic system design - hannover germany + * Author: Stefan Roese + * stefan.roese@esd-electronics.com * - * Authors: Matthias Fuchs - * matthias.fuchs@esd-electronics.com - * Stefan Roese - * stefan.roese@esd-electronics.com + * Copyright 2001 esd electronic system design - hannover germany * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -22,17 +20,9 @@ #include #include #include -#include -#include #include -#include -#include -#ifdef CONFIG_GEN_RTC void *cpci405_nvram; -#endif - -extern bd_t __res; /* * Some IRQs unique to CPCI-405. @@ -46,69 +36,18 @@ ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) * A B C D */ { - {28, 29, 30, 27}, /* IDSEL 15 - cPCI slot 8 */ - {29, 30, 27, 28}, /* IDSEL 16 - cPCI slot 7 */ - {30, 27, 28, 29}, /* IDSEL 17 - cPCI slot 6 */ - {27, 28, 29, 30}, /* IDSEL 18 - cPCI slot 5 */ - {28, 29, 30, 27}, /* IDSEL 19 - cPCI slot 4 */ - {29, 30, 27, 28}, /* IDSEL 20 - cPCI slot 3 */ - {30, 27, 28, 29}, /* IDSEL 21 - cPCI slot 2 */ + {28, 28, 28, 28}, /* IDSEL 15 - cPCI slot 8 */ + {29, 29, 29, 29}, /* IDSEL 16 - cPCI slot 7 */ + {30, 30, 30, 30}, /* IDSEL 17 - cPCI slot 6 */ + {27, 27, 27, 27}, /* IDSEL 18 - cPCI slot 5 */ + {28, 28, 28, 28}, /* IDSEL 19 - cPCI slot 4 */ + {29, 29, 29, 29}, /* IDSEL 20 - cPCI slot 3 */ + {30, 30, 30, 30}, /* IDSEL 21 - cPCI slot 2 */ }; const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; return PCI_IRQ_TABLE_LOOKUP; }; -/* The serial clock for the chip is an internal clock determined by - * different clock speeds/dividers. - * Calculate the proper input baud rate and setup the serial driver. - */ -static void __init -cpci405_early_serial_map(void) -{ - u32 uart_div; - int uart_clock; - struct uart_port port; - - /* Calculate the serial clock input frequency - * - * The uart clock is the cpu frequency (provided in the board info - * structure) divided by the external UART Divisor. - */ - uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1; - uart_clock = __res.bi_procfreq / uart_div; - - /* Setup serial port access */ - memset(&port, 0, sizeof(port)); -#if defined(CONFIG_UART0_TTYS0) - port.membase = (void*)UART0_IO_BASE; - port.irq = UART0_INT; -#else - port.membase = (void*)UART1_IO_BASE; - port.irq = UART1_INT; -#endif - port.uartclk = uart_clock; - port.regshift = 0; - port.iotype = UPIO_MEM; - port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; - port.line = 0; - - if (early_serial_setup(&port) != 0) { - printk("Early serial init of port 0 failed\n"); - } -#if defined(CONFIG_UART0_TTYS0) - port.membase = (void*)UART1_IO_BASE; - port.irq = UART1_INT; -#else - port.membase = (void*)UART0_IO_BASE; - port.irq = UART0_INT; -#endif - port.line = 1; - - if (early_serial_setup(&port) != 0) { - printk("Early serial init of port 1 failed\n"); - } -} - void __init cpci405_setup_arch(void) { @@ -116,68 +55,14 @@ cpci405_setup_arch(void) ibm_ocp_set_emac(0, 0); - cpci405_early_serial_map(); - -#ifdef CONFIG_GEN_RTC - TODC_INIT(TODC_TYPE_MK48T35, - cpci405_nvram, cpci405_nvram, cpci405_nvram, 8); -#endif -} - -void __init -bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) -{ - unsigned int bar_response, bar; - - /* Disable region first */ - out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); - /* PLB starting addr, PCI: 0x80000000 */ - out_le32((void *) &(pcip->pmm[0].la), 0x80000000); - /* PCI start addr, 0x80000000 */ - out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); - /* 512MB range of PLB to PCI */ - out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); - /* Enable no pre-fetch, enable region */ - out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - - (PPC405_PCI_UPPER_MEM - - PPC405_PCI_MEM_BASE)) | 0x01)); - - /* Disable region one */ - out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); - out_le32((void *) &(pcip->pmm[1].la), 0x00000000); - out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); - out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); - out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); - out_le32((void *) &(pcip->ptm1ms), 0x00000001); - - /* Disable region two */ - out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); - out_le32((void *) &(pcip->pmm[2].la), 0x00000000); - out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); - out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); - out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); - out_le32((void *) &(pcip->ptm2ms), 0x00000000); - out_le32((void *) &(pcip->ptm2la), 0x00000000); - - /* Zero config bars */ - for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { - early_write_config_dword(hose, hose->first_busno, - PCI_FUNC(hose->first_busno), bar, - 0x00000000); - early_read_config_dword(hose, hose->first_busno, - PCI_FUNC(hose->first_busno), bar, - &bar_response); - } + TODC_INIT(TODC_TYPE_MK48T35, cpci405_nvram, cpci405_nvram, cpci405_nvram, 8); } void __init cpci405_map_io(void) { ppc4xx_map_io(); - -#ifdef CONFIG_GEN_RTC cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE); -#endif } void __init @@ -189,11 +74,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = cpci405_setup_arch; ppc_md.setup_io_mappings = cpci405_map_io; -#ifdef CONFIG_GEN_RTC ppc_md.time_init = todc_time_init; ppc_md.set_rtc_time = todc_set_rtc_time; ppc_md.get_rtc_time = todc_get_rtc_time; ppc_md.nvram_read_val = todc_direct_read_val; ppc_md.nvram_write_val = todc_direct_write_val; -#endif } diff --git a/trunk/arch/ppc/platforms/4xx/cpci405.h b/trunk/arch/ppc/platforms/4xx/cpci405.h index f5a5c0cd062d..e27f7cb650d8 100644 --- a/trunk/arch/ppc/platforms/4xx/cpci405.h +++ b/trunk/arch/ppc/platforms/4xx/cpci405.h @@ -1,29 +1,37 @@ /* * CPCI-405 board specific definitions * - * Copyright 2001-2006 esd electronic system design - hannover germany - * - * Authors: Matthias Fuchs - * matthias.fuchs@esd-electronics.com - * Stefan Roese - * stefan.roese@esd-electronics.com + * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com) */ #ifdef __KERNEL__ -#ifndef __CPCI405_H__ -#define __CPCI405_H__ +#ifndef __ASM_CPCI405_H__ +#define __ASM_CPCI405_H__ #include + +/* We have a 405GP core */ #include + #include +#ifndef __ASSEMBLY__ +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + /* Map for the NVRAM space */ #define CPCI405_NVRAM_PADDR ((uint)0xf0200000) #define CPCI405_NVRAM_SIZE ((uint)32*1024) -#define BASE_BAUD 0 +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif -#define PPC4xx_MACHINE_NAME "esd CPCI-405" +#define PPC4xx_MACHINE_NAME "esd CPCI-405" -#endif /* __CPCI405_H__ */ +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_CPCI405_H__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 4368dc3f3c30..c9e0aeeca3d8 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -379,12 +379,13 @@ mpc85xx_cds_pcibios_fixup(void) PCI_DEVICE_ID_VIA_82C586_2, NULL))) { dev->irq = 10; pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); + pci_dev_put(dev); + } - if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, + if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev))) { - dev->irq = 11; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); - } + dev->irq = 11; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); pci_dev_put(dev); } } diff --git a/trunk/arch/ppc/syslib/mpc83xx_devices.c b/trunk/arch/ppc/syslib/mpc83xx_devices.c index 5c4932ca8e9b..1af2c000fcfa 100644 --- a/trunk/arch/ppc/syslib/mpc83xx_devices.c +++ b/trunk/arch/ppc/syslib/mpc83xx_devices.c @@ -186,7 +186,7 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, [MPC83xx_USB2_DR] = { - .name = "fsl-ehci", + .name = "fsl-usb2-dr", .id = 1, .num_resources = 2, .resource = (struct resource[]) { @@ -203,8 +203,8 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, [MPC83xx_USB2_MPH] = { - .name = "fsl-ehci", - .id = 2, + .name = "fsl-usb2-mph", + .id = 1, .num_resources = 2, .resource = (struct resource[]) { { diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 821a141889de..01c5c082f970 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -446,14 +446,6 @@ config NO_IDLE_HZ_INIT The HZ timer is switched off in idle by default. That means the HZ timer is already disabled at boot time. -config S390_HYPFS_FS - bool "s390 hypervisor file system support" - select SYS_HYPERVISOR - default y - help - This is a virtual file system intended to provide accounting - information in an s390 hypervisor environment. - config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index b3791fb094a8..7bb16fb97d4f 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -76,7 +76,7 @@ LDFLAGS_vmlinux := -e start head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \ - arch/$(ARCH)/appldata/ arch/$(ARCH)/hypfs/ + arch/$(ARCH)/appldata/ libs-y += arch/$(ARCH)/lib/ drivers-y += drivers/s390/ drivers-$(CONFIG_MATHEMU) += arch/$(ARCH)/math-emu/ diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index 54d35c130907..9a22434a580c 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -652,7 +652,7 @@ appldata_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __devinitdata appldata_nb = { +static struct notifier_block appldata_nb = { .notifier_call = appldata_cpu_notify, }; diff --git a/trunk/arch/s390/crypto/aes_s390.c b/trunk/arch/s390/crypto/aes_s390.c index 5713c7e5bd16..c5ca2dc5d428 100644 --- a/trunk/arch/s390/crypto/aes_s390.c +++ b/trunk/arch/s390/crypto/aes_s390.c @@ -37,10 +37,10 @@ struct s390_aes_ctx { int key_len; }; -static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int aes_set_key(void *ctx, const u8 *in_key, unsigned int key_len, + u32 *flags) { - struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_aes_ctx *sctx = ctx; switch (key_len) { case 16: @@ -70,9 +70,9 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, return -EINVAL; } -static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void aes_encrypt(void *ctx, u8 *out, const u8 *in) { - const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); + const struct s390_aes_ctx *sctx = ctx; switch (sctx->key_len) { case 16: @@ -90,9 +90,9 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) } } -static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void aes_decrypt(void *ctx, u8 *out, const u8 *in) { - const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); + const struct s390_aes_ctx *sctx = ctx; switch (sctx->key_len) { case 16: diff --git a/trunk/arch/s390/crypto/des_s390.c b/trunk/arch/s390/crypto/des_s390.c index b3f7496a79b4..e3c37aa0a199 100644 --- a/trunk/arch/s390/crypto/des_s390.c +++ b/trunk/arch/s390/crypto/des_s390.c @@ -44,10 +44,10 @@ struct crypt_s390_des3_192_ctx { u8 key[DES3_192_KEY_SIZE]; }; -static int des_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) { - struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des_ctx *dctx = ctx; int ret; /* test if key is valid (not a weak key) */ @@ -57,16 +57,16 @@ static int des_setkey(struct crypto_tfm *tfm, const u8 *key, return ret; } -static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void des_encrypt(void *ctx, u8 *out, const u8 *in) { - struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des_ctx *dctx = ctx; crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE); } -static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void des_decrypt(void *ctx, u8 *out, const u8 *in) { - struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des_ctx *dctx = ctx; crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); } @@ -166,11 +166,11 @@ static struct crypto_alg des_alg = { * Implementers MUST reject keys that exhibit this property. * */ -static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) { int i, ret; - struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_128_ctx *dctx = ctx; const u8* temp_key = key; if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { @@ -186,17 +186,17 @@ static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void des3_128_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) { - struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_128_ctx *dctx = ctx; crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, DES3_128_BLOCK_SIZE); } -static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_128_ctx *dctx = ctx; crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, DES3_128_BLOCK_SIZE); @@ -302,11 +302,11 @@ static struct crypto_alg des3_128_alg = { * property. * */ -static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) { int i, ret; - struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_192_ctx *dctx = ctx; const u8* temp_key = key; if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && @@ -325,17 +325,17 @@ static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) { - struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_192_ctx *dctx = ctx; crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, DES3_192_BLOCK_SIZE); } -static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); + struct crypt_s390_des3_192_ctx *dctx = ctx; crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, DES3_192_BLOCK_SIZE); diff --git a/trunk/arch/s390/crypto/sha1_s390.c b/trunk/arch/s390/crypto/sha1_s390.c index 9d34a35b1aa5..98c896b86dcd 100644 --- a/trunk/arch/s390/crypto/sha1_s390.c +++ b/trunk/arch/s390/crypto/sha1_s390.c @@ -40,29 +40,28 @@ struct crypt_s390_sha1_ctx { u8 buffer[2 * SHA1_BLOCK_SIZE]; }; -static void sha1_init(struct crypto_tfm *tfm) +static void +sha1_init(void *ctx) { - struct crypt_s390_sha1_ctx *ctx = crypto_tfm_ctx(tfm); - static const u32 initstate[5] = { - 0x67452301, - 0xEFCDAB89, - 0x98BADCFE, - 0x10325476, - 0xC3D2E1F0 + static const struct crypt_s390_sha1_ctx initstate = { + .state = { + 0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0 + }, }; - - ctx->count = 0; - memcpy(ctx->state, &initstate, sizeof(initstate)); - ctx->buf_len = 0; + memcpy(ctx, &initstate, sizeof(initstate)); } -static void sha1_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void +sha1_update(void *ctx, const u8 *data, unsigned int len) { struct crypt_s390_sha1_ctx *sctx; long imd_len; - sctx = crypto_tfm_ctx(tfm); + sctx = ctx; sctx->count += len * 8; //message bit length //anything in buffer yet? -> must be completed @@ -111,9 +110,10 @@ pad_message(struct crypt_s390_sha1_ctx* sctx) } /* Add padding and return the message digest. */ -static void sha1_final(struct crypto_tfm *tfm, u8 *out) +static void +sha1_final(void* ctx, u8 *out) { - struct crypt_s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); + struct crypt_s390_sha1_ctx *sctx = ctx; //must perform manual padding pad_message(sctx); diff --git a/trunk/arch/s390/crypto/sha256_s390.c b/trunk/arch/s390/crypto/sha256_s390.c index f573df30f31d..1ec5e92b3454 100644 --- a/trunk/arch/s390/crypto/sha256_s390.c +++ b/trunk/arch/s390/crypto/sha256_s390.c @@ -31,9 +31,9 @@ struct s390_sha256_ctx { u8 buf[2 * SHA256_BLOCK_SIZE]; }; -static void sha256_init(struct crypto_tfm *tfm) +static void sha256_init(void *ctx) { - struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_sha256_ctx *sctx = ctx; sctx->state[0] = 0x6a09e667; sctx->state[1] = 0xbb67ae85; @@ -44,12 +44,12 @@ static void sha256_init(struct crypto_tfm *tfm) sctx->state[6] = 0x1f83d9ab; sctx->state[7] = 0x5be0cd19; sctx->count = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); } -static void sha256_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void sha256_update(void *ctx, const u8 *data, unsigned int len) { - struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_sha256_ctx *sctx = ctx; unsigned int index; int ret; @@ -108,9 +108,9 @@ static void pad_message(struct s390_sha256_ctx* sctx) } /* Add padding and return the message digest */ -static void sha256_final(struct crypto_tfm *tfm, u8 *out) +static void sha256_final(void* ctx, u8 *out) { - struct s390_sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct s390_sha256_ctx *sctx = ctx; /* must perform manual padding */ pad_message(sctx); diff --git a/trunk/arch/s390/hypfs/Makefile b/trunk/arch/s390/hypfs/Makefile deleted file mode 100644 index f4b00cd81f7c..000000000000 --- a/trunk/arch/s390/hypfs/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux hypfs filesystem routines. -# - -obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o - -s390_hypfs-objs := inode.o hypfs_diag.o diff --git a/trunk/arch/s390/hypfs/hypfs.h b/trunk/arch/s390/hypfs/hypfs.h deleted file mode 100644 index ea5567be00fc..000000000000 --- a/trunk/arch/s390/hypfs/hypfs.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * fs/hypfs/hypfs.h - * Hypervisor filesystem for Linux on s390. - * - * Copyright (C) IBM Corp. 2006 - * Author(s): Michael Holzheu - */ - -#ifndef _HYPFS_H_ -#define _HYPFS_H_ - -#include -#include - -#define REG_FILE_MODE 0440 -#define UPDATE_FILE_MODE 0220 -#define DIR_MODE 0550 - -extern struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, - const char *name); - -extern struct dentry *hypfs_create_u64(struct super_block *sb, - struct dentry *dir, const char *name, - __u64 value); - -extern struct dentry *hypfs_create_str(struct super_block *sb, - struct dentry *dir, const char *name, - char *string); - -#endif /* _HYPFS_H_ */ diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c deleted file mode 100644 index efa74af7f04a..000000000000 --- a/trunk/arch/s390/hypfs/hypfs_diag.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * fs/hypfs/hypfs_diag.c - * Hypervisor filesystem for Linux on s390. Diag 204 and 224 - * implementation. - * - * Copyright (C) IBM Corp. 2006 - * Author(s): Michael Holzheu - */ - -#include -#include -#include -#include -#include -#include "hypfs.h" - -#define LPAR_NAME_LEN 8 /* lpar name len in diag 204 data */ -#define CPU_NAME_LEN 16 /* type name len of cpus in diag224 name table */ -#define TMP_SIZE 64 /* size of temporary buffers */ - -/* diag 204 subcodes */ -enum diag204_sc { - SUBC_STIB4 = 4, - SUBC_RSI = 5, - SUBC_STIB6 = 6, - SUBC_STIB7 = 7 -}; - -/* The two available diag 204 data formats */ -enum diag204_format { - INFO_SIMPLE = 0, - INFO_EXT = 0x00010000 -}; - -/* bit is set in flags, when physical cpu info is included in diag 204 data */ -#define LPAR_PHYS_FLG 0x80 - -static char *diag224_cpu_names; /* diag 224 name table */ -static enum diag204_sc diag204_store_sc; /* used subcode for store */ -static enum diag204_format diag204_info_type; /* used diag 204 data format */ - -static void *diag204_buf; /* 4K aligned buffer for diag204 data */ -static void *diag204_buf_vmalloc; /* vmalloc pointer for diag204 data */ -static int diag204_buf_pages; /* number of pages for diag204 data */ - -/* - * DIAG 204 data structures and member access functions. - * - * Since we have two different diag 204 data formats for old and new s390 - * machines, we do not access the structs directly, but use getter functions for - * each struct member instead. This should make the code more readable. - */ - -/* Time information block */ - -struct info_blk_hdr { - __u8 npar; - __u8 flags; - __u16 tslice; - __u16 phys_cpus; - __u16 this_part; - __u64 curtod; -} __attribute__ ((packed)); - -struct x_info_blk_hdr { - __u8 npar; - __u8 flags; - __u16 tslice; - __u16 phys_cpus; - __u16 this_part; - __u64 curtod1; - __u64 curtod2; - char reserved[40]; -} __attribute__ ((packed)); - -static inline int info_blk_hdr__size(enum diag204_format type) -{ - if (type == INFO_SIMPLE) - return sizeof(struct info_blk_hdr); - else /* INFO_EXT */ - return sizeof(struct x_info_blk_hdr); -} - -static inline __u8 info_blk_hdr__npar(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct info_blk_hdr *)hdr)->npar; - else /* INFO_EXT */ - return ((struct x_info_blk_hdr *)hdr)->npar; -} - -static inline __u8 info_blk_hdr__flags(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct info_blk_hdr *)hdr)->flags; - else /* INFO_EXT */ - return ((struct x_info_blk_hdr *)hdr)->flags; -} - -static inline __u16 info_blk_hdr__pcpus(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct info_blk_hdr *)hdr)->phys_cpus; - else /* INFO_EXT */ - return ((struct x_info_blk_hdr *)hdr)->phys_cpus; -} - -/* Partition header */ - -struct part_hdr { - __u8 pn; - __u8 cpus; - char reserved[6]; - char part_name[LPAR_NAME_LEN]; -} __attribute__ ((packed)); - -struct x_part_hdr { - __u8 pn; - __u8 cpus; - __u8 rcpus; - __u8 pflag; - __u32 mlu; - char part_name[LPAR_NAME_LEN]; - char lpc_name[8]; - char os_name[8]; - __u64 online_cs; - __u64 online_es; - __u8 upid; - char reserved1[3]; - __u32 group_mlu; - char group_name[8]; - char reserved2[32]; -} __attribute__ ((packed)); - -static inline int part_hdr__size(enum diag204_format type) -{ - if (type == INFO_SIMPLE) - return sizeof(struct part_hdr); - else /* INFO_EXT */ - return sizeof(struct x_part_hdr); -} - -static inline __u8 part_hdr__rcpus(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct part_hdr *)hdr)->cpus; - else /* INFO_EXT */ - return ((struct x_part_hdr *)hdr)->rcpus; -} - -static inline void part_hdr__part_name(enum diag204_format type, void *hdr, - char *name) -{ - if (type == INFO_SIMPLE) - memcpy(name, ((struct part_hdr *)hdr)->part_name, - LPAR_NAME_LEN); - else /* INFO_EXT */ - memcpy(name, ((struct x_part_hdr *)hdr)->part_name, - LPAR_NAME_LEN); - EBCASC(name, LPAR_NAME_LEN); - name[LPAR_NAME_LEN] = 0; - strstrip(name); -} - -struct cpu_info { - __u16 cpu_addr; - char reserved1[2]; - __u8 ctidx; - __u8 cflag; - __u16 weight; - __u64 acc_time; - __u64 lp_time; -} __attribute__ ((packed)); - -struct x_cpu_info { - __u16 cpu_addr; - char reserved1[2]; - __u8 ctidx; - __u8 cflag; - __u16 weight; - __u64 acc_time; - __u64 lp_time; - __u16 min_weight; - __u16 cur_weight; - __u16 max_weight; - char reseved2[2]; - __u64 online_time; - __u64 wait_time; - __u32 pma_weight; - __u32 polar_weight; - char reserved3[40]; -} __attribute__ ((packed)); - -/* CPU info block */ - -static inline int cpu_info__size(enum diag204_format type) -{ - if (type == INFO_SIMPLE) - return sizeof(struct cpu_info); - else /* INFO_EXT */ - return sizeof(struct x_cpu_info); -} - -static inline __u8 cpu_info__ctidx(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct cpu_info *)hdr)->ctidx; - else /* INFO_EXT */ - return ((struct x_cpu_info *)hdr)->ctidx; -} - -static inline __u16 cpu_info__cpu_addr(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct cpu_info *)hdr)->cpu_addr; - else /* INFO_EXT */ - return ((struct x_cpu_info *)hdr)->cpu_addr; -} - -static inline __u64 cpu_info__acc_time(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct cpu_info *)hdr)->acc_time; - else /* INFO_EXT */ - return ((struct x_cpu_info *)hdr)->acc_time; -} - -static inline __u64 cpu_info__lp_time(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct cpu_info *)hdr)->lp_time; - else /* INFO_EXT */ - return ((struct x_cpu_info *)hdr)->lp_time; -} - -static inline __u64 cpu_info__online_time(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return 0; /* online_time not available in simple info */ - else /* INFO_EXT */ - return ((struct x_cpu_info *)hdr)->online_time; -} - -/* Physical header */ - -struct phys_hdr { - char reserved1[1]; - __u8 cpus; - char reserved2[6]; - char mgm_name[8]; -} __attribute__ ((packed)); - -struct x_phys_hdr { - char reserved1[1]; - __u8 cpus; - char reserved2[6]; - char mgm_name[8]; - char reserved3[80]; -} __attribute__ ((packed)); - -static inline int phys_hdr__size(enum diag204_format type) -{ - if (type == INFO_SIMPLE) - return sizeof(struct phys_hdr); - else /* INFO_EXT */ - return sizeof(struct x_phys_hdr); -} - -static inline __u8 phys_hdr__cpus(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct phys_hdr *)hdr)->cpus; - else /* INFO_EXT */ - return ((struct x_phys_hdr *)hdr)->cpus; -} - -/* Physical CPU info block */ - -struct phys_cpu { - __u16 cpu_addr; - char reserved1[2]; - __u8 ctidx; - char reserved2[3]; - __u64 mgm_time; - char reserved3[8]; -} __attribute__ ((packed)); - -struct x_phys_cpu { - __u16 cpu_addr; - char reserved1[2]; - __u8 ctidx; - char reserved2[3]; - __u64 mgm_time; - char reserved3[80]; -} __attribute__ ((packed)); - -static inline int phys_cpu__size(enum diag204_format type) -{ - if (type == INFO_SIMPLE) - return sizeof(struct phys_cpu); - else /* INFO_EXT */ - return sizeof(struct x_phys_cpu); -} - -static inline __u16 phys_cpu__cpu_addr(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct phys_cpu *)hdr)->cpu_addr; - else /* INFO_EXT */ - return ((struct x_phys_cpu *)hdr)->cpu_addr; -} - -static inline __u64 phys_cpu__mgm_time(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct phys_cpu *)hdr)->mgm_time; - else /* INFO_EXT */ - return ((struct x_phys_cpu *)hdr)->mgm_time; -} - -static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr) -{ - if (type == INFO_SIMPLE) - return ((struct phys_cpu *)hdr)->ctidx; - else /* INFO_EXT */ - return ((struct x_phys_cpu *)hdr)->ctidx; -} - -/* Diagnose 204 functions */ - -static int diag204(unsigned long subcode, unsigned long size, void *addr) -{ - register unsigned long _subcode asm("0") = subcode; - register unsigned long _size asm("1") = size; - - asm volatile (" diag %2,%0,0x204\n" - "0: \n" ".section __ex_table,\"a\"\n" -#ifndef __s390x__ - " .align 4\n" - " .long 0b,0b\n" -#else - " .align 8\n" - " .quad 0b,0b\n" -#endif - ".previous":"+d" (_subcode), "+d"(_size) - :"d"(addr) - :"memory"); - if (_subcode) - return -1; - else - return _size; -} - -/* - * For the old diag subcode 4 with simple data format we have to use real - * memory. If we use subcode 6 or 7 with extended data format, we can (and - * should) use vmalloc, since we need a lot of memory in that case. Currently - * up to 93 pages! - */ - -static void diag204_free_buffer(void) -{ - if (!diag204_buf) - return; - if (diag204_buf_vmalloc) { - vfree(diag204_buf_vmalloc); - diag204_buf_vmalloc = NULL; - } else { - free_pages((unsigned long) diag204_buf, 0); - } - diag204_buf_pages = 0; - diag204_buf = NULL; -} - -static void *diag204_alloc_vbuf(int pages) -{ - /* The buffer has to be page aligned! */ - diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1)); - if (!diag204_buf_vmalloc) - return ERR_PTR(-ENOMEM); - diag204_buf = (void*)((unsigned long)diag204_buf_vmalloc - & ~0xfffUL) + 0x1000; - diag204_buf_pages = pages; - return diag204_buf; -} - -static void *diag204_alloc_rbuf(void) -{ - diag204_buf = (void*)__get_free_pages(GFP_KERNEL,0); - if (diag204_buf) - return ERR_PTR(-ENOMEM); - diag204_buf_pages = 1; - return diag204_buf; -} - -static void *diag204_get_buffer(enum diag204_format fmt, int *pages) -{ - if (diag204_buf) { - *pages = diag204_buf_pages; - return diag204_buf; - } - if (fmt == INFO_SIMPLE) { - *pages = 1; - return diag204_alloc_rbuf(); - } else {/* INFO_EXT */ - *pages = diag204(SUBC_RSI | INFO_EXT, 0, 0); - if (*pages <= 0) - return ERR_PTR(-ENOSYS); - else - return diag204_alloc_vbuf(*pages); - } -} - -/* - * diag204_probe() has to find out, which type of diagnose 204 implementation - * we have on our machine. Currently there are three possible scanarios: - * - subcode 4 + simple data format (only one page) - * - subcode 4-6 + extended data format - * - subcode 4-7 + extended data format - * - * Subcode 5 is used to retrieve the size of the data, provided by subcodes - * 6 and 7. Subcode 7 basically has the same function as subcode 6. In addition - * to subcode 6 it provides also information about secondary cpus. - * In order to get as much information as possible, we first try - * subcode 7, then 6 and if both fail, we use subcode 4. - */ - -static int diag204_probe(void) -{ - void *buf; - int pages, rc; - - buf = diag204_get_buffer(INFO_EXT, &pages); - if (!IS_ERR(buf)) { - if (diag204(SUBC_STIB7 | INFO_EXT, pages, buf) >= 0) { - diag204_store_sc = SUBC_STIB7; - diag204_info_type = INFO_EXT; - goto out; - } - if (diag204(SUBC_STIB6 | INFO_EXT, pages, buf) >= 0) { - diag204_store_sc = SUBC_STIB7; - diag204_info_type = INFO_EXT; - goto out; - } - diag204_free_buffer(); - } - - /* subcodes 6 and 7 failed, now try subcode 4 */ - - buf = diag204_get_buffer(INFO_SIMPLE, &pages); - if (IS_ERR(buf)) { - rc = PTR_ERR(buf); - goto fail_alloc; - } - if (diag204(SUBC_STIB4 | INFO_SIMPLE, pages, buf) >= 0) { - diag204_store_sc = SUBC_STIB4; - diag204_info_type = INFO_SIMPLE; - goto out; - } else { - rc = -ENOSYS; - goto fail_store; - } -out: - rc = 0; -fail_store: - diag204_free_buffer(); -fail_alloc: - return rc; -} - -static void *diag204_store(void) -{ - void *buf; - int pages; - - buf = diag204_get_buffer(diag204_info_type, &pages); - if (IS_ERR(buf)) - goto out; - if (diag204(diag204_store_sc | diag204_info_type, pages, buf) < 0) - return ERR_PTR(-ENOSYS); -out: - return buf; -} - -/* Diagnose 224 functions */ - -static void diag224(void *ptr) -{ - asm volatile(" diag %0,%1,0x224\n" - : :"d" (0), "d"(ptr) : "memory"); -} - -static int diag224_get_name_table(void) -{ - /* memory must be below 2GB */ - diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); - if (!diag224_cpu_names) - return -ENOMEM; - diag224(diag224_cpu_names); - EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); - return 0; -} - -static void diag224_delete_name_table(void) -{ - kfree(diag224_cpu_names); -} - -static int diag224_idx2name(int index, char *name) -{ - memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN), - CPU_NAME_LEN); - name[CPU_NAME_LEN] = 0; - strstrip(name); - return 0; -} - -__init int hypfs_diag_init(void) -{ - int rc; - - if (diag204_probe()) { - printk(KERN_ERR "hypfs: diag 204 not working."); - return -ENODATA; - } - rc = diag224_get_name_table(); - if (rc) { - diag224_delete_name_table(); - printk(KERN_ERR "hypfs: could not get name table.\n"); - } - return rc; -} - -__exit void hypfs_diag_exit(void) -{ - diag224_delete_name_table(); - diag204_free_buffer(); -} - -/* - * Functions to create the directory structure - * ******************************************* - */ - -static int hypfs_create_cpu_files(struct super_block *sb, - struct dentry *cpus_dir, void *cpu_info) -{ - struct dentry *cpu_dir; - char buffer[TMP_SIZE]; - void *rc; - - snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_info_type, - cpu_info)); - cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer); - rc = hypfs_create_u64(sb, cpu_dir, "mgmtime", - cpu_info__acc_time(diag204_info_type, cpu_info) - - cpu_info__lp_time(diag204_info_type, cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); - rc = hypfs_create_u64(sb, cpu_dir, "cputime", - cpu_info__lp_time(diag204_info_type, cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); - if (diag204_info_type == INFO_EXT) { - rc = hypfs_create_u64(sb, cpu_dir, "onlinetime", - cpu_info__online_time(diag204_info_type, - cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); - } - diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer); - rc = hypfs_create_str(sb, cpu_dir, "type", buffer); - if (IS_ERR(rc)) - return PTR_ERR(rc); - return 0; -} - -static void *hypfs_create_lpar_files(struct super_block *sb, - struct dentry *systems_dir, void *part_hdr) -{ - struct dentry *cpus_dir; - struct dentry *lpar_dir; - char lpar_name[LPAR_NAME_LEN + 1]; - void *cpu_info; - int i; - - part_hdr__part_name(diag204_info_type, part_hdr, lpar_name); - lpar_name[LPAR_NAME_LEN] = 0; - lpar_dir = hypfs_mkdir(sb, systems_dir, lpar_name); - if (IS_ERR(lpar_dir)) - return lpar_dir; - cpus_dir = hypfs_mkdir(sb, lpar_dir, "cpus"); - if (IS_ERR(cpus_dir)) - return cpus_dir; - cpu_info = part_hdr + part_hdr__size(diag204_info_type); - for (i = 0; i < part_hdr__rcpus(diag204_info_type, part_hdr); i++) { - int rc; - rc = hypfs_create_cpu_files(sb, cpus_dir, cpu_info); - if (rc) - return ERR_PTR(rc); - cpu_info += cpu_info__size(diag204_info_type); - } - return cpu_info; -} - -static int hypfs_create_phys_cpu_files(struct super_block *sb, - struct dentry *cpus_dir, void *cpu_info) -{ - struct dentry *cpu_dir; - char buffer[TMP_SIZE]; - void *rc; - - snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_info_type, - cpu_info)); - cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer); - if (IS_ERR(cpu_dir)) - return PTR_ERR(cpu_dir); - rc = hypfs_create_u64(sb, cpu_dir, "mgmtime", - phys_cpu__mgm_time(diag204_info_type, cpu_info)); - if (IS_ERR(rc)) - return PTR_ERR(rc); - diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer); - rc = hypfs_create_str(sb, cpu_dir, "type", buffer); - if (IS_ERR(rc)) - return PTR_ERR(rc); - return 0; -} - -static void *hypfs_create_phys_files(struct super_block *sb, - struct dentry *parent_dir, void *phys_hdr) -{ - int i; - void *cpu_info; - struct dentry *cpus_dir; - - cpus_dir = hypfs_mkdir(sb, parent_dir, "cpus"); - if (IS_ERR(cpus_dir)) - return cpus_dir; - cpu_info = phys_hdr + phys_hdr__size(diag204_info_type); - for (i = 0; i < phys_hdr__cpus(diag204_info_type, phys_hdr); i++) { - int rc; - rc = hypfs_create_phys_cpu_files(sb, cpus_dir, cpu_info); - if (rc) - return ERR_PTR(rc); - cpu_info += phys_cpu__size(diag204_info_type); - } - return cpu_info; -} - -int hypfs_diag_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *systems_dir, *hyp_dir; - void *time_hdr, *part_hdr; - int i, rc; - void *buffer, *ptr; - - buffer = diag204_store(); - if (IS_ERR(buffer)) - return PTR_ERR(buffer); - - systems_dir = hypfs_mkdir(sb, root, "systems"); - if (IS_ERR(systems_dir)) { - rc = PTR_ERR(systems_dir); - goto err_out; - } - time_hdr = (struct x_info_blk_hdr *)buffer; - part_hdr = time_hdr + info_blk_hdr__size(diag204_info_type); - for (i = 0; i < info_blk_hdr__npar(diag204_info_type, time_hdr); i++) { - part_hdr = hypfs_create_lpar_files(sb, systems_dir, part_hdr); - if (IS_ERR(part_hdr)) { - rc = PTR_ERR(part_hdr); - goto err_out; - } - } - if (info_blk_hdr__flags(diag204_info_type, time_hdr) & LPAR_PHYS_FLG) { - ptr = hypfs_create_phys_files(sb, root, part_hdr); - if (IS_ERR(ptr)) { - rc = PTR_ERR(ptr); - goto err_out; - } - } - hyp_dir = hypfs_mkdir(sb, root, "hyp"); - if (IS_ERR(hyp_dir)) { - rc = PTR_ERR(hyp_dir); - goto err_out; - } - ptr = hypfs_create_str(sb, hyp_dir, "type", "LPAR Hypervisor"); - if (IS_ERR(ptr)) { - rc = PTR_ERR(ptr); - goto err_out; - } - rc = 0; - -err_out: - return rc; -} diff --git a/trunk/arch/s390/hypfs/hypfs_diag.h b/trunk/arch/s390/hypfs/hypfs_diag.h deleted file mode 100644 index 793dea6b9bb6..000000000000 --- a/trunk/arch/s390/hypfs/hypfs_diag.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * fs/hypfs/hypfs_diag.h - * Hypervisor filesystem for Linux on s390. - * - * Copyright (C) IBM Corp. 2006 - * Author(s): Michael Holzheu - */ - -#ifndef _HYPFS_DIAG_H_ -#define _HYPFS_DIAG_H_ - -extern int hypfs_diag_init(void); -extern void hypfs_diag_exit(void); -extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root); - -#endif /* _HYPFS_DIAG_H_ */ diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c deleted file mode 100644 index 18c091925ea5..000000000000 --- a/trunk/arch/s390/hypfs/inode.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * fs/hypfs/inode.c - * Hypervisor filesystem for Linux on s390. - * - * Copyright (C) IBM Corp. 2006 - * Author(s): Michael Holzheu - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hypfs.h" -#include "hypfs_diag.h" - -#define HYPFS_MAGIC 0x687970 /* ASCII 'hyp' */ -#define TMP_SIZE 64 /* size of temporary buffers */ - -static struct dentry *hypfs_create_update_file(struct super_block *sb, - struct dentry *dir); - -struct hypfs_sb_info { - uid_t uid; /* uid used for files and dirs */ - gid_t gid; /* gid used for files and dirs */ - struct dentry *update_file; /* file to trigger update */ - time_t last_update; /* last update time in secs since 1970 */ - struct mutex lock; /* lock to protect update process */ -}; - -static struct file_operations hypfs_file_ops; -static struct file_system_type hypfs_type; -static struct super_operations hypfs_s_ops; - -/* start of list of all dentries, which have to be deleted on update */ -static struct dentry *hypfs_last_dentry; - -static void hypfs_update_update(struct super_block *sb) -{ - struct hypfs_sb_info *sb_info = sb->s_fs_info; - struct inode *inode = sb_info->update_file->d_inode; - - sb_info->last_update = get_seconds(); - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; -} - -/* directory tree removal functions */ - -static void hypfs_add_dentry(struct dentry *dentry) -{ - dentry->d_fsdata = hypfs_last_dentry; - hypfs_last_dentry = dentry; -} - -static void hypfs_remove(struct dentry *dentry) -{ - struct dentry *parent; - - parent = dentry->d_parent; - if (S_ISDIR(dentry->d_inode->i_mode)) - simple_rmdir(parent->d_inode, dentry); - else - simple_unlink(parent->d_inode, dentry); - d_delete(dentry); - dput(dentry); -} - -static void hypfs_delete_tree(struct dentry *root) -{ - while (hypfs_last_dentry) { - struct dentry *next_dentry; - next_dentry = hypfs_last_dentry->d_fsdata; - hypfs_remove(hypfs_last_dentry); - hypfs_last_dentry = next_dentry; - } -} - -static struct inode *hypfs_make_inode(struct super_block *sb, int mode) -{ - struct inode *ret = new_inode(sb); - - if (ret) { - struct hypfs_sb_info *hypfs_info = sb->s_fs_info; - ret->i_mode = mode; - ret->i_uid = hypfs_info->uid; - ret->i_gid = hypfs_info->gid; - ret->i_blksize = PAGE_CACHE_SIZE; - ret->i_blocks = 0; - ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; - if (mode & S_IFDIR) - ret->i_nlink = 2; - else - ret->i_nlink = 1; - } - return ret; -} - -static void hypfs_drop_inode(struct inode *inode) -{ - kfree(inode->u.generic_ip); - generic_delete_inode(inode); -} - -static int hypfs_open(struct inode *inode, struct file *filp) -{ - char *data = filp->f_dentry->d_inode->u.generic_ip; - struct hypfs_sb_info *fs_info; - - if (filp->f_mode & FMODE_WRITE) { - if (!(inode->i_mode & S_IWUGO)) - return -EACCES; - } - if (filp->f_mode & FMODE_READ) { - if (!(inode->i_mode & S_IRUGO)) - return -EACCES; - } - - fs_info = inode->i_sb->s_fs_info; - if(data) { - mutex_lock(&fs_info->lock); - filp->private_data = kstrdup(data, GFP_KERNEL); - if (!filp->private_data) { - mutex_unlock(&fs_info->lock); - return -ENOMEM; - } - mutex_unlock(&fs_info->lock); - } - return 0; -} - -static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf, - size_t count, loff_t offset) -{ - char *data; - size_t len; - struct file *filp = iocb->ki_filp; - - data = filp->private_data; - len = strlen(data); - if (offset > len) { - count = 0; - goto out; - } - if (count > len - offset) - count = len - offset; - if (copy_to_user(buf, data + offset, count)) { - count = -EFAULT; - goto out; - } - iocb->ki_pos += count; - file_accessed(filp); -out: - return count; -} -static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) -{ - int rc; - struct super_block *sb; - struct hypfs_sb_info *fs_info; - - sb = iocb->ki_filp->f_dentry->d_inode->i_sb; - fs_info = sb->s_fs_info; - /* - * Currently we only allow one update per second for two reasons: - * 1. diag 204 is VERY expensive - * 2. If several processes do updates in parallel and then read the - * hypfs data, the likelihood of collisions is reduced, if we restrict - * the minimum update interval. A collision occurs, if during the - * data gathering of one process another process triggers an update - * If the first process wants to ensure consistent data, it has - * to restart data collection in this case. - */ - mutex_lock(&fs_info->lock); - if (fs_info->last_update == get_seconds()) { - rc = -EBUSY; - goto out; - } - hypfs_delete_tree(sb->s_root); - rc = hypfs_diag_create_files(sb, sb->s_root); - if (rc) { - printk(KERN_ERR "hypfs: Update failed\n"); - hypfs_delete_tree(sb->s_root); - goto out; - } - hypfs_update_update(sb); - rc = count; -out: - mutex_unlock(&fs_info->lock); - return rc; -} - -static int hypfs_release(struct inode *inode, struct file *filp) -{ - kfree(filp->private_data); - return 0; -} - -enum { opt_uid, opt_gid, opt_err }; - -static match_table_t hypfs_tokens = { - {opt_uid, "uid=%u"}, - {opt_gid, "gid=%u"}, - {opt_err, NULL} -}; - -static int hypfs_parse_options(char *options, struct super_block *sb) -{ - char *str; - substring_t args[MAX_OPT_ARGS]; - - if (!options) - return 0; - while ((str = strsep(&options, ",")) != NULL) { - int token, option; - struct hypfs_sb_info *hypfs_info = sb->s_fs_info; - - if (!*str) - continue; - token = match_token(str, hypfs_tokens, args); - switch (token) { - case opt_uid: - if (match_int(&args[0], &option)) - return -EINVAL; - hypfs_info->uid = option; - break; - case opt_gid: - if (match_int(&args[0], &option)) - return -EINVAL; - hypfs_info->gid = option; - break; - case opt_err: - default: - printk(KERN_ERR "hypfs: Unrecognized mount option " - "\"%s\" or missing value\n", str); - return -EINVAL; - } - } - return 0; -} - -static int hypfs_fill_super(struct super_block *sb, void *data, int silent) -{ - struct inode *root_inode; - struct dentry *root_dentry; - int rc = 0; - struct hypfs_sb_info *sbi; - - sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); - if (!sbi) - return -ENOMEM; - mutex_init(&sbi->lock); - sbi->uid = current->uid; - sbi->gid = current->gid; - sb->s_fs_info = sbi; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = HYPFS_MAGIC; - sb->s_op = &hypfs_s_ops; - if (hypfs_parse_options(data, sb)) { - rc = -EINVAL; - goto err_alloc; - } - root_inode = hypfs_make_inode(sb, S_IFDIR | 0755); - if (!root_inode) { - rc = -ENOMEM; - goto err_alloc; - } - root_inode->i_op = &simple_dir_inode_operations; - root_inode->i_fop = &simple_dir_operations; - root_dentry = d_alloc_root(root_inode); - if (!root_dentry) { - iput(root_inode); - rc = -ENOMEM; - goto err_alloc; - } - rc = hypfs_diag_create_files(sb, root_dentry); - if (rc) - goto err_tree; - sbi->update_file = hypfs_create_update_file(sb, root_dentry); - if (IS_ERR(sbi->update_file)) { - rc = PTR_ERR(sbi->update_file); - goto err_tree; - } - hypfs_update_update(sb); - sb->s_root = root_dentry; - return 0; - -err_tree: - hypfs_delete_tree(root_dentry); - d_genocide(root_dentry); - dput(root_dentry); -err_alloc: - kfree(sbi); - return rc; -} - -static int hypfs_get_super(struct file_system_type *fst, int flags, - const char *devname, void *data, struct vfsmount *mnt) -{ - return get_sb_single(fst, flags, data, hypfs_fill_super, mnt); -} - -static void hypfs_kill_super(struct super_block *sb) -{ - struct hypfs_sb_info *sb_info = sb->s_fs_info; - - hypfs_delete_tree(sb->s_root); - hypfs_remove(sb_info->update_file); - kfree(sb->s_fs_info); - sb->s_fs_info = NULL; - kill_litter_super(sb); -} - -static struct dentry *hypfs_create_file(struct super_block *sb, - struct dentry *parent, const char *name, - char *data, mode_t mode) -{ - struct dentry *dentry; - struct inode *inode; - struct qstr qname; - - qname.name = name; - qname.len = strlen(name); - qname.hash = full_name_hash(name, qname.len); - dentry = lookup_one_len(name, parent, strlen(name)); - if (IS_ERR(dentry)) - return ERR_PTR(-ENOMEM); - inode = hypfs_make_inode(sb, mode); - if (!inode) { - dput(dentry); - return ERR_PTR(-ENOMEM); - } - if (mode & S_IFREG) { - inode->i_fop = &hypfs_file_ops; - if (data) - inode->i_size = strlen(data); - else - inode->i_size = 0; - } else if (mode & S_IFDIR) { - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - parent->d_inode->i_nlink++; - } else - BUG(); - inode->u.generic_ip = data; - d_instantiate(dentry, inode); - dget(dentry); - return dentry; -} - -struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, - const char *name) -{ - struct dentry *dentry; - - dentry = hypfs_create_file(sb, parent, name, NULL, S_IFDIR | DIR_MODE); - if (IS_ERR(dentry)) - return dentry; - hypfs_add_dentry(dentry); - parent->d_inode->i_nlink++; - return dentry; -} - -static struct dentry *hypfs_create_update_file(struct super_block *sb, - struct dentry *dir) -{ - struct dentry *dentry; - - dentry = hypfs_create_file(sb, dir, "update", NULL, - S_IFREG | UPDATE_FILE_MODE); - /* - * We do not put the update file on the 'delete' list with - * hypfs_add_dentry(), since it should not be removed when the tree - * is updated. - */ - return dentry; -} - -struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, - const char *name, __u64 value) -{ - char *buffer; - char tmp[TMP_SIZE]; - struct dentry *dentry; - - snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value); - buffer = kstrdup(tmp, GFP_KERNEL); - if (!buffer) - return ERR_PTR(-ENOMEM); - dentry = - hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE); - if (IS_ERR(dentry)) { - kfree(buffer); - return ERR_PTR(-ENOMEM); - } - hypfs_add_dentry(dentry); - return dentry; -} - -struct dentry *hypfs_create_str(struct super_block *sb, struct dentry *dir, - const char *name, char *string) -{ - char *buffer; - struct dentry *dentry; - - buffer = kmalloc(strlen(string) + 2, GFP_KERNEL); - if (!buffer) - return ERR_PTR(-ENOMEM); - sprintf(buffer, "%s\n", string); - dentry = - hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE); - if (IS_ERR(dentry)) { - kfree(buffer); - return ERR_PTR(-ENOMEM); - } - hypfs_add_dentry(dentry); - return dentry; -} - -static struct file_operations hypfs_file_ops = { - .open = hypfs_open, - .release = hypfs_release, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = hypfs_aio_read, - .aio_write = hypfs_aio_write, -}; - -static struct file_system_type hypfs_type = { - .owner = THIS_MODULE, - .name = "s390_hypfs", - .get_sb = hypfs_get_super, - .kill_sb = hypfs_kill_super -}; - -static struct super_operations hypfs_s_ops = { - .statfs = simple_statfs, - .drop_inode = hypfs_drop_inode, -}; - -static decl_subsys(s390, NULL, NULL); - -static int __init hypfs_init(void) -{ - int rc; - - if (MACHINE_IS_VM) - return -ENODATA; - if (hypfs_diag_init()) { - rc = -ENODATA; - goto fail_diag; - } - kset_set_kset_s(&s390_subsys, hypervisor_subsys); - rc = subsystem_register(&s390_subsys); - if (rc) - goto fail_sysfs; - rc = register_filesystem(&hypfs_type); - if (rc) - goto fail_filesystem; - return 0; - -fail_filesystem: - subsystem_unregister(&s390_subsys); -fail_sysfs: - hypfs_diag_exit(); -fail_diag: - printk(KERN_ERR "hypfs: Initialization failed with rc = %i.\n", rc); - return rc; -} - -static void __exit hypfs_exit(void) -{ - hypfs_diag_exit(); - unregister_filesystem(&hypfs_type); - subsystem_unregister(&s390_subsys); -} - -module_init(hypfs_init) -module_exit(hypfs_exit) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michael Holzheu "); -MODULE_DESCRIPTION("s390 Hypervisor Filesystem"); diff --git a/trunk/arch/s390/kernel/machine_kexec.c b/trunk/arch/s390/kernel/machine_kexec.c index fbde6a915264..bad81b5832db 100644 --- a/trunk/arch/s390/kernel/machine_kexec.c +++ b/trunk/arch/s390/kernel/machine_kexec.c @@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *); typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); -extern const unsigned char relocate_kernel[]; -extern const unsigned long long relocate_kernel_len; +const extern unsigned char relocate_kernel[]; +const extern unsigned long long relocate_kernel_len; int machine_kexec_prepare(struct kimage *image) diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index b282034452a4..0a04e4a564b2 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -47,7 +47,6 @@ #include #include #include -#include /* * Machine setup.. @@ -66,6 +65,11 @@ volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; +/* + * Setup options + */ +extern int _text,_etext, _edata, _end; + /* * This is set up by the setup-routine at boot-time * for S390 need to find out, what we have to setup @@ -76,11 +80,15 @@ static unsigned long __initdata memory_end; static struct resource code_resource = { .name = "Kernel code", + .start = (unsigned long) &_text, + .end = (unsigned long) &_etext - 1, .flags = IORESOURCE_BUSY | IORESOURCE_MEM, }; static struct resource data_resource = { .name = "Kernel data", + .start = (unsigned long) &_etext, + .end = (unsigned long) &_edata - 1, .flags = IORESOURCE_BUSY | IORESOURCE_MEM, }; @@ -414,11 +422,6 @@ setup_resources(void) struct resource *res; int i; - code_resource.start = (unsigned long) &_text; - code_resource.end = (unsigned long) &_etext - 1; - data_resource.start = (unsigned long) &_etext; - data_resource.end = (unsigned long) &_edata - 1; - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { res = alloc_bootmem_low(sizeof(struct resource)); res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8e03219eea76..343120c9223d 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -869,7 +869,7 @@ static int __init topology_init(void) int ret; for_each_possible_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/trunk/arch/s390/kernel/vtime.c b/trunk/arch/s390/kernel/vtime.c index 1f0439dc245a..dfe6f0856617 100644 --- a/trunk/arch/s390/kernel/vtime.c +++ b/trunk/arch/s390/kernel/vtime.c @@ -356,7 +356,7 @@ static void internal_add_vtimer(struct vtimer_list *timer) set_vtimer(event->expires); spin_unlock_irqrestore(&vt_list->lock, flags); - /* release CPU acquired in prepare_vtimer or mod_virt_timer() */ + /* release CPU aquired in prepare_vtimer or mod_virt_timer() */ put_cpu(); } diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index e467a450662b..c72e17a96eed 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -147,7 +147,7 @@ endif # them changed. We use .arch and .mach to indicate when they were # updated last, otherwise make uses the target directory mtime. -include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf +include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu @@ -157,7 +157,7 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf # don't, just reference the parent directory so the semantics are # kept roughly the same. -include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf +include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER @echo -n ' SYMLINK include/asm-sh/mach -> ' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c index 6bcd8d92399f..43546525f28f 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)( unsigned long start_address, unsigned long vbr_reg) ATTRIB_NORET; -extern const unsigned char relocate_new_kernel[]; -extern const unsigned int relocate_new_kernel_size; +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; extern void *gdb_vbr_vector; /* diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 9af22116c9a2..bb229ef030f3 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -402,7 +402,7 @@ static int __init topology_init(void) int cpu_id; for_each_possible_cpu(cpu_id) - register_cpu(&cpu[cpu_id], cpu_id); + register_cpu(&cpu[cpu_id], cpu_id, NULL); return 0; } diff --git a/trunk/arch/sh/oprofile/op_model_sh7750.c b/trunk/arch/sh/oprofile/op_model_sh7750.c index c265185b22a7..5ec9ddcc4b0b 100644 --- a/trunk/arch/sh/oprofile/op_model_sh7750.c +++ b/trunk/arch/sh/oprofile/op_model_sh7750.c @@ -198,7 +198,7 @@ static int sh7750_perf_counter_create_files(struct super_block *sb, struct dentr for (i = 0; i < NR_CNTRS; i++) { struct dentry *dir; - char buf[4]; + char buf[3]; snprintf(buf, sizeof(buf), "%d", i); dir = oprofilefs_mkdir(sb, root, buf); diff --git a/trunk/arch/sh64/kernel/setup.c b/trunk/arch/sh64/kernel/setup.c index da98d8dbcf95..d2711c9c9d13 100644 --- a/trunk/arch/sh64/kernel/setup.c +++ b/trunk/arch/sh64/kernel/setup.c @@ -309,7 +309,7 @@ static struct cpu cpu[1]; static int __init topology_init(void) { - return register_cpu(cpu, 0); + return register_cpu(cpu, 0, NULL); } subsys_initcall(topology_init); diff --git a/trunk/arch/sh64/kernel/signal.c b/trunk/arch/sh64/kernel/signal.c index 9e2ffc45c0e0..3ea8929e483b 100644 --- a/trunk/arch/sh64/kernel/signal.c +++ b/trunk/arch/sh64/kernel/signal.c @@ -407,7 +407,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, static inline void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) { - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void __user *)((sp - frame_size) & -8ul); diff --git a/trunk/arch/sparc/kernel/Makefile b/trunk/arch/sparc/kernel/Makefile index 6616ee05c313..1b83e21841b5 100644 --- a/trunk/arch/sparc/kernel/Makefile +++ b/trunk/arch/sparc/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ sys_sparc.o sunos_asm.o systbls.o \ time.o windows.o cpu.o devices.o sclow.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \ - unaligned.o muldiv.o semaphore.o prom.o of_device.o + unaligned.o muldiv.o semaphore.o obj-$(CONFIG_PCI) += pcic.o obj-$(CONFIG_SUN4) += sun4setup.o diff --git a/trunk/arch/sparc/kernel/ebus.c b/trunk/arch/sparc/kernel/ebus.c index a7a4892956c8..5c3529ceb5d6 100644 --- a/trunk/arch/sparc/kernel/ebus.c +++ b/trunk/arch/sparc/kernel/ebus.c @@ -20,7 +20,6 @@ #include #include #include -#include #include struct linux_ebus *ebus_chain = NULL; @@ -84,81 +83,79 @@ int __init ebus_blacklist_irq(char *name) return 0; } -void __init fill_ebus_child(struct device_node *dp, - struct linux_ebus_child *dev) +void __init fill_ebus_child(int node, struct linux_prom_registers *preg, + struct linux_ebus_child *dev) { - int *regs; - int *irqs; + int regs[PROMREG_MAX]; + int irqs[PROMREG_MAX]; + char lbuf[128]; int i, len; - dev->prom_node = dp; - regs = of_get_property(dp, "reg", &len); - if (!regs) - len = 0; + dev->prom_node = node; + prom_getstring(node, "name", lbuf, sizeof(lbuf)); + strcpy(dev->prom_name, lbuf); + + len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); + if (len == -1) len = 0; dev->num_addrs = len / sizeof(regs[0]); for (i = 0; i < dev->num_addrs; i++) { if (regs[i] >= dev->parent->num_addrs) { prom_printf("UGH: property for %s was %d, need < %d\n", - dev->prom_node->name, len, - dev->parent->num_addrs); + dev->prom_name, len, dev->parent->num_addrs); panic(__FUNCTION__); } - - /* XXX resource */ - dev->resource[i].start = - dev->parent->resource[regs[i]].start; + dev->resource[i].start = dev->parent->resource[regs[i]].start; /* XXX resource */ } for (i = 0; i < PROMINTR_MAX; i++) dev->irqs[i] = PCI_IRQ_NONE; - if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { + if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { dev->num_irqs = 1; + } else if ((len = prom_getproperty(node, "interrupts", + (char *)&irqs, sizeof(irqs))) == -1 || len == 0) { + dev->num_irqs = 0; + dev->irqs[0] = 0; + if (dev->parent->num_irqs != 0) { + dev->num_irqs = 1; + dev->irqs[0] = dev->parent->irqs[0]; +/* P3 */ /* printk("EBUS: dev %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */ + } } else { - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { + dev->num_irqs = len / sizeof(irqs[0]); + if (irqs[0] == 0 || irqs[0] >= 8) { + /* + * XXX Zero is a valid pin number... + * This works as long as Ebus is not wired to INTA#. + */ + printk("EBUS: %s got bad irq %d from PROM\n", + dev->prom_name, irqs[0]); dev->num_irqs = 0; dev->irqs[0] = 0; - if (dev->parent->num_irqs != 0) { - dev->num_irqs = 1; - dev->irqs[0] = dev->parent->irqs[0]; - } } else { - dev->num_irqs = len / sizeof(irqs[0]); - if (irqs[0] == 0 || irqs[0] >= 8) { - /* - * XXX Zero is a valid pin number... - * This works as long as Ebus is not wired - * to INTA#. - */ - printk("EBUS: %s got bad irq %d from PROM\n", - dev->prom_node->name, irqs[0]); - dev->num_irqs = 0; - dev->irqs[0] = 0; - } else { - dev->irqs[0] = - pcic_pin_to_irq(irqs[0], - dev->prom_node->name); - } + dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name); } } } -void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) +void __init fill_ebus_device(int node, struct linux_ebus_device *dev) { - struct linux_prom_registers *regs; + struct linux_prom_registers regs[PROMREG_MAX]; struct linux_ebus_child *child; - int *irqs; + int irqs[PROMINTR_MAX]; + char lbuf[128]; int i, n, len; unsigned long baseaddr; - dev->prom_node = dp; + dev->prom_node = node; + prom_getstring(node, "name", lbuf, sizeof(lbuf)); + strcpy(dev->prom_name, lbuf); - regs = of_get_property(dp, "reg", &len); + len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); if (len % sizeof(struct linux_prom_registers)) { prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", - dev->prom_node->name, len, + dev->prom_name, len, (int)sizeof(struct linux_prom_registers)); panic(__FUNCTION__); } @@ -200,7 +197,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d if ((baseaddr = (unsigned long) ioremap(baseaddr, regs[i].reg_size)) == 0) { panic("ebus: unable to remap dev %s", - dev->prom_node->name); + dev->prom_name); } } dev->resource[i].start = baseaddr; /* XXX Unaligned */ @@ -209,43 +206,29 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d for (i = 0; i < PROMINTR_MAX; i++) dev->irqs[i] = PCI_IRQ_NONE; - if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { + if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { dev->num_irqs = 1; + } else if ((len = prom_getproperty(node, "interrupts", + (char *)&irqs, sizeof(irqs))) == -1 || len == 0) { + dev->num_irqs = 0; + if ((dev->irqs[0] = dev->bus->self->irq) != 0) { + dev->num_irqs = 1; +/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */ + } } else { - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { + dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */ + if (irqs[0] == 0 || irqs[0] >= 8) { + /* See above for the parent. XXX */ + printk("EBUS: %s got bad irq %d from PROM\n", + dev->prom_name, irqs[0]); dev->num_irqs = 0; - if ((dev->irqs[0] = dev->bus->self->irq) != 0) { - dev->num_irqs = 1; -/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */ - } + dev->irqs[0] = 0; } else { - dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */ - if (irqs[0] == 0 || irqs[0] >= 8) { - /* See above for the parent. XXX */ - printk("EBUS: %s got bad irq %d from PROM\n", - dev->prom_node->name, irqs[0]); - dev->num_irqs = 0; - dev->irqs[0] = 0; - } else { - dev->irqs[0] = - pcic_pin_to_irq(irqs[0], - dev->prom_node->name); - } + dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name); } } - dev->ofdev.node = dp; - dev->ofdev.dev.parent = &dev->bus->ofdev.dev; - dev->ofdev.dev.bus = &ebus_bus_type; - strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); - - /* Register with core */ - if (of_device_register(&dev->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dev->ofdev.dev.bus_id); - - if ((dp = dp->child) != NULL) { + if ((node = prom_getchild(node))) { dev->children = (struct linux_ebus_child *) ebus_alloc(sizeof(struct linux_ebus_child)); @@ -253,9 +236,9 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d child->next = NULL; child->parent = dev; child->bus = dev->bus; - fill_ebus_child(dp, child); + fill_ebus_child(node, ®s[0], child); - while ((dp = dp->sibling) != NULL) { + while ((node = prom_getsibling(node)) != 0) { child->next = (struct linux_ebus_child *) ebus_alloc(sizeof(struct linux_ebus_child)); @@ -263,49 +246,51 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d child->next = NULL; child->parent = dev; child->bus = dev->bus; - fill_ebus_child(dp, child); + fill_ebus_child(node, ®s[0], child); } } } void __init ebus_init(void) { - struct linux_prom_pci_registers *regs; + struct linux_prom_pci_registers regs[PROMREG_MAX]; struct linux_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct ebus_system_entry *sp; struct pci_dev *pdev; struct pcidev_cookie *cookie; - struct device_node *dp; + char lbuf[128]; unsigned long addr, *base; unsigned short pci_command; - int len, reg, nreg; + int nd, len, ebusnd; + int reg, nreg; int num_ebus = 0; - dp = of_find_node_by_path("/"); + prom_getstring(prom_root_node, "name", lbuf, sizeof(lbuf)); for (sp = ebus_blacklist; sp->esname != NULL; sp++) { - if (strcmp(dp->name, sp->esname) == 0) { + if (strcmp(lbuf, sp->esname) == 0) { ebus_blackp = sp->ipt; break; } } pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL); - if (!pdev) + if (!pdev) { return; - + } cookie = pdev->sysdata; - dp = cookie->prom_node; + ebusnd = cookie->prom_node; ebus_chain = ebus = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); ebus->next = NULL; - while (dp) { - struct device_node *nd; + while (ebusnd) { - ebus->prom_node = dp; + prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf)); + ebus->prom_node = ebusnd; + strcpy(ebus->prom_name, lbuf); ebus->self = pdev; ebus->parent = pbm = cookie->pbm; @@ -314,8 +299,9 @@ void __init ebus_init(void) pci_command |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, pci_command); - regs = of_get_property(dp, "reg", &len); - if (!regs) { + len = prom_getproperty(ebusnd, "reg", (void *)regs, + sizeof(regs)); + if (len == 0 || len == -1) { prom_printf("%s: can't find reg property\n", __FUNCTION__); prom_halt(); @@ -331,18 +317,7 @@ void __init ebus_init(void) *base++ = addr; } - ebus->ofdev.node = dp; - ebus->ofdev.dev.parent = &pdev->dev; - ebus->ofdev.dev.bus = &ebus_bus_type; - strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); - - /* Register with core */ - if (of_device_register(&ebus->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - ebus->ofdev.dev.bus_id); - - - nd = dp->child; + nd = prom_getchild(ebusnd); if (!nd) goto next_ebus; @@ -355,7 +330,7 @@ void __init ebus_init(void) dev->bus = ebus; fill_ebus_device(nd, dev); - while ((nd = nd->sibling) != NULL) { + while ((nd = prom_getsibling(nd)) != 0) { dev->next = (struct linux_ebus_device *) ebus_alloc(sizeof(struct linux_ebus_device)); @@ -373,7 +348,7 @@ void __init ebus_init(void) break; cookie = pdev->sysdata; - dp = cookie->prom_node; + ebusnd = cookie->prom_node; ebus->next = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c index ae4c667c906f..f9ff29734848 100644 --- a/trunk/arch/sparc/kernel/ioport.c +++ b/trunk/arch/sparc/kernel/ioport.c @@ -39,8 +39,6 @@ #include #include #include -#include -#include #include #include #include @@ -226,54 +224,10 @@ static void _sparc_free_io(struct resource *res) #ifdef CONFIG_SBUS -void sbus_set_sbus64(struct sbus_dev *sdev, int x) -{ +void sbus_set_sbus64(struct sbus_dev *sdev, int x) { printk("sbus_set_sbus64: unsupported\n"); } -extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); -void __init sbus_fill_device_irq(struct sbus_dev *sdev) -{ - struct linux_prom_irqs irqs[PROMINTR_MAX]; - int len; - - len = prom_getproperty(sdev->prom_node, "intr", - (char *)irqs, sizeof(irqs)); - if (len != -1) { - sdev->num_irqs = len / 8; - if (sdev->num_irqs == 0) { - sdev->irqs[0] = 0; - } else if (sparc_cpu_model == sun4d) { - for (len = 0; len < sdev->num_irqs; len++) - sdev->irqs[len] = - sun4d_build_irq(sdev, irqs[len].pri); - } else { - for (len = 0; len < sdev->num_irqs; len++) - sdev->irqs[len] = irqs[len].pri; - } - } else { - int interrupts[PROMINTR_MAX]; - - /* No "intr" node found-- check for "interrupts" node. - * This node contains SBus interrupt levels, not IPLs - * as in "intr", and no vector values. We convert - * SBus interrupt levels to PILs (platform specific). - */ - len = prom_getproperty(sdev->prom_node, "interrupts", - (char *)interrupts, sizeof(interrupts)); - if (len == -1) { - sdev->irqs[0] = 0; - sdev->num_irqs = 0; - } else { - sdev->num_irqs = len / sizeof(int); - for (len = 0; len < sdev->num_irqs; len++) { - sdev->irqs[len] = - sbint_to_irq(sdev, interrupts[len]); - } - } - } -} - /* * Allocate a chunk of memory suitable for DMA. * Typically devices use them for control blocks. @@ -460,89 +414,6 @@ void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, { printk("sbus_dma_sync_sg_for_device: not implemented yet\n"); } - -/* Support code for sbus_init(). */ -/* - * XXX This functions appears to be a distorted version of - * prom_sbus_ranges_init(), with all sun4d stuff cut away. - * Ask DaveM what is going on here, how is sun4d supposed to work... XXX - */ -/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ -void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) -{ - int parent_node = pn->node; - - if (sparc_cpu_model == sun4d) { - struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; - int num_iounit_ranges, len; - - len = prom_getproperty(parent_node, "ranges", - (char *) iounit_ranges, - sizeof (iounit_ranges)); - if (len != -1) { - num_iounit_ranges = - (len / sizeof(struct linux_prom_ranges)); - prom_adjust_ranges(sbus->sbus_ranges, - sbus->num_sbus_ranges, - iounit_ranges, num_iounit_ranges); - } - } -} - -void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) -{ - struct device_node *parent = dp->parent; - - if (sparc_cpu_model != sun4d && - parent != NULL && - !strcmp(parent->name, "iommu")) { - extern void iommu_init(int iommu_node, struct sbus_bus *sbus); - - iommu_init(parent->node, sbus); - } - - if (sparc_cpu_model == sun4d) { - extern void iounit_init(int sbi_node, int iounit_node, - struct sbus_bus *sbus); - - iounit_init(dp->node, parent->node, sbus); - } -} - -void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) -{ - if (sparc_cpu_model == sun4d) { - struct device_node *parent = dp->parent; - - sbus->devid = of_getintprop_default(parent, "device-id", 0); - sbus->board = of_getintprop_default(parent, "board#", 0); - } -} - -int __init sbus_arch_preinit(void) -{ - extern void register_proc_sparc_ioport(void); - - register_proc_sparc_ioport(); - -#ifdef CONFIG_SUN4 - { - extern void sun4_dvma_init(void); - sun4_dvma_init(); - } - return 1; -#else - return 0; -#endif -} - -void __init sbus_arch_postinit(void) -{ - if (sparc_cpu_model == sun4d) { - extern void sun4d_init_sbi_irq(void); - sun4d_init_sbi_irq(); - } -} #endif /* CONFIG_SBUS */ #ifdef CONFIG_PCI diff --git a/trunk/arch/sparc/kernel/of_device.c b/trunk/arch/sparc/kernel/of_device.c deleted file mode 100644 index 80a809478781..000000000000 --- a/trunk/arch/sparc/kernel/of_device.c +++ /dev/null @@ -1,270 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in - * @dev: the of device structure to match against - * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. - */ -const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) -{ - if (!dev->node) - return NULL; - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); - if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); - if (matches->compatible[0]) - match &= of_device_is_compatible(dev->node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; -} - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_device_id * matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; -} - -struct of_device *of_dev_get(struct of_device *dev) -{ - struct device *tmp; - - if (!dev) - return NULL; - tmp = get_device(&dev->dev); - if (tmp) - return to_of_device(tmp); - else - return NULL; -} - -void of_dev_put(struct of_device *dev) -{ - if (dev) - put_device(&dev->dev); -} - - -static int of_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_device_remove(struct device *dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_device_resume(struct device * dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -#ifdef CONFIG_PCI -struct bus_type ebus_bus_type = { - .name = "ebus", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; -EXPORT_SYMBOL(ebus_bus_type); -#endif - -#ifdef CONFIG_SBUS -struct bus_type sbus_bus_type = { - .name = "sbus", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; -EXPORT_SYMBOL(sbus_bus_type); -#endif - -static int __init of_bus_driver_init(void) -{ - int err = 0; - -#ifdef CONFIG_PCI - if (!err) - err = bus_register(&ebus_bus_type); -#endif -#ifdef CONFIG_SBUS - if (!err) - err = bus_register(&sbus_bus_type); -#endif - return 0; -} - -postcore_initcall(of_bus_driver_init); - -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* initialize common driver fields */ - drv->driver.name = drv->name; - drv->driver.bus = bus; - - /* register with core */ - return driver_register(&drv->driver); -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - - -static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); -} - -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); - -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - - kfree(ofdev); -} - -int of_device_register(struct of_device *ofdev) -{ - int rc; - - BUG_ON(ofdev->node == NULL); - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; -} - -void of_device_unregister(struct of_device *ofdev) -{ - device_remove_file(&ofdev->dev, &dev_attr_devspec); - device_unregister(&ofdev->dev); -} - -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent, - struct bus_type *bus) -{ - struct of_device *dev; - - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->dev.parent = parent; - dev->dev.bus = bus; - dev->dev.release = of_release_dev; - - strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); - - if (of_device_register(dev) != 0) { - kfree(dev); - return NULL; - } - - return dev; -} - -EXPORT_SYMBOL(of_match_device); -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); -EXPORT_SYMBOL(of_device_register); -EXPORT_SYMBOL(of_device_unregister); -EXPORT_SYMBOL(of_dev_get); -EXPORT_SYMBOL(of_dev_put); -EXPORT_SYMBOL(of_platform_device_create); -EXPORT_SYMBOL(of_release_dev); diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index bcfdddd0418a..bcdf5ad0f035 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -666,7 +665,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) /* cookies */ pcp = pci_devcookie_alloc(); pcp->pbm = &pcic->pbm; - pcp->prom_node = of_find_node_by_phandle(node); + pcp->prom_node = node; dev->sysdata = pcp; /* fixing I/O to look like memory */ diff --git a/trunk/arch/sparc/kernel/prom.c b/trunk/arch/sparc/kernel/prom.c deleted file mode 100644 index 946ce6d15819..000000000000 --- a/trunk/arch/sparc/kernel/prom.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Procedures for creating, accessing and interpreting the device tree. - * - * Paul Mackerras August 1996. - * Copyright (C) 1996-2005 Paul Mackerras. - * - * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. - * {engebret|bergner}@us.ibm.com - * - * Adapted for sparc32 by David S. Miller davem@davemloft.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -static struct device_node *allnodes; - -/* use when traversing tree through the allnext, child, sibling, - * or parent members of struct device_node. - */ -static DEFINE_RWLOCK(devtree_lock); - -int of_device_is_compatible(struct device_node *device, const char *compat) -{ - const char* cp; - int cplen, l; - - cp = (char *) of_get_property(device, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (strncmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; -} -EXPORT_SYMBOL(of_device_is_compatible); - -struct device_node *of_get_parent(const struct device_node *node) -{ - struct device_node *np; - - if (!node) - return NULL; - - np = node->parent; - - return np; -} -EXPORT_SYMBOL(of_get_parent); - -struct device_node *of_get_next_child(const struct device_node *node, - struct device_node *prev) -{ - struct device_node *next; - - next = prev ? prev->sibling : node->child; - for (; next != 0; next = next->sibling) { - break; - } - - return next; -} -EXPORT_SYMBOL(of_get_next_child); - -struct device_node *of_find_node_by_path(const char *path) -{ - struct device_node *np = allnodes; - - for (; np != 0; np = np->allnext) { - if (np->full_name != 0 && strcmp(np->full_name, path) == 0) - break; - } - - return np; -} -EXPORT_SYMBOL(of_find_node_by_path); - -struct device_node *of_find_node_by_phandle(phandle handle) -{ - struct device_node *np; - - for (np = allnodes; np != 0; np = np->allnext) - if (np->node == handle) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_phandle); - -struct device_node *of_find_node_by_name(struct device_node *from, - const char *name) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != NULL; np = np->allnext) - if (np->name != NULL && strcmp(np->name, name) == 0) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_name); - -struct device_node *of_find_node_by_type(struct device_node *from, - const char *type) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != 0; np = np->allnext) - if (np->type != 0 && strcmp(np->type, type) == 0) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_type); - -struct device_node *of_find_compatible_node(struct device_node *from, - const char *type, const char *compatible) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != 0; np = np->allnext) { - if (type != NULL - && !(np->type != 0 && strcmp(np->type, type) == 0)) - continue; - if (of_device_is_compatible(np, compatible)) - break; - } - - return np; -} -EXPORT_SYMBOL(of_find_compatible_node); - -struct property *of_find_property(struct device_node *np, const char *name, - int *lenp) -{ - struct property *pp; - - for (pp = np->properties; pp != 0; pp = pp->next) { - if (strcmp(pp->name, name) == 0) { - if (lenp != 0) - *lenp = pp->length; - break; - } - } - return pp; -} -EXPORT_SYMBOL(of_find_property); - -/* - * Find a property with a given name for a given node - * and return the value. - */ -void *of_get_property(struct device_node *np, const char *name, int *lenp) -{ - struct property *pp = of_find_property(np,name,lenp); - return pp ? pp->value : NULL; -} -EXPORT_SYMBOL(of_get_property); - -int of_getintprop_default(struct device_node *np, const char *name, int def) -{ - struct property *prop; - int len; - - prop = of_find_property(np, name, &len); - if (!prop || len != 4) - return def; - - return *(int *) prop->value; -} -EXPORT_SYMBOL(of_getintprop_default); - -int of_set_property(struct device_node *dp, const char *name, void *val, int len) -{ - struct property **prevp; - void *new_val; - int err; - - new_val = kmalloc(len, GFP_KERNEL); - if (!new_val) - return -ENOMEM; - - memcpy(new_val, val, len); - - err = -ENODEV; - - write_lock(&devtree_lock); - prevp = &dp->properties; - while (*prevp) { - struct property *prop = *prevp; - - if (!strcmp(prop->name, name)) { - void *old_val = prop->value; - int ret; - - ret = prom_setprop(dp->node, name, val, len); - err = -EINVAL; - if (ret >= 0) { - prop->value = new_val; - prop->length = len; - - if (OF_IS_DYNAMIC(prop)) - kfree(old_val); - - OF_MARK_DYNAMIC(prop); - - err = 0; - } - break; - } - prevp = &(*prevp)->next; - } - write_unlock(&devtree_lock); - - /* XXX Upate procfs if necessary... */ - - return err; -} -EXPORT_SYMBOL(of_set_property); - -static unsigned int prom_early_allocated; - -static void * __init prom_early_alloc(unsigned long size) -{ - void *ret; - - ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); - if (ret != NULL) - memset(ret, 0, size); - - prom_early_allocated += size; - - return ret; -} - -static int is_root_node(const struct device_node *dp) -{ - if (!dp) - return 0; - - return (dp->parent == NULL); -} - -/* The following routines deal with the black magic of fully naming a - * node. - * - * Certain well known named nodes are just the simple name string. - * - * Actual devices have an address specifier appended to the base name - * string, like this "foo@addr". The "addr" can be in any number of - * formats, and the platform plus the type of the node determine the - * format and how it is constructed. - * - * For children of the ROOT node, the naming convention is fixed and - * determined by whether this is a sun4u or sun4v system. - * - * For children of other nodes, it is bus type specific. So - * we walk up the tree until we discover a "device_type" property - * we recognize and we go from there. - */ -static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_registers *regs; - struct property *rprop; - - rprop = of_find_property(dp, "reg", NULL); - if (!rprop) - return; - - regs = rprop->value; - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - regs->which_io, regs->phys_addr); -} - -/* "name@slot,offset" */ -static void __init sbus_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - regs->which_io, - regs->phys_addr); -} - -/* "name@devnum[,func]" */ -static void __init pci_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_pci_registers *regs; - struct property *prop; - unsigned int devfn; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - devfn = (regs->phys_hi >> 8) & 0xff; - if (devfn & 0x07) { - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - devfn >> 3, - devfn & 0x07); - } else { - sprintf(tmp_buf, "%s@%x", - dp->name, - devfn >> 3); - } -} - -/* "name@addrhi,addrlo" */ -static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - regs->which_io, regs->phys_addr); -} - -static void __init __build_path_component(struct device_node *dp, char *tmp_buf) -{ - struct device_node *parent = dp->parent; - - if (parent != NULL) { - if (!strcmp(parent->type, "pci") || - !strcmp(parent->type, "pciex")) - return pci_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "sbus")) - return sbus_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "ebus")) - return ebus_path_component(dp, tmp_buf); - - /* "isa" is handled with platform naming */ - } - - /* Use platform naming convention. */ - return sparc32_path_component(dp, tmp_buf); -} - -static char * __init build_path_component(struct device_node *dp) -{ - char tmp_buf[64], *n; - - tmp_buf[0] = '\0'; - __build_path_component(dp, tmp_buf); - if (tmp_buf[0] == '\0') - strcpy(tmp_buf, dp->name); - - n = prom_early_alloc(strlen(tmp_buf) + 1); - strcpy(n, tmp_buf); - - return n; -} - -static char * __init build_full_name(struct device_node *dp) -{ - int len, ourlen, plen; - char *n; - - plen = strlen(dp->parent->full_name); - ourlen = strlen(dp->path_component_name); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!is_root_node(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, dp->path_component_name); - - return n; -} - -static unsigned int unique_id; - -static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) -{ - static struct property *tmp = NULL; - struct property *p; - int len; - - if (tmp) { - p = tmp; - memset(p, 0, sizeof(*p) + 32); - tmp = NULL; - } else { - p = prom_early_alloc(sizeof(struct property) + 32); - p->unique_id = unique_id++; - } - - p->name = (char *) (p + 1); - if (special_name) { - p->length = special_len; - p->value = prom_early_alloc(special_len); - memcpy(p->value, special_val, special_len); - } else { - if (prev == NULL) { - prom_firstprop(node, p->name); - } else { - prom_nextprop(node, prev, p->name); - } - if (strlen(p->name) == 0) { - tmp = p; - return NULL; - } - p->length = prom_getproplen(node, p->name); - if (p->length <= 0) { - p->length = 0; - } else { - p->value = prom_early_alloc(p->length + 1); - prom_getproperty(node, p->name, p->value, p->length); - ((unsigned char *)p->value)[p->length] = '\0'; - } - } - return p; -} - -static struct property * __init build_prop_list(phandle node) -{ - struct property *head, *tail; - - head = tail = build_one_prop(node, NULL, - ".node", &node, sizeof(node)); - - tail->next = build_one_prop(node, NULL, NULL, NULL, 0); - tail = tail->next; - while(tail) { - tail->next = build_one_prop(node, tail->name, - NULL, NULL, 0); - tail = tail->next; - } - - return head; -} - -static char * __init get_one_property(phandle node, char *name) -{ - char *buf = ""; - int len; - - len = prom_getproplen(node, name); - if (len > 0) { - buf = prom_early_alloc(len); - len = prom_getproperty(node, name, buf, len); - } - - return buf; -} - -static struct device_node * __init create_node(phandle node) -{ - struct device_node *dp; - - if (!node) - return NULL; - - dp = prom_early_alloc(sizeof(*dp)); - dp->unique_id = unique_id++; - - kref_init(&dp->kref); - - dp->name = get_one_property(node, "name"); - dp->type = get_one_property(node, "device_type"); - dp->node = node; - - /* Build interrupts later... */ - - dp->properties = build_prop_list(node); - - return dp; -} - -static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) -{ - struct device_node *dp; - - dp = create_node(node); - if (dp) { - *(*nextp) = dp; - *nextp = &dp->allnext; - - dp->parent = parent; - dp->path_component_name = build_path_component(dp); - dp->full_name = build_full_name(dp); - - dp->child = build_tree(dp, prom_getchild(node), nextp); - - dp->sibling = build_tree(parent, prom_getsibling(node), nextp); - } - - return dp; -} - -void __init prom_build_devicetree(void) -{ - struct device_node **nextp; - - allnodes = create_node(prom_root_node); - allnodes->path_component_name = ""; - allnodes->full_name = "/"; - - nextp = &allnodes->allnext; - allnodes->child = build_tree(allnodes, - prom_getchild(allnodes->node), - &nextp); - printk("PROM: Built device tree with %u bytes of memory.\n", - prom_early_allocated); -} diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index a893a9cc9534..2cbf282f0d00 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -332,7 +332,7 @@ void __init setup_arch(char **cmdline_p) if (!root_flags) root_mountflags &= ~MS_RDONLY; ROOT_DEV = old_decode_dev(root_dev); -#ifdef CONFIG_BLK_DEV_RAM +#ifdef CONFIG_BLK_DEV_INITRD rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK; rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); diff --git a/trunk/arch/sparc/lib/Makefile b/trunk/arch/sparc/lib/Makefile index 5db7e1d85385..fa5006946062 100644 --- a/trunk/arch/sparc/lib/Makefile +++ b/trunk/arch/sparc/lib/Makefile @@ -9,5 +9,3 @@ lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \ strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \ copy_user.o locks.o atomic.o atomic32.o bitops.o \ lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o - -obj-y += iomap.o diff --git a/trunk/arch/sparc/lib/iomap.c b/trunk/arch/sparc/lib/iomap.c deleted file mode 100644 index 54501c1ca785..000000000000 --- a/trunk/arch/sparc/lib/iomap.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Implement the sparc iomap interfaces - */ -#include -#include -#include - -/* Create a virtual mapping cookie for an IO port range */ -void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return (void __iomem *) (unsigned long) port; -} - -void ioport_unmap(void __iomem *addr) -{ - /* Nothing to do */ -} -EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); - -/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - /* What? */ - return NULL; -} - -void pci_iounmap(struct pci_dev *dev, void __iomem * addr) -{ - /* nothing to do */ -} -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); diff --git a/trunk/arch/sparc/mm/init.c b/trunk/arch/sparc/mm/init.c index cfa7d3456634..898669732466 100644 --- a/trunk/arch/sparc/mm/init.c +++ b/trunk/arch/sparc/mm/init.c @@ -31,7 +31,6 @@ #include #include /* bug in asm-generic/tlb.h: check_pgt_cache */ #include -#include DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -350,7 +349,6 @@ void __init paging_init(void) protection_map[14] = PAGE_SHARED; protection_map[15] = PAGE_SHARED; btfixup(); - prom_build_devicetree(); device_scan(); } diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index b2f41147d0e4..9da75f89fe2c 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.17 -# Fri Jun 23 23:17:09 2006 +# Tue Jun 20 01:26:43 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -286,7 +286,6 @@ CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -435,7 +434,6 @@ CONFIG_ISCSI_TCP=m # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set @@ -735,7 +733,6 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_I810 is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set @@ -779,7 +776,6 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -808,12 +804,10 @@ CONFIG_HWMON=y # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set @@ -1024,7 +1018,6 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1104,12 +1097,10 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1207,7 +1198,6 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set diff --git a/trunk/arch/sparc64/kernel/Makefile b/trunk/arch/sparc64/kernel/Makefile index 86c9fe3f3e4a..6f6816488b04 100644 --- a/trunk/arch/sparc64/kernel/Makefile +++ b/trunk/arch/sparc64/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \ unaligned.o central.o pci.o starfire.o semaphore.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ - visemul.o prom.o of_device.o + visemul.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ diff --git a/trunk/arch/sparc64/kernel/auxio.c b/trunk/arch/sparc64/kernel/auxio.c index c2c69c167d18..8852c20c8d99 100644 --- a/trunk/arch/sparc64/kernel/auxio.c +++ b/trunk/arch/sparc64/kernel/auxio.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -17,8 +16,8 @@ #include #include +/* This cannot be static, as it is referenced in irq.c */ void __iomem *auxio_register = NULL; -EXPORT_SYMBOL(auxio_register); enum auxio_type { AUXIO_TYPE_NODEV, @@ -111,82 +110,43 @@ void auxio_set_lte(int on) } } -static void __devinit auxio_report_dev(struct device_node *dp) +void __init auxio_probe(void) { - printk(KERN_INFO "AUXIO: Found device at %s\n", - dp->full_name); -} - -static struct of_device_id auxio_match[] = { - { - .name = "auxio", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, auxio_match); - -#ifdef CONFIG_SBUS -static int __devinit auxio_sbus_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - auxio_devtype = AUXIO_TYPE_SBUS; - auxio_register = sbus_ioremap(&sdev->resource[0], 0, - sdev->reg_addrs[0].reg_size, - "auxiliaryIO"); - if (!auxio_register) - return -ENODEV; - - auxio_report_dev(dev->node); - return 0; -} - -static struct of_platform_driver auxio_sbus_driver = { - .name = "auxio", - .match_table = auxio_match, - .probe = auxio_sbus_probe, -}; -#endif - + struct sbus_bus *sbus; + struct sbus_dev *sdev = NULL; + + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if(!strcmp(sdev->prom_name, "auxio")) + goto found_sdev; + } + } + +found_sdev: + if (sdev) { + auxio_devtype = AUXIO_TYPE_SBUS; + auxio_register = sbus_ioremap(&sdev->resource[0], 0, + sdev->reg_addrs[0].reg_size, + "auxiliaryIO"); + } #ifdef CONFIG_PCI -static int __devinit auxio_ebus_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct linux_ebus_device *edev = to_ebus_device(&dev->dev); - - auxio_devtype = AUXIO_TYPE_EBUS; - auxio_register = ioremap(edev->resource[0].start, sizeof(u32)); - if (!auxio_register) - return -ENODEV; - - auxio_report_dev(dev->node); - + else { + struct linux_ebus *ebus; + struct linux_ebus_device *edev = NULL; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "auxio")) + goto ebus_done; + } + } + ebus_done: + if (edev) { + auxio_devtype = AUXIO_TYPE_EBUS; + auxio_register = + ioremap(edev->resource[0].start, sizeof(u32)); + } + } auxio_set_led(AUXIO_LED_ON); - - return 0; -} - -static struct of_platform_driver auxio_ebus_driver = { - .name = "auxio", - .match_table = auxio_match, - .probe = auxio_ebus_probe, -}; #endif - -static int __init auxio_probe(void) -{ -#ifdef CONFIG_SBUS - of_register_driver(&auxio_sbus_driver, &sbus_bus_type); -#endif -#ifdef CONFIG_PCI - of_register_driver(&auxio_ebus_driver, &ebus_bus_type); -#endif - - return 0; } - -/* Must be after subsys_initcall() so that busses are probed. Must - * be before device_initcall() because things like the floppy driver - * need to use the AUXIO register. - */ -fs_initcall(auxio_probe); diff --git a/trunk/arch/sparc64/kernel/central.c b/trunk/arch/sparc64/kernel/central.c index b66336db00ee..3d184a784968 100644 --- a/trunk/arch/sparc64/kernel/central.c +++ b/trunk/arch/sparc64/kernel/central.c @@ -29,34 +29,28 @@ static void central_probe_failure(int line) prom_halt(); } -static void central_ranges_init(struct linux_central *central) +static void central_ranges_init(int cnode, struct linux_central *central) { - struct device_node *dp = central->prom_node; - void *pval; - int len; + int success; central->num_central_ranges = 0; - pval = of_get_property(dp, "ranges", &len); - if (pval) { - memcpy(central->central_ranges, pval, len); - central->num_central_ranges = - (len / sizeof(struct linux_prom_ranges)); - } + success = prom_getproperty(central->prom_node, "ranges", + (char *) central->central_ranges, + sizeof (central->central_ranges)); + if (success != -1) + central->num_central_ranges = (success/sizeof(struct linux_prom_ranges)); } -static void fhc_ranges_init(struct linux_fhc *fhc) +static void fhc_ranges_init(int fnode, struct linux_fhc *fhc) { - struct device_node *dp = fhc->prom_node; - void *pval; - int len; + int success; fhc->num_fhc_ranges = 0; - pval = of_get_property(dp, "ranges", &len); - if (pval) { - memcpy(fhc->fhc_ranges, pval, len); - fhc->num_fhc_ranges = - (len / sizeof(struct linux_prom_ranges)); - } + success = prom_getproperty(fhc->prom_node, "ranges", + (char *) fhc->fhc_ranges, + sizeof (fhc->fhc_ranges)); + if (success != -1) + fhc->num_fhc_ranges = (success/sizeof(struct linux_prom_ranges)); } /* Range application routines are exported to various drivers, @@ -118,10 +112,15 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r) static void probe_other_fhcs(void) { - struct device_node *dp; - struct linux_prom64_registers *fpregs; + struct linux_prom64_registers fpregs[6]; + char namebuf[128]; + int node; - for_each_node_by_name(dp, "fhc") { + node = prom_getchild(prom_root_node); + node = prom_searchsiblings(node, "fhc"); + if (node == 0) + central_probe_failure(__LINE__); + while (node) { struct linux_fhc *fhc; int board; u32 tmp; @@ -138,12 +137,14 @@ static void probe_other_fhcs(void) /* Toplevel FHCs have no parent. */ fhc->parent = NULL; - fhc->prom_node = dp; - fhc_ranges_init(fhc); + fhc->prom_node = node; + prom_getstring(node, "name", namebuf, sizeof(namebuf)); + strcpy(fhc->prom_name, namebuf); + fhc_ranges_init(node, fhc); /* Non-central FHC's have 64-bit OBP format registers. */ - fpregs = of_get_property(dp, "reg", NULL); - if (!fpregs) + if (prom_getproperty(node, "reg", + (char *)&fpregs[0], sizeof(fpregs)) == -1) central_probe_failure(__LINE__); /* Only central FHC needs special ranges applied. */ @@ -154,7 +155,7 @@ static void probe_other_fhcs(void) fhc->fhc_regs.uregs = fpregs[4].phys_addr; fhc->fhc_regs.tregs = fpregs[5].phys_addr; - board = of_getintprop_default(dp, "board#", -1); + board = prom_getintdefault(node, "board#", -1); fhc->board = board; tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL); @@ -178,33 +179,33 @@ static void probe_other_fhcs(void) tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL); tmp |= FHC_CONTROL_IXIST; upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL); + + /* Look for the next FHC. */ + node = prom_getsibling(node); + if (node == 0) + break; + node = prom_searchsiblings(node, "fhc"); + if (node == 0) + break; } } static void probe_clock_board(struct linux_central *central, struct linux_fhc *fhc, - struct device_node *fp) + int cnode, int fnode) { - struct device_node *dp; - struct linux_prom_registers cregs[3], *pr; - int nslots, tmp, nregs; + struct linux_prom_registers cregs[3]; + int clknode, nslots, tmp, nregs; - dp = fp->child; - while (dp) { - if (!strcmp(dp->name, "clock-board")) - break; - dp = dp->sibling; - } - if (!dp) + clknode = prom_searchsiblings(prom_getchild(fnode), "clock-board"); + if (clknode == 0 || clknode == -1) central_probe_failure(__LINE__); - pr = of_get_property(dp, "reg", &nregs); - if (!pr) + nregs = prom_getproperty(clknode, "reg", (char *)&cregs[0], sizeof(cregs)); + if (nregs == -1) central_probe_failure(__LINE__); - memcpy(cregs, pr, nregs); nregs /= sizeof(struct linux_prom_registers); - apply_fhc_ranges(fhc, &cregs[0], nregs); apply_central_ranges(central, &cregs[0], nregs); central->cfreg = prom_reg_to_paddr(&cregs[0]); @@ -295,13 +296,13 @@ static void init_all_fhc_hw(void) void central_probe(void) { - struct linux_prom_registers fpregs[6], *pr; + struct linux_prom_registers fpregs[6]; struct linux_fhc *fhc; - struct device_node *dp, *fp; - int err; + char namebuf[128]; + int cnode, fnode, err; - dp = of_find_node_by_name(NULL, "central"); - if (!dp) { + cnode = prom_finddevice("/central"); + if (cnode == 0 || cnode == -1) { if (this_is_starfire) starfire_cpu_setup(); return; @@ -320,31 +321,31 @@ void central_probe(void) /* First init central. */ central_bus->child = fhc; - central_bus->prom_node = dp; - central_ranges_init(central_bus); + central_bus->prom_node = cnode; + + prom_getstring(cnode, "name", namebuf, sizeof(namebuf)); + strcpy(central_bus->prom_name, namebuf); + + central_ranges_init(cnode, central_bus); /* And then central's FHC. */ fhc->next = fhc_list; fhc_list = fhc; fhc->parent = central_bus; - fp = dp->child; - while (fp) { - if (!strcmp(fp->name, "fhc")) - break; - fp = fp->sibling; - } - if (!fp) + fnode = prom_searchsiblings(prom_getchild(cnode), "fhc"); + if (fnode == 0 || fnode == -1) central_probe_failure(__LINE__); - fhc->prom_node = fp; - fhc_ranges_init(fhc); + fhc->prom_node = fnode; + prom_getstring(fnode, "name", namebuf, sizeof(namebuf)); + strcpy(fhc->prom_name, namebuf); + + fhc_ranges_init(fnode, fhc); /* Now, map in FHC register set. */ - pr = of_get_property(fp, "reg", NULL); - if (!pr) + if (prom_getproperty(fnode, "reg", (char *)&fpregs[0], sizeof(fpregs)) == -1) central_probe_failure(__LINE__); - memcpy(fpregs, pr, sizeof(fpregs)); apply_central_ranges(central_bus, &fpregs[0], 6); @@ -365,7 +366,7 @@ void central_probe(void) fhc->jtag_master = 0; /* Attach the clock board registers for CENTRAL. */ - probe_clock_board(central_bus, fhc, fp); + probe_clock_board(central_bus, fhc, cnode, fnode); err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID); printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n", diff --git a/trunk/arch/sparc64/kernel/chmc.c b/trunk/arch/sparc64/kernel/chmc.c index 259f37e516f5..97cf912f0853 100644 --- a/trunk/arch/sparc64/kernel/chmc.c +++ b/trunk/arch/sparc64/kernel/chmc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #define CHMCTRL_NDGRPS 2 @@ -68,6 +67,7 @@ struct bank_info { struct mctrl_info { struct list_head list; int portid; + int index; struct obp_mem_layout layout_prop; int layout_size; @@ -339,13 +339,12 @@ static void fetch_decode_regs(struct mctrl_info *mp) read_mcreg(mp, CHMCTRL_DECODE4)); } -static int init_one_mctrl(struct device_node *dp) +static int init_one_mctrl(int node, int index) { struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); - int portid = of_getintprop_default(dp, "portid", -1); - struct linux_prom64_registers *regs; - void *pval; - int len; + int portid = prom_getintdefault(node, "portid", -1); + struct linux_prom64_registers p_reg_prop; + int t; if (!mp) return -1; @@ -354,21 +353,24 @@ static int init_one_mctrl(struct device_node *dp) goto fail; mp->portid = portid; - pval = of_get_property(dp, "memory-layout", &len); - mp->layout_size = len; - if (!pval) + mp->layout_size = prom_getproplen(node, "memory-layout"); + if (mp->layout_size < 0) mp->layout_size = 0; - else { - if (mp->layout_size > sizeof(mp->layout_prop)) - goto fail; - memcpy(&mp->layout_prop, pval, len); - } + if (mp->layout_size > sizeof(mp->layout_prop)) + goto fail; - regs = of_get_property(dp, "reg", NULL); - if (!regs || regs->reg_size != 0x48) + if (mp->layout_size > 0) + prom_getproperty(node, "memory-layout", + (char *) &mp->layout_prop, + mp->layout_size); + + t = prom_getproperty(node, "reg", + (char *) &p_reg_prop, + sizeof(p_reg_prop)); + if (t < 0 || p_reg_prop.reg_size != 0x48) goto fail; - mp->regs = ioremap(regs->phys_addr, regs->reg_size); + mp->regs = ioremap(p_reg_prop.phys_addr, p_reg_prop.reg_size); if (mp->regs == NULL) goto fail; @@ -382,11 +384,13 @@ static int init_one_mctrl(struct device_node *dp) fetch_decode_regs(mp); + mp->index = index; + list_add(&mp->list, &mctrl_list); /* Report the device. */ - printk(KERN_INFO "%s: US3 memory controller at %p [%s]\n", - dp->full_name, + printk(KERN_INFO "chmc%d: US3 memory controller at %p [%s]\n", + mp->index, mp->regs, (mp->layout_size ? "ACTIVE" : "INACTIVE")); return 0; @@ -400,19 +404,34 @@ static int init_one_mctrl(struct device_node *dp) return -1; } +static int __init probe_for_string(char *name, int index) +{ + int node = prom_getchild(prom_root_node); + + while ((node = prom_searchsiblings(node, name)) != 0) { + int ret = init_one_mctrl(node, index); + + if (!ret) + index++; + + node = prom_getsibling(node); + if (!node) + break; + } + + return index; +} + static int __init chmc_init(void) { - struct device_node *dp; + int index; /* This driver is only for cheetah platforms. */ if (tlb_type != cheetah && tlb_type != cheetah_plus) return -ENODEV; - for_each_node_by_name(dp, "memory-controller") - init_one_mctrl(dp); - - for_each_node_by_name(dp, "mc-us3") - init_one_mctrl(dp); + index = probe_for_string("memory-controller", 0); + index = probe_for_string("mc-us3", index); return 0; } diff --git a/trunk/arch/sparc64/kernel/devices.c b/trunk/arch/sparc64/kernel/devices.c index 389301c95cb2..0dd95ae50e12 100644 --- a/trunk/arch/sparc64/kernel/devices.c +++ b/trunk/arch/sparc64/kernel/devices.c @@ -33,7 +33,7 @@ extern void cpu_probe(void); extern void central_probe(void); u32 sun4v_vdev_devhandle; -struct device_node *sun4v_vdev_root; +int sun4v_vdev_root; struct vdev_intmap { unsigned int phys; @@ -50,68 +50,102 @@ struct vdev_intmask { static struct vdev_intmap *vdev_intmap; static int vdev_num_intmap; -static struct vdev_intmask *vdev_intmask; +static struct vdev_intmask vdev_intmask; static void __init sun4v_virtual_device_probe(void) { - struct linux_prom64_registers *regs; - struct property *prop; - struct device_node *dp; - int sz; + struct linux_prom64_registers regs; + struct vdev_intmap *ip; + int node, sz, err; if (tlb_type != hypervisor) return; - dp = of_find_node_by_name(NULL, "virtual-devices"); - if (!dp) { + node = prom_getchild(prom_root_node); + node = prom_searchsiblings(node, "virtual-devices"); + if (!node) { prom_printf("SUN4V: Fatal error, no virtual-devices node.\n"); prom_halt(); } - sun4v_vdev_root = dp; + sun4v_vdev_root = node; - prop = of_find_property(dp, "reg", NULL); - regs = prop->value; - sun4v_vdev_devhandle = (regs[0].phys_addr >> 32UL) & 0x0fffffff; + prom_getproperty(node, "reg", (char *)®s, sizeof(regs)); + sun4v_vdev_devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; - prop = of_find_property(dp, "interrupt-map", &sz); - vdev_intmap = prop->value; - vdev_num_intmap = sz / sizeof(struct vdev_intmap); + sz = prom_getproplen(node, "interrupt-map"); + if (sz <= 0) { + prom_printf("SUN4V: Error, no vdev interrupt-map.\n"); + prom_halt(); + } + + if ((sz % sizeof(*ip)) != 0) { + prom_printf("SUN4V: Bogus interrupt-map property size %d\n", + sz); + prom_halt(); + } + + vdev_intmap = ip = alloc_bootmem_low_pages(sz); + if (!vdev_intmap) { + prom_printf("SUN4V: Error, cannot allocate vdev_intmap.\n"); + prom_halt(); + } + + err = prom_getproperty(node, "interrupt-map", (char *) ip, sz); + if (err == -1) { + prom_printf("SUN4V: Fatal error, no vdev interrupt-map.\n"); + prom_halt(); + } + if (err != sz) { + prom_printf("SUN4V: Inconsistent interrupt-map size, " + "proplen(%d) vs getprop(%d).\n", sz,err); + prom_halt(); + } + + vdev_num_intmap = err / sizeof(*ip); - prop = of_find_property(dp, "interrupt-map-mask", NULL); - vdev_intmask = prop->value; + err = prom_getproperty(node, "interrupt-map-mask", + (char *) &vdev_intmask, + sizeof(vdev_intmask)); + if (err <= 0) { + prom_printf("SUN4V: Fatal error, no vdev " + "interrupt-map-mask.\n"); + prom_halt(); + } + if (err % sizeof(vdev_intmask)) { + prom_printf("SUN4V: Bogus interrupt-map-mask " + "property size %d\n", err); + prom_halt(); + } - printk("%s: Virtual Device Bus devhandle[%x]\n", - dp->full_name, sun4v_vdev_devhandle); + printk("SUN4V: virtual-devices devhandle[%x]\n", + sun4v_vdev_devhandle); } -unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node) +unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node) { - struct property *prop; unsigned int irq, reg; - int i; + int err, i; - prop = of_find_property(dev_node, "interrupts", NULL); - if (!prop) { + err = prom_getproperty(dev_node, "interrupts", + (char *) &irq, sizeof(irq)); + if (err <= 0) { printk("VDEV: Cannot get \"interrupts\" " - "property for OBP node %s\n", - dev_node->full_name); + "property for OBP node %x\n", dev_node); return 0; } - irq = *(unsigned int *) prop->value; - prop = of_find_property(dev_node, "reg", NULL); - if (!prop) { + err = prom_getproperty(dev_node, "reg", + (char *) ®, sizeof(reg)); + if (err <= 0) { printk("VDEV: Cannot get \"reg\" " - "property for OBP node %s\n", - dev_node->full_name); + "property for OBP node %x\n", dev_node); return 0; } - reg = *(unsigned int *) prop->value; for (i = 0; i < vdev_num_intmap; i++) { - if (vdev_intmap[i].phys == (reg & vdev_intmask->phys) && - vdev_intmap[i].irq == (irq & vdev_intmask->interrupt)) { + if (vdev_intmap[i].phys == (reg & vdev_intmask.phys) && + vdev_intmap[i].irq == (irq & vdev_intmask.interrupt)) { irq = vdev_intmap[i].cinterrupt; break; } @@ -119,7 +153,7 @@ unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node) if (i == vdev_num_intmap) { printk("VDEV: No matching interrupt map entry " - "for OBP node %s\n", dev_node->full_name); + "for OBP node %x\n", dev_node); return 0; } @@ -133,44 +167,38 @@ static const char *cpu_mid_prop(void) return "portid"; } -static int get_cpu_mid(struct device_node *dp) +static int get_cpu_mid(int prom_node) { - struct property *prop; - if (tlb_type == hypervisor) { - struct linux_prom64_registers *reg; - int len; + struct linux_prom64_registers reg; - prop = of_find_property(dp, "cpuid", &len); - if (prop && len == 4) - return *(int *) prop->value; + if (prom_getproplen(prom_node, "cpuid") == 4) + return prom_getintdefault(prom_node, "cpuid", 0); - prop = of_find_property(dp, "reg", NULL); - reg = prop->value; - return (reg[0].phys_addr >> 32) & 0x0fffffffUL; + prom_getproperty(prom_node, "reg", (char *) ®, sizeof(reg)); + return (reg.phys_addr >> 32) & 0x0fffffffUL; } else { const char *prop_name = cpu_mid_prop(); - prop = of_find_property(dp, prop_name, NULL); - if (prop) - return *(int *) prop->value; - return 0; + return prom_getintdefault(prom_node, prop_name, 0); } } -static int check_cpu_node(struct device_node *dp, int *cur_inst, - int (*compare)(struct device_node *, int, void *), - void *compare_arg, - struct device_node **dev_node, int *mid) +static int check_cpu_node(int nd, int *cur_inst, + int (*compare)(int, int, void *), void *compare_arg, + int *prom_node, int *mid) { - if (strcmp(dp->type, "cpu")) + char node_str[128]; + + prom_getstring(nd, "device_type", node_str, sizeof(node_str)); + if (strcmp(node_str, "cpu")) return -ENODEV; - if (!compare(dp, *cur_inst, compare_arg)) { - if (dev_node) - *dev_node = dp; + if (!compare(nd, *cur_inst, compare_arg)) { + if (prom_node) + *prom_node = nd; if (mid) - *mid = get_cpu_mid(dp); + *mid = get_cpu_mid(nd); return 0; } @@ -179,18 +207,25 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst, return -ENODEV; } -static int __cpu_find_by(int (*compare)(struct device_node *, int, void *), - void *compare_arg, - struct device_node **dev_node, int *mid) +static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, + int *prom_node, int *mid) { - struct device_node *dp; - int cur_inst; + int nd, cur_inst, err; + nd = prom_root_node; cur_inst = 0; - for_each_node_by_type(dp, "cpu") { - int err = check_cpu_node(dp, &cur_inst, - compare, compare_arg, - dev_node, mid); + + err = check_cpu_node(nd, &cur_inst, + compare, compare_arg, + prom_node, mid); + if (err == 0) + return 0; + + nd = prom_getchild(nd); + while ((nd = prom_getsibling(nd)) != 0) { + err = check_cpu_node(nd, &cur_inst, + compare, compare_arg, + prom_node, mid); if (err == 0) return 0; } @@ -198,7 +233,7 @@ static int __cpu_find_by(int (*compare)(struct device_node *, int, void *), return -ENODEV; } -static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg) +static int cpu_instance_compare(int nd, int instance, void *_arg) { int desired_instance = (int) (long) _arg; @@ -207,27 +242,27 @@ static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg return -ENODEV; } -int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid) +int cpu_find_by_instance(int instance, int *prom_node, int *mid) { return __cpu_find_by(cpu_instance_compare, (void *)(long)instance, - dev_node, mid); + prom_node, mid); } -static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg) +static int cpu_mid_compare(int nd, int instance, void *_arg) { int desired_mid = (int) (long) _arg; int this_mid; - this_mid = get_cpu_mid(dp); + this_mid = get_cpu_mid(nd); if (this_mid == desired_mid) return 0; return -ENODEV; } -int cpu_find_by_mid(int mid, struct device_node **dev_node) +int cpu_find_by_mid(int mid, int *prom_node) { return __cpu_find_by(cpu_mid_compare, (void *)(long)mid, - dev_node, NULL); + prom_node, NULL); } void __init device_scan(void) @@ -239,47 +274,50 @@ void __init device_scan(void) #ifndef CONFIG_SMP { - struct device_node *dp; - int err, def; + int err, cpu_node, def; - err = cpu_find_by_instance(0, &dp, NULL); + err = cpu_find_by_instance(0, &cpu_node, NULL); if (err) { prom_printf("No cpu nodes, cannot continue\n"); prom_halt(); } - cpu_data(0).clock_tick = - of_getintprop_default(dp, "clock-frequency", 0); + cpu_data(0).clock_tick = prom_getintdefault(cpu_node, + "clock-frequency", + 0); def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024)); - cpu_data(0).dcache_size = of_getintprop_default(dp, - "dcache-size", - def); + cpu_data(0).dcache_size = prom_getintdefault(cpu_node, + "dcache-size", + def); def = 32; cpu_data(0).dcache_line_size = - of_getintprop_default(dp, "dcache-line-size", def); + prom_getintdefault(cpu_node, "dcache-line-size", + def); def = 16 * 1024; - cpu_data(0).icache_size = of_getintprop_default(dp, - "icache-size", - def); + cpu_data(0).icache_size = prom_getintdefault(cpu_node, + "icache-size", + def); def = 32; cpu_data(0).icache_line_size = - of_getintprop_default(dp, "icache-line-size", def); + prom_getintdefault(cpu_node, "icache-line-size", + def); def = ((tlb_type == hypervisor) ? (3 * 1024 * 1024) : (4 * 1024 * 1024)); - cpu_data(0).ecache_size = of_getintprop_default(dp, - "ecache-size", - def); + cpu_data(0).ecache_size = prom_getintdefault(cpu_node, + "ecache-size", + def); def = 64; cpu_data(0).ecache_line_size = - of_getintprop_default(dp, "ecache-line-size", def); + prom_getintdefault(cpu_node, "ecache-line-size", + def); printk("CPU[0]: Caches " "D[sz(%d):line_sz(%d)] " "I[sz(%d):line_sz(%d)] " diff --git a/trunk/arch/sparc64/kernel/ebus.c b/trunk/arch/sparc64/kernel/ebus.c index 98e0a8cbeecd..c69504aa638f 100644 --- a/trunk/arch/sparc64/kernel/ebus.c +++ b/trunk/arch/sparc64/kernel/ebus.c @@ -269,6 +269,10 @@ EXPORT_SYMBOL(ebus_dma_enable); struct linux_ebus *ebus_chain = NULL; +#ifdef CONFIG_SUN_AUXIO +extern void auxio_probe(void); +#endif + static inline void *ebus_alloc(size_t size) { void *mem; @@ -279,55 +283,77 @@ static inline void *ebus_alloc(size_t size) return mem; } +static void __init ebus_ranges_init(struct linux_ebus *ebus) +{ + int success; + + ebus->num_ebus_ranges = 0; + success = prom_getproperty(ebus->prom_node, "ranges", + (char *)ebus->ebus_ranges, + sizeof(ebus->ebus_ranges)); + if (success != -1) + ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges)); +} + +static void __init ebus_intmap_init(struct linux_ebus *ebus) +{ + int success; + + ebus->num_ebus_intmap = 0; + success = prom_getproperty(ebus->prom_node, "interrupt-map", + (char *)ebus->ebus_intmap, + sizeof(ebus->ebus_intmap)); + if (success == -1) + return; + + ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap)); + + success = prom_getproperty(ebus->prom_node, "interrupt-map-mask", + (char *)&ebus->ebus_intmask, + sizeof(ebus->ebus_intmask)); + if (success == -1) { + prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__); + prom_halt(); + } +} + int __init ebus_intmap_match(struct linux_ebus *ebus, struct linux_prom_registers *reg, int *interrupt) { - struct linux_prom_ebus_intmap *imap; - struct linux_prom_ebus_intmask *imask; unsigned int hi, lo, irq; - int i, len, n_imap; - - imap = of_get_property(ebus->prom_node, "interrupt-map", &len); - if (!imap) - return 0; - n_imap = len / sizeof(imap[0]); + int i; - imask = of_get_property(ebus->prom_node, "interrupt-map-mask", NULL); - if (!imask) + if (!ebus->num_ebus_intmap) return 0; - hi = reg->which_io & imask->phys_hi; - lo = reg->phys_addr & imask->phys_lo; - irq = *interrupt & imask->interrupt; - for (i = 0; i < n_imap; i++) { - if ((imap[i].phys_hi == hi) && - (imap[i].phys_lo == lo) && - (imap[i].interrupt == irq)) { - *interrupt = imap[i].cinterrupt; + hi = reg->which_io & ebus->ebus_intmask.phys_hi; + lo = reg->phys_addr & ebus->ebus_intmask.phys_lo; + irq = *interrupt & ebus->ebus_intmask.interrupt; + for (i = 0; i < ebus->num_ebus_intmap; i++) { + if ((ebus->ebus_intmap[i].phys_hi == hi) && + (ebus->ebus_intmap[i].phys_lo == lo) && + (ebus->ebus_intmap[i].interrupt == irq)) { + *interrupt = ebus->ebus_intmap[i].cinterrupt; return 0; } } return -1; } -void __init fill_ebus_child(struct device_node *dp, - struct linux_prom_registers *preg, - struct linux_ebus_child *dev, - int non_standard_regs) +void __init fill_ebus_child(int node, struct linux_prom_registers *preg, + struct linux_ebus_child *dev, int non_standard_regs) { - int *regs; - int *irqs; + int regs[PROMREG_MAX]; + int irqs[PROMREG_MAX]; int i, len; - dev->prom_node = dp; - printk(" (%s)", dp->name); + dev->prom_node = node; + prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); + printk(" (%s)", dev->prom_name); - regs = of_get_property(dp, "reg", &len); - if (!regs) - dev->num_addrs = 0; - else - dev->num_addrs = len / sizeof(regs[0]); + len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); + dev->num_addrs = len / sizeof(regs[0]); if (non_standard_regs) { /* This is to handle reg properties which are not @@ -344,21 +370,21 @@ void __init fill_ebus_child(struct device_node *dp, int rnum = regs[i]; if (rnum >= dev->parent->num_addrs) { prom_printf("UGH: property for %s was %d, need < %d\n", - dp->name, len, dev->parent->num_addrs); - prom_halt(); + dev->prom_name, len, dev->parent->num_addrs); + panic(__FUNCTION__); } dev->resource[i].start = dev->parent->resource[i].start; dev->resource[i].end = dev->parent->resource[i].end; dev->resource[i].flags = IORESOURCE_MEM; - dev->resource[i].name = dp->name; + dev->resource[i].name = dev->prom_name; } } for (i = 0; i < PROMINTR_MAX; i++) dev->irqs[i] = PCI_IRQ_NONE; - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { + len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); + if ((len == -1) || (len == 0)) { dev->num_irqs = 0; /* * Oh, well, some PROMs don't export interrupts @@ -366,8 +392,8 @@ void __init fill_ebus_child(struct device_node *dp, * * Be smart about PS/2 keyboard and mouse. */ - if (!strcmp(dev->parent->prom_node->name, "8042")) { - if (!strcmp(dev->prom_node->name, "kb_ps2")) { + if (!strcmp(dev->parent->prom_name, "8042")) { + if (!strcmp(dev->prom_name, "kb_ps2")) { dev->num_irqs = 1; dev->irqs[0] = dev->parent->irqs[0]; } else { @@ -397,32 +423,32 @@ void __init fill_ebus_child(struct device_node *dp, static int __init child_regs_nonstandard(struct linux_ebus_device *dev) { - if (!strcmp(dev->prom_node->name, "i2c") || - !strcmp(dev->prom_node->name, "SUNW,lombus")) + if (!strcmp(dev->prom_name, "i2c") || + !strcmp(dev->prom_name, "SUNW,lombus")) return 1; return 0; } -void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) +void __init fill_ebus_device(int node, struct linux_ebus_device *dev) { - struct linux_prom_registers *regs; + struct linux_prom_registers regs[PROMREG_MAX]; struct linux_ebus_child *child; - int *irqs; + int irqs[PROMINTR_MAX]; int i, n, len; - dev->prom_node = dp; - - printk(" [%s", dp->name); + dev->prom_node = node; + prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); + printk(" [%s", dev->prom_name); - regs = of_get_property(dp, "reg", &len); - if (!regs) { + len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); + if (len == -1) { dev->num_addrs = 0; goto probe_interrupts; } if (len % sizeof(struct linux_prom_registers)) { prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", - dev->prom_node->name, len, + dev->prom_name, len, (int)sizeof(struct linux_prom_registers)); prom_halt(); } @@ -440,7 +466,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d dev->resource[i].end = (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); dev->resource[i].flags = IORESOURCE_MEM; - dev->resource[i].name = dev->prom_node->name; + dev->resource[i].name = dev->prom_name; request_resource(&dev->bus->self->resource[n], &dev->resource[i]); } @@ -449,8 +475,8 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d for (i = 0; i < PROMINTR_MAX; i++) dev->irqs[i] = PCI_IRQ_NONE; - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { + len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); + if ((len == -1) || (len == 0)) { dev->num_irqs = 0; } else { dev->num_irqs = len / sizeof(irqs[0]); @@ -471,18 +497,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d } } - dev->ofdev.node = dp; - dev->ofdev.dev.parent = &dev->bus->ofdev.dev; - dev->ofdev.dev.bus = &ebus_bus_type; - strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); - - /* Register with core */ - if (of_device_register(&dev->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dev->ofdev.dev.bus_id); - - dp = dp->child; - if (dp) { + if ((node = prom_getchild(node))) { printk(" ->"); dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); @@ -490,18 +505,18 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d child->next = NULL; child->parent = dev; child->bus = dev->bus; - fill_ebus_child(dp, regs, child, - child_regs_nonstandard(dev)); + fill_ebus_child(node, ®s[0], + child, child_regs_nonstandard(dev)); - while ((dp = dp->sibling) != NULL) { + while ((node = prom_getsibling(node)) != 0) { child->next = ebus_alloc(sizeof(struct linux_ebus_child)); child = child->next; child->next = NULL; child->parent = dev; child->bus = dev->bus; - fill_ebus_child(dp, regs, child, - child_regs_nonstandard(dev)); + fill_ebus_child(node, ®s[0], + child, child_regs_nonstandard(dev)); } } printk("]"); @@ -528,8 +543,7 @@ void __init ebus_init(void) struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; - struct device_node *dp; - int is_rio; + int nd, ebusnd, is_rio; int num_ebus = 0; pdev = find_next_ebus(NULL, &is_rio); @@ -539,22 +553,20 @@ void __init ebus_init(void) } cookie = pdev->sysdata; - dp = cookie->prom_node; + ebusnd = cookie->prom_node; ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); ebus->next = NULL; ebus->is_rio = is_rio; - while (dp) { - struct device_node *child; - + while (ebusnd) { /* SUNW,pci-qfe uses four empty ebuses on it. I think we should not consider them here, as they have half of the properties this code expects and once we do PCI hot-plug, we'd have to tweak with the ebus_chain in the runtime after initialization. -jj */ - if (!dp->child) { + if (!prom_getchild (ebusnd)) { pdev = find_next_ebus(pdev, &is_rio); if (!pdev) { if (ebus == ebus_chain) { @@ -566,29 +578,22 @@ void __init ebus_init(void) } ebus->is_rio = is_rio; cookie = pdev->sysdata; - dp = cookie->prom_node; + ebusnd = cookie->prom_node; continue; } printk("ebus%d:", num_ebus); + prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name)); ebus->index = num_ebus; - ebus->prom_node = dp; + ebus->prom_node = ebusnd; ebus->self = pdev; ebus->parent = pbm = cookie->pbm; - ebus->ofdev.node = dp; - ebus->ofdev.dev.parent = &pdev->dev; - ebus->ofdev.dev.bus = &ebus_bus_type; - strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); + ebus_ranges_init(ebus); + ebus_intmap_init(ebus); - /* Register with core */ - if (of_device_register(&ebus->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - ebus->ofdev.dev.bus_id); - - - child = dp->child; - if (!child) + nd = prom_getchild(ebusnd); + if (!nd) goto next_ebus; ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); @@ -597,16 +602,16 @@ void __init ebus_init(void) dev->next = NULL; dev->children = NULL; dev->bus = ebus; - fill_ebus_device(child, dev); + fill_ebus_device(nd, dev); - while ((child = child->sibling) != NULL) { + while ((nd = prom_getsibling(nd)) != 0) { dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; dev->next = NULL; dev->children = NULL; dev->bus = ebus; - fill_ebus_device(child, dev); + fill_ebus_device(nd, dev); } next_ebus: @@ -617,7 +622,7 @@ void __init ebus_init(void) break; cookie = pdev->sysdata; - dp = cookie->prom_node; + ebusnd = cookie->prom_node; ebus->next = ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; @@ -626,4 +631,8 @@ void __init ebus_init(void) ++num_ebus; } pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */ + +#ifdef CONFIG_SUN_AUXIO + auxio_probe(); +#endif } diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index cc89b06d0178..a8c9dc8d1958 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -563,6 +562,67 @@ void handler_irq(int irq, struct pt_regs *regs) irq_exit(); } +#ifdef CONFIG_BLK_DEV_FD +extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *); + +/* XXX No easy way to include asm/floppy.h XXX */ +extern unsigned char *pdma_vaddr; +extern unsigned long pdma_size; +extern volatile int doing_pdma; +extern unsigned long fdc_status; + +irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) +{ + if (likely(doing_pdma)) { + void __iomem *stat = (void __iomem *) fdc_status; + unsigned char *vaddr = pdma_vaddr; + unsigned long size = pdma_size; + u8 val; + + while (size) { + val = readb(stat); + if (unlikely(!(val & 0x80))) { + pdma_vaddr = vaddr; + pdma_size = size; + return IRQ_HANDLED; + } + if (unlikely(!(val & 0x20))) { + pdma_vaddr = vaddr; + pdma_size = size; + doing_pdma = 0; + goto main_interrupt; + } + if (val & 0x40) { + /* read */ + *vaddr++ = readb(stat + 1); + } else { + unsigned char data = *vaddr++; + + /* write */ + writeb(data, stat + 1); + } + size--; + } + + pdma_vaddr = vaddr; + pdma_size = size; + + /* Send Terminal Count pulse to floppy controller. */ + val = readb(auxio_register); + val |= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); + val &= ~AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); + + doing_pdma = 0; + } + +main_interrupt: + return floppy_interrupt(irq, dev_cookie, regs); +} +EXPORT_SYMBOL(sparc_floppy_irq); +#endif + struct sun5_timer { u64 count0; u64 limit0; @@ -575,29 +635,23 @@ static u64 prom_limit0, prom_limit1; static void map_prom_timers(void) { - struct device_node *dp; - unsigned int *addr; + unsigned int addr[3]; + int tnode, err; /* PROM timer node hangs out in the top level of device siblings... */ - dp = of_find_node_by_path("/"); - dp = dp->child; - while (dp) { - if (!strcmp(dp->name, "counter-timer")) - break; - dp = dp->sibling; - } + tnode = prom_finddevice("/counter-timer"); /* Assume if node is not present, PROM uses different tick mechanism * which we should not care about. */ - if (!dp) { + if (tnode == 0 || tnode == -1) { prom_timers = (struct sun5_timer *) 0; return; } /* If PROM is really using this, it must be mapped by him. */ - addr = of_get_property(dp, "address", NULL); - if (!addr) { + err = prom_getproperty(tnode, "address", (char *)addr, sizeof(addr)); + if (err == -1) { prom_printf("PROM does not have timer mapped, trying to continue.\n"); prom_timers = (struct sun5_timer *) 0; return; diff --git a/trunk/arch/sparc64/kernel/isa.c b/trunk/arch/sparc64/kernel/isa.c index 6f16dee280a8..30862abee611 100644 --- a/trunk/arch/sparc64/kernel/isa.c +++ b/trunk/arch/sparc64/kernel/isa.c @@ -15,19 +15,23 @@ static void __init fatal_err(const char *reason) static void __init report_dev(struct sparc_isa_device *isa_dev, int child) { if (child) - printk(" (%s)", isa_dev->prom_node->name); + printk(" (%s)", isa_dev->prom_name); else - printk(" [%s", isa_dev->prom_node->name); + printk(" [%s", isa_dev->prom_name); } -static struct linux_prom_registers * __init -isa_dev_get_resource(struct sparc_isa_device *isa_dev) +static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev, + struct linux_prom_registers *pregs, + int pregs_size) { - struct linux_prom_registers *pregs; unsigned long base, len; int prop_len; - pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len); + prop_len = prom_getproperty(isa_dev->prom_node, "reg", + (char *) pregs, pregs_size); + + if (prop_len <= 0) + return; /* Only the first one is interesting. */ len = pregs[0].reg_size; @@ -38,12 +42,10 @@ isa_dev_get_resource(struct sparc_isa_device *isa_dev) isa_dev->resource.start = base; isa_dev->resource.end = (base + len - 1UL); isa_dev->resource.flags = IORESOURCE_IO; - isa_dev->resource.name = isa_dev->prom_node->name; + isa_dev->resource.name = isa_dev->prom_name; request_resource(&isa_dev->bus->parent->io_space, &isa_dev->resource); - - return pregs; } /* I can't believe they didn't put a real INO in the isa device @@ -72,30 +74,19 @@ static struct { static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev, struct sparc_isa_bridge *isa_br, int *interrupt, - struct linux_prom_registers *reg) + struct linux_prom_registers *pregs) { - struct linux_prom_ebus_intmap *imap; - struct linux_prom_ebus_intmap *imask; unsigned int hi, lo, irq; - int i, len, n_imap; - - imap = of_get_property(isa_br->prom_node, "interrupt-map", &len); - if (!imap) - return 0; - n_imap = len / sizeof(imap[0]); - - imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL); - if (!imask) - return 0; - - hi = reg->which_io & imask->phys_hi; - lo = reg->phys_addr & imask->phys_lo; - irq = *interrupt & imask->interrupt; - for (i = 0; i < n_imap; i++) { - if ((imap[i].phys_hi == hi) && - (imap[i].phys_lo == lo) && - (imap[i].interrupt == irq)) { - *interrupt = imap[i].cinterrupt; + int i; + + hi = pregs->which_io & isa_br->isa_intmask.phys_hi; + lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo; + irq = *interrupt & isa_br->isa_intmask.interrupt; + for (i = 0; i < isa_br->num_isa_intmap; i++) { + if ((isa_br->isa_intmap[i].phys_hi == hi) && + (isa_br->isa_intmap[i].phys_lo == lo) && + (isa_br->isa_intmap[i].interrupt == irq)) { + *interrupt = isa_br->isa_intmap[i].cinterrupt; return 0; } } @@ -107,8 +98,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, { int irq_prop; - irq_prop = of_getintprop_default(isa_dev->prom_node, - "interrupts", -1); + irq_prop = prom_getintdefault(isa_dev->prom_node, + "interrupts", -1); if (irq_prop <= 0) { goto no_irq; } else { @@ -116,8 +107,7 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, struct pci_pbm_info *pbm; int i; - if (of_find_property(isa_dev->bus->prom_node, - "interrupt-map", NULL)) { + if (isa_dev->bus->num_isa_intmap) { if (!isa_dev_get_irq_using_imap(isa_dev, isa_dev->bus, &irq_prop, @@ -151,15 +141,16 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) { - struct device_node *dp = parent_isa_dev->prom_node->child; + int node = prom_getchild(parent_isa_dev->prom_node); - if (!dp) + if (node == 0) return; printk(" ->"); - while (dp) { - struct linux_prom_registers *regs; + while (node != 0) { + struct linux_prom_registers regs[PROMREG_MAX]; struct sparc_isa_device *isa_dev; + int prop_len; isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { @@ -174,46 +165,49 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) parent_isa_dev->child = isa_dev; isa_dev->bus = parent_isa_dev->bus; - isa_dev->prom_node = dp; + isa_dev->prom_node = node; + prop_len = prom_getproperty(node, "name", + (char *) isa_dev->prom_name, + sizeof(isa_dev->prom_name)); + if (prop_len <= 0) { + fatal_err("cannot get child isa_dev OBP node name"); + prom_halt(); + } - regs = isa_dev_get_resource(isa_dev); + prop_len = prom_getproperty(node, "compatible", + (char *) isa_dev->compatible, + sizeof(isa_dev->compatible)); + + /* Not having this is OK. */ + if (prop_len <= 0) + isa_dev->compatible[0] = '\0'; + + isa_dev_get_resource(isa_dev, regs, sizeof(regs)); isa_dev_get_irq(isa_dev, regs); report_dev(isa_dev, 1); - dp = dp->sibling; + node = prom_getsibling(node); } } static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) { - struct device_node *dp = isa_br->prom_node->child; + int node = prom_getchild(isa_br->prom_node); - while (dp) { - struct linux_prom_registers *regs; + while (node != 0) { + struct linux_prom_registers regs[PROMREG_MAX]; struct sparc_isa_device *isa_dev; + int prop_len; isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { - printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); - return; + fatal_err("cannot allocate isa_dev"); + prom_halt(); } memset(isa_dev, 0, sizeof(*isa_dev)); - isa_dev->ofdev.node = dp; - isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; - isa_dev->ofdev.dev.bus = &isa_bus_type; - strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name); - - /* Register with core */ - if (of_device_register(&isa_dev->ofdev) != 0) { - printk(KERN_DEBUG "isa: device registration error for %s!\n", - isa_dev->ofdev.dev.bus_id); - kfree(isa_dev); - goto next_sibling; - } - /* Link it in. */ isa_dev->next = NULL; if (isa_br->devices == NULL) { @@ -228,9 +222,24 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) } isa_dev->bus = isa_br; - isa_dev->prom_node = dp; + isa_dev->prom_node = node; + prop_len = prom_getproperty(node, "name", + (char *) isa_dev->prom_name, + sizeof(isa_dev->prom_name)); + if (prop_len <= 0) { + fatal_err("cannot get isa_dev OBP node name"); + prom_halt(); + } + + prop_len = prom_getproperty(node, "compatible", + (char *) isa_dev->compatible, + sizeof(isa_dev->compatible)); - regs = isa_dev_get_resource(isa_dev); + /* Not having this is OK. */ + if (prop_len <= 0) + isa_dev->compatible[0] = '\0'; + + isa_dev_get_resource(isa_dev, regs, sizeof(regs)); isa_dev_get_irq(isa_dev, regs); report_dev(isa_dev, 0); @@ -239,8 +248,7 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) printk("]"); - next_sibling: - dp = dp->sibling; + node = prom_getsibling(node); } } @@ -258,7 +266,7 @@ void __init isa_init(void) struct pcidev_cookie *pdev_cookie; struct pci_pbm_info *pbm; struct sparc_isa_bridge *isa_br; - struct device_node *dp; + int prop_len; pdev_cookie = pdev->sysdata; if (!pdev_cookie) { @@ -267,29 +275,15 @@ void __init isa_init(void) continue; } pbm = pdev_cookie->pbm; - dp = pdev_cookie->prom_node; isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); if (!isa_br) { - printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); - return; + fatal_err("cannot allocate sparc_isa_bridge"); + prom_halt(); } memset(isa_br, 0, sizeof(*isa_br)); - isa_br->ofdev.node = dp; - isa_br->ofdev.dev.parent = &pdev->dev; - isa_br->ofdev.dev.bus = &isa_bus_type; - strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name); - - /* Register with core */ - if (of_device_register(&isa_br->ofdev) != 0) { - printk(KERN_DEBUG "isa: device registration error for %s!\n", - isa_br->ofdev.dev.bus_id); - kfree(isa_br); - return; - } - /* Link it in. */ isa_br->next = isa_chain; isa_chain = isa_br; @@ -298,6 +292,33 @@ void __init isa_init(void) isa_br->self = pdev; isa_br->index = index++; isa_br->prom_node = pdev_cookie->prom_node; + strncpy(isa_br->prom_name, pdev_cookie->prom_name, + sizeof(isa_br->prom_name)); + + prop_len = prom_getproperty(isa_br->prom_node, + "ranges", + (char *) isa_br->isa_ranges, + sizeof(isa_br->isa_ranges)); + if (prop_len <= 0) + isa_br->num_isa_ranges = 0; + else + isa_br->num_isa_ranges = + (prop_len / sizeof(struct linux_prom_isa_ranges)); + + prop_len = prom_getproperty(isa_br->prom_node, + "interrupt-map", + (char *) isa_br->isa_intmap, + sizeof(isa_br->isa_intmap)); + if (prop_len <= 0) + isa_br->num_isa_intmap = 0; + else + isa_br->num_isa_intmap = + (prop_len / sizeof(struct linux_prom_isa_intmap)); + + prop_len = prom_getproperty(isa_br->prom_node, + "interrupt-map-mask", + (char *) &(isa_br->isa_intmask), + sizeof(isa_br->isa_intmask)); printk("isa%d:", isa_br->index); diff --git a/trunk/arch/sparc64/kernel/of_device.c b/trunk/arch/sparc64/kernel/of_device.c deleted file mode 100644 index 768475bbce82..000000000000 --- a/trunk/arch/sparc64/kernel/of_device.c +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in - * @dev: the of device structure to match against - * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. - */ -const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) -{ - if (!dev->node) - return NULL; - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); - if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); - if (matches->compatible[0]) - match &= of_device_is_compatible(dev->node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; -} - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_device_id * matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; -} - -struct of_device *of_dev_get(struct of_device *dev) -{ - struct device *tmp; - - if (!dev) - return NULL; - tmp = get_device(&dev->dev); - if (tmp) - return to_of_device(tmp); - else - return NULL; -} - -void of_dev_put(struct of_device *dev) -{ - if (dev) - put_device(&dev->dev); -} - - -static int of_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_device_remove(struct device *dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_device_resume(struct device * dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -#ifdef CONFIG_PCI -struct bus_type isa_bus_type = { - .name = "isa", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; -EXPORT_SYMBOL(isa_bus_type); - -struct bus_type ebus_bus_type = { - .name = "ebus", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; -EXPORT_SYMBOL(ebus_bus_type); -#endif - -#ifdef CONFIG_SBUS -struct bus_type sbus_bus_type = { - .name = "sbus", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; -EXPORT_SYMBOL(sbus_bus_type); -#endif - -static int __init of_bus_driver_init(void) -{ - int err = 0; - -#ifdef CONFIG_PCI - if (!err) - err = bus_register(&isa_bus_type); - if (!err) - err = bus_register(&ebus_bus_type); -#endif -#ifdef CONFIG_SBUS - if (!err) - err = bus_register(&sbus_bus_type); -#endif - return 0; -} - -postcore_initcall(of_bus_driver_init); - -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* initialize common driver fields */ - drv->driver.name = drv->name; - drv->driver.bus = bus; - - /* register with core */ - return driver_register(&drv->driver); -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - - -static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); -} - -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); - -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct of_device *ofdev; - - ofdev = to_of_device(dev); - - kfree(ofdev); -} - -int of_device_register(struct of_device *ofdev) -{ - int rc; - - BUG_ON(ofdev->node == NULL); - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; -} - -void of_device_unregister(struct of_device *ofdev) -{ - device_remove_file(&ofdev->dev, &dev_attr_devspec); - device_unregister(&ofdev->dev); -} - -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent, - struct bus_type *bus) -{ - struct of_device *dev; - - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->dev.parent = parent; - dev->dev.bus = bus; - dev->dev.release = of_release_dev; - - strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); - - if (of_device_register(dev) != 0) { - kfree(dev); - return NULL; - } - - return dev; -} - -EXPORT_SYMBOL(of_match_device); -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); -EXPORT_SYMBOL(of_device_register); -EXPORT_SYMBOL(of_device_unregister); -EXPORT_SYMBOL(of_dev_get); -EXPORT_SYMBOL(of_dev_put); -EXPORT_SYMBOL(of_platform_device_create); -EXPORT_SYMBOL(of_release_dev); diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index 6c9e3e94abaa..9472580a4319 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -22,7 +22,6 @@ #include #include #include -#include unsigned long pci_memspace_mask = 0xffffffffUL; @@ -178,16 +177,16 @@ void pci_config_write32(u32 *addr, u32 val) } /* Probe for all PCI controllers in the system. */ -extern void sabre_init(struct device_node *, const char *); -extern void psycho_init(struct device_node *, const char *); -extern void schizo_init(struct device_node *, const char *); -extern void schizo_plus_init(struct device_node *, const char *); -extern void tomatillo_init(struct device_node *, const char *); -extern void sun4v_pci_init(struct device_node *, const char *); +extern void sabre_init(int, char *); +extern void psycho_init(int, char *); +extern void schizo_init(int, char *); +extern void schizo_plus_init(int, char *); +extern void tomatillo_init(int, char *); +extern void sun4v_pci_init(int, char *); static struct { char *model_name; - void (*init)(struct device_node *, const char *); + void (*init)(int, char *); } pci_controller_table[] __initdata = { { "SUNW,sabre", sabre_init }, { "pci108e,a000", sabre_init }, @@ -205,7 +204,7 @@ static struct { #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) -static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) +static int __init pci_controller_init(char *model_name, int namelen, int node) { int i; @@ -213,15 +212,18 @@ static int __init pci_controller_init(const char *model_name, int namelen, struc if (!strncmp(model_name, pci_controller_table[i].model_name, namelen)) { - pci_controller_table[i].init(dp, model_name); + pci_controller_table[i].init(node, model_name); return 1; } } + printk("PCI: Warning unknown controller, model name [%s]\n", + model_name); + printk("PCI: Ignoring controller...\n"); return 0; } -static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) +static int __init pci_is_controller(char *model_name, int namelen, int node) { int i; @@ -235,35 +237,36 @@ static int __init pci_is_controller(const char *model_name, int namelen, struct return 0; } -static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) +static int __init pci_controller_scan(int (*handler)(char *, int, int)) { - struct device_node *dp; + char namebuf[64]; + int node; int count = 0; - for_each_node_by_name(dp, "pci") { - struct property *prop; + node = prom_getchild(prom_root_node); + while ((node = prom_searchsiblings(node, "pci")) != 0) { int len; - prop = of_find_property(dp, "model", &len); - if (!prop) - prop = of_find_property(dp, "compatible", &len); - - if (prop) { - const char *model = prop->value; + if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 || + (len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) { int item_len = 0; /* Our value may be a multi-valued string in the * case of some compatible properties. For sanity, - * only try the first one. - */ - while (model[item_len] && len) { + * only try the first one. */ + + while (namebuf[item_len] && len) { len--; item_len++; } - if (handler(model, item_len, dp)) + if (handler(namebuf, item_len, node)) count++; } + + node = prom_getsibling(node); + if (!node) + break; } return count; @@ -406,14 +409,8 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, } EXPORT_SYMBOL(pcibios_bus_to_resource); -extern int pci_irq_verbose; - char * __init pcibios_setup(char *str) { - if (!strcmp(str, "irq_verbose")) { - pci_irq_verbose = 1; - return NULL; - } return str; } diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index b06a2955bf5f..33dedb1aacd4 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -9,12 +9,6 @@ #include #include -#include - -#include "pci_impl.h" - -/* Pass "pci=irq_verbose" on the kernel command line to enable this. */ -int pci_irq_verbose; /* Fix self device of BUS and hook it into BUS->self. * The pci_scan_bus does not do this for the host bridge. @@ -34,14 +28,16 @@ void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) prom_halt(); } -/* Find the OBP PROM device tree node for a PCI device. */ -static struct device_node * __init -find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev, - struct device_node *bus_node, - struct linux_prom_pci_registers **pregs, - int *nregs) +/* Find the OBP PROM device tree node for a PCI device. + * Return zero if not found. + */ +static int __init find_device_prom_node(struct pci_pbm_info *pbm, + struct pci_dev *pdev, + int bus_prom_node, + struct linux_prom_pci_registers *pregs, + int *nregs) { - struct device_node *dp; + int node; *nregs = 0; @@ -58,30 +54,24 @@ find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev, pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || pdev->device == PCI_DEVICE_ID_SUN_SABRE || pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) - return bus_node; - - dp = bus_node->child; - while (dp) { - struct linux_prom_pci_registers *regs; - struct property *prop; - int len; - - prop = of_find_property(dp, "reg", &len); - if (!prop) + return bus_prom_node; + + node = prom_getchild(bus_prom_node); + while (node != 0) { + int err = prom_getproperty(node, "reg", + (char *)pregs, + sizeof(*pregs) * PROMREG_MAX); + if (err == 0 || err == -1) goto do_next_sibling; - - regs = prop->value; - if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { - *pregs = regs; - *nregs = len / sizeof(struct linux_prom_pci_registers); - return dp; + if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { + *nregs = err / sizeof(*pregs); + return node; } do_next_sibling: - dp = dp->sibling; + node = prom_getsibling(node); } - - return NULL; + return 0; } /* Older versions of OBP on PCI systems encode 64-bit MEM @@ -138,17 +128,15 @@ static void __init fixup_obp_assignments(struct pci_dev *pdev, */ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, struct pci_dev *pdev, - struct device_node *bus_node) + int bus_prom_node) { - struct linux_prom_pci_registers *pregs = NULL; + struct linux_prom_pci_registers pregs[PROMREG_MAX]; struct pcidev_cookie *pcp; - struct device_node *dp; - struct property *prop; - int nregs, len; + int device_prom_node, nregs, err; - dp = find_device_prom_node(pbm, pdev, bus_node, - &pregs, &nregs); - if (!dp) { + device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node, + pregs, &nregs); + if (device_prom_node == 0) { /* If it is not in the OBP device tree then * there must be a damn good reason for it. * @@ -162,43 +150,45 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, return; } - pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC); + pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC); if (pcp == NULL) { prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); prom_halt(); } pcp->pbm = pbm; - pcp->prom_node = dp; - memcpy(pcp->prom_regs, pregs, - nregs * sizeof(struct linux_prom_pci_registers)); + pcp->prom_node = device_prom_node; + memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs)); pcp->num_prom_regs = nregs; - - /* We can't have the pcidev_cookie assignments be just - * direct pointers into the property value, since they - * are potentially modified by the probing process. - */ - prop = of_find_property(dp, "assigned-addresses", &len); - if (!prop) { + err = prom_getproperty(device_prom_node, "name", + pcp->prom_name, sizeof(pcp->prom_name)); + if (err > 0) + pcp->prom_name[err] = 0; + else + pcp->prom_name[0] = 0; + + err = prom_getproperty(device_prom_node, + "assigned-addresses", + (char *)pcp->prom_assignments, + sizeof(pcp->prom_assignments)); + if (err == 0 || err == -1) pcp->num_prom_assignments = 0; - } else { - memcpy(pcp->prom_assignments, prop->value, len); + else pcp->num_prom_assignments = - (len / sizeof(pcp->prom_assignments[0])); - } + (err / sizeof(pcp->prom_assignments[0])); - if (strcmp(dp->name, "ebus") == 0) { - struct linux_prom_ebus_ranges *erng; + if (strcmp(pcp->prom_name, "ebus") == 0) { + struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX]; int iter; /* EBUS is special... */ - prop = of_find_property(dp, "ranges", &len); - if (!prop) { + err = prom_getproperty(device_prom_node, "ranges", + (char *)&erng[0], sizeof(erng)); + if (err == 0 || err == -1) { prom_printf("EBUS: Fatal error, no range property\n"); prom_halt(); } - erng = prop->value; - len = (len / sizeof(erng[0])); - for (iter = 0; iter < len; iter++) { + err = (err / sizeof(erng[0])); + for(iter = 0; iter < err; iter++) { struct linux_prom_ebus_ranges *ep = &erng[iter]; struct linux_prom_pci_registers *ap; @@ -210,7 +200,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, ap->size_hi = 0; ap->size_lo = ep->size; } - pcp->num_prom_assignments = len; + pcp->num_prom_assignments = err; } fixup_obp_assignments(pdev, pcp); @@ -220,7 +210,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, struct pci_pbm_info *pbm, - struct device_node *dp) + int prom_node) { struct pci_dev *pdev, *pdev_next; struct pci_bus *this_pbus, *pbus_next; @@ -228,7 +218,7 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, /* This must be _safe because the cookie fillin routine can delete devices from the tree. */ list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) - pdev_cookie_fillin(pbm, pdev, dp); + pdev_cookie_fillin(pbm, pdev, prom_node); list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { struct pcidev_cookie *pcp = this_pbus->self->sysdata; @@ -251,6 +241,7 @@ static void __init bad_assignment(struct pci_dev *pdev, if (res) prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", res->start, res->end, res->flags); + prom_printf("Please email this information to davem@redhat.com\n"); if (do_prom_halt) prom_halt(); } @@ -282,7 +273,8 @@ __init get_root_resource(struct linux_prom_pci_registers *ap, return &pbm->mem_space; default: - printk("PCI: What is resource space %x?\n", space); + printk("PCI: What is resource space %x? " + "Tell davem@redhat.com about it!\n", space); return NULL; }; } @@ -564,10 +556,9 @@ static inline unsigned int pci_slot_swivel(struct pci_pbm_info *pbm, ret = ((interrupt - 1 + (PCI_SLOT(pdev->devfn) & 3)) & 3) + 1; - if (pci_irq_verbose) - printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n", - pbm->name, pci_name(toplevel_pdev), pci_name(pdev), - interrupt, PCI_SLOT(pdev->devfn), ret); + printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n", + pbm->name, pci_name(toplevel_pdev), pci_name(pdev), + interrupt, PCI_SLOT(pdev->devfn), ret); return ret; } @@ -577,60 +568,58 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm, struct pci_dev *pbus, struct pci_dev *pdev, unsigned int interrupt, - struct device_node **cnode) + unsigned int *cnode) { - struct linux_prom_pci_intmap *imap; - struct linux_prom_pci_intmask *imask; + struct linux_prom_pci_intmap imap[PROM_PCIIMAP_MAX]; + struct linux_prom_pci_intmask imask; struct pcidev_cookie *pbus_pcp = pbus->sysdata; struct pcidev_cookie *pdev_pcp = pdev->sysdata; struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs; - struct property *prop; int plen, num_imap, i; unsigned int hi, mid, lo, irq, orig_interrupt; *cnode = pbus_pcp->prom_node; - prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen); - if (!prop || + plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map", + (char *) &imap[0], sizeof(imap)); + if (plen <= 0 || (plen % sizeof(struct linux_prom_pci_intmap)) != 0) { printk("%s: Device %s interrupt-map has bad len %d\n", pbm->name, pci_name(pbus), plen); goto no_intmap; } - imap = prop->value; num_imap = plen / sizeof(struct linux_prom_pci_intmap); - prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen); - if (!prop || + plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map-mask", + (char *) &imask, sizeof(imask)); + if (plen <= 0 || (plen % sizeof(struct linux_prom_pci_intmask)) != 0) { printk("%s: Device %s interrupt-map-mask has bad len %d\n", pbm->name, pci_name(pbus), plen); goto no_intmap; } - imask = prop->value; orig_interrupt = interrupt; - hi = pregs->phys_hi & imask->phys_hi; - mid = pregs->phys_mid & imask->phys_mid; - lo = pregs->phys_lo & imask->phys_lo; - irq = interrupt & imask->interrupt; + hi = pregs->phys_hi & imask.phys_hi; + mid = pregs->phys_mid & imask.phys_mid; + lo = pregs->phys_lo & imask.phys_lo; + irq = interrupt & imask.interrupt; for (i = 0; i < num_imap; i++) { if (imap[i].phys_hi == hi && imap[i].phys_mid == mid && imap[i].phys_lo == lo && imap[i].interrupt == irq) { - *cnode = of_find_node_by_phandle(imap[i].cnode); + *cnode = imap[i].cnode; interrupt = imap[i].cinterrupt; } } - if (pci_irq_verbose) - printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n", - pbm->name, pci_name(toplevel_pdev), - pci_name(pbus), pci_name(pdev), - orig_interrupt, interrupt); + printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n", + pbm->name, pci_name(toplevel_pdev), + pci_name(pbus), pci_name(pdev), + orig_interrupt, interrupt); no_intmap: return interrupt; @@ -644,22 +633,21 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm, * all interrupt translations are complete, else we should use that node's * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt. */ -static struct device_node * __init -pci_intmap_match_to_root(struct pci_pbm_info *pbm, - struct pci_dev *pdev, - unsigned int *interrupt) +static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm, + struct pci_dev *pdev, + unsigned int *interrupt) { struct pci_dev *toplevel_pdev = pdev; struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata; - struct device_node *cnode = toplevel_pcp->prom_node; + unsigned int cnode = toplevel_pcp->prom_node; while (pdev->bus->number != pbm->pci_first_busno) { struct pci_dev *pbus = pdev->bus->self; struct pcidev_cookie *pcp = pbus->sysdata; - struct property *prop; + int plen; - prop = of_find_property(pcp->prom_node, "interrupt-map", NULL); - if (!prop) { + plen = prom_getproplen(pcp->prom_node, "interrupt-map"); + if (plen <= 0) { *interrupt = pci_slot_swivel(pbm, toplevel_pdev, pdev, *interrupt); cnode = pcp->prom_node; @@ -687,29 +675,26 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt { struct pcidev_cookie *dev_pcp = pdev->sysdata; struct pci_pbm_info *pbm = dev_pcp->pbm; - struct linux_prom_pci_registers *reg; - struct device_node *cnode; - struct property *prop; + struct linux_prom_pci_registers reg[PROMREG_MAX]; unsigned int hi, mid, lo, irq; - int i, plen; + int i, cnode, plen; cnode = pci_intmap_match_to_root(pbm, pdev, interrupt); if (cnode == pbm->prom_node) goto success; - prop = of_find_property(cnode, "reg", &plen); - if (!prop || + plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg)); + if (plen <= 0 || (plen % sizeof(struct linux_prom_pci_registers)) != 0) { - printk("%s: OBP node %s reg property has bad len %d\n", - pbm->name, cnode->full_name, plen); + printk("%s: OBP node %x reg property has bad len %d\n", + pbm->name, cnode, plen); goto fail; } - reg = prop->value; - hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi; - mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid; - lo = reg[0].phys_lo & pbm->pbm_intmask->phys_lo; - irq = *interrupt & pbm->pbm_intmask->interrupt; + hi = reg[0].phys_hi & pbm->pbm_intmask.phys_hi; + mid = reg[0].phys_mid & pbm->pbm_intmask.phys_mid; + lo = reg[0].phys_lo & pbm->pbm_intmask.phys_lo; + irq = *interrupt & pbm->pbm_intmask.interrupt; for (i = 0; i < pbm->num_pbm_intmap; i++) { struct linux_prom_pci_intmap *intmap; @@ -729,11 +714,9 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt return 0; success: - if (pci_irq_verbose) - printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n", - pbm->name, - pdev->bus->number, PCI_SLOT(pdev->devfn), - *interrupt); + printk("PCI-IRQ: Routing bus[%2x] slot[%2x] to INO[%02x]\n", + pdev->bus->number, PCI_SLOT(pdev->devfn), + *interrupt); return 1; } @@ -744,8 +727,8 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev) struct pci_controller_info *p = pbm->parent; unsigned int portid = pbm->portid; unsigned int prom_irq; - struct device_node *dp = pcp->prom_node; - struct property *prop; + int prom_node = pcp->prom_node; + int err; /* If this is an empty EBUS device, sometimes OBP fails to * give it a valid fully specified interrupts property. @@ -756,17 +739,17 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev) */ if (pdev->vendor == PCI_VENDOR_ID_SUN && pdev->device == PCI_DEVICE_ID_SUN_EBUS && - !dp->child) { + !prom_getchild(prom_node)) { pdev->irq = 0; return; } - prop = of_find_property(dp, "interrupts", NULL); - if (!prop) { + err = prom_getproperty(prom_node, "interrupts", + (char *)&prom_irq, sizeof(prom_irq)); + if (err == 0 || err == -1) { pdev->irq = 0; return; } - prom_irq = *(unsigned int *) prop->value; if (tlb_type != hypervisor) { /* Fully specified already? */ diff --git a/trunk/arch/sparc64/kernel/pci_impl.h b/trunk/arch/sparc64/kernel/pci_impl.h index 971e2bea30b4..6c3205962544 100644 --- a/trunk/arch/sparc64/kernel/pci_impl.h +++ b/trunk/arch/sparc64/kernel/pci_impl.h @@ -10,7 +10,6 @@ #include #include #include -#include extern struct pci_controller_info *pci_controller_root; @@ -20,7 +19,7 @@ extern int pci_num_controllers; extern void pci_fixup_host_bridge_self(struct pci_bus *pbus); extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus, struct pci_pbm_info *pbm, - struct device_node *prom_node); + int prom_node); extern void pci_record_assignments(struct pci_pbm_info *pbm, struct pci_bus *pbus); extern void pci_assign_unassigned(struct pci_pbm_info *pbm, diff --git a/trunk/arch/sparc64/kernel/pci_psycho.c b/trunk/arch/sparc64/kernel/pci_psycho.c index 5b2261ebda6f..24db22aa9728 100644 --- a/trunk/arch/sparc64/kernel/pci_psycho.c +++ b/trunk/arch/sparc64/kernel/pci_psycho.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -1292,12 +1291,11 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p, #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL static void psycho_pbm_init(struct pci_controller_info *p, - struct device_node *dp, int is_pbm_a) + int prom_node, int is_pbm_a) { - unsigned int *busrange; - struct property *prop; + unsigned int busrange[2]; struct pci_pbm_info *pbm; - int len; + int err; if (is_pbm_a) { pbm = &p->pbm_A; @@ -1312,14 +1310,10 @@ static void psycho_pbm_init(struct pci_controller_info *p, } pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; - pbm->chip_version = 0; - prop = of_find_property(dp, "version#", NULL); - if (prop) - pbm->chip_version = *(int *) prop->value; - pbm->chip_revision = 0; - prop = of_find_property(dp, "module-revision#", NULL); - if (prop) - pbm->chip_revision = *(int *) prop->value; + pbm->chip_version = + prom_getintdefault(prom_node, "version#", 0); + pbm->chip_revision = + prom_getintdefault(prom_node, "module-revision#", 0); pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE; pbm->io_space.flags = IORESOURCE_IO; @@ -1328,36 +1322,45 @@ static void psycho_pbm_init(struct pci_controller_info *p, pbm_register_toplevel_resources(p, pbm); pbm->parent = p; - pbm->prom_node = dp; - pbm->name = dp->full_name; - - printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", - pbm->name, - pbm->chip_version, pbm->chip_revision); - - prop = of_find_property(dp, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; + pbm->prom_node = prom_node; + prom_getstring(prom_node, "name", + pbm->prom_name, + sizeof(pbm->prom_name)); + + err = prom_getproperty(prom_node, "ranges", + (char *)pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err != -1) pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { + (err / sizeof(struct linux_prom_pci_ranges)); + else pbm->num_pbm_ranges = 0; - } - - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; + err = prom_getproperty(prom_node, "interrupt-map", + (char *)pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + if (err != -1) { + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(prom_node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == -1) { + prom_printf("PSYCHO-PBM: Fatal error, no " + "interrupt-map-mask.\n"); + prom_halt(); + } } else { pbm->num_pbm_intmap = 0; + memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } - prop = of_find_property(dp, "bus-range", NULL); - busrange = prop->value; + err = prom_getproperty(prom_node, "bus-range", + (char *)&busrange[0], + sizeof(busrange)); + if (err == 0 || err == -1) { + prom_printf("PSYCHO-PBM: Fatal error, no bus-range.\n"); + prom_halt(); + } pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; @@ -1366,24 +1369,20 @@ static void psycho_pbm_init(struct pci_controller_info *p, #define PSYCHO_CONFIGSPACE 0x001000000UL -void psycho_init(struct device_node *dp, char *model_name) +void psycho_init(int node, char *model_name) { - struct linux_prom64_registers *pr_regs; + struct linux_prom64_registers pr_regs[3]; struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; u32 upa_portid; - int is_pbm_a; + int is_pbm_a, err; - upa_portid = 0xff; - prop = of_find_property(dp, "upa-portid", NULL); - if (prop) - upa_portid = *(u32 *) prop->value; + upa_portid = prom_getintdefault(node, "upa-portid", 0xff); for(p = pci_controller_root; p; p = p->next) { if (p->pbm_A.portid == upa_portid) { - is_pbm_a = (p->pbm_A.prom_node == NULL); - psycho_pbm_init(p, dp, is_pbm_a); + is_pbm_a = (p->pbm_A.prom_node == 0); + psycho_pbm_init(p, node, is_pbm_a); return; } } @@ -1413,14 +1412,23 @@ void psycho_init(struct device_node *dp, char *model_name) p->resource_adjust = psycho_resource_adjust; p->pci_ops = &psycho_ops; - prop = of_find_property(dp, "reg", NULL); - pr_regs = prop->value; + err = prom_getproperty(node, "reg", + (char *)&pr_regs[0], + sizeof(pr_regs)); + if (err == 0 || err == -1) { + prom_printf("PSYCHO: Fatal error, no reg property.\n"); + prom_halt(); + } p->pbm_A.controller_regs = pr_regs[2].phys_addr; p->pbm_B.controller_regs = pr_regs[2].phys_addr; + printk("PCI: Found PSYCHO, control regs at %016lx\n", + p->pbm_A.controller_regs); p->pbm_A.config_space = p->pbm_B.config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); + printk("PSYCHO: Shared PCI config space at %016lx\n", + p->pbm_A.config_space); /* * Psycho's PCI MEM space is mapped to a 2GB aligned area, so @@ -1433,5 +1441,5 @@ void psycho_init(struct device_node *dp, char *model_name) psycho_iommu_init(p); is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); - psycho_pbm_init(p, dp, is_pbm_a); + psycho_pbm_init(p, node, is_pbm_a); } diff --git a/trunk/arch/sparc64/kernel/pci_sabre.c b/trunk/arch/sparc64/kernel/pci_sabre.c index 26f194ce4400..b7d997b55f0a 100644 --- a/trunk/arch/sparc64/kernel/pci_sabre.c +++ b/trunk/arch/sparc64/kernel/pci_sabre.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -1307,36 +1306,34 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p, &pbm->mem_space); } -static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin) +static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) { struct pci_pbm_info *pbm; - struct device_node *node; - struct property *prop; - u32 *busrange; - int len, simbas_found; + char namebuf[128]; + u32 busrange[2]; + int node, simbas_found; simbas_found = 0; - node = dp->child; - while (node != NULL) { - if (strcmp(node->name, "pci")) - goto next_pci; + node = prom_getchild(sabre_node); + while ((node = prom_searchsiblings(node, "pci")) != 0) { + int err; - prop = of_find_property(node, "model", NULL); - if (!prop || strncmp(prop->value, "SUNW,simba", prop->length)) + err = prom_getproperty(node, "model", namebuf, sizeof(namebuf)); + if ((err <= 0) || strncmp(namebuf, "SUNW,simba", err)) goto next_pci; - simbas_found++; + err = prom_getproperty(node, "bus-range", + (char *)&busrange[0], sizeof(busrange)); + if (err == 0 || err == -1) { + prom_printf("APB: Error, cannot get PCI bus-range.\n"); + prom_halt(); + } - prop = of_find_property(node, "bus-range", NULL); - busrange = prop->value; + simbas_found++; if (busrange[0] == 1) pbm = &p->pbm_B; else pbm = &p->pbm_A; - - pbm->name = node->full_name; - printk("%s: SABRE PCI Bus Module\n", pbm->name); - pbm->chip_type = PBM_CHIP_TYPE_SABRE; pbm->parent = p; pbm->prom_node = node; @@ -1344,68 +1341,83 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; - prop = of_find_property(node, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; + prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name)); + err = prom_getproperty(node, "ranges", + (char *)pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err != -1) pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { + (err / sizeof(struct linux_prom_pci_ranges)); + else pbm->num_pbm_ranges = 0; - } - prop = of_find_property(node, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(node, "interrupt-map-mask", - NULL); - pbm->pbm_intmask = prop->value; + err = prom_getproperty(node, "interrupt-map", + (char *)pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + if (err != -1) { + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == -1) { + prom_printf("APB: Fatal error, no interrupt-map-mask.\n"); + prom_halt(); + } } else { pbm->num_pbm_intmap = 0; + memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } pbm_register_toplevel_resources(p, pbm); next_pci: - node = node->sibling; + node = prom_getsibling(node); + if (!node) + break; } if (simbas_found == 0) { + int err; + /* No APBs underneath, probably this is a hummingbird * system. */ pbm = &p->pbm_A; pbm->parent = p; - pbm->prom_node = dp; + pbm->prom_node = sabre_node; pbm->pci_first_busno = p->pci_first_busno; pbm->pci_last_busno = p->pci_last_busno; - prop = of_find_property(dp, "ranges", &len); - if (prop) { - pbm->pbm_ranges = prop->value; + prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name)); + err = prom_getproperty(sabre_node, "ranges", + (char *) pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err != -1) pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); - } else { + (err / sizeof(struct linux_prom_pci_ranges)); + else pbm->num_pbm_ranges = 0; - } - - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - prop = of_find_property(dp, "interrupt-map-mask", - NULL); - pbm->pbm_intmask = prop->value; + err = prom_getproperty(sabre_node, "interrupt-map", + (char *) pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + + if (err != -1) { + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(sabre_node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == -1) { + prom_printf("Hummingbird: Fatal error, no interrupt-map-mask.\n"); + prom_halt(); + } } else { pbm->num_pbm_intmap = 0; + memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } - pbm->name = dp->full_name; - printk("%s: SABRE PCI Bus Module\n", pbm->name); + sprintf(pbm->name, "SABRE%d PBM%c", p->index, + (pbm == &p->pbm_A ? 'A' : 'B')); pbm->io_space.name = pbm->mem_space.name = pbm->name; /* Hack up top-level resources. */ @@ -1431,15 +1443,14 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp } } -void sabre_init(struct device_node *dp, char *model_name) +void sabre_init(int pnode, char *model_name) { - struct linux_prom64_registers *pr_regs; + struct linux_prom64_registers pr_regs[2]; struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; - int tsbsize; - u32 *busrange; - u32 *vdma; + int tsbsize, err; + u32 busrange[2]; + u32 vdma[2]; u32 upa_portid, dma_mask; u64 clear_irq; @@ -1447,21 +1458,22 @@ void sabre_init(struct device_node *dp, char *model_name) if (!strcmp(model_name, "pci108e,a001")) hummingbird_p = 1; else if (!strcmp(model_name, "SUNW,sabre")) { - prop = of_find_property(dp, "compatible", NULL); - if (prop) { - const char *compat = prop->value; + char compat[64]; - if (!strcmp(compat, "pci108e,a001")) - hummingbird_p = 1; - } - if (!hummingbird_p) { - struct device_node *dp; + if (prom_getproperty(pnode, "compatible", + compat, sizeof(compat)) > 0 && + !strcmp(compat, "pci108e,a001")) { + hummingbird_p = 1; + } else { + int cpu_node; /* Of course, Sun has to encode things a thousand * different ways, inconsistently. */ - cpu_find_by_instance(0, &dp, NULL); - if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe")) + cpu_find_by_instance(0, &cpu_node, NULL); + if (prom_getproperty(cpu_node, "name", + compat, sizeof(compat)) > 0 && + !strcmp(compat, "SUNW,UltraSPARC-IIe")) hummingbird_p = 1; } } @@ -1479,10 +1491,7 @@ void sabre_init(struct device_node *dp, char *model_name) } p->pbm_A.iommu = p->pbm_B.iommu = iommu; - upa_portid = 0xff; - prop = of_find_property(dp, "upa-portid", NULL); - if (prop) - upa_portid = *(u32 *) prop->value; + upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff); p->next = pci_controller_root; pci_controller_root = p; @@ -1500,9 +1509,13 @@ void sabre_init(struct device_node *dp, char *model_name) /* * Map in SABRE register set and report the presence of this SABRE. */ - - prop = of_find_property(dp, "reg", NULL); - pr_regs = prop->value; + err = prom_getproperty(pnode, "reg", + (char *)&pr_regs[0], sizeof(pr_regs)); + if(err == 0 || err == -1) { + prom_printf("SABRE: Error, cannot get U2P registers " + "from PROM.\n"); + prom_halt(); + } /* * First REG in property is base of entire SABRE register space. @@ -1510,6 +1523,9 @@ void sabre_init(struct device_node *dp, char *model_name) p->pbm_A.controller_regs = pr_regs[0].phys_addr; p->pbm_B.controller_regs = pr_regs[0].phys_addr; + printk("PCI: Found SABRE, main regs at %016lx\n", + p->pbm_A.controller_regs); + /* Clear interrupts */ /* PCI first */ @@ -1528,9 +1544,16 @@ void sabre_init(struct device_node *dp, char *model_name) /* Now map in PCI config space for entire SABRE. */ p->pbm_A.config_space = p->pbm_B.config_space = (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); - - prop = of_find_property(dp, "virtual-dma", NULL); - vdma = prop->value; + printk("SABRE: Shared PCI config space at %016lx\n", + p->pbm_A.config_space); + + err = prom_getproperty(pnode, "virtual-dma", + (char *)&vdma[0], sizeof(vdma)); + if(err == 0 || err == -1) { + prom_printf("SABRE: Error, cannot get virtual-dma property " + "from PROM.\n"); + prom_halt(); + } dma_mask = vdma[0]; switch(vdma[1]) { @@ -1554,13 +1577,21 @@ void sabre_init(struct device_node *dp, char *model_name) sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); - prop = of_find_property(dp, "bus-range", NULL); - busrange = prop->value; + printk("SABRE: DVMA at %08x [%08x]\n", vdma[0], vdma[1]); + + err = prom_getproperty(pnode, "bus-range", + (char *)&busrange[0], sizeof(busrange)); + if(err == 0 || err == -1) { + prom_printf("SABRE: Error, cannot get PCI bus-range " + " from PROM.\n"); + prom_halt(); + } + p->pci_first_busno = busrange[0]; p->pci_last_busno = busrange[1]; /* * Look for APB underneath. */ - sabre_pbm_init(p, dp, vdma[0]); + sabre_pbm_init(p, pnode, vdma[0]); } diff --git a/trunk/arch/sparc64/kernel/pci_schizo.c b/trunk/arch/sparc64/kernel/pci_schizo.c index f16449ccd7bc..cc662e915d32 100644 --- a/trunk/arch/sparc64/kernel/pci_schizo.c +++ b/trunk/arch/sparc64/kernel/pci_schizo.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -1457,12 +1456,10 @@ static void __schizo_scan_bus(struct pci_controller_info *p, pbm_config_busmastering(&p->pbm_B); p->pbm_B.is_66mhz_capable = - (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) - != NULL); + prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); pbm_config_busmastering(&p->pbm_A); p->pbm_A.is_66mhz_capable = - (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) - != NULL); + prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); pbm_scan_bus(p, &p->pbm_B); pbm_scan_bus(p, &p->pbm_A); @@ -1664,18 +1661,13 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) { struct pci_iommu *iommu = pbm->iommu; unsigned long i, tagbase, database; - struct property *prop; u32 vdma[2], dma_mask; u64 control; - int tsbsize; + int err, tsbsize; - prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); - if (prop) { - u32 *val = prop->value; - - vdma[0] = val[0]; - vdma[1] = val[1]; - } else { + err = prom_getproperty(pbm->prom_node, "virtual-dma", + (char *)&vdma[0], sizeof(vdma)); + if (err == 0 || err == -1) { /* No property, use default values. */ vdma[0] = 0xc0000000; vdma[1] = 0x40000000; @@ -1786,7 +1778,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) { - struct property *prop; u64 tmp; schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); @@ -1800,8 +1791,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - prop = of_find_property(pbm->prom_node, "no-bus-parking", NULL); - if (!prop) + if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; @@ -1841,17 +1831,16 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } static void schizo_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 portid, + int prom_node, u32 portid, int chip_type) { - struct linux_prom64_registers *regs; - struct property *prop; - unsigned int *busrange; + struct linux_prom64_registers pr_regs[4]; + unsigned int busrange[2]; struct pci_pbm_info *pbm; const char *chipset_name; - u32 *ino_bitmap; + u32 ino_bitmap[2]; int is_pbm_a; - int len; + int err; switch (chip_type) { case PBM_CHIP_TYPE_TOMATILLO: @@ -1879,10 +1868,16 @@ static void schizo_pbm_init(struct pci_controller_info *p, * 3) PBM PCI config space * 4) Ichip regs */ - prop = of_find_property(dp, "reg", NULL); - regs = prop->value; + err = prom_getproperty(prom_node, "reg", + (char *)&pr_regs[0], + sizeof(pr_regs)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no reg property.\n", + chipset_name); + prom_halt(); + } - is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); + is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); if (is_pbm_a) pbm = &p->pbm_A; @@ -1891,62 +1886,92 @@ static void schizo_pbm_init(struct pci_controller_info *p, pbm->portid = portid; pbm->parent = p; - pbm->prom_node = dp; + pbm->prom_node = prom_node; pbm->pci_first_slot = 1; pbm->chip_type = chip_type; - pbm->chip_version = 0; - prop = of_find_property(dp, "version#", NULL); - if (prop) - pbm->chip_version = *(int *) prop->value; - pbm->chip_revision = 0; - prop = of_find_property(dp, "module-revision#", NULL); - if (prop) - pbm->chip_revision = *(int *) prop->value; - - pbm->pbm_regs = regs[0].phys_addr; - pbm->controller_regs = regs[1].phys_addr - 0x10000UL; + pbm->chip_version = + prom_getintdefault(prom_node, "version#", 0); + pbm->chip_revision = + prom_getintdefault(prom_node, "module-revision#", 0); + + pbm->pbm_regs = pr_regs[0].phys_addr; + pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; if (chip_type == PBM_CHIP_TYPE_TOMATILLO) - pbm->sync_reg = regs[3].phys_addr + 0x1a18UL; + pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; - pbm->name = dp->full_name; + sprintf(pbm->name, + (chip_type == PBM_CHIP_TYPE_TOMATILLO ? + "TOMATILLO%d PBM%c" : + "SCHIZO%d PBM%c"), + p->index, + (pbm == &p->pbm_A ? 'A' : 'B')); - printk("%s: %s PCI Bus Module ver[%x:%x]\n", + printk("%s: ver[%x:%x], portid %x, " + "cregs[%lx] pregs[%lx]\n", pbm->name, - (chip_type == PBM_CHIP_TYPE_TOMATILLO ? - "TOMATILLO" : "SCHIZO"), - pbm->chip_version, pbm->chip_revision); + pbm->chip_version, pbm->chip_revision, + pbm->portid, + pbm->controller_regs, + pbm->pbm_regs); schizo_pbm_hw_init(pbm); - prop = of_find_property(dp, "ranges", &len); - pbm->pbm_ranges = prop->value; + prom_getstring(prom_node, "name", + pbm->prom_name, + sizeof(pbm->prom_name)); + + err = prom_getproperty(prom_node, "ranges", + (char *) pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no ranges property.\n", + pbm->name); + prom_halt(); + } + pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); + (err / sizeof(struct linux_prom_pci_ranges)); schizo_determine_mem_io_space(pbm); pbm_register_toplevel_resources(p, pbm); - prop = of_find_property(dp, "interrupt-map", &len); - if (prop) { - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); - - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; + err = prom_getproperty(prom_node, "interrupt-map", + (char *)pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + if (err != -1) { + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(prom_node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == -1) { + prom_printf("%s: Fatal error, no " + "interrupt-map-mask.\n", pbm->name); + prom_halt(); + } } else { pbm->num_pbm_intmap = 0; + memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask)); } - prop = of_find_property(dp, "ino-bitmap", NULL); - ino_bitmap = prop->value; + err = prom_getproperty(prom_node, "ino-bitmap", + (char *) &ino_bitmap[0], + sizeof(ino_bitmap)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name); + prom_halt(); + } pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | ((u64)ino_bitmap[0] << 0UL)); - prop = of_find_property(dp, "bus-range", NULL); - busrange = prop->value; + err = prom_getproperty(prom_node, "bus-range", + (char *)&busrange[0], + sizeof(busrange)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no bus-range.\n", pbm->name); + prom_halt(); + } pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; @@ -1964,20 +1989,16 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) return (x == y); } -static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) +static void __schizo_init(int node, char *model_name, int chip_type) { struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; int is_pbm_a; u32 portid; - portid = 0xff; - prop = of_find_property(dp, "portid", NULL); - if (prop) - portid = *(u32 *) prop->value; + portid = prom_getintdefault(node, "portid", 0xff); - for (p = pci_controller_root; p; p = p->next) { + for(p = pci_controller_root; p; p = p->next) { struct pci_pbm_info *pbm; if (p->pbm_A.prom_node && p->pbm_B.prom_node) @@ -1988,8 +2009,8 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ &p->pbm_B); if (portid_compare(pbm->portid, portid, chip_type)) { - is_pbm_a = (p->pbm_A.prom_node == NULL); - schizo_pbm_init(p, dp, portid, chip_type); + is_pbm_a = (p->pbm_A.prom_node == 0); + schizo_pbm_init(p, node, portid, chip_type); return; } } @@ -2030,20 +2051,20 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ /* Like PSYCHO we have a 2GB aligned area for memory space. */ pci_memspace_mask = 0x7fffffffUL; - schizo_pbm_init(p, dp, portid, chip_type); + schizo_pbm_init(p, node, portid, chip_type); } -void schizo_init(struct device_node *dp, char *model_name) +void schizo_init(int node, char *model_name) { - __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO); + __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); } -void schizo_plus_init(struct device_node *dp, char *model_name) +void schizo_plus_init(int node, char *model_name) { - __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); + __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); } -void tomatillo_init(struct device_node *dp, char *model_name) +void tomatillo_init(int node, char *model_name) { - __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO); + __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); } diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index b69e2270a721..5419480edf41 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -647,37 +646,35 @@ static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, u /* Recursively descend into the OBP device tree, rooted at toplevel_node, * looking for a PCI device matching bus and devfn. */ -static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn) +static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) { - toplevel_node = toplevel_node->child; + toplevel_node = prom_getchild(toplevel_node); - while (toplevel_node != NULL) { - struct linux_prom_pci_registers *regs; - struct property *prop; - int ret; + while (toplevel_node != 0) { + int ret = obp_find(pregs, toplevel_node, bus, devfn); - ret = obp_find(toplevel_node, bus, devfn); if (ret != 0) return ret; - prop = of_find_property(toplevel_node, "reg", NULL); - if (!prop) + ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, + sizeof(*pregs) * PROMREG_MAX); + if (ret == 0 || ret == -1) goto next_sibling; - regs = prop->value; - if (((regs->phys_hi >> 16) & 0xff) == bus && - ((regs->phys_hi >> 8) & 0xff) == devfn) + if (((pregs[0].phys_hi >> 16) & 0xff) == bus && + ((pregs[0].phys_hi >> 8) & 0xff) == devfn) break; next_sibling: - toplevel_node = toplevel_node->sibling; + toplevel_node = prom_getsibling(toplevel_node); } - return toplevel_node != NULL; + return toplevel_node; } static int pdev_htab_populate(struct pci_pbm_info *pbm) { + struct linux_prom_pci_registers pr[PROMREG_MAX]; u32 devhandle = pbm->devhandle; unsigned int bus; @@ -688,7 +685,7 @@ static int pdev_htab_populate(struct pci_pbm_info *pbm) unsigned int device = PCI_SLOT(devfn); unsigned int func = PCI_FUNC(devfn); - if (obp_find(pbm->prom_node, bus, devfn)) { + if (obp_find(pr, pbm->prom_node, bus, devfn)) { int err = pdev_htab_add(devhandle, bus, device, func); if (err) @@ -814,7 +811,8 @@ static void pbm_scan_bus(struct pci_controller_info *p, pci_fixup_host_bridge_self(pbm->pci_bus); pbm->pci_bus->self->sysdata = cookie; #endif - pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); + pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, + pbm->prom_node); pci_record_assignments(pbm, pbm->pci_bus); pci_assign_unassigned(pbm, pbm->pci_bus); pci_fixup_irq(pbm, pbm->pci_bus); @@ -824,18 +822,15 @@ static void pbm_scan_bus(struct pci_controller_info *p, static void pci_sun4v_scan_bus(struct pci_controller_info *p) { - struct property *prop; - struct device_node *dp; - - if ((dp = p->pbm_A.prom_node) != NULL) { - prop = of_find_property(dp, "66mhz-capable", NULL); - p->pbm_A.is_66mhz_capable = (prop != NULL); + if (p->pbm_A.prom_node) { + p->pbm_A.is_66mhz_capable = + prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); pbm_scan_bus(p, &p->pbm_A); } - if ((dp = p->pbm_B.prom_node) != NULL) { - prop = of_find_property(dp, "66mhz-capable", NULL); - p->pbm_B.is_66mhz_capable = (prop != NULL); + if (p->pbm_B.prom_node) { + p->pbm_B.is_66mhz_capable = + prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); pbm_scan_bus(p, &p->pbm_B); } @@ -987,13 +982,8 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, HV_PCI_TSBID(0, i), &io_attrs, &ra); if (ret == HV_EOK) { - if (page_in_phys_avail(ra)) { - pci_sun4v_iommu_demap(devhandle, - HV_PCI_TSBID(0, i), 1); - } else { - cnt++; - __set_bit(i, arena->map); - } + cnt++; + __set_bit(i, arena->map); } } @@ -1003,18 +993,13 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) { struct pci_iommu *iommu = pbm->iommu; - struct property *prop; unsigned long num_tsb_entries, sz; u32 vdma[2], dma_mask, dma_offset; - int tsbsize; - - prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); - if (prop) { - u32 *val = prop->value; + int err, tsbsize; - vdma[0] = val[0]; - vdma[1] = val[1]; - } else { + err = prom_getproperty(pbm->prom_node, "virtual-dma", + (char *)&vdma[0], sizeof(vdma)); + if (err == 0 || err == -1) { /* No property, use default values. */ vdma[0] = 0x80000000; vdma[1] = 0x80000000; @@ -1066,30 +1051,34 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) iommu->arena.limit = num_tsb_entries; sz = probe_existing_entries(pbm, iommu); - if (sz) - printk("%s: Imported %lu TSB entries from OBP\n", - pbm->name, sz); + + printk("%s: TSB entries [%lu], existing mapings [%lu]\n", + pbm->name, num_tsb_entries, sz); } static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) { - struct property *prop; - unsigned int *busrange; - - prop = of_find_property(pbm->prom_node, "bus-range", NULL); - - busrange = prop->value; + unsigned int busrange[2]; + int prom_node = pbm->prom_node; + int err; + + err = prom_getproperty(prom_node, "bus-range", + (char *)&busrange[0], + sizeof(busrange)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no bus-range.\n", pbm->name); + prom_halt(); + } pbm->pci_first_busno = busrange[0]; pbm->pci_last_busno = busrange[1]; } -static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) +static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 devhandle) { struct pci_pbm_info *pbm; - struct property *prop; - int len, i; + int err, i; if (devhandle & 0x40) pbm = &p->pbm_B; @@ -1097,19 +1086,32 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pbm = &p->pbm_A; pbm->parent = p; - pbm->prom_node = dp; + pbm->prom_node = prom_node; pbm->pci_first_slot = 1; pbm->devhandle = devhandle; - pbm->name = dp->full_name; + sprintf(pbm->name, "SUN4V-PCI%d PBM%c", + p->index, (pbm == &p->pbm_A ? 'A' : 'B')); - printk("%s: SUN4V PCI Bus Module\n", pbm->name); + printk("%s: devhandle[%x] prom_node[%x:%x]\n", + pbm->name, pbm->devhandle, + pbm->prom_node, prom_getchild(pbm->prom_node)); + + prom_getstring(prom_node, "name", + pbm->prom_name, sizeof(pbm->prom_name)); + + err = prom_getproperty(prom_node, "ranges", + (char *) pbm->pbm_ranges, + sizeof(pbm->pbm_ranges)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no ranges property.\n", + pbm->name); + prom_halt(); + } - prop = of_find_property(dp, "ranges", &len); - pbm->pbm_ranges = prop->value; pbm->num_pbm_ranges = - (len / sizeof(struct linux_prom_pci_ranges)); + (err / sizeof(struct linux_prom_pci_ranges)); /* Mask out the top 8 bits of the ranges, leaving the real * physical address. @@ -1120,13 +1122,24 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_sun4v_determine_mem_io_space(pbm); pbm_register_toplevel_resources(p, pbm); - prop = of_find_property(dp, "interrupt-map", &len); - pbm->pbm_intmap = prop->value; - pbm->num_pbm_intmap = - (len / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(prom_node, "interrupt-map", + (char *)pbm->pbm_intmap, + sizeof(pbm->pbm_intmap)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no interrupt-map property.\n", + pbm->name); + prom_halt(); + } - prop = of_find_property(dp, "interrupt-map-mask", NULL); - pbm->pbm_intmask = prop->value; + pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); + err = prom_getproperty(prom_node, "interrupt-map-mask", + (char *)&pbm->pbm_intmask, + sizeof(pbm->pbm_intmask)); + if (err == 0 || err == -1) { + prom_printf("%s: Fatal error, no interrupt-map-mask.\n", + pbm->name); + prom_halt(); + } pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); @@ -1134,19 +1147,16 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pdev_htab_populate(pbm); } -void sun4v_pci_init(struct device_node *dp, char *model_name) +void sun4v_pci_init(int node, char *model_name) { struct pci_controller_info *p; struct pci_iommu *iommu; - struct property *prop; - struct linux_prom64_registers *regs; + struct linux_prom64_registers regs; u32 devhandle; int i; - prop = of_find_property(dp, "reg", NULL); - regs = prop->value; - - devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; + prom_getproperty(node, "reg", (char *)®s, sizeof(regs)); + devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; for (p = pci_controller_root; p; p = p->next) { struct pci_pbm_info *pbm; @@ -1159,7 +1169,7 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) &p->pbm_B); if (pbm->devhandle == (devhandle ^ 0x40)) { - pci_sun4v_pbm_init(p, dp, devhandle); + pci_sun4v_pbm_init(p, node, devhandle); return; } } @@ -1210,7 +1220,7 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) */ pci_memspace_mask = 0x7fffffffUL; - pci_sun4v_pbm_init(p, dp, devhandle); + pci_sun4v_pbm_init(p, node, devhandle); return; fatal_memory_error: diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 9496c7734014..30bcaf58e3ab 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -105,25 +105,76 @@ static int powerd(void *__unused) return 0; } -static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) +static int __init has_button_interrupt(unsigned int irq, int prom_node) { if (irq == PCI_IRQ_NONE) return 0; - if (!of_find_property(dp, "button", NULL)) + if (!prom_node_has_property(prom_node, "button")) return 0; return 1; } -static void __devinit power_probe_common(struct of_device *dev, struct resource *res, unsigned int irq) +static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p) { - power_reg = ioremap(res->start, 0x4); + struct linux_ebus *ebus; + struct linux_ebus_device *edev; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "power")) { + *resp = &edev->resource[0]; + *irq_p = edev->irqs[0]; + *prom_node_p = edev->prom_node; + return 0; + } + } + } + return -ENODEV; +} - printk("power: Control reg at %p ... ", power_reg); +static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p) +{ + struct sparc_isa_bridge *isa_bus; + struct sparc_isa_device *isa_dev; + + for_each_isa(isa_bus) { + for_each_isadev(isa_dev, isa_bus) { + if (!strcmp(isa_dev->prom_name, "power")) { + *resp = &isa_dev->resource; + *irq_p = isa_dev->irq; + *prom_node_p = isa_dev->prom_node; + return 0; + } + } + } + return -ENODEV; +} - poweroff_method = machine_halt; /* able to use the standard halt */ +void __init power_init(void) +{ + struct resource *res = NULL; + unsigned int irq; + int prom_node; + static int invoked; + + if (invoked) + return; + invoked = 1; + + if (!power_probe_ebus(&res, &irq, &prom_node)) + goto found; - if (has_button_interrupt(irq, dev->node)) { + if (!power_probe_isa(&res, &irq, &prom_node)) + goto found; + + return; + +found: + power_reg = ioremap(res->start, 0x4); + printk("power: Control reg at %p ... ", power_reg); + poweroff_method = machine_halt; /* able to use the standard halt */ + if (has_button_interrupt(irq, prom_node)) { if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { printk("Failed to start power daemon.\n"); return; @@ -137,52 +188,4 @@ static void __devinit power_probe_common(struct of_device *dev, struct resource printk("not using powerd.\n"); } } - -static struct of_device_id power_match[] = { - { - .name = "power", - }, - {}, -}; - -static int __devinit ebus_power_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct linux_ebus_device *edev = to_ebus_device(&dev->dev); - struct resource *res = &edev->resource[0]; - unsigned int irq = edev->irqs[0]; - - power_probe_common(dev, res,irq); - - return 0; -} - -static struct of_platform_driver ebus_power_driver = { - .name = "power", - .match_table = power_match, - .probe = ebus_power_probe, -}; - -static int __devinit isa_power_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sparc_isa_device *idev = to_isa_device(&dev->dev); - struct resource *res = &idev->resource; - unsigned int irq = idev->irq; - - power_probe_common(dev, res,irq); - - return 0; -} - -static struct of_platform_driver isa_power_driver = { - .name = "power", - .match_table = power_match, - .probe = isa_power_probe, -}; - -void __init power_init(void) -{ - of_register_driver(&ebus_power_driver, &ebus_bus_type); - of_register_driver(&isa_power_driver, &isa_bus_type); - return; -} #endif /* CONFIG_PCI */ diff --git a/trunk/arch/sparc64/kernel/prom.c b/trunk/arch/sparc64/kernel/prom.c deleted file mode 100644 index 8e87e7ea0325..000000000000 --- a/trunk/arch/sparc64/kernel/prom.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Procedures for creating, accessing and interpreting the device tree. - * - * Paul Mackerras August 1996. - * Copyright (C) 1996-2005 Paul Mackerras. - * - * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. - * {engebret|bergner}@us.ibm.com - * - * Adapted for sparc64 by David S. Miller davem@davemloft.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -static struct device_node *allnodes; - -/* use when traversing tree through the allnext, child, sibling, - * or parent members of struct device_node. - */ -static DEFINE_RWLOCK(devtree_lock); - -int of_device_is_compatible(struct device_node *device, const char *compat) -{ - const char* cp; - int cplen, l; - - cp = (char *) of_get_property(device, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (strncmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; -} -EXPORT_SYMBOL(of_device_is_compatible); - -struct device_node *of_get_parent(const struct device_node *node) -{ - struct device_node *np; - - if (!node) - return NULL; - - np = node->parent; - - return np; -} -EXPORT_SYMBOL(of_get_parent); - -struct device_node *of_get_next_child(const struct device_node *node, - struct device_node *prev) -{ - struct device_node *next; - - next = prev ? prev->sibling : node->child; - for (; next != 0; next = next->sibling) { - break; - } - - return next; -} -EXPORT_SYMBOL(of_get_next_child); - -struct device_node *of_find_node_by_path(const char *path) -{ - struct device_node *np = allnodes; - - for (; np != 0; np = np->allnext) { - if (np->full_name != 0 && strcmp(np->full_name, path) == 0) - break; - } - - return np; -} -EXPORT_SYMBOL(of_find_node_by_path); - -struct device_node *of_find_node_by_phandle(phandle handle) -{ - struct device_node *np; - - for (np = allnodes; np != 0; np = np->allnext) - if (np->node == handle) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_phandle); - -struct device_node *of_find_node_by_name(struct device_node *from, - const char *name) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != NULL; np = np->allnext) - if (np->name != NULL && strcmp(np->name, name) == 0) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_name); - -struct device_node *of_find_node_by_type(struct device_node *from, - const char *type) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != 0; np = np->allnext) - if (np->type != 0 && strcmp(np->type, type) == 0) - break; - - return np; -} -EXPORT_SYMBOL(of_find_node_by_type); - -struct device_node *of_find_compatible_node(struct device_node *from, - const char *type, const char *compatible) -{ - struct device_node *np; - - np = from ? from->allnext : allnodes; - for (; np != 0; np = np->allnext) { - if (type != NULL - && !(np->type != 0 && strcmp(np->type, type) == 0)) - continue; - if (of_device_is_compatible(np, compatible)) - break; - } - - return np; -} -EXPORT_SYMBOL(of_find_compatible_node); - -struct property *of_find_property(struct device_node *np, const char *name, - int *lenp) -{ - struct property *pp; - - for (pp = np->properties; pp != 0; pp = pp->next) { - if (strcmp(pp->name, name) == 0) { - if (lenp != 0) - *lenp = pp->length; - break; - } - } - return pp; -} -EXPORT_SYMBOL(of_find_property); - -/* - * Find a property with a given name for a given node - * and return the value. - */ -void *of_get_property(struct device_node *np, const char *name, int *lenp) -{ - struct property *pp = of_find_property(np,name,lenp); - return pp ? pp->value : NULL; -} -EXPORT_SYMBOL(of_get_property); - -int of_getintprop_default(struct device_node *np, const char *name, int def) -{ - struct property *prop; - int len; - - prop = of_find_property(np, name, &len); - if (!prop || len != 4) - return def; - - return *(int *) prop->value; -} -EXPORT_SYMBOL(of_getintprop_default); - -int of_set_property(struct device_node *dp, const char *name, void *val, int len) -{ - struct property **prevp; - void *new_val; - int err; - - new_val = kmalloc(len, GFP_KERNEL); - if (!new_val) - return -ENOMEM; - - memcpy(new_val, val, len); - - err = -ENODEV; - - write_lock(&devtree_lock); - prevp = &dp->properties; - while (*prevp) { - struct property *prop = *prevp; - - if (!strcmp(prop->name, name)) { - void *old_val = prop->value; - int ret; - - ret = prom_setprop(dp->node, name, val, len); - err = -EINVAL; - if (ret >= 0) { - prop->value = new_val; - prop->length = len; - - if (OF_IS_DYNAMIC(prop)) - kfree(old_val); - - OF_MARK_DYNAMIC(prop); - - err = 0; - } - break; - } - prevp = &(*prevp)->next; - } - write_unlock(&devtree_lock); - - /* XXX Upate procfs if necessary... */ - - return err; -} -EXPORT_SYMBOL(of_set_property); - -static unsigned int prom_early_allocated; - -static void * __init prom_early_alloc(unsigned long size) -{ - void *ret; - - ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); - if (ret != NULL) - memset(ret, 0, size); - - prom_early_allocated += size; - - return ret; -} - -static int is_root_node(const struct device_node *dp) -{ - if (!dp) - return 0; - - return (dp->parent == NULL); -} - -/* The following routines deal with the black magic of fully naming a - * node. - * - * Certain well known named nodes are just the simple name string. - * - * Actual devices have an address specifier appended to the base name - * string, like this "foo@addr". The "addr" can be in any number of - * formats, and the platform plus the type of the node determine the - * format and how it is constructed. - * - * For children of the ROOT node, the naming convention is fixed and - * determined by whether this is a sun4u or sun4v system. - * - * For children of other nodes, it is bus type specific. So - * we walk up the tree until we discover a "device_type" property - * we recognize and we go from there. - * - * As an example, the boot device on my workstation has a full path: - * - * /pci@1e,600000/ide@d/disk@0,0:c - */ -static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom64_registers *regs; - struct property *rprop; - u32 high_bits, low_bits, type; - - rprop = of_find_property(dp, "reg", NULL); - if (!rprop) - return; - - regs = rprop->value; - if (!is_root_node(dp->parent)) { - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - (unsigned int) (regs->phys_addr >> 32UL), - (unsigned int) (regs->phys_addr & 0xffffffffUL)); - return; - } - - type = regs->phys_addr >> 60UL; - high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL; - low_bits = (regs->phys_addr & 0xffffffffUL); - - if (type == 0 || type == 8) { - const char *prefix = (type == 0) ? "m" : "i"; - - if (low_bits) - sprintf(tmp_buf, "%s@%s%x,%x", - dp->name, prefix, - high_bits, low_bits); - else - sprintf(tmp_buf, "%s@%s%x", - dp->name, - prefix, - high_bits); - } else if (type == 12) { - sprintf(tmp_buf, "%s@%x", - dp->name, high_bits); - } -} - -static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom64_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - if (!is_root_node(dp->parent)) { - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - (unsigned int) (regs->phys_addr >> 32UL), - (unsigned int) (regs->phys_addr & 0xffffffffUL)); - return; - } - - prop = of_find_property(dp, "upa-portid", NULL); - if (!prop) - prop = of_find_property(dp, "portid", NULL); - if (prop) { - unsigned long mask = 0xffffffffUL; - - if (tlb_type >= cheetah) - mask = 0x7fffff; - - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - *(u32 *)prop->value, - (unsigned int) (regs->phys_addr & mask)); - } -} - -/* "name@slot,offset" */ -static void __init sbus_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - regs->which_io, - regs->phys_addr); -} - -/* "name@devnum[,func]" */ -static void __init pci_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom_pci_registers *regs; - struct property *prop; - unsigned int devfn; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - devfn = (regs->phys_hi >> 8) & 0xff; - if (devfn & 0x07) { - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - devfn >> 3, - devfn & 0x07); - } else { - sprintf(tmp_buf, "%s@%x", - dp->name, - devfn >> 3); - } -} - -/* "name@UPA_PORTID,offset" */ -static void __init upa_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom64_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - prop = of_find_property(dp, "upa-portid", NULL); - if (!prop) - return; - - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - *(u32 *) prop->value, - (unsigned int) (regs->phys_addr & 0xffffffffUL)); -} - -/* "name@reg" */ -static void __init vdev_path_component(struct device_node *dp, char *tmp_buf) -{ - struct property *prop; - u32 *regs; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - sprintf(tmp_buf, "%s@%x", dp->name, *regs); -} - -/* "name@addrhi,addrlo" */ -static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) -{ - struct linux_prom64_registers *regs; - struct property *prop; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - sprintf(tmp_buf, "%s@%x,%x", - dp->name, - (unsigned int) (regs->phys_addr >> 32UL), - (unsigned int) (regs->phys_addr & 0xffffffffUL)); -} - -/* "name@bus,addr" */ -static void __init i2c_path_component(struct device_node *dp, char *tmp_buf) -{ - struct property *prop; - u32 *regs; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - /* This actually isn't right... should look at the #address-cells - * property of the i2c bus node etc. etc. - */ - sprintf(tmp_buf, "%s@%x,%x", - dp->name, regs[0], regs[1]); -} - -/* "name@reg0[,reg1]" */ -static void __init usb_path_component(struct device_node *dp, char *tmp_buf) -{ - struct property *prop; - u32 *regs; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - if (prop->length == sizeof(u32) || regs[1] == 1) { - sprintf(tmp_buf, "%s@%x", - dp->name, regs[0]); - } else { - sprintf(tmp_buf, "%s@%x,%x", - dp->name, regs[0], regs[1]); - } -} - -/* "name@reg0reg1[,reg2reg3]" */ -static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf) -{ - struct property *prop; - u32 *regs; - - prop = of_find_property(dp, "reg", NULL); - if (!prop) - return; - - regs = prop->value; - - if (regs[2] || regs[3]) { - sprintf(tmp_buf, "%s@%08x%08x,%04x%08x", - dp->name, regs[0], regs[1], regs[2], regs[3]); - } else { - sprintf(tmp_buf, "%s@%08x%08x", - dp->name, regs[0], regs[1]); - } -} - -static void __init __build_path_component(struct device_node *dp, char *tmp_buf) -{ - struct device_node *parent = dp->parent; - - if (parent != NULL) { - if (!strcmp(parent->type, "pci") || - !strcmp(parent->type, "pciex")) - return pci_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "sbus")) - return sbus_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "upa")) - return upa_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "ebus")) - return ebus_path_component(dp, tmp_buf); - if (!strcmp(parent->name, "usb") || - !strcmp(parent->name, "hub")) - return usb_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "i2c")) - return i2c_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "firewire")) - return ieee1394_path_component(dp, tmp_buf); - if (!strcmp(parent->type, "virtual-devices")) - return vdev_path_component(dp, tmp_buf); - - /* "isa" is handled with platform naming */ - } - - /* Use platform naming convention. */ - if (tlb_type == hypervisor) - return sun4v_path_component(dp, tmp_buf); - else - return sun4u_path_component(dp, tmp_buf); -} - -static char * __init build_path_component(struct device_node *dp) -{ - char tmp_buf[64], *n; - - tmp_buf[0] = '\0'; - __build_path_component(dp, tmp_buf); - if (tmp_buf[0] == '\0') - strcpy(tmp_buf, dp->name); - - n = prom_early_alloc(strlen(tmp_buf) + 1); - strcpy(n, tmp_buf); - - return n; -} - -static char * __init build_full_name(struct device_node *dp) -{ - int len, ourlen, plen; - char *n; - - plen = strlen(dp->parent->full_name); - ourlen = strlen(dp->path_component_name); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!is_root_node(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, dp->path_component_name); - - return n; -} - -static unsigned int unique_id; - -static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) -{ - static struct property *tmp = NULL; - struct property *p; - - if (tmp) { - p = tmp; - memset(p, 0, sizeof(*p) + 32); - tmp = NULL; - } else { - p = prom_early_alloc(sizeof(struct property) + 32); - p->unique_id = unique_id++; - } - - p->name = (char *) (p + 1); - if (special_name) { - strcpy(p->name, special_name); - p->length = special_len; - p->value = prom_early_alloc(special_len); - memcpy(p->value, special_val, special_len); - } else { - if (prev == NULL) { - prom_firstprop(node, p->name); - } else { - prom_nextprop(node, prev, p->name); - } - if (strlen(p->name) == 0) { - tmp = p; - return NULL; - } - p->length = prom_getproplen(node, p->name); - if (p->length <= 0) { - p->length = 0; - } else { - p->value = prom_early_alloc(p->length + 1); - prom_getproperty(node, p->name, p->value, p->length); - ((unsigned char *)p->value)[p->length] = '\0'; - } - } - return p; -} - -static struct property * __init build_prop_list(phandle node) -{ - struct property *head, *tail; - - head = tail = build_one_prop(node, NULL, - ".node", &node, sizeof(node)); - - tail->next = build_one_prop(node, NULL, NULL, NULL, 0); - tail = tail->next; - while(tail) { - tail->next = build_one_prop(node, tail->name, - NULL, NULL, 0); - tail = tail->next; - } - - return head; -} - -static char * __init get_one_property(phandle node, const char *name) -{ - char *buf = ""; - int len; - - len = prom_getproplen(node, name); - if (len > 0) { - buf = prom_early_alloc(len); - prom_getproperty(node, name, buf, len); - } - - return buf; -} - -static struct device_node * __init create_node(phandle node) -{ - struct device_node *dp; - - if (!node) - return NULL; - - dp = prom_early_alloc(sizeof(*dp)); - dp->unique_id = unique_id++; - - kref_init(&dp->kref); - - dp->name = get_one_property(node, "name"); - dp->type = get_one_property(node, "device_type"); - dp->node = node; - - /* Build interrupts later... */ - - dp->properties = build_prop_list(node); - - return dp; -} - -static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) -{ - struct device_node *dp; - - dp = create_node(node); - if (dp) { - *(*nextp) = dp; - *nextp = &dp->allnext; - - dp->parent = parent; - dp->path_component_name = build_path_component(dp); - dp->full_name = build_full_name(dp); - - dp->child = build_tree(dp, prom_getchild(node), nextp); - - dp->sibling = build_tree(parent, prom_getsibling(node), nextp); - } - - return dp; -} - -void __init prom_build_devicetree(void) -{ - struct device_node **nextp; - - allnodes = create_node(prom_root_node); - allnodes->path_component_name = ""; - allnodes->full_name = "/"; - - nextp = &allnodes->allnext; - allnodes->child = build_tree(allnodes, - prom_getchild(allnodes->node), - &nextp); - printk("PROM: Built device tree with %u bytes of memory.\n", - prom_early_allocated); -} diff --git a/trunk/arch/sparc64/kernel/sbus.c b/trunk/arch/sparc64/kernel/sbus.c index ac05e0f692ef..8812417247d4 100644 --- a/trunk/arch/sparc64/kernel/sbus.c +++ b/trunk/arch/sparc64/kernel/sbus.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "iommu_common.h" @@ -1099,25 +1098,24 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) } /* Boot time initialization. */ -static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) +void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus) { - struct linux_prom64_registers *pr; - struct device_node *dp; + struct linux_prom64_registers rprop; struct sbus_iommu *iommu; unsigned long regs, tsb_base; u64 control; - int i; - - dp = of_find_node_by_phandle(__node); + int err, i; - sbus->portid = of_getintprop_default(dp, "upa-portid", -1); + sbus->portid = prom_getintdefault(sbus->prom_node, + "upa-portid", -1); - pr = of_get_property(dp, "reg", NULL); - if (!pr) { + err = prom_getproperty(prom_node, "reg", + (char *)&rprop, sizeof(rprop)); + if (err < 0) { prom_printf("sbus_iommu_init: Cannot map SYSIO control registers.\n"); prom_halt(); } - regs = pr->phys_addr; + regs = rprop.phys_addr; iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC); if (iommu == NULL) { @@ -1227,50 +1225,3 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) sysio_register_error_handlers(sbus); } - -void sbus_fill_device_irq(struct sbus_dev *sdev) -{ - struct device_node *dp = of_find_node_by_phandle(sdev->prom_node); - struct linux_prom_irqs *irqs; - - irqs = of_get_property(dp, "interrupts", NULL); - if (!irqs) { - sdev->irqs[0] = 0; - sdev->num_irqs = 0; - } else { - unsigned int pri = irqs[0].pri; - - sdev->num_irqs = 1; - if (pri < 0x20) - pri += sdev->slot * 8; - - sdev->irqs[0] = sbus_build_irq(sdev->bus, pri); - } -} - -void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) -{ -} - -void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) -{ - sbus_iommu_init(dp->node, sbus); -} - -void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) -{ -} - -int __init sbus_arch_preinit(void) -{ - return 0; -} - -void __init sbus_arch_postinit(void) -{ - extern void firetruck_init(void); - extern void clock_probe(void); - - firetruck_init(); - clock_probe(); -} diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index 116d9632002d..9cf1c88cd774 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -376,12 +376,12 @@ void __init setup_arch(char **cmdline_p) } #endif + smp_setup_cpu_possible_map(); + /* Get boot processor trap_block[] setup. */ init_cur_cpu_trap(current_thread_info()); paging_init(); - - smp_setup_cpu_possible_map(); } static int __init set_preferred_console(void) @@ -537,7 +537,7 @@ static int __init topology_init(void) for_each_possible_cpu(i) { struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (p) { - register_cpu(p, i); + register_cpu(p, i, NULL); err = 0; } } diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index f62bf3a2de1a..f03d52d0b88d 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -39,7 +39,6 @@ #include #include #include -#include extern void calibrate_delay(void); @@ -77,42 +76,41 @@ void smp_bogo(struct seq_file *m) void __init smp_store_cpu_info(int id) { - struct device_node *dp; - int def; + int cpu_node, def; /* multiplier and counter set by smp_setup_percpu_timer() */ cpu_data(id).udelay_val = loops_per_jiffy; - cpu_find_by_mid(id, &dp); - cpu_data(id).clock_tick = - of_getintprop_default(dp, "clock-frequency", 0); + cpu_find_by_mid(id, &cpu_node); + cpu_data(id).clock_tick = prom_getintdefault(cpu_node, + "clock-frequency", 0); def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024)); - cpu_data(id).dcache_size = - of_getintprop_default(dp, "dcache-size", def); + cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", + def); def = 32; cpu_data(id).dcache_line_size = - of_getintprop_default(dp, "dcache-line-size", def); + prom_getintdefault(cpu_node, "dcache-line-size", def); def = 16 * 1024; - cpu_data(id).icache_size = - of_getintprop_default(dp, "icache-size", def); + cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", + def); def = 32; cpu_data(id).icache_line_size = - of_getintprop_default(dp, "icache-line-size", def); + prom_getintdefault(cpu_node, "icache-line-size", def); def = ((tlb_type == hypervisor) ? (3 * 1024 * 1024) : (4 * 1024 * 1024)); - cpu_data(id).ecache_size = - of_getintprop_default(dp, "ecache-size", def); + cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", + def); def = 64; cpu_data(id).ecache_line_size = - of_getintprop_default(dp, "ecache-line-size", def); + prom_getintdefault(cpu_node, "ecache-line-size", def); printk("CPU[%d]: Caches " "D[sz(%d):line_sz(%d)] " @@ -344,10 +342,10 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) prom_startcpu_cpuid(cpu, entry, cookie); } else { - struct device_node *dp; + int cpu_node; - cpu_find_by_mid(cpu, &dp); - prom_startcpu(dp->node, entry, cookie); + cpu_find_by_mid(cpu, &cpu_node); + prom_startcpu(cpu_node, entry, cookie); } for (timeout = 0; timeout < 5000000; timeout++) { @@ -1291,8 +1289,7 @@ int setup_profiling_timer(unsigned int multiplier) static void __init smp_tune_scheduling(void) { - struct device_node *dp; - int instance; + int instance, node; unsigned int def, smallest = ~0U; def = ((tlb_type == hypervisor) ? @@ -1300,10 +1297,10 @@ static void __init smp_tune_scheduling(void) (4 * 1024 * 1024)); instance = 0; - while (!cpu_find_by_instance(instance, &dp, NULL)) { + while (!cpu_find_by_instance(instance, &node, NULL)) { unsigned int val; - val = of_getintprop_default(dp, "ecache-size", def); + val = prom_getintdefault(node, "ecache-size", def); if (val < smallest) smallest = val; diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index 348b82035561..0f00a99927e9 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -48,7 +48,6 @@ #include #include #include -#include DEFINE_SPINLOCK(mostek_lock); DEFINE_SPINLOCK(rtc_lock); @@ -756,200 +755,24 @@ static int hypervisor_set_time(u32 secs) return -EOPNOTSUPP; } -static int __init clock_model_matches(char *model) -{ - if (strcmp(model, "mk48t02") && - strcmp(model, "mk48t08") && - strcmp(model, "mk48t59") && - strcmp(model, "m5819") && - strcmp(model, "m5819p") && - strcmp(model, "m5823") && - strcmp(model, "ds1287")) - return 0; - - return 1; -} - -static void __init __clock_assign_common(void __iomem *addr, char *model) -{ - if (model[5] == '0' && model[6] == '2') { - mstk48t02_regs = addr; - } else if(model[5] == '0' && model[6] == '8') { - mstk48t08_regs = addr; - mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02; - } else { - mstk48t59_regs = addr; - mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; - } -} - -static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg, - char *model) -{ - unsigned long addr; - - addr = ((unsigned long) clk_reg[0].phys_addr | - (((unsigned long) clk_reg[0].which_io) << 32UL)); - - __clock_assign_common((void __iomem *) addr, model); -} - -static int __init clock_probe_central(void) +void __init clock_probe(void) { - struct linux_prom_registers clk_reg[2], *pr; - struct device_node *dp; - char *model; - - if (!central_bus) - return 0; - - /* Get Central FHC's prom node. */ - dp = central_bus->child->prom_node; - - /* Then get the first child device below it. */ - dp = dp->child; - - while (dp) { - model = of_get_property(dp, "model", NULL); - if (!model || !clock_model_matches(model)) - goto next_sibling; - - pr = of_get_property(dp, "reg", NULL); - memcpy(clk_reg, pr, sizeof(clk_reg)); - - apply_fhc_ranges(central_bus->child, clk_reg, 1); - apply_central_ranges(central_bus, clk_reg, 1); - - clock_assign_clk_reg(clk_reg, model); - return 1; - - next_sibling: - dp = dp->sibling; - } - - return 0; -} - + struct linux_prom_registers clk_reg[2]; + char model[128]; + int node, busnd = -1, err; + unsigned long flags; + struct linux_central *cbus; #ifdef CONFIG_PCI -static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model) -{ - if (!strcmp(model, "ds1287") || - !strcmp(model, "m5819") || - !strcmp(model, "m5819p") || - !strcmp(model, "m5823")) { - ds1287_regs = res->start; - } else { - mstk48t59_regs = (void __iomem *) res->start; - mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; - } -} - -static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev) -{ - struct device_node *dp = edev->prom_node; - char *model; - - model = of_get_property(dp, "model", NULL); - if (!clock_model_matches(model)) - return 0; - - clock_isa_ebus_assign_regs(&edev->resource[0], model); - - return 1; -} - -static int __init clock_probe_ebus(void) -{ - struct linux_ebus *ebus; - - for_each_ebus(ebus) { - struct linux_ebus_device *edev; - - for_each_ebusdev(edev, ebus) { - if (clock_probe_one_ebus_dev(edev)) - return 1; - } - } - - return 0; -} - -static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev) -{ - struct device_node *dp = idev->prom_node; - char *model; - - model = of_get_property(dp, "model", NULL); - if (!clock_model_matches(model)) - return 0; - - clock_isa_ebus_assign_regs(&idev->resource, model); - - return 1; -} - -static int __init clock_probe_isa(void) -{ - struct sparc_isa_bridge *isa_br; - - for_each_isa(isa_br) { - struct sparc_isa_device *isa_dev; - - for_each_isadev(isa_dev, isa_br) { - if (clock_probe_one_isa_dev(isa_dev)) - return 1; - } - } - - return 0; -} -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_SBUS -static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev) -{ - struct resource *res; - char model[64]; - void __iomem *addr; - - prom_getstring(sdev->prom_node, "model", model, sizeof(model)); - if (!clock_model_matches(model)) - return 0; - - res = &sdev->resource[0]; - addr = sbus_ioremap(res, 0, 0x800UL, "eeprom"); - - __clock_assign_common(addr, model); - - return 1; -} - -static int __init clock_probe_sbus(void) -{ - struct sbus_bus *sbus; - - for_each_sbus(sbus) { - struct sbus_dev *sdev; - - for_each_sbusdev(sdev, sbus) { - if (clock_probe_one_sbus_dev(sbus, sdev)) - return 1; - } - } - - return 0; -} + struct linux_ebus *ebus = NULL; + struct sparc_isa_bridge *isa_br = NULL; #endif - -void __init clock_probe(void) -{ static int invoked; - unsigned long flags; if (invoked) return; invoked = 1; + if (this_is_starfire) { xtime.tv_sec = starfire_get_time(); xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); @@ -965,26 +788,182 @@ void __init clock_probe(void) return; } + local_irq_save(flags); + + cbus = central_bus; + if (cbus != NULL) + busnd = central_bus->child->prom_node; + /* Check FHC Central then EBUSs then ISA bridges then SBUSs. * That way we handle the presence of multiple properly. * * As a special case, machines with Central must provide the * timer chip there. */ - if (!clock_probe_central() && #ifdef CONFIG_PCI - !clock_probe_ebus() && - !clock_probe_isa() && -#endif -#ifdef CONFIG_SBUS - !clock_probe_sbus() + if (ebus_chain != NULL) { + ebus = ebus_chain; + if (busnd == -1) + busnd = ebus->prom_node; + } + if (isa_chain != NULL) { + isa_br = isa_chain; + if (busnd == -1) + busnd = isa_br->prom_node; + } #endif - ) { - printk(KERN_WARNING "No clock chip found.\n"); - return; + if (sbus_root != NULL && busnd == -1) + busnd = sbus_root->prom_node; + + if (busnd == -1) { + prom_printf("clock_probe: problem, cannot find bus to search.\n"); + prom_halt(); } - local_irq_save(flags); + node = prom_getchild(busnd); + + while (1) { + if (!node) + model[0] = 0; + else + prom_getstring(node, "model", model, sizeof(model)); + if (strcmp(model, "mk48t02") && + strcmp(model, "mk48t08") && + strcmp(model, "mk48t59") && + strcmp(model, "m5819") && + strcmp(model, "m5819p") && + strcmp(model, "m5823") && + strcmp(model, "ds1287")) { + if (cbus != NULL) { + prom_printf("clock_probe: Central bus lacks timer chip.\n"); + prom_halt(); + } + + if (node != 0) + node = prom_getsibling(node); +#ifdef CONFIG_PCI + while ((node == 0) && ebus != NULL) { + ebus = ebus->next; + if (ebus != NULL) { + busnd = ebus->prom_node; + node = prom_getchild(busnd); + } + } + while ((node == 0) && isa_br != NULL) { + isa_br = isa_br->next; + if (isa_br != NULL) { + busnd = isa_br->prom_node; + node = prom_getchild(busnd); + } + } +#endif + if (node == 0) { + prom_printf("clock_probe: Cannot find timer chip\n"); + prom_halt(); + } + continue; + } + + err = prom_getproperty(node, "reg", (char *)clk_reg, + sizeof(clk_reg)); + if(err == -1) { + prom_printf("clock_probe: Cannot get Mostek reg property\n"); + prom_halt(); + } + + if (cbus != NULL) { + apply_fhc_ranges(central_bus->child, clk_reg, 1); + apply_central_ranges(central_bus, clk_reg, 1); + } +#ifdef CONFIG_PCI + else if (ebus != NULL) { + struct linux_ebus_device *edev; + + for_each_ebusdev(edev, ebus) + if (edev->prom_node == node) + break; + if (edev == NULL) { + if (isa_chain != NULL) + goto try_isa_clock; + prom_printf("%s: Mostek not probed by EBUS\n", + __FUNCTION__); + prom_halt(); + } + + if (!strcmp(model, "ds1287") || + !strcmp(model, "m5819") || + !strcmp(model, "m5819p") || + !strcmp(model, "m5823")) { + ds1287_regs = edev->resource[0].start; + } else { + mstk48t59_regs = (void __iomem *) + edev->resource[0].start; + mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; + } + break; + } + else if (isa_br != NULL) { + struct sparc_isa_device *isadev; + +try_isa_clock: + for_each_isadev(isadev, isa_br) + if (isadev->prom_node == node) + break; + if (isadev == NULL) { + prom_printf("%s: Mostek not probed by ISA\n"); + prom_halt(); + } + if (!strcmp(model, "ds1287") || + !strcmp(model, "m5819") || + !strcmp(model, "m5819p") || + !strcmp(model, "m5823")) { + ds1287_regs = isadev->resource.start; + } else { + mstk48t59_regs = (void __iomem *) + isadev->resource.start; + mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; + } + break; + } +#endif + else { + if (sbus_root->num_sbus_ranges) { + int nranges = sbus_root->num_sbus_ranges; + int rngc; + + for (rngc = 0; rngc < nranges; rngc++) + if (clk_reg[0].which_io == + sbus_root->sbus_ranges[rngc].ot_child_space) + break; + if (rngc == nranges) { + prom_printf("clock_probe: Cannot find ranges for " + "clock regs.\n"); + prom_halt(); + } + clk_reg[0].which_io = + sbus_root->sbus_ranges[rngc].ot_parent_space; + clk_reg[0].phys_addr += + sbus_root->sbus_ranges[rngc].ot_parent_base; + } + } + + if(model[5] == '0' && model[6] == '2') { + mstk48t02_regs = (void __iomem *) + (((u64)clk_reg[0].phys_addr) | + (((u64)clk_reg[0].which_io)<<32UL)); + } else if(model[5] == '0' && model[6] == '8') { + mstk48t08_regs = (void __iomem *) + (((u64)clk_reg[0].phys_addr) | + (((u64)clk_reg[0].which_io)<<32UL)); + mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02; + } else { + mstk48t59_regs = (void __iomem *) + (((u64)clk_reg[0].phys_addr) | + (((u64)clk_reg[0].which_io)<<32UL)); + mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02; + } + break; + } if (mstk48t02_regs != NULL) { /* Report a low battery voltage condition. */ @@ -1004,14 +983,12 @@ void __init clock_probe(void) /* This is gets the master TICK_INT timer going. */ static unsigned long sparc64_init_timers(void) { - struct device_node *dp; - struct property *prop; unsigned long clock; + int node; #ifdef CONFIG_SMP extern void smp_tick_init(void); #endif - dp = of_find_node_by_path("/"); if (tlb_type == spitfire) { unsigned long ver, manuf, impl; @@ -1022,17 +999,18 @@ static unsigned long sparc64_init_timers(void) if (manuf == 0x17 && impl == 0x13) { /* Hummingbird, aka Ultra-IIe */ tick_ops = &hbtick_operations; - prop = of_find_property(dp, "stick-frequency", NULL); + node = prom_root_node; + clock = prom_getint(node, "stick-frequency"); } else { tick_ops = &tick_operations; - cpu_find_by_instance(0, &dp, NULL); - prop = of_find_property(dp, "clock-frequency", NULL); + cpu_find_by_instance(0, &node, NULL); + clock = prom_getint(node, "clock-frequency"); } } else { tick_ops = &stick_operations; - prop = of_find_property(dp, "stick-frequency", NULL); + node = prom_root_node; + clock = prom_getint(node, "stick-frequency"); } - clock = *(unsigned int *) prop->value; timer_tick_offset = clock / HZ; #ifdef CONFIG_SMP diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index 1ff34b019f3f..5059cbd4feee 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -42,7 +42,6 @@ #ifdef CONFIG_KMOD #include #endif -#include ATOMIC_NOTIFIER_HEAD(sparc64die_chain); @@ -808,8 +807,7 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector void __init cheetah_ecache_flush_init(void) { unsigned long largest_size, smallest_linesize, order, ver; - struct device_node *dp; - int i, instance, sz; + int node, i, instance; /* Scan all cpu device tree nodes, note two values: * 1) largest E-cache size @@ -819,14 +817,14 @@ void __init cheetah_ecache_flush_init(void) smallest_linesize = ~0UL; instance = 0; - while (!cpu_find_by_instance(instance, &dp, NULL)) { + while (!cpu_find_by_instance(instance, &node, NULL)) { unsigned long val; - val = of_getintprop_default(dp, "ecache-size", - (2 * 1024 * 1024)); + val = prom_getintdefault(node, "ecache-size", + (2 * 1024 * 1024)); if (val > largest_size) largest_size = val; - val = of_getintprop_default(dp, "ecache-line-size", 64); + val = prom_getintdefault(node, "ecache-line-size", 64); if (val < smallest_linesize) smallest_linesize = val; instance++; @@ -851,16 +849,16 @@ void __init cheetah_ecache_flush_init(void) } /* Now allocate error trap reporting scoreboard. */ - sz = NR_CPUS * (2 * sizeof(struct cheetah_err_info)); + node = NR_CPUS * (2 * sizeof(struct cheetah_err_info)); for (order = 0; order < MAX_ORDER; order++) { - if ((PAGE_SIZE << order) >= sz) + if ((PAGE_SIZE << order) >= node) break; } cheetah_error_log = (struct cheetah_err_info *) __get_free_pages(GFP_KERNEL, order); if (!cheetah_error_log) { prom_printf("cheetah_ecache_flush_init: Failed to allocate " - "error logging scoreboard (%d bytes).\n", sz); + "error logging scoreboard (%d bytes).\n", node); prom_halt(); } memset(cheetah_error_log, 0, PAGE_SIZE << order); diff --git a/trunk/arch/sparc64/kernel/unaligned.c b/trunk/arch/sparc64/kernel/unaligned.c index bb2d68577855..001e8518331f 100644 --- a/trunk/arch/sparc64/kernel/unaligned.c +++ b/trunk/arch/sparc64/kernel/unaligned.c @@ -279,21 +279,12 @@ static void kernel_mna_trap_fault(void) asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) { - static unsigned long count, last_time; enum direction dir = decode_direction(insn); int size = decode_access_size(insn); current_thread_info()->kern_una_regs = regs; current_thread_info()->kern_una_insn = insn; - if (jiffies - last_time > 5 * HZ) - count = 0; - if (count < 5) { - last_time = jiffies; - count++; - printk("Kernel unaligned access at TPC[%lx]\n", regs->tpc); - } - if (!ok_for_kernel(insn) || dir == both) { printk("Unsupported unaligned load/store trap for kernel " "at <%016lx>.\n", regs->tpc); diff --git a/trunk/arch/sparc64/mm/fault.c b/trunk/arch/sparc64/mm/fault.c index 1605967cce91..6e002aacb961 100644 --- a/trunk/arch/sparc64/mm/fault.c +++ b/trunk/arch/sparc64/mm/fault.c @@ -31,40 +31,6 @@ #include #include -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif - /* * To debug kernel to catch accesses to certain virtual/physical addresses. * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. @@ -297,7 +263,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code = get_thread_fault_code(); - if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, + if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, fault_code, 0, SIGSEGV) == NOTIFY_STOP) return; diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index cb75a27adb51..1539a8362b6f 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ #include #include #include -#include extern void device_scan(void); @@ -103,6 +101,8 @@ static void __init read_obp_memory(const char *property, prom_halt(); } + *num_ents = ents; + /* Sanitize what we got from the firmware, by page aligning * everything. */ @@ -124,25 +124,6 @@ static void __init read_obp_memory(const char *property, regs[i].phys_addr = base; regs[i].reg_size = size; } - - for (i = 0; i < ents; i++) { - if (regs[i].reg_size == 0UL) { - int j; - - for (j = i; j < ents - 1; j++) { - regs[j].phys_addr = - regs[j+1].phys_addr; - regs[j].reg_size = - regs[j+1].reg_size; - } - - ents--; - i--; - } - } - - *num_ents = ents; - sort(regs, ents, sizeof(struct linux_prom64_registers), cmp_p64, NULL); } @@ -1358,8 +1339,6 @@ void __init paging_init(void) kernel_physical_mapping_init(); - prom_build_devicetree(); - { unsigned long zones_size[MAX_NR_ZONES]; unsigned long zholes_size[MAX_NR_ZONES]; @@ -1397,7 +1376,7 @@ static void __init taint_real_pages(void) while (old_start < old_end) { int n; - for (n = 0; n < pavail_rescan_ents; n++) { + for (n = 0; pavail_rescan_ents; n++) { unsigned long new_start, new_end; new_start = pavail_rescan[n].phys_addr; @@ -1419,32 +1398,6 @@ static void __init taint_real_pages(void) } } -int __init page_in_phys_avail(unsigned long paddr) -{ - int i; - - paddr &= PAGE_MASK; - - for (i = 0; i < pavail_rescan_ents; i++) { - unsigned long start, end; - - start = pavail_rescan[i].phys_addr; - end = start + pavail_rescan[i].reg_size; - - if (paddr >= start && paddr < end) - return 1; - } - if (paddr >= kern_base && paddr < (kern_base + kern_size)) - return 1; -#ifdef CONFIG_BLK_DEV_INITRD - if (paddr >= __pa(initrd_start) && - paddr < __pa(PAGE_ALIGN(initrd_end))) - return 1; -#endif - - return 0; -} - void __init mem_init(void) { unsigned long codepages, datapages, initpages; @@ -1521,7 +1474,7 @@ void free_initmem(void) page = (addr + ((unsigned long) __va(kern_base)) - ((unsigned long) KERNBASE)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); p = virt_to_page(page); ClearPageReserved(p); @@ -1569,7 +1522,6 @@ pgprot_t PAGE_EXEC __read_mostly; unsigned long pg_iobits __read_mostly; unsigned long _PAGE_IE __read_mostly; -EXPORT_SYMBOL(_PAGE_IE); unsigned long _PAGE_E __read_mostly; EXPORT_SYMBOL(_PAGE_E); diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c index 0f0eb6aa1c40..4885ca6cbc77 100644 --- a/trunk/arch/sparc64/solaris/fs.c +++ b/trunk/arch/sparc64/solaris/fs.c @@ -356,7 +356,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf) int error; struct sol_statvfs __user *ss = A(buf); - error = vfs_statfs(mnt->mnt_root, &s); + error = vfs_statfs(mnt->mnt_sb, &s); if (!error) { const char *p = mnt->mnt_sb->s_type->name; int i = 0; @@ -392,7 +392,7 @@ static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf) int error; struct sol_statvfs64 __user *ss = A(buf); - error = vfs_statfs(mnt->mnt_root, &s); + error = vfs_statfs(mnt->mnt_sb, &s); if (!error) { const char *p = mnt->mnt_sb->s_type->name; int i = 0; diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index 719c90905a1e..5284996780a7 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "conv.h" @@ -195,17 +194,14 @@ static char *machine(void) } } -static char *platform(char *buffer, int sz) +static char *platform(char *buffer) { - struct device_node *dp = of_find_node_by_path("/"); int len; *buffer = 0; - len = strlen(dp->name); - if (len > sz) - len = sz; - memcpy(buffer, dp->name, len); - buffer[len] = 0; + len = prom_getproperty(prom_root_node, "name", buffer, 256); + if(len > 0) + buffer[len] = 0; if (*buffer) { char *p; @@ -217,22 +213,16 @@ static char *platform(char *buffer, int sz) return "sun4u"; } -static char *serial(char *buffer, int sz) +static char *serial(char *buffer) { - struct device_node *dp = of_find_node_by_path("/options"); + int node = prom_getchild(prom_root_node); int len; + node = prom_searchsiblings(node, "options"); *buffer = 0; - if (dp) { - char *val = of_get_property(dp, "system-board-serial#", &len); - - if (val && len > 0) { - if (len > sz) - len = sz; - memcpy(buffer, val, len); - buffer[len] = 0; - } - } + len = prom_getproperty(node, "system-board-serial#", buffer, 256); + if(len > 0) + buffer[len] = 0; if (!*buffer) return "4512348717234"; else @@ -315,8 +305,8 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) case SI_MACHINE: r = machine(); break; case SI_ARCHITECTURE: r = "sparc"; break; case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; - case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break; - case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break; + case SI_HW_SERIAL: r = serial(buffer); break; + case SI_PLATFORM: r = platform(buffer); break; case SI_SRPC_DOMAIN: r = ""; break; case SI_VERSION: r = "Generic"; break; default: return -EINVAL; diff --git a/trunk/arch/um/Kconfig.debug b/trunk/arch/um/Kconfig.debug index bab51d619173..5681a8bd370b 100644 --- a/trunk/arch/um/Kconfig.debug +++ b/trunk/arch/um/Kconfig.debug @@ -49,6 +49,7 @@ config GCOV config SYSCALL_DEBUG bool "Enable system call debugging" + default N depends on DEBUG_INFO help This adds some system debugging to UML, including keeping a ring buffer diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 79149314ed04..6d7173fc55a3 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -300,6 +300,8 @@ void mconsole_reboot(struct mc_request *req) machine_restart(NULL); } +extern void ctrl_alt_del(void); + void mconsole_cad(struct mc_request *req) { mconsole_reply(req, "", 0, 0); diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 290cec6d69e2..0897852b09a3 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -1222,7 +1222,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, } } - /* Successful return case! */ + /* Succesful return case! */ if(backing_file_out == NULL) return(fd); diff --git a/trunk/arch/um/include/sysdep-x86_64/syscalls.h b/trunk/arch/um/include/sysdep-x86_64/syscalls.h index 5e86aa047b2b..e06f83e80f4a 100644 --- a/trunk/arch/um/include/sysdep-x86_64/syscalls.h +++ b/trunk/arch/um/include/sysdep-x86_64/syscalls.h @@ -12,6 +12,8 @@ typedef long syscall_handler_t(void); +extern syscall_handler_t *ia32_sys_call_table[]; + extern syscall_handler_t *sys_call_table[]; #define EXECUTE_SYSCALL(syscall, regs) \ diff --git a/trunk/arch/um/kernel/time_kern.c b/trunk/arch/um/kernel/time_kern.c index 87cdbc560d36..86f51d04c98d 100644 --- a/trunk/arch/um/kernel/time_kern.c +++ b/trunk/arch/um/kernel/time_kern.c @@ -87,7 +87,7 @@ void timer_irq(union uml_pt_regs *regs) void time_init_kern(void) { - long long nsecs; + unsigned long long nsecs; nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, diff --git a/trunk/arch/um/sys-ppc/misc.S b/trunk/arch/um/sys-ppc/misc.S index f0c971db47e4..11b7bd768cfd 100644 --- a/trunk/arch/um/sys-ppc/misc.S +++ b/trunk/arch/um/sys-ppc/misc.S @@ -23,10 +23,14 @@ #define CACHE_LINE_SIZE 16 #define LG_CACHE_LINE_SIZE 4 #define MAX_COPY_PREFETCH 1 -#else +#elif !defined(CONFIG_PPC64BRIDGE) #define CACHE_LINE_SIZE 32 #define LG_CACHE_LINE_SIZE 5 #define MAX_COPY_PREFETCH 4 +#else +#define CACHE_LINE_SIZE 128 +#define LG_CACHE_LINE_SIZE 7 +#define MAX_COPY_PREFETCH 1 #endif /* CONFIG_4xx || CONFIG_8xx */ .text diff --git a/trunk/arch/v850/kernel/signal.c b/trunk/arch/v850/kernel/signal.c index 17c2d4359b04..633e4e1b825f 100644 --- a/trunk/arch/v850/kernel/signal.c +++ b/trunk/arch/v850/kernel/signal.c @@ -274,7 +274,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) /* Default to using normal stack */ unsigned long sp = regs->gpr[GPR_SP]; - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void *)((sp - frame_size) & -8UL); diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index ccc4a7fb97a3..408d44a59756 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -299,7 +299,6 @@ config X86_64_ACPI_NUMA bool "ACPI NUMA detection" depends on NUMA select ACPI - select PCI select ACPI_NUMA default y help @@ -386,47 +385,27 @@ config HPET_EMULATE_RTC bool "Provide RTC interrupt" depends on HPET_TIMER && RTC=y -# Mark as embedded because too many people got it wrong. -# The code disables itself when not needed. -config IOMMU - bool "IOMMU support" if EMBEDDED +config GART_IOMMU + bool "K8 GART IOMMU support" default y select SWIOTLB - select AGP depends on PCI 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, - sound, many IDE/SATA chipsets and some other devices. - Provides a driver for the AMD Athlon64/Opteron/Turion/Sempron GART - based IOMMU and a software bounce buffer based IOMMU used on Intel - systems and as fallback. - The code is only active when needed (enough memory and limited - device) unless CONFIG_IOMMU_DEBUG or iommu=force is specified - too. - -config CALGARY_IOMMU - bool "IBM Calgary IOMMU support" - default y - select SWIOTLB - depends on PCI && EXPERIMENTAL - help - Support for hardware IOMMUs in IBM's xSeries x366 and x460 - systems. Needed to run systems with more than 3GB of memory - properly with 32-bit PCI devices that do not support DAC - (Double Address Cycle). Calgary also supports bus level - isolation, where all DMAs pass through the IOMMU. This - prevents them from going anywhere except their intended - destination. This catches hard-to-find kernel bugs and - mis-behaving drivers and devices that do not use the DMA-API - properly to set up their DMA buffers. The IOMMU can be - turned off at boot time with the iommu=off parameter. - Normally the kernel will make the right choice by itself. - If unsure, say Y. - -# need this always selected by IOMMU for the VIA workaround + Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors + and for the bounce buffering software IOMMU. + Needed to run systems with more than 3GB of memory properly with + 32-bit PCI devices that do not support DAC (Double Address Cycle). + The IOMMU can be turned off at runtime with the iommu=off parameter. + Normally the kernel will take the right choice by itself. + This option includes a driver for the AMD Opteron/Athlon64 IOMMU + northbridge and a software emulation used on other systems without + hardware IOMMU. If unsure, say Y. + +# need this always enabled with GART_IOMMU for the VIA workaround config SWIOTLB bool + default y + depends on GART_IOMMU config X86_MCE bool "Machine check support" if EMBEDDED @@ -522,10 +501,6 @@ config REORDER optimal TLB usage. If you have pretty much any version of binutils, this can increase your kernel build time by roughly one minute. -config K8_NB - def_bool y - depends on AGP_AMD64 || IOMMU || (PCI && NUMA) - endmenu # diff --git a/trunk/arch/x86_64/Kconfig.debug b/trunk/arch/x86_64/Kconfig.debug index 1d92ab56c0f9..ea31b4c62105 100644 --- a/trunk/arch/x86_64/Kconfig.debug +++ b/trunk/arch/x86_64/Kconfig.debug @@ -13,7 +13,7 @@ config DEBUG_RODATA If in doubt, say "N". config IOMMU_DEBUG - depends on IOMMU && DEBUG_KERNEL + depends on GART_IOMMU && DEBUG_KERNEL bool "Enable IOMMU debugging" help Force the IOMMU to on even when you have less than 4GB of @@ -35,22 +35,6 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -config DEBUG_STACKOVERFLOW - bool "Check for stack overflows" - depends on DEBUG_KERNEL - help - This option will cause messages to be printed if free stack space - drops below a certain limit. - -config DEBUG_STACK_USAGE - bool "Stack utilization instrumentation" - depends on DEBUG_KERNEL - help - Enables the display of the minimum amount of free stack which each - task has ever had available in the sysrq-T and sysrq-P debug output. - - This option will slow down process creation somewhat. - #config X86_REMOTE_DEBUG # bool "kgdb debugging stub" diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 431bb4bc36cd..e573e2ab5510 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -27,7 +27,6 @@ LDFLAGS_vmlinux := CHECKFLAGS += -D__x86_64__ -m64 cflags-y := -cflags-kernel-y := cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) @@ -36,7 +35,7 @@ cflags-y += -m64 cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel cflags-y += -pipe -cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections +cflags-$(CONFIG_REORDER) += -ffunction-sections # this makes reading assembly source easier, but produces worse code # actually it makes the kernel smaller too. cflags-y += -fno-reorder-blocks @@ -56,7 +55,6 @@ cflags-y += $(call cc-option,-funit-at-a-time) cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) CFLAGS += $(cflags-y) -CFLAGS_KERNEL += $(cflags-kernel-y) AFLAGS += -m64 head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o diff --git a/trunk/arch/x86_64/boot/Makefile b/trunk/arch/x86_64/boot/Makefile index deb063e7762d..43ee6c50c277 100644 --- a/trunk/arch/x86_64/boot/Makefile +++ b/trunk/arch/x86_64/boot/Makefile @@ -107,13 +107,8 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf isoimage: $(BOOTIMAGE) -rm -rf $(obj)/isoimage mkdir $(obj)/isoimage - for i in lib lib64 share end ; do \ - if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ - cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ - break ; \ - fi ; \ - if [ $$i = end ] ; then exit 1 ; fi ; \ - done + cp `echo /usr/lib*/syslinux/isolinux.bin | awk '{ print $1; }'` \ + $(obj)/isoimage cp $(BOOTIMAGE) $(obj)/isoimage/linux echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg if [ -f '$(FDINITRD)' ] ; then \ diff --git a/trunk/arch/x86_64/boot/compressed/misc.c b/trunk/arch/x86_64/boot/compressed/misc.c index 3755b2e394d0..cf4b88c416dc 100644 --- a/trunk/arch/x86_64/boot/compressed/misc.c +++ b/trunk/arch/x86_64/boot/compressed/misc.c @@ -77,11 +77,11 @@ static void gzip_release(void **); */ static unsigned char *real_mode; /* Pointer to real-mode data */ -#define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) +#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) +#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) +#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern unsigned char input_data[]; extern int input_len; @@ -92,9 +92,9 @@ static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); - -static void *memset(void *s, int c, unsigned n); -static void *memcpy(void *dest, const void *src, unsigned n); + +void* memset(void* s, int c, unsigned n); +void* memcpy(void* dest, const void* src, unsigned n); static void putstr(const char *); @@ -162,8 +162,8 @@ static void putstr(const char *s) int x,y,pos; char c; - x = RM_SCREEN_INFO.orig_x; - y = RM_SCREEN_INFO.orig_y; + x = SCREEN_INFO.orig_x; + y = SCREEN_INFO.orig_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { @@ -184,8 +184,8 @@ static void putstr(const char *s) } } - RM_SCREEN_INFO.orig_x = x; - RM_SCREEN_INFO.orig_y = y; + SCREEN_INFO.orig_x = x; + SCREEN_INFO.orig_y = y; pos = (x + cols * y) * 2; /* Update cursor position */ outb_p(14, vidport); @@ -194,7 +194,7 @@ static void putstr(const char *s) outb_p(0xff & (pos >> 1), vidport+1); } -static void* memset(void* s, int c, unsigned n) +void* memset(void* s, int c, unsigned n) { int i; char *ss = (char*)s; @@ -203,7 +203,7 @@ static void* memset(void* s, int c, unsigned n) return s; } -static void* memcpy(void* dest, const void* src, unsigned n) +void* memcpy(void* dest, const void* src, unsigned n) { int i; char *d = (char *)dest, *s = (char *)src; @@ -278,15 +278,15 @@ static void error(char *x) putstr(x); putstr("\n\n -- System halted"); - while(1); /* Halt */ + while(1); } -static void setup_normal_output_buffer(void) +void setup_normal_output_buffer(void) { #ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); + if (EXT_MEM_K < 1024) error("Less than 2MB of memory"); #else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); + if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; @@ -297,13 +297,13 @@ struct moveparams { uch *high_buffer_start; int hcount; }; -static void setup_output_buffer_if_we_run_high(struct moveparams *mv) +void setup_output_buffer_if_we_run_high(struct moveparams *mv) { high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); #ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); + if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); #else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); + if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); #endif mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX @@ -319,7 +319,7 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) mv->high_buffer_start = high_buffer_start; } -static void close_output_buffer_if_we_run_high(struct moveparams *mv) +void close_output_buffer_if_we_run_high(struct moveparams *mv) { if (bytes_out > low_buffer_size) { mv->lcount = low_buffer_size; @@ -335,7 +335,7 @@ int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; - if (RM_SCREEN_INFO.orig_video_mode == 7) { + if (SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { @@ -343,8 +343,8 @@ int decompress_kernel(struct moveparams *mv, void *rmode) vidport = 0x3d4; } - lines = RM_SCREEN_INFO.orig_video_lines; - cols = RM_SCREEN_INFO.orig_video_cols; + lines = SCREEN_INFO.orig_video_lines; + cols = SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); diff --git a/trunk/arch/x86_64/boot/tools/build.c b/trunk/arch/x86_64/boot/tools/build.c index eae86691709a..c44f5e2ec100 100644 --- a/trunk/arch/x86_64/boot/tools/build.c +++ b/trunk/arch/x86_64/boot/tools/build.c @@ -149,8 +149,10 @@ int main(int argc, char ** argv) sz = sb.st_size; fprintf (stderr, "System is %d kB\n", sz/1024); sys_size = (sz + 15) / 16; - if (!is_big_kernel && sys_size > DEF_SYSSIZE) - die("System is too big. Try using bzImage or modules."); + /* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */ + if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE)) + die("System is too big. Try using %smodules.", + is_big_kernel ? "" : "bzImage or "); while (sz > 0) { int l, n; diff --git a/trunk/arch/x86_64/boot/video.S b/trunk/arch/x86_64/boot/video.S index 2aa565c136e5..32327bb37aff 100644 --- a/trunk/arch/x86_64/boot/video.S +++ b/trunk/arch/x86_64/boot/video.S @@ -1929,7 +1929,6 @@ skip10: movb %ah, %al ret store_edid: -#ifdef CONFIG_FIRMWARE_EDID pushw %es # just save all registers pushw %ax pushw %bx @@ -1947,22 +1946,6 @@ store_edid: rep stosl - pushw %es # save ES - xorw %di, %di # Report Capability - pushw %di - popw %es # ES:DI must be 0:0 - movw $0x4f15, %ax - xorw %bx, %bx - xorw %cx, %cx - int $0x10 - popw %es # restore ES - - cmpb $0x00, %ah # call successful - jne no_edid - - cmpb $0x4f, %al # function supported - jne no_edid - movw $0x4f15, %ax # do VBE/DDC movw $0x01, %bx movw $0x00, %cx @@ -1970,14 +1953,12 @@ store_edid: movw $0x140, %di int $0x10 -no_edid: popw %di # restore all registers popw %dx popw %cx popw %bx popw %ax popw %es -#endif ret # VIDEO_SELECT-only variables diff --git a/trunk/arch/x86_64/crypto/aes-x86_64-asm.S b/trunk/arch/x86_64/crypto/aes-x86_64-asm.S index 26b40de4d0b0..483cbb23ab8d 100644 --- a/trunk/arch/x86_64/crypto/aes-x86_64-asm.S +++ b/trunk/arch/x86_64/crypto/aes-x86_64-asm.S @@ -15,10 +15,6 @@ .text -#include - -#define BASE crypto_tfm_ctx_offset - #define R1 %rax #define R1E %eax #define R1X %ax @@ -50,19 +46,19 @@ #define R10 %r10 #define R11 %r11 -#define prologue(FUNC,KEY,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ +#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ .global FUNC; \ .type FUNC,@function; \ .align 8; \ FUNC: movq r1,r2; \ movq r3,r4; \ - leaq BASE+KEY+52(r8),r9; \ + leaq BASE+52(r8),r9; \ movq r10,r11; \ movl (r7),r5 ## E; \ movl 4(r7),r1 ## E; \ movl 8(r7),r6 ## E; \ movl 12(r7),r7 ## E; \ - movl BASE(r8),r10 ## E; \ + movl (r8),r10 ## E; \ xorl -48(r9),r5 ## E; \ xorl -44(r9),r1 ## E; \ xorl -40(r9),r6 ## E; \ @@ -132,8 +128,8 @@ FUNC: movq r1,r2; \ movl r3 ## E,r1 ## E; \ movl r4 ## E,r2 ## E; -#define entry(FUNC,KEY,B128,B192) \ - prologue(FUNC,KEY,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) +#define entry(FUNC,BASE,B128,B192) \ + prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) #define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11) @@ -151,9 +147,9 @@ FUNC: movq r1,r2; \ #define decrypt_final(TAB,OFFSET) \ round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) -/* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */ +/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */ - entry(aes_enc_blk,0,enc128,enc192) + entry(aes_encrypt,0,enc128,enc192) encrypt_round(aes_ft_tab,-96) encrypt_round(aes_ft_tab,-80) enc192: encrypt_round(aes_ft_tab,-64) @@ -170,9 +166,9 @@ enc128: encrypt_round(aes_ft_tab,-32) encrypt_final(aes_fl_tab,112) return -/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */ +/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */ - entry(aes_dec_blk,240,dec128,dec192) + entry(aes_decrypt,240,dec128,dec192) decrypt_round(aes_it_tab,-96) decrypt_round(aes_it_tab,-80) dec192: decrypt_round(aes_it_tab,-64) diff --git a/trunk/arch/x86_64/crypto/aes.c b/trunk/arch/x86_64/crypto/aes.c index 68866fab37aa..6f77e7700d32 100644 --- a/trunk/arch/x86_64/crypto/aes.c +++ b/trunk/arch/x86_64/crypto/aes.c @@ -227,10 +227,10 @@ static void __init gen_tabs(void) t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ } -static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, + u32 *flags) { - struct aes_ctx *ctx = crypto_tfm_ctx(tfm); + struct aes_ctx *ctx = ctx_arg; const __le32 *key = (const __le32 *)in_key; u32 i, j, t, u, v, w; @@ -283,18 +283,8 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, return 0; } -asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); -asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); - -static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - aes_enc_blk(tfm, dst, src); -} - -static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - aes_dec_blk(tfm, dst, src); -} +extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in); +extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in); static struct crypto_alg aes_alg = { .cra_name = "aes", diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index e69d403949c8..69db0c0721d1 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git6 -# Sat Jun 24 00:52:28 2006 +# Linux kernel version: 2.6.17-rc1-git11 +# Sun Apr 16 07:22:36 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -42,6 +42,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y +CONFIG_VM86=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y @@ -56,6 +57,7 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_DOUBLEFAULT=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -142,8 +144,7 @@ CONFIG_NR_CPUS=32 CONFIG_HOTPLUG_CPU=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y -CONFIG_IOMMU=y -# CONFIG_CALGARY_IOMMU is not set +CONFIG_GART_IOMMU=y CONFIG_SWIOTLB=y CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y @@ -157,7 +158,6 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_REORDER is not set -CONFIG_K8_NB=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -293,8 +293,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -307,10 +305,7 @@ CONFIG_IPV6=y # CONFIG_INET6_IPCOMP is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_IPV6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -349,7 +344,6 @@ CONFIG_IPV6=y # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -366,7 +360,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -533,7 +526,6 @@ CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_MV is not set CONFIG_SCSI_SATA_NV=y # CONFIG_SCSI_PDC_ADMA is not set -# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_PROMISE is not set # CONFIG_SCSI_SATA_SX4 is not set @@ -599,7 +591,10 @@ CONFIG_IEEE1394=y # # Device Drivers # -# CONFIG_IEEE1394_PCILYNX is not set + +# +# Texas Instruments PCILynx requires I2C +# CONFIG_IEEE1394_OHCI1394=y # @@ -650,16 +645,7 @@ CONFIG_VORTEX=y # # Tulip family network device support # -CONFIG_NET_TULIP=y -# CONFIG_DE2104X is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_TULIP_NAPI is not set -# CONFIG_DE4X5 is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_DM9102 is not set -# CONFIG_ULI526X is not set +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set @@ -711,7 +697,6 @@ CONFIG_TIGON3=y # CONFIG_IXGB is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -902,56 +887,7 @@ CONFIG_HPET_MMAP=y # # I2C support # -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_ISA=m -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C is not set # # SPI support @@ -962,51 +898,14 @@ CONFIG_I2C_ISA=m # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -CONFIG_SENSORS_SMSC47B397=m -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -1019,7 +918,6 @@ CONFIG_SENSORS_SMSC47B397=m # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1055,17 +953,28 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y +CONFIG_OBSOLETE_OSS_DRIVER=y # CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set CONFIG_SOUND_ICH=y +# CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set # # USB support @@ -1091,7 +1000,6 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1181,12 +1089,10 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1234,19 +1140,6 @@ CONFIG_USB_MON=y # # CONFIG_RTC_CLASS is not set -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - # # Firmware Drivers # @@ -1282,7 +1175,6 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y @@ -1439,8 +1331,7 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y +# CONFIG_UNWIND_INFO is not set # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_RODATA is not set diff --git a/trunk/arch/x86_64/ia32/fpu32.c b/trunk/arch/x86_64/ia32/fpu32.c index 2c8209a3605a..1c23095f1813 100644 --- a/trunk/arch/x86_64/ia32/fpu32.c +++ b/trunk/arch/x86_64/ia32/fpu32.c @@ -2,6 +2,7 @@ * Copyright 2002 Andi Kleen, SuSE Labs. * FXSAVE<->i387 conversion support. Based on code by Gareth Hughes. * This is used for ptrace, signals and coredumps in 32bit emulation. + * $Id: fpu32.c,v 1.1 2002/03/21 14:16:32 ak Exp $ */ #include diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index 25e5ca22204c..e0a92439f634 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -6,6 +6,8 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen + * + * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $ */ #include diff --git a/trunk/arch/x86_64/ia32/ia32entry.S b/trunk/arch/x86_64/ia32/ia32entry.S index c536fa98ea37..5a92fed2d1d5 100644 --- a/trunk/arch/x86_64/ia32/ia32entry.S +++ b/trunk/arch/x86_64/ia32/ia32entry.S @@ -155,7 +155,6 @@ sysenter_tracesys: .previous jmp sysenter_do_call CFI_ENDPROC -ENDPROC(ia32_sysenter_target) /* * 32bit SYSCALL instruction entry. @@ -179,7 +178,7 @@ ENDPROC(ia32_sysenter_target) */ ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple - CFI_DEF_CFA rsp,PDA_STACKOFFSET + CFI_DEF_CFA rsp,0 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ swapgs @@ -250,7 +249,6 @@ cstar_tracesys: .quad 1b,ia32_badarg .previous jmp cstar_do_call -END(ia32_cstar_target) ia32_badarg: movq $-EFAULT,%rax @@ -316,13 +314,16 @@ ia32_tracesys: LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST jmp ia32_do_syscall -END(ia32_syscall) ia32_badsys: movq $0,ORIG_RAX-ARGOFFSET(%rsp) movq $-ENOSYS,RAX-ARGOFFSET(%rsp) jmp int_ret_from_sys_call +ni_syscall: + movq %rax,%rdi + jmp sys32_ni_syscall + quiet_ni_syscall: movq $-ENOSYS,%rax ret @@ -369,10 +370,10 @@ ENTRY(ia32_ptregs_common) RESTORE_REST jmp ia32_sysret /* misbalances the return cache */ CFI_ENDPROC -END(ia32_ptregs_common) .section .rodata,"a" .align 8 + .globl ia32_sys_call_table ia32_sys_call_table: .quad sys_restart_syscall .quad sys_exit @@ -695,5 +696,4 @@ ia32_sys_call_table: .quad sys_sync_file_range .quad sys_tee .quad compat_sys_vmsplice - .quad compat_sys_move_pages ia32_syscall_end: diff --git a/trunk/arch/x86_64/ia32/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index a590b7a0d92d..23a4515a73b4 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/arch/x86_64/ia32/ptrace32.c @@ -7,6 +7,8 @@ * * This allows to access 64bit processes too; but there is no way to see the extended * register contents. + * + * $Id: ptrace32.c,v 1.16 2003/03/14 16:06:35 ak Exp $ */ #include @@ -25,7 +27,6 @@ #include #include #include -#include /* * Determines which flags the user has access to [1 = access, 0 = no access]. @@ -198,24 +199,6 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) #undef R32 -static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) -{ - int ret; - compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); - siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); - if (request == PTRACE_SETSIGINFO) { - ret = copy_siginfo_from_user32(si, si32); - if (ret) - return ret; - } - ret = sys_ptrace(request, pid, addr, (unsigned long)si); - if (ret) - return ret; - if (request == PTRACE_GETSIGINFO) - ret = copy_siginfo_to_user32(si32, si); - return ret; -} - asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) { struct task_struct *child; @@ -225,18 +208,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) __u32 val; switch (request) { - case PTRACE_TRACEME: - case PTRACE_ATTACH: - case PTRACE_KILL: - case PTRACE_CONT: - case PTRACE_SINGLESTEP: - case PTRACE_DETACH: - case PTRACE_SYSCALL: - case PTRACE_SETOPTIONS: - return sys_ptrace(request, pid, addr, data); - default: - return -EINVAL; + return sys_ptrace(request, pid, addr, data); case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: @@ -252,11 +225,10 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_GETFPXREGS: case PTRACE_GETEVENTMSG: break; + } - case PTRACE_SETSIGINFO: - case PTRACE_GETSIGINFO: - return ptrace32_siginfo(request, pid, addr, data); - } + if (request == PTRACE_TRACEME) + return ptrace_traceme(); child = ptrace_get_task_struct(pid); if (IS_ERR(child)) @@ -377,7 +349,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) break; default: - BUG(); + ret = -EINVAL; + break; } out: diff --git a/trunk/arch/x86_64/ia32/sys_ia32.c b/trunk/arch/x86_64/ia32/sys_ia32.c index dc88154c412b..f182b20858e2 100644 --- a/trunk/arch/x86_64/ia32/sys_ia32.c +++ b/trunk/arch/x86_64/ia32/sys_ia32.c @@ -508,6 +508,19 @@ sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) return compat_sys_wait4(pid, stat_addr, options, NULL); } +int sys32_ni_syscall(int call) +{ + struct task_struct *me = current; + static char lastcomm[sizeof(me->comm)]; + + if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { + printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", + call, me->comm); + strncpy(lastcomm, me->comm, sizeof(lastcomm)); + } + return -ENOSYS; +} + /* 32-bit timeval and related flotsam. */ asmlinkage long @@ -903,7 +916,7 @@ long sys32_vm86_warning(void) struct task_struct *me = current; static char lastcomm[sizeof(me->comm)]; if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { - compat_printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", + printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", me->comm); strncpy(lastcomm, me->comm, sizeof(lastcomm)); } @@ -916,3 +929,13 @@ long sys32_lookup_dcookie(u32 addr_low, u32 addr_high, return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len); } +static int __init ia32_init (void) +{ + printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n"); + return 0; +} + +__initcall(ia32_init); + +extern unsigned long ia32_sys_call_table[]; +EXPORT_SYMBOL(ia32_sys_call_table); diff --git a/trunk/arch/x86_64/kernel/Makefile b/trunk/arch/x86_64/kernel/Makefile index aeb9c560be88..059c88313f4e 100644 --- a/trunk/arch/x86_64/kernel/Makefile +++ b/trunk/arch/x86_64/kernel/Makefile @@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ - pci-dma.o pci-nommu.o alternative.o + pci-dma.o pci-nommu.o obj-$(CONFIG_X86_MCE) += mce.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o @@ -28,13 +28,11 @@ obj-$(CONFIG_PM) += suspend.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o -obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o +obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_X86_VSMP) += vsmp.o -obj-$(CONFIG_K8_NB) += k8.o obj-$(CONFIG_MODULES) += module.o @@ -51,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o -alternative-y += ../../i386/kernel/alternative.o - diff --git a/trunk/arch/x86_64/kernel/acpi/Makefile b/trunk/arch/x86_64/kernel/acpi/Makefile index 080b9963f1bc..4fe97071f297 100644 --- a/trunk/arch/x86_64/kernel/acpi/Makefile +++ b/trunk/arch/x86_64/kernel/acpi/Makefile @@ -4,6 +4,5 @@ obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o ifneq ($(CONFIG_ACPI_PROCESSOR),) obj-y += processor.o -processor-y := ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o endif diff --git a/trunk/arch/x86_64/kernel/acpi/processor.c b/trunk/arch/x86_64/kernel/acpi/processor.c new file mode 100644 index 000000000000..3bdc2baa5bb1 --- /dev/null +++ b/trunk/arch/x86_64/kernel/acpi/processor.c @@ -0,0 +1,72 @@ +/* + * arch/x86_64/kernel/acpi/processor.c + * + * Copyright (C) 2005 Intel Corporation + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ + +#include +#include +#include +#include + +#include +#include + +static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return; + } + + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + pr->pdc = obj_list; + + return; +} + +/* Initialize _PDC data based on the CPU vendor */ +void arch_acpi_processor_init_pdc(struct acpi_processor *pr) +{ + unsigned int cpu = pr->id; + struct cpuinfo_x86 *c = cpu_data + cpu; + + pr->pdc = NULL; + if (c->x86_vendor == X86_VENDOR_INTEL && cpu_has(c, X86_FEATURE_EST)) + init_intel_pdc(pr, c); + + return; +} + +EXPORT_SYMBOL(arch_acpi_processor_init_pdc); diff --git a/trunk/arch/x86_64/kernel/acpi/sleep.c b/trunk/arch/x86_64/kernel/acpi/sleep.c index 091bc79c888f..867a0ebee177 100644 --- a/trunk/arch/x86_64/kernel/acpi/sleep.c +++ b/trunk/arch/x86_64/kernel/acpi/sleep.c @@ -35,8 +35,6 @@ #include #include #include -#include - #include #include #include @@ -68,8 +66,7 @@ static void init_low_mapping(void) pgd_t *slot0 = pgd_offset(current->mm, 0UL); low_ptr = *slot0; set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); - WARN_ON(num_online_cpus() != 1); - local_flush_tlb(); + flush_tlb_all(); } /** @@ -95,7 +92,7 @@ int acpi_save_state_mem(void) void acpi_restore_state_mem(void) { set_pgd(pgd_offset(current->mm, 0UL), low_ptr); - local_flush_tlb(); + flush_tlb_all(); } /** diff --git a/trunk/arch/x86_64/kernel/aperture.c b/trunk/arch/x86_64/kernel/aperture.c index a195ef06ec55..70b9d21ed675 100644 --- a/trunk/arch/x86_64/kernel/aperture.c +++ b/trunk/arch/x86_64/kernel/aperture.c @@ -8,6 +8,7 @@ * because only the bootmem allocator can allocate 32+MB. * * Copyright 2002 Andi Kleen, SuSE Labs. + * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $ */ #include #include @@ -23,7 +24,6 @@ #include #include #include -#include int iommu_aperture; int iommu_aperture_disabled __initdata = 0; @@ -37,6 +37,8 @@ int fix_aperture __initdata = 1; /* This code runs before the PCI subsystem is initialized, so just access the northbridge directly. */ +#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) + static u32 __init allocate_aperture(void) { pg_data_t *nd0 = NODE_DATA(0); @@ -66,20 +68,20 @@ static u32 __init allocate_aperture(void) return (u32)__pa(p); } -static int __init aperture_valid(u64 aper_base, u32 aper_size) +static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) { if (!aper_base) return 0; if (aper_size < 64*1024*1024) { - printk("Aperture too small (%d MB)\n", aper_size>>20); + printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20); return 0; } if (aper_base + aper_size >= 0xffffffff) { - printk("Aperture beyond 4GB. Ignoring.\n"); + printk("Aperture from %s beyond 4GB. Ignoring.\n",name); return 0; } if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { - printk("Aperture pointing to e820 RAM. Ignoring.\n"); + printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); return 0; } return 1; @@ -138,7 +140,7 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", aper, 32 << *order, apsizereg); - if (!aperture_valid(aper, (32*1024*1024) << *order)) + if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order)) return 0; return (u32)aper; } @@ -206,10 +208,10 @@ void __init iommu_hole_init(void) fix = 0; for (num = 24; num < 32; num++) { - if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) - continue; + char name[30]; + if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) + continue; - iommu_detected = 1; iommu_aperture = 1; aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; @@ -220,7 +222,9 @@ void __init iommu_hole_init(void) printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, aper_base, aper_size>>20); - if (!aperture_valid(aper_base, aper_size)) { + sprintf(name, "northbridge cpu %d", num-24); + + if (!aperture_valid(name, aper_base, aper_size)) { fix = 1; break; } @@ -269,7 +273,7 @@ void __init iommu_hole_init(void) /* Fix up the north bridges */ for (num = 24; num < 32; num++) { - if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) + if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) continue; /* Don't enable translation yet. That is done later. diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index b2ead91df218..100a30c40044 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -51,7 +51,7 @@ int disable_apic_timer __initdata; static cpumask_t timer_interrupt_broadcast_ipi_mask; /* Using APIC to generate smp_local_timer_interrupt? */ -int using_apic_timer __read_mostly = 0; +int using_apic_timer = 0; static void apic_pm_activate(void); @@ -100,7 +100,7 @@ void clear_local_APIC(void) maxlvt = get_maxlvt(); /* - * Masking an LVT entry can trigger a local APIC error + * Masking an LVT entry on a P6 can trigger a local APIC error * if the vector is zero. Mask LVTERR first to prevent this. */ if (maxlvt >= 3) { @@ -851,18 +851,7 @@ void disable_APIC_timer(void) unsigned long v; v = apic_read(APIC_LVTT); - /* - * When an illegal vector value (0-15) is written to an LVT - * entry and delivery mode is Fixed, the APIC may signal an - * illegal vector error, with out regard to whether the mask - * bit is set or whether an interrupt is actually seen on input. - * - * Boot sequence might call this function when the LVTT has - * '0' vector value. So make sure vector field is set to - * valid value. - */ - v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); - apic_write(APIC_LVTT, v); + apic_write(APIC_LVTT, v | APIC_LVT_MASKED); } } @@ -920,13 +909,15 @@ int setup_profiling_timer(unsigned int multiplier) return -EINVAL; } -void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, - unsigned char msg_type, unsigned char mask) +#ifdef CONFIG_X86_MCE_AMD +void setup_threshold_lvt(unsigned long lvt_off) { - unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE; - unsigned int v = (mask << 16) | (msg_type << 8) | vector; + unsigned int v = 0; + unsigned long reg = (lvt_off << 4) + 0x500; + v |= THRESHOLD_APIC_VECTOR; apic_write(reg, v); } +#endif /* CONFIG_X86_MCE_AMD */ #undef APIC_DIVISOR @@ -992,7 +983,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) } /* - * apic_is_clustered_box() -- Check if we can expect good TSC + * oem_force_hpet_timer -- force HPET mode for some boxes. * * Thus far, the major user of this is IBM's Summit2 series: * @@ -1000,7 +991,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) * multi-chassis. Use available data to take a good guess. * If in doubt, go HPET. */ -__cpuinit int apic_is_clustered_box(void) +__cpuinit int oem_force_hpet_timer(void) { int i, clusters, zeros; unsigned id; @@ -1031,7 +1022,8 @@ __cpuinit int apic_is_clustered_box(void) } /* - * If clusters > 2, then should be multi-chassis. + * If clusters > 2, then should be multi-chassis. Return 1 for HPET. + * Else return 0 to use TSC. * May have to revisit this when multi-core + hyperthreaded CPUs come * out, but AFAIK this will work even for them. */ diff --git a/trunk/arch/x86_64/kernel/asm-offsets.c b/trunk/arch/x86_64/kernel/asm-offsets.c index 96687e2beb2c..38834bbbae11 100644 --- a/trunk/arch/x86_64/kernel/asm-offsets.c +++ b/trunk/arch/x86_64/kernel/asm-offsets.c @@ -4,7 +4,6 @@ * and format the required data. */ -#include #include #include #include @@ -69,7 +68,5 @@ int main(void) DEFINE(pbe_next, offsetof(struct pbe, next)); BLANK(); DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); - BLANK(); - DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); return 0; } diff --git a/trunk/arch/x86_64/kernel/crash.c b/trunk/arch/x86_64/kernel/crash.c index d8d5750d6106..4e6c3b729e39 100644 --- a/trunk/arch/x86_64/kernel/crash.c +++ b/trunk/arch/x86_64/kernel/crash.c @@ -111,14 +111,14 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ for(;;) - halt(); + asm("hlt"); return 1; } static void smp_send_nmi_allbutself(void) { - send_IPI_allbutself(NMI_VECTOR); + send_IPI_allbutself(APIC_DM_NMI); } /* @@ -161,7 +161,7 @@ void machine_crash_shutdown(struct pt_regs *regs) { /* * This function is only called after the system - * has panicked or is otherwise in a critical state. + * has paniced or is otherwise in a critical state. * The minimum amount of code to allow a kexec'd kernel * to run successfully needs to happen here. * diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index 9e94d834624b..1ef6028f721e 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -1,6 +1,7 @@ /* * Handle the memory map. * The functions here do the job until bootmem takes over. + * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ * * Getting sanitize_e820_map() in sync with i386 version by applying change: * - Provisions for empty E820 memory regions (reported by certain BIOSes). @@ -620,7 +621,6 @@ void __init parse_memmapopt(char *p, char **from) } unsigned long pci_mem_start = 0xaeedbabe; -EXPORT_SYMBOL(pci_mem_start); /* * Search for the biggest gap in the low 32 bits of the e820 diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 22cac4487b57..586b34c00c48 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -154,7 +154,6 @@ rff_trace: GET_THREAD_INFO(%rcx) jmp rff_action CFI_ENDPROC -END(ret_from_fork) /* * System call entry. Upto 6 arguments in registers are supported. @@ -189,7 +188,7 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple - CFI_DEF_CFA rsp,PDA_STACKOFFSET + CFI_DEF_CFA rsp,0 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ swapgs @@ -286,7 +285,6 @@ tracesys: /* Use IRET because user could have changed frame */ jmp int_ret_from_sys_call CFI_ENDPROC -END(system_call) /* * Syscall return path ending with IRET. @@ -366,7 +364,6 @@ int_restore_rest: cli jmp int_with_check CFI_ENDPROC -END(int_ret_from_sys_call) /* * Certain special system calls that need to save a complete full stack frame. @@ -378,7 +375,6 @@ END(int_ret_from_sys_call) leaq \func(%rip),%rax leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */ jmp ptregscall_common -END(\label) .endm CFI_STARTPROC @@ -408,7 +404,6 @@ ENTRY(ptregscall_common) CFI_REL_OFFSET rip, 0 ret CFI_ENDPROC -END(ptregscall_common) ENTRY(stub_execve) CFI_STARTPROC @@ -423,7 +418,6 @@ ENTRY(stub_execve) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC -END(stub_execve) /* * sigreturn is special because it needs to restore all registers on return. @@ -441,7 +435,6 @@ ENTRY(stub_rt_sigreturn) RESTORE_REST jmp int_ret_from_sys_call CFI_ENDPROC -END(stub_rt_sigreturn) /* * initial frame state for interrupts and exceptions @@ -473,18 +466,29 @@ END(stub_rt_sigreturn) /* 0(%rsp): interrupt number */ .macro interrupt func cld - SAVE_ARGS - leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler - pushq %rbp - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbp, 0 +#ifdef CONFIG_DEBUG_INFO + SAVE_ALL + movq %rsp,%rdi + /* + * Setup a stack frame pointer. This allows gdb to trace + * back to the original stack. + */ movq %rsp,%rbp CFI_DEF_CFA_REGISTER rbp +#else + SAVE_ARGS + leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler +#endif testl $3,CS(%rdi) je 1f swapgs 1: incl %gs:pda_irqcount # RED-PEN should check preempt count - cmoveq %gs:pda_irqstackptr,%rsp + movq %gs:pda_irqstackptr,%rax + cmoveq %rax,%rsp /*todo This needs CFI annotation! */ + pushq %rdi # save old stack +#ifndef CONFIG_DEBUG_INFO + CFI_ADJUST_CFA_OFFSET 8 +#endif call \func .endm @@ -493,11 +497,17 @@ ENTRY(common_interrupt) interrupt do_IRQ /* 0(%rsp): oldrsp-ARGOFFSET */ ret_from_intr: + popq %rdi +#ifndef CONFIG_DEBUG_INFO + CFI_ADJUST_CFA_OFFSET -8 +#endif cli decl %gs:pda_irqcount - leaveq +#ifdef CONFIG_DEBUG_INFO + movq RBP(%rdi),%rbp CFI_DEF_CFA_REGISTER rsp - CFI_ADJUST_CFA_OFFSET -8 +#endif + leaq ARGOFFSET(%rdi),%rsp /*todo This needs CFI annotation! */ exit_intr: GET_THREAD_INFO(%rcx) testl $3,CS-ARGOFFSET(%rsp) @@ -579,16 +589,14 @@ retint_kernel: call preempt_schedule_irq jmp exit_intr #endif - CFI_ENDPROC -END(common_interrupt) /* * APIC interrupts. */ .macro apicinterrupt num,func INTR_FRAME - pushq $~(\num) + pushq $\num-256 CFI_ADJUST_CFA_OFFSET 8 interrupt \func jmp ret_from_intr @@ -597,21 +605,17 @@ END(common_interrupt) ENTRY(thermal_interrupt) apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt -END(thermal_interrupt) ENTRY(threshold_interrupt) apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt -END(threshold_interrupt) #ifdef CONFIG_SMP ENTRY(reschedule_interrupt) apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt -END(reschedule_interrupt) .macro INVALIDATE_ENTRY num ENTRY(invalidate_interrupt\num) apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt -END(invalidate_interrupt\num) .endm INVALIDATE_ENTRY 0 @@ -625,21 +629,17 @@ END(invalidate_interrupt\num) ENTRY(call_function_interrupt) apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt -END(call_function_interrupt) #endif #ifdef CONFIG_X86_LOCAL_APIC ENTRY(apic_timer_interrupt) apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt -END(apic_timer_interrupt) ENTRY(error_interrupt) apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt -END(error_interrupt) ENTRY(spurious_interrupt) apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt -END(spurious_interrupt) #endif /* @@ -777,7 +777,6 @@ error_kernelspace: cmpq $gs_change,RIP(%rsp) je error_swapgs jmp error_sti -END(error_entry) /* Reload gs selector with exception handling */ /* edi: new selector */ @@ -795,7 +794,6 @@ gs_change: CFI_ADJUST_CFA_OFFSET -8 ret CFI_ENDPROC -ENDPROC(load_gs_index) .section __ex_table,"a" .align 8 @@ -849,7 +847,7 @@ ENTRY(kernel_thread) UNFAKE_STACK_FRAME ret CFI_ENDPROC -ENDPROC(kernel_thread) + child_rip: /* @@ -862,7 +860,6 @@ child_rip: # exit xorl %edi, %edi call do_exit -ENDPROC(child_rip) /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. @@ -892,24 +889,19 @@ ENTRY(execve) UNFAKE_STACK_FRAME ret CFI_ENDPROC -ENDPROC(execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault -END(page_fault) .previous .text ENTRY(coprocessor_error) zeroentry do_coprocessor_error -END(coprocessor_error) ENTRY(simd_coprocessor_error) zeroentry do_simd_coprocessor_error -END(simd_coprocessor_error) ENTRY(device_not_available) zeroentry math_state_restore -END(device_not_available) /* runs on exception stack */ KPROBE_ENTRY(debug) @@ -919,7 +911,6 @@ KPROBE_ENTRY(debug) paranoidentry do_debug, DEBUG_STACK jmp paranoid_exit CFI_ENDPROC -END(debug) .previous .text /* runs on exception stack */ @@ -970,7 +961,6 @@ paranoid_schedule: cli jmp paranoid_userspace CFI_ENDPROC -END(nmi) .previous .text KPROBE_ENTRY(int3) @@ -980,28 +970,22 @@ KPROBE_ENTRY(int3) paranoidentry do_int3, DEBUG_STACK jmp paranoid_exit CFI_ENDPROC -END(int3) .previous .text ENTRY(overflow) zeroentry do_overflow -END(overflow) ENTRY(bounds) zeroentry do_bounds -END(bounds) ENTRY(invalid_op) zeroentry do_invalid_op -END(invalid_op) ENTRY(coprocessor_segment_overrun) zeroentry do_coprocessor_segment_overrun -END(coprocessor_segment_overrun) ENTRY(reserved) zeroentry do_reserved -END(reserved) /* runs on exception stack */ ENTRY(double_fault) @@ -1009,15 +993,12 @@ ENTRY(double_fault) paranoidentry do_double_fault jmp paranoid_exit CFI_ENDPROC -END(double_fault) ENTRY(invalid_TSS) errorentry do_invalid_TSS -END(invalid_TSS) ENTRY(segment_not_present) errorentry do_segment_not_present -END(segment_not_present) /* runs on exception stack */ ENTRY(stack_segment) @@ -1025,24 +1006,19 @@ ENTRY(stack_segment) paranoidentry do_stack_segment jmp paranoid_exit CFI_ENDPROC -END(stack_segment) KPROBE_ENTRY(general_protection) errorentry do_general_protection -END(general_protection) .previous .text ENTRY(alignment_check) errorentry do_alignment_check -END(alignment_check) ENTRY(divide_error) zeroentry do_divide_error -END(divide_error) ENTRY(spurious_interrupt_bug) zeroentry do_spurious_interrupt_bug -END(spurious_interrupt_bug) #ifdef CONFIG_X86_MCE /* runs on exception stack */ @@ -1053,7 +1029,6 @@ ENTRY(machine_check) paranoidentry do_machine_check jmp paranoid_exit CFI_ENDPROC -END(machine_check) #endif ENTRY(call_softirq) @@ -1071,37 +1046,3 @@ ENTRY(call_softirq) decl %gs:pda_irqcount ret CFI_ENDPROC -ENDPROC(call_softirq) - -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movq %r15, R15(%rdi) - movq %r14, R14(%rdi) - xchgq %rsi, %rdx - movq %r13, R13(%rdi) - movq %r12, R12(%rdi) - xorl %eax, %eax - movq %rbp, RBP(%rdi) - movq %rbx, RBX(%rdi) - movq (%rsp), %rcx - movq %rax, R11(%rdi) - movq %rax, R10(%rdi) - movq %rax, R9(%rdi) - movq %rax, R8(%rdi) - movq %rax, RAX(%rdi) - movq %rax, RCX(%rdi) - movq %rax, RDX(%rdi) - movq %rax, RSI(%rdi) - movq %rax, RDI(%rdi) - movq %rax, ORIG_RAX(%rdi) - movq %rcx, RIP(%rdi) - leaq 8(%rsp), %rcx - movq $__KERNEL_CS, CS(%rdi) - movq %rax, EFLAGS(%rdi) - movq %rcx, RSP(%rdi) - movq $__KERNEL_DS, SS(%rdi) - jmpq *%rdx - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index 21c7066e236a..1a2ab825be98 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -78,29 +78,22 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) static void flat_send_IPI_allbutself(int vector) { -#ifdef CONFIG_HOTPLUG_CPU - int hotplug = 1; +#ifndef CONFIG_HOTPLUG_CPU + if (((num_online_cpus()) - 1) >= 1) + __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); #else - int hotplug = 0; -#endif - if (hotplug || vector == NMI_VECTOR) { - cpumask_t allbutme = cpu_online_map; + cpumask_t allbutme = cpu_online_map; - cpu_clear(smp_processor_id(), allbutme); + cpu_clear(smp_processor_id(), allbutme); - if (!cpus_empty(allbutme)) - flat_send_IPI_mask(allbutme, vector); - } else if (num_online_cpus() > 1) { - __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); - } + if (!cpus_empty(allbutme)) + flat_send_IPI_mask(allbutme, vector); +#endif } static void flat_send_IPI_all(int vector) { - if (vector == NMI_VECTOR) - flat_send_IPI_mask(cpu_online_map, vector); - else - __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); + __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); } static int flat_apic_id_registered(void) @@ -115,7 +108,10 @@ static unsigned int flat_cpu_mask_to_apicid(cpumask_t cpumask) static unsigned int phys_pkg_id(int index_msb) { - return hard_smp_processor_id() >> index_msb; + u32 ebx; + + ebx = cpuid_ebx(1); + return ((ebx >> 24) & 0xFF) >> index_msb; } struct genapic apic_flat = { diff --git a/trunk/arch/x86_64/kernel/head64.c b/trunk/arch/x86_64/kernel/head64.c index e6a71c9556d9..cea20a66c150 100644 --- a/trunk/arch/x86_64/kernel/head64.c +++ b/trunk/arch/x86_64/kernel/head64.c @@ -2,6 +2,8 @@ * linux/arch/x86_64/kernel/head64.c -- prepare to run common code * * Copyright (C) 2000 Andrea Arcangeli SuSE + * + * $Id: head64.c,v 1.22 2001/07/06 14:28:20 ak Exp $ */ #include diff --git a/trunk/arch/x86_64/kernel/i387.c b/trunk/arch/x86_64/kernel/i387.c index 44ddb1ec808d..a5d7e16b928e 100644 --- a/trunk/arch/x86_64/kernel/i387.c +++ b/trunk/arch/x86_64/kernel/i387.c @@ -24,7 +24,7 @@ #include #include -unsigned int mxcsr_feature_mask __read_mostly = 0xffffffff; +unsigned int mxcsr_feature_mask = 0xffffffff; void mxcsr_feature_mask_init(void) { diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 86b2c1e197aa..5ecd34ab8c2b 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -44,11 +44,11 @@ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) -#define BUILD_15_IRQS(x) \ +#define BUILD_14_IRQS(x) \ BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ - BI(x,c) BI(x,d) BI(x,e) + BI(x,c) BI(x,d) /* * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: @@ -73,13 +73,13 @@ BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) #ifdef CONFIG_PCI_MSI - BUILD_15_IRQS(0xe) + BUILD_14_IRQS(0xe) #endif #endif #undef BUILD_16_IRQS -#undef BUILD_15_IRQS +#undef BUILD_14_IRQS #undef BI @@ -92,11 +92,11 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) -#define IRQLIST_15(x) \ +#define IRQLIST_14(x) \ IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ - IRQ(x,c), IRQ(x,d), IRQ(x,e) + IRQ(x,c), IRQ(x,d) void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), @@ -108,7 +108,7 @@ void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0xc), IRQLIST_16(0xd) #ifdef CONFIG_PCI_MSI - , IRQLIST_15(0xe) + , IRQLIST_14(0xe) #endif #endif @@ -278,7 +278,7 @@ static void mask_and_ack_8259A(unsigned int irq) * Lightweight spurious IRQ detection. We do not want * to overdo spurious IRQ handling - it's usually a sign * of hardware problems, so we only do the checks we can - * do without slowing down good hardware unnecessarily. + * do without slowing down good hardware unnecesserily. * * Note that IRQ7 and IRQ15 (the two spurious IRQs * usually resulting from the 8259A-1|2 PICs) occur diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index c768d8a036d0..9cc7031b7151 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -41,7 +41,6 @@ #include #include #include -#include #define __apicdebuginit __init @@ -57,7 +56,6 @@ int timer_over_8254 __initdata = 0; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); /* * # of IRQ routing registers @@ -319,7 +317,7 @@ void __init check_ioapic(void) vendor &= 0xffff; switch (vendor) { case PCI_VENDOR_ID_VIA: -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU if ((end_pfn > MAX_DMA32_PFN || force_iommu) && !iommu_aperture_allowed) { @@ -836,17 +834,10 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; int assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; - unsigned long flags; - int vector; BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); - - spin_lock_irqsave(&vector_lock, flags); - - if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { - spin_unlock_irqrestore(&vector_lock, flags); + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) return IO_APIC_VECTOR(irq); - } next: current_vector += 8; if (current_vector == IA32_SYSCALL_VECTOR) @@ -858,14 +849,11 @@ int assign_irq_vector(int irq) current_vector = FIRST_DEVICE_VECTOR + offset; } - vector = current_vector; - vector_irq[vector] = irq; + vector_irq[current_vector] = irq; if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = vector; - - spin_unlock_irqrestore(&vector_lock, flags); + IO_APIC_VECTOR(irq) = current_vector; - return vector; + return current_vector; } extern void (*interrupt[NR_IRQS])(void); @@ -878,14 +866,21 @@ static struct hw_interrupt_type ioapic_edge_type; static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - unsigned idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; - - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[idx].handler = &ioapic_level_type; - else - irq_desc[idx].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[idx]); + if (use_pci_vector() && !platform_legacy_irq(irq)) { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[vector].handler = &ioapic_level_type; + else + irq_desc[vector].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[vector]); + } else { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[irq].handler = &ioapic_level_type; + else + irq_desc[irq].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[irq]); + } } static void __init setup_IO_APIC_irqs(void) diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index 3be0a7e4bf08..d8bd0b345b1e 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -26,30 +26,6 @@ atomic_t irq_mis_count; #endif #endif -#ifdef CONFIG_DEBUG_STACKOVERFLOW -/* - * Probabilistic stack overflow check: - * - * Only check the stack in process context, because everything else - * runs on the big interrupt stacks. Checking reliably is too expensive, - * so we just check from interrupts. - */ -static inline void stack_overflow_check(struct pt_regs *regs) -{ - u64 curbase = (u64) current->thread_info; - static unsigned long warned = -60*HZ; - - if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && - regs->rsp < curbase + sizeof(struct thread_info) + 128 && - time_after(jiffies, warned + 60*HZ)) { - printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", - current->comm, curbase, regs->rsp); - show_stack(NULL,NULL); - warned = jiffies; - } -} -#endif - /* * Generic, controller-independent functions: */ @@ -63,7 +39,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); for_each_online_cpu(j) - seq_printf(p, "CPU%-8d",j); + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); } @@ -115,14 +91,12 @@ int show_interrupts(struct seq_file *p, void *v) */ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) { - /* high bit used in ret_from_ code */ - unsigned irq = ~regs->orig_rax; + /* high bits used in ret_from_ code */ + unsigned irq = regs->orig_rax & 0xff; exit_idle(); irq_enter(); -#ifdef CONFIG_DEBUG_STACKOVERFLOW - stack_overflow_check(regs); -#endif + __do_IRQ(irq, regs); irq_exit(); diff --git a/trunk/arch/x86_64/kernel/k8.c b/trunk/arch/x86_64/kernel/k8.c deleted file mode 100644 index 6416682d33d0..000000000000 --- a/trunk/arch/x86_64/kernel/k8.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Shared support code for AMD K8 northbridges and derivates. - * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. - */ -#include -#include -#include -#include -#include -#include -#include - -int num_k8_northbridges; -EXPORT_SYMBOL(num_k8_northbridges); - -static u32 *flush_words; - -struct pci_device_id k8_nb_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) }, - {} -}; -EXPORT_SYMBOL(k8_nb_ids); - -struct pci_dev **k8_northbridges; -EXPORT_SYMBOL(k8_northbridges); - -static struct pci_dev *next_k8_northbridge(struct pci_dev *dev) -{ - do { - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); - if (!dev) - break; - } while (!pci_match_id(&k8_nb_ids[0], dev)); - return dev; -} - -int cache_k8_northbridges(void) -{ - int i; - struct pci_dev *dev; - if (num_k8_northbridges) - return 0; - - num_k8_northbridges = 0; - dev = NULL; - while ((dev = next_k8_northbridge(dev)) != NULL) - num_k8_northbridges++; - - k8_northbridges = kmalloc((num_k8_northbridges + 1) * sizeof(void *), - GFP_KERNEL); - if (!k8_northbridges) - return -ENOMEM; - - flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL); - if (!flush_words) { - kfree(k8_northbridges); - return -ENOMEM; - } - - dev = NULL; - i = 0; - while ((dev = next_k8_northbridge(dev)) != NULL) { - k8_northbridges[i++] = dev; - pci_read_config_dword(dev, 0x9c, &flush_words[i]); - } - k8_northbridges[i] = NULL; - return 0; -} -EXPORT_SYMBOL_GPL(cache_k8_northbridges); - -/* Ignores subdevice/subvendor but as far as I can figure out - they're useless anyways */ -int __init early_is_k8_nb(u32 device) -{ - struct pci_device_id *id; - u32 vendor = device & 0xffff; - device >>= 16; - for (id = k8_nb_ids; id->vendor; id++) - if (vendor == id->vendor && device == id->device) - return 1; - return 0; -} - -void k8_flush_garts(void) -{ - int flushed, i; - unsigned long flags; - static DEFINE_SPINLOCK(gart_lock); - - /* Avoid races between AGP and IOMMU. In theory it's not needed - but I'm not sure if the hardware won't lose flush requests - when another is pending. This whole thing is so expensive anyways - that it doesn't matter to serialize more. -AK */ - spin_lock_irqsave(&gart_lock, flags); - flushed = 0; - for (i = 0; i < num_k8_northbridges; i++) { - pci_write_config_dword(k8_northbridges[i], 0x9c, - flush_words[i]|1); - flushed++; - } - for (i = 0; i < num_k8_northbridges; i++) { - u32 w; - /* Make sure the hardware actually executed the flush*/ - for (;;) { - pci_read_config_dword(k8_northbridges[i], - 0x9c, &w); - if (!(w & 1)) - break; - cpu_relax(); - } - } - spin_unlock_irqrestore(&gart_lock, flags); - if (!flushed) - printk("nothing to flush?\n"); -} -EXPORT_SYMBOL_GPL(k8_flush_garts); - diff --git a/trunk/arch/x86_64/kernel/machine_kexec.c b/trunk/arch/x86_64/kernel/machine_kexec.c index 83fb24a02821..25ac8a3faae6 100644 --- a/trunk/arch/x86_64/kernel/machine_kexec.c +++ b/trunk/arch/x86_64/kernel/machine_kexec.c @@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, unsigned long start_address, unsigned long pgtable) ATTRIB_NORET; -extern const unsigned char relocate_new_kernel[]; -extern const unsigned long relocate_new_kernel_size; +const extern unsigned char relocate_new_kernel[]; +const extern unsigned long relocate_new_kernel_size; int machine_kexec_prepare(struct kimage *image) { diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index 88845674c661..c69fc43cee7b 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -562,7 +562,7 @@ static struct sysdev_class mce_sysclass = { set_kset_name("machinecheck"), }; -DEFINE_PER_CPU(struct sys_device, device_mce); +static DEFINE_PER_CPU(struct sys_device, device_mce); /* Why are there no generic functions for this? */ #define ACCESSOR(name, var, start) \ @@ -629,7 +629,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) #endif /* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static __cpuinit int +static int mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -647,7 +647,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block __cpuinitdata mce_cpu_notifier = { +static struct notifier_block mce_cpu_notifier = { .notifier_call = mce_cpu_callback, }; diff --git a/trunk/arch/x86_64/kernel/mce_amd.c b/trunk/arch/x86_64/kernel/mce_amd.c index 335200aa2737..d13b241ad094 100644 --- a/trunk/arch/x86_64/kernel/mce_amd.c +++ b/trunk/arch/x86_64/kernel/mce_amd.c @@ -1,5 +1,5 @@ /* - * (c) 2005, 2006 Advanced Micro Devices, Inc. + * (c) 2005 Advanced Micro Devices, Inc. * Your use of this code is subject to the terms and conditions of the * GNU general public license version 2. See "COPYING" or * http://www.gnu.org/licenses/gpl.html @@ -8,10 +8,9 @@ * * Support : jacob.shin@amd.com * - * April 2006 - * - added support for AMD Family 0x10 processors + * MC4_MISC0 DRAM ECC Error Threshold available under AMD K8 Rev F. + * MC4_MISC0 exists per physical processor. * - * All MC4_MISCi registers are shared between multi-cores */ #include @@ -30,45 +29,32 @@ #include #include -#define PFX "mce_threshold: " -#define VERSION "version 1.1.1" -#define NR_BANKS 6 -#define NR_BLOCKS 9 -#define THRESHOLD_MAX 0xFFF -#define INT_TYPE_APIC 0x00020000 -#define MASK_VALID_HI 0x80000000 -#define MASK_LVTOFF_HI 0x00F00000 -#define MASK_COUNT_EN_HI 0x00080000 -#define MASK_INT_TYPE_HI 0x00060000 -#define MASK_OVERFLOW_HI 0x00010000 +#define PFX "mce_threshold: " +#define VERSION "version 1.00.9" +#define NR_BANKS 5 +#define THRESHOLD_MAX 0xFFF +#define INT_TYPE_APIC 0x00020000 +#define MASK_VALID_HI 0x80000000 +#define MASK_LVTOFF_HI 0x00F00000 +#define MASK_COUNT_EN_HI 0x00080000 +#define MASK_INT_TYPE_HI 0x00060000 +#define MASK_OVERFLOW_HI 0x00010000 #define MASK_ERR_COUNT_HI 0x00000FFF -#define MASK_BLKPTR_LO 0xFF000000 -#define MCG_XBLK_ADDR 0xC0000400 +#define MASK_OVERFLOW 0x0001000000000000L -struct threshold_block { - unsigned int block; - unsigned int bank; +struct threshold_bank { unsigned int cpu; - u32 address; - u16 interrupt_enable; + u8 bank; + u8 interrupt_enable; u16 threshold_limit; struct kobject kobj; - struct list_head miscj; }; -/* defaults used early on boot */ -static struct threshold_block threshold_defaults = { +static struct threshold_bank threshold_defaults = { .interrupt_enable = 0, .threshold_limit = THRESHOLD_MAX, }; -struct threshold_bank { - struct kobject kobj; - struct threshold_block *blocks; - cpumask_t cpus; -}; -static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]); - #ifdef CONFIG_SMP static unsigned char shared_bank[NR_BANKS] = { 0, 0, 0, 0, 1 @@ -82,12 +68,12 @@ static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ */ /* must be called with correct cpu affinity */ -static void threshold_restart_bank(struct threshold_block *b, +static void threshold_restart_bank(struct threshold_bank *b, int reset, u16 old_limit) { u32 mci_misc_hi, mci_misc_lo; - rdmsr(b->address, mci_misc_lo, mci_misc_hi); + rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi); if (b->threshold_limit < (mci_misc_hi & THRESHOLD_MAX)) reset = 1; /* limit cannot be lower than err count */ @@ -108,57 +94,35 @@ static void threshold_restart_bank(struct threshold_block *b, (mci_misc_hi &= ~MASK_INT_TYPE_HI); mci_misc_hi |= MASK_COUNT_EN_HI; - wrmsr(b->address, mci_misc_lo, mci_misc_hi); + wrmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi); } -/* cpu init entry point, called from mce.c with preempt off */ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) { - unsigned int bank, block; + int bank; + u32 mci_misc_lo, mci_misc_hi; unsigned int cpu = smp_processor_id(); - u32 low = 0, high = 0, address = 0; for (bank = 0; bank < NR_BANKS; ++bank) { - for (block = 0; block < NR_BLOCKS; ++block) { - if (block == 0) - address = MSR_IA32_MC0_MISC + bank * 4; - else if (block == 1) - address = MCG_XBLK_ADDR - + ((low & MASK_BLKPTR_LO) >> 21); - else - ++address; - - if (rdmsr_safe(address, &low, &high)) - continue; + rdmsr(MSR_IA32_MC0_MISC + bank * 4, mci_misc_lo, mci_misc_hi); - if (!(high & MASK_VALID_HI)) { - if (block) - continue; - else - break; - } + /* !valid, !counter present, bios locked */ + if (!(mci_misc_hi & MASK_VALID_HI) || + !(mci_misc_hi & MASK_VALID_HI >> 1) || + (mci_misc_hi & MASK_VALID_HI >> 2)) + continue; - if (!(high & MASK_VALID_HI >> 1) || - (high & MASK_VALID_HI >> 2)) - continue; + per_cpu(bank_map, cpu) |= (1 << bank); - if (!block) - per_cpu(bank_map, cpu) |= (1 << bank); #ifdef CONFIG_SMP - if (shared_bank[bank] && c->cpu_core_id) - break; + if (shared_bank[bank] && cpu_core_id[cpu]) + continue; #endif - high &= ~MASK_LVTOFF_HI; - high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; - wrmsr(address, low, high); - setup_APIC_extened_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, - THRESHOLD_APIC_VECTOR, - K8_APIC_EXT_INT_MSG_FIX, 0); - - threshold_defaults.address = address; - threshold_restart_bank(&threshold_defaults, 0, 0); - } + setup_threshold_lvt((mci_misc_hi & MASK_LVTOFF_HI) >> 20); + threshold_defaults.cpu = cpu; + threshold_defaults.bank = bank; + threshold_restart_bank(&threshold_defaults, 0, 0); } } @@ -173,9 +137,8 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) */ asmlinkage void mce_threshold_interrupt(void) { - unsigned int bank, block; + int bank; struct mce m; - u32 low = 0, high = 0, address = 0; ack_APIC_irq(); exit_idle(); @@ -187,42 +150,15 @@ asmlinkage void mce_threshold_interrupt(void) /* assume first bank caused it */ for (bank = 0; bank < NR_BANKS; ++bank) { - for (block = 0; block < NR_BLOCKS; ++block) { - if (block == 0) - address = MSR_IA32_MC0_MISC + bank * 4; - else if (block == 1) - address = MCG_XBLK_ADDR - + ((low & MASK_BLKPTR_LO) >> 21); - else - ++address; - - if (rdmsr_safe(address, &low, &high)) - continue; + m.bank = MCE_THRESHOLD_BASE + bank; + rdmsrl(MSR_IA32_MC0_MISC + bank * 4, m.misc); - if (!(high & MASK_VALID_HI)) { - if (block) - continue; - else - break; - } - - if (!(high & MASK_VALID_HI >> 1) || - (high & MASK_VALID_HI >> 2)) - continue; - - if (high & MASK_OVERFLOW_HI) { - rdmsrl(address, m.misc); - rdmsrl(MSR_IA32_MC0_STATUS + bank * 4, - m.status); - m.bank = K8_MCE_THRESHOLD_BASE - + bank * NR_BLOCKS - + block; - mce_log(&m); - goto out; - } + if (m.misc & MASK_OVERFLOW) { + mce_log(&m); + goto out; } } -out: + out: irq_exit(); } @@ -230,12 +166,20 @@ asmlinkage void mce_threshold_interrupt(void) * Sysfs Interface */ +static struct sysdev_class threshold_sysclass = { + set_kset_name("threshold"), +}; + +static DEFINE_PER_CPU(struct sys_device, device_threshold); + struct threshold_attr { - struct attribute attr; - ssize_t(*show) (struct threshold_block *, char *); - ssize_t(*store) (struct threshold_block *, const char *, size_t count); + struct attribute attr; + ssize_t(*show) (struct threshold_bank *, char *); + ssize_t(*store) (struct threshold_bank *, const char *, size_t count); }; +static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]); + static cpumask_t affinity_set(unsigned int cpu) { cpumask_t oldmask = current->cpus_allowed; @@ -250,15 +194,15 @@ static void affinity_restore(cpumask_t oldmask) set_cpus_allowed(current, oldmask); } -#define SHOW_FIELDS(name) \ -static ssize_t show_ ## name(struct threshold_block * b, char *buf) \ -{ \ - return sprintf(buf, "%lx\n", (unsigned long) b->name); \ -} +#define SHOW_FIELDS(name) \ + static ssize_t show_ ## name(struct threshold_bank * b, char *buf) \ + { \ + return sprintf(buf, "%lx\n", (unsigned long) b->name); \ + } SHOW_FIELDS(interrupt_enable) SHOW_FIELDS(threshold_limit) -static ssize_t store_interrupt_enable(struct threshold_block *b, +static ssize_t store_interrupt_enable(struct threshold_bank *b, const char *buf, size_t count) { char *end; @@ -275,7 +219,7 @@ static ssize_t store_interrupt_enable(struct threshold_block *b, return end - buf; } -static ssize_t store_threshold_limit(struct threshold_block *b, +static ssize_t store_threshold_limit(struct threshold_bank *b, const char *buf, size_t count) { char *end; @@ -298,18 +242,18 @@ static ssize_t store_threshold_limit(struct threshold_block *b, return end - buf; } -static ssize_t show_error_count(struct threshold_block *b, char *buf) +static ssize_t show_error_count(struct threshold_bank *b, char *buf) { u32 high, low; cpumask_t oldmask; oldmask = affinity_set(b->cpu); - rdmsr(b->address, low, high); + rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, low, high); /* ignore low 32 */ affinity_restore(oldmask); return sprintf(buf, "%x\n", (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit)); } -static ssize_t store_error_count(struct threshold_block *b, +static ssize_t store_error_count(struct threshold_bank *b, const char *buf, size_t count) { cpumask_t oldmask; @@ -325,13 +269,13 @@ static ssize_t store_error_count(struct threshold_block *b, .store = _store, \ }; -#define RW_ATTR(name) \ -static struct threshold_attr name = \ +#define ATTR_FIELDS(name) \ + static struct threshold_attr name = \ THRESHOLD_ATTR(name, 0644, show_## name, store_## name) -RW_ATTR(interrupt_enable); -RW_ATTR(threshold_limit); -RW_ATTR(error_count); +ATTR_FIELDS(interrupt_enable); +ATTR_FIELDS(threshold_limit); +ATTR_FIELDS(error_count); static struct attribute *default_attrs[] = { &interrupt_enable.attr, @@ -340,12 +284,12 @@ static struct attribute *default_attrs[] = { NULL }; -#define to_block(k) container_of(k, struct threshold_block, kobj) -#define to_attr(a) container_of(a, struct threshold_attr, attr) +#define to_bank(k) container_of(k,struct threshold_bank,kobj) +#define to_attr(a) container_of(a,struct threshold_attr,attr) static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct threshold_block *b = to_block(kobj); + struct threshold_bank *b = to_bank(kobj); struct threshold_attr *a = to_attr(attr); ssize_t ret; ret = a->show ? a->show(b, buf) : -EIO; @@ -355,7 +299,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) static ssize_t store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { - struct threshold_block *b = to_block(kobj); + struct threshold_bank *b = to_bank(kobj); struct threshold_attr *a = to_attr(attr); ssize_t ret; ret = a->store ? a->store(b, buf, count) : -EIO; @@ -372,174 +316,69 @@ static struct kobj_type threshold_ktype = { .default_attrs = default_attrs, }; -static __cpuinit int allocate_threshold_blocks(unsigned int cpu, - unsigned int bank, - unsigned int block, - u32 address) -{ - int err; - u32 low, high; - struct threshold_block *b = NULL; - - if ((bank >= NR_BANKS) || (block >= NR_BLOCKS)) - return 0; - - if (rdmsr_safe(address, &low, &high)) - goto recurse; - - if (!(high & MASK_VALID_HI)) { - if (block) - goto recurse; - else - return 0; - } - - if (!(high & MASK_VALID_HI >> 1) || - (high & MASK_VALID_HI >> 2)) - goto recurse; - - b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL); - if (!b) - return -ENOMEM; - memset(b, 0, sizeof(struct threshold_block)); - - b->block = block; - b->bank = bank; - b->cpu = cpu; - b->address = address; - b->interrupt_enable = 0; - b->threshold_limit = THRESHOLD_MAX; - - INIT_LIST_HEAD(&b->miscj); - - if (per_cpu(threshold_banks, cpu)[bank]->blocks) - list_add(&b->miscj, - &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj); - else - per_cpu(threshold_banks, cpu)[bank]->blocks = b; - - kobject_set_name(&b->kobj, "misc%i", block); - b->kobj.parent = &per_cpu(threshold_banks, cpu)[bank]->kobj; - b->kobj.ktype = &threshold_ktype; - err = kobject_register(&b->kobj); - if (err) - goto out_free; -recurse: - if (!block) { - address = (low & MASK_BLKPTR_LO) >> 21; - if (!address) - return 0; - address += MCG_XBLK_ADDR; - } else - ++address; - - err = allocate_threshold_blocks(cpu, bank, ++block, address); - if (err) - goto out_free; - - return err; - -out_free: - if (b) { - kobject_unregister(&b->kobj); - kfree(b); - } - return err; -} - /* symlinks sibling shared banks to first core. first core owns dir/files. */ -static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) +static __cpuinit int threshold_create_bank(unsigned int cpu, int bank) { - int i, err = 0; + int err = 0; struct threshold_bank *b = NULL; - cpumask_t oldmask = CPU_MASK_NONE; - char name[32]; - - sprintf(name, "threshold_bank%i", bank); #ifdef CONFIG_SMP - if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */ - i = first_cpu(cpu_core_map[cpu]); - - /* first core not up yet */ - if (cpu_data[i].cpu_core_id) - goto out; - - /* already linked */ - if (per_cpu(threshold_banks, cpu)[bank]) - goto out; - - b = per_cpu(threshold_banks, i)[bank]; + if (cpu_core_id[cpu] && shared_bank[bank]) { /* symlink */ + char name[16]; + unsigned lcpu = first_cpu(cpu_core_map[cpu]); + if (cpu_core_id[lcpu]) + goto out; /* first core not up yet */ + b = per_cpu(threshold_banks, lcpu)[bank]; if (!b) goto out; - - err = sysfs_create_link(&per_cpu(device_mce, cpu).kobj, + sprintf(name, "bank%i", bank); + err = sysfs_create_link(&per_cpu(device_threshold, cpu).kobj, &b->kobj, name); if (err) goto out; - - b->cpus = cpu_core_map[cpu]; per_cpu(threshold_banks, cpu)[bank] = b; goto out; } #endif - b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL); + b = kmalloc(sizeof(struct threshold_bank), GFP_KERNEL); if (!b) { err = -ENOMEM; goto out; } memset(b, 0, sizeof(struct threshold_bank)); - kobject_set_name(&b->kobj, "threshold_bank%i", bank); - b->kobj.parent = &per_cpu(device_mce, cpu).kobj; -#ifndef CONFIG_SMP - b->cpus = CPU_MASK_ALL; -#else - b->cpus = cpu_core_map[cpu]; -#endif - err = kobject_register(&b->kobj); - if (err) - goto out_free; - - per_cpu(threshold_banks, cpu)[bank] = b; - - oldmask = affinity_set(cpu); - err = allocate_threshold_blocks(cpu, bank, 0, - MSR_IA32_MC0_MISC + bank * 4); - affinity_restore(oldmask); - - if (err) - goto out_free; - - for_each_cpu_mask(i, b->cpus) { - if (i == cpu) - continue; - - err = sysfs_create_link(&per_cpu(device_mce, i).kobj, - &b->kobj, name); - if (err) - goto out; + b->cpu = cpu; + b->bank = bank; + b->interrupt_enable = 0; + b->threshold_limit = THRESHOLD_MAX; + kobject_set_name(&b->kobj, "bank%i", bank); + b->kobj.parent = &per_cpu(device_threshold, cpu).kobj; + b->kobj.ktype = &threshold_ktype; - per_cpu(threshold_banks, i)[bank] = b; + err = kobject_register(&b->kobj); + if (err) { + kfree(b); + goto out; } - - goto out; - -out_free: - per_cpu(threshold_banks, cpu)[bank] = NULL; - kfree(b); -out: + per_cpu(threshold_banks, cpu)[bank] = b; + out: return err; } /* create dir/files for all valid threshold banks */ static __cpuinit int threshold_create_device(unsigned int cpu) { - unsigned int bank; + int bank; int err = 0; + per_cpu(device_threshold, cpu).id = cpu; + per_cpu(device_threshold, cpu).cls = &threshold_sysclass; + err = sysdev_register(&per_cpu(device_threshold, cpu)); + if (err) + goto out; + for (bank = 0; bank < NR_BANKS; ++bank) { if (!(per_cpu(bank_map, cpu) & 1 << bank)) continue; @@ -547,7 +386,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu) if (err) goto out; } -out: + out: return err; } @@ -558,85 +397,92 @@ static __cpuinit int threshold_create_device(unsigned int cpu) * of shared sysfs dir/files, and rest of the cores will be symlinked to it. */ -static __cpuinit void deallocate_threshold_block(unsigned int cpu, - unsigned int bank) -{ - struct threshold_block *pos = NULL; - struct threshold_block *tmp = NULL; - struct threshold_bank *head = per_cpu(threshold_banks, cpu)[bank]; - - if (!head) - return; - - list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) { - kobject_unregister(&pos->kobj); - list_del(&pos->miscj); - kfree(pos); - } - - kfree(per_cpu(threshold_banks, cpu)[bank]->blocks); - per_cpu(threshold_banks, cpu)[bank]->blocks = NULL; -} - +/* cpu hotplug call removes all symlinks before first core dies */ static __cpuinit void threshold_remove_bank(unsigned int cpu, int bank) { - int i = 0; struct threshold_bank *b; - char name[32]; + char name[16]; b = per_cpu(threshold_banks, cpu)[bank]; - if (!b) return; - - if (!b->blocks) - goto free_out; - - sprintf(name, "threshold_bank%i", bank); - - /* sibling symlink */ - if (shared_bank[bank] && b->blocks->cpu != cpu) { - sysfs_remove_link(&per_cpu(device_mce, cpu).kobj, name); - per_cpu(threshold_banks, i)[bank] = NULL; - return; - } - - /* remove all sibling symlinks before unregistering */ - for_each_cpu_mask(i, b->cpus) { - if (i == cpu) - continue; - - sysfs_remove_link(&per_cpu(device_mce, i).kobj, name); - per_cpu(threshold_banks, i)[bank] = NULL; + if (shared_bank[bank] && atomic_read(&b->kobj.kref.refcount) > 2) { + sprintf(name, "bank%i", bank); + sysfs_remove_link(&per_cpu(device_threshold, cpu).kobj, name); + per_cpu(threshold_banks, cpu)[bank] = NULL; + } else { + kobject_unregister(&b->kobj); + kfree(per_cpu(threshold_banks, cpu)[bank]); } - - deallocate_threshold_block(cpu, bank); - -free_out: - kobject_unregister(&b->kobj); - kfree(b); - per_cpu(threshold_banks, cpu)[bank] = NULL; } static __cpuinit void threshold_remove_device(unsigned int cpu) { - unsigned int bank; + int bank; for (bank = 0; bank < NR_BANKS; ++bank) { if (!(per_cpu(bank_map, cpu) & 1 << bank)) continue; threshold_remove_bank(cpu, bank); } + sysdev_unregister(&per_cpu(device_threshold, cpu)); } +/* link all existing siblings when first core comes up */ +static __cpuinit int threshold_create_symlinks(unsigned int cpu) +{ + int bank, err = 0; + unsigned int lcpu = 0; + + if (cpu_core_id[cpu]) + return 0; + for_each_cpu_mask(lcpu, cpu_core_map[cpu]) { + if (lcpu == cpu) + continue; + for (bank = 0; bank < NR_BANKS; ++bank) { + if (!(per_cpu(bank_map, cpu) & 1 << bank)) + continue; + if (!shared_bank[bank]) + continue; + err = threshold_create_bank(lcpu, bank); + } + } + return err; +} + +/* remove all symlinks before first core dies. */ +static __cpuinit void threshold_remove_symlinks(unsigned int cpu) +{ + int bank; + unsigned int lcpu = 0; + if (cpu_core_id[cpu]) + return; + for_each_cpu_mask(lcpu, cpu_core_map[cpu]) { + if (lcpu == cpu) + continue; + for (bank = 0; bank < NR_BANKS; ++bank) { + if (!(per_cpu(bank_map, cpu) & 1 << bank)) + continue; + if (!shared_bank[bank]) + continue; + threshold_remove_bank(lcpu, bank); + } + } +} #else /* !CONFIG_HOTPLUG_CPU */ +static __cpuinit void threshold_create_symlinks(unsigned int cpu) +{ +} +static __cpuinit void threshold_remove_symlinks(unsigned int cpu) +{ +} static void threshold_remove_device(unsigned int cpu) { } #endif /* get notified when a cpu comes on/off */ -static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, +static int threshold_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { /* cpu was unsigned int to begin with */ @@ -648,6 +494,13 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: threshold_create_device(cpu); + threshold_create_symlinks(cpu); + break; + case CPU_DOWN_PREPARE: + threshold_remove_symlinks(cpu); + break; + case CPU_DOWN_FAILED: + threshold_create_symlinks(cpu); break; case CPU_DEAD: threshold_remove_device(cpu); @@ -659,22 +512,29 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block threshold_cpu_notifier __cpuinitdata = { +static struct notifier_block threshold_cpu_notifier = { .notifier_call = threshold_cpu_callback, }; static __init int threshold_init_device(void) { - unsigned lcpu = 0; + int err; + int lcpu = 0; + + err = sysdev_class_register(&threshold_sysclass); + if (err) + goto out; /* to hit CPUs online before the notifier is up */ for_each_online_cpu(lcpu) { - int err = threshold_create_device(lcpu); + err = threshold_create_device(lcpu); if (err) - return err; + goto out; } register_cpu_notifier(&threshold_cpu_notifier); - return 0; + + out: + return err; } device_initcall(threshold_init_device); diff --git a/trunk/arch/x86_64/kernel/module.c b/trunk/arch/x86_64/kernel/module.c index 9d0958ff547f..bac195c74bcc 100644 --- a/trunk/arch/x86_64/kernel/module.c +++ b/trunk/arch/x86_64/kernel/module.c @@ -145,38 +145,26 @@ int apply_relocate(Elf_Shdr *sechdrs, return -ENOSYS; } +extern void apply_alternatives(void *start, void *end); + int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) + const Elf_Shdr *sechdrs, + struct module *me) { - const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; + const Elf_Shdr *s; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { - if (!strcmp(".text", secstrings + s->sh_name)) - text = s; - if (!strcmp(".altinstructions", secstrings + s->sh_name)) - alt = s; - if (!strcmp(".smp_locks", secstrings + s->sh_name)) - locks= s; - } - - if (alt) { - /* patch .altinstructions */ - void *aseg = (void *)alt->sh_addr; - apply_alternatives(aseg, aseg + alt->sh_size); - } - if (locks && text) { - void *lseg = (void *)locks->sh_addr; - void *tseg = (void *)text->sh_addr; - alternatives_smp_module_add(me, me->name, - lseg, lseg + locks->sh_size, - tseg, tseg + text->sh_size); - } + /* look for .altinstructions to patch */ + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + void *seg; + if (strcmp(".altinstructions", secstrings + s->sh_name)) + continue; + seg = (void *)s->sh_addr; + apply_alternatives(seg, seg + s->sh_size); + } return 0; } void module_arch_cleanup(struct module *mod) { - alternatives_smp_module_del(mod); } diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 399489c93132..4e6357fe0ec3 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -15,7 +15,11 @@ #include #include #include +#include +#include #include +#include +#include #include #include #include @@ -23,11 +27,14 @@ #include #include +#include +#include #include +#include #include #include +#include #include -#include /* * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: @@ -67,9 +74,6 @@ static unsigned int nmi_p4_cccr_val; #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - #define MSR_P4_MISC_ENABLE 0x1A0 #define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) #define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) @@ -101,10 +105,7 @@ static __cpuinit inline int nmi_known_cpu(void) case X86_VENDOR_AMD: return boot_cpu_data.x86 == 15; case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return 1; - else - return (boot_cpu_data.x86 == 15); + return boot_cpu_data.x86 == 15; } return 0; } @@ -210,8 +211,6 @@ int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); -static void disable_intel_arch_watchdog(void); - static void disable_lapic_nmi_watchdog(void) { if (nmi_active <= 0) @@ -224,8 +223,6 @@ static void disable_lapic_nmi_watchdog(void) if (boot_cpu_data.x86 == 15) { wrmsr(MSR_P4_IQ_CCCR0, 0, 0); wrmsr(MSR_P4_CRU_ESCR0, 0, 0); - } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - disable_intel_arch_watchdog(); } break; } @@ -378,53 +375,6 @@ static void setup_k7_watchdog(void) wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -static void disable_intel_arch_watchdog(void) -{ - unsigned ebx; - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebp indicates event present. - */ - ebx = cpuid_ebx(10); - if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); -} - -static int setup_intel_arch_watchdog(void) -{ - unsigned int evntsel; - unsigned ebx; - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebp indicates event present. - */ - ebx = cpuid_ebx(10); - if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return 0; - - nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - - clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); - clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); - - evntsel = ARCH_PERFMON_EVENTSEL_INT - | ARCH_PERFMON_EVENTSEL_OS - | ARCH_PERFMON_EVENTSEL_USR - | ARCH_PERFMON_NMI_EVENT_SEL - | ARCH_PERFMON_NMI_EVENT_UMASK; - - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); - wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); - return 1; -} - static int setup_p4_watchdog(void) { @@ -478,16 +428,10 @@ void setup_apic_nmi_watchdog(void) setup_k7_watchdog(); break; case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - } else if (boot_cpu_data.x86 == 15) { - if (!setup_p4_watchdog()) - return; - } else { + if (boot_cpu_data.x86 != 15) + return; + if (!setup_p4_watchdog()) return; - } - break; default: @@ -572,14 +516,7 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) */ wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); - } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { - /* - * For Intel based architectural perfmon - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - } + } wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); } } diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c deleted file mode 100644 index d91cb843f54d..000000000000 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * Derived from arch/powerpc/kernel/iommu.c - * - * Copyright (C) 2006 Jon Mason , IBM Corporation - * Copyright (C) 2006 Muli Ben-Yehuda , IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 -#define PCI_VENDOR_DEVICE_ID_CALGARY \ - (PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16) - -/* we need these for register space address calculation */ -#define START_ADDRESS 0xfe000000 -#define CHASSIS_BASE 0 -#define ONE_BASED_CHASSIS_NUM 1 - -/* register offsets inside the host bridge space */ -#define PHB_CSR_OFFSET 0x0110 -#define PHB_PLSSR_OFFSET 0x0120 -#define PHB_CONFIG_RW_OFFSET 0x0160 -#define PHB_IOBASE_BAR_LOW 0x0170 -#define PHB_IOBASE_BAR_HIGH 0x0180 -#define PHB_MEM_1_LOW 0x0190 -#define PHB_MEM_1_HIGH 0x01A0 -#define PHB_IO_ADDR_SIZE 0x01B0 -#define PHB_MEM_1_SIZE 0x01C0 -#define PHB_MEM_ST_OFFSET 0x01D0 -#define PHB_AER_OFFSET 0x0200 -#define PHB_CONFIG_0_HIGH 0x0220 -#define PHB_CONFIG_0_LOW 0x0230 -#define PHB_CONFIG_0_END 0x0240 -#define PHB_MEM_2_LOW 0x02B0 -#define PHB_MEM_2_HIGH 0x02C0 -#define PHB_MEM_2_SIZE_HIGH 0x02D0 -#define PHB_MEM_2_SIZE_LOW 0x02E0 -#define PHB_DOSHOLE_OFFSET 0x08E0 - -/* PHB_CONFIG_RW */ -#define PHB_TCE_ENABLE 0x20000000 -#define PHB_SLOT_DISABLE 0x1C000000 -#define PHB_DAC_DISABLE 0x01000000 -#define PHB_MEM2_ENABLE 0x00400000 -#define PHB_MCSR_ENABLE 0x00100000 -/* TAR (Table Address Register) */ -#define TAR_SW_BITS 0x0000ffffffff800fUL -#define TAR_VALID 0x0000000000000008UL -/* CSR (Channel/DMA Status Register) */ -#define CSR_AGENT_MASK 0xffe0ffff - -#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * 2) /* max dev->bus->number */ -#define PHBS_PER_CALGARY 4 - -/* register offsets in Calgary's internal register space */ -static const unsigned long tar_offsets[] = { - 0x0580 /* TAR0 */, - 0x0588 /* TAR1 */, - 0x0590 /* TAR2 */, - 0x0598 /* TAR3 */ -}; - -static const unsigned long split_queue_offsets[] = { - 0x4870 /* SPLIT QUEUE 0 */, - 0x5870 /* SPLIT QUEUE 1 */, - 0x6870 /* SPLIT QUEUE 2 */, - 0x7870 /* SPLIT QUEUE 3 */ -}; - -static const unsigned long phb_offsets[] = { - 0x8000 /* PHB0 */, - 0x9000 /* PHB1 */, - 0xA000 /* PHB2 */, - 0xB000 /* PHB3 */ -}; - -void* tce_table_kva[MAX_NUM_OF_PHBS * MAX_NUMNODES]; -unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; -static int translate_empty_slots __read_mostly = 0; -static int calgary_detected __read_mostly = 0; - -/* - * the bitmap of PHBs the user requested that we disable - * translation on. - */ -static DECLARE_BITMAP(translation_disabled, MAX_NUMNODES * MAX_PHB_BUS_NUM); - -static void tce_cache_blast(struct iommu_table *tbl); - -/* enable this to stress test the chip's TCE cache */ -#ifdef CONFIG_IOMMU_DEBUG -static inline void tce_cache_blast_stress(struct iommu_table *tbl) -{ - tce_cache_blast(tbl); -} -#else -static inline void tce_cache_blast_stress(struct iommu_table *tbl) -{ -} -#endif /* BLAST_TCE_CACHE_ON_UNMAP */ - -static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) -{ - unsigned int npages; - - npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK); - npages >>= PAGE_SHIFT; - - return npages; -} - -static inline int translate_phb(struct pci_dev* dev) -{ - int disabled = test_bit(dev->bus->number, translation_disabled); - return !disabled; -} - -static void iommu_range_reserve(struct iommu_table *tbl, - unsigned long start_addr, unsigned int npages) -{ - unsigned long index; - unsigned long end; - - index = start_addr >> PAGE_SHIFT; - - /* bail out if we're asked to reserve a region we don't cover */ - if (index >= tbl->it_size) - return; - - end = index + npages; - if (end > tbl->it_size) /* don't go off the table */ - end = tbl->it_size; - - while (index < end) { - if (test_bit(index, tbl->it_map)) - printk(KERN_ERR "Calgary: entry already allocated at " - "0x%lx tbl %p dma 0x%lx npages %u\n", - index, tbl, start_addr, npages); - ++index; - } - set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages); -} - -static unsigned long iommu_range_alloc(struct iommu_table *tbl, - unsigned int npages) -{ - unsigned long offset; - - BUG_ON(npages == 0); - - offset = find_next_zero_string(tbl->it_map, tbl->it_hint, - tbl->it_size, npages); - if (offset == ~0UL) { - tce_cache_blast(tbl); - offset = find_next_zero_string(tbl->it_map, 0, - tbl->it_size, npages); - if (offset == ~0UL) { - printk(KERN_WARNING "Calgary: IOMMU full.\n"); - if (panic_on_overflow) - panic("Calgary: fix the allocator.\n"); - else - return bad_dma_address; - } - } - - set_bit_string(tbl->it_map, offset, npages); - tbl->it_hint = offset + npages; - BUG_ON(tbl->it_hint > tbl->it_size); - - return offset; -} - -static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr, - unsigned int npages, int direction) -{ - unsigned long entry, flags; - dma_addr_t ret = bad_dma_address; - - spin_lock_irqsave(&tbl->it_lock, flags); - - entry = iommu_range_alloc(tbl, npages); - - if (unlikely(entry == bad_dma_address)) - goto error; - - /* set the return dma address */ - ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK); - - /* put the TCEs in the HW table */ - tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK, - direction); - - spin_unlock_irqrestore(&tbl->it_lock, flags); - - return ret; - -error: - spin_unlock_irqrestore(&tbl->it_lock, flags); - printk(KERN_WARNING "Calgary: failed to allocate %u pages in " - "iommu %p\n", npages, tbl); - return bad_dma_address; -} - -static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, - unsigned int npages) -{ - unsigned long entry; - unsigned long i; - - entry = dma_addr >> PAGE_SHIFT; - - BUG_ON(entry + npages > tbl->it_size); - - tce_free(tbl, entry, npages); - - for (i = 0; i < npages; ++i) { - if (!test_bit(entry + i, tbl->it_map)) - printk(KERN_ERR "Calgary: bit is off at 0x%lx " - "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", - entry + i, tbl, dma_addr, entry, npages); - } - - __clear_bit_string(tbl->it_map, entry, npages); - - tce_cache_blast_stress(tbl); -} - -static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, - unsigned int npages) -{ - unsigned long flags; - - spin_lock_irqsave(&tbl->it_lock, flags); - - __iommu_free(tbl, dma_addr, npages); - - spin_unlock_irqrestore(&tbl->it_lock, flags); -} - -static void __calgary_unmap_sg(struct iommu_table *tbl, - struct scatterlist *sglist, int nelems, int direction) -{ - while (nelems--) { - unsigned int npages; - dma_addr_t dma = sglist->dma_address; - unsigned int dmalen = sglist->dma_length; - - if (dmalen == 0) - break; - - npages = num_dma_pages(dma, dmalen); - __iommu_free(tbl, dma, npages); - sglist++; - } -} - -void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, int direction) -{ - unsigned long flags; - struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; - - if (!translate_phb(to_pci_dev(dev))) - return; - - spin_lock_irqsave(&tbl->it_lock, flags); - - __calgary_unmap_sg(tbl, sglist, nelems, direction); - - spin_unlock_irqrestore(&tbl->it_lock, flags); -} - -static int calgary_nontranslate_map_sg(struct device* dev, - struct scatterlist *sg, int nelems, int direction) -{ - int i; - - for (i = 0; i < nelems; i++ ) { - struct scatterlist *s = &sg[i]; - BUG_ON(!s->page); - s->dma_address = virt_to_bus(page_address(s->page) +s->offset); - s->dma_length = s->length; - } - return nelems; -} - -int calgary_map_sg(struct device *dev, struct scatterlist *sg, - int nelems, int direction) -{ - struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; - unsigned long flags; - unsigned long vaddr; - unsigned int npages; - unsigned long entry; - int i; - - if (!translate_phb(to_pci_dev(dev))) - return calgary_nontranslate_map_sg(dev, sg, nelems, direction); - - spin_lock_irqsave(&tbl->it_lock, flags); - - for (i = 0; i < nelems; i++ ) { - struct scatterlist *s = &sg[i]; - BUG_ON(!s->page); - - vaddr = (unsigned long)page_address(s->page) + s->offset; - npages = num_dma_pages(vaddr, s->length); - - entry = iommu_range_alloc(tbl, npages); - if (entry == bad_dma_address) { - /* makes sure unmap knows to stop */ - s->dma_length = 0; - goto error; - } - - s->dma_address = (entry << PAGE_SHIFT) | s->offset; - - /* insert into HW table */ - tce_build(tbl, entry, npages, vaddr & PAGE_MASK, - direction); - - s->dma_length = s->length; - } - - spin_unlock_irqrestore(&tbl->it_lock, flags); - - return nelems; -error: - __calgary_unmap_sg(tbl, sg, nelems, direction); - for (i = 0; i < nelems; i++) { - sg[i].dma_address = bad_dma_address; - sg[i].dma_length = 0; - } - spin_unlock_irqrestore(&tbl->it_lock, flags); - return 0; -} - -dma_addr_t calgary_map_single(struct device *dev, void *vaddr, - size_t size, int direction) -{ - dma_addr_t dma_handle = bad_dma_address; - unsigned long uaddr; - unsigned int npages; - struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; - - uaddr = (unsigned long)vaddr; - npages = num_dma_pages(uaddr, size); - - if (translate_phb(to_pci_dev(dev))) - dma_handle = iommu_alloc(tbl, vaddr, npages, direction); - else - dma_handle = virt_to_bus(vaddr); - - return dma_handle; -} - -void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) -{ - struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata; - unsigned int npages; - - if (!translate_phb(to_pci_dev(dev))) - return; - - npages = num_dma_pages(dma_handle, size); - iommu_free(tbl, dma_handle, npages); -} - -void* calgary_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - void *ret = NULL; - dma_addr_t mapping; - unsigned int npages, order; - struct iommu_table *tbl; - - tbl = to_pci_dev(dev)->bus->self->sysdata; - - size = PAGE_ALIGN(size); /* size rounded up to full pages */ - npages = size >> PAGE_SHIFT; - order = get_order(size); - - /* alloc enough pages (and possibly more) */ - ret = (void *)__get_free_pages(flag, order); - if (!ret) - goto error; - memset(ret, 0, size); - - if (translate_phb(to_pci_dev(dev))) { - /* set up tces to cover the allocated range */ - mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL); - if (mapping == bad_dma_address) - goto free; - - *dma_handle = mapping; - } else /* non translated slot */ - *dma_handle = virt_to_bus(ret); - - return ret; - -free: - free_pages((unsigned long)ret, get_order(size)); - ret = NULL; -error: - return ret; -} - -static struct dma_mapping_ops calgary_dma_ops = { - .alloc_coherent = calgary_alloc_coherent, - .map_single = calgary_map_single, - .unmap_single = calgary_unmap_single, - .map_sg = calgary_map_sg, - .unmap_sg = calgary_unmap_sg, -}; - -static inline int busno_to_phbid(unsigned char num) -{ - return bus_to_phb(num) % PHBS_PER_CALGARY; -} - -static inline unsigned long split_queue_offset(unsigned char num) -{ - size_t idx = busno_to_phbid(num); - - return split_queue_offsets[idx]; -} - -static inline unsigned long tar_offset(unsigned char num) -{ - size_t idx = busno_to_phbid(num); - - return tar_offsets[idx]; -} - -static inline unsigned long phb_offset(unsigned char num) -{ - size_t idx = busno_to_phbid(num); - - return phb_offsets[idx]; -} - -static inline void __iomem* calgary_reg(void __iomem *bar, unsigned long offset) -{ - unsigned long target = ((unsigned long)bar) | offset; - return (void __iomem*)target; -} - -static void tce_cache_blast(struct iommu_table *tbl) -{ - u64 val; - u32 aer; - int i = 0; - void __iomem *bbar = tbl->bbar; - void __iomem *target; - - /* disable arbitration on the bus */ - target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET); - aer = readl(target); - writel(0, target); - - /* read plssr to ensure it got there */ - target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET); - val = readl(target); - - /* poll split queues until all DMA activity is done */ - target = calgary_reg(bbar, split_queue_offset(tbl->it_busno)); - do { - val = readq(target); - i++; - } while ((val & 0xff) != 0xff && i < 100); - if (i == 100) - printk(KERN_WARNING "Calgary: PCI bus not quiesced, " - "continuing anyway\n"); - - /* invalidate TCE cache */ - target = calgary_reg(bbar, tar_offset(tbl->it_busno)); - writeq(tbl->tar_val, target); - - /* enable arbitration */ - target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET); - writel(aer, target); - (void)readl(target); /* flush */ -} - -static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start, - u64 limit) -{ - unsigned int numpages; - - limit = limit | 0xfffff; - limit++; - - numpages = ((limit - start) >> PAGE_SHIFT); - iommu_range_reserve(dev->sysdata, start, numpages); -} - -static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev) -{ - void __iomem *target; - u64 low, high, sizelow; - u64 start, limit; - struct iommu_table *tbl = dev->sysdata; - unsigned char busnum = dev->bus->number; - void __iomem *bbar = tbl->bbar; - - /* peripheral MEM_1 region */ - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_LOW); - low = be32_to_cpu(readl(target)); - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_HIGH); - high = be32_to_cpu(readl(target)); - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_SIZE); - sizelow = be32_to_cpu(readl(target)); - - start = (high << 32) | low; - limit = sizelow; - - calgary_reserve_mem_region(dev, start, limit); -} - -static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev) -{ - void __iomem *target; - u32 val32; - u64 low, high, sizelow, sizehigh; - u64 start, limit; - struct iommu_table *tbl = dev->sysdata; - unsigned char busnum = dev->bus->number; - void __iomem *bbar = tbl->bbar; - - /* is it enabled? */ - target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); - val32 = be32_to_cpu(readl(target)); - if (!(val32 & PHB_MEM2_ENABLE)) - return; - - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_LOW); - low = be32_to_cpu(readl(target)); - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_HIGH); - high = be32_to_cpu(readl(target)); - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_LOW); - sizelow = be32_to_cpu(readl(target)); - target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_HIGH); - sizehigh = be32_to_cpu(readl(target)); - - start = (high << 32) | low; - limit = (sizehigh << 32) | sizelow; - - calgary_reserve_mem_region(dev, start, limit); -} - -/* - * some regions of the IO address space do not get translated, so we - * must not give devices IO addresses in those regions. The regions - * are the 640KB-1MB region and the two PCI peripheral memory holes. - * Reserve all of them in the IOMMU bitmap to avoid giving them out - * later. - */ -static void __init calgary_reserve_regions(struct pci_dev *dev) -{ - unsigned int npages; - void __iomem *bbar; - unsigned char busnum; - u64 start; - struct iommu_table *tbl = dev->sysdata; - - bbar = tbl->bbar; - busnum = dev->bus->number; - - /* reserve bad_dma_address in case it's a legal address */ - iommu_range_reserve(tbl, bad_dma_address, 1); - - /* avoid the BIOS/VGA first 640KB-1MB region */ - start = (640 * 1024); - npages = ((1024 - 640) * 1024) >> PAGE_SHIFT; - iommu_range_reserve(tbl, start, npages); - - /* reserve the two PCI peripheral memory regions in IO space */ - calgary_reserve_peripheral_mem_1(dev); - calgary_reserve_peripheral_mem_2(dev); -} - -static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) -{ - u64 val64; - u64 table_phys; - void __iomem *target; - int ret; - struct iommu_table *tbl; - - /* build TCE tables for each PHB */ - ret = build_tce_table(dev, bbar); - if (ret) - return ret; - - calgary_reserve_regions(dev); - - /* set TARs for each PHB */ - target = calgary_reg(bbar, tar_offset(dev->bus->number)); - val64 = be64_to_cpu(readq(target)); - - /* zero out all TAR bits under sw control */ - val64 &= ~TAR_SW_BITS; - - tbl = dev->sysdata; - table_phys = (u64)__pa(tbl->it_base); - val64 |= table_phys; - - BUG_ON(specified_table_size > TCE_TABLE_SIZE_8M); - val64 |= (u64) specified_table_size; - - tbl->tar_val = cpu_to_be64(val64); - writeq(tbl->tar_val, target); - readq(target); /* flush */ - - return 0; -} - -static void __init calgary_free_tar(struct pci_dev *dev) -{ - u64 val64; - struct iommu_table *tbl = dev->sysdata; - void __iomem *target; - - target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); - val64 = be64_to_cpu(readq(target)); - val64 &= ~TAR_SW_BITS; - writeq(cpu_to_be64(val64), target); - readq(target); /* flush */ - - kfree(tbl); - dev->sysdata = NULL; -} - -static void calgary_watchdog(unsigned long data) -{ - struct pci_dev *dev = (struct pci_dev *)data; - struct iommu_table *tbl = dev->sysdata; - void __iomem *bbar = tbl->bbar; - u32 val32; - void __iomem *target; - - target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET); - val32 = be32_to_cpu(readl(target)); - - /* If no error, the agent ID in the CSR is not valid */ - if (val32 & CSR_AGENT_MASK) { - printk(KERN_EMERG "calgary_watchdog: DMA error on bus %d, " - "CSR = %#x\n", dev->bus->number, val32); - writel(0, target); - - /* Disable bus that caused the error */ - target = calgary_reg(bbar, phb_offset(tbl->it_busno) | - PHB_CONFIG_RW_OFFSET); - val32 = be32_to_cpu(readl(target)); - val32 |= PHB_SLOT_DISABLE; - writel(cpu_to_be32(val32), target); - readl(target); /* flush */ - } else { - /* Reset the timer */ - mod_timer(&tbl->watchdog_timer, jiffies + 2 * HZ); - } -} - -static void __init calgary_enable_translation(struct pci_dev *dev) -{ - u32 val32; - unsigned char busnum; - void __iomem *target; - void __iomem *bbar; - struct iommu_table *tbl; - - busnum = dev->bus->number; - tbl = dev->sysdata; - bbar = tbl->bbar; - - /* enable TCE in PHB Config Register */ - target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); - val32 = be32_to_cpu(readl(target)); - val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE; - - printk(KERN_INFO "Calgary: enabling translation on PHB %d\n", busnum); - printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this " - "bus.\n"); - - writel(cpu_to_be32(val32), target); - readl(target); /* flush */ - - init_timer(&tbl->watchdog_timer); - tbl->watchdog_timer.function = &calgary_watchdog; - tbl->watchdog_timer.data = (unsigned long)dev; - mod_timer(&tbl->watchdog_timer, jiffies); -} - -static void __init calgary_disable_translation(struct pci_dev *dev) -{ - u32 val32; - unsigned char busnum; - void __iomem *target; - void __iomem *bbar; - struct iommu_table *tbl; - - busnum = dev->bus->number; - tbl = dev->sysdata; - bbar = tbl->bbar; - - /* disable TCE in PHB Config Register */ - target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET); - val32 = be32_to_cpu(readl(target)); - val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE); - - printk(KERN_INFO "Calgary: disabling translation on PHB %d!\n", busnum); - writel(cpu_to_be32(val32), target); - readl(target); /* flush */ - - del_timer_sync(&tbl->watchdog_timer); -} - -static inline unsigned int __init locate_register_space(struct pci_dev *dev) -{ - int rionodeid; - u32 address; - - rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2; - /* - * register space address calculation as follows: - * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) - * ChassisBase is always zero for x366/x260/x460 - * RioNodeId is 2 for first Calgary, 3 for second Calgary - */ - address = START_ADDRESS - - (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) + - (0x100000) * (rionodeid - CHASSIS_BASE); - return address; -} - -static int __init calgary_init_one_nontraslated(struct pci_dev *dev) -{ - dev->sysdata = NULL; - dev->bus->self = dev; - - return 0; -} - -static int __init calgary_init_one(struct pci_dev *dev) -{ - u32 address; - void __iomem *bbar; - int ret; - - address = locate_register_space(dev); - /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(address, 1024 * 1024); - if (!bbar) { - ret = -ENODATA; - goto done; - } - - ret = calgary_setup_tar(dev, bbar); - if (ret) - goto iounmap; - - dev->bus->self = dev; - calgary_enable_translation(dev); - - return 0; - -iounmap: - iounmap(bbar); -done: - return ret; -} - -static int __init calgary_init(void) -{ - int i, ret = -ENODEV; - struct pci_dev *dev = NULL; - - for (i = 0; i <= num_online_nodes() * MAX_NUM_OF_PHBS; i++) { - dev = pci_get_device(PCI_VENDOR_ID_IBM, - PCI_DEVICE_ID_IBM_CALGARY, - dev); - if (!dev) - break; - if (!translate_phb(dev)) { - calgary_init_one_nontraslated(dev); - continue; - } - if (!tce_table_kva[i] && !translate_empty_slots) { - pci_dev_put(dev); - continue; - } - ret = calgary_init_one(dev); - if (ret) - goto error; - } - - return ret; - -error: - for (i--; i >= 0; i--) { - dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, - PCI_DEVICE_ID_IBM_CALGARY, - dev); - if (!translate_phb(dev)) { - pci_dev_put(dev); - continue; - } - if (!tce_table_kva[i] && !translate_empty_slots) - continue; - calgary_disable_translation(dev); - calgary_free_tar(dev); - pci_dev_put(dev); - } - - return ret; -} - -static inline int __init determine_tce_table_size(u64 ram) -{ - int ret; - - if (specified_table_size != TCE_TABLE_SIZE_UNSPECIFIED) - return specified_table_size; - - /* - * Table sizes are from 0 to 7 (TCE_TABLE_SIZE_64K to - * TCE_TABLE_SIZE_8M). Table size 0 has 8K entries and each - * larger table size has twice as many entries, so shift the - * max ram address by 13 to divide by 8K and then look at the - * order of the result to choose between 0-7. - */ - ret = get_order(ram >> 13); - if (ret > TCE_TABLE_SIZE_8M) - ret = TCE_TABLE_SIZE_8M; - - return ret; -} - -void __init detect_calgary(void) -{ - u32 val; - int bus, table_idx; - void *tbl; - int detected = 0; - - /* - * if the user specified iommu=off or iommu=soft or we found - * another HW IOMMU already, bail out. - */ - if (swiotlb || no_iommu || iommu_detected) - return; - - specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); - - for (bus = 0, table_idx = 0; - bus <= num_online_nodes() * MAX_PHB_BUS_NUM; - bus++) { - BUG_ON(bus > MAX_NUMNODES * MAX_PHB_BUS_NUM); - if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) - continue; - if (test_bit(bus, translation_disabled)) { - printk(KERN_INFO "Calgary: translation is disabled for " - "PHB 0x%x\n", bus); - /* skip this phb, don't allocate a tbl for it */ - tce_table_kva[table_idx] = NULL; - table_idx++; - continue; - } - /* - * scan the first slot of the PCI bus to see if there - * are any devices present - */ - val = read_pci_config(bus, 1, 0, 0); - if (val != 0xffffffff || translate_empty_slots) { - tbl = alloc_tce_table(); - if (!tbl) - goto cleanup; - detected = 1; - } else - tbl = NULL; - - tce_table_kva[table_idx] = tbl; - table_idx++; - } - - if (detected) { - iommu_detected = 1; - calgary_detected = 1; - printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " - "TCE table spec is %d.\n", specified_table_size); - } - return; - -cleanup: - for (--table_idx; table_idx >= 0; --table_idx) - if (tce_table_kva[table_idx]) - free_tce_table(tce_table_kva[table_idx]); -} - -int __init calgary_iommu_init(void) -{ - int ret; - - if (no_iommu || swiotlb) - return -ENODEV; - - if (!calgary_detected) - return -ENODEV; - - /* ok, we're trying to use Calgary - let's roll */ - printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n"); - - ret = calgary_init(); - if (ret) { - printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " - "falling back to no_iommu\n", ret); - if (end_pfn > MAX_DMA32_PFN) - printk(KERN_ERR "WARNING more than 4GB of memory, " - "32bit PCI may malfunction.\n"); - return ret; - } - - force_iommu = 1; - dma_ops = &calgary_dma_ops; - - return 0; -} - -static int __init calgary_parse_options(char *p) -{ - unsigned int bridge; - size_t len; - char* endp; - - while (*p) { - if (!strncmp(p, "64k", 3)) - specified_table_size = TCE_TABLE_SIZE_64K; - else if (!strncmp(p, "128k", 4)) - specified_table_size = TCE_TABLE_SIZE_128K; - else if (!strncmp(p, "256k", 4)) - specified_table_size = TCE_TABLE_SIZE_256K; - else if (!strncmp(p, "512k", 4)) - specified_table_size = TCE_TABLE_SIZE_512K; - else if (!strncmp(p, "1M", 2)) - specified_table_size = TCE_TABLE_SIZE_1M; - else if (!strncmp(p, "2M", 2)) - specified_table_size = TCE_TABLE_SIZE_2M; - else if (!strncmp(p, "4M", 2)) - specified_table_size = TCE_TABLE_SIZE_4M; - else if (!strncmp(p, "8M", 2)) - specified_table_size = TCE_TABLE_SIZE_8M; - - len = strlen("translate_empty_slots"); - if (!strncmp(p, "translate_empty_slots", len)) - translate_empty_slots = 1; - - len = strlen("disable"); - if (!strncmp(p, "disable", len)) { - p += len; - if (*p == '=') - ++p; - if (*p == '\0') - break; - bridge = simple_strtol(p, &endp, 0); - if (p == endp) - break; - - if (bridge <= (num_online_nodes() * MAX_PHB_BUS_NUM)) { - printk(KERN_INFO "Calgary: disabling " - "translation for PHB 0x%x\n", bridge); - set_bit(bridge, translation_disabled); - } - } - - p = strpbrk(p, ","); - if (!p) - break; - - p++; /* skip ',' */ - } - return 1; -} -__setup("calgary=", calgary_parse_options); diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index 9c44f4f2433d..a9275c9557cf 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -9,7 +9,6 @@ #include #include #include -#include int iommu_merge __read_mostly = 0; EXPORT_SYMBOL(iommu_merge); @@ -34,15 +33,12 @@ int panic_on_overflow __read_mostly = 0; int force_iommu __read_mostly= 0; #endif -/* Set this to 1 if there is a HW IOMMU in the system */ -int iommu_detected __read_mostly = 0; - /* Dummy device used for NULL arguments (normally ISA). Better would be probably a smaller DMA mask, but this is bug-to-bug compatible to i386. */ struct device fallback_dev = { .bus_id = "fallback device", - .coherent_dma_mask = DMA_32BIT_MASK, + .coherent_dma_mask = 0xffffffff, .dma_mask = &fallback_dev.coherent_dma_mask, }; @@ -81,7 +77,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, dev = &fallback_dev; dma_mask = dev->coherent_dma_mask; if (dma_mask == 0) - dma_mask = DMA_32BIT_MASK; + dma_mask = 0xffffffff; /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; @@ -94,7 +90,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, larger than 16MB and in this case we have a chance of finding fitting memory in the next higher zone first. If not retry with true GFP_DMA. -AK */ - if (dma_mask <= DMA_32BIT_MASK) + if (dma_mask <= 0xffffffff) gfp |= GFP_DMA32; again: @@ -115,7 +111,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Don't use the 16MB ZONE_DMA unless absolutely needed. It's better to use remapping first. */ - if (dma_mask < DMA_32BIT_MASK && !(gfp & GFP_DMA)) { + if (dma_mask < 0xffffffff && !(gfp & GFP_DMA)) { gfp = (gfp & ~GFP_DMA32) | GFP_DMA; goto again; } @@ -178,7 +174,7 @@ int dma_supported(struct device *dev, u64 mask) /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. The caller just has to use GFP_DMA in this case. */ - if (mask < DMA_24BIT_MASK) + if (mask < 0x00ffffff) return 0; /* Tell the device to use SAC when IOMMU force is on. This @@ -193,7 +189,7 @@ int dma_supported(struct device *dev, u64 mask) SAC for these. Assume all masks <= 40 bits are of this type. Normally this doesn't make any difference, but gives more gentle handling of IOMMU overflow. */ - if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { + if (iommu_sac_force && (mask >= 0xffffffffffULL)) { printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->bus_id,mask); return 0; } @@ -270,7 +266,7 @@ __init int iommu_setup(char *p) swiotlb = 1; #endif -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU gart_parse_options(p); #endif @@ -280,40 +276,3 @@ __init int iommu_setup(char *p) } return 1; } -__setup("iommu=", iommu_setup); - -void __init pci_iommu_alloc(void) -{ - /* - * The order of these functions is important for - * fall-back/fail-over reasons - */ -#ifdef CONFIG_IOMMU - iommu_hole_init(); -#endif - -#ifdef CONFIG_CALGARY_IOMMU - detect_calgary(); -#endif - -#ifdef CONFIG_SWIOTLB - pci_swiotlb_init(); -#endif -} - -static int __init pci_iommu_init(void) -{ -#ifdef CONFIG_CALGARY_IOMMU - calgary_iommu_init(); -#endif - -#ifdef CONFIG_IOMMU - gart_iommu_init(); -#endif - - no_iommu_init(); - return 0; -} - -/* Must execute after PCI subsystem */ -fs_initcall(pci_iommu_init); diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 4ca674d16b09..82a7c9bfdfa0 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -32,7 +32,6 @@ #include #include #include -#include unsigned long iommu_bus_base; /* GART remapping area (physical) */ static unsigned long iommu_size; /* size of remapping area bytes */ @@ -47,6 +46,8 @@ u32 *iommu_gatt_base; /* Remapping table */ also seen with Qlogic at least). */ int iommu_fullflush = 1; +#define MAX_NB 8 + /* Allocation bitmap for the remapping area */ static DEFINE_SPINLOCK(iommu_bitmap_lock); static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */ @@ -62,6 +63,13 @@ static u32 gart_unmapped_entry; #define to_pages(addr,size) \ (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) +#define for_all_nb(dev) \ + dev = NULL; \ + while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL) + +static struct pci_dev *northbridges[MAX_NB]; +static u32 northbridge_flush_word[MAX_NB]; + #define EMERGENCY_PAGES 32 /* = 128KB */ #ifdef CONFIG_AGP @@ -85,7 +93,7 @@ static unsigned long alloc_iommu(int size) offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size); if (offset == -1) { need_flush = 1; - offset = find_next_zero_string(iommu_gart_bitmap,0,iommu_pages,size); + offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size); } if (offset != -1) { set_bit_string(iommu_gart_bitmap, offset, size); @@ -112,17 +120,44 @@ static void free_iommu(unsigned long offset, int size) /* * Use global flush state to avoid races with multiple flushers. */ -static void flush_gart(void) +static void flush_gart(struct device *dev) { unsigned long flags; + int flushed = 0; + int i, max; + spin_lock_irqsave(&iommu_bitmap_lock, flags); - if (need_flush) { - k8_flush_garts(); + if (need_flush) { + max = 0; + for (i = 0; i < MAX_NB; i++) { + if (!northbridges[i]) + continue; + pci_write_config_dword(northbridges[i], 0x9c, + northbridge_flush_word[i] | 1); + flushed++; + max = i; + } + for (i = 0; i <= max; i++) { + u32 w; + if (!northbridges[i]) + continue; + /* Make sure the hardware actually executed the flush. */ + for (;;) { + pci_read_config_dword(northbridges[i], 0x9c, &w); + if (!(w & 1)) + break; + cpu_relax(); + } + } + if (!flushed) + printk("nothing to flush?\n"); need_flush = 0; } spin_unlock_irqrestore(&iommu_bitmap_lock, flags); } + + #ifdef CONFIG_IOMMU_LEAK #define SET_LEAK(x) if (iommu_leak_tab) \ @@ -231,7 +266,7 @@ static dma_addr_t gart_map_simple(struct device *dev, char *buf, size_t size, int dir) { dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir); - flush_gart(); + flush_gart(dev); return map; } @@ -253,28 +288,6 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) return bus; } -/* - * Free a DMA mapping. - */ -void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction) -{ - unsigned long iommu_page; - int npages; - int i; - - if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || - dma_addr >= iommu_bus_base + iommu_size) - return; - iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; - npages = to_pages(dma_addr, size); - for (i = 0; i < npages; i++) { - iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; - CLEAR_LEAK(iommu_page + i); - } - free_iommu(iommu_page, npages); -} - /* * Wrapper for pci_unmap_single working with scatterlists. */ @@ -286,7 +299,7 @@ void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int di struct scatterlist *s = &sg[i]; if (!s->dma_length || !s->length) break; - gart_unmap_single(dev, s->dma_address, s->dma_length, dir); + dma_unmap_single(dev, s->dma_address, s->dma_length, dir); } } @@ -316,7 +329,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, s->dma_address = addr; s->dma_length = s->length; } - flush_gart(); + flush_gart(dev); return nents; } @@ -423,13 +436,13 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0) goto error; out++; - flush_gart(); + flush_gart(dev); if (out < nents) sg[out].dma_length = 0; return out; error: - flush_gart(); + flush_gart(NULL); gart_unmap_sg(dev, sg, nents, dir); /* When it was forced or merged try again in a dumb way */ if (force_iommu || iommu_merge) { @@ -445,6 +458,28 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) return 0; } +/* + * Free a DMA mapping. + */ +void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction) +{ + unsigned long iommu_page; + int npages; + int i; + + if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || + dma_addr >= iommu_bus_base + iommu_size) + return; + iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; + npages = to_pages(dma_addr, size); + for (i = 0; i < npages; i++) { + iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; + CLEAR_LEAK(iommu_page + i); + } + free_iommu(iommu_page, npages); +} + static int no_agp; static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size) @@ -497,13 +532,10 @@ static __init int init_k8_gatt(struct agp_kern_info *info) void *gatt; unsigned aper_base, new_aper_base; unsigned aper_size, gatt_size, new_aper_size; - int i; - + printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; - dev = NULL; - for (i = 0; i < num_k8_northbridges; i++) { - dev = k8_northbridges[i]; + for_all_nb(dev) { new_aper_base = read_aperture(dev, &new_aper_size); if (!new_aper_base) goto nommu; @@ -526,12 +558,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) panic("Cannot allocate GATT table"); memset(gatt, 0, gatt_size); agp_gatt_table = gatt; - - for (i = 0; i < num_k8_northbridges; i++) { + + for_all_nb(dev) { u32 ctl; u32 gatt_reg; - dev = k8_northbridges[i]; gatt_reg = __pa(gatt) >> 12; gatt_reg <<= 4; pci_write_config_dword(dev, 0x98, gatt_reg); @@ -542,7 +573,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) pci_write_config_dword(dev, 0x90, ctl); } - flush_gart(); + flush_gart(NULL); printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); return 0; @@ -571,19 +602,15 @@ static struct dma_mapping_ops gart_dma_ops = { .unmap_sg = gart_unmap_sg, }; -void __init gart_iommu_init(void) +static int __init pci_iommu_init(void) { struct agp_kern_info info; unsigned long aper_size; unsigned long iommu_start; + struct pci_dev *dev; unsigned long scratch; long i; - if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) { - printk(KERN_INFO "PCI-GART: No AMD northbridge found.\n"); - return; - } - #ifndef CONFIG_AGP_AMD64 no_agp = 1; #else @@ -595,11 +622,7 @@ void __init gart_iommu_init(void) #endif if (swiotlb) - return; - - /* Did we detect a different HW IOMMU? */ - if (iommu_detected && !iommu_aperture) - return; + return -1; if (no_iommu || (!force_iommu && end_pfn <= MAX_DMA32_PFN) || @@ -611,7 +634,15 @@ void __init gart_iommu_init(void) "but IOMMU not available.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); } - return; + return -1; + } + + i = 0; + for_all_nb(dev) + i++; + if (i > MAX_NB) { + printk(KERN_ERR "PCI-GART: Too many northbridges (%ld). Disabled\n", i); + return -1; } printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); @@ -676,10 +707,26 @@ void __init gart_iommu_init(void) for (i = EMERGENCY_PAGES; i < iommu_pages; i++) iommu_gatt_base[i] = gart_unmapped_entry; - flush_gart(); + for_all_nb(dev) { + u32 flag; + int cpu = PCI_SLOT(dev->devfn) - 24; + if (cpu >= MAX_NB) + continue; + northbridges[cpu] = dev; + pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */ + northbridge_flush_word[cpu] = flag; + } + + flush_gart(NULL); + dma_ops = &gart_dma_ops; + + return 0; } +/* Must execute after PCI subsystem */ +fs_initcall(pci_iommu_init); + void gart_parse_options(char *p) { int arg; diff --git a/trunk/arch/x86_64/kernel/pci-nommu.c b/trunk/arch/x86_64/kernel/pci-nommu.c index c4c3cc36ac5b..1f6ecc62061d 100644 --- a/trunk/arch/x86_64/kernel/pci-nommu.c +++ b/trunk/arch/x86_64/kernel/pci-nommu.c @@ -4,8 +4,6 @@ #include #include #include -#include - #include #include #include @@ -14,11 +12,10 @@ static int check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) { if (hwdev && bus + size > *hwdev->dma_mask) { - if (*hwdev->dma_mask >= DMA_32BIT_MASK) + if (*hwdev->dma_mask >= 0xffffffffULL) printk(KERN_ERR - "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", - name, (long long)bus, size, - (long long)*hwdev->dma_mask); + "nommu_%s: overflow %Lx+%lu of device mask %Lx\n", + name, (long long)bus, size, (long long)*hwdev->dma_mask); return 0; } return 1; diff --git a/trunk/arch/x86_64/kernel/pci-swiotlb.c b/trunk/arch/x86_64/kernel/pci-swiotlb.c index ebdb77fe2057..990ed67896f2 100644 --- a/trunk/arch/x86_64/kernel/pci-swiotlb.c +++ b/trunk/arch/x86_64/kernel/pci-swiotlb.c @@ -31,7 +31,7 @@ struct dma_mapping_ops swiotlb_dma_ops = { void pci_swiotlb_init(void) { /* don't initialize swiotlb if iommu=off (no_iommu=1) */ - if (!iommu_detected && !no_iommu && + if (!iommu_aperture && !no_iommu && (end_pfn > MAX_DMA32_PFN || force_iommu)) swiotlb = 1; if (swiotlb) { diff --git a/trunk/arch/x86_64/kernel/pmtimer.c b/trunk/arch/x86_64/kernel/pmtimer.c index 7554458dc9cb..bf421ed26808 100644 --- a/trunk/arch/x86_64/kernel/pmtimer.c +++ b/trunk/arch/x86_64/kernel/pmtimer.c @@ -27,7 +27,7 @@ /* The I/O port the PMTMR resides at. * The location is detected during setup_arch(), * in arch/i386/kernel/acpi/boot.c */ -u32 pmtmr_ioport __read_mostly; +u32 pmtmr_ioport; /* value of the Power timer at last timer interrupt */ static u32 offset_delay; diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index ca56e19b8b6e..fb903e65e079 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -10,6 +10,7 @@ * Andi Kleen. * * CPU hotplug support - ashok.raj@intel.com + * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ */ /* @@ -63,7 +64,6 @@ EXPORT_SYMBOL(boot_option_idle_override); * Powermanagement idle function, if any.. */ void (*pm_idle)(void); -EXPORT_SYMBOL(pm_idle); static DEFINE_PER_CPU(unsigned int, cpu_idle_state); static ATOMIC_NOTIFIER_HEAD(idle_notifier); @@ -111,7 +111,7 @@ static void default_idle(void) { local_irq_enable(); - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); while (!need_resched()) { local_irq_disable(); @@ -120,7 +120,7 @@ static void default_idle(void) else local_irq_enable(); } - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); } /* @@ -203,7 +203,8 @@ static inline void play_dead(void) */ void cpu_idle (void) { - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); + /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { @@ -334,7 +335,7 @@ void show_regs(struct pt_regs *regs) { printk("CPU %d:", smp_processor_id()); __show_regs(regs); - show_trace(NULL, regs, (void *)(regs + 1)); + show_trace(®s->rsp); } /* @@ -364,11 +365,8 @@ void flush_thread(void) struct task_struct *tsk = current; struct thread_info *t = current_thread_info(); - if (t->flags & _TIF_ABI_PENDING) { + if (t->flags & _TIF_ABI_PENDING) t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); - if (t->flags & _TIF_IA32) - current_thread_info()->status |= TS_COMPAT; - } tsk->thread.debugreg0 = 0; tsk->thread.debugreg1 = 0; diff --git a/trunk/arch/x86_64/kernel/reboot.c b/trunk/arch/x86_64/kernel/reboot.c index 2d6769847456..57117b8beb2b 100644 --- a/trunk/arch/x86_64/kernel/reboot.c +++ b/trunk/arch/x86_64/kernel/reboot.c @@ -20,7 +20,6 @@ * Power off function, if any */ void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); static long no_idt[3]; static enum { diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index 1129918ede82..655b9192eeb3 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -5,6 +5,8 @@ * * Nov 2001 Dave Jones * Forked from i386 setup code. + * + * $Id$ */ /* @@ -63,7 +65,9 @@ #include #include #include +#include #include +#include #include /* @@ -71,7 +75,6 @@ */ struct cpuinfo_x86 boot_cpu_data __read_mostly; -EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; @@ -100,14 +103,12 @@ char dmi_alloc_data[DMI_MAX_DATA]; * Setup options */ struct screen_info screen_info; -EXPORT_SYMBOL(screen_info); struct sys_desc_table_struct { unsigned short length; unsigned char table[0]; }; struct edid_info edid_info; -EXPORT_SYMBOL_GPL(edid_info); struct e820map e820; extern int root_mountflags; @@ -472,6 +473,80 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) } #endif +/* Use inline assembly to define this because the nops are defined + as inline assembly strings in the include files and we cannot + get them easily into strings. */ +asm("\t.data\nk8nops: " + K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 + K8_NOP7 K8_NOP8); + +extern unsigned char k8nops[]; +static unsigned char *k8_nops[ASM_NOP_MAX+1] = { + NULL, + k8nops, + k8nops + 1, + k8nops + 1 + 2, + k8nops + 1 + 2 + 3, + k8nops + 1 + 2 + 3 + 4, + k8nops + 1 + 2 + 3 + 4 + 5, + k8nops + 1 + 2 + 3 + 4 + 5 + 6, + k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, +}; + +extern char __vsyscall_0; + +/* Replace instructions with better alternatives for this CPU type. + + This runs before SMP is initialized to avoid SMP problems with + self modifying code. This implies that assymetric systems where + APs have less capabilities than the boot processor are not handled. + In this case boot with "noreplacement". */ +void apply_alternatives(void *start, void *end) +{ + struct alt_instr *a; + int diff, i, k; + for (a = start; (void *)a < end; a++) { + u8 *instr; + + if (!boot_cpu_has(a->cpuid)) + continue; + + BUG_ON(a->replacementlen > a->instrlen); + instr = a->instr; + /* vsyscall code is not mapped yet. resolve it manually. */ + if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) + instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0)); + __inline_memcpy(instr, a->replacement, a->replacementlen); + diff = a->instrlen - a->replacementlen; + + /* Pad the rest with nops */ + for (i = a->replacementlen; diff > 0; diff -= k, i += k) { + k = diff; + if (k > ASM_NOP_MAX) + k = ASM_NOP_MAX; + __inline_memcpy(instr + i, k8_nops[k], k); + } + } +} + +static int no_replacement __initdata = 0; + +void __init alternative_instructions(void) +{ + extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; + if (no_replacement) + return; + apply_alternatives(__alt_instructions, __alt_instructions_end); +} + +static int __init noreplacement_setup(char *s) +{ + no_replacement = 1; + return 1; +} + +__setup("noreplacement", noreplacement_setup); + #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -653,7 +728,7 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_KEXEC if (crashk_res.start != crashk_res.end) { - reserve_bootmem_generic(crashk_res.start, + reserve_bootmem(crashk_res.start, crashk_res.end - crashk_res.start + 1); } #endif @@ -704,6 +779,10 @@ void __init setup_arch(char **cmdline_p) e820_setup_gap(); +#ifdef CONFIG_GART_IOMMU + iommu_hole_init(); +#endif + #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con; @@ -788,32 +867,24 @@ static int nearby_node(int apicid) static void __init amd_detect_cmp(struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP + int cpu = smp_processor_id(); unsigned bits; #ifdef CONFIG_NUMA - int cpu = smp_processor_id(); int node = 0; unsigned apicid = hard_smp_processor_id(); #endif - unsigned ecx = cpuid_ecx(0x80000008); - - c->x86_max_cores = (ecx & 0xff) + 1; - /* CPU telling us the core id bits shift? */ - bits = (ecx >> 12) & 0xF; - - /* Otherwise recompute */ - if (bits == 0) { - while ((1 << bits) < c->x86_max_cores) - bits++; - } + bits = 0; + while ((1 << bits) < c->x86_max_cores) + bits++; /* Low order bits define the core id (index of core in socket) */ - c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1); + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1); /* Convert the APIC ID into the socket ID */ - c->phys_proc_id = phys_pkg_id(bits); + phys_proc_id[cpu] = phys_pkg_id(bits); #ifdef CONFIG_NUMA - node = c->phys_proc_id; + node = phys_proc_id[cpu]; if (apicid_to_node[apicid] != NUMA_NO_NODE) node = apicid_to_node[apicid]; if (!node_online(node)) { @@ -826,7 +897,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) but in the same order as the HT nodeids. If that doesn't result in a usable node fall back to the path for the previous case. */ - int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits); + int ht_nodeid = apicid - (phys_proc_id[0] << bits); if (ht_nodeid >= 0 && apicid_to_node[ht_nodeid] != NUMA_NO_NODE) node = apicid_to_node[ht_nodeid]; @@ -836,13 +907,15 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) } numa_set_node(cpu, node); - printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); + printk(KERN_INFO "CPU %d/%x(%d) -> Node %d -> Core %d\n", + cpu, apicid, c->x86_max_cores, node, cpu_core_id[cpu]); #endif #endif } -static void __init init_amd(struct cpuinfo_x86 *c) +static int __init init_amd(struct cpuinfo_x86 *c) { + int r; unsigned level; #ifdef CONFIG_SMP @@ -875,8 +948,8 @@ static void __init init_amd(struct cpuinfo_x86 *c) if (c->x86 >= 6) set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); - level = get_model_name(c); - if (!level) { + r = get_model_name(c); + if (!r) { switch (c->x86) { case 15: /* Should distinguish Models here, but this is only @@ -891,12 +964,13 @@ static void __init init_amd(struct cpuinfo_x86 *c) if (c->x86_power & (1<<8)) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); - /* Multi core CPU? */ - if (c->extended_cpuid_level >= 0x80000008) + if (c->extended_cpuid_level >= 0x80000008) { + c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; + amd_detect_cmp(c); + } - /* Fix cpuid4 emulation for more */ - num_cache_leaves = 3; + return r; } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -904,14 +978,13 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) #ifdef CONFIG_SMP u32 eax, ebx, ecx, edx; int index_msb, core_bits; + int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); - if (!cpu_has(c, X86_FEATURE_HT)) + if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; - if (cpu_has(c, X86_FEATURE_CMP_LEGACY)) - goto out; smp_num_siblings = (ebx & 0xff0000) >> 16; @@ -926,7 +999,10 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) } index_msb = get_count_order(smp_num_siblings); - c->phys_proc_id = phys_pkg_id(index_msb); + phys_proc_id[cpu] = phys_pkg_id(index_msb); + + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", + phys_proc_id[cpu]); smp_num_siblings = smp_num_siblings / c->x86_max_cores; @@ -934,15 +1010,13 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) core_bits = get_count_order(c->x86_max_cores); - c->cpu_core_id = phys_pkg_id(index_msb) & + cpu_core_id[cpu] = phys_pkg_id(index_msb) & ((1 << core_bits) - 1); - } -out: - if ((c->x86_max_cores * smp_num_siblings) > 1) { - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", c->phys_proc_id); - printk(KERN_INFO "CPU: Processor Core ID: %d\n", c->cpu_core_id); - } + if (c->x86_max_cores > 1) + printk(KERN_INFO "CPU: Processor Core ID: %d\n", + cpu_core_id[cpu]); + } #endif } @@ -951,12 +1025,15 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) */ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) { - unsigned int eax, t; + unsigned int eax; if (c->cpuid_level < 4) return 1; - cpuid_count(4, 0, &eax, &t, &t, &t); + __asm__("cpuid" + : "=a" (eax) + : "0" (4), "c" (0) + : "bx", "dx"); if (eax & 0x1f) return ((eax >> 26) + 1); @@ -969,17 +1046,16 @@ static void srat_detect_node(void) #ifdef CONFIG_NUMA unsigned node; int cpu = smp_processor_id(); - int apicid = hard_smp_processor_id(); /* Don't do the funky fallback heuristics the AMD version employs for now. */ - node = apicid_to_node[apicid]; + node = apicid_to_node[hard_smp_processor_id()]; if (node == NUMA_NO_NODE) node = first_node(node_online_map); numa_set_node(cpu, node); if (acpi_numa > 0) - printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); + printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node); #endif } @@ -989,13 +1065,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) unsigned n; init_intel_cacheinfo(c); - if (c->cpuid_level > 9 ) { - unsigned eax = cpuid_eax(10); - /* Check for version and the number of counters */ - if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) - set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); - } - n = c->extended_cpuid_level; if (n >= 0x80000008) { unsigned eax = cpuid_eax(0x80000008); @@ -1087,7 +1156,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) } #ifdef CONFIG_SMP - c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; + phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; #endif } @@ -1214,7 +1283,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, - NULL, "fxsr_opt", NULL, "rdtscp", NULL, "lm", "3dnowext", "3dnow", + NULL, "fxsr_opt", "rdtscp", NULL, NULL, "lm", "3dnowext", "3dnow", /* Transmeta-defined */ "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, @@ -1225,7 +1294,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Other (Linux-defined) */ "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, "constant_tsc", NULL, NULL, - "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -1295,9 +1364,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) #ifdef CONFIG_SMP if (smp_num_siblings * c->x86_max_cores > 1) { int cpu = c - cpu_data; - seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); + seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu])); - seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); + seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } #endif @@ -1371,7 +1440,7 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; -#if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE) +#ifdef CONFIG_INPUT_PCSPKR #include static __init int add_pcspkr(void) { diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index f5934cb4a2b6..8a691fa6d393 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -3,6 +3,7 @@ * Copyright (C) 1995 Linus Torvalds * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen. * See setup.c for older changelog. + * $Id: setup64.c,v 1.12 2002/03/21 10:09:17 ak Exp $ */ #include #include @@ -30,7 +31,6 @@ char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(_cpu_pda); struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned; struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; @@ -38,7 +38,6 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); unsigned long __supported_pte_mask __read_mostly = ~0UL; -EXPORT_SYMBOL(__supported_pte_mask); static int do_not_nx __cpuinitdata = 0; /* noexec=on|off diff --git a/trunk/arch/x86_64/kernel/signal.c b/trunk/arch/x86_64/kernel/signal.c index 28161170fb0a..e5f5ce7909a3 100644 --- a/trunk/arch/x86_64/kernel/signal.c +++ b/trunk/arch/x86_64/kernel/signal.c @@ -7,6 +7,8 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen + * + * $Id: signal.c,v 1.18 2001/10/17 22:30:37 ak Exp $ */ #include @@ -237,6 +239,7 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) rsp = regs->rsp - 128; /* This is the X/Open sanctioned signal stack switching. */ + /* RED-PEN: redzone on that stack? */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(rsp) == 0) rsp = current->sas_ss_sp + current->sas_ss_size; diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 5a1c0a3bf872..4a6628b14d99 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) cpu = smp_processor_id(); /* - * orig_rax contains the negated interrupt vector. + * orig_rax contains the interrupt vector - 256. * Use that to determine where the sender put the data. */ - sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; + sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; f = &per_cpu(flush_state, sender); if (!cpu_isset(cpu, f->flush_cpumask)) @@ -224,7 +224,6 @@ void flush_tlb_current_task(void) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_current_task); void flush_tlb_mm (struct mm_struct * mm) { @@ -245,7 +244,6 @@ void flush_tlb_mm (struct mm_struct * mm) preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_mm); void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) { @@ -268,7 +266,6 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_page); static void do_flush_tlb_all(void* info) { @@ -446,7 +443,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, spin_unlock(&call_lock); return 0; } -EXPORT_SYMBOL(smp_call_function); void smp_stop_cpu(void) { @@ -464,7 +460,7 @@ static void smp_really_stop_cpu(void *dummy) { smp_stop_cpu(); for (;;) - halt(); + asm("hlt"); } void smp_send_stop(void) @@ -474,7 +470,7 @@ void smp_send_stop(void) return; /* Don't deadlock on the call lock in panic */ if (!spin_trylock(&call_lock)) { - /* ignore locking because we have panicked anyways */ + /* ignore locking because we have paniced anyways */ nolock = 1; } __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); @@ -524,13 +520,13 @@ asmlinkage void smp_call_function_interrupt(void) int safe_smp_processor_id(void) { - unsigned apicid, i; + int apicid, i; if (disable_apic) return 0; apicid = hard_smp_processor_id(); - if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid) + if (x86_cpu_to_apicid[apicid] == apicid) return apicid; for (i = 0; i < NR_CPUS; ++i) { diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 540c0ccbcccc..71a7222cf9ce 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -63,11 +63,13 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -EXPORT_SYMBOL(smp_num_siblings); +/* Package ID of each logical CPU */ +u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; +/* core ID of each logical CPU */ +u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; /* Last level cache ID of each logical CPU */ u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; -EXPORT_SYMBOL(cpu_llc_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map __read_mostly; @@ -80,21 +82,18 @@ EXPORT_SYMBOL(cpu_online_map); */ cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; -EXPORT_SYMBOL(cpu_callout_map); cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL(cpu_data); /* Set when the idlers are all forked */ int smp_threads_ready; /* representing HT siblings of each logical CPU */ cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(cpu_sibling_map); /* representing HT and core siblings of each logical CPU */ cpumask_t cpu_core_map[NR_CPUS] __read_mostly; @@ -455,12 +454,10 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * And for power savings, we return cpu_core_map + * TBD: when power saving sched policy is added, we will return + * cpu_core_map when power saving policy is enabled */ - if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; - else - return c->llc_shared_map; + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ @@ -475,8 +472,8 @@ static inline void set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu_mask(i, cpu_sibling_setup_map) { - if (c[cpu].phys_proc_id == c[i].phys_proc_id && - c[cpu].cpu_core_id == c[i].cpu_core_id) { + if (phys_proc_id[cpu] == phys_proc_id[i] && + cpu_core_id[cpu] == cpu_core_id[i]) { cpu_set(i, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[i]); cpu_set(i, cpu_core_map[cpu]); @@ -503,7 +500,7 @@ static inline void set_cpu_sibling_map(int cpu) cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } - if (c[cpu].phys_proc_id == c[i].phys_proc_id) { + if (phys_proc_id[cpu] == phys_proc_id[i]) { cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); /* @@ -800,8 +797,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) } - alternatives_smp_switch(1); - c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -1204,8 +1199,8 @@ static void remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_map[sibling]); cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); - c[cpu].phys_proc_id = 0; - c[cpu].cpu_core_id = 0; + phys_proc_id[cpu] = BAD_APICID; + cpu_core_id[cpu] = BAD_APICID; cpu_clear(cpu, cpu_sibling_setup_map); } @@ -1264,8 +1259,6 @@ void __cpu_die(unsigned int cpu) /* They ack this in play_dead by setting CPU_DEAD */ if (per_cpu(cpu_state, cpu) == CPU_DEAD) { printk ("CPU %d is now offline\n", cpu); - if (1 == num_online_cpus()) - alternatives_smp_switch(0); return; } msleep(100); diff --git a/trunk/arch/x86_64/kernel/tce.c b/trunk/arch/x86_64/kernel/tce.c deleted file mode 100644 index 8d4c67f61b8e..000000000000 --- a/trunk/arch/x86_64/kernel/tce.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Derived from arch/powerpc/platforms/pseries/iommu.c - * - * Copyright (C) 2006 Jon Mason , IBM Corporation - * Copyright (C) 2006 Muli Ben-Yehuda , IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* flush a tce at 'tceaddr' to main memory */ -static inline void flush_tce(void* tceaddr) -{ - /* a single tce can't cross a cache line */ - if (cpu_has_clflush) - asm volatile("clflush (%0)" :: "r" (tceaddr)); - else - asm volatile("wbinvd":::"memory"); -} - -void tce_build(struct iommu_table *tbl, unsigned long index, - unsigned int npages, unsigned long uaddr, int direction) -{ - u64* tp; - u64 t; - u64 rpn; - - t = (1 << TCE_READ_SHIFT); - if (direction != DMA_TO_DEVICE) - t |= (1 << TCE_WRITE_SHIFT); - - tp = ((u64*)tbl->it_base) + index; - - while (npages--) { - rpn = (virt_to_bus((void*)uaddr)) >> PAGE_SHIFT; - t &= ~TCE_RPN_MASK; - t |= (rpn << TCE_RPN_SHIFT); - - *tp = cpu_to_be64(t); - flush_tce(tp); - - uaddr += PAGE_SIZE; - tp++; - } -} - -void tce_free(struct iommu_table *tbl, long index, unsigned int npages) -{ - u64* tp; - - tp = ((u64*)tbl->it_base) + index; - - while (npages--) { - *tp = cpu_to_be64(0); - flush_tce(tp); - tp++; - } -} - -static inline unsigned int table_size_to_number_of_entries(unsigned char size) -{ - /* - * size is the order of the table, 0-7 - * smallest table is 8K entries, so shift result by 13 to - * multiply by 8K - */ - return (1 << size) << 13; -} - -static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) -{ - unsigned int bitmapsz; - unsigned int tce_table_index; - unsigned long bmppages; - int ret; - - tbl->it_busno = dev->bus->number; - - /* set the tce table size - measured in entries */ - tbl->it_size = table_size_to_number_of_entries(specified_table_size); - - tce_table_index = bus_to_phb(tbl->it_busno); - tbl->it_base = (unsigned long)tce_table_kva[tce_table_index]; - if (!tbl->it_base) { - printk(KERN_ERR "Calgary: iommu_table_setparms: " - "no table allocated?!\n"); - ret = -ENOMEM; - goto done; - } - - /* - * number of bytes needed for the bitmap size in number of - * entries; we need one bit per entry - */ - bitmapsz = tbl->it_size / BITS_PER_BYTE; - bmppages = __get_free_pages(GFP_KERNEL, get_order(bitmapsz)); - if (!bmppages) { - printk(KERN_ERR "Calgary: cannot allocate bitmap\n"); - ret = -ENOMEM; - goto done; - } - - tbl->it_map = (unsigned long*)bmppages; - - memset(tbl->it_map, 0, bitmapsz); - - tbl->it_hint = 0; - - spin_lock_init(&tbl->it_lock); - - return 0; - -done: - return ret; -} - -int build_tce_table(struct pci_dev *dev, void __iomem *bbar) -{ - struct iommu_table *tbl; - int ret; - - if (dev->sysdata) { - printk(KERN_ERR "Calgary: dev %p has sysdata %p\n", - dev, dev->sysdata); - BUG(); - } - - tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL); - if (!tbl) { - printk(KERN_ERR "Calgary: error allocating iommu_table\n"); - ret = -ENOMEM; - goto done; - } - - ret = tce_table_setparms(dev, tbl); - if (ret) - goto free_tbl; - - tce_free(tbl, 0, tbl->it_size); - - tbl->bbar = bbar; - - /* - * NUMA is already using the bus's sysdata pointer, so we use - * the bus's pci_dev's sysdata instead. - */ - dev->sysdata = tbl; - - return 0; - -free_tbl: - kfree(tbl); -done: - return ret; -} - -void* alloc_tce_table(void) -{ - unsigned int size; - - size = table_size_to_number_of_entries(specified_table_size); - size *= TCE_ENTRY_SIZE; - - return __alloc_bootmem_low(size, size, 0); -} - -void free_tce_table(void *tbl) -{ - unsigned int size; - - if (!tbl) - return; - - size = table_size_to_number_of_entries(specified_table_size); - size *= TCE_ENTRY_SIZE; - - free_bootmem(__pa(tbl), size); -} diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index ebbee6f59ff5..7392570f975d 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -8,7 +8,7 @@ * Copyright (c) 1995 Markus Kuhn * Copyright (c) 1996 Ingo Molnar * Copyright (c) 1998 Andrea Arcangeli - * Copyright (c) 2002,2006 Vojtech Pavlik + * Copyright (c) 2002 Vojtech Pavlik * Copyright (c) 2003 Andi Kleen * RTC support code taken from arch/i386/kernel/timers/time_hpet.c */ @@ -51,21 +51,14 @@ extern int using_apic_timer; static char *time_init_gtod(void); DEFINE_SPINLOCK(rtc_lock); -EXPORT_SYMBOL(rtc_lock); DEFINE_SPINLOCK(i8253_lock); int nohpet __initdata = 0; static int notsc __initdata = 0; -#define USEC_PER_TICK (USEC_PER_SEC / HZ) -#define NSEC_PER_TICK (NSEC_PER_SEC / HZ) -#define FSEC_PER_TICK (FSEC_PER_SEC / HZ) - -#define NS_SCALE 10 /* 2^10, carefully chosen */ -#define US_SCALE 32 /* 2^32, arbitralrily chosen */ +#undef HPET_HACK_ENABLE_DANGEROUS unsigned int cpu_khz; /* TSC clocks / usec, not used here */ -EXPORT_SYMBOL(cpu_khz); static unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* HPET clocks / interrupt */ int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ @@ -97,7 +90,7 @@ static inline unsigned int do_gettimeoffset_tsc(void) t = get_cycles_sync(); if (t < vxtime.last_tsc) t = vxtime.last_tsc; /* hack */ - x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> US_SCALE; + x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> 32; return x; } @@ -105,7 +98,7 @@ static inline unsigned int do_gettimeoffset_hpet(void) { /* cap counter read to one tick to avoid inconsistencies */ unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last; - return (min(counter,hpet_tick) * vxtime.quot) >> US_SCALE; + return (min(counter,hpet_tick) * vxtime.quot) >> 32; } unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; @@ -125,7 +118,7 @@ void do_gettimeofday(struct timeval *tv) seq = read_seqbegin(&xtime_lock); sec = xtime.tv_sec; - usec = xtime.tv_nsec / NSEC_PER_USEC; + usec = xtime.tv_nsec / 1000; /* i386 does some correction here to keep the clock monotonous even when ntpd is fixing drift. @@ -136,14 +129,14 @@ void do_gettimeofday(struct timeval *tv) in arch/x86_64/kernel/vsyscall.c and export all needed variables in vmlinux.lds. -AK */ - t = (jiffies - wall_jiffies) * USEC_PER_TICK + + t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); usec += t; } while (read_seqretry(&xtime_lock, seq)); - tv->tv_sec = sec + usec / USEC_PER_SEC; - tv->tv_usec = usec % USEC_PER_SEC; + tv->tv_sec = sec + usec / 1000000; + tv->tv_usec = usec % 1000000; } EXPORT_SYMBOL(do_gettimeofday); @@ -164,8 +157,8 @@ int do_settimeofday(struct timespec *tv) write_seqlock_irq(&xtime_lock); - nsec -= do_gettimeoffset() * NSEC_PER_USEC + - (jiffies - wall_jiffies) * NSEC_PER_TICK; + nsec -= do_gettimeoffset() * 1000 + + (jiffies - wall_jiffies) * (NSEC_PER_SEC/HZ); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -295,7 +288,7 @@ unsigned long long monotonic_clock(void) this_offset = hpet_readl(HPET_COUNTER); } while (read_seqretry(&xtime_lock, seq)); offset = (this_offset - last_offset); - offset *= NSEC_PER_TICK / hpet_tick; + offset *= (NSEC_PER_SEC/HZ) / hpet_tick; } else { do { seq = read_seqbegin(&xtime_lock); @@ -304,8 +297,7 @@ unsigned long long monotonic_clock(void) base = monotonic_base; } while (read_seqretry(&xtime_lock, seq)); this_offset = get_cycles_sync(); - /* FIXME: 1000 or 1000000? */ - offset = (this_offset - last_offset)*1000 / cpu_khz; + offset = (this_offset - last_offset)*1000 / cpu_khz; } return base + offset; } @@ -390,7 +382,7 @@ void main_timer_handler(struct pt_regs *regs) } monotonic_base += - (offset - vxtime.last) * NSEC_PER_TICK / hpet_tick; + (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; vxtime.last = offset; #ifdef CONFIG_X86_PM_TIMER @@ -399,25 +391,24 @@ void main_timer_handler(struct pt_regs *regs) #endif } else { offset = (((tsc - vxtime.last_tsc) * - vxtime.tsc_quot) >> US_SCALE) - USEC_PER_TICK; + vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); if (offset < 0) offset = 0; - if (offset > USEC_PER_TICK) { - lost = offset / USEC_PER_TICK; - offset %= USEC_PER_TICK; + if (offset > (USEC_PER_SEC / HZ)) { + lost = offset / (USEC_PER_SEC / HZ); + offset %= (USEC_PER_SEC / HZ); } - /* FIXME: 1000 or 1000000? */ - monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz; + monotonic_base += (tsc - vxtime.last_tsc)*1000000/cpu_khz ; vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; if ((((tsc - vxtime.last_tsc) * - vxtime.tsc_quot) >> US_SCALE) < offset) + vxtime.tsc_quot) >> 32) < offset) vxtime.last_tsc = tsc - - (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1; + (((long) offset << 32) / vxtime.tsc_quot) - 1; } if (lost > 0) { @@ -477,15 +468,16 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static unsigned int cyc2ns_scale __read_mostly; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ static inline void set_cyc2ns_scale(unsigned long cpu_khz) { - cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / cpu_khz; + cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; } static inline unsigned long long cycles_2_ns(unsigned long long cyc) { - return (cyc * cyc2ns_scale) >> NS_SCALE; + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; } unsigned long long sched_clock(void) @@ -498,7 +490,7 @@ unsigned long long sched_clock(void) Disadvantage is a small drift between CPUs in some configurations, but that should be tolerable. */ if (__vxtime.mode == VXTIME_HPET) - return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> US_SCALE; + return (hpet_readl(HPET_COUNTER) * vxtime.quot) >> 32; #endif /* Could do CPU core sync here. Opteron can execute rdtsc speculatively, @@ -641,7 +633,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; + vxtime.tsc_quot = (1000L << 32) / cpu_khz; } set_cyc2ns_scale(cpu_khz_ref); @@ -797,8 +789,8 @@ static int hpet_timer_stop_set_go(unsigned long tick) if (hpet_use_timer) { hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT, HPET_T0_CFG); - hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */ - hpet_writel(hpet_tick, HPET_T0_CMP); /* period */ + hpet_writel(hpet_tick, HPET_T0_CMP); + hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ cfg |= HPET_CFG_LEGACY; } /* @@ -833,7 +825,8 @@ static int hpet_init(void) if (hpet_period < 100000 || hpet_period > 100000000) return -1; - hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period; + hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) / + hpet_period; hpet_use_timer = (id & HPET_ID_LEGSUP); @@ -897,6 +890,18 @@ void __init time_init(void) char *timename; char *gtod; +#ifdef HPET_HACK_ENABLE_DANGEROUS + if (!vxtime.hpet_address) { + printk(KERN_WARNING "time.c: WARNING: Enabling HPET base " + "manually!\n"); + outl(0x800038a0, 0xcf8); + outl(0xff000001, 0xcfc); + outl(0x800038a0, 0xcf8); + vxtime.hpet_address = inl(0xcfc) & 0xfffffffe; + printk(KERN_WARNING "time.c: WARNING: Enabled HPET " + "at %#lx.\n", vxtime.hpet_address); + } +#endif if (nohpet) vxtime.hpet_address = 0; @@ -907,7 +912,7 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); if (!hpet_init()) - vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period; + vxtime_hz = (1000000000000000L + hpet_period / 2) / hpet_period; else vxtime.hpet_address = 0; @@ -936,8 +941,8 @@ void __init time_init(void) vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); - vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; - vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; + vxtime.quot = (1000000L << 32) / vxtime_hz; + vxtime.tsc_quot = (1000L << 32) / cpu_khz; vxtime.last_tsc = get_cycles_sync(); setup_irq(0, &irq0); @@ -951,10 +956,10 @@ void __init time_init(void) __cpuinit int unsynchronized_tsc(void) { #ifdef CONFIG_SMP - if (apic_is_clustered_box()) + if (oem_force_hpet_timer()) return 1; /* Intel systems are normally all synchronized. Exceptions - are handled in the check above. */ + are handled in the OEM check above. */ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) return 0; #endif diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 3d11a2fe45b7..cea335e8746c 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -6,6 +6,8 @@ * * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 + * + * $Id: traps.c,v 1.36 2002/03/24 11:09:10 ak Exp $ */ /* @@ -29,7 +31,6 @@ #include #include #include -#include #include #include @@ -40,7 +41,7 @@ #include #include #include -#include + #include #include #include @@ -70,7 +71,6 @@ asmlinkage void machine_check(void); asmlinkage void spurious_interrupt_bug(void); ATOMIC_NOTIFIER_HEAD(die_chain); -EXPORT_SYMBOL(die_chain); int register_die_notifier(struct notifier_block *nb) { @@ -107,8 +107,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) preempt_enable_no_resched(); } -static int kstack_depth_to_print = 12; -static int call_trace = 1; +static int kstack_depth_to_print = 10; #ifdef CONFIG_KALLSYMS #include @@ -192,25 +191,6 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -static int show_trace_unwind(struct unwind_frame_info *info, void *context) -{ - int i = 11, n = 0; - - while (unwind(info) == 0 && UNW_PC(info)) { - ++n; - if (i > 50) { - printk("\n "); - i = 7; - } else - i += printk(" "); - i += printk_address(UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - } - printk("\n"); - return n; -} - /* * x86-64 can have upto three kernel stacks: * process stack @@ -218,39 +198,15 @@ static int show_trace_unwind(struct unwind_frame_info *info, void *context) * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack) +void show_trace(unsigned long *stack) { const unsigned cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; - int i = 11; + int i; unsigned used = 0; printk("\nCall Trace:"); - if (!tsk) - tsk = current; - - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - - if (regs) { - if (unwind_init_frame_info(&info, tsk, regs) == 0) - unw_ret = show_trace_unwind(&info, NULL); - } else if (tsk == current) - unw_ret = unwind_init_running(&info, show_trace_unwind, NULL); - else { - if (unwind_init_blocked(&info, tsk) == 0) - unw_ret = show_trace_unwind(&info, NULL); - } - if (unw_ret > 0) { - if (call_trace > 0) - return; - printk("Legacy call trace:"); - i = 18; - } - } - #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ @@ -273,7 +229,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s } \ } while (0) - for(; ; ) { + for(i = 11; ; ) { const char *id; unsigned long *estack_end; estack_end = in_exception_stack(cpu, (unsigned long)stack, @@ -308,7 +264,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s printk("\n"); } -static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp) +void show_stack(struct task_struct *tsk, unsigned long * rsp) { unsigned long *stack; int i; @@ -342,12 +298,7 @@ static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned printk("%016lx ", *stack++); touch_nmi_watchdog(); } - show_trace(tsk, regs, rsp); -} - -void show_stack(struct task_struct *tsk, unsigned long * rsp) -{ - _show_stack(tsk, NULL, rsp); + show_trace((unsigned long *)rsp); } /* @@ -356,7 +307,7 @@ void show_stack(struct task_struct *tsk, unsigned long * rsp) void dump_stack(void) { unsigned long dummy; - show_trace(NULL, NULL, &dummy); + show_trace(&dummy); } EXPORT_SYMBOL(dump_stack); @@ -383,7 +334,7 @@ void show_registers(struct pt_regs *regs) if (in_kernel) { printk("Stack: "); - _show_stack(NULL, regs, (unsigned long*)rsp); + show_stack(NULL, (unsigned long*)rsp); printk("\nCode: "); if (regs->rip < PAGE_OFFSET) @@ -432,7 +383,6 @@ void out_of_line_bug(void) { BUG(); } -EXPORT_SYMBOL(out_of_line_bug); #endif static DEFINE_SPINLOCK(die_lock); @@ -1062,14 +1012,3 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); -static int __init call_trace_setup(char *s) -{ - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "new") == 0) - call_trace = 1; - return 1; -} -__setup("call_trace=", call_trace_setup); diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index 1c6a5f322919..b81f473c4a19 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -45,15 +45,6 @@ SECTIONS RODATA -#ifdef CONFIG_STACK_UNWIND - . = ALIGN(8); - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { - __start_unwind = .; - *(.eh_frame) - __end_unwind = .; - } -#endif - /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) @@ -140,26 +131,6 @@ SECTIONS *(.data.page_aligned) } - /* might get freed after init */ - . = ALIGN(4096); - __smp_alt_begin = .; - __smp_alt_instructions = .; - .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { - *(.smp_altinstructions) - } - __smp_alt_instructions_end = .; - . = ALIGN(8); - __smp_locks = .; - .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { - *(.smp_locks) - } - __smp_locks_end = .; - .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { - *(.smp_altinstr_replacement) - } - . = ALIGN(4096); - __smp_alt_end = .; - . = ALIGN(4096); /* Init code and data */ __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index f603037df162..9468fb20b0bc 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -107,7 +107,7 @@ static __always_inline long time_syscall(long *t) int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) { - if (!__sysctl_vsyscall) + if (unlikely(!__sysctl_vsyscall)) return gettimeofday(tv,tz); if (tv) do_vgettimeofday(tv); @@ -120,7 +120,7 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) * unlikely */ time_t __vsyscall(1) vtime(time_t *t) { - if (!__sysctl_vsyscall) + if (unlikely(!__sysctl_vsyscall)) return time_syscall(t); else if (t) *t = __xtime.tv_sec; diff --git a/trunk/arch/x86_64/kernel/x8664_ksyms.c b/trunk/arch/x86_64/kernel/x8664_ksyms.c index 370952c4ff22..1def21c9f7cd 100644 --- a/trunk/arch/x86_64/kernel/x8664_ksyms.c +++ b/trunk/arch/x86_64/kernel/x8664_ksyms.c @@ -1,21 +1,66 @@ -/* Exports for assembly files. - All C exports should go in the respective C files. */ - #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include + +extern spinlock_t rtc_lock; +#ifdef CONFIG_SMP +extern void __write_lock_failed(rwlock_t *rw); +extern void __read_lock_failed(rwlock_t *rw); +#endif + +/* platform dependent support */ +EXPORT_SYMBOL(boot_cpu_data); +//EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(ioremap_nocache); +EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(pm_idle); +EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(__down_failed); EXPORT_SYMBOL(__down_failed_interruptible); EXPORT_SYMBOL(__down_failed_trylock); EXPORT_SYMBOL(__up_wakeup); +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy_nocheck); +EXPORT_SYMBOL(ip_compute_csum); +/* Delay loops */ +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__ndelay); +EXPORT_SYMBOL(__delay); +EXPORT_SYMBOL(__const_udelay); EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); @@ -26,20 +71,42 @@ EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); +EXPORT_SYMBOL(strncpy_from_user); +EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(clear_user); +EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(copy_user_generic); EXPORT_SYMBOL(copy_from_user); EXPORT_SYMBOL(copy_to_user); +EXPORT_SYMBOL(copy_in_user); +EXPORT_SYMBOL(strnlen_user); + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_mem_start); +#endif EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(_cpu_pda); #ifdef CONFIG_SMP -extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); -extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); +EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__read_lock_failed); + +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(cpu_callout_map); +#endif + +#ifdef CONFIG_VT +EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(rtc_lock); + +EXPORT_SYMBOL_GPL(set_nmi_callback); +EXPORT_SYMBOL_GPL(unset_nmi_callback); + /* Export string functions. We normally rely on gcc builtin for most of these, but gcc sometimes decides not to inline them. */ #undef memcpy @@ -47,14 +114,51 @@ EXPORT_SYMBOL(__read_lock_failed); #undef memmove extern void * memset(void *,int,__kernel_size_t); +extern size_t strlen(const char *); +extern void * memmove(void * dest,const void *src,size_t count); extern void * memcpy(void *,const void *,__kernel_size_t); extern void * __memcpy(void *,const void *,__kernel_size_t); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__memcpy); +#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM +/* prototypes are wrong, these are assembly with custom calling functions */ +extern void rwsem_down_read_failed_thunk(void); +extern void rwsem_wake_thunk(void); +extern void rwsem_downgrade_thunk(void); +extern void rwsem_down_write_failed_thunk(void); +EXPORT_SYMBOL(rwsem_down_read_failed_thunk); +EXPORT_SYMBOL(rwsem_wake_thunk); +EXPORT_SYMBOL(rwsem_downgrade_thunk); +EXPORT_SYMBOL(rwsem_down_write_failed_thunk); +#endif + EXPORT_SYMBOL(empty_zero_page); + +EXPORT_SYMBOL(die_chain); + +#ifdef CONFIG_SMP +EXPORT_SYMBOL(cpu_sibling_map); +EXPORT_SYMBOL(smp_num_siblings); +#endif + +#ifdef CONFIG_BUG +EXPORT_SYMBOL(out_of_line_bug); +#endif + EXPORT_SYMBOL(init_level4_pgt); + +extern unsigned long __supported_pte_mask; +EXPORT_SYMBOL(__supported_pte_mask); + +#ifdef CONFIG_SMP +EXPORT_SYMBOL(flush_tlb_page); +#endif + +EXPORT_SYMBOL(cpu_khz); + EXPORT_SYMBOL(load_gs_index); diff --git a/trunk/arch/x86_64/lib/csum-partial.c b/trunk/arch/x86_64/lib/csum-partial.c index c493735218da..5384e227cdf6 100644 --- a/trunk/arch/x86_64/lib/csum-partial.c +++ b/trunk/arch/x86_64/lib/csum-partial.c @@ -147,5 +147,4 @@ unsigned short ip_compute_csum(unsigned char * buff, int len) { return csum_fold(csum_partial(buff,len,0)); } -EXPORT_SYMBOL(ip_compute_csum); diff --git a/trunk/arch/x86_64/lib/csum-wrappers.c b/trunk/arch/x86_64/lib/csum-wrappers.c index b1320ec58428..94323f20816e 100644 --- a/trunk/arch/x86_64/lib/csum-wrappers.c +++ b/trunk/arch/x86_64/lib/csum-wrappers.c @@ -109,7 +109,6 @@ csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, { return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL); } -EXPORT_SYMBOL(csum_partial_copy_nocheck); unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len, unsigned short proto, unsigned int sum) diff --git a/trunk/arch/x86_64/lib/delay.c b/trunk/arch/x86_64/lib/delay.c index b6cd3cca2f45..03c460cbdd1c 100644 --- a/trunk/arch/x86_64/lib/delay.c +++ b/trunk/arch/x86_64/lib/delay.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -37,22 +36,18 @@ void __delay(unsigned long loops) } while((now-bclock) < loops); } -EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { __delay((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32); } -EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) { __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } -EXPORT_SYMBOL(__udelay); void __ndelay(unsigned long nsecs) { __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } -EXPORT_SYMBOL(__ndelay); diff --git a/trunk/arch/x86_64/lib/memmove.c b/trunk/arch/x86_64/lib/memmove.c index 751ebae8ec42..e93d5255fdc9 100644 --- a/trunk/arch/x86_64/lib/memmove.c +++ b/trunk/arch/x86_64/lib/memmove.c @@ -3,13 +3,12 @@ */ #define _STRING_C #include -#include #undef memmove void *memmove(void * dest,const void *src,size_t count) { if (dest < src) { - return memcpy(dest,src,count); + __inline_memcpy(dest,src,count); } else { char *p = (char *) dest + count; char *s = (char *) src + count; @@ -18,4 +17,3 @@ void *memmove(void * dest,const void *src,size_t count) } return dest; } -EXPORT_SYMBOL(memmove); diff --git a/trunk/arch/x86_64/lib/usercopy.c b/trunk/arch/x86_64/lib/usercopy.c index 893d43f838cc..9bc2c295818e 100644 --- a/trunk/arch/x86_64/lib/usercopy.c +++ b/trunk/arch/x86_64/lib/usercopy.c @@ -5,7 +5,6 @@ * Copyright 1997 Linus Torvalds * Copyright 2002 Andi Kleen */ -#include #include /* @@ -48,17 +47,15 @@ __strncpy_from_user(char *dst, const char __user *src, long count) __do_strncpy_from_user(dst, src, count, res); return res; } -EXPORT_SYMBOL(__strncpy_from_user); long strncpy_from_user(char *dst, const char __user *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) - return __strncpy_from_user(dst, src, count); + __do_strncpy_from_user(dst, src, count, res); return res; } -EXPORT_SYMBOL(strncpy_from_user); /* * Zero Userspace @@ -97,7 +94,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size) [zero] "r" (0UL), [eight] "r" (8UL)); return size; } -EXPORT_SYMBOL(__clear_user); + unsigned long clear_user(void __user *to, unsigned long n) { @@ -105,7 +102,6 @@ unsigned long clear_user(void __user *to, unsigned long n) return __clear_user(to, n); return n; } -EXPORT_SYMBOL(clear_user); /* * Return the size of a string (including the ending 0) @@ -129,7 +125,6 @@ long __strnlen_user(const char __user *s, long n) s++; } } -EXPORT_SYMBOL(__strnlen_user); long strnlen_user(const char __user *s, long n) { @@ -137,7 +132,6 @@ long strnlen_user(const char __user *s, long n) return 0; return __strnlen_user(s, n); } -EXPORT_SYMBOL(strnlen_user); long strlen_user(const char __user *s) { @@ -153,7 +147,6 @@ long strlen_user(const char __user *s) s++; } } -EXPORT_SYMBOL(strlen_user); unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) { @@ -162,5 +155,3 @@ unsigned long copy_in_user(void __user *to, const void __user *from, unsigned le } return len; } -EXPORT_SYMBOL(copy_in_user); - diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 08dc696f54ee..55250593d8c9 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -41,41 +41,6 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) -{ - vmalloc_sync_all(); - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif - void bust_spinlocks(int yes) { int loglevel_save = console_loglevel; @@ -195,7 +160,7 @@ void dump_pagetable(unsigned long address) printk("PGD %lx ", pgd_val(*pgd)); if (!pgd_present(*pgd)) goto ret; - pud = pud_offset(pgd, address); + pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address); if (bad_address(pud)) goto bad; printk("PUD %lx ", pud_val(*pud)); if (!pud_present(*pud)) goto ret; @@ -383,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (vmalloc_fault(address) >= 0) return; } - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; /* @@ -393,7 +358,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } - if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; @@ -445,10 +410,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (error_code & 4) { - /* Allow userspace just enough access below the stack pointer - * to let the 'enter' instruction work. - */ - if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp) + // XXX: align red zone size with ABI + if (address + 128 < regs->rsp) goto bad_area; } if (expand_stack(vma, address)) diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 95bd232ff0cf..4ba34e95d835 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -42,6 +41,8 @@ #include #include #include +#include +#include #ifndef Dprintk #define Dprintk(x...) @@ -89,6 +90,8 @@ void show_mem(void) printk(KERN_INFO "%lu pages swap cached\n",cached); } +/* References to section boundaries */ + int after_bootmem; static __init void *spp_getpage(void) @@ -258,10 +261,9 @@ phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { unsigned long entry; - if (address >= end) { - if (!after_bootmem) - for (; i < PTRS_PER_PMD; i++, pmd++) - set_pmd(pmd, __pmd(0)); + if (address > end) { + for (; i < PTRS_PER_PMD; i++, pmd++) + set_pmd(pmd, __pmd(0)); break; } entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; @@ -339,8 +341,7 @@ static void __init find_early_table_space(unsigned long end) table_end = table_start; early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n", - end, table_start << PAGE_SHIFT, - (table_start << PAGE_SHIFT) + tables); + end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT); } /* Setup the direct mapping of the physical memory at PAGE_OFFSET. @@ -371,7 +372,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) pud_t *pud; if (after_bootmem) - pud = pud_offset(pgd, start & PGDIR_MASK); + pud = pud_offset_k(pgd, start & PGDIR_MASK); else pud = alloc_low_page(&map, &pud_phys); @@ -507,6 +508,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) /* * Memory hotplug specific functions */ +#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) + void online_page(struct page *page) { ClearPageReserved(page); @@ -516,17 +519,31 @@ void online_page(struct page *page) num_physpages++; } -#ifdef CONFIG_MEMORY_HOTPLUG +#ifndef CONFIG_MEMORY_HOTPLUG /* - * XXX: memory_add_physaddr_to_nid() is to find node id from physical address - * via probe interface of sysfs. If acpi notifies hot-add event, then it - * can tell node id by searching dsdt. But, probe interface doesn't have - * node id. So, return 0 as node id at this time. + * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, + * just online the pages. */ -#ifdef CONFIG_NUMA -int memory_add_physaddr_to_nid(u64 start) +int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) { - return 0; + int err = -EIO; + unsigned long pfn; + unsigned long total = 0, mem = 0; + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + if (pfn_valid(pfn)) { + online_page(pfn_to_page(pfn)); + err = 0; + mem++; + } + total++; + } + if (!err) { + z->spanned_pages += total; + z->present_pages += mem; + z->zone_pgdat->node_spanned_pages += total; + z->zone_pgdat->node_present_pages += mem; + } + return err; } #endif @@ -534,9 +551,9 @@ int memory_add_physaddr_to_nid(u64 start) * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. */ -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { - struct pglist_data *pgdat = NODE_DATA(nid); + struct pglist_data *pgdat = NODE_DATA(0); struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -553,7 +570,7 @@ int arch_add_memory(int nid, u64 start, u64 size) printk("%s: Problem encountered in __add_pages!\n", __func__); return ret; } -EXPORT_SYMBOL_GPL(arch_add_memory); +EXPORT_SYMBOL_GPL(add_memory); int remove_memory(u64 start, u64 size) { @@ -561,33 +578,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#else /* CONFIG_MEMORY_HOTPLUG */ -/* - * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, - * just online the pages. - */ -int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) -{ - int err = -EIO; - unsigned long pfn; - unsigned long total = 0, mem = 0; - for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { - if (pfn_valid(pfn)) { - online_page(pfn_to_page(pfn)); - err = 0; - mem++; - } - total++; - } - if (!err) { - z->spanned_pages += total; - z->present_pages += mem; - z->zone_pgdat->node_spanned_pages += total; - z->zone_pgdat->node_present_pages += mem; - } - return err; -} -#endif /* CONFIG_MEMORY_HOTPLUG */ +#endif static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -596,7 +587,10 @@ void __init mem_init(void) { long codesize, reservedpages, datasize, initsize; - pci_iommu_alloc(); +#ifdef CONFIG_SWIOTLB + pci_swiotlb_init(); +#endif + no_iommu_init(); /* How many end-of-memory variables you have, grandma! */ max_low_pfn = end_pfn; @@ -650,31 +644,20 @@ void __init mem_init(void) #endif } -void free_init_pages(char *what, unsigned long begin, unsigned long end) +void free_initmem(void) { unsigned long addr; - if (begin >= end) - return; - - printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); - for (addr = begin; addr < end; addr += PAGE_SIZE) { + addr = (unsigned long)(&__init_begin); + for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)(addr & ~(PAGE_SIZE-1)), - POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); free_page(addr); totalram_pages++; } -} - -void free_initmem(void) -{ - memset(__initdata_begin, POISON_FREE_INITDATA, - __initdata_end - __initdata_begin); - free_init_pages("unused kernel memory", - (unsigned long)(&__init_begin), - (unsigned long)(&__init_end)); + memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); + printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); } #ifdef CONFIG_DEBUG_RODATA @@ -703,7 +686,15 @@ void mark_rodata_ro(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", start, end); + if (start >= end) + return; + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + init_page_count(virt_to_page(start)); + free_page(start); + totalram_pages++; + } } #endif diff --git a/trunk/arch/x86_64/mm/ioremap.c b/trunk/arch/x86_64/mm/ioremap.c index 45d7d823c3b8..ae207064201e 100644 --- a/trunk/arch/x86_64/mm/ioremap.c +++ b/trunk/arch/x86_64/mm/ioremap.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -220,7 +219,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } return (__force void __iomem *) (offset + (char *)addr); } -EXPORT_SYMBOL(__ioremap); /** * ioremap_nocache - map bus memory into CPU space @@ -248,7 +246,6 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) { return __ioremap(phys_addr, size, _PAGE_PCD); } -EXPORT_SYMBOL(ioremap_nocache); /** * iounmap - Free a IO remapping @@ -294,5 +291,3 @@ void iounmap(volatile void __iomem *addr) BUG_ON(p != o || o == NULL); kfree(p); } -EXPORT_SYMBOL(iounmap); - diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 502fce65e96a..474df22c6ed2 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -30,6 +30,7 @@ static struct acpi_table_slit *acpi_slit; static nodemask_t nodes_parsed __initdata; +static nodemask_t nodes_found __initdata; static struct bootnode nodes[MAX_NUMNODES] __initdata; static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static int found_add_area __initdata; @@ -37,14 +38,33 @@ int hotadd_percent __initdata = 0; #ifndef RESERVE_HOTADD #define hotadd_percent 0 /* Ignore all settings */ #endif +static u8 pxm2node[256] = { [0 ... 255] = 0xff }; /* Too small nodes confuse the VM badly. Usually they result from BIOS bugs. */ #define NODE_MIN_SIZE (4*1024*1024) +static int node_to_pxm(int n); + +int pxm_to_node(int pxm) +{ + if ((unsigned)pxm >= 256) + return -1; + /* Extend 0xff to (int)-1 */ + return (signed char)pxm2node[pxm]; +} + static __init int setup_node(int pxm) { - return acpi_map_pxm_to_node(pxm); + unsigned node = pxm2node[pxm]; + if (node == 0xff) { + if (nodes_weight(nodes_found) >= MAX_NUMNODES) + return -1; + node = first_unset_node(nodes_found); + node_set(node, nodes_found); + pxm2node[pxm] = node; + } + return pxm2node[pxm]; } static __init int conflicting_nodes(unsigned long start, unsigned long end) @@ -420,6 +440,17 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) return 0; } +static int node_to_pxm(int n) +{ + int i; + if (pxm2node[n] == n) + return n; + for (i = 0; i < 256; i++) + if (pxm2node[i] == n) + return i; + return 0; +} + void __init srat_reserve_add_area(int nodeid) { if (found_add_area && nodes_add[nodeid].end) { diff --git a/trunk/arch/x86_64/pci/k8-bus.c b/trunk/arch/x86_64/pci/k8-bus.c index b50a7c7c47f8..3acf60ded2a0 100644 --- a/trunk/arch/x86_64/pci/k8-bus.c +++ b/trunk/arch/x86_64/pci/k8-bus.c @@ -2,7 +2,6 @@ #include #include #include -#include /* * This discovers the pcibus <-> node mapping on AMD K8. @@ -19,6 +18,7 @@ #define NR_LDT_BUS_NUMBER_REGISTERS 3 #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF) #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF) +#define PCI_DEVICE_ID_K8HTCONFIG 0x1100 /** * fill_mp_bus_to_cpumask() @@ -28,7 +28,8 @@ __init static int fill_mp_bus_to_cpumask(void) { - int i, j, k; + struct pci_dev *nb_dev = NULL; + int i, j; u32 ldtbus, nid; static int lbnr[3] = { LDT_BUS_NUMBER_REGISTER_0, @@ -36,9 +37,8 @@ fill_mp_bus_to_cpumask(void) LDT_BUS_NUMBER_REGISTER_2 }; - cache_k8_northbridges(); - for (k = 0; k < num_k8_northbridges; k++) { - struct pci_dev *nb_dev = k8_northbridges[k]; + while ((nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, + PCI_DEVICE_ID_K8HTCONFIG, nb_dev))) { pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid); for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) { diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index 3c55c76c6fd5..a2060e4d5de6 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -13,10 +13,7 @@ #include "pci.h" -/* aperture is up to 256MB but BIOS may reserve less */ -#define MMCONFIG_APER_MIN (2 * 1024*1024) -#define MMCONFIG_APER_MAX (256 * 1024*1024) - +#define MMCONFIG_APER_SIZE (256*1024*1024) /* Verify the first 16 busses. We assume that systems with more busses get MCFG right. */ #define MAX_CHECK_BUS 16 @@ -178,10 +175,9 @@ void __init pci_mmcfg_init(void) return; if (!e820_all_mapped(pci_mmcfg_config[0].base_address, - pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", - pci_mmcfg_config[0].base_address); + printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); return; } @@ -194,8 +190,7 @@ void __init pci_mmcfg_init(void) } for (i = 0; i < pci_mmcfg_config_num; ++i) { pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; - pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, - MMCONFIG_APER_MAX); + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); if (!pci_mmcfg_virt[i].virt) { printk("PCI: Cannot map mmconfig aperture for segment %d\n", pci_mmcfg_config[i].pci_segment_group_number); diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 848f173db257..dbeb3504c3c8 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -34,6 +34,10 @@ config GENERIC_HARDIRQS bool default y +config RWSEM_GENERIC_SPINLOCK + bool + default y + source "init/Kconfig" menu "Processor type and features" diff --git a/trunk/arch/xtensa/Makefile b/trunk/arch/xtensa/Makefile index 3a3a4c66ef87..98fac8489aed 100644 --- a/trunk/arch/xtensa/Makefile +++ b/trunk/arch/xtensa/Makefile @@ -71,7 +71,7 @@ archprepare: $(archinc)/.platform # Update machine cpu and platform symlinks if something which affects # them changed. -$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' $(Q)mkdir -p $(archinc) $(Q)mkdir -p $(archinc)/xtensa diff --git a/trunk/arch/xtensa/boot/lib/Makefile b/trunk/arch/xtensa/boot/lib/Makefile index d3d2aa2d883a..9e73bb8aeb7a 100644 --- a/trunk/arch/xtensa/boot/lib/Makefile +++ b/trunk/arch/xtensa/boot/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for some libs needed by zImage. # -zlib := inffast.c inflate.c inftrees.c +zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c lib-y += $(zlib:.c=.o) zmem.o diff --git a/trunk/arch/xtensa/kernel/entry.S b/trunk/arch/xtensa/kernel/entry.S index 89e409e9e0de..5c018c503dfa 100644 --- a/trunk/arch/xtensa/kernel/entry.S +++ b/trunk/arch/xtensa/kernel/entry.S @@ -1102,7 +1102,7 @@ ENTRY(fast_syscall_sysxtensa) s32i a7, a2, PT_AREG7 movi a7, 4 # sizeof(unsigned int) - access_ok a0, a3, a7, a2, .Leac + verify_area a3, a7, a0, a2, .Leac _beqi a6, SYSXTENSA_ATOMIC_SET, .Lset _beqi a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg diff --git a/trunk/arch/xtensa/kernel/pci.c b/trunk/arch/xtensa/kernel/pci.c index c6f471b9eaa0..de19501aa809 100644 --- a/trunk/arch/xtensa/kernel/pci.c +++ b/trunk/arch/xtensa/kernel/pci.c @@ -349,6 +349,17 @@ __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; } +/* + * Set vm_flags of VMA, as appropriate for this architecture, for a pci device + * mapping. + */ +static __inline__ void +__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; +} + /* * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci * device mapping. @@ -388,6 +399,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, if (ret < 0) return ret; + __pci_mmap_set_flags(dev, vma, mmap_state); __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine); ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index c494f0826fc5..e252b61e45a5 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -104,7 +104,7 @@ sys_sigaction(int sig, const struct old_sigaction *act, if (act) { old_sigset_t mask; - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + if (verify_area(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) return -EFAULT; @@ -116,7 +116,7 @@ sys_sigaction(int sig, const struct old_sigaction *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) return -EFAULT; @@ -236,7 +236,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4); err |= __get_user(buf, &sc->sc_cpstate); if (buf) { - if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) + if (verify_area(VERIFY_READ, buf, sizeof(*buf))) goto badframe; err |= restore_cpextra(buf); } @@ -357,7 +357,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) if (regs->depc > 64) panic ("Double exception sys_sigreturn\n"); - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) @@ -394,7 +394,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) return 0; } - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) @@ -433,7 +433,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) static inline void * get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) { - if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; return (void *)((sp - frame_size) & -16ul); diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index fe14909f45e0..937d81f62f43 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -29,7 +29,7 @@ extern volatile unsigned long wall_jiffies; -DEFINE_SPINLOCK(rtc_lock); +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; EXPORT_SYMBOL(rtc_lock); diff --git a/trunk/arch/xtensa/kernel/traps.c b/trunk/arch/xtensa/kernel/traps.c index 27e409089a7b..225d64d73f04 100644 --- a/trunk/arch/xtensa/kernel/traps.c +++ b/trunk/arch/xtensa/kernel/traps.c @@ -461,7 +461,7 @@ void show_code(unsigned int *pc) } } -DEFINE_SPINLOCK(die_lock); +spinlock_t die_lock = SPIN_LOCK_UNLOCKED; void die(const char * str, struct pt_regs * regs, long err) { diff --git a/trunk/block/Kconfig.iosched b/trunk/block/Kconfig.iosched index 48d090e266fc..f3b7753aac99 100644 --- a/trunk/block/Kconfig.iosched +++ b/trunk/block/Kconfig.iosched @@ -40,7 +40,7 @@ config IOSCHED_CFQ choice prompt "Default I/O scheduler" - default DEFAULT_CFQ + default DEFAULT_AS help Select the I/O scheduler which will be used by default for all block devices. diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 3af31ed49a9c..0c750393be4a 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -96,7 +96,7 @@ struct as_data { struct as_rq *next_arq[2]; /* next in sort order */ sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */ - struct hlist_head *hash; /* request hash */ + struct list_head *hash; /* request hash */ unsigned long exit_prob; /* probability a task will exit while being waited on */ @@ -165,7 +165,8 @@ struct as_rq { /* * request hash, key is the ending offset (for back merge lookup) */ - struct hlist_node hash; + struct list_head hash; + unsigned int on_hash; /* * expire fifo @@ -281,15 +282,17 @@ static const int as_hash_shift = 6; #define AS_HASH_FN(sec) (hash_long(AS_HASH_BLOCK((sec)), as_hash_shift)) #define AS_HASH_ENTRIES (1 << as_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) +#define list_entry_hash(ptr) list_entry((ptr), struct as_rq, hash) static inline void __as_del_arq_hash(struct as_rq *arq) { - hlist_del_init(&arq->hash); + arq->on_hash = 0; + list_del_init(&arq->hash); } static inline void as_del_arq_hash(struct as_rq *arq) { - if (!hlist_unhashed(&arq->hash)) + if (arq->on_hash) __as_del_arq_hash(arq); } @@ -297,9 +300,10 @@ static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq) { struct request *rq = arq->request; - BUG_ON(!hlist_unhashed(&arq->hash)); + BUG_ON(arq->on_hash); - hlist_add_head(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]); + arq->on_hash = 1; + list_add(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]); } /* @@ -308,29 +312,31 @@ static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq) static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq) { struct request *rq = arq->request; - struct hlist_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))]; + struct list_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))]; - if (hlist_unhashed(&arq->hash)) { + if (!arq->on_hash) { WARN_ON(1); return; } - if (&arq->hash != head->first) { - hlist_del(&arq->hash); - hlist_add_head(&arq->hash, head); + if (arq->hash.prev != head) { + list_del(&arq->hash); + list_add(&arq->hash, head); } } static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset) { - struct hlist_head *hash_list = &ad->hash[AS_HASH_FN(offset)]; - struct hlist_node *entry, *next; - struct as_rq *arq; + struct list_head *hash_list = &ad->hash[AS_HASH_FN(offset)]; + struct list_head *entry, *next = hash_list->next; - hlist_for_each_entry_safe(arq, entry, next, hash_list, hash) { + while ((entry = next) != hash_list) { + struct as_rq *arq = list_entry_hash(entry); struct request *__rq = arq->request; - BUG_ON(hlist_unhashed(&arq->hash)); + next = entry->next; + + BUG_ON(!arq->on_hash); if (!rq_mergeable(__rq)) { as_del_arq_hash(arq); @@ -347,6 +353,9 @@ static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset) /* * rb tree support functions */ +#define RB_EMPTY(root) ((root)->rb_node == NULL) +#define ON_RB(node) (rb_parent(node) != node) +#define RB_CLEAR(node) (rb_set_parent(node, node)) #define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node) #define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync]) #define rq_rb_key(rq) (rq)->sector @@ -415,13 +424,13 @@ static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq) static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq) { - if (!RB_EMPTY_NODE(&arq->rb_node)) { + if (!ON_RB(&arq->rb_node)) { WARN_ON(1); return; } rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq)); - RB_CLEAR_NODE(&arq->rb_node); + RB_CLEAR(&arq->rb_node); } static struct request * @@ -542,7 +551,7 @@ static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last) struct rb_node *rbprev = rb_prev(&last->rb_node); struct as_rq *arq_next, *arq_prev; - BUG_ON(!RB_EMPTY_NODE(&last->rb_node)); + BUG_ON(!ON_RB(&last->rb_node)); if (rbprev) arq_prev = rb_entry_arq(rbprev); @@ -892,7 +901,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) } /* - * as_can_anticipate indicates whether we should either run arq + * as_can_anticipate indicates weather we should either run arq * or keep anticipating a better request. */ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) @@ -1119,7 +1128,7 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) struct request *rq = arq->request; const int data_dir = arq->is_sync; - BUG_ON(!RB_EMPTY_NODE(&arq->rb_node)); + BUG_ON(!ON_RB(&arq->rb_node)); as_antic_stop(ad); ad->antic_status = ANTIC_OFF; @@ -1244,7 +1253,7 @@ static int as_dispatch_request(request_queue_t *q, int force) */ if (reads) { - BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[REQ_SYNC])); + BUG_ON(RB_EMPTY(&ad->sort_list[REQ_SYNC])); if (writes && ad->batch_data_dir == REQ_SYNC) /* @@ -1268,7 +1277,7 @@ static int as_dispatch_request(request_queue_t *q, int force) if (writes) { dispatch_writes: - BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[REQ_ASYNC])); + BUG_ON(RB_EMPTY(&ad->sort_list[REQ_ASYNC])); if (ad->batch_data_dir == REQ_SYNC) { ad->changed_batch = 1; @@ -1336,7 +1345,7 @@ static void as_add_request(request_queue_t *q, struct request *rq) arq->state = AS_RQ_NEW; if (rq_data_dir(arq->request) == READ - || (arq->request->flags & REQ_RW_SYNC)) + || current->flags&PF_SYNCWRITE) arq->is_sync = 1; else arq->is_sync = 0; @@ -1588,11 +1597,12 @@ static int as_set_request(request_queue_t *q, struct request *rq, if (arq) { memset(arq, 0, sizeof(*arq)); - RB_CLEAR_NODE(&arq->rb_node); + RB_CLEAR(&arq->rb_node); arq->request = rq; arq->state = AS_RQ_PRESCHED; arq->io_context = NULL; - INIT_HLIST_NODE(&arq->hash); + INIT_LIST_HEAD(&arq->hash); + arq->on_hash = 0; INIT_LIST_HEAD(&arq->fifo); rq->elevator_private = arq; return 0; @@ -1652,7 +1662,7 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) ad->q = q; /* Identify what queue the data belongs to */ - ad->hash = kmalloc_node(sizeof(struct hlist_head)*AS_HASH_ENTRIES, + ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES, GFP_KERNEL, q->node); if (!ad->hash) { kfree(ad); @@ -1674,7 +1684,7 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) INIT_WORK(&ad->antic_work, as_work_handler, q); for (i = 0; i < AS_HASH_ENTRIES; i++) - INIT_HLIST_HEAD(&ad->hash[i]); + INIT_LIST_HEAD(&ad->hash[i]); INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]); INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index e25223e147a2..e2e6ad0a158e 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -26,7 +26,7 @@ static const int cfq_back_penalty = 2; /* penalty of a backwards seek */ static const int cfq_slice_sync = HZ / 10; static int cfq_slice_async = HZ / 25; static const int cfq_slice_async_rq = 2; -static int cfq_slice_idle = HZ / 125; +static int cfq_slice_idle = HZ / 70; #define CFQ_IDLE_GRACE (HZ / 10) #define CFQ_SLICE_SCALE (5) @@ -60,6 +60,11 @@ static DEFINE_SPINLOCK(cfq_exit_lock); /* * rb-tree defines */ +#define RB_EMPTY(node) ((node)->rb_node == NULL) +#define RB_CLEAR(node) do { \ + memset(node, 0, sizeof(*node)); \ +} while (0) +#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL) #define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node) #define rq_rb_key(rq) (rq)->sector @@ -118,6 +123,8 @@ struct cfq_data { */ struct hlist_head *crq_hash; + unsigned int max_queued; + mempool_t *crq_pool; int rq_in_driver; @@ -272,6 +279,8 @@ static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsi static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *); static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask); +#define process_sync(tsk) ((tsk)->flags & PF_SYNCWRITE) + /* * lots of deadline iosched dupes, can be abstracted later... */ @@ -327,7 +336,7 @@ static int cfq_queue_empty(request_queue_t *q) static inline pid_t cfq_queue_pid(struct task_struct *task, int rw) { - if (rw == READ || rw == WRITE_SYNC) + if (rw == READ || process_sync(task)) return task->pid; return CFQ_KEY_ASYNC; @@ -554,7 +563,7 @@ static inline void cfq_del_crq_rb(struct cfq_rq *crq) rb_erase(&crq->rb_node, &cfqq->sort_list); - if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) + if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list)) cfq_del_cfqq_rr(cfqd, cfqq); } @@ -901,15 +910,13 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd) return cfqq; } -#define CIC_SEEKY(cic) ((cic)->seek_mean > (128 * 1024)) - static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) { struct cfq_io_context *cic; unsigned long sl; - WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list)); + WARN_ON(!RB_EMPTY(&cfqq->sort_list)); WARN_ON(cfqq != cfqd->active_queue); /* @@ -936,7 +943,7 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) * fair distribution of slice time for a process doing back-to-back * seeks. so allow a little bit of time for him to submit a new rq */ - if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic)) + if (sample_valid(cic->seek_samples) && cic->seek_mean > 131072) sl = 2; mod_timer(&cfqd->idle_slice_timer, jiffies + sl); @@ -947,15 +954,11 @@ static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq) { struct cfq_data *cfqd = q->elevator->elevator_data; struct cfq_queue *cfqq = crq->cfq_queue; - struct request *rq; cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq); cfq_remove_request(crq->request); cfqq->on_dispatch[cfq_crq_is_sync(crq)]++; elv_dispatch_sort(q, crq->request); - - rq = list_entry(q->queue_head.prev, struct request, queuelist); - cfqd->last_sector = rq->sector + rq->nr_sectors; } /* @@ -1037,12 +1040,10 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) * if queue has requests, dispatch one. if not, check if * enough slice is left to wait for one */ - if (!RB_EMPTY_ROOT(&cfqq->sort_list)) + if (!RB_EMPTY(&cfqq->sort_list)) goto keep_queue; - else if (cfq_cfqq_dispatched(cfqq)) { - cfqq = NULL; - goto keep_queue; - } else if (cfq_cfqq_class_sync(cfqq)) { + else if (cfq_cfqq_class_sync(cfqq) && + time_before(now, cfqq->slice_end)) { if (cfq_arm_slice_timer(cfqd, cfqq)) return NULL; } @@ -1061,7 +1062,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, { int dispatched = 0; - BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); + BUG_ON(RB_EMPTY(&cfqq->sort_list)); do { struct cfq_rq *crq; @@ -1085,13 +1086,14 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqd->active_cic = crq->io_context; } - if (RB_EMPTY_ROOT(&cfqq->sort_list)) + if (RB_EMPTY(&cfqq->sort_list)) break; } while (dispatched < max_dispatch); /* - * if slice end isn't set yet, set it. + * if slice end isn't set yet, set it. if at least one request was + * sync, use the sync time slice value */ if (!cfqq->slice_end) cfq_set_prio_slice(cfqd, cfqq); @@ -1102,8 +1104,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ if ((!cfq_cfqq_sync(cfqq) && cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) || - cfq_class_idle(cfqq) || - !cfq_cfqq_idle_window(cfqq)) + cfq_class_idle(cfqq)) cfq_slice_expired(cfqd, 0); return dispatched; @@ -1112,11 +1113,10 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, static int cfq_forced_dispatch_cfqqs(struct list_head *list) { + int dispatched = 0; struct cfq_queue *cfqq, *next; struct cfq_rq *crq; - int dispatched; - dispatched = 0; list_for_each_entry_safe(cfqq, next, list, cfq_list) { while ((crq = cfqq->next_crq)) { cfq_dispatch_insert(cfqq->cfqd->queue, crq); @@ -1124,7 +1124,6 @@ cfq_forced_dispatch_cfqqs(struct list_head *list) } BUG_ON(!list_empty(&cfqq->fifo)); } - return dispatched; } @@ -1151,8 +1150,7 @@ static int cfq_dispatch_requests(request_queue_t *q, int force) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq, *prev_cfqq; - int dispatched; + struct cfq_queue *cfqq; if (!cfqd->busy_queues) return 0; @@ -1160,17 +1158,10 @@ cfq_dispatch_requests(request_queue_t *q, int force) if (unlikely(force)) return cfq_forced_dispatch(cfqd); - dispatched = 0; - prev_cfqq = NULL; - while ((cfqq = cfq_select_queue(cfqd)) != NULL) { + cfqq = cfq_select_queue(cfqd); + if (cfqq) { int max_dispatch; - /* - * Don't repeat dispatch from the previous queue. - */ - if (prev_cfqq == cfqq) - break; - cfq_clear_cfqq_must_dispatch(cfqq); cfq_clear_cfqq_wait_request(cfqq); del_timer(&cfqd->idle_slice_timer); @@ -1179,19 +1170,10 @@ cfq_dispatch_requests(request_queue_t *q, int force) if (cfq_class_idle(cfqq)) max_dispatch = 1; - dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); - - /* - * If the dispatch cfqq has idling enabled and is still - * the active queue, break out. - */ - if (cfq_cfqq_idle_window(cfqq) && cfqd->active_queue) - break; - - prev_cfqq = cfqq; + return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); } - return dispatched; + return 0; } /* @@ -1397,28 +1379,25 @@ static inline void changed_ioprio(struct cfq_io_context *cic) { struct cfq_data *cfqd = cic->key; struct cfq_queue *cfqq; - - if (unlikely(!cfqd)) - return; - - spin_lock(cfqd->queue->queue_lock); - - cfqq = cic->cfqq[ASYNC]; - if (cfqq) { - struct cfq_queue *new_cfqq; - new_cfqq = cfq_get_queue(cfqd, CFQ_KEY_ASYNC, cic->ioc->task, - GFP_ATOMIC); - if (new_cfqq) { - cic->cfqq[ASYNC] = new_cfqq; - cfq_put_queue(cfqq); + if (cfqd) { + spin_lock(cfqd->queue->queue_lock); + cfqq = cic->cfqq[ASYNC]; + if (cfqq) { + struct cfq_queue *new_cfqq; + new_cfqq = cfq_get_queue(cfqd, CFQ_KEY_ASYNC, + cic->ioc->task, GFP_ATOMIC); + if (new_cfqq) { + cic->cfqq[ASYNC] = new_cfqq; + cfq_put_queue(cfqq); + } + } + cfqq = cic->cfqq[SYNC]; + if (cfqq) { + cfq_mark_cfqq_prio_changed(cfqq); + cfq_init_prio_data(cfqq); } + spin_unlock(cfqd->queue->queue_lock); } - - cfqq = cic->cfqq[SYNC]; - if (cfqq) - cfq_mark_cfqq_prio_changed(cfqq); - - spin_unlock(cfqd->queue->queue_lock); } /* @@ -1475,6 +1454,7 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, INIT_HLIST_NODE(&cfqq->cfq_hash); INIT_LIST_HEAD(&cfqq->cfq_list); + RB_CLEAR_ROOT(&cfqq->sort_list); INIT_LIST_HEAD(&cfqq->fifo); cfqq->key = key; @@ -1486,7 +1466,8 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, * set ->slice_left to allow preemption for a new process */ cfqq->slice_left = 2 * cfqd->cfq_slice_idle; - cfq_mark_cfqq_idle_window(cfqq); + if (!cfqd->hw_tag) + cfq_mark_cfqq_idle_window(cfqq); cfq_mark_cfqq_prio_changed(cfqq); cfq_init_prio_data(cfqq); } @@ -1677,8 +1658,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, { int enable_idle = cfq_cfqq_idle_window(cfqq); - if (!cic->ioc->task || !cfqd->cfq_slice_idle || - (cfqd->hw_tag && CIC_SEEKY(cic))) + if (!cic->ioc->task || !cfqd->cfq_slice_idle || cfqd->hw_tag) enable_idle = 0; else if (sample_valid(cic->ttime_samples)) { if (cic->ttime_mean > cfqd->cfq_slice_idle) @@ -1708,7 +1688,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, return 0; if (!cfqq) - return 0; + return 1; if (cfq_class_idle(cfqq)) return 1; @@ -1740,7 +1720,7 @@ static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2; cfqq->slice_end = cfqq->slice_left + jiffies; - cfq_slice_expired(cfqd, 1); + __cfq_slice_expired(cfqd, cfqq, 1); __cfq_set_active_queue(cfqd, cfqq); } @@ -1765,7 +1745,11 @@ static void cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, struct cfq_rq *crq) { - struct cfq_io_context *cic = crq->io_context; + struct cfq_io_context *cic; + + cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); + + cic = crq->io_context; /* * we never wait for an async request and we don't allow preemption @@ -1855,23 +1839,11 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) cfqq->service_last = now; cfq_resort_rr_list(cfqq, 0); } + cfq_schedule_dispatch(cfqd); } - if (sync) + if (cfq_crq_is_sync(crq)) crq->io_context->last_end_request = now; - - /* - * If this is the active queue, check if it needs to be expired, - * or if we want to idle in case it has no pending requests. - */ - if (cfqd->active_queue == cfqq) { - if (time_after(now, cfqq->slice_end)) - cfq_slice_expired(cfqd, 0); - else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list)) { - if (!cfq_arm_slice_timer(cfqd, cfqq)) - cfq_schedule_dispatch(cfqd); - } - } } static struct request * @@ -1938,6 +1910,7 @@ static inline int __cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, struct task_struct *task, int rw) { +#if 1 if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) && !cfq_cfqq_must_alloc_slice(cfqq)) { cfq_mark_cfqq_must_alloc_slice(cfqq); @@ -1945,6 +1918,39 @@ __cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, } return ELV_MQUEUE_MAY; +#else + if (!cfqq || task->flags & PF_MEMALLOC) + return ELV_MQUEUE_MAY; + if (!cfqq->allocated[rw] || cfq_cfqq_must_alloc(cfqq)) { + if (cfq_cfqq_wait_request(cfqq)) + return ELV_MQUEUE_MUST; + + /* + * only allow 1 ELV_MQUEUE_MUST per slice, otherwise we + * can quickly flood the queue with writes from a single task + */ + if (rw == READ || !cfq_cfqq_must_alloc_slice(cfqq)) { + cfq_mark_cfqq_must_alloc_slice(cfqq); + return ELV_MQUEUE_MUST; + } + + return ELV_MQUEUE_MAY; + } + if (cfq_class_idle(cfqq)) + return ELV_MQUEUE_NO; + if (cfqq->allocated[rw] >= cfqd->max_queued) { + struct io_context *ioc = get_io_context(GFP_ATOMIC); + int ret = ELV_MQUEUE_NO; + + if (ioc && ioc->nr_batch_requests) + ret = ELV_MQUEUE_MAY; + + put_io_context(ioc); + return ret; + } + + return ELV_MQUEUE_MAY; +#endif } static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) @@ -1973,13 +1979,16 @@ static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq) { struct cfq_data *cfqd = q->elevator->elevator_data; + struct request_list *rl = &q->rq; - if (unlikely(cfqd->rq_starved)) { - struct request_list *rl = &q->rq; - + if (cfqq->allocated[READ] <= cfqd->max_queued || cfqd->rq_starved) { smp_mb(); if (waitqueue_active(&rl->wait[READ])) wake_up(&rl->wait[READ]); + } + + if (cfqq->allocated[WRITE] <= cfqd->max_queued || cfqd->rq_starved) { + smp_mb(); if (waitqueue_active(&rl->wait[WRITE])) wake_up(&rl->wait[WRITE]); } @@ -2053,7 +2062,7 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, crq = mempool_alloc(cfqd->crq_pool, gfp_mask); if (crq) { - RB_CLEAR_NODE(&crq->rb_node); + RB_CLEAR(&crq->rb_node); crq->rb_key = 0; crq->request = rq; INIT_HLIST_NODE(&crq->hash); @@ -2139,13 +2148,16 @@ static void cfq_idle_slice_timer(unsigned long data) * only expire and reinvoke request handler, if there are * other queues with pending requests */ - if (!cfqd->busy_queues) + if (!cfqd->busy_queues) { + cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end); + add_timer(&cfqd->idle_slice_timer); goto out_cont; + } /* * not expired and it has a request pending, let it dispatch */ - if (!RB_EMPTY_ROOT(&cfqq->sort_list)) { + if (!RB_EMPTY(&cfqq->sort_list)) { cfq_mark_cfqq_must_dispatch(cfqq); goto out_kick; } @@ -2266,6 +2278,9 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->queue = q; + cfqd->max_queued = q->nr_requests / 4; + q->nr_batching = cfq_queued; + init_timer(&cfqd->idle_slice_timer); cfqd->idle_slice_timer.function = cfq_idle_slice_timer; cfqd->idle_slice_timer.data = (unsigned long) cfqd; diff --git a/trunk/block/deadline-iosched.c b/trunk/block/deadline-iosched.c index 4469dd84623c..c94de8e12fbf 100644 --- a/trunk/block/deadline-iosched.c +++ b/trunk/block/deadline-iosched.c @@ -30,7 +30,8 @@ static const int deadline_hash_shift = 5; #define DL_HASH_FN(sec) (hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift)) #define DL_HASH_ENTRIES (1 << deadline_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) -#define ON_HASH(drq) (!hlist_unhashed(&(drq)->hash)) +#define list_entry_hash(ptr) list_entry((ptr), struct deadline_rq, hash) +#define ON_HASH(drq) (drq)->on_hash struct deadline_data { /* @@ -47,7 +48,7 @@ struct deadline_data { * next in sort order. read, write or both are NULL */ struct deadline_rq *next_drq[2]; - struct hlist_head *hash; /* request hash */ + struct list_head *hash; /* request hash */ unsigned int batching; /* number of sequential requests made */ sector_t last_sector; /* head position */ unsigned int starved; /* times reads have starved writes */ @@ -78,7 +79,8 @@ struct deadline_rq { /* * request hash, key is the ending offset (for back merge lookup) */ - struct hlist_node hash; + struct list_head hash; + char on_hash; /* * expire fifo @@ -98,7 +100,8 @@ static kmem_cache_t *drq_pool; */ static inline void __deadline_del_drq_hash(struct deadline_rq *drq) { - hlist_del_init(&drq->hash); + drq->on_hash = 0; + list_del_init(&drq->hash); } static inline void deadline_del_drq_hash(struct deadline_rq *drq) @@ -114,7 +117,8 @@ deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) BUG_ON(ON_HASH(drq)); - hlist_add_head(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]); + drq->on_hash = 1; + list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]); } /* @@ -124,24 +128,26 @@ static inline void deadline_hot_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) { struct request *rq = drq->request; - struct hlist_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))]; + struct list_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))]; - if (ON_HASH(drq) && &drq->hash != head->first) { - hlist_del(&drq->hash); - hlist_add_head(&drq->hash, head); + if (ON_HASH(drq) && drq->hash.prev != head) { + list_del(&drq->hash); + list_add(&drq->hash, head); } } static struct request * deadline_find_drq_hash(struct deadline_data *dd, sector_t offset) { - struct hlist_head *hash_list = &dd->hash[DL_HASH_FN(offset)]; - struct hlist_node *entry, *next; - struct deadline_rq *drq; + struct list_head *hash_list = &dd->hash[DL_HASH_FN(offset)]; + struct list_head *entry, *next = hash_list->next; - hlist_for_each_entry_safe(drq, entry, next, hash_list, hash) { + while ((entry = next) != hash_list) { + struct deadline_rq *drq = list_entry_hash(entry); struct request *__rq = drq->request; + next = entry->next; + BUG_ON(!ON_HASH(drq)); if (!rq_mergeable(__rq)) { @@ -159,6 +165,9 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset) /* * rb tree support functions */ +#define RB_EMPTY(root) ((root)->rb_node == NULL) +#define ON_RB(node) (rb_parent(node) != node) +#define RB_CLEAR(node) (rb_set_parent(node, node)) #define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node) #define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)]) #define rq_rb_key(rq) (rq)->sector @@ -217,9 +226,9 @@ deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) dd->next_drq[data_dir] = rb_entry_drq(rbnext); } - BUG_ON(!RB_EMPTY_NODE(&drq->rb_node)); + BUG_ON(!ON_RB(&drq->rb_node)); rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); - RB_CLEAR_NODE(&drq->rb_node); + RB_CLEAR(&drq->rb_node); } static struct request * @@ -493,7 +502,7 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) */ if (reads) { - BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[READ])); + BUG_ON(RB_EMPTY(&dd->sort_list[READ])); if (writes && (dd->starved++ >= dd->writes_starved)) goto dispatch_writes; @@ -509,7 +518,7 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) if (writes) { dispatch_writes: - BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[WRITE])); + BUG_ON(RB_EMPTY(&dd->sort_list[WRITE])); dd->starved = 0; @@ -616,7 +625,7 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) return NULL; memset(dd, 0, sizeof(*dd)); - dd->hash = kmalloc_node(sizeof(struct hlist_head)*DL_HASH_ENTRIES, + dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES, GFP_KERNEL, q->node); if (!dd->hash) { kfree(dd); @@ -632,7 +641,7 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) } for (i = 0; i < DL_HASH_ENTRIES; i++) - INIT_HLIST_HEAD(&dd->hash[i]); + INIT_LIST_HEAD(&dd->hash[i]); INIT_LIST_HEAD(&dd->fifo_list[READ]); INIT_LIST_HEAD(&dd->fifo_list[WRITE]); @@ -665,10 +674,11 @@ deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio, drq = mempool_alloc(dd->drq_pool, gfp_mask); if (drq) { memset(drq, 0, sizeof(*drq)); - RB_CLEAR_NODE(&drq->rb_node); + RB_CLEAR(&drq->rb_node); drq->request = rq; - INIT_HLIST_NODE(&drq->hash); + INIT_LIST_HEAD(&drq->hash); + drq->on_hash = 0; INIT_LIST_HEAD(&drq->fifo); diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index d00b283f31d2..a0afdd317cef 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -850,9 +850,12 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) * one again (along with re-adding the sysfs dir) */ elevator_exit(e); + e = NULL; q->elevator = old_elevator; elv_register_queue(q); clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); + if (e) + kobject_put(&e->kobj); return 0; } diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 8d7339511e5e..5a8d3bf02f17 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -17,7 +17,8 @@ #include #include -struct subsystem block_subsys; +static struct subsystem block_subsys; + static DEFINE_MUTEX(block_subsys_lock); /* @@ -510,7 +511,9 @@ static struct kset_uevent_ops block_uevent_ops = { .uevent = block_uevent, }; -decl_subsys(block, &ktype_block, &block_uevent_ops); +/* declare block_subsys. */ +static decl_subsys(block, &ktype_block, &block_uevent_ops); + /* * aggregate disk stat collector. Uses the same stats that the sysfs diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index eee03a3876a3..7eb36c53f4b7 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -638,7 +638,7 @@ void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) /* Assume anything <= 4GB can be handled by IOMMU. Actually some IOMMUs can handle everything, but I don't know of a way to test this here. */ - if (bounce_pfn < (min_t(u64,0xffffffff,BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) + if (bounce_pfn < (0xffffffff>>PAGE_SHIFT)) dma = 1; q->bounce_pfn = max_low_pfn; #else @@ -1663,8 +1663,6 @@ static void blk_unplug_timeout(unsigned long data) **/ void blk_start_queue(request_queue_t *q) { - WARN_ON(!irqs_disabled()); - clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags); /* @@ -1880,8 +1878,7 @@ EXPORT_SYMBOL(blk_alloc_queue_node); * get dealt with eventually. * * The queue spin lock must be held while manipulating the requests on the - * request queue; this lock will be taken also from interrupt context, so irq - * disabling is needed for it. + * request queue. * * Function returns a pointer to the initialized request queue, or NULL if * it didn't succeed. @@ -2745,7 +2742,7 @@ static int attempt_merge(request_queue_t *q, struct request *req, return 0; /* - * not contiguous + * not contigious */ if (req->sector + req->nr_sectors != next->sector) return 0; @@ -2827,9 +2824,6 @@ static void init_request_from_bio(struct request *req, struct bio *bio) if (unlikely(bio_barrier(bio))) req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); - if (bio_sync(bio)) - req->flags |= REQ_RW_SYNC; - req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; req->hard_nr_sectors = req->nr_sectors = bio_sectors(bio); @@ -3365,11 +3359,12 @@ EXPORT_SYMBOL(end_that_request_chunk); */ static void blk_done_softirq(struct softirq_action *h) { - struct list_head *cpu_list, local_list; + struct list_head *cpu_list; + LIST_HEAD(local_list); local_irq_disable(); cpu_list = &__get_cpu_var(blk_cpu_done); - list_replace_init(cpu_list, &local_list); + list_splice_init(cpu_list, &local_list); local_irq_enable(); while (!list_empty(&local_list)) { @@ -3403,7 +3398,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action, } -static struct notifier_block __devinitdata blk_cpu_notifier = { +static struct notifier_block blk_cpu_notifier = { .notifier_call = blk_cpu_notify, }; @@ -3415,7 +3410,7 @@ static struct notifier_block __devinitdata blk_cpu_notifier = { * * Description: * Ends all I/O on a request. It does not handle partial completions, - * unless the driver actually implements this in its completion callback + * unless the driver actually implements this in its completionc callback * through requeueing. Theh actual completion happens out-of-order, * through a softirq handler. The user must have registered a completion * callback through blk_queue_softirq_done(). @@ -3541,7 +3536,9 @@ int __init blk_dev_init(void) INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); - register_hotcpu_notifier(&blk_cpu_notifier); +#ifdef CONFIG_HOTPLUG_CPU + register_cpu_notifier(&blk_cpu_notifier); +#endif blk_max_low_pfn = max_low_pfn; blk_max_pfn = max_pfn; diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index ba133d557045..c442f2e7ce46 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -337,7 +337,7 @@ config CRYPTO_CRC32C config CRYPTO_TEST tristate "Testing module" - depends on CRYPTO && m + depends on CRYPTO help Quick & dirty crypto test module. diff --git a/trunk/crypto/aes.c b/trunk/crypto/aes.c index a038711831e7..a5017292e066 100644 --- a/trunk/crypto/aes.c +++ b/trunk/crypto/aes.c @@ -248,10 +248,10 @@ gen_tabs (void) t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ } -static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int +aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) { - struct aes_ctx *ctx = crypto_tfm_ctx(tfm); + struct aes_ctx *ctx = ctx_arg; const __le32 *key = (const __le32 *)in_key; u32 i, t, u, v, w; @@ -318,9 +318,9 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, f_rl(bo, bi, 2, k); \ f_rl(bo, bi, 3, k) -static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in) { - const struct aes_ctx *ctx = crypto_tfm_ctx(tfm); + const struct aes_ctx *ctx = ctx_arg; const __le32 *src = (const __le32 *)in; __le32 *dst = (__le32 *)out; u32 b0[4], b1[4]; @@ -373,9 +373,9 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) i_rl(bo, bi, 2, k); \ i_rl(bo, bi, 3, k) -static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in) { - const struct aes_ctx *ctx = crypto_tfm_ctx(tfm); + const struct aes_ctx *ctx = ctx_arg; const __le32 *src = (const __le32 *)in; __le32 *dst = (__le32 *)out; u32 b0[4], b1[4]; diff --git a/trunk/crypto/anubis.c b/trunk/crypto/anubis.c index 7e2e1a29800e..2c796bdb91a6 100644 --- a/trunk/crypto/anubis.c +++ b/trunk/crypto/anubis.c @@ -460,15 +460,16 @@ static const u32 rc[] = { 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, }; -static int anubis_setkey(struct crypto_tfm *tfm, const u8 *in_key, +static int anubis_setkey(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) { - struct anubis_ctx *ctx = crypto_tfm_ctx(tfm); const __be32 *key = (const __be32 *)in_key; int N, R, i, r; u32 kappa[ANUBIS_MAX_N]; u32 inter[ANUBIS_MAX_N]; + struct anubis_ctx *ctx = ctx_arg; + switch (key_len) { case 16: case 20: case 24: case 28: @@ -659,15 +660,15 @@ static void anubis_crypt(u32 roundKey[ANUBIS_MAX_ROUNDS + 1][4], dst[i] = cpu_to_be32(inter[i]); } -static void anubis_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void anubis_encrypt(void *ctx_arg, u8 *dst, const u8 *src) { - struct anubis_ctx *ctx = crypto_tfm_ctx(tfm); + struct anubis_ctx *ctx = ctx_arg; anubis_crypt(ctx->E, dst, src, ctx->R); } -static void anubis_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void anubis_decrypt(void *ctx_arg, u8 *dst, const u8 *src) { - struct anubis_ctx *ctx = crypto_tfm_ctx(tfm); + struct anubis_ctx *ctx = ctx_arg; anubis_crypt(ctx->D, dst, src, ctx->R); } diff --git a/trunk/crypto/api.c b/trunk/crypto/api.c index c11ec1fd4f18..80bba637fba7 100644 --- a/trunk/crypto/api.c +++ b/trunk/crypto/api.c @@ -188,16 +188,13 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) if (crypto_init_flags(tfm, flags)) goto out_free_tfm; - if (crypto_init_ops(tfm)) + if (crypto_init_ops(tfm)) { + crypto_exit_ops(tfm); goto out_free_tfm; - - if (alg->cra_init && alg->cra_init(tfm)) - goto cra_init_failed; + } goto out; -cra_init_failed: - crypto_exit_ops(tfm); out_free_tfm: kfree(tfm); tfm = NULL; @@ -218,8 +215,6 @@ void crypto_free_tfm(struct crypto_tfm *tfm) alg = tfm->__crt_alg; size = sizeof(*tfm) + alg->cra_ctxsize; - if (alg->cra_exit) - alg->cra_exit(tfm); crypto_exit_ops(tfm); crypto_alg_put(alg); memset(tfm, 0, size); @@ -229,7 +224,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm) static inline int crypto_set_driver_name(struct crypto_alg *alg) { static const char suffix[] = "-generic"; - char *driver_name = alg->cra_driver_name; + char *driver_name = (char *)alg->cra_driver_name; int len; if (*driver_name) @@ -267,13 +262,13 @@ int crypto_register_alg(struct crypto_alg *alg) down_write(&crypto_alg_sem); list_for_each_entry(q, &crypto_alg_list, cra_list) { - if (q == alg) { + if (!strcmp(q->cra_driver_name, alg->cra_driver_name)) { ret = -EEXIST; goto out; } } - list_add(&alg->cra_list, &crypto_alg_list); + list_add_tail(&alg->cra_list, &crypto_alg_list); out: up_write(&crypto_alg_sem); return ret; diff --git a/trunk/crypto/arc4.c b/trunk/crypto/arc4.c index 5edc6a65b987..9efbcaae88a1 100644 --- a/trunk/crypto/arc4.c +++ b/trunk/crypto/arc4.c @@ -24,10 +24,9 @@ struct arc4_ctx { u8 x, y; }; -static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); + struct arc4_ctx *ctx = ctx_arg; int i, j = 0, k = 0; ctx->x = 1; @@ -49,9 +48,9 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, return 0; } -static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in) { - struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); + struct arc4_ctx *ctx = ctx_arg; u8 *const S = ctx->S; u8 x = ctx->x; diff --git a/trunk/crypto/blowfish.c b/trunk/crypto/blowfish.c index 490265f42b3b..7f710b201f20 100644 --- a/trunk/crypto/blowfish.c +++ b/trunk/crypto/blowfish.c @@ -349,7 +349,7 @@ static void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src) dst[1] = yl; } -static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void bf_encrypt(void *ctx, u8 *dst, const u8 *src) { const __be32 *in_blk = (const __be32 *)src; __be32 *const out_blk = (__be32 *)dst; @@ -357,18 +357,17 @@ static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) in32[0] = be32_to_cpu(in_blk[0]); in32[1] = be32_to_cpu(in_blk[1]); - encrypt_block(crypto_tfm_ctx(tfm), out32, in32); + encrypt_block(ctx, out32, in32); out_blk[0] = cpu_to_be32(out32[0]); out_blk[1] = cpu_to_be32(out32[1]); } -static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void bf_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct bf_ctx *ctx = crypto_tfm_ctx(tfm); const __be32 *in_blk = (const __be32 *)src; __be32 *const out_blk = (__be32 *)dst; - const u32 *P = ctx->p; - const u32 *S = ctx->s; + const u32 *P = ((struct bf_ctx *)ctx)->p; + const u32 *S = ((struct bf_ctx *)ctx)->s; u32 yl = be32_to_cpu(in_blk[0]); u32 yr = be32_to_cpu(in_blk[1]); @@ -399,14 +398,12 @@ static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) /* * Calculates the blowfish S and P boxes for encryption and decryption. */ -static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int bf_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { - struct bf_ctx *ctx = crypto_tfm_ctx(tfm); - u32 *P = ctx->p; - u32 *S = ctx->s; short i, j, count; u32 data[2], temp; + u32 *P = ((struct bf_ctx *)ctx)->p; + u32 *S = ((struct bf_ctx *)ctx)->s; /* Copy the initialization s-boxes */ for (i = 0, count = 0; i < 256; i++) diff --git a/trunk/crypto/cast5.c b/trunk/crypto/cast5.c index 08eef58c1d3d..8834c8580c04 100644 --- a/trunk/crypto/cast5.c +++ b/trunk/crypto/cast5.c @@ -577,9 +577,9 @@ static const u32 sb8[256] = { (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) ) -static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) +static void cast5_encrypt(void *ctx, u8 * outbuf, const u8 * inbuf) { - struct cast5_ctx *c = crypto_tfm_ctx(tfm); + struct cast5_ctx *c = (struct cast5_ctx *) ctx; const __be32 *src = (const __be32 *)inbuf; __be32 *dst = (__be32 *)outbuf; u32 l, r, t; @@ -642,9 +642,9 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) dst[1] = cpu_to_be32(l); } -static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) +static void cast5_decrypt(void *ctx, u8 * outbuf, const u8 * inbuf) { - struct cast5_ctx *c = crypto_tfm_ctx(tfm); + struct cast5_ctx *c = (struct cast5_ctx *) ctx; const __be32 *src = (const __be32 *)inbuf; __be32 *dst = (__be32 *)outbuf; u32 l, r, t; @@ -769,15 +769,15 @@ static void key_schedule(u32 * x, u32 * z, u32 * k) } -static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned key_len, u32 *flags) +static int +cast5_setkey(void *ctx, const u8 * key, unsigned key_len, u32 * flags) { - struct cast5_ctx *c = crypto_tfm_ctx(tfm); int i; u32 x[4]; u32 z[4]; u32 k[16]; __be32 p_key[4]; + struct cast5_ctx *c = (struct cast5_ctx *) ctx; if (key_len < 5 || key_len > 16) { *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; diff --git a/trunk/crypto/cast6.c b/trunk/crypto/cast6.c index 08e33bfc3ad1..9e28740ba775 100644 --- a/trunk/crypto/cast6.c +++ b/trunk/crypto/cast6.c @@ -381,13 +381,13 @@ static inline void W(u32 *key, unsigned int i) { key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]); } -static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key, - unsigned key_len, u32 *flags) +static int +cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags) { int i; u32 key[8]; __be32 p_key[8]; /* padded key */ - struct cast6_ctx *c = crypto_tfm_ctx(tfm); + struct cast6_ctx *c = (struct cast6_ctx *) ctx; if (key_len < 16 || key_len > 32 || key_len % 4 != 0) { *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; @@ -444,9 +444,8 @@ static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) { block[2] ^= F1(block[3], Kr[0], Km[0]); } -static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) -{ - struct cast6_ctx *c = crypto_tfm_ctx(tfm); +static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; const __be32 *src = (const __be32 *)inbuf; __be32 *dst = (__be32 *)outbuf; u32 block[4]; @@ -477,8 +476,8 @@ static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) dst[3] = cpu_to_be32(block[3]); } -static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) { - struct cast6_ctx * c = crypto_tfm_ctx(tfm); +static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) { + struct cast6_ctx * c = (struct cast6_ctx *)ctx; const __be32 *src = (const __be32 *)inbuf; __be32 *dst = (__be32 *)outbuf; u32 block[4]; diff --git a/trunk/crypto/cipher.c b/trunk/crypto/cipher.c index b899eb97abd7..65bcea0cd17c 100644 --- a/trunk/crypto/cipher.c +++ b/trunk/crypto/cipher.c @@ -187,7 +187,7 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; int bsize = crypto_tfm_alg_blocksize(tfm); - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; u8 *iv = desc->info; unsigned int done = 0; @@ -195,7 +195,7 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, do { xor(iv, src); - fn(tfm, dst, iv); + fn(crypto_tfm_ctx(tfm), dst, iv); memcpy(iv, dst, bsize); src += bsize; @@ -218,7 +218,7 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, u8 *buf = (u8 *)ALIGN((unsigned long)stack, alignmask + 1); u8 **dst_p = src == dst ? &buf : &dst; - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; u8 *iv = desc->info; unsigned int done = 0; @@ -227,7 +227,7 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, do { u8 *tmp_dst = *dst_p; - fn(tfm, tmp_dst, src); + fn(crypto_tfm_ctx(tfm), tmp_dst, src); xor(tmp_dst, iv); memcpy(iv, src, bsize); if (tmp_dst != dst) @@ -245,13 +245,13 @@ static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, { struct crypto_tfm *tfm = desc->tfm; int bsize = crypto_tfm_alg_blocksize(tfm); - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; unsigned int done = 0; nbytes -= bsize; do { - fn(tfm, dst, src); + fn(crypto_tfm_ctx(tfm), dst, src); src += bsize; dst += bsize; @@ -268,7 +268,7 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; return -EINVAL; } else - return cia->cia_setkey(tfm, key, keylen, + return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen, &tfm->crt_flags); } diff --git a/trunk/crypto/compress.c b/trunk/crypto/compress.c index eca182aa3380..eb36d9364da3 100644 --- a/trunk/crypto/compress.c +++ b/trunk/crypto/compress.c @@ -22,7 +22,8 @@ static int crypto_compress(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { - return tfm->__crt_alg->cra_compress.coa_compress(tfm, src, slen, dst, + return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm), + src, slen, dst, dlen); } @@ -30,7 +31,8 @@ static int crypto_decompress(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { - return tfm->__crt_alg->cra_compress.coa_decompress(tfm, src, slen, dst, + return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm), + src, slen, dst, dlen); } @@ -41,14 +43,21 @@ int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) int crypto_init_compress_ops(struct crypto_tfm *tfm) { + int ret = 0; struct compress_tfm *ops = &tfm->crt_compress; + + ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm)); + if (ret) + goto out; ops->cot_compress = crypto_compress; ops->cot_decompress = crypto_decompress; - return 0; +out: + return ret; } void crypto_exit_compress_ops(struct crypto_tfm *tfm) { + tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm)); } diff --git a/trunk/crypto/crc32c.c b/trunk/crypto/crc32c.c index f2660123aeb4..953362423a5c 100644 --- a/trunk/crypto/crc32c.c +++ b/trunk/crypto/crc32c.c @@ -31,9 +31,9 @@ struct chksum_ctx { * crc using table. */ -static void chksum_init(struct crypto_tfm *tfm) +static void chksum_init(void *ctx) { - struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + struct chksum_ctx *mctx = ctx; mctx->crc = ~(u32)0; /* common usage */ } @@ -43,10 +43,10 @@ static void chksum_init(struct crypto_tfm *tfm) * If your algorithm starts with ~0, then XOR with ~0 before you set * the seed. */ -static int chksum_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) { - struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + struct chksum_ctx *mctx = ctx; if (keylen != sizeof(mctx->crc)) { if (flags) @@ -57,10 +57,9 @@ static int chksum_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void chksum_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int length) +static void chksum_update(void *ctx, const u8 *data, unsigned int length) { - struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + struct chksum_ctx *mctx = ctx; u32 mcrc; mcrc = crc32c(mctx->crc, data, (size_t)length); @@ -68,9 +67,9 @@ static void chksum_update(struct crypto_tfm *tfm, const u8 *data, mctx->crc = mcrc; } -static void chksum_final(struct crypto_tfm *tfm, u8 *out) +static void chksum_final(void *ctx, u8 *out) { - struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + struct chksum_ctx *mctx = ctx; u32 mcrc = (mctx->crc ^ ~(u32)0); *(u32 *)out = __le32_to_cpu(mcrc); diff --git a/trunk/crypto/crypto_null.c b/trunk/crypto/crypto_null.c index a0d956b52949..3fcf6e887e87 100644 --- a/trunk/crypto/crypto_null.c +++ b/trunk/crypto/crypto_null.c @@ -27,8 +27,8 @@ #define NULL_BLOCK_SIZE 1 #define NULL_DIGEST_SIZE 0 -static int null_compress(struct crypto_tfm *tfm, const u8 *src, - unsigned int slen, u8 *dst, unsigned int *dlen) +static int null_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { if (slen > *dlen) return -EINVAL; @@ -37,21 +37,20 @@ static int null_compress(struct crypto_tfm *tfm, const u8 *src, return 0; } -static void null_init(struct crypto_tfm *tfm) +static void null_init(void *ctx) { } -static void null_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void null_update(void *ctx, const u8 *data, unsigned int len) { } -static void null_final(struct crypto_tfm *tfm, u8 *out) +static void null_final(void *ctx, u8 *out) { } -static int null_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int null_setkey(void *ctx, const u8 *key, + unsigned int keylen, u32 *flags) { return 0; } -static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void null_crypt(void *ctx, u8 *dst, const u8 *src) { memcpy(dst, src, NULL_BLOCK_SIZE); } diff --git a/trunk/crypto/deflate.c b/trunk/crypto/deflate.c index 6588bbf82e9b..f209368d62ae 100644 --- a/trunk/crypto/deflate.c +++ b/trunk/crypto/deflate.c @@ -102,9 +102,8 @@ static void deflate_decomp_exit(struct deflate_ctx *ctx) kfree(ctx->decomp_stream.workspace); } -static int deflate_init(struct crypto_tfm *tfm) +static int deflate_init(void *ctx) { - struct deflate_ctx *ctx = crypto_tfm_ctx(tfm); int ret; ret = deflate_comp_init(ctx); @@ -117,19 +116,17 @@ static int deflate_init(struct crypto_tfm *tfm) return ret; } -static void deflate_exit(struct crypto_tfm *tfm) +static void deflate_exit(void *ctx) { - struct deflate_ctx *ctx = crypto_tfm_ctx(tfm); - deflate_comp_exit(ctx); deflate_decomp_exit(ctx); } -static int deflate_compress(struct crypto_tfm *tfm, const u8 *src, - unsigned int slen, u8 *dst, unsigned int *dlen) +static int deflate_compress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { int ret = 0; - struct deflate_ctx *dctx = crypto_tfm_ctx(tfm); + struct deflate_ctx *dctx = ctx; struct z_stream_s *stream = &dctx->comp_stream; ret = zlib_deflateReset(stream); @@ -154,12 +151,12 @@ static int deflate_compress(struct crypto_tfm *tfm, const u8 *src, return ret; } -static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src, - unsigned int slen, u8 *dst, unsigned int *dlen) +static int deflate_decompress(void *ctx, const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { int ret = 0; - struct deflate_ctx *dctx = crypto_tfm_ctx(tfm); + struct deflate_ctx *dctx = ctx; struct z_stream_s *stream = &dctx->decomp_stream; ret = zlib_inflateReset(stream); @@ -201,9 +198,9 @@ static struct crypto_alg alg = { .cra_ctxsize = sizeof(struct deflate_ctx), .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(alg.cra_list), - .cra_init = deflate_init, - .cra_exit = deflate_exit, .cra_u = { .compress = { + .coa_init = deflate_init, + .coa_exit = deflate_exit, .coa_compress = deflate_compress, .coa_decompress = deflate_decompress } } }; diff --git a/trunk/crypto/des.c b/trunk/crypto/des.c index a9d3c235a6af..2d74cab40c3e 100644 --- a/trunk/crypto/des.c +++ b/trunk/crypto/des.c @@ -783,10 +783,9 @@ static void dkey(u32 *pe, const u8 *k) } } -static int des_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { - struct des_ctx *dctx = crypto_tfm_ctx(tfm); + struct des_ctx *dctx = ctx; u32 tmp[DES_EXPKEY_WORDS]; int ret; @@ -804,10 +803,9 @@ static int des_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des_encrypt(void *ctx, u8 *dst, const u8 *src) { - struct des_ctx *ctx = crypto_tfm_ctx(tfm); - const u32 *K = ctx->expkey; + const u32 *K = ((struct des_ctx *)ctx)->expkey; const __le32 *s = (const __le32 *)src; __le32 *d = (__le32 *)dst; u32 L, R, A, B; @@ -827,10 +825,9 @@ static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) d[1] = cpu_to_le32(L); } -static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct des_ctx *ctx = crypto_tfm_ctx(tfm); - const u32 *K = ctx->expkey + DES_EXPKEY_WORDS - 2; + const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2; const __le32 *s = (const __le32 *)src; __le32 *d = (__le32 *)dst; u32 L, R, A, B; @@ -863,11 +860,11 @@ static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) * property. * */ -static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, +static int des3_ede_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { const u32 *K = (const u32 *)key; - struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); + struct des3_ede_ctx *dctx = ctx; u32 *expkey = dctx->expkey; if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || @@ -884,9 +881,9 @@ static int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src) { - struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); + struct des3_ede_ctx *dctx = ctx; const u32 *K = dctx->expkey; const __le32 *s = (const __le32 *)src; __le32 *d = (__le32 *)dst; @@ -915,9 +912,9 @@ static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) d[1] = cpu_to_le32(L); } -static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct des3_ede_ctx *dctx = crypto_tfm_ctx(tfm); + struct des3_ede_ctx *dctx = ctx; const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2; const __le32 *s = (const __le32 *)src; __le32 *d = (__le32 *)dst; diff --git a/trunk/crypto/digest.c b/trunk/crypto/digest.c index 603006a7bef2..d9b6ac9dbf8d 100644 --- a/trunk/crypto/digest.c +++ b/trunk/crypto/digest.c @@ -20,14 +20,13 @@ static void init(struct crypto_tfm *tfm) { - tfm->__crt_alg->cra_digest.dia_init(tfm); + tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm)); } static void update(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg) { unsigned int i; - unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); for (i = 0; i < nsg; i++) { @@ -39,22 +38,12 @@ static void update(struct crypto_tfm *tfm, unsigned int bytes_from_page = min(l, ((unsigned int) (PAGE_SIZE)) - offset); - char *src = crypto_kmap(pg, 0); - char *p = src + offset; + char *p = crypto_kmap(pg, 0) + offset; - if (unlikely(offset & alignmask)) { - unsigned int bytes = - alignmask + 1 - (offset & alignmask); - bytes = min(bytes, bytes_from_page); - tfm->__crt_alg->cra_digest.dia_update(tfm, p, - bytes); - p += bytes; - bytes_from_page -= bytes; - l -= bytes; - } - tfm->__crt_alg->cra_digest.dia_update(tfm, p, - bytes_from_page); - crypto_kunmap(src, 0); + tfm->__crt_alg->cra_digest.dia_update + (crypto_tfm_ctx(tfm), p, + bytes_from_page); + crypto_kunmap(p, 0); crypto_yield(tfm); offset = 0; pg++; @@ -65,15 +54,7 @@ static void update(struct crypto_tfm *tfm, static void final(struct crypto_tfm *tfm, u8 *out) { - unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); - if (unlikely((unsigned long)out & alignmask)) { - unsigned int size = crypto_tfm_alg_digestsize(tfm); - u8 buffer[size + alignmask]; - u8 *dst = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); - tfm->__crt_alg->cra_digest.dia_final(tfm, dst); - memcpy(out, dst, size); - } else - tfm->__crt_alg->cra_digest.dia_final(tfm, out); + tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -81,15 +62,25 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) u32 flags; if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) return -ENOSYS; - return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen, &flags); + return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), + key, keylen, &flags); } static void digest(struct crypto_tfm *tfm, struct scatterlist *sg, unsigned int nsg, u8 *out) { - init(tfm); - update(tfm, sg, nsg); - final(tfm, out); + unsigned int i; + + tfm->crt_digest.dit_init(tfm); + + for (i = 0; i < nsg; i++) { + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; + tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), + p, sg[i].length); + crypto_kunmap(p, 0); + crypto_yield(tfm); + } + crypto_digest_final(tfm, out); } int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) diff --git a/trunk/crypto/khazad.c b/trunk/crypto/khazad.c index d4c9d3657b36..807f2bf4ea24 100644 --- a/trunk/crypto/khazad.c +++ b/trunk/crypto/khazad.c @@ -754,11 +754,11 @@ static const u64 c[KHAZAD_ROUNDS + 1] = { 0xccc41d14c363da5dULL, 0x5fdc7dcd7f5a6c5cULL, 0xf726ffede89d6f8eULL }; -static int khazad_setkey(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int khazad_setkey(void *ctx_arg, const u8 *in_key, + unsigned int key_len, u32 *flags) { - struct khazad_ctx *ctx = crypto_tfm_ctx(tfm); - const __be32 *key = (const __be32 *)in_key; + struct khazad_ctx *ctx = ctx_arg; + const __be64 *key = (const __be64 *)in_key; int r; const u64 *S = T7; u64 K2, K1; @@ -769,9 +769,8 @@ static int khazad_setkey(struct crypto_tfm *tfm, const u8 *in_key, return -EINVAL; } - /* key is supposed to be 32-bit aligned */ - K2 = ((u64)be32_to_cpu(key[0]) << 32) | be32_to_cpu(key[1]); - K1 = ((u64)be32_to_cpu(key[2]) << 32) | be32_to_cpu(key[3]); + K2 = be64_to_cpu(key[0]); + K1 = be64_to_cpu(key[1]); /* setup the encrypt key */ for (r = 0; r <= KHAZAD_ROUNDS; r++) { @@ -841,15 +840,15 @@ static void khazad_crypt(const u64 roundKey[KHAZAD_ROUNDS + 1], *dst = cpu_to_be64(state); } -static void khazad_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void khazad_encrypt(void *ctx_arg, u8 *dst, const u8 *src) { - struct khazad_ctx *ctx = crypto_tfm_ctx(tfm); + struct khazad_ctx *ctx = ctx_arg; khazad_crypt(ctx->E, dst, src); } -static void khazad_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void khazad_decrypt(void *ctx_arg, u8 *dst, const u8 *src) { - struct khazad_ctx *ctx = crypto_tfm_ctx(tfm); + struct khazad_ctx *ctx = ctx_arg; khazad_crypt(ctx->D, dst, src); } diff --git a/trunk/crypto/md4.c b/trunk/crypto/md4.c index c1bc71bdc16b..a2d6df5c0f8c 100644 --- a/trunk/crypto/md4.c +++ b/trunk/crypto/md4.c @@ -152,9 +152,9 @@ static inline void md4_transform_helper(struct md4_ctx *ctx) md4_transform(ctx->hash, ctx->block); } -static void md4_init(struct crypto_tfm *tfm) +static void md4_init(void *ctx) { - struct md4_ctx *mctx = crypto_tfm_ctx(tfm); + struct md4_ctx *mctx = ctx; mctx->hash[0] = 0x67452301; mctx->hash[1] = 0xefcdab89; @@ -163,9 +163,9 @@ static void md4_init(struct crypto_tfm *tfm) mctx->byte_count = 0; } -static void md4_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) +static void md4_update(void *ctx, const u8 *data, unsigned int len) { - struct md4_ctx *mctx = crypto_tfm_ctx(tfm); + struct md4_ctx *mctx = ctx; const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); mctx->byte_count += len; @@ -193,9 +193,9 @@ static void md4_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) memcpy(mctx->block, data, len); } -static void md4_final(struct crypto_tfm *tfm, u8 *out) +static void md4_final(void *ctx, u8 *out) { - struct md4_ctx *mctx = crypto_tfm_ctx(tfm); + struct md4_ctx *mctx = ctx; const unsigned int offset = mctx->byte_count & 0x3f; char *p = (char *)mctx->block + offset; int padding = 56 - (offset + 1); diff --git a/trunk/crypto/md5.c b/trunk/crypto/md5.c index 93d18e8b3d53..7f041aef5da2 100644 --- a/trunk/crypto/md5.c +++ b/trunk/crypto/md5.c @@ -147,9 +147,9 @@ static inline void md5_transform_helper(struct md5_ctx *ctx) md5_transform(ctx->hash, ctx->block); } -static void md5_init(struct crypto_tfm *tfm) +static void md5_init(void *ctx) { - struct md5_ctx *mctx = crypto_tfm_ctx(tfm); + struct md5_ctx *mctx = ctx; mctx->hash[0] = 0x67452301; mctx->hash[1] = 0xefcdab89; @@ -158,9 +158,9 @@ static void md5_init(struct crypto_tfm *tfm) mctx->byte_count = 0; } -static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) +static void md5_update(void *ctx, const u8 *data, unsigned int len) { - struct md5_ctx *mctx = crypto_tfm_ctx(tfm); + struct md5_ctx *mctx = ctx; const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); mctx->byte_count += len; @@ -188,9 +188,9 @@ static void md5_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) memcpy(mctx->block, data, len); } -static void md5_final(struct crypto_tfm *tfm, u8 *out) +static void md5_final(void *ctx, u8 *out) { - struct md5_ctx *mctx = crypto_tfm_ctx(tfm); + struct md5_ctx *mctx = ctx; const unsigned int offset = mctx->byte_count & 0x3f; char *p = (char *)mctx->block + offset; int padding = 56 - (offset + 1); diff --git a/trunk/crypto/michael_mic.c b/trunk/crypto/michael_mic.c index d061da21cfda..4f6ab23e14ad 100644 --- a/trunk/crypto/michael_mic.c +++ b/trunk/crypto/michael_mic.c @@ -45,17 +45,16 @@ do { \ } while (0) -static void michael_init(struct crypto_tfm *tfm) +static void michael_init(void *ctx) { - struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); + struct michael_mic_ctx *mctx = ctx; mctx->pending_len = 0; } -static void michael_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void michael_update(void *ctx, const u8 *data, unsigned int len) { - struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); + struct michael_mic_ctx *mctx = ctx; const __le32 *src; if (mctx->pending_len) { @@ -91,9 +90,9 @@ static void michael_update(struct crypto_tfm *tfm, const u8 *data, } -static void michael_final(struct crypto_tfm *tfm, u8 *out) +static void michael_final(void *ctx, u8 *out) { - struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); + struct michael_mic_ctx *mctx = ctx; u8 *data = mctx->pending; __le32 *dst = (__le32 *)out; @@ -122,10 +121,10 @@ static void michael_final(struct crypto_tfm *tfm, u8 *out) } -static int michael_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen, + u32 *flags) { - struct michael_mic_ctx *mctx = crypto_tfm_ctx(tfm); + struct michael_mic_ctx *mctx = ctx; const __le32 *data = (const __le32 *)key; if (keylen != 8) { @@ -146,7 +145,6 @@ static struct crypto_alg michael_mic_alg = { .cra_blocksize = 8, .cra_ctxsize = sizeof(struct michael_mic_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 3, .cra_list = LIST_HEAD_INIT(michael_mic_alg.cra_list), .cra_u = { .digest = { .dia_digestsize = 8, diff --git a/trunk/crypto/serpent.c b/trunk/crypto/serpent.c index de60cdddbf4a..e366406ab49d 100644 --- a/trunk/crypto/serpent.c +++ b/trunk/crypto/serpent.c @@ -215,11 +215,9 @@ struct serpent_ctx { }; -static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int serpent_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { - struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); - u32 *k = ctx->expkey; + u32 *k = ((struct serpent_ctx *)ctx)->expkey; u8 *k8 = (u8 *)k; u32 r0,r1,r2,r3,r4; int i; @@ -367,11 +365,10 @@ static int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, return 0; } -static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void serpent_encrypt(void *ctx, u8 *dst, const u8 *src) { - struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); const u32 - *k = ctx->expkey, + *k = ((struct serpent_ctx *)ctx)->expkey, *s = (const u32 *)src; u32 *d = (u32 *)dst, r0, r1, r2, r3, r4; @@ -426,9 +423,8 @@ static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) d[3] = cpu_to_le32(r3); } -static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void serpent_decrypt(void *ctx, u8 *dst, const u8 *src) { - struct serpent_ctx *ctx = crypto_tfm_ctx(tfm); const u32 *k = ((struct serpent_ctx *)ctx)->expkey, *s = (const u32 *)src; @@ -496,8 +492,7 @@ static struct crypto_alg serpent_alg = { .cia_decrypt = serpent_decrypt } } }; -static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen, u32 *flags) +static int tnepres_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { u8 rev_key[SERPENT_MAX_KEY_SIZE]; int i; @@ -511,10 +506,10 @@ static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key, for (i = 0; i < keylen; ++i) rev_key[keylen - i - 1] = key[i]; - return serpent_setkey(tfm, rev_key, keylen, flags); + return serpent_setkey(ctx, rev_key, keylen, flags); } -static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void tnepres_encrypt(void *ctx, u8 *dst, const u8 *src) { const u32 * const s = (const u32 * const)src; u32 * const d = (u32 * const)dst; @@ -526,7 +521,7 @@ static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) rs[2] = swab32(s[1]); rs[3] = swab32(s[0]); - serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs); + serpent_encrypt(ctx, (u8 *)rd, (u8 *)rs); d[0] = swab32(rd[3]); d[1] = swab32(rd[2]); @@ -534,7 +529,7 @@ static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) d[3] = swab32(rd[0]); } -static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) +static void tnepres_decrypt(void *ctx, u8 *dst, const u8 *src) { const u32 * const s = (const u32 * const)src; u32 * const d = (u32 * const)dst; @@ -546,7 +541,7 @@ static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) rs[2] = swab32(s[1]); rs[3] = swab32(s[0]); - serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs); + serpent_decrypt(ctx, (u8 *)rd, (u8 *)rs); d[0] = swab32(rd[3]); d[1] = swab32(rd[2]); diff --git a/trunk/crypto/sha1.c b/trunk/crypto/sha1.c index 6c77b689f87e..21571ed35b7e 100644 --- a/trunk/crypto/sha1.c +++ b/trunk/crypto/sha1.c @@ -34,9 +34,9 @@ struct sha1_ctx { u8 buffer[64]; }; -static void sha1_init(struct crypto_tfm *tfm) +static void sha1_init(void *ctx) { - struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha1_ctx *sctx = ctx; static const struct sha1_ctx initstate = { 0, { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }, @@ -46,10 +46,9 @@ static void sha1_init(struct crypto_tfm *tfm) *sctx = initstate; } -static void sha1_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void sha1_update(void *ctx, const u8 *data, unsigned int len) { - struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha1_ctx *sctx = ctx; unsigned int partial, done; const u8 *src; @@ -81,9 +80,9 @@ static void sha1_update(struct crypto_tfm *tfm, const u8 *data, /* Add padding and return the message digest. */ -static void sha1_final(struct crypto_tfm *tfm, u8 *out) +static void sha1_final(void* ctx, u8 *out) { - struct sha1_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha1_ctx *sctx = ctx; __be32 *dst = (__be32 *)out; u32 i, index, padlen; __be64 bits; @@ -94,10 +93,10 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out) /* Pad out to 56 mod 64 */ index = sctx->count & 0x3f; padlen = (index < 56) ? (56 - index) : ((64+56) - index); - sha1_update(tfm, padding, padlen); + sha1_update(sctx, padding, padlen); /* Append length */ - sha1_update(tfm, (const u8 *)&bits, sizeof(bits)); + sha1_update(sctx, (const u8 *)&bits, sizeof(bits)); /* Store state in digest */ for (i = 0; i < 5; i++) @@ -113,7 +112,6 @@ static struct crypto_alg alg = { .cra_blocksize = SHA1_HMAC_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sha1_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 3, .cra_list = LIST_HEAD_INIT(alg.cra_list), .cra_u = { .digest = { .dia_digestsize = SHA1_DIGEST_SIZE, diff --git a/trunk/crypto/sha256.c b/trunk/crypto/sha256.c index bc71d85a7d02..9d5ef674d6a9 100644 --- a/trunk/crypto/sha256.c +++ b/trunk/crypto/sha256.c @@ -230,9 +230,9 @@ static void sha256_transform(u32 *state, const u8 *input) memset(W, 0, 64 * sizeof(u32)); } -static void sha256_init(struct crypto_tfm *tfm) +static void sha256_init(void *ctx) { - struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha256_ctx *sctx = ctx; sctx->state[0] = H0; sctx->state[1] = H1; sctx->state[2] = H2; @@ -242,12 +242,12 @@ static void sha256_init(struct crypto_tfm *tfm) sctx->state[6] = H6; sctx->state[7] = H7; sctx->count[0] = sctx->count[1] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); } -static void sha256_update(struct crypto_tfm *tfm, const u8 *data, - unsigned int len) +static void sha256_update(void *ctx, const u8 *data, unsigned int len) { - struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha256_ctx *sctx = ctx; unsigned int i, index, part_len; /* Compute number of bytes mod 128 */ @@ -277,9 +277,9 @@ static void sha256_update(struct crypto_tfm *tfm, const u8 *data, memcpy(&sctx->buf[index], &data[i], len-i); } -static void sha256_final(struct crypto_tfm *tfm, u8 *out) +static void sha256_final(void* ctx, u8 *out) { - struct sha256_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha256_ctx *sctx = ctx; __be32 *dst = (__be32 *)out; __be32 bits[2]; unsigned int index, pad_len; @@ -293,10 +293,10 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out) /* Pad out to 56 mod 64. */ index = (sctx->count[0] >> 3) & 0x3f; pad_len = (index < 56) ? (56 - index) : ((64+56) - index); - sha256_update(tfm, padding, pad_len); + sha256_update(sctx, padding, pad_len); /* Append length (before padding) */ - sha256_update(tfm, (const u8 *)bits, sizeof(bits)); + sha256_update(sctx, (const u8 *)bits, sizeof(bits)); /* Store state in digest */ for (i = 0; i < 8; i++) @@ -313,7 +313,6 @@ static struct crypto_alg alg = { .cra_blocksize = SHA256_HMAC_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sha256_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 3, .cra_list = LIST_HEAD_INIT(alg.cra_list), .cra_u = { .digest = { .dia_digestsize = SHA256_DIGEST_SIZE, diff --git a/trunk/crypto/sha512.c b/trunk/crypto/sha512.c index 2dfe7f170b48..3e6e9392310c 100644 --- a/trunk/crypto/sha512.c +++ b/trunk/crypto/sha512.c @@ -161,9 +161,9 @@ sha512_transform(u64 *state, u64 *W, const u8 *input) } static void -sha512_init(struct crypto_tfm *tfm) +sha512_init(void *ctx) { - struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha512_ctx *sctx = ctx; sctx->state[0] = H0; sctx->state[1] = H1; sctx->state[2] = H2; @@ -173,12 +173,13 @@ sha512_init(struct crypto_tfm *tfm) sctx->state[6] = H6; sctx->state[7] = H7; sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); } static void -sha384_init(struct crypto_tfm *tfm) +sha384_init(void *ctx) { - struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha512_ctx *sctx = ctx; sctx->state[0] = HP0; sctx->state[1] = HP1; sctx->state[2] = HP2; @@ -188,12 +189,13 @@ sha384_init(struct crypto_tfm *tfm) sctx->state[6] = HP6; sctx->state[7] = HP7; sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0; + memset(sctx->buf, 0, sizeof(sctx->buf)); } static void -sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) +sha512_update(void *ctx, const u8 *data, unsigned int len) { - struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha512_ctx *sctx = ctx; unsigned int i, index, part_len; @@ -231,9 +233,9 @@ sha512_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len) } static void -sha512_final(struct crypto_tfm *tfm, u8 *hash) +sha512_final(void *ctx, u8 *hash) { - struct sha512_ctx *sctx = crypto_tfm_ctx(tfm); + struct sha512_ctx *sctx = ctx; static u8 padding[128] = { 0x80, }; __be64 *dst = (__be64 *)hash; __be32 bits[4]; @@ -249,10 +251,10 @@ sha512_final(struct crypto_tfm *tfm, u8 *hash) /* Pad out to 112 mod 128. */ index = (sctx->count[0] >> 3) & 0x7f; pad_len = (index < 112) ? (112 - index) : ((128+112) - index); - sha512_update(tfm, padding, pad_len); + sha512_update(sctx, padding, pad_len); /* Append length (before padding) */ - sha512_update(tfm, (const u8 *)bits, sizeof(bits)); + sha512_update(sctx, (const u8 *)bits, sizeof(bits)); /* Store state in digest */ for (i = 0; i < 8; i++) @@ -262,11 +264,12 @@ sha512_final(struct crypto_tfm *tfm, u8 *hash) memset(sctx, 0, sizeof(struct sha512_ctx)); } -static void sha384_final(struct crypto_tfm *tfm, u8 *hash) +static void sha384_final(void *ctx, u8 *hash) { + struct sha512_ctx *sctx = ctx; u8 D[64]; - sha512_final(tfm, D); + sha512_final(sctx, D); memcpy(hash, D, 48); memset(D, 0, 64); @@ -278,7 +281,6 @@ static struct crypto_alg sha512 = { .cra_blocksize = SHA512_HMAC_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sha512_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 3, .cra_list = LIST_HEAD_INIT(sha512.cra_list), .cra_u = { .digest = { .dia_digestsize = SHA512_DIGEST_SIZE, @@ -293,7 +295,6 @@ static struct crypto_alg sha384 = { .cra_flags = CRYPTO_ALG_TYPE_DIGEST, .cra_blocksize = SHA384_HMAC_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sha512_ctx), - .cra_alignmask = 3, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(sha384.cra_list), .cra_u = { .digest = { diff --git a/trunk/crypto/tcrypt.c b/trunk/crypto/tcrypt.c index e52f56c5bd5e..49e344f00806 100644 --- a/trunk/crypto/tcrypt.c +++ b/trunk/crypto/tcrypt.c @@ -570,122 +570,6 @@ static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec, crypto_free_tfm(tfm); } -static void test_digest_jiffies(struct crypto_tfm *tfm, char *p, int blen, - int plen, char *out, int sec) -{ - struct scatterlist sg[1]; - unsigned long start, end; - int bcount, pcount; - - for (start = jiffies, end = start + sec * HZ, bcount = 0; - time_before(jiffies, end); bcount++) { - crypto_digest_init(tfm); - for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); - crypto_digest_update(tfm, sg, 1); - } - /* we assume there is enough space in 'out' for the result */ - crypto_digest_final(tfm, out); - } - - printk("%6u opers/sec, %9lu bytes/sec\n", - bcount / sec, ((long)bcount * blen) / sec); - - return; -} - -static void test_digest_cycles(struct crypto_tfm *tfm, char *p, int blen, - int plen, char *out) -{ - struct scatterlist sg[1]; - unsigned long cycles = 0; - int i, pcount; - - local_bh_disable(); - local_irq_disable(); - - /* Warm-up run. */ - for (i = 0; i < 4; i++) { - crypto_digest_init(tfm); - for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); - crypto_digest_update(tfm, sg, 1); - } - crypto_digest_final(tfm, out); - } - - /* The real thing. */ - for (i = 0; i < 8; i++) { - cycles_t start, end; - - crypto_digest_init(tfm); - - start = get_cycles(); - - for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); - crypto_digest_update(tfm, sg, 1); - } - crypto_digest_final(tfm, out); - - end = get_cycles(); - - cycles += end - start; - } - - local_irq_enable(); - local_bh_enable(); - - printk("%6lu cycles/operation, %4lu cycles/byte\n", - cycles / 8, cycles / (8 * blen)); - - return; -} - -static void test_digest_speed(char *algo, unsigned int sec, - struct digest_speed *speed) -{ - struct crypto_tfm *tfm; - char output[1024]; - int i; - - printk("\ntesting speed of %s\n", algo); - - tfm = crypto_alloc_tfm(algo, 0); - - if (tfm == NULL) { - printk("failed to load transform for %s\n", algo); - return; - } - - if (crypto_tfm_alg_digestsize(tfm) > sizeof(output)) { - printk("digestsize(%u) > outputbuffer(%zu)\n", - crypto_tfm_alg_digestsize(tfm), sizeof(output)); - goto out; - } - - for (i = 0; speed[i].blen != 0; i++) { - if (speed[i].blen > TVMEMSIZE) { - printk("template (%u) too big for tvmem (%u)\n", - speed[i].blen, TVMEMSIZE); - goto out; - } - - printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ", - i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); - - memset(tvmem, 0xff, speed[i].blen); - - if (sec) - test_digest_jiffies(tfm, tvmem, speed[i].blen, speed[i].plen, output, sec); - else - test_digest_cycles(tfm, tvmem, speed[i].blen, speed[i].plen, output); - } - -out: - crypto_free_tfm(tfm); -} - static void test_deflate(void) { unsigned int i; @@ -1202,60 +1086,6 @@ static void do_test(void) des_speed_template); break; - case 300: - /* fall through */ - - case 301: - test_digest_speed("md4", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 302: - test_digest_speed("md5", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 303: - test_digest_speed("sha1", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 304: - test_digest_speed("sha256", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 305: - test_digest_speed("sha384", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 306: - test_digest_speed("sha512", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 307: - test_digest_speed("wp256", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 308: - test_digest_speed("wp384", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 309: - test_digest_speed("wp512", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 310: - test_digest_speed("tgr128", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 311: - test_digest_speed("tgr160", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 312: - test_digest_speed("tgr192", sec, generic_digest_speed_template); - if (mode > 300 && mode < 400) break; - - case 399: - break; - case 1000: test_available(); break; @@ -1283,14 +1113,7 @@ static int __init init(void) kfree(xbuf); kfree(tvmem); - - /* We intentionaly return -EAGAIN to prevent keeping - * the module. It does all its work from init() - * and doesn't offer any runtime functionality - * => we don't need it in the memory, do we? - * -- mludvig - */ - return -EAGAIN; + return 0; } /* diff --git a/trunk/crypto/tcrypt.h b/trunk/crypto/tcrypt.h index 1fac5602f633..1f683ba794ee 100644 --- a/trunk/crypto/tcrypt.h +++ b/trunk/crypto/tcrypt.h @@ -65,11 +65,6 @@ struct cipher_speed { unsigned int blen; }; -struct digest_speed { - unsigned int blen; /* buffer length */ - unsigned int plen; /* per-update length */ -}; - /* * MD4 test vectors from RFC1320 */ @@ -2980,35 +2975,4 @@ static struct cipher_speed des_speed_template[] = { { .klen = 0, .blen = 0, } }; -/* - * Digest speed tests - */ -static struct digest_speed generic_digest_speed_template[] = { - { .blen = 16, .plen = 16, }, - { .blen = 64, .plen = 16, }, - { .blen = 64, .plen = 64, }, - { .blen = 256, .plen = 16, }, - { .blen = 256, .plen = 64, }, - { .blen = 256, .plen = 256, }, - { .blen = 1024, .plen = 16, }, - { .blen = 1024, .plen = 256, }, - { .blen = 1024, .plen = 1024, }, - { .blen = 2048, .plen = 16, }, - { .blen = 2048, .plen = 256, }, - { .blen = 2048, .plen = 1024, }, - { .blen = 2048, .plen = 2048, }, - { .blen = 4096, .plen = 16, }, - { .blen = 4096, .plen = 256, }, - { .blen = 4096, .plen = 1024, }, - { .blen = 4096, .plen = 4096, }, - { .blen = 8192, .plen = 16, }, - { .blen = 8192, .plen = 256, }, - { .blen = 8192, .plen = 1024, }, - { .blen = 8192, .plen = 4096, }, - { .blen = 8192, .plen = 8192, }, - - /* End marker */ - { .blen = 0, .plen = 0, } -}; - #endif /* _CRYPTO_TCRYPT_H */ diff --git a/trunk/crypto/tea.c b/trunk/crypto/tea.c index 5367adc82fc9..a6a02b30e470 100644 --- a/trunk/crypto/tea.c +++ b/trunk/crypto/tea.c @@ -45,10 +45,10 @@ struct xtea_ctx { u32 KEY[4]; }; -static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) -{ - struct tea_ctx *ctx = crypto_tfm_ctx(tfm); +static int tea_setkey(void *ctx_arg, const u8 *in_key, + unsigned int key_len, u32 *flags) +{ + struct tea_ctx *ctx = ctx_arg; const __le32 *key = (const __le32 *)in_key; if (key_len != 16) @@ -66,11 +66,12 @@ static int tea_setkey(struct crypto_tfm *tfm, const u8 *in_key, } -static void tea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void tea_encrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, n, sum = 0; u32 k0, k1, k2, k3; - struct tea_ctx *ctx = crypto_tfm_ctx(tfm); + + struct tea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; @@ -94,11 +95,11 @@ static void tea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) out[1] = cpu_to_le32(z); } -static void tea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void tea_decrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, n, sum; u32 k0, k1, k2, k3; - struct tea_ctx *ctx = crypto_tfm_ctx(tfm); + struct tea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; @@ -124,10 +125,10 @@ static void tea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) out[1] = cpu_to_le32(z); } -static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) -{ - struct xtea_ctx *ctx = crypto_tfm_ctx(tfm); +static int xtea_setkey(void *ctx_arg, const u8 *in_key, + unsigned int key_len, u32 *flags) +{ + struct xtea_ctx *ctx = ctx_arg; const __le32 *key = (const __le32 *)in_key; if (key_len != 16) @@ -145,11 +146,12 @@ static int xtea_setkey(struct crypto_tfm *tfm, const u8 *in_key, } -static void xtea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void xtea_encrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, sum = 0; u32 limit = XTEA_DELTA * XTEA_ROUNDS; - struct xtea_ctx *ctx = crypto_tfm_ctx(tfm); + + struct xtea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; @@ -166,10 +168,10 @@ static void xtea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) out[1] = cpu_to_le32(z); } -static void xtea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void xtea_decrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, sum; - struct tea_ctx *ctx = crypto_tfm_ctx(tfm); + struct tea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; @@ -189,11 +191,12 @@ static void xtea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) } -static void xeta_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void xeta_encrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, sum = 0; u32 limit = XTEA_DELTA * XTEA_ROUNDS; - struct xtea_ctx *ctx = crypto_tfm_ctx(tfm); + + struct xtea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; @@ -210,10 +213,10 @@ static void xeta_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) out[1] = cpu_to_le32(z); } -static void xeta_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ +static void xeta_decrypt(void *ctx_arg, u8 *dst, const u8 *src) +{ u32 y, z, sum; - struct tea_ctx *ctx = crypto_tfm_ctx(tfm); + struct tea_ctx *ctx = ctx_arg; const __le32 *in = (const __le32 *)src; __le32 *out = (__le32 *)dst; diff --git a/trunk/crypto/tgr192.c b/trunk/crypto/tgr192.c index a0fadf3dd3e2..2d8e44f6fbe9 100644 --- a/trunk/crypto/tgr192.c +++ b/trunk/crypto/tgr192.c @@ -496,10 +496,11 @@ static void tgr192_transform(struct tgr192_ctx *tctx, const u8 * data) tctx->c = c; } -static void tgr192_init(struct crypto_tfm *tfm) +static void tgr192_init(void *ctx) { - struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); + struct tgr192_ctx *tctx = ctx; + memset (tctx->hash, 0, 64); tctx->a = 0x0123456789abcdefULL; tctx->b = 0xfedcba9876543210ULL; tctx->c = 0xf096a5b4c3b2e187ULL; @@ -510,10 +511,9 @@ static void tgr192_init(struct crypto_tfm *tfm) /* Update the message digest with the contents * of INBUF with length INLEN. */ -static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf, - unsigned int len) +static void tgr192_update(void *ctx, const u8 * inbuf, unsigned int len) { - struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); + struct tgr192_ctx *tctx = ctx; if (tctx->count == 64) { /* flush the buffer */ tgr192_transform(tctx, tctx->hash); @@ -527,7 +527,7 @@ static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf, for (; len && tctx->count < 64; len--) { tctx->hash[tctx->count++] = *inbuf++; } - tgr192_update(tfm, NULL, 0); + tgr192_update(tctx, NULL, 0); if (!len) { return; } @@ -549,15 +549,15 @@ static void tgr192_update(struct crypto_tfm *tfm, const u8 *inbuf, /* The routine terminates the computation */ -static void tgr192_final(struct crypto_tfm *tfm, u8 * out) +static void tgr192_final(void *ctx, u8 * out) { - struct tgr192_ctx *tctx = crypto_tfm_ctx(tfm); + struct tgr192_ctx *tctx = ctx; __be64 *dst = (__be64 *)out; __be64 *be64p; __le32 *le32p; u32 t, msb, lsb; - tgr192_update(tfm, NULL, 0); /* flush */ ; + tgr192_update(tctx, NULL, 0); /* flush */ ; msb = 0; t = tctx->nblocks; @@ -585,7 +585,7 @@ static void tgr192_final(struct crypto_tfm *tfm, u8 * out) while (tctx->count < 64) { tctx->hash[tctx->count++] = 0; } - tgr192_update(tfm, NULL, 0); /* flush */ ; + tgr192_update(tctx, NULL, 0); /* flush */ ; memset(tctx->hash, 0, 56); /* fill next block with zeroes */ } /* append the 64 bit count */ @@ -601,20 +601,22 @@ static void tgr192_final(struct crypto_tfm *tfm, u8 * out) dst[2] = be64p[2] = cpu_to_be64(tctx->c); } -static void tgr160_final(struct crypto_tfm *tfm, u8 * out) +static void tgr160_final(void *ctx, u8 * out) { + struct tgr192_ctx *wctx = ctx; u8 D[64]; - tgr192_final(tfm, D); + tgr192_final(wctx, D); memcpy(out, D, TGR160_DIGEST_SIZE); memset(D, 0, TGR192_DIGEST_SIZE); } -static void tgr128_final(struct crypto_tfm *tfm, u8 * out) +static void tgr128_final(void *ctx, u8 * out) { + struct tgr192_ctx *wctx = ctx; u8 D[64]; - tgr192_final(tfm, D); + tgr192_final(wctx, D); memcpy(out, D, TGR128_DIGEST_SIZE); memset(D, 0, TGR192_DIGEST_SIZE); } @@ -625,7 +627,6 @@ static struct crypto_alg tgr192 = { .cra_blocksize = TGR192_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tgr192_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 7, .cra_list = LIST_HEAD_INIT(tgr192.cra_list), .cra_u = {.digest = { .dia_digestsize = TGR192_DIGEST_SIZE, @@ -640,7 +641,6 @@ static struct crypto_alg tgr160 = { .cra_blocksize = TGR192_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tgr192_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 7, .cra_list = LIST_HEAD_INIT(tgr160.cra_list), .cra_u = {.digest = { .dia_digestsize = TGR160_DIGEST_SIZE, @@ -655,7 +655,6 @@ static struct crypto_alg tgr128 = { .cra_blocksize = TGR192_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tgr192_ctx), .cra_module = THIS_MODULE, - .cra_alignmask = 7, .cra_list = LIST_HEAD_INIT(tgr128.cra_list), .cra_u = {.digest = { .dia_digestsize = TGR128_DIGEST_SIZE, diff --git a/trunk/crypto/twofish.c b/trunk/crypto/twofish.c index ec2488242e2d..ddfd5a3fcc5f 100644 --- a/trunk/crypto/twofish.c +++ b/trunk/crypto/twofish.c @@ -643,11 +643,11 @@ struct twofish_ctx { }; /* Perform the key setup. */ -static int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int key_len, u32 *flags) +static int twofish_setkey(void *cx, const u8 *key, + unsigned int key_len, u32 *flags) { - struct twofish_ctx *ctx = crypto_tfm_ctx(tfm); + struct twofish_ctx *ctx = cx; int i, j, k; @@ -802,9 +802,9 @@ static int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, } /* Encrypt one block. in and out may be the same. */ -static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void twofish_encrypt(void *cx, u8 *out, const u8 *in) { - struct twofish_ctx *ctx = crypto_tfm_ctx(tfm); + struct twofish_ctx *ctx = cx; const __le32 *src = (const __le32 *)in; __le32 *dst = (__le32 *)out; @@ -839,9 +839,9 @@ static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) } /* Decrypt one block. in and out may be the same. */ -static void twofish_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void twofish_decrypt(void *cx, u8 *out, const u8 *in) { - struct twofish_ctx *ctx = crypto_tfm_ctx(tfm); + struct twofish_ctx *ctx = cx; const __le32 *src = (const __le32 *)in; __le32 *dst = (__le32 *)out; diff --git a/trunk/crypto/wp512.c b/trunk/crypto/wp512.c index 727d05a19ff4..b226a126cfae 100644 --- a/trunk/crypto/wp512.c +++ b/trunk/crypto/wp512.c @@ -981,9 +981,9 @@ static void wp512_process_buffer(struct wp512_ctx *wctx) { } -static void wp512_init(struct crypto_tfm *tfm) { - struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); +static void wp512_init (void *ctx) { int i; + struct wp512_ctx *wctx = ctx; memset(wctx->bitLength, 0, 32); wctx->bufferBits = wctx->bufferPos = 0; @@ -993,10 +993,10 @@ static void wp512_init(struct crypto_tfm *tfm) { } } -static void wp512_update(struct crypto_tfm *tfm, const u8 *source, - unsigned int len) +static void wp512_update(void *ctx, const u8 *source, unsigned int len) { - struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); + + struct wp512_ctx *wctx = ctx; int sourcePos = 0; unsigned int bits_len = len * 8; // convert to number of bits int sourceGap = (8 - ((int)bits_len & 7)) & 7; @@ -1054,9 +1054,9 @@ static void wp512_update(struct crypto_tfm *tfm, const u8 *source, } -static void wp512_final(struct crypto_tfm *tfm, u8 *out) +static void wp512_final(void *ctx, u8 *out) { - struct wp512_ctx *wctx = crypto_tfm_ctx(tfm); + struct wp512_ctx *wctx = ctx; int i; u8 *buffer = wctx->buffer; u8 *bitLength = wctx->bitLength; @@ -1087,20 +1087,22 @@ static void wp512_final(struct crypto_tfm *tfm, u8 *out) wctx->bufferPos = bufferPos; } -static void wp384_final(struct crypto_tfm *tfm, u8 *out) +static void wp384_final(void *ctx, u8 *out) { + struct wp512_ctx *wctx = ctx; u8 D[64]; - wp512_final(tfm, D); + wp512_final (wctx, D); memcpy (out, D, WP384_DIGEST_SIZE); memset (D, 0, WP512_DIGEST_SIZE); } -static void wp256_final(struct crypto_tfm *tfm, u8 *out) +static void wp256_final(void *ctx, u8 *out) { + struct wp512_ctx *wctx = ctx; u8 D[64]; - wp512_final(tfm, D); + wp512_final (wctx, D); memcpy (out, D, WP256_DIGEST_SIZE); memset (D, 0, WP512_DIGEST_SIZE); } diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index fc2d744a4e4a..3c5170310bd0 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -74,5 +74,4 @@ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ obj-$(CONFIG_SUPERH) += sh/ -obj-$(CONFIG_GENERIC_TIME) += clocksource/ obj-$(CONFIG_DMA_ENGINE) += dma/ diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 610d2cc02cf8..c24652d31bf9 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -10,8 +10,9 @@ menu "ACPI (Advanced Configuration and Power Interface) Support" config ACPI bool "ACPI Support" depends on IA64 || X86 - depends on PCI select PM + select PCI + default y ---help--- Advanced Configuration and Power Interface (ACPI) support for @@ -161,7 +162,7 @@ config ACPI_THERMAL config ACPI_NUMA bool "NUMA support" depends on NUMA - depends on (X86 || IA64) + depends on (IA64 || X86_64) default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_ASUS @@ -328,7 +329,7 @@ config ACPI_CONTAINER config ACPI_HOTPLUG_MEMORY tristate "Memory Hotplug" depends on ACPI - depends on MEMORY_HOTPLUG + depends on MEMORY_HOTPLUG || X86_64 default n help This driver adds supports for ACPI Memory Hotplug. This driver diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 1012284ff4f7..d882bf87fa96 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -57,7 +57,6 @@ MODULE_LICENSE("GPL"); static int acpi_memory_device_add(struct acpi_device *device); static int acpi_memory_device_remove(struct acpi_device *device, int type); -static int acpi_memory_device_start(struct acpi_device *device); static struct acpi_driver acpi_memory_device_driver = { .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, @@ -66,79 +65,49 @@ static struct acpi_driver acpi_memory_device_driver = { .ops = { .add = acpi_memory_device_add, .remove = acpi_memory_device_remove, - .start = acpi_memory_device_start, }, }; -struct acpi_memory_info { - struct list_head list; - u64 start_addr; /* Memory Range start physical addr */ - u64 length; /* Memory Range length */ - unsigned short caching; /* memory cache attribute */ - unsigned short write_protect; /* memory read/write attribute */ - unsigned int enabled:1; -}; - struct acpi_memory_device { acpi_handle handle; unsigned int state; /* State of the memory device */ - struct list_head res_list; + unsigned short caching; /* memory cache attribute */ + unsigned short write_protect; /* memory read/write attribute */ + u64 start_addr; /* Memory Range start physical addr */ + u64 end_addr; /* Memory Range end physical addr */ }; -static acpi_status -acpi_memory_get_resource(struct acpi_resource *resource, void *context) -{ - struct acpi_memory_device *mem_device = context; - struct acpi_resource_address64 address64; - struct acpi_memory_info *info, *new; - acpi_status status; - - status = acpi_resource_to_address64(resource, &address64); - if (ACPI_FAILURE(status) || - (address64.resource_type != ACPI_MEMORY_RANGE)) - return AE_OK; - - list_for_each_entry(info, &mem_device->res_list, list) { - /* Can we combine the resource range information? */ - if ((info->caching == address64.info.mem.caching) && - (info->write_protect == address64.info.mem.write_protect) && - (info->start_addr + info->length == address64.minimum)) { - info->length += address64.address_length; - return AE_OK; - } - } - - new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); - if (!new) - return AE_ERROR; - - INIT_LIST_HEAD(&new->list); - new->caching = address64.info.mem.caching; - new->write_protect = address64.info.mem.write_protect; - new->start_addr = address64.minimum; - new->length = address64.address_length; - list_add_tail(&new->list, &mem_device->res_list); - - return AE_OK; -} - static int acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) { acpi_status status; - struct acpi_memory_info *info, *n; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_resource *resource = NULL; + struct acpi_resource_address64 address64; ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources"); - status = acpi_walk_resources(mem_device->handle, METHOD_NAME__CRS, - acpi_memory_get_resource, mem_device); - if (ACPI_FAILURE(status)) { - list_for_each_entry_safe(info, n, &mem_device->res_list, list) - kfree(info); - return -EINVAL; + /* Get the range from the _CRS */ + status = acpi_get_current_resources(mem_device->handle, &buffer); + if (ACPI_FAILURE(status)) + return_VALUE(-EINVAL); + + resource = (struct acpi_resource *)buffer.pointer; + status = acpi_resource_to_address64(resource, &address64); + if (ACPI_SUCCESS(status)) { + if (address64.resource_type == ACPI_MEMORY_RANGE) { + /* Populate the structure */ + mem_device->caching = + address64.info.mem.caching; + mem_device->write_protect = + address64.info.mem.write_protect; + mem_device->start_addr = address64.minimum; + mem_device->end_addr = address64.maximum; + } } - return 0; + acpi_os_free(buffer.pointer); + return_VALUE(0); } static int @@ -213,9 +182,7 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) { - int result, num_enabled = 0; - struct acpi_memory_info *info; - int node; + int result; ACPI_FUNCTION_TRACE("acpi_memory_enable_device"); @@ -228,35 +195,16 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) return result; } - node = acpi_get_node(mem_device->handle); /* * Tell the VM there is more memory here... * Note: Assume that this function returns zero on success - * We don't have memory-hot-add rollback function,now. - * (i.e. memory-hot-remove function) */ - list_for_each_entry(info, &mem_device->res_list, list) { - u64 start_pfn, end_pfn; - - start_pfn = info->start_addr >> PAGE_SHIFT; - end_pfn = (info->start_addr + info->length - 1) >> PAGE_SHIFT; - - if (pfn_valid(start_pfn) || pfn_valid(end_pfn)) { - /* already enabled. try next area */ - num_enabled++; - continue; - } - - result = add_memory(node, info->start_addr, info->length); - if (result) - continue; - info->enabled = 1; - num_enabled++; - } - if (!num_enabled) { + result = add_memory(mem_device->start_addr, + (mem_device->end_addr - mem_device->start_addr) + 1); + if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n")); mem_device->state = MEMORY_INVALID_STATE; - return -EINVAL; + return result; } return result; @@ -300,7 +248,8 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) { int result; - struct acpi_memory_info *info, *n; + u64 start = mem_device->start_addr; + u64 len = mem_device->end_addr - start + 1; ACPI_FUNCTION_TRACE("acpi_memory_disable_device"); @@ -308,13 +257,10 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) * Ask the VM to offline this memory range. * Note: Assume that this function returns zero on success */ - list_for_each_entry_safe(info, n, &mem_device->res_list, list) { - if (info->enabled) { - result = remove_memory(info->start_addr, info->length); - if (result) - return result; - } - kfree(info); + result = remove_memory(start, len); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n")); + return_VALUE(result); } /* Power-off and eject the device */ @@ -412,7 +358,6 @@ static int acpi_memory_device_add(struct acpi_device *device) return_VALUE(-ENOMEM); memset(mem_device, 0, sizeof(struct acpi_memory_device)); - INIT_LIST_HEAD(&mem_device->res_list); mem_device->handle = device->handle; sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); @@ -448,25 +393,6 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) return_VALUE(0); } -static int acpi_memory_device_start (struct acpi_device *device) -{ - struct acpi_memory_device *mem_device; - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_memory_device_start"); - - mem_device = acpi_driver_data(device); - - if (!acpi_memory_check_device(mem_device)) { - /* call add_memory func */ - result = acpi_memory_enable_device(mem_device); - if (result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error in acpi_memory_enable_device\n")); - } - return_VALUE(result); -} - /* * Helper function to check for memory device */ diff --git a/trunk/drivers/acpi/asus_acpi.c b/trunk/drivers/acpi/asus_acpi.c index 839f423d738d..f4c87750dbf2 100644 --- a/trunk/drivers/acpi/asus_acpi.c +++ b/trunk/drivers/acpi/asus_acpi.c @@ -817,7 +817,7 @@ typedef int (proc_writefunc) (struct file * file, const char __user * buffer, unsigned long count, void *data); static int -asus_proc_add(char *name, proc_writefunc * writefunc, +__init asus_proc_add(char *name, proc_writefunc * writefunc, proc_readfunc * readfunc, mode_t mode, struct acpi_device *device) { @@ -836,7 +836,7 @@ asus_proc_add(char *name, proc_writefunc * writefunc, return 0; } -static int asus_hotk_add_fs(struct acpi_device *device) +static int __init asus_hotk_add_fs(struct acpi_device *device) { struct proc_dir_entry *proc; mode_t mode; @@ -954,7 +954,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) * This function is used to initialize the hotk with right values. In this * method, we can make all the detection we want, and modify the hotk struct */ -static int asus_hotk_get_info(void) +static int __init asus_hotk_get_info(void) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -970,7 +970,7 @@ static int asus_hotk_get_info(void) * HID), this bit will be moved. A global variable asus_info contains * the DSDT header. */ - status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); + status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) printk(KERN_WARNING " Couldn't get the DSDT table header\n"); else @@ -1101,7 +1101,7 @@ static int asus_hotk_get_info(void) return AE_OK; } -static int asus_hotk_check(void) +static int __init asus_hotk_check(void) { int result = 0; @@ -1119,9 +1119,7 @@ static int asus_hotk_check(void) return result; } -static int asus_hotk_found; - -static int asus_hotk_add(struct acpi_device *device) +static int __init asus_hotk_add(struct acpi_device *device) { acpi_status status = AE_OK; int result; @@ -1182,8 +1180,6 @@ static int asus_hotk_add(struct acpi_device *device) } } - asus_hotk_found = 1; - end: if (result) { kfree(hotk); @@ -1230,22 +1226,10 @@ static int __init asus_acpi_init(void) asus_proc_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&asus_hotk_driver); - if (result < 0) { - remove_proc_entry(PROC_ASUS, acpi_root_dir); - return -ENODEV; - } - - /* - * This is a bit of a kludge. We only want this module loaded - * for ASUS systems, but there's currently no way to probe the - * ACPI namespace for ASUS HIDs. So we just return failure if - * we didn't find one, which will cause the module to be - * unloaded. - */ - if (!asus_hotk_found) { + if (result < 1) { acpi_bus_unregister_driver(&asus_hotk_driver); remove_proc_entry(PROC_ASUS, acpi_root_dir); - return result; + return -ENODEV; } return 0; diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index dd3983cece92..606f8733a776 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -43,7 +43,7 @@ ACPI_MODULE_NAME("acpi_bus") extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); #endif -struct fadt_descriptor acpi_fadt; +FADT_DESCRIPTOR acpi_fadt; EXPORT_SYMBOL(acpi_fadt); struct acpi_device *acpi_root; @@ -205,14 +205,12 @@ int acpi_bus_set_power(acpi_handle handle, int state) * Get device's current power state if it's unknown * This means device power state isn't initialized or previous setting failed */ - if (!device->flags.force_power_state) { - if (device->power.state == ACPI_STATE_UNKNOWN) - acpi_bus_get_power(device->handle, &device->power.state); - if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", - state)); - return_VALUE(0); - } + if (device->power.state == ACPI_STATE_UNKNOWN) + acpi_bus_get_power(device->handle, &device->power.state); + if (state == device->power.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", + state)); + return_VALUE(0); } if (!device->power.states[state].flags.valid) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", @@ -598,8 +596,6 @@ void __init acpi_early_init(void) if (acpi_disabled) return_VOID; - printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); - /* enable workarounds, unless strict ACPI spec. compliance */ if (!acpi_strict) acpi_gbl_enable_interpreter_slack = TRUE; @@ -621,7 +617,7 @@ void __init acpi_early_init(void) /* * Get a separate copy of the FADT for use by other drivers. */ - status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer); + status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to get the FADT\n"); goto error0; @@ -747,6 +743,8 @@ static int __init acpi_init(void) ACPI_FUNCTION_TRACE("acpi_init"); + printk(KERN_INFO PREFIX "Subsystem revision %08x\n", ACPI_CA_VERSION); + if (acpi_disabled) { printk(KERN_INFO PREFIX "Interpreter disabled.\n"); return_VALUE(-ENODEV); diff --git a/trunk/drivers/acpi/dispatcher/dsfield.c b/trunk/drivers/acpi/dispatcher/dsfield.c index a6d77efb41a0..76bc0463f6de 100644 --- a/trunk/drivers/acpi/dispatcher/dsfield.c +++ b/trunk/drivers/acpi/dispatcher/dsfield.c @@ -87,7 +87,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, union acpi_operand_object *second_desc = NULL; u32 flags; - ACPI_FUNCTION_TRACE(ds_create_buffer_field); + ACPI_FUNCTION_TRACE("ds_create_buffer_field"); /* Get the name_string argument */ @@ -210,7 +210,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, acpi_status status; acpi_integer position; - ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); + ACPI_FUNCTION_TRACE_PTR("ds_get_field_names", info); /* First field starts at bit zero */ @@ -342,7 +342,7 @@ acpi_ds_create_field(union acpi_parse_object *op, union acpi_parse_object *arg; struct acpi_create_field_info info; - ACPI_FUNCTION_TRACE_PTR(ds_create_field, op); + ACPI_FUNCTION_TRACE_PTR("ds_create_field", op); /* First arg is the name of the parent op_region (must already exist) */ @@ -399,7 +399,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, struct acpi_namespace_node *node; u8 type = 0; - ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); + ACPI_FUNCTION_TRACE_PTR("ds_init_field_objects", op); switch (walk_state->opcode) { case AML_FIELD_OP: @@ -425,7 +425,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, * Walk the list of entries in the field_list */ while (arg) { - /* Ignore OFFSET and ACCESSAS terms here */ if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { @@ -482,7 +481,7 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, union acpi_parse_object *arg; struct acpi_create_field_info info; - ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op); + ACPI_FUNCTION_TRACE_PTR("ds_create_bank_field", op); /* First arg is the name of the parent op_region (must already exist) */ @@ -555,7 +554,7 @@ acpi_ds_create_index_field(union acpi_parse_object *op, union acpi_parse_object *arg; struct acpi_create_field_info info; - ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op); + ACPI_FUNCTION_TRACE_PTR("ds_create_index_field", op); /* First arg is the name of the Index register (must already exist) */ diff --git a/trunk/drivers/acpi/dispatcher/dsinit.c b/trunk/drivers/acpi/dispatcher/dsinit.c index bbdf990e9f65..e65a07ad2422 100644 --- a/trunk/drivers/acpi/dispatcher/dsinit.c +++ b/trunk/drivers/acpi/dispatcher/dsinit.c @@ -184,7 +184,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, * * RETURN: Status * - * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any + * DESCRIPTION: Walk the namespace starting at "start_node" and perform any * necessary initialization on the objects found therein * ******************************************************************************/ @@ -196,7 +196,7 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, acpi_status status; struct acpi_init_walk_info info; - ACPI_FUNCTION_TRACE(ds_initialize_objects); + ACPI_FUNCTION_TRACE("ds_initialize_objects"); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); @@ -213,7 +213,7 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, acpi_ds_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, diff --git a/trunk/drivers/acpi/dispatcher/dsmethod.c b/trunk/drivers/acpi/dispatcher/dsmethod.c index bc9aca4e7401..c475546535b6 100644 --- a/trunk/drivers/acpi/dispatcher/dsmethod.c +++ b/trunk/drivers/acpi/dispatcher/dsmethod.c @@ -81,7 +81,6 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) /* Invoke the global exception handler */ if (acpi_gbl_exception_handler) { - /* Exit the interpreter, allow handler to execute methods */ acpi_ex_exit_interpreter(); @@ -101,7 +100,6 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) } #ifdef ACPI_DISASSEMBLER if (ACPI_FAILURE(status)) { - /* Display method locals/args if disassembler is present */ acpi_dm_dump_method_info(status, walk_state, walk_state->op); @@ -134,7 +132,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ds_begin_method_execution, method_node); + ACPI_FUNCTION_TRACE_PTR("ds_begin_method_execution", method_node); if (!method_node) { return_ACPI_STATUS(AE_NULL_ENTRY); @@ -170,14 +168,11 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, /* * Get a unit from the method semaphore. This releases the - * interpreter if we block (then reacquires it) + * interpreter if we block */ status = acpi_ex_system_wait_semaphore(obj_desc->method.semaphore, ACPI_WAIT_FOREVER); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } } /* @@ -188,7 +183,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, if (!obj_desc->method.owner_id) { status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); if (ACPI_FAILURE(status)) { - goto cleanup; + return_ACPI_STATUS(status); } } @@ -198,14 +193,6 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node, */ obj_desc->method.thread_count++; return_ACPI_STATUS(status); - - cleanup: - /* On error, must signal the method semaphore if present */ - - if (obj_desc->method.semaphore) { - (void)acpi_os_signal_semaphore(obj_desc->method.semaphore, 1); - } - return_ACPI_STATUS(status); } /******************************************************************************* @@ -231,10 +218,10 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, struct acpi_namespace_node *method_node; struct acpi_walk_state *next_walk_state = NULL; union acpi_operand_object *obj_desc; - struct acpi_evaluate_info *info; + struct acpi_parameter_info info; u32 i; - ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_call_control_method", this_walk_state); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n", @@ -253,31 +240,25 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, return_ACPI_STATUS(AE_NULL_OBJECT); } - /* Init for new method, possibly wait on concurrency semaphore */ + /* Init for new method, wait on concurrency semaphore */ status = acpi_ds_begin_method_execution(method_node, obj_desc, this_walk_state->method_node); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto cleanup; } - /* - * 1) Parse the method. All "normal" methods are parsed for each execution. - * Internal methods (_OSI, etc.) do not require parsing. - */ if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { - - /* Create a new walk state for the parse */ + /* 1) Parse: Create a new walk state for the preempting walk */ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, op, obj_desc, NULL); if (!next_walk_state) { - status = AE_NO_MEMORY; - goto cleanup; + return_ACPI_STATUS(AE_NO_MEMORY); } - /* Create and init a parse tree root */ + /* Create and init a Root Node */ op = acpi_ps_create_scope_op(); if (!op) { @@ -290,20 +271,17 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, obj_desc->method.aml_length, NULL, 1); if (ACPI_FAILURE(status)) { - acpi_ps_delete_parse_tree(op); + acpi_ds_delete_walk_state(next_walk_state); goto cleanup; } - /* Begin AML parse (deletes next_walk_state) */ + /* Begin AML parse */ status = acpi_ps_parse_aml(next_walk_state); acpi_ps_delete_parse_tree(op); - if (ACPI_FAILURE(status)) { - goto cleanup; - } } - /* 2) Begin method execution. Create a new walk state */ + /* 2) Execute: Create a new state for the preempting walk */ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, obj_desc, thread); @@ -311,7 +289,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, status = AE_NO_MEMORY; goto cleanup; } - /* * The resolved arguments were put on the previous walk state's operand * stack. Operands on the previous walk state stack always @@ -319,24 +296,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, */ this_walk_state->operands[this_walk_state->num_operands] = NULL; - /* - * Allocate and initialize the evaluation information block - * TBD: this is somewhat inefficient, should change interface to - * ds_init_aml_walk. For now, keeps this struct off the CPU stack - */ - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - info->parameters = &this_walk_state->operands[0]; - info->parameter_type = ACPI_PARAM_ARGS; + info.parameters = &this_walk_state->operands[0]; + info.parameter_type = ACPI_PARAM_ARGS; status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, obj_desc->method.aml_start, - obj_desc->method.aml_length, info, 3); - - ACPI_FREE(info); + obj_desc->method.aml_length, &info, 3); if (ACPI_FAILURE(status)) { goto cleanup; } @@ -358,8 +323,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, "Starting nested execution, newstate=%p\n", next_walk_state)); - /* Invoke an internal method if necessary */ - if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { status = obj_desc->method.implementation(next_walk_state); } @@ -367,14 +330,16 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, return_ACPI_STATUS(status); cleanup: + /* Decrement the thread count on the method parse tree */ - /* On error, we must terminate the method properly */ - - acpi_ds_terminate_control_method(obj_desc, next_walk_state); - if (next_walk_state) { - acpi_ds_delete_walk_state(next_walk_state); + if (next_walk_state && (next_walk_state->method_desc)) { + next_walk_state->method_desc->method.thread_count--; } + /* On error, we must delete the new walk state */ + + acpi_ds_terminate_control_method(next_walk_state); + acpi_ds_delete_walk_state(next_walk_state); return_ACPI_STATUS(status); } @@ -397,33 +362,25 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, union acpi_operand_object *return_desc) { acpi_status status; - int same_as_implicit_return; - ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_restart_control_method", walk_state); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n", + "****Restart [%4.4s] Op %p return_value_from_callee %p\n", (char *)&walk_state->method_node->name, walk_state->method_call_op, return_desc)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n", + " return_from_this_method_used?=%X res_stack %p Walk %p\n", walk_state->return_used, walk_state->results, walk_state)); /* Did the called method return a value? */ if (return_desc) { - - /* Is the implicit return object the same as the return desc? */ - - same_as_implicit_return = - (walk_state->implicit_return_obj == return_desc); - /* Are we actually going to use the return value? */ if (walk_state->return_used) { - /* Save the return value from the previous method */ status = acpi_ds_result_push(return_desc, walk_state); @@ -440,23 +397,18 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, } /* - * The following code is the optional support for the so-called - * "implicit return". Some AML code assumes that the last value of the - * method is "implicitly" returned to the caller, in the absence of an - * explicit return value. - * - * Just save the last result of the method as the return value. - * + * The following code is the + * optional support for a so-called "implicit return". Some AML code + * assumes that the last value of the method is "implicitly" returned + * to the caller. Just save the last result as the return value. * NOTE: this is optional because the ASL language does not actually * support this behavior. */ else if (!acpi_ds_do_implicit_return - (return_desc, walk_state, FALSE) - || same_as_implicit_return) { + (return_desc, walk_state, FALSE)) { /* * Delete the return value if it will not be used by the - * calling method or remove one reference if the explicit return - * is the same as the implicit return value. + * calling method */ acpi_ut_remove_reference(return_desc); } @@ -469,8 +421,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, * * FUNCTION: acpi_ds_terminate_control_method * - * PARAMETERS: method_desc - Method object - * walk_state - State associated with the method + * PARAMETERS: walk_state - State of the method * * RETURN: None * @@ -480,100 +431,95 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, * ******************************************************************************/ -void -acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, - struct acpi_walk_state *walk_state) +void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state) { + union acpi_operand_object *obj_desc; struct acpi_namespace_node *method_node; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); - - /* method_desc is required, walk_state is optional */ + ACPI_FUNCTION_TRACE_PTR("ds_terminate_control_method", walk_state); - if (!method_desc) { + if (!walk_state) { return_VOID; } - if (walk_state) { - - /* Delete all arguments and locals */ + /* The current method object was saved in the walk state */ - acpi_ds_method_data_delete_all(walk_state); + obj_desc = walk_state->method_desc; + if (!obj_desc) { + return_VOID; } + /* Delete all arguments and locals */ + + acpi_ds_method_data_delete_all(walk_state); + /* * Lock the parser while we terminate this method. * If this is the last thread executing the method, * we have additional cleanup to perform */ - status = acpi_ut_acquire_mutex(ACPI_MTX_CONTROL_METHOD); + status = acpi_ut_acquire_mutex(ACPI_MTX_PARSER); if (ACPI_FAILURE(status)) { return_VOID; } /* Signal completion of the execution of this method if necessary */ - if (method_desc->method.semaphore) { + if (walk_state->method_desc->method.semaphore) { status = - acpi_os_signal_semaphore(method_desc->method.semaphore, 1); + acpi_os_signal_semaphore(walk_state->method_desc->method. + semaphore, 1); if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not signal method semaphore")); - /* Ignore error and continue */ - - ACPI_EXCEPTION((AE_INFO, status, - "Could not signal method semaphore")); + /* Ignore error and continue cleanup */ } } - if (walk_state) { - /* - * Delete any objects created by this method during execution. - * The method Node is stored in the walk state - */ - method_node = walk_state->method_node; - - /* Lock namespace for possible update */ - - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE(status)) { - goto exit; - } + /* + * There are no more threads executing this method. Perform + * additional cleanup. + * + * The method Node is stored in the walk state + */ + method_node = walk_state->method_node; - /* - * Delete any namespace entries created immediately underneath - * the method - */ - if (method_node && method_node->child) { - acpi_ns_delete_namespace_subtree(method_node); - } + /* Lock namespace for possible update */ - /* - * Delete any namespace entries created anywhere else within - * the namespace by the execution of this method - */ - acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id); - status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto exit; } - /* Decrement the thread count on the method */ - - if (method_desc->method.thread_count) { - method_desc->method.thread_count--; - } else { - ACPI_ERROR((AE_INFO, "Invalid zero thread count in method")); + /* + * Delete any namespace entries created immediately underneath + * the method + */ + if (method_node->child) { + acpi_ns_delete_namespace_subtree(method_node); } + /* + * Delete any namespace entries created anywhere else within + * the namespace by the execution of this method + */ + acpi_ns_delete_namespace_by_owner(walk_state->method_desc->method. + owner_id); + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + /* Are there any other threads currently executing this method? */ - if (method_desc->method.thread_count) { + if (walk_state->method_desc->method.thread_count) { /* * Additional threads. Do not release the owner_id in this case, * we immediately reuse it for the next thread executing this method */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "*** Completed execution of one thread, %d threads remaining\n", - method_desc->method.thread_count)); + walk_state->method_desc->method. + thread_count)); } else { /* This is the only executing thread for this method */ @@ -587,20 +533,22 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, * This code is here because we must wait until the last thread exits * before creating the synchronization semaphore. */ - if ((method_desc->method.concurrency == 1) && - (!method_desc->method.semaphore)) { + if ((walk_state->method_desc->method.concurrency == 1) && + (!walk_state->method_desc->method.semaphore)) { status = acpi_os_create_semaphore(1, 1, - &method_desc->method. + &walk_state-> + method_desc->method. semaphore); } /* No more threads, we can free the owner_id */ - acpi_ut_release_owner_id(&method_desc->method.owner_id); + acpi_ut_release_owner_id(&walk_state->method_desc->method. + owner_id); } exit: - (void)acpi_ut_release_mutex(ACPI_MTX_CONTROL_METHOD); + (void)acpi_ut_release_mutex(ACPI_MTX_PARSER); return_VOID; } @@ -633,7 +581,7 @@ acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) union acpi_parse_object *op; struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE_PTR(ds_parse_method, node); + ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node); /* Parameter Validation */ @@ -642,7 +590,7 @@ acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) } ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** Parsing [%4.4s] **** NamedObj=%p\n", + "**** Parsing [%4.4s] **** named_obj=%p\n", acpi_ut_get_node_name(node), node)); /* Extract the method object from the method Node */ @@ -721,7 +669,7 @@ acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node) } ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "**** [%4.4s] Parsed **** NamedObj=%p Op=%p\n", + "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", acpi_ut_get_node_name(node), node, op)); /* diff --git a/trunk/drivers/acpi/dispatcher/dsmthdat.c b/trunk/drivers/acpi/dispatcher/dsmthdat.c index 459160ff9058..c025674f938b 100644 --- a/trunk/drivers/acpi/dispatcher/dsmthdat.c +++ b/trunk/drivers/acpi/dispatcher/dsmthdat.c @@ -81,7 +81,7 @@ acpi_ds_method_data_get_type(u16 opcode, * special data types. * * NOTES: walk_state fields are initialized to zero by the - * ACPI_ALLOCATE_ZEROED(). + * ACPI_MEM_CALLOCATE(). * * A pseudo-Namespace Node is assigned to each argument and local * so that ref_of() can return a pointer to the Node. @@ -92,7 +92,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) { u32 i; - ACPI_FUNCTION_TRACE(ds_method_data_init); + ACPI_FUNCTION_TRACE("ds_method_data_init"); /* Init the method arguments */ @@ -100,10 +100,10 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) ACPI_MOVE_32_TO_32(&walk_state->arguments[i].name, NAMEOF_ARG_NTE); walk_state->arguments[i].name.integer |= (i << 24); - walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED; + walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED; walk_state->arguments[i].type = ACPI_TYPE_ANY; - walk_state->arguments[i].flags = - ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; + walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | + ANOBJ_METHOD_ARG; } /* Init the method locals */ @@ -113,11 +113,11 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) NAMEOF_LOCAL_NTE); walk_state->local_variables[i].name.integer |= (i << 24); - walk_state->local_variables[i].descriptor_type = + walk_state->local_variables[i].descriptor = ACPI_DESC_TYPE_NAMED; walk_state->local_variables[i].type = ACPI_TYPE_ANY; - walk_state->local_variables[i].flags = - ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; + walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | + ANOBJ_METHOD_LOCAL; } return_VOID; @@ -140,7 +140,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) { u32 index; - ACPI_FUNCTION_TRACE(ds_method_data_delete_all); + ACPI_FUNCTION_TRACE("ds_method_data_delete_all"); /* Detach the locals */ @@ -199,7 +199,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, acpi_status status; u32 index = 0; - ACPI_FUNCTION_TRACE_PTR(ds_method_data_init_args, params); + ACPI_FUNCTION_TRACE_PTR("ds_method_data_init_args", params); if (!params) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -251,7 +251,7 @@ acpi_ds_method_data_get_node(u16 opcode, struct acpi_walk_state *walk_state, struct acpi_namespace_node **node) { - ACPI_FUNCTION_TRACE(ds_method_data_get_node); + ACPI_FUNCTION_TRACE("ds_method_data_get_node"); /* * Method Locals and Arguments are supported @@ -318,10 +318,10 @@ acpi_ds_method_data_set_value(u16 opcode, acpi_status status; struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(ds_method_data_set_value); + ACPI_FUNCTION_TRACE("ds_method_data_set_value"); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "NewObj %p Opcode %X, Refs=%d [%s]\n", object, + "new_obj %p Opcode %X, Refs=%d [%s]\n", object, opcode, object->common.reference_count, acpi_ut_get_type_name(object->common.type))); @@ -336,7 +336,7 @@ acpi_ds_method_data_set_value(u16 opcode, * Increment ref count so object can't be deleted while installed. * NOTE: We do not copy the object in order to preserve the call by * reference semantics of ACPI Control Method invocation. - * (See ACPI Specification 2.0_c) + * (See ACPI specification 2.0_c) */ acpi_ut_add_reference(object); @@ -351,7 +351,7 @@ acpi_ds_method_data_set_value(u16 opcode, * FUNCTION: acpi_ds_method_data_get_value * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to get + * Index - which local_var or argument to get * walk_state - Current walk state object * dest_desc - Where Arg or Local value is returned * @@ -372,7 +372,7 @@ acpi_ds_method_data_get_value(u16 opcode, struct acpi_namespace_node *node; union acpi_operand_object *object; - ACPI_FUNCTION_TRACE(ds_method_data_get_value); + ACPI_FUNCTION_TRACE("ds_method_data_get_value"); /* Validate the object descriptor */ @@ -459,7 +459,7 @@ acpi_ds_method_data_get_value(u16 opcode, * FUNCTION: acpi_ds_method_data_delete_value * * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP - * Index - Which local_var or argument to delete + * Index - which local_var or argument to delete * walk_state - Current walk state object * * RETURN: None @@ -477,7 +477,7 @@ acpi_ds_method_data_delete_value(u16 opcode, struct acpi_namespace_node *node; union acpi_operand_object *object; - ACPI_FUNCTION_TRACE(ds_method_data_delete_value); + ACPI_FUNCTION_TRACE("ds_method_data_delete_value"); /* Get the namespace node for the arg/local */ @@ -538,7 +538,7 @@ acpi_ds_store_object_to_local(u16 opcode, union acpi_operand_object *current_obj_desc; union acpi_operand_object *new_obj_desc; - ACPI_FUNCTION_TRACE(ds_store_object_to_local); + ACPI_FUNCTION_TRACE("ds_store_object_to_local"); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n", opcode, index, obj_desc)); @@ -614,7 +614,7 @@ acpi_ds_store_object_to_local(u16 opcode, && (current_obj_desc->reference.opcode == AML_REF_OF_OP)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Arg (%p) is an ObjRef(Node), storing in node %p\n", + "Arg (%p) is an obj_ref(Node), storing in node %p\n", new_obj_desc, current_obj_desc)); @@ -688,7 +688,7 @@ acpi_ds_method_data_get_type(u16 opcode, struct acpi_namespace_node *node; union acpi_operand_object *object; - ACPI_FUNCTION_TRACE(ds_method_data_get_type); + ACPI_FUNCTION_TRACE("ds_method_data_get_type"); /* Get the namespace node for the arg/local */ @@ -701,7 +701,6 @@ acpi_ds_method_data_get_type(u16 opcode, object = acpi_ns_get_attached_object(node); if (!object) { - /* Uninitialized local/arg, return TYPE_ANY */ return_VALUE(ACPI_TYPE_ANY); diff --git a/trunk/drivers/acpi/dispatcher/dsobject.c b/trunk/drivers/acpi/dispatcher/dsobject.c index 72190abb1d59..8b21f0f9e517 100644 --- a/trunk/drivers/acpi/dispatcher/dsobject.c +++ b/trunk/drivers/acpi/dispatcher/dsobject.c @@ -81,7 +81,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(ds_build_internal_object); + ACPI_FUNCTION_TRACE("ds_build_internal_object"); *obj_desc_ptr = NULL; if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { @@ -103,7 +103,6 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, common. node))); if (ACPI_FAILURE(status)) { - /* Check if we are resolving a named reference within a package */ if ((status == AE_NOT_FOUND) @@ -187,7 +186,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, union acpi_parse_object *byte_list; u32 byte_list_length = 0; - ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj); + ACPI_FUNCTION_TRACE("ds_build_internal_buffer_obj"); /* * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". @@ -196,7 +195,6 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, */ obj_desc = *obj_desc_ptr; if (!obj_desc) { - /* Create a new buffer object */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); @@ -245,7 +243,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, "Buffer defined with zero length in AML, creating\n")); } else { obj_desc->buffer.pointer = - ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length); + ACPI_MEM_CALLOCATE(obj_desc->buffer.length); if (!obj_desc->buffer.pointer) { acpi_ut_delete_object_desc(obj_desc); return_ACPI_STATUS(AE_NO_MEMORY); @@ -293,7 +291,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, acpi_status status = AE_OK; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); + ACPI_FUNCTION_TRACE("ds_build_internal_package_obj"); /* Find the parent of a possibly nested package */ @@ -341,10 +339,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, * individual objects). Add an extra pointer slot so * that the list is always null terminated. */ - obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) - obj_desc->package. - count + - 1) * sizeof(void *)); + obj_desc->package.elements = ACPI_MEM_CALLOCATE(((acpi_size) obj_desc-> + package.count + + 1) * sizeof(void *)); if (!obj_desc->package.elements) { acpi_ut_delete_object_desc(obj_desc); @@ -358,7 +355,6 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, arg = arg->common.next; for (i = 0; arg; i++) { if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { - /* Object (package or buffer) is already built */ obj_desc->package.elements[i] = @@ -400,7 +396,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state, acpi_status status; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE_PTR(ds_create_node, op); + ACPI_FUNCTION_TRACE_PTR("ds_create_node", op); /* * Because of the execution pass through the non-control-method @@ -412,7 +408,6 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state, } if (!op->common.value.arg) { - /* No arguments, there is nothing to do */ return_ACPI_STATUS(AE_OK); @@ -469,12 +464,11 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, union acpi_operand_object *obj_desc; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ds_init_object_from_op); + ACPI_FUNCTION_TRACE("ds_init_object_from_op"); obj_desc = *ret_obj_desc; op_info = acpi_ps_get_opcode_info(opcode); if (op_info->class == AML_CLASS_UNKNOWN) { - /* Unknown opcode */ return_ACPI_STATUS(AE_TYPE); @@ -632,7 +626,6 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, default: /* Other literals, etc.. */ if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { - /* Node was saved in Op */ obj_desc->reference.node = op->common.node; diff --git a/trunk/drivers/acpi/dispatcher/dsopcode.c b/trunk/drivers/acpi/dispatcher/dsopcode.c index 5b974a8fe614..6229c10674e1 100644 --- a/trunk/drivers/acpi/dispatcher/dsopcode.c +++ b/trunk/drivers/acpi/dispatcher/dsopcode.c @@ -91,7 +91,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, union acpi_parse_object *op; struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE(ds_execute_arguments); + ACPI_FUNCTION_TRACE("ds_execute_arguments"); /* * Allocate a new parser op to be the root of the parsed tree @@ -193,7 +193,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ds_get_buffer_field_arguments", obj_desc); if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { return_ACPI_STATUS(AE_OK); @@ -206,7 +206,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n", acpi_ut_get_node_name(node))); /* Execute the AML code for the term_arg arguments */ @@ -235,7 +235,7 @@ acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ds_get_buffer_arguments", obj_desc); if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { return_ACPI_STATUS(AE_OK); @@ -279,7 +279,7 @@ acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ds_get_package_arguments", obj_desc); if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { return_ACPI_STATUS(AE_OK); @@ -324,7 +324,7 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) acpi_status status; union acpi_operand_object *extra_desc; - ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ds_get_region_arguments", obj_desc); if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { return_ACPI_STATUS(AE_OK); @@ -342,7 +342,8 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "[%4.4s] op_region Arg Init at AML %p\n", acpi_ut_get_node_name(node), extra_desc->extra.aml_start)); @@ -351,28 +352,6 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), extra_desc->extra.aml_length, extra_desc->extra.aml_start); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Validate the region address/length via the host OS */ - - status = acpi_os_validate_address(obj_desc->region.space_id, - obj_desc->region.address, - (acpi_size) obj_desc->region.length); - if (ACPI_FAILURE(status)) { - /* - * Invalid address/length. We will emit an error message and mark - * the region as invalid, so that it will cause an additional error if - * it is ever used. Then return AE_OK. - */ - ACPI_EXCEPTION((AE_INFO, status, - "During address validation of OpRegion [%4.4s]", - node->name.ascii)); - obj_desc->common.flags |= AOPOBJ_INVALID; - status = AE_OK; - } - return_ACPI_STATUS(status); } @@ -432,7 +411,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, u8 field_flags; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ds_init_buffer_field", obj_desc); /* Host object must be a Buffer */ @@ -478,7 +457,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, if (bit_count == 0) { ACPI_ERROR((AE_INFO, - "Attempt to CreateField of length zero")); + "Attempt to create_field of length zero")); status = AE_AML_OPERAND_VALUE; goto cleanup; } @@ -616,7 +595,7 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, struct acpi_namespace_node *node; union acpi_parse_object *next_op; - ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op); + ACPI_FUNCTION_TRACE_PTR("ds_eval_buffer_field_operands", op); /* * This is where we evaluate the address and length fields of the @@ -648,7 +627,7 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, acpi_ps_get_opcode_name(op->common.aml_opcode), walk_state->num_operands, - "after AcpiExResolveOperands"); + "after acpi_ex_resolve_operands"); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", @@ -661,7 +640,6 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, /* Initialize the Buffer Field */ if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { - /* NOTE: Slightly different operands for this opcode */ status = @@ -707,7 +685,7 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, struct acpi_namespace_node *node; union acpi_parse_object *next_op; - ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); + ACPI_FUNCTION_TRACE_PTR("ds_eval_region_operands", op); /* * This is where we evaluate the address and length fields of the @@ -740,7 +718,7 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, acpi_ps_get_opcode_name(op->common.aml_opcode), - 1, "after AcpiExResolveOperands"); + 1, "after acpi_ex_resolve_operands"); obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { @@ -766,7 +744,7 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, operand_desc->integer.value; acpi_ut_remove_reference(operand_desc); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n", obj_desc, ACPI_FORMAT_UINT64(obj_desc->region.address), obj_desc->region.length)); @@ -802,7 +780,7 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, union acpi_operand_object *arg_desc; u32 length; - ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); + ACPI_FUNCTION_TRACE("ds_eval_data_object_operands"); /* The first operand (for all of these data objects) is the length */ @@ -896,7 +874,7 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, acpi_status status = AE_OK; union acpi_generic_state *control_state; - ACPI_FUNCTION_NAME(ds_exec_begin_control_op); + ACPI_FUNCTION_NAME("ds_exec_begin_control_op"); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, op->common.aml_opcode, walk_state)); @@ -974,7 +952,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, acpi_status status = AE_OK; union acpi_generic_state *control_state; - ACPI_FUNCTION_NAME(ds_exec_end_control_op); + ACPI_FUNCTION_NAME("ds_exec_end_control_op"); switch (op->common.aml_opcode) { case AML_IF_OP: @@ -1006,7 +984,6 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); if (walk_state->control_state->common.value) { - /* Predicate was true, go back and evaluate it again! */ status = AE_CTRL_PENDING; @@ -1037,7 +1014,6 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, * has been bubbled up the tree */ if (op->common.value.arg) { - /* Since we have a real Return(), delete any implicit return */ acpi_ds_clear_implicit_return(walk_state); @@ -1071,7 +1047,6 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, walk_state->return_desc = walk_state->operands[0]; } else if ((walk_state->results) && (walk_state->results->results.num_results > 0)) { - /* Since we have a real Return(), delete any implicit return */ acpi_ds_clear_implicit_return(walk_state); @@ -1120,7 +1095,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, } ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Completed RETURN_OP State=%p, RetVal=%p\n", + "Completed RETURN_OP State=%p, ret_val=%p\n", walk_state, walk_state->return_desc)); /* End the control method execution right now */ diff --git a/trunk/drivers/acpi/dispatcher/dsutils.c b/trunk/drivers/acpi/dispatcher/dsutils.c index 05230baf5de8..53356a591ac1 100644 --- a/trunk/drivers/acpi/dispatcher/dsutils.c +++ b/trunk/drivers/acpi/dispatcher/dsutils.c @@ -68,7 +68,7 @@ ACPI_MODULE_NAME("dsutils") ******************************************************************************/ void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state) { - ACPI_FUNCTION_NAME(ds_clear_implicit_return); + ACPI_FUNCTION_NAME("ds_clear_implicit_return"); /* * Slack must be enabled for this feature @@ -115,7 +115,7 @@ u8 acpi_ds_do_implicit_return(union acpi_operand_object *return_desc, struct acpi_walk_state *walk_state, u8 add_reference) { - ACPI_FUNCTION_NAME(ds_do_implicit_return); + ACPI_FUNCTION_NAME("ds_do_implicit_return"); /* * Slack must be enabled for this feature, and we must @@ -171,7 +171,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, { const struct acpi_opcode_info *parent_info; - ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op); + ACPI_FUNCTION_TRACE_PTR("ds_is_result_used", op); /* Must have both an Op and a Result Object */ @@ -202,7 +202,6 @@ acpi_ds_is_result_used(union acpi_parse_object * op, */ if ((!op->common.parent) || (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) { - /* No parent, the return value cannot possibly be used */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, @@ -341,7 +340,7 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj); + ACPI_FUNCTION_TRACE_PTR("ds_delete_result_if_not_used", result_obj); if (!op) { ACPI_ERROR((AE_INFO, "Null Op")); @@ -353,7 +352,6 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op, } if (!acpi_ds_is_result_used(op, walk_state)) { - /* Must pop the result stack (obj_desc should be equal to result_obj) */ status = acpi_ds_result_pop(&obj_desc, walk_state); @@ -384,7 +382,7 @@ acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state) u32 i; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_resolve_operands", walk_state); /* * Attempt to resolve each of the valid operands @@ -419,7 +417,7 @@ void acpi_ds_clear_operands(struct acpi_walk_state *walk_state) { u32 i; - ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_clear_operands", walk_state); /* Remove a reference on each operand on the stack */ @@ -467,7 +465,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, acpi_interpreter_mode interpreter_mode; const struct acpi_opcode_info *op_info; - ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg); + ACPI_FUNCTION_TRACE_PTR("ds_create_operand", arg); /* A valid name must be looked up in the namespace */ @@ -500,9 +498,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, */ if ((walk_state->deferred_node) && (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) - && (arg_index == - (u32) ((walk_state->opcode == - AML_CREATE_FIELD_OP) ? 3 : 2))) { + && (arg_index != 0)) { obj_desc = ACPI_CAST_PTR(union acpi_operand_object, walk_state->deferred_node); @@ -525,7 +521,6 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, && (parent_op->common.aml_opcode != AML_REGION_OP) && (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) { - /* Enter name into namespace if not found */ interpreter_mode = ACPI_IMODE_LOAD_PASS2; @@ -577,7 +572,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, /* Free the namestring created above */ - ACPI_FREE(name_string); + ACPI_MEM_FREE(name_string); /* Check status from the lookup */ @@ -701,7 +696,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, union acpi_parse_object *arg; u32 arg_count = 0; - ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); + ACPI_FUNCTION_TRACE_PTR("ds_create_operands", first_arg); /* For all arguments in the list... */ diff --git a/trunk/drivers/acpi/dispatcher/dswexec.c b/trunk/drivers/acpi/dispatcher/dswexec.c index 3acbd9145d72..f1af655ff113 100644 --- a/trunk/drivers/acpi/dispatcher/dswexec.c +++ b/trunk/drivers/acpi/dispatcher/dswexec.c @@ -49,6 +49,7 @@ #include #include #include +#include #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswexec") @@ -92,7 +93,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, union acpi_operand_object *obj_desc; union acpi_operand_object *local_obj_desc = NULL; - ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_get_predicate_value", walk_state); walk_state->control_state->common.state = 0; @@ -122,7 +123,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, if (!obj_desc) { ACPI_ERROR((AE_INFO, - "No predicate ObjDesc=%p State=%p", + "No predicate obj_desc=%p State=%p", obj_desc, walk_state)); return_ACPI_STATUS(AE_AML_NO_OPERAND); @@ -139,7 +140,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, - "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X", + "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X", obj_desc, walk_state, ACPI_GET_OBJECT_TYPE(obj_desc))); @@ -213,7 +214,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, acpi_status status = AE_OK; u32 opcode_class; - ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_exec_begin_op", walk_state); op = walk_state->op; if (!op) { @@ -295,7 +296,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, case AML_CLASS_NAMED_OBJECT: - if (walk_state->walk_type & ACPI_WALK_METHOD) { + if (walk_state->walk_type == ACPI_WALK_METHOD) { /* * Found a named object declaration during method execution; * we must enter this object into the namespace. The created @@ -353,7 +354,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) union acpi_parse_object *next_op; union acpi_parse_object *first_arg; - ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_exec_end_op", walk_state); op = walk_state->op; op_type = walk_state->op_info->type; @@ -408,7 +409,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) * being the object_type and size_of operators. */ if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) { - /* Resolve all operands */ status = acpi_ex_resolve_operands(walk_state->opcode, @@ -423,7 +423,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) acpi_ps_get_opcode_name (walk_state->opcode), walk_state->num_operands, - "after ExResolveOperands"); + "after ex_resolve_operands"); } } @@ -437,7 +437,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) acpi_gbl_op_type_dispatch[op_type] (walk_state); } else { /* - * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the + * Treat constructs of the form "Store(local_x,local_x)" as noops when the * Local is uninitialized. */ if ((status == AE_AML_UNINITIALIZED_LOCAL) && @@ -548,7 +548,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) */ status = acpi_ds_resolve_operands(walk_state); if (ACPI_FAILURE(status)) { - /* On error, clear all resolved operands */ acpi_ds_clear_operands(walk_state); @@ -570,7 +569,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) case AML_TYPE_CREATE_FIELD: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing CreateField Buffer/Index Op=%p\n", + "Executing create_field Buffer/Index Op=%p\n", op)); status = acpi_ds_load2_end_op(walk_state); @@ -585,7 +584,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) case AML_TYPE_CREATE_OBJECT: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing CreateObject (Buffer/Package) Op=%p\n", + "Executing create_object (Buffer/Package) Op=%p\n", op)); switch (op->common.parent->common.aml_opcode) { @@ -658,7 +657,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) if (op->common.aml_opcode == AML_REGION_OP) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Executing OpRegion Address/Length Op=%p\n", + "Executing op_region Address/Length Op=%p\n", op)); status = @@ -723,7 +722,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) cleanup: if (walk_state->result_obj) { - /* Break to debugger to display result */ ACPI_DEBUGGER_EXEC(acpi_db_display_result_object diff --git a/trunk/drivers/acpi/dispatcher/dswload.c b/trunk/drivers/acpi/dispatcher/dswload.c index 35074399c617..d3d24da31c81 100644 --- a/trunk/drivers/acpi/dispatcher/dswload.c +++ b/trunk/drivers/acpi/dispatcher/dswload.c @@ -127,7 +127,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, char *path; u32 flags; - ACPI_FUNCTION_TRACE(ds_load1_begin_op); + ACPI_FUNCTION_TRACE("ds_load1_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, @@ -178,12 +178,12 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, * Target of Scope() not found. Generate an External for it, and * insert the name into the namespace. */ - acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0); + acpi_dm_add_to_external_list(path); status = acpi_ns_lookup(walk_state->scope_info, path, object_type, ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, - &node); + &(node)); } #endif if (ACPI_FAILURE(status)) { @@ -261,7 +261,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, */ if (walk_state->deferred_node) { - /* This name is already in the namespace, get the node */ node = walk_state->deferred_node; @@ -301,41 +300,10 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, status = acpi_ns_lookup(walk_state->scope_info, path, object_type, ACPI_IMODE_LOAD_PASS1, flags, walk_state, - &node); + &(node)); if (ACPI_FAILURE(status)) { - if (status == AE_ALREADY_EXISTS) { - - /* The name already exists in this scope */ - - if (node->flags & ANOBJ_IS_EXTERNAL) { - /* - * Allow one create on an object or segment that was - * previously declared External - */ - node->flags &= ~ANOBJ_IS_EXTERNAL; - node->type = (u8) object_type; - - /* Just retyped a node, probably will need to open a scope */ - - if (acpi_ns_opens_scope(object_type)) { - status = - acpi_ds_scope_stack_push - (node, object_type, - walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS - (status); - } - } - status = AE_OK; - } - } - - if (ACPI_FAILURE(status)) { - - ACPI_ERROR_NAMESPACE(path, status); - return_ACPI_STATUS(status); - } + ACPI_ERROR_NAMESPACE(path, status); + return_ACPI_STATUS(status); } break; } @@ -343,7 +311,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, /* Common exit */ if (!op) { - /* Create a new op */ op = acpi_ps_alloc_op(walk_state->opcode); @@ -392,7 +359,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) acpi_object_type object_type; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ds_load1_end_op); + ACPI_FUNCTION_TRACE("ds_load1_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, @@ -446,7 +413,6 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) #endif if (op->common.aml_opcode == AML_NAME_OP) { - /* For Name opcode, get the object type from the argument */ if (op->common.value.arg) { @@ -479,7 +445,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) * arguments.) */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "LOADING-Method: State=%p Op=%p NamedObj=%p\n", + "LOADING-Method: State=%p Op=%p named_obj=%p\n", walk_state, op, op->named.node)); if (!acpi_ns_get_attached_object(op->named.node)) { @@ -545,7 +511,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, acpi_object_type object_type; char *buffer_ptr; - ACPI_FUNCTION_TRACE(ds_load2_begin_op); + ACPI_FUNCTION_TRACE("ds_load2_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, @@ -555,7 +521,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, if ((walk_state->control_state) && (walk_state->control_state->common.state == ACPI_CONTROL_CONDITIONAL_EXECUTING)) { - /* We are executing a while loop outside of a method */ status = acpi_ds_exec_begin_op(walk_state, out_op); @@ -589,12 +554,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, /* Get the name we are going to enter or lookup in the namespace */ if (walk_state->opcode == AML_INT_NAMEPATH_OP) { - /* For Namepath op, get the path string */ buffer_ptr = op->common.value.string; if (!buffer_ptr) { - /* No name, just exit */ return_ACPI_STATUS(AE_OK); @@ -717,7 +680,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, /* All other opcodes */ if (op && op->common.node) { - /* This op/node was previously entered into the namespace */ node = op->common.node; @@ -743,7 +705,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, * Note: Name may already exist if we are executing a deferred opcode. */ if (walk_state->deferred_node) { - /* This name is already in the namespace, get the node */ node = walk_state->deferred_node; @@ -766,7 +727,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, } if (!op) { - /* Create a new op */ op = acpi_ps_alloc_op(walk_state->opcode); @@ -816,7 +776,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) u32 i; #endif - ACPI_FUNCTION_TRACE(ds_load2_end_op); + ACPI_FUNCTION_TRACE("ds_load2_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", @@ -910,7 +870,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Create-Load [%s] State=%p Op=%p NamedObj=%p\n", + "Create-Load [%s] State=%p Op=%p named_obj=%p\n", acpi_ps_get_opcode_name(op->common.aml_opcode), walk_state, op, node)); @@ -1085,7 +1045,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) * arguments.) */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "LOADING-Method: State=%p Op=%p NamedObj=%p\n", + "LOADING-Method: State=%p Op=%p named_obj=%p\n", walk_state, op, op->named.node)); if (!acpi_ns_get_attached_object(op->named.node)) { @@ -1130,7 +1090,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) case AML_CLASS_METHOD_CALL: ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n", + "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n", walk_state, op, node)); /* @@ -1144,6 +1104,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) ACPI_NS_DONT_OPEN_SCOPE, walk_state, &(new_node)); if (ACPI_SUCCESS(status)) { + /* * Make sure that what we found is indeed a method * We didn't search for a method on purpose, to see if the name diff --git a/trunk/drivers/acpi/dispatcher/dswscope.c b/trunk/drivers/acpi/dispatcher/dswscope.c index c9228972f5f6..ada21ef4a174 100644 --- a/trunk/drivers/acpi/dispatcher/dswscope.c +++ b/trunk/drivers/acpi/dispatcher/dswscope.c @@ -63,10 +63,9 @@ void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state) { union acpi_generic_state *scope_info; - ACPI_FUNCTION_NAME(ds_scope_stack_clear); + ACPI_FUNCTION_NAME("ds_scope_stack_clear"); while (walk_state->scope_info) { - /* Pop a scope off the stack */ scope_info = walk_state->scope_info; @@ -103,10 +102,9 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, union acpi_generic_state *scope_info; union acpi_generic_state *old_scope_info; - ACPI_FUNCTION_TRACE(ds_scope_stack_push); + ACPI_FUNCTION_TRACE("ds_scope_stack_push"); if (!node) { - /* Invalid scope */ ACPI_ERROR((AE_INFO, "Null scope parameter")); @@ -128,7 +126,7 @@ acpi_ds_scope_stack_push(struct acpi_namespace_node *node, /* Init new scope object */ - scope_info->common.descriptor_type = ACPI_DESC_TYPE_STATE_WSCOPE; + scope_info->common.data_type = ACPI_DESC_TYPE_STATE_WSCOPE; scope_info->scope.node = node; scope_info->common.value = (u16) type; @@ -178,7 +176,7 @@ acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state) union acpi_generic_state *scope_info; union acpi_generic_state *new_scope_info; - ACPI_FUNCTION_TRACE(ds_scope_stack_pop); + ACPI_FUNCTION_TRACE("ds_scope_stack_pop"); /* * Pop scope info object off the stack. diff --git a/trunk/drivers/acpi/dispatcher/dswstate.c b/trunk/drivers/acpi/dispatcher/dswstate.c index 7817e5522679..fa78cb74ee36 100644 --- a/trunk/drivers/acpi/dispatcher/dswstate.c +++ b/trunk/drivers/acpi/dispatcher/dswstate.c @@ -66,6 +66,7 @@ void *acpi_ds_obj_stack_get_value(u32 index, #endif #ifdef ACPI_FUTURE_USAGE + /******************************************************************************* * * FUNCTION: acpi_ds_result_remove @@ -87,7 +88,7 @@ acpi_ds_result_remove(union acpi_operand_object **object, { union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_remove); + ACPI_FUNCTION_NAME("ds_result_remove"); state = walk_state->results; if (!state) { @@ -127,6 +128,7 @@ acpi_ds_result_remove(union acpi_operand_object **object, return (AE_OK); } + #endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* @@ -150,7 +152,7 @@ acpi_ds_result_pop(union acpi_operand_object ** object, acpi_native_uint index; union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_pop); + ACPI_FUNCTION_NAME("ds_result_pop"); state = walk_state->results; if (!state) { @@ -168,7 +170,6 @@ acpi_ds_result_pop(union acpi_operand_object ** object, state->results.num_results--; for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { - /* Check for a valid result object */ if (state->results.obj_desc[index - 1]) { @@ -212,7 +213,7 @@ acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, acpi_native_uint index; union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_pop_from_bottom); + ACPI_FUNCTION_NAME("ds_result_pop_from_bottom"); state = walk_state->results; if (!state) { @@ -277,7 +278,7 @@ acpi_ds_result_push(union acpi_operand_object * object, { union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_push); + ACPI_FUNCTION_NAME("ds_result_push"); state = walk_state->results; if (!state) { @@ -330,14 +331,14 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) { union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_stack_push); + ACPI_FUNCTION_NAME("ds_result_stack_push"); state = acpi_ut_create_generic_state(); if (!state) { return (AE_NO_MEMORY); } - state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; + state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT; acpi_ut_push_generic_state(&walk_state->results, state); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", @@ -362,7 +363,7 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) { union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_stack_pop); + ACPI_FUNCTION_NAME("ds_result_stack_pop"); /* Check for stack underflow */ @@ -375,7 +376,7 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) state = acpi_ut_pop_generic_state(&walk_state->results); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Result=%p RemainingResults=%X State=%p\n", + "Result=%p remaining_results=%X State=%p\n", state, state->results.num_results, walk_state)); acpi_ut_delete_generic_state(state); @@ -399,7 +400,7 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) acpi_status acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) { - ACPI_FUNCTION_NAME(ds_obj_stack_push); + ACPI_FUNCTION_NAME("ds_obj_stack_push"); /* Check for stack overflow */ @@ -444,10 +445,9 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) { u32 i; - ACPI_FUNCTION_NAME(ds_obj_stack_pop); + ACPI_FUNCTION_NAME("ds_obj_stack_pop"); for (i = 0; i < pop_count; i++) { - /* Check for stack underflow */ if (walk_state->num_operands == 0) { @@ -491,10 +491,9 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, u32 i; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); + ACPI_FUNCTION_NAME("ds_obj_stack_pop_and_delete"); for (i = 0; i < pop_count; i++) { - /* Check for stack underflow */ if (walk_state->num_operands == 0) { @@ -539,13 +538,13 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state *thread) { - ACPI_FUNCTION_NAME(ds_get_current_walk_state); + ACPI_FUNCTION_NAME("ds_get_current_walk_state"); if (!thread) { return (NULL); } - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n", + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current walk_state %p\n", thread->walk_state_list)); return (thread->walk_state_list); @@ -568,7 +567,7 @@ void acpi_ds_push_walk_state(struct acpi_walk_state *walk_state, struct acpi_thread_state *thread) { - ACPI_FUNCTION_TRACE(ds_push_walk_state); + ACPI_FUNCTION_TRACE("ds_push_walk_state"); walk_state->next = thread->walk_state_list; thread->walk_state_list = walk_state; @@ -594,12 +593,11 @@ struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread) { struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE(ds_pop_walk_state); + ACPI_FUNCTION_TRACE("ds_pop_walk_state"); walk_state = thread->walk_state_list; if (walk_state) { - /* Next walk state becomes the current walk state */ thread->walk_state_list = walk_state->next; @@ -620,7 +618,7 @@ struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread) * * PARAMETERS: owner_id - ID for object creation * Origin - Starting point for this walk - * method_desc - Method object + * mth_desc - Method object * Thread - Current thread state * * RETURN: Pointer to the new walk state. @@ -634,24 +632,24 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object *origin, union acpi_operand_object - *method_desc, + *mth_desc, struct acpi_thread_state *thread) { struct acpi_walk_state *walk_state; acpi_status status; - ACPI_FUNCTION_TRACE(ds_create_walk_state); + ACPI_FUNCTION_TRACE("ds_create_walk_state"); - walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state)); + walk_state = ACPI_MEM_CALLOCATE(sizeof(struct acpi_walk_state)); if (!walk_state) { return_PTR(NULL); } - walk_state->descriptor_type = ACPI_DESC_TYPE_WALK; - walk_state->method_desc = method_desc; + walk_state->data_type = ACPI_DESC_TYPE_WALK; walk_state->owner_id = owner_id; walk_state->origin = origin; + walk_state->method_desc = mth_desc; walk_state->thread = thread; walk_state->parser_state.start_op = origin; @@ -666,7 +664,7 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, status = acpi_ds_result_stack_push(walk_state); if (ACPI_FAILURE(status)) { - ACPI_FREE(walk_state); + ACPI_MEM_FREE(walk_state); return_PTR(NULL); } @@ -703,13 +701,13 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, struct acpi_namespace_node *method_node, u8 * aml_start, u32 aml_length, - struct acpi_evaluate_info *info, u8 pass_number) + struct acpi_parameter_info *info, u8 pass_number) { acpi_status status; struct acpi_parse_state *parser_state = &walk_state->parser_state; union acpi_parse_object *extra_op; - ACPI_FUNCTION_TRACE(ds_init_aml_walk); + ACPI_FUNCTION_TRACE("ds_init_aml_walk"); walk_state->parser_state.aml = walk_state->parser_state.aml_start = aml_start; @@ -780,7 +778,6 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, } if (parser_state->start_node) { - /* Push start scope on scope stack and make it current */ status = @@ -813,24 +810,21 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_delete_walk_state", walk_state); if (!walk_state) { return; } - if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) { + if (walk_state->data_type != ACPI_DESC_TYPE_WALK) { ACPI_ERROR((AE_INFO, "%p is not a valid walk state", walk_state)); return; } - /* There should not be any open scopes */ - if (walk_state->parser_state.scope) { ACPI_ERROR((AE_INFO, "%p walk still has a scope list", walk_state)); - acpi_ps_cleanup_scope(&walk_state->parser_state); } /* Always must free any linked control states */ @@ -860,7 +854,7 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) acpi_ut_delete_generic_state(state); } - ACPI_FREE(walk_state); + ACPI_MEM_FREE(walk_state); return_VOID; } @@ -885,7 +879,7 @@ acpi_ds_result_insert(void *object, { union acpi_generic_state *state; - ACPI_FUNCTION_NAME(ds_result_insert); + ACPI_FUNCTION_NAME("ds_result_insert"); state = walk_state->results; if (!state) { @@ -943,7 +937,7 @@ acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state) { u32 i; - ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_obj_stack_delete_all", walk_state); /* The stack size is configurable, but fixed */ @@ -975,7 +969,7 @@ acpi_status acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, struct acpi_walk_state *walk_state) { - ACPI_FUNCTION_NAME(ds_obj_stack_pop_object); + ACPI_FUNCTION_NAME("ds_obj_stack_pop_object"); /* Check for stack underflow */ @@ -1031,7 +1025,7 @@ acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state) { - ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state); + ACPI_FUNCTION_TRACE_PTR("ds_obj_stack_get_value", walk_state); /* Can't do it if the stack is empty */ diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 18b3ea9dace2..eee0864ba300 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -116,7 +116,7 @@ union acpi_ec { struct acpi_generic_address command_addr; struct acpi_generic_address data_addr; unsigned long global_lock; - struct semaphore sem; + spinlock_t lock; } poll; }; @@ -323,6 +323,7 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) { acpi_status status = AE_OK; int result = 0; + unsigned long flags = 0; u32 glk = 0; ACPI_FUNCTION_TRACE("acpi_ec_read"); @@ -338,11 +339,8 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) return_VALUE(-ENODEV); } - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; - } - + spin_lock_irqsave(&ec->poll.lock, flags); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); @@ -360,8 +358,8 @@ static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) *data, address)); end: - up(&ec->poll.sem); -end_nosem: + spin_unlock_irqrestore(&ec->poll.lock, flags); + if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -372,6 +370,7 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) { int result = 0; acpi_status status = AE_OK; + unsigned long flags = 0; u32 glk = 0; ACPI_FUNCTION_TRACE("acpi_ec_write"); @@ -385,11 +384,8 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) return_VALUE(-ENODEV); } - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; - } - + spin_lock_irqsave(&ec->poll.lock, flags); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); @@ -410,8 +406,8 @@ static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) data, address)); end: - up(&ec->poll.sem); -end_nosem: + spin_unlock_irqrestore(&ec->poll.lock, flags); + if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -572,6 +568,7 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) { int result = 0; acpi_status status = AE_OK; + unsigned long flags = 0; u32 glk = 0; ACPI_FUNCTION_TRACE("acpi_ec_query"); @@ -592,11 +589,8 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) * Note that successful completion of the query causes the ACPI_EC_SCI * bit to be cleared (and thus clearing the interrupt source). */ - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; - } - + spin_lock_irqsave(&ec->poll.lock, flags); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); @@ -608,8 +602,8 @@ static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) result = -ENODATA; end: - up(&ec->poll.sem); -end_nosem: + spin_unlock_irqrestore(&ec->poll.lock, flags); + if (ec->common.global_lock) acpi_release_global_lock(glk); @@ -686,6 +680,7 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value = 0; + unsigned long flags = 0; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' @@ -696,11 +691,9 @@ static void acpi_ec_gpe_poll_query(void *ec_cxt) if (!ec_cxt) goto end; - if (down_interruptible (&ec->poll.sem)) { - return_VOID; - } + spin_lock_irqsave(&ec->poll.lock, flags); acpi_hw_low_level_read(8, &value, &ec->common.command_addr); - up(&ec->poll.sem); + spin_unlock_irqrestore(&ec->poll.lock, flags); /* TBD: Implement asynch events! * NOTE: All we care about are EC-SCI's. Other EC events are @@ -770,7 +763,8 @@ static u32 acpi_ec_gpe_poll_handler(void *data) acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); - status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec); + status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, + acpi_ec_gpe_query, ec); if (status == AE_OK) return ACPI_INTERRUPT_HANDLED; @@ -805,7 +799,7 @@ static u32 acpi_ec_gpe_intr_handler(void *data) if (value & ACPI_EC_FLAG_SCI) { atomic_add(1, &ec->intr.pending_gpe); - status = acpi_os_execute(OSL_EC_BURST_HANDLER, + status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, acpi_ec_gpe_query, ec); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; @@ -997,6 +991,7 @@ static int acpi_ec_poll_add(struct acpi_device *device) int result = 0; acpi_status status = AE_OK; union acpi_ec *ec = NULL; + unsigned long uid; ACPI_FUNCTION_TRACE("acpi_ec_add"); @@ -1010,7 +1005,7 @@ static int acpi_ec_poll_add(struct acpi_device *device) ec->common.handle = device->handle; ec->common.uid = -1; - init_MUTEX(&ec->poll.sem); + spin_lock_init(&ec->poll.lock); strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); acpi_driver_data(device) = ec; @@ -1019,9 +1014,10 @@ static int acpi_ec_poll_add(struct acpi_device *device) acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); - /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: - http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ - if (ec_ecdt) { + /* If our UID matches the UID for the ECDT-enumerated EC, + we now have the *real* EC info, so kill the makeshift one. */ + acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); + if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); @@ -1066,6 +1062,7 @@ static int acpi_ec_intr_add(struct acpi_device *device) int result = 0; acpi_status status = AE_OK; union acpi_ec *ec = NULL; + unsigned long uid; ACPI_FUNCTION_TRACE("acpi_ec_add"); @@ -1091,9 +1088,10 @@ static int acpi_ec_intr_add(struct acpi_device *device) acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); - /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: - http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ - if (ec_ecdt) { + /* If our UID matches the UID for the ECDT-enumerated EC, + we now have the *real* EC info, so kill the makeshift one. */ + acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); + if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); @@ -1302,7 +1300,7 @@ acpi_fake_ecdt_poll_callback(acpi_handle handle, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; - init_MUTEX(&ec_ecdt->poll.sem); + spin_lock_init(&ec_ecdt->poll.lock); ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.handle = handle; @@ -1418,7 +1416,7 @@ static int __init acpi_ec_poll_get_real_ecdt(void) ec_ecdt->common.status_addr = ecdt_ptr->ec_control; ec_ecdt->common.data_addr = ecdt_ptr->ec_data; ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; - init_MUTEX(&ec_ecdt->poll.sem); + spin_lock_init(&ec_ecdt->poll.lock); /* use the GL just to be safe */ ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; diff --git a/trunk/drivers/acpi/events/evevent.c b/trunk/drivers/acpi/events/evevent.c index 919037d6acff..c9ac05c4685f 100644 --- a/trunk/drivers/acpi/events/evevent.c +++ b/trunk/drivers/acpi/events/evevent.c @@ -68,7 +68,7 @@ acpi_status acpi_ev_initialize_events(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_initialize_events); + ACPI_FUNCTION_TRACE("ev_initialize_events"); /* Make sure we have ACPI tables */ @@ -118,7 +118,7 @@ acpi_status acpi_ev_install_fadt_gpes(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); + ACPI_FUNCTION_TRACE("ev_install_fadt_gpes"); /* Namespace must be locked */ @@ -157,7 +157,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers); + ACPI_FUNCTION_TRACE("ev_install_xrupt_handlers"); /* Install the SCI handler */ @@ -241,7 +241,7 @@ u32 acpi_ev_fixed_event_detect(void) u32 fixed_enable; acpi_native_uint i; - ACPI_FUNCTION_NAME(ev_fixed_event_detect); + ACPI_FUNCTION_NAME("ev_fixed_event_detect"); /* * Read the fixed feature status and enable registers, as all the cases @@ -260,14 +260,12 @@ u32 acpi_ev_fixed_event_detect(void) * Check for all possible Fixed Events and dispatch those that are active */ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { - /* Both the status and enable bits must be on for this event */ if ((fixed_status & acpi_gbl_fixed_event_info[i]. status_bit_mask) && (fixed_enable & acpi_gbl_fixed_event_info[i]. enable_bit_mask)) { - /* Found an active (signalled) event */ int_status |= acpi_ev_fixed_event_dispatch((u32) i); diff --git a/trunk/drivers/acpi/events/evgpe.c b/trunk/drivers/acpi/events/evgpe.c index f01d339407f8..f64f977dd3d5 100644 --- a/trunk/drivers/acpi/events/evgpe.c +++ b/trunk/drivers/acpi/events/evgpe.c @@ -69,7 +69,7 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_set_gpe_type); + ACPI_FUNCTION_TRACE("ev_set_gpe_type"); /* Validate type and update register enable masks */ @@ -115,7 +115,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, struct acpi_gpe_register_info *gpe_register_info; u8 register_bit; - ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); + ACPI_FUNCTION_TRACE("ev_update_gpe_enable_masks"); gpe_register_info = gpe_event_info->register_info; if (!gpe_register_info) { @@ -178,7 +178,7 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, { acpi_status status; - ACPI_FUNCTION_TRACE(ev_enable_gpe); + ACPI_FUNCTION_TRACE("ev_enable_gpe"); /* Make sure HW enable masks are updated */ @@ -207,7 +207,6 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); if (write_to_hardware) { - /* Clear the GPE (of stale events), then enable it */ status = acpi_hw_clear_gpe(gpe_event_info); @@ -244,7 +243,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_disable_gpe); + ACPI_FUNCTION_TRACE("ev_disable_gpe"); if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) { return_ACPI_STATUS(AE_OK); @@ -314,7 +313,6 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, /* A NULL gpe_block means use the FADT-defined GPE block(s) */ if (!gpe_device) { - /* Examine GPE Block 0 and 1 (These blocks are permanent) */ for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) { @@ -382,11 +380,10 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) u32 status_reg; u32 enable_reg; acpi_cpu_flags flags; - acpi_cpu_flags hw_flags; acpi_native_uint i; acpi_native_uint j; - ACPI_FUNCTION_NAME(ev_gpe_detect); + ACPI_FUNCTION_NAME("ev_gpe_detect"); /* Check for the case where there are no GPEs */ @@ -394,12 +391,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) return (int_status); } - /* We need to hold the GPE lock now, hardware lock in the loop */ - - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - /* Examine all GPE blocks attached to this interrupt level */ + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); gpe_block = gpe_xrupt_list->gpe_block_list_head; while (gpe_block) { /* @@ -408,13 +402,10 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) * Find all currently active GP events. */ for (i = 0; i < gpe_block->register_count; i++) { - /* Get the next status/enable pair */ gpe_register_info = &gpe_block->register_info[i]; - hw_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); - /* Read the Status Register */ status = @@ -423,8 +414,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) &gpe_register_info-> status_address); if (ACPI_FAILURE(status)) { - acpi_os_release_lock(acpi_gbl_hardware_lock, - hw_flags); goto unlock_and_exit; } @@ -435,8 +424,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) &enable_reg, &gpe_register_info-> enable_address); - acpi_os_release_lock(acpi_gbl_hardware_lock, hw_flags); - if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -450,7 +437,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) enabled_status_byte = (u8) (status_reg & enable_reg); if (!enabled_status_byte) { - /* No active GPEs in this register, move on */ continue; @@ -459,7 +445,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { - /* Examine one GPE bit */ if (enabled_status_byte & @@ -498,9 +483,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) * * RETURN: None * - * DESCRIPTION: Perform the actual execution of a GPE control method. This - * function is called from an invocation of acpi_os_execute and - * therefore does NOT execute at interrupt level - so that + * DESCRIPTION: Perform the actual execution of a GPE control method. This + * function is called from an invocation of acpi_os_queue_for_execution + * (and therefore does NOT execute at interrupt level) so that * the control method itself is not executed in the context of * an interrupt handler. * @@ -509,11 +494,12 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) { struct acpi_gpe_event_info *gpe_event_info = (void *)context; + u32 gpe_number = 0; acpi_status status; struct acpi_gpe_event_info local_gpe_event_info; - struct acpi_evaluate_info *info; + struct acpi_parameter_info info; - ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); + ACPI_FUNCTION_TRACE("ev_asynch_execute_gpe_method"); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { @@ -549,35 +535,22 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) */ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) { + /* + * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx + * control method that corresponds to this GPE + */ + info.node = local_gpe_event_info.dispatch.method_node; + info.parameters = + ACPI_CAST_PTR(union acpi_operand_object *, gpe_event_info); + info.parameter_type = ACPI_PARAM_GPE; - /* Allocate the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - status = AE_NO_MEMORY; - } else { - /* - * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx - * control method that corresponds to this GPE - */ - info->prefix_node = - local_gpe_event_info.dispatch.method_node; - info->parameters = - ACPI_CAST_PTR(union acpi_operand_object *, - gpe_event_info); - info->parameter_type = ACPI_PARAM_GPE; - info->flags = ACPI_IGNORE_RETURN_VALUE; - - status = acpi_ns_evaluate(info); - ACPI_FREE(info); - } - + status = acpi_ns_evaluate_by_handle(&info); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "While evaluating GPE method [%4.4s]", + "While evaluating method [%4.4s] for GPE[%2X]", acpi_ut_get_node_name (local_gpe_event_info.dispatch. - method_node))); + method_node), gpe_number)); } } @@ -620,7 +593,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_gpe_dispatch); + ACPI_FUNCTION_TRACE("ev_gpe_dispatch"); /* * If edge-triggered, clear the GPE status bit now. Note that @@ -696,9 +669,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * Execute the method associated with the GPE * NOTE: Level-triggered GPEs are cleared after the method completes. */ - status = acpi_os_execute(OSL_GPE_HANDLER, - acpi_ev_asynch_execute_gpe_method, - gpe_event_info); + status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, + acpi_ev_asynch_execute_gpe_method, + gpe_event_info); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to queue handler for GPE[%2X] - event disabled", @@ -743,7 +716,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * * DESCRIPTION: Determine if a a GPE is "wake-only". * - * Called from Notify() code in interpreter when a "DeviceWake" + * Called from Notify() code in interpreter when a "device_wake" * Notify comes in. * ******************************************************************************/ @@ -753,7 +726,7 @@ acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe); + ACPI_FUNCTION_TRACE("ev_check_for_wake_only_gpe"); if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */ diff --git a/trunk/drivers/acpi/events/evgpeblk.c b/trunk/drivers/acpi/events/evgpeblk.c index 95ddeb48bc0f..0fd00b5ad650 100644 --- a/trunk/drivers/acpi/events/evgpeblk.c +++ b/trunk/drivers/acpi/events/evgpeblk.c @@ -131,14 +131,14 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) * ******************************************************************************/ -acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) +acpi_status acpi_ev_walk_gpe_list(ACPI_GPE_CALLBACK gpe_walk_callback) { struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; acpi_status status = AE_OK; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(ev_walk_gpe_list); + ACPI_FUNCTION_TRACE("ev_walk_gpe_list"); flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); @@ -146,12 +146,10 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; while (gpe_xrupt_info) { - /* Walk all Gpe Blocks attached to this interrupt level */ gpe_block = gpe_xrupt_info->gpe_block_list_head; while (gpe_block) { - /* One callback per GPE block */ status = gpe_walk_callback(gpe_xrupt_info, gpe_block); @@ -192,12 +190,11 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_native_uint i; acpi_native_uint j; - ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers); + ACPI_FUNCTION_TRACE("ev_delete_gpe_handlers"); /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { @@ -207,7 +204,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { - ACPI_FREE(gpe_event_info->dispatch.handler); + ACPI_MEM_FREE(gpe_event_info->dispatch.handler); gpe_event_info->dispatch.handler = NULL; gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; @@ -251,7 +248,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle, u8 type; acpi_status status; - ACPI_FUNCTION_TRACE(ev_save_method_info); + ACPI_FUNCTION_TRACE("ev_save_method_info"); /* * _Lxx and _Exx GPE method support @@ -282,9 +279,9 @@ acpi_ev_save_method_info(acpi_handle obj_handle, default: /* Unknown method type, just ignore it! */ - ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)", - name)); + ACPI_ERROR((AE_INFO, + "Unknown GPE method type: %s (name not of form _Lxx or _Exx)", + name)); return_ACPI_STATUS(AE_OK); } @@ -292,12 +289,11 @@ acpi_ev_save_method_info(acpi_handle obj_handle, gpe_number = ACPI_STRTOUL(&name[2], NULL, 16); if (gpe_number == ACPI_UINT32_MAX) { - /* Conversion failed; invalid method, just ignore it */ - ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)", - name)); + ACPI_ERROR((AE_INFO, + "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)", + name)); return_ACPI_STATUS(AE_OK); } @@ -368,14 +364,13 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, u32 gpe_number; acpi_status status; - ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe); + ACPI_FUNCTION_TRACE("ev_match_prw_and_gpe"); /* Check for a _PRW method under this device */ status = acpi_ut_evaluate_object(obj_handle, METHOD_NAME__PRW, ACPI_BTYPE_PACKAGE, &pkg_desc); if (ACPI_FAILURE(status)) { - /* Ignore all errors from _PRW, we don't want to abort the subsystem */ return_ACPI_STATUS(AE_OK); @@ -399,7 +394,6 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, obj_desc = pkg_desc->package.elements[0]; if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - /* Use FADT-defined GPE device (from definition of _PRW) */ target_gpe_device = acpi_gbl_fadt_gpe_device; @@ -408,7 +402,6 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, gpe_number = (u32) obj_desc->integer.value; } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { - /* Package contains a GPE reference and GPE number within a GPE block */ if ((obj_desc->package.count < 2) || @@ -489,7 +482,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(ev_get_gpe_xrupt_block); + ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block"); /* No need for lock since we are not changing any list elements here */ @@ -504,7 +497,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 /* Not found, must allocate a new xrupt descriptor */ - gpe_xrupt = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_xrupt_info)); + gpe_xrupt = ACPI_MEM_CALLOCATE(sizeof(struct acpi_gpe_xrupt_info)); if (!gpe_xrupt) { return_PTR(NULL); } @@ -563,7 +556,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(ev_delete_gpe_xrupt); + ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt"); /* We never want to remove the SCI interrupt handler */ @@ -595,7 +588,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) /* Free the block */ - ACPI_FREE(gpe_xrupt); + ACPI_MEM_FREE(gpe_xrupt); return_ACPI_STATUS(AE_OK); } @@ -621,7 +614,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(ev_install_gpe_block); + ACPI_FUNCTION_TRACE("ev_install_gpe_block"); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { @@ -674,7 +667,7 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(ev_install_gpe_block); + ACPI_FUNCTION_TRACE("ev_install_gpe_block"); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { @@ -686,7 +679,6 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block); if (!gpe_block->previous && !gpe_block->next) { - /* This is the last gpe_block on this interrupt */ status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block); @@ -712,9 +704,9 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) /* Free the gpe_block */ - ACPI_FREE(gpe_block->register_info); - ACPI_FREE(gpe_block->event_info); - ACPI_FREE(gpe_block); + ACPI_MEM_FREE(gpe_block->register_info); + ACPI_MEM_FREE(gpe_block->event_info); + ACPI_MEM_FREE(gpe_block); unlock_and_exit: status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); @@ -744,17 +736,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) acpi_native_uint j; acpi_status status; - ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks); + ACPI_FUNCTION_TRACE("ev_create_gpe_info_blocks"); /* Allocate the GPE register information block */ - gpe_register_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block-> - register_count * - sizeof(struct - acpi_gpe_register_info)); + gpe_register_info = ACPI_MEM_CALLOCATE((acpi_size) gpe_block-> + register_count * + sizeof(struct + acpi_gpe_register_info)); if (!gpe_register_info) { ACPI_ERROR((AE_INFO, - "Could not allocate the GpeRegisterInfo table")); + "Could not allocate the gpe_register_info table")); return_ACPI_STATUS(AE_NO_MEMORY); } @@ -762,14 +754,13 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) * Allocate the GPE event_info block. There are eight distinct GPEs * per register. Initialization to zeros is sufficient. */ - gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block-> - register_count * - ACPI_GPE_REGISTER_WIDTH) * - sizeof(struct - acpi_gpe_event_info)); + gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block-> + register_count * + ACPI_GPE_REGISTER_WIDTH) * + sizeof(struct acpi_gpe_event_info)); if (!gpe_event_info) { ACPI_ERROR((AE_INFO, - "Could not allocate the GpeEventInfo table")); + "Could not allocate the gpe_event_info table")); status = AE_NO_MEMORY; goto error_exit; } @@ -789,7 +780,6 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) this_event = gpe_event_info; for (i = 0; i < gpe_block->register_count; i++) { - /* Init the register_info for this GPE register (8 GPEs) */ this_register->base_gpe_number = @@ -849,10 +839,10 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) error_exit: if (gpe_register_info) { - ACPI_FREE(gpe_register_info); + ACPI_MEM_FREE(gpe_register_info); } if (gpe_event_info) { - ACPI_FREE(gpe_event_info); + ACPI_MEM_FREE(gpe_event_info); } return_ACPI_STATUS(status); @@ -888,7 +878,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, acpi_status status; struct acpi_gpe_block_info *gpe_block; - ACPI_FUNCTION_TRACE(ev_create_gpe_block); + ACPI_FUNCTION_TRACE("ev_create_gpe_block"); if (!register_count) { return_ACPI_STATUS(AE_OK); @@ -896,7 +886,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, /* Allocate a new GPE block */ - gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info)); + gpe_block = ACPI_MEM_CALLOCATE(sizeof(struct acpi_gpe_block_info)); if (!gpe_block) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -916,7 +906,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, */ status = acpi_ev_create_gpe_info_blocks(gpe_block); if (ACPI_FAILURE(status)) { - ACPI_FREE(gpe_block); + ACPI_MEM_FREE(gpe_block); return_ACPI_STATUS(status); } @@ -924,7 +914,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, status = acpi_ev_install_gpe_block(gpe_block, interrupt_number); if (ACPI_FAILURE(status)) { - ACPI_FREE(gpe_block); + ACPI_MEM_FREE(gpe_block); return_ACPI_STATUS(status); } @@ -981,7 +971,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, acpi_native_uint i; acpi_native_uint j; - ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); + ACPI_FUNCTION_TRACE("ev_initialize_gpe_block"); /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ @@ -1023,7 +1013,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, for (i = 0; i < gpe_block->register_count; i++) { for (j = 0; j < 8; j++) { - /* Get the info block for this particular GPE */ gpe_event_info = @@ -1051,7 +1040,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p", + ACPI_ERROR((AE_INFO, "Could not enable GPEs in gpe_block %p", gpe_block)); } @@ -1077,7 +1066,7 @@ acpi_status acpi_ev_gpe_initialize(void) u32 gpe_number_max = 0; acpi_status status; - ACPI_FUNCTION_TRACE(ev_gpe_initialize); + ACPI_FUNCTION_TRACE("ev_gpe_initialize"); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -1110,7 +1099,6 @@ acpi_status acpi_ev_gpe_initialize(void) * particular block is not supported. */ if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { - /* GPE block 0 exists (has both length and address > 0) */ register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); @@ -1133,7 +1121,6 @@ acpi_status acpi_ev_gpe_initialize(void) } if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { - /* GPE block 1 exists (has both length and address > 0) */ register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); @@ -1181,7 +1168,6 @@ acpi_status acpi_ev_gpe_initialize(void) /* Exit if there are no GPE registers */ if ((register_count0 + register_count1) == 0) { - /* GPEs are not required by ACPI, this is OK */ ACPI_DEBUG_PRINT((ACPI_DB_INIT, diff --git a/trunk/drivers/acpi/events/evmisc.c b/trunk/drivers/acpi/events/evmisc.c index 6eef4efddcf6..0909ba69577e 100644 --- a/trunk/drivers/acpi/events/evmisc.c +++ b/trunk/drivers/acpi/events/evmisc.c @@ -49,13 +49,12 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evmisc") -/* Names for Notify() values, used for debug output */ #ifdef ACPI_DEBUG_OUTPUT static const char *acpi_notify_value_names[] = { "Bus Check", "Device Check", "Device Wake", - "Eject Request", + "Eject request", "Device Check Light", "Frequency Mismatch", "Bus Mode Mismatch", @@ -125,7 +124,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, union acpi_generic_state *notify_info; acpi_status status = AE_OK; - ACPI_FUNCTION_NAME(ev_queue_notify_request); + ACPI_FUNCTION_NAME("ev_queue_notify_request"); /* * For value 3 (Ejection Request), some device method may need to be run. @@ -151,7 +150,6 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { - /* We have the notify object, Get the right handler */ switch (node->type) { @@ -186,15 +184,14 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, return (AE_NO_MEMORY); } - notify_info->common.descriptor_type = - ACPI_DESC_TYPE_STATE_NOTIFY; + notify_info->common.data_type = ACPI_DESC_TYPE_STATE_NOTIFY; notify_info->notify.node = node; notify_info->notify.value = (u16) notify_value; notify_info->notify.handler_obj = handler_obj; - status = - acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, - notify_info); + status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH, + acpi_ev_notify_dispatch, + notify_info); if (ACPI_FAILURE(status)) { acpi_ut_delete_generic_state(notify_info); } @@ -243,7 +240,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) * to the device. */ if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) { - /* Global system notification handler */ if (acpi_gbl_system_notify.handler) { @@ -301,7 +297,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context) /* Signal threads that are waiting for the lock */ if (acpi_gbl_global_lock_thread_count) { - /* Send sufficient units to the semaphore */ status = @@ -340,16 +335,15 @@ static u32 acpi_ev_global_lock_handler(void *context) */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { - /* Got the lock, now wake all threads waiting for it */ acpi_gbl_global_lock_acquired = TRUE; /* Run the Global Lock thread which will signal all waiting threads */ - status = - acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, - acpi_ev_global_lock_thread, context); + status = acpi_os_queue_for_execution(OSD_PRIORITY_HIGH, + acpi_ev_global_lock_thread, + context); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not queue Global Lock thread")); @@ -377,7 +371,7 @@ acpi_status acpi_ev_init_global_lock_handler(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); + ACPI_FUNCTION_TRACE("ev_init_global_lock_handler"); acpi_gbl_global_lock_present = TRUE; status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, @@ -419,7 +413,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) acpi_status status = AE_OK; u8 acquired = FALSE; - ACPI_FUNCTION_TRACE(ev_acquire_global_lock); + ACPI_FUNCTION_TRACE("ev_acquire_global_lock"); #ifndef ACPI_APPLICATION /* Make sure that we actually have a global lock */ @@ -445,7 +439,6 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { - /* We got the lock */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -465,9 +458,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) * Acquire the global lock semaphore first. * Since this wait will block, we must release the interpreter */ - status = - acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, - timeout); + status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, + timeout); return_ACPI_STATUS(status); } @@ -488,7 +480,7 @@ acpi_status acpi_ev_release_global_lock(void) u8 pending = FALSE; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ev_release_global_lock); + ACPI_FUNCTION_TRACE("ev_release_global_lock"); if (!acpi_gbl_global_lock_thread_count) { ACPI_WARNING((AE_INFO, @@ -500,7 +492,6 @@ acpi_status acpi_ev_release_global_lock(void) acpi_gbl_global_lock_thread_count--; if (acpi_gbl_global_lock_thread_count) { - /* There are still some threads holding the lock, cannot release */ return_ACPI_STATUS(AE_OK); @@ -542,7 +533,7 @@ void acpi_ev_terminate(void) acpi_native_uint i; acpi_status status; - ACPI_FUNCTION_TRACE(ev_terminate); + ACPI_FUNCTION_TRACE("ev_terminate"); if (acpi_gbl_events_initialized) { /* @@ -582,7 +573,7 @@ void acpi_ev_terminate(void) if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) { status = acpi_disable(); if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "AcpiDisable failed")); + ACPI_WARNING((AE_INFO, "acpi_disable failed")); } } return_VOID; diff --git a/trunk/drivers/acpi/events/evregion.c b/trunk/drivers/acpi/events/evregion.c index 094a17e4c86d..6da58e776413 100644 --- a/trunk/drivers/acpi/events/evregion.c +++ b/trunk/drivers/acpi/events/evregion.c @@ -83,7 +83,7 @@ acpi_status acpi_ev_install_region_handlers(void) acpi_status status; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ev_install_region_handlers); + ACPI_FUNCTION_TRACE("ev_install_region_handlers"); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -153,7 +153,7 @@ acpi_status acpi_ev_initialize_op_regions(void) acpi_status status; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ev_initialize_op_regions); + ACPI_FUNCTION_TRACE("ev_initialize_op_regions"); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -164,7 +164,6 @@ acpi_status acpi_ev_initialize_op_regions(void) * Run the _REG methods for op_regions in each default address space */ for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { - /* TBD: Make sure handler is the DEFAULT handler, otherwise * _REG will have already been run. */ @@ -193,12 +192,12 @@ acpi_status acpi_ev_initialize_op_regions(void) acpi_status acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) { - struct acpi_evaluate_info *info; - union acpi_operand_object *args[3]; + struct acpi_parameter_info info; + union acpi_operand_object *params[3]; union acpi_operand_object *region_obj2; acpi_status status; - ACPI_FUNCTION_TRACE(ev_execute_reg_method); + ACPI_FUNCTION_TRACE("ev_execute_reg_method"); region_obj2 = acpi_ns_get_secondary_object(region_obj); if (!region_obj2) { @@ -209,60 +208,48 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) return_ACPI_STATUS(AE_OK); } - /* Allocate and initialize the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - info->prefix_node = region_obj2->extra.method_REG; - info->pathname = NULL; - info->parameters = args; - info->parameter_type = ACPI_PARAM_ARGS; - info->flags = ACPI_IGNORE_RETURN_VALUE; - /* * The _REG method has two arguments: * - * Arg0 - Integer: - * Operation region space ID Same value as region_obj->Region.space_id - * - * Arg1 - Integer: - * connection status 1 for connecting the handler, 0 for disconnecting - * the handler (Passed as a parameter) + * Arg0, Integer: Operation region space ID + * Same value as region_obj->Region.space_id + * Arg1, Integer: connection status + * 1 for connecting the handler, + * 0 for disconnecting the handler + * Passed as a parameter */ - args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); - if (!args[0]) { - status = AE_NO_MEMORY; - goto cleanup1; + params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); + if (!params[0]) { + return_ACPI_STATUS(AE_NO_MEMORY); } - args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); - if (!args[1]) { + params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); + if (!params[1]) { status = AE_NO_MEMORY; - goto cleanup2; + goto cleanup; } /* Setup the parameter objects */ - args[0]->integer.value = region_obj->region.space_id; - args[1]->integer.value = function; - args[2] = NULL; + params[0]->integer.value = region_obj->region.space_id; + params[1]->integer.value = function; + params[2] = NULL; + + info.node = region_obj2->extra.method_REG; + info.parameters = params; + info.parameter_type = ACPI_PARAM_ARGS; /* Execute the method, no return value */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_METHOD, info->prefix_node, NULL)); + (ACPI_TYPE_METHOD, info.node, NULL)); + status = acpi_ns_evaluate_by_handle(&info); - status = acpi_ns_evaluate(info); - acpi_ut_remove_reference(args[1]); + acpi_ut_remove_reference(params[1]); - cleanup2: - acpi_ut_remove_reference(args[0]); + cleanup: + acpi_ut_remove_reference(params[0]); - cleanup1: - ACPI_FREE(info); return_ACPI_STATUS(status); } @@ -274,8 +261,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) * Function - Read or Write operation * Address - Where in the space to read or write * bit_width - Field width in bits (8, 16, 32, or 64) - * Value - Pointer to in or out value, must be - * full 64-bit acpi_integer + * Value - Pointer to in or out value * * RETURN: Status * @@ -288,7 +274,7 @@ acpi_status acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 function, acpi_physical_address address, - u32 bit_width, acpi_integer * value) + u32 bit_width, void *value) { acpi_status status; acpi_status status2; @@ -298,7 +284,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, union acpi_operand_object *region_obj2; void *region_context = NULL; - ACPI_FUNCTION_TRACE(ev_address_space_dispatch); + ACPI_FUNCTION_TRACE("ev_address_space_dispatch"); region_obj2 = acpi_ns_get_secondary_object(region_obj); if (!region_obj2) { @@ -329,7 +315,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, */ region_setup = handler_desc->address_space.setup; if (!region_setup) { - /* No initialization routine, exit with error */ ACPI_ERROR((AE_INFO, @@ -376,10 +361,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; if (region_obj2->extra.region_context) { - /* The handler for this region was already installed */ - ACPI_FREE(region_context); + ACPI_MEM_FREE(region_context); } else { /* * Save the returned context for use in all accesses to @@ -402,8 +386,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, acpi_ut_get_region_name(region_obj->region. space_id))); - if (!(handler_desc->address_space.handler_flags & - ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (! + (handler_desc->address_space. + hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't @@ -424,8 +409,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, space_id))); } - if (!(handler_desc->address_space.handler_flags & - ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (! + (handler_desc->address_space. + hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter @@ -465,7 +451,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, union acpi_operand_object *region_obj2; acpi_status status; - ACPI_FUNCTION_TRACE(ev_detach_region); + ACPI_FUNCTION_TRACE("ev_detach_region"); region_obj2 = acpi_ns_get_secondary_object(region_obj); if (!region_obj2) { @@ -477,7 +463,6 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, handler_obj = region_obj->region.handler; if (!handler_obj) { - /* This region has no handler, all done */ return_VOID; @@ -489,7 +474,6 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, last_obj_ptr = &handler_obj->address_space.region_list; while (obj_desc) { - /* Is this the correct Region? */ if (obj_desc == region_obj) { @@ -599,7 +583,7 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj, u8 acpi_ns_is_locked) { - ACPI_FUNCTION_TRACE(ev_attach_region); + ACPI_FUNCTION_TRACE("ev_attach_region"); ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Adding Region [%4.4s] %p to address handler %p [%s]\n", @@ -652,7 +636,7 @@ acpi_ev_install_handler(acpi_handle obj_handle, struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_NAME(ev_install_handler); + ACPI_FUNCTION_NAME("ev_install_handler"); handler_obj = (union acpi_operand_object *)context; @@ -682,7 +666,6 @@ acpi_ev_install_handler(acpi_handle obj_handle, obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { - /* No object, just exit */ return (AE_OK); @@ -691,12 +674,10 @@ acpi_ev_install_handler(acpi_handle obj_handle, /* Devices are handled different than regions */ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) { - /* Check if this Device already has a handler for this address space */ next_handler_obj = obj_desc->device.handler; while (next_handler_obj) { - /* Found a handler, is it for the same address space? */ if (next_handler_obj->address_space.space_id == @@ -783,9 +764,9 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, union acpi_operand_object *handler_obj; acpi_status status; acpi_object_type type; - u8 flags = 0; + u16 flags = 0; - ACPI_FUNCTION_TRACE(ev_install_space_handler); + ACPI_FUNCTION_TRACE("ev_install_space_handler"); /* * This registration is valid for only the types below @@ -858,7 +839,6 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, /* Walk the handler list for this device */ while (handler_obj) { - /* Same space_id indicates a handler already installed */ if (handler_obj->address_space.space_id == space_id) { @@ -941,7 +921,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, /* Init handler obj */ handler_obj->address_space.space_id = (u8) space_id; - handler_obj->address_space.handler_flags = flags; + handler_obj->address_space.hflags = flags; handler_obj->address_space.region_list = NULL; handler_obj->address_space.node = node; handler_obj->address_space.handler = handler; @@ -999,7 +979,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, { acpi_status status; - ACPI_FUNCTION_TRACE(ev_execute_reg_methods); + ACPI_FUNCTION_TRACE("ev_execute_reg_methods"); /* * Run all _REG methods for all Operation Regions for this @@ -1021,7 +1001,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, * * PARAMETERS: walk_namespace callback * - * DESCRIPTION: Run _REG method for region objects of the requested space_iD + * DESCRIPTION: Run _REg method for region objects of the requested space_iD * ******************************************************************************/ @@ -1055,7 +1035,6 @@ acpi_ev_reg_run(acpi_handle obj_handle, obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { - /* No object, just exit */ return (AE_OK); diff --git a/trunk/drivers/acpi/events/evrgnini.c b/trunk/drivers/acpi/events/evrgnini.c index 5b3c7a85eb9a..baed8c1a1b9f 100644 --- a/trunk/drivers/acpi/events/evrgnini.c +++ b/trunk/drivers/acpi/events/evrgnini.c @@ -71,22 +71,11 @@ acpi_ev_system_memory_region_setup(acpi_handle handle, (union acpi_operand_object *)handle; struct acpi_mem_space_context *local_region_context; - ACPI_FUNCTION_TRACE(ev_system_memory_region_setup); + ACPI_FUNCTION_TRACE("ev_system_memory_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { if (*region_context) { - local_region_context = - (struct acpi_mem_space_context *)*region_context; - - /* Delete a cached mapping if present */ - - if (local_region_context->mapped_length) { - acpi_os_unmap_memory(local_region_context-> - mapped_logical_address, - local_region_context-> - mapped_length); - } - ACPI_FREE(local_region_context); + ACPI_MEM_FREE(*region_context); *region_context = NULL; } return_ACPI_STATUS(AE_OK); @@ -95,7 +84,7 @@ acpi_ev_system_memory_region_setup(acpi_handle handle, /* Create a new context */ local_region_context = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context)); + ACPI_MEM_CALLOCATE(sizeof(struct acpi_mem_space_context)); if (!(local_region_context)) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -129,7 +118,7 @@ acpi_ev_io_space_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context) { - ACPI_FUNCTION_TRACE(ev_io_space_region_setup); + ACPI_FUNCTION_TRACE("ev_io_space_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; @@ -172,7 +161,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, (union acpi_operand_object *)handle; struct acpi_device_id object_hID; - ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); + ACPI_FUNCTION_TRACE("ev_pci_config_region_setup"); handler_obj = region_obj->region.handler; if (!handler_obj) { @@ -189,7 +178,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, *region_context = NULL; if (function == ACPI_REGION_DEACTIVATE) { if (pci_id) { - ACPI_FREE(pci_id); + ACPI_MEM_FREE(pci_id); } return_ACPI_STATUS(status); } @@ -210,7 +199,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, * handlers with that device. */ if (handler_obj->address_space.node == acpi_gbl_root_node) { - /* Start search from the parent object */ pci_root_node = parent_node; @@ -232,7 +220,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, PCI_EXPRESS_ROOT_HID_STRING, sizeof(PCI_EXPRESS_ROOT_HID_STRING))))) { - /* Install a handler for this PCI root bridge */ status = @@ -248,7 +235,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } else { ACPI_EXCEPTION((AE_INFO, status, - "Could not install PciConfig handler for Root Bridge %4.4s", + "Could not install pci_config handler for Root Bridge %4.4s", acpi_ut_get_node_name (pci_root_node))); } @@ -275,7 +262,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, /* Region is still not initialized. Create a new context */ - pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id)); + pci_id = ACPI_MEM_CALLOCATE(sizeof(struct acpi_pci_id)); if (!pci_id) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -350,7 +337,7 @@ acpi_ev_pci_bar_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context) { - ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup); + ACPI_FUNCTION_TRACE("ev_pci_bar_region_setup"); return_ACPI_STATUS(AE_OK); } @@ -377,7 +364,7 @@ acpi_ev_cmos_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context) { - ACPI_FUNCTION_TRACE(ev_cmos_region_setup); + ACPI_FUNCTION_TRACE("ev_cmos_region_setup"); return_ACPI_STATUS(AE_OK); } @@ -402,7 +389,7 @@ acpi_ev_default_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context) { - ACPI_FUNCTION_TRACE(ev_default_region_setup); + ACPI_FUNCTION_TRACE("ev_default_region_setup"); if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; @@ -448,7 +435,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG; union acpi_operand_object *region_obj2; - ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked); + ACPI_FUNCTION_TRACE_U32("ev_initialize_region", acpi_ns_locked); if (!region_obj) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -475,9 +462,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, /* Find any "_REG" method associated with this region definition */ - status = - acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD, - &method_node); + status = acpi_ns_search_node(*reg_name_ptr, node, + ACPI_TYPE_METHOD, &method_node); if (ACPI_SUCCESS(status)) { /* * The _REG method is optional and there can be only one per region @@ -492,13 +478,11 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, * ie: acpi_gbl_root_node->parent_entry being set to NULL */ while (node) { - /* Check to see if a handler exists */ handler_obj = NULL; obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { - /* Can only be a handler if the object exists */ switch (node->type) { @@ -523,12 +507,10 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, } while (handler_obj) { - /* Is this handler of the correct type? */ if (handler_obj->address_space.space_id == space_id) { - /* Found correct handler */ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, @@ -589,7 +571,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, /* If we get here, there is no handler for this region */ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, - "No handler for RegionType %s(%X) (RegionObj %p)\n", + "No handler for region_type %s(%X) (region_obj %p)\n", acpi_ut_get_region_name(space_id), space_id, region_obj)); diff --git a/trunk/drivers/acpi/events/evsci.c b/trunk/drivers/acpi/events/evsci.c index 8106215ad554..9a622169008a 100644 --- a/trunk/drivers/acpi/events/evsci.c +++ b/trunk/drivers/acpi/events/evsci.c @@ -69,7 +69,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; - ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); + ACPI_FUNCTION_TRACE("ev_sci_xrupt_handler"); /* * We are guaranteed by the ACPI CA initialization/shutdown code that @@ -108,7 +108,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) struct acpi_gpe_xrupt_info *gpe_xrupt_list = context; u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; - ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler); + ACPI_FUNCTION_TRACE("ev_gpe_xrupt_handler"); /* * We are guaranteed by the ACPI CA initialization/shutdown code that @@ -140,7 +140,7 @@ u32 acpi_ev_install_sci_handler(void) { u32 status = AE_OK; - ACPI_FUNCTION_TRACE(ev_install_sci_handler); + ACPI_FUNCTION_TRACE("ev_install_sci_handler"); status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_xrupt_handler, @@ -171,7 +171,7 @@ acpi_status acpi_ev_remove_sci_handler(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ev_remove_sci_handler); + ACPI_FUNCTION_TRACE("ev_remove_sci_handler"); /* Just let the OS remove the handler and disable the level */ diff --git a/trunk/drivers/acpi/events/evxface.c b/trunk/drivers/acpi/events/evxface.c index 76c34a66e0e0..b38b39dde543 100644 --- a/trunk/drivers/acpi/events/evxface.c +++ b/trunk/drivers/acpi/events/evxface.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -66,7 +68,7 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_install_exception_handler); + ACPI_FUNCTION_TRACE("acpi_install_exception_handler"); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { @@ -88,8 +90,6 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler) (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); } - -ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) #endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* @@ -107,13 +107,14 @@ ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) * event. * ******************************************************************************/ + acpi_status acpi_install_fixed_event_handler(u32 event, acpi_event_handler handler, void *context) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); + ACPI_FUNCTION_TRACE("acpi_install_fixed_event_handler"); /* Parameter validation */ @@ -160,7 +161,7 @@ acpi_install_fixed_event_handler(u32 event, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) +EXPORT_SYMBOL(acpi_install_fixed_event_handler); /******************************************************************************* * @@ -174,12 +175,13 @@ ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) * DESCRIPTION: Disables the event and unregisters the event handler. * ******************************************************************************/ + acpi_status acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); + ACPI_FUNCTION_TRACE("acpi_remove_fixed_event_handler"); /* Parameter validation */ @@ -214,7 +216,7 @@ acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) +EXPORT_SYMBOL(acpi_remove_fixed_event_handler); /******************************************************************************* * @@ -233,6 +235,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) * DESCRIPTION: Install a handler for notifies on an ACPI device * ******************************************************************************/ + acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, @@ -243,7 +246,7 @@ acpi_install_notify_handler(acpi_handle device, struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_install_notify_handler); + ACPI_FUNCTION_TRACE("acpi_install_notify_handler"); /* Parameter validation */ @@ -272,7 +275,6 @@ acpi_install_notify_handler(acpi_handle device, * only one global handler can be regsitered (per notify type). */ if (device == ACPI_ROOT_OBJECT) { - /* Make sure the handler is not already installed */ if (((handler_type & ACPI_SYSTEM_NOTIFY) && @@ -315,7 +317,6 @@ acpi_install_notify_handler(acpi_handle device, obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { - /* Object exists - make sure there's no handler */ if (((handler_type & ACPI_SYSTEM_NOTIFY) && @@ -369,7 +370,6 @@ acpi_install_notify_handler(acpi_handle device, } if (handler_type == ACPI_ALL_NOTIFY) { - /* Extra ref if installed in both */ acpi_ut_add_reference(notify_obj); @@ -381,7 +381,7 @@ acpi_install_notify_handler(acpi_handle device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_install_notify_handler) +EXPORT_SYMBOL(acpi_install_notify_handler); /******************************************************************************* * @@ -399,6 +399,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_notify_handler) * DESCRIPTION: Remove a handler for notifies on an ACPI device * ******************************************************************************/ + acpi_status acpi_remove_notify_handler(acpi_handle device, u32 handler_type, acpi_notify_handler handler) @@ -408,7 +409,7 @@ acpi_remove_notify_handler(acpi_handle device, struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); + ACPI_FUNCTION_TRACE("acpi_remove_notify_handler"); /* Parameter validation */ @@ -534,7 +535,7 @@ acpi_remove_notify_handler(acpi_handle device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) +EXPORT_SYMBOL(acpi_remove_notify_handler); /******************************************************************************* * @@ -553,6 +554,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) * DESCRIPTION: Install a handler for a General Purpose Event. * ******************************************************************************/ + acpi_status acpi_install_gpe_handler(acpi_handle gpe_device, u32 gpe_number, @@ -563,7 +565,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(acpi_install_gpe_handler); + ACPI_FUNCTION_TRACE("acpi_install_gpe_handler"); /* Parameter validation */ @@ -594,7 +596,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, /* Allocate and init handler object */ - handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); + handler = ACPI_MEM_CALLOCATE(sizeof(struct acpi_handler_info)); if (!handler) { status = AE_NO_MEMORY; goto unlock_and_exit; @@ -628,7 +630,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) +EXPORT_SYMBOL(acpi_install_gpe_handler); /******************************************************************************* * @@ -644,6 +646,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) * DESCRIPTION: Remove a handler for a General Purpose acpi_event. * ******************************************************************************/ + acpi_status acpi_remove_gpe_handler(acpi_handle gpe_device, u32 gpe_number, acpi_event_handler address) @@ -653,7 +656,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, acpi_status status; acpi_cpu_flags flags; - ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler); + ACPI_FUNCTION_TRACE("acpi_remove_gpe_handler"); /* Parameter validation */ @@ -721,14 +724,14 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, /* Now we can free the handler object */ - ACPI_FREE(handler); + ACPI_MEM_FREE(handler); unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler) +EXPORT_SYMBOL(acpi_remove_gpe_handler); /******************************************************************************* * @@ -743,6 +746,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler) * DESCRIPTION: Acquire the ACPI Global Lock * ******************************************************************************/ + acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) { acpi_status status; @@ -767,7 +771,7 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) return (status); } -ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock) +EXPORT_SYMBOL(acpi_acquire_global_lock); /******************************************************************************* * @@ -780,6 +784,7 @@ ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock) * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. * ******************************************************************************/ + acpi_status acpi_release_global_lock(u32 handle) { acpi_status status; @@ -792,4 +797,4 @@ acpi_status acpi_release_global_lock(u32 handle) return (status); } -ACPI_EXPORT_SYMBOL(acpi_release_global_lock) +EXPORT_SYMBOL(acpi_release_global_lock); diff --git a/trunk/drivers/acpi/events/evxfevnt.c b/trunk/drivers/acpi/events/evxfevnt.c index 7ebc2efac936..ec9ce8429f15 100644 --- a/trunk/drivers/acpi/events/evxfevnt.c +++ b/trunk/drivers/acpi/events/evxfevnt.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -63,7 +65,7 @@ acpi_status acpi_enable(void) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_enable); + ACPI_FUNCTION_TRACE("acpi_enable"); /* Make sure we have the FADT */ @@ -92,8 +94,6 @@ acpi_status acpi_enable(void) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_enable) - /******************************************************************************* * * FUNCTION: acpi_disable @@ -105,11 +105,12 @@ ACPI_EXPORT_SYMBOL(acpi_enable) * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. * ******************************************************************************/ + acpi_status acpi_disable(void) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_disable); + ACPI_FUNCTION_TRACE("acpi_disable"); if (!acpi_gbl_FADT) { ACPI_WARNING((AE_INFO, "No FADT information present!")); @@ -136,8 +137,6 @@ acpi_status acpi_disable(void) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_disable) - /******************************************************************************* * * FUNCTION: acpi_enable_event @@ -150,12 +149,13 @@ ACPI_EXPORT_SYMBOL(acpi_disable) * DESCRIPTION: Enable an ACPI event (fixed) * ******************************************************************************/ + acpi_status acpi_enable_event(u32 event, u32 flags) { acpi_status status = AE_OK; u32 value; - ACPI_FUNCTION_TRACE(acpi_enable_event); + ACPI_FUNCTION_TRACE("acpi_enable_event"); /* Decode the Fixed Event */ @@ -193,7 +193,7 @@ acpi_status acpi_enable_event(u32 event, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_enable_event) +EXPORT_SYMBOL(acpi_enable_event); /******************************************************************************* * @@ -208,12 +208,13 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) * DESCRIPTION: Set the type of an individual GPE * ******************************************************************************/ + acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE(acpi_set_gpe_type); + ACPI_FUNCTION_TRACE("acpi_set_gpe_type"); /* Ensure that we have a valid GPE number */ @@ -235,7 +236,7 @@ acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) +EXPORT_SYMBOL(acpi_set_gpe_type); /******************************************************************************* * @@ -251,12 +252,13 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) * DESCRIPTION: Enable an ACPI event (general purpose) * ******************************************************************************/ + acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE(acpi_enable_gpe); + ACPI_FUNCTION_TRACE("acpi_enable_gpe"); /* Use semaphore lock if not executing at interrupt level */ @@ -286,7 +288,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_enable_gpe) +EXPORT_SYMBOL(acpi_enable_gpe); /******************************************************************************* * @@ -302,12 +304,13 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) * DESCRIPTION: Disable an ACPI event (general purpose) * ******************************************************************************/ + acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE(acpi_disable_gpe); + ACPI_FUNCTION_TRACE("acpi_disable_gpe"); /* Use semaphore lock if not executing at interrupt level */ @@ -335,8 +338,6 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_disable_gpe) - /******************************************************************************* * * FUNCTION: acpi_disable_event @@ -349,12 +350,13 @@ ACPI_EXPORT_SYMBOL(acpi_disable_gpe) * DESCRIPTION: Disable an ACPI event (fixed) * ******************************************************************************/ + acpi_status acpi_disable_event(u32 event, u32 flags) { acpi_status status = AE_OK; u32 value; - ACPI_FUNCTION_TRACE(acpi_disable_event); + ACPI_FUNCTION_TRACE("acpi_disable_event"); /* Decode the Fixed Event */ @@ -390,7 +392,7 @@ acpi_status acpi_disable_event(u32 event, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_disable_event) +EXPORT_SYMBOL(acpi_disable_event); /******************************************************************************* * @@ -403,11 +405,12 @@ ACPI_EXPORT_SYMBOL(acpi_disable_event) * DESCRIPTION: Clear an ACPI event (fixed) * ******************************************************************************/ + acpi_status acpi_clear_event(u32 event) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_clear_event); + ACPI_FUNCTION_TRACE("acpi_clear_event"); /* Decode the Fixed Event */ @@ -426,7 +429,7 @@ acpi_status acpi_clear_event(u32 event) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_clear_event) +EXPORT_SYMBOL(acpi_clear_event); /******************************************************************************* * @@ -441,12 +444,13 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event) * DESCRIPTION: Clear an ACPI event (general purpose) * ******************************************************************************/ + acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE(acpi_clear_gpe); + ACPI_FUNCTION_TRACE("acpi_clear_gpe"); /* Use semaphore lock if not executing at interrupt level */ @@ -474,8 +478,6 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_clear_gpe) - #ifdef ACPI_FUTURE_USAGE /******************************************************************************* * @@ -490,11 +492,12 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe) * DESCRIPTION: Obtains and returns the current status of the event * ******************************************************************************/ + acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_get_event_status); + ACPI_FUNCTION_TRACE("acpi_get_event_status"); if (!event_status) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -515,8 +518,6 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_event_status) - /******************************************************************************* * * FUNCTION: acpi_get_gpe_status @@ -532,6 +533,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_event_status) * DESCRIPTION: Get status of an event (general purpose) * ******************************************************************************/ + acpi_status acpi_get_gpe_status(acpi_handle gpe_device, u32 gpe_number, u32 flags, acpi_event_status * event_status) @@ -539,7 +541,7 @@ acpi_get_gpe_status(acpi_handle gpe_device, acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; - ACPI_FUNCTION_TRACE(acpi_get_gpe_status); + ACPI_FUNCTION_TRACE("acpi_get_gpe_status"); /* Use semaphore lock if not executing at interrupt level */ @@ -568,8 +570,6 @@ acpi_get_gpe_status(acpi_handle gpe_device, } return_ACPI_STATUS(status); } - -ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) #endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* @@ -586,6 +586,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) * DESCRIPTION: Create and Install a block of GPE registers * ******************************************************************************/ + acpi_status acpi_install_gpe_block(acpi_handle gpe_device, struct acpi_generic_address *gpe_block_address, @@ -596,7 +597,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, struct acpi_namespace_node *node; struct acpi_gpe_block_info *gpe_block; - ACPI_FUNCTION_TRACE(acpi_install_gpe_block); + ACPI_FUNCTION_TRACE("acpi_install_gpe_block"); if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -635,7 +636,6 @@ acpi_install_gpe_block(acpi_handle gpe_device, obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { - /* No object, create a new one */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); @@ -665,7 +665,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) +EXPORT_SYMBOL(acpi_install_gpe_block); /******************************************************************************* * @@ -678,13 +678,14 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) * DESCRIPTION: Remove a previously installed block of GPE registers * ******************************************************************************/ + acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) { union acpi_operand_object *obj_desc; acpi_status status; struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); + ACPI_FUNCTION_TRACE("acpi_remove_gpe_block"); if (!gpe_device) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -720,4 +721,4 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) +EXPORT_SYMBOL(acpi_remove_gpe_block); diff --git a/trunk/drivers/acpi/events/evxfregn.c b/trunk/drivers/acpi/events/evxfregn.c index e8b86a0baad0..abf5caca9ae5 100644 --- a/trunk/drivers/acpi/events/evxfregn.c +++ b/trunk/drivers/acpi/events/evxfregn.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -73,7 +75,7 @@ acpi_install_address_space_handler(acpi_handle device, struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_install_address_space_handler); + ACPI_FUNCTION_TRACE("acpi_install_address_space_handler"); /* Parameter validation */ @@ -112,7 +114,7 @@ acpi_install_address_space_handler(acpi_handle device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler) +EXPORT_SYMBOL(acpi_install_address_space_handler); /******************************************************************************* * @@ -127,6 +129,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler) * DESCRIPTION: Remove a previously installed handler. * ******************************************************************************/ + acpi_status acpi_remove_address_space_handler(acpi_handle device, acpi_adr_space_type space_id, @@ -139,7 +142,7 @@ acpi_remove_address_space_handler(acpi_handle device, struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_remove_address_space_handler); + ACPI_FUNCTION_TRACE("acpi_remove_address_space_handler"); /* Parameter validation */ @@ -173,11 +176,9 @@ acpi_remove_address_space_handler(acpi_handle device, handler_obj = obj_desc->device.handler; last_obj_ptr = &obj_desc->device.handler; while (handler_obj) { - /* We have a handler, see if user requested this one */ if (handler_obj->address_space.space_id == space_id) { - /* Matched space_id, first dereference this in the Regions */ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, @@ -228,7 +229,7 @@ acpi_remove_address_space_handler(acpi_handle device, /* The handler does not exist */ ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, - "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", + "Unable to remove address handler %p for %s(%X), dev_node %p, obj %p\n", handler, acpi_ut_get_region_name(space_id), space_id, node, obj_desc)); @@ -239,4 +240,4 @@ acpi_remove_address_space_handler(acpi_handle device, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler) +EXPORT_SYMBOL(acpi_remove_address_space_handler); diff --git a/trunk/drivers/acpi/executer/exconfig.c b/trunk/drivers/acpi/executer/exconfig.c index 823352435e08..a29782fe3ecf 100644 --- a/trunk/drivers/acpi/executer/exconfig.c +++ b/trunk/drivers/acpi/executer/exconfig.c @@ -82,7 +82,7 @@ acpi_ex_add_table(struct acpi_table_header *table, struct acpi_table_desc table_info; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE(ex_add_table); + ACPI_FUNCTION_TRACE("ex_add_table"); /* Create an object to be the table handle */ @@ -100,7 +100,7 @@ acpi_ex_add_table(struct acpi_table_header *table, ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); - table_info.type = ACPI_TABLE_ID_SSDT; + table_info.type = ACPI_TABLE_SSDT; table_info.pointer = table; table_info.length = (acpi_size) table->length; table_info.allocation = ACPI_MEM_ALLOCATED; @@ -110,7 +110,6 @@ acpi_ex_add_table(struct acpi_table_header *table, if (ACPI_FAILURE(status)) { if (status == AE_ALREADY_EXISTS) { - /* Table already exists, just return the handle */ return_ACPI_STATUS(AE_OK); @@ -122,7 +121,6 @@ acpi_ex_add_table(struct acpi_table_header *table, status = acpi_ns_load_table(table_info.installed_desc, parent_node); if (ACPI_FAILURE(status)) { - /* Uninstall table on error */ (void)acpi_tb_uninstall_table(table_info.installed_desc); @@ -162,7 +160,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parameter_node = NULL; union acpi_operand_object *ddb_handle; - ACPI_FUNCTION_TRACE(ex_load_table_op); + ACPI_FUNCTION_TRACE("ex_load_table_op"); #if 0 /* @@ -171,7 +169,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, */ status = acpi_tb_match_signature(operand[0]->string.pointer, NULL); if (status == AE_OK) { - /* Signature matched -- don't allow override */ return_ACPI_STATUS(AE_ALREADY_EXISTS); @@ -214,8 +211,9 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, * location within the namespace where the table will be loaded. */ status = - acpi_ns_get_node(start_node, operand[3]->string.pointer, - ACPI_NS_SEARCH_PARENT, &parent_node); + acpi_ns_get_node_by_path(operand[3]->string.pointer, + start_node, ACPI_NS_SEARCH_PARENT, + &parent_node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -236,8 +234,9 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, /* Find the node referenced by the parameter_path_string */ status = - acpi_ns_get_node(start_node, operand[4]->string.pointer, - ACPI_NS_SEARCH_PARENT, ¶meter_node); + acpi_ns_get_node_by_path(operand[4]->string.pointer, + start_node, ACPI_NS_SEARCH_PARENT, + ¶meter_node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -253,7 +252,6 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, /* Parameter Data (optional) */ if (parameter_node) { - /* Store the parameter data into the optional parameter object */ status = acpi_ex_store(operand[5], @@ -296,10 +294,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, struct acpi_table_header *table_ptr = NULL; acpi_physical_address address; struct acpi_table_header table_header; - acpi_integer temp; u32 i; - ACPI_FUNCTION_TRACE(ex_load_op); + ACPI_FUNCTION_TRACE("ex_load_op"); /* Object can be either an op_region or a Field */ @@ -325,7 +322,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, address = obj_desc->region.address; - /* Get part of the table header to get the table length */ + /* Get the table length from the table header */ table_header.length = 0; for (i = 0; i < 8; i++) { @@ -333,14 +330,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, (acpi_physical_address) (i + address), 8, - &temp); + ((u8 *) & + table_header) + i); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - - /* Get the one valid byte of the returned 64-bit value */ - - ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp; } /* Sanity check the table length */ @@ -351,7 +345,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, /* Allocate a buffer for the entire table */ - table_ptr = ACPI_ALLOCATE(table_header.length); + table_ptr = ACPI_MEM_ALLOCATE(table_header.length); if (!table_ptr) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -363,14 +357,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, (acpi_physical_address) (i + address), 8, - &temp); + ((u8 *) table_ptr + + i)); if (ACPI_FAILURE(status)) { goto cleanup; } - - /* Get the one valid byte of the returned 64-bit value */ - - ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp; } break; @@ -416,8 +407,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, /* The table must be either an SSDT or a PSDT */ - if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && - (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { + if ((!ACPI_STRNCMP(table_ptr->signature, + acpi_gbl_table_data[ACPI_TABLE_PSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) && + (!ACPI_STRNCMP(table_ptr->signature, + acpi_gbl_table_data[ACPI_TABLE_SSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) { ACPI_ERROR((AE_INFO, "Table has invalid signature [%4.4s], must be SSDT or PSDT", table_ptr->signature)); @@ -429,7 +424,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); if (ACPI_FAILURE(status)) { - /* On error, table_ptr was deallocated above */ return_ACPI_STATUS(status); @@ -448,7 +442,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, cleanup: if (ACPI_FAILURE(status)) { - ACPI_FREE(table_ptr); + ACPI_MEM_FREE(table_ptr); } return_ACPI_STATUS(status); } @@ -471,7 +465,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) union acpi_operand_object *table_desc = ddb_handle; struct acpi_table_desc *table_info; - ACPI_FUNCTION_TRACE(ex_unload_table); + ACPI_FUNCTION_TRACE("ex_unload_table"); /* * Validate the handle diff --git a/trunk/drivers/acpi/executer/exconvrt.c b/trunk/drivers/acpi/executer/exconvrt.c index b732e399b1ef..e6d52e12d77a 100644 --- a/trunk/drivers/acpi/executer/exconvrt.c +++ b/trunk/drivers/acpi/executer/exconvrt.c @@ -79,7 +79,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, u32 count; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_convert_to_integer", obj_desc); switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_INTEGER: @@ -199,7 +199,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, union acpi_operand_object *return_desc; u8 *new_buf; - ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_convert_to_buffer", obj_desc); switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_BUFFER: @@ -319,7 +319,6 @@ acpi_ex_convert_to_ascii(acpi_integer integer, remainder = 0; for (i = decimal_length; i > 0; i--) { - /* Divide by nth factor of 10 */ digit = integer; @@ -347,7 +346,6 @@ acpi_ex_convert_to_ascii(acpi_integer integer, hex_length = (acpi_native_uint) ACPI_MUL_2(data_width); for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) { - /* Get one hex digit, most significant digits first */ string[k] = @@ -402,7 +400,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, u16 base = 16; u8 separator = ','; - ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_convert_to_string", obj_desc); switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_STRING: @@ -569,7 +567,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_convert_to_target_type); + ACPI_FUNCTION_TRACE("ex_convert_to_target_type"); /* Default behavior */ @@ -659,7 +657,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, default: ACPI_ERROR((AE_INFO, - "Unknown Target type ID 0x%X AmlOpcode %X DestType %s", + "Unknown Target type ID 0x%X aml_opcode %X dest_type %s", GET_CURRENT_ARG_TYPE(walk_state->op_info-> runtime_args), walk_state->opcode, diff --git a/trunk/drivers/acpi/executer/excreate.c b/trunk/drivers/acpi/executer/excreate.c index 106dc7219df7..680575402835 100644 --- a/trunk/drivers/acpi/executer/excreate.c +++ b/trunk/drivers/acpi/executer/excreate.c @@ -69,7 +69,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) struct acpi_namespace_node *alias_node; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_create_alias); + ACPI_FUNCTION_TRACE("ex_create_alias"); /* Get the source/alias operands (both namespace nodes) */ @@ -164,7 +164,7 @@ acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state) acpi_status status; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE(ex_create_event); + ACPI_FUNCTION_TRACE("ex_create_event"); obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_EVENT); if (!obj_desc) { @@ -216,7 +216,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state) acpi_status status = AE_OK; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE_PTR(ex_create_mutex, ACPI_WALK_OPERANDS); + ACPI_FUNCTION_TRACE_PTR("ex_create_mutex", ACPI_WALK_OPERANDS); /* Create the new mutex object */ @@ -243,9 +243,8 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state) obj_desc->mutex.node = (struct acpi_namespace_node *)walk_state->operands[0]; - status = - acpi_ns_attach_object(obj_desc->mutex.node, obj_desc, - ACPI_TYPE_MUTEX); + status = acpi_ns_attach_object(obj_desc->mutex.node, + obj_desc, ACPI_TYPE_MUTEX); cleanup: /* @@ -281,7 +280,7 @@ acpi_ex_create_region(u8 * aml_start, struct acpi_namespace_node *node; union acpi_operand_object *region_obj2; - ACPI_FUNCTION_TRACE(ex_create_region); + ACPI_FUNCTION_TRACE("ex_create_region"); /* Get the Namespace Node */ @@ -301,7 +300,7 @@ acpi_ex_create_region(u8 * aml_start, */ if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && (region_space < ACPI_USER_REGION_BEGIN)) { - ACPI_ERROR((AE_INFO, "Invalid AddressSpace type %X", + ACPI_ERROR((AE_INFO, "Invalid address_space type %X", region_space)); return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); } @@ -365,7 +364,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) struct acpi_table_header *table; union acpi_operand_object *region_obj2; - ACPI_FUNCTION_TRACE(ex_create_table_region); + ACPI_FUNCTION_TRACE("ex_create_table_region"); /* Get the Node from the object stack */ @@ -453,7 +452,7 @@ acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state) union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ex_create_processor, walk_state); + ACPI_FUNCTION_TRACE_PTR("ex_create_processor", walk_state); /* Create the processor object */ @@ -465,9 +464,9 @@ acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state) /* Initialize the processor object from the operands */ obj_desc->processor.proc_id = (u8) operand[1]->integer.value; - obj_desc->processor.length = (u8) operand[3]->integer.value; obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value; + obj_desc->processor.length = (u8) operand[3]->integer.value; /* Install the processor object in the parent Node */ @@ -500,7 +499,7 @@ acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state) acpi_status status; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE_PTR(ex_create_power_resource, walk_state); + ACPI_FUNCTION_TRACE_PTR("ex_create_power_resource", walk_state); /* Create the power resource object */ @@ -550,7 +549,7 @@ acpi_ex_create_method(u8 * aml_start, acpi_status status; u8 method_flags; - ACPI_FUNCTION_TRACE_PTR(ex_create_method, walk_state); + ACPI_FUNCTION_TRACE_PTR("ex_create_method", walk_state); /* Create a new method object */ diff --git a/trunk/drivers/acpi/executer/exdump.c b/trunk/drivers/acpi/executer/exdump.c index 7b9718e976bf..a7cca8d4f855 100644 --- a/trunk/drivers/acpi/executer/exdump.c +++ b/trunk/drivers/acpi/executer/exdump.c @@ -61,10 +61,6 @@ static void acpi_ex_out_pointer(char *title, void *value); static void acpi_ex_out_address(char *title, acpi_physical_address value); -static void -acpi_ex_dump_object(union acpi_operand_object *obj_desc, - struct acpi_exdump_info *info); - static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc); static void @@ -123,7 +119,7 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { static struct acpi_exdump_info acpi_ex_dump_method[8] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "param_count"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.concurrency), "Concurrency"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.semaphore), "Semaphore"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, @@ -267,10 +263,12 @@ static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} }; -static struct acpi_exdump_info acpi_ex_dump_node[5] = { +static struct acpi_exdump_info acpi_ex_dump_node[6] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"}, + {ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(reference_count), + "Reference Count"}, {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"}, {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"} }; @@ -332,7 +330,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, if (!info) { acpi_os_printf - ("ExDumpObject: Display not implemented for object type %s\n", + ("ex_dump_object: Display not implemented for object type %s\n", acpi_ut_get_object_type_name(obj_desc)); return; } @@ -456,7 +454,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) u32 length; u32 index; - ACPI_FUNCTION_NAME(ex_dump_operand) + ACPI_FUNCTION_NAME("ex_dump_operand") if (! ((ACPI_LV_EXEC & acpi_dbg_level) @@ -465,7 +463,6 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) } if (!obj_desc) { - /* This could be a null element of a package */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n")); @@ -525,7 +522,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case AML_REF_OF_OP: - acpi_os_printf("Reference: (RefOf) %p\n", + acpi_os_printf("Reference: (ref_of) %p\n", obj_desc->reference.object); break; @@ -535,7 +532,6 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - /* Value is an Integer */ acpi_os_printf(" value is [%8.8X%8.8x]", @@ -614,7 +610,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_PACKAGE: - acpi_os_printf("Package [Len %X] ElementArray %p\n", + acpi_os_printf("Package [Len %X] element_array %p\n", obj_desc->package.count, obj_desc->package.elements); @@ -666,13 +662,13 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_LOCAL_BANK_FIELD: - acpi_os_printf("BankField\n"); + acpi_os_printf("bank_field\n"); break; case ACPI_TYPE_LOCAL_REGION_FIELD: acpi_os_printf - ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n", + ("region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n", obj_desc->field.bit_length, obj_desc->field.access_byte_width, obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, @@ -685,12 +681,12 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_LOCAL_INDEX_FIELD: - acpi_os_printf("IndexField\n"); + acpi_os_printf("index_field\n"); break; case ACPI_TYPE_BUFFER_FIELD: - acpi_os_printf("BufferField: %X bits at byte %X bit %X of\n", + acpi_os_printf("buffer_field: %X bits at byte %X bit %X of\n", obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset, obj_desc->buffer_field.start_field_bit_offset); @@ -781,7 +777,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, { acpi_native_uint i; - ACPI_FUNCTION_NAME(ex_dump_operands); + ACPI_FUNCTION_NAME("ex_dump_operands"); if (!ident) { ident = "?"; @@ -905,7 +901,7 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) acpi_os_printf("Could not convert name to pathname\n"); } else { acpi_os_printf("%s\n", (char *)ret_buf.pointer); - ACPI_FREE(ret_buf.pointer); + ACPI_MEM_FREE(ret_buf.pointer); } } else if (obj_desc->reference.object) { acpi_os_printf("\nReferenced Object: %p\n", @@ -1021,7 +1017,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, void acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) { - ACPI_FUNCTION_TRACE(ex_dump_object_descriptor); + ACPI_FUNCTION_TRACE("ex_dump_object_descriptor"); if (!obj_desc) { return_VOID; @@ -1050,7 +1046,7 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { acpi_os_printf - ("ExDumpObjectDescriptor: %p is not an ACPI operand object: [%s]\n", + ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n", obj_desc, acpi_ut_get_descriptor_name(obj_desc)); return_VOID; } diff --git a/trunk/drivers/acpi/executer/exfield.c b/trunk/drivers/acpi/executer/exfield.c index 9ea9c3a67ca9..e259201ce9a0 100644 --- a/trunk/drivers/acpi/executer/exfield.c +++ b/trunk/drivers/acpi/executer/exfield.c @@ -73,7 +73,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, void *buffer; u8 locked; - ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_read_data_from_field", obj_desc); /* Parameter validation */ @@ -142,7 +142,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, length = (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); if (length > acpi_gbl_integer_byte_width) { - /* Field is too large for an Integer, create a Buffer instead */ buffer_desc = acpi_ut_create_buffer_object(length); @@ -164,11 +163,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, } ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", + "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n", obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer, (u32) length)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n", + "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n", obj_desc->common_field.bit_length, obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.base_byte_offset)); @@ -220,7 +219,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, u8 locked; union acpi_operand_object *buffer_desc; - ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_write_data_to_field", obj_desc); /* Parameter validation */ @@ -330,10 +329,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); if (length < required_length) { - /* We need to create a new buffer */ - new_buffer = ACPI_ALLOCATE_ZEROED(required_length); + new_buffer = ACPI_MEM_CALLOCATE(required_length); if (!new_buffer) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -349,14 +347,14 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, } ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", + "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n", source_desc, acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE (source_desc)), ACPI_GET_OBJECT_TYPE(source_desc), buffer, length)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n", + "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n", obj_desc, acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)), ACPI_GET_OBJECT_TYPE(obj_desc), @@ -377,7 +375,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, /* Free temporary buffer if we used one */ if (new_buffer) { - ACPI_FREE(new_buffer); + ACPI_MEM_FREE(new_buffer); } return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/executer/exfldio.c b/trunk/drivers/acpi/executer/exfldio.c index 051053f7cccb..bd1af35f7fcf 100644 --- a/trunk/drivers/acpi/executer/exfldio.c +++ b/trunk/drivers/acpi/executer/exfldio.c @@ -87,7 +87,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, acpi_status status = AE_OK; union acpi_operand_object *rgn_desc; - ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset); + ACPI_FUNCTION_TRACE_U32("ex_setup_region", field_datum_byte_offset); rgn_desc = obj_desc->common_field.region_obj; @@ -112,18 +112,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, } } - /* Exit if Address/Length have been disallowed by the host OS */ - - if (rgn_desc->common.flags & AOPOBJ_INVALID) { - return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); - } - - /* - * Exit now for SMBus address space, it has a non-linear address space - * and the request cannot be directly validated - */ if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { - /* SMBus has a non-linear address space */ return_ACPI_STATUS(AE_OK); @@ -145,10 +134,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * length of one field datum (access width) must fit within the region. * (Region length is specified in bytes) */ - if (rgn_desc->region.length < - (obj_desc->common_field.base_byte_offset + - field_datum_byte_offset + - obj_desc->common_field.access_byte_width)) { + if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + + field_datum_byte_offset + + obj_desc->common_field. + access_byte_width)) { if (acpi_gbl_enable_interpreter_slack) { /* * Slack mode only: We will go ahead and allow access to this @@ -228,7 +217,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, union acpi_operand_object *rgn_desc; acpi_physical_address address; - ACPI_FUNCTION_TRACE(ex_access_region); + ACPI_FUNCTION_TRACE("ex_access_region"); /* * Ensure that the region operands are fully evaluated and verify @@ -257,7 +246,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, - " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", + " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name(rgn_desc->region. space_id), rgn_desc->region.space_id, @@ -363,7 +352,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, acpi_status status; acpi_integer local_value; - ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset); + ACPI_FUNCTION_TRACE_U32("ex_field_datum_io", field_datum_byte_offset); if (read_write == ACPI_READ) { if (!value) { @@ -498,11 +487,10 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "I/O to Data Register: ValuePtr %p\n", + "I/O to Data Register: value_ptr %p\n", value)); if (read_write == ACPI_READ) { - /* Read the datum from the data_register */ status = @@ -571,7 +559,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, acpi_integer merged_value; acpi_integer current_value; - ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask); + ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask); /* Start with the new bits */ @@ -580,7 +568,6 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, /* If the mask is all ones, we don't need to worry about the update rule */ if (mask != ACPI_INTEGER_MAX) { - /* Decode the update rule */ switch (obj_desc->common_field. @@ -627,7 +614,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, default: ACPI_ERROR((AE_INFO, - "Unknown UpdateRule value: %X", + "Unknown update_rule value: %X", (obj_desc->common_field. field_flags & AML_FIELD_UPDATE_RULE_MASK))); @@ -636,7 +623,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, } ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n", + "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", ACPI_FORMAT_UINT64(mask), field_datum_byte_offset, obj_desc->common_field.access_byte_width, @@ -679,7 +666,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, u32 field_datum_count; u32 i; - ACPI_FUNCTION_TRACE(ex_extract_from_field); + ACPI_FUNCTION_TRACE("ex_extract_from_field"); /* Validate target buffer and clear it */ @@ -717,7 +704,6 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, /* Read the rest of the field */ for (i = 1; i < field_datum_count; i++) { - /* Get next input datum from the field */ field_offset += obj_desc->common_field.access_byte_width; @@ -785,7 +771,6 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, { acpi_status status; acpi_integer mask; - acpi_integer width_mask; acpi_integer merged_datum; acpi_integer raw_datum = 0; u32 field_offset = 0; @@ -795,7 +780,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, u32 field_datum_count; u32 i; - ACPI_FUNCTION_TRACE(ex_insert_into_field); + ACPI_FUNCTION_TRACE("ex_insert_into_field"); /* Validate input buffer */ @@ -810,20 +795,15 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, /* Compute the number of datums (access width data items) */ - width_mask = - ACPI_MASK_BITS_ABOVE(obj_desc->common_field.access_bit_width); mask = - width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field. - start_field_bit_offset); - - datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, - obj_desc->common_field.access_bit_width); - - field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + - obj_desc->common_field. - start_field_bit_offset, - obj_desc->common_field. - access_bit_width); + ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); + datum_count = + ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, + obj_desc->common_field.access_bit_width); + field_datum_count = + ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + + obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.access_bit_width); /* Get initial Datum from the input buffer */ @@ -837,7 +817,6 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, /* Write the entire field */ for (i = 1; i < field_datum_count; i++) { - /* Write merged datum to the target field */ merged_datum &= mask; @@ -854,7 +833,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, merged_datum = raw_datum >> (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset); - mask = width_mask; + mask = ACPI_INTEGER_MAX; if (i == datum_count) { break; diff --git a/trunk/drivers/acpi/executer/exmisc.c b/trunk/drivers/acpi/executer/exmisc.c index bd98aab017cf..48c18d29222a 100644 --- a/trunk/drivers/acpi/executer/exmisc.c +++ b/trunk/drivers/acpi/executer/exmisc.c @@ -72,7 +72,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, union acpi_operand_object *reference_obj; union acpi_operand_object *referenced_obj; - ACPI_FUNCTION_TRACE_PTR(ex_get_object_reference, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_get_object_reference", obj_desc); *return_desc = NULL; @@ -168,7 +168,7 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, acpi_size length1; acpi_size new_length; - ACPI_FUNCTION_TRACE(ex_concat_template); + ACPI_FUNCTION_TRACE("ex_concat_template"); /* * Find the end_tag descriptor in each resource template. @@ -250,7 +250,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, char *new_buf; acpi_status status; - ACPI_FUNCTION_TRACE(ex_do_concatenate); + ACPI_FUNCTION_TRACE("ex_do_concatenate"); /* * Convert the second operand if necessary. The first operand @@ -445,24 +445,10 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ - /* - * We need to check if the shiftcount is larger than the integer bit - * width since the behavior of this is not well-defined in the C language. - */ - if (integer1 >= acpi_gbl_integer_bit_width) { - return (0); - } return (integer0 << integer1); case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ - /* - * We need to check if the shiftcount is larger than the integer bit - * width since the behavior of this is not well-defined in the C language. - */ - if (integer1 >= acpi_gbl_integer_bit_width) { - return (0); - } return (integer0 >> integer1); case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ @@ -503,7 +489,7 @@ acpi_ex_do_logical_numeric_op(u16 opcode, acpi_status status = AE_OK; u8 local_result = FALSE; - ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op); + ACPI_FUNCTION_TRACE("ex_do_logical_numeric_op"); switch (opcode) { case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ @@ -571,7 +557,7 @@ acpi_ex_do_logical_op(u16 opcode, u8 local_result = FALSE; int compare; - ACPI_FUNCTION_TRACE(ex_do_logical_op); + ACPI_FUNCTION_TRACE("ex_do_logical_op"); /* * Convert the second operand if necessary. The first operand @@ -663,7 +649,6 @@ acpi_ex_do_logical_op(u16 opcode, /* Length and all bytes must be equal */ if ((length0 == length1) && (compare == 0)) { - /* Length and all bytes match ==> TRUE */ local_result = TRUE; diff --git a/trunk/drivers/acpi/executer/exmutex.c b/trunk/drivers/acpi/executer/exmutex.c index 93098d68cadf..f843b22e20b9 100644 --- a/trunk/drivers/acpi/executer/exmutex.c +++ b/trunk/drivers/acpi/executer/exmutex.c @@ -61,7 +61,7 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc, * * RETURN: None * - * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list + * DESCRIPTION: Remove a mutex from the "acquired_mutex" list * ******************************************************************************/ @@ -95,7 +95,7 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) * * RETURN: None * - * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk + * DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk * ******************************************************************************/ @@ -144,7 +144,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, { acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_acquire_mutex", obj_desc); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -165,7 +165,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, */ if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { ACPI_ERROR((AE_INFO, - "Cannot acquire Mutex [%4.4s], incorrect SyncLevel", + "Cannot acquire Mutex [%4.4s], incorrect sync_level", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } @@ -173,7 +173,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, /* Support for multiple acquires by the owning thread */ if (obj_desc->mutex.owner_thread) { - /* Special case for Global Lock, allow all threads */ if ((obj_desc->mutex.owner_thread->thread_id == @@ -193,7 +192,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, status = acpi_ex_system_acquire_mutex(time_desc, obj_desc); if (ACPI_FAILURE(status)) { - /* Includes failure from a timeout on time_desc */ return_ACPI_STATUS(status); @@ -234,7 +232,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, { acpi_status status; - ACPI_FUNCTION_TRACE(ex_release_mutex); + ACPI_FUNCTION_TRACE("ex_release_mutex"); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -279,7 +277,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, */ if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { ACPI_ERROR((AE_INFO, - "Cannot release Mutex [%4.4s], incorrect SyncLevel", + "Cannot release Mutex [%4.4s], incorrect sync_level", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } @@ -288,7 +286,6 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, obj_desc->mutex.acquisition_depth--; if (obj_desc->mutex.acquisition_depth != 0) { - /* Just decrement the depth and return */ return_ACPI_STATUS(AE_OK); diff --git a/trunk/drivers/acpi/executer/exnames.c b/trunk/drivers/acpi/executer/exnames.c index d3d70364626c..054fe5e1a314 100644 --- a/trunk/drivers/acpi/executer/exnames.c +++ b/trunk/drivers/acpi/executer/exnames.c @@ -77,7 +77,7 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) char *name_string; u32 size_needed; - ACPI_FUNCTION_TRACE(ex_allocate_name_string); + ACPI_FUNCTION_TRACE("ex_allocate_name_string"); /* * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix. @@ -85,7 +85,6 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) * This may actually be somewhat longer than needed. */ if (prefix_count == ACPI_UINT32_MAX) { - /* Special case for root */ size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1; @@ -98,7 +97,7 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) * Allocate a buffer for the name. * This buffer must be deleted by the caller! */ - name_string = ACPI_ALLOCATE(size_needed); + name_string = ACPI_MEM_ALLOCATE(size_needed); if (!name_string) { ACPI_ERROR((AE_INFO, "Could not allocate size %d", size_needed)); @@ -120,13 +119,11 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) /* Set up Dual or Multi prefixes if needed */ if (num_name_segs > 2) { - /* Set up multi prefixes */ *temp_ptr++ = AML_MULTI_NAME_PREFIX_OP; *temp_ptr++ = (char)num_name_segs; } else if (2 == num_name_segs) { - /* Set up dual prefixes */ *temp_ptr++ = AML_DUAL_NAME_PREFIX; @@ -162,7 +159,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) u32 index; char char_buf[5]; - ACPI_FUNCTION_TRACE(ex_name_segment); + ACPI_FUNCTION_TRACE("ex_name_segment"); /* * If first character is a digit, then we know that we aren't looking at a @@ -179,7 +176,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) for (index = 0; (index < ACPI_NAME_SIZE) - && (acpi_ut_valid_acpi_char(*aml_address, 0)); index++) { + && (acpi_ut_valid_acpi_character(*aml_address)); index++) { char_buf[index] = *aml_address++; ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index])); } @@ -187,7 +184,6 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) /* Valid name segment */ if (index == 4) { - /* Found 4 valid characters */ char_buf[4] = '\0'; @@ -253,12 +249,11 @@ acpi_ex_get_name_string(acpi_object_type data_type, u32 prefix_count = 0; u8 has_prefix = FALSE; - ACPI_FUNCTION_TRACE_PTR(ex_get_name_string, aml_address); + ACPI_FUNCTION_TRACE_PTR("ex_get_name_string", aml_address); if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type || ACPI_TYPE_LOCAL_BANK_FIELD == data_type || ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) { - /* Disallow prefixes for types associated with field_unit names */ name_string = acpi_ex_allocate_name_string(0, 1); @@ -277,7 +272,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, case AML_ROOT_PREFIX: ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "RootPrefix(\\) at %p\n", + "root_prefix(\\) at %p\n", aml_address)); /* @@ -295,7 +290,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, do { ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "ParentPrefix (^) at %p\n", + "parent_prefix (^) at %p\n", aml_address)); aml_address++; @@ -319,7 +314,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, case AML_DUAL_NAME_PREFIX: ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "DualNamePrefix at %p\n", + "dual_name_prefix at %p\n", aml_address)); aml_address++; @@ -346,7 +341,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, case AML_MULTI_NAME_PREFIX_OP: ACPI_DEBUG_PRINT((ACPI_DB_LOAD, - "MultiNamePrefix at %p\n", + "multi_name_prefix at %p\n", aml_address)); /* Fetch count of segments remaining in name path */ @@ -382,7 +377,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, if (prefix_count == ACPI_UINT32_MAX) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "NameSeg is \"\\\" followed by NULL\n")); + "name_seg is \"\\\" followed by NULL\n")); } /* Consume the NULL byte */ @@ -415,7 +410,6 @@ acpi_ex_get_name_string(acpi_object_type data_type, } if (AE_CTRL_PENDING == status && has_prefix) { - /* Ran out of segments after processing a prefix */ ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string)); @@ -424,7 +418,7 @@ acpi_ex_get_name_string(acpi_object_type data_type, if (ACPI_FAILURE(status)) { if (name_string) { - ACPI_FREE(name_string); + ACPI_MEM_FREE(name_string); } return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/executer/exoparg1.c b/trunk/drivers/acpi/executer/exoparg1.c index 6374d8be88e0..23d0823bcd5e 100644 --- a/trunk/drivers/acpi/executer/exoparg1.c +++ b/trunk/drivers/acpi/executer/exoparg1.c @@ -89,7 +89,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) acpi_status status = AE_OK; union acpi_operand_object *return_desc = NULL; - ACPI_FUNCTION_TRACE_STR(ex_opcode_0A_0T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the AML opcode */ @@ -150,7 +150,7 @@ acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state) union acpi_operand_object **operand = &walk_state->operands[0]; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_0R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the AML opcode */ @@ -216,7 +216,7 @@ acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state) acpi_status status = AE_OK; union acpi_operand_object **operand = &walk_state->operands[0]; - ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_0R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the AML opcode */ @@ -264,7 +264,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) acpi_integer power_of_ten; acpi_integer digit; - ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the AML opcode */ @@ -322,9 +322,8 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) /* Since the bit position is one-based, subtract from 33 (65) */ - return_desc->integer.value = - temp32 == - 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32; + return_desc->integer.value = temp32 == 0 ? 0 : + (ACPI_INTEGER_BIT_SIZE + 1) - temp32; break; case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */ @@ -343,7 +342,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) { - /* Get the least significant 4-bit BCD digit */ temp32 = ((u32) digit) & 0xF; @@ -489,7 +487,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) status = acpi_ex_convert_to_string(operand[0], &return_desc, ACPI_EXPLICIT_CONVERT_DECIMAL); if (return_desc == operand[0]) { - /* No conversion performed, add ref to handle return value */ acpi_ut_add_reference(return_desc); } @@ -500,7 +497,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) status = acpi_ex_convert_to_string(operand[0], &return_desc, ACPI_EXPLICIT_CONVERT_HEX); if (return_desc == operand[0]) { - /* No conversion performed, add ref to handle return value */ acpi_ut_add_reference(return_desc); } @@ -510,7 +506,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) status = acpi_ex_convert_to_buffer(operand[0], &return_desc); if (return_desc == operand[0]) { - /* No conversion performed, add ref to handle return value */ acpi_ut_add_reference(return_desc); } @@ -521,7 +516,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) status = acpi_ex_convert_to_integer(operand[0], &return_desc, ACPI_ANY_BASE); if (return_desc == operand[0]) { - /* No conversion performed, add ref to handle return value */ acpi_ut_add_reference(return_desc); } @@ -547,7 +541,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) } if (ACPI_SUCCESS(status)) { - /* Store the return value computed above into the target object */ status = acpi_ex_store(return_desc, operand[1], walk_state); @@ -555,18 +548,16 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) cleanup: + if (!walk_state->result_obj) { + walk_state->result_obj = return_desc; + } + /* Delete return object on error */ if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(return_desc); } - /* Save return object on success */ - - else if (!walk_state->result_obj) { - walk_state->result_obj = return_desc; - } - return_ACPI_STATUS(status); } @@ -591,7 +582,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) u32 type; acpi_integer value; - ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the AML opcode */ @@ -634,7 +625,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) temp_desc = operand[0]; if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) == ACPI_DESC_TYPE_OPERAND) { - /* Internal reference object - prevent deletion */ acpi_ut_add_reference(temp_desc); @@ -699,7 +689,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) if (ACPI_FAILURE(status)) { goto cleanup; } - /* Allocate a descriptor to hold the type. */ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); @@ -788,25 +777,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) /* Check for a method local or argument, or standalone String */ - if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) == + if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) != ACPI_DESC_TYPE_NAMED) { - temp_desc = - acpi_ns_get_attached_object((struct - acpi_namespace_node *) - operand[0]); - if (temp_desc - && - ((ACPI_GET_OBJECT_TYPE(temp_desc) == - ACPI_TYPE_STRING) - || (ACPI_GET_OBJECT_TYPE(temp_desc) == - ACPI_TYPE_LOCAL_REFERENCE))) { - operand[0] = temp_desc; - acpi_ut_add_reference(temp_desc); - } else { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - } else { switch (ACPI_GET_OBJECT_TYPE(operand[0])) { case ACPI_TYPE_LOCAL_REFERENCE: /* @@ -855,35 +827,26 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) break; case ACPI_TYPE_STRING: - break; - default: - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - } - - if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) != - ACPI_DESC_TYPE_NAMED) { - if (ACPI_GET_OBJECT_TYPE(operand[0]) == - ACPI_TYPE_STRING) { /* * This is a deref_of (String). The string is a reference * to a named ACPI object. * * 1) Find the owning Node - * 2) Dereference the node to an actual object. Could be a + * 2) Dereference the node to an actual object. Could be a * Field, so we need to resolve the node to a value. */ status = - acpi_ns_get_node(walk_state->scope_info-> - scope.node, - operand[0]->string.pointer, - ACPI_NS_SEARCH_PARENT, - ACPI_CAST_INDIRECT_PTR - (struct - acpi_namespace_node, - &return_desc)); + acpi_ns_get_node_by_path(operand[0]->string. + pointer, + walk_state-> + scope_info->scope. + node, + ACPI_NS_SEARCH_PARENT, + ACPI_CAST_INDIRECT_PTR + (struct + acpi_namespace_node, + &return_desc)); if (ACPI_FAILURE(status)) { goto cleanup; } @@ -894,6 +857,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) (struct acpi_namespace_node, &return_desc), walk_state); goto cleanup; + + default: + + status = AE_AML_OPERAND_TYPE; + goto cleanup; } } @@ -969,12 +937,13 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) acpi_ut_add_reference (return_desc); } + break; default: ACPI_ERROR((AE_INFO, - "Unknown Index TargetType %X in obj %p", + "Unknown Index target_type %X in obj %p", operand[0]->reference. target_type, operand[0])); status = AE_AML_OPERAND_TYPE; @@ -988,6 +957,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) == ACPI_DESC_TYPE_NAMED) { + return_desc = acpi_ns_get_attached_object((struct acpi_namespace_node @@ -1002,7 +972,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: ACPI_ERROR((AE_INFO, - "Unknown opcode in reference(%p) - %X", + "Unknown opcode in ref(%p) - %X", operand[0], operand[0]->reference.opcode)); @@ -1028,11 +998,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) acpi_ut_remove_reference(return_desc); } - /* Save return object on success */ - - else { - walk_state->result_obj = return_desc; - } - + walk_state->result_obj = return_desc; return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/executer/exoparg2.c b/trunk/drivers/acpi/executer/exoparg2.c index 7d2cbc113160..e263a5ddd405 100644 --- a/trunk/drivers/acpi/executer/exoparg2.c +++ b/trunk/drivers/acpi/executer/exoparg2.c @@ -92,7 +92,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) u32 value; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_0R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Examine the opcode */ @@ -121,7 +121,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) #ifdef ACPI_GPE_NOTIFY_CHECK /* * GPE method wake/notify check. Here, we want to ensure that we - * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx + * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx * GPE method during system runtime. If we do, the GPE is marked * as "wake-only" and disabled. * @@ -138,7 +138,6 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) acpi_ev_check_for_wake_only_gpe(walk_state-> gpe_event_info); if (ACPI_FAILURE(status)) { - /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ return_ACPI_STATUS(AE_OK) @@ -186,7 +185,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) union acpi_operand_object *return_desc2 = NULL; acpi_status status; - ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_2T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Execute the opcode */ @@ -253,7 +252,6 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) acpi_ut_remove_reference(return_desc2); if (ACPI_FAILURE(status)) { - /* Delete the return object */ acpi_ut_remove_reference(return_desc1); @@ -283,13 +281,12 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) acpi_status status = AE_OK; acpi_size length; - ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_1T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Execute the opcode */ if (walk_state->op_info->flags & AML_MATH) { - /* All simple math opcodes (add, etc.) */ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); @@ -386,70 +383,54 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) goto cleanup; } - /* Initialize the Index reference object */ - index = operand[1]->integer.value; - return_desc->reference.offset = (u32) index; - return_desc->reference.opcode = AML_INDEX_OP; - /* - * At this point, the Source operand is a String, Buffer, or Package. - * Verify that the index is within range. - */ - switch (ACPI_GET_OBJECT_TYPE(operand[0])) { - case ACPI_TYPE_STRING: + /* At this point, the Source operand is a Package, Buffer, or String */ - if (index >= operand[0]->string.length) { - status = AE_AML_STRING_LIMIT; - } - - return_desc->reference.target_type = - ACPI_TYPE_BUFFER_FIELD; - break; - - case ACPI_TYPE_BUFFER: - - if (index >= operand[0]->buffer.length) { - status = AE_AML_BUFFER_LIMIT; - } - - return_desc->reference.target_type = - ACPI_TYPE_BUFFER_FIELD; - break; - - case ACPI_TYPE_PACKAGE: + if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) { + /* Object to be indexed is a Package */ if (index >= operand[0]->package.count) { + ACPI_ERROR((AE_INFO, + "Index value (%X%8.8X) beyond package end (%X)", + ACPI_FORMAT_UINT64(index), + operand[0]->package.count)); status = AE_AML_PACKAGE_LIMIT; + goto cleanup; } return_desc->reference.target_type = ACPI_TYPE_PACKAGE; + return_desc->reference.object = operand[0]; return_desc->reference.where = &operand[0]->package.elements[index]; - break; - - default: - - status = AE_AML_INTERNAL; - goto cleanup; - } + } else { + /* Object to be indexed is a Buffer/String */ - /* Failure means that the Index was beyond the end of the object */ + if (index >= operand[0]->buffer.length) { + ACPI_ERROR((AE_INFO, + "Index value (%X%8.8X) beyond end of buffer (%X)", + ACPI_FORMAT_UINT64(index), + operand[0]->buffer.length)); + status = AE_AML_BUFFER_LIMIT; + goto cleanup; + } - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Index (%X%8.8X) is beyond end of object", - ACPI_FORMAT_UINT64(index))); - goto cleanup; + return_desc->reference.target_type = + ACPI_TYPE_BUFFER_FIELD; + return_desc->reference.object = operand[0]; } /* - * Save the target object and add a reference to it for the life - * of the index + * Add a reference to the target package/buffer/string for the life + * of the index. */ - return_desc->reference.object = operand[0]; acpi_ut_add_reference(operand[0]); + /* Complete the Index reference object */ + + return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.offset = (u32) index; + /* Store the reference to the Target */ status = acpi_ex_store(return_desc, operand[2], walk_state); @@ -514,7 +495,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) acpi_status status = AE_OK; u8 logical_result = FALSE; - ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); /* Create the internal return object */ @@ -528,7 +509,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) /* Execute the Opcode */ if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) { - /* logical_op (Operand0, Operand1) */ status = acpi_ex_do_logical_numeric_op(walk_state->opcode, @@ -538,7 +518,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) value, &logical_result); goto store_logical_result; } else if (walk_state->op_info->flags & AML_LOGICAL) { - /* logical_op (Operand0, Operand1) */ status = acpi_ex_do_logical_op(walk_state->opcode, operand[0], diff --git a/trunk/drivers/acpi/executer/exoparg3.c b/trunk/drivers/acpi/executer/exoparg3.c index e2d945dfd509..6a3a883cb8a3 100644 --- a/trunk/drivers/acpi/executer/exoparg3.c +++ b/trunk/drivers/acpi/executer/exoparg3.c @@ -88,19 +88,20 @@ acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state) struct acpi_signal_fatal_info *fatal; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_0T_0R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name(walk_state->opcode)); switch (walk_state->opcode) { case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "FatalOp: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", (u32) operand[0]->integer.value, (u32) operand[1]->integer.value, (u32) operand[2]->integer.value)); - fatal = ACPI_ALLOCATE(sizeof(struct acpi_signal_fatal_info)); + fatal = + ACPI_MEM_ALLOCATE(sizeof(struct acpi_signal_fatal_info)); if (fatal) { fatal->type = (u32) operand[0]->integer.value; fatal->code = (u32) operand[1]->integer.value; @@ -113,7 +114,7 @@ acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state) /* Might return while OS is shutting down, just continue */ - ACPI_FREE(fatal); + ACPI_MEM_FREE(fatal); break; default: @@ -150,7 +151,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) acpi_integer index; acpi_size length; - ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_1T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); switch (walk_state->opcode) { @@ -195,7 +196,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) /* Always allocate a new buffer for the String */ - buffer = ACPI_ALLOCATE_ZEROED((acpi_size) length + 1); + buffer = ACPI_MEM_CALLOCATE((acpi_size) length + 1); if (!buffer) { status = AE_NO_MEMORY; goto cleanup; @@ -207,10 +208,9 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) /* If the requested length is zero, don't allocate a buffer */ if (length > 0) { - /* Allocate a new buffer for the Buffer */ - buffer = ACPI_ALLOCATE_ZEROED(length); + buffer = ACPI_MEM_CALLOCATE(length); if (!buffer) { status = AE_NO_MEMORY; goto cleanup; @@ -225,7 +225,6 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) } if (buffer) { - /* We have a buffer, copy the portion requested */ ACPI_MEMCPY(buffer, operand[0]->string.pointer + index, diff --git a/trunk/drivers/acpi/executer/exoparg6.c b/trunk/drivers/acpi/executer/exoparg6.c index f0c0ba6eb408..e043d924444f 100644 --- a/trunk/drivers/acpi/executer/exoparg6.c +++ b/trunk/drivers/acpi/executer/exoparg6.c @@ -220,7 +220,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) acpi_integer index; union acpi_operand_object *this_element; - ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R, + ACPI_FUNCTION_TRACE_STR("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name(walk_state->opcode)); switch (walk_state->opcode) { @@ -276,7 +276,6 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) * match was found. */ for (; index < operand[0]->package.count; index++) { - /* Get the current package element */ this_element = operand[0]->package.elements[index]; diff --git a/trunk/drivers/acpi/executer/exprep.c b/trunk/drivers/acpi/executer/exprep.c index 44d064f427b9..7719ae5d4f16 100644 --- a/trunk/drivers/acpi/executer/exprep.c +++ b/trunk/drivers/acpi/executer/exprep.c @@ -97,7 +97,7 @@ acpi_ex_generate_access(u32 field_bit_offset, u32 minimum_accesses = 0xFFFFFFFF; u32 accesses; - ACPI_FUNCTION_TRACE(ex_generate_access); + ACPI_FUNCTION_TRACE("ex_generate_access"); /* Round Field start offset and length to "minimal" byte boundaries */ @@ -146,7 +146,7 @@ acpi_ex_generate_access(u32 field_bit_offset, accesses = field_end_offset - field_start_offset; ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "AccessWidth %d end is within region\n", + "access_width %d end is within region\n", access_byte_width)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, @@ -173,7 +173,7 @@ acpi_ex_generate_access(u32 field_bit_offset, } } else { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "AccessWidth %d end is NOT within region\n", + "access_width %d end is NOT within region\n", access_byte_width)); if (access_byte_width == 1) { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, @@ -228,7 +228,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, u32 byte_alignment; u32 bit_length; - ACPI_FUNCTION_TRACE(ex_decode_field_access); + ACPI_FUNCTION_TRACE("ex_decode_field_access"); access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK); @@ -322,7 +322,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, u32 byte_alignment; u32 nearest_byte_address; - ACPI_FUNCTION_TRACE(ex_prep_common_field_object); + ACPI_FUNCTION_TRACE("ex_prep_common_field_object"); /* * Note: the structure being initialized is the @@ -415,13 +415,13 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) u32 type; acpi_status status; - ACPI_FUNCTION_TRACE(ex_prep_field_value); + ACPI_FUNCTION_TRACE("ex_prep_field_value"); /* Parameter validation */ if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) { if (!info->region_node) { - ACPI_ERROR((AE_INFO, "Null RegionNode")); + ACPI_ERROR((AE_INFO, "Null region_node")); return_ACPI_STATUS(AE_AML_NO_OPERAND); } @@ -467,7 +467,7 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->field.region_obj); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", + "region_field: bit_off %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, obj_desc->field.access_byte_width, @@ -488,7 +488,7 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->bank_field.bank_obj); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n", + "Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n", obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset, obj_desc->field.access_byte_width, @@ -519,29 +519,16 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->index_field.index_obj); /* - * April 2006: Changed to match MS behavior - * * The value written to the Index register is the byte offset of the - * target field in units of the granularity of the index_field - * - * Previously, the value was calculated as an index in terms of the - * width of the Data register, as below: - * - * obj_desc->index_field.Value = (u32) - * (Info->field_bit_position / ACPI_MUL_8 ( - * obj_desc->Field.access_byte_width)); - * - * February 2006: Tried value as a byte offset: - * obj_desc->index_field.Value = (u32) - * ACPI_DIV_8 (Info->field_bit_position); + * target field + * Note: may change code to: ACPI_DIV_8 (Info->field_bit_position) */ - obj_desc->index_field.value = - (u32) ACPI_ROUND_DOWN(ACPI_DIV_8(info->field_bit_position), - obj_desc->index_field. - access_byte_width); + obj_desc->index_field.value = (u32) + (info->field_bit_position / + ACPI_MUL_8(obj_desc->field.access_byte_width)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", + "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset, obj_desc->index_field.value, @@ -563,7 +550,7 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ns_get_type(info->field_node)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Set NamedObj %p [%4.4s], ObjDesc %p\n", + "Set named_obj %p [%4.4s], obj_desc %p\n", info->field_node, acpi_ut_get_node_name(info->field_node), obj_desc)); diff --git a/trunk/drivers/acpi/executer/exregion.c b/trunk/drivers/acpi/executer/exregion.c index 3cc97ba48b36..6a4cfdff606d 100644 --- a/trunk/drivers/acpi/executer/exregion.c +++ b/trunk/drivers/acpi/executer/exregion.c @@ -81,7 +81,7 @@ acpi_ex_system_memory_space_handler(u32 function, u32 remainder; #endif - ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); + ACPI_FUNCTION_TRACE("ex_system_memory_space_handler"); /* Validate and translate the bit width */ @@ -103,7 +103,7 @@ acpi_ex_system_memory_space_handler(u32 function, break; default: - ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %d", + ACPI_ERROR((AE_INFO, "Invalid system_memory width %d", bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } @@ -135,7 +135,6 @@ acpi_ex_system_memory_space_handler(u32 function, * Delete the existing mapping and create a new one. */ if (mem_info->mapped_length) { - /* Valid mapping, delete it */ acpi_os_unmap_memory(mem_info->mapped_logical_address, @@ -182,8 +181,8 @@ acpi_ex_system_memory_space_handler(u32 function, (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", - bit_width, function, ACPI_FORMAT_UINT64(address))); + "system_memory %d (%d width) Address=%8.8X%8.8X\n", + function, bit_width, ACPI_FORMAT_UINT64(address))); /* * Perform the memory read or write @@ -284,11 +283,11 @@ acpi_ex_system_io_space_handler(u32 function, acpi_status status = AE_OK; u32 value32; - ACPI_FUNCTION_TRACE(ex_system_io_space_handler); + ACPI_FUNCTION_TRACE("ex_system_io_space_handler"); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", - bit_width, function, ACPI_FORMAT_UINT64(address))); + "system_iO %d (%d width) Address=%8.8X%8.8X\n", + function, bit_width, ACPI_FORMAT_UINT64(address))); /* Decode the function parameter */ @@ -343,7 +342,7 @@ acpi_ex_pci_config_space_handler(u32 function, struct acpi_pci_id *pci_id; u16 pci_register; - ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); + ACPI_FUNCTION_TRACE("ex_pci_config_space_handler"); /* * The arguments to acpi_os(Read|Write)pci_configuration are: @@ -361,7 +360,7 @@ acpi_ex_pci_config_space_handler(u32 function, pci_register = (u16) (u32) address; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Pci-Config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", + "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", function, bit_width, pci_id->segment, pci_id->bus, pci_id->device, pci_id->function, pci_register)); @@ -415,7 +414,7 @@ acpi_ex_cmos_space_handler(u32 function, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_cmos_space_handler); + ACPI_FUNCTION_TRACE("ex_cmos_space_handler"); return_ACPI_STATUS(status); } @@ -447,7 +446,7 @@ acpi_ex_pci_bar_space_handler(u32 function, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler); + ACPI_FUNCTION_TRACE("ex_pci_bar_space_handler"); return_ACPI_STATUS(status); } @@ -477,16 +476,23 @@ acpi_ex_data_table_space_handler(u32 function, acpi_integer * value, void *handler_context, void *region_context) { - ACPI_FUNCTION_TRACE(ex_data_table_space_handler); + acpi_status status = AE_OK; + u32 byte_width = ACPI_DIV_8(bit_width); + u32 i; + char *logical_addr_ptr; + + ACPI_FUNCTION_TRACE("ex_data_table_space_handler"); + + logical_addr_ptr = ACPI_PHYSADDR_TO_PTR(address); /* Perform the memory read or write */ switch (function) { case ACPI_READ: - ACPI_MEMCPY(ACPI_CAST_PTR(char, value), - ACPI_PHYSADDR_TO_PTR(address), - ACPI_DIV_8(bit_width)); + for (i = 0; i < byte_width; i++) { + ((char *)value)[i] = logical_addr_ptr[i]; + } break; case ACPI_WRITE: @@ -495,5 +501,5 @@ acpi_ex_data_table_space_handler(u32 function, return_ACPI_STATUS(AE_SUPPORT); } - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/executer/exresnte.c b/trunk/drivers/acpi/executer/exresnte.c index 3089b05a1368..01b26c80d22b 100644 --- a/trunk/drivers/acpi/executer/exresnte.c +++ b/trunk/drivers/acpi/executer/exresnte.c @@ -87,7 +87,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, struct acpi_namespace_node *node; acpi_object_type entry_type; - ACPI_FUNCTION_TRACE(ex_resolve_node_to_value); + ACPI_FUNCTION_TRACE("ex_resolve_node_to_value"); /* * The stack pointer points to a struct acpi_namespace_node (Node). Get the @@ -97,13 +97,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, source_desc = acpi_ns_get_attached_object(node); entry_type = acpi_ns_get_type((acpi_handle) node); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p source_desc=%p [%s]\n", node, source_desc, acpi_ut_get_type_name(entry_type))); if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) || (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { - /* There is always exactly one level of indirection */ node = ACPI_CAST_PTR(struct acpi_namespace_node, node->object); @@ -114,11 +113,10 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, /* * Several object types require no further processing: - * 1) Device/Thermal objects don't have a "real" subobject, return the Node + * 1) Devices rarely have an attached object, return the Node * 2) Method locals and arguments have a pseudo-Node */ - if ((entry_type == ACPI_TYPE_DEVICE) || - (entry_type == ACPI_TYPE_THERMAL) || + if (entry_type == ACPI_TYPE_DEVICE || (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { return_ACPI_STATUS(AE_OK); } @@ -143,7 +141,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, status = acpi_ds_get_package_arguments(source_desc); if (ACPI_SUCCESS(status)) { - /* Return an additional reference to the object */ obj_desc = source_desc; @@ -161,7 +158,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, status = acpi_ds_get_buffer_arguments(source_desc); if (ACPI_SUCCESS(status)) { - /* Return an additional reference to the object */ obj_desc = source_desc; @@ -203,7 +199,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_LOCAL_INDEX_FIELD: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "FieldRead Node=%p SourceDesc=%p Type=%X\n", + "field_read Node=%p source_desc=%p Type=%X\n", node, source_desc, entry_type)); status = @@ -217,6 +213,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_METHOD: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_THERMAL: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: @@ -243,8 +240,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, /* This is a ddb_handle */ /* Return an additional reference to the object */ - case AML_REF_OF_OP: - obj_desc = source_desc; acpi_ut_add_reference(obj_desc); break; diff --git a/trunk/drivers/acpi/executer/exresolv.c b/trunk/drivers/acpi/executer/exresolv.c index 6499de878017..1deed492fe88 100644 --- a/trunk/drivers/acpi/executer/exresolv.c +++ b/trunk/drivers/acpi/executer/exresolv.c @@ -78,7 +78,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, { acpi_status status; - ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr); + ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr); if (!stack_ptr || !*stack_ptr) { ACPI_ERROR((AE_INFO, "Internal - null pointer")); @@ -144,7 +144,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, union acpi_operand_object *obj_desc; u16 opcode; - ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); + ACPI_FUNCTION_TRACE("ex_resolve_object_to_value"); stack_desc = *stack_ptr; @@ -190,7 +190,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "[Arg/Local %X] ValueObj is %p\n", + "[Arg/Local %X] value_obj is %p\n", stack_desc->reference.offset, obj_desc)); @@ -239,7 +239,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, /* Invalid reference object */ ACPI_ERROR((AE_INFO, - "Unknown TargetType %X in Index/Reference obj %p", + "Unknown target_type %X in Index/Reference obj %p", stack_desc->reference.target_type, stack_desc)); status = AE_AML_INTERNAL; @@ -257,24 +257,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, case AML_INT_NAMEPATH_OP: /* Reference to a named object */ - /* Dereference the name */ - - if ((stack_desc->reference.node->type == - ACPI_TYPE_DEVICE) - || (stack_desc->reference.node->type == - ACPI_TYPE_THERMAL)) { - - /* These node types do not have 'real' subobjects */ - - *stack_ptr = (void *)stack_desc->reference.node; - } else { - /* Get the object pointed to by the namespace node */ - - *stack_ptr = - (stack_desc->reference.node)->object; - acpi_ut_add_reference(*stack_ptr); - } + /* Get the object pointed to by the namespace node */ + *stack_ptr = (stack_desc->reference.node)->object; + acpi_ut_add_reference(*stack_ptr); acpi_ut_remove_reference(stack_desc); break; @@ -307,7 +293,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, case ACPI_TYPE_LOCAL_INDEX_FIELD: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "FieldRead SourceDesc=%p Type=%X\n", + "field_read source_desc=%p Type=%X\n", stack_desc, ACPI_GET_OBJECT_TYPE(stack_desc))); @@ -351,7 +337,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, acpi_object_type type; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple); + ACPI_FUNCTION_TRACE("acpi_ex_resolve_multiple"); /* Operand can be either a namespace node or an operand descriptor */ @@ -396,16 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { switch (obj_desc->reference.opcode) { case AML_REF_OF_OP: - case AML_INT_NAMEPATH_OP: /* Dereference the reference pointer */ - if (obj_desc->reference.opcode == AML_REF_OF_OP) { - node = obj_desc->reference.object; - } else { /* AML_INT_NAMEPATH_OP */ - - node = obj_desc->reference.node; - } + node = obj_desc->reference.object; /* All "References" point to a NS node */ @@ -421,7 +401,6 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { - /* No object, use the NS node type */ type = acpi_ns_get_type(node); @@ -453,7 +432,6 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, */ obj_desc = *(obj_desc->reference.where); if (!obj_desc) { - /* NULL package elements are allowed */ type = 0; /* Uninitialized */ @@ -461,6 +439,39 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, } break; + case AML_INT_NAMEPATH_OP: + + /* Dereference the reference pointer */ + + node = obj_desc->reference.node; + + /* All "References" point to a NS node */ + + if (ACPI_GET_DESCRIPTOR_TYPE(node) != + ACPI_DESC_TYPE_NAMED) { + ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]", + node, + acpi_ut_get_descriptor_name(node))); + return_ACPI_STATUS(AE_AML_INTERNAL); + } + + /* Get the attached object */ + + obj_desc = acpi_ns_get_attached_object(node); + if (!obj_desc) { + /* No object, use the NS node type */ + + type = acpi_ns_get_type(node); + goto exit; + } + + /* Check for circular references */ + + if (obj_desc == operand) { + return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE); + } + break; + case AML_LOCAL_OP: case AML_ARG_OP: @@ -502,7 +513,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, case AML_DEBUG_OP: - /* The Debug Object is of type "DebugObject" */ + /* The Debug Object is of type "debug_object" */ type = ACPI_TYPE_DEBUG_OBJECT; goto exit; diff --git a/trunk/drivers/acpi/executer/exresop.c b/trunk/drivers/acpi/executer/exresop.c index 4c93d0972333..a1c000f5a415 100644 --- a/trunk/drivers/acpi/executer/exresop.c +++ b/trunk/drivers/acpi/executer/exresop.c @@ -77,7 +77,6 @@ acpi_ex_check_object_type(acpi_object_type type_needed, ACPI_FUNCTION_ENTRY(); if (type_needed == ACPI_TYPE_ANY) { - /* All types OK, so we don't perform any typechecks */ return (AE_OK); @@ -144,7 +143,7 @@ acpi_ex_resolve_operands(u16 opcode, acpi_object_type type_needed; u16 target_op = 0; - ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode); + ACPI_FUNCTION_TRACE_U32("ex_resolve_operands", opcode); op_info = acpi_ps_get_opcode_info(opcode); if (op_info->class == AML_CLASS_UNKNOWN) { @@ -159,7 +158,7 @@ acpi_ex_resolve_operands(u16 opcode, } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Opcode %X [%s] RequiredOperandTypes=%8.8X\n", + "Opcode %X [%s] required_operand_types=%8.8X\n", opcode, op_info->name, arg_types)); /* @@ -225,7 +224,6 @@ acpi_ex_resolve_operands(u16 opcode, } if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { - /* Decode the Reference */ op_info = acpi_ps_get_opcode_info(opcode); @@ -249,7 +247,7 @@ acpi_ex_resolve_operands(u16 opcode, ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, - "Operand is a Reference, RefOpcode [%s]\n", + "Operand is a Reference, ref_opcode [%s]\n", (acpi_ps_get_opcode_info (obj_desc-> reference. @@ -334,7 +332,6 @@ acpi_ex_resolve_operands(u16 opcode, } if (obj_desc->reference.opcode == AML_NAME_OP) { - /* Convert a named reference to the actual named object */ temp_node = obj_desc->reference.object; @@ -626,7 +623,7 @@ acpi_ex_resolve_operands(u16 opcode, default: ACPI_ERROR((AE_INFO, - "Needed [Region/RegionField], found [%s] %p", + "Needed [Region/region_field], found [%s] %p", acpi_ut_get_object_type_name (obj_desc), obj_desc)); @@ -665,7 +662,6 @@ acpi_ex_resolve_operands(u16 opcode, } if (target_op == AML_DEBUG_OP) { - /* Allow store of any object to the Debug object */ break; diff --git a/trunk/drivers/acpi/executer/exstore.c b/trunk/drivers/acpi/executer/exstore.c index 0456405ba019..3f020c0e2b95 100644 --- a/trunk/drivers/acpi/executer/exstore.c +++ b/trunk/drivers/acpi/executer/exstore.c @@ -82,7 +82,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, { u32 i; - ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); + ACPI_FUNCTION_TRACE_PTR("ex_do_debug_object", source_desc); ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", level, " ")); @@ -245,7 +245,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, acpi_status status = AE_OK; union acpi_operand_object *ref_desc = dest_desc; - ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc); + ACPI_FUNCTION_TRACE_PTR("ex_store", dest_desc); /* Validate parameters */ @@ -297,7 +297,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, ACPI_DUMP_STACK_ENTRY(source_desc); ACPI_DUMP_STACK_ENTRY(dest_desc); - ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ExStore", + ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ex_store", 2, "Target is not a Reference or Constant object"); @@ -396,7 +396,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, u8 value = 0; u32 i; - ACPI_FUNCTION_TRACE(ex_store_object_to_index); + ACPI_FUNCTION_TRACE("ex_store_object_to_index"); /* * Destination must be a reference pointer, and @@ -423,7 +423,6 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, } if (obj_desc) { - /* Decrement reference count by the ref count of the parent package */ for (i = 0; i < ((union acpi_operand_object *) @@ -503,7 +502,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, break; default: - ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField")); + ACPI_ERROR((AE_INFO, + "Target is not a Package or buffer_field")); status = AE_AML_OPERAND_TYPE; break; } @@ -548,7 +548,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, union acpi_operand_object *new_desc; acpi_object_type target_type; - ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc); + ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_node", source_desc); /* Get current type of the node, and object attached to Node */ @@ -572,7 +572,6 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, /* If no implicit conversion, drop into the default case below */ if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { - /* Force execution of default (no implicit conversion) */ target_type = ACPI_TYPE_ANY; diff --git a/trunk/drivers/acpi/executer/exstoren.c b/trunk/drivers/acpi/executer/exstoren.c index 591aaf0e18b3..42967baf760d 100644 --- a/trunk/drivers/acpi/executer/exstoren.c +++ b/trunk/drivers/acpi/executer/exstoren.c @@ -72,7 +72,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, union acpi_operand_object *source_desc = *source_desc_ptr; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_resolve_object); + ACPI_FUNCTION_TRACE("ex_resolve_object"); /* Ensure we have a Target that can be stored to */ @@ -97,7 +97,6 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, */ if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_LOCAL_REFERENCE) { - /* Resolve a reference object first */ status = @@ -122,7 +121,6 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, !((ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) { - /* Conversion successful but still not a valid type */ ACPI_ERROR((AE_INFO, @@ -201,7 +199,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, union acpi_operand_object *actual_src_desc; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc); + ACPI_FUNCTION_TRACE_PTR("ex_store_object_to_object", source_desc); actual_src_desc = source_desc; if (!dest_desc) { @@ -291,7 +289,6 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, } if (actual_src_desc != source_desc) { - /* Delete the intermediate (temporary) source object */ acpi_ut_remove_reference(actual_src_desc); diff --git a/trunk/drivers/acpi/executer/exstorob.c b/trunk/drivers/acpi/executer/exstorob.c index 99ebe5adfcda..6ab707087750 100644 --- a/trunk/drivers/acpi/executer/exstorob.c +++ b/trunk/drivers/acpi/executer/exstorob.c @@ -67,7 +67,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, u32 length; u8 *buffer; - ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc); + ACPI_FUNCTION_TRACE_PTR("ex_store_buffer_to_buffer", source_desc); /* We know that source_desc is a buffer by now */ @@ -80,7 +80,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, */ if ((target_desc->buffer.length == 0) || (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) { - target_desc->buffer.pointer = ACPI_ALLOCATE(length); + target_desc->buffer.pointer = ACPI_MEM_ALLOCATE(length); if (!target_desc->buffer.pointer) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -91,7 +91,6 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, /* Copy source buffer to target buffer */ if (length <= target_desc->buffer.length) { - /* Clear existing buffer and copy in the new one */ ACPI_MEMSET(target_desc->buffer.pointer, 0, @@ -103,7 +102,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, * NOTE: ACPI versions up to 3.0 specified that the buffer must be * truncated if the string is smaller than the buffer. However, "other" * implementations of ACPI never did this and thus became the defacto - * standard. ACPI 3.0_a changes this behavior such that the buffer + * standard. ACPi 3.0_a changes this behavior such that the buffer * is no longer truncated. */ @@ -114,7 +113,6 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, * copy must not truncate the original buffer. */ if (original_src_type == ACPI_TYPE_STRING) { - /* Set the new length of the target */ target_desc->buffer.length = length; @@ -158,7 +156,7 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc, u32 length; u8 *buffer; - ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc); + ACPI_FUNCTION_TRACE_PTR("ex_store_string_to_string", source_desc); /* We know that source_desc is a string by now */ @@ -185,14 +183,13 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc, */ if (target_desc->string.pointer && (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) { - /* Only free if not a pointer into the DSDT */ - ACPI_FREE(target_desc->string.pointer); + ACPI_MEM_FREE(target_desc->string.pointer); } - target_desc->string.pointer = ACPI_ALLOCATE_ZEROED((acpi_size) - length + 1); + target_desc->string.pointer = ACPI_MEM_CALLOCATE((acpi_size) + length + 1); if (!target_desc->string.pointer) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/trunk/drivers/acpi/executer/exsystem.c b/trunk/drivers/acpi/executer/exsystem.c index 52beee3674a0..ea9144f42e1f 100644 --- a/trunk/drivers/acpi/executer/exsystem.c +++ b/trunk/drivers/acpi/executer/exsystem.c @@ -68,7 +68,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout) acpi_status status; acpi_status status2; - ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); + ACPI_FUNCTION_TRACE("ex_system_wait_semaphore"); status = acpi_os_wait_semaphore(semaphore, 1, 0); if (ACPI_SUCCESS(status)) { @@ -76,7 +76,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout) } if (status == AE_TIME) { - /* We must wait, so unlock the interpreter */ acpi_ex_exit_interpreter(); @@ -91,7 +90,6 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout) status2 = acpi_ex_enter_interpreter(); if (ACPI_FAILURE(status2)) { - /* Report fatal error, could not acquire interpreter */ return_ACPI_STATUS(status2); @@ -193,7 +191,7 @@ acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ex_system_acquire_mutex", obj_desc); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -231,7 +229,7 @@ acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_system_release_mutex); + ACPI_FUNCTION_TRACE("ex_system_release_mutex"); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -265,7 +263,7 @@ acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_system_signal_event); + ACPI_FUNCTION_TRACE("ex_system_signal_event"); if (obj_desc) { status = acpi_os_signal_semaphore(obj_desc->event.semaphore, 1); @@ -295,7 +293,7 @@ acpi_ex_system_wait_event(union acpi_operand_object *time_desc, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ex_system_wait_event); + ACPI_FUNCTION_TRACE("ex_system_wait_event"); if (obj_desc) { status = diff --git a/trunk/drivers/acpi/executer/exutils.c b/trunk/drivers/acpi/executer/exutils.c index 982c8b65876f..f73a61aeb7ec 100644 --- a/trunk/drivers/acpi/executer/exutils.c +++ b/trunk/drivers/acpi/executer/exutils.c @@ -87,9 +87,9 @@ acpi_status acpi_ex_enter_interpreter(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ex_enter_interpreter); + ACPI_FUNCTION_TRACE("ex_enter_interpreter"); - status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); + status = acpi_ut_acquire_mutex(ACPI_MTX_EXECUTE); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); } @@ -123,9 +123,9 @@ void acpi_ex_exit_interpreter(void) { acpi_status status; - ACPI_FUNCTION_TRACE(ex_exit_interpreter); + ACPI_FUNCTION_TRACE("ex_exit_interpreter"); - status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); + status = acpi_ut_release_mutex(ACPI_MTX_EXECUTE); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); } @@ -189,12 +189,11 @@ u8 acpi_ex_acquire_global_lock(u32 field_flags) u8 locked = FALSE; acpi_status status; - ACPI_FUNCTION_TRACE(ex_acquire_global_lock); + ACPI_FUNCTION_TRACE("ex_acquire_global_lock"); /* Only attempt lock if the always_lock bit is set */ if (field_flags & AML_FIELD_LOCK_RULE_MASK) { - /* We should attempt to get the lock, wait forever */ status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER); @@ -226,17 +225,15 @@ void acpi_ex_release_global_lock(u8 locked_by_me) { acpi_status status; - ACPI_FUNCTION_TRACE(ex_release_global_lock); + ACPI_FUNCTION_TRACE("ex_release_global_lock"); /* Only attempt unlock if the caller locked it */ if (locked_by_me) { - /* OK, now release the lock */ status = acpi_ev_release_global_lock(); if (ACPI_FAILURE(status)) { - /* Report the error, but there isn't much else we can do */ ACPI_EXCEPTION((AE_INFO, status, @@ -266,7 +263,7 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) u32 num_digits; acpi_integer current_value; - ACPI_FUNCTION_TRACE(ex_digits_needed); + ACPI_FUNCTION_TRACE("ex_digits_needed"); /* acpi_integer is unsigned, so we don't worry about a '-' prefix */ diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index 1cd25784b7a4..e8165c4f162a 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -48,8 +48,6 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); -static int acpi_fan_suspend(struct acpi_device *device, int state); -static int acpi_fan_resume(struct acpi_device *device, int state); static struct acpi_driver acpi_fan_driver = { .name = ACPI_FAN_DRIVER_NAME, @@ -58,8 +56,6 @@ static struct acpi_driver acpi_fan_driver = { .ops = { .add = acpi_fan_add, .remove = acpi_fan_remove, - .suspend = acpi_fan_suspend, - .resume = acpi_fan_resume, }, }; @@ -210,10 +206,6 @@ static int acpi_fan_add(struct acpi_device *device) goto end; } - device->flags.force_power_state = 1; - acpi_bus_set_power(device->handle, state); - device->flags.force_power_state = 0; - result = acpi_fan_add_fs(device); if (result) goto end; @@ -247,38 +239,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return_VALUE(0); } -static int acpi_fan_suspend(struct acpi_device *device, int state) -{ - if (!device) - return -EINVAL; - - acpi_bus_set_power(device->handle, ACPI_STATE_D0); - - return AE_OK; -} - -static int acpi_fan_resume(struct acpi_device *device, int state) -{ - int result = 0; - int power_state = 0; - - if (!device) - return -EINVAL; - - result = acpi_bus_get_power(device->handle, &power_state); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading fan power state\n")); - return result; - } - - device->flags.force_power_state = 1; - acpi_bus_set_power(device->handle, power_state); - device->flags.force_power_state = 0; - - return result; -} - static int __init acpi_fan_init(void) { int result = 0; diff --git a/trunk/drivers/acpi/hardware/hwacpi.c b/trunk/drivers/acpi/hardware/hwacpi.c index de50fab2a910..ea2f13271ff1 100644 --- a/trunk/drivers/acpi/hardware/hwacpi.c +++ b/trunk/drivers/acpi/hardware/hwacpi.c @@ -63,7 +63,7 @@ acpi_status acpi_hw_initialize(void) { acpi_status status; - ACPI_FUNCTION_TRACE(hw_initialize); + ACPI_FUNCTION_TRACE("hw_initialize"); /* We must have the ACPI tables by the time we get here */ @@ -100,7 +100,7 @@ acpi_status acpi_hw_set_mode(u32 mode) acpi_status status; u32 retry; - ACPI_FUNCTION_TRACE(hw_set_mode); + ACPI_FUNCTION_TRACE("hw_set_mode"); /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, @@ -198,7 +198,7 @@ u32 acpi_hw_get_mode(void) acpi_status status; u32 value; - ACPI_FUNCTION_TRACE(hw_get_mode); + ACPI_FUNCTION_TRACE("hw_get_mode"); /* * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, diff --git a/trunk/drivers/acpi/hardware/hwgpe.c b/trunk/drivers/acpi/hardware/hwgpe.c index 608a3a60ee11..d84942d22dd5 100644 --- a/trunk/drivers/acpi/hardware/hwgpe.c +++ b/trunk/drivers/acpi/hardware/hwgpe.c @@ -214,7 +214,6 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - /* Disable all GPEs in this register */ status = acpi_hw_low_level_write(8, 0x00, @@ -251,7 +250,6 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info, /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - /* Clear status on all GPEs in this register */ status = acpi_hw_low_level_write(8, 0xFF, @@ -370,7 +368,7 @@ acpi_status acpi_hw_disable_all_gpes(void) { acpi_status status; - ACPI_FUNCTION_TRACE(hw_disable_all_gpes); + ACPI_FUNCTION_TRACE("hw_disable_all_gpes"); status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); @@ -393,7 +391,7 @@ acpi_status acpi_hw_enable_all_runtime_gpes(void) { acpi_status status; - ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes); + ACPI_FUNCTION_TRACE("hw_enable_all_runtime_gpes"); status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block); return_ACPI_STATUS(status); @@ -415,7 +413,7 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void) { acpi_status status; - ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes); + ACPI_FUNCTION_TRACE("hw_enable_all_wakeup_gpes"); status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block); return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c index ae142de19507..e1fe75498415 100644 --- a/trunk/drivers/acpi/hardware/hwregs.c +++ b/trunk/drivers/acpi/hardware/hwregs.c @@ -43,6 +43,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -61,21 +63,23 @@ ACPI_MODULE_NAME("hwregs") * DESCRIPTION: Clears all fixed and general purpose status bits * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * - * NOTE: TBD: Flags parameter is obsolete, to be removed - * ******************************************************************************/ acpi_status acpi_hw_clear_acpi_status(u32 flags) { acpi_status status; - acpi_cpu_flags lock_flags = 0; - ACPI_FUNCTION_TRACE(hw_clear_acpi_status); + ACPI_FUNCTION_TRACE("hw_clear_acpi_status"); ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", ACPI_BITMASK_ALL_FIXED_STATUS, (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); - lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, @@ -100,7 +104,9 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags) status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); unlock_and_exit: - acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + if (flags & ACPI_MTX_LOCK) { + (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE); + } return_ACPI_STATUS(status); } @@ -123,9 +129,10 @@ acpi_status acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) { acpi_status status = AE_OK; - struct acpi_evaluate_info *info; + struct acpi_parameter_info info; + char *sleep_state_name; - ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); + ACPI_FUNCTION_TRACE("acpi_get_sleep_type_data"); /* Validate parameters */ @@ -133,39 +140,34 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Allocate the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } + /* Evaluate the namespace object containing the values for this state */ - info->pathname = + info.parameters = NULL; + info.return_object = NULL; + sleep_state_name = ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); - /* Evaluate the namespace object containing the values for this state */ - - status = acpi_ns_evaluate(info); + status = acpi_ns_evaluate_by_name(sleep_state_name, &info); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "%s while evaluating SleepState [%s]\n", + "%s while evaluating sleep_state [%s]\n", acpi_format_exception(status), - info->pathname)); + sleep_state_name)); - goto cleanup; + return_ACPI_STATUS(status); } /* Must have a return object */ - if (!info->return_object) { + if (!info.return_object) { ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", - info->pathname)); + sleep_state_name)); status = AE_NOT_EXIST; } /* It must be of type Package */ - else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { + else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) { ACPI_ERROR((AE_INFO, "Sleep State return object is not a Package")); status = AE_AML_OPERAND_TYPE; @@ -178,7 +180,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) * by BIOS vendors seems to be to have 2 or more elements, at least * one per sleep type (A/B). */ - else if (info->return_object->package.count < 2) { + else if (info.return_object->package.count < 2) { ACPI_ERROR((AE_INFO, "Sleep State return package does not have at least two elements")); status = AE_AML_NO_OPERAND; @@ -186,42 +188,39 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) /* The first two elements must both be of type Integer */ - else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) + else if ((ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) || - (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) + (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) { ACPI_ERROR((AE_INFO, "Sleep State return package elements are not both Integers (%s, %s)", - acpi_ut_get_object_type_name(info->return_object-> + acpi_ut_get_object_type_name(info.return_object-> package.elements[0]), - acpi_ut_get_object_type_name(info->return_object-> + acpi_ut_get_object_type_name(info.return_object-> package.elements[1]))); status = AE_AML_OPERAND_TYPE; } else { /* Valid _Sx_ package size, type, and value */ *sleep_type_a = (u8) - (info->return_object->package.elements[0])->integer.value; + (info.return_object->package.elements[0])->integer.value; *sleep_type_b = (u8) - (info->return_object->package.elements[1])->integer.value; + (info.return_object->package.elements[1])->integer.value; } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "While evaluating SleepState [%s], bad Sleep object %p type %s", - info->pathname, info->return_object, - acpi_ut_get_object_type_name(info-> + "While evaluating sleep_state [%s], bad Sleep object %p type %s", + sleep_state_name, info.return_object, + acpi_ut_get_object_type_name(info. return_object))); } - acpi_ut_remove_reference(info->return_object); - - cleanup: - ACPI_FREE(info); + acpi_ut_remove_reference(info.return_object); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) +EXPORT_SYMBOL(acpi_get_sleep_type_data); /******************************************************************************* * @@ -234,12 +233,13 @@ ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) * DESCRIPTION: Map register_id into a register bitmask. * ******************************************************************************/ + struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) { ACPI_FUNCTION_ENTRY(); if (register_id > ACPI_BITREG_MAX) { - ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", + ACPI_ERROR((AE_INFO, "Invalid bit_register ID: %X", register_id)); return (NULL); } @@ -260,8 +260,6 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) * * DESCRIPTION: ACPI bit_register read function. * - * NOTE: TBD: Flags parameter is obsolete, to be removed - * ******************************************************************************/ acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) @@ -270,7 +268,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) struct acpi_bit_register_info *bit_reg_info; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_register); + ACPI_FUNCTION_TRACE("acpi_get_register"); /* Get the info structure corresponding to the requested ACPI Register */ @@ -279,14 +277,24 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) return_ACPI_STATUS(AE_BAD_PARAMETER); } + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } + /* Read from the register */ - status = acpi_hw_register_read(ACPI_MTX_LOCK, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, bit_reg_info->parent_register, ®ister_value); - if (ACPI_SUCCESS(status)) { + if (flags & ACPI_MTX_LOCK) { + (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE); + } + if (ACPI_SUCCESS(status)) { /* Normalize the value that was read */ register_value = @@ -303,7 +311,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_register) +EXPORT_SYMBOL(acpi_get_register); /******************************************************************************* * @@ -318,28 +326,31 @@ ACPI_EXPORT_SYMBOL(acpi_get_register) * * DESCRIPTION: ACPI Bit Register write function. * - * NOTE: TBD: Flags parameter is obsolete, to be removed - * ******************************************************************************/ + acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; acpi_status status; - acpi_cpu_flags lock_flags; - ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); + ACPI_FUNCTION_TRACE_U32("acpi_set_register", register_id); /* Get the info structure corresponding to the requested ACPI Register */ bit_reg_info = acpi_hw_get_bit_register_info(register_id); if (!bit_reg_info) { - ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", + ACPI_ERROR((AE_INFO, "Bad ACPI HW register_id: %X", register_id)); return_ACPI_STATUS(AE_BAD_PARAMETER); } - lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + if (flags & ACPI_MTX_LOCK) { + status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } /* Always do a register read first so we can insert the new bits */ @@ -447,7 +458,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) unlock_and_exit: - acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + if (flags & ACPI_MTX_LOCK) { + (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE); + } /* Normalize the value that was read */ @@ -461,7 +474,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_set_register) +EXPORT_SYMBOL(acpi_set_register); /****************************************************************************** * @@ -477,18 +490,21 @@ ACPI_EXPORT_SYMBOL(acpi_set_register) * given offset. * ******************************************************************************/ + acpi_status acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) { u32 value1 = 0; u32 value2 = 0; acpi_status status; - acpi_cpu_flags lock_flags = 0; - ACPI_FUNCTION_TRACE(hw_register_read); + ACPI_FUNCTION_TRACE("hw_register_read"); if (ACPI_MTX_LOCK == use_lock) { - lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } switch (register_id) { @@ -566,7 +582,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) unlock_and_exit: if (ACPI_MTX_LOCK == use_lock) { - acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE); } if (ACPI_SUCCESS(status)) { @@ -594,12 +610,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) { acpi_status status; - acpi_cpu_flags lock_flags = 0; - ACPI_FUNCTION_TRACE(hw_register_write); + ACPI_FUNCTION_TRACE("hw_register_write"); if (ACPI_MTX_LOCK == use_lock) { - lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + status = acpi_ut_acquire_mutex(ACPI_MTX_HARDWARE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } switch (register_id) { @@ -689,7 +707,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) unlock_and_exit: if (ACPI_MTX_LOCK == use_lock) { - acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + (void)acpi_ut_release_mutex(ACPI_MTX_HARDWARE); } return_ACPI_STATUS(status); @@ -715,7 +733,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) u64 address; acpi_status status; - ACPI_FUNCTION_NAME(hw_low_level_read); + ACPI_FUNCTION_NAME("hw_low_level_read"); /* * Must have a valid pointer to a GAS structure, and @@ -787,7 +805,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) u64 address; acpi_status status; - ACPI_FUNCTION_NAME(hw_low_level_write); + ACPI_FUNCTION_NAME("hw_low_level_write"); /* * Must have a valid pointer to a GAS structure, and diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 8bb43cae60c2..89269272fd62 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -42,6 +42,7 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include #include #define _COMPONENT ACPI_HARDWARE @@ -63,7 +64,7 @@ acpi_status acpi_set_firmware_waking_vector(acpi_physical_address physical_address) { - ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); + ACPI_FUNCTION_TRACE("acpi_set_firmware_waking_vector"); /* Set the vector */ @@ -78,8 +79,6 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) - /******************************************************************************* * * FUNCTION: acpi_get_firmware_waking_vector @@ -93,12 +92,13 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) * DESCRIPTION: Access function for the firmware_waking_vector field in FACS * ******************************************************************************/ + #ifdef ACPI_FUTURE_USAGE acpi_status acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) { - ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); + ACPI_FUNCTION_TRACE("acpi_get_firmware_waking_vector"); if (!physical_address) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -118,8 +118,6 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) return_ACPI_STATUS(AE_OK); } - -ACPI_EXPORT_SYMBOL(acpi_get_firmware_waking_vector) #endif /******************************************************************************* @@ -136,13 +134,14 @@ ACPI_EXPORT_SYMBOL(acpi_get_firmware_waking_vector) * various OS-specific tasks between the two steps. * ******************************************************************************/ + acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) { acpi_status status; struct acpi_object_list arg_list; union acpi_object arg; - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); + ACPI_FUNCTION_TRACE("acpi_enter_sleep_state_prep"); /* * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. @@ -207,8 +206,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) - /******************************************************************************* * * FUNCTION: acpi_enter_sleep_state @@ -221,6 +218,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ + acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) { u32 PM1Acontrol; @@ -230,7 +228,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) u32 in_value; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); + ACPI_FUNCTION_TRACE("acpi_enter_sleep_state"); if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { @@ -380,7 +378,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) +EXPORT_SYMBOL(acpi_enter_sleep_state); /******************************************************************************* * @@ -394,12 +392,13 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ + acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) { u32 in_value; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); + ACPI_FUNCTION_TRACE("acpi_enter_sleep_state_s4bios"); status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); @@ -444,7 +443,7 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) +EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios); /******************************************************************************* * @@ -458,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) * Called with interrupts ENABLED. * ******************************************************************************/ + acpi_status acpi_leave_sleep_state(u8 sleep_state) { struct acpi_object_list arg_list; @@ -468,7 +468,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) u32 PM1Acontrol; u32 PM1Bcontrol; - ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); + ACPI_FUNCTION_TRACE("acpi_leave_sleep_state"); /* * Set SLP_TYPE and SLP_EN to state S0. @@ -490,7 +490,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); if (ACPI_SUCCESS(status)) { - /* Clear SLP_EN and SLP_TYP fields */ PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | @@ -584,5 +583,3 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) return_ACPI_STATUS(status); } - -ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) diff --git a/trunk/drivers/acpi/hardware/hwtimer.c b/trunk/drivers/acpi/hardware/hwtimer.c index c4ec47c939fd..fc10b7cb456f 100644 --- a/trunk/drivers/acpi/hardware/hwtimer.c +++ b/trunk/drivers/acpi/hardware/hwtimer.c @@ -42,6 +42,7 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include #include #define _COMPONENT ACPI_HARDWARE @@ -60,13 +61,13 @@ ACPI_MODULE_NAME("hwtimer") ******************************************************************************/ acpi_status acpi_get_timer_resolution(u32 * resolution) { - ACPI_FUNCTION_TRACE(acpi_get_timer_resolution); + ACPI_FUNCTION_TRACE("acpi_get_timer_resolution"); if (!resolution) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - if (acpi_gbl_FADT->tmr_val_ext == 0) { + if (0 == acpi_gbl_FADT->tmr_val_ext) { *resolution = 24; } else { *resolution = 32; @@ -75,8 +76,6 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution) - /****************************************************************************** * * FUNCTION: acpi_get_timer @@ -88,11 +87,12 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution) * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks). * ******************************************************************************/ + acpi_status acpi_get_timer(u32 * ticks) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_timer); + ACPI_FUNCTION_TRACE("acpi_get_timer"); if (!ticks) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -103,7 +103,7 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_timer) +EXPORT_SYMBOL(acpi_get_timer); /****************************************************************************** * @@ -133,6 +133,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer) * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes * ******************************************************************************/ + acpi_status acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) { @@ -140,7 +141,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) u32 delta_ticks; acpi_integer quotient; - ACPI_FUNCTION_TRACE(acpi_get_timer_duration); + ACPI_FUNCTION_TRACE("acpi_get_timer_duration"); if (!time_elapsed) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -153,8 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; } else if (start_ticks > end_ticks) { - if (acpi_gbl_FADT->tmr_val_ext == 0) { - + if (0 == acpi_gbl_FADT->tmr_val_ext) { /* 24-bit Timer */ delta_ticks = @@ -183,4 +183,4 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_timer_duration) +EXPORT_SYMBOL(acpi_get_timer_duration); diff --git a/trunk/drivers/acpi/hotkey.c b/trunk/drivers/acpi/hotkey.c index c25b2b92edcf..2e2e4051dfa7 100644 --- a/trunk/drivers/acpi/hotkey.c +++ b/trunk/drivers/acpi/hotkey.c @@ -723,8 +723,6 @@ get_parms(char *config_record, goto do_fail; count = tmp1 - tmp; *action_handle = (char *)kmalloc(count + 1, GFP_KERNEL); - if (!*action_handle) - goto do_fail; strncpy(*action_handle, tmp, count); *(*action_handle + count) = 0; diff --git a/trunk/drivers/acpi/ibm_acpi.c b/trunk/drivers/acpi/ibm_acpi.c index 15fc12482ba0..262b1f41335a 100644 --- a/trunk/drivers/acpi/ibm_acpi.c +++ b/trunk/drivers/acpi/ibm_acpi.c @@ -567,69 +567,6 @@ static int bluetooth_write(char *buf) return 0; } -static int wan_supported; - -static int wan_init(void) -{ - wan_supported = hkey_handle && - acpi_evalf(hkey_handle, NULL, "GWAN", "qv"); - - return 0; -} - -static int wan_status(void) -{ - int status; - - if (!wan_supported || - !acpi_evalf(hkey_handle, &status, "GWAN", "d")) - status = 0; - - return status; -} - -static int wan_read(char *p) -{ - int len = 0; - int status = wan_status(); - - if (!wan_supported) - len += sprintf(p + len, "status:\t\tnot supported\n"); - else if (!(status & 1)) - len += sprintf(p + len, "status:\t\tnot installed\n"); - else { - len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1)); - len += sprintf(p + len, "commands:\tenable, disable\n"); - } - - return len; -} - -static int wan_write(char *buf) -{ - int status = wan_status(); - char *cmd; - int do_cmd = 0; - - if (!wan_supported) - return -ENODEV; - - while ((cmd = next_cmd(&buf))) { - if (strlencmp(cmd, "enable") == 0) { - status |= 2; - } else if (strlencmp(cmd, "disable") == 0) { - status &= ~2; - } else - return -EINVAL; - do_cmd = 1; - } - - if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) - return -EIO; - - return 0; -} - static int video_supported; static int video_orig_autosw; @@ -1625,13 +1562,6 @@ static struct ibm_struct ibms[] = { .read = bluetooth_read, .write = bluetooth_write, }, - { - .name = "wan", - .init = wan_init, - .read = wan_read, - .write = wan_write, - .experimental = 1, - }, { .name = "video", .init = video_init, diff --git a/trunk/drivers/acpi/motherboard.c b/trunk/drivers/acpi/motherboard.c index d51d68f5dd8d..468244147ec1 100644 --- a/trunk/drivers/acpi/motherboard.c +++ b/trunk/drivers/acpi/motherboard.c @@ -37,7 +37,7 @@ ACPI_MODULE_NAME("acpi_motherboard") #define ACPI_MB_HID2 "PNP0C02" /** * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved - * Doesn't care about the failure of 'request_region', since other may reserve + * Doesn't care about the failure of 'request_region', since other may reserve * the io ports as well */ #define IS_RESERVED_ADDR(base, len) \ @@ -46,7 +46,7 @@ ACPI_MODULE_NAME("acpi_motherboard") /* * Clearing the flag (IORESOURCE_BUSY) allows drivers to use * the io ports if they really know they can use it, while - * still preventing hotplug PCI devices from using it. + * still preventing hotplug PCI devices from using it. */ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) { @@ -123,54 +123,49 @@ static struct acpi_driver acpi_motherboard_driver2 = { }, }; -static void __init acpi_request_region (struct acpi_generic_address *addr, - unsigned int length, char *desc) -{ - if (!addr->address || !length) - return; - - if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) - request_region(addr->address, length, desc); - else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) - request_mem_region(addr->address, length, desc); -} - static void __init acpi_reserve_resources(void) { - acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk, - acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK"); + if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) + request_region(acpi_gbl_FADT->xpm1a_evt_blk.address, + acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK"); - acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk, - acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK"); + if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len) + request_region(acpi_gbl_FADT->xpm1b_evt_blk.address, + acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK"); - acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk, - acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK"); + if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) + request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address, + acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK"); - acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk, - acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK"); + if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len) + request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address, + acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK"); - if (acpi_gbl_FADT->pm_tm_len == 4) - acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR"); + if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4) + request_region(acpi_gbl_FADT->xpm_tmr_blk.address, 4, "PM_TMR"); - acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk, - acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK"); + if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len) + request_region(acpi_gbl_FADT->xpm2_cnt_blk.address, + acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK"); /* Length of GPE blocks must be a non-negative multiple of 2 */ - if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1)) - acpi_request_region(&acpi_gbl_FADT->xgpe0_blk, - acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK"); + if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len && + !(acpi_gbl_FADT->gpe0_blk_len & 0x1)) + request_region(acpi_gbl_FADT->xgpe0_blk.address, + acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK"); - if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1)) - acpi_request_region(&acpi_gbl_FADT->xgpe1_blk, - acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK"); + if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len && + !(acpi_gbl_FADT->gpe1_blk_len & 0x1)) + request_region(acpi_gbl_FADT->xgpe1_blk.address, + acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK"); } static int __init acpi_motherboard_init(void) { acpi_bus_register_driver(&acpi_motherboard_driver1); acpi_bus_register_driver(&acpi_motherboard_driver2); - /* + /* * Guarantee motherboard IO reservation first * This module must run after scan.c */ diff --git a/trunk/drivers/acpi/namespace/nsaccess.c b/trunk/drivers/acpi/namespace/nsaccess.c index 48fadade52e2..1149bc18fb35 100644 --- a/trunk/drivers/acpi/namespace/nsaccess.c +++ b/trunk/drivers/acpi/namespace/nsaccess.c @@ -70,7 +70,7 @@ acpi_status acpi_ns_root_initialize(void) union acpi_operand_object *obj_desc; acpi_string val = NULL; - ACPI_FUNCTION_TRACE(ns_root_initialize); + ACPI_FUNCTION_TRACE("ns_root_initialize"); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -98,7 +98,6 @@ acpi_status acpi_ns_root_initialize(void) "Entering predefined entries into namespace\n")); for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { - /* _OSI is optional for now, will be permanent later */ if (!ACPI_STRCMP(init_val->name, "_OSI") @@ -157,7 +156,7 @@ acpi_status acpi_ns_root_initialize(void) #if defined (ACPI_ASL_COMPILER) - /* Save the parameter count for the i_aSL compiler */ + /* save the parameter count for the i_aSL compiler */ new_node->value = obj_desc->method.param_count; #else @@ -259,8 +258,10 @@ acpi_status acpi_ns_root_initialize(void) /* Save a handle to "_GPE", it is always present */ if (ACPI_SUCCESS(status)) { - status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, - &acpi_gbl_fadt_gpe_device); + status = + acpi_ns_get_node_by_path("\\_GPE", NULL, + ACPI_NS_NO_UPSEARCH, + &acpi_gbl_fadt_gpe_device); } return_ACPI_STATUS(status); @@ -309,17 +310,17 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, acpi_object_type type_to_check_for; acpi_object_type this_search_type; u32 search_parent_flag = ACPI_NS_SEARCH_PARENT; - u32 local_flags; + u32 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | + ACPI_NS_SEARCH_PARENT); - ACPI_FUNCTION_TRACE(ns_lookup); + ACPI_FUNCTION_TRACE("ns_lookup"); if (!return_node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT); - *return_node = ACPI_ENTRY_NOT_FOUND; acpi_gbl_ns_lookup_count++; + *return_node = ACPI_ENTRY_NOT_FOUND; if (!acpi_gbl_root_node) { return_ACPI_STATUS(AE_NO_NAMESPACE); @@ -345,17 +346,14 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, return_ACPI_STATUS(AE_AML_INTERNAL); } - if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { - /* - * This node might not be a actual "scope" node (such as a - * Device/Method, etc.) It could be a Package or other object node. - * Backup up the tree to find the containing scope node. - */ - while (!acpi_ns_opens_scope(prefix_node->type) && - prefix_node->type != ACPI_TYPE_ANY) { - prefix_node = - acpi_ns_get_parent_node(prefix_node); - } + /* + * This node might not be a actual "scope" node (such as a + * Device/Method, etc.) It could be a Package or other object node. + * Backup up the tree to find the containing scope node. + */ + while (!acpi_ns_opens_scope(prefix_node->type) && + prefix_node->type != ACPI_TYPE_ANY) { + prefix_node = acpi_ns_get_parent_node(prefix_node); } } @@ -367,7 +365,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, * Begin examination of the actual pathname */ if (!pathname) { - /* A Null name_path is allowed and refers to the root */ num_segments = 0; @@ -392,7 +389,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, * to the current scope). */ if (*path == (u8) AML_ROOT_PREFIX) { - /* Pathname is fully qualified, start from the root */ this_node = acpi_gbl_root_node; @@ -420,7 +416,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, this_node = prefix_node; num_carats = 0; while (*path == (u8) AML_PARENT_PREFIX) { - /* Name is fully qualified, no search rules apply */ search_parent_flag = ACPI_NS_NO_UPSEARCH; @@ -435,7 +430,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, num_carats++; this_node = acpi_ns_get_parent_node(this_node); if (!this_node) { - /* Current scope has no parent scope */ ACPI_ERROR((AE_INFO, @@ -575,7 +569,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, &this_node); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) { - /* Name not found in ACPI namespace */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, @@ -609,11 +602,10 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && (this_node->type != ACPI_TYPE_ANY) && (this_node->type != type_to_check_for)) { - /* Complain about a type mismatch */ ACPI_WARNING((AE_INFO, - "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", + "ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)", ACPI_CAST_PTR(char, &simple_name), acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name diff --git a/trunk/drivers/acpi/namespace/nsalloc.c b/trunk/drivers/acpi/namespace/nsalloc.c index dc3f0739a46b..9b871f38b61b 100644 --- a/trunk/drivers/acpi/namespace/nsalloc.c +++ b/trunk/drivers/acpi/namespace/nsalloc.c @@ -47,6 +47,9 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsalloc") +/* Local prototypes */ +static void acpi_ns_remove_reference(struct acpi_namespace_node *node); + /******************************************************************************* * * FUNCTION: acpi_ns_create_node @@ -58,13 +61,14 @@ ACPI_MODULE_NAME("nsalloc") * DESCRIPTION: Create a namespace node * ******************************************************************************/ + struct acpi_namespace_node *acpi_ns_create_node(u32 name) { struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(ns_create_node); + ACPI_FUNCTION_TRACE("ns_create_node"); - node = acpi_os_acquire_object(acpi_gbl_namespace_cache); + node = ACPI_MEM_CALLOCATE(sizeof(struct acpi_namespace_node)); if (!node) { return_PTR(NULL); } @@ -72,7 +76,9 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); node->name.integer = name; + node->reference_count = 1; ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED); + return_PTR(node); } @@ -94,7 +100,7 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) struct acpi_namespace_node *prev_node; struct acpi_namespace_node *next_node; - ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); + ACPI_FUNCTION_TRACE_PTR("ns_delete_node", node); parent_node = acpi_ns_get_parent_node(node); @@ -109,7 +115,6 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) } if (prev_node) { - /* Node is not first child, unlink it */ prev_node->peer = next_node->peer; @@ -120,7 +125,6 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) /* Node is first child (has no previous peer) */ if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { - /* No peers at all */ parent_node->child = NULL; @@ -133,10 +137,10 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); /* - * Detach an object if there is one, then delete the node + * Detach an object if there is one then delete the node */ acpi_ns_detach_object(node); - (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); + ACPI_MEM_FREE(node); return_VOID; } @@ -167,7 +171,7 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp acpi_owner_id owner_id = 0; struct acpi_namespace_node *child_node; - ACPI_FUNCTION_TRACE(ns_install_node); + ACPI_FUNCTION_TRACE("ns_install_node"); /* * Get the owner ID from the Walk state @@ -212,6 +216,14 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp acpi_ut_get_type_name(parent_node->type), parent_node)); + /* + * Increment the reference count(s) of all parents up to + * the root! + */ + while ((node = acpi_ns_get_parent_node(node)) != NULL) { + node->reference_count++; + } + return_VOID; } @@ -232,9 +244,10 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) { struct acpi_namespace_node *child_node; struct acpi_namespace_node *next_node; + struct acpi_namespace_node *node; u8 flags; - ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); + ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node); if (!parent_node) { return_VOID; @@ -251,7 +264,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) * Deallocate all children at this level */ do { - /* Get the things we need */ next_node = child_node->peer; @@ -277,10 +289,26 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) */ acpi_ns_detach_object(child_node); + /* + * Decrement the reference count(s) of all parents up to + * the root! (counts were incremented when the node was created) + */ + node = child_node; + while ((node = acpi_ns_get_parent_node(node)) != NULL) { + node->reference_count--; + } + + /* There should be only one reference remaining on this node */ + + if (child_node->reference_count != 1) { + ACPI_WARNING((AE_INFO, + "Existing references (%d) on node being deleted (%p)", + child_node->reference_count, child_node)); + } + /* Now we can delete the node */ - (void)acpi_os_release_object(acpi_gbl_namespace_cache, - child_node); + ACPI_MEM_FREE(child_node); /* And move on to the next child in the list */ @@ -313,7 +341,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) struct acpi_namespace_node *child_node = NULL; u32 level = 1; - ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); + ACPI_FUNCTION_TRACE("ns_delete_namespace_subtree"); if (!parent_node) { return_VOID; @@ -324,14 +352,11 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) * to where we started. */ while (level > 0) { - /* Get the next node in this scope (NULL if none) */ - child_node = - acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, - child_node); + child_node = acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, + child_node); if (child_node) { - /* Found a child node - detach any attached object */ acpi_ns_detach_object(child_node); @@ -374,6 +399,55 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) return_VOID; } +/******************************************************************************* + * + * FUNCTION: acpi_ns_remove_reference + * + * PARAMETERS: Node - Named node whose reference count is to be + * decremented + * + * RETURN: None. + * + * DESCRIPTION: Remove a Node reference. Decrements the reference count + * of all parent Nodes up to the root. Any node along + * the way that reaches zero references is freed. + * + ******************************************************************************/ + +static void acpi_ns_remove_reference(struct acpi_namespace_node *node) +{ + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *this_node; + + ACPI_FUNCTION_ENTRY(); + + /* + * Decrement the reference count(s) of this node and all + * nodes up to the root, Delete anything with zero remaining references. + */ + this_node = node; + while (this_node) { + /* Prepare to move up to parent */ + + parent_node = acpi_ns_get_parent_node(this_node); + + /* Decrement the reference count on this node */ + + this_node->reference_count--; + + /* Delete the node if no more references */ + + if (!this_node->reference_count) { + /* Delete all children and delete the node */ + + acpi_ns_delete_children(this_node); + acpi_ns_delete_node(this_node); + } + + this_node = parent_node; + } +} + /******************************************************************************* * * FUNCTION: acpi_ns_delete_namespace_by_owner @@ -395,15 +469,15 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) u32 level; struct acpi_namespace_node *parent_node; - ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id); + ACPI_FUNCTION_TRACE_U32("ns_delete_namespace_by_owner", owner_id); if (owner_id == 0) { return_VOID; } - deletion_node = NULL; parent_node = acpi_gbl_root_node; child_node = NULL; + deletion_node = NULL; level = 1; /* @@ -420,14 +494,12 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) child_node); if (deletion_node) { - acpi_ns_delete_children(deletion_node); - acpi_ns_delete_node(deletion_node); + acpi_ns_remove_reference(deletion_node); deletion_node = NULL; } if (child_node) { if (child_node->owner_id == owner_id) { - /* Found a matching child node - detach any attached object */ acpi_ns_detach_object(child_node); diff --git a/trunk/drivers/acpi/namespace/nsdump.c b/trunk/drivers/acpi/namespace/nsdump.c index d72df66aa965..a2807317a84b 100644 --- a/trunk/drivers/acpi/namespace/nsdump.c +++ b/trunk/drivers/acpi/namespace/nsdump.c @@ -75,7 +75,7 @@ void acpi_ns_print_pathname(u32 num_segments, char *pathname) { acpi_native_uint i; - ACPI_FUNCTION_NAME(ns_print_pathname); + ACPI_FUNCTION_NAME("ns_print_pathname"); if (!(acpi_dbg_level & ACPI_LV_NAMES) || !(acpi_dbg_layer & ACPI_NAMESPACE)) { @@ -123,7 +123,7 @@ void acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component) { - ACPI_FUNCTION_TRACE(ns_dump_pathname); + ACPI_FUNCTION_TRACE("ns_dump_pathname"); /* Do this only if the requested debug level and component are enabled */ @@ -167,7 +167,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, u32 dbg_level; u32 i; - ACPI_FUNCTION_NAME(ns_dump_one_object); + ACPI_FUNCTION_NAME("ns_dump_one_object"); /* Is output enabled? */ @@ -191,7 +191,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, } if (!(info->display_type & ACPI_DISPLAY_SHORT)) { - /* Indent the object according to the level */ acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " "); @@ -204,9 +203,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, } if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { - this_node->name.integer = - acpi_ut_repair_name(this_node->name.integer); - ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", this_node->name.integer)); } @@ -230,7 +226,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, case ACPI_DISPLAY_SUMMARY: if (!obj_desc) { - /* No attached object, we are done */ acpi_os_printf("\n"); @@ -424,7 +419,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, acpi_os_printf("O:%p", obj_desc); if (!obj_desc) { - /* No attached object, we are done */ acpi_os_printf("\n"); @@ -675,7 +669,7 @@ void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth) { acpi_handle search_handle = search_base; - ACPI_FUNCTION_TRACE(ns_dump_tables); + ACPI_FUNCTION_TRACE("ns_dump_tables"); if (!acpi_gbl_root_node) { /* @@ -688,7 +682,6 @@ void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth) } if (ACPI_NS_ALL == search_base) { - /* Entire namespace */ search_handle = acpi_gbl_root_node; diff --git a/trunk/drivers/acpi/namespace/nsdumpdv.c b/trunk/drivers/acpi/namespace/nsdumpdv.c index c6bf5d30fca3..aff899a935e3 100644 --- a/trunk/drivers/acpi/namespace/nsdumpdv.c +++ b/trunk/drivers/acpi/namespace/nsdumpdv.c @@ -74,7 +74,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, acpi_status status; u32 i; - ACPI_FUNCTION_NAME(ns_dump_one_device); + ACPI_FUNCTION_NAME("ns_dump_one_device"); status = acpi_ns_dump_one_object(obj_handle, level, context, return_value); @@ -92,7 +92,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, info->hardware_id.value, ACPI_FORMAT_UINT64(info->address), info->current_status)); - ACPI_FREE(info); + ACPI_MEM_FREE(info); } return (status); @@ -115,7 +115,7 @@ void acpi_ns_dump_root_devices(void) acpi_handle sys_bus_handle; acpi_status status; - ACPI_FUNCTION_NAME(ns_dump_root_devices); + ACPI_FUNCTION_NAME("ns_dump_root_devices"); /* Only dump the table if tracing is enabled */ diff --git a/trunk/drivers/acpi/namespace/nseval.c b/trunk/drivers/acpi/namespace/nseval.c index 4b0a4a8c9843..19d7b94d40c3 100644 --- a/trunk/drivers/acpi/namespace/nseval.c +++ b/trunk/drivers/acpi/namespace/nseval.c @@ -1,6 +1,7 @@ /******************************************************************************* * - * Module Name: nseval - Object evaluation, includes control method execution + * Module Name: nseval - Object evaluation interfaces -- includes control + * method lookup and execution. * ******************************************************************************/ @@ -49,14 +50,196 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nseval") +/* Local prototypes */ +static acpi_status +acpi_ns_execute_control_method(struct acpi_parameter_info *info); + +static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info); + +/******************************************************************************* + * + * FUNCTION: acpi_ns_evaluate_relative + * + * PARAMETERS: Pathname - Name of method to execute, If NULL, the + * handle is the object to execute + * Info - Method info block, contains: + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * Params - List of parameters to pass to the method, + * terminated by NULL. Params itself may be + * NULL if no parameters are being passed. + * + * RETURN: Status + * + * DESCRIPTION: Evaluate the object or find and execute the requested method + * + * MUTEX: Locks Namespace + * + ******************************************************************************/ + +acpi_status +acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info) +{ + acpi_status status; + struct acpi_namespace_node *node = NULL; + union acpi_generic_state *scope_info; + char *internal_path = NULL; + + ACPI_FUNCTION_TRACE("ns_evaluate_relative"); + + /* + * Must have a valid object handle + */ + if (!info || !info->node) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + /* Build an internal name string for the method */ + + status = acpi_ns_internalize_name(pathname, &internal_path); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + scope_info = acpi_ut_create_generic_state(); + if (!scope_info) { + goto cleanup1; + } + + /* Get the prefix handle and Node */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + info->node = acpi_ns_map_handle_to_node(info->node); + if (!info->node) { + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + status = AE_BAD_PARAMETER; + goto cleanup; + } + + /* Lookup the name in the namespace */ + + scope_info->scope.node = info->node; + status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY, + ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, + &node); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", + pathname, acpi_format_exception(status))); + goto cleanup; + } + + /* + * Now that we have a handle to the object, we can attempt to evaluate it. + */ + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", + pathname, node, acpi_ns_get_attached_object(node))); + + info->node = node; + status = acpi_ns_evaluate_by_handle(info); + + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, + "*** Completed eval of object %s ***\n", pathname)); + + cleanup: + acpi_ut_delete_generic_state(scope_info); + + cleanup1: + ACPI_MEM_FREE(internal_path); + return_ACPI_STATUS(status); +} + /******************************************************************************* * - * FUNCTION: acpi_ns_evaluate + * FUNCTION: acpi_ns_evaluate_by_name * - * PARAMETERS: Info - Evaluation info block, contains: - * prefix_node - Prefix or Method/Object Node to execute - * Pathname - Name of method to execute, If NULL, the - * Node is the object to execute + * PARAMETERS: Pathname - Fully qualified pathname to the object + * Info - Method info block, contains: + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * Params - List of parameters to pass to the method, + * terminated by NULL. Params itself may be + * NULL if no parameters are being passed. + * + * RETURN: Status + * + * DESCRIPTION: Evaluate the object or rind and execute the requested method + * passing the given parameters + * + * MUTEX: Locks Namespace + * + ******************************************************************************/ + +acpi_status +acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info) +{ + acpi_status status; + char *internal_path = NULL; + + ACPI_FUNCTION_TRACE("ns_evaluate_by_name"); + + /* Build an internal name string for the method */ + + status = acpi_ns_internalize_name(pathname, &internal_path); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Lookup the name in the namespace */ + + status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, + ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, + &info->node); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, + "Object at [%s] was not found, status=%.4X\n", + pathname, status)); + goto cleanup; + } + + /* + * Now that we have a handle to the object, we can attempt to evaluate it. + */ + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", + pathname, info->node, + acpi_ns_get_attached_object(info->node))); + + status = acpi_ns_evaluate_by_handle(info); + + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, + "*** Completed eval of object %s ***\n", pathname)); + + cleanup: + + /* Cleanup */ + + if (internal_path) { + ACPI_MEM_FREE(internal_path); + } + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_evaluate_by_handle + * + * PARAMETERS: Info - Method info block, contains: + * Node - Method/Object Node to execute * Parameters - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. @@ -65,21 +248,29 @@ ACPI_MODULE_NAME("nseval") * parameter_type - Type of Parameter list * return_object - Where to put method's return value (if * any). If NULL, no value is returned. - * Flags - ACPI_IGNORE_RETURN_VALUE to delete return * * RETURN: Status * - * DESCRIPTION: Execute a control method or return the current value of an - * ACPI namespace object. + * DESCRIPTION: Evaluate object or execute the requested method passing the + * given parameters * - * MUTEX: Locks interpreter + * MUTEX: Locks Namespace * ******************************************************************************/ -acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) + +acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info) { acpi_status status; - ACPI_FUNCTION_TRACE(ns_evaluate); + ACPI_FUNCTION_TRACE("ns_evaluate_by_handle"); + + /* Check if namespace has been initialized */ + + if (!acpi_gbl_root_node) { + return_ACPI_STATUS(AE_NO_NAMESPACE); + } + + /* Parameter Validation */ if (!info) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -89,120 +280,202 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) info->return_object = NULL; - /* - * Get the actual namespace node for the target object. Handles these cases: - * - * 1) Null node, Pathname (absolute path) - * 2) Node, Pathname (path relative to Node) - * 3) Node, Null Pathname - */ - status = acpi_ns_get_node(info->prefix_node, info->pathname, - ACPI_NS_NO_UPSEARCH, &info->resolved_node); + /* Get the prefix handle and Node */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + info->node = acpi_ns_map_handle_to_node(info->node); + if (!info->node) { + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + /* * For a method alias, we must grab the actual method node so that proper * scoping context will be established before execution. */ - if (acpi_ns_get_type(info->resolved_node) == - ACPI_TYPE_LOCAL_METHOD_ALIAS) { - info->resolved_node = + if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { + info->node = ACPI_CAST_PTR(struct acpi_namespace_node, - info->resolved_node->object); + info->node->object); } - ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname, - info->resolved_node, - acpi_ns_get_attached_object(info->resolved_node))); - /* * Two major cases here: - * - * 1) The object is a control method -- execute it + * 1) The object is an actual control method -- execute it. * 2) The object is not a method -- just return it's current value + * + * In both cases, the namespace is unlocked by the acpi_ns* procedure */ - if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) { + if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) { + /* + * Case 1) We have an actual control method to execute + */ + status = acpi_ns_execute_control_method(info); + } else { /* - * 1) Object is a control method - execute it + * Case 2) Object is NOT a method, just return its current value */ + status = acpi_ns_get_object_value(info); + } + + /* + * Check if there is a return value on the stack that must be dealt with + */ + if (status == AE_CTRL_RETURN_VALUE) { + /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ - /* Verify that there is a method object associated with this node */ + status = AE_OK; + } - info->obj_desc = - acpi_ns_get_attached_object(info->resolved_node); - if (!info->obj_desc) { - ACPI_ERROR((AE_INFO, - "Control method has no attached sub-object")); - return_ACPI_STATUS(AE_NULL_OBJECT); - } + /* + * Namespace was unlocked by the handling acpi_ns* function, so we + * just return + */ + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_execute_control_method + * + * PARAMETERS: Info - Method info block, contains: + * Node - Method Node to execute + * obj_desc - Method object + * Parameters - List of parameters to pass to the method, + * terminated by NULL. Params itself may be + * NULL if no parameters are being passed. + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * parameter_type - Type of Parameter list + * return_object - Where to put method's return value (if + * any). If NULL, no value is returned. + * + * RETURN: Status + * + * DESCRIPTION: Execute the requested method passing the given parameters + * + * MUTEX: Assumes namespace is locked + * + ******************************************************************************/ - ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", - ACPI_LV_INFO, _COMPONENT); +static acpi_status +acpi_ns_execute_control_method(struct acpi_parameter_info *info) +{ + acpi_status status; - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Method at AML address %p Length %X\n", - info->obj_desc->method.aml_start + 1, - info->obj_desc->method.aml_length - 1)); + ACPI_FUNCTION_TRACE("ns_execute_control_method"); - /* - * Any namespace deletion must acquire both the namespace and - * interpreter locks to ensure that no thread is using the portion of - * the namespace that is being deleted. - * - * Execute the method via the interpreter. The interpreter is locked - * here before calling into the AML parser - */ - status = acpi_ex_enter_interpreter(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } + /* Verify that there is a method associated with this object */ - status = acpi_ps_execute_method(info); - acpi_ex_exit_interpreter(); - } else { - /* - * 2) Object is not a method, return its current value - */ + info->obj_desc = acpi_ns_get_attached_object(info->node); + if (!info->obj_desc) { + ACPI_ERROR((AE_INFO, "No attached method object")); - /* - * Objects require additional resolution steps (e.g., the Node may be - * a field that must be read, etc.) -- we can't just grab the object - * out of the node. - * - * Use resolve_node_to_value() to get the associated value. - * - * NOTE: we can get away with passing in NULL for a walk state because - * resolved_node is guaranteed to not be a reference to either a method - * local or a method argument (because this interface is never called - * from a running method.) - * - * Even though we do not directly invoke the interpreter for object - * resolution, we must lock it because we could access an opregion. - * The opregion access code assumes that the interpreter is locked. - */ - status = acpi_ex_enter_interpreter(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(AE_NULL_OBJECT); + } - /* Function has a strange interface */ + ACPI_DUMP_PATHNAME(info->node, "Execute Method:", + ACPI_LV_INFO, _COMPONENT); - status = - acpi_ex_resolve_node_to_value(&info->resolved_node, NULL); - acpi_ex_exit_interpreter(); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", + info->obj_desc->method.aml_start + 1, + info->obj_desc->method.aml_length - 1)); + /* + * Unlock the namespace before execution. This allows namespace access + * via the external Acpi* interfaces while a method is being executed. + * However, any namespace deletion must acquire both the namespace and + * interpreter locks to ensure that no thread is using the portion of the + * namespace that is being deleted. + */ + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Execute the method via the interpreter. The interpreter is locked + * here before calling into the AML parser + */ + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_ps_execute_method(info); + acpi_ex_exit_interpreter(); + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_object_value + * + * PARAMETERS: Info - Method info block, contains: + * Node - Object's NS node + * return_object - Where to put object value (if + * any). If NULL, no value is returned. + * + * RETURN: Status + * + * DESCRIPTION: Return the current value of the object + * + * MUTEX: Assumes namespace is locked, leaves namespace unlocked + * + ******************************************************************************/ + +static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info) +{ + acpi_status status = AE_OK; + struct acpi_namespace_node *resolved_node = info->node; + + ACPI_FUNCTION_TRACE("ns_get_object_value"); + + /* + * Objects require additional resolution steps (e.g., the Node may be a + * field that must be read, etc.) -- we can't just grab the object out of + * the node. + */ + + /* + * Use resolve_node_to_value() to get the associated value. This call always + * deletes obj_desc (allocated above). + * + * NOTE: we can get away with passing in NULL for a walk state because + * obj_desc is guaranteed to not be a reference to either a method local or + * a method argument (because this interface can only be called from the + * acpi_evaluate external interface, never called from a running method.) + * + * Even though we do not directly invoke the interpreter for this, we must + * enter it because we could access an opregion. The opregion access code + * assumes that the interpreter is locked. + * + * We must release the namespace lock before entering the intepreter. + */ + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_ex_enter_interpreter(); + if (ACPI_SUCCESS(status)) { + status = acpi_ex_resolve_node_to_value(&resolved_node, NULL); /* * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed * in resolved_node. */ + acpi_ex_exit_interpreter(); + if (ACPI_SUCCESS(status)) { status = AE_CTRL_RETURN_VALUE; - info->return_object = - ACPI_CAST_PTR(union acpi_operand_object, - info->resolved_node); - + info->return_object = ACPI_CAST_PTR + (union acpi_operand_object, resolved_node); ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Returning object %p [%s]\n", info->return_object, @@ -211,30 +484,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) } } - /* - * Check if there is a return value that must be dealt with - */ - if (status == AE_CTRL_RETURN_VALUE) { - - /* If caller does not want the return value, delete it */ + /* Namespace is unlocked */ - if (info->flags & ACPI_IGNORE_RETURN_VALUE) { - acpi_ut_remove_reference(info->return_object); - info->return_object = NULL; - } - - /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ - - status = AE_OK; - } - - ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "*** Completed evaluation of object %s ***\n", - info->pathname)); - - /* - * Namespace was unlocked by the handling acpi_ns* function, so we - * just return - */ return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/namespace/nsinit.c b/trunk/drivers/acpi/namespace/nsinit.c index aec8488c0019..9f929e479fd8 100644 --- a/trunk/drivers/acpi/namespace/nsinit.c +++ b/trunk/drivers/acpi/namespace/nsinit.c @@ -58,10 +58,6 @@ static acpi_status acpi_ns_init_one_device(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value); -static acpi_status -acpi_ns_find_ini_methods(acpi_handle obj_handle, - u32 nesting_level, void *context, void **return_value); - /******************************************************************************* * * FUNCTION: acpi_ns_initialize_objects @@ -80,7 +76,7 @@ acpi_status acpi_ns_initialize_objects(void) acpi_status status; struct acpi_init_walk_info info; - ACPI_FUNCTION_TRACE(ns_initialize_objects); + ACPI_FUNCTION_TRACE("ns_initialize_objects"); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); @@ -97,7 +93,7 @@ acpi_status acpi_ns_initialize_objects(void) ACPI_UINT32_MAX, acpi_ns_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, @@ -137,7 +133,7 @@ acpi_status acpi_ns_initialize_devices(void) acpi_status status; struct acpi_device_walk_info info; - ACPI_FUNCTION_TRACE(ns_initialize_devices); + ACPI_FUNCTION_TRACE("ns_initialize_devices"); /* Init counters */ @@ -146,46 +142,30 @@ acpi_status acpi_ns_initialize_devices(void) info.num_INI = 0; ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "Initializing Device/Processor/Thermal objects by executing _INI methods:")); - - /* Tree analysis: find all subtrees that contain _INI methods */ + "Executing all Device _STA and_INI methods:")); - status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, - acpi_ns_find_ini_methods, &info, NULL); + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - goto error_exit; + return_ACPI_STATUS(status); } - /* Allocate the evaluation information block */ - - info.evaluate_info = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info.evaluate_info) { - status = AE_NO_MEMORY; - goto error_exit; - } - - /* Walk namespace to execute all _INIs on present devices */ + /* Walk namespace for all objects */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, + ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL); - ACPI_FREE(info.evaluate_info); + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { - goto error_exit; + ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n", - info.num_INI, info.num_STA, info.device_count)); + "\n%hd Devices found - executed %hd _STA, %hd _INI methods\n", + info.device_count, info.num_STA, info.num_INI)); return_ACPI_STATUS(status); - - error_exit: - ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); - return_ACPI_STATUS(status); } /******************************************************************************* @@ -220,7 +200,7 @@ acpi_ns_init_one_object(acpi_handle obj_handle, (struct acpi_namespace_node *)obj_handle; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_NAME(ns_init_one_object); + ACPI_FUNCTION_NAME("ns_init_one_object"); info->object_count++; @@ -329,72 +309,6 @@ acpi_ns_init_one_object(acpi_handle obj_handle, return (AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ns_find_ini_methods - * - * PARAMETERS: acpi_walk_callback - * - * RETURN: acpi_status - * - * DESCRIPTION: Called during namespace walk. Finds objects named _INI under - * device/processor/thermal objects, and marks the entire subtree - * with a SUBTREE_HAS_INI flag. This flag is used during the - * subsequent device initialization walk to avoid entire subtrees - * that do not contain an _INI. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_find_ini_methods(acpi_handle obj_handle, - u32 nesting_level, void *context, void **return_value) -{ - struct acpi_device_walk_info *info = - ACPI_CAST_PTR(struct acpi_device_walk_info, context); - struct acpi_namespace_node *node; - struct acpi_namespace_node *parent_node; - - /* Keep count of device/processor/thermal objects */ - - node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); - if ((node->type == ACPI_TYPE_DEVICE) || - (node->type == ACPI_TYPE_PROCESSOR) || - (node->type == ACPI_TYPE_THERMAL)) { - info->device_count++; - return (AE_OK); - } - - /* We are only looking for methods named _INI */ - - if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) { - return (AE_OK); - } - - /* - * The only _INI methods that we care about are those that are - * present under Device, Processor, and Thermal objects. - */ - parent_node = acpi_ns_get_parent_node(node); - switch (parent_node->type) { - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_PROCESSOR: - case ACPI_TYPE_THERMAL: - - /* Mark parent and bubble up the INI present flag to the root */ - - while (parent_node) { - parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; - parent_node = acpi_ns_get_parent_node(parent_node); - } - break; - - default: - break; - } - - return (AE_OK); -} - /******************************************************************************* * * FUNCTION: acpi_ns_init_one_device @@ -413,165 +327,119 @@ static acpi_status acpi_ns_init_one_device(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { - struct acpi_device_walk_info *walk_info = - ACPI_CAST_PTR(struct acpi_device_walk_info, context); - struct acpi_evaluate_info *info = walk_info->evaluate_info; + struct acpi_device_walk_info *info = + (struct acpi_device_walk_info *)context; + struct acpi_parameter_info pinfo; u32 flags; acpi_status status; + struct acpi_namespace_node *ini_node; struct acpi_namespace_node *device_node; - ACPI_FUNCTION_TRACE(ns_init_one_device); + ACPI_FUNCTION_TRACE("ns_init_one_device"); - /* We are interested in Devices, Processors and thermal_zones only */ + device_node = acpi_ns_map_handle_to_node(obj_handle); + if (!device_node) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); + /* + * We will run _STA/_INI on Devices, Processors and thermal_zones only + */ if ((device_node->type != ACPI_TYPE_DEVICE) && (device_node->type != ACPI_TYPE_PROCESSOR) && (device_node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } + if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && + (!(acpi_dbg_level & ACPI_LV_INFO))) { + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); + } + + info->device_count++; + /* - * Because of an earlier namespace analysis, all subtrees that contain an - * _INI method are tagged. - * - * If this device subtree does not contain any _INI methods, we - * can exit now and stop traversing this entire subtree. + * Check if the _INI method exists for this device - + * if _INI does not exist, there is no need to run _STA + * No _INI means device requires no initialization */ - if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { - return_ACPI_STATUS(AE_CTRL_DEPTH); + status = acpi_ns_search_node(*ACPI_CAST_PTR(u32, METHOD_NAME__INI), + device_node, ACPI_TYPE_METHOD, &ini_node); + if (ACPI_FAILURE(status)) { + /* No _INI method found - move on to next device */ + + return_ACPI_STATUS(AE_OK); } /* - * Run _STA to determine if this device is present and functioning. We - * must know this information for two important reasons (from ACPI spec): - * - * 1) We can only run _INI if the device is present. - * 2) We must abort the device tree walk on this subtree if the device is - * not present and is not functional (we will not examine the children) - * - * The _STA method is not required to be present under the device, we - * assume the device is present if _STA does not exist. + * Run _STA to determine if we can run _INI on the device - + * the device must be present before _INI can be run. + * However, _STA is not required - assume device present if no _STA */ - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, + device_node, + METHOD_NAME__STA)); - status = acpi_ut_execute_STA(device_node, &flags); - if (ACPI_FAILURE(status)) { + pinfo.node = device_node; + pinfo.parameters = NULL; + pinfo.parameter_type = ACPI_PARAM_ARGS; + status = acpi_ut_execute_STA(pinfo.node, &flags); + if (ACPI_FAILURE(status)) { /* Ignore error and move on to next device */ return_ACPI_STATUS(AE_OK); } - /* - * Flags == -1 means that _STA was not found. In this case, we assume that - * the device is both present and functional. - * - * From the ACPI spec, description of _STA: - * - * "If a device object (including the processor object) does not have an - * _STA object, then OSPM assumes that all of the above bits are set (in - * other words, the device is present, ..., and functioning)" - */ if (flags != ACPI_UINT32_MAX) { - walk_info->num_STA++; + info->num_STA++; } - /* - * Examine the PRESENT and FUNCTIONING status bits - * - * Note: ACPI spec does not seem to specify behavior for the present but - * not functioning case, so we assume functioning if present. - */ if (!(flags & ACPI_STA_DEVICE_PRESENT)) { + /* Don't look at children of a not present device */ - /* Device is not present, we must examine the Functioning bit */ - - if (flags & ACPI_STA_DEVICE_FUNCTIONING) { - /* - * Device is not present but is "functioning". In this case, - * we will not run _INI, but we continue to examine the children - * of this device. - * - * From the ACPI spec, description of _STA: (Note - no mention - * of whether to run _INI or not on the device in question) - * - * "_STA may return bit 0 clear (not present) with bit 3 set - * (device is functional). This case is used to indicate a valid - * device for which no device driver should be loaded (for example, - * a bridge device.) Children of this device may be present and - * valid. OSPM should continue enumeration below a device whose - * _STA returns this bit combination" - */ - return_ACPI_STATUS(AE_OK); - } else { - /* - * Device is not present and is not functioning. We must abort the - * walk of this subtree immediately -- don't look at the children - * of such a device. - * - * From the ACPI spec, description of _INI: - * - * "If the _STA method indicates that the device is not present, - * OSPM will not run the _INI and will not examine the children - * of the device for _INI methods" - */ - return_ACPI_STATUS(AE_CTRL_DEPTH); - } + return_ACPI_STATUS(AE_CTRL_DEPTH); } /* - * The device is present or is assumed present if no _STA exists. - * Run the _INI if it exists (not required to exist) - * - * Note: We know there is an _INI within this subtree, but it may not be - * under this particular device, it may be lower in the branch. + * The device is present and _INI exists. Run the _INI method. + * (We already have the _INI node from above) */ - ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname - (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); - - info->prefix_node = device_node; - info->pathname = METHOD_NAME__INI; - info->parameters = NULL; - info->parameter_type = ACPI_PARAM_ARGS; - info->flags = ACPI_IGNORE_RETURN_VALUE; - - status = acpi_ns_evaluate(info); - if (ACPI_SUCCESS(status)) { - walk_info->num_INI++; - - if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && - (!(acpi_dbg_level & ACPI_LV_INFO))) { - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); - } - } -#ifdef ACPI_DEBUG_OUTPUT - else if (status != AE_NOT_FOUND) { + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, + pinfo.node, + METHOD_NAME__INI)); + pinfo.node = ini_node; + status = acpi_ns_evaluate_by_handle(&pinfo); + if (ACPI_FAILURE(status)) { /* Ignore error and move on to next device */ - char *scope_name = - acpi_ns_get_external_pathname(info->resolved_node); +#ifdef ACPI_DEBUG_OUTPUT + char *scope_name = acpi_ns_get_external_pathname(ini_node); + + ACPI_WARNING((AE_INFO, "%s._INI failed: %s", + scope_name, acpi_format_exception(status))); - ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", - scope_name)); - ACPI_FREE(scope_name); - } + ACPI_MEM_FREE(scope_name); #endif + } else { + /* Delete any return object (especially if implicit_return is enabled) */ - /* Ignore errors from above */ + if (pinfo.return_object) { + acpi_ut_remove_reference(pinfo.return_object); + } - status = AE_OK; + /* Count of successful INIs */ + + info->num_INI++; + } - /* - * The _INI method has been run if present; call the Global Initialization - * Handler for this device. - */ if (acpi_gbl_init_handler) { + /* External initialization handler is present, call it */ + status = - acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); + acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); } - return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/namespace/nsload.c b/trunk/drivers/acpi/namespace/nsload.c index fe75d888e183..4e0b0524c188 100644 --- a/trunk/drivers/acpi/namespace/nsload.c +++ b/trunk/drivers/acpi/namespace/nsload.c @@ -77,14 +77,13 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, { acpi_status status; - ACPI_FUNCTION_TRACE(ns_load_table); + ACPI_FUNCTION_TRACE("ns_load_table"); /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ if (! (acpi_gbl_table_data[table_desc->type]. flags & ACPI_TABLE_EXECUTABLE)) { - /* Just ignore this table */ return_ACPI_STATUS(AE_OK); @@ -169,7 +168,7 @@ static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) acpi_status status; struct acpi_table_desc *table_desc; - ACPI_FUNCTION_TRACE(ns_load_table_by_type); + ACPI_FUNCTION_TRACE("ns_load_table_by_type"); status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); if (ACPI_FAILURE(status)) { @@ -181,11 +180,11 @@ static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) * DSDT (one), SSDT/PSDT (multiple) */ switch (table_type) { - case ACPI_TABLE_ID_DSDT: + case ACPI_TABLE_DSDT: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); - table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next; /* If table already loaded into namespace, just return */ @@ -201,8 +200,8 @@ static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) } break; - case ACPI_TABLE_ID_SSDT: - case ACPI_TABLE_ID_PSDT: + case ACPI_TABLE_SSDT: + case ACPI_TABLE_PSDT: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: %d SSDT or PSDTs\n", @@ -259,7 +258,7 @@ acpi_status acpi_ns_load_namespace(void) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_load_name_space); + ACPI_FUNCTION_TRACE("acpi_load_name_space"); /* There must be at least a DSDT installed */ @@ -272,15 +271,15 @@ acpi_status acpi_ns_load_namespace(void) * Load the namespace. The DSDT is required, * but the SSDT and PSDT tables are optional. */ - status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT); + status = acpi_ns_load_table_by_type(ACPI_TABLE_DSDT); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Ignore exceptions from these */ - (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT); - (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT); + (void)acpi_ns_load_table_by_type(ACPI_TABLE_SSDT); + (void)acpi_ns_load_table_by_type(ACPI_TABLE_PSDT); ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "ACPI Namespace successfully loaded at root %p\n", @@ -315,7 +314,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) acpi_handle dummy; u32 level; - ACPI_FUNCTION_TRACE(ns_delete_subtree); + ACPI_FUNCTION_TRACE("ns_delete_subtree"); parent_handle = start_handle; child_handle = NULL; @@ -326,7 +325,6 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) * to where we started. */ while (level > 0) { - /* Attempt to get the next object in this scope */ status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, @@ -337,7 +335,6 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) /* Did we get a new object? */ if (ACPI_SUCCESS(status)) { - /* Check if this object has any children */ if (ACPI_SUCCESS @@ -395,7 +392,7 @@ acpi_status acpi_ns_unload_namespace(acpi_handle handle) { acpi_status status; - ACPI_FUNCTION_TRACE(ns_unload_name_space); + ACPI_FUNCTION_TRACE("ns_unload_name_space"); /* Parameter validation */ diff --git a/trunk/drivers/acpi/namespace/nsnames.c b/trunk/drivers/acpi/namespace/nsnames.c index 97b8332c9746..639f653b4b6b 100644 --- a/trunk/drivers/acpi/namespace/nsnames.c +++ b/trunk/drivers/acpi/namespace/nsnames.c @@ -48,6 +48,11 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames") +/* Local prototypes */ +static void +acpi_ns_build_external_path(struct acpi_namespace_node *node, + acpi_size size, char *name_buffer); + /******************************************************************************* * * FUNCTION: acpi_ns_build_external_path @@ -62,7 +67,8 @@ ACPI_MODULE_NAME("nsnames") * DESCRIPTION: Generate a full pathaname * ******************************************************************************/ -void + +static void acpi_ns_build_external_path(struct acpi_namespace_node *node, acpi_size size, char *name_buffer) { @@ -132,7 +138,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) char *name_buffer; acpi_size size; - ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node); + ACPI_FUNCTION_TRACE_PTR("ns_get_external_pathname", node); /* Calculate required buffer size based on depth below root */ @@ -140,7 +146,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) /* Allocate a buffer to be returned to caller */ - name_buffer = ACPI_ALLOCATE_ZEROED(size); + name_buffer = ACPI_MEM_CALLOCATE(size); if (!name_buffer) { ACPI_ERROR((AE_INFO, "Allocation failure")); return_PTR(NULL); @@ -213,7 +219,7 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle, struct acpi_namespace_node *node; acpi_size required_size; - ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle); + ACPI_FUNCTION_TRACE_PTR("ns_handle_to_pathname", target_handle); node = acpi_ns_map_handle_to_node(target_handle); if (!node) { diff --git a/trunk/drivers/acpi/namespace/nsobject.c b/trunk/drivers/acpi/namespace/nsobject.c index aabe8794b908..10ae6292bca4 100644 --- a/trunk/drivers/acpi/namespace/nsobject.c +++ b/trunk/drivers/acpi/namespace/nsobject.c @@ -76,21 +76,19 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, union acpi_operand_object *last_obj_desc; acpi_object_type object_type = ACPI_TYPE_ANY; - ACPI_FUNCTION_TRACE(ns_attach_object); + ACPI_FUNCTION_TRACE("ns_attach_object"); /* * Parameter validation */ if (!node) { - /* Invalid handle */ - ACPI_ERROR((AE_INFO, "Null NamedObj handle")); + ACPI_ERROR((AE_INFO, "Null named_obj handle")); return_ACPI_STATUS(AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { - /* Null object */ ACPI_ERROR((AE_INFO, @@ -99,7 +97,6 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, } if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { - /* Not a name handle */ ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", @@ -111,7 +108,7 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, if (node->object == object) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Obj %p already installed in NameObj %p\n", + "Obj %p already installed in name_obj %p\n", object, node)); return_ACPI_STATUS(AE_OK); @@ -204,7 +201,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) { union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE(ns_detach_object); + ACPI_FUNCTION_TRACE("ns_detach_object"); obj_desc = node->object; @@ -255,7 +252,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct acpi_namespace_node *node) { - ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node); + ACPI_FUNCTION_TRACE_PTR("ns_get_attached_object", node); if (!node) { ACPI_WARNING((AE_INFO, "Null Node ptr")); @@ -290,7 +287,7 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union acpi_operand_object *obj_desc) { - ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc); + ACPI_FUNCTION_TRACE_PTR("ns_get_secondary_object", obj_desc); if ((!obj_desc) || (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) || diff --git a/trunk/drivers/acpi/namespace/nsparse.c b/trunk/drivers/acpi/namespace/nsparse.c index 155505a4ef69..232be4303653 100644 --- a/trunk/drivers/acpi/namespace/nsparse.c +++ b/trunk/drivers/acpi/namespace/nsparse.c @@ -62,13 +62,13 @@ ACPI_MODULE_NAME("nsparse") * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) +acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc * table_desc) { union acpi_parse_object *parse_root; acpi_status status; struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE(ns_one_complete_parse); + ACPI_FUNCTION_TRACE("ns_one_complete_parse"); /* Create and init a Root Node */ @@ -124,7 +124,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, { acpi_status status; - ACPI_FUNCTION_TRACE(ns_parse_table); + ACPI_FUNCTION_TRACE("ns_parse_table"); /* * AML Parse, pass 1 diff --git a/trunk/drivers/acpi/namespace/nssearch.c b/trunk/drivers/acpi/namespace/nssearch.c index 500e2bbcfaf7..d64b78952f24 100644 --- a/trunk/drivers/acpi/namespace/nssearch.c +++ b/trunk/drivers/acpi/namespace/nssearch.c @@ -56,16 +56,16 @@ acpi_ns_search_parent_tree(u32 target_name, /******************************************************************************* * - * FUNCTION: acpi_ns_search_one_scope + * FUNCTION: acpi_ns_search_node * * PARAMETERS: target_name - Ascii ACPI name to search for - * parent_node - Starting node where search will begin + * Node - Starting node where search will begin * Type - Object type to match * return_node - Where the matched Named obj is returned * * RETURN: Status * - * DESCRIPTION: Search a single level of the namespace. Performs a + * DESCRIPTION: Search a single level of the namespace. Performs a * simple search of the specified level, and does not add * entries or search parents. * @@ -75,40 +75,35 @@ acpi_ns_search_parent_tree(u32 target_name, * * All namespace searching is linear in this implementation, but * could be easily modified to support any improved search - * algorithm. However, the linear search was chosen for simplicity + * algorithm. However, the linear search was chosen for simplicity * and because the trees are small and the other interpreter * execution overhead is relatively high. * - * Note: CPU execution analysis has shown that the AML interpreter spends - * a very small percentage of its time searching the namespace. Therefore, - * the linear search seems to be sufficient, as there would seem to be - * little value in improving the search. - * ******************************************************************************/ acpi_status -acpi_ns_search_one_scope(u32 target_name, - struct acpi_namespace_node *parent_node, - acpi_object_type type, - struct acpi_namespace_node **return_node) +acpi_ns_search_node(u32 target_name, + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_namespace_node **return_node) { - struct acpi_namespace_node *node; + struct acpi_namespace_node *next_node; - ACPI_FUNCTION_TRACE(ns_search_one_scope); + ACPI_FUNCTION_TRACE("ns_search_node"); #ifdef ACPI_DEBUG_OUTPUT if (ACPI_LV_NAMES & acpi_dbg_level) { char *scope_name; - scope_name = acpi_ns_get_external_pathname(parent_node); + scope_name = acpi_ns_get_external_pathname(node); if (scope_name) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n", - scope_name, parent_node, - ACPI_CAST_PTR(char, &target_name), + scope_name, node, ACPI_CAST_PTR(char, + &target_name), acpi_ut_get_type_name(type))); - ACPI_FREE(scope_name); + ACPI_MEM_FREE(scope_name); } } #endif @@ -117,33 +112,32 @@ acpi_ns_search_one_scope(u32 target_name, * Search for name at this namespace level, which is to say that we * must search for the name among the children of this object */ - node = parent_node->child; - while (node) { - + next_node = node->child; + while (next_node) { /* Check for match against the name */ - if (node->name.integer == target_name) { - + if (next_node->name.integer == target_name) { /* Resolve a control method alias if any */ - if (acpi_ns_get_type(node) == + if (acpi_ns_get_type(next_node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { - node = + next_node = ACPI_CAST_PTR(struct acpi_namespace_node, - node->object); + next_node->object); } - /* Found matching entry */ - + /* + * Found matching entry. + */ ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", ACPI_CAST_PTR(char, &target_name), - acpi_ut_get_type_name(node->type), - node, - acpi_ut_get_node_name(parent_node), - parent_node)); + acpi_ut_get_type_name(next_node-> + type), + next_node, + acpi_ut_get_node_name(node), node)); - *return_node = node; + *return_node = next_node; return_ACPI_STATUS(AE_OK); } @@ -151,8 +145,7 @@ acpi_ns_search_one_scope(u32 target_name, * The last entry in the list points back to the parent, * so a flag is used to indicate the end-of-list */ - if (node->flags & ANOBJ_END_OF_PEER_LIST) { - + if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { /* Searched entire list, we are done */ break; @@ -160,7 +153,7 @@ acpi_ns_search_one_scope(u32 target_name, /* Didn't match name, move on to the next peer object */ - node = node->peer; + next_node = next_node->peer; } /* Searched entire namespace level, not found */ @@ -169,8 +162,7 @@ acpi_ns_search_one_scope(u32 target_name, "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", ACPI_CAST_PTR(char, &target_name), acpi_ut_get_type_name(type), - acpi_ut_get_node_name(parent_node), parent_node, - parent_node->child)); + acpi_ut_get_node_name(node), node, node->child)); return_ACPI_STATUS(AE_NOT_FOUND); } @@ -187,14 +179,14 @@ acpi_ns_search_one_scope(u32 target_name, * RETURN: Status * * DESCRIPTION: Called when a name has not been found in the current namespace - * level. Before adding it or giving up, ACPI scope rules require + * level. Before adding it or giving up, ACPI scope rules require * searching enclosing scopes in cases identified by acpi_ns_local(). * * "A name is located by finding the matching name in the current * name space, and then in the parent name space. If the parent * name space does not contain the name, the search continues * recursively until either the name is found or the name space - * does not have a parent (the root of the name space). This + * does not have a parent (the root of the name space). This * indicates that the name is not found" (From ACPI Specification, * section 5.3) * @@ -209,7 +201,7 @@ acpi_ns_search_parent_tree(u32 target_name, acpi_status status; struct acpi_namespace_node *parent_node; - ACPI_FUNCTION_TRACE(ns_search_parent_tree); + ACPI_FUNCTION_TRACE("ns_search_parent_tree"); parent_node = acpi_ns_get_parent_node(node); @@ -243,19 +235,20 @@ acpi_ns_search_parent_tree(u32 target_name, */ while (parent_node) { /* - * Search parent scope. Use TYPE_ANY because we don't care about the + * Search parent scope. Use TYPE_ANY because we don't care about the * object type at this point, we only care about the existence of - * the actual name we are searching for. Typechecking comes later. + * the actual name we are searching for. Typechecking comes later. */ - status = - acpi_ns_search_one_scope(target_name, parent_node, + status = acpi_ns_search_node(target_name, parent_node, ACPI_TYPE_ANY, return_node); if (ACPI_SUCCESS(status)) { return_ACPI_STATUS(status); } - /* Not found here, go up another level (until we reach the root) */ - + /* + * Not found here, go up another level + * (until we reach the root) + */ parent_node = acpi_ns_get_parent_node(parent_node); } @@ -280,7 +273,7 @@ acpi_ns_search_parent_tree(u32 target_name, * RETURN: Status * * DESCRIPTION: Search for a name segment in a single namespace level, - * optionally adding it if it is not found. If the passed + * optionally adding it if it is not found. If the passed * Type is not Any and the type previously stored in the * entry was Any (i.e. unknown), update the stored type. * @@ -300,46 +293,29 @@ acpi_ns_search_and_enter(u32 target_name, acpi_status status; struct acpi_namespace_node *new_node; - ACPI_FUNCTION_TRACE(ns_search_and_enter); + ACPI_FUNCTION_TRACE("ns_search_and_enter"); /* Parameter validation */ if (!node || !target_name || !return_node) { ACPI_ERROR((AE_INFO, - "Null parameter: Node %p Name %X ReturnNode %p", + "Null param: Node %p Name %X return_node %p", node, target_name, return_node)); return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* - * Name must consist of valid ACPI characters. We will repair the name if - * necessary because we don't want to abort because of this, but we want - * all namespace names to be printable. A warning message is appropriate. - * - * This issue came up because there are in fact machines that exhibit - * this problem, and we want to be able to enable ACPI support for them, - * even though there are a few bad names. - */ + /* Name must consist of printable characters */ + if (!acpi_ut_valid_acpi_name(target_name)) { - target_name = acpi_ut_repair_name(target_name); - - /* Report warning only if in strict mode or debug mode */ - - if (!acpi_gbl_enable_interpreter_slack) { - ACPI_WARNING((AE_INFO, - "Found bad character(s) in name, repaired: [%4.4s]\n", - ACPI_CAST_PTR(char, &target_name))); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Found bad character(s) in name, repaired: [%4.4s]\n", - ACPI_CAST_PTR(char, &target_name))); - } + ACPI_ERROR((AE_INFO, "Bad character in ACPI Name: %X", + target_name)); + return_ACPI_STATUS(AE_BAD_CHARACTER); } /* Try to find the name in the namespace level specified by the caller */ *return_node = ACPI_ENTRY_NOT_FOUND; - status = acpi_ns_search_one_scope(target_name, node, type, return_node); + status = acpi_ns_search_node(target_name, node, type, return_node); if (status != AE_NOT_FOUND) { /* * If we found it AND the request specifies that a find is an error, @@ -349,16 +325,18 @@ acpi_ns_search_and_enter(u32 target_name, status = AE_ALREADY_EXISTS; } - /* Either found it or there was an error: finished either way */ - + /* + * Either found it or there was an error + * -- finished either way + */ return_ACPI_STATUS(status); } /* - * The name was not found. If we are NOT performing the first pass + * The name was not found. If we are NOT performing the first pass * (name entry) of loading the namespace, search the parent tree (all the * way to the root if necessary.) We don't want to perform the parent - * search when the namespace is actually being loaded. We want to perform + * search when the namespace is actually being loaded. We want to perform * the search when namespace references are being resolved (load pass 2) * and during the execution phase. */ @@ -376,8 +354,9 @@ acpi_ns_search_and_enter(u32 target_name, } } - /* In execute mode, just search, never add names. Exit now */ - + /* + * In execute mode, just search, never add names. Exit now. + */ if (interpreter_mode == ACPI_IMODE_EXECUTE) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", @@ -392,18 +371,11 @@ acpi_ns_search_and_enter(u32 target_name, if (!new_node) { return_ACPI_STATUS(AE_NO_MEMORY); } -#ifdef ACPI_ASL_COMPILER - /* - * Node is an object defined by an External() statement - */ - if (flags & ACPI_NS_EXTERNAL) { - new_node->flags |= ANOBJ_IS_EXTERNAL; - } -#endif /* Install the new object into the parent's list of children */ acpi_ns_install_node(walk_state, node, new_node, type); *return_node = new_node; + return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/namespace/nsutils.c b/trunk/drivers/acpi/namespace/nsutils.c index aa4e799d9a8c..3e7cad549a38 100644 --- a/trunk/drivers/acpi/namespace/nsutils.c +++ b/trunk/drivers/acpi/namespace/nsutils.c @@ -78,17 +78,15 @@ acpi_ns_report_error(char *module_name, char *internal_name, acpi_status lookup_status) { acpi_status status; - u32 bad_name; char *name = NULL; - acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + acpi_ut_report_error(module_name, line_number); if (lookup_status == AE_BAD_CHARACTER) { - /* There is a non-ascii character in the name */ - ACPI_MOVE_32_TO_32(&bad_name, internal_name); - acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); + acpi_os_printf("[0x%4.4X] (NON-ASCII)", + *(ACPI_CAST_PTR(u32, internal_name))); } else { /* Convert path to external format */ @@ -104,7 +102,7 @@ acpi_ns_report_error(char *module_name, } if (name) { - ACPI_FREE(name); + ACPI_MEM_FREE(name); } } @@ -139,12 +137,11 @@ acpi_ns_report_method_error(char *module_name, acpi_status status; struct acpi_namespace_node *node = prefix_node; - acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + acpi_ut_report_error(module_name, line_number); if (path) { - status = - acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, - &node); + status = acpi_ns_get_node_by_path(path, prefix_node, + ACPI_NS_NO_UPSEARCH, &node); if (ACPI_FAILURE(status)) { acpi_os_printf("[Could not get node by pathname]"); } @@ -188,7 +185,7 @@ acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message) } acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node); - ACPI_FREE(buffer.pointer); + ACPI_MEM_FREE(buffer.pointer); } } @@ -242,7 +239,7 @@ static u8 acpi_ns_valid_path_separator(char sep) acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) { - ACPI_FUNCTION_TRACE(ns_get_type); + ACPI_FUNCTION_TRACE("ns_get_type"); if (!node) { ACPI_WARNING((AE_INFO, "Null Node parameter")); @@ -267,10 +264,9 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) u32 acpi_ns_local(acpi_object_type type) { - ACPI_FUNCTION_TRACE(ns_local); + ACPI_FUNCTION_TRACE("ns_local"); if (!acpi_ut_valid_object_type(type)) { - /* Type code out of range */ ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); @@ -367,7 +363,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) char *result = NULL; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ns_build_internal_name); + ACPI_FUNCTION_TRACE("ns_build_internal_name"); /* Setup the correct prefixes, counts, and pointers */ @@ -415,7 +411,6 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) for (i = 0; i < ACPI_NAME_SIZE; i++) { if (acpi_ns_valid_path_separator(*external_name) || (*external_name == 0)) { - /* Pad the segment with underscore(s) if segment is short */ result[i] = '_'; @@ -478,7 +473,7 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) struct acpi_namestring_info info; acpi_status status; - ACPI_FUNCTION_TRACE(ns_internalize_name); + ACPI_FUNCTION_TRACE("ns_internalize_name"); if ((!external_name) || (*external_name == 0) || (!converted_name)) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -491,7 +486,7 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) /* We need a segment to store the internal name */ - internal_name = ACPI_ALLOCATE_ZEROED(info.length); + internal_name = ACPI_MEM_CALLOCATE(info.length); if (!internal_name) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -501,7 +496,7 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) info.internal_name = internal_name; status = acpi_ns_build_internal_name(&info); if (ACPI_FAILURE(status)) { - ACPI_FREE(internal_name); + ACPI_MEM_FREE(internal_name); return_ACPI_STATUS(status); } @@ -538,7 +533,7 @@ acpi_ns_externalize_name(u32 internal_name_length, acpi_native_uint i = 0; acpi_native_uint j = 0; - ACPI_FUNCTION_TRACE(ns_externalize_name); + ACPI_FUNCTION_TRACE("ns_externalize_name"); if (!internal_name_length || !internal_name || !converted_name) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -633,7 +628,7 @@ acpi_ns_externalize_name(u32 internal_name_length, /* * Build converted_name */ - *converted_name = ACPI_ALLOCATE_ZEROED(required_length); + *converted_name = ACPI_MEM_CALLOCATE(required_length); if (!(*converted_name)) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -686,9 +681,13 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) ACPI_FUNCTION_ENTRY(); /* - * Simple implementation + * Simple implementation. */ - if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { + if (!handle) { + return (NULL); + } + + if (handle == ACPI_ROOT_OBJECT) { return (acpi_gbl_root_node); } @@ -698,7 +697,7 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) return (NULL); } - return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); + return ((struct acpi_namespace_node *)handle); } /******************************************************************************* @@ -753,7 +752,7 @@ void acpi_ns_terminate(void) { union acpi_operand_object *obj_desc; - ACPI_FUNCTION_TRACE(ns_terminate); + ACPI_FUNCTION_TRACE("ns_terminate"); /* * 1) Free the entire namespace -- all nodes and objects @@ -793,10 +792,9 @@ void acpi_ns_terminate(void) u32 acpi_ns_opens_scope(acpi_object_type type) { - ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type)); + ACPI_FUNCTION_TRACE_STR("ns_opens_scope", acpi_ut_get_type_name(type)); if (!acpi_ut_valid_object_type(type)) { - /* type code out of range */ ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); @@ -808,12 +806,12 @@ u32 acpi_ns_opens_scope(acpi_object_type type) /******************************************************************************* * - * FUNCTION: acpi_ns_get_node + * FUNCTION: acpi_ns_get_node_by_path * * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The * \ (backslash) and ^ (carat) prefixes, and the * . (period) to separate segments are supported. - * prefix_node - Root of subtree to be searched, or NS_ALL for the + * start_node - Root of subtree to be searched, or NS_ALL for the * root of the name space. If Name is fully * qualified (first s8 is '\'), the passed value * of Scope will not be accessed. @@ -829,29 +827,23 @@ u32 acpi_ns_opens_scope(acpi_object_type type) ******************************************************************************/ acpi_status -acpi_ns_get_node(struct acpi_namespace_node *prefix_node, - char *pathname, - u32 flags, struct acpi_namespace_node **return_node) +acpi_ns_get_node_by_path(char *pathname, + struct acpi_namespace_node *start_node, + u32 flags, struct acpi_namespace_node **return_node) { union acpi_generic_state scope_info; acpi_status status; - char *internal_path; - - ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); + char *internal_path = NULL; - if (!pathname) { - *return_node = prefix_node; - if (!prefix_node) { - *return_node = acpi_gbl_root_node; - } - return_ACPI_STATUS(AE_OK); - } + ACPI_FUNCTION_TRACE_PTR("ns_get_node_by_path", pathname); - /* Convert path to internal representation */ + if (pathname) { + /* Convert path to internal representation */ - status = acpi_ns_internalize_name(pathname, &internal_path); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + status = acpi_ns_internalize_name(pathname, &internal_path); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } } /* Must lock namespace during lookup */ @@ -863,23 +855,26 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, /* Setup lookup scope (search starting point) */ - scope_info.scope.node = prefix_node; + scope_info.scope.node = start_node; /* Lookup the name in the namespace */ - status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, - (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, - return_node); + status = acpi_ns_lookup(&scope_info, internal_path, + ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, + (flags | ACPI_NS_DONT_OPEN_SCOPE), + NULL, return_node); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", - pathname, acpi_format_exception(status))); + internal_path, + acpi_format_exception(status))); } (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); cleanup: - ACPI_FREE(internal_path); + if (internal_path) { + ACPI_MEM_FREE(internal_path); + } return_ACPI_STATUS(status); } @@ -965,10 +960,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node) { struct acpi_namespace_node *parent_node; - ACPI_FUNCTION_TRACE(ns_find_parent_name); + ACPI_FUNCTION_TRACE("ns_find_parent_name"); if (child_node) { - /* Valid entry. Get the parent Node */ parent_node = acpi_ns_get_parent_node(child_node); diff --git a/trunk/drivers/acpi/namespace/nswalk.c b/trunk/drivers/acpi/namespace/nswalk.c index c8f6bef16ed0..fcab1e784b81 100644 --- a/trunk/drivers/acpi/namespace/nswalk.c +++ b/trunk/drivers/acpi/namespace/nswalk.c @@ -76,7 +76,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, ACPI_FUNCTION_ENTRY(); if (!child_node) { - /* It's really the parent's _scope_ that we want */ if (parent_node->child) { @@ -93,7 +92,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, /* If any type is OK, we are done */ if (type == ACPI_TYPE_ANY) { - /* next_node is NULL if we are at the end-of-list */ return (next_node); @@ -102,7 +100,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, /* Must search for the node -- but within this scope only */ while (next_node) { - /* If type matches, we are done */ if (next_node->type == type) { @@ -164,7 +161,7 @@ acpi_ns_walk_namespace(acpi_object_type type, acpi_object_type child_type; u32 level; - ACPI_FUNCTION_TRACE(ns_walk_namespace); + ACPI_FUNCTION_TRACE("ns_walk_namespace"); /* Special case for the namespace Root Node */ @@ -185,7 +182,6 @@ acpi_ns_walk_namespace(acpi_object_type type, * bubbled up to (and passed) the original parent handle (start_entry) */ while (level > 0) { - /* Get the next node in this scope. Null if not found */ status = AE_OK; diff --git a/trunk/drivers/acpi/namespace/nsxfeval.c b/trunk/drivers/acpi/namespace/nsxfeval.c index 6d9bd45af30a..a95f636dc35d 100644 --- a/trunk/drivers/acpi/namespace/nsxfeval.c +++ b/trunk/drivers/acpi/namespace/nsxfeval.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -49,7 +51,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfeval") -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_evaluate_object_typed @@ -70,17 +71,18 @@ ACPI_MODULE_NAME("nsxfeval") * be valid (non-null) * ******************************************************************************/ +#ifdef ACPI_FUTURE_USAGE acpi_status acpi_evaluate_object_typed(acpi_handle handle, acpi_string pathname, - struct acpi_object_list * external_params, - struct acpi_buffer * return_buffer, + struct acpi_object_list *external_params, + struct acpi_buffer *return_buffer, acpi_object_type return_type) { acpi_status status; u8 must_free = FALSE; - ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed); + ACPI_FUNCTION_TRACE("acpi_evaluate_object_typed"); /* Return buffer must be valid */ @@ -108,7 +110,6 @@ acpi_evaluate_object_typed(acpi_handle handle, } if (return_buffer->length == 0) { - /* Error because caller specifically asked for a return value */ ACPI_ERROR((AE_INFO, "No return value")); @@ -130,7 +131,6 @@ acpi_evaluate_object_typed(acpi_handle handle, acpi_ut_get_type_name(return_type))); if (must_free) { - /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ acpi_os_free(return_buffer->pointer); @@ -140,8 +140,6 @@ acpi_evaluate_object_typed(acpi_handle handle, return_buffer->length = 0; return_ACPI_STATUS(AE_TYPE); } - -ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) #endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* @@ -163,6 +161,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) * be valid (non-null) * ******************************************************************************/ + acpi_status acpi_evaluate_object(acpi_handle handle, acpi_string pathname, @@ -171,61 +170,51 @@ acpi_evaluate_object(acpi_handle handle, { acpi_status status; acpi_status status2; - struct acpi_evaluate_info *info; + struct acpi_parameter_info info; acpi_size buffer_space_needed; u32 i; - ACPI_FUNCTION_TRACE(acpi_evaluate_object); + ACPI_FUNCTION_TRACE("acpi_evaluate_object"); - /* Allocate and initialize the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - info->pathname = pathname; - info->parameter_type = ACPI_PARAM_ARGS; - - /* Convert and validate the device handle */ - - info->prefix_node = acpi_ns_map_handle_to_node(handle); - if (!info->prefix_node) { - status = AE_BAD_PARAMETER; - goto cleanup; - } + info.node = handle; + info.parameters = NULL; + info.return_object = NULL; + info.parameter_type = ACPI_PARAM_ARGS; /* - * If there are parameters to be passed to a control method, the external - * objects must all be converted to internal objects + * If there are parameters to be passed to the object + * (which must be a control method), the external objects + * must be converted to internal objects */ if (external_params && external_params->count) { /* * Allocate a new parameter block for the internal objects * Add 1 to count to allow for null terminated internal list */ - info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) - external_params-> - count + - 1) * sizeof(void *)); - if (!info->parameters) { - status = AE_NO_MEMORY; - goto cleanup; + info.parameters = ACPI_MEM_CALLOCATE(((acpi_size) + external_params->count + + 1) * sizeof(void *)); + if (!info.parameters) { + return_ACPI_STATUS(AE_NO_MEMORY); } - /* Convert each external object in the list to an internal object */ - + /* + * Convert each external object in the list to an + * internal object + */ for (i = 0; i < external_params->count; i++) { status = acpi_ut_copy_eobject_to_iobject(&external_params-> pointer[i], - &info-> + &info. parameters[i]); if (ACPI_FAILURE(status)) { - goto cleanup; + acpi_ut_delete_internal_object_list(info. + parameters); + return_ACPI_STATUS(status); } } - info->parameters[external_params->count] = NULL; + info.parameters[external_params->count] = NULL; } /* @@ -235,31 +224,43 @@ acpi_evaluate_object(acpi_handle handle, * 3) Valid handle */ if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) { - - /* The path is fully qualified, just evaluate by name */ - - info->prefix_node = NULL; - status = acpi_ns_evaluate(info); + /* + * The path is fully qualified, just evaluate by name + */ + status = acpi_ns_evaluate_by_name(pathname, &info); } else if (!handle) { /* - * A handle is optional iff a fully qualified pathname is specified. - * Since we've already handled fully qualified names above, this is - * an error + * A handle is optional iff a fully qualified pathname + * is specified. Since we've already handled fully + * qualified names above, this is an error */ if (!pathname) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Both Handle and Pathname are NULL")); + ACPI_ERROR((AE_INFO, + "Both Handle and Pathname are NULL")); } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Null Handle with relative pathname [%s]", - pathname)); + ACPI_ERROR((AE_INFO, + "Handle is NULL and Pathname is relative")); } status = AE_BAD_PARAMETER; } else { - /* We have a namespace a node and a possible relative path */ - - status = acpi_ns_evaluate(info); + /* + * We get here if we have a handle -- and if we have a + * pathname it is relative. The handle will be validated + * in the lower procedures + */ + if (!pathname) { + /* + * The null pathname case means the handle is for + * the actual object to be evaluated + */ + status = acpi_ns_evaluate_by_handle(&info); + } else { + /* + * Both a Handle and a relative Pathname + */ + status = acpi_ns_evaluate_relative(pathname, &info); + } } /* @@ -267,10 +268,10 @@ acpi_evaluate_object(acpi_handle handle, * copy the return value to an external object. */ if (return_buffer) { - if (!info->return_object) { + if (!info.return_object) { return_buffer->length = 0; } else { - if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) == + if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) == ACPI_DESC_TYPE_NAMED) { /* * If we received a NS Node as a return object, this means that @@ -281,19 +282,19 @@ acpi_evaluate_object(acpi_handle handle, * support for various types at a later date if necessary. */ status = AE_TYPE; - info->return_object = NULL; /* No need to delete a NS Node */ + info.return_object = NULL; /* No need to delete a NS Node */ return_buffer->length = 0; } if (ACPI_SUCCESS(status)) { - - /* Get the size of the returned object */ - + /* + * Find out how large a buffer is needed + * to contain the returned object + */ status = - acpi_ut_get_object_size(info->return_object, + acpi_ut_get_object_size(info.return_object, &buffer_space_needed); if (ACPI_SUCCESS(status)) { - /* Validate/Allocate/Clear caller buffer */ status = @@ -302,8 +303,7 @@ acpi_evaluate_object(acpi_handle handle, buffer_space_needed); if (ACPI_FAILURE(status)) { /* - * Caller's buffer is too small or a new one can't - * be allocated + * Caller's buffer is too small or a new one can't be allocated */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Needed buffer size %X, %s\n", @@ -312,11 +312,12 @@ acpi_evaluate_object(acpi_handle handle, acpi_format_exception (status))); } else { - /* We have enough space for the object, build it */ - + /* + * We have enough space for the object, build it + */ status = acpi_ut_copy_iobject_to_eobject - (info->return_object, + (info.return_object, return_buffer); } } @@ -324,37 +325,35 @@ acpi_evaluate_object(acpi_handle handle, } } - if (info->return_object) { + if (info.return_object) { /* - * Delete the internal return object. NOTE: Interpreter must be - * locked to avoid race condition. + * Delete the internal return object. NOTE: Interpreter + * must be locked to avoid race condition. */ status2 = acpi_ex_enter_interpreter(); if (ACPI_SUCCESS(status2)) { - - /* Remove one reference on the return object (should delete it) */ - - acpi_ut_remove_reference(info->return_object); + /* + * Delete the internal return object. (Or at least + * decrement the reference count by one) + */ + acpi_ut_remove_reference(info.return_object); acpi_ex_exit_interpreter(); } } - cleanup: - - /* Free the input parameter list (if we created one) */ - - if (info->parameters) { - + /* + * Free the input parameter list (if we created one), + */ + if (info.parameters) { /* Free the allocated parameter block */ - acpi_ut_delete_internal_object_list(info->parameters); + acpi_ut_delete_internal_object_list(info.parameters); } - ACPI_FREE(info); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_evaluate_object) +EXPORT_SYMBOL(acpi_evaluate_object); /******************************************************************************* * @@ -385,6 +384,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object) * function, etc. * ******************************************************************************/ + acpi_status acpi_walk_namespace(acpi_object_type type, acpi_handle start_object, @@ -394,7 +394,7 @@ acpi_walk_namespace(acpi_object_type type, { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_walk_namespace); + ACPI_FUNCTION_TRACE("acpi_walk_namespace"); /* Parameter validation */ @@ -421,7 +421,7 @@ acpi_walk_namespace(acpi_object_type type, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_walk_namespace) +EXPORT_SYMBOL(acpi_walk_namespace); /******************************************************************************* * @@ -436,6 +436,7 @@ ACPI_EXPORT_SYMBOL(acpi_walk_namespace) * on that. * ******************************************************************************/ + static acpi_status acpi_ns_get_device_callback(acpi_handle obj_handle, u32 nesting_level, @@ -472,7 +473,6 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, } if (!(flags & ACPI_STA_DEVICE_PRESENT)) { - /* Don't examine children of the device if not present */ return (AE_CTRL_DEPTH); @@ -489,7 +489,6 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, } if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { - /* Get the list of Compatible IDs */ status = acpi_ut_execute_CID(node, &cid); @@ -506,11 +505,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, sizeof(struct acpi_compatible_id)) != 0) { - ACPI_FREE(cid); + ACPI_MEM_FREE(cid); return (AE_OK); } } - ACPI_FREE(cid); + ACPI_MEM_FREE(cid); } } @@ -552,7 +551,7 @@ acpi_get_devices(char *HID, acpi_status status; struct acpi_get_devices_info info; - ACPI_FUNCTION_TRACE(acpi_get_devices); + ACPI_FUNCTION_TRACE("acpi_get_devices"); /* Parameter validation */ @@ -564,9 +563,9 @@ acpi_get_devices(char *HID, * We're going to call their callback from OUR callback, so we need * to know what it is, and their context parameter. */ - info.hid = HID; info.context = context; info.user_function = user_function; + info.hid = HID; /* * Lock the namespace around the walk. @@ -579,8 +578,9 @@ acpi_get_devices(char *HID, return_ACPI_STATUS(status); } - status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, + status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ns_get_device_callback, &info, return_value); @@ -588,7 +588,7 @@ acpi_get_devices(char *HID, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_devices) +EXPORT_SYMBOL(acpi_get_devices); /******************************************************************************* * @@ -603,6 +603,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_devices) * DESCRIPTION: Attach arbitrary data and handler to a namespace node. * ******************************************************************************/ + acpi_status acpi_attach_data(acpi_handle obj_handle, acpi_object_handler handler, void *data) @@ -636,8 +637,6 @@ acpi_attach_data(acpi_handle obj_handle, return (status); } -ACPI_EXPORT_SYMBOL(acpi_attach_data) - /******************************************************************************* * * FUNCTION: acpi_detach_data @@ -650,6 +649,7 @@ ACPI_EXPORT_SYMBOL(acpi_attach_data) * DESCRIPTION: Remove data that was previously attached to a node. * ******************************************************************************/ + acpi_status acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) { @@ -682,8 +682,6 @@ acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) return (status); } -ACPI_EXPORT_SYMBOL(acpi_detach_data) - /******************************************************************************* * * FUNCTION: acpi_get_data @@ -697,6 +695,7 @@ ACPI_EXPORT_SYMBOL(acpi_detach_data) * DESCRIPTION: Retrieve data that was previously attached to a namespace node. * ******************************************************************************/ + acpi_status acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) { @@ -728,5 +727,3 @@ acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return (status); } - -ACPI_EXPORT_SYMBOL(acpi_get_data) diff --git a/trunk/drivers/acpi/namespace/nsxfname.c b/trunk/drivers/acpi/namespace/nsxfname.c index 978213a6c19f..8cd8675a47c0 100644 --- a/trunk/drivers/acpi/namespace/nsxfname.c +++ b/trunk/drivers/acpi/namespace/nsxfname.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include @@ -112,8 +114,9 @@ acpi_get_handle(acpi_handle parent, /* * Find the Node and convert to a handle */ - status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, - &node); + status = + acpi_ns_get_node_by_path(pathname, prefix_node, ACPI_NS_NO_UPSEARCH, + &node); *ret_handle = NULL; if (ACPI_SUCCESS(status)) { @@ -123,7 +126,7 @@ acpi_get_handle(acpi_handle parent, return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_handle) +EXPORT_SYMBOL(acpi_get_handle); /****************************************************************************** * @@ -140,6 +143,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_handle) * complementary functions. * ******************************************************************************/ + acpi_status acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) { @@ -158,7 +162,6 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) } if (name_type == ACPI_FULL_PATHNAME) { - /* Get the full pathname (From the namespace root) */ status = acpi_ns_handle_to_pathname(handle, buffer); @@ -200,7 +203,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_name) +EXPORT_SYMBOL(acpi_get_name); /****************************************************************************** * @@ -216,6 +219,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) * control methods (Such as in the case of a device.) * ******************************************************************************/ + acpi_status acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) { @@ -237,7 +241,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) return (status); } - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); + info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_device_info)); if (!info) { return (AE_NO_MEMORY); } @@ -341,11 +345,11 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) } cleanup: - ACPI_FREE(info); + ACPI_MEM_FREE(info); if (cid_list) { - ACPI_FREE(cid_list); + ACPI_MEM_FREE(cid_list); } return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_object_info) +EXPORT_SYMBOL(acpi_get_object_info); diff --git a/trunk/drivers/acpi/namespace/nsxfobj.c b/trunk/drivers/acpi/namespace/nsxfobj.c index a163e1d3708d..a0332595677a 100644 --- a/trunk/drivers/acpi/namespace/nsxfobj.c +++ b/trunk/drivers/acpi/namespace/nsxfobj.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include @@ -99,7 +101,7 @@ acpi_status acpi_get_type(acpi_handle handle, acpi_object_type * ret_type) return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_type) +EXPORT_SYMBOL(acpi_get_type); /******************************************************************************* * @@ -114,6 +116,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type) * Handle. * ******************************************************************************/ + acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) { struct acpi_namespace_node *node; @@ -159,7 +162,7 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_parent) +EXPORT_SYMBOL(acpi_get_parent); /******************************************************************************* * @@ -178,6 +181,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_parent) * Scope is returned. * ******************************************************************************/ + acpi_status acpi_get_next_object(acpi_object_type type, acpi_handle parent, @@ -202,7 +206,6 @@ acpi_get_next_object(acpi_object_type type, /* If null handle, use the parent */ if (!child) { - /* Start search at the beginning of the specified scope */ parent_node = acpi_ns_map_handle_to_node(parent); @@ -239,4 +242,4 @@ acpi_get_next_object(acpi_object_type type, return (status); } -ACPI_EXPORT_SYMBOL(acpi_get_next_object) +EXPORT_SYMBOL(acpi_get_next_object); diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 13d6d5bdea26..64b98e82feb7 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -36,60 +36,12 @@ #define _COMPONENT ACPI_NUMA ACPI_MODULE_NAME("numa") -static nodemask_t nodes_found_map = NODE_MASK_NONE; -#define PXM_INVAL -1 -#define NID_INVAL -1 - -/* maps to convert between proximity domain and logical node ID */ -int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS] - = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL }; -int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] - = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; - extern int __init acpi_table_parse_madt_family(enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries); -int __cpuinit pxm_to_node(int pxm) -{ - if (pxm < 0) - return NID_INVAL; - return pxm_to_node_map[pxm]; -} - -int __cpuinit node_to_pxm(int node) -{ - if (node < 0) - return PXM_INVAL; - return node_to_pxm_map[node]; -} - -int __cpuinit acpi_map_pxm_to_node(int pxm) -{ - int node = pxm_to_node_map[pxm]; - - if (node < 0){ - if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) - return NID_INVAL; - node = first_unset_node(nodes_found_map); - pxm_to_node_map[pxm] = node; - node_to_pxm_map[node] = pxm; - node_set(node, nodes_found_map); - } - - return node; -} - -void __cpuinit acpi_unmap_pxm_to_node(int node) -{ - int pxm = node_to_pxm_map[node]; - pxm_to_node_map[pxm] = NID_INVAL; - node_to_pxm_map[node] = PXM_INVAL; - node_clear(node, nodes_found_map); -} - void __init acpi_table_print_srat_entry(acpi_table_entry_header * header) { @@ -254,18 +206,5 @@ int acpi_get_pxm(acpi_handle h) } while (ACPI_SUCCESS(status)); return -1; } -EXPORT_SYMBOL(acpi_get_pxm); -int acpi_get_node(acpi_handle *handle) -{ - int pxm, node = -1; - - ACPI_FUNCTION_TRACE("acpi_get_node"); - - pxm = acpi_get_pxm(handle); - if (pxm >= 0) - node = acpi_map_pxm_to_node(pxm); - - return_VALUE(node); -} -EXPORT_SYMBOL(acpi_get_node); +EXPORT_SYMBOL(acpi_get_pxm); diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 1bb558adee66..13b5fd5854a8 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -601,41 +600,23 @@ static void acpi_os_execute_deferred(void *context) return_VOID; } -static int acpi_os_execute_thread(void *context) -{ - struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context; - if (dpc) { - dpc->function(dpc->context); - kfree(dpc); - } - do_exit(0); -} - -/******************************************************************************* - * - * FUNCTION: acpi_os_execute - * - * PARAMETERS: Type - Type of the callback - * Function - Function to be executed - * Context - Function parameters - * - * RETURN: Status - * - * DESCRIPTION: Depending on type, either queues function for deferred execution or - * immediately executes function on a separate thread. - * - ******************************************************************************/ - -acpi_status acpi_os_execute(acpi_execute_type type, +acpi_status +acpi_os_queue_for_execution(u32 priority, acpi_osd_exec_callback function, void *context) { acpi_status status = AE_OK; struct acpi_os_dpc *dpc; struct work_struct *task; - struct task_struct *p; + + ACPI_FUNCTION_TRACE("os_queue_for_execution"); + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Scheduling function [%p(%p)] for deferred execution.\n", + function, context)); if (!function) - return AE_BAD_PARAMETER; + return_ACPI_STATUS(AE_BAD_PARAMETER); + /* * Allocate/initialize DPC structure. Note that this memory will be * freed by the callee. The kernel handles the tq_struct list in a @@ -646,37 +627,30 @@ acpi_status acpi_os_execute(acpi_execute_type type, * We can save time and code by allocating the DPC and tq_structs * from the same memory. */ - if (type == OSL_NOTIFY_HANDLER) { - dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_KERNEL); - } else { - dpc = kmalloc(sizeof(struct acpi_os_dpc) + - sizeof(struct work_struct), GFP_ATOMIC); - } + + dpc = + kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), + GFP_ATOMIC); if (!dpc) - return AE_NO_MEMORY; + return_ACPI_STATUS(AE_NO_MEMORY); + dpc->function = function; dpc->context = context; - if (type == OSL_NOTIFY_HANDLER) { - p = kthread_create(acpi_os_execute_thread, dpc, "kacpid_notify"); - if (!IS_ERR(p)) { - wake_up_process(p); - } else { - status = AE_NO_MEMORY; - kfree(dpc); - } - } else { - task = (void *)(dpc + 1); - INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); - if (!queue_work(kacpid_wq, task)) { - status = AE_ERROR; - kfree(dpc); - } + task = (void *)(dpc + 1); + INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); + + if (!queue_work(kacpid_wq, task)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Call to queue_work() failed.\n")); + kfree(dpc); + status = AE_ERROR; } - return status; + + return_ACPI_STATUS(status); } -EXPORT_SYMBOL(acpi_os_execute); +EXPORT_SYMBOL(acpi_os_queue_for_execution); void acpi_os_wait_events_complete(void *context) { @@ -795,6 +769,9 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); + if (in_atomic()) + timeout = 0; + switch (timeout) { /* * No Wait: @@ -919,6 +896,14 @@ u8 acpi_os_writable(void *ptr, acpi_size len) } #endif +u32 acpi_os_get_thread_id(void) +{ + if (!in_atomic()) + return current->pid; + + return 0; +} + acpi_status acpi_os_signal(u32 function, void *info) { switch (function) { @@ -1065,12 +1050,12 @@ void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags) * * FUNCTION: acpi_os_create_cache * - * PARAMETERS: name - Ascii name for the cache - * size - Size of each cached object - * depth - Maximum depth of the cache (in objects) - * cache - Where the new cache object is returned + * PARAMETERS: CacheName - Ascii name for the cache + * ObjectSize - Size of each cached object + * MaxDepth - Maximum depth of the cache (in objects) + * ReturnCache - Where the new cache object is returned * - * RETURN: status + * RETURN: Status * * DESCRIPTION: Create a cache object * @@ -1080,10 +1065,7 @@ acpi_status acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) { *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); - if (cache == NULL) - return AE_ERROR; - else - return AE_OK; + return AE_OK; } /******************************************************************************* @@ -1152,63 +1134,16 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) * * RETURN: Status * - * DESCRIPTION: Return a zero-filled object. + * DESCRIPTION: Get an object from the specified cache. If cache is empty, + * the object is allocated. * ******************************************************************************/ void *acpi_os_acquire_object(acpi_cache_t * cache) { - void *object = kmem_cache_zalloc(cache, GFP_KERNEL); + void *object = kmem_cache_alloc(cache, GFP_KERNEL); WARN_ON(!object); return object; } -/****************************************************************************** - * - * FUNCTION: acpi_os_validate_interface - * - * PARAMETERS: interface - Requested interface to be validated - * - * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise - * - * DESCRIPTION: Match an interface string to the interfaces supported by the - * host. Strings originate from an AML call to the _OSI method. - * - *****************************************************************************/ - -acpi_status -acpi_os_validate_interface (char *interface) -{ - - return AE_SUPPORT; -} - - -/****************************************************************************** - * - * FUNCTION: acpi_os_validate_address - * - * PARAMETERS: space_id - ACPI space ID - * address - Physical address - * length - Address length - * - * RETURN: AE_OK if address/length is valid for the space_id. Otherwise, - * should return AE_AML_ILLEGAL_ADDRESS. - * - * DESCRIPTION: Validate a system address via the host OS. Used to validate - * the addresses accessed by AML operation regions. - * - *****************************************************************************/ - -acpi_status -acpi_os_validate_address ( - u8 space_id, - acpi_physical_address address, - acpi_size length) -{ - - return AE_OK; -} - - #endif diff --git a/trunk/drivers/acpi/parser/psargs.c b/trunk/drivers/acpi/parser/psargs.c index bf88e076c3e9..de573be52718 100644 --- a/trunk/drivers/acpi/parser/psargs.c +++ b/trunk/drivers/acpi/parser/psargs.c @@ -79,7 +79,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) acpi_native_uint byte_count; u8 byte_zero_mask = 0x3F; /* Default [0:5] */ - ACPI_FUNCTION_TRACE(ps_get_next_package_length); + ACPI_FUNCTION_TRACE("ps_get_next_package_length"); /* * Byte 0 bits [6:7] contain the number of additional bytes @@ -128,7 +128,7 @@ u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) u8 *start = parser_state->aml; u32 package_length; - ACPI_FUNCTION_TRACE(ps_get_next_package_end); + ACPI_FUNCTION_TRACE("ps_get_next_package_end"); /* Function below updates parser_state->Aml */ @@ -157,7 +157,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) u8 *start = parser_state->aml; u8 *end = parser_state->aml; - ACPI_FUNCTION_TRACE(ps_get_next_namestring); + ACPI_FUNCTION_TRACE("ps_get_next_namestring"); /* Point past any namestring prefix characters (backslash or carat) */ @@ -237,7 +237,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, struct acpi_namespace_node *node; union acpi_generic_state scope_info; - ACPI_FUNCTION_TRACE(ps_get_next_namepath); + ACPI_FUNCTION_TRACE("ps_get_next_namepath"); path = acpi_ps_get_next_namestring(parser_state); acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP); @@ -275,7 +275,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, */ if (ACPI_SUCCESS(status) && possible_method_call && (node->type == ACPI_TYPE_METHOD)) { - /* This name is actually a control method invocation */ method_desc = acpi_ns_get_attached_object(node); @@ -320,7 +319,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, * some not_found cases are allowed */ if (status == AE_NOT_FOUND) { - /* 1) not_found is ok during load pass 1/2 (allow forward references) */ if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) != @@ -356,7 +354,6 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { - /* Report a control method execution error */ status = acpi_ds_method_error(status, walk_state); @@ -391,7 +388,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, u16 opcode; u8 *aml = parser_state->aml; - ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type); + ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type); switch (arg_type) { case ARGP_BYTEDATA: @@ -456,7 +453,7 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state, default: - ACPI_ERROR((AE_INFO, "Invalid ArgType %X", arg_type)); + ACPI_ERROR((AE_INFO, "Invalid arg_type %X", arg_type)); return_VOID; } @@ -487,7 +484,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state u16 opcode; u32 name; - ACPI_FUNCTION_TRACE(ps_get_next_field); + ACPI_FUNCTION_TRACE("ps_get_next_field"); /* Determine field type */ @@ -593,7 +590,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, u32 subop; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state); + ACPI_FUNCTION_TRACE_PTR("ps_get_next_arg", parser_state); switch (arg_type) { case ARGP_BYTEDATA: @@ -623,7 +620,6 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, case ARGP_FIELDLIST: if (parser_state->aml < parser_state->pkg_end) { - /* Non-empty list */ while (parser_state->aml < parser_state->pkg_end) { @@ -649,7 +645,6 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, case ARGP_BYTELIST: if (parser_state->aml < parser_state->pkg_end) { - /* Non-empty list */ arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); @@ -678,7 +673,6 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, if (subop == 0 || acpi_ps_is_leading_char(subop) || acpi_ps_is_prefix_char(subop)) { - /* null_name or name_string */ arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); @@ -709,7 +703,6 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, case ARGP_OBJLIST: if (parser_state->aml < parser_state->pkg_end) { - /* Non-empty list of variable arguments, nothing returned */ walk_state->arg_count = ACPI_VAR_ARGS; @@ -718,7 +711,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, default: - ACPI_ERROR((AE_INFO, "Invalid ArgType: %X", arg_type)); + ACPI_ERROR((AE_INFO, "Invalid arg_type: %X", arg_type)); status = AE_AML_OPERAND_TYPE; break; } diff --git a/trunk/drivers/acpi/parser/psloop.c b/trunk/drivers/acpi/parser/psloop.c index e1541db3753a..00b072e15d19 100644 --- a/trunk/drivers/acpi/parser/psloop.c +++ b/trunk/drivers/acpi/parser/psloop.c @@ -83,7 +83,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) struct acpi_parse_state *parser_state; u8 *aml_op_start = NULL; - ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); + ACPI_FUNCTION_TRACE_PTR("ps_parse_loop", walk_state); if (walk_state->descending_callback == NULL) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -95,7 +95,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { - /* We are restarting a preempted control method */ if (acpi_ps_has_completed_scope(parser_state)) { @@ -129,7 +128,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) } ACPI_EXCEPTION((AE_INFO, status, - "GetPredicate Failed")); + "get_predicate Failed")); return_ACPI_STATUS(status); } @@ -144,7 +143,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); } else if (walk_state->prev_op) { - /* We were in the middle of an op */ op = walk_state->prev_op; @@ -158,7 +156,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) while ((parser_state->aml < parser_state->aml_end) || (op)) { aml_op_start = parser_state->aml; if (!op) { - /* Get the next opcode from the AML stream */ walk_state->aml_offset = @@ -216,7 +213,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* Create Op structure and append to parent's argument list */ if (walk_state->op_info->flags & AML_NAMED) { - /* Allocate a new pre_op if necessary */ if (!pre_op) { @@ -375,7 +371,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) if (walk_state->op_info) { ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", + "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n", (u32) op->common.aml_opcode, walk_state->op_info->name, op, parser_state->aml, @@ -392,7 +388,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) /* Are there any arguments that must be processed? */ if (walk_state->arg_types) { - /* Get arguments */ switch (op->common.aml_opcode) { @@ -747,19 +742,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) if (ACPI_FAILURE(status2)) { return_ACPI_STATUS(status2); } - - status2 = - acpi_ds_result_stack_pop - (walk_state); - if (ACPI_FAILURE(status2)) { - return_ACPI_STATUS(status2); - } - - acpi_ut_delete_generic_state - (acpi_ut_pop_generic_state - (&walk_state->control_state)); } - acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); @@ -779,7 +762,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) return_ACPI_STATUS(status2); } } - acpi_ps_pop_scope(parser_state, &op, &walk_state->arg_types, &walk_state->arg_count); @@ -871,7 +853,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) } else if (ACPI_FAILURE(status)) { - /* First error is most important */ (void) diff --git a/trunk/drivers/acpi/parser/psopcode.c b/trunk/drivers/acpi/parser/psopcode.c index 4bd25e32769f..11d6351ab8b2 100644 --- a/trunk/drivers/acpi/parser/psopcode.c +++ b/trunk/drivers/acpi/parser/psopcode.c @@ -725,13 +725,12 @@ static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = { const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) { - ACPI_FUNCTION_NAME(ps_get_opcode_info); + ACPI_FUNCTION_NAME("ps_get_opcode_info"); /* * Detect normal 8-bit opcode or extended 16-bit opcode */ if (!(opcode & 0xFF00)) { - /* Simple (8-bit) opcode: 0-255, can't index beyond table */ return (&acpi_gbl_aml_op_info @@ -740,7 +739,6 @@ const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode) if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) && (((u8) opcode) <= MAX_EXTENDED_OPCODE)) { - /* Valid extended (16-bit) opcode */ return (&acpi_gbl_aml_op_info @@ -781,7 +779,7 @@ char *acpi_ps_get_opcode_name(u16 opcode) return (op->name); #else - return ("OpcodeName unavailable"); + return ("AE_NOT_CONFIGURED"); #endif } diff --git a/trunk/drivers/acpi/parser/psparse.c b/trunk/drivers/acpi/parser/psparse.c index 7ee2f2e77525..a9f3229f4106 100644 --- a/trunk/drivers/acpi/parser/psparse.c +++ b/trunk/drivers/acpi/parser/psparse.c @@ -106,7 +106,6 @@ u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state) opcode = (u16) ACPI_GET8(aml); if (opcode == AML_EXTENDED_OP_PREFIX) { - /* Extended opcode, get the second opcode byte */ aml++; @@ -138,7 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, const struct acpi_opcode_info *parent_info; union acpi_parse_object *replacement_op = NULL; - ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); + ACPI_FUNCTION_TRACE_PTR("ps_complete_this_op", op); /* Check for null Op, can happen if AML code is corrupt */ @@ -159,7 +158,6 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, if (op->common.parent) { prev = op->common.parent->common.value.arg; if (!prev) { - /* Nothing more to do */ goto cleanup; @@ -247,7 +245,6 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, /* We must unlink this op from the parent tree */ if (prev == op) { - /* This op is the first in the list */ if (replacement_op) { @@ -268,7 +265,6 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, else while (prev) { - /* Traverse all siblings in the parent's argument list */ next = prev->common.next; @@ -333,7 +329,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, struct acpi_parse_state *parser_state = &walk_state->parser_state; acpi_status status = AE_CTRL_PENDING; - ACPI_FUNCTION_TRACE_PTR(ps_next_parse_state, op); + ACPI_FUNCTION_TRACE_PTR("ps_next_parse_state", op); switch (callback_status) { case AE_CTRL_TERMINATE: @@ -453,10 +449,10 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; struct acpi_walk_state *previous_walk_state; - ACPI_FUNCTION_TRACE(ps_parse_aml); + ACPI_FUNCTION_TRACE("ps_parse_aml"); ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "Entered with WalkState=%p Aml=%p size=%X\n", + "Entered with walk_state=%p Aml=%p size=%X\n", walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size)); @@ -464,7 +460,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) thread = acpi_ut_create_thread_state(); if (!thread) { - acpi_ds_delete_walk_state(walk_state); return_ACPI_STATUS(AE_NO_MEMORY); } @@ -515,7 +510,6 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } else if (status == AE_CTRL_TERMINATE) { status = AE_OK; } else if ((status != AE_OK) && (walk_state->method_desc)) { - /* Either the method parse or actual execution failed */ ACPI_ERROR_METHOD("Method parse/execution failed", @@ -556,9 +550,20 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) */ if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) { - acpi_ds_terminate_control_method(walk_state-> - method_desc, - walk_state); + if (walk_state->method_desc) { + /* Decrement the thread count on the method parse tree */ + + if (walk_state->method_desc->method. + thread_count) { + walk_state->method_desc->method. + thread_count--; + } else { + ACPI_ERROR((AE_INFO, + "Invalid zero thread count in method")); + } + } + + acpi_ds_terminate_control_method(walk_state); } /* Delete this walk state and all linked control states */ @@ -567,7 +572,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) previous_walk_state = walk_state; ACPI_DEBUG_PRINT((ACPI_DB_PARSE, - "ReturnValue=%p, ImplicitValue=%p State=%p\n", + "return_value=%p, implicit_value=%p State=%p\n", walk_state->return_desc, walk_state->implicit_return_obj, walk_state)); @@ -628,14 +633,12 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) } } else { if (previous_walk_state->return_desc) { - /* Caller doesn't want it, must delete it */ acpi_ut_remove_reference(previous_walk_state-> return_desc); } if (previous_walk_state->implicit_return_obj) { - /* Caller doesn't want it, must delete it */ acpi_ut_remove_reference(previous_walk_state-> diff --git a/trunk/drivers/acpi/parser/psscope.c b/trunk/drivers/acpi/parser/psscope.c index a3e0314de24d..bc6047caccd9 100644 --- a/trunk/drivers/acpi/parser/psscope.c +++ b/trunk/drivers/acpi/parser/psscope.c @@ -106,14 +106,14 @@ acpi_ps_init_scope(struct acpi_parse_state * parser_state, { union acpi_generic_state *scope; - ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op); + ACPI_FUNCTION_TRACE_PTR("ps_init_scope", root_op); scope = acpi_ut_create_generic_state(); if (!scope) { return_ACPI_STATUS(AE_NO_MEMORY); } - scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE; + scope->common.data_type = ACPI_DESC_TYPE_STATE_RPSCOPE; scope->parse_scope.op = root_op; scope->parse_scope.arg_count = ACPI_VAR_ARGS; scope->parse_scope.arg_end = parser_state->aml_end; @@ -147,14 +147,14 @@ acpi_ps_push_scope(struct acpi_parse_state *parser_state, { union acpi_generic_state *scope; - ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op); + ACPI_FUNCTION_TRACE_PTR("ps_push_scope", op); scope = acpi_ut_create_generic_state(); if (!scope) { return_ACPI_STATUS(AE_NO_MEMORY); } - scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE; + scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE; scope->parse_scope.op = op; scope->parse_scope.arg_list = remaining_args; scope->parse_scope.arg_count = arg_count; @@ -165,7 +165,6 @@ acpi_ps_push_scope(struct acpi_parse_state *parser_state, acpi_ut_push_generic_state(&parser_state->scope, scope); if (arg_count == ACPI_VAR_ARGS) { - /* Multiple arguments */ scope->parse_scope.arg_end = parser_state->pkg_end; @@ -200,14 +199,14 @@ acpi_ps_pop_scope(struct acpi_parse_state *parser_state, { union acpi_generic_state *scope = parser_state->scope; - ACPI_FUNCTION_TRACE(ps_pop_scope); + ACPI_FUNCTION_TRACE("ps_pop_scope"); /* Only pop the scope if there is in fact a next scope */ if (scope->common.next) { scope = acpi_ut_pop_generic_state(&parser_state->scope); - /* Return to parsing previous op */ + /* return to parsing previous op */ *op = scope->parse_scope.op; *arg_list = scope->parse_scope.arg_list; @@ -218,7 +217,7 @@ acpi_ps_pop_scope(struct acpi_parse_state *parser_state, acpi_ut_delete_generic_state(scope); } else { - /* Empty parse stack, prepare to fetch next opcode */ + /* empty parse stack, prepare to fetch next opcode */ *op = NULL; *arg_list = 0; @@ -247,7 +246,7 @@ void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state) { union acpi_generic_state *scope; - ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state); + ACPI_FUNCTION_TRACE_PTR("ps_cleanup_scope", parser_state); if (!parser_state) { return_VOID; diff --git a/trunk/drivers/acpi/parser/pstree.c b/trunk/drivers/acpi/parser/pstree.c index 0015717ef096..dd6f16726fc4 100644 --- a/trunk/drivers/acpi/parser/pstree.c +++ b/trunk/drivers/acpi/parser/pstree.c @@ -77,7 +77,6 @@ union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn) op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); if (op_info->class == AML_CLASS_UNKNOWN) { - /* Invalid opcode or ASCII character */ return (NULL); @@ -86,7 +85,6 @@ union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn) /* Check if this opcode requires argument sub-objects */ if (!(op_info->flags & AML_HAS_ARGS)) { - /* Has no linked argument objects */ return (NULL); @@ -132,7 +130,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); if (op_info->class == AML_CLASS_UNKNOWN) { - /* Invalid opcode */ ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X", @@ -143,7 +140,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) /* Check if this opcode requires argument sub-objects */ if (!(op_info->flags & AML_HAS_ARGS)) { - /* Has no linked argument objects */ return; @@ -152,7 +148,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) /* Append the argument to the linked argument list */ if (op->common.value.arg) { - /* Append to existing argument list */ prev_arg = op->common.value.arg; @@ -227,14 +222,12 @@ union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin, } if (arg == origin) { - /* Reached parent of origin, end search */ return (NULL); } if (parent->common.next) { - /* Found sibling of parent */ return (parent->common.next); @@ -306,4 +299,5 @@ union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op) return (child); } #endif + #endif /* ACPI_FUTURE_USAGE */ diff --git a/trunk/drivers/acpi/parser/psutils.c b/trunk/drivers/acpi/parser/psutils.c index 182474ae8ce9..3e07cb9cb748 100644 --- a/trunk/drivers/acpi/parser/psutils.c +++ b/trunk/drivers/acpi/parser/psutils.c @@ -89,7 +89,7 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) { ACPI_FUNCTION_ENTRY(); - op->common.descriptor_type = ACPI_DESC_TYPE_PARSER; + op->common.data_type = ACPI_DESC_TYPE_PARSER; op->common.aml_opcode = opcode; ACPI_DISASM_ONLY_MEMBERS(ACPI_STRNCPY(op->common.aml_op_name, @@ -135,7 +135,6 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode) /* Allocate the minimum required size object */ if (flags == ACPI_PARSEOP_GENERIC) { - /* The generic op (default) is by far the most common (16 to 1) */ op = acpi_os_acquire_object(acpi_gbl_ps_node_cache); @@ -172,7 +171,7 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode) void acpi_ps_free_op(union acpi_parse_object *op) { - ACPI_FUNCTION_NAME(ps_free_op); + ACPI_FUNCTION_NAME("ps_free_op"); if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n", diff --git a/trunk/drivers/acpi/parser/pswalk.c b/trunk/drivers/acpi/parser/pswalk.c index a84a547a0f1b..06f05bfd7612 100644 --- a/trunk/drivers/acpi/parser/pswalk.c +++ b/trunk/drivers/acpi/parser/pswalk.c @@ -64,21 +64,18 @@ void acpi_ps_delete_parse_tree(union acpi_parse_object *subtree_root) union acpi_parse_object *next = NULL; union acpi_parse_object *parent = NULL; - ACPI_FUNCTION_TRACE_PTR(ps_delete_parse_tree, subtree_root); + ACPI_FUNCTION_TRACE_PTR("ps_delete_parse_tree", subtree_root); /* Visit all nodes in the subtree */ while (op) { - /* Check if we are not ascending */ if (op != parent) { - /* Look for an argument or child of the current op */ next = acpi_ps_get_arg(op, 0); if (next) { - /* Still going downward in tree (Op is not completed yet) */ op = next; diff --git a/trunk/drivers/acpi/parser/psxface.c b/trunk/drivers/acpi/parser/psxface.c index 5d996c1140af..2dd48cbb7c02 100644 --- a/trunk/drivers/acpi/parser/psxface.c +++ b/trunk/drivers/acpi/parser/psxface.c @@ -50,14 +50,14 @@ ACPI_MODULE_NAME("psxface") /* Local Prototypes */ -static void acpi_ps_start_trace(struct acpi_evaluate_info *info); +static void acpi_ps_start_trace(struct acpi_parameter_info *info); -static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); +static void acpi_ps_stop_trace(struct acpi_parameter_info *info); -static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); +static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); static void -acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); +acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); /******************************************************************************* * @@ -113,7 +113,7 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) * ******************************************************************************/ -static void acpi_ps_start_trace(struct acpi_evaluate_info *info) +static void acpi_ps_start_trace(struct acpi_parameter_info *info) { acpi_status status; @@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info) } if ((!acpi_gbl_trace_method_name) || - (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { + (acpi_gbl_trace_method_name != info->node->name.integer)) { goto exit; } @@ -158,7 +158,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info) * ******************************************************************************/ -static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) +static void acpi_ps_stop_trace(struct acpi_parameter_info *info) { acpi_status status; @@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) } if ((!acpi_gbl_trace_method_name) || - (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { + (acpi_gbl_trace_method_name != info->node->name.integer)) { goto exit; } @@ -212,23 +212,22 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) * ******************************************************************************/ -acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) +acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) { acpi_status status; - ACPI_FUNCTION_TRACE(ps_execute_method); + ACPI_FUNCTION_TRACE("ps_execute_method"); /* Validate the Info and method Node */ - if (!info || !info->resolved_node) { + if (!info || !info->node) { return_ACPI_STATUS(AE_NULL_ENTRY); } /* Init for new method, wait on concurrency semaphore */ status = - acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc, - NULL); + acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -249,7 +248,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Begin Method Parse **** Entry=%p obj=%p\n", - info->resolved_node, info->obj_desc)); + info->node, info->obj_desc)); info->pass_number = 1; status = acpi_ps_execute_pass(info); @@ -262,7 +261,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Begin Method Execution **** Entry=%p obj=%p\n", - info->resolved_node, info->obj_desc)); + info->node, info->obj_desc)); info->pass_number = 3; status = acpi_ps_execute_pass(info); @@ -287,7 +286,8 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) * a control exception code */ if (info->return_object) { - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Method returned obj_desc=%p\n", info->return_object)); ACPI_DUMP_STACK_ENTRY(info->return_object); @@ -301,7 +301,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) * * FUNCTION: acpi_ps_update_parameter_list * - * PARAMETERS: Info - See struct acpi_evaluate_info + * PARAMETERS: Info - See struct acpi_parameter_info * (Used: parameter_type and Parameters) * Action - Add or Remove reference * @@ -312,16 +312,14 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ******************************************************************************/ static void -acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) +acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) { acpi_native_uint i; if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { - /* Update reference count for each parameter */ for (i = 0; info->parameters[i]; i++) { - /* Ignore errors, just do them all */ (void)acpi_ut_update_object_reference(info-> @@ -335,7 +333,7 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) * * FUNCTION: acpi_ps_execute_pass * - * PARAMETERS: Info - See struct acpi_evaluate_info + * PARAMETERS: Info - See struct acpi_parameter_info * (Used: pass_number, Node, and obj_desc) * * RETURN: Status @@ -344,13 +342,13 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) * ******************************************************************************/ -static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) +static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info) { acpi_status status; union acpi_parse_object *op; struct acpi_walk_state *walk_state; - ACPI_FUNCTION_TRACE(ps_execute_pass); + ACPI_FUNCTION_TRACE("ps_execute_pass"); /* Create and init a Root Node */ @@ -369,7 +367,7 @@ static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) goto cleanup; } - status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, + status = acpi_ds_init_aml_walk(walk_state, op, info->node, info->obj_desc->method.aml_start, info->obj_desc->method.aml_length, info->pass_number == 1 ? NULL : info, diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 228bdb626502..8920e8c6e246 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -92,7 +91,7 @@ static struct { int count; struct list_head entries; } acpi_link; -DEFINE_MUTEX(acpi_link_lock); +DECLARE_MUTEX(acpi_link_lock); /* -------------------------------------------------------------------------- PCI Link Device Management @@ -642,19 +641,19 @@ acpi_pci_link_allocate_irq(acpi_handle handle, return_VALUE(-1); } - mutex_lock(&acpi_link_lock); + down(&acpi_link_lock); if (acpi_pci_link_allocate(link)) { - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); return_VALUE(-1); } if (!link->irq.active) { - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n")); return_VALUE(-1); } link->refcnt++; - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); if (triggering) *triggering = link->irq.triggering; @@ -692,9 +691,9 @@ int acpi_pci_link_free_irq(acpi_handle handle) return_VALUE(-1); } - mutex_lock(&acpi_link_lock); + down(&acpi_link_lock); if (!link->irq.initialized) { - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n")); return_VALUE(-1); } @@ -717,7 +716,7 @@ int acpi_pci_link_free_irq(acpi_handle handle) if (link->refcnt == 0) { acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); } - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); return_VALUE(link->irq.active); } @@ -748,7 +747,7 @@ static int acpi_pci_link_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); acpi_driver_data(device) = link; - mutex_lock(&acpi_link_lock); + down(&acpi_link_lock); result = acpi_pci_link_get_possible(link); if (result) goto end; @@ -783,7 +782,7 @@ static int acpi_pci_link_add(struct acpi_device *device) end: /* disable all links -- to be activated on use */ acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); if (result) kfree(link); @@ -841,9 +840,9 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type) link = (struct acpi_pci_link *)acpi_driver_data(device); - mutex_lock(&acpi_link_lock); + down(&acpi_link_lock); list_del(&link->node); - mutex_unlock(&acpi_link_lock); + up(&acpi_link_lock); kfree(link); diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index decaebb4cbe9..713b763884a9 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -110,7 +110,7 @@ static struct file_operations acpi_processor_info_fops = { }; struct acpi_processor *processors[NR_CPUS]; -struct acpi_processor_errata errata __read_mostly; +struct acpi_processor_errata errata; /* -------------------------------------------------------------------------- Errata Handling @@ -388,7 +388,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) /* Use the acpiid in MADT to map cpus in case of SMP */ #ifndef CONFIG_SMP -#define convert_acpiid_to_cpu(acpi_id) (-1) +#define convert_acpiid_to_cpu(acpi_id) (0xff) #else #ifdef CONFIG_IA64 @@ -401,7 +401,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) #define ARCH_BAD_APICID (0xff) #endif -static int convert_acpiid_to_cpu(u8 acpi_id) +static u8 convert_acpiid_to_cpu(u8 acpi_id) { u16 apic_id; int i; @@ -427,7 +427,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) acpi_status status = 0; union acpi_object object = { 0 }; struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; - int cpu_index; + u8 cpu_index; static int cpu0_initialized; ACPI_FUNCTION_TRACE("acpi_processor_get_info"); @@ -473,7 +473,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) cpu_index = convert_acpiid_to_cpu(pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ - if (!cpu0_initialized && (cpu_index == -1) && + if (!cpu0_initialized && (cpu_index == 0xff) && (num_online_cpus() == 1)) { cpu_index = 0; } @@ -487,7 +487,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) * less than the max # of CPUs. They should be ignored _iff * they are physically not present. */ - if (cpu_index == -1) { + if (cpu_index >= NR_CPUS) { if (ACPI_FAILURE (acpi_processor_hotadd_init(pr->handle, &pr->id))) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, @@ -558,8 +558,8 @@ static int acpi_processor_start(struct acpi_device *device) */ if (processor_device_array[pr->id] != NULL && processor_device_array[pr->id] != (void *)device) { - printk(KERN_WARNING "BIOS reported wrong ACPI id" - "for the processor\n"); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "BIOS reporting wrong ACPI id" + "for the processor\n")); return_VALUE(-ENODEV); } processor_device_array[pr->id] = (void *)device; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 8a74bf3efd8e..80fa43471f48 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -54,10 +54,10 @@ ACPI_MODULE_NAME("acpi_processor") #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ -static void (*pm_idle_save) (void) __read_mostly; +static void (*pm_idle_save) (void); module_param(max_cstate, uint, 0644); -static unsigned int nocst __read_mostly; +static unsigned int nocst = 0; module_param(nocst, uint, 0000); /* @@ -67,7 +67,7 @@ module_param(nocst, uint, 0000); * 100 HZ: 0x0000000F: 4 jiffies = 40ms * reduce history for more aggressive entry into C3 */ -static unsigned int bm_history __read_mostly = +static unsigned int bm_history = (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); module_param(bm_history, uint, 0644); /* -------------------------------------------------------------------------- @@ -206,11 +206,11 @@ acpi_processor_power_activate(struct acpi_processor *pr, static void acpi_safe_halt(void) { - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); if (!need_resched()) safe_halt(); - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); } static atomic_t c3_cpu_count; @@ -330,10 +330,10 @@ static void acpi_processor_idle(void) * Invoke the current Cx state to put the processor to sleep. */ if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { - current_thread_info()->status &= ~TS_POLLING; + clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); if (need_resched()) { - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); local_irq_enable(); return; } @@ -369,14 +369,9 @@ static void acpi_processor_idle(void) t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); - -#ifdef CONFIG_GENERIC_TIME - /* TSC halts in C2, so notify users */ - mark_tsc_unstable(); -#endif /* Re-enable interrupts */ local_irq_enable(); - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; @@ -414,13 +409,9 @@ static void acpi_processor_idle(void) ACPI_MTX_DO_NOT_LOCK); } -#ifdef CONFIG_GENERIC_TIME - /* TSC halts in C3, so notify users */ - mark_tsc_unstable(); -#endif /* Re-enable interrupts */ local_irq_enable(); - current_thread_info()->status |= TS_POLLING; + set_thread_flag(TIF_POLLING_NRFLAG); /* Compute time (ticks) that we were actually asleep */ sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; @@ -1090,7 +1081,7 @@ int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) { acpi_status status = 0; - static int first_run; + static int first_run = 0; struct proc_dir_entry *entry = NULL; unsigned int i; diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 41aaaba74b19..f36db22ce1ae 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -34,7 +34,6 @@ #ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF #include #include -#include #include #endif @@ -49,7 +48,7 @@ #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("acpi_processor") -static DEFINE_MUTEX(performance_mutex); +static DECLARE_MUTEX(performance_sem); /* * _PPC support is implemented as a CPUfreq policy notifier: @@ -73,7 +72,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, struct acpi_processor *pr; unsigned int ppc = 0; - mutex_lock(&performance_mutex); + down(&performance_sem); if (event != CPUFREQ_INCOMPATIBLE) goto out; @@ -94,7 +93,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, core_frequency * 1000); out: - mutex_unlock(&performance_mutex); + up(&performance_sem); return 0; } @@ -554,230 +553,6 @@ static void acpi_cpufreq_remove_file(struct acpi_processor *pr) } #endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */ -static int acpi_processor_get_psd(struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"}; - struct acpi_buffer state = {0, NULL}; - union acpi_object *psd = NULL; - struct acpi_psd_package *pdomain; - - status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer); - if (ACPI_FAILURE(status)) { - return -ENODEV; - } - - psd = (union acpi_object *) buffer.pointer; - if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); - result = -EFAULT; - goto end; - } - - if (psd->package.count != 1) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); - result = -EFAULT; - goto end; - } - - pdomain = &(pr->performance->domain_info); - - state.length = sizeof(struct acpi_psd_package); - state.pointer = pdomain; - - status = acpi_extract_package(&(psd->package.elements[0]), - &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); - result = -EFAULT; - goto end; - } - - if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n")); - result = -EFAULT; - goto end; - } - - if (pdomain->revision != ACPI_PSD_REV0_REVISION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n")); - result = -EFAULT; - goto end; - } - -end: - acpi_os_free(buffer.pointer); - return result; -} - -int acpi_processor_preregister_performance( - struct acpi_processor_performance **performance) -{ - int count, count_target; - int retval = 0; - unsigned int i, j; - cpumask_t covered_cpus; - struct acpi_processor *pr; - struct acpi_psd_package *pdomain; - struct acpi_processor *match_pr; - struct acpi_psd_package *match_pdomain; - - mutex_lock(&performance_mutex); - - retval = 0; - - /* Call _PSD for all CPUs */ - for_each_possible_cpu(i) { - pr = processors[i]; - if (!pr) { - /* Look only at processors in ACPI namespace */ - continue; - } - - if (pr->performance) { - retval = -EBUSY; - continue; - } - - if (!performance || !performance[i]) { - retval = -EINVAL; - continue; - } - - pr->performance = performance[i]; - cpu_set(i, pr->performance->shared_cpu_map); - if (acpi_processor_get_psd(pr)) { - retval = -EINVAL; - continue; - } - } - if (retval) - goto err_ret; - - /* - * Now that we have _PSD data from all CPUs, lets setup P-state - * domain info. - */ - for_each_possible_cpu(i) { - pr = processors[i]; - if (!pr) - continue; - - /* Basic validity check for domain info */ - pdomain = &(pr->performance->domain_info); - if ((pdomain->revision != ACPI_PSD_REV0_REVISION) || - (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) { - retval = -EINVAL; - goto err_ret; - } - if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && - pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && - pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { - retval = -EINVAL; - goto err_ret; - } - } - - cpus_clear(covered_cpus); - for_each_possible_cpu(i) { - pr = processors[i]; - if (!pr) - continue; - - if (cpu_isset(i, covered_cpus)) - continue; - - pdomain = &(pr->performance->domain_info); - cpu_set(i, pr->performance->shared_cpu_map); - cpu_set(i, covered_cpus); - if (pdomain->num_processors <= 1) - continue; - - /* Validate the Domain info */ - count_target = pdomain->num_processors; - count = 1; - if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL || - pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL) { - pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL; - } else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) { - pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ANY; - } - - for_each_possible_cpu(j) { - if (i == j) - continue; - - match_pr = processors[j]; - if (!match_pr) - continue; - - match_pdomain = &(match_pr->performance->domain_info); - if (match_pdomain->domain != pdomain->domain) - continue; - - /* Here i and j are in the same domain */ - - if (match_pdomain->num_processors != count_target) { - retval = -EINVAL; - goto err_ret; - } - - if (pdomain->coord_type != match_pdomain->coord_type) { - retval = -EINVAL; - goto err_ret; - } - - cpu_set(j, covered_cpus); - cpu_set(j, pr->performance->shared_cpu_map); - count++; - } - - for_each_possible_cpu(j) { - if (i == j) - continue; - - match_pr = processors[j]; - if (!match_pr) - continue; - - match_pdomain = &(match_pr->performance->domain_info); - if (match_pdomain->domain != pdomain->domain) - continue; - - match_pr->performance->shared_type = - pr->performance->shared_type; - match_pr->performance->shared_cpu_map = - pr->performance->shared_cpu_map; - } - } - -err_ret: - if (retval) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error while parsing _PSD domain information. Assuming no coordination\n")); - } - - for_each_possible_cpu(i) { - pr = processors[i]; - if (!pr || !pr->performance) - continue; - - /* Assume no coordination on any error parsing domain info */ - if (retval) { - cpus_clear(pr->performance->shared_cpu_map); - cpu_set(i, pr->performance->shared_cpu_map); - pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL; - } - pr->performance = NULL; /* Will be set for real in register */ - } - - mutex_unlock(&performance_mutex); - return retval; -} -EXPORT_SYMBOL(acpi_processor_preregister_performance); - - int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu) @@ -789,16 +564,16 @@ acpi_processor_register_performance(struct acpi_processor_performance if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return_VALUE(-EINVAL); - mutex_lock(&performance_mutex); + down(&performance_sem); pr = processors[cpu]; if (!pr) { - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VALUE(-ENODEV); } if (pr->performance) { - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VALUE(-EBUSY); } @@ -808,13 +583,13 @@ acpi_processor_register_performance(struct acpi_processor_performance if (acpi_processor_get_performance_info(pr)) { pr->performance = NULL; - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VALUE(-EIO); } acpi_cpufreq_add_file(pr); - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VALUE(0); } @@ -828,11 +603,11 @@ acpi_processor_unregister_performance(struct acpi_processor_performance ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance"); - mutex_lock(&performance_mutex); + down(&performance_sem); pr = processors[cpu]; if (!pr) { - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VOID; } @@ -842,7 +617,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance acpi_cpufreq_remove_file(pr); - mutex_unlock(&performance_mutex); + up(&performance_sem); return_VOID; } diff --git a/trunk/drivers/acpi/resources/rscalc.c b/trunk/drivers/acpi/resources/rscalc.c index cf87b0230026..4038dbfa63a0 100644 --- a/trunk/drivers/acpi/resources/rscalc.c +++ b/trunk/drivers/acpi/resources/rscalc.c @@ -78,7 +78,6 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) ACPI_FUNCTION_ENTRY(); for (bits_set = 0; bit_field; bits_set++) { - /* Zero the least significant bit that is set */ bit_field &= (bit_field - 1); @@ -155,18 +154,15 @@ acpi_rs_stream_option_length(u32 resource_length, * length, minus one byte for the resource_source_index itself. */ if (resource_length > minimum_aml_resource_length) { - /* Compute the length of the optional string */ string_length = resource_length - minimum_aml_resource_length - 1; } - /* - * Round the length up to a multiple of the native word in order to - * guarantee that the entire resource descriptor is native word aligned - */ - return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length)); + /* Round up length to 32 bits for internal structure alignment */ + + return (ACPI_ROUND_UP_to_32_bITS(string_length)); } /******************************************************************************* @@ -190,12 +186,11 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) acpi_size aml_size_needed = 0; acpi_rs_length total_size; - ACPI_FUNCTION_TRACE(rs_get_aml_length); + ACPI_FUNCTION_TRACE("rs_get_aml_length"); /* Traverse entire list of internal resource descriptors */ while (resource) { - /* Validate the descriptor type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { @@ -219,7 +214,6 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) * is a Large Resource data type. */ if (resource->data.vendor.byte_length > 7) { - /* Base size of a Large resource descriptor */ total_size = @@ -338,22 +332,20 @@ acpi_rs_get_list_length(u8 * aml_buffer, acpi_status status; u8 *end_aml; u8 *buffer; - u32 buffer_size; + u32 buffer_size = 0; u16 temp16; u16 resource_length; u32 extra_struct_bytes; u8 resource_index; u8 minimum_aml_resource_length; - ACPI_FUNCTION_TRACE(rs_get_list_length); + ACPI_FUNCTION_TRACE("rs_get_list_length"); - *size_needed = 0; end_aml = aml_buffer + aml_buffer_length; /* Walk the list of AML resource descriptors */ while (aml_buffer < end_aml) { - /* Validate the Resource Type and Resource Length */ status = acpi_ut_validate_resource(aml_buffer, &resource_index); @@ -394,28 +386,35 @@ acpi_rs_get_list_length(u8 * aml_buffer, break; case ACPI_RESOURCE_NAME_VENDOR_SMALL: - case ACPI_RESOURCE_NAME_VENDOR_LARGE: /* * Vendor Resource: - * Get the number of vendor data bytes + * Ensure a 32-bit boundary for the structure */ - extra_struct_bytes = resource_length; + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length); break; case ACPI_RESOURCE_NAME_END_TAG: /* - * End Tag: - * This is the normal exit, add size of end_tag + * End Tag: This is the normal exit, add size of end_tag */ - *size_needed += ACPI_RS_SIZE_MIN; + *size_needed = buffer_size + ACPI_RS_SIZE_MIN; return_ACPI_STATUS(AE_OK); + case ACPI_RESOURCE_NAME_VENDOR_LARGE: + /* + * Vendor Resource: + * Add vendor data and ensure a 32-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_32_bITS(resource_length); + break; + case ACPI_RESOURCE_NAME_ADDRESS32: case ACPI_RESOURCE_NAME_ADDRESS16: - case ACPI_RESOURCE_NAME_ADDRESS64: /* - * Address Resource: - * Add the size of the optional resource_source + * 32-Bit or 16-bit Address Resource: + * Add the size of any optional data (resource_source) */ extra_struct_bytes = acpi_rs_stream_option_length(resource_length, @@ -424,46 +423,50 @@ acpi_rs_get_list_length(u8 * aml_buffer, case ACPI_RESOURCE_NAME_EXTENDED_IRQ: /* - * Extended IRQ Resource: - * Using the interrupt_table_length, add 4 bytes for each additional - * interrupt. Note: at least one interrupt is required and is - * included in the minimum descriptor size (reason for the -1) + * Extended IRQ: + * Point past the interrupt_vector_flags to get the + * interrupt_table_length. */ - extra_struct_bytes = (buffer[1] - 1) * sizeof(u32); - - /* Add the size of the optional resource_source */ + buffer++; - extra_struct_bytes += + extra_struct_bytes = + /* + * Add 4 bytes for each additional interrupt. Note: at + * least one interrupt is required and is included in + * the minimum descriptor size + */ + ((*buffer - 1) * sizeof(u32)) + + /* Add the size of any optional data (resource_source) */ acpi_rs_stream_option_length(resource_length - extra_struct_bytes, minimum_aml_resource_length); break; + case ACPI_RESOURCE_NAME_ADDRESS64: + /* + * 64-Bit Address Resource: + * Add the size of any optional data (resource_source) + * Ensure a 64-bit boundary for the structure + */ + extra_struct_bytes = + ACPI_ROUND_UP_to_64_bITS + (acpi_rs_stream_option_length + (resource_length, minimum_aml_resource_length)); + break; + default: break; } - /* - * Update the required buffer size for the internal descriptor structs - * - * Important: Round the size up for the appropriate alignment. This - * is a requirement on IA64. - */ - buffer_size = acpi_gbl_resource_struct_sizes[resource_index] + - extra_struct_bytes; - buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size); + /* Update the required buffer size for the internal descriptor structs */ - *size_needed += buffer_size; - - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Type %.2X, AmlLength %.2X InternalLength %.2X\n", - acpi_ut_get_resource_type(aml_buffer), - acpi_ut_get_descriptor_length(aml_buffer), - buffer_size)); + temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + + extra_struct_bytes); + buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); /* - * Point to the next resource within the AML stream using the length - * contained in the resource descriptor header + * Point to the next resource within the stream + * using the size of the header plus the length contained in the header */ aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); } @@ -503,7 +506,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, u8 name_found; u32 table_index; - ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length); + ACPI_FUNCTION_TRACE("rs_get_pci_routing_table_length"); number_of_elements = package_object->package.count; @@ -520,7 +523,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, top_object_list = package_object->package.elements; for (index = 0; index < number_of_elements; index++) { - /* Dereference the sub-package */ package_element = *top_object_list; @@ -579,7 +581,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, /* Round up the size since each element must be aligned */ - temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed); + temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed); /* Point to the next union acpi_operand_object */ @@ -587,7 +589,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, } /* - * Add an extra element to the end of the list, essentially a + * Adding an extra element to the end of the list, essentially a * NULL terminator */ *buffer_size_needed = diff --git a/trunk/drivers/acpi/resources/rscreate.c b/trunk/drivers/acpi/resources/rscreate.c index 008058acdd39..8c128dea3252 100644 --- a/trunk/drivers/acpi/resources/rscreate.c +++ b/trunk/drivers/acpi/resources/rscreate.c @@ -75,11 +75,10 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, u8 *aml_start; acpi_size list_size_needed = 0; u32 aml_buffer_length; - void *resource; - ACPI_FUNCTION_TRACE(rs_create_resource_list); + ACPI_FUNCTION_TRACE("rs_create_resource_list"); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlBuffer = %p\n", aml_buffer)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_buffer = %p\n", aml_buffer)); /* Params already validated, so we don't re-validate here */ @@ -93,7 +92,7 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, status = acpi_rs_get_list_length(aml_start, aml_buffer_length, &list_size_needed); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", status, (u32) list_size_needed)); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -108,15 +107,13 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, /* Do the conversion */ - resource = output_buffer->pointer; - status = acpi_ut_walk_aml_resources(aml_start, aml_buffer_length, - acpi_rs_convert_aml_to_resources, - &resource); + status = acpi_rs_convert_aml_to_resources(aml_start, aml_buffer_length, + output_buffer->pointer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n", output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS(AE_OK); } @@ -158,7 +155,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, acpi_status status; struct acpi_buffer path_buffer; - ACPI_FUNCTION_TRACE(rs_create_pci_routing_table); + ACPI_FUNCTION_TRACE("rs_create_pci_routing_table"); /* Params already validated, so we don't re-validate here */ @@ -170,7 +167,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, return_ACPI_STATUS(status); } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "BufferSizeNeeded = %X\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "buffer_size_needed = %X\n", (u32) buffer_size_needed)); /* Validate/Allocate/Clear caller buffer */ @@ -335,7 +332,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* Now align the current length */ user_prt->length = - (u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length); + (u32) ACPI_ROUND_UP_to_64_bITS(user_prt->length); /* 4) Fourth subobject: Dereference the PRT.source_index */ @@ -344,7 +341,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, user_prt->source_index = (u32) obj_desc->integer.value; } else { ACPI_ERROR((AE_INFO, - "(PRT[%X].SourceIndex) Need Integer, found %s", + "(PRT[%X].source_index) Need Integer, found %s", index, acpi_ut_get_object_type_name(obj_desc))); return_ACPI_STATUS(AE_BAD_DATA); @@ -355,7 +352,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, top_object_list++; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n", output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS(AE_OK); } @@ -385,9 +382,9 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, acpi_status status; acpi_size aml_size_needed = 0; - ACPI_FUNCTION_TRACE(rs_create_aml_resources); + ACPI_FUNCTION_TRACE("rs_create_aml_resources"); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n", linked_list_buffer)); /* @@ -398,7 +395,7 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, */ status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_size_needed=%X, %s\n", (u32) aml_size_needed, acpi_format_exception(status))); if (ACPI_FAILURE(status)) { @@ -422,7 +419,7 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, return_ACPI_STATUS(status); } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "output_buffer %p Length %X\n", output_buffer->pointer, (u32) output_buffer->length)); return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/resources/rsdump.c b/trunk/drivers/acpi/resources/rsdump.c index 9c99a723a860..e7de061cf883 100644 --- a/trunk/drivers/acpi/resources/rsdump.c +++ b/trunk/drivers/acpi/resources/rsdump.c @@ -91,11 +91,11 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); struct acpi_rsdump_info acpi_rs_dump_irq[6] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", - acpi_gbl_he_decode}, + acpi_gbl_HEdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", - acpi_gbl_ll_decode}, + acpi_gbl_LLdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing", - acpi_gbl_shr_decode}, + acpi_gbl_SHRdecode}, {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count), "Interrupt Count", NULL}, {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]), @@ -105,11 +105,11 @@ struct acpi_rsdump_info acpi_rs_dump_irq[6] = { struct acpi_rsdump_info acpi_rs_dump_dma[6] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed", - acpi_gbl_typ_decode}, + acpi_gbl_TYPdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering", - acpi_gbl_bm_decode}, + acpi_gbl_BMdecode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type", - acpi_gbl_siz_decode}, + acpi_gbl_SIZdecode}, {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count", NULL}, {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List", @@ -158,7 +158,7 @@ struct acpi_rsdump_info acpi_rs_dump_vendor[3] = { }; struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = { - {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag", + {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "end_tag", NULL} }; @@ -166,7 +166,7 @@ struct acpi_rsdump_info acpi_rs_dump_memory24[6] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24), "24-Bit Memory Range", NULL}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect), - "Write Protect", acpi_gbl_rw_decode}, + "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum", NULL}, {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum", @@ -181,7 +181,7 @@ struct acpi_rsdump_info acpi_rs_dump_memory32[6] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32), "32-Bit Memory Range", NULL}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect), - "Write Protect", acpi_gbl_rw_decode}, + "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum", NULL}, {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum", @@ -196,7 +196,7 @@ struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = { {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32), "32-Bit Fixed Memory Range", NULL}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect), - "Write Protect", acpi_gbl_rw_decode}, + "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address", NULL}, {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length), @@ -278,11 +278,11 @@ struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = { {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer), "Type", acpi_gbl_consume_decode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering), - "Triggering", acpi_gbl_he_decode}, + "Triggering", acpi_gbl_HEdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity", - acpi_gbl_ll_decode}, + acpi_gbl_LLdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing", - acpi_gbl_shr_decode}, + acpi_gbl_SHRdecode}, {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL, NULL}, {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count), @@ -314,7 +314,7 @@ static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = { {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer), "Consumer/Producer", acpi_gbl_consume_decode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode", - acpi_gbl_dec_decode}, + acpi_gbl_DECdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed), "Min Relocatability", acpi_gbl_min_decode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed), @@ -325,24 +325,24 @@ static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags), "Resource Type", (void *)"Memory Range"}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect), - "Write Protect", acpi_gbl_rw_decode}, + "Write Protect", acpi_gbl_RWdecode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching), - "Caching", acpi_gbl_mem_decode}, + "Caching", acpi_gbl_MEMdecode}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type), - "Range Type", acpi_gbl_mtp_decode}, + "Range Type", acpi_gbl_MTPdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation), - "Translation", acpi_gbl_ttp_decode} + "Translation", acpi_gbl_TTPdecode} }; static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = { {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags), "Resource Type", (void *)"I/O Range"}, {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type), - "Range Type", acpi_gbl_rng_decode}, + "Range Type", acpi_gbl_RNGdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation), - "Translation", acpi_gbl_ttp_decode}, + "Translation", acpi_gbl_TTPdecode}, {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type), - "Translation Type", acpi_gbl_trs_decode} + "Translation Type", acpi_gbl_TRSdecode} }; /* diff --git a/trunk/drivers/acpi/resources/rsinfo.c b/trunk/drivers/acpi/resources/rsinfo.c index 9e7ae2f8a1d3..d9ae64b77bd9 100644 --- a/trunk/drivers/acpi/resources/rsinfo.c +++ b/trunk/drivers/acpi/resources/rsinfo.c @@ -141,7 +141,6 @@ struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = { acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ }; #endif - #endif /* ACPI_FUTURE_USAGE */ /* * Base sizes for external AML resource descriptors, indexed by internal type. diff --git a/trunk/drivers/acpi/resources/rslist.c b/trunk/drivers/acpi/resources/rslist.c index 29423ce030ca..1434e786477e 100644 --- a/trunk/drivers/acpi/resources/rslist.c +++ b/trunk/drivers/acpi/resources/rslist.c @@ -51,62 +51,76 @@ ACPI_MODULE_NAME("rslist") * * FUNCTION: acpi_rs_convert_aml_to_resources * - * PARAMETERS: acpi_walk_aml_callback - * resource_ptr - Pointer to the buffer that will - * contain the output structures + * PARAMETERS: Aml - Pointer to the resource byte stream + * aml_length - Length of Aml + * output_buffer - Pointer to the buffer that will + * contain the output structures * * RETURN: Status * - * DESCRIPTION: Convert an AML resource to an internal representation of the - * resource that is aligned and easier to access. + * DESCRIPTION: Takes the resource byte stream and parses it, creating a + * linked list of resources in the caller's output buffer * ******************************************************************************/ acpi_status -acpi_rs_convert_aml_to_resources(u8 * aml, - u32 length, - u32 offset, u8 resource_index, void **context) +acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) { - struct acpi_resource **resource_ptr = - ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context); - struct acpi_resource *resource; + struct acpi_resource *resource = (void *)output_buffer; acpi_status status; + u8 resource_index; + u8 *end_aml; - ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources); + ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); - /* - * Check that the input buffer and all subsequent pointers into it - * are aligned on a native word boundary. Most important on IA64 - */ - resource = *resource_ptr; - if (ACPI_IS_MISALIGNED(resource)) { - ACPI_WARNING((AE_INFO, - "Misaligned resource pointer %p", resource)); - } + end_aml = aml + aml_length; - /* Convert the AML byte stream resource to a local resource struct */ - - status = - acpi_rs_convert_aml_to_resource(resource, - ACPI_CAST_PTR(union aml_resource, - aml), - acpi_gbl_get_resource_dispatch - [resource_index]); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not convert AML resource (Type %X)", - *aml)); - return_ACPI_STATUS(status); - } + /* Loop until end-of-buffer or an end_tag is found */ + + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ + + status = acpi_ut_validate_resource(aml, &resource_index); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Convert the AML byte stream resource to a local resource struct */ - ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, - "Type %.2X, AmlLength %.2X InternalLength %.2X\n", - acpi_ut_get_resource_type(aml), length, - resource->length)); + status = + acpi_rs_convert_aml_to_resource(resource, + ACPI_CAST_PTR(union + aml_resource, + aml), + acpi_gbl_get_resource_dispatch + [resource_index]); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert AML resource (Type %X)", + *aml)); + return_ACPI_STATUS(status); + } - /* Point to the next structure in the output buffer */ + /* Normal exit on completion of an end_tag resource descriptor */ - *resource_ptr = ACPI_ADD_PTR(void, resource, resource->length); - return_ACPI_STATUS(AE_OK); + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + return_ACPI_STATUS(AE_OK); + } + + /* Point to the next input AML resource */ + + aml += acpi_ut_get_descriptor_length(aml); + + /* Point to the next structure in the output buffer */ + + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); + } + + /* Did not find an end_tag resource descriptor */ + + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } /******************************************************************************* @@ -136,12 +150,11 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, u8 *end_aml = output_buffer + aml_size_needed; acpi_status status; - ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml); + ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); /* Walk the resource descriptor list, convert each descriptor */ while (aml < end_aml) { - /* Validate the (internal) Resource Type */ if (resource->type > ACPI_RESOURCE_TYPE_MAX) { @@ -178,7 +191,6 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, /* Check for end-of-list, normal exit */ if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { - /* An End Tag indicates the end of the input Resource Template */ return_ACPI_STATUS(AE_OK); diff --git a/trunk/drivers/acpi/resources/rsmisc.c b/trunk/drivers/acpi/resources/rsmisc.c index faf6e106b785..ed866cf1c6d2 100644 --- a/trunk/drivers/acpi/resources/rsmisc.c +++ b/trunk/drivers/acpi/resources/rsmisc.c @@ -81,10 +81,9 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, u16 item_count = 0; u16 temp16 = 0; - ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); + ACPI_FUNCTION_TRACE("rs_get_resource"); if (((acpi_native_uint) resource) & 0x3) { - /* Each internal resource struct is expected to be 32-bit aligned */ ACPI_WARNING((AE_INFO, @@ -296,11 +295,9 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, exit: if (!flags_mode) { + /* Round the resource struct length up to the next 32-bit boundary */ - /* Round the resource struct length up to the next boundary (32 or 64) */ - - resource->length = - (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length); + resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length); } return_ACPI_STATUS(AE_OK); } @@ -332,7 +329,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, u16 temp16 = 0; u16 item_count = 0; - ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml); + ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml"); /* * First table entry must be ACPI_RSC_INITxxx and must contain the @@ -538,7 +535,6 @@ if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { resource->data.extended_irq.interrupt_count = temp8; if (temp8 < 1) { - /* Must have at least one IRQ */ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); diff --git a/trunk/drivers/acpi/resources/rsutils.c b/trunk/drivers/acpi/resources/rsutils.c index a9cbee8e8b44..25b5aedd6612 100644 --- a/trunk/drivers/acpi/resources/rsutils.c +++ b/trunk/drivers/acpi/resources/rsutils.c @@ -205,7 +205,6 @@ acpi_rs_set_resource_length(acpi_rsdesc_size total_length, /* Length is stored differently for large and small descriptors */ if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { - /* Large descriptor -- bytes 1-2 contain the 16-bit length */ ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, @@ -299,8 +298,7 @@ static u16 acpi_rs_strcpy(char *destination, char *source) * string_ptr - (optional) where to store the actual * resource_source string * - * RETURN: Length of the string plus NULL terminator, rounded up to native - * word boundary + * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit * * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor * to an internal resource descriptor @@ -330,7 +328,6 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, * we add 1 to the minimum length. */ if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) { - /* Get the resource_source_index */ resource_source->index = aml_resource_source[0]; @@ -347,26 +344,23 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length, } /* - * In order for the Resource length to be a multiple of the native - * word, calculate the length of the string (+1 for NULL terminator) - * and expand to the next word multiple. + * In order for the struct_size to fall on a 32-bit boundary, calculate + * the length of the string (+1 for the NULL terminator) and expand the + * struct_size to the next 32-bit boundary. * * Zero the entire area of the buffer. */ total_length = - (u32) - ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) + - 1; - total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length); - + ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN + ((char *)&aml_resource_source[1]) + + 1); ACPI_MEMSET(resource_source->string_ptr, 0, total_length); /* Copy the resource_source string to the destination */ resource_source->string_length = acpi_rs_strcpy(resource_source->string_ptr, - ACPI_CAST_PTR(char, - &aml_resource_source[1])); + (char *)&aml_resource_source[1]); return ((acpi_rs_length) total_length); } @@ -411,7 +405,6 @@ acpi_rs_set_resource_source(union aml_resource * aml, /* Non-zero string length indicates presence of a resource_source */ if (resource_source->string_length) { - /* Point to the end of the AML descriptor */ aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length); @@ -422,7 +415,7 @@ acpi_rs_set_resource_source(union aml_resource * aml, /* Copy the resource_source string */ - ACPI_STRCPY(ACPI_CAST_PTR(char, &aml_resource_source[1]), + ACPI_STRCPY((char *)&aml_resource_source[1], resource_source->string_ptr); /* @@ -442,9 +435,9 @@ acpi_rs_set_resource_source(union aml_resource * aml, * * FUNCTION: acpi_rs_get_prt_method_data * - * PARAMETERS: Node - Device node - * ret_buffer - Pointer to a buffer structure for the - * results + * PARAMETERS: Handle - a handle to the containing object + * ret_buffer - a pointer to a buffer structure for the + * results * * RETURN: Status * @@ -457,19 +450,18 @@ acpi_rs_set_resource_source(union aml_resource * aml, ******************************************************************************/ acpi_status -acpi_rs_get_prt_method_data(struct acpi_namespace_node * node, - struct acpi_buffer * ret_buffer) +acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) { union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(rs_get_prt_method_data); + ACPI_FUNCTION_TRACE("rs_get_prt_method_data"); /* Parameters guaranteed valid by caller */ /* Execute the method, no parameters */ - status = acpi_ut_evaluate_object(node, METHOD_NAME__PRT, + status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE, &obj_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -491,9 +483,9 @@ acpi_rs_get_prt_method_data(struct acpi_namespace_node * node, * * FUNCTION: acpi_rs_get_crs_method_data * - * PARAMETERS: Node - Device node - * ret_buffer - Pointer to a buffer structure for the - * results + * PARAMETERS: Handle - a handle to the containing object + * ret_buffer - a pointer to a buffer structure for the + * results * * RETURN: Status * @@ -506,19 +498,18 @@ acpi_rs_get_prt_method_data(struct acpi_namespace_node * node, ******************************************************************************/ acpi_status -acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, - struct acpi_buffer *ret_buffer) +acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) { union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(rs_get_crs_method_data); + ACPI_FUNCTION_TRACE("rs_get_crs_method_data"); /* Parameters guaranteed valid by caller */ /* Execute the method, no parameters */ - status = acpi_ut_evaluate_object(node, METHOD_NAME__CRS, + status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER, &obj_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -531,7 +522,7 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, */ status = acpi_rs_create_resource_list(obj_desc, ret_buffer); - /* On exit, we must delete the object returned by evaluate_object */ + /* on exit, we must delete the object returned by evaluate_object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); @@ -541,9 +532,9 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, * * FUNCTION: acpi_rs_get_prs_method_data * - * PARAMETERS: Node - Device node - * ret_buffer - Pointer to a buffer structure for the - * results + * PARAMETERS: Handle - a handle to the containing object + * ret_buffer - a pointer to a buffer structure for the + * results * * RETURN: Status * @@ -557,19 +548,18 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, #ifdef ACPI_FUTURE_USAGE acpi_status -acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, - struct acpi_buffer *ret_buffer) +acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) { union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(rs_get_prs_method_data); + ACPI_FUNCTION_TRACE("rs_get_prs_method_data"); /* Parameters guaranteed valid by caller */ /* Execute the method, no parameters */ - status = acpi_ut_evaluate_object(node, METHOD_NAME__PRS, + status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER, &obj_desc); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -582,7 +572,7 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, */ status = acpi_rs_create_resource_list(obj_desc, ret_buffer); - /* On exit, we must delete the object returned by evaluate_object */ + /* on exit, we must delete the object returned by evaluate_object */ acpi_ut_remove_reference(obj_desc); return_ACPI_STATUS(status); @@ -593,10 +583,10 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, * * FUNCTION: acpi_rs_get_method_data * - * PARAMETERS: Handle - Handle to the containing object + * PARAMETERS: Handle - a handle to the containing object * Path - Path to method, relative to Handle - * ret_buffer - Pointer to a buffer structure for the - * results + * ret_buffer - a pointer to a buffer structure for the + * results * * RETURN: Status * @@ -615,7 +605,7 @@ acpi_rs_get_method_data(acpi_handle handle, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(rs_get_method_data); + ACPI_FUNCTION_TRACE("rs_get_method_data"); /* Parameters guaranteed valid by caller */ @@ -644,9 +634,9 @@ acpi_rs_get_method_data(acpi_handle handle, * * FUNCTION: acpi_rs_set_srs_method_data * - * PARAMETERS: Node - Device node - * in_buffer - Pointer to a buffer structure of the - * parameter + * PARAMETERS: Handle - a handle to the containing object + * in_buffer - a pointer to a buffer structure of the + * parameter * * RETURN: Status * @@ -656,37 +646,23 @@ acpi_rs_get_method_data(acpi_handle handle, * If the function fails an appropriate status will be returned * and the contents of the callers buffer is undefined. * - * Note: Parameters guaranteed valid by caller - * ******************************************************************************/ acpi_status -acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, - struct acpi_buffer *in_buffer) +acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) { - struct acpi_evaluate_info *info; - union acpi_operand_object *args[2]; + struct acpi_parameter_info info; + union acpi_operand_object *params[2]; acpi_status status; struct acpi_buffer buffer; - ACPI_FUNCTION_TRACE(rs_set_srs_method_data); - - /* Allocate and initialize the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } + ACPI_FUNCTION_TRACE("rs_set_srs_method_data"); - info->prefix_node = node; - info->pathname = METHOD_NAME__SRS; - info->parameters = args; - info->parameter_type = ACPI_PARAM_ARGS; - info->flags = ACPI_IGNORE_RETURN_VALUE; + /* Parameters guaranteed valid by caller */ /* * The in_buffer parameter will point to a linked list of - * resource parameters. It needs to be formatted into a + * resource parameters. It needs to be formatted into a * byte stream to be sent in as an input parameter to _SRS * * Convert the linked list into a byte stream @@ -694,36 +670,41 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); if (ACPI_FAILURE(status)) { - goto cleanup; + return_ACPI_STATUS(status); } - /* Create and initialize the method parameter object */ + /* Init the param object */ - args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); - if (!args[0]) { - /* - * Must free the buffer allocated above (otherwise it is freed - * later) - */ - ACPI_FREE(buffer.pointer); - status = AE_NO_MEMORY; - goto cleanup; + params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); + if (!params[0]) { + acpi_os_free(buffer.pointer); + return_ACPI_STATUS(AE_NO_MEMORY); } - args[0]->buffer.length = (u32) buffer.length; - args[0]->buffer.pointer = buffer.pointer; - args[0]->common.flags = AOPOBJ_DATA_VALID; - args[1] = NULL; + /* Set up the parameter object */ + + params[0]->buffer.length = (u32) buffer.length; + params[0]->buffer.pointer = buffer.pointer; + params[0]->common.flags = AOPOBJ_DATA_VALID; + params[1] = NULL; + + info.node = handle; + info.parameters = params; + info.parameter_type = ACPI_PARAM_ARGS; - /* Execute the method, no return value is expected */ + /* Execute the method, no return value */ - status = acpi_ns_evaluate(info); + status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info); + if (ACPI_SUCCESS(status)) { + /* Delete any return object (especially if implicit_return is enabled) */ - /* Clean up and return the status from acpi_ns_evaluate */ + if (info.return_object) { + acpi_ut_remove_reference(info.return_object); + } + } - acpi_ut_remove_reference(args[0]); + /* Clean up and return the status from acpi_ns_evaluate_relative */ - cleanup: - ACPI_FREE(info); + acpi_ut_remove_reference(params[0]); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/resources/rsxface.c b/trunk/drivers/acpi/resources/rsxface.c index 1999e2ab7daa..88b67077aeeb 100644 --- a/trunk/drivers/acpi/resources/rsxface.c +++ b/trunk/drivers/acpi/resources/rsxface.c @@ -41,9 +41,10 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include -#include #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsxface") @@ -67,262 +68,312 @@ ACPI_MODULE_NAME("rsxface") static acpi_status acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); -static acpi_status -acpi_rs_validate_parameters(acpi_handle device_handle, - struct acpi_buffer *buffer, - struct acpi_namespace_node **return_node); - /******************************************************************************* * - * FUNCTION: acpi_rs_validate_parameters + * FUNCTION: acpi_get_irq_routing_table * - * PARAMETERS: device_handle - Handle to a device - * Buffer - Pointer to a data buffer - * return_node - Pointer to where the device node is returned + * PARAMETERS: device_handle - a handle to the Bus device we are querying + * ret_buffer - a pointer to a buffer to receive the + * current resources for the device * * RETURN: Status * - * DESCRIPTION: Common parameter validation for resource interfaces + * DESCRIPTION: This function is called to get the IRQ routing table for a + * specific bus. The caller must first acquire a handle for the + * desired bus. The routine table is placed in the buffer pointed + * to by the ret_buffer variable parameter. + * + * If the function fails an appropriate status will be returned + * and the value of ret_buffer is undefined. + * + * This function attempts to execute the _PRT method contained in + * the object indicated by the passed device_handle. * ******************************************************************************/ -static acpi_status -acpi_rs_validate_parameters(acpi_handle device_handle, - struct acpi_buffer *buffer, - struct acpi_namespace_node **return_node) +acpi_status +acpi_get_irq_routing_table(acpi_handle device_handle, + struct acpi_buffer *ret_buffer) { acpi_status status; - struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(rs_validate_parameters); + ACPI_FUNCTION_TRACE("acpi_get_irq_routing_table "); /* - * Must have a valid handle to an ACPI device + * Must have a valid handle and buffer, So we have to have a handle + * and a return buffer structure, and if there is a non-zero buffer length + * we also need a valid pointer in the buffer. If it's a zero buffer length, + * we'll be returning the needed buffer size, so keep going. */ if (!device_handle) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - node = acpi_ns_map_handle_to_node(device_handle); - if (!node) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (node->type != ACPI_TYPE_DEVICE) { - return_ACPI_STATUS(AE_TYPE); - } - - /* - * Validate the user buffer object - * - * if there is a non-zero buffer length we also need a valid pointer in - * the buffer. If it's a zero buffer length, we'll be returning the - * needed buffer size (later), so keep going. - */ - status = acpi_ut_validate_buffer(buffer); + status = acpi_ut_validate_buffer(ret_buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - *return_node = node; - return_ACPI_STATUS(AE_OK); + status = acpi_rs_get_prt_method_data(device_handle, ret_buffer); + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_get_irq_routing_table + * FUNCTION: acpi_get_current_resources * - * PARAMETERS: device_handle - Handle to the Bus device we are querying - * ret_buffer - Pointer to a buffer to receive the + * PARAMETERS: device_handle - a handle to the device object for the + * device we are querying + * ret_buffer - a pointer to a buffer to receive the * current resources for the device * * RETURN: Status * - * DESCRIPTION: This function is called to get the IRQ routing table for a - * specific bus. The caller must first acquire a handle for the - * desired bus. The routine table is placed in the buffer pointed - * to by the ret_buffer variable parameter. + * DESCRIPTION: This function is called to get the current resources for a + * specific device. The caller must first acquire a handle for + * the desired device. The resource data is placed in the buffer + * pointed to by the ret_buffer variable parameter. * * If the function fails an appropriate status will be returned * and the value of ret_buffer is undefined. * - * This function attempts to execute the _PRT method contained in + * This function attempts to execute the _CRS method contained in * the object indicated by the passed device_handle. * ******************************************************************************/ acpi_status -acpi_get_irq_routing_table(acpi_handle device_handle, +acpi_get_current_resources(acpi_handle device_handle, struct acpi_buffer *ret_buffer) { acpi_status status; - struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table); + ACPI_FUNCTION_TRACE("acpi_get_current_resources"); - /* Validate parameters then dispatch to internal routine */ + /* + * Must have a valid handle and buffer, So we have to have a handle + * and a return buffer structure, and if there is a non-zero buffer length + * we also need a valid pointer in the buffer. If it's a zero buffer length, + * we'll be returning the needed buffer size, so keep going. + */ + if (!device_handle) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); + status = acpi_ut_validate_buffer(ret_buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_rs_get_prt_method_data(node, ret_buffer); + status = acpi_rs_get_crs_method_data(device_handle, ret_buffer); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table) +EXPORT_SYMBOL(acpi_get_current_resources); /******************************************************************************* * - * FUNCTION: acpi_get_current_resources + * FUNCTION: acpi_get_possible_resources * - * PARAMETERS: device_handle - Handle to the device object for the + * PARAMETERS: device_handle - a handle to the device object for the * device we are querying - * ret_buffer - Pointer to a buffer to receive the - * current resources for the device + * ret_buffer - a pointer to a buffer to receive the + * resources for the device * * RETURN: Status * - * DESCRIPTION: This function is called to get the current resources for a - * specific device. The caller must first acquire a handle for - * the desired device. The resource data is placed in the buffer - * pointed to by the ret_buffer variable parameter. + * DESCRIPTION: This function is called to get a list of the possible resources + * for a specific device. The caller must first acquire a handle + * for the desired device. The resource data is placed in the + * buffer pointed to by the ret_buffer variable. * * If the function fails an appropriate status will be returned * and the value of ret_buffer is undefined. * - * This function attempts to execute the _CRS method contained in - * the object indicated by the passed device_handle. - * ******************************************************************************/ + +#ifdef ACPI_FUTURE_USAGE acpi_status -acpi_get_current_resources(acpi_handle device_handle, - struct acpi_buffer *ret_buffer) +acpi_get_possible_resources(acpi_handle device_handle, + struct acpi_buffer *ret_buffer) { acpi_status status; - struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(acpi_get_current_resources); + ACPI_FUNCTION_TRACE("acpi_get_possible_resources"); - /* Validate parameters then dispatch to internal routine */ + /* + * Must have a valid handle and buffer, So we have to have a handle + * and a return buffer structure, and if there is a non-zero buffer length + * we also need a valid pointer in the buffer. If it's a zero buffer length, + * we'll be returning the needed buffer size, so keep going. + */ + if (!device_handle) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); + status = acpi_ut_validate_buffer(ret_buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_rs_get_crs_method_data(node, ret_buffer); + status = acpi_rs_get_prs_method_data(device_handle, ret_buffer); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_current_resources) +EXPORT_SYMBOL(acpi_get_possible_resources); +#endif /* ACPI_FUTURE_USAGE */ -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * - * FUNCTION: acpi_get_possible_resources + * FUNCTION: acpi_walk_resources * * PARAMETERS: device_handle - Handle to the device object for the * device we are querying - * ret_buffer - Pointer to a buffer to receive the - * resources for the device + * Name - Method name of the resources we want + * (METHOD_NAME__CRS or METHOD_NAME__PRS) + * user_function - Called for each resource + * Context - Passed to user_function * * RETURN: Status * - * DESCRIPTION: This function is called to get a list of the possible resources - * for a specific device. The caller must first acquire a handle - * for the desired device. The resource data is placed in the - * buffer pointed to by the ret_buffer variable. - * - * If the function fails an appropriate status will be returned - * and the value of ret_buffer is undefined. + * DESCRIPTION: Retrieves the current or possible resource list for the + * specified device. The user_function is called once for + * each resource in the list. * ******************************************************************************/ + acpi_status -acpi_get_possible_resources(acpi_handle device_handle, - struct acpi_buffer *ret_buffer) +acpi_walk_resources(acpi_handle device_handle, + char *name, + ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) { acpi_status status; - struct acpi_namespace_node *node; + struct acpi_buffer buffer; + struct acpi_resource *resource; + struct acpi_resource *resource_end; + + ACPI_FUNCTION_TRACE("acpi_walk_resources"); + + /* Parameter validation */ - ACPI_FUNCTION_TRACE(acpi_get_possible_resources); + if (!device_handle || !user_function || !name || + (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && + ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } - /* Validate parameters then dispatch to internal routine */ + /* Get the _CRS or _PRS resource list */ - status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_rs_get_method_data(device_handle, name, &buffer); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_rs_get_prs_method_data(node, ret_buffer); + /* Buffer now contains the resource list */ + + resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); + resource_end = + ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); + + /* Walk the resource list until the end_tag is found (or buffer end) */ + + while (resource < resource_end) { + /* Sanity check the resource */ + + if (resource->type > ACPI_RESOURCE_TYPE_MAX) { + status = AE_AML_INVALID_RESOURCE_TYPE; + break; + } + + /* Invoke the user function, abort on any error returned */ + + status = user_function(resource, context); + if (ACPI_FAILURE(status)) { + if (status == AE_CTRL_TERMINATE) { + /* This is an OK termination by the user function */ + + status = AE_OK; + } + break; + } + + /* end_tag indicates end-of-list */ + + if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { + break; + } + + /* Get the next resource descriptor */ + + resource = + ACPI_ADD_PTR(struct acpi_resource, resource, + resource->length); + } + + ACPI_MEM_FREE(buffer.pointer); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_possible_resources) -#endif /* ACPI_FUTURE_USAGE */ +EXPORT_SYMBOL(acpi_walk_resources); /******************************************************************************* * * FUNCTION: acpi_set_current_resources * - * PARAMETERS: device_handle - Handle to the device object for the - * device we are setting resources - * in_buffer - Pointer to a buffer containing the + * PARAMETERS: device_handle - a handle to the device object for the + * device we are changing the resources of + * in_buffer - a pointer to a buffer containing the * resources to be set for the device * * RETURN: Status * * DESCRIPTION: This function is called to set the current resources for a - * specific device. The caller must first acquire a handle for - * the desired device. The resource data is passed to the routine + * specific device. The caller must first acquire a handle for + * the desired device. The resource data is passed to the routine * the buffer pointed to by the in_buffer variable. * ******************************************************************************/ + acpi_status acpi_set_current_resources(acpi_handle device_handle, struct acpi_buffer *in_buffer) { acpi_status status; - struct acpi_namespace_node *node; - ACPI_FUNCTION_TRACE(acpi_set_current_resources); + ACPI_FUNCTION_TRACE("acpi_set_current_resources"); - /* Validate the buffer, don't allow zero length */ + /* Must have a valid handle and buffer */ - if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { + if ((!device_handle) || + (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Validate parameters then dispatch to internal routine */ - - status = acpi_rs_validate_parameters(device_handle, in_buffer, &node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = acpi_rs_set_srs_method_data(node, in_buffer); + status = acpi_rs_set_srs_method_data(device_handle, in_buffer); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_set_current_resources) +EXPORT_SYMBOL(acpi_set_current_resources); /****************************************************************************** * * FUNCTION: acpi_resource_to_address64 * - * PARAMETERS: Resource - Pointer to a resource - * Out - Pointer to the users's return buffer - * (a struct acpi_resource_address64) + * PARAMETERS: Resource - Pointer to a resource + * Out - Pointer to the users's return + * buffer (a struct + * struct acpi_resource_address64) * * RETURN: Status * * DESCRIPTION: If the resource is an address16, address32, or address64, - * copy it to the address64 return buffer. This saves the + * copy it to the address64 return buffer. This saves the * caller from having to duplicate code for different-sized * addresses. * ******************************************************************************/ + acpi_status acpi_resource_to_address64(struct acpi_resource *resource, struct acpi_resource_address64 *out) @@ -364,18 +415,18 @@ acpi_resource_to_address64(struct acpi_resource *resource, return (AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_resource_to_address64) +EXPORT_SYMBOL(acpi_resource_to_address64); /******************************************************************************* * * FUNCTION: acpi_get_vendor_resource * - * PARAMETERS: device_handle - Handle for the parent device object - * Name - Method name for the parent resource - * (METHOD_NAME__CRS or METHOD_NAME__PRS) - * Uuid - Pointer to the UUID to be matched. - * includes both subtype and 16-byte UUID - * ret_buffer - Where the vendor resource is returned + * PARAMETERS: device_handle - Handle for the parent device object + * Name - Method name for the parent resource + * (METHOD_NAME__CRS or METHOD_NAME__PRS) + * Uuid - Pointer to the UUID to be matched. + * includes both subtype and 16-byte UUID + * ret_buffer - Where the vendor resource is returned * * RETURN: Status * @@ -384,6 +435,7 @@ ACPI_EXPORT_SYMBOL(acpi_resource_to_address64) * UUID subtype. Returns a struct acpi_resource of type Vendor. * ******************************************************************************/ + acpi_status acpi_get_vendor_resource(acpi_handle device_handle, char *name, @@ -415,19 +467,18 @@ acpi_get_vendor_resource(acpi_handle device_handle, return (info.status); } -ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource) - /******************************************************************************* * * FUNCTION: acpi_rs_match_vendor_resource * - * PARAMETERS: acpi_walk_resource_callback + * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK * * RETURN: Status * * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID * ******************************************************************************/ + static acpi_status acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) { @@ -475,101 +526,3 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) info->status = AE_OK; return (AE_CTRL_TERMINATE); } - -ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource) - -/******************************************************************************* - * - * FUNCTION: acpi_walk_resources - * - * PARAMETERS: device_handle - Handle to the device object for the - * device we are querying - * Name - Method name of the resources we want - * (METHOD_NAME__CRS or METHOD_NAME__PRS) - * user_function - Called for each resource - * Context - Passed to user_function - * - * RETURN: Status - * - * DESCRIPTION: Retrieves the current or possible resource list for the - * specified device. The user_function is called once for - * each resource in the list. - * - ******************************************************************************/ - -acpi_status -acpi_walk_resources(acpi_handle device_handle, - char *name, - acpi_walk_resource_callback user_function, void *context) -{ - acpi_status status; - struct acpi_buffer buffer; - struct acpi_resource *resource; - struct acpi_resource *resource_end; - - ACPI_FUNCTION_TRACE(acpi_walk_resources); - - /* Parameter validation */ - - if (!device_handle || !user_function || !name || - (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && - !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* Get the _CRS or _PRS resource list */ - - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_rs_get_method_data(device_handle, name, &buffer); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Buffer now contains the resource list */ - - resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); - resource_end = - ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); - - /* Walk the resource list until the end_tag is found (or buffer end) */ - - while (resource < resource_end) { - - /* Sanity check the resource */ - - if (resource->type > ACPI_RESOURCE_TYPE_MAX) { - status = AE_AML_INVALID_RESOURCE_TYPE; - break; - } - - /* Invoke the user function, abort on any error returned */ - - status = user_function(resource, context); - if (ACPI_FAILURE(status)) { - if (status == AE_CTRL_TERMINATE) { - - /* This is an OK termination by the user function */ - - status = AE_OK; - } - break; - } - - /* end_tag indicates end-of-list */ - - if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { - break; - } - - /* Get the next resource descriptor */ - - resource = - ACPI_ADD_PTR(struct acpi_resource, resource, - resource->length); - } - - ACPI_FREE(buffer.pointer); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_walk_resources) diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index f8316a05ede7..a0ab828b2cc5 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -142,7 +142,7 @@ static void acpi_device_register(struct acpi_device *device, create_sysfs_device_files(device); } -static void acpi_device_unregister(struct acpi_device *device, int type) +static int acpi_device_unregister(struct acpi_device *device, int type) { spin_lock(&acpi_device_lock); if (device->parent) { @@ -158,6 +158,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type) acpi_detach_data(device->handle, acpi_bus_data_handler); remove_sysfs_device_files(device); kobject_unregister(&device->kobj); + return 0; } void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) @@ -233,9 +234,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) int acpi_match_ids(struct acpi_device *device, char *ids) { + int error = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + if (device->flags.hardware_id) if (strstr(ids, device->pnp.hardware_id)) - return 0; + goto Done; if (device->flags.compatible_ids) { struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; @@ -244,10 +248,15 @@ int acpi_match_ids(struct acpi_device *device, char *ids) /* compare multiple _CID entries against driver ids */ for (i = 0; i < cid_list->count; i++) { if (strstr(ids, cid_list->id[i].value)) - return 0; + goto Done; } } - return -ENOENT; + error = -ENOENT; + + Done: + if (buffer.pointer) + acpi_os_free(buffer.pointer); + return error; } static acpi_status @@ -432,7 +441,10 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count) islockable = device->flags.lockable; handle = device->handle; - result = acpi_bus_trim(device, 1); + if (type == ACPI_TYPE_PROCESSOR) + result = acpi_bus_trim(device, 0); + else + result = acpi_bus_trim(device, 1); if (!result) result = acpi_eject_operation(handle, islockable); @@ -459,6 +471,7 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device) -------------------------------------------------------------------------- */ static LIST_HEAD(acpi_bus_drivers); +static DECLARE_MUTEX(acpi_bus_drivers_lock); /** * acpi_bus_match - match device IDs to driver's supported IDs @@ -535,9 +548,10 @@ static int acpi_start_single_object(struct acpi_device *device) return_VALUE(result); } -static void acpi_driver_attach(struct acpi_driver *drv) +static int acpi_driver_attach(struct acpi_driver *drv) { struct list_head *node, *next; + int count = 0; ACPI_FUNCTION_TRACE("acpi_driver_attach"); @@ -554,6 +568,7 @@ static void acpi_driver_attach(struct acpi_driver *drv) if (!acpi_bus_driver_init(dev, drv)) { acpi_start_single_object(dev); atomic_inc(&drv->references); + count++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", drv->name, dev->pnp.bus_id)); @@ -562,9 +577,10 @@ static void acpi_driver_attach(struct acpi_driver *drv) spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); + return_VALUE(count); } -static void acpi_driver_detach(struct acpi_driver *drv) +static int acpi_driver_detach(struct acpi_driver *drv) { struct list_head *node, *next; @@ -586,6 +602,7 @@ static void acpi_driver_detach(struct acpi_driver *drv) } } spin_unlock(&acpi_device_lock); + return_VALUE(0); } /** @@ -593,22 +610,28 @@ static void acpi_driver_detach(struct acpi_driver *drv) * @driver: driver being registered * * Registers a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and binds. Returns zero for - * success or a negative error status for failure. + * devices that match the driver's criteria and binds. Returns the + * number of devices that were claimed by the driver, or a negative + * error status for failure. */ int acpi_bus_register_driver(struct acpi_driver *driver) { + int count; + ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); if (acpi_disabled) return_VALUE(-ENODEV); + if (!driver) + return_VALUE(-EINVAL); + spin_lock(&acpi_device_lock); list_add_tail(&driver->node, &acpi_bus_drivers); spin_unlock(&acpi_device_lock); - acpi_driver_attach(driver); + count = acpi_driver_attach(driver); - return_VALUE(0); + return_VALUE(count); } EXPORT_SYMBOL(acpi_bus_register_driver); @@ -620,16 +643,23 @@ EXPORT_SYMBOL(acpi_bus_register_driver); * Unregisters a driver with the ACPI bus. Searches the namespace for all * devices that match the driver's criteria and unbinds. */ -void acpi_bus_unregister_driver(struct acpi_driver *driver) +int acpi_bus_unregister_driver(struct acpi_driver *driver) { - acpi_driver_detach(driver); + int error = 0; - if (!atomic_read(&driver->references)) { - spin_lock(&acpi_device_lock); - list_del_init(&driver->node); - spin_unlock(&acpi_device_lock); - } - return; + ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver"); + + if (driver) { + acpi_driver_detach(driver); + + if (!atomic_read(&driver->references)) { + spin_lock(&acpi_device_lock); + list_del_init(&driver->node); + spin_unlock(&acpi_device_lock); + } + } else + error = -EINVAL; + return_VALUE(error); } EXPORT_SYMBOL(acpi_bus_unregister_driver); @@ -1341,100 +1371,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) return_VALUE(result); } - -static inline struct acpi_device * to_acpi_dev(struct device * dev) -{ - return container_of(dev, struct acpi_device, dev); -} - - -static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state) -{ - struct acpi_device * dev, * next; - int result; - - spin_lock(&acpi_device_lock); - list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) { - if (dev->driver && dev->driver->ops.suspend) { - spin_unlock(&acpi_device_lock); - result = dev->driver->ops.suspend(dev, 0); - if (result) { - printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n", - acpi_device_name(dev), - acpi_device_bid(dev), result); - } - spin_lock(&acpi_device_lock); - } - } - spin_unlock(&acpi_device_lock); - return 0; -} - - -static int acpi_device_suspend(struct device * dev, pm_message_t state) -{ - struct acpi_device * acpi_dev = to_acpi_dev(dev); - - /* - * For now, we should only register 1 generic device - - * the ACPI root device - and from there, we walk the - * tree of ACPI devices to suspend each one using the - * ACPI driver methods. - */ - if (acpi_dev->handle == ACPI_ROOT_OBJECT) - root_suspend(acpi_dev, state); - return 0; -} - - - -static int root_resume(struct acpi_device * acpi_dev) -{ - struct acpi_device * dev, * next; - int result; - - spin_lock(&acpi_device_lock); - list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) { - if (dev->driver && dev->driver->ops.resume) { - spin_unlock(&acpi_device_lock); - result = dev->driver->ops.resume(dev, 0); - if (result) { - printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n", - acpi_device_name(dev), - acpi_device_bid(dev), result); - } - spin_lock(&acpi_device_lock); - } - } - spin_unlock(&acpi_device_lock); - return 0; -} - - -static int acpi_device_resume(struct device * dev) -{ - struct acpi_device * acpi_dev = to_acpi_dev(dev); - - /* - * For now, we should only register 1 generic device - - * the ACPI root device - and from there, we walk the - * tree of ACPI devices to resume each one using the - * ACPI driver methods. - */ - if (acpi_dev->handle == ACPI_ROOT_OBJECT) - root_resume(acpi_dev); - return 0; -} - - -struct bus_type acpi_bus_type = { - .name = "acpi", - .suspend = acpi_device_suspend, - .resume = acpi_device_resume, -}; - - - static int __init acpi_scan_init(void) { int result; @@ -1447,12 +1383,6 @@ static int __init acpi_scan_init(void) kset_register(&acpi_namespace_kset); - result = bus_register(&acpi_bus_type); - if (result) { - /* We don't want to quit even if we failed to add suspend/resume */ - printk(KERN_ERR PREFIX "Could not register bus type\n"); - } - /* * Create the root device in the bus's device tree */ @@ -1462,16 +1392,6 @@ static int __init acpi_scan_init(void) goto Done; result = acpi_start_single_object(acpi_root); - if (result) - goto Done; - - acpi_root->dev.bus = &acpi_bus_type; - snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name); - result = device_register(&acpi_root->dev); - if (result) { - /* We don't want to quit even if we failed to add suspend/resume */ - printk(KERN_ERR PREFIX "Could not register device\n"); - } /* * Enumerate devices in the ACPI namespace. diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c index 62ce87d71651..930427fc0c4b 100644 --- a/trunk/drivers/acpi/sleep/main.c +++ b/trunk/drivers/acpi/sleep/main.c @@ -105,14 +105,6 @@ static int acpi_pm_enter(suspend_state_t pm_state) default: return -EINVAL; } - - /* ACPI 3.0 specs (P62) says that it's the responsabilty - * of the OSPM to clear the status bit [ implying that the - * POWER_BUTTON event should not reach userspace ] - */ - if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) - acpi_clear_event(ACPI_EVENT_POWER_BUTTON); - local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); diff --git a/trunk/drivers/acpi/sleep/wakeup.c b/trunk/drivers/acpi/sleep/wakeup.c index af1dbabaf0b1..85df0ceda2a9 100644 --- a/trunk/drivers/acpi/sleep/wakeup.c +++ b/trunk/drivers/acpi/sleep/wakeup.c @@ -155,6 +155,7 @@ static int __init acpi_wakeup_device_init(void) if (acpi_disabled) return 0; + printk("ACPI wakeup devices: \n"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { @@ -173,8 +174,10 @@ static int __init acpi_wakeup_device_init(void) dev->wakeup.state.enabled = 1; spin_lock(&acpi_device_lock); } + printk("%4s ", dev->pnp.bus_id); } spin_unlock(&acpi_device_lock); + printk("\n"); return 0; } diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index a934ac42178d..e4308c7a6743 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -39,7 +39,7 @@ ACPI_MODULE_NAME("acpi_system") #define ACPI_SYSTEM_FILE_EVENT "event" #define ACPI_SYSTEM_FILE_DSDT "dsdt" #define ACPI_SYSTEM_FILE_FADT "fadt" -extern struct fadt_descriptor acpi_fadt; +extern FADT_DESCRIPTOR acpi_fadt; /* -------------------------------------------------------------------------- FS Interface (/proc) @@ -82,7 +82,7 @@ acpi_system_read_dsdt(struct file *file, ACPI_FUNCTION_TRACE("acpi_system_read_dsdt"); - status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); + status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); @@ -110,7 +110,7 @@ acpi_system_read_fadt(struct file *file, ACPI_FUNCTION_TRACE("acpi_system_read_fadt"); - status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt); + status = acpi_get_table(ACPI_TABLE_FADT, 1, &fadt); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); diff --git a/trunk/drivers/acpi/tables.c b/trunk/drivers/acpi/tables.c index ed5e8816d83d..7f37c7cc5ef1 100644 --- a/trunk/drivers/acpi/tables.c +++ b/trunk/drivers/acpi/tables.c @@ -282,8 +282,8 @@ acpi_get_table_header_early(enum acpi_table_id id, /* Map the DSDT header via the pointer in the FADT */ if (id == ACPI_DSDT) { - struct fadt_descriptor *fadt = - (struct fadt_descriptor *)*header; + struct fadt_descriptor_rev2 *fadt = + (struct fadt_descriptor_rev2 *)*header; if (fadt->revision == 3 && fadt->Xdsdt) { *header = (void *)__acpi_map_table(fadt->Xdsdt, diff --git a/trunk/drivers/acpi/tables/tbconvrt.c b/trunk/drivers/acpi/tables/tbconvrt.c index d697fcb35d52..03b37d2223bc 100644 --- a/trunk/drivers/acpi/tables/tbconvrt.c +++ b/trunk/drivers/acpi/tables/tbconvrt.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include @@ -54,15 +56,15 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, acpi_physical_address address); static void -acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, +acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt, struct fadt_descriptor_rev1 *original_fadt); static void -acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, - struct fadt_descriptor *original_fadt); +acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt, + struct fadt_descriptor_rev2 *original_fadt); u8 acpi_fadt_is_v1; -ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) +EXPORT_SYMBOL(acpi_fadt_is_v1); /******************************************************************************* * @@ -120,7 +122,7 @@ acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) { acpi_size table_size; u32 i; - struct xsdt_descriptor *new_table; + XSDT_DESCRIPTOR *new_table; ACPI_FUNCTION_ENTRY(); @@ -131,7 +133,7 @@ acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) /* Allocate an XSDT */ - new_table = ACPI_ALLOCATE_ZEROED(table_size); + new_table = ACPI_MEM_CALLOCATE(table_size); if (!new_table) { return (AE_NO_MEMORY); } @@ -145,18 +147,17 @@ acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) /* Copy the table pointers */ for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { - /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], (ACPI_CAST_PTR - (struct rsdt_descriptor, + (struct rsdt_descriptor_rev1, table_info->pointer))-> table_offset_entry[i]); } else { new_table->table_offset_entry[i] = - (ACPI_CAST_PTR(struct xsdt_descriptor, + (ACPI_CAST_PTR(XSDT_DESCRIPTOR, table_info->pointer))-> table_offset_entry[i]; } @@ -218,7 +219,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, ******************************************************************************/ static void -acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, +acpi_tb_convert_fadt1(struct fadt_descriptor_rev2 *local_fadt, struct fadt_descriptor_rev1 *original_fadt) { @@ -364,13 +365,14 @@ acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, ******************************************************************************/ static void -acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, - struct fadt_descriptor *original_fadt) +acpi_tb_convert_fadt2(struct fadt_descriptor_rev2 *local_fadt, + struct fadt_descriptor_rev2 *original_fadt) { /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ - ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); + ACPI_MEMCPY(local_fadt, original_fadt, + sizeof(struct fadt_descriptor_rev2)); /* * "X" fields are optional extensions to the original V1.0 fields, so @@ -489,10 +491,10 @@ acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, acpi_status acpi_tb_convert_table_fadt(void) { - struct fadt_descriptor *local_fadt; + struct fadt_descriptor_rev2 *local_fadt; struct acpi_table_desc *table_desc; - ACPI_FUNCTION_TRACE(tb_convert_table_fadt); + ACPI_FUNCTION_TRACE("tb_convert_table_fadt"); /* * acpi_gbl_FADT is valid. Validate the FADT length. The table must be @@ -506,14 +508,13 @@ acpi_status acpi_tb_convert_table_fadt(void) /* Allocate buffer for the ACPI 2.0(+) FADT */ - local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); + local_fadt = ACPI_MEM_CALLOCATE(sizeof(struct fadt_descriptor_rev2)); if (!local_fadt) { return_ACPI_STATUS(AE_NO_MEMORY); } if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { - if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { - + if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev2)) { /* Length is too short to be a V2.0 table */ ACPI_WARNING((AE_INFO, @@ -537,11 +538,11 @@ acpi_status acpi_tb_convert_table_fadt(void) /* Global FADT pointer will point to the new common V2.0 FADT */ acpi_gbl_FADT = local_fadt; - acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); + acpi_gbl_FADT->length = sizeof(FADT_DESCRIPTOR); /* Free the original table */ - table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next; acpi_tb_delete_single_table(table_desc); /* Install the new table */ @@ -549,7 +550,7 @@ acpi_status acpi_tb_convert_table_fadt(void) table_desc->pointer = ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); table_desc->allocation = ACPI_MEM_ALLOCATED; - table_desc->length = sizeof(struct fadt_descriptor); + table_desc->length = sizeof(struct fadt_descriptor_rev2); /* Dump the entire FADT */ @@ -579,7 +580,7 @@ acpi_status acpi_tb_convert_table_fadt(void) acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) { - ACPI_FUNCTION_TRACE(tb_build_common_facs); + ACPI_FUNCTION_TRACE("tb_build_common_facs"); /* Absolute minimum length is 24, but the ACPI spec says 64 */ @@ -602,7 +603,6 @@ acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) if ((acpi_gbl_RSDP->revision < 2) || (acpi_gbl_FACS->length < 32) || (!(acpi_gbl_FACS->xfirmware_waking_vector))) { - /* ACPI 1.0 FACS or short table or optional X_ field is zero */ acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, diff --git a/trunk/drivers/acpi/tables/tbget.c b/trunk/drivers/acpi/tables/tbget.c index 99eacceff563..09b4ee6dfd60 100644 --- a/trunk/drivers/acpi/tables/tbget.c +++ b/trunk/drivers/acpi/tables/tbget.c @@ -78,7 +78,7 @@ acpi_tb_get_table(struct acpi_pointer *address, acpi_status status; struct acpi_table_header header; - ACPI_FUNCTION_TRACE(tb_get_table); + ACPI_FUNCTION_TRACE("tb_get_table"); /* Get the header in order to get signature and table size */ @@ -124,7 +124,7 @@ acpi_tb_get_table_header(struct acpi_pointer *address, acpi_status status = AE_OK; struct acpi_table_header *header = NULL; - ACPI_FUNCTION_TRACE(tb_get_table_header); + ACPI_FUNCTION_TRACE("tb_get_table_header"); /* * Flags contains the current processor mode (Virtual or Physical @@ -148,10 +148,6 @@ acpi_tb_get_table_header(struct acpi_pointer *address, sizeof(struct acpi_table_header), (void *)&header); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not map memory at %8.8X%8.8X for table header", - ACPI_FORMAT_UINT64(address->pointer. - physical))); return_ACPI_STATUS(status); } @@ -202,7 +198,7 @@ acpi_tb_get_table_body(struct acpi_pointer *address, { acpi_status status; - ACPI_FUNCTION_TRACE(tb_get_table_body); + ACPI_FUNCTION_TRACE("tb_get_table_body"); if (!table_info || !address) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -212,7 +208,6 @@ acpi_tb_get_table_body(struct acpi_pointer *address, status = acpi_tb_table_override(header, table_info); if (ACPI_SUCCESS(status)) { - /* Table was overridden by the host OS */ return_ACPI_STATUS(status); @@ -246,7 +241,7 @@ acpi_tb_table_override(struct acpi_table_header *header, acpi_status status; struct acpi_pointer address; - ACPI_FUNCTION_TRACE(tb_table_override); + ACPI_FUNCTION_TRACE("tb_table_override"); /* * The OSL will examine the header and decide whether to override this @@ -255,7 +250,6 @@ acpi_tb_table_override(struct acpi_table_header *header, */ status = acpi_os_table_override(header, &new_table); if (ACPI_FAILURE(status)) { - /* Some severe error from the OSL, but we basically ignore it */ ACPI_EXCEPTION((AE_INFO, status, @@ -264,7 +258,6 @@ acpi_tb_table_override(struct acpi_table_header *header, } if (!new_table) { - /* No table override */ return_ACPI_STATUS(AE_NO_ACPI_TABLES); @@ -318,7 +311,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, u8 allocation; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(tb_get_this_table); + ACPI_FUNCTION_TRACE("tb_get_this_table"); /* * Flags contains the current processor mode (Virtual or Physical @@ -330,7 +323,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, /* Pointer matches processor mode, copy the table to a new buffer */ - full_table = ACPI_ALLOCATE(header->length); + full_table = ACPI_MEM_ALLOCATE(header->length); if (!full_table) { ACPI_ERROR((AE_INFO, "Could not allocate table memory for [%4.4s] length %X", @@ -383,12 +376,11 @@ acpi_tb_get_this_table(struct acpi_pointer *address, * Validate checksum for _most_ tables, * even the ones whose signature we don't recognize */ - if (table_info->type != ACPI_TABLE_ID_FACS) { + if (table_info->type != ACPI_TABLE_FACS) { status = acpi_tb_verify_table_checksum(full_table); #if (!ACPI_CHECKSUM_ABORT) if (ACPI_FAILURE(status)) { - /* Ignore the error if configuration says so */ status = AE_OK; @@ -417,7 +409,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, * * PARAMETERS: table_type - one of the defined table types * Instance - Which table of this type - * return_table - pointer to location to place the pointer for + * table_ptr_loc - pointer to location to place the pointer for * return * * RETURN: Status @@ -428,34 +420,57 @@ acpi_tb_get_this_table(struct acpi_pointer *address, acpi_status acpi_tb_get_table_ptr(acpi_table_type table_type, - u32 instance, struct acpi_table_header **return_table) + u32 instance, struct acpi_table_header **table_ptr_loc) { struct acpi_table_desc *table_desc; u32 i; - ACPI_FUNCTION_TRACE(tb_get_table_ptr); + ACPI_FUNCTION_TRACE("tb_get_table_ptr"); + + if (!acpi_gbl_DSDT) { + return_ACPI_STATUS(AE_NO_ACPI_TABLES); + } - if (table_type > ACPI_TABLE_ID_MAX) { + if (table_type > ACPI_TABLE_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Check for instance out of range of the current table count */ + /* + * For all table types (Single/Multiple), the first + * instance is always in the list head. + */ + if (instance == 1) { + /* Get the first */ + + *table_ptr_loc = NULL; + if (acpi_gbl_table_lists[table_type].next) { + *table_ptr_loc = + acpi_gbl_table_lists[table_type].next->pointer; + } + return_ACPI_STATUS(AE_OK); + } + + /* Check for instance out of range */ if (instance > acpi_gbl_table_lists[table_type].count) { return_ACPI_STATUS(AE_NOT_EXIST); } - /* - * Walk the list to get the desired table - * Note: Instance is one-based + /* Walk the list to get the desired table + * Since the if (Instance == 1) check above checked for the + * first table, setting table_desc equal to the .Next member + * is actually pointing to the second table. Therefore, we + * need to walk from the 2nd table until we reach the Instance + * that the user is looking for and return its table pointer. */ table_desc = acpi_gbl_table_lists[table_type].next; - for (i = 1; i < instance; i++) { + for (i = 2; i < instance; i++) { table_desc = table_desc->next; } /* We are now pointing to the requested table's descriptor */ - *return_table = table_desc->pointer; + *table_ptr_loc = table_desc->pointer; + return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/tables/tbgetall.c b/trunk/drivers/acpi/tables/tbgetall.c index ad982112e4c6..134e5dce0bc1 100644 --- a/trunk/drivers/acpi/tables/tbgetall.c +++ b/trunk/drivers/acpi/tables/tbgetall.c @@ -77,7 +77,7 @@ acpi_tb_get_primary_table(struct acpi_pointer *address, acpi_status status; struct acpi_table_header header; - ACPI_FUNCTION_TRACE(tb_get_primary_table); + ACPI_FUNCTION_TRACE("tb_get_primary_table"); /* Ignore a NULL address in the RSDT */ @@ -140,7 +140,7 @@ acpi_tb_get_secondary_table(struct acpi_pointer *address, acpi_status status; struct acpi_table_header header; - ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); + ACPI_FUNCTION_TRACE_STR("tb_get_secondary_table", signature); /* Get the header in order to match the signature */ @@ -151,7 +151,7 @@ acpi_tb_get_secondary_table(struct acpi_pointer *address, /* Signature must match request */ - if (!ACPI_COMPARE_NAME(header.signature, signature)) { + if (ACPI_STRNCMP(header.signature, signature, ACPI_NAME_SIZE)) { ACPI_ERROR((AE_INFO, "Incorrect table signature - wanted [%s] found [%4.4s]", signature, header.signature)); @@ -207,7 +207,7 @@ acpi_status acpi_tb_get_required_tables(void) struct acpi_table_desc table_info; struct acpi_pointer address; - ACPI_FUNCTION_TRACE(tb_get_required_tables); + ACPI_FUNCTION_TRACE("tb_get_required_tables"); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", acpi_gbl_rsdt_table_count)); @@ -223,7 +223,6 @@ acpi_status acpi_tb_get_required_tables(void) * any SSDTs. */ for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { - /* Get the table address from the common internal XSDT */ address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; @@ -306,6 +305,6 @@ acpi_status acpi_tb_get_required_tables(void) /* Always delete the RSDP mapping, we are done with it */ - acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP); + acpi_tb_delete_tables_by_type(ACPI_TABLE_RSDP); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/tables/tbinstal.c b/trunk/drivers/acpi/tables/tbinstal.c index 7ca2df75bb11..7ffd0fddb4e5 100644 --- a/trunk/drivers/acpi/tables/tbinstal.c +++ b/trunk/drivers/acpi/tables/tbinstal.c @@ -73,18 +73,17 @@ acpi_tb_match_signature(char *signature, { acpi_native_uint i; - ACPI_FUNCTION_TRACE(tb_match_signature); + ACPI_FUNCTION_TRACE("tb_match_signature"); /* Search for a signature match among the known table types */ - for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { if (!(acpi_gbl_table_data[i].flags & search_type)) { continue; } if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, acpi_gbl_table_data[i].sig_length)) { - /* Found a signature match, return index if requested */ if (table_info) { @@ -123,7 +122,7 @@ acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) { acpi_status status; - ACPI_FUNCTION_TRACE(tb_install_table); + ACPI_FUNCTION_TRACE("tb_install_table"); /* Lock tables while installing */ @@ -188,7 +187,7 @@ acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) struct acpi_table_header *table_header; acpi_status status; - ACPI_FUNCTION_TRACE(tb_recognize_table); + ACPI_FUNCTION_TRACE("tb_recognize_table"); /* Ensure that we have a valid table pointer */ @@ -219,6 +218,7 @@ acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) /* Return the table type and length via the info struct */ table_info->length = (acpi_size) table_header->length; + return_ACPI_STATUS(status); } @@ -243,11 +243,11 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, struct acpi_table_desc *table_desc; acpi_status status; - ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); + ACPI_FUNCTION_TRACE_U32("tb_init_table_descriptor", table_type); /* Allocate a descriptor for this table */ - table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + table_desc = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc)); if (!table_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -274,7 +274,7 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, * at this location, so return an error. */ if (list_head->next) { - ACPI_FREE(table_desc); + ACPI_MEM_FREE(table_desc); return_ACPI_STATUS(AE_ALREADY_EXISTS); } @@ -312,14 +312,15 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, /* Finish initialization of the table descriptor */ - table_desc->loaded_into_namespace = FALSE; table_desc->type = (u8) table_type; table_desc->pointer = table_info->pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), - table_desc->aml_length = (u32) - (table_desc->length - (u32) sizeof(struct acpi_table_header)); + table_desc->aml_length = (u32) (table_desc->length - + (u32) sizeof(struct + acpi_table_header)); + table_desc->loaded_into_namespace = FALSE; /* * Set the appropriate global pointer (if there is one) to point to the @@ -334,6 +335,7 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, table_info->owner_id = table_desc->owner_id; table_info->installed_desc = table_desc; + return_ACPI_STATUS(AE_OK); } @@ -357,7 +359,7 @@ void acpi_tb_delete_all_tables(void) * Free memory allocated for ACPI tables * Memory can either be mapped or allocated */ - for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { + for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) { acpi_tb_delete_tables_by_type(type); } } @@ -381,9 +383,9 @@ void acpi_tb_delete_tables_by_type(acpi_table_type type) u32 count; u32 i; - ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); + ACPI_FUNCTION_TRACE_U32("tb_delete_tables_by_type", type); - if (type > ACPI_TABLE_ID_MAX) { + if (type > ACPI_TABLE_MAX) { return_VOID; } @@ -394,28 +396,28 @@ void acpi_tb_delete_tables_by_type(acpi_table_type type) /* Clear the appropriate "typed" global table pointer */ switch (type) { - case ACPI_TABLE_ID_RSDP: + case ACPI_TABLE_RSDP: acpi_gbl_RSDP = NULL; break; - case ACPI_TABLE_ID_DSDT: + case ACPI_TABLE_DSDT: acpi_gbl_DSDT = NULL; break; - case ACPI_TABLE_ID_FADT: + case ACPI_TABLE_FADT: acpi_gbl_FADT = NULL; break; - case ACPI_TABLE_ID_FACS: + case ACPI_TABLE_FACS: acpi_gbl_FACS = NULL; break; - case ACPI_TABLE_ID_XSDT: + case ACPI_TABLE_XSDT: acpi_gbl_XSDT = NULL; break; - case ACPI_TABLE_ID_SSDT: - case ACPI_TABLE_ID_PSDT: + case ACPI_TABLE_SSDT: + case ACPI_TABLE_PSDT: default: break; } @@ -469,7 +471,7 @@ void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) case ACPI_MEM_ALLOCATED: - ACPI_FREE(table_desc->pointer); + ACPI_MEM_FREE(table_desc->pointer); break; case ACPI_MEM_MAPPED: @@ -501,7 +503,7 @@ struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc { struct acpi_table_desc *next_desc; - ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); + ACPI_FUNCTION_TRACE_PTR("tb_uninstall_table", table_desc); if (!table_desc) { return_PTR(NULL); @@ -528,7 +530,7 @@ struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc /* Free the table descriptor */ next_desc = table_desc->next; - ACPI_FREE(table_desc); + ACPI_MEM_FREE(table_desc); /* Return pointer to the next descriptor */ diff --git a/trunk/drivers/acpi/tables/tbrsdt.c b/trunk/drivers/acpi/tables/tbrsdt.c index abcb08c2592a..4d308220225d 100644 --- a/trunk/drivers/acpi/tables/tbrsdt.c +++ b/trunk/drivers/acpi/tables/tbrsdt.c @@ -64,7 +64,7 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) acpi_status status; struct rsdp_descriptor *rsdp; - ACPI_FUNCTION_TRACE(tb_verify_rsdp); + ACPI_FUNCTION_TRACE("tb_verify_rsdp"); switch (address->pointer_type) { case ACPI_LOGICAL_POINTER: @@ -78,7 +78,7 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) */ status = acpi_os_map_memory(address->pointer.physical, sizeof(struct rsdp_descriptor), - ACPI_CAST_PTR(void, &rsdp)); + (void *)&rsdp); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -95,20 +95,15 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) goto cleanup; } - /* RSDP is ok. Init the table info */ + /* The RSDP supplied is OK */ table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); table_info.length = sizeof(struct rsdp_descriptor); - - if (address->pointer_type == ACPI_PHYSICAL_POINTER) { - table_info.allocation = ACPI_MEM_MAPPED; - } else { - table_info.allocation = ACPI_MEM_NOT_ALLOCATED; - } + table_info.allocation = ACPI_MEM_MAPPED; /* Save the table pointers and allocation info */ - status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); + status = acpi_tb_init_table_descriptor(ACPI_TABLE_RSDP, &table_info); if (ACPI_FAILURE(status)) { goto cleanup; } @@ -179,20 +174,22 @@ void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) { - char *signature; + int no_match; ACPI_FUNCTION_ENTRY(); - /* Search for appropriate signature, RSDT or XSDT */ - + /* + * Search for appropriate signature, RSDT or XSDT + */ if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { - signature = RSDT_SIG; + no_match = ACPI_STRNCMP((char *)table_ptr, RSDT_SIG, + sizeof(RSDT_SIG) - 1); } else { - signature = XSDT_SIG; + no_match = ACPI_STRNCMP((char *)table_ptr, XSDT_SIG, + sizeof(XSDT_SIG) - 1); } - if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { - + if (no_match) { /* Invalid RSDT or XSDT signature */ ACPI_ERROR((AE_INFO, @@ -201,8 +198,10 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); ACPI_ERROR((AE_INFO, - "RSDT/XSDT signature at %X is invalid", - acpi_gbl_RSDP->rsdt_physical_address)); + "RSDT/XSDT signature at %X (%p) is invalid", + acpi_gbl_RSDP->rsdt_physical_address, + (void *)(acpi_native_uint) acpi_gbl_RSDP-> + rsdt_physical_address)); if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { ACPI_ERROR((AE_INFO, "Looking for RSDT")); @@ -235,13 +234,13 @@ acpi_status acpi_tb_get_table_rsdt(void) acpi_status status; struct acpi_pointer address; - ACPI_FUNCTION_TRACE(tb_get_table_rsdt); + ACPI_FUNCTION_TRACE("tb_get_table_rsdt"); /* Get the RSDT/XSDT via the RSDP */ acpi_tb_get_rsdt_address(&address); - table_info.type = ACPI_TABLE_ID_XSDT; + table_info.type = ACPI_TABLE_XSDT; status = acpi_tb_get_table(&address, &table_info); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, @@ -275,13 +274,12 @@ acpi_status acpi_tb_get_table_rsdt(void) /* Save the table pointers and allocation info */ - status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); + status = acpi_tb_init_table_descriptor(ACPI_TABLE_XSDT, &table_info); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - acpi_gbl_XSDT = - ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); + acpi_gbl_XSDT = ACPI_CAST_PTR(XSDT_DESCRIPTOR, table_info.pointer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c index 209a401801e3..bc571592f087 100644 --- a/trunk/drivers/acpi/tables/tbutils.c +++ b/trunk/drivers/acpi/tables/tbutils.c @@ -71,7 +71,7 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) { struct acpi_table_desc *table_desc; - ACPI_FUNCTION_TRACE(tb_is_table_installed); + ACPI_FUNCTION_TRACE("tb_is_table_installed"); /* Get the list descriptor and first table descriptor */ @@ -96,11 +96,10 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) (!ACPI_MEMCMP (table_desc->pointer, new_table_desc->pointer, new_table_desc->pointer->length))) { - /* Match: this table is already installed */ ACPI_DEBUG_PRINT((ACPI_DB_TABLES, - "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", + "Table [%4.4s] already installed: Rev %X oem_table_id [%8.8s]\n", new_table_desc->pointer->signature, new_table_desc->pointer->revision, new_table_desc->pointer-> @@ -160,8 +159,12 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) ACPI_MOVE_32_TO_32(&signature, table_header->signature); if (!acpi_ut_valid_acpi_name(signature)) { - ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", - signature)); + ACPI_ERROR((AE_INFO, + "Table signature at %p [%p] has invalid characters", + table_header, &signature)); + + ACPI_WARNING((AE_INFO, "Invalid table signature found: [%4.4s]", + ACPI_CAST_PTR(char, &signature))); ACPI_DUMP_BUFFER(table_header, sizeof(struct acpi_table_header)); @@ -172,9 +175,12 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) if (table_header->length < sizeof(struct acpi_table_header)) { ACPI_ERROR((AE_INFO, - "Invalid length 0x%X in table with signature %4.4s", - (u32) table_header->length, - ACPI_CAST_PTR(char, &signature))); + "Invalid length in table header %p name %4.4s", + table_header, (char *)&signature)); + + ACPI_WARNING((AE_INFO, + "Invalid table header length (0x%X) found", + (u32) table_header->length)); ACPI_DUMP_BUFFER(table_header, sizeof(struct acpi_table_header)); @@ -186,119 +192,72 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) /******************************************************************************* * - * FUNCTION: acpi_tb_sum_table - * - * PARAMETERS: Buffer - Buffer to sum - * Length - Size of the buffer - * - * RETURN: 8 bit sum of buffer - * - * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. - * - ******************************************************************************/ - -u8 acpi_tb_sum_table(void *buffer, u32 length) -{ - acpi_native_uint i; - u8 sum = 0; - - if (!buffer || !length) { - return (0); - } - - for (i = 0; i < length; i++) { - sum = (u8) (sum + ((u8 *) buffer)[i]); - } - return (sum); -} - -/******************************************************************************* - * - * FUNCTION: acpi_tb_generate_checksum + * FUNCTION: acpi_tb_verify_table_checksum * - * PARAMETERS: Table - Pointer to a valid ACPI table (with a - * standard ACPI header) + * PARAMETERS: *table_header - ACPI table to verify * - * RETURN: 8 bit checksum of buffer + * RETURN: 8 bit checksum of table * - * DESCRIPTION: Computes an 8 bit checksum of the table. + * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct + * table should have a checksum of 0. * ******************************************************************************/ -u8 acpi_tb_generate_checksum(struct acpi_table_header * table) +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) { u8 checksum; + acpi_status status = AE_OK; - /* Sum the entire table as-is */ - - checksum = acpi_tb_sum_table(table, table->length); + ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); - /* Subtract off the existing checksum value in the table */ + /* Compute the checksum on the table */ - checksum = (u8) (checksum - table->checksum); + checksum = + acpi_tb_generate_checksum(table_header, table_header->length); - /* Compute the final checksum */ + /* Return the appropriate exception */ - checksum = (u8) (0 - checksum); - return (checksum); -} + if (checksum) { + ACPI_WARNING((AE_INFO, + "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)", + table_header->signature, + (u32) table_header->checksum, (u32) checksum)); -/******************************************************************************* - * - * FUNCTION: acpi_tb_set_checksum - * - * PARAMETERS: Table - Pointer to a valid ACPI table (with a - * standard ACPI header) - * - * RETURN: None. Sets the table checksum field - * - * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the - * checksum into the table header. - * - ******************************************************************************/ - -void acpi_tb_set_checksum(struct acpi_table_header *table) -{ - - table->checksum = acpi_tb_generate_checksum(table); + status = AE_BAD_CHECKSUM; + } + return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_tb_verify_table_checksum + * FUNCTION: acpi_tb_generate_checksum * - * PARAMETERS: *table_header - ACPI table to verify + * PARAMETERS: Buffer - Buffer to checksum + * Length - Size of the buffer * - * RETURN: 8 bit checksum of table + * RETURN: 8 bit checksum of buffer * - * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares - * it to the existing checksum value. + * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. * ******************************************************************************/ -acpi_status -acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) +u8 acpi_tb_generate_checksum(void *buffer, u32 length) { - u8 checksum; - - ACPI_FUNCTION_TRACE(tb_verify_table_checksum); - - /* Compute the checksum on the table */ + u8 *end_buffer; + u8 *rover; + u8 sum = 0; - checksum = acpi_tb_generate_checksum(table_header); + if (buffer && length) { + /* Buffer and Length are valid */ - /* Checksum ok? */ + end_buffer = ACPI_ADD_PTR(u8, buffer, length); - if (checksum == table_header->checksum) { - return_ACPI_STATUS(AE_OK); + for (rover = buffer; rover < end_buffer; rover++) { + sum = (u8) (sum + *rover); + } } - - ACPI_WARNING((AE_INFO, - "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", - table_header->signature, table_header->checksum, - checksum)); - - return_ACPI_STATUS(AE_BAD_CHECKSUM); + return (sum); } #ifdef ACPI_OBSOLETE_FUNCTIONS @@ -317,12 +276,12 @@ acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) acpi_status acpi_tb_handle_to_object(u16 table_id, - struct acpi_table_desc **return_table_desc) + struct acpi_table_desc ** return_table_desc) { u32 i; struct acpi_table_desc *table_desc; - ACPI_FUNCTION_NAME(tb_handle_to_object); + ACPI_FUNCTION_NAME("tb_handle_to_object"); for (i = 0; i < ACPI_TABLE_MAX; i++) { table_desc = acpi_gbl_table_lists[i].next; @@ -336,7 +295,7 @@ acpi_tb_handle_to_object(u16 table_id, } } - ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); + ACPI_ERROR((AE_INFO, "table_id=%X does not exist", table_id)); return (AE_BAD_PARAMETER); } #endif diff --git a/trunk/drivers/acpi/tables/tbxface.c b/trunk/drivers/acpi/tables/tbxface.c index 4e91f2984815..9fe53c9d5b9a 100644 --- a/trunk/drivers/acpi/tables/tbxface.c +++ b/trunk/drivers/acpi/tables/tbxface.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -66,7 +68,7 @@ acpi_status acpi_load_tables(void) struct acpi_pointer rsdp_address; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_load_tables); + ACPI_FUNCTION_TRACE("acpi_load_tables"); /* Get the RSDP */ @@ -121,8 +123,6 @@ acpi_status acpi_load_tables(void) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_load_tables) - #ifdef ACPI_FUTURE_USAGE /******************************************************************************* * @@ -139,13 +139,14 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables) * is determined that the table is invalid, the call will fail. * ******************************************************************************/ + acpi_status acpi_load_table(struct acpi_table_header *table_ptr) { acpi_status status; struct acpi_table_desc table_info; struct acpi_pointer address; - ACPI_FUNCTION_TRACE(acpi_load_table); + ACPI_FUNCTION_TRACE("acpi_load_table"); if (!table_ptr) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -173,7 +174,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) status = acpi_tb_install_table(&table_info); if (ACPI_FAILURE(status)) { if (status == AE_ALREADY_EXISTS) { - /* Table already exists, no error */ status = AE_OK; @@ -188,12 +188,12 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) /* Convert the table to common format if necessary */ switch (table_info.type) { - case ACPI_TABLE_ID_FADT: + case ACPI_TABLE_FADT: status = acpi_tb_convert_table_fadt(); break; - case ACPI_TABLE_ID_FACS: + case ACPI_TABLE_FACS: status = acpi_tb_build_common_facs(&table_info); break; @@ -208,7 +208,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) } if (ACPI_FAILURE(status)) { - /* Uninstall table and free the buffer */ (void)acpi_tb_uninstall_table(table_info.installed_desc); @@ -217,8 +216,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_load_table) - /******************************************************************************* * * FUNCTION: acpi_unload_table @@ -230,15 +227,16 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) * DESCRIPTION: This routine is used to force the unload of a table * ******************************************************************************/ + acpi_status acpi_unload_table(acpi_table_type table_type) { struct acpi_table_desc *table_desc; - ACPI_FUNCTION_TRACE(acpi_unload_table); + ACPI_FUNCTION_TRACE("acpi_unload_table"); /* Parameter validation */ - if (table_type > ACPI_TABLE_ID_MAX) { + if (table_type > ACPI_TABLE_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -263,8 +261,6 @@ acpi_status acpi_unload_table(acpi_table_type table_type) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_unload_table) - /******************************************************************************* * * FUNCTION: acpi_get_table_header @@ -285,6 +281,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table) * have a standard header and is fixed length. * ******************************************************************************/ + acpi_status acpi_get_table_header(acpi_table_type table_type, u32 instance, struct acpi_table_header *out_table_header) @@ -292,16 +289,16 @@ acpi_get_table_header(acpi_table_type table_type, struct acpi_table_header *tbl_ptr; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_get_table_header); + ACPI_FUNCTION_TRACE("acpi_get_table_header"); if ((instance == 0) || - (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { + (table_type == ACPI_TABLE_RSDP) || (!out_table_header)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Check the table type and instance */ - if ((table_type > ACPI_TABLE_ID_MAX) || + if ((table_type > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -328,7 +325,6 @@ acpi_get_table_header(acpi_table_type table_type, return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_table_header) #endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* @@ -353,6 +349,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_header) * a complete table including the header. * ******************************************************************************/ + acpi_status acpi_get_table(acpi_table_type table_type, u32 instance, struct acpi_buffer *ret_buffer) @@ -361,7 +358,7 @@ acpi_get_table(acpi_table_type table_type, acpi_status status; acpi_size table_length; - ACPI_FUNCTION_TRACE(acpi_get_table); + ACPI_FUNCTION_TRACE("acpi_get_table"); /* Parameter validation */ @@ -376,7 +373,7 @@ acpi_get_table(acpi_table_type table_type, /* Check the table type and instance */ - if ((table_type > ACPI_TABLE_ID_MAX) || + if ((table_type > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -399,8 +396,7 @@ acpi_get_table(acpi_table_type table_type, /* Get the table length */ - if (table_type == ACPI_TABLE_ID_RSDP) { - + if (table_type == ACPI_TABLE_RSDP) { /* RSD PTR is the only "table" without a header */ table_length = sizeof(struct rsdp_descriptor); @@ -421,4 +417,4 @@ acpi_get_table(acpi_table_type table_type, return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_table) +EXPORT_SYMBOL(acpi_get_table); diff --git a/trunk/drivers/acpi/tables/tbxfroot.c b/trunk/drivers/acpi/tables/tbxfroot.c index da2648bbdbc0..a62db6af83c9 100644 --- a/trunk/drivers/acpi/tables/tbxfroot.c +++ b/trunk/drivers/acpi/tables/tbxfroot.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include @@ -73,7 +75,6 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) * The signature and checksum must both be correct */ if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { - /* Nope, BAD Signature */ return (AE_BAD_SIGNATURE); @@ -81,14 +82,15 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) /* Check the standard checksum */ - if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { + if (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { return (AE_BAD_CHECKSUM); } /* Check extended checksum if table version >= 2 */ if ((rsdp->revision >= 2) && - (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { + (acpi_tb_generate_checksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != + 0)) { return (AE_BAD_CHECKSUM); } @@ -119,7 +121,7 @@ acpi_tb_find_table(char *signature, acpi_status status; struct acpi_table_header *table; - ACPI_FUNCTION_TRACE(tb_find_table); + ACPI_FUNCTION_TRACE("tb_find_table"); /* Validate string lengths */ @@ -129,7 +131,7 @@ acpi_tb_find_table(char *signature, return_ACPI_STATUS(AE_AML_STRING_LIMIT); } - if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { + if (!ACPI_STRNCMP(signature, DSDT_SIG, ACPI_NAME_SIZE)) { /* * The DSDT pointer is contained in the FADT, not the RSDT. * This code should suffice, because the only code that would perform @@ -154,12 +156,10 @@ acpi_tb_find_table(char *signature, /* Check oem_id and oem_table_id */ - if ((oem_id[0] && - ACPI_STRNCMP(oem_id, table->oem_id, - sizeof(table->oem_id))) || - (oem_table_id[0] && - ACPI_STRNCMP(oem_table_id, table->oem_table_id, - sizeof(table->oem_table_id)))) { + if ((oem_id[0] && ACPI_STRNCMP(oem_id, table->oem_id, + sizeof(table->oem_id))) || + (oem_table_id[0] && ACPI_STRNCMP(oem_table_id, table->oem_table_id, + sizeof(table->oem_table_id)))) { return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); } @@ -203,7 +203,7 @@ acpi_get_firmware_table(acpi_string signature, u32 i; u32 j; - ACPI_FUNCTION_TRACE(acpi_get_firmware_table); + ACPI_FUNCTION_TRACE("acpi_get_firmware_table"); /* * Ensure that at least the table manager is initialized. We don't @@ -217,7 +217,6 @@ acpi_get_firmware_table(acpi_string signature, /* Ensure that we have a RSDP */ if (!acpi_gbl_RSDP) { - /* Get the RSDP */ status = acpi_os_get_root_pointer(flags, &address); @@ -262,7 +261,7 @@ acpi_get_firmware_table(acpi_string signature, /* Get and validate the RSDT */ - rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); + rsdt_info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc)); if (!rsdt_info) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -279,13 +278,13 @@ acpi_get_firmware_table(acpi_string signature, /* Allocate a scratch table header and table descriptor */ - header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); + header = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_header)); if (!header) { status = AE_NO_MEMORY; goto cleanup; } - table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); + table_info = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_desc)); if (!table_info) { status = AE_NO_MEMORY; goto cleanup; @@ -309,12 +308,12 @@ acpi_get_firmware_table(acpi_string signature, if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { address.pointer.value = (ACPI_CAST_PTR - (struct rsdt_descriptor, + (RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; } else { address.pointer.value = (ACPI_CAST_PTR - (struct xsdt_descriptor, + (XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; } @@ -327,13 +326,11 @@ acpi_get_firmware_table(acpi_string signature, /* Compare table signatures and table instance */ - if (ACPI_COMPARE_NAME(header->signature, signature)) { - + if (!ACPI_STRNCMP(header->signature, signature, ACPI_NAME_SIZE)) { /* An instance of the table was found */ j++; if (j >= instance) { - /* Found the correct instance, get the entire table */ status = @@ -358,21 +355,23 @@ acpi_get_firmware_table(acpi_string signature, acpi_os_unmap_memory(rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length); } - ACPI_FREE(rsdt_info); + ACPI_MEM_FREE(rsdt_info); if (header) { - ACPI_FREE(header); + ACPI_MEM_FREE(header); } if (table_info) { - ACPI_FREE(table_info); + ACPI_MEM_FREE(table_info); } return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) +EXPORT_SYMBOL(acpi_get_firmware_table); /* TBD: Move to a new file */ + #if ACPI_MACHINE_WIDTH != 16 + /******************************************************************************* * * FUNCTION: acpi_find_root_pointer @@ -385,12 +384,13 @@ ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) * DESCRIPTION: Find the RSDP * ******************************************************************************/ + acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) { struct acpi_table_desc table_info; acpi_status status; - ACPI_FUNCTION_TRACE(acpi_find_root_pointer); + ACPI_FUNCTION_TRACE("acpi_find_root_pointer"); /* Get the RSDP */ @@ -407,8 +407,6 @@ acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) - /******************************************************************************* * * FUNCTION: acpi_tb_scan_memory_for_rsdp @@ -421,13 +419,14 @@ ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) * DESCRIPTION: Search a block of memory for the RSDP signature * ******************************************************************************/ + static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) { acpi_status status; u8 *mem_rover; u8 *end_address; - ACPI_FUNCTION_TRACE(tb_scan_memory_for_rsdp); + ACPI_FUNCTION_TRACE("tb_scan_memory_for_rsdp"); end_address = start_address + length; @@ -435,14 +434,12 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) for (mem_rover = start_address; mem_rover < end_address; mem_rover += ACPI_RSDP_SCAN_STEP) { - /* The RSDP signature and checksum must both be correct */ status = acpi_tb_validate_rsdp(ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover)); if (ACPI_SUCCESS(status)) { - /* Sig and checksum valid, we have found a real RSDP */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -472,10 +469,10 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) * * RETURN: Status, RSDP physical address * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor * pointer structure. If it is found, set *RSDP to point to it. * - * NOTE1: The RSDP must be either in the first 1_k of the Extended + * NOTE1: The RSDp must be either in the first 1_k of the Extended * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) * Only a 32-bit physical address is necessary. * @@ -492,13 +489,12 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) u32 physical_address; acpi_status status; - ACPI_FUNCTION_TRACE(tb_find_rsdp); + ACPI_FUNCTION_TRACE("tb_find_rsdp"); /* * Scan supports either logical addressing or physical addressing */ if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { - /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ status = acpi_os_map_memory((acpi_physical_address) @@ -525,7 +521,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) if (physical_address > 0x400) { /* - * 1b) Search EBDA paragraphs (EBDA is required to be a + * 1b) Search EBDA paragraphs (EBDa is required to be a * minimum of 1_k length) */ status = acpi_os_map_memory((acpi_physical_address) @@ -546,11 +542,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); if (mem_rover) { - /* Return the physical address */ physical_address += - (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); + ACPI_PTR_DIFF(mem_rover, table_ptr); table_info->physical_address = (acpi_physical_address) physical_address; @@ -581,12 +576,11 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { - /* Return the physical address */ - physical_address = (u32) - (ACPI_HI_RSDP_WINDOW_BASE + - ACPI_PTR_DIFF(mem_rover, table_ptr)); + physical_address = + ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF(mem_rover, + table_ptr); table_info->physical_address = (acpi_physical_address) physical_address; @@ -607,7 +601,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) if (physical_address > 0x400) { /* - * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of + * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of * 1_k length) */ mem_rover = @@ -615,7 +609,6 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) (physical_address), ACPI_EBDA_WINDOW_SIZE); if (mem_rover) { - /* Return the physical address */ table_info->physical_address = @@ -631,7 +624,6 @@ acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { - /* Found it, return the physical address */ table_info->physical_address = diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index e7fe3a14fdaf..19f3ea48475e 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -82,7 +82,6 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); -static int acpi_thermal_resume(struct acpi_device *device, int state); static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); @@ -104,7 +103,6 @@ static struct acpi_driver acpi_thermal_driver = { .ops = { .add = acpi_thermal_add, .remove = acpi_thermal_remove, - .resume = acpi_thermal_resume, }, }; @@ -686,7 +684,8 @@ static void acpi_thermal_run(unsigned long data) { struct acpi_thermal *tz = (struct acpi_thermal *)data; if (!tz->zombie) - acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data); + acpi_os_queue_for_execution(OSD_PRIORITY_GPE, + acpi_thermal_check, (void *)data); } static void acpi_thermal_check(void *data) @@ -943,10 +942,8 @@ acpi_thermal_write_trip_points(struct file *file, memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN); active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); - if (!active) { - kfree(limit_string); + if (!active) return_VALUE(-ENOMEM); - } if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); @@ -1345,7 +1342,7 @@ static int acpi_thermal_add(struct acpi_device *device) result = acpi_thermal_add_fs(device); if (result) - goto end; + return_VALUE(result); init_timer(&tz->timer); @@ -1419,20 +1416,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) return_VALUE(0); } -static int acpi_thermal_resume(struct acpi_device *device, int state) -{ - struct acpi_thermal *tz = NULL; - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - tz = (struct acpi_thermal *)acpi_driver_data(device); - - acpi_thermal_check(tz); - - return AE_OK; -} - static int __init acpi_thermal_init(void) { int result = 0; diff --git a/trunk/drivers/acpi/utilities/utalloc.c b/trunk/drivers/acpi/utilities/utalloc.c index 7940fc1bd69e..03b0044974c2 100644 --- a/trunk/drivers/acpi/utilities/utalloc.c +++ b/trunk/drivers/acpi/utilities/utalloc.c @@ -46,6 +46,24 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utalloc") +/* Local prototypes */ +#ifdef ACPI_DBG_TRACK_ALLOCATIONS +static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); + +static acpi_status +acpi_ut_track_allocation(struct acpi_debug_mem_block *address, + acpi_size size, + u8 alloc_type, u32 component, char *module, u32 line); + +static acpi_status +acpi_ut_remove_allocation(struct acpi_debug_mem_block *address, + u32 component, char *module, u32 line); + +static acpi_status +acpi_ut_create_list(char *list_name, + u16 object_size, struct acpi_memory_list **return_cache); +#endif + /******************************************************************************* * * FUNCTION: acpi_ut_create_caches @@ -57,23 +75,33 @@ ACPI_MODULE_NAME("utalloc") * DESCRIPTION: Create all local caches * ******************************************************************************/ + acpi_status acpi_ut_create_caches(void) { acpi_status status; - /* Object Caches, for frequently used objects */ +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + + /* Memory allocation lists */ + + status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); + if (ACPI_FAILURE(status)) { + return (status); + } status = - acpi_os_create_cache("Acpi-Namespace", - sizeof(struct acpi_namespace_node), - ACPI_MAX_NAMESPACE_CACHE_DEPTH, - &acpi_gbl_namespace_cache); + acpi_ut_create_list("Acpi-Namespace", + sizeof(struct acpi_namespace_node), + &acpi_gbl_ns_node_list); if (ACPI_FAILURE(status)) { return (status); } +#endif + + /* Object Caches, for frequently used objects */ status = - acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state), + acpi_os_create_cache("acpi_state", sizeof(union acpi_generic_state), ACPI_MAX_STATE_CACHE_DEPTH, &acpi_gbl_state_cache); if (ACPI_FAILURE(status)) { @@ -81,7 +109,7 @@ acpi_status acpi_ut_create_caches(void) } status = - acpi_os_create_cache("Acpi-Parse", + acpi_os_create_cache("acpi_parse", sizeof(struct acpi_parse_obj_common), ACPI_MAX_PARSE_CACHE_DEPTH, &acpi_gbl_ps_node_cache); @@ -90,7 +118,7 @@ acpi_status acpi_ut_create_caches(void) } status = - acpi_os_create_cache("Acpi-ParseExt", + acpi_os_create_cache("acpi_parse_ext", sizeof(struct acpi_parse_obj_named), ACPI_MAX_EXTPARSE_CACHE_DEPTH, &acpi_gbl_ps_node_ext_cache); @@ -99,7 +127,7 @@ acpi_status acpi_ut_create_caches(void) } status = - acpi_os_create_cache("Acpi-Operand", + acpi_os_create_cache("acpi_operand", sizeof(union acpi_operand_object), ACPI_MAX_OBJECT_CACHE_DEPTH, &acpi_gbl_operand_cache); @@ -107,24 +135,6 @@ acpi_status acpi_ut_create_caches(void) return (status); } -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - /* Memory allocation lists */ - - status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); - if (ACPI_FAILURE(status)) { - return (status); - } - - status = - acpi_ut_create_list("Acpi-Namespace", - sizeof(struct acpi_namespace_node), - &acpi_gbl_ns_node_list); - if (ACPI_FAILURE(status)) { - return (status); - } -#endif - return (AE_OK); } @@ -143,9 +153,6 @@ acpi_status acpi_ut_create_caches(void) acpi_status acpi_ut_delete_caches(void) { - (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); - acpi_gbl_namespace_cache = NULL; - (void)acpi_os_delete_cache(acpi_gbl_state_cache); acpi_gbl_state_cache = NULL; @@ -158,21 +165,6 @@ acpi_status acpi_ut_delete_caches(void) (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); acpi_gbl_ps_node_ext_cache = NULL; -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - /* Debug only - display leftover memory allocation, if any */ - - acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); - - /* Free memory lists */ - - acpi_os_free(acpi_gbl_global_list); - acpi_gbl_global_list = NULL; - - acpi_os_free(acpi_gbl_ns_node_list); - acpi_gbl_ns_node_list = NULL; -#endif - return (AE_OK); } @@ -260,7 +252,7 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, /* Allocate a new buffer with local interface to allow tracking */ - buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length); + buffer->pointer = ACPI_MEM_CALLOCATE(required_length); if (!buffer->pointer) { return (AE_NO_MEMORY); } @@ -296,7 +288,7 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, * * RETURN: Address of the allocated memory on success, NULL on failure. * - * DESCRIPTION: Subsystem equivalent of malloc. + * DESCRIPTION: The subsystem's equivalent of malloc. * ******************************************************************************/ @@ -304,23 +296,23 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) { void *allocation; - ACPI_FUNCTION_TRACE_U32(ut_allocate, size); + ACPI_FUNCTION_TRACE_U32("ut_allocate", size); /* Check for an inadvertent size of zero bytes */ if (!size) { - ACPI_WARNING((module, line, - "Attempt to allocate zero bytes, allocating 1 byte")); + ACPI_ERROR((module, line, + "ut_allocate: Attempt to allocate zero bytes, allocating 1 byte")); size = 1; } allocation = acpi_os_allocate(size); if (!allocation) { - /* Report allocation error */ - ACPI_WARNING((module, line, - "Could not allocate size %X", (u32) size)); + ACPI_ERROR((module, line, + "ut_allocate: Could not allocate size %X", + (u32) size)); return_PTR(NULL); } @@ -330,7 +322,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) /******************************************************************************* * - * FUNCTION: acpi_ut_allocate_zeroed + * FUNCTION: acpi_ut_callocate * * PARAMETERS: Size - Size of the allocation * Component - Component type of caller @@ -339,24 +331,542 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) * * RETURN: Address of the allocated memory on success, NULL on failure. * - * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. + * DESCRIPTION: Subsystem equivalent of calloc. * ******************************************************************************/ -void *acpi_ut_allocate_zeroed(acpi_size size, - u32 component, char *module, u32 line) +void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) { void *allocation; + ACPI_FUNCTION_TRACE_U32("ut_callocate", size); + + /* Check for an inadvertent size of zero bytes */ + + if (!size) { + ACPI_ERROR((module, line, + "Attempt to allocate zero bytes, allocating 1 byte")); + size = 1; + } + + allocation = acpi_os_allocate(size); + if (!allocation) { + /* Report allocation error */ + + ACPI_ERROR((module, line, + "Could not allocate size %X", (u32) size)); + return_PTR(NULL); + } + + /* Clear the memory block */ + + ACPI_MEMSET(allocation, 0, size); + return_PTR(allocation); +} + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS +/* + * These procedures are used for tracking memory leaks in the subsystem, and + * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. + * + * Each memory allocation is tracked via a doubly linked list. Each + * element contains the caller's component, module name, function name, and + * line number. acpi_ut_allocate and acpi_ut_callocate call + * acpi_ut_track_allocation to add an element to the list; deletion + * occurs in the body of acpi_ut_free. + */ + +/******************************************************************************* + * + * FUNCTION: acpi_ut_create_list + * + * PARAMETERS: cache_name - Ascii name for the cache + * object_size - Size of each cached object + * return_cache - Where the new cache object is returned + * + * RETURN: Status + * + * DESCRIPTION: Create a local memory list for tracking purposed + * + ******************************************************************************/ + +static acpi_status +acpi_ut_create_list(char *list_name, + u16 object_size, struct acpi_memory_list **return_cache) +{ + struct acpi_memory_list *cache; + + cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); + if (!cache) { + return (AE_NO_MEMORY); + } + + ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); + + cache->list_name = list_name; + cache->object_size = object_size; + + *return_cache = cache; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_allocate_and_track + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: The subsystem's equivalent of malloc. + * + ******************************************************************************/ + +void *acpi_ut_allocate_and_track(acpi_size size, + u32 component, char *module, u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + allocation = + acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header), + component, module, line); + if (!allocation) { + return (NULL); + } + + status = acpi_ut_track_allocation(allocation, size, + ACPI_MEM_MALLOC, component, module, + line); + if (ACPI_FAILURE(status)) { + acpi_os_free(allocation); + return (NULL); + } + + acpi_gbl_global_list->total_allocated++; + acpi_gbl_global_list->current_total_size += (u32) size; + + return ((void *)&allocation->user_space); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_callocate_and_track + * + * PARAMETERS: Size - Size of the allocation + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: Subsystem equivalent of calloc. + * + ******************************************************************************/ + +void *acpi_ut_callocate_and_track(acpi_size size, + u32 component, char *module, u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + allocation = + acpi_ut_callocate(size + sizeof(struct acpi_debug_mem_header), + component, module, line); + if (!allocation) { + /* Report allocation error */ + + ACPI_ERROR((module, line, + "Could not allocate size %X", (u32) size)); + return (NULL); + } + + status = acpi_ut_track_allocation(allocation, size, + ACPI_MEM_CALLOC, component, module, + line); + if (ACPI_FAILURE(status)) { + acpi_os_free(allocation); + return (NULL); + } + + acpi_gbl_global_list->total_allocated++; + acpi_gbl_global_list->current_total_size += (u32) size; + + return ((void *)&allocation->user_space); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_free_and_track + * + * PARAMETERS: Allocation - Address of the memory to deallocate + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: None + * + * DESCRIPTION: Frees the memory at Allocation + * + ******************************************************************************/ + +void +acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) +{ + struct acpi_debug_mem_block *debug_block; + acpi_status status; + + ACPI_FUNCTION_TRACE_PTR("ut_free", allocation); + + if (NULL == allocation) { + ACPI_ERROR((module, line, "Attempt to delete a NULL address")); + + return_VOID; + } + + debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block, + (((char *)allocation) - + sizeof(struct acpi_debug_mem_header))); + + acpi_gbl_global_list->total_freed++; + acpi_gbl_global_list->current_total_size -= debug_block->size; + + status = acpi_ut_remove_allocation(debug_block, + component, module, line); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not free memory")); + } + + acpi_os_free(debug_block); + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); + return_VOID; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_find_allocation + * + * PARAMETERS: Allocation - Address of allocated memory + * + * RETURN: A list element if found; NULL otherwise. + * + * DESCRIPTION: Searches for an element in the global allocation tracking list. + * + ******************************************************************************/ + +static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) +{ + struct acpi_debug_mem_block *element; + ACPI_FUNCTION_ENTRY(); - allocation = acpi_ut_allocate(size, component, module, line); - if (allocation) { + element = acpi_gbl_global_list->list_head; + + /* Search for the address. */ + + while (element) { + if (element == allocation) { + return (element); + } + + element = element->next; + } + + return (NULL); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_track_allocation + * + * PARAMETERS: Allocation - Address of allocated memory + * Size - Size of the allocation + * alloc_type - MEM_MALLOC or MEM_CALLOC + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: None. + * + * DESCRIPTION: Inserts an element into the global allocation tracking list. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, + acpi_size size, + u8 alloc_type, u32 component, char *module, u32 line) +{ + struct acpi_memory_list *mem_list; + struct acpi_debug_mem_block *element; + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE_PTR("ut_track_allocation", allocation); + + mem_list = acpi_gbl_global_list; + status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Search list for this address to make sure it is not already on the list. + * This will catch several kinds of problems. + */ + element = acpi_ut_find_allocation(allocation); + if (element) { + ACPI_ERROR((AE_INFO, + "ut_track_allocation: Allocation already present in list! (%p)", + allocation)); + + ACPI_ERROR((AE_INFO, "Element %p Address %p", + element, allocation)); + + goto unlock_and_exit; + } + + /* Fill in the instance data. */ + + allocation->size = (u32) size; + allocation->alloc_type = alloc_type; + allocation->component = component; + allocation->line = line; + + ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME); + allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; + + /* Insert at list head */ + + if (mem_list->list_head) { + ((struct acpi_debug_mem_block *)(mem_list->list_head))-> + previous = allocation; + } + + allocation->next = mem_list->list_head; + allocation->previous = NULL; + + mem_list->list_head = allocation; + + unlock_and_exit: + status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_allocation + * + * PARAMETERS: Allocation - Address of allocated memory + * Component - Component type of caller + * Module - Source file name of caller + * Line - Line number of caller + * + * RETURN: + * + * DESCRIPTION: Deletes an element from the global allocation tracking list. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, + u32 component, char *module, u32 line) +{ + struct acpi_memory_list *mem_list; + acpi_status status; + + ACPI_FUNCTION_TRACE("ut_remove_allocation"); + + mem_list = acpi_gbl_global_list; + if (NULL == mem_list->list_head) { + /* No allocations! */ + + ACPI_ERROR((module, line, + "Empty allocation list, nothing to free!")); + + return_ACPI_STATUS(AE_OK); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Unlink */ + + if (allocation->previous) { + (allocation->previous)->next = allocation->next; + } else { + mem_list->list_head = allocation->next; + } + + if (allocation->next) { + (allocation->next)->previous = allocation->previous; + } + + /* Mark the segment as deleted */ + + ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size); + + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", + allocation->size)); - /* Clear the memory block */ + status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_allocation_info + * + * PARAMETERS: + * + * RETURN: None + * + * DESCRIPTION: Print some info about the outstanding allocations. + * + ******************************************************************************/ - ACPI_MEMSET(allocation, 0, size); +#ifdef ACPI_FUTURE_USAGE +void acpi_ut_dump_allocation_info(void) +{ +/* + struct acpi_memory_list *mem_list; +*/ + + ACPI_FUNCTION_TRACE("ut_dump_allocation_info"); + +/* + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Current allocations", + mem_list->current_count, + ROUND_UP_TO_1K (mem_list->current_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", + mem_list->max_concurrent_count, + ROUND_UP_TO_1K (mem_list->max_concurrent_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", + running_object_count, + ROUND_UP_TO_1K (running_object_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", + running_alloc_count, + ROUND_UP_TO_1K (running_alloc_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Current Nodes", + acpi_gbl_current_node_count, + ROUND_UP_TO_1K (acpi_gbl_current_node_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Max Nodes", + acpi_gbl_max_concurrent_node_count, + ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * + sizeof (struct acpi_namespace_node))))); +*/ + return_VOID; +} +#endif /* ACPI_FUTURE_USAGE */ + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_allocations + * + * PARAMETERS: Component - Component(s) to dump info for. + * Module - Module to dump info for. NULL means all. + * + * RETURN: None + * + * DESCRIPTION: Print a list of all outstanding allocations. + * + ******************************************************************************/ + +void acpi_ut_dump_allocations(u32 component, char *module) +{ + struct acpi_debug_mem_block *element; + union acpi_descriptor *descriptor; + u32 num_outstanding = 0; + + ACPI_FUNCTION_TRACE("ut_dump_allocations"); + + /* + * Walk the allocation list. + */ + if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) { + return; } - return (allocation); + element = acpi_gbl_global_list->list_head; + while (element) { + if ((element->component & component) && + ((module == NULL) + || (0 == ACPI_STRCMP(module, element->module)))) { + /* Ignore allocated objects that are in a cache */ + + descriptor = + ACPI_CAST_PTR(union acpi_descriptor, + &element->user_space); + if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { + acpi_os_printf("%p Len %04X %9.9s-%d [%s] ", + descriptor, element->size, + element->module, element->line, + acpi_ut_get_descriptor_name + (descriptor)); + + /* Most of the elements will be Operand objects. */ + + switch (ACPI_GET_DESCRIPTOR_TYPE(descriptor)) { + case ACPI_DESC_TYPE_OPERAND: + acpi_os_printf("%12.12s R%hd", + acpi_ut_get_type_name + (descriptor->object. + common.type), + descriptor->object. + common.reference_count); + break; + + case ACPI_DESC_TYPE_PARSER: + acpi_os_printf("aml_opcode %04hX", + descriptor->op.asl. + aml_opcode); + break; + + case ACPI_DESC_TYPE_NAMED: + acpi_os_printf("%4.4s", + acpi_ut_get_node_name + (&descriptor->node)); + break; + + default: + break; + } + + acpi_os_printf("\n"); + num_outstanding++; + } + } + element = element->next; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY); + + /* Print summary */ + + if (!num_outstanding) { + ACPI_INFO((AE_INFO, "No outstanding allocations")); + } else { + ACPI_ERROR((AE_INFO, + "%d(%X) Outstanding allocations", + num_outstanding, num_outstanding)); + } + + return_VOID; } + +#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ diff --git a/trunk/drivers/acpi/utilities/utcache.c b/trunk/drivers/acpi/utilities/utcache.c index 56270a30718a..2177cb1ef2c4 100644 --- a/trunk/drivers/acpi/utilities/utcache.c +++ b/trunk/drivers/acpi/utilities/utcache.c @@ -118,14 +118,13 @@ acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) /* Walk the list of objects in this cache */ while (cache->list_head) { - /* Delete and unlink one cached state object */ next = *(ACPI_CAST_INDIRECT_PTR(char, &(((char *)cache-> list_head)[cache-> link_offset]))); - ACPI_FREE(cache->list_head); + ACPI_MEM_FREE(cache->list_head); cache->list_head = next; cache->current_depth--; @@ -194,7 +193,7 @@ acpi_os_release_object(struct acpi_memory_list * cache, void *object) /* If cache is full, just free this object */ if (cache->current_depth >= cache->max_depth) { - ACPI_FREE(object); + ACPI_MEM_FREE(object); ACPI_MEM_TRACKING(cache->total_freed++); } @@ -244,7 +243,7 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) acpi_status status; void *object; - ACPI_FUNCTION_NAME(os_acquire_object); + ACPI_FUNCTION_NAME("os_acquire_object"); if (!cache) { return (NULL); @@ -260,7 +259,6 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) /* Check the cache first */ if (cache->list_head) { - /* There is an object available, use it */ object = cache->list_head; @@ -272,9 +270,9 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) cache->current_depth--; ACPI_MEM_TRACKING(cache->hits++); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Object %p from %s cache\n", object, - cache->list_name)); + ACPI_MEM_TRACKING(ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Object %p from %s cache\n", + object, cache->list_name))); status = acpi_ut_release_mutex(ACPI_MTX_CACHES); if (ACPI_FAILURE(status)) { @@ -289,14 +287,14 @@ void *acpi_os_acquire_object(struct acpi_memory_list *cache) ACPI_MEM_TRACKING(cache->total_allocated++); - /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ + /* Avoid deadlock with ACPI_MEM_CALLOCATE */ status = acpi_ut_release_mutex(ACPI_MTX_CACHES); if (ACPI_FAILURE(status)) { return (NULL); } - object = ACPI_ALLOCATE_ZEROED(cache->object_size); + object = ACPI_MEM_CALLOCATE(cache->object_size); if (!object) { return (NULL); } diff --git a/trunk/drivers/acpi/utilities/utcopy.c b/trunk/drivers/acpi/utilities/utcopy.c index 5e1a80d1bc36..df2d32096b72 100644 --- a/trunk/drivers/acpi/utilities/utcopy.c +++ b/trunk/drivers/acpi/utilities/utcopy.c @@ -109,7 +109,7 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple); + ACPI_FUNCTION_TRACE("ut_copy_isimple_to_esimple"); *buffer_space_used = 0; @@ -325,7 +325,7 @@ acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, acpi_status status; struct acpi_pkg_info info; - ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage); + ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_epackage"); /* * First package at head of the buffer @@ -383,7 +383,7 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, { acpi_status status; - ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject); + ACPI_FUNCTION_TRACE("ut_copy_iobject_to_eobject"); if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) { /* @@ -442,7 +442,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, { union acpi_operand_object *internal_object; - ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple); + ACPI_FUNCTION_TRACE("ut_copy_esimple_to_isimple"); /* * Simple types supported are: String, Buffer, Integer @@ -472,8 +472,8 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, case ACPI_TYPE_STRING: internal_object->string.pointer = - ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string. - length + 1); + ACPI_MEM_CALLOCATE((acpi_size) external_object->string. + length + 1); if (!internal_object->string.pointer) { goto error_exit; } @@ -488,7 +488,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, case ACPI_TYPE_BUFFER: internal_object->buffer.pointer = - ACPI_ALLOCATE_ZEROED(external_object->buffer.length); + ACPI_MEM_CALLOCATE(external_object->buffer.length); if (!internal_object->buffer.pointer) { goto error_exit; } @@ -552,7 +552,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object, union acpi_operand_object *this_internal_obj; union acpi_object *this_external_obj; - ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); + ACPI_FUNCTION_TRACE("ut_copy_epackage_to_ipackage"); /* * First package at head of the buffer @@ -600,7 +600,7 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, { acpi_status status; - ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); + ACPI_FUNCTION_TRACE("ut_copy_eobject_to_iobject"); if (external_object->type == ACPI_TYPE_PACKAGE) { /* @@ -676,7 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, if ((source_desc->buffer.pointer) && (source_desc->buffer.length)) { dest_desc->buffer.pointer = - ACPI_ALLOCATE(source_desc->buffer.length); + ACPI_MEM_ALLOCATE(source_desc->buffer.length); if (!dest_desc->buffer.pointer) { return (AE_NO_MEMORY); } @@ -697,8 +697,8 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, */ if (source_desc->string.pointer) { dest_desc->string.pointer = - ACPI_ALLOCATE((acpi_size) source_desc->string. - length + 1); + ACPI_MEM_ALLOCATE((acpi_size) source_desc->string. + length + 1); if (!dest_desc->string.pointer) { return (AE_NO_MEMORY); } @@ -805,7 +805,9 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type, /* * Create the object array */ - target_object->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) source_object->package.count + 1) * sizeof(void *)); + target_object->package.elements = + ACPI_MEM_CALLOCATE(((acpi_size) source_object->package. + count + 1) * sizeof(void *)); if (!target_object->package.elements) { status = AE_NO_MEMORY; goto error_exit; @@ -854,7 +856,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage); + ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_ipackage"); dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj); dest_obj->common.flags = source_obj->common.flags; @@ -863,10 +865,10 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, /* * Create the object array and walk the source package tree */ - dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) - source_obj->package. - count + - 1) * sizeof(void *)); + dest_obj->package.elements = ACPI_MEM_CALLOCATE(((acpi_size) + source_obj->package. + count + + 1) * sizeof(void *)); if (!dest_obj->package.elements) { ACPI_ERROR((AE_INFO, "Package allocation failure")); return_ACPI_STATUS(AE_NO_MEMORY); @@ -880,7 +882,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, acpi_ut_copy_ielement_to_ielement, walk_state); if (ACPI_FAILURE(status)) { - /* On failure, delete the destination package object */ acpi_ut_remove_reference(dest_obj); @@ -910,7 +911,7 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject); + ACPI_FUNCTION_TRACE("ut_copy_iobject_to_iobject"); /* Create the top level object */ diff --git a/trunk/drivers/acpi/utilities/utdebug.c b/trunk/drivers/acpi/utilities/utdebug.c index 5ec1cfcc611d..35f3d581e034 100644 --- a/trunk/drivers/acpi/utilities/utdebug.c +++ b/trunk/drivers/acpi/utilities/utdebug.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #define _COMPONENT ACPI_UTILITIES @@ -121,14 +123,12 @@ static const char *acpi_ut_trim_function_name(const char *function_name) /* All Function names are longer than 4 chars, check is safe */ if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_MIXED) { - /* This is the case where the original source has not been modified */ return (function_name + 4); } if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_LOWER) { - /* This is the case where the source has been 'linuxized' */ return (function_name + 5); @@ -162,7 +162,7 @@ acpi_ut_debug_print(u32 requested_debug_level, const char *function_name, char *module_name, u32 component_id, char *format, ...) { - acpi_thread_id thread_id; + u32 thread_id; va_list args; /* @@ -177,6 +177,7 @@ acpi_ut_debug_print(u32 requested_debug_level, * Thread tracking and context switch notification */ thread_id = acpi_os_get_thread_id(); + if (thread_id != acpi_gbl_prev_thread_id) { if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf @@ -205,7 +206,7 @@ acpi_ut_debug_print(u32 requested_debug_level, acpi_os_vprintf(format, args); } -ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) +EXPORT_SYMBOL(acpi_ut_debug_print); /******************************************************************************* * @@ -225,6 +226,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) * debug_print so that the same macros can be used. * ******************************************************************************/ + void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print_raw(u32 requested_debug_level, u32 line_number, @@ -242,7 +244,7 @@ acpi_ut_debug_print_raw(u32 requested_debug_level, acpi_os_vprintf(format, args); } -ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) +EXPORT_SYMBOL(acpi_ut_debug_print_raw); /******************************************************************************* * @@ -259,6 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) * set in debug_level * ******************************************************************************/ + void acpi_ut_trace(u32 line_number, const char *function_name, char *module_name, u32 component_id) @@ -272,7 +275,7 @@ acpi_ut_trace(u32 line_number, component_id, "%s\n", acpi_gbl_fn_entry_str); } -ACPI_EXPORT_SYMBOL(acpi_ut_trace) +EXPORT_SYMBOL(acpi_ut_trace); /******************************************************************************* * @@ -290,6 +293,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace) * set in debug_level * ******************************************************************************/ + void acpi_ut_trace_ptr(u32 line_number, const char *function_name, @@ -396,7 +400,7 @@ acpi_ut_exit(u32 line_number, acpi_gbl_nesting_level--; } -ACPI_EXPORT_SYMBOL(acpi_ut_exit) +EXPORT_SYMBOL(acpi_ut_exit); /******************************************************************************* * @@ -414,6 +418,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit) * set in debug_level. Prints exit status also. * ******************************************************************************/ + void acpi_ut_status_exit(u32 line_number, const char *function_name, @@ -437,7 +442,7 @@ acpi_ut_status_exit(u32 line_number, acpi_gbl_nesting_level--; } -ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) +EXPORT_SYMBOL(acpi_ut_status_exit); /******************************************************************************* * @@ -455,6 +460,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) * set in debug_level. Prints exit value also. * ******************************************************************************/ + void acpi_ut_value_exit(u32 line_number, const char *function_name, @@ -469,7 +475,7 @@ acpi_ut_value_exit(u32 line_number, acpi_gbl_nesting_level--; } -ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) +EXPORT_SYMBOL(acpi_ut_value_exit); /******************************************************************************* * @@ -487,6 +493,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) * set in debug_level. Prints exit value also. * ******************************************************************************/ + void acpi_ut_ptr_exit(u32 line_number, const char *function_name, @@ -517,13 +524,20 @@ acpi_ut_ptr_exit(u32 line_number, * ******************************************************************************/ -void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) +void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) { acpi_native_uint i = 0; acpi_native_uint j; u32 temp32; u8 buf_char; + /* Only dump the buffer if tracing is enabled */ + + if (!((ACPI_LV_TABLES & acpi_dbg_level) && + (component_id & acpi_dbg_layer))) { + return; + } + if ((count < 4) || (count & 0x01)) { display = DB_BYTE_DISPLAY; } @@ -531,7 +545,6 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) /* Nasty little dump buffer routine! */ while (i < count) { - /* Print current offset */ acpi_os_printf("%6.4X: ", (u32) i); @@ -540,7 +553,6 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) for (j = 0; j < 16;) { if (i + j >= count) { - /* Dump fill spaces */ acpi_os_printf("%*s", ((display * 2) + 1), " "); @@ -549,7 +561,6 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) } switch (display) { - case DB_BYTE_DISPLAY: default: /* Default is BYTE display */ acpi_os_printf("%02X ", buffer[i + j]); @@ -607,31 +618,3 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) return; } - -/******************************************************************************* - * - * FUNCTION: acpi_ut_dump_buffer - * - * PARAMETERS: Buffer - Buffer to dump - * Count - Amount to dump, in bytes - * Display - BYTE, WORD, DWORD, or QWORD display - * component_iD - Caller's component ID - * - * RETURN: None - * - * DESCRIPTION: Generic dump buffer in both hex and ascii. - * - ******************************************************************************/ - -void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) -{ - - /* Only dump the buffer if tracing is enabled */ - - if (!((ACPI_LV_TABLES & acpi_dbg_level) && - (component_id & acpi_dbg_layer))) { - return; - } - - acpi_ut_dump_buffer2(buffer, count, display); -} diff --git a/trunk/drivers/acpi/utilities/utdelete.c b/trunk/drivers/acpi/utilities/utdelete.c index 67b9f325c6fa..1db9695b0029 100644 --- a/trunk/drivers/acpi/utilities/utdelete.c +++ b/trunk/drivers/acpi/utilities/utdelete.c @@ -76,7 +76,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) union acpi_operand_object *second_desc; union acpi_operand_object *next_desc; - ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); + ACPI_FUNCTION_TRACE_PTR("ut_delete_internal_obj", object); if (!object) { return_VOID; @@ -96,7 +96,6 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) /* Free the actual string buffer */ if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { - /* But only if it is NOT a pointer into an ACPI table */ obj_pointer = object->string.pointer; @@ -112,7 +111,6 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) /* Free the actual buffer */ if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { - /* But only if it is NOT a pointer into an ACPI table */ obj_pointer = object->buffer.pointer; @@ -200,22 +198,11 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) */ handler_desc = object->region.handler; if (handler_desc) { - if (handler_desc->address_space.handler_flags & + if (handler_desc->address_space. + hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { - - /* Deactivate region and free region context */ - - if (handler_desc->address_space.setup) { - (void)handler_desc-> - address_space.setup(object, - ACPI_REGION_DEACTIVATE, - handler_desc-> - address_space. - context, - &second_desc-> - extra. - region_context); - } + obj_pointer = + second_desc->extra.region_context; } acpi_ut_remove_reference(handler_desc); @@ -247,7 +234,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) if (obj_pointer) { ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", obj_pointer)); - ACPI_FREE(obj_pointer); + ACPI_MEM_FREE(obj_pointer); } /* Now the object can be safely deleted */ @@ -276,7 +263,7 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list) { union acpi_operand_object **internal_obj; - ACPI_FUNCTION_TRACE(ut_delete_internal_object_list); + ACPI_FUNCTION_TRACE("ut_delete_internal_object_list"); /* Walk the null-terminated internal list */ @@ -286,7 +273,7 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list) /* Free the combined parameter pointer list and object array */ - ACPI_FREE(obj_list); + ACPI_MEM_FREE(obj_list); return_VOID; } @@ -309,7 +296,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) u16 count; u16 new_count; - ACPI_FUNCTION_NAME(ut_update_ref_count); + ACPI_FUNCTION_NAME("ut_update_ref_count"); if (!object) { return; @@ -319,9 +306,11 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) new_count = count; /* - * Perform the reference count action (increment, decrement, force delete) + * Perform the reference count action + * (increment, decrement, or force delete) */ switch (action) { + case REF_INCREMENT: new_count++; @@ -358,6 +347,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) if (new_count == 0) { acpi_ut_delete_internal_obj(object); } + break; case REF_FORCE_DELETE: @@ -382,10 +372,13 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) * (A deleted object will have a huge reference count) */ if (count > ACPI_MAX_REFERENCE_COUNT) { + ACPI_WARNING((AE_INFO, - "Large Reference Count (%X) in object %p", count, - object)); + "Large Reference Count (%X) in object %p", + count, object)); } + + return; } /******************************************************************************* @@ -411,7 +404,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) ******************************************************************************/ acpi_status -acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) +acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action) { acpi_status status = AE_OK; union acpi_generic_state *state_list = NULL; @@ -419,10 +412,9 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) union acpi_generic_state *state; acpi_native_uint i; - ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object); + ACPI_FUNCTION_TRACE_PTR("ut_update_object_reference", object); while (object) { - /* Make sure that this isn't a namespace handle */ if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) { @@ -515,11 +507,11 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) case ACPI_TYPE_REGION: default: - break; /* No subobjects for all other types */ + break; /* No subobjects */ } /* - * Now we can update the count in the main object. This can only + * Now we can update the count in the main object. This can only * happen after we update the sub-objects in case this causes the * main object to be deleted. */ @@ -564,7 +556,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) void acpi_ut_add_reference(union acpi_operand_object *object) { - ACPI_FUNCTION_TRACE_PTR(ut_add_reference, object); + ACPI_FUNCTION_TRACE_PTR("ut_add_reference", object); /* Ensure that we have a valid object */ @@ -597,11 +589,11 @@ void acpi_ut_add_reference(union acpi_operand_object *object) void acpi_ut_remove_reference(union acpi_operand_object *object) { - ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); + ACPI_FUNCTION_TRACE_PTR("ut_remove_reference", object); /* - * Allow a NULL pointer to be passed in, just ignore it. This saves - * each caller from having to check. Also, ignore NS nodes. + * Allow a NULL pointer to be passed in, just ignore it. This saves + * each caller from having to check. Also, ignore NS nodes. * */ if (!object || @@ -621,7 +613,7 @@ void acpi_ut_remove_reference(union acpi_operand_object *object) /* * Decrement the reference count, and only actually delete the object - * if the reference count becomes 0. (Must also decrement the ref count + * if the reference count becomes 0. (Must also decrement the ref count * of all subobjects!) */ (void)acpi_ut_update_object_reference(object, REF_DECREMENT); diff --git a/trunk/drivers/acpi/utilities/uteval.c b/trunk/drivers/acpi/utilities/uteval.c index d6d7121583c0..106cc97cb4af 100644 --- a/trunk/drivers/acpi/utilities/uteval.c +++ b/trunk/drivers/acpi/utilities/uteval.c @@ -56,34 +56,6 @@ static acpi_status acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, struct acpi_compatible_id *one_cid); -/* - * Strings supported by the _OSI predefined (internal) method. - */ -static const char *acpi_interfaces_supported[] = { - /* Operating System Vendor Strings */ - - "Linux", - "Windows 2000", - "Windows 2001", - "Windows 2001 SP0", - "Windows 2001 SP1", - "Windows 2001 SP2", - "Windows 2001 SP3", - "Windows 2001 SP4", - "Windows 2001.1", - "Windows 2001.1 SP1", /* Added 03/2006 */ - "Windows 2006", /* Added 03/2006 */ - - /* Feature Group Strings */ - - "Extended Address Space Descriptor" - /* - * All "optional" feature group strings (features that are implemented - * by the host) should be implemented in the host version of - * acpi_os_validate_interface and should not be added here. - */ -}; - /******************************************************************************* * * FUNCTION: acpi_ut_osi_implementation @@ -92,18 +64,18 @@ static const char *acpi_interfaces_supported[] = { * * RETURN: Status * - * DESCRIPTION: Implementation of the _OSI predefined control method + * DESCRIPTION: Implementation of _OSI predefined control method + * Supported = _OSI (String) * ******************************************************************************/ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) { - acpi_status status; union acpi_operand_object *string_desc; union acpi_operand_object *return_desc; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ut_osi_implementation); + ACPI_FUNCTION_TRACE("ut_osi_implementation"); /* Validate the string input argument */ @@ -112,47 +84,28 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) return_ACPI_STATUS(AE_TYPE); } - /* Create a return object */ + /* Create a return object (Default value = 0) */ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } - /* Default return value is SUPPORTED */ - - return_desc->integer.value = ACPI_UINT32_MAX; - walk_state->return_desc = return_desc; - - /* Compare input string to static table of supported interfaces */ + /* Compare input string to table of supported strings */ - for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { - if (!ACPI_STRCMP - (string_desc->string.pointer, - acpi_interfaces_supported[i])) { + for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { + if (!ACPI_STRCMP(string_desc->string.pointer, + ACPI_CAST_PTR(char, + acpi_gbl_valid_osi_strings[i]))) + { + /* This string is supported */ - /* The interface is supported */ - - return_ACPI_STATUS(AE_CTRL_TERMINATE); + return_desc->integer.value = 0xFFFFFFFF; + break; } } - /* - * Did not match the string in the static table, call the host OSL to - * check for a match with one of the optional strings (such as - * "Module Device", "3.0 Thermal Model", etc.) - */ - status = acpi_os_validate_interface(string_desc->string.pointer); - if (ACPI_SUCCESS(status)) { - - /* The interface is supported */ - - return_ACPI_STATUS(AE_CTRL_TERMINATE); - } - - /* The interface is not supported */ - - return_desc->integer.value = 0; + walk_state->return_desc = return_desc; return_ACPI_STATUS(AE_CTRL_TERMINATE); } @@ -181,26 +134,19 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, u32 expected_return_btypes, union acpi_operand_object **return_desc) { - struct acpi_evaluate_info *info; + struct acpi_parameter_info info; acpi_status status; u32 return_btype; - ACPI_FUNCTION_TRACE(ut_evaluate_object); + ACPI_FUNCTION_TRACE("ut_evaluate_object"); - /* Allocate the evaluation information block */ - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - info->prefix_node = prefix_node; - info->pathname = path; - info->parameter_type = ACPI_PARAM_ARGS; + info.node = prefix_node; + info.parameters = NULL; + info.parameter_type = ACPI_PARAM_ARGS; /* Evaluate the object/method */ - status = acpi_ns_evaluate(info); + status = acpi_ns_evaluate_relative(path, &info); if (ACPI_FAILURE(status)) { if (status == AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, @@ -212,25 +158,25 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, prefix_node, path, status); } - goto cleanup; + return_ACPI_STATUS(status); } /* Did we get a return object? */ - if (!info->return_object) { + if (!info.return_object) { if (expected_return_btypes) { ACPI_ERROR_METHOD("No object was returned from", prefix_node, path, AE_NOT_EXIST); - status = AE_NOT_EXIST; + return_ACPI_STATUS(AE_NOT_EXIST); } - goto cleanup; + return_ACPI_STATUS(AE_OK); } /* Map the return object type to the bitmapped type */ - switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { + switch (ACPI_GET_OBJECT_TYPE(info.return_object)) { case ACPI_TYPE_INTEGER: return_btype = ACPI_BTYPE_INTEGER; break; @@ -258,8 +204,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, * happen frequently if the "implicit return" feature is enabled. * Just delete the return object and return AE_OK. */ - acpi_ut_remove_reference(info->return_object); - goto cleanup; + acpi_ut_remove_reference(info.return_object); + return_ACPI_STATUS(AE_OK); } /* Is the return object one of the expected types? */ @@ -271,23 +217,19 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, ACPI_ERROR((AE_INFO, "Type returned from %s was incorrect: %s, expected Btypes: %X", path, - acpi_ut_get_object_type_name(info->return_object), + acpi_ut_get_object_type_name(info.return_object), expected_return_btypes)); /* On error exit, we must delete the return object */ - acpi_ut_remove_reference(info->return_object); - status = AE_TYPE; - goto cleanup; + acpi_ut_remove_reference(info.return_object); + return_ACPI_STATUS(AE_TYPE); } /* Object type is OK, return it */ - *return_desc = info->return_object; - - cleanup: - ACPI_FREE(info); - return_ACPI_STATUS(status); + *return_desc = info.return_object; + return_ACPI_STATUS(AE_OK); } /******************************************************************************* @@ -315,7 +257,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); + ACPI_FUNCTION_TRACE("ut_evaluate_numeric_object"); status = acpi_ut_evaluate_object(device_node, object_name, ACPI_BTYPE_INTEGER, &obj_desc); @@ -391,7 +333,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(ut_execute_HID); + ACPI_FUNCTION_TRACE("ut_execute_HID"); status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, @@ -401,7 +343,6 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, } if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - /* Convert the Numeric HID to string */ acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, @@ -495,7 +436,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, struct acpi_compatible_id_list *cid_list; acpi_native_uint i; - ACPI_FUNCTION_TRACE(ut_execute_CID); + ACPI_FUNCTION_TRACE("ut_execute_CID"); /* Evaluate the _CID method for this device */ @@ -518,7 +459,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, size = (((count - 1) * sizeof(struct acpi_compatible_id)) + sizeof(struct acpi_compatible_id_list)); - cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); + cid_list = ACPI_MEM_CALLOCATE((acpi_size) size); if (!cid_list) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -538,7 +479,6 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, /* The _CID object can be either a single CID or a package (list) of CIDs */ if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { - /* Translate each package element */ for (i = 0; i < count; i++) { @@ -559,7 +499,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, /* Cleanup on error */ if (ACPI_FAILURE(status)) { - ACPI_FREE(cid_list); + ACPI_MEM_FREE(cid_list); } else { *return_cid_list = cid_list; } @@ -593,7 +533,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(ut_execute_UID); + ACPI_FUNCTION_TRACE("ut_execute_UID"); status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, @@ -603,7 +543,6 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, } if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - /* Convert the Numeric UID to string */ acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, @@ -643,7 +582,7 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) union acpi_operand_object *obj_desc; acpi_status status; - ACPI_FUNCTION_TRACE(ut_execute_STA); + ACPI_FUNCTION_TRACE("ut_execute_STA"); status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, ACPI_BTYPE_INTEGER, &obj_desc); @@ -693,7 +632,7 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) acpi_status status; u32 i; - ACPI_FUNCTION_TRACE(ut_execute_sxds); + ACPI_FUNCTION_TRACE("ut_execute_Sxds"); for (i = 0; i < 4; i++) { highest[i] = 0xFF; diff --git a/trunk/drivers/acpi/utilities/utglobal.c b/trunk/drivers/acpi/utilities/utglobal.c index e5999c65c0b8..ffd13383a325 100644 --- a/trunk/drivers/acpi/utilities/utglobal.c +++ b/trunk/drivers/acpi/utilities/utglobal.c @@ -43,6 +43,7 @@ #define DEFINE_ACPI_GLOBALS +#include #include #include @@ -118,7 +119,6 @@ const char *acpi_format_exception(acpi_status status) } if (!exception) { - /* Exception code was not recognized */ ACPI_ERROR((AE_INFO, @@ -143,10 +143,12 @@ const char *acpi_format_exception(acpi_status status) /* Debug switch - level and trace mask */ u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; +EXPORT_SYMBOL(acpi_dbg_level); /* Debug switch - layer (component) mask */ u32 acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; +EXPORT_SYMBOL(acpi_dbg_layer); u32 acpi_gbl_nesting_level = 0; /* Debugger globals */ @@ -181,6 +183,28 @@ const char *acpi_gbl_highest_dstate_names[4] = { "_S4D" }; +/* + * Strings supported by the _OSI predefined (internal) method. + * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS. + */ +const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = { + /* Operating System Vendor Strings */ + + "Linux", + "Windows 2000", + "Windows 2001", + "Windows 2001.1", + "Windows 2001 SP0", + "Windows 2001 SP1", + "Windows 2001 SP2", + "Windows 2001 SP3", + "Windows 2001 SP4", + + /* Feature Group Strings */ + + "Extended Address Space Descriptor" +}; + /******************************************************************************* * * Namespace globals @@ -293,9 +317,9 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) * ******************************************************************************/ -struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; +struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; -struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = { +struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = { /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1, @@ -443,6 +467,7 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = /* Region type decoding */ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { +/*! [Begin] no source code translation (keep these ASL Keywords as-is) */ "SystemMemory", "SystemIO", "PCI_Config", @@ -451,15 +476,16 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { "CMOS", "PCIBARTarget", "DataTable" +/*! [End] no source code translation !*/ }; char *acpi_ut_get_region_name(u8 space_id) { if (space_id >= ACPI_USER_REGION_BEGIN) { - return ("UserDefinedRegion"); + return ("user_defined_region"); } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { - return ("InvalidSpaceId"); + return ("invalid_space_id"); } return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id])); @@ -480,18 +506,20 @@ char *acpi_ut_get_region_name(u8 space_id) /* Event type decoding */ static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = { +/*! [Begin] no source code translation (keep these strings as-is) */ "PM_Timer", "GlobalLock", "PowerButton", "SleepButton", "RealTimeClock", +/*! [End] no source code translation !*/ }; char *acpi_ut_get_event_name(u32 event_id) { if (event_id > ACPI_EVENT_MAX) { - return ("InvalidEventID"); + return ("invalid_event_iD"); } return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id])); @@ -522,6 +550,7 @@ static const char acpi_gbl_bad_type[] = "UNDEFINED"; /* Printable names of the ACPI object types */ static const char *acpi_gbl_ns_type_names[] = { +/*! [Begin] no source code translation (keep these strings as-is) */ /* 00 */ "Untyped", /* 01 */ "Integer", /* 02 */ "String", @@ -553,6 +582,7 @@ static const char *acpi_gbl_ns_type_names[] = { /* 28 */ "Extra", /* 29 */ "Data", /* 30 */ "Invalid" +/*! [End] no source code translation !*/ }; char *acpi_ut_get_type_name(acpi_object_type type) @@ -605,14 +635,14 @@ char *acpi_ut_get_node_name(void *object) /* Descriptor must be a namespace node */ - if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { + if (node->descriptor != ACPI_DESC_TYPE_NAMED) { return ("####"); } /* Name must be a valid ACPI name */ if (!acpi_ut_valid_acpi_name(node->name.integer)) { - node->name.integer = acpi_ut_repair_name(node->name.integer); + return ("????"); } /* Return the name */ @@ -635,6 +665,7 @@ char *acpi_ut_get_node_name(void *object) /* Printable names of object descriptor types */ static const char *acpi_gbl_desc_type_names[] = { +/*! [Begin] no source code translation (keep these ASL Keywords as-is) */ /* 00 */ "Invalid", /* 01 */ "Cached", /* 02 */ "State-Generic", @@ -651,6 +682,7 @@ static const char *acpi_gbl_desc_type_names[] = { /* 13 */ "Parser", /* 14 */ "Operand", /* 15 */ "Node" +/*! [End] no source code translation !*/ }; char *acpi_ut_get_descriptor_name(void *object) @@ -691,7 +723,7 @@ char *acpi_ut_get_descriptor_name(void *object) char *acpi_ut_get_mutex_name(u32 mutex_id) { - if (mutex_id > ACPI_MAX_MUTEX) { + if (mutex_id > MAX_MUTEX) { return ("Invalid Mutex ID"); } @@ -715,7 +747,6 @@ u8 acpi_ut_valid_object_type(acpi_object_type type) { if (type > ACPI_TYPE_LOCAL_MAX) { - /* Note: Assumes all TYPEs are contiguous (external/local) */ return (FALSE); @@ -742,7 +773,7 @@ void acpi_ut_init_globals(void) acpi_status status; u32 i; - ACPI_FUNCTION_TRACE(ut_init_globals); + ACPI_FUNCTION_TRACE("ut_init_globals"); /* Create all memory caches */ @@ -753,14 +784,14 @@ void acpi_ut_init_globals(void) /* ACPI table structure */ - for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { acpi_gbl_table_lists[i].next = NULL; acpi_gbl_table_lists[i].count = 0; } /* Mutex locked flags */ - for (i = 0; i < ACPI_NUM_MUTEX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { acpi_gbl_mutex_info[i].mutex = NULL; acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; acpi_gbl_mutex_info[i].use_count = 0; @@ -825,7 +856,7 @@ void acpi_ut_init_globals(void) acpi_gbl_root_node = NULL; acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; - acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; + acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED; acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; acpi_gbl_root_node_struct.child = NULL; acpi_gbl_root_node_struct.peer = NULL; @@ -838,6 +869,3 @@ void acpi_ut_init_globals(void) return_VOID; } - -ACPI_EXPORT_SYMBOL(acpi_dbg_level) -ACPI_EXPORT_SYMBOL(acpi_dbg_layer) diff --git a/trunk/drivers/acpi/utilities/utinit.c b/trunk/drivers/acpi/utilities/utinit.c index ff76055eb7d6..ba771b4f39bc 100644 --- a/trunk/drivers/acpi/utilities/utinit.c +++ b/trunk/drivers/acpi/utilities/utinit.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utinit") /* Local prototypes */ static void -acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset); +acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset); static void acpi_ut_terminate(void); @@ -69,12 +69,12 @@ static void acpi_ut_terminate(void); ******************************************************************************/ static void -acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) +acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset) { ACPI_WARNING((AE_INFO, "Invalid FADT value %s=%X at offset %X FADT=%p", - register_name, value, offset, acpi_gbl_FADT)); + register_name, value, (u32) offset, acpi_gbl_FADT)); } /****************************************************************************** @@ -176,7 +176,7 @@ static void acpi_ut_terminate(void) struct acpi_gpe_xrupt_info *gpe_xrupt_info; struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; - ACPI_FUNCTION_TRACE(ut_terminate); + ACPI_FUNCTION_TRACE("ut_terminate"); /* Free global tables, etc. */ /* Free global GPE blocks and related info structures */ @@ -186,14 +186,14 @@ static void acpi_ut_terminate(void) gpe_block = gpe_xrupt_info->gpe_block_list_head; while (gpe_block) { next_gpe_block = gpe_block->next; - ACPI_FREE(gpe_block->event_info); - ACPI_FREE(gpe_block->register_info); - ACPI_FREE(gpe_block); + ACPI_MEM_FREE(gpe_block->event_info); + ACPI_MEM_FREE(gpe_block->register_info); + ACPI_MEM_FREE(gpe_block); gpe_block = next_gpe_block; } next_gpe_xrupt_info = gpe_xrupt_info->next; - ACPI_FREE(gpe_xrupt_info); + ACPI_MEM_FREE(gpe_xrupt_info); gpe_xrupt_info = next_gpe_xrupt_info; } @@ -216,7 +216,7 @@ static void acpi_ut_terminate(void) void acpi_ut_subsystem_shutdown(void) { - ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); + ACPI_FUNCTION_TRACE("ut_subsystem_shutdown"); /* Just exit if subsystem is already shutdown */ @@ -228,7 +228,6 @@ void acpi_ut_subsystem_shutdown(void) /* Subsystem appears active, go ahead and shut it down */ acpi_gbl_shutdown = TRUE; - acpi_gbl_startup_flags = 0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); /* Close the acpi_event Handling */ @@ -246,5 +245,12 @@ void acpi_ut_subsystem_shutdown(void) /* Purge the local caches */ (void)acpi_ut_delete_caches(); + + /* Debug only - display leftover memory allocation, if any */ + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); +#endif + return_VOID; } diff --git a/trunk/drivers/acpi/utilities/utmath.c b/trunk/drivers/acpi/utilities/utmath.c index 19d74bedce27..4a3360484e72 100644 --- a/trunk/drivers/acpi/utilities/utmath.c +++ b/trunk/drivers/acpi/utilities/utmath.c @@ -77,7 +77,7 @@ acpi_ut_short_divide(acpi_integer dividend, union uint64_overlay quotient; u32 remainder32; - ACPI_FUNCTION_TRACE(ut_short_divide); + ACPI_FUNCTION_TRACE("ut_short_divide"); /* Always check for a zero divisor */ @@ -139,7 +139,7 @@ acpi_ut_divide(acpi_integer in_dividend, union uint64_overlay partial2; union uint64_overlay partial3; - ACPI_FUNCTION_TRACE(ut_divide); + ACPI_FUNCTION_TRACE("ut_divide"); /* Always check for a zero divisor */ @@ -261,7 +261,7 @@ acpi_ut_short_divide(acpi_integer in_dividend, acpi_integer * out_quotient, u32 * out_remainder) { - ACPI_FUNCTION_TRACE(ut_short_divide); + ACPI_FUNCTION_TRACE("ut_short_divide"); /* Always check for a zero divisor */ @@ -287,7 +287,7 @@ acpi_ut_divide(acpi_integer in_dividend, acpi_integer in_divisor, acpi_integer * out_quotient, acpi_integer * out_remainder) { - ACPI_FUNCTION_TRACE(ut_divide); + ACPI_FUNCTION_TRACE("ut_divide"); /* Always check for a zero divisor */ diff --git a/trunk/drivers/acpi/utilities/utmisc.c b/trunk/drivers/acpi/utilities/utmisc.c index 5c75d35ad1cd..7364f5f8c9cd 100644 --- a/trunk/drivers/acpi/utilities/utmisc.c +++ b/trunk/drivers/acpi/utilities/utmisc.c @@ -47,33 +47,6 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") -/******************************************************************************* - * - * FUNCTION: acpi_ut_is_aml_table - * - * PARAMETERS: Table - An ACPI table - * - * RETURN: TRUE if table contains executable AML; FALSE otherwise - * - * DESCRIPTION: Check ACPI Signature for a table that contains AML code. - * Currently, these are DSDT,SSDT,PSDT. All other table types are - * data tables that do not contain AML code. - * - ******************************************************************************/ -u8 acpi_ut_is_aml_table(struct acpi_table_header *table) -{ - - /* Ignore tables that contain AML */ - - if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || - ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || - ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { - return (TRUE); - } - - return (FALSE); -} - /******************************************************************************* * * FUNCTION: acpi_ut_allocate_owner_id @@ -87,7 +60,6 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table) * when the method exits or the table is unloaded. * ******************************************************************************/ - acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { acpi_native_uint i; @@ -95,7 +67,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) acpi_native_uint k; acpi_status status; - ACPI_FUNCTION_TRACE(ut_allocate_owner_id); + ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); /* Guard against multiple allocations of ID to the same location */ @@ -125,7 +97,6 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) { if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) { - /* There are no free IDs in this mask */ break; @@ -152,7 +123,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j)); ACPI_DEBUG_PRINT((ACPI_DB_VALUES, - "Allocated OwnerId: %2.2X\n", + "Allocated owner_id: %2.2X\n", (unsigned int)*owner_id)); goto exit; } @@ -173,7 +144,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) */ status = AE_OWNER_ID_LIMIT; ACPI_ERROR((AE_INFO, - "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); + "Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT")); exit: (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); @@ -201,7 +172,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) acpi_native_uint index; u32 bit; - ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id); + ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); /* Always clear the input owner_id (zero is an invalid ID) */ @@ -210,7 +181,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) /* Zero is not a valid owner_iD */ if (owner_id == 0) { - ACPI_ERROR((AE_INFO, "Invalid OwnerId: %2.2X", owner_id)); + ACPI_ERROR((AE_INFO, "Invalid owner_id: %2.2X", owner_id)); return_VOID; } @@ -236,7 +207,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) acpi_gbl_owner_id_mask[index] ^= bit; } else { ACPI_ERROR((AE_INFO, - "Release of non-allocated OwnerId: %2.2X", + "Release of non-allocated owner_id: %2.2X", owner_id + 1)); } @@ -302,7 +273,6 @@ void acpi_ut_print_string(char *string, u8 max_length) acpi_os_printf("\""); for (i = 0; string[i] && (i < max_length); i++) { - /* Escape sequences */ switch (string[i]) { @@ -491,45 +461,10 @@ acpi_ut_display_init_pathname(u8 type, } acpi_os_printf("\n"); - ACPI_FREE(buffer.pointer); + ACPI_MEM_FREE(buffer.pointer); } #endif -/******************************************************************************* - * - * FUNCTION: acpi_ut_valid_acpi_char - * - * PARAMETERS: Char - The character to be examined - * - * RETURN: TRUE if the character is valid, FALSE otherwise - * - * DESCRIPTION: Check for a valid ACPI character. Must be one of: - * 1) Upper case alpha - * 2) numeric - * 3) underscore - * - * We allow a '!' as the last character because of the ASF! table - * - ******************************************************************************/ - -u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) -{ - - if (!((character >= 'A' && character <= 'Z') || - (character >= '0' && character <= '9') || (character == '_'))) { - - /* Allow a '!' in the last position */ - - if (character == '!' && position == 3) { - return (TRUE); - } - - return (FALSE); - } - - return (TRUE); -} - /******************************************************************************* * * FUNCTION: acpi_ut_valid_acpi_name @@ -547,13 +482,19 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) u8 acpi_ut_valid_acpi_name(u32 name) { + char *name_ptr = (char *)&name; + char character; acpi_native_uint i; ACPI_FUNCTION_ENTRY(); for (i = 0; i < ACPI_NAME_SIZE; i++) { - if (!acpi_ut_valid_acpi_char - ((ACPI_CAST_PTR(char, &name))[i], i)) { + character = *name_ptr; + name_ptr++; + + if (!((character == '_') || + (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9'))) { return (FALSE); } } @@ -563,37 +504,24 @@ u8 acpi_ut_valid_acpi_name(u32 name) /******************************************************************************* * - * FUNCTION: acpi_ut_repair_name + * FUNCTION: acpi_ut_valid_acpi_character * - * PARAMETERS: Name - The ACPI name to be repaired + * PARAMETERS: Character - The character to be examined * - * RETURN: Repaired version of the name + * RETURN: 1 if Character may appear in a name, else 0 * - * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and - * return the new name. + * DESCRIPTION: Check for a printable character * ******************************************************************************/ -acpi_name acpi_ut_repair_name(acpi_name name) +u8 acpi_ut_valid_acpi_character(char character) { - char *name_ptr = ACPI_CAST_PTR(char, &name); - char new_name[ACPI_NAME_SIZE]; - acpi_native_uint i; - - for (i = 0; i < ACPI_NAME_SIZE; i++) { - new_name[i] = name_ptr[i]; - /* - * Replace a bad character with something printable, yet technically - * still invalid. This prevents any collisions with existing "good" - * names in the namespace. - */ - if (!acpi_ut_valid_acpi_char(name_ptr[i], i)) { - new_name[i] = '*'; - } - } + ACPI_FUNCTION_ENTRY(); - return (*ACPI_CAST_PTR(u32, new_name)); + return ((u8) ((character == '_') || + (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9'))); } /******************************************************************************* @@ -601,8 +529,7 @@ acpi_name acpi_ut_repair_name(acpi_name name) * FUNCTION: acpi_ut_strtoul64 * * PARAMETERS: String - Null terminated string - * Base - Radix of the string: 16 or ACPI_ANY_BASE; - * ACPI_ANY_BASE means 'in behalf of to_integer' + * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE * ret_integer - Where the converted integer is returned * * RETURN: Status and Converted value @@ -618,17 +545,16 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) u32 this_digit = 0; acpi_integer return_value = 0; acpi_integer quotient; - acpi_integer dividend; - u32 to_integer_op = (base == ACPI_ANY_BASE); - u32 mode32 = (acpi_gbl_integer_byte_width == 4); - u8 valid_digits = 0; - u8 sign_of0x = 0; - u8 term = 0; - ACPI_FUNCTION_TRACE(ut_stroul64); + ACPI_FUNCTION_TRACE("ut_stroul64"); + + if ((!string) || !(*string)) { + goto error_exit; + } switch (base) { case ACPI_ANY_BASE: + case 10: case 16: break; @@ -637,110 +563,76 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) return_ACPI_STATUS(AE_BAD_PARAMETER); } - if (!string) { - goto error_exit; - } - /* Skip over any white space in the buffer */ - while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) { + while (ACPI_IS_SPACE(*string) || *string == '\t') { string++; } - if (to_integer_op) { - /* - * Base equal to ACPI_ANY_BASE means 'to_integer operation case'. - * We need to determine if it is decimal or hexadecimal. - */ + /* + * If the input parameter Base is zero, then we need to + * determine if it is decimal or hexadecimal: + */ + if (base == 0) { if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { - sign_of0x = 1; base = 16; - - /* Skip over the leading '0x' */ string += 2; } else { base = 10; } } - /* Any string left? Check that '0x' is not followed by white space. */ - - if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') { - if (to_integer_op) { - goto error_exit; - } else { - goto all_done; - } + /* + * For hexadecimal base, skip over the leading + * 0 or 0x, if they are present. + */ + if ((base == 16) && + (*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { + string += 2; } - dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; + /* Any string left? */ - /* At least one character in the string here */ + if (!(*string)) { + goto error_exit; + } /* Main loop: convert the string to a 64-bit integer */ while (*string) { if (ACPI_IS_DIGIT(*string)) { - /* Convert ASCII 0-9 to Decimal value */ this_digit = ((u8) * string) - '0'; - } else if (base == 10) { + } else { + if (base == 10) { + /* Digit is out of range */ - /* Digit is out of range; possible in to_integer case only */ + goto error_exit; + } - term = 1; - } else { this_digit = (u8) ACPI_TOUPPER(*string); if (ACPI_IS_XDIGIT((char)this_digit)) { - /* Convert ASCII Hex char to value */ this_digit = this_digit - 'A' + 10; } else { - term = 1; - } - } - - if (term) { - if (to_integer_op) { - goto error_exit; - } else { + /* + * We allow non-hex chars, just stop now, same as end-of-string. + * See ACPI spec, string-to-integer conversion. + */ break; } - } else if ((valid_digits == 0) && (this_digit == 0) - && !sign_of0x) { - - /* Skip zeros */ - string++; - continue; - } - - valid_digits++; - - if (sign_of0x - && ((valid_digits > 16) - || ((valid_digits > 8) && mode32))) { - /* - * This is to_integer operation case. - * No any restrictions for string-to-integer conversion, - * see ACPI spec. - */ - goto error_exit; } /* Divide the digit into the correct position */ (void) - acpi_ut_short_divide((dividend - (acpi_integer) this_digit), - base, "ient, NULL); - + acpi_ut_short_divide((ACPI_INTEGER_MAX - + (acpi_integer) this_digit), base, + "ient, NULL); if (return_value > quotient) { - if (to_integer_op) { - goto error_exit; - } else { - break; - } + goto error_exit; } return_value *= base; @@ -750,8 +642,6 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) /* All done, normal exit */ - all_done: - *ret_integer = return_value; return_ACPI_STATUS(AE_OK); @@ -829,7 +719,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, u32 this_index; union acpi_operand_object *this_source_obj; - ACPI_FUNCTION_TRACE(ut_walk_package_tree); + ACPI_FUNCTION_TRACE("ut_walk_package_tree"); state = acpi_ut_create_pkg_state(source_object, target_object, 0); if (!state) { @@ -837,7 +727,6 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, } while (state) { - /* Get one element of the package */ this_index = state->pkg.index; @@ -923,6 +812,31 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, return_ACPI_STATUS(AE_AML_INTERNAL); } +/******************************************************************************* + * + * FUNCTION: acpi_ut_generate_checksum + * + * PARAMETERS: Buffer - Buffer to be scanned + * Length - number of bytes to examine + * + * RETURN: The generated checksum + * + * DESCRIPTION: Generate a checksum on a raw buffer + * + ******************************************************************************/ + +u8 acpi_ut_generate_checksum(u8 * buffer, u32 length) +{ + u32 i; + signed char sum = 0; + + for (i = 0; i < length; i++) { + sum = (signed char)(sum + buffer[i]); + } + + return ((u8) (0 - sum)); +} + /******************************************************************************* * * FUNCTION: acpi_ut_error, acpi_ut_warning, acpi_ut_info @@ -986,3 +900,36 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...) acpi_os_vprintf(format, args); acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); } + +/******************************************************************************* + * + * FUNCTION: acpi_ut_report_error, Warning, Info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * + * RETURN: None + * + * DESCRIPTION: Print error message + * + * Note: Legacy only, should be removed when no longer used by drivers. + * + ******************************************************************************/ + +void acpi_ut_report_error(char *module_name, u32 line_number) +{ + + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); +} + +void acpi_ut_report_warning(char *module_name, u32 line_number) +{ + + acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); +} + +void acpi_ut_report_info(char *module_name, u32 line_number) +{ + + acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number); +} diff --git a/trunk/drivers/acpi/utilities/utmutex.c b/trunk/drivers/acpi/utilities/utmutex.c index 25eb34369afa..45a7244df924 100644 --- a/trunk/drivers/acpi/utilities/utmutex.c +++ b/trunk/drivers/acpi/utilities/utmutex.c @@ -68,26 +68,19 @@ acpi_status acpi_ut_mutex_initialize(void) u32 i; acpi_status status; - ACPI_FUNCTION_TRACE(ut_mutex_initialize); + ACPI_FUNCTION_TRACE("ut_mutex_initialize"); /* * Create each of the predefined mutex objects */ - for (i = 0; i < ACPI_NUM_MUTEX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { status = acpi_ut_create_mutex(i); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } } - /* Create the spinlocks for use at interrupt level */ - status = acpi_os_create_lock(&acpi_gbl_gpe_lock); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = acpi_os_create_lock(&acpi_gbl_hardware_lock); return_ACPI_STATUS(status); } @@ -107,19 +100,16 @@ void acpi_ut_mutex_terminate(void) { u32 i; - ACPI_FUNCTION_TRACE(ut_mutex_terminate); + ACPI_FUNCTION_TRACE("ut_mutex_terminate"); /* * Delete each predefined mutex object */ - for (i = 0; i < ACPI_NUM_MUTEX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { (void)acpi_ut_delete_mutex(i); } - /* Delete the spinlocks */ - acpi_os_delete_lock(acpi_gbl_gpe_lock); - acpi_os_delete_lock(acpi_gbl_hardware_lock); return_VOID; } @@ -139,9 +129,9 @@ static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id); + ACPI_FUNCTION_TRACE_U32("ut_create_mutex", mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -173,9 +163,9 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) { acpi_status status; - ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id); + ACPI_FUNCTION_TRACE_U32("ut_delete_mutex", mutex_id); - if (mutex_id > ACPI_MAX_MUTEX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } @@ -202,11 +192,11 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) { acpi_status status; - acpi_thread_id this_thread_id; + u32 this_thread_id; - ACPI_FUNCTION_NAME(ut_acquire_mutex); + ACPI_FUNCTION_NAME("ut_acquire_mutex"); - if (mutex_id > ACPI_MAX_MUTEX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } @@ -223,7 +213,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { + for (i = mutex_id; i < MAX_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, @@ -285,16 +275,16 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) { acpi_status status; - acpi_thread_id this_thread_id; + u32 this_thread_id; - ACPI_FUNCTION_NAME(ut_release_mutex); + ACPI_FUNCTION_NAME("ut_release_mutex"); this_thread_id = acpi_os_get_thread_id(); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %X releasing Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name(mutex_id))); - if (mutex_id > ACPI_MAX_MUTEX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } @@ -319,7 +309,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { + for (i = mutex_id; i < MAX_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { continue; diff --git a/trunk/drivers/acpi/utilities/utobject.c b/trunk/drivers/acpi/utilities/utobject.c index ba7d8ac702df..7ee2d1d98071 100644 --- a/trunk/drivers/acpi/utilities/utobject.c +++ b/trunk/drivers/acpi/utilities/utobject.c @@ -92,7 +92,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, union acpi_operand_object *object; union acpi_operand_object *second_object; - ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg, + ACPI_FUNCTION_TRACE_STR("ut_create_internal_object_dbg", acpi_ut_get_type_name(type)); /* Allocate the raw object descriptor */ @@ -161,7 +161,7 @@ union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size) union acpi_operand_object *buffer_desc; u8 *buffer = NULL; - ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size); + ACPI_FUNCTION_TRACE_U32("ut_create_buffer_object", buffer_size); /* Create a new Buffer object */ @@ -173,10 +173,9 @@ union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size) /* Create an actual buffer only if size > 0 */ if (buffer_size > 0) { - /* Allocate the actual buffer */ - buffer = ACPI_ALLOCATE_ZEROED(buffer_size); + buffer = ACPI_MEM_CALLOCATE(buffer_size); if (!buffer) { ACPI_ERROR((AE_INFO, "Could not allocate size %X", (u32) buffer_size)); @@ -215,7 +214,7 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) union acpi_operand_object *string_desc; char *string; - ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size); + ACPI_FUNCTION_TRACE_U32("ut_create_string_object", string_size); /* Create a new String object */ @@ -228,7 +227,7 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) * Allocate the actual string buffer -- (Size + 1) for NULL terminator. * NOTE: Zero-length strings are NULL terminated */ - string = ACPI_ALLOCATE_ZEROED(string_size + 1); + string = ACPI_MEM_CALLOCATE(string_size + 1); if (!string) { ACPI_ERROR((AE_INFO, "Could not allocate size %X", (u32) string_size)); @@ -261,7 +260,7 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size) u8 acpi_ut_valid_internal_object(void *object) { - ACPI_FUNCTION_NAME(ut_valid_internal_object); + ACPI_FUNCTION_NAME("ut_valid_internal_object"); /* Check for a null pointer */ @@ -309,7 +308,7 @@ void *acpi_ut_allocate_object_desc_dbg(char *module_name, { union acpi_operand_object *object; - ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg); + ACPI_FUNCTION_TRACE("ut_allocate_object_desc_dbg"); object = acpi_os_acquire_object(acpi_gbl_operand_cache); if (!object) { @@ -320,7 +319,6 @@ void *acpi_ut_allocate_object_desc_dbg(char *module_name, } /* Mark the descriptor type */ - memset(object, 0, sizeof(union acpi_operand_object)); ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND); @@ -344,7 +342,7 @@ void *acpi_ut_allocate_object_desc_dbg(char *module_name, void acpi_ut_delete_object_desc(union acpi_operand_object *object) { - ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object); + ACPI_FUNCTION_TRACE_PTR("ut_delete_object_desc", object); /* Object must be an union acpi_operand_object */ @@ -383,7 +381,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, acpi_size length; acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object); + ACPI_FUNCTION_TRACE_PTR("ut_get_simple_object_size", internal_object); /* * Handle a null object (Could be a uninitialized package @@ -399,7 +397,6 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, length = sizeof(union acpi_object); if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) { - /* Object is a named object (reference), just return the length */ *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length); @@ -562,7 +559,7 @@ acpi_ut_get_package_object_size(union acpi_operand_object *internal_object, acpi_status status; struct acpi_pkg_info info; - ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object); + ACPI_FUNCTION_TRACE_PTR("ut_get_package_object_size", internal_object); info.length = 0; info.object_space = 0; diff --git a/trunk/drivers/acpi/utilities/utresrc.c b/trunk/drivers/acpi/utilities/utresrc.c index 5a2de92831d3..16461317113f 100644 --- a/trunk/drivers/acpi/utilities/utresrc.c +++ b/trunk/drivers/acpi/utilities/utresrc.c @@ -45,113 +45,113 @@ #include #define _COMPONENT ACPI_UTILITIES -ACPI_MODULE_NAME("utresrc") +ACPI_MODULE_NAME("utmisc") #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) /* * Strings used to decode resource descriptors. * Used by both the disasssembler and the debugger resource dump routines */ -const char *acpi_gbl_bm_decode[] = { - "NotBusMaster", - "BusMaster" +const char *acpi_gbl_BMdecode[2] = { + "not_bus_master", + "bus_master" }; -const char *acpi_gbl_config_decode[] = { +const char *acpi_gbl_config_decode[4] = { "0 - Good Configuration", "1 - Acceptable Configuration", "2 - Suboptimal Configuration", "3 - ***Invalid Configuration***", }; -const char *acpi_gbl_consume_decode[] = { - "ResourceProducer", - "ResourceConsumer" +const char *acpi_gbl_consume_decode[2] = { + "resource_producer", + "resource_consumer" }; -const char *acpi_gbl_dec_decode[] = { - "PosDecode", - "SubDecode" +const char *acpi_gbl_DECdecode[2] = { + "pos_decode", + "sub_decode" }; -const char *acpi_gbl_he_decode[] = { +const char *acpi_gbl_HEdecode[2] = { "Level", "Edge" }; -const char *acpi_gbl_io_decode[] = { +const char *acpi_gbl_io_decode[2] = { "Decode10", "Decode16" }; -const char *acpi_gbl_ll_decode[] = { - "ActiveHigh", - "ActiveLow" +const char *acpi_gbl_LLdecode[2] = { + "active_high", + "active_low" }; -const char *acpi_gbl_max_decode[] = { - "MaxNotFixed", - "MaxFixed" +const char *acpi_gbl_max_decode[2] = { + "max_not_fixed", + "max_fixed" }; -const char *acpi_gbl_mem_decode[] = { - "NonCacheable", +const char *acpi_gbl_MEMdecode[4] = { + "non_cacheable", "Cacheable", - "WriteCombining", + "write_combining", "Prefetchable" }; -const char *acpi_gbl_min_decode[] = { - "MinNotFixed", - "MinFixed" +const char *acpi_gbl_min_decode[2] = { + "min_not_fixed", + "min_fixed" }; -const char *acpi_gbl_mtp_decode[] = { - "AddressRangeMemory", - "AddressRangeReserved", - "AddressRangeACPI", - "AddressRangeNVS" +const char *acpi_gbl_MTPdecode[4] = { + "address_range_memory", + "address_range_reserved", + "address_range_aCPI", + "address_range_nVS" }; -const char *acpi_gbl_rng_decode[] = { - "InvalidRanges", - "NonISAOnlyRanges", - "ISAOnlyRanges", - "EntireRange" +const char *acpi_gbl_RNGdecode[4] = { + "invalid_ranges", + "non_iSAonly_ranges", + "ISAonly_ranges", + "entire_range" }; -const char *acpi_gbl_rw_decode[] = { - "ReadOnly", - "ReadWrite" +const char *acpi_gbl_RWdecode[2] = { + "read_only", + "read_write" }; -const char *acpi_gbl_shr_decode[] = { +const char *acpi_gbl_SHRdecode[2] = { "Exclusive", "Shared" }; -const char *acpi_gbl_siz_decode[] = { +const char *acpi_gbl_SIZdecode[4] = { "Transfer8", "Transfer8_16", "Transfer16", - "InvalidSize" + "invalid_size" }; -const char *acpi_gbl_trs_decode[] = { - "DenseTranslation", - "SparseTranslation" +const char *acpi_gbl_TRSdecode[2] = { + "dense_translation", + "sparse_translation" }; -const char *acpi_gbl_ttp_decode[] = { - "TypeStatic", - "TypeTranslation" +const char *acpi_gbl_TTPdecode[2] = { + "type_static", + "type_translation" }; -const char *acpi_gbl_typ_decode[] = { +const char *acpi_gbl_TYPdecode[4] = { "Compatibility", - "TypeA", - "TypeB", - "TypeF" + "type_a", + "type_b", + "type_f" }; #endif @@ -238,104 +238,6 @@ static const u8 acpi_gbl_resource_types[] = { ACPI_FIXED_LENGTH }; -/******************************************************************************* - * - * FUNCTION: acpi_ut_walk_aml_resources - * - * PARAMETERS: Aml - Pointer to the raw AML resource template - * aml_length - Length of the entire template - * user_function - Called once for each descriptor found. If - * NULL, a pointer to the end_tag is returned - * Context - Passed to user_function - * - * RETURN: Status - * - * DESCRIPTION: Walk a raw AML resource list(buffer). User function called - * once for each resource found. - * - ******************************************************************************/ - -acpi_status -acpi_ut_walk_aml_resources(u8 * aml, - acpi_size aml_length, - acpi_walk_aml_callback user_function, void **context) -{ - acpi_status status; - u8 *end_aml; - u8 resource_index; - u32 length; - u32 offset = 0; - - ACPI_FUNCTION_TRACE(ut_walk_aml_resources); - - /* The absolute minimum resource template is one end_tag descriptor */ - - if (aml_length < sizeof(struct aml_resource_end_tag)) { - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); - } - - /* Point to the end of the resource template buffer */ - - end_aml = aml + aml_length; - - /* Walk the byte list, abort on any invalid descriptor type or length */ - - while (aml < end_aml) { - - /* Validate the Resource Type and Resource Length */ - - status = acpi_ut_validate_resource(aml, &resource_index); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Get the length of this descriptor */ - - length = acpi_ut_get_descriptor_length(aml); - - /* Invoke the user function */ - - if (user_function) { - status = - user_function(aml, length, offset, resource_index, - context); - if (ACPI_FAILURE(status)) { - return (status); - } - } - - /* An end_tag descriptor terminates this resource template */ - - if (acpi_ut_get_resource_type(aml) == - ACPI_RESOURCE_NAME_END_TAG) { - /* - * There must be at least one more byte in the buffer for - * the 2nd byte of the end_tag - */ - if ((aml + 1) >= end_aml) { - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); - } - - /* Return the pointer to the end_tag if requested */ - - if (!user_function) { - *context = aml; - } - - /* Normal exit */ - - return_ACPI_STATUS(AE_OK); - } - - aml += length; - offset += length; - } - - /* Did not find an end_tag descriptor */ - - return (AE_AML_NO_RESOURCE_END_TAG); -} - /******************************************************************************* * * FUNCTION: acpi_ut_validate_resource @@ -371,7 +273,6 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) * Examine the large/small bit in the resource header */ if (resource_type & ACPI_RESOURCE_NAME_LARGE) { - /* Verify the large resource type (name) against the max */ if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { @@ -475,7 +376,6 @@ u8 acpi_ut_get_resource_type(void *aml) * Examine the large/small bit in the resource header */ if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource Type -- bits 6:0 contain the name */ return (ACPI_GET8(aml)); @@ -511,7 +411,6 @@ u16 acpi_ut_get_resource_length(void *aml) * Examine the large/small bit in the resource header */ if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { - /* Large Resource type -- bytes 1-2 contain the 16-bit length */ ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1)); @@ -596,21 +495,60 @@ acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, u8 ** end_tag) { acpi_status status; + u8 *aml; + u8 *end_aml; + + ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); - ACPI_FUNCTION_TRACE(ut_get_resource_end_tag); + /* Get start and end pointers */ + + aml = obj_desc->buffer.pointer; + end_aml = aml + obj_desc->buffer.length; /* Allow a buffer length of zero */ if (!obj_desc->buffer.length) { - *end_tag = obj_desc->buffer.pointer; + *end_tag = aml; return_ACPI_STATUS(AE_OK); } - /* Validate the template and get a pointer to the end_tag */ + /* Walk the resource template, one descriptor per iteration */ + + while (aml < end_aml) { + /* Validate the Resource Type and Resource Length */ + + status = acpi_ut_validate_resource(aml, NULL); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* end_tag resource indicates the end of the resource template */ + + if (acpi_ut_get_resource_type(aml) == + ACPI_RESOURCE_NAME_END_TAG) { + /* + * There must be at least one more byte in the buffer for + * the 2nd byte of the end_tag + */ + if ((aml + 1) >= end_aml) { + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); + } + + /* Return the pointer to the end_tag */ + + *end_tag = aml; + return_ACPI_STATUS(AE_OK); + } + + /* + * Point to the next resource descriptor in the AML buffer. The + * descriptor length is guaranteed to be non-zero by resource + * validation above. + */ + aml += acpi_ut_get_descriptor_length(aml); + } - status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer, - obj_desc->buffer.length, NULL, - (void **)end_tag); + /* Did not find an end_tag resource descriptor */ - return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); } diff --git a/trunk/drivers/acpi/utilities/utstate.c b/trunk/drivers/acpi/utilities/utstate.c index 0f5c5bb5deff..4b134a722907 100644 --- a/trunk/drivers/acpi/utilities/utstate.c +++ b/trunk/drivers/acpi/utilities/utstate.c @@ -96,7 +96,7 @@ void acpi_ut_push_generic_state(union acpi_generic_state **list_head, union acpi_generic_state *state) { - ACPI_FUNCTION_TRACE(ut_push_generic_state); + ACPI_FUNCTION_TRACE("ut_push_generic_state"); /* Push the state object onto the front of the list (stack) */ @@ -123,13 +123,12 @@ union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE(ut_pop_generic_state); + ACPI_FUNCTION_TRACE("ut_pop_generic_state"); /* Remove the state object at the head of the list (stack) */ state = *list_head; if (state) { - /* Update the list head */ *list_head = state->common.next; @@ -159,10 +158,9 @@ union acpi_generic_state *acpi_ut_create_generic_state(void) state = acpi_os_acquire_object(acpi_gbl_state_cache); if (state) { - /* Initialize */ memset(state, 0, sizeof(union acpi_generic_state)); - state->common.descriptor_type = ACPI_DESC_TYPE_STATE; + state->common.data_type = ACPI_DESC_TYPE_STATE; } return (state); @@ -185,7 +183,7 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void) { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE(ut_create_thread_state); + ACPI_FUNCTION_TRACE("ut_create_thread_state"); /* Create the generic state object */ @@ -196,7 +194,7 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void) /* Init fields specific to the update struct */ - state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD; + state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; state->thread.thread_id = acpi_os_get_thread_id(); return_PTR((struct acpi_thread_state *)state); @@ -222,7 +220,7 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE_PTR(ut_create_update_state, object); + ACPI_FUNCTION_TRACE_PTR("ut_create_update_state", object); /* Create the generic state object */ @@ -233,7 +231,7 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object /* Init fields specific to the update struct */ - state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE; + state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; state->update.object = object; state->update.value = action; @@ -259,7 +257,7 @@ union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE_PTR(ut_create_pkg_state, internal_object); + ACPI_FUNCTION_TRACE_PTR("ut_create_pkg_state", internal_object); /* Create the generic state object */ @@ -270,7 +268,7 @@ union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object, /* Init fields specific to the update struct */ - state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE; + state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; state->pkg.source_object = (union acpi_operand_object *)internal_object; state->pkg.dest_object = external_object; state->pkg.index = index; @@ -296,7 +294,7 @@ union acpi_generic_state *acpi_ut_create_control_state(void) { union acpi_generic_state *state; - ACPI_FUNCTION_TRACE(ut_create_control_state); + ACPI_FUNCTION_TRACE("ut_create_control_state"); /* Create the generic state object */ @@ -307,7 +305,7 @@ union acpi_generic_state *acpi_ut_create_control_state(void) /* Init fields specific to the control struct */ - state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL; + state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; return_PTR(state); @@ -321,19 +319,15 @@ union acpi_generic_state *acpi_ut_create_control_state(void) * * RETURN: None * - * DESCRIPTION: Release a state object to the state cache. NULL state objects - * are ignored. + * DESCRIPTION: Put a state object back into the global state cache. The object + * is not actually freed at this time. * ******************************************************************************/ void acpi_ut_delete_generic_state(union acpi_generic_state *state) { - ACPI_FUNCTION_TRACE(ut_delete_generic_state); - - /* Ignore null state */ + ACPI_FUNCTION_TRACE("ut_delete_generic_state"); - if (state) { - (void)acpi_os_release_object(acpi_gbl_state_cache, state); - } + (void)acpi_os_release_object(acpi_gbl_state_cache, state); return_VOID; } diff --git a/trunk/drivers/acpi/utilities/utxface.c b/trunk/drivers/acpi/utilities/utxface.c index 3538f69c82a1..308a960871be 100644 --- a/trunk/drivers/acpi/utilities/utxface.c +++ b/trunk/drivers/acpi/utilities/utxface.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#include + #include #include #include @@ -65,7 +67,7 @@ acpi_status acpi_initialize_subsystem(void) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); + ACPI_FUNCTION_TRACE("acpi_initialize_subsystem"); ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); @@ -107,8 +109,6 @@ acpi_status acpi_initialize_subsystem(void) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) - /******************************************************************************* * * FUNCTION: acpi_enable_subsystem @@ -121,11 +121,12 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) * Puts system into ACPI mode if it isn't already. * ******************************************************************************/ + acpi_status acpi_enable_subsystem(u32 flags) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_enable_subsystem); + ACPI_FUNCTION_TRACE("acpi_enable_subsystem"); /* * We must initialize the hardware before we can enable ACPI. @@ -151,7 +152,7 @@ acpi_status acpi_enable_subsystem(u32 flags) status = acpi_enable(); if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "AcpiEnable failed")); + ACPI_WARNING((AE_INFO, "acpi_enable failed")); return_ACPI_STATUS(status); } } @@ -228,8 +229,6 @@ acpi_status acpi_enable_subsystem(u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) - /******************************************************************************* * * FUNCTION: acpi_initialize_objects @@ -242,11 +241,12 @@ ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) * objects and executing AML code for Regions, buffers, etc. * ******************************************************************************/ + acpi_status acpi_initialize_objects(u32 flags) { acpi_status status = AE_OK; - ACPI_FUNCTION_TRACE(acpi_initialize_objects); + ACPI_FUNCTION_TRACE("acpi_initialize_objects"); /* * Run all _REG methods @@ -257,7 +257,7 @@ acpi_status acpi_initialize_objects(u32 flags) */ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "[Init] Executing _REG OpRegion methods\n")); + "[Init] Executing _REG op_region methods\n")); status = acpi_ev_initialize_op_regions(); if (ACPI_FAILURE(status)) { @@ -305,8 +305,6 @@ acpi_status acpi_initialize_objects(u32 flags) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_initialize_objects) - /******************************************************************************* * * FUNCTION: acpi_terminate @@ -318,11 +316,12 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_objects) * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. * ******************************************************************************/ + acpi_status acpi_terminate(void) { acpi_status status; - ACPI_FUNCTION_TRACE(acpi_terminate); + ACPI_FUNCTION_TRACE("acpi_terminate"); /* Terminate the AML Debugger if present */ @@ -349,8 +348,6 @@ acpi_status acpi_terminate(void) return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_terminate) - #ifdef ACPI_FUTURE_USAGE /******************************************************************************* * @@ -365,6 +362,7 @@ ACPI_EXPORT_SYMBOL(acpi_terminate) * initialized successfully. * ******************************************************************************/ + acpi_status acpi_subsystem_status(void) { @@ -375,8 +373,6 @@ acpi_status acpi_subsystem_status(void) } } -ACPI_EXPORT_SYMBOL(acpi_subsystem_status) - /******************************************************************************* * * FUNCTION: acpi_get_system_info @@ -394,13 +390,14 @@ ACPI_EXPORT_SYMBOL(acpi_subsystem_status) * and the value of out_buffer is undefined. * ******************************************************************************/ + acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) { struct acpi_system_info *info_ptr; acpi_status status; u32 i; - ACPI_FUNCTION_TRACE(acpi_get_system_info); + ACPI_FUNCTION_TRACE("acpi_get_system_info"); /* Parameter validation */ @@ -451,15 +448,15 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) /* Current status of the ACPI tables, per table type */ - info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1; - for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { + info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES; + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; } return_ACPI_STATUS(AE_OK); } -ACPI_EXPORT_SYMBOL(acpi_get_system_info) +EXPORT_SYMBOL(acpi_get_system_info); /***************************************************************************** * @@ -475,6 +472,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_system_info) * TBD: When a second function is added, must save the Function also. * ****************************************************************************/ + acpi_status acpi_install_initialization_handler(acpi_init_handler handler, u32 function) { @@ -491,7 +489,6 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) return AE_OK; } -ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) #endif /* ACPI_FUTURE_USAGE */ /***************************************************************************** @@ -505,9 +502,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) * DESCRIPTION: Empty all caches (delete the cached objects) * ****************************************************************************/ + acpi_status acpi_purge_cached_objects(void) { - ACPI_FUNCTION_TRACE(acpi_purge_cached_objects); + ACPI_FUNCTION_TRACE("acpi_purge_cached_objects"); (void)acpi_os_purge_cache(acpi_gbl_state_cache); (void)acpi_os_purge_cache(acpi_gbl_operand_cache); @@ -515,5 +513,3 @@ acpi_status acpi_purge_cached_objects(void) (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache); return_ACPI_STATUS(AE_OK); } - -ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) diff --git a/trunk/drivers/acpi/utils.c b/trunk/drivers/acpi/utils.c index 6b516852ac12..6458c47f7ac2 100644 --- a/trunk/drivers/acpi/utils.c +++ b/trunk/drivers/acpi/utils.c @@ -273,13 +273,11 @@ acpi_evaluate_integer(acpi_handle handle, status = acpi_evaluate_object(handle, pathname, arguments, &buffer); if (ACPI_FAILURE(status)) { acpi_util_eval_error(handle, pathname, status); - kfree(element); return_ACPI_STATUS(status); } if (element->type != ACPI_TYPE_INTEGER) { acpi_util_eval_error(handle, pathname, AE_BAD_DATA); - kfree(element); return_ACPI_STATUS(AE_BAD_DATA); } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index e7e9a693953a..bd4887518373 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -323,7 +323,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, if (!ACPI_SUCCESS(status)) return_VALUE(status); obj = (union acpi_object *)buffer.pointer; - if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { + if (!obj && (obj->type != ACPI_TYPE_PACKAGE)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _BCL data\n")); status = -EFAULT; goto err; @@ -1294,7 +1294,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, struct acpi_video_bus *video) { unsigned long device_id; - int status; + int status, result; struct acpi_video_device *data; ACPI_FUNCTION_TRACE("acpi_video_bus_get_one_device"); @@ -1346,11 +1346,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n")); - if(data->brightness) - kfree(data->brightness->levels); - kfree(data->brightness); - kfree(data); - return -ENODEV; + result = -ENODEV; + goto end; } down(&video->sem); @@ -1362,6 +1359,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, return_VALUE(0); } + end: return_VALUE(-ENOENT); } @@ -1645,9 +1643,8 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video) printk(KERN_WARNING PREFIX "hhuuhhuu bug in acpi video driver.\n"); - if (data->brightness) - kfree(data->brightness->levels); kfree(data->brightness); + kfree(data); } @@ -1788,10 +1785,6 @@ static int acpi_video_bus_add(struct acpi_device *device) if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n")); - acpi_video_bus_stop_devices(video); - acpi_video_bus_put_devices(video); - kfree(video->attached_array); - acpi_video_bus_remove_fs(device); result = -ENODEV; goto end; } @@ -1803,8 +1796,10 @@ static int acpi_video_bus_add(struct acpi_device *device) video->flags.post ? "yes" : "no"); end: - if (result) + if (result) { + acpi_video_bus_remove_fs(device); kfree(video); + } return_VALUE(result); } diff --git a/trunk/drivers/atm/firestream.c b/trunk/drivers/atm/firestream.c index 1bca86edf570..7f7ec288824d 100644 --- a/trunk/drivers/atm/firestream.c +++ b/trunk/drivers/atm/firestream.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -755,7 +754,7 @@ static void process_txdone_queue (struct fs_dev *dev, struct queue *q) fs_kfree_skb (skb); fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td); - memset (td, ATM_POISON_FREE, sizeof(struct FS_BPENTRY)); + memset (td, 0x12, sizeof (struct FS_BPENTRY)); kfree (td); break; default: @@ -952,7 +951,7 @@ static int fs_open(struct atm_vcc *atm_vcc) it most likely that the chip will notice it. It also prevents us from having to wait for completion. On the other hand, we may need to wait for completion anyway, to see if it completed - successfully. */ + succesfully. */ switch (atm_vcc->qos.aal) { case ATM_AAL2: diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig index 80502dc6ed66..f0eff3dac58d 100644 --- a/trunk/drivers/base/Kconfig +++ b/trunk/drivers/base/Kconfig @@ -38,7 +38,3 @@ config DEBUG_DRIVER If you are unsure about this, say N here. endmenu - -config SYS_HYPERVISOR - bool - default n diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index b539e5e75b56..e99471d3232b 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -5,12 +5,10 @@ obj-y := core.o sys.o bus.o dd.o \ cpu.o firmware.o init.o map.o dmapool.o \ attribute_container.o transport_class.o obj-y += power/ -obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o obj-$(CONFIG_SMP) += topology.o -obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o ifeq ($(CONFIG_DEBUG_DRIVER),y) EXTRA_CFLAGS += -DDEBUG diff --git a/trunk/drivers/base/attribute_container.c b/trunk/drivers/base/attribute_container.c index 22220733f76f..2a7d7ae83e1e 100644 --- a/trunk/drivers/base/attribute_container.c +++ b/trunk/drivers/base/attribute_container.c @@ -236,6 +236,7 @@ attribute_container_remove_device(struct device *dev, } up(&attribute_container_mutex); } +EXPORT_SYMBOL_GPL(attribute_container_remove_device); /** * attribute_container_device_trigger - execute a trigger for each matching classdev @@ -275,6 +276,7 @@ attribute_container_device_trigger(struct device *dev, } up(&attribute_container_mutex); } +EXPORT_SYMBOL_GPL(attribute_container_device_trigger); /** * attribute_container_trigger - trigger a function for each matching container @@ -302,6 +304,7 @@ attribute_container_trigger(struct device *dev, } up(&attribute_container_mutex); } +EXPORT_SYMBOL_GPL(attribute_container_trigger); /** * attribute_container_add_attrs - add attributes @@ -330,6 +333,7 @@ attribute_container_add_attrs(struct class_device *classdev) return 0; } +EXPORT_SYMBOL_GPL(attribute_container_add_attrs); /** * attribute_container_add_class_device - same function as class_device_add @@ -348,6 +352,7 @@ attribute_container_add_class_device(struct class_device *classdev) return error; return attribute_container_add_attrs(classdev); } +EXPORT_SYMBOL_GPL(attribute_container_add_class_device); /** * attribute_container_add_class_device_adapter - simple adapter for triggers @@ -362,6 +367,7 @@ attribute_container_add_class_device_adapter(struct attribute_container *cont, { return attribute_container_add_class_device(classdev); } +EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter); /** * attribute_container_remove_attrs - remove any attribute files @@ -383,6 +389,7 @@ attribute_container_remove_attrs(struct class_device *classdev) for (i = 0; attrs[i]; i++) class_device_remove_file(classdev, attrs[i]); } +EXPORT_SYMBOL_GPL(attribute_container_remove_attrs); /** * attribute_container_class_device_del - equivalent of class_device_del @@ -398,6 +405,7 @@ attribute_container_class_device_del(struct class_device *classdev) attribute_container_remove_attrs(classdev); class_device_del(classdev); } +EXPORT_SYMBOL_GPL(attribute_container_class_device_del); /** * attribute_container_find_class_device - find the corresponding class_device diff --git a/trunk/drivers/base/base.h b/trunk/drivers/base/base.h index c3b8dc98b8a7..5735b38582d0 100644 --- a/trunk/drivers/base/base.h +++ b/trunk/drivers/base/base.h @@ -5,21 +5,13 @@ extern int devices_init(void); extern int buses_init(void); extern int classes_init(void); extern int firmware_init(void); -#ifdef CONFIG_SYS_HYPERVISOR -extern int hypervisor_init(void); -#else -static inline int hypervisor_init(void) { return 0; } -#endif extern int platform_bus_init(void); extern int system_bus_init(void); extern int cpu_dev_init(void); extern int attribute_container_init(void); extern int bus_add_device(struct device * dev); -extern void bus_attach_device(struct device * dev); extern void bus_remove_device(struct device * dev); -extern struct bus_type *get_bus(struct bus_type * bus); -extern void put_bus(struct bus_type * bus); extern int bus_add_driver(struct device_driver *); extern void bus_remove_driver(struct device_driver *); @@ -42,5 +34,4 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) return container_of(_attr, struct class_device_attribute, attr); } -extern char *make_class_name(const char *name, struct kobject *kobj); diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 050d86d0b872..76656acd00d4 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -362,7 +362,8 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) * @dev: device being added * * - Add the device to its bus's list of devices. - * - Create link to device's bus. + * - Try to attach to driver. + * - Create link to device's physical location. */ int bus_add_device(struct device * dev) { @@ -371,32 +372,17 @@ int bus_add_device(struct device * dev) if (bus) { pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); + device_attach(dev); + klist_add_tail(&dev->knode_bus, &bus->klist_devices); error = device_add_attrs(bus, dev); if (!error) { sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); - sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); } } return error; } -/** - * bus_attach_device - add device to bus - * @dev: device tried to attach to a driver - * - * - Try to attach to driver. - */ -void bus_attach_device(struct device * dev) -{ - struct bus_type * bus = dev->bus; - - if (bus) { - device_attach(dev); - klist_add_tail(&dev->knode_bus, &bus->klist_devices); - } -} - /** * bus_remove_device - remove device from bus * @dev: device to be removed @@ -409,7 +395,6 @@ void bus_attach_device(struct device * dev) void bus_remove_device(struct device * dev) { if (dev->bus) { - sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); @@ -747,9 +732,14 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev); EXPORT_SYMBOL_GPL(bus_find_device); EXPORT_SYMBOL_GPL(bus_for_each_drv); +EXPORT_SYMBOL_GPL(bus_add_device); +EXPORT_SYMBOL_GPL(bus_remove_device); EXPORT_SYMBOL_GPL(bus_register); EXPORT_SYMBOL_GPL(bus_unregister); EXPORT_SYMBOL_GPL(bus_rescan_devices); +EXPORT_SYMBOL_GPL(get_bus); +EXPORT_SYMBOL_GPL(put_bus); +EXPORT_SYMBOL_GPL(find_bus); EXPORT_SYMBOL_GPL(bus_create_file); EXPORT_SYMBOL_GPL(bus_remove_file); diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index 9aa127460262..b1ea4df85c7d 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -91,14 +91,14 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr) sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); } -static struct class *class_get(struct class *cls) +struct class * class_get(struct class * cls) { if (cls) return container_of(subsys_get(&cls->subsys), struct class, subsys); return NULL; } -static void class_put(struct class * cls) +void class_put(struct class * cls) { if (cls) subsys_put(&cls->subsys); @@ -142,7 +142,6 @@ int class_register(struct class * cls) pr_debug("device class '%s': registering\n", cls->name); INIT_LIST_HEAD(&cls->children); - INIT_LIST_HEAD(&cls->devices); INIT_LIST_HEAD(&cls->interfaces); init_MUTEX(&cls->sem); error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); @@ -505,21 +504,22 @@ void class_device_initialize(struct class_device *class_dev) INIT_LIST_HEAD(&class_dev->node); } -char *make_class_name(const char *name, struct kobject *kobj) +static char *make_class_name(struct class_device *class_dev) { - char *class_name; + char *name; int size; - size = strlen(name) + strlen(kobject_name(kobj)) + 2; + size = strlen(class_dev->class->name) + + strlen(kobject_name(&class_dev->kobj)) + 2; - class_name = kmalloc(size, GFP_KERNEL); - if (!class_name) + name = kmalloc(size, GFP_KERNEL); + if (!name) return ERR_PTR(-ENOMEM); - strcpy(class_name, name); - strcat(class_name, ":"); - strcat(class_name, kobject_name(kobj)); - return class_name; + strcpy(name, class_dev->class->name); + strcat(name, ":"); + strcat(name, kobject_name(&class_dev->kobj)); + return name; } int class_device_add(struct class_device *class_dev) @@ -535,22 +535,18 @@ int class_device_add(struct class_device *class_dev) return -EINVAL; if (!strlen(class_dev->class_id)) - goto out1; + goto register_done; parent_class = class_get(class_dev->class); if (!parent_class) - goto out1; - + goto register_done; parent_class_dev = class_device_get(class_dev->parent); pr_debug("CLASS: registering class device: ID = '%s'\n", class_dev->class_id); /* first, register with generic layer. */ - error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); - if (error) - goto out2; - + kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); if (parent_class_dev) class_dev->kobj.parent = &parent_class_dev->kobj; else @@ -558,58 +554,41 @@ int class_device_add(struct class_device *class_dev) error = kobject_add(&class_dev->kobj); if (error) - goto out2; + goto register_done; /* add the needed attributes to this device */ - sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); class_dev->uevent_attr.attr.name = "uevent"; class_dev->uevent_attr.attr.mode = S_IWUSR; class_dev->uevent_attr.attr.owner = parent_class->owner; class_dev->uevent_attr.store = store_uevent; - error = class_device_create_file(class_dev, &class_dev->uevent_attr); - if (error) - goto out3; + class_device_create_file(class_dev, &class_dev->uevent_attr); if (MAJOR(class_dev->devt)) { struct class_device_attribute *attr; attr = kzalloc(sizeof(*attr), GFP_KERNEL); if (!attr) { error = -ENOMEM; - goto out4; + kobject_del(&class_dev->kobj); + goto register_done; } attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; attr->attr.owner = parent_class->owner; attr->show = show_dev; - error = class_device_create_file(class_dev, attr); - if (error) { - kfree(attr); - goto out4; - } - + class_device_create_file(class_dev, attr); class_dev->devt_attr = attr; } - error = class_device_add_attrs(class_dev); - if (error) - goto out5; - + class_device_add_attrs(class_dev); if (class_dev->dev) { - class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); - error = sysfs_create_link(&class_dev->kobj, - &class_dev->dev->kobj, "device"); - if (error) - goto out6; - error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, - class_name); - if (error) - goto out7; + class_name = make_class_name(class_dev); + sysfs_create_link(&class_dev->kobj, + &class_dev->dev->kobj, "device"); + sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, + class_name); } - error = class_device_add_groups(class_dev); - if (error) - goto out8; + class_device_add_groups(class_dev); kobject_uevent(&class_dev->kobj, KOBJ_ADD); @@ -622,28 +601,11 @@ int class_device_add(struct class_device *class_dev) } up(&parent_class->sem); - goto out1; - - out8: - if (class_dev->dev) - sysfs_remove_link(&class_dev->kobj, class_name); - out7: - if (class_dev->dev) - sysfs_remove_link(&class_dev->kobj, "device"); - out6: - class_device_remove_attrs(class_dev); - out5: - if (class_dev->devt_attr) - class_device_remove_file(class_dev, class_dev->devt_attr); - out4: - class_device_remove_file(class_dev, &class_dev->uevent_attr); - out3: - kobject_del(&class_dev->kobj); - out2: - if(parent_class_dev) + register_done: + if (error) { + class_put(parent_class); class_device_put(parent_class_dev); - class_put(parent_class); - out1: + } class_device_put(class_dev); kfree(class_name); return error; @@ -733,12 +695,10 @@ void class_device_del(struct class_device *class_dev) } if (class_dev->dev) { - class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); + class_name = make_class_name(class_dev); sysfs_remove_link(&class_dev->kobj, "device"); sysfs_remove_link(&class_dev->dev->kobj, class_name); } - sysfs_remove_link(&class_dev->kobj, "subsystem"); class_device_remove_file(class_dev, &class_dev->uevent_attr); if (class_dev->devt_attr) class_device_remove_file(class_dev, class_dev->devt_attr); @@ -800,16 +760,14 @@ int class_device_rename(struct class_device *class_dev, char *new_name) new_name); if (class_dev->dev) - old_class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); + old_class_name = make_class_name(class_dev); strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); error = kobject_rename(&class_dev->kobj, new_name); if (class_dev->dev) { - new_class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); + new_class_name = make_class_name(class_dev); sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, new_class_name); sysfs_remove_link(&class_dev->dev->kobj, old_class_name); @@ -900,6 +858,8 @@ EXPORT_SYMBOL_GPL(class_create_file); EXPORT_SYMBOL_GPL(class_remove_file); EXPORT_SYMBOL_GPL(class_register); EXPORT_SYMBOL_GPL(class_unregister); +EXPORT_SYMBOL_GPL(class_get); +EXPORT_SYMBOL_GPL(class_put); EXPORT_SYMBOL_GPL(class_create); EXPORT_SYMBOL_GPL(class_destroy); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 27c2176895de..6b355bd7816d 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -29,22 +28,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL; * sysfs bindings for devices. */ -/** - * dev_driver_string - Return a device's driver name, if at all possible - * @dev: struct device to get the name of - * - * Will return the device's driver's name if it is bound to a device. If - * the device is not bound to a device, it will return the name of the bus - * it is attached to. If it is not attached to a bus either, an empty - * string will be returned. - */ -const char *dev_driver_string(struct device *dev) -{ - return dev->driver ? dev->driver->name : - (dev->bus ? dev->bus->name : ""); -} -EXPORT_SYMBOL_GPL(dev_driver_string); - #define to_dev(obj) container_of(obj, struct device, kobj) #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) @@ -115,8 +98,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) struct device *dev = to_dev(kobj); if (dev->bus) return 1; - if (dev->class) - return 1; } return 0; } @@ -125,11 +106,7 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) { struct device *dev = to_dev(kobj); - if (dev->bus) - return dev->bus->name; - if (dev->class) - return dev->class->name; - return NULL; + return dev->bus->name; } static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, @@ -140,16 +117,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, int length = 0; int retval = 0; - /* add the major/minor if present */ - if (MAJOR(dev->devt)) { - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MAJOR=%u", MAJOR(dev->devt)); - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MINOR=%u", MINOR(dev->devt)); - } - /* add bus name of physical device */ if (dev->bus) add_uevent_var(envp, num_envp, &i, @@ -194,12 +161,6 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t show_dev(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return print_dev_t(buf, dev->devt); -} - /* * devices_subsys - structure to be registered with kobject core. */ @@ -270,7 +231,6 @@ void device_initialize(struct device *dev) klist_init(&dev->klist_children, klist_children_get, klist_children_put); INIT_LIST_HEAD(&dev->dma_pools); - INIT_LIST_HEAD(&dev->node); init_MUTEX(&dev->sem); device_init_wakeup(dev, 0); } @@ -289,7 +249,6 @@ void device_initialize(struct device *dev) int device_add(struct device *dev) { struct device *parent = NULL; - char *class_name = NULL; int error = -EINVAL; dev = get_device(dev); @@ -315,69 +274,23 @@ int device_add(struct device *dev) dev->uevent_attr.store = store_uevent; device_create_file(dev, &dev->uevent_attr); - if (MAJOR(dev->devt)) { - struct device_attribute *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); - if (!attr) { - error = -ENOMEM; - goto PMError; - } - attr->attr.name = "dev"; - attr->attr.mode = S_IRUGO; - if (dev->driver) - attr->attr.owner = dev->driver->owner; - attr->show = show_dev; - error = device_create_file(dev, attr); - if (error) { - kfree(attr); - goto attrError; - } - - dev->devt_attr = attr; - } - - if (dev->class) { - sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, - "subsystem"); - sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, - dev->bus_id); - - sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); - class_name = make_class_name(dev->class->name, &dev->kobj); - sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); - } - + kobject_uevent(&dev->kobj, KOBJ_ADD); if ((error = device_pm_add(dev))) goto PMError; if ((error = bus_add_device(dev))) goto BusError; - kobject_uevent(&dev->kobj, KOBJ_ADD); - bus_attach_device(dev); if (parent) klist_add_tail(&dev->knode_parent, &parent->klist_children); - if (dev->class) { - /* tie the class to the device */ - down(&dev->class->sem); - list_add_tail(&dev->node, &dev->class->devices); - up(&dev->class->sem); - } - /* notify platform of device entry */ if (platform_notify) platform_notify(dev); Done: - kfree(class_name); put_device(dev); return error; BusError: device_pm_remove(dev); PMError: - if (dev->devt_attr) { - device_remove_file(dev, dev->devt_attr); - kfree(dev->devt_attr); - } - attrError: kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); Error: @@ -449,23 +362,9 @@ void put_device(struct device * dev) void device_del(struct device * dev) { struct device * parent = dev->parent; - char *class_name = NULL; if (parent) klist_del(&dev->knode_parent); - if (dev->devt_attr) - device_remove_file(dev, dev->devt_attr); - if (dev->class) { - sysfs_remove_link(&dev->kobj, "subsystem"); - sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); - class_name = make_class_name(dev->class->name, &dev->kobj); - sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&dev->parent->kobj, class_name); - kfree(class_name); - down(&dev->class->sem); - list_del_init(&dev->node); - up(&dev->class->sem); - } device_remove_file(dev, &dev->uevent_attr); /* Notify the platform of the removal, in case they @@ -550,98 +449,3 @@ EXPORT_SYMBOL_GPL(put_device); EXPORT_SYMBOL_GPL(device_create_file); EXPORT_SYMBOL_GPL(device_remove_file); - - -static void device_create_release(struct device *dev) -{ - pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id); - kfree(dev); -} - -/** - * device_create - creates a device and registers it with sysfs - * @cs: pointer to the struct class that this device should be registered to. - * @parent: pointer to the parent struct device of this new device, if any. - * @dev: the dev_t for the char device to be added. - * @fmt: string for the class device's name - * - * This function can be used by char device classes. A struct - * device will be created in sysfs, registered to the specified - * class. - * A "dev" file will be created, showing the dev_t for the device, if - * the dev_t is not 0,0. - * If a pointer to a parent struct device is passed in, the newly - * created struct device will be a child of that device in sysfs. The - * pointer to the struct device will be returned from the call. Any - * further sysfs files that might be required can be created using this - * pointer. - * - * Note: the struct class passed to this function must have previously - * been created with a call to class_create(). - */ -struct device *device_create(struct class *class, struct device *parent, - dev_t devt, char *fmt, ...) -{ - va_list args; - struct device *dev = NULL; - int retval = -ENODEV; - - if (class == NULL || IS_ERR(class)) - goto error; - if (parent == NULL) { - printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__); - goto error; - } - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - retval = -ENOMEM; - goto error; - } - - dev->devt = devt; - dev->class = class; - dev->parent = parent; - dev->release = device_create_release; - - va_start(args, fmt); - vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); - va_end(args); - retval = device_register(dev); - if (retval) - goto error; - - return dev; - -error: - kfree(dev); - return ERR_PTR(retval); -} -EXPORT_SYMBOL_GPL(device_create); - -/** - * device_destroy - removes a device that was created with device_create() - * @class: the pointer to the struct class that this device was registered * with. - * @dev: the dev_t of the device that was previously registered. - * - * This call unregisters and cleans up a class device that was created with a - * call to class_device_create() - */ -void device_destroy(struct class *class, dev_t devt) -{ - struct device *dev = NULL; - struct device *dev_tmp; - - down(&class->sem); - list_for_each_entry(dev_tmp, &class->devices, node) { - if (dev_tmp->devt == devt) { - dev = dev_tmp; - break; - } - } - up(&class->sem); - - if (dev) - device_unregister(dev); -} -EXPORT_SYMBOL_GPL(device_destroy); diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index 4bef76a2f3f2..dd712b24ec91 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "base.h" @@ -58,12 +57,13 @@ static void __devinit register_cpu_control(struct cpu *cpu) { sysdev_create_file(&cpu->sysdev, &attr_online); } -void unregister_cpu(struct cpu *cpu) +void unregister_cpu(struct cpu *cpu, struct node *root) { int logical_cpu = cpu->sysdev.id; - unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); - + if (root) + sysfs_remove_link(&root->sysdev.kobj, + kobject_name(&cpu->sysdev.kobj)); sysdev_remove_file(&cpu->sysdev, &attr_online); sysdev_unregister(&cpu->sysdev); @@ -109,21 +109,23 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); * * Initialize and register the CPU device. */ -int __devinit register_cpu(struct cpu *cpu, int num) +int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) { int error; + cpu->node_id = cpu_to_node(num); cpu->sysdev.id = num; cpu->sysdev.cls = &cpu_sysdev_class; error = sysdev_register(&cpu->sysdev); - + if (!error && root) + error = sysfs_create_link(&root->sysdev.kobj, + &cpu->sysdev.kobj, + kobject_name(&cpu->sysdev.kobj)); if (!error && !cpu->no_control) register_cpu_control(cpu); if (!error) cpu_sys_devices[num] = &cpu->sysdev; - if (!error) - register_cpu_under_node(num, cpu_to_node(num)); #ifdef CONFIG_KEXEC if (!error) @@ -143,13 +145,5 @@ EXPORT_SYMBOL_GPL(get_cpu_sysdev); int __init cpu_dev_init(void) { - int err; - - err = sysdev_class_register(&cpu_sysdev_class); -#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) - if (!err) - err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); -#endif - - return err; + return sysdev_class_register(&cpu_sysdev_class); } diff --git a/trunk/drivers/base/dmapool.c b/trunk/drivers/base/dmapool.c index 33c5cce1560b..e2f64f91ed05 100644 --- a/trunk/drivers/base/dmapool.c +++ b/trunk/drivers/base/dmapool.c @@ -7,7 +7,6 @@ #include #include #include -#include /* * Pool allocator ... wraps the dma_alloc_coherent page allocator, so @@ -36,6 +35,8 @@ struct dma_page { /* cacheable header for 'allocation' bytes */ }; #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) +#define POOL_POISON_FREED 0xa7 /* !inuse */ +#define POOL_POISON_ALLOCATED 0xa9 /* !initted */ static DECLARE_MUTEX (pools_lock); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 5d6c011183f5..0c99ae6a3407 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include "base.h" @@ -36,7 +36,7 @@ static int loading_timeout = 10; /* In seconds */ /* fw_lock could be moved to 'struct firmware_priv' but since it is just * guarding for corner cases a global lock should be OK */ -static DEFINE_MUTEX(fw_lock); +static DECLARE_MUTEX(fw_lock); struct firmware_priv { char fw_id[FIRMWARE_NAME_MAX]; @@ -142,9 +142,9 @@ firmware_loading_store(struct class_device *class_dev, switch (loading) { case 1: - mutex_lock(&fw_lock); + down(&fw_lock); if (!fw_priv->fw) { - mutex_unlock(&fw_lock); + up(&fw_lock); break; } vfree(fw_priv->fw->data); @@ -152,7 +152,7 @@ firmware_loading_store(struct class_device *class_dev, fw_priv->fw->size = 0; fw_priv->alloc_size = 0; set_bit(FW_STATUS_LOADING, &fw_priv->status); - mutex_unlock(&fw_lock); + up(&fw_lock); break; case 0: if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { @@ -185,7 +185,7 @@ firmware_data_read(struct kobject *kobj, struct firmware *fw; ssize_t ret_count = count; - mutex_lock(&fw_lock); + down(&fw_lock); fw = fw_priv->fw; if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ret_count = -ENODEV; @@ -200,7 +200,7 @@ firmware_data_read(struct kobject *kobj, memcpy(buffer, fw->data + offset, ret_count); out: - mutex_unlock(&fw_lock); + up(&fw_lock); return ret_count; } @@ -253,7 +253,7 @@ firmware_data_write(struct kobject *kobj, if (!capable(CAP_SYS_RAWIO)) return -EPERM; - mutex_lock(&fw_lock); + down(&fw_lock); fw = fw_priv->fw; if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { retval = -ENODEV; @@ -268,7 +268,7 @@ firmware_data_write(struct kobject *kobj, fw->size = max_t(size_t, offset + count, fw->size); retval = count; out: - mutex_unlock(&fw_lock); + up(&fw_lock); return retval; } @@ -436,14 +436,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name, } else wait_for_completion(&fw_priv->completion); - mutex_lock(&fw_lock); + down(&fw_lock); if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { retval = -ENOENT; release_firmware(fw_priv->fw); *firmware_p = NULL; } fw_priv->fw = NULL; - mutex_unlock(&fw_lock); + up(&fw_lock); class_device_unregister(class_dev); goto out; diff --git a/trunk/drivers/base/hypervisor.c b/trunk/drivers/base/hypervisor.c deleted file mode 100644 index 0c85e9d6a448..000000000000 --- a/trunk/drivers/base/hypervisor.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * hypervisor.c - /sys/hypervisor subsystem. - * - * This file is released under the GPLv2 - * - */ - -#include -#include - -#include "base.h" - -decl_subsys(hypervisor, NULL, NULL); -EXPORT_SYMBOL_GPL(hypervisor_subsys); - -int __init hypervisor_init(void) -{ - return subsystem_register(&hypervisor_subsys); -} diff --git a/trunk/drivers/base/init.c b/trunk/drivers/base/init.c index 37138154f9e8..c648914b9cde 100644 --- a/trunk/drivers/base/init.c +++ b/trunk/drivers/base/init.c @@ -27,7 +27,6 @@ void __init driver_init(void) buses_init(); classes_init(); firmware_init(); - hypervisor_init(); /* These are also core pieces, but must come after the * core core pieces. diff --git a/trunk/drivers/base/isa.c b/trunk/drivers/base/isa.c deleted file mode 100644 index d2222397a401..000000000000 --- a/trunk/drivers/base/isa.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * ISA bus. - */ - -#include -#include -#include -#include -#include -#include - -static struct device isa_bus = { - .bus_id = "isa" -}; - -struct isa_dev { - struct device dev; - struct device *next; - unsigned int id; -}; - -#define to_isa_dev(x) container_of((x), struct isa_dev, dev) - -static int isa_bus_match(struct device *dev, struct device_driver *driver) -{ - struct isa_driver *isa_driver = to_isa_driver(driver); - - if (dev->platform_data == isa_driver) { - if (!isa_driver->match || - isa_driver->match(dev, to_isa_dev(dev)->id)) - return 1; - dev->platform_data = NULL; - } - return 0; -} - -static int isa_bus_probe(struct device *dev) -{ - struct isa_driver *isa_driver = dev->platform_data; - - if (isa_driver->probe) - return isa_driver->probe(dev, to_isa_dev(dev)->id); - - return 0; -} - -static int isa_bus_remove(struct device *dev) -{ - struct isa_driver *isa_driver = dev->platform_data; - - if (isa_driver->remove) - return isa_driver->remove(dev, to_isa_dev(dev)->id); - - return 0; -} - -static void isa_bus_shutdown(struct device *dev) -{ - struct isa_driver *isa_driver = dev->platform_data; - - if (isa_driver->shutdown) - isa_driver->shutdown(dev, to_isa_dev(dev)->id); -} - -static int isa_bus_suspend(struct device *dev, pm_message_t state) -{ - struct isa_driver *isa_driver = dev->platform_data; - - if (isa_driver->suspend) - return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); - - return 0; -} - -static int isa_bus_resume(struct device *dev) -{ - struct isa_driver *isa_driver = dev->platform_data; - - if (isa_driver->resume) - return isa_driver->resume(dev, to_isa_dev(dev)->id); - - return 0; -} - -static struct bus_type isa_bus_type = { - .name = "isa", - .match = isa_bus_match, - .probe = isa_bus_probe, - .remove = isa_bus_remove, - .shutdown = isa_bus_shutdown, - .suspend = isa_bus_suspend, - .resume = isa_bus_resume -}; - -static void isa_dev_release(struct device *dev) -{ - kfree(to_isa_dev(dev)); -} - -void isa_unregister_driver(struct isa_driver *isa_driver) -{ - struct device *dev = isa_driver->devices; - - while (dev) { - struct device *tmp = to_isa_dev(dev)->next; - device_unregister(dev); - dev = tmp; - } - driver_unregister(&isa_driver->driver); -} -EXPORT_SYMBOL_GPL(isa_unregister_driver); - -int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) -{ - int error; - unsigned int id; - - isa_driver->driver.bus = &isa_bus_type; - isa_driver->devices = NULL; - - error = driver_register(&isa_driver->driver); - if (error) - return error; - - for (id = 0; id < ndev; id++) { - struct isa_dev *isa_dev; - - isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); - if (!isa_dev) { - error = -ENOMEM; - break; - } - - isa_dev->dev.parent = &isa_bus; - isa_dev->dev.bus = &isa_bus_type; - - snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u", - isa_driver->driver.name, id); - - isa_dev->dev.platform_data = isa_driver; - isa_dev->dev.release = isa_dev_release; - isa_dev->id = id; - - error = device_register(&isa_dev->dev); - if (error) { - put_device(&isa_dev->dev); - break; - } - - if (isa_dev->dev.platform_data) { - isa_dev->next = isa_driver->devices; - isa_driver->devices = &isa_dev->dev; - } else - device_unregister(&isa_dev->dev); - } - - if (!error && !isa_driver->devices) - error = -ENODEV; - - if (error) - isa_unregister_driver(isa_driver); - - return error; -} -EXPORT_SYMBOL_GPL(isa_register_driver); - -static int __init isa_bus_init(void) -{ - int error; - - error = bus_register(&isa_bus_type); - if (!error) { - error = device_register(&isa_bus); - if (error) - bus_unregister(&isa_bus_type); - } - return error; -} - -device_initcall(isa_bus_init); diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c index c6b7d9c4b651..dd547af4681a 100644 --- a/trunk/drivers/base/memory.c +++ b/trunk/drivers/base/memory.c @@ -306,13 +306,11 @@ static ssize_t memory_probe_store(struct class *class, const char *buf, size_t count) { u64 phys_addr; - int nid; int ret; phys_addr = simple_strtoull(buf, NULL, 0); - nid = memory_add_physaddr_to_nid(phys_addr); - ret = add_memory(nid, phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); + ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); if (ret) count = ret; diff --git a/trunk/drivers/base/node.c b/trunk/drivers/base/node.c index eae2bdc183bb..c80c3aeed004 100644 --- a/trunk/drivers/base/node.c +++ b/trunk/drivers/base/node.c @@ -11,7 +11,6 @@ #include #include #include -#include static struct sysdev_class node_class = { set_kset_name("node"), @@ -191,66 +190,6 @@ void unregister_node(struct node *node) sysdev_unregister(&node->sysdev); } -struct node node_devices[MAX_NUMNODES]; - -/* - * register cpu under node - */ -int register_cpu_under_node(unsigned int cpu, unsigned int nid) -{ - if (node_online(nid)) { - struct sys_device *obj = get_cpu_sysdev(cpu); - if (!obj) - return 0; - return sysfs_create_link(&node_devices[nid].sysdev.kobj, - &obj->kobj, - kobject_name(&obj->kobj)); - } - - return 0; -} - -int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) -{ - if (node_online(nid)) { - struct sys_device *obj = get_cpu_sysdev(cpu); - if (obj) - sysfs_remove_link(&node_devices[nid].sysdev.kobj, - kobject_name(&obj->kobj)); - } - return 0; -} - -int register_one_node(int nid) -{ - int error = 0; - int cpu; - - if (node_online(nid)) { - int p_node = parent_node(nid); - struct node *parent = NULL; - - if (p_node != nid) - parent = &node_devices[p_node]; - - error = register_node(&node_devices[nid], nid, parent); - - /* link cpu under this node */ - for_each_present_cpu(cpu) { - if (cpu_to_node(cpu) == nid) - register_cpu_under_node(cpu, nid); - } - } - - return error; - -} - -void unregister_one_node(int nid) -{ - unregister_node(&node_devices[nid]); -} - static int __init register_node_type(void) { return sysdev_class_register(&node_class); diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 2b8755db76c6..83f5c5984d1a 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -275,7 +275,7 @@ int platform_device_add(struct platform_device *pdev) pr_debug("Registering platform device '%s'. Parent at %s\n", pdev->dev.bus_id, pdev->dev.parent->bus_id); - ret = device_add(&pdev->dev); + ret = device_register(&pdev->dev); if (ret == 0) return ret; @@ -452,37 +452,6 @@ void platform_driver_unregister(struct platform_driver *drv) EXPORT_SYMBOL_GPL(platform_driver_unregister); -/* modalias support enables more hands-off userspace setup: - * (a) environment variable lets new-style hotplug events work once system is - * fully running: "modprobe $MODALIAS" - * (b) sysfs attribute lets new-style coldplug recover from hotplug events - * mishandled before system is fully running: "modprobe $(cat modalias)" - */ -static ssize_t -modalias_show(struct device *dev, struct device_attribute *a, char *buf) -{ - struct platform_device *pdev = to_platform_device(dev); - int len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->name); - - return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; -} - -static struct device_attribute platform_dev_attrs[] = { - __ATTR_RO(modalias), - __ATTR_NULL, -}; - -static int platform_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - struct platform_device *pdev = to_platform_device(dev); - - envp[0] = buffer; - snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name); - return 0; -} - - /** * platform_match - bind platform device to platform driver. * @dev: device. @@ -527,9 +496,7 @@ static int platform_resume(struct device * dev) struct bus_type platform_bus_type = { .name = "platform", - .dev_attrs = platform_dev_attrs, .match = platform_match, - .uevent = platform_uevent, .suspend = platform_suspend, .resume = platform_resume, }; diff --git a/trunk/drivers/base/power/Makefile b/trunk/drivers/base/power/Makefile index 91f230939c1e..c0219ad94aca 100644 --- a/trunk/drivers/base/power/Makefile +++ b/trunk/drivers/base/power/Makefile @@ -1,10 +1,6 @@ obj-y := shutdown.o obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o -obj-$(CONFIG_PM_TRACE) += trace.o ifeq ($(CONFIG_DEBUG_DRIVER),y) EXTRA_CFLAGS += -DDEBUG endif -ifeq ($(CONFIG_PM_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif diff --git a/trunk/drivers/base/power/resume.c b/trunk/drivers/base/power/resume.c index 826093ef4c7e..317edbf0feca 100644 --- a/trunk/drivers/base/power/resume.c +++ b/trunk/drivers/base/power/resume.c @@ -9,7 +9,6 @@ */ #include -#include #include "../base.h" #include "power.h" @@ -24,8 +23,6 @@ int resume_device(struct device * dev) { int error = 0; - TRACE_DEVICE(dev); - TRACE_RESUME(0); down(&dev->sem); if (dev->power.pm_parent && dev->power.pm_parent->power.power_state.event) { @@ -39,7 +36,6 @@ int resume_device(struct device * dev) error = dev->bus->resume(dev); } up(&dev->sem); - TRACE_RESUME(error); return error; } @@ -53,7 +49,8 @@ void dpm_resume(void) struct device * dev = to_device(entry); get_device(dev); - list_move_tail(entry, &dpm_active); + list_del_init(entry); + list_add_tail(entry, &dpm_active); up(&dpm_list_sem); if (!dev->power.prev_state.event) @@ -100,7 +97,8 @@ void dpm_power_up(void) struct device * dev = to_device(entry); get_device(dev); - list_move_tail(entry, &dpm_active); + list_del_init(entry); + list_add_tail(entry, &dpm_active); resume_device(dev); put_device(dev); } diff --git a/trunk/drivers/base/power/suspend.c b/trunk/drivers/base/power/suspend.c index 69509e02f703..2a769cc6f5f9 100644 --- a/trunk/drivers/base/power/suspend.c +++ b/trunk/drivers/base/power/suspend.c @@ -29,15 +29,6 @@ * lists. This way, the ancestors will be accessed before their descendents. */ -static inline char *suspend_verb(u32 event) -{ - switch (event) { - case PM_EVENT_SUSPEND: return "suspend"; - case PM_EVENT_FREEZE: return "freeze"; - default: return "(unknown suspend event)"; - } -} - /** * suspend_device - Save state of one device. @@ -66,13 +57,7 @@ int suspend_device(struct device * dev, pm_message_t state) dev->power.prev_state = dev->power.power_state; if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { - dev_dbg(dev, "%s%s\n", - suspend_verb(state.event), - ((state.event == PM_EVENT_SUSPEND) - && device_may_wakeup(dev)) - ? ", may wakeup" - : "" - ); + dev_dbg(dev, "suspending\n"); error = dev->bus->suspend(dev, state); suspend_report_result(dev->bus->suspend, error); } @@ -116,10 +101,12 @@ int device_suspend(pm_message_t state) /* Check if the device got removed */ if (!list_empty(&dev->power.entry)) { /* Move it to the dpm_off or dpm_off_irq list */ - if (!error) - list_move(&dev->power.entry, &dpm_off); - else if (error == -EAGAIN) { - list_move(&dev->power.entry, &dpm_off_irq); + if (!error) { + list_del(&dev->power.entry); + list_add(&dev->power.entry, &dpm_off); + } else if (error == -EAGAIN) { + list_del(&dev->power.entry); + list_add(&dev->power.entry, &dpm_off_irq); error = 0; } } @@ -137,7 +124,8 @@ int device_suspend(pm_message_t state) */ while (!list_empty(&dpm_off_irq)) { struct list_head * entry = dpm_off_irq.next; - list_move(entry, &dpm_off); + list_del(entry); + list_add(entry, &dpm_off); } dpm_resume(); } diff --git a/trunk/drivers/base/power/trace.c b/trunk/drivers/base/power/trace.c deleted file mode 100644 index a9ab30fefffc..000000000000 --- a/trunk/drivers/base/power/trace.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * drivers/base/power/trace.c - * - * Copyright (C) 2006 Linus Torvalds - * - * Trace facility for suspend/resume problems, when none of the - * devices may be working. - */ - -#include -#include - -#include - -#include "power.h" - -/* - * Horrid, horrid, horrid. - * - * It turns out that the _only_ piece of hardware that actually - * keeps its value across a hard boot (and, more importantly, the - * POST init sequence) is literally the realtime clock. - * - * Never mind that an RTC chip has 114 bytes (and often a whole - * other bank of an additional 128 bytes) of nice SRAM that is - * _designed_ to keep data - the POST will clear it. So we literally - * can just use the few bytes of actual time data, which means that - * we're really limited. - * - * It means, for example, that we can't use the seconds at all - * (since the time between the hang and the boot might be more - * than a minute), and we'd better not depend on the low bits of - * the minutes either. - * - * There are the wday fields etc, but I wouldn't guarantee those - * are dependable either. And if the date isn't valid, either the - * hw or POST will do strange things. - * - * So we're left with: - * - year: 0-99 - * - month: 0-11 - * - day-of-month: 1-28 - * - hour: 0-23 - * - min: (0-30)*2 - * - * Giving us a total range of 0-16128000 (0xf61800), ie less - * than 24 bits of actual data we can save across reboots. - * - * And if your box can't boot in less than three minutes, - * you're screwed. - * - * Now, almost 24 bits of data is pitifully small, so we need - * to be pretty dense if we want to use it for anything nice. - * What we do is that instead of saving off nice readable info, - * we save off _hashes_ of information that we can hopefully - * regenerate after the reboot. - * - * In particular, this means that we might be unlucky, and hit - * a case where we have a hash collision, and we end up not - * being able to tell for certain exactly which case happened. - * But that's hopefully unlikely. - * - * What we do is to take the bits we can fit, and split them - * into three parts (16*997*1009 = 16095568), and use the values - * for: - * - 0-15: user-settable - * - 0-996: file + line number - * - 0-1008: device - */ -#define USERHASH (16) -#define FILEHASH (997) -#define DEVHASH (1009) - -#define DEVSEED (7919) - -static unsigned int dev_hash_value; - -static int set_magic_time(unsigned int user, unsigned int file, unsigned int device) -{ - unsigned int n = user + USERHASH*(file + FILEHASH*device); - - // June 7th, 2006 - static struct rtc_time time = { - .tm_sec = 0, - .tm_min = 0, - .tm_hour = 0, - .tm_mday = 7, - .tm_mon = 5, // June - counting from zero - .tm_year = 106, - .tm_wday = 3, - .tm_yday = 160, - .tm_isdst = 1 - }; - - time.tm_year = (n % 100); - n /= 100; - time.tm_mon = (n % 12); - n /= 12; - time.tm_mday = (n % 28) + 1; - n /= 28; - time.tm_hour = (n % 24); - n /= 24; - time.tm_min = (n % 20) * 3; - n /= 20; - set_rtc_time(&time); - return n ? -1 : 0; -} - -static unsigned int read_magic_time(void) -{ - struct rtc_time time; - unsigned int val; - - get_rtc_time(&time); - printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", - time.tm_hour, time.tm_min, time.tm_sec, - time.tm_mon, time.tm_mday, time.tm_year); - val = time.tm_year; /* 100 years */ - if (val > 100) - val -= 100; - val += time.tm_mon * 100; /* 12 months */ - val += (time.tm_mday-1) * 100 * 12; /* 28 month-days */ - val += time.tm_hour * 100 * 12 * 28; /* 24 hours */ - val += (time.tm_min / 3) * 100 * 12 * 28 * 24; /* 20 3-minute intervals */ - return val; -} - -/* - * This is just the sdbm hash function with a user-supplied - * seed and final size parameter. - */ -static unsigned int hash_string(unsigned int seed, const char *data, unsigned int mod) -{ - unsigned char c; - while ((c = *data++) != 0) { - seed = (seed << 16) + (seed << 6) - seed + c; - } - return seed % mod; -} - -void set_trace_device(struct device *dev) -{ - dev_hash_value = hash_string(DEVSEED, dev->bus_id, DEVHASH); -} - -/* - * We could just take the "tracedata" index into the .tracedata - * section instead. Generating a hash of the data gives us a - * chance to work across kernel versions, and perhaps more - * importantly it also gives us valid/invalid check (ie we will - * likely not give totally bogus reports - if the hash matches, - * it's not any guarantee, but it's a high _likelihood_ that - * the match is valid). - */ -void generate_resume_trace(void *tracedata, unsigned int user) -{ - unsigned short lineno = *(unsigned short *)tracedata; - const char *file = *(const char **)(tracedata + 2); - unsigned int user_hash_value, file_hash_value; - - user_hash_value = user % USERHASH; - file_hash_value = hash_string(lineno, file, FILEHASH); - set_magic_time(user_hash_value, file_hash_value, dev_hash_value); -} - -extern char __tracedata_start, __tracedata_end; -static int show_file_hash(unsigned int value) -{ - int match; - char *tracedata; - - match = 0; - for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 6) { - unsigned short lineno = *(unsigned short *)tracedata; - const char *file = *(const char **)(tracedata + 2); - unsigned int hash = hash_string(lineno, file, FILEHASH); - if (hash != value) - continue; - printk(" hash matches %s:%u\n", file, lineno); - match++; - } - return match; -} - -static int show_dev_hash(unsigned int value) -{ - int match = 0; - struct list_head * entry = dpm_active.prev; - - while (entry != &dpm_active) { - struct device * dev = to_device(entry); - unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH); - if (hash == value) { - printk(" hash matches device %s\n", dev->bus_id); - match++; - } - entry = entry->prev; - } - return match; -} - -static unsigned int hash_value_early_read; - -static int early_resume_init(void) -{ - hash_value_early_read = read_magic_time(); - return 0; -} - -static int late_resume_init(void) -{ - unsigned int val = hash_value_early_read; - unsigned int user, file, dev; - - user = val % USERHASH; - val = val / USERHASH; - file = val % FILEHASH; - val = val / FILEHASH; - dev = val /* % DEVHASH */; - - printk(" Magic number: %d:%d:%d\n", user, file, dev); - show_file_hash(file); - show_dev_hash(dev); - return 0; -} - -core_initcall(early_resume_init); -late_initcall(late_resume_init); diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c index 6858178b3aff..6fc23ab127bd 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -80,59 +80,10 @@ void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a) EXPORT_SYMBOL_GPL(sysdev_create_file); EXPORT_SYMBOL_GPL(sysdev_remove_file); -#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj) -#define to_sysdev_class_attr(a) container_of(a, \ - struct sysdev_class_attribute, attr) - -static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, - char *buffer) -{ - struct sysdev_class * class = to_sysdev_class(kobj); - struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); - - if (class_attr->show) - return class_attr->show(class, buffer); - return -EIO; -} - -static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) -{ - struct sysdev_class * class = to_sysdev_class(kobj); - struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr); - - if (class_attr->store) - return class_attr->store(class, buffer, count); - return -EIO; -} - -static struct sysfs_ops sysfs_class_ops = { - .show = sysdev_class_show, - .store = sysdev_class_store, -}; - -static struct kobj_type ktype_sysdev_class = { - .sysfs_ops = &sysfs_class_ops, -}; - -int sysdev_class_create_file(struct sysdev_class *c, - struct sysdev_class_attribute *a) -{ - return sysfs_create_file(&c->kset.kobj, &a->attr); -} -EXPORT_SYMBOL_GPL(sysdev_class_create_file); - -void sysdev_class_remove_file(struct sysdev_class *c, - struct sysdev_class_attribute *a) -{ - sysfs_remove_file(&c->kset.kobj, &a->attr); -} -EXPORT_SYMBOL_GPL(sysdev_class_remove_file); - /* * declare system_subsys */ -static decl_subsys(system, &ktype_sysdev_class, NULL); +static decl_subsys(system, &ktype_sysdev, NULL); int sysdev_class_register(struct sysdev_class * cls) { diff --git a/trunk/drivers/base/topology.c b/trunk/drivers/base/topology.c index c2d621632383..8c52421cbc54 100644 --- a/trunk/drivers/base/topology.c +++ b/trunk/drivers/base/topology.c @@ -107,7 +107,7 @@ static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) return 0; } -static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, +static int topology_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -125,7 +125,7 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata topology_cpu_notifier = +static struct notifier_block topology_cpu_notifier = { .notifier_call = topology_cpu_callback, }; diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index dd8a1501142f..45bcda544880 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -17,8 +17,8 @@ */ -#define DAC960_DriverVersion "2.5.48" -#define DAC960_DriverDate "14 May 2006" +#define DAC960_DriverVersion "2.5.47" +#define DAC960_DriverDate "14 November 2002" #include @@ -4780,16 +4780,15 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) (NewPhysicalDeviceInfo->LogicalUnit != PhysicalDeviceInfo->LogicalUnit)) { - PhysicalDeviceInfo = + PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *) kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC); InquiryUnitSerialNumber = + (DAC960_SCSI_Inquiry_UnitSerialNumber_T *) kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC); - if (InquiryUnitSerialNumber == NULL || - PhysicalDeviceInfo == NULL) + if (InquiryUnitSerialNumber == NULL && + PhysicalDeviceInfo != NULL) { - kfree(InquiryUnitSerialNumber); - InquiryUnitSerialNumber = NULL; kfree(PhysicalDeviceInfo); PhysicalDeviceInfo = NULL; } diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 93d94749310b..ae0949b3394f 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -402,7 +402,6 @@ config BLK_DEV_RAM_SIZE config BLK_DEV_INITRD bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" - depends on BROKEN || !FRV help The initial RAM filesystem is a ramfs which is loaded by the boot loader (loadlin or lilo) and that is mounted as root diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 2641597c6549..2a8af685926f 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 39b0f53186e8..1319d8f20640 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -64,129 +64,143 @@ MODULE_LICENSE("GPL"); /* define the PCI info for the cards we can control */ static const struct pci_device_id cciss_pci_device_id[] = { - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS, 0x0E11, 0x4070}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4080}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4082}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4083}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x4091}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409A}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409B}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409C}, - {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409D}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA, 0x103C, 0x3225}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3223}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3234}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3235}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3211}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3212}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3213}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS, + 0x0E11, 0x4070, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, + 0x0E11, 0x4080, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, + 0x0E11, 0x4082, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, + 0x0E11, 0x4083, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409A, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409B, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409C, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x409D, 0, 0, 0}, + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, + 0x0E11, 0x4091, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA, + 0x103C, 0x3225, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, + 0x103c, 0x3223, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, + 0x103c, 0x3234, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, + 0x103c, 0x3235, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, + 0x103c, 0x3211, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, + 0x103c, 0x3212, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, + 0x103c, 0x3213, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, + 0x103c, 0x3214, 0, 0, 0}, + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, + 0x103c, 0x3215, 0, 0, 0}, {0,} }; - MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); +#define NR_PRODUCTS ARRAY_SIZE(products) + /* board_id = Subsystem Device ID & Vendor ID * product = Marketing Name for the board - * access = Address of the struct of function pointers + * access = Address of the struct of function pointers */ static struct board_type products[] = { - {0x40700E11, "Smart Array 5300", &SA5_access}, - {0x40800E11, "Smart Array 5i", &SA5B_access}, - {0x40820E11, "Smart Array 532", &SA5B_access}, - {0x40830E11, "Smart Array 5312", &SA5B_access}, - {0x409A0E11, "Smart Array 641", &SA5_access}, - {0x409B0E11, "Smart Array 642", &SA5_access}, - {0x409C0E11, "Smart Array 6400", &SA5_access}, - {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, - {0x40910E11, "Smart Array 6i", &SA5_access}, - {0x3225103C, "Smart Array P600", &SA5_access}, - {0x3223103C, "Smart Array P800", &SA5_access}, - {0x3234103C, "Smart Array P400", &SA5_access}, - {0x3235103C, "Smart Array P400i", &SA5_access}, - {0x3211103C, "Smart Array E200i", &SA5_access}, - {0x3212103C, "Smart Array E200", &SA5_access}, - {0x3213103C, "Smart Array E200i", &SA5_access}, - {0x3214103C, "Smart Array E200i", &SA5_access}, - {0x3215103C, "Smart Array E200i", &SA5_access}, + { 0x40700E11, "Smart Array 5300", &SA5_access }, + { 0x40800E11, "Smart Array 5i", &SA5B_access}, + { 0x40820E11, "Smart Array 532", &SA5B_access}, + { 0x40830E11, "Smart Array 5312", &SA5B_access}, + { 0x409A0E11, "Smart Array 641", &SA5_access}, + { 0x409B0E11, "Smart Array 642", &SA5_access}, + { 0x409C0E11, "Smart Array 6400", &SA5_access}, + { 0x409D0E11, "Smart Array 6400 EM", &SA5_access}, + { 0x40910E11, "Smart Array 6i", &SA5_access}, + { 0x3225103C, "Smart Array P600", &SA5_access}, + { 0x3223103C, "Smart Array P800", &SA5_access}, + { 0x3234103C, "Smart Array P400", &SA5_access}, + { 0x3235103C, "Smart Array P400i", &SA5_access}, + { 0x3211103C, "Smart Array E200i", &SA5_access}, + { 0x3212103C, "Smart Array E200", &SA5_access}, + { 0x3213103C, "Smart Array E200i", &SA5_access}, + { 0x3214103C, "Smart Array E200i", &SA5_access}, + { 0x3215103C, "Smart Array E200i", &SA5_access}, }; -/* How long to wait (in milliseconds) for board to go into simple mode */ -#define MAX_CONFIG_WAIT 30000 +/* How long to wait (in millesconds) for board to go into simple mode */ +#define MAX_CONFIG_WAIT 30000 #define MAX_IOCTL_CONFIG_WAIT 1000 /*define how many times we will try a command because of bus resets */ #define MAX_CMD_RETRIES 3 #define READ_AHEAD 1024 -#define NR_CMDS 384 /* #commands that can be outstanding */ +#define NR_CMDS 384 /* #commands that can be outstanding */ #define MAX_CTLR 32 /* Originally cciss driver only supports 8 major numbers */ #define MAX_CTLR_ORIG 8 + static ctlr_info_t *hba[MAX_CTLR]; static void do_cciss_request(request_queue_t *q); static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs); static int cciss_open(struct inode *inode, struct file *filep); static int cciss_release(struct inode *inode, struct file *filep); -static int cciss_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg); +static int cciss_ioctl(struct inode *inode, struct file *filep, + unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int revalidate_allvol(ctlr_info_t *host); static int cciss_revalidate(struct gendisk *disk); static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); -static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, - int clear_all); +static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all); static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, - int withirq, unsigned int *total_size, - unsigned int *block_size); -static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq, - unsigned int total_size, - unsigned int block_size, - InquiryData_struct *inq_buff, - drive_info_struct *drv); + int withirq, unsigned int *total_size, unsigned int *block_size); +static void cciss_geometry_inquiry(int ctlr, int logvol, + int withirq, unsigned int total_size, + unsigned int block_size, InquiryData_struct *inq_buff, + drive_info_struct *drv); static void cciss_getgeometry(int cntl_num); -static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, - __u32); -static void start_io(ctlr_info_t *h); -static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size, - unsigned int use_unit_num, unsigned int log_unit, - __u8 page_code, unsigned char *scsi3addr, int cmd_type); -static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, - unsigned int use_unit_num, unsigned int log_unit, - __u8 page_code, int cmd_type); +static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32); +static void start_io( ctlr_info_t *h); +static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, + unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, + unsigned char *scsi3addr, int cmd_type); +static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, + unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, + int cmd_type); static void fail_all_cmds(unsigned long ctlr); #ifdef CONFIG_PROC_FS -static int cciss_proc_get_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data); +static int cciss_proc_get_info(char *buffer, char **start, off_t offset, + int length, int *eof, void *data); static void cciss_procinit(int i); #else -static void cciss_procinit(int i) -{ -} -#endif /* CONFIG_PROC_FS */ +static void cciss_procinit(int i) {} +#endif /* CONFIG_PROC_FS */ #ifdef CONFIG_COMPAT static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); #endif -static struct block_device_operations cciss_fops = { - .owner = THIS_MODULE, - .open = cciss_open, - .release = cciss_release, - .ioctl = cciss_ioctl, - .getgeo = cciss_getgeo, +static struct block_device_operations cciss_fops = { + .owner = THIS_MODULE, + .open = cciss_open, + .release = cciss_release, + .ioctl = cciss_ioctl, + .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT - .compat_ioctl = cciss_compat_ioctl, + .compat_ioctl = cciss_compat_ioctl, #endif - .revalidate_disk = cciss_revalidate, + .revalidate_disk= cciss_revalidate, }; /* @@ -194,29 +208,28 @@ static struct block_device_operations cciss_fops = { */ static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c) { - if (*Qptr == NULL) { - *Qptr = c; - c->next = c->prev = c; - } else { - c->prev = (*Qptr)->prev; - c->next = (*Qptr); - (*Qptr)->prev->next = c; - (*Qptr)->prev = c; - } + if (*Qptr == NULL) { + *Qptr = c; + c->next = c->prev = c; + } else { + c->prev = (*Qptr)->prev; + c->next = (*Qptr); + (*Qptr)->prev->next = c; + (*Qptr)->prev = c; + } } -static inline CommandList_struct *removeQ(CommandList_struct **Qptr, - CommandList_struct *c) +static inline CommandList_struct *removeQ(CommandList_struct **Qptr, + CommandList_struct *c) { - if (c && c->next != c) { - if (*Qptr == c) - *Qptr = c->next; - c->prev->next = c->next; - c->next->prev = c->prev; - } else { - *Qptr = NULL; - } - return c; + if (c && c->next != c) { + if (*Qptr == c) *Qptr = c->next; + c->prev->next = c->next; + c->next->prev = c->prev; + } else { + *Qptr = NULL; + } + return c; } #include "cciss_scsi.c" /* For SCSI tape support */ @@ -229,24 +242,23 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr, #define ENG_GIG 1000000000 #define ENG_GIG_FACTOR (ENG_GIG/512) #define RAID_UNKNOWN 6 -static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", - "UNKNOWN" -}; +static const char *raid_label[] = {"0","4","1(1+0)","5","5+1","ADG", + "UNKNOWN"}; static struct proc_dir_entry *proc_cciss; -static int cciss_proc_get_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static int cciss_proc_get_info(char *buffer, char **start, off_t offset, + int length, int *eof, void *data) { - off_t pos = 0; - off_t len = 0; - int size, i, ctlr; - ctlr_info_t *h = (ctlr_info_t *) data; - drive_info_struct *drv; + off_t pos = 0; + off_t len = 0; + int size, i, ctlr; + ctlr_info_t *h = (ctlr_info_t*)data; + drive_info_struct *drv; unsigned long flags; - sector_t vol_sz, vol_sz_frac; + sector_t vol_sz, vol_sz_frac; - ctlr = h->ctlr; + ctlr = h->ctlr; /* prevent displaying bogus info during configuration * or deconfiguration of a logical volume @@ -254,35 +266,35 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, spin_lock_irqsave(CCISS_LOCK(ctlr), flags); if (h->busy_configuring) { spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - return -EBUSY; + return -EBUSY; } h->busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - size = sprintf(buffer, "%s: HP %s Controller\n" - "Board ID: 0x%08lx\n" - "Firmware Version: %c%c%c%c\n" - "IRQ: %d\n" - "Logical drives: %d\n" - "Current Q depth: %d\n" - "Current # commands on controller: %d\n" - "Max Q depth since init: %d\n" - "Max # commands on controller since init: %d\n" - "Max SG entries since init: %d\n\n", - h->devname, - h->product_name, - (unsigned long)h->board_id, - h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], - h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], - h->num_luns, h->Qdepth, h->commands_outstanding, - h->maxQsinceinit, h->max_outstanding, h->maxSG); - - pos += size; - len += size; + size = sprintf(buffer, "%s: HP %s Controller\n" + "Board ID: 0x%08lx\n" + "Firmware Version: %c%c%c%c\n" + "IRQ: %d\n" + "Logical drives: %d\n" + "Current Q depth: %d\n" + "Current # commands on controller: %d\n" + "Max Q depth since init: %d\n" + "Max # commands on controller since init: %d\n" + "Max SG entries since init: %d\n\n", + h->devname, + h->product_name, + (unsigned long)h->board_id, + h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], + (unsigned int)h->intr[SIMPLE_MODE_INT], + h->num_luns, + h->Qdepth, h->commands_outstanding, + h->maxQsinceinit, h->max_outstanding, h->maxSG); + + pos += size; len += size; cciss_proc_tape_report(ctlr, buffer, &pos, &len); - for (i = 0; i <= h->highest_lun; i++) { + for(i=0; i<=h->highest_lun; i++) { - drv = &h->drv[i]; + drv = &h->drv[i]; if (drv->heads == 0) continue; @@ -293,26 +305,25 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, if (drv->raid_level > 5) drv->raid_level = RAID_UNKNOWN; - size = sprintf(buffer + len, "cciss/c%dd%d:" - "\t%4u.%02uGB\tRAID %s\n", - ctlr, i, (int)vol_sz, (int)vol_sz_frac, - raid_label[drv->raid_level]); - pos += size; - len += size; - } - - *eof = 1; - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; + size = sprintf(buffer+len, "cciss/c%dd%d:" + "\t%4u.%02uGB\tRAID %s\n", + ctlr, i, (int)vol_sz, (int)vol_sz_frac, + raid_label[drv->raid_level]); + pos += size; len += size; + } + + *eof = 1; + *start = buffer+offset; + len -= offset; + if (len>length) + len = length; h->busy_configuring = 0; - return len; + return len; } -static int -cciss_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int +cciss_proc_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) { unsigned char cmd[80]; int len; @@ -321,23 +332,20 @@ cciss_proc_write(struct file *file, const char __user *buffer, int rc; #endif - if (count > sizeof(cmd) - 1) - return -EINVAL; - if (copy_from_user(cmd, buffer, count)) - return -EFAULT; + if (count > sizeof(cmd)-1) return -EINVAL; + if (copy_from_user(cmd, buffer, count)) return -EFAULT; cmd[count] = '\0'; len = strlen(cmd); // above 3 lines ensure safety - if (len && cmd[len - 1] == '\n') + if (len && cmd[len-1] == '\n') cmd[--len] = '\0'; # ifdef CONFIG_CISS_SCSI_TAPE - if (strcmp("engage scsi", cmd) == 0) { - rc = cciss_engage_scsi(h->ctlr); - if (rc != 0) - return -rc; - return count; - } - /* might be nice to have "disengage" too, but it's not - safely possible. (only 1 module use count, lock issues.) */ + if (strcmp("engage scsi", cmd)==0) { + rc = cciss_engage_scsi(h->ctlr); + if (rc != 0) return -rc; + return count; + } + /* might be nice to have "disengage" too, but it's not + safely possible. (only 1 module use count, lock issues.) */ # endif return -EINVAL; } @@ -350,113 +358,116 @@ static void __devinit cciss_procinit(int i) { struct proc_dir_entry *pde; - if (proc_cciss == NULL) { - proc_cciss = proc_mkdir("cciss", proc_root_driver); - if (!proc_cciss) + if (proc_cciss == NULL) { + proc_cciss = proc_mkdir("cciss", proc_root_driver); + if (!proc_cciss) return; - } + } - pde = create_proc_read_entry(hba[i]->devname, - S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, - proc_cciss, cciss_proc_get_info, hba[i]); + pde = create_proc_read_entry(hba[i]->devname, + S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, + proc_cciss, cciss_proc_get_info, hba[i]); pde->write_proc = cciss_proc_write; } -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_PROC_FS */ -/* - * For operations that cannot sleep, a command block is allocated at init, +/* + * For operations that cannot sleep, a command block is allocated at init, * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track - * which ones are free or in use. For operations that can wait for kmalloc - * to possible sleep, this routine can be called with get_from_pool set to 0. - * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was. - */ -static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) + * which ones are free or in use. For operations that can wait for kmalloc + * to possible sleep, this routine can be called with get_from_pool set to 0. + * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was. + */ +static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool) { CommandList_struct *c; - int i; + int i; u64bit temp64; dma_addr_t cmd_dma_handle, err_dma_handle; - if (!get_from_pool) { - c = (CommandList_struct *) pci_alloc_consistent(h->pdev, - sizeof(CommandList_struct), &cmd_dma_handle); - if (c == NULL) - return NULL; + if (!get_from_pool) + { + c = (CommandList_struct *) pci_alloc_consistent( + h->pdev, sizeof(CommandList_struct), &cmd_dma_handle); + if(c==NULL) + return NULL; memset(c, 0, sizeof(CommandList_struct)); c->cmdindex = -1; - c->err_info = (ErrorInfo_struct *) - pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), - &err_dma_handle); - - if (c->err_info == NULL) { - pci_free_consistent(h->pdev, + c->err_info = (ErrorInfo_struct *)pci_alloc_consistent( + h->pdev, sizeof(ErrorInfo_struct), + &err_dma_handle); + + if (c->err_info == NULL) + { + pci_free_consistent(h->pdev, sizeof(CommandList_struct), c, cmd_dma_handle); return NULL; } memset(c->err_info, 0, sizeof(ErrorInfo_struct)); - } else { /* get it out of the controllers pool */ - - do { - i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); - if (i == NR_CMDS) - return NULL; - } while (test_and_set_bit - (i & (BITS_PER_LONG - 1), - h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); + } else /* get it out of the controllers pool */ + { + do { + i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); + if (i == NR_CMDS) + return NULL; + } while(test_and_set_bit(i & (BITS_PER_LONG - 1), h->cmd_pool_bits+(i/BITS_PER_LONG)) != 0); #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss: using command buffer %d\n", i); #endif - c = h->cmd_pool + i; + c = h->cmd_pool + i; memset(c, 0, sizeof(CommandList_struct)); - cmd_dma_handle = h->cmd_pool_dhandle - + i * sizeof(CommandList_struct); + cmd_dma_handle = h->cmd_pool_dhandle + + i*sizeof(CommandList_struct); c->err_info = h->errinfo_pool + i; memset(c->err_info, 0, sizeof(ErrorInfo_struct)); - err_dma_handle = h->errinfo_pool_dhandle - + i * sizeof(ErrorInfo_struct); - h->nr_allocs++; + err_dma_handle = h->errinfo_pool_dhandle + + i*sizeof(ErrorInfo_struct); + h->nr_allocs++; c->cmdindex = i; - } + } c->busaddr = (__u32) cmd_dma_handle; - temp64.val = (__u64) err_dma_handle; + temp64.val = (__u64) err_dma_handle; c->ErrDesc.Addr.lower = temp64.val32.lower; c->ErrDesc.Addr.upper = temp64.val32.upper; c->ErrDesc.Len = sizeof(ErrorInfo_struct); - + c->ctlr = h->ctlr; - return c; + return c; + + } -/* - * Frees a command block that was previously allocated with cmd_alloc(). +/* + * Frees a command block that was previously allocated with cmd_alloc(). */ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) { int i; u64bit temp64; - if (!got_from_pool) { + if( !got_from_pool) + { temp64.val32.lower = c->ErrDesc.Addr.lower; temp64.val32.upper = c->ErrDesc.Addr.upper; - pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), - c->err_info, (dma_addr_t) temp64.val); - pci_free_consistent(h->pdev, sizeof(CommandList_struct), - c, (dma_addr_t) c->busaddr); - } else { + pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), + c->err_info, (dma_addr_t) temp64.val); + pci_free_consistent(h->pdev, sizeof(CommandList_struct), + c, (dma_addr_t) c->busaddr); + } else + { i = c - h->cmd_pool; - clear_bit(i & (BITS_PER_LONG - 1), - h->cmd_pool_bits + (i / BITS_PER_LONG)); - h->nr_frees++; - } + clear_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)); + h->nr_frees++; + } } static inline ctlr_info_t *get_host(struct gendisk *disk) { - return disk->queue->queuedata; + return disk->queue->queuedata; } static inline drive_info_struct *get_drv(struct gendisk *disk) @@ -474,7 +485,7 @@ static int cciss_open(struct inode *inode, struct file *filep) #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ if (host->busy_initializing || drv->busy_configuring) return -EBUSY; @@ -487,10 +498,10 @@ static int cciss_open(struct inode *inode, struct file *filep) * for "raw controller". */ if (drv->nr_blocks == 0) { - if (iminor(inode) != 0) { /* not node 0? */ + if (iminor(inode) != 0) { /* not node 0? */ /* if not node 0 make sure it is a partition = 0 */ if (iminor(inode) & 0x0f) { - return -ENXIO; + return -ENXIO; /* if it is, make sure we have a LUN ID */ } else if (drv->LunID == 0) { return -ENXIO; @@ -503,7 +514,6 @@ static int cciss_open(struct inode *inode, struct file *filep) host->usage_count++; return 0; } - /* * Close. Sync first. */ @@ -513,9 +523,8 @@ static int cciss_release(struct inode *inode, struct file *filep) drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk); #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_release %s\n", - inode->i_bdev->bd_disk->disk_name); -#endif /* CCISS_DEBUG */ + printk(KERN_DEBUG "cciss_release %s\n", inode->i_bdev->bd_disk->disk_name); +#endif /* CCISS_DEBUG */ drv->usage_count--; host->usage_count--; @@ -533,10 +542,8 @@ static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg) return ret; } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg); -static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd, - unsigned long arg); +static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, unsigned long arg); +static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd, unsigned long arg); static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) { @@ -568,26 +575,19 @@ static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) } } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, unsigned long arg) { IOCTL32_Command_struct __user *arg32 = - (IOCTL32_Command_struct __user *) arg; + (IOCTL32_Command_struct __user *) arg; IOCTL_Command_struct arg64; IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64)); int err; u32 cp; err = 0; - err |= - copy_from_user(&arg64.LUN_info, &arg32->LUN_info, - sizeof(arg64.LUN_info)); - err |= - copy_from_user(&arg64.Request, &arg32->Request, - sizeof(arg64.Request)); - err |= - copy_from_user(&arg64.error_info, &arg32->error_info, - sizeof(arg64.error_info)); + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info)); err |= get_user(arg64.buf_size, &arg32->buf_size); err |= get_user(cp, &arg32->buf); arg64.buf = compat_ptr(cp); @@ -596,38 +596,28 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, if (err) return -EFAULT; - err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long)p); + err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long) p); if (err) return err; - err |= - copy_in_user(&arg32->error_info, &p->error_info, - sizeof(arg32->error_info)); + err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info)); if (err) return -EFAULT; return err; } -static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned long arg) { BIG_IOCTL32_Command_struct __user *arg32 = - (BIG_IOCTL32_Command_struct __user *) arg; + (BIG_IOCTL32_Command_struct __user *) arg; BIG_IOCTL_Command_struct arg64; - BIG_IOCTL_Command_struct __user *p = - compat_alloc_user_space(sizeof(arg64)); + BIG_IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64)); int err; u32 cp; err = 0; - err |= - copy_from_user(&arg64.LUN_info, &arg32->LUN_info, - sizeof(arg64.LUN_info)); - err |= - copy_from_user(&arg64.Request, &arg32->Request, - sizeof(arg64.Request)); - err |= - copy_from_user(&arg64.error_info, &arg32->error_info, - sizeof(arg64.error_info)); + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info)); err |= get_user(arg64.buf_size, &arg32->buf_size); err |= get_user(arg64.malloc_size, &arg32->malloc_size); err |= get_user(cp, &arg32->buf); @@ -635,14 +625,12 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, err |= copy_to_user(p, &arg64, sizeof(arg64)); if (err) - return -EFAULT; + return -EFAULT; - err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long)p); + err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long) p); if (err) return err; - err |= - copy_in_user(&arg32->error_info, &p->error_info, - sizeof(arg32->error_info)); + err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info)); if (err) return -EFAULT; return err; @@ -663,10 +651,10 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /* - * ioctl + * ioctl */ -static int cciss_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg) +static int cciss_ioctl(struct inode *inode, struct file *filep, + unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; struct gendisk *disk = bdev->bd_disk; @@ -677,193 +665,171 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); -#endif /* CCISS_DEBUG */ - - switch (cmd) { +#endif /* CCISS_DEBUG */ + + switch(cmd) { case CCISS_GETPCIINFO: - { - cciss_pci_info_struct pciinfo; - - if (!arg) - return -EINVAL; - pciinfo.domain = pci_domain_nr(host->pdev->bus); - pciinfo.bus = host->pdev->bus->number; - pciinfo.dev_fn = host->pdev->devfn; - pciinfo.board_id = host->board_id; - if (copy_to_user - (argp, &pciinfo, sizeof(cciss_pci_info_struct))) - return -EFAULT; - return 0; - } + { + cciss_pci_info_struct pciinfo; + + if (!arg) return -EINVAL; + pciinfo.domain = pci_domain_nr(host->pdev->bus); + pciinfo.bus = host->pdev->bus->number; + pciinfo.dev_fn = host->pdev->devfn; + pciinfo.board_id = host->board_id; + if (copy_to_user(argp, &pciinfo, sizeof( cciss_pci_info_struct ))) + return -EFAULT; + return(0); + } case CCISS_GETINTINFO: - { - cciss_coalint_struct intinfo; - if (!arg) - return -EINVAL; - intinfo.delay = - readl(&host->cfgtable->HostWrite.CoalIntDelay); - intinfo.count = - readl(&host->cfgtable->HostWrite.CoalIntCount); - if (copy_to_user - (argp, &intinfo, sizeof(cciss_coalint_struct))) - return -EFAULT; - return 0; - } + { + cciss_coalint_struct intinfo; + if (!arg) return -EINVAL; + intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay); + intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount); + if (copy_to_user(argp, &intinfo, sizeof( cciss_coalint_struct ))) + return -EFAULT; + return(0); + } case CCISS_SETINTINFO: - { - cciss_coalint_struct intinfo; - unsigned long flags; - int i; + { + cciss_coalint_struct intinfo; + unsigned long flags; + int i; - if (!arg) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (copy_from_user - (&intinfo, argp, sizeof(cciss_coalint_struct))) - return -EFAULT; - if ((intinfo.delay == 0) && (intinfo.count == 0)) - { -// printk("cciss_ioctl: delay and count cannot be 0\n"); - return -EINVAL; - } - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - /* Update the field, and then ring the doorbell */ - writel(intinfo.delay, - &(host->cfgtable->HostWrite.CoalIntDelay)); - writel(intinfo.count, - &(host->cfgtable->HostWrite.CoalIntCount)); - writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); - - for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { - if (!(readl(host->vaddr + SA5_DOORBELL) - & CFGTBL_ChangeReq)) - break; - /* delay and try again */ - udelay(1000); - } - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - if (i >= MAX_IOCTL_CONFIG_WAIT) - return -EAGAIN; - return 0; - } - case CCISS_GETNODENAME: - { - NodeName_type NodeName; - int i; + if (!arg) return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if (copy_from_user(&intinfo, argp, sizeof( cciss_coalint_struct))) + return -EFAULT; + if ( (intinfo.delay == 0 ) && (intinfo.count == 0)) - if (!arg) - return -EINVAL; - for (i = 0; i < 16; i++) - NodeName[i] = - readb(&host->cfgtable->ServerName[i]); - if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) - return -EFAULT; - return 0; - } - case CCISS_SETNODENAME: { - NodeName_type NodeName; - unsigned long flags; - int i; - - if (!arg) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (copy_from_user - (NodeName, argp, sizeof(NodeName_type))) - return -EFAULT; - - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - - /* Update the field, and then ring the doorbell */ - for (i = 0; i < 16; i++) - writeb(NodeName[i], - &host->cfgtable->ServerName[i]); - - writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); - - for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { - if (!(readl(host->vaddr + SA5_DOORBELL) - & CFGTBL_ChangeReq)) - break; - /* delay and try again */ - udelay(1000); - } - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - if (i >= MAX_IOCTL_CONFIG_WAIT) - return -EAGAIN; - return 0; +// printk("cciss_ioctl: delay and count cannot be 0\n"); + return( -EINVAL); } + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + /* Update the field, and then ring the doorbell */ + writel( intinfo.delay, + &(host->cfgtable->HostWrite.CoalIntDelay)); + writel( intinfo.count, + &(host->cfgtable->HostWrite.CoalIntCount)); + writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); + + for(i=0;ivaddr + SA5_DOORBELL) + & CFGTBL_ChangeReq)) + break; + /* delay and try again */ + udelay(1000); + } + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + if (i >= MAX_IOCTL_CONFIG_WAIT) + return -EAGAIN; + return(0); + } + case CCISS_GETNODENAME: + { + NodeName_type NodeName; + int i; + + if (!arg) return -EINVAL; + for(i=0;i<16;i++) + NodeName[i] = readb(&host->cfgtable->ServerName[i]); + if (copy_to_user(argp, NodeName, sizeof( NodeName_type))) + return -EFAULT; + return(0); + } + case CCISS_SETNODENAME: + { + NodeName_type NodeName; + unsigned long flags; + int i; + + if (!arg) return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + + if (copy_from_user(NodeName, argp, sizeof( NodeName_type))) + return -EFAULT; + + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + + /* Update the field, and then ring the doorbell */ + for(i=0;i<16;i++) + writeb( NodeName[i], &host->cfgtable->ServerName[i]); + + writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); + + for(i=0;ivaddr + SA5_DOORBELL) + & CFGTBL_ChangeReq)) + break; + /* delay and try again */ + udelay(1000); + } + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + if (i >= MAX_IOCTL_CONFIG_WAIT) + return -EAGAIN; + return(0); + } case CCISS_GETHEARTBEAT: - { - Heartbeat_type heartbeat; - - if (!arg) - return -EINVAL; - heartbeat = readl(&host->cfgtable->HeartBeat); - if (copy_to_user - (argp, &heartbeat, sizeof(Heartbeat_type))) - return -EFAULT; - return 0; - } + { + Heartbeat_type heartbeat; + + if (!arg) return -EINVAL; + heartbeat = readl(&host->cfgtable->HeartBeat); + if (copy_to_user(argp, &heartbeat, sizeof( Heartbeat_type))) + return -EFAULT; + return(0); + } case CCISS_GETBUSTYPES: - { - BusTypes_type BusTypes; - - if (!arg) - return -EINVAL; - BusTypes = readl(&host->cfgtable->BusTypes); - if (copy_to_user - (argp, &BusTypes, sizeof(BusTypes_type))) - return -EFAULT; - return 0; - } + { + BusTypes_type BusTypes; + + if (!arg) return -EINVAL; + BusTypes = readl(&host->cfgtable->BusTypes); + if (copy_to_user(argp, &BusTypes, sizeof( BusTypes_type) )) + return -EFAULT; + return(0); + } case CCISS_GETFIRMVER: - { - FirmwareVer_type firmware; + { + FirmwareVer_type firmware; - if (!arg) - return -EINVAL; - memcpy(firmware, host->firm_ver, 4); + if (!arg) return -EINVAL; + memcpy(firmware, host->firm_ver, 4); - if (copy_to_user - (argp, firmware, sizeof(FirmwareVer_type))) - return -EFAULT; - return 0; - } - case CCISS_GETDRIVVER: - { - DriverVer_type DriverVer = DRIVER_VERSION; + if (copy_to_user(argp, firmware, sizeof( FirmwareVer_type))) + return -EFAULT; + return(0); + } + case CCISS_GETDRIVVER: + { + DriverVer_type DriverVer = DRIVER_VERSION; - if (!arg) - return -EINVAL; + if (!arg) return -EINVAL; - if (copy_to_user - (argp, &DriverVer, sizeof(DriverVer_type))) - return -EFAULT; - return 0; - } + if (copy_to_user(argp, &DriverVer, sizeof( DriverVer_type) )) + return -EFAULT; + return(0); + } case CCISS_REVALIDVOLS: if (bdev != bdev->bd_contains || drv != host->drv) return -ENXIO; - return revalidate_allvol(host); - - case CCISS_GETLUNINFO:{ - LogvolInfo_struct luninfo; - - luninfo.LunID = drv->LunID; - luninfo.num_opens = drv->usage_count; - luninfo.num_parts = 0; - if (copy_to_user(argp, &luninfo, - sizeof(LogvolInfo_struct))) - return -EFAULT; - return 0; - } + return revalidate_allvol(host); + + case CCISS_GETLUNINFO: { + LogvolInfo_struct luninfo; + + luninfo.LunID = drv->LunID; + luninfo.num_opens = drv->usage_count; + luninfo.num_parts = 0; + if (copy_to_user(argp, &luninfo, + sizeof(LogvolInfo_struct))) + return -EFAULT; + return(0); + } case CCISS_DEREGDISK: return rebuild_lun_table(host, disk); @@ -871,284 +837,278 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, return rebuild_lun_table(host, NULL); case CCISS_PASSTHRU: + { + IOCTL_Command_struct iocommand; + CommandList_struct *c; + char *buff = NULL; + u64bit temp64; + unsigned long flags; + DECLARE_COMPLETION(wait); + + if (!arg) return -EINVAL; + + if (!capable(CAP_SYS_RAWIO)) return -EPERM; + + if (copy_from_user(&iocommand, argp, sizeof( IOCTL_Command_struct) )) + return -EFAULT; + if((iocommand.buf_size < 1) && + (iocommand.Request.Type.Direction != XFER_NONE)) + { + return -EINVAL; + } +#if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */ + /* Check kmalloc limits */ + if(iocommand.buf_size > 128000) + return -EINVAL; +#endif + if(iocommand.buf_size > 0) { - IOCTL_Command_struct iocommand; - CommandList_struct *c; - char *buff = NULL; - u64bit temp64; - unsigned long flags; - DECLARE_COMPLETION(wait); - - if (!arg) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - if (copy_from_user - (&iocommand, argp, sizeof(IOCTL_Command_struct))) + buff = kmalloc(iocommand.buf_size, GFP_KERNEL); + if( buff == NULL) return -EFAULT; - if ((iocommand.buf_size < 1) && - (iocommand.Request.Type.Direction != XFER_NONE)) { - return -EINVAL; - } -#if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */ - /* Check kmalloc limits */ - if (iocommand.buf_size > 128000) - return -EINVAL; -#endif - if (iocommand.buf_size > 0) { - buff = kmalloc(iocommand.buf_size, GFP_KERNEL); - if (buff == NULL) - return -EFAULT; - } - if (iocommand.Request.Type.Direction == XFER_WRITE) { - /* Copy the data into the buffer we created */ - if (copy_from_user - (buff, iocommand.buf, iocommand.buf_size)) { - kfree(buff); - return -EFAULT; - } - } else { - memset(buff, 0, iocommand.buf_size); - } - if ((c = cmd_alloc(host, 0)) == NULL) { - kfree(buff); - return -ENOMEM; - } - // Fill in the command type - c->cmd_type = CMD_IOCTL_PEND; - // Fill in Command Header - c->Header.ReplyQueue = 0; // unused in simple mode - if (iocommand.buf_size > 0) // buffer to fill - { - c->Header.SGList = 1; - c->Header.SGTotal = 1; - } else // no buffers to fill + } + if (iocommand.Request.Type.Direction == XFER_WRITE) + { + /* Copy the data into the buffer we created */ + if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) { - c->Header.SGList = 0; - c->Header.SGTotal = 0; - } - c->Header.LUN = iocommand.LUN_info; - c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag - - // Fill in Request block - c->Request = iocommand.Request; - - // Fill in the scatter gather information - if (iocommand.buf_size > 0) { - temp64.val = pci_map_single(host->pdev, buff, - iocommand.buf_size, - PCI_DMA_BIDIRECTIONAL); - c->SG[0].Addr.lower = temp64.val32.lower; - c->SG[0].Addr.upper = temp64.val32.upper; - c->SG[0].Len = iocommand.buf_size; - c->SG[0].Ext = 0; // we are not chaining - } - c->waiting = &wait; - - /* Put the request on the tail of the request queue */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - addQ(&host->reqQ, c); - host->Qdepth++; - start_io(host); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - - wait_for_completion(&wait); - - /* unlock the buffers from DMA */ - temp64.val32.lower = c->SG[0].Addr.lower; - temp64.val32.upper = c->SG[0].Addr.upper; - pci_unmap_single(host->pdev, (dma_addr_t) temp64.val, - iocommand.buf_size, - PCI_DMA_BIDIRECTIONAL); - - /* Copy the error information out */ - iocommand.error_info = *(c->err_info); - if (copy_to_user - (argp, &iocommand, sizeof(IOCTL_Command_struct))) { kfree(buff); - cmd_free(host, c, 0); return -EFAULT; } + } else { + memset(buff, 0, iocommand.buf_size); + } + if ((c = cmd_alloc(host , 0)) == NULL) + { + kfree(buff); + return -ENOMEM; + } + // Fill in the command type + c->cmd_type = CMD_IOCTL_PEND; + // Fill in Command Header + c->Header.ReplyQueue = 0; // unused in simple mode + if( iocommand.buf_size > 0) // buffer to fill + { + c->Header.SGList = 1; + c->Header.SGTotal= 1; + } else // no buffers to fill + { + c->Header.SGList = 0; + c->Header.SGTotal= 0; + } + c->Header.LUN = iocommand.LUN_info; + c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag + + // Fill in Request block + c->Request = iocommand.Request; + + // Fill in the scatter gather information + if (iocommand.buf_size > 0 ) + { + temp64.val = pci_map_single( host->pdev, buff, + iocommand.buf_size, + PCI_DMA_BIDIRECTIONAL); + c->SG[0].Addr.lower = temp64.val32.lower; + c->SG[0].Addr.upper = temp64.val32.upper; + c->SG[0].Len = iocommand.buf_size; + c->SG[0].Ext = 0; // we are not chaining + } + c->waiting = &wait; - if (iocommand.Request.Type.Direction == XFER_READ) { - /* Copy the data out of the buffer we created */ - if (copy_to_user - (iocommand.buf, buff, iocommand.buf_size)) { - kfree(buff); - cmd_free(host, c, 0); - return -EFAULT; - } - } + /* Put the request on the tail of the request queue */ + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + addQ(&host->reqQ, c); + host->Qdepth++; + start_io(host); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + + wait_for_completion(&wait); + + /* unlock the buffers from DMA */ + temp64.val32.lower = c->SG[0].Addr.lower; + temp64.val32.upper = c->SG[0].Addr.upper; + pci_unmap_single( host->pdev, (dma_addr_t) temp64.val, + iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); + + /* Copy the error information out */ + iocommand.error_info = *(c->err_info); + if ( copy_to_user(argp, &iocommand, sizeof( IOCTL_Command_struct) ) ) + { kfree(buff); cmd_free(host, c, 0); - return 0; - } - case CCISS_BIG_PASSTHRU:{ - BIG_IOCTL_Command_struct *ioc; - CommandList_struct *c; - unsigned char **buff = NULL; - int *buff_size = NULL; - u64bit temp64; - unsigned long flags; - BYTE sg_used = 0; - int status = 0; - int i; - DECLARE_COMPLETION(wait); - __u32 left; - __u32 sz; - BYTE __user *data_ptr; - - if (!arg) - return -EINVAL; - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - ioc = (BIG_IOCTL_Command_struct *) - kmalloc(sizeof(*ioc), GFP_KERNEL); - if (!ioc) { - status = -ENOMEM; - goto cleanup1; - } - if (copy_from_user(ioc, argp, sizeof(*ioc))) { - status = -EFAULT; - goto cleanup1; - } - if ((ioc->buf_size < 1) && - (ioc->Request.Type.Direction != XFER_NONE)) { - status = -EINVAL; - goto cleanup1; - } - /* Check kmalloc limits using all SGs */ - if (ioc->malloc_size > MAX_KMALLOC_SIZE) { - status = -EINVAL; - goto cleanup1; + return( -EFAULT); + } + + if (iocommand.Request.Type.Direction == XFER_READ) + { + /* Copy the data out of the buffer we created */ + if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) + { + kfree(buff); + cmd_free(host, c, 0); + return -EFAULT; } - if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) { + } + kfree(buff); + cmd_free(host, c, 0); + return(0); + } + case CCISS_BIG_PASSTHRU: { + BIG_IOCTL_Command_struct *ioc; + CommandList_struct *c; + unsigned char **buff = NULL; + int *buff_size = NULL; + u64bit temp64; + unsigned long flags; + BYTE sg_used = 0; + int status = 0; + int i; + DECLARE_COMPLETION(wait); + __u32 left; + __u32 sz; + BYTE __user *data_ptr; + + if (!arg) + return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + ioc = (BIG_IOCTL_Command_struct *) + kmalloc(sizeof(*ioc), GFP_KERNEL); + if (!ioc) { + status = -ENOMEM; + goto cleanup1; + } + if (copy_from_user(ioc, argp, sizeof(*ioc))) { + status = -EFAULT; + goto cleanup1; + } + if ((ioc->buf_size < 1) && + (ioc->Request.Type.Direction != XFER_NONE)) { status = -EINVAL; goto cleanup1; - } - buff = - kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL); - if (!buff) { - status = -ENOMEM; - goto cleanup1; - } - buff_size = (int *)kmalloc(MAXSGENTRIES * sizeof(int), - GFP_KERNEL); - if (!buff_size) { + } + /* Check kmalloc limits using all SGs */ + if (ioc->malloc_size > MAX_KMALLOC_SIZE) { + status = -EINVAL; + goto cleanup1; + } + if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) { + status = -EINVAL; + goto cleanup1; + } + buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL); + if (!buff) { + status = -ENOMEM; + goto cleanup1; + } + buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), + GFP_KERNEL); + if (!buff_size) { + status = -ENOMEM; + goto cleanup1; + } + left = ioc->buf_size; + data_ptr = ioc->buf; + while (left) { + sz = (left > ioc->malloc_size) ? ioc->malloc_size : left; + buff_size[sg_used] = sz; + buff[sg_used] = kmalloc(sz, GFP_KERNEL); + if (buff[sg_used] == NULL) { status = -ENOMEM; goto cleanup1; } - left = ioc->buf_size; - data_ptr = ioc->buf; - while (left) { - sz = (left > - ioc->malloc_size) ? ioc-> - malloc_size : left; - buff_size[sg_used] = sz; - buff[sg_used] = kmalloc(sz, GFP_KERNEL); - if (buff[sg_used] == NULL) { + if (ioc->Request.Type.Direction == XFER_WRITE) { + if (copy_from_user(buff[sg_used], data_ptr, sz)) { status = -ENOMEM; goto cleanup1; } - if (ioc->Request.Type.Direction == XFER_WRITE) { - if (copy_from_user - (buff[sg_used], data_ptr, sz)) { - status = -ENOMEM; - goto cleanup1; - } - } else { - memset(buff[sg_used], 0, sz); - } - left -= sz; - data_ptr += sz; - sg_used++; - } - if ((c = cmd_alloc(host, 0)) == NULL) { - status = -ENOMEM; - goto cleanup1; - } - c->cmd_type = CMD_IOCTL_PEND; - c->Header.ReplyQueue = 0; - - if (ioc->buf_size > 0) { - c->Header.SGList = sg_used; - c->Header.SGTotal = sg_used; } else { - c->Header.SGList = 0; - c->Header.SGTotal = 0; - } - c->Header.LUN = ioc->LUN_info; - c->Header.Tag.lower = c->busaddr; - - c->Request = ioc->Request; - if (ioc->buf_size > 0) { - int i; - for (i = 0; i < sg_used; i++) { - temp64.val = - pci_map_single(host->pdev, buff[i], - buff_size[i], - PCI_DMA_BIDIRECTIONAL); - c->SG[i].Addr.lower = - temp64.val32.lower; - c->SG[i].Addr.upper = - temp64.val32.upper; - c->SG[i].Len = buff_size[i]; - c->SG[i].Ext = 0; /* we are not chaining */ - } + memset(buff[sg_used], 0, sz); } - c->waiting = &wait; - /* Put the request on the tail of the request queue */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - addQ(&host->reqQ, c); - host->Qdepth++; - start_io(host); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - wait_for_completion(&wait); - /* unlock the buffers from DMA */ - for (i = 0; i < sg_used; i++) { - temp64.val32.lower = c->SG[i].Addr.lower; - temp64.val32.upper = c->SG[i].Addr.upper; - pci_unmap_single(host->pdev, - (dma_addr_t) temp64.val, buff_size[i], + left -= sz; + data_ptr += sz; + sg_used++; + } + if ((c = cmd_alloc(host , 0)) == NULL) { + status = -ENOMEM; + goto cleanup1; + } + c->cmd_type = CMD_IOCTL_PEND; + c->Header.ReplyQueue = 0; + + if( ioc->buf_size > 0) { + c->Header.SGList = sg_used; + c->Header.SGTotal= sg_used; + } else { + c->Header.SGList = 0; + c->Header.SGTotal= 0; + } + c->Header.LUN = ioc->LUN_info; + c->Header.Tag.lower = c->busaddr; + + c->Request = ioc->Request; + if (ioc->buf_size > 0 ) { + int i; + for(i=0; ipdev, buff[i], + buff_size[i], PCI_DMA_BIDIRECTIONAL); + c->SG[i].Addr.lower = temp64.val32.lower; + c->SG[i].Addr.upper = temp64.val32.upper; + c->SG[i].Len = buff_size[i]; + c->SG[i].Ext = 0; /* we are not chaining */ } - /* Copy the error information out */ - ioc->error_info = *(c->err_info); - if (copy_to_user(argp, ioc, sizeof(*ioc))) { - cmd_free(host, c, 0); - status = -EFAULT; - goto cleanup1; - } - if (ioc->Request.Type.Direction == XFER_READ) { - /* Copy the data out of the buffer we created */ - BYTE __user *ptr = ioc->buf; - for (i = 0; i < sg_used; i++) { - if (copy_to_user - (ptr, buff[i], buff_size[i])) { - cmd_free(host, c, 0); - status = -EFAULT; - goto cleanup1; - } - ptr += buff_size[i]; - } - } + } + c->waiting = &wait; + /* Put the request on the tail of the request queue */ + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + addQ(&host->reqQ, c); + host->Qdepth++; + start_io(host); + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + wait_for_completion(&wait); + /* unlock the buffers from DMA */ + for(i=0; iSG[i].Addr.lower; + temp64.val32.upper = c->SG[i].Addr.upper; + pci_unmap_single( host->pdev, (dma_addr_t) temp64.val, + buff_size[i], PCI_DMA_BIDIRECTIONAL); + } + /* Copy the error information out */ + ioc->error_info = *(c->err_info); + if (copy_to_user(argp, ioc, sizeof(*ioc))) { cmd_free(host, c, 0); - status = 0; - cleanup1: - if (buff) { - for (i = 0; i < sg_used; i++) - kfree(buff[i]); - kfree(buff); + status = -EFAULT; + goto cleanup1; + } + if (ioc->Request.Type.Direction == XFER_READ) { + /* Copy the data out of the buffer we created */ + BYTE __user *ptr = ioc->buf; + for(i=0; i< sg_used; i++) { + if (copy_to_user(ptr, buff[i], buff_size[i])) { + cmd_free(host, c, 0); + status = -EFAULT; + goto cleanup1; + } + ptr += buff_size[i]; } - kfree(buff_size); - kfree(ioc); - return status; } + cmd_free(host, c, 0); + status = 0; +cleanup1: + if (buff) { + for(i=0; ictlr, i; unsigned long flags; - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - if (host->usage_count > 1) { - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - printk(KERN_WARNING "cciss: Device busy for volume" - " revalidation (usage=%d)\n", host->usage_count); - return -EBUSY; - } - host->usage_count++; + spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + if (host->usage_count > 1) { + spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + printk(KERN_WARNING "cciss: Device busy for volume" + " revalidation (usage=%d)\n", host->usage_count); + return -EBUSY; + } + host->usage_count++; spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - for (i = 0; i < NWD; i++) { + for(i=0; i< NWD; i++) { struct gendisk *disk = host->gendisk[i]; if (disk) { request_queue_t *q = disk->queue; @@ -1189,22 +1149,22 @@ static int revalidate_allvol(ctlr_info_t *host) } } - /* - * Set the partition and block size structures for all volumes - * on this controller to zero. We will reread all of this data - */ - memset(host->drv, 0, sizeof(drive_info_struct) - * CISS_MAX_LUN); - /* - * Tell the array controller not to give us any interrupts while - * we check the new geometry. Then turn interrupts back on when - * we're done. - */ - host->access.set_intr_mask(host, CCISS_INTR_OFF); - cciss_getgeometry(ctlr); - host->access.set_intr_mask(host, CCISS_INTR_ON); - - /* Loop through each real device */ + /* + * Set the partition and block size structures for all volumes + * on this controller to zero. We will reread all of this data + */ + memset(host->drv, 0, sizeof(drive_info_struct) + * CISS_MAX_LUN); + /* + * Tell the array controller not to give us any interrupts while + * we check the new geometry. Then turn interrupts back on when + * we're done. + */ + host->access.set_intr_mask(host, CCISS_INTR_OFF); + cciss_getgeometry(ctlr); + host->access.set_intr_mask(host, CCISS_INTR_ON); + + /* Loop through each real device */ for (i = 0; i < NWD; i++) { struct gendisk *disk = host->gendisk[i]; drive_info_struct *drv = &(host->drv[i]); @@ -1216,8 +1176,8 @@ static int revalidate_allvol(ctlr_info_t *host) set_capacity(disk, drv->nr_blocks); add_disk(disk); } - host->usage_count--; - return 0; + host->usage_count--; + return 0; } static inline void complete_buffers(struct bio *bio, int status) @@ -1231,6 +1191,7 @@ static inline void complete_buffers(struct bio *bio, int status) bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); bio = xbh; } + } static void cciss_softirq_done(struct request *rq) @@ -1248,7 +1209,7 @@ static void cciss_softirq_done(struct request *rq) /* command did not need to be retried */ /* unmap the DMA mapping for all the scatter gather elements */ - for (i = 0; i < cmd->Header.SGList; i++) { + for(i=0; iHeader.SGList; i++) { temp64.val32.lower = cmd->SG[i].Addr.lower; temp64.val32.upper = cmd->SG[i].Addr.upper; pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); @@ -1258,12 +1219,11 @@ static void cciss_softirq_done(struct request *rq) #ifdef CCISS_DEBUG printk("Done with %p\n", rq); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ - add_disk_randomness(rq->rq_disk); spin_lock_irqsave(&h->lock, flags); end_that_request_last(rq, rq->errors); - cmd_free(h, cmd, 1); + cmd_free(h, cmd,1); spin_unlock_irqrestore(&h->lock, flags); } @@ -1274,9 +1234,9 @@ static void cciss_softirq_done(struct request *rq) * will always be left registered with the kernel since it is also the * controller node. Any changes to disk 0 will show up on the next * reboot. - */ +*/ static void cciss_update_drive_info(int ctlr, int drv_index) -{ + { ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; ReadCapdata_struct *size_buff = NULL; @@ -1286,13 +1246,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index) unsigned long flags = 0; int ret = 0; - /* if the disk already exists then deregister it before proceeding */ - if (h->drv[drv_index].raid_level != -1) { + /* if the disk already exists then deregister it before proceeding*/ + if (h->drv[drv_index].raid_level != -1){ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); h->drv[drv_index].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); ret = deregister_disk(h->gendisk[drv_index], - &h->drv[drv_index], 0); + &h->drv[drv_index], 0); h->drv[drv_index].busy_configuring = 0; } @@ -1300,25 +1260,27 @@ static void cciss_update_drive_info(int ctlr, int drv_index) if (ret) return; - /* Get information about the disk and modify the driver structure */ - size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (size_buff == NULL) + + /* Get information about the disk and modify the driver sturcture */ + size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) goto mem_msg; - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); + inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) goto mem_msg; cciss_read_capacity(ctlr, drv_index, size_buff, 1, - &total_size, &block_size); + &total_size, &block_size); cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, - inq_buff, &h->drv[drv_index]); + inq_buff, &h->drv[drv_index]); ++h->num_luns; disk = h->gendisk[drv_index]; set_capacity(disk, h->drv[drv_index].nr_blocks); + /* if it's the controller it's already added */ - if (drv_index) { + if (drv_index){ disk->queue = blk_init_queue(do_cciss_request, &h->lock); /* Set up queue information */ @@ -1338,17 +1300,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index) disk->queue->queuedata = hba[ctlr]; blk_queue_hardsect_size(disk->queue, - hba[ctlr]->drv[drv_index].block_size); + hba[ctlr]->drv[drv_index].block_size); h->drv[drv_index].queue = disk->queue; add_disk(disk); } - freeret: +freeret: kfree(size_buff); kfree(inq_buff); return; - mem_msg: +mem_msg: printk(KERN_ERR "cciss: out of memory\n"); goto freeret; } @@ -1358,13 +1320,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index) * where new drives will be added. If the index to be returned is greater * than the highest_lun index for the controller then highest_lun is set * to this new index. If there are no available indexes then -1 is returned. - */ +*/ static int cciss_find_free_drive_index(int ctlr) { int i; - for (i = 0; i < CISS_MAX_LUN; i++) { - if (hba[ctlr]->drv[i].raid_level == -1) { + for (i=0; i < CISS_MAX_LUN; i++){ + if (hba[ctlr]->drv[i].raid_level == -1){ if (i > hba[ctlr]->highest_lun) hba[ctlr]->highest_lun = i; return i; @@ -1374,7 +1336,7 @@ static int cciss_find_free_drive_index(int ctlr) } /* This function will add and remove logical drives from the Logical - * drive array of the controller and maintain persistency of ordering + * drive array of the controller and maintain persistancy of ordering * so that mount points are preserved until the next reboot. This allows * for the removal of logical drives in the middle of the drive array * without a re-ordering of those drives. @@ -1382,7 +1344,7 @@ static int cciss_find_free_drive_index(int ctlr) * h = The controller to perform the operations on * del_disk = The disk to remove if specified. If the value given * is NULL then no disk is removed. - */ +*/ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) { int ctlr = h->ctlr; @@ -1399,12 +1361,12 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) /* Set busy_configuring flag for this operation */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - if (h->num_luns >= CISS_MAX_LUN) { + if (h->num_luns >= CISS_MAX_LUN){ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return -EINVAL; } - if (h->busy_configuring) { + if (h->busy_configuring){ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return -EBUSY; } @@ -1414,7 +1376,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) * and update the logical drive table. If it is not NULL then * we will check if the disk is in use or not. */ - if (del_disk != NULL) { + if (del_disk != NULL){ drv = get_drv(del_disk); drv->busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); @@ -1432,67 +1394,61 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) goto mem_msg; return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, - sizeof(ReportLunData_struct), 0, - 0, 0, TYPE_CMD); - - if (return_code == IO_OK) { - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[0])) - << 24; - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[1])) - << 16; - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[2])) - << 8; - listlength |= - 0xff & (unsigned int)(ld_buff->LUNListLength[3]); - } else { /* reading number of logical volumes failed */ + sizeof(ReportLunData_struct), 0, 0, 0, + TYPE_CMD); + + if (return_code == IO_OK){ + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; + listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); + } else{ /* reading number of logical volumes failed */ printk(KERN_WARNING "cciss: report logical volume" - " command failed\n"); + " command failed\n"); listlength = 0; goto freeret; } num_luns = listlength / 8; /* 8 bytes per entry */ - if (num_luns > CISS_MAX_LUN) { + if (num_luns > CISS_MAX_LUN){ num_luns = CISS_MAX_LUN; printk(KERN_WARNING "cciss: more luns configured" - " on controller than can be handled by" - " this driver.\n"); + " on controller than can be handled by" + " this driver.\n"); } /* Compare controller drive array to drivers drive array. - * Check for updates in the drive information and any new drives - * on the controller. - */ - for (i = 0; i < num_luns; i++) { + * Check for updates in the drive information and any new drives + * on the controller. + */ + for (i=0; i < num_luns; i++){ int j; drv_found = 0; - lunid = (0xff & - (unsigned int)(ld_buff->LUN[i][3])) << 24; - lunid |= (0xff & - (unsigned int)(ld_buff->LUN[i][2])) << 16; - lunid |= (0xff & - (unsigned int)(ld_buff->LUN[i][1])) << 8; - lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); + lunid = (0xff & + (unsigned int)(ld_buff->LUN[i][3])) << 24; + lunid |= (0xff & + (unsigned int)(ld_buff->LUN[i][2])) << 16; + lunid |= (0xff & + (unsigned int)(ld_buff->LUN[i][1])) << 8; + lunid |= 0xff & + (unsigned int)(ld_buff->LUN[i][0]); /* Find if the LUN is already in the drive array * of the controller. If so then update its info * if not is use. If it does not exist then find * the first free index and add it. - */ - for (j = 0; j <= h->highest_lun; j++) { - if (h->drv[j].LunID == lunid) { + */ + for (j=0; j <= h->highest_lun; j++){ + if (h->drv[j].LunID == lunid){ drv_index = j; drv_found = 1; } } /* check if the drive was found already in the array */ - if (!drv_found) { + if (!drv_found){ drv_index = cciss_find_free_drive_index(ctlr); if (drv_index == -1) goto freeret; @@ -1500,18 +1456,18 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) } h->drv[drv_index].LunID = lunid; cciss_update_drive_info(ctlr, drv_index); - } /* end for */ - } /* end else */ + } /* end for */ + } /* end else */ - freeret: +freeret: kfree(ld_buff); h->busy_configuring = 0; /* We return -1 here to tell the ACU that we have registered/updated * all of the drives that we can and to keep it from calling us * additional times. - */ + */ return -1; - mem_msg: +mem_msg: printk(KERN_ERR "cciss: out of memory\n"); goto freeret; } @@ -1527,7 +1483,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) * clear_all = This flag determines whether or not the disk information * is going to be completely cleared out and the highest_lun * reset. Sometimes we want to clear out information about - * the disk in preparation for re-adding it. In this case + * the disk in preperation for re-adding it. In this case * the highest_lun should be left unchanged and the LunID * should not be cleared. */ @@ -1540,17 +1496,19 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, return -EPERM; /* make sure logical volume is NOT is use */ - if (clear_all || (h->gendisk[0] == disk)) { - if (drv->usage_count > 1) - return -EBUSY; - } else if (drv->usage_count > 0) - return -EBUSY; + if(clear_all || (h->gendisk[0] == disk)) { + if (drv->usage_count > 1) + return -EBUSY; + } + else + if( drv->usage_count > 0 ) + return -EBUSY; /* invalidate the devices and deregister the disk. If it is disk * zero do not deregister it but just zero out it's values. This * allows us to delete disk zero but keep the controller registered. - */ - if (h->gendisk[0] != disk) { + */ + if (h->gendisk[0] != disk){ if (disk) { request_queue_t *q = disk->queue; if (disk->flags & GENHD_FL_UP) @@ -1572,90 +1530,91 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, drv->raid_level = -1; /* This can be used as a flag variable to * indicate that this element of the drive * array is free. - */ - - if (clear_all) { - /* check to see if it was the last disk */ - if (drv == h->drv + h->highest_lun) { - /* if so, find the new hightest lun */ - int i, newhighest = -1; - for (i = 0; i < h->highest_lun; i++) { - /* if the disk has size > 0, it is available */ + */ + + if (clear_all){ + /* check to see if it was the last disk */ + if (drv == h->drv + h->highest_lun) { + /* if so, find the new hightest lun */ + int i, newhighest =-1; + for(i=0; ihighest_lun; i++) { + /* if the disk has size > 0, it is available */ if (h->drv[i].heads) - newhighest = i; - } - h->highest_lun = newhighest; + newhighest = i; } + h->highest_lun = newhighest; + } - drv->LunID = 0; + drv->LunID = 0; } - return 0; + return(0); } -static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_t size, unsigned int use_unit_num, /* 0: address the controller, - 1: address logical volume log_unit, - 2: periph device address is scsi3addr */ - unsigned int log_unit, __u8 page_code, - unsigned char *scsi3addr, int cmd_type) +static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, + size_t size, + unsigned int use_unit_num, /* 0: address the controller, + 1: address logical volume log_unit, + 2: periph device address is scsi3addr */ + unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr, + int cmd_type) { - ctlr_info_t *h = hba[ctlr]; + ctlr_info_t *h= hba[ctlr]; u64bit buff_dma_handle; int status = IO_OK; c->cmd_type = CMD_IOCTL_PEND; c->Header.ReplyQueue = 0; - if (buff != NULL) { + if( buff != NULL) { c->Header.SGList = 1; - c->Header.SGTotal = 1; + c->Header.SGTotal= 1; } else { c->Header.SGList = 0; - c->Header.SGTotal = 0; + c->Header.SGTotal= 0; } c->Header.Tag.lower = c->busaddr; c->Request.Type.Type = cmd_type; if (cmd_type == TYPE_CMD) { - switch (cmd) { - case CISS_INQUIRY: + switch(cmd) { + case CISS_INQUIRY: /* If the logical unit number is 0 then, this is going - to controller so It's a physical command - mode = 0 target = 0. So we have nothing to write. - otherwise, if use_unit_num == 1, - mode = 1(volume set addressing) target = LUNID - otherwise, if use_unit_num == 2, - mode = 0(periph dev addr) target = scsi3addr */ + to controller so It's a physical command + mode = 0 target = 0. So we have nothing to write. + otherwise, if use_unit_num == 1, + mode = 1(volume set addressing) target = LUNID + otherwise, if use_unit_num == 2, + mode = 0(periph dev addr) target = scsi3addr */ if (use_unit_num == 1) { - c->Header.LUN.LogDev.VolId = - h->drv[log_unit].LunID; - c->Header.LUN.LogDev.Mode = 1; + c->Header.LUN.LogDev.VolId= + h->drv[log_unit].LunID; + c->Header.LUN.LogDev.Mode = 1; } else if (use_unit_num == 2) { - memcpy(c->Header.LUN.LunAddrBytes, scsi3addr, - 8); + memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8); c->Header.LUN.LogDev.Mode = 0; } /* are we trying to read a vital product page */ - if (page_code != 0) { + if(page_code != 0) { c->Request.CDB[1] = 0x01; c->Request.CDB[2] = page_code; } c->Request.CDBLen = 6; - c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; c->Request.Timeout = 0; - c->Request.CDB[0] = CISS_INQUIRY; - c->Request.CDB[4] = size & 0xFF; - break; + c->Request.CDB[0] = CISS_INQUIRY; + c->Request.CDB[4] = size & 0xFF; + break; case CISS_REPORT_LOG: case CISS_REPORT_PHYS: - /* Talking to controller so It's a physical command + /* Talking to controller so It's a physical command mode = 00 target = 0. Nothing to write. - */ + */ c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; c->Request.Timeout = 0; c->Request.CDB[0] = cmd; - c->Request.CDB[6] = (size >> 24) & 0xFF; //MSB + c->Request.CDB[6] = (size >> 24) & 0xFF; //MSB c->Request.CDB[7] = (size >> 16) & 0xFF; c->Request.CDB[8] = (size >> 8) & 0xFF; c->Request.CDB[9] = size & 0xFF; @@ -1669,7 +1628,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ c->Request.Type.Direction = XFER_READ; c->Request.Timeout = 0; c->Request.CDB[0] = cmd; - break; + break; case CCISS_CACHE_FLUSH: c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1677,32 +1636,32 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ c->Request.Timeout = 0; c->Request.CDB[0] = BMIC_WRITE; c->Request.CDB[6] = BMIC_CACHE_FLUSH; - break; + break; default: printk(KERN_WARNING - "cciss%d: Unknown Command 0x%c\n", ctlr, cmd); - return IO_ERROR; + "cciss%d: Unknown Command 0x%c\n", ctlr, cmd); + return(IO_ERROR); } } else if (cmd_type == TYPE_MSG) { switch (cmd) { - case 0: /* ABORT message */ + case 0: /* ABORT message */ c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_WRITE; c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; /* abort */ - c->Request.CDB[1] = 0; /* abort a command */ + c->Request.CDB[0] = cmd; /* abort */ + c->Request.CDB[1] = 0; /* abort a command */ /* buff contains the tag of the command to abort */ memcpy(&c->Request.CDB[4], buff, 8); break; - case 1: /* RESET message */ + case 1: /* RESET message */ c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_WRITE; c->Request.Timeout = 0; memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); - c->Request.CDB[0] = cmd; /* reset */ - c->Request.CDB[1] = 0x04; /* reset a LUN */ + c->Request.CDB[0] = cmd; /* reset */ + c->Request.CDB[1] = 0x04; /* reset a LUN */ case 3: /* No-Op message */ c->Request.CDBLen = 1; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1712,164 +1671,168 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ break; default: printk(KERN_WARNING - "cciss%d: unknown message type %d\n", ctlr, cmd); + "cciss%d: unknown message type %d\n", + ctlr, cmd); return IO_ERROR; } } else { printk(KERN_WARNING - "cciss%d: unknown command type %d\n", ctlr, cmd_type); + "cciss%d: unknown command type %d\n", ctlr, cmd_type); return IO_ERROR; } /* Fill in the scatter gather information */ if (size > 0) { buff_dma_handle.val = (__u64) pci_map_single(h->pdev, - buff, size, - PCI_DMA_BIDIRECTIONAL); + buff, size, PCI_DMA_BIDIRECTIONAL); c->SG[0].Addr.lower = buff_dma_handle.val32.lower; c->SG[0].Addr.upper = buff_dma_handle.val32.upper; c->SG[0].Len = size; - c->SG[0].Ext = 0; /* we are not chaining */ + c->SG[0].Ext = 0; /* we are not chaining */ } return status; } - -static int sendcmd_withirq(__u8 cmd, - int ctlr, - void *buff, - size_t size, - unsigned int use_unit_num, - unsigned int log_unit, __u8 page_code, int cmd_type) +static int sendcmd_withirq(__u8 cmd, + int ctlr, + void *buff, + size_t size, + unsigned int use_unit_num, + unsigned int log_unit, + __u8 page_code, + int cmd_type) { ctlr_info_t *h = hba[ctlr]; CommandList_struct *c; - u64bit buff_dma_handle; + u64bit buff_dma_handle; unsigned long flags; int return_status; DECLARE_COMPLETION(wait); - - if ((c = cmd_alloc(h, 0)) == NULL) + + if ((c = cmd_alloc(h , 0)) == NULL) return -ENOMEM; return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num, - log_unit, page_code, NULL, cmd_type); + log_unit, page_code, NULL, cmd_type); if (return_status != IO_OK) { cmd_free(h, c, 0); return return_status; } - resend_cmd2: +resend_cmd2: c->waiting = &wait; - + /* Put the request on the tail of the queue and send it */ spin_lock_irqsave(CCISS_LOCK(ctlr), flags); addQ(&h->reqQ, c); h->Qdepth++; start_io(h); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - + wait_for_completion(&wait); - if (c->err_info->CommandStatus != 0) { /* an error has occurred */ - switch (c->err_info->CommandStatus) { - case CMD_TARGET_STATUS: - printk(KERN_WARNING "cciss: cmd %p has " - " completed with errors\n", c); - if (c->err_info->ScsiStatus) { - printk(KERN_WARNING "cciss: cmd %p " - "has SCSI Status = %x\n", - c, c->err_info->ScsiStatus); - } + if(c->err_info->CommandStatus != 0) + { /* an error has occurred */ + switch(c->err_info->CommandStatus) + { + case CMD_TARGET_STATUS: + printk(KERN_WARNING "cciss: cmd %p has " + " completed with errors\n", c); + if( c->err_info->ScsiStatus) + { + printk(KERN_WARNING "cciss: cmd %p " + "has SCSI Status = %x\n", + c, + c->err_info->ScsiStatus); + } break; - case CMD_DATA_UNDERRUN: - case CMD_DATA_OVERRUN: + case CMD_DATA_UNDERRUN: + case CMD_DATA_OVERRUN: /* expected for inquire and report lun commands */ break; - case CMD_INVALID: - printk(KERN_WARNING "cciss: Cmd %p is " - "reported invalid\n", c); - return_status = IO_ERROR; - break; - case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cmd %p has " - "protocol error \n", c); - return_status = IO_ERROR; - break; - case CMD_HARDWARE_ERR: - printk(KERN_WARNING "cciss: cmd %p had " - " hardware error\n", c); - return_status = IO_ERROR; + case CMD_INVALID: + printk(KERN_WARNING "cciss: Cmd %p is " + "reported invalid\n", c); + return_status = IO_ERROR; break; - case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cmd %p had " - "connection lost\n", c); - return_status = IO_ERROR; + case CMD_PROTOCOL_ERR: + printk(KERN_WARNING "cciss: cmd %p has " + "protocol error \n", c); + return_status = IO_ERROR; + break; +case CMD_HARDWARE_ERR: + printk(KERN_WARNING "cciss: cmd %p had " + " hardware error\n", c); + return_status = IO_ERROR; + break; + case CMD_CONNECTION_LOST: + printk(KERN_WARNING "cciss: cmd %p had " + "connection lost\n", c); + return_status = IO_ERROR; break; - case CMD_ABORTED: - printk(KERN_WARNING "cciss: cmd %p was " - "aborted\n", c); - return_status = IO_ERROR; + case CMD_ABORTED: + printk(KERN_WARNING "cciss: cmd %p was " + "aborted\n", c); + return_status = IO_ERROR; break; - case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cmd %p reports " - "abort failed\n", c); - return_status = IO_ERROR; + case CMD_ABORT_FAILED: + printk(KERN_WARNING "cciss: cmd %p reports " + "abort failed\n", c); + return_status = IO_ERROR; break; - case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING - "cciss%d: unsolicited abort %p\n", ctlr, c); - if (c->retry_count < MAX_CMD_RETRIES) { - printk(KERN_WARNING - "cciss%d: retrying %p\n", ctlr, c); - c->retry_count++; - /* erase the old error information */ - memset(c->err_info, 0, - sizeof(ErrorInfo_struct)); - return_status = IO_OK; - INIT_COMPLETION(wait); - goto resend_cmd2; - } - return_status = IO_ERROR; + case CMD_UNSOLICITED_ABORT: + printk(KERN_WARNING + "cciss%d: unsolicited abort %p\n", + ctlr, c); + if (c->retry_count < MAX_CMD_RETRIES) { + printk(KERN_WARNING + "cciss%d: retrying %p\n", + ctlr, c); + c->retry_count++; + /* erase the old error information */ + memset(c->err_info, 0, + sizeof(ErrorInfo_struct)); + return_status = IO_OK; + INIT_COMPLETION(wait); + goto resend_cmd2; + } + return_status = IO_ERROR; break; - default: - printk(KERN_WARNING "cciss: cmd %p returned " - "unknown status %x\n", c, - c->err_info->CommandStatus); - return_status = IO_ERROR; + default: + printk(KERN_WARNING "cciss: cmd %p returned " + "unknown status %x\n", c, + c->err_info->CommandStatus); + return_status = IO_ERROR; } - } + } /* unlock the buffers from DMA */ buff_dma_handle.val32.lower = c->SG[0].Addr.lower; buff_dma_handle.val32.upper = c->SG[0].Addr.upper; - pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val, - c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); + pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val, + c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); cmd_free(h, c, 0); - return return_status; -} + return(return_status); +} static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, unsigned int total_size, - unsigned int block_size, - InquiryData_struct *inq_buff, - drive_info_struct *drv) + int withirq, unsigned int total_size, + unsigned int block_size, InquiryData_struct *inq_buff, + drive_info_struct *drv) { int return_code; memset(inq_buff, 0, sizeof(InquiryData_struct)); if (withirq) return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, - inq_buff, sizeof(*inq_buff), 1, - logvol, 0xC1, TYPE_CMD); + inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1, TYPE_CMD); else return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff, - sizeof(*inq_buff), 1, logvol, 0xC1, NULL, - TYPE_CMD); + sizeof(*inq_buff), 1, logvol ,0xC1, NULL, TYPE_CMD); if (return_code == IO_OK) { - if (inq_buff->data_byte[8] == 0xFF) { + if(inq_buff->data_byte[8] == 0xFF) { printk(KERN_WARNING - "cciss: reading geometry failed, volume " - "does not support reading geometry\n"); + "cciss: reading geometry failed, volume " + "does not support reading geometry\n"); drv->block_size = block_size; drv->nr_blocks = total_size; drv->heads = 255; - drv->sectors = 32; // Sectors per track + drv->sectors = 32; // Sectors per track drv->cylinders = total_size / 255 / 32; } else { unsigned int t; @@ -1883,42 +1846,37 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->raid_level = inq_buff->data_byte[8]; t = drv->heads * drv->sectors; if (t > 1) { - drv->cylinders = total_size / t; + drv->cylinders = total_size/t; } } - } else { /* Get geometry failed */ + } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); } printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n", - drv->heads, drv->sectors, drv->cylinders); + drv->heads, drv->sectors, drv->cylinders); } - static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, - int withirq, unsigned int *total_size, - unsigned int *block_size) + int withirq, unsigned int *total_size, unsigned int *block_size) { int return_code; memset(buf, 0, sizeof(*buf)); if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(*buf), 1, - logvol, 0, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, logvol, 0, TYPE_CMD); else return_code = sendcmd(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(*buf), 1, logvol, 0, - NULL, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = - be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; - *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0])); - } else { /* read capacity command failed */ + *total_size = be32_to_cpu(*((__be32 *) &buf->total_size[0]))+1; + *block_size = be32_to_cpu(*((__be32 *) &buf->block_size[0])); + } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } printk(KERN_INFO " blocks= %u block_size= %d\n", - *total_size, *block_size); + *total_size, *block_size); return; } @@ -1927,38 +1885,38 @@ static int cciss_revalidate(struct gendisk *disk) ctlr_info_t *h = get_host(disk); drive_info_struct *drv = get_drv(disk); int logvol; - int FOUND = 0; + int FOUND=0; unsigned int block_size; unsigned int total_size; ReadCapdata_struct *size_buff = NULL; InquiryData_struct *inq_buff = NULL; - for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { - if (h->drv[logvol].LunID == drv->LunID) { - FOUND = 1; + for(logvol=0; logvol < CISS_MAX_LUN; logvol++) + { + if(h->drv[logvol].LunID == drv->LunID) { + FOUND=1; break; } } - if (!FOUND) - return 1; + if (!FOUND) return 1; - size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (size_buff == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); - return 1; - } - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - if (inq_buff == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); + size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) + { + printk(KERN_WARNING "cciss: out of memory\n"); + return 1; + } + inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); + if (inq_buff == NULL) + { + printk(KERN_WARNING "cciss: out of memory\n"); kfree(size_buff); - return 1; - } + return 1; + } - cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, - &block_size); - cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, - inq_buff, drv); + cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); + cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); blk_queue_hardsect_size(drv->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); @@ -1985,7 +1943,7 @@ static unsigned long pollcomplete(int ctlr) if (done == FIFO_EMPTY) schedule_timeout_uninterruptible(1); else - return done; + return (done); } /* Invalid address to tell caller we ran out of time */ return 1; @@ -1994,28 +1952,28 @@ static unsigned long pollcomplete(int ctlr) static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete) { /* We get in here if sendcmd() is polling for completions - and gets some command back that it wasn't expecting -- - something other than that which it just sent down. - Ordinarily, that shouldn't happen, but it can happen when + and gets some command back that it wasn't expecting -- + something other than that which it just sent down. + Ordinarily, that shouldn't happen, but it can happen when the scsi tape stuff gets into error handling mode, and - starts using sendcmd() to try to abort commands and + starts using sendcmd() to try to abort commands and reset tape drives. In that case, sendcmd may pick up completions of commands that were sent to logical drives - through the block i/o system, or cciss ioctls completing, etc. + through the block i/o system, or cciss ioctls completing, etc. In that case, we need to save those completions for later processing by the interrupt handler. - */ + */ #ifdef CONFIG_CISS_SCSI_TAPE - struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects; + struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects; /* If it's not the scsi tape stuff doing error handling, (abort */ /* or reset) then we don't expect anything weird. */ if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) { #endif - printk(KERN_WARNING "cciss cciss%d: SendCmd " - "Invalid command list address returned! (%lx)\n", - ctlr, complete); + printk( KERN_WARNING "cciss cciss%d: SendCmd " + "Invalid command list address returned! (%lx)\n", + ctlr, complete); /* not much we can do. */ #ifdef CONFIG_CISS_SCSI_TAPE return 1; @@ -2026,7 +1984,7 @@ static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete) if (srl->ncompletions >= (NR_CMDS + 2)) { /* Uh oh. No room to save it for later... */ printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, " - "reject list overflow, command lost!\n", ctlr); + "reject list overflow, command lost!\n", ctlr); return 1; } /* Save it for later */ @@ -2037,327 +1995,340 @@ static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete) } /* - * Send a command to the controller, and wait for it to complete. - * Only used at init time. + * Send a command to the controller, and wait for it to complete. + * Only used at init time. */ -static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size, unsigned int use_unit_num, /* 0: address the controller, - 1: address logical volume log_unit, - 2: periph device address is scsi3addr */ - unsigned int log_unit, - __u8 page_code, unsigned char *scsi3addr, int cmd_type) +static int sendcmd( + __u8 cmd, + int ctlr, + void *buff, + size_t size, + unsigned int use_unit_num, /* 0: address the controller, + 1: address logical volume log_unit, + 2: periph device address is scsi3addr */ + unsigned int log_unit, + __u8 page_code, + unsigned char *scsi3addr, + int cmd_type) { CommandList_struct *c; int i; unsigned long complete; - ctlr_info_t *info_p = hba[ctlr]; + ctlr_info_t *info_p= hba[ctlr]; u64bit buff_dma_handle; int status, done = 0; if ((c = cmd_alloc(info_p, 1)) == NULL) { printk(KERN_WARNING "cciss: unable to get memory"); - return IO_ERROR; + return(IO_ERROR); } status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num, - log_unit, page_code, scsi3addr, cmd_type); + log_unit, page_code, scsi3addr, cmd_type); if (status != IO_OK) { cmd_free(info_p, c, 1); return status; } - resend_cmd1: +resend_cmd1: /* - * Disable interrupt - */ + * Disable interrupt + */ #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss: turning intr off\n"); -#endif /* CCISS_DEBUG */ - info_p->access.set_intr_mask(info_p, CCISS_INTR_OFF); - +#endif /* CCISS_DEBUG */ + info_p->access.set_intr_mask(info_p, CCISS_INTR_OFF); + /* Make sure there is room in the command FIFO */ - /* Actually it should be completely empty at this time */ + /* Actually it should be completely empty at this time */ /* unless we are in here doing error handling for the scsi */ /* tape side of the driver. */ - for (i = 200000; i > 0; i--) { + for (i = 200000; i > 0; i--) + { /* if fifo isn't full go */ - if (!(info_p->access.fifo_full(info_p))) { - - break; - } - udelay(10); - printk(KERN_WARNING "cciss cciss%d: SendCmd FIFO full," - " waiting!\n", ctlr); - } - /* - * Send the cmd - */ - info_p->access.submit_command(info_p, c); + if (!(info_p->access.fifo_full(info_p))) + { + + break; + } + udelay(10); + printk(KERN_WARNING "cciss cciss%d: SendCmd FIFO full," + " waiting!\n", ctlr); + } + /* + * Send the cmd + */ + info_p->access.submit_command(info_p, c); done = 0; do { complete = pollcomplete(ctlr); #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss: command completed\n"); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ if (complete == 1) { - printk(KERN_WARNING - "cciss cciss%d: SendCmd Timeout out, " - "No command list address returned!\n", ctlr); + printk( KERN_WARNING + "cciss cciss%d: SendCmd Timeout out, " + "No command list address returned!\n", + ctlr); status = IO_ERROR; done = 1; break; } /* This will need to change for direct lookup completions */ - if ((complete & CISS_ERROR_BIT) - && (complete & ~CISS_ERROR_BIT) == c->busaddr) { - /* if data overrun or underun on Report command - ignore it - */ + if ( (complete & CISS_ERROR_BIT) + && (complete & ~CISS_ERROR_BIT) == c->busaddr) + { + /* if data overrun or underun on Report command + ignore it + */ if (((c->Request.CDB[0] == CISS_REPORT_LOG) || (c->Request.CDB[0] == CISS_REPORT_PHYS) || (c->Request.CDB[0] == CISS_INQUIRY)) && - ((c->err_info->CommandStatus == - CMD_DATA_OVERRUN) || - (c->err_info->CommandStatus == CMD_DATA_UNDERRUN) - )) { + ((c->err_info->CommandStatus == + CMD_DATA_OVERRUN) || + (c->err_info->CommandStatus == + CMD_DATA_UNDERRUN) + )) + { complete = c->busaddr; } else { if (c->err_info->CommandStatus == - CMD_UNSOLICITED_ABORT) { + CMD_UNSOLICITED_ABORT) { printk(KERN_WARNING "cciss%d: " - "unsolicited abort %p\n", - ctlr, c); + "unsolicited abort %p\n", + ctlr, c); if (c->retry_count < MAX_CMD_RETRIES) { printk(KERN_WARNING - "cciss%d: retrying %p\n", - ctlr, c); + "cciss%d: retrying %p\n", + ctlr, c); c->retry_count++; /* erase the old error */ /* information */ memset(c->err_info, 0, - sizeof - (ErrorInfo_struct)); + sizeof(ErrorInfo_struct)); goto resend_cmd1; } else { printk(KERN_WARNING - "cciss%d: retried %p too " - "many times\n", ctlr, c); + "cciss%d: retried %p too " + "many times\n", ctlr, c); status = IO_ERROR; goto cleanup1; } - } else if (c->err_info->CommandStatus == - CMD_UNABORTABLE) { - printk(KERN_WARNING - "cciss%d: command could not be aborted.\n", - ctlr); + } else if (c->err_info->CommandStatus == CMD_UNABORTABLE) { + printk(KERN_WARNING "cciss%d: command could not be aborted.\n", ctlr); status = IO_ERROR; goto cleanup1; } printk(KERN_WARNING "ciss ciss%d: sendcmd" - " Error %x \n", ctlr, - c->err_info->CommandStatus); + " Error %x \n", ctlr, + c->err_info->CommandStatus); printk(KERN_WARNING "ciss ciss%d: sendcmd" - " offensive info\n" - " size %x\n num %x value %x\n", - ctlr, - c->err_info->MoreErrInfo.Invalid_Cmd. - offense_size, - c->err_info->MoreErrInfo.Invalid_Cmd. - offense_num, - c->err_info->MoreErrInfo.Invalid_Cmd. - offense_value); + " offensive info\n" + " size %x\n num %x value %x\n", ctlr, + c->err_info->MoreErrInfo.Invalid_Cmd.offense_size, + c->err_info->MoreErrInfo.Invalid_Cmd.offense_num, + c->err_info->MoreErrInfo.Invalid_Cmd.offense_value); status = IO_ERROR; goto cleanup1; } } /* This will need changing for direct lookup completions */ - if (complete != c->busaddr) { + if (complete != c->busaddr) { if (add_sendcmd_reject(cmd, ctlr, complete) != 0) { - BUG(); /* we are pretty much hosed if we get here. */ + BUG(); /* we are pretty much hosed if we get here. */ } continue; - } else + } else done = 1; - } while (!done); - - cleanup1: + } while (!done); + +cleanup1: /* unlock the data buffer from DMA */ buff_dma_handle.val32.lower = c->SG[0].Addr.lower; buff_dma_handle.val32.upper = c->SG[0].Addr.upper; pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val, - c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); + c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); #ifdef CONFIG_CISS_SCSI_TAPE /* if we saved some commands for later, process them now. */ if (info_p->scsi_rejects.ncompletions > 0) do_cciss_intr(0, info_p, NULL); #endif cmd_free(info_p, c, 1); - return status; -} - + return (status); +} /* * Map (physical) PCI mem into (virtual) kernel space */ static void __iomem *remap_pci_mem(ulong base, ulong size) { - ulong page_base = ((ulong) base) & PAGE_MASK; - ulong page_offs = ((ulong) base) - page_base; - void __iomem *page_remapped = ioremap(page_base, page_offs + size); + ulong page_base = ((ulong) base) & PAGE_MASK; + ulong page_offs = ((ulong) base) - page_base; + void __iomem *page_remapped = ioremap(page_base, page_offs+size); - return page_remapped ? (page_remapped + page_offs) : NULL; + return page_remapped ? (page_remapped + page_offs) : NULL; } -/* - * Takes jobs of the Q and sends them to the hardware, then puts it on - * the Q to wait for completion. - */ -static void start_io(ctlr_info_t *h) +/* + * Takes jobs of the Q and sends them to the hardware, then puts it on + * the Q to wait for completion. + */ +static void start_io( ctlr_info_t *h) { CommandList_struct *c; - - while ((c = h->reqQ) != NULL) { + + while(( c = h->reqQ) != NULL ) + { /* can't do anything if fifo is full */ if ((h->access.fifo_full(h))) { printk(KERN_WARNING "cciss: fifo full\n"); break; } - /* Get the first entry from the Request Q */ + /* Get the first entry from the Request Q */ removeQ(&(h->reqQ), c); h->Qdepth--; - - /* Tell the controller execute command */ + + /* Tell the controller execute command */ h->access.submit_command(h, c); - - /* Put job onto the completed Q */ - addQ(&(h->cmpQ), c); + + /* Put job onto the completed Q */ + addQ (&(h->cmpQ), c); } } - /* Assumes that CCISS_LOCK(h->ctlr) is held. */ /* Zeros out the error record and then resends the command back */ /* to the controller */ -static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) +static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c) { /* erase the old error information */ memset(c->err_info, 0, sizeof(ErrorInfo_struct)); /* add it to software queue and then send it to the controller */ - addQ(&(h->reqQ), c); + addQ(&(h->reqQ),c); h->Qdepth++; - if (h->Qdepth > h->maxQsinceinit) + if(h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth; start_io(h); } -/* checks the status of the job and calls complete buffers to mark all +/* checks the status of the job and calls complete buffers to mark all * buffers for the completed job. Note that this function does not need * to hold the hba/queue lock. - */ -static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, - int timeout) + */ +static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, + int timeout) { int status = 1; int retry_cmd = 0; - + if (timeout) - status = 0; + status = 0; - if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */ - switch (cmd->err_info->CommandStatus) { + if(cmd->err_info->CommandStatus != 0) + { /* an error has occurred */ + switch(cmd->err_info->CommandStatus) + { unsigned char sense_key; - case CMD_TARGET_STATUS: - status = 0; - - if (cmd->err_info->ScsiStatus == 0x02) { - printk(KERN_WARNING "cciss: cmd %p " - "has CHECK CONDITION " - " byte 2 = 0x%x\n", cmd, - cmd->err_info->SenseInfo[2] - ); - /* check the sense key */ - sense_key = 0xf & cmd->err_info->SenseInfo[2]; - /* no status or recovered error */ - if ((sense_key == 0x0) || (sense_key == 0x1)) { - status = 1; + case CMD_TARGET_STATUS: + status = 0; + + if( cmd->err_info->ScsiStatus == 0x02) + { + printk(KERN_WARNING "cciss: cmd %p " + "has CHECK CONDITION " + " byte 2 = 0x%x\n", cmd, + cmd->err_info->SenseInfo[2] + ); + /* check the sense key */ + sense_key = 0xf & + cmd->err_info->SenseInfo[2]; + /* no status or recovered error */ + if((sense_key == 0x0) || + (sense_key == 0x1)) + { + status = 1; + } + } else + { + printk(KERN_WARNING "cciss: cmd %p " + "has SCSI Status 0x%x\n", + cmd, cmd->err_info->ScsiStatus); } - } else { - printk(KERN_WARNING "cciss: cmd %p " - "has SCSI Status 0x%x\n", - cmd, cmd->err_info->ScsiStatus); - } - break; - case CMD_DATA_UNDERRUN: - printk(KERN_WARNING "cciss: cmd %p has" - " completed with data underrun " - "reported\n", cmd); break; - case CMD_DATA_OVERRUN: - printk(KERN_WARNING "cciss: cmd %p has" - " completed with data overrun " - "reported\n", cmd); + case CMD_DATA_UNDERRUN: + printk(KERN_WARNING "cciss: cmd %p has" + " completed with data underrun " + "reported\n", cmd); break; - case CMD_INVALID: - printk(KERN_WARNING "cciss: cmd %p is " - "reported invalid\n", cmd); - status = 0; + case CMD_DATA_OVERRUN: + printk(KERN_WARNING "cciss: cmd %p has" + " completed with data overrun " + "reported\n", cmd); break; - case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cmd %p has " - "protocol error \n", cmd); - status = 0; + case CMD_INVALID: + printk(KERN_WARNING "cciss: cmd %p is " + "reported invalid\n", cmd); + status = 0; break; - case CMD_HARDWARE_ERR: - printk(KERN_WARNING "cciss: cmd %p had " - " hardware error\n", cmd); - status = 0; + case CMD_PROTOCOL_ERR: + printk(KERN_WARNING "cciss: cmd %p has " + "protocol error \n", cmd); + status = 0; + break; + case CMD_HARDWARE_ERR: + printk(KERN_WARNING "cciss: cmd %p had " + " hardware error\n", cmd); + status = 0; + break; + case CMD_CONNECTION_LOST: + printk(KERN_WARNING "cciss: cmd %p had " + "connection lost\n", cmd); + status=0; break; - case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cmd %p had " - "connection lost\n", cmd); - status = 0; + case CMD_ABORTED: + printk(KERN_WARNING "cciss: cmd %p was " + "aborted\n", cmd); + status=0; break; - case CMD_ABORTED: - printk(KERN_WARNING "cciss: cmd %p was " - "aborted\n", cmd); - status = 0; + case CMD_ABORT_FAILED: + printk(KERN_WARNING "cciss: cmd %p reports " + "abort failed\n", cmd); + status=0; break; - case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cmd %p reports " - "abort failed\n", cmd); - status = 0; - break; - case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING "cciss%d: unsolicited " - "abort %p\n", h->ctlr, cmd); - if (cmd->retry_count < MAX_CMD_RETRIES) { - retry_cmd = 1; - printk(KERN_WARNING - "cciss%d: retrying %p\n", h->ctlr, cmd); - cmd->retry_count++; - } else - printk(KERN_WARNING - "cciss%d: %p retried too " - "many times\n", h->ctlr, cmd); - status = 0; + case CMD_UNSOLICITED_ABORT: + printk(KERN_WARNING "cciss%d: unsolicited " + "abort %p\n", h->ctlr, cmd); + if (cmd->retry_count < MAX_CMD_RETRIES) { + retry_cmd=1; + printk(KERN_WARNING + "cciss%d: retrying %p\n", + h->ctlr, cmd); + cmd->retry_count++; + } else + printk(KERN_WARNING + "cciss%d: %p retried too " + "many times\n", h->ctlr, cmd); + status=0; break; - case CMD_TIMEOUT: - printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); - status = 0; + case CMD_TIMEOUT: + printk(KERN_WARNING "cciss: cmd %p timedout\n", + cmd); + status=0; break; - default: - printk(KERN_WARNING "cciss: cmd %p returned " - "unknown status %x\n", cmd, - cmd->err_info->CommandStatus); - status = 0; + default: + printk(KERN_WARNING "cciss: cmd %p returned " + "unknown status %x\n", cmd, + cmd->err_info->CommandStatus); + status=0; } } /* We need to return this command */ - if (retry_cmd) { - resend_cciss_cmd(h, cmd); + if(retry_cmd) { + resend_cciss_cmd(h,cmd); return; - } + } cmd->rq->completion_data = cmd; cmd->rq->errors = status; @@ -2365,12 +2336,12 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, blk_complete_request(cmd->rq); } -/* - * Get a request and submit it to the controller. +/* + * Get a request and submit it to the controller. */ static void do_cciss_request(request_queue_t *q) { - ctlr_info_t *h = q->queuedata; + ctlr_info_t *h= q->queuedata; CommandList_struct *c; int start_blk, seg; struct request *creq; @@ -2381,18 +2352,18 @@ static void do_cciss_request(request_queue_t *q) /* We call start_io here in case there is a command waiting on the * queue that has not been sent. - */ + */ if (blk_queue_plugged(q)) goto startio; - queue: +queue: creq = elv_next_request(q); if (!creq) goto startio; BUG_ON(creq->nr_phys_segments > MAXSGENTRIES); - if ((c = cmd_alloc(h, 1)) == NULL) + if (( c = cmd_alloc(h, 1)) == NULL) goto full; blkdev_dequeue_request(creq); @@ -2401,82 +2372,81 @@ static void do_cciss_request(request_queue_t *q) c->cmd_type = CMD_RWREQ; c->rq = creq; - - /* fill in the request */ + + /* fill in the request */ drv = creq->rq_disk->private_data; - c->Header.ReplyQueue = 0; // unused in simple mode + c->Header.ReplyQueue = 0; // unused in simple mode /* got command from pool, so use the command block index instead */ /* for direct lookups. */ /* The first 2 bits are reserved for controller error reporting. */ c->Header.Tag.lower = (c->cmdindex << 3); - c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ - c->Header.LUN.LogDev.VolId = drv->LunID; + c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ + c->Header.LUN.LogDev.VolId= drv->LunID; c->Header.LUN.LogDev.Mode = 1; - c->Request.CDBLen = 10; // 12 byte commands not in FW yet; - c->Request.Type.Type = TYPE_CMD; // It is a command. - c->Request.Type.Attribute = ATTR_SIMPLE; - c->Request.Type.Direction = - (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; - c->Request.Timeout = 0; // Don't time out - c->Request.CDB[0] = - (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; + c->Request.CDBLen = 10; // 12 byte commands not in FW yet; + c->Request.Type.Type = TYPE_CMD; // It is a command. + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = + (rq_data_dir(creq) == READ) ? XFER_READ: XFER_WRITE; + c->Request.Timeout = 0; // Don't time out + c->Request.CDB[0] = (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; start_blk = creq->sector; #ifdef CCISS_DEBUG - printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, - (int)creq->nr_sectors); -#endif /* CCISS_DEBUG */ + printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",(int) creq->sector, + (int) creq->nr_sectors); +#endif /* CCISS_DEBUG */ seg = blk_rq_map_sg(q, creq, tmp_sg); - /* get the DMA records for the setup */ + /* get the DMA records for the setup */ if (c->Request.Type.Direction == XFER_READ) dir = PCI_DMA_FROMDEVICE; else dir = PCI_DMA_TODEVICE; - for (i = 0; i < seg; i++) { + for (i=0; iSG[i].Len = tmp_sg[i].length; temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page, - tmp_sg[i].offset, - tmp_sg[i].length, dir); + tmp_sg[i].offset, tmp_sg[i].length, + dir); c->SG[i].Addr.lower = temp64.val32.lower; - c->SG[i].Addr.upper = temp64.val32.upper; - c->SG[i].Ext = 0; // we are not chaining + c->SG[i].Addr.upper = temp64.val32.upper; + c->SG[i].Ext = 0; // we are not chaining } - /* track how many SG entries we are using */ - if (seg > h->maxSG) - h->maxSG = seg; + /* track how many SG entries we are using */ + if( seg > h->maxSG) + h->maxSG = seg; #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", - creq->nr_sectors, seg); -#endif /* CCISS_DEBUG */ + printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); +#endif /* CCISS_DEBUG */ c->Header.SGList = c->Header.SGTotal = seg; - c->Request.CDB[1] = 0; - c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB - c->Request.CDB[3] = (start_blk >> 16) & 0xff; - c->Request.CDB[4] = (start_blk >> 8) & 0xff; - c->Request.CDB[5] = start_blk & 0xff; - c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB - c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[8] = creq->nr_sectors & 0xff; + c->Request.CDB[1]= 0; + c->Request.CDB[2]= (start_blk >> 24) & 0xff; //MSB + c->Request.CDB[3]= (start_blk >> 16) & 0xff; + c->Request.CDB[4]= (start_blk >> 8) & 0xff; + c->Request.CDB[5]= start_blk & 0xff; + c->Request.CDB[6]= 0; // (sect >> 24) & 0xff; MSB + c->Request.CDB[7]= (creq->nr_sectors >> 8) & 0xff; + c->Request.CDB[8]= creq->nr_sectors & 0xff; c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; spin_lock_irq(q->queue_lock); - addQ(&(h->reqQ), c); + addQ(&(h->reqQ),c); h->Qdepth++; - if (h->Qdepth > h->maxQsinceinit) - h->maxQsinceinit = h->Qdepth; + if(h->Qdepth > h->maxQsinceinit) + h->maxQsinceinit = h->Qdepth; goto queue; - full: +full: blk_stop_queue(q); - startio: +startio: /* We will already have the driver lock here so not need * to lock it. - */ + */ start_io(h); } @@ -2503,7 +2473,7 @@ static inline unsigned long get_next_completion(ctlr_info_t *h) static inline int interrupt_pending(ctlr_info_t *h) { #ifdef CONFIG_CISS_SCSI_TAPE - return (h->access.intr_pending(h) + return ( h->access.intr_pending(h) || (h->scsi_rejects.ncompletions > 0)); #else return h->access.intr_pending(h); @@ -2513,11 +2483,11 @@ static inline int interrupt_pending(ctlr_info_t *h) static inline long interrupt_not_for_us(ctlr_info_t *h) { #ifdef CONFIG_CISS_SCSI_TAPE - return (((h->access.intr_pending(h) == 0) || - (h->interrupts_enabled == 0)) - && (h->scsi_rejects.ncompletions == 0)); + return (((h->access.intr_pending(h) == 0) || + (h->interrupts_enabled == 0)) + && (h->scsi_rejects.ncompletions == 0)); #else - return (((h->access.intr_pending(h) == 0) || + return (((h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0))); #endif } @@ -2539,14 +2509,12 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); while (interrupt_pending(h)) { - while ((a = get_next_completion(h)) != FIFO_EMPTY) { + while((a = get_next_completion(h)) != FIFO_EMPTY) { a1 = a; if ((a & 0x04)) { a2 = (a >> 3); if (a2 >= NR_CMDS) { - printk(KERN_WARNING - "cciss: controller cciss%d failed, stopping.\n", - h->ctlr); + printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr); fail_all_cmds(h->ctlr); return IRQ_HANDLED; } @@ -2555,24 +2523,22 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) a = c->busaddr; } else { - a &= ~3; + a &= ~3; if ((c = h->cmpQ) == NULL) { - printk(KERN_WARNING - "cciss: Completion of %08x ignored\n", - a1); - continue; - } - while (c->busaddr != a) { - c = c->next; - if (c == h->cmpQ) - break; - } + printk(KERN_WARNING "cciss: Completion of %08x ignored\n", a1); + continue; + } + while(c->busaddr != a) { + c = c->next; + if (c == h->cmpQ) + break; + } } /* * If we've found the command, take it off the * completion Q and free it */ - if (c->busaddr == a) { + if (c->busaddr == a) { removeQ(&h->cmpQ, c); if (c->cmd_type == CMD_RWREQ) { complete_command(h, c, 0); @@ -2588,118 +2554,130 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) } } - /* check to see if we have maxed out the number of commands that can - * be placed on the queue. If so then exit. We do this check here - * in case the interrupt we serviced was from an ioctl and did not - * free any new commands. - */ - if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) - goto cleanup; - - /* We have room on the queue for more commands. Now we need to queue - * them up. We will also keep track of the next queue to run so - * that every queue gets a chance to be started first. + /* check to see if we have maxed out the number of commands that can + * be placed on the queue. If so then exit. We do this check here + * in case the interrupt we serviced was from an ioctl and did not + * free any new commands. */ - for (j = 0; j < h->highest_lun + 1; j++) { + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) + goto cleanup; + + /* We have room on the queue for more commands. Now we need to queue + * them up. We will also keep track of the next queue to run so + * that every queue gets a chance to be started first. + */ + for (j=0; j < h->highest_lun + 1; j++){ int curr_queue = (start_queue + j) % (h->highest_lun + 1); - /* make sure the disk has been added and the drive is real - * because this can be called from the middle of init_one. - */ - if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) - continue; - blk_start_queue(h->gendisk[curr_queue]->queue); - - /* check to see if we have maxed out the number of commands - * that can be placed on the queue. - */ - if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { - if (curr_queue == start_queue) { - h->next_to_run = - (start_queue + 1) % (h->highest_lun + 1); - goto cleanup; - } else { - h->next_to_run = curr_queue; - goto cleanup; - } - } else { + /* make sure the disk has been added and the drive is real + * because this can be called from the middle of init_one. + */ + if(!(h->drv[curr_queue].queue) || + !(h->drv[curr_queue].heads)) + continue; + blk_start_queue(h->gendisk[curr_queue]->queue); + + /* check to see if we have maxed out the number of commands + * that can be placed on the queue. + */ + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) + { + if (curr_queue == start_queue){ + h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); + goto cleanup; + } else { + h->next_to_run = curr_queue; + goto cleanup; + } + } else { curr_queue = (curr_queue + 1) % (h->highest_lun + 1); - } - } + } + } - cleanup: +cleanup: spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return IRQ_HANDLED; } - -/* - * We cannot read the structure directly, for portability we must use +/* + * We cannot read the structure directly, for portablity we must use * the io functions. - * This is for debug only. + * This is for debug only. */ #ifdef CCISS_DEBUG -static void print_cfg_table(CfgTable_struct *tb) +static void print_cfg_table( CfgTable_struct *tb) { int i; char temp_name[17]; printk("Controller Configuration information\n"); printk("------------------------------------\n"); - for (i = 0; i < 4; i++) + for(i=0;i<4;i++) temp_name[i] = readb(&(tb->Signature[i])); - temp_name[4] = '\0'; - printk(" Signature = %s\n", temp_name); + temp_name[4]='\0'; + printk(" Signature = %s\n", temp_name); printk(" Spec Number = %d\n", readl(&(tb->SpecValence))); - printk(" Transport methods supported = 0x%x\n", - readl(&(tb->TransportSupport))); - printk(" Transport methods active = 0x%x\n", - readl(&(tb->TransportActive))); - printk(" Requested transport Method = 0x%x\n", - readl(&(tb->HostWrite.TransportRequest))); - printk(" Coalesce Interrupt Delay = 0x%x\n", - readl(&(tb->HostWrite.CoalIntDelay))); - printk(" Coalesce Interrupt Count = 0x%x\n", - readl(&(tb->HostWrite.CoalIntCount))); - printk(" Max outstanding commands = 0x%d\n", - readl(&(tb->CmdsOutMax))); - printk(" Bus Types = 0x%x\n", readl(&(tb->BusTypes))); - for (i = 0; i < 16; i++) + printk(" Transport methods supported = 0x%x\n", + readl(&(tb-> TransportSupport))); + printk(" Transport methods active = 0x%x\n", + readl(&(tb->TransportActive))); + printk(" Requested transport Method = 0x%x\n", + readl(&(tb->HostWrite.TransportRequest))); + printk(" Coalese Interrupt Delay = 0x%x\n", + readl(&(tb->HostWrite.CoalIntDelay))); + printk(" Coalese Interrupt Count = 0x%x\n", + readl(&(tb->HostWrite.CoalIntCount))); + printk(" Max outstanding commands = 0x%d\n", + readl(&(tb->CmdsOutMax))); + printk(" Bus Types = 0x%x\n", readl(&(tb-> BusTypes))); + for(i=0;i<16;i++) temp_name[i] = readb(&(tb->ServerName[i])); temp_name[16] = '\0'; printk(" Server Name = %s\n", temp_name); - printk(" Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat))); + printk(" Heartbeat Counter = 0x%x\n\n\n", + readl(&(tb->HeartBeat))); +} +#endif /* CCISS_DEBUG */ + +static void release_io_mem(ctlr_info_t *c) +{ + /* if IO mem was not protected do nothing */ + if( c->io_mem_addr == 0) + return; + release_region(c->io_mem_addr, c->io_mem_length); + c->io_mem_addr = 0; + c->io_mem_length = 0; } -#endif /* CCISS_DEBUG */ -static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) +static int find_PCI_BAR_index(struct pci_dev *pdev, + unsigned long pci_bar_addr) { int i, offset, mem_type, bar_type; - if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */ + if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */ return 0; offset = 0; - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - bar_type = pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE; + for (i=0; iintr[0] = cciss_msix_entries[0].vector; - c->intr[1] = cciss_msix_entries[1].vector; - c->intr[2] = cciss_msix_entries[2].vector; - c->intr[3] = cciss_msix_entries[3].vector; - c->msix_vector = 1; - return; - } - if (err > 0) { - printk(KERN_WARNING "cciss: only %d MSI-X vectors " - "available\n", err); - } else { - printk(KERN_WARNING "cciss: MSI-X init failed %d\n", - err); - } - } - if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { - if (!pci_enable_msi(pdev)) { - c->intr[SIMPLE_MODE_INT] = pdev->irq; - c->msi_vector = 1; - return; - } else { - printk(KERN_WARNING "cciss: MSI init failed\n"); - c->intr[SIMPLE_MODE_INT] = pdev->irq; - return; - } - } - default_int_mode: -#endif /* CONFIG_PCI_MSI */ + if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { + err = pci_enable_msix(pdev, cciss_msix_entries, 4); + if (!err) { + c->intr[0] = cciss_msix_entries[0].vector; + c->intr[1] = cciss_msix_entries[1].vector; + c->intr[2] = cciss_msix_entries[2].vector; + c->intr[3] = cciss_msix_entries[3].vector; + c->msix_vector = 1; + return; + } + if (err > 0) { + printk(KERN_WARNING "cciss: only %d MSI-X vectors " + "available\n", err); + } else { + printk(KERN_WARNING "cciss: MSI-X init failed %d\n", + err); + } + } + if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { + if (!pci_enable_msi(pdev)) { + c->intr[SIMPLE_MODE_INT] = pdev->irq; + c->msi_vector = 1; + return; + } else { + printk(KERN_WARNING "cciss: MSI init failed\n"); + c->intr[SIMPLE_MODE_INT] = pdev->irq; + return; + } + } +default_int_mode: +#endif /* CONFIG_PCI_MSI */ /* if we get here we're going to use the default interrupt mode */ - c->intr[SIMPLE_MODE_INT] = pdev->irq; + c->intr[SIMPLE_MODE_INT] = pdev->irq; return; } @@ -2766,40 +2743,58 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) __u64 cfg_offset; __u32 cfg_base_addr; __u64 cfg_base_addr_index; - int i, err; + int i; /* check to see if controller has been disabled */ /* BEFORE trying to enable it */ - (void)pci_read_config_word(pdev, PCI_COMMAND, &command); - if (!(command & 0x02)) { - printk(KERN_WARNING - "cciss: controller appears to be disabled\n"); - return -ENODEV; + (void) pci_read_config_word(pdev, PCI_COMMAND,&command); + if(!(command & 0x02)) + { + printk(KERN_WARNING "cciss: controller appears to be disabled\n"); + return(-1); } - err = pci_enable_device(pdev); - if (err) { + if (pci_enable_device(pdev)) + { printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); - return err; - } - - err = pci_request_regions(pdev, "cciss"); - if (err) { - printk(KERN_ERR "cciss: Cannot obtain PCI resources, " - "aborting\n"); - goto err_out_disable_pdev; + return( -1); } subsystem_vendor_id = pdev->subsystem_vendor; subsystem_device_id = pdev->subsystem_device; board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | - subsystem_vendor_id); + subsystem_vendor_id); + + /* search for our IO range so we can protect it */ + for(i=0; iio_mem_addr = pci_resource_start(pdev, i); + c->io_mem_length = pci_resource_end(pdev, i) - + pci_resource_start(pdev, i) +1; +#ifdef CCISS_DEBUG + printk("IO value found base_addr[%d] %lx %lx\n", i, + c->io_mem_addr, c->io_mem_length); +#endif /* CCISS_DEBUG */ + /* register the IO range */ + if(!request_region( c->io_mem_addr, + c->io_mem_length, "cciss")) + { + printk(KERN_WARNING "cciss I/O memory range already in use addr=%lx length=%ld\n", + c->io_mem_addr, c->io_mem_length); + c->io_mem_addr= 0; + c->io_mem_length = 0; + } + break; + } + } #ifdef CCISS_DEBUG printk("command = %x\n", command); printk("irq = %x\n", pdev->irq); printk("board_id = %x\n", board_id); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. @@ -2808,28 +2803,27 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) /* * Memory base addr is first addr , the second points to the config - * table + * table */ - c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ + c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */ #ifdef CCISS_DEBUG printk("address 0 = %x\n", c->paddr); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ c->vaddr = remap_pci_mem(c->paddr, 200); /* Wait for the board to become ready. (PCI hotplug needs this.) * We poll for up to 120 secs, once per 100ms. */ - for (i = 0; i < 1200; i++) { + for (i=0; i < 1200; i++) { scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET); if (scratchpad == CCISS_FIRMWARE_READY) break; set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); /* wait 100ms */ + schedule_timeout(HZ / 10); /* wait 100ms */ } if (scratchpad != CCISS_FIRMWARE_READY) { printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); - err = -ENODEV; - goto err_out_free_res; + return -1; } /* get the address index number */ @@ -2837,108 +2831,103 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) cfg_base_addr &= (__u32) 0x0000ffff; #ifdef CCISS_DEBUG printk("cfg base address = %x\n", cfg_base_addr); -#endif /* CCISS_DEBUG */ - cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); +#endif /* CCISS_DEBUG */ + cfg_base_addr_index = + find_PCI_BAR_index(pdev, cfg_base_addr); #ifdef CCISS_DEBUG printk("cfg base address index = %x\n", cfg_base_addr_index); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ if (cfg_base_addr_index == -1) { printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); - err = -ENODEV; - goto err_out_free_res; + release_io_mem(c); + return -1; } cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); #ifdef CCISS_DEBUG printk("cfg offset = %x\n", cfg_offset); -#endif /* CCISS_DEBUG */ - c->cfgtable = remap_pci_mem(pci_resource_start(pdev, - cfg_base_addr_index) + - cfg_offset, sizeof(CfgTable_struct)); +#endif /* CCISS_DEBUG */ + c->cfgtable = remap_pci_mem(pci_resource_start(pdev, + cfg_base_addr_index) + cfg_offset, + sizeof(CfgTable_struct)); c->board_id = board_id; #ifdef CCISS_DEBUG print_cfg_table(c->cfgtable); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ - for (i = 0; i < ARRAY_SIZE(products); i++) { + for(i=0; iproduct_name = products[i].product_name; c->access = *(products[i].access); break; } } - if (i == ARRAY_SIZE(products)) { + if (i == NR_PRODUCTS) { printk(KERN_WARNING "cciss: Sorry, I don't know how" - " to access the Smart Array controller %08lx\n", - (unsigned long)board_id); - err = -ENODEV; - goto err_out_free_res; - } - if ((readb(&c->cfgtable->Signature[0]) != 'C') || - (readb(&c->cfgtable->Signature[1]) != 'I') || - (readb(&c->cfgtable->Signature[2]) != 'S') || - (readb(&c->cfgtable->Signature[3]) != 'S')) { - printk("Does not appear to be a valid CISS config table\n"); - err = -ENODEV; - goto err_out_free_res; + " to access the Smart Array controller %08lx\n", + (unsigned long)board_id); + return -1; } -#ifdef CONFIG_X86 + if ( (readb(&c->cfgtable->Signature[0]) != 'C') || + (readb(&c->cfgtable->Signature[1]) != 'I') || + (readb(&c->cfgtable->Signature[2]) != 'S') || + (readb(&c->cfgtable->Signature[3]) != 'S') ) { - /* Need to enable prefetch in the SCSI core for 6400 in x86 */ - __u32 prefetch; - prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); - prefetch |= 0x100; - writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); + printk("Does not appear to be a valid CISS config table\n"); + return -1; } + +#ifdef CONFIG_X86 +{ + /* Need to enable prefetch in the SCSI core for 6400 in x86 */ + __u32 prefetch; + prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); +} #endif #ifdef CCISS_DEBUG printk("Trying to put board into Simple mode\n"); -#endif /* CCISS_DEBUG */ +#endif /* CCISS_DEBUG */ c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); - /* Update the field, and then ring the doorbell */ - writel(CFGTBL_Trans_Simple, &(c->cfgtable->HostWrite.TransportRequest)); - writel(CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); + /* Update the field, and then ring the doorbell */ + writel( CFGTBL_Trans_Simple, + &(c->cfgtable->HostWrite.TransportRequest)); + writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); /* under certain very rare conditions, this can take awhile. * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right * as we enter this code.) */ - for (i = 0; i < MAX_CONFIG_WAIT; i++) { + for(i=0;ivaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; /* delay and try again */ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10); - } + } #ifdef CCISS_DEBUG - printk(KERN_DEBUG "I counter got to %d %x\n", i, - readl(c->vaddr + SA5_DOORBELL)); -#endif /* CCISS_DEBUG */ + printk(KERN_DEBUG "I counter got to %d %x\n", i, readl(c->vaddr + SA5_DOORBELL)); +#endif /* CCISS_DEBUG */ #ifdef CCISS_DEBUG - print_cfg_table(c->cfgtable); -#endif /* CCISS_DEBUG */ + print_cfg_table(c->cfgtable); +#endif /* CCISS_DEBUG */ - if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { + if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) + { printk(KERN_WARNING "cciss: unable to get board into" - " simple mode\n"); - err = -ENODEV; - goto err_out_free_res; + " simple mode\n"); + return -1; } return 0; - err_out_free_res: - pci_release_regions(pdev); - - err_out_disable_pdev: - pci_disable_device(pdev); - return err; } -/* - * Gets information about the local volumes attached to the controller. - */ +/* + * Gets information about the local volumes attached to the controller. + */ static void cciss_getgeometry(int cntl_num) { ReportLunData_struct *ld_buff; @@ -2949,102 +2938,102 @@ static void cciss_getgeometry(int cntl_num) int listlength = 0; __u32 lunid = 0; int block_size; - int total_size; + int total_size; ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); - if (ld_buff == NULL) { - printk(KERN_ERR "cciss: out of memory\n"); - return; - } - size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (size_buff == NULL) { + if (ld_buff == NULL) + { printk(KERN_ERR "cciss: out of memory\n"); - kfree(ld_buff); return; } - inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); - if (inq_buff == NULL) { - printk(KERN_ERR "cciss: out of memory\n"); + size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) + { + printk(KERN_ERR "cciss: out of memory\n"); kfree(ld_buff); + return; + } + inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); + if (inq_buff == NULL) + { + printk(KERN_ERR "cciss: out of memory\n"); + kfree(ld_buff); kfree(size_buff); - return; - } - /* Get the firmware version */ - return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, - sizeof(InquiryData_struct), 0, 0, 0, NULL, - TYPE_CMD); - if (return_code == IO_OK) { + return; + } + /* Get the firmware version */ + return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, + sizeof(InquiryData_struct), 0, 0 ,0, NULL, TYPE_CMD); + if (return_code == IO_OK) + { hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; - } else { /* send command failed */ - + } else /* send command failed */ + { printk(KERN_WARNING "cciss: unable to determine firmware" - " version of controller\n"); + " version of controller\n"); } - /* Get the number of logical volumes */ - return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, - sizeof(ReportLunData_struct), 0, 0, 0, NULL, - TYPE_CMD); + /* Get the number of logical volumes */ + return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, + sizeof(ReportLunData_struct), 0, 0, 0, NULL, TYPE_CMD); - if (return_code == IO_OK) { + if( return_code == IO_OK) + { #ifdef CCISS_DEBUG printk("LUN Data\n--------------------------\n"); -#endif /* CCISS_DEBUG */ - - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; - listlength |= - (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; - listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); - } else { /* reading number of logical volumes failed */ +#endif /* CCISS_DEBUG */ + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; + listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; + listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); + } else /* reading number of logical volumes failed */ + { printk(KERN_WARNING "cciss: report logical volume" - " command failed\n"); + " command failed\n"); listlength = 0; } - hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry - if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { - printk(KERN_ERR - "ciss: only %d number of logical volumes supported\n", - CISS_MAX_LUN); + hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry + if (hba[cntl_num]->num_luns > CISS_MAX_LUN) + { + printk(KERN_ERR "ciss: only %d number of logical volumes supported\n", + CISS_MAX_LUN); hba[cntl_num]->num_luns = CISS_MAX_LUN; } #ifdef CCISS_DEBUG - printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", - ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], - ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], - hba[cntl_num]->num_luns); -#endif /* CCISS_DEBUG */ - - hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; -// for(i=0; i< hba[cntl_num]->num_luns; i++) - for (i = 0; i < CISS_MAX_LUN; i++) { - if (i < hba[cntl_num]->num_luns) { - lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) - << 24; - lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) - << 16; - lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) - << 8; - lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); - - hba[cntl_num]->drv[i].LunID = lunid; + printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0], + ld_buff->LUNListLength[1], ld_buff->LUNListLength[2], + ld_buff->LUNListLength[3], hba[cntl_num]->num_luns); +#endif /* CCISS_DEBUG */ + + hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns-1; +// for(i=0; i< hba[cntl_num]->num_luns; i++) + for(i=0; i < CISS_MAX_LUN; i++) + { + if (i < hba[cntl_num]->num_luns){ + lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) + << 24; + lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) + << 16; + lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) + << 8; + lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); + + hba[cntl_num]->drv[i].LunID = lunid; + #ifdef CCISS_DEBUG - printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, - ld_buff->LUN[i][0], ld_buff->LUN[i][1], - ld_buff->LUN[i][2], ld_buff->LUN[i][3], - hba[cntl_num]->drv[i].LunID); -#endif /* CCISS_DEBUG */ - cciss_read_capacity(cntl_num, i, size_buff, 0, - &total_size, &block_size); + printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, + ld_buff->LUN[i][0], ld_buff->LUN[i][1], + ld_buff->LUN[i][2], ld_buff->LUN[i][3], + hba[cntl_num]->drv[i].LunID); +#endif /* CCISS_DEBUG */ + cciss_read_capacity(cntl_num, i, size_buff, 0, + &total_size, &block_size); cciss_geometry_inquiry(cntl_num, i, 0, total_size, - block_size, inq_buff, - &hba[cntl_num]->drv[i]); + block_size, inq_buff, &hba[cntl_num]->drv[i]); } else { /* initialize raid_level to indicate a free space */ hba[cntl_num]->drv[i].raid_level = -1; @@ -3053,7 +3042,7 @@ static void cciss_getgeometry(int cntl_num) kfree(ld_buff); kfree(size_buff); kfree(inq_buff); -} +} /* Function to find the first free pointer into our hba[] array */ /* Returns -1 if no free entries are left. */ @@ -3067,7 +3056,7 @@ static int alloc_cciss_hba(void) goto out; } - for (i = 0; i < MAX_CTLR; i++) { + for(i=0; i< MAX_CTLR; i++) { if (!hba[i]) { ctlr_info_t *p; p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); @@ -3080,11 +3069,11 @@ static int alloc_cciss_hba(void) } } printk(KERN_WARNING "cciss: This driver supports a maximum" - " of %d controllers.\n", MAX_CTLR); + " of %d controllers.\n", MAX_CTLR); goto out; - Enomem: +Enomem: printk(KERN_ERR "cciss: out of memory.\n"); - out: +out: while (n--) put_disk(disk[n]); return -1; @@ -3107,17 +3096,20 @@ static void free_hba(int i) * returns the number of block devices registered. */ static int __devinit cciss_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { request_queue_t *q; int i; int j; int rc; - int dac; + printk(KERN_DEBUG "cciss: Device 0x%x has been found at" + " bus %d dev %d func %d\n", + pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); i = alloc_cciss_hba(); - if (i < 0) - return -1; + if(i < 0) + return (-1); hba[i]->busy_initializing = 1; @@ -3130,11 +3122,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* configure PCI DMA stuff */ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) - dac = 1; + printk("cciss: using DAC cycles\n"); else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) - dac = 0; + printk("cciss: not using DAC cycles\n"); else { - printk(KERN_ERR "cciss: no suitable DMA available\n"); + printk("cciss: no suitable DMA available\n"); goto clean1; } @@ -3146,69 +3138,60 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, if (i < MAX_CTLR_ORIG) hba[i]->major = COMPAQ_CISS_MAJOR + i; rc = register_blkdev(hba[i]->major, hba[i]->devname); - if (rc == -EBUSY || rc == -EINVAL) { + if(rc == -EBUSY || rc == -EINVAL) { printk(KERN_ERR - "cciss: Unable to get major number %d for %s " - "on hba %d\n", hba[i]->major, hba[i]->devname, i); + "cciss: Unable to get major number %d for %s " + "on hba %d\n", hba[i]->major, hba[i]->devname, i); goto clean1; - } else { + } + else { if (i >= MAX_CTLR_ORIG) hba[i]->major = rc; } /* make sure the board interrupts are off */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); - if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, - SA_INTERRUPT | SA_SHIRQ, hba[i]->devname, hba[i])) { + if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + hba[i]->devname, hba[i])) { printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", - hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); + hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); goto clean2; } - - printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", - hba[i]->devname, pdev->device, pci_name(pdev), - hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not"); - - hba[i]->cmd_pool_bits = - kmalloc(((NR_CMDS + BITS_PER_LONG - - 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); - hba[i]->cmd_pool = (CommandList_struct *) - pci_alloc_consistent(hba[i]->pdev, - NR_CMDS * sizeof(CommandList_struct), - &(hba[i]->cmd_pool_dhandle)); - hba[i]->errinfo_pool = (ErrorInfo_struct *) - pci_alloc_consistent(hba[i]->pdev, - NR_CMDS * sizeof(ErrorInfo_struct), - &(hba[i]->errinfo_pool_dhandle)); - if ((hba[i]->cmd_pool_bits == NULL) - || (hba[i]->cmd_pool == NULL) - || (hba[i]->errinfo_pool == NULL)) { - printk(KERN_ERR "cciss: out of memory"); + hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); + hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent( + hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), + &(hba[i]->cmd_pool_dhandle)); + hba[i]->errinfo_pool = (ErrorInfo_struct *)pci_alloc_consistent( + hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), + &(hba[i]->errinfo_pool_dhandle)); + if((hba[i]->cmd_pool_bits == NULL) + || (hba[i]->cmd_pool == NULL) + || (hba[i]->errinfo_pool == NULL)) { + printk( KERN_ERR "cciss: out of memory"); goto clean4; } #ifdef CONFIG_CISS_SCSI_TAPE - hba[i]->scsi_rejects.complete = - kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) * - (NR_CMDS + 5), GFP_KERNEL); + hba[i]->scsi_rejects.complete = + kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) * + (NR_CMDS + 5), GFP_KERNEL); if (hba[i]->scsi_rejects.complete == NULL) { - printk(KERN_ERR "cciss: out of memory"); + printk( KERN_ERR "cciss: out of memory"); goto clean4; } #endif spin_lock_init(&hba[i]->lock); - /* Initialize the pdev driver private data. - have it point to hba[i]. */ + /* Initialize the pdev driver private data. + have it point to hba[i]. */ pci_set_drvdata(pdev, hba[i]); - /* command and error info recs zeroed out before - they are used */ - memset(hba[i]->cmd_pool_bits, 0, - ((NR_CMDS + BITS_PER_LONG - - 1) / BITS_PER_LONG) * sizeof(unsigned long)); + /* command and error info recs zeroed out before + they are used */ + memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long)); -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); -#endif /* CCISS_DEBUG */ +#ifdef CCISS_DEBUG + printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i); +#endif /* CCISS_DEBUG */ cciss_getgeometry(i); @@ -3220,15 +3203,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, cciss_procinit(i); hba[i]->busy_initializing = 0; - for (j = 0; j < NWD; j++) { /* mfm */ + for(j=0; j < NWD; j++) { /* mfm */ drive_info_struct *drv = &(hba[i]->drv[j]); struct gendisk *disk = hba[i]->gendisk[j]; q = blk_init_queue(do_cciss_request, &hba[i]->lock); if (!q) { printk(KERN_ERR - "cciss: unable to allocate queue for disk %d\n", - j); + "cciss: unable to allocate queue for disk %d\n", + j); break; } drv->queue = q; @@ -3254,90 +3237,94 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, disk->fops = &cciss_fops; disk->queue = q; disk->private_data = drv; - disk->driverfs_dev = &pdev->dev; /* we must register the controller even if no disks exist */ /* this is for the online array utilities */ - if (!drv->heads && j) + if(!drv->heads && j) continue; blk_queue_hardsect_size(q, drv->block_size); set_capacity(disk, drv->nr_blocks); add_disk(disk); } - return 1; + return(1); - clean4: +clean4: #ifdef CONFIG_CISS_SCSI_TAPE kfree(hba[i]->scsi_rejects.complete); #endif kfree(hba[i]->cmd_pool_bits); - if (hba[i]->cmd_pool) + if(hba[i]->cmd_pool) pci_free_consistent(hba[i]->pdev, - NR_CMDS * sizeof(CommandList_struct), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - if (hba[i]->errinfo_pool) + NR_CMDS * sizeof(CommandList_struct), + hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); + if(hba[i]->errinfo_pool) pci_free_consistent(hba[i]->pdev, - NR_CMDS * sizeof(ErrorInfo_struct), - hba[i]->errinfo_pool, - hba[i]->errinfo_pool_dhandle); + NR_CMDS * sizeof( ErrorInfo_struct), + hba[i]->errinfo_pool, + hba[i]->errinfo_pool_dhandle); free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); - clean2: +clean2: unregister_blkdev(hba[i]->major, hba[i]->devname); - clean1: +clean1: + release_io_mem(hba[i]); hba[i]->busy_initializing = 0; free_hba(i); - return -1; + return(-1); } -static void __devexit cciss_remove_one(struct pci_dev *pdev) +static void __devexit cciss_remove_one (struct pci_dev *pdev) { ctlr_info_t *tmp_ptr; int i, j; char flush_buf[4]; - int return_code; + int return_code; - if (pci_get_drvdata(pdev) == NULL) { - printk(KERN_ERR "cciss: Unable to remove device \n"); + if (pci_get_drvdata(pdev) == NULL) + { + printk( KERN_ERR "cciss: Unable to remove device \n"); return; } tmp_ptr = pci_get_drvdata(pdev); i = tmp_ptr->ctlr; - if (hba[i] == NULL) { + if (hba[i] == NULL) + { printk(KERN_ERR "cciss: device appears to " - "already be removed \n"); + "already be removed \n"); return; } /* Turn board interrupts off and send the flush cache command */ /* sendcmd will turn off interrupt, and send the flush... - * To write all data in the battery backed cache to disks */ + * To write all data in the battery backed cache to disks */ memset(flush_buf, 0, 4); return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL, - TYPE_CMD); - if (return_code != IO_OK) { - printk(KERN_WARNING "Error Flushing cache on controller %d\n", - i); + TYPE_CMD); + if(return_code != IO_OK) + { + printk(KERN_WARNING "Error Flushing cache on controller %d\n", + i); } free_irq(hba[i]->intr[2], hba[i]); #ifdef CONFIG_PCI_MSI - if (hba[i]->msix_vector) - pci_disable_msix(hba[i]->pdev); - else if (hba[i]->msi_vector) - pci_disable_msi(hba[i]->pdev); -#endif /* CONFIG_PCI_MSI */ + if (hba[i]->msix_vector) + pci_disable_msix(hba[i]->pdev); + else if (hba[i]->msi_vector) + pci_disable_msi(hba[i]->pdev); +#endif /* CONFIG_PCI_MSI */ + pci_set_drvdata(pdev, NULL); iounmap(hba[i]->vaddr); - cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ + cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ unregister_blkdev(hba[i]->major, hba[i]->devname); - remove_proc_entry(hba[i]->devname, proc_cciss); - + remove_proc_entry(hba[i]->devname, proc_cciss); + /* remove it from the disk list */ for (j = 0; j < NWD; j++) { struct gendisk *disk = hba[i]->gendisk[j]; if (disk) { request_queue_t *q = disk->queue; - if (disk->flags & GENHD_FL_UP) + if (disk->flags & GENHD_FL_UP) del_gendisk(disk); if (q) blk_cleanup_queue(q); @@ -3346,28 +3333,26 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(ErrorInfo_struct), - hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); + pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), + hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); kfree(hba[i]->cmd_pool_bits); #ifdef CONFIG_CISS_SCSI_TAPE kfree(hba[i]->scsi_rejects.complete); #endif - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); + release_io_mem(hba[i]); free_hba(i); -} +} static struct pci_driver cciss_pci_driver = { - .name = "cciss", - .probe = cciss_init_one, - .remove = __devexit_p(cciss_remove_one), - .id_table = cciss_pci_device_id, /* id_table */ + .name = "cciss", + .probe = cciss_init_one, + .remove = __devexit_p(cciss_remove_one), + .id_table = cciss_pci_device_id, /* id_table */ }; /* * This is it. Register the PCI driver information for the cards we control - * the OS will call our registered routines when it finds one of our cards. + * the OS will call our registered routines when it finds one of our cards. */ static int __init cciss_init(void) { @@ -3383,10 +3368,12 @@ static void __exit cciss_cleanup(void) pci_unregister_driver(&cciss_pci_driver); /* double check that all controller entrys have been removed */ - for (i = 0; i < MAX_CTLR; i++) { - if (hba[i] != NULL) { + for (i=0; i< MAX_CTLR; i++) + { + if (hba[i] != NULL) + { printk(KERN_WARNING "cciss: had to remove" - " controller %d\n", i); + " controller %d\n", i); cciss_remove_one(hba[i]->pdev); } } @@ -3401,21 +3388,21 @@ static void fail_all_cmds(unsigned long ctlr) unsigned long flags; printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr); - h->alive = 0; /* the controller apparently died... */ + h->alive = 0; /* the controller apparently died... */ spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - pci_disable_device(h->pdev); /* Make sure it is really dead. */ + pci_disable_device(h->pdev); /* Make sure it is really dead. */ /* move everything off the request queue onto the completed queue */ - while ((c = h->reqQ) != NULL) { + while( (c = h->reqQ) != NULL ) { removeQ(&(h->reqQ), c); h->Qdepth--; - addQ(&(h->cmpQ), c); + addQ (&(h->cmpQ), c); } /* Now, fail everything on the completed queue with a HW error */ - while ((c = h->cmpQ) != NULL) { + while( (c = h->cmpQ) != NULL ) { removeQ(&h->cmpQ, c); c->err_info->CommandStatus = CMD_HARDWARE_ERR; if (c->cmd_type == CMD_RWREQ) { @@ -3423,8 +3410,8 @@ static void fail_all_cmds(unsigned long ctlr) } else if (c->cmd_type == CMD_IOCTL_PEND) complete(c->waiting); #ifdef CONFIG_CISS_SCSI_TAPE - else if (c->cmd_type == CMD_SCSI) - complete_scsi_command(c, 0, 0); + else if (c->cmd_type == CMD_SCSI) + complete_scsi_command(c, 0, 0); #endif } spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 868e0d862b0d..b24fc0553ccf 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -60,6 +60,8 @@ struct ctlr_info __u32 board_id; void __iomem *vaddr; unsigned long paddr; + unsigned long io_mem_addr; + unsigned long io_mem_length; CfgTable_struct __iomem *cfgtable; int interrupts_enabled; int major; diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index afdff32f6724..597c007fe81b 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -578,7 +578,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) if (cmd->use_sg) { pci_unmap_sg(ctlr->pdev, - cmd->request_buffer, cmd->use_sg, + cmd->buffer, cmd->use_sg, cmd->sc_data_direction); } else if (cmd->request_bufflen) { @@ -1210,7 +1210,7 @@ cciss_scatter_gather(struct pci_dev *pdev, struct scsi_cmnd *cmd) { unsigned int use_sg, nsegs=0, len; - struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer; + struct scatterlist *scatter = (struct scatterlist *) cmd->buffer; __u64 addr64; /* is it just one virtual address? */ @@ -1232,7 +1232,7 @@ cciss_scatter_gather(struct pci_dev *pdev, } /* else, must be a list of virtual addresses.... */ else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */ - use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, + use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, cmd->sc_data_direction); for (nsegs=0; nsegs < use_sg; nsegs++) { diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index 5eb6fb7b5cfa..b6ea2f0c7276 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -392,7 +392,7 @@ static void __devexit cpqarray_remove_one_eisa (int i) } /* pdev is NULL for eisa */ -static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) +static int cpqarray_register_ctlr( int i, struct pci_dev *pdev) { request_queue_t *q; int j; @@ -410,7 +410,8 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) } hba[i]->access.set_intr_mask(hba[i], 0); if (request_irq(hba[i]->intr, do_ida_intr, - SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) + SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM, + hba[i]->devname, hba[i])) { printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", hba[i]->intr, hba[i]->devname); @@ -744,7 +745,7 @@ __setup("smart2=", cpqarray_setup); /* * Find an EISA controller's signature. Set up an hba if we find it. */ -static int __init cpqarray_eisa_detect(void) +static int cpqarray_eisa_detect(void) { int i=0, j; __u32 board_id; @@ -1035,8 +1036,6 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) complete_buffers(cmd->rq->bio, ok); - add_disk_randomness(cmd->rq->rq_disk); - DBGPX(printk("Done with %p\n", cmd->rq);); end_that_request_last(cmd->rq, ok ? 1 : -EIO); } diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 3c74ea729fc7..9c3b94e8f03b 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -818,7 +818,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, lo->lo_device = bdev; lo->lo_flags = lo_flags; lo->lo_backing_file = file; - lo->transfer = transfer_none; + lo->transfer = NULL; lo->ioctl = NULL; lo->lo_sizelimit = 0; lo->old_gfp_mask = mapping_gfp_mask(mapping); diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 7f554f2ed079..8bca4905d7f7 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -7,9 +7,39 @@ * Copyright 1997-2000 Pavel Machek * Parts copyright 2001 Steven Whitehouse * - * This file is released under GPLv2 or later. - * * (part of code stolen from loop.c) + * + * 97-3-25 compiled 0-th version, not yet tested it + * (it did not work, BTW) (later that day) HEY! it works! + * (bit later) hmm, not that much... 2:00am next day: + * yes, it works, but it gives something like 50kB/sec + * 97-4-01 complete rewrite to make it possible for many requests at + * once to be processed + * 97-4-11 Making protocol independent of endianity etc. + * 97-9-13 Cosmetic changes + * 98-5-13 Attempt to make 64-bit-clean on 64-bit machines + * 99-1-11 Attempt to make 64-bit-clean on 32-bit machines + * 01-2-27 Fix to store proper blockcount for kernel (calculated using + * BLOCK_SIZE_BITS, not device blocksize) + * 01-3-11 Make nbd work with new Linux block layer code. It now supports + * plugging like all the other block devices. Also added in MSG_MORE to + * reduce number of partial TCP segments sent. + * 01-12-6 Fix deadlock condition by making queue locks independent of + * the transmit lock. + * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes. + * + * 03-06-22 Make nbd work with new linux 2.5 block layer design. This fixes + * memory corruption from module removal and possible memory corruption + * from sending/receiving disk data. + * 03-06-23 Cosmetic changes. + * 03-06-23 Enhance diagnostics support. + * 03-06-24 Remove unneeded blksize_bits field from nbd_device struct. + * + * 03-06-24 Cleanup PARANOIA usage & code. + * 04-02-19 Remove PARANOIA, plus various cleanups (Paul Clements) + * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall + * why not: would need access_ok and friends, would share yet another + * structure with userland */ #include diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 60e9a9457c6b..c688c25992e4 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -10,13 +10,17 @@ * TODO (sorted by decreasing priority) * -- set readonly flag for CDs, set removable flag for CF readers * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) + * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries * -- verify the 13 conditions and do bulk resets + * -- kill last_pipe and simply do two-state clearing on both pipes * -- highmem * -- move top_sense and work_bcs into separate allocations (if they survive) * for cache purists and esoteric architectures. * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ? * -- prune comments, they are too volumnous + * -- Exterminate P3 printks * -- Resove XXX's + * -- Redo "benh's retries", perhaps have spin-up code to handle them. V:D=? * -- CLEAR, CLR2STS, CLRRS seem to be ripe for refactoring. */ #include @@ -176,6 +180,7 @@ struct ub_dev; #define UB_DIR_ILLEGAL2 2 #define UB_DIR_WRITE 3 +/* P3 */ #define UB_DIR_CHAR(c) (((c)==UB_DIR_WRITE)? 'w': \ (((c)==UB_DIR_READ)? 'r': 'n')) @@ -664,9 +669,8 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) */ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]); if (n_elem < 0) { - /* Impossible, because blk_rq_map_sg should not hit ENOMEM. */ printk(KERN_INFO "%s: failed request map (%d)\n", - lun->name, n_elem); + lun->name, n_elem); /* P3 */ goto drop; } if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ @@ -820,9 +824,7 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, if (urq->current_try >= 3) return -EIO; urq->current_try++; - - /* Remove this if anyone complains of flooding. */ - printk(KERN_DEBUG "%s: dir %c len/act %d/%d " + /* P3 */ printk("%s: dir %c len/act %d/%d " "[sense %x %02x %02x] retry %d\n", sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len, cmd->key, cmd->asc, cmd->ascq, urq->current_try); @@ -1239,6 +1241,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * to check. But it's not all right if the device * counts disagree with our counts. */ + /* P3 */ printk("%s: resid %d len %d act %d\n", + sc->name, len, cmd->len, cmd->act_len); goto Bad_End; } @@ -1249,6 +1253,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) ub_state_sense(sc, cmd); return; case US_BULK_STAT_PHASE: + /* P3 */ printk("%s: status PHASE\n", sc->name); goto Bad_End; default: printk(KERN_INFO "%s: unknown CSW status 0x%x\n", @@ -1563,14 +1568,16 @@ static void ub_reset_task(void *arg) } if (atomic_read(&sc->poison)) { - ; + printk(KERN_NOTICE "%s: Not resetting disconnected device\n", + sc->name); /* P3 This floods. Remove soon. XXX */ } else if ((sc->reset & 1) == 0) { ub_sync_reset(sc); msleep(700); /* usb-storage sleeps 6s (!) */ ub_probe_clear_stall(sc, sc->recv_bulk_pipe); ub_probe_clear_stall(sc, sc->send_bulk_pipe); } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { - ; + printk(KERN_NOTICE "%s: Not resetting multi-interface device\n", + sc->name); /* P3 This floods. Remove soon. XXX */ } else { if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) { printk(KERN_NOTICE @@ -1644,11 +1651,15 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) static int ub_bd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_lun *lun = disk->private_data; - struct ub_dev *sc = lun->udev; + struct ub_lun *lun; + struct ub_dev *sc; unsigned long flags; int rc; + if ((lun = disk->private_data) == NULL) + return -ENXIO; + sc = lun->udev; + spin_lock_irqsave(&ub_lock, flags); if (atomic_read(&sc->poison)) { spin_unlock_irqrestore(&ub_lock, flags); @@ -1812,8 +1823,10 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) rc = ub_submit_scsi(sc, cmd); spin_unlock_irqrestore(sc->lock, flags); - if (rc != 0) + if (rc != 0) { + printk("ub: testing ready: submit error (%d)\n", rc); /* P3 */ goto err_submit; + } wait_for_completion(&compl); @@ -1871,16 +1884,20 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, rc = ub_submit_scsi(sc, cmd); spin_unlock_irqrestore(sc->lock, flags); - if (rc != 0) + if (rc != 0) { + printk("ub: reading capacity: submit error (%d)\n", rc); /* P3 */ goto err_submit; + } wait_for_completion(&compl); if (cmd->error != 0) { + printk("ub: reading capacity: error %d\n", cmd->error); /* P3 */ rc = -EIO; goto err_read; } if (cmd->act_len != 8) { + printk("ub: reading capacity: size %d\n", cmd->act_len); /* P3 */ rc = -EIO; goto err_read; } @@ -1894,6 +1911,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, case 2048: shift = 2; break; case 4096: shift = 3; break; default: + printk("ub: Bad sector size %u\n", bsize); /* P3 */ rc = -EDOM; goto err_inv_bsize; } @@ -2005,8 +2023,17 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) sc->work_urb.error_count = 0; sc->work_urb.status = 0; - if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { + if (rc == -EPIPE) { + printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n", + sc->name); /* P3 */ + } else { + printk(KERN_NOTICE + "%s: Unable to submit GetMaxLUN (%d)\n", + sc->name, rc); + } goto err_submit; + } init_timer(&timer); timer.function = ub_probe_timeout; @@ -2019,10 +2046,21 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) del_timer_sync(&timer); usb_kill_urb(&sc->work_urb); - if ((rc = sc->work_urb.status) < 0) + if ((rc = sc->work_urb.status) < 0) { + if (rc == -EPIPE) { + printk("%s: Stall at GetMaxLUN, using 1 LUN\n", + sc->name); /* P3 */ + } else { + printk(KERN_NOTICE + "%s: Error at GetMaxLUN (%d)\n", + sc->name, rc); + } goto err_io; + } if (sc->work_urb.actual_length != 1) { + printk("%s: GetMaxLUN returned %d bytes\n", sc->name, + sc->work_urb.actual_length); /* P3 */ nluns = 0; } else { if ((nluns = *p) == 55) { @@ -2033,6 +2071,8 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) if (nluns > UB_MAX_LUNS) nluns = UB_MAX_LUNS; } + printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name, + *p, nluns); /* P3 */ } kfree(p); @@ -2230,7 +2270,7 @@ static int ub_probe(struct usb_interface *intf, * has to succeed, so we clear checks with an additional one here. * In any case it's not our business how revaliadation is implemented. */ - for (i = 0; i < 3; i++) { /* Retries for the schwag key from KS'04 */ + for (i = 0; i < 3; i++) { /* Retries for benh's key */ if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; if (rc != 0x6) break; msleep(10); @@ -2278,6 +2318,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) goto err_id; lun->udev = sc; + list_add(&lun->link, &sc->luns); snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)", lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num); @@ -2290,6 +2331,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL) goto err_diskalloc; + lun->disk = disk; sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); disk->major = UB_MAJOR; @@ -2311,9 +2353,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) blk_queue_max_sectors(q, UB_MAX_SECTORS); blk_queue_hardsect_size(q, lun->capacity.bsize); - lun->disk = disk; q->queuedata = lun; - list_add(&lun->link, &sc->luns); set_capacity(disk, lun->capacity.nsec); if (lun->removable) @@ -2326,6 +2366,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) err_blkqinit: put_disk(disk); err_diskalloc: + list_del(&lun->link); ub_id_put(lun->id); err_id: kfree(lun); @@ -2338,6 +2379,7 @@ static void ub_disconnect(struct usb_interface *intf) struct ub_dev *sc = usb_get_intfdata(intf); struct list_head *p; struct ub_lun *lun; + struct gendisk *disk; unsigned long flags; /* @@ -2393,7 +2435,9 @@ static void ub_disconnect(struct usb_interface *intf) */ list_for_each (p, &sc->luns) { lun = list_entry(p, struct ub_lun, link); - del_gendisk(lun->disk); + disk = lun->disk; + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); /* * I wish I could do: * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); diff --git a/trunk/drivers/block/viodasd.c b/trunk/drivers/block/viodasd.c index b0df4f5ab97a..f63e07bd9f9c 100644 --- a/trunk/drivers/block/viodasd.c +++ b/trunk/drivers/block/viodasd.c @@ -747,7 +747,7 @@ static int viodasd_remove(struct vio_dev *vdev) * support. */ static struct vio_device_id viodasd_device_table[] __devinitdata = { - { "block", "IBM,iSeries-viodasd" }, + { "viodasd", "" }, { "", "" } }; MODULE_DEVICE_TABLE(vio, viodasd_device_table); diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index ed8dca84ff69..a71a240611e0 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -423,9 +423,6 @@ static int dtl1_hci_send_frame(struct sk_buff *skb) nsh.len = skb->len; s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC); - if (!s) - return -ENOMEM; - skb_reserve(s, NSHL); memcpy(skb_put(s, skb->len), skb->data, skb->len); if (skb->len & 0x0001) diff --git a/trunk/drivers/cdrom/mcdx.c b/trunk/drivers/cdrom/mcdx.c index 0f6e7aab8d2c..a0b580c22d80 100644 --- a/trunk/drivers/cdrom/mcdx.c +++ b/trunk/drivers/cdrom/mcdx.c @@ -1006,7 +1006,7 @@ static int mcdx_talk(struct s_drive_stuff *stuffp, /* MODULE STUFF ***********************************************************/ -static int __init __mcdx_init(void) +int __mcdx_init(void) { int i; int drives = 0; diff --git a/trunk/drivers/cdrom/viocd.c b/trunk/drivers/cdrom/viocd.c index af6b3bfd169b..c0f817ba7adb 100644 --- a/trunk/drivers/cdrom/viocd.c +++ b/trunk/drivers/cdrom/viocd.c @@ -731,7 +731,7 @@ static int viocd_remove(struct vio_dev *vdev) * support. */ static struct vio_device_id viocd_device_table[] __devinitdata = { - { "block", "IBM,iSeries-viocd" }, + { "viocd", "" }, { "", "" } }; MODULE_DEVICE_TABLE(vio, viocd_device_table); diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 410d70cb76fb..78d928f9d9f1 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -62,23 +62,6 @@ config HW_CONSOLE depends on VT && !S390 && !UML default y -config VT_HW_CONSOLE_BINDING - bool "Support for binding and unbinding console drivers" - depends on HW_CONSOLE - default n - ---help--- - The virtual terminal is the device that interacts with the physical - terminal through console drivers. On these systems, at least one - console driver is loaded. In other configurations, additional console - drivers may be enabled, such as the framebuffer console. If more than - 1 console driver is enabled, setting this to 'y' will allow you to - select the console driver that will serve as the backend for the - virtual terminals. - - See for more - information. For framebuffer console users, please refer to - . - config SERIAL_NONSTANDARD bool "Non-standard serial port support" ---help--- @@ -687,7 +670,20 @@ config NWFLASH If you're not sure, say N. -source "drivers/char/hw_random/Kconfig" +config HW_RANDOM + tristate "Intel/AMD/VIA HW Random Number Generator support" + depends on (X86 || IA64) && PCI + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on Intel i8xx-based motherboards, + AMD 76x-based motherboards, and Via Nehemiah CPUs. + + Provides a character driver, used to read() entropy data. + + To compile this driver as a module, choose M here: the + module will be called hw_random. + + If unsure, say N. config NVRAM tristate "/dev/nvram support" @@ -869,7 +865,6 @@ config SONYPI config TANBAC_TB0219 tristate "TANBAC TB0219 base board support" depends TANBAC_TB022X - select GPIO_VR41XX menu "Ftape, the floppy tape device driver" @@ -939,35 +934,12 @@ config MWAVE config SCx200_GPIO tristate "NatSemi SCx200 GPIO Support" depends on SCx200 - select NSC_GPIO help Give userspace access to the GPIO pins on the National Semiconductor SCx200 processors. If compiled as a module, it will be called scx200_gpio. -config PC8736x_GPIO - tristate "NatSemi PC8736x GPIO Support" - depends on X86 - default SCx200_GPIO # mostly N - select NSC_GPIO # needed for support routines - help - Give userspace access to the GPIO pins on the National - Semiconductor PC-8736x (x=[03456]) SuperIO chip. The chip - has multiple functional units, inc several managed by - hwmon/pc87360 driver. Tested with PC-87366 - - If compiled as a module, it will be called pc8736x_gpio. - -config NSC_GPIO - tristate "NatSemi Base GPIO Support" - # selected by SCx200_GPIO and PC8736x_GPIO - # what about 2 selectors differing: m != y - help - Common support used (and needed) by scx200_gpio and - pc8736x_gpio drivers. If those drivers are built as - modules, this one will be too, named nsc_gpio - config CS5535_GPIO tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" depends on X86_32 diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 6e0f4469d8bb..fb919bfb2824 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -75,15 +75,13 @@ endif obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_I8K) += i8k.o obj-$(CONFIG_DS1620) += ds1620.o -obj-$(CONFIG_HW_RANDOM) += hw_random/ +obj-$(CONFIG_HW_RANDOM) += hw_random.o obj-$(CONFIG_FTAPE) += ftape/ obj-$(CONFIG_COBALT_LCD) += lcd.o obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o -obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o -obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_TANBAC_TB0219) += tb0219.o diff --git a/trunk/drivers/char/agp/Kconfig b/trunk/drivers/char/agp/Kconfig index 9826a399fa02..7c88c060a9e6 100644 --- a/trunk/drivers/char/agp/Kconfig +++ b/trunk/drivers/char/agp/Kconfig @@ -1,6 +1,7 @@ config AGP - tristate "/dev/agpgart (AGP Support)" + tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU depends on ALPHA || IA64 || PPC || X86 + default y if GART_IOMMU ---help--- AGP (Accelerated Graphics Port) is a bus system mainly used to connect graphics cards to the rest of the system. @@ -55,9 +56,9 @@ config AGP_AMD X on AMD Irongate, 761, and 762 chipsets. config AGP_AMD64 - tristate "AMD Opteron/Athlon64 on-CPU GART support" if !IOMMU + tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU depends on AGP && X86 - default y if IOMMU + default y if GART_IOMMU help This option gives you AGP support for the GLX component of X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. diff --git a/trunk/drivers/char/agp/amd-k7-agp.c b/trunk/drivers/char/agp/amd-k7-agp.c index 51d0d562d01e..1f776651ac64 100644 --- a/trunk/drivers/char/agp/amd-k7-agp.c +++ b/trunk/drivers/char/agp/amd-k7-agp.c @@ -118,7 +118,7 @@ static int amd_create_gatt_pages(int nr_tables) return retval; } -/* Since we don't need contiguous memory we just try +/* Since we don't need contigious memory we just try * to get the gatt table once */ diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index f690ee8cb732..ac3c33a2e37d 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -15,9 +15,11 @@ #include #include #include /* PAGE_SIZE */ -#include #include "agp.h" +/* Will need to be increased if AMD64 ever goes >8-way. */ +#define MAX_HAMMER_GARTS 8 + /* PTE bits. */ #define GPTE_VALID 1 #define GPTE_COHERENT 2 @@ -51,12 +53,28 @@ #define ULI_X86_64_HTT_FEA_REG 0x50 #define ULI_X86_64_ENU_SCR_REG 0x54 +static int nr_garts; +static struct pci_dev * hammers[MAX_HAMMER_GARTS]; + static struct resource *aperture_resource; static int __initdata agp_try_unsupported = 1; +#define for_each_nb() for(gart_iterator=0;gart_iteratorgatt_table_real); - int i; + int gart_iterator; /* Configure AGP regs in each x86-64 host bridge. */ - for (i = 0; i < num_k8_northbridges; i++) { + for_each_nb() { agp_bridge->gart_bus_addr = - amd64_configure(k8_northbridges[i], gatt_bus); + amd64_configure(hammers[gart_iterator],gatt_bus); } - k8_flush_garts(); return 0; } @@ -216,13 +236,12 @@ static int amd_8151_configure(void) static void amd64_cleanup(void) { u32 tmp; - int i; - for (i = 0; i < num_k8_northbridges; i++) { - struct pci_dev *dev = k8_northbridges[i]; + int gart_iterator; + for_each_nb() { /* disable gart translation */ - pci_read_config_dword (dev, AMD64_GARTAPERTURECTL, &tmp); + pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp); tmp &= ~AMD64_GARTEN; - pci_write_config_dword (dev, AMD64_GARTAPERTURECTL, tmp); + pci_write_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, tmp); } } @@ -292,7 +311,7 @@ static int __devinit aperture_valid(u64 aper, u32 size) /* * W*s centric BIOS sometimes only set up the aperture in the AGP * bridge, not the northbridge. On AMD64 this is handled early - * in aperture.c, but when IOMMU is not enabled or we run + * in aperture.c, but when GART_IOMMU is not enabled or we run * on a 32bit kernel this needs to be redone. * Unfortunately it is impossible to fix the aperture here because it's too late * to allocate that much memory. But at least error out cleanly instead of @@ -342,15 +361,17 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) { - int i; - - if (cache_k8_northbridges() < 0) - return -ENODEV; - - i = 0; - for (i = 0; i < num_k8_northbridges; i++) { - struct pci_dev *dev = k8_northbridges[i]; - if (fix_northbridge(dev, pdev, cap_ptr) < 0) { + struct pci_dev *loop_dev = NULL; + int i = 0; + + /* cache pci_devs of northbridges. */ + while ((loop_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) + != NULL) { + if (i == MAX_HAMMER_GARTS) { + printk(KERN_ERR PFX "Too many northbridges for AGP\n"); + return -1; + } + if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { printk(KERN_ERR PFX "No usable aperture found.\n"); #ifdef __x86_64__ /* should port this to i386 */ @@ -358,8 +379,10 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) #endif return -1; } + hammers[i++] = loop_dev; } - return 0; + nr_garts = i; + return i == 0 ? -1 : 0; } /* Handle AMD 8151 quirks */ @@ -427,7 +450,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) } /* shadow x86-64 registers into ULi registers */ - pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &httfea); + pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea); /* if x86-64 aperture base is beyond 4G, exit here */ if ((httfea & 0x7fff) >> (32 - 25)) @@ -490,7 +513,7 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp); /* shadow x86-64 registers into NVIDIA registers */ - pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &apbase); + pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); /* if x86-64 aperture base is beyond 4G, exit here */ if ( (apbase & 0x7fff) >> (32 - 25) ) { @@ -731,6 +754,10 @@ static struct pci_driver agp_amd64_pci_driver = { int __init agp_amd64_init(void) { int err = 0; + static struct pci_device_id amd64nb[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, + { }, + }; if (agp_off) return -EINVAL; @@ -747,7 +774,7 @@ int __init agp_amd64_init(void) } /* First check that we have at least one AMD64 NB */ - if (!pci_dev_present(k8_nb_ids)) + if (!pci_dev_present(amd64nb)) return -ENODEV; /* Look for any AGP bridge */ @@ -775,7 +802,7 @@ static void __exit agp_amd64_cleanup(void) /* On AMD64 the PCI driver needs to initialize this driver early for the IOMMU, so it has to be called via a backdoor. */ -#ifndef CONFIG_IOMMU +#ifndef CONFIG_GART_IOMMU module_init(agp_amd64_init); module_exit(agp_amd64_cleanup); #endif diff --git a/trunk/drivers/char/agp/ati-agp.c b/trunk/drivers/char/agp/ati-agp.c index 160564345993..06fd10ba0c5e 100644 --- a/trunk/drivers/char/agp/ati-agp.c +++ b/trunk/drivers/char/agp/ati-agp.c @@ -261,7 +261,7 @@ static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state) #endif /* - *Since we don't need contiguous memory we just try + *Since we don't need contigious memory we just try * to get the gatt table once */ diff --git a/trunk/drivers/char/agp/efficeon-agp.c b/trunk/drivers/char/agp/efficeon-agp.c index b788b0a3bbf3..86a966b65236 100644 --- a/trunk/drivers/char/agp/efficeon-agp.c +++ b/trunk/drivers/char/agp/efficeon-agp.c @@ -177,7 +177,7 @@ static int efficeon_free_gatt_table(struct agp_bridge_data *bridge) /* - * Since we don't need contiguous memory we just try + * Since we don't need contigious memory we just try * to get the gatt table once */ diff --git a/trunk/drivers/char/agp/hp-agp.c b/trunk/drivers/char/agp/hp-agp.c index 907fb66ec4a9..8c4c6ef748ec 100644 --- a/trunk/drivers/char/agp/hp-agp.c +++ b/trunk/drivers/char/agp/hp-agp.c @@ -497,7 +497,7 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) info = buffer.pointer; info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0'; match = (strcmp(info->hardware_id.value, "HWP0001") == 0); - kfree(info); + ACPI_MEM_FREE(info); if (match) { status = hp_acpi_csr_space(handle, &sba_hpa, &length); if (ACPI_SUCCESS(status)) diff --git a/trunk/drivers/char/agp/sgi-agp.c b/trunk/drivers/char/agp/sgi-agp.c index d73be4c2db8a..cfa7922cb431 100644 --- a/trunk/drivers/char/agp/sgi-agp.c +++ b/trunk/drivers/char/agp/sgi-agp.c @@ -329,8 +329,9 @@ static int __devinit agp_sgi_init(void) static void __devexit agp_sgi_cleanup(void) { - kfree(sgi_tioca_agp_bridges); - sgi_tioca_agp_bridges = NULL; + if (sgi_tioca_agp_bridges) + kfree(sgi_tioca_agp_bridges); + sgi_tioca_agp_bridges=NULL; } module_init(agp_sgi_init); diff --git a/trunk/drivers/char/applicom.c b/trunk/drivers/char/applicom.c index 9275d5e52e6d..a370e7a0bad5 100644 --- a/trunk/drivers/char/applicom.c +++ b/trunk/drivers/char/applicom.c @@ -166,7 +166,11 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc, return boardno + 1; } -static void __exit applicom_exit(void) +#ifdef MODULE + +#define applicom_init init_module + +void cleanup_module(void) { unsigned int i; @@ -184,7 +188,9 @@ static void __exit applicom_exit(void) } } -static int __init applicom_init(void) +#endif /* MODULE */ + +int __init applicom_init(void) { int i, numisa = 0; struct pci_dev *dev = NULL; @@ -349,9 +355,10 @@ static int __init applicom_init(void) return ret; } -module_init(applicom_init); -module_exit(applicom_exit); +#ifndef MODULE +__initcall(applicom_init); +#endif static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { @@ -844,3 +851,28 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un return 0; } +#ifndef MODULE +static int __init applicom_setup(char *str) +{ + int ints[4]; + + (void) get_options(str, 4, ints); + + if (ints[0] > 2) { + printk(KERN_WARNING "Too many arguments to 'applicom=', expected mem,irq only.\n"); + } + + if (ints[0] < 2) { + printk(KERN_INFO"applicom numargs: %d\n", ints[0]); + return 0; + } + + mem = ints[1]; + irq = ints[2]; + return 1; +} + +__setup("applicom=", applicom_setup); + +#endif /* MODULE */ + diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 122e7a72a4e1..cc7acf877dc0 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -2833,8 +2833,9 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count) return 0; } - if (!info->xmit_buf || !tmp_buf) - return 0; + if (!tty || !info->xmit_buf || !tmp_buf){ + return 0; + } CY_LOCK(info, flags); while (1) { @@ -2883,7 +2884,7 @@ cy_put_char(struct tty_struct *tty, unsigned char ch) if (serial_paranoia_check(info, tty->name, "cy_put_char")) return; - if (!info->xmit_buf) + if (!tty || !info->xmit_buf) return; CY_LOCK(info, flags); diff --git a/trunk/drivers/char/drm/drm_memory_debug.h b/trunk/drivers/char/drm/drm_memory_debug.h index d117cc997192..6543b9a14c42 100644 --- a/trunk/drivers/char/drm/drm_memory_debug.h +++ b/trunk/drivers/char/drm/drm_memory_debug.h @@ -43,7 +43,7 @@ typedef struct drm_mem_stats { unsigned long bytes_freed; } drm_mem_stats_t; -static DEFINE_SPINLOCK(drm_mem_lock); +static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; static unsigned long drm_ram_available = 0; /* In pages */ static unsigned long drm_ram_used = 0; static drm_mem_stats_t drm_mem_stats[] = diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index a94233bdbc0e..9f4b8ce4c05e 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -758,9 +758,7 @@ drm_ioctl_desc_t i915_ioctls[] = { [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH }, + [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/trunk/drivers/char/drm/i915_drm.h b/trunk/drivers/char/drm/i915_drm.h index 5aa3e0e3bb45..4cb3da578330 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -124,8 +124,6 @@ typedef struct _drm_i915_sarea { #define DRM_I915_INIT_HEAP 0x0a #define DRM_I915_CMDBUFFER 0x0b #define DRM_I915_DESTROY_HEAP 0x0c -#define DRM_I915_SET_VBLANK_PIPE 0x0d -#define DRM_I915_GET_VBLANK_PIPE 0x0e #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -140,8 +138,6 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) -#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) -#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -228,13 +224,4 @@ typedef struct drm_i915_mem_destroy_heap { int region; } drm_i915_mem_destroy_heap_t; -/* Allow X server to configure which pipes to monitor for vblank signals - */ -#define DRM_I915_VBLANK_PIPE_A 1 -#define DRM_I915_VBLANK_PIPE_B 2 - -typedef struct drm_i915_vblank_pipe { - int pipe; -} drm_i915_vblank_pipe_t; - #endif /* _I915_DRM_H_ */ diff --git a/trunk/drivers/char/drm/i915_drv.h b/trunk/drivers/char/drm/i915_drv.h index 2d565031c002..7a65666899e4 100644 --- a/trunk/drivers/char/drm/i915_drv.h +++ b/trunk/drivers/char/drm/i915_drv.h @@ -45,10 +45,9 @@ * 1.2: Add Power Management * 1.3: Add vblank support * 1.4: Fix cmdbuffer path, add heap destroy - * 1.5: Add vblank pipe configuration */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 5 +#define DRIVER_MINOR 4 #define DRIVER_PATCHLEVEL 0 typedef struct _drm_i915_ring_buffer { @@ -97,7 +96,6 @@ typedef struct drm_i915_private { int allow_batchbuffer; struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; - int vblank_pipe; } drm_i915_private_t; extern drm_ioctl_desc_t i915_ioctls[]; @@ -121,8 +119,6 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(drm_device_t * dev); extern void i915_driver_irq_postinstall(drm_device_t * dev); extern void i915_driver_irq_uninstall(drm_device_t * dev); -extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS); -extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS); /* i915_mem.c */ extern int i915_mem_alloc(DRM_IOCTL_ARGS); diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index cd96cfa430db..a752afd86ab8 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -44,8 +44,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) u16 temp; temp = I915_READ16(I915REG_INT_IDENTITY_R); - - temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); + temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG); DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); @@ -59,7 +58,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (temp & USER_INT_FLAG) DRM_WAKEUP(&dev_priv->irq_queue); - if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { + if (temp & VSYNC_PIPEA_FLAG) { atomic_inc(&dev->vbl_received); DRM_WAKEUP(&dev->vbl_queue); drm_vbl_send_signals(dev); @@ -183,68 +182,6 @@ int i915_irq_wait(DRM_IOCTL_ARGS) return i915_wait_irq(dev, irqwait.irq_seq); } -static int i915_enable_interrupt (drm_device_t *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u16 flag; - - flag = 0; - if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) - flag |= VSYNC_PIPEA_FLAG; - if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) - flag |= VSYNC_PIPEB_FLAG; - if (dev_priv->vblank_pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { - DRM_ERROR("%s called with invalid pipe 0x%x\n", - __FUNCTION__, dev_priv->vblank_pipe); - return DRM_ERR(EINVAL); - } - I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); - return 0; -} - -/* Set the vblank monitor pipe - */ -int i915_vblank_pipe_set(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t pipe; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - - DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data, - sizeof(pipe)); - - dev_priv->vblank_pipe = pipe.pipe; - return i915_enable_interrupt (dev); -} - -int i915_vblank_pipe_get(DRM_IOCTL_ARGS) -{ - DRM_DEVICE; - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t pipe; - u16 flag; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - - flag = I915_READ(I915REG_INT_ENABLE_R); - pipe.pipe = 0; - if (flag & VSYNC_PIPEA_FLAG) - pipe.pipe |= DRM_I915_VBLANK_PIPE_A; - if (flag & VSYNC_PIPEB_FLAG) - pipe.pipe |= DRM_I915_VBLANK_PIPE_B; - DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_pipe_t __user *) data, pipe, - sizeof(pipe)); - return 0; -} - /* drm_dma.h hooks */ void i915_driver_irq_preinstall(drm_device_t * dev) @@ -260,7 +197,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - i915_enable_interrupt(dev); + I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); } diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 5ad43ba7b5aa..7f949c9c9691 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -39,7 +39,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev); /* CP microcode (from ATI) */ -static const u32 R200_cp_microcode[][2] = { +static u32 R200_cp_microcode[][2] = { {0x21007000, 0000000000}, {0x20007000, 0000000000}, {0x000000ab, 0x00000004}, @@ -298,7 +298,7 @@ static const u32 R200_cp_microcode[][2] = { {0000000000, 0000000000}, }; -static const u32 radeon_cp_microcode[][2] = { +static u32 radeon_cp_microcode[][2] = { {0x21007000, 0000000000}, {0x20007000, 0000000000}, {0x000000b4, 0x00000004}, @@ -557,7 +557,7 @@ static const u32 radeon_cp_microcode[][2] = { {0000000000, 0000000000}, }; -static const u32 R300_cp_microcode[][2] = { +static u32 R300_cp_microcode[][2] = { {0x4200e000, 0000000000}, {0x4000e000, 0000000000}, {0x000000af, 0x00000008}, diff --git a/trunk/drivers/char/drm/radeon_drm.h b/trunk/drivers/char/drm/radeon_drm.h index 8d6350dd5360..c8e279e89c2e 100644 --- a/trunk/drivers/char/drm/radeon_drm.h +++ b/trunk/drivers/char/drm/radeon_drm.h @@ -161,8 +161,7 @@ #define R200_EMIT_PP_TXCTLALL_3 91 #define R200_EMIT_PP_TXCTLALL_4 92 #define R200_EMIT_PP_TXCTLALL_5 93 -#define R200_EMIT_VAP_PVS_CNTL 94 -#define RADEON_MAX_STATE_PACKETS 95 +#define RADEON_MAX_STATE_PACKETS 94 /* Commands understood by cmd_buffer ioctl. More can be added but * obviously these can't be removed or changed: @@ -177,7 +176,6 @@ #define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: * doesn't make the cpu wait, just * the graphics hardware */ -#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */ typedef union { int i; @@ -193,9 +191,6 @@ typedef union { struct { unsigned char cmd_type, offset, stride, count; } vectors; - struct { - unsigned char cmd_type, addr_lo, addr_hi, count; - } veclinear; struct { unsigned char cmd_type, buf_idx, pad0, pad1; } dma; diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index e5a256f5429c..78345cee8f8e 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20060524" +#define DRIVER_DATE "20060225" /* Interface history: * @@ -93,11 +93,9 @@ * 1.22- Add support for texture cache flushes (R300_TX_CNTL) * 1.23- Add new radeon memory map work from benh * 1.24- Add general-purpose packet for manipulating scratch registers (r300) - * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, - * new packet type) */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 25 +#define DRIVER_MINOR 24 #define DRIVER_PATCHLEVEL 0 /* @@ -886,8 +884,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 #define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 -#define RADEON_SE_TCL_STATE_FLUSH 0x2284 - #define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 #define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 #define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 @@ -909,8 +905,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define R200_PP_AFS_0 0x2f80 #define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ -#define R200_VAP_PVS_CNTL_1 0x22D0 - /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index 5bb2234a9094..c5b8f774a599 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -249,7 +249,6 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_PP_TXCTLALL_3: case R200_EMIT_PP_TXCTLALL_4: case R200_EMIT_PP_TXCTLALL_5: - case R200_EMIT_VAP_PVS_CNTL: /* These packets don't contain memory offsets */ break; @@ -627,7 +626,6 @@ static struct { {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, - {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"}, }; /* ================================================================ @@ -2597,8 +2595,7 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, int stride = header.vectors.stride; RING_LOCALS; - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); + BEGIN_RING(3 + sz); OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); @@ -2610,32 +2607,6 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, return 0; } -static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.veclinear.count * 4; - int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8); - RING_LOCALS; - - if (!sz) - return 0; - if (sz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); - - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); - OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_TABLE(cmdbuf->buf, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - static int radeon_emit_packet3(drm_device_t * dev, drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t *cmdbuf) @@ -2894,14 +2865,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) goto err; } break; - case RADEON_CMD_VECLINEAR: - DRM_DEBUG("RADEON_CMD_VECLINEAR\n"); - if (radeon_emit_veclinear(dev_priv, header, &cmdbuf)) { - DRM_ERROR("radeon_emit_veclinear failed\n"); - goto err; - } - break; - default: DRM_ERROR("bad cmd_type %d at %p\n", header.header.cmd_type, diff --git a/trunk/drivers/char/drm/via_dmablit.c b/trunk/drivers/char/drm/via_dmablit.c index 78a81a4a99c5..b7f17457b424 100644 --- a/trunk/drivers/char/drm/via_dmablit.c +++ b/trunk/drivers/char/drm/via_dmablit.c @@ -557,7 +557,7 @@ via_init_dmablit(drm_device_t *dev) blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; - spin_lock_init(&blitq->blit_lock); + blitq->blit_lock = SPIN_LOCK_UNLOCKED; for (j=0; jblit_queue + j); } diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index dc0602ae8503..9cad8501d62c 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -80,7 +80,7 @@ static int invalid_lilo_config; /* The ISA boards do window flipping into the same spaces so its only sane with a single lock. It's still pretty efficient */ -static DEFINE_SPINLOCK(epca_lock); +static spinlock_t epca_lock = SPIN_LOCK_UNLOCKED; /* ----------------------------------------------------------------------- MAXBOARDS is typically 12, but ISA and EISA cards are restricted to diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index 922174d527ae..09dc4b01232c 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/drivers/char/esp.c @@ -1212,7 +1212,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch) if (serial_paranoia_check(info, tty->name, "rs_put_char")) return; - if (!info->xmit_buf) + if (!tty || !info->xmit_buf) return; spin_lock_irqsave(&info->lock, flags); @@ -1256,7 +1256,7 @@ static int rs_write(struct tty_struct * tty, if (serial_paranoia_check(info, tty->name, "rs_write")) return 0; - if (!info->xmit_buf) + if (!tty || !info->xmit_buf) return 0; while (1) { diff --git a/trunk/drivers/char/hangcheck-timer.c b/trunk/drivers/char/hangcheck-timer.c index d69f2ad9a67d..ac626418b329 100644 --- a/trunk/drivers/char/hangcheck-timer.c +++ b/trunk/drivers/char/hangcheck-timer.c @@ -117,12 +117,12 @@ __setup("hcheck_reboot", hangcheck_parse_reboot); __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); #endif /* not MODULE */ -#if defined(CONFIG_X86_64) || defined(CONFIG_S390) +#if defined(CONFIG_X86) || defined(CONFIG_S390) # define HAVE_MONOTONIC # define TIMER_FREQ 1000000000ULL #elif defined(CONFIG_IA64) # define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq) -#else +#elif defined(CONFIG_PPC64) # define TIMER_FREQ (HZ*loops_per_jiffy) #endif diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index 07473cd84121..ef140ebde117 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -925,8 +925,11 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) status = acpi_resource_to_address64(res, &addr); if (ACPI_SUCCESS(status)) { + unsigned long size; + + size = addr.maximum - addr.minimum + 1; hdp->hd_phys_address = addr.minimum; - hdp->hd_address = ioremap(addr.minimum, addr.address_length); + hdp->hd_address = ioremap(addr.minimum, size); if (hpet_is_known(hdp)) { printk(KERN_DEBUG "%s: 0x%lx is busy\n", diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index a5c6a9d7ff08..2b6a56b2bf35 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -553,6 +553,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) #define HVC_POLL_READ 0x00000001 #define HVC_POLL_WRITE 0x00000002 +#define HVC_POLL_QUICK 0x00000004 static int hvc_poll(struct hvc_struct *hp) { @@ -567,7 +568,6 @@ static int hvc_poll(struct hvc_struct *hp) /* Push pending writes */ if (hp->n_outbuf > 0) hvc_push(hp); - /* Reschedule us if still some write pending */ if (hp->n_outbuf > 0) poll_mask |= HVC_POLL_WRITE; @@ -680,7 +680,7 @@ int khvcd(void *unused) poll_mask |= HVC_POLL_READ; if (hvc_kicked) continue; - if (poll_mask & HVC_POLL_WRITE) { + if (poll_mask & HVC_POLL_QUICK) { yield(); continue; } diff --git a/trunk/drivers/char/hvc_rtas.c b/trunk/drivers/char/hvc_rtas.c index 57106e02fd2e..83364ea63cba 100644 --- a/trunk/drivers/char/hvc_rtas.c +++ b/trunk/drivers/char/hvc_rtas.c @@ -41,28 +41,37 @@ #define hvc_rtas_cookie 0x67781e15 struct hvc_struct *hvc_rtas_dev; +#define RTASCONS_PUT_ATTEMPTS 16 + static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE; static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE; +static int rtascons_put_delay = 100; +module_param_named(put_delay, rtascons_put_delay, int, 0644); -static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, - int count) +static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count) { - int i; + int done; - for (i = 0; i < count; i++) { - if (rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[i])) + /* if there is more than one character to be displayed, wait a bit */ + for (done = 0; done < count; done++) { + int result; + result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]); + if (result) break; } - - return i; + /* the calling routine expects to receive the number of bytes sent */ + return done; } static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count) { - int i, c; + int i; for (i = 0; i < count; i++) { - if (rtas_call(rtascons_get_char_token, 0, 2, &c)) + int c, err; + + err = rtas_call(rtascons_get_char_token, 0, 2, &c); + if (err) break; buf[i] = c; @@ -97,9 +106,7 @@ static int hvc_rtas_init(void) hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops); if (IS_ERR(hp)) return PTR_ERR(hp); - hvc_rtas_dev = hp; - return 0; } module_init(hvc_rtas_init); @@ -107,8 +114,8 @@ module_init(hvc_rtas_init); /* This will tear down the tty portion of the driver */ static void __exit hvc_rtas_exit(void) { - /* Really the fun isn't over until the worker thread breaks down and - * the tty cleans up */ + /* Really the fun isn't over until the worker thread breaks down and the + * tty cleans up */ if (hvc_rtas_dev) hvc_remove(hvc_rtas_dev); } @@ -120,14 +127,12 @@ static int hvc_rtas_console_init(void) rtascons_put_char_token = rtas_token("put-term-char"); if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) return -EIO; - rtascons_get_char_token = rtas_token("get-term-char"); if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) return -EIO; - hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops); + hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops ); add_preferred_console("hvc", 0, NULL); - return 0; } console_initcall(hvc_rtas_console_init); diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index afa26b65dac3..8d97b3911293 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -1320,12 +1320,11 @@ static struct tty_operations hvcs_ops = { static int hvcs_alloc_index_list(int n) { int i; - hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); if (!hvcs_index_list) return -ENOMEM; hvcs_index_count = n; - for (i = 0; i < hvcs_index_count; i++) + for(i = 0; i < hvcs_index_count; i++) hvcs_index_list[i] = -1; return 0; } @@ -1333,9 +1332,11 @@ static int hvcs_alloc_index_list(int n) static void hvcs_free_index_list(void) { /* Paranoia check to be thorough. */ - kfree(hvcs_index_list); - hvcs_index_list = NULL; - hvcs_index_count = 0; + if (hvcs_index_list) { + kfree(hvcs_index_list); + hvcs_index_list = NULL; + hvcs_index_count = 0; + } } static int __init hvcs_module_init(void) diff --git a/trunk/drivers/char/hvsi.c b/trunk/drivers/char/hvsi.c index a0370ed752ce..a9522189fc9e 100644 --- a/trunk/drivers/char/hvsi.c +++ b/trunk/drivers/char/hvsi.c @@ -1179,7 +1179,7 @@ static int __init hvsi_init(void) if (tty_register_driver(hvsi_driver)) panic("Couldn't register hvsi console driver\n"); - printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); + printk(KERN_INFO "HVSI: registered %i devices\n", hvsi_count); return 0; } diff --git a/trunk/drivers/char/hw_random.c b/trunk/drivers/char/hw_random.c new file mode 100644 index 000000000000..29dc87e59020 --- /dev/null +++ b/trunk/drivers/char/hw_random.c @@ -0,0 +1,698 @@ +/* + Added support for the AMD Geode LX RNG + (c) Copyright 2004-2005 Advanced Micro Devices, Inc. + + derived from + + Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) + (c) Copyright 2003 Red Hat Inc + + derived from + + Hardware driver for the AMD 768 Random Number Generator (RNG) + (c) Copyright 2001 Red Hat Inc + + derived from + + Hardware driver for Intel i810 Random Number Generator (RNG) + Copyright 2000,2001 Jeff Garzik + Copyright 2000,2001 Philipp Rumpf + + Please read Documentation/hw_random.txt for details on use. + + ---------------------------------------------------------- + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. + + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __i386__ +#include +#include +#endif + +#include +#include + + +/* + * core module and version information + */ +#define RNG_VERSION "1.0.0" +#define RNG_MODULE_NAME "hw_random" +#define RNG_DRIVER_NAME RNG_MODULE_NAME " hardware driver " RNG_VERSION +#define PFX RNG_MODULE_NAME ": " + + +/* + * debugging macros + */ + +/* pr_debug() collapses to a no-op if DEBUG is not defined */ +#define DPRINTK(fmt, args...) pr_debug(PFX "%s: " fmt, __FUNCTION__ , ## args) + + +#undef RNG_NDEBUG /* define to enable lightweight runtime checks */ +#ifdef RNG_NDEBUG +#define assert(expr) \ + if(!(expr)) { \ + printk(KERN_DEBUG PFX "Assertion failed! %s,%s,%s," \ + "line=%d\n", #expr, __FILE__, __FUNCTION__, __LINE__); \ + } +#else +#define assert(expr) +#endif + +#define RNG_MISCDEV_MINOR 183 /* official */ + +static int rng_dev_open (struct inode *inode, struct file *filp); +static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, + loff_t * offp); + +static int __init intel_init (struct pci_dev *dev); +static void intel_cleanup(void); +static unsigned int intel_data_present (void); +static u32 intel_data_read (void); + +static int __init amd_init (struct pci_dev *dev); +static void amd_cleanup(void); +static unsigned int amd_data_present (void); +static u32 amd_data_read (void); + +#ifdef __i386__ +static int __init via_init(struct pci_dev *dev); +static void via_cleanup(void); +static unsigned int via_data_present (void); +static u32 via_data_read (void); +#endif + +static int __init geode_init(struct pci_dev *dev); +static void geode_cleanup(void); +static unsigned int geode_data_present (void); +static u32 geode_data_read (void); + +struct rng_operations { + int (*init) (struct pci_dev *dev); + void (*cleanup) (void); + unsigned int (*data_present) (void); + u32 (*data_read) (void); + unsigned int n_bytes; /* number of bytes per ->data_read */ +}; +static struct rng_operations *rng_ops; + +static struct file_operations rng_chrdev_ops = { + .owner = THIS_MODULE, + .open = rng_dev_open, + .read = rng_dev_read, +}; + + +static struct miscdevice rng_miscdev = { + RNG_MISCDEV_MINOR, + RNG_MODULE_NAME, + &rng_chrdev_ops, +}; + +enum { + rng_hw_none, + rng_hw_intel, + rng_hw_amd, +#ifdef __i386__ + rng_hw_via, +#endif + rng_hw_geode, +}; + +static struct rng_operations rng_vendor_ops[] = { + /* rng_hw_none */ + { }, + + /* rng_hw_intel */ + { intel_init, intel_cleanup, intel_data_present, + intel_data_read, 1 }, + + /* rng_hw_amd */ + { amd_init, amd_cleanup, amd_data_present, amd_data_read, 4 }, + +#ifdef __i386__ + /* rng_hw_via */ + { via_init, via_cleanup, via_data_present, via_data_read, 1 }, +#endif + + /* rng_hw_geode */ + { geode_init, geode_cleanup, geode_data_present, geode_data_read, 4 } +}; + +/* + * Data for PCI driver interface + * + * This data only exists for exporting the supported + * PCI ids via MODULE_DEVICE_TABLE. We do not actually + * register a pci_driver, because someone else might one day + * want to register another driver on the same PCI id. + */ +static struct pci_device_id rng_pci_tbl[] = { + { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd }, + { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd }, + + { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, + + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_geode }, + + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE (pci, rng_pci_tbl); + + +/*********************************************************************** + * + * Intel RNG operations + * + */ + +/* + * RNG registers (offsets from rng_mem) + */ +#define INTEL_RNG_HW_STATUS 0 +#define INTEL_RNG_PRESENT 0x40 +#define INTEL_RNG_ENABLED 0x01 +#define INTEL_RNG_STATUS 1 +#define INTEL_RNG_DATA_PRESENT 0x01 +#define INTEL_RNG_DATA 2 + +/* + * Magic address at which Intel PCI bridges locate the RNG + */ +#define INTEL_RNG_ADDR 0xFFBC015F +#define INTEL_RNG_ADDR_LEN 3 + +/* token to our ioremap'd RNG register area */ +static void __iomem *rng_mem; + +static inline u8 intel_hwstatus (void) +{ + assert (rng_mem != NULL); + return readb (rng_mem + INTEL_RNG_HW_STATUS); +} + +static inline u8 intel_hwstatus_set (u8 hw_status) +{ + assert (rng_mem != NULL); + writeb (hw_status, rng_mem + INTEL_RNG_HW_STATUS); + return intel_hwstatus (); +} + +static unsigned int intel_data_present(void) +{ + assert (rng_mem != NULL); + + return (readb (rng_mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT) ? + 1 : 0; +} + +static u32 intel_data_read(void) +{ + assert (rng_mem != NULL); + + return readb (rng_mem + INTEL_RNG_DATA); +} + +static int __init intel_init (struct pci_dev *dev) +{ + int rc; + u8 hw_status; + + DPRINTK ("ENTER\n"); + + rng_mem = ioremap (INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); + if (rng_mem == NULL) { + printk (KERN_ERR PFX "cannot ioremap RNG Memory\n"); + rc = -EBUSY; + goto err_out; + } + + /* Check for Intel 82802 */ + hw_status = intel_hwstatus (); + if ((hw_status & INTEL_RNG_PRESENT) == 0) { + printk (KERN_ERR PFX "RNG not detected\n"); + rc = -ENODEV; + goto err_out_free_map; + } + + /* turn RNG h/w on, if it's off */ + if ((hw_status & INTEL_RNG_ENABLED) == 0) + hw_status = intel_hwstatus_set (hw_status | INTEL_RNG_ENABLED); + if ((hw_status & INTEL_RNG_ENABLED) == 0) { + printk (KERN_ERR PFX "cannot enable RNG, aborting\n"); + rc = -EIO; + goto err_out_free_map; + } + + DPRINTK ("EXIT, returning 0\n"); + return 0; + +err_out_free_map: + iounmap (rng_mem); + rng_mem = NULL; +err_out: + DPRINTK ("EXIT, returning %d\n", rc); + return rc; +} + +static void intel_cleanup(void) +{ + u8 hw_status; + + hw_status = intel_hwstatus (); + if (hw_status & INTEL_RNG_ENABLED) + intel_hwstatus_set (hw_status & ~INTEL_RNG_ENABLED); + else + printk(KERN_WARNING PFX "unusual: RNG already disabled\n"); + iounmap(rng_mem); + rng_mem = NULL; +} + +/*********************************************************************** + * + * AMD RNG operations + * + */ + +static u32 pmbase; /* PMxx I/O base */ +static struct pci_dev *amd_dev; + +static unsigned int amd_data_present (void) +{ + return inl(pmbase + 0xF4) & 1; +} + + +static u32 amd_data_read (void) +{ + return inl(pmbase + 0xF0); +} + +static int __init amd_init (struct pci_dev *dev) +{ + int rc; + u8 rnen; + + DPRINTK ("ENTER\n"); + + pci_read_config_dword(dev, 0x58, &pmbase); + + pmbase &= 0x0000FF00; + + if (pmbase == 0) + { + printk (KERN_ERR PFX "power management base not set\n"); + rc = -EIO; + goto err_out; + } + + pci_read_config_byte(dev, 0x40, &rnen); + rnen |= (1 << 7); /* RNG on */ + pci_write_config_byte(dev, 0x40, rnen); + + pci_read_config_byte(dev, 0x41, &rnen); + rnen |= (1 << 7); /* PMIO enable */ + pci_write_config_byte(dev, 0x41, rnen); + + pr_info( PFX "AMD768 system management I/O registers at 0x%X.\n", + pmbase); + + amd_dev = dev; + + DPRINTK ("EXIT, returning 0\n"); + return 0; + +err_out: + DPRINTK ("EXIT, returning %d\n", rc); + return rc; +} + +static void amd_cleanup(void) +{ + u8 rnen; + + pci_read_config_byte(amd_dev, 0x40, &rnen); + rnen &= ~(1 << 7); /* RNG off */ + pci_write_config_byte(amd_dev, 0x40, rnen); + + /* FIXME: twiddle pmio, also? */ +} + +#ifdef __i386__ +/*********************************************************************** + * + * VIA RNG operations + * + */ + +enum { + VIA_STRFILT_CNT_SHIFT = 16, + VIA_STRFILT_FAIL = (1 << 15), + VIA_STRFILT_ENABLE = (1 << 14), + VIA_RAWBITS_ENABLE = (1 << 13), + VIA_RNG_ENABLE = (1 << 6), + VIA_XSTORE_CNT_MASK = 0x0F, + + VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */ + VIA_RNG_CHUNK_4 = 0x01, /* 32 rand bits, 32 stored bits */ + VIA_RNG_CHUNK_4_MASK = 0xFFFFFFFF, + VIA_RNG_CHUNK_2 = 0x02, /* 16 rand bits, 32 stored bits */ + VIA_RNG_CHUNK_2_MASK = 0xFFFF, + VIA_RNG_CHUNK_1 = 0x03, /* 8 rand bits, 32 stored bits */ + VIA_RNG_CHUNK_1_MASK = 0xFF, +}; + +static u32 via_rng_datum; + +/* + * Investigate using the 'rep' prefix to obtain 32 bits of random data + * in one insn. The upside is potentially better performance. The + * downside is that the instruction becomes no longer atomic. Due to + * this, just like familiar issues with /dev/random itself, the worst + * case of a 'rep xstore' could potentially pause a cpu for an + * unreasonably long time. In practice, this condition would likely + * only occur when the hardware is failing. (or so we hope :)) + * + * Another possible performance boost may come from simply buffering + * until we have 4 bytes, thus returning a u32 at a time, + * instead of the current u8-at-a-time. + */ + +static inline u32 xstore(u32 *addr, u32 edx_in) +{ + u32 eax_out; + + asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" + :"=m"(*addr), "=a"(eax_out) + :"D"(addr), "d"(edx_in)); + + return eax_out; +} + +static unsigned int via_data_present(void) +{ + u32 bytes_out; + + /* We choose the recommended 1-byte-per-instruction RNG rate, + * for greater randomness at the expense of speed. Larger + * values 2, 4, or 8 bytes-per-instruction yield greater + * speed at lesser randomness. + * + * If you change this to another VIA_CHUNK_n, you must also + * change the ->n_bytes values in rng_vendor_ops[] tables. + * VIA_CHUNK_8 requires further code changes. + * + * A copy of MSR_VIA_RNG is placed in eax_out when xstore + * completes. + */ + via_rng_datum = 0; /* paranoia, not really necessary */ + bytes_out = xstore(&via_rng_datum, VIA_RNG_CHUNK_1) & VIA_XSTORE_CNT_MASK; + if (bytes_out == 0) + return 0; + + return 1; +} + +static u32 via_data_read(void) +{ + return via_rng_datum; +} + +static int __init via_init(struct pci_dev *dev) +{ + u32 lo, hi, old_lo; + + /* Control the RNG via MSR. Tread lightly and pay very close + * close attention to values written, as the reserved fields + * are documented to be "undefined and unpredictable"; but it + * does not say to write them as zero, so I make a guess that + * we restore the values we find in the register. + */ + rdmsr(MSR_VIA_RNG, lo, hi); + + old_lo = lo; + lo &= ~(0x7f << VIA_STRFILT_CNT_SHIFT); + lo &= ~VIA_XSTORE_CNT_MASK; + lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE); + lo |= VIA_RNG_ENABLE; + + if (lo != old_lo) + wrmsr(MSR_VIA_RNG, lo, hi); + + /* perhaps-unnecessary sanity check; remove after testing if + unneeded */ + rdmsr(MSR_VIA_RNG, lo, hi); + if ((lo & VIA_RNG_ENABLE) == 0) { + printk(KERN_ERR PFX "cannot enable VIA C3 RNG, aborting\n"); + return -ENODEV; + } + + return 0; +} + +static void via_cleanup(void) +{ + /* do nothing */ +} +#endif + +/*********************************************************************** + * + * AMD Geode RNG operations + * + */ + +static void __iomem *geode_rng_base = NULL; + +#define GEODE_RNG_DATA_REG 0x50 +#define GEODE_RNG_STATUS_REG 0x54 + +static u32 geode_data_read(void) +{ + u32 val; + + assert(geode_rng_base != NULL); + val = readl(geode_rng_base + GEODE_RNG_DATA_REG); + return val; +} + +static unsigned int geode_data_present(void) +{ + u32 val; + + assert(geode_rng_base != NULL); + val = readl(geode_rng_base + GEODE_RNG_STATUS_REG); + return val; +} + +static void geode_cleanup(void) +{ + iounmap(geode_rng_base); + geode_rng_base = NULL; +} + +static int geode_init(struct pci_dev *dev) +{ + unsigned long rng_base = pci_resource_start(dev, 0); + + if (rng_base == 0) + return 1; + + geode_rng_base = ioremap(rng_base, 0x58); + + if (geode_rng_base == NULL) { + printk(KERN_ERR PFX "Cannot ioremap RNG memory\n"); + return -EBUSY; + } + + return 0; +} + +/*********************************************************************** + * + * /dev/hwrandom character device handling (major 10, minor 183) + * + */ + +static int rng_dev_open (struct inode *inode, struct file *filp) +{ + /* enforce read-only access to this chrdev */ + if ((filp->f_mode & FMODE_READ) == 0) + return -EINVAL; + if (filp->f_mode & FMODE_WRITE) + return -EINVAL; + + return 0; +} + + +static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, + loff_t * offp) +{ + static DEFINE_SPINLOCK(rng_lock); + unsigned int have_data; + u32 data = 0; + ssize_t ret = 0; + + while (size) { + spin_lock(&rng_lock); + + have_data = 0; + if (rng_ops->data_present()) { + data = rng_ops->data_read(); + have_data = rng_ops->n_bytes; + } + + spin_unlock (&rng_lock); + + while (have_data && size) { + if (put_user((u8)data, buf++)) { + ret = ret ? : -EFAULT; + break; + } + size--; + ret++; + have_data--; + data>>=8; + } + + if (filp->f_flags & O_NONBLOCK) + return ret ? : -EAGAIN; + + if(need_resched()) + schedule_timeout_interruptible(1); + else + udelay(200); /* FIXME: We could poll for 250uS ?? */ + + if (signal_pending (current)) + return ret ? : -ERESTARTSYS; + } + return ret; +} + + + +/* + * rng_init_one - look for and attempt to init a single RNG + */ +static int __init rng_init_one (struct pci_dev *dev) +{ + int rc; + + DPRINTK ("ENTER\n"); + + assert(rng_ops != NULL); + + rc = rng_ops->init(dev); + if (rc) + goto err_out; + + rc = misc_register (&rng_miscdev); + if (rc) { + printk (KERN_ERR PFX "misc device register failed\n"); + goto err_out_cleanup_hw; + } + + DPRINTK ("EXIT, returning 0\n"); + return 0; + +err_out_cleanup_hw: + rng_ops->cleanup(); +err_out: + DPRINTK ("EXIT, returning %d\n", rc); + return rc; +} + + + +MODULE_AUTHOR("The Linux Kernel team"); +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL"); + + +/* + * rng_init - initialize RNG module + */ +static int __init rng_init (void) +{ + int rc; + struct pci_dev *pdev = NULL; + const struct pci_device_id *ent; + + DPRINTK ("ENTER\n"); + + /* Probe for Intel, AMD, Geode RNGs */ + for_each_pci_dev(pdev) { + ent = pci_match_id(rng_pci_tbl, pdev); + if (ent) { + rng_ops = &rng_vendor_ops[ent->driver_data]; + goto match; + } + } + +#ifdef __i386__ + /* Probe for VIA RNG */ + if (cpu_has_xstore) { + rng_ops = &rng_vendor_ops[rng_hw_via]; + pdev = NULL; + goto match; + } +#endif + + DPRINTK ("EXIT, returning -ENODEV\n"); + return -ENODEV; + +match: + rc = rng_init_one (pdev); + if (rc) + return rc; + + pr_info( RNG_DRIVER_NAME " loaded\n"); + + DPRINTK ("EXIT, returning 0\n"); + return 0; +} + + +/* + * rng_init - shutdown RNG module + */ +static void __exit rng_cleanup (void) +{ + DPRINTK ("ENTER\n"); + + misc_deregister (&rng_miscdev); + + if (rng_ops->cleanup) + rng_ops->cleanup(); + + DPRINTK ("EXIT\n"); +} + + +module_init (rng_init); +module_exit (rng_cleanup); diff --git a/trunk/drivers/char/hw_random/Kconfig b/trunk/drivers/char/hw_random/Kconfig deleted file mode 100644 index 9f7635f75178..000000000000 --- a/trunk/drivers/char/hw_random/Kconfig +++ /dev/null @@ -1,90 +0,0 @@ -# -# Hardware Random Number Generator (RNG) configuration -# - -config HW_RANDOM - bool "Hardware Random Number Generator Core support" - default y - ---help--- - Hardware Random Number Generator Core infrastructure. - - If unsure, say Y. - -config HW_RANDOM_INTEL - tristate "Intel HW Random Number Generator support" - depends on HW_RANDOM && (X86 || IA64) && PCI - default y - ---help--- - This driver provides kernel-side support for the Random Number - Generator hardware found on Intel i8xx-based motherboards. - - To compile this driver as a module, choose M here: the - module will be called intel-rng. - - If unsure, say Y. - -config HW_RANDOM_AMD - tristate "AMD HW Random Number Generator support" - depends on HW_RANDOM && X86 && PCI - default y - ---help--- - This driver provides kernel-side support for the Random Number - Generator hardware found on AMD 76x-based motherboards. - - To compile this driver as a module, choose M here: the - module will be called amd-rng. - - If unsure, say Y. - -config HW_RANDOM_GEODE - tristate "AMD Geode HW Random Number Generator support" - depends on HW_RANDOM && X86 && PCI - default y - ---help--- - This driver provides kernel-side support for the Random Number - Generator hardware found on the AMD Geode LX. - - To compile this driver as a module, choose M here: the - module will be called geode-rng. - - If unsure, say Y. - -config HW_RANDOM_VIA - tristate "VIA HW Random Number Generator support" - depends on HW_RANDOM && X86_32 - default y - ---help--- - This driver provides kernel-side support for the Random Number - Generator hardware found on VIA based motherboards. - - To compile this driver as a module, choose M here: the - module will be called via-rng. - - If unsure, say Y. - -config HW_RANDOM_IXP4XX - tristate "Intel IXP4xx NPU HW Random Number Generator support" - depends on HW_RANDOM && ARCH_IXP4XX - default y - ---help--- - This driver provides kernel-side support for the Random - Number Generator hardware found on the Intel IXP4xx NPU. - - To compile this driver as a module, choose M here: the - module will be called ixp4xx-rng. - - If unsure, say Y. - -config HW_RANDOM_OMAP - tristate "OMAP Random Number Generator support" - depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX) - default y - ---help--- - This driver provides kernel-side support for the Random Number - Generator hardware found on OMAP16xx and OMAP24xx multimedia - processors. - - To compile this driver as a module, choose M here: the - module will be called omap-rng. - - If unsure, say Y. diff --git a/trunk/drivers/char/hw_random/Makefile b/trunk/drivers/char/hw_random/Makefile deleted file mode 100644 index e263ae96f940..000000000000 --- a/trunk/drivers/char/hw_random/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for HW Random Number Generator (RNG) device drivers. -# - -obj-$(CONFIG_HW_RANDOM) += core.o -obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o -obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o -obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o -obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o -obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o -obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o diff --git a/trunk/drivers/char/hw_random/amd-rng.c b/trunk/drivers/char/hw_random/amd-rng.c deleted file mode 100644 index 71e4e0f3fd54..000000000000 --- a/trunk/drivers/char/hw_random/amd-rng.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * RNG driver for AMD RNGs - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * with the majority of the code coming from: - * - * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) - * (c) Copyright 2003 Red Hat Inc - * - * derived from - * - * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc - * - * derived from - * - * Hardware driver for Intel i810 Random Number Generator (RNG) - * Copyright 2000,2001 Jeff Garzik - * Copyright 2000,2001 Philipp Rumpf - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - - -#define PFX KBUILD_MODNAME ": " - - -/* - * Data for PCI driver interface - * - * This data only exists for exporting the supported - * PCI ids via MODULE_DEVICE_TABLE. We do not actually - * register a pci_driver, because someone else might one day - * want to register another driver on the same PCI id. - */ -static const struct pci_device_id pci_tbl[] = { - { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0, }, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct pci_dev *amd_pdev; - - -static int amd_rng_data_present(struct hwrng *rng) -{ - u32 pmbase = (u32)rng->priv; - - return !!(inl(pmbase + 0xF4) & 1); -} - -static int amd_rng_data_read(struct hwrng *rng, u32 *data) -{ - u32 pmbase = (u32)rng->priv; - - *data = inl(pmbase + 0xF0); - - return 4; -} - -static int amd_rng_init(struct hwrng *rng) -{ - u8 rnen; - - pci_read_config_byte(amd_pdev, 0x40, &rnen); - rnen |= (1 << 7); /* RNG on */ - pci_write_config_byte(amd_pdev, 0x40, rnen); - - pci_read_config_byte(amd_pdev, 0x41, &rnen); - rnen |= (1 << 7); /* PMIO enable */ - pci_write_config_byte(amd_pdev, 0x41, rnen); - - return 0; -} - -static void amd_rng_cleanup(struct hwrng *rng) -{ - u8 rnen; - - pci_read_config_byte(amd_pdev, 0x40, &rnen); - rnen &= ~(1 << 7); /* RNG off */ - pci_write_config_byte(amd_pdev, 0x40, rnen); -} - - -static struct hwrng amd_rng = { - .name = "amd", - .init = amd_rng_init, - .cleanup = amd_rng_cleanup, - .data_present = amd_rng_data_present, - .data_read = amd_rng_data_read, -}; - - -static int __init mod_init(void) -{ - int err = -ENODEV; - struct pci_dev *pdev = NULL; - const struct pci_device_id *ent; - u32 pmbase; - - for_each_pci_dev(pdev) { - ent = pci_match_id(pci_tbl, pdev); - if (ent) - goto found; - } - /* Device not found. */ - goto out; - -found: - err = pci_read_config_dword(pdev, 0x58, &pmbase); - if (err) - goto out; - err = -EIO; - pmbase &= 0x0000FF00; - if (pmbase == 0) - goto out; - amd_rng.priv = (unsigned long)pmbase; - amd_pdev = pdev; - - printk(KERN_INFO "AMD768 RNG detected\n"); - err = hwrng_register(&amd_rng); - if (err) { - printk(KERN_ERR PFX "RNG registering failed (%d)\n", - err); - goto out; - } -out: - return err; -} - -static void __exit mod_exit(void) -{ - hwrng_unregister(&amd_rng); -} - -subsys_initcall(mod_init); -module_exit(mod_exit); - -MODULE_AUTHOR("The Linux Kernel team"); -MODULE_DESCRIPTION("H/W RNG driver for AMD chipsets"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/core.c b/trunk/drivers/char/hw_random/core.c deleted file mode 100644 index 88b026639f10..000000000000 --- a/trunk/drivers/char/hw_random/core.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - Added support for the AMD Geode LX RNG - (c) Copyright 2004-2005 Advanced Micro Devices, Inc. - - derived from - - Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) - (c) Copyright 2003 Red Hat Inc - - derived from - - Hardware driver for the AMD 768 Random Number Generator (RNG) - (c) Copyright 2001 Red Hat Inc - - derived from - - Hardware driver for Intel i810 Random Number Generator (RNG) - Copyright 2000,2001 Jeff Garzik - Copyright 2000,2001 Philipp Rumpf - - Added generic RNG API - Copyright 2006 Michael Buesch - Copyright 2005 (c) MontaVista Software, Inc. - - Please read Documentation/hw_random.txt for details on use. - - ---------------------------------------------------------- - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define RNG_MODULE_NAME "hw_random" -#define PFX RNG_MODULE_NAME ": " -#define RNG_MISCDEV_MINOR 183 /* official */ - - -static struct hwrng *current_rng; -static LIST_HEAD(rng_list); -static DEFINE_MUTEX(rng_mutex); - - -static inline int hwrng_init(struct hwrng *rng) -{ - if (!rng->init) - return 0; - return rng->init(rng); -} - -static inline void hwrng_cleanup(struct hwrng *rng) -{ - if (rng && rng->cleanup) - rng->cleanup(rng); -} - -static inline int hwrng_data_present(struct hwrng *rng) -{ - if (!rng->data_present) - return 1; - return rng->data_present(rng); -} - -static inline int hwrng_data_read(struct hwrng *rng, u32 *data) -{ - return rng->data_read(rng, data); -} - - -static int rng_dev_open(struct inode *inode, struct file *filp) -{ - /* enforce read-only access to this chrdev */ - if ((filp->f_mode & FMODE_READ) == 0) - return -EINVAL; - if (filp->f_mode & FMODE_WRITE) - return -EINVAL; - return 0; -} - -static ssize_t rng_dev_read(struct file *filp, char __user *buf, - size_t size, loff_t *offp) -{ - u32 data; - ssize_t ret = 0; - int i, err = 0; - int data_present; - int bytes_read; - - while (size) { - err = -ERESTARTSYS; - if (mutex_lock_interruptible(&rng_mutex)) - goto out; - if (!current_rng) { - mutex_unlock(&rng_mutex); - err = -ENODEV; - goto out; - } - if (filp->f_flags & O_NONBLOCK) { - data_present = hwrng_data_present(current_rng); - } else { - /* Some RNG require some time between data_reads to gather - * new entropy. Poll it. - */ - for (i = 0; i < 20; i++) { - data_present = hwrng_data_present(current_rng); - if (data_present) - break; - udelay(10); - } - } - bytes_read = 0; - if (data_present) - bytes_read = hwrng_data_read(current_rng, &data); - mutex_unlock(&rng_mutex); - - err = -EAGAIN; - if (!bytes_read && (filp->f_flags & O_NONBLOCK)) - goto out; - - err = -EFAULT; - while (bytes_read && size) { - if (put_user((u8)data, buf++)) - goto out; - size--; - ret++; - bytes_read--; - data >>= 8; - } - - if (need_resched()) - schedule_timeout_interruptible(1); - err = -ERESTARTSYS; - if (signal_pending(current)) - goto out; - } -out: - return ret ? : err; -} - - -static struct file_operations rng_chrdev_ops = { - .owner = THIS_MODULE, - .open = rng_dev_open, - .read = rng_dev_read, -}; - -static struct miscdevice rng_miscdev = { - .minor = RNG_MISCDEV_MINOR, - .name = RNG_MODULE_NAME, - .fops = &rng_chrdev_ops, -}; - - -static ssize_t hwrng_attr_current_store(struct class_device *class, - const char *buf, size_t len) -{ - int err; - struct hwrng *rng; - - err = mutex_lock_interruptible(&rng_mutex); - if (err) - return -ERESTARTSYS; - err = -ENODEV; - list_for_each_entry(rng, &rng_list, list) { - if (strcmp(rng->name, buf) == 0) { - if (rng == current_rng) { - err = 0; - break; - } - err = hwrng_init(rng); - if (err) - break; - hwrng_cleanup(current_rng); - current_rng = rng; - err = 0; - break; - } - } - mutex_unlock(&rng_mutex); - - return err ? : len; -} - -static ssize_t hwrng_attr_current_show(struct class_device *class, - char *buf) -{ - int err; - ssize_t ret; - const char *name = "none"; - - err = mutex_lock_interruptible(&rng_mutex); - if (err) - return -ERESTARTSYS; - if (current_rng) - name = current_rng->name; - ret = snprintf(buf, PAGE_SIZE, "%s\n", name); - mutex_unlock(&rng_mutex); - - return ret; -} - -static ssize_t hwrng_attr_available_show(struct class_device *class, - char *buf) -{ - int err; - ssize_t ret = 0; - struct hwrng *rng; - - err = mutex_lock_interruptible(&rng_mutex); - if (err) - return -ERESTARTSYS; - buf[0] = '\0'; - list_for_each_entry(rng, &rng_list, list) { - strncat(buf, rng->name, PAGE_SIZE - ret - 1); - ret += strlen(rng->name); - strncat(buf, " ", PAGE_SIZE - ret - 1); - ret++; - } - strncat(buf, "\n", PAGE_SIZE - ret - 1); - ret++; - mutex_unlock(&rng_mutex); - - return ret; -} - -static CLASS_DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, - hwrng_attr_current_show, - hwrng_attr_current_store); -static CLASS_DEVICE_ATTR(rng_available, S_IRUGO, - hwrng_attr_available_show, - NULL); - - -static void unregister_miscdev(void) -{ - class_device_remove_file(rng_miscdev.class, - &class_device_attr_rng_available); - class_device_remove_file(rng_miscdev.class, - &class_device_attr_rng_current); - misc_deregister(&rng_miscdev); -} - -static int register_miscdev(void) -{ - int err; - - err = misc_register(&rng_miscdev); - if (err) - goto out; - err = class_device_create_file(rng_miscdev.class, - &class_device_attr_rng_current); - if (err) - goto err_misc_dereg; - err = class_device_create_file(rng_miscdev.class, - &class_device_attr_rng_available); - if (err) - goto err_remove_current; -out: - return err; - -err_remove_current: - class_device_remove_file(rng_miscdev.class, - &class_device_attr_rng_current); -err_misc_dereg: - misc_deregister(&rng_miscdev); - goto out; -} - -int hwrng_register(struct hwrng *rng) -{ - int must_register_misc; - int err = -EINVAL; - struct hwrng *old_rng, *tmp; - - if (rng->name == NULL || - rng->data_read == NULL) - goto out; - - mutex_lock(&rng_mutex); - - /* Must not register two RNGs with the same name. */ - err = -EEXIST; - list_for_each_entry(tmp, &rng_list, list) { - if (strcmp(tmp->name, rng->name) == 0) - goto out_unlock; - } - - must_register_misc = (current_rng == NULL); - old_rng = current_rng; - if (!old_rng) { - err = hwrng_init(rng); - if (err) - goto out_unlock; - current_rng = rng; - } - err = 0; - if (must_register_misc) { - err = register_miscdev(); - if (err) { - if (!old_rng) { - hwrng_cleanup(rng); - current_rng = NULL; - } - goto out_unlock; - } - } - INIT_LIST_HEAD(&rng->list); - list_add_tail(&rng->list, &rng_list); -out_unlock: - mutex_unlock(&rng_mutex); -out: - return err; -} -EXPORT_SYMBOL_GPL(hwrng_register); - -void hwrng_unregister(struct hwrng *rng) -{ - int err; - - mutex_lock(&rng_mutex); - - list_del(&rng->list); - if (current_rng == rng) { - hwrng_cleanup(rng); - if (list_empty(&rng_list)) { - current_rng = NULL; - } else { - current_rng = list_entry(rng_list.prev, struct hwrng, list); - err = hwrng_init(current_rng); - if (err) - current_rng = NULL; - } - } - if (list_empty(&rng_list)) - unregister_miscdev(); - - mutex_unlock(&rng_mutex); -} -EXPORT_SYMBOL_GPL(hwrng_unregister); - - -MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/geode-rng.c b/trunk/drivers/char/hw_random/geode-rng.c deleted file mode 100644 index be61f22ee7bb..000000000000 --- a/trunk/drivers/char/hw_random/geode-rng.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * RNG driver for AMD Geode RNGs - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * with the majority of the code coming from: - * - * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) - * (c) Copyright 2003 Red Hat Inc - * - * derived from - * - * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc - * - * derived from - * - * Hardware driver for Intel i810 Random Number Generator (RNG) - * Copyright 2000,2001 Jeff Garzik - * Copyright 2000,2001 Philipp Rumpf - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - - -#define PFX KBUILD_MODNAME ": " - -#define GEODE_RNG_DATA_REG 0x50 -#define GEODE_RNG_STATUS_REG 0x54 - -/* - * Data for PCI driver interface - * - * This data only exists for exporting the supported - * PCI ids via MODULE_DEVICE_TABLE. We do not actually - * register a pci_driver, because someone else might one day - * want to register another driver on the same PCI id. - */ -static const struct pci_device_id pci_tbl[] = { - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0, }, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, pci_tbl); - - -static int geode_rng_data_read(struct hwrng *rng, u32 *data) -{ - void __iomem *mem = (void __iomem *)rng->priv; - - *data = readl(mem + GEODE_RNG_DATA_REG); - - return 4; -} - -static int geode_rng_data_present(struct hwrng *rng) -{ - void __iomem *mem = (void __iomem *)rng->priv; - - return !!(readl(mem + GEODE_RNG_STATUS_REG)); -} - - -static struct hwrng geode_rng = { - .name = "geode", - .data_present = geode_rng_data_present, - .data_read = geode_rng_data_read, -}; - - -static int __init mod_init(void) -{ - int err = -ENODEV; - struct pci_dev *pdev = NULL; - const struct pci_device_id *ent; - void __iomem *mem; - unsigned long rng_base; - - for_each_pci_dev(pdev) { - ent = pci_match_id(pci_tbl, pdev); - if (ent) - goto found; - } - /* Device not found. */ - goto out; - -found: - rng_base = pci_resource_start(pdev, 0); - if (rng_base == 0) - goto out; - err = -ENOMEM; - mem = ioremap(rng_base, 0x58); - if (!mem) - goto out; - geode_rng.priv = (unsigned long)mem; - - printk(KERN_INFO "AMD Geode RNG detected\n"); - err = hwrng_register(&geode_rng); - if (err) { - printk(KERN_ERR PFX "RNG registering failed (%d)\n", - err); - goto out; - } -out: - return err; -} - -static void __exit mod_exit(void) -{ - void __iomem *mem = (void __iomem *)geode_rng.priv; - - hwrng_unregister(&geode_rng); - iounmap(mem); -} - -subsys_initcall(mod_init); -module_exit(mod_exit); - -MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/intel-rng.c b/trunk/drivers/char/hw_random/intel-rng.c deleted file mode 100644 index 6594bd5645f4..000000000000 --- a/trunk/drivers/char/hw_random/intel-rng.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * RNG driver for Intel RNGs - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * with the majority of the code coming from: - * - * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) - * (c) Copyright 2003 Red Hat Inc - * - * derived from - * - * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc - * - * derived from - * - * Hardware driver for Intel i810 Random Number Generator (RNG) - * Copyright 2000,2001 Jeff Garzik - * Copyright 2000,2001 Philipp Rumpf - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - - -#define PFX KBUILD_MODNAME ": " - -/* - * RNG registers - */ -#define INTEL_RNG_HW_STATUS 0 -#define INTEL_RNG_PRESENT 0x40 -#define INTEL_RNG_ENABLED 0x01 -#define INTEL_RNG_STATUS 1 -#define INTEL_RNG_DATA_PRESENT 0x01 -#define INTEL_RNG_DATA 2 - -/* - * Magic address at which Intel PCI bridges locate the RNG - */ -#define INTEL_RNG_ADDR 0xFFBC015F -#define INTEL_RNG_ADDR_LEN 3 - -/* - * Data for PCI driver interface - * - * This data only exists for exporting the supported - * PCI ids via MODULE_DEVICE_TABLE. We do not actually - * register a pci_driver, because someone else might one day - * want to register another driver on the same PCI id. - */ -static const struct pci_device_id pci_tbl[] = { - { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { 0, }, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, pci_tbl); - - -static inline u8 hwstatus_get(void __iomem *mem) -{ - return readb(mem + INTEL_RNG_HW_STATUS); -} - -static inline u8 hwstatus_set(void __iomem *mem, - u8 hw_status) -{ - writeb(hw_status, mem + INTEL_RNG_HW_STATUS); - return hwstatus_get(mem); -} - -static int intel_rng_data_present(struct hwrng *rng) -{ - void __iomem *mem = (void __iomem *)rng->priv; - - return !!(readb(mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT); -} - -static int intel_rng_data_read(struct hwrng *rng, u32 *data) -{ - void __iomem *mem = (void __iomem *)rng->priv; - - *data = readb(mem + INTEL_RNG_DATA); - - return 1; -} - -static int intel_rng_init(struct hwrng *rng) -{ - void __iomem *mem = (void __iomem *)rng->priv; - u8 hw_status; - int err = -EIO; - - hw_status = hwstatus_get(mem); - /* turn RNG h/w on, if it's off */ - if ((hw_status & INTEL_RNG_ENABLED) == 0) - hw_status = hwstatus_set(mem, hw_status | INTEL_RNG_ENABLED); - if ((hw_status & INTEL_RNG_ENABLED) == 0) { - printk(KERN_ERR PFX "cannot enable RNG, aborting\n"); - goto out; - } - err = 0; -out: - return err; -} - -static void intel_rng_cleanup(struct hwrng *rng) -{ - void __iomem *mem = (void __iomem *)rng->priv; - u8 hw_status; - - hw_status = hwstatus_get(mem); - if (hw_status & INTEL_RNG_ENABLED) - hwstatus_set(mem, hw_status & ~INTEL_RNG_ENABLED); - else - printk(KERN_WARNING PFX "unusual: RNG already disabled\n"); -} - - -static struct hwrng intel_rng = { - .name = "intel", - .init = intel_rng_init, - .cleanup = intel_rng_cleanup, - .data_present = intel_rng_data_present, - .data_read = intel_rng_data_read, -}; - - -static int __init mod_init(void) -{ - int err = -ENODEV; - void __iomem *mem; - u8 hw_status; - - if (!pci_dev_present(pci_tbl)) - goto out; /* Device not found. */ - - err = -ENOMEM; - mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); - if (!mem) - goto out; - intel_rng.priv = (unsigned long)mem; - - /* Check for Intel 82802 */ - err = -ENODEV; - hw_status = hwstatus_get(mem); - if ((hw_status & INTEL_RNG_PRESENT) == 0) - goto err_unmap; - - printk(KERN_INFO "Intel 82802 RNG detected\n"); - err = hwrng_register(&intel_rng); - if (err) { - printk(KERN_ERR PFX "RNG registering failed (%d)\n", - err); - goto out; - } -out: - return err; - -err_unmap: - iounmap(mem); - goto out; -} - -static void __exit mod_exit(void) -{ - void __iomem *mem = (void __iomem *)intel_rng.priv; - - hwrng_unregister(&intel_rng); - iounmap(mem); -} - -subsys_initcall(mod_init); -module_exit(mod_exit); - -MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/ixp4xx-rng.c b/trunk/drivers/char/hw_random/ixp4xx-rng.c deleted file mode 100644 index ef71022423c9..000000000000 --- a/trunk/drivers/char/hw_random/ixp4xx-rng.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * drivers/char/rng/ixp4xx-rng.c - * - * RNG driver for Intel IXP4xx family of NPUs - * - * Author: Deepak Saxena - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * Fixes by Michael Buesch - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer) -{ - void __iomem * rng_base = (void __iomem *)rng->priv; - - *buffer = __raw_readl(rng_base); - - return 4; -} - -static struct hwrng ixp4xx_rng_ops = { - .name = "ixp4xx", - .data_read = ixp4xx_rng_data_read, -}; - -static int __init ixp4xx_rng_init(void) -{ - void __iomem * rng_base; - int err; - - rng_base = ioremap(0x70002100, 4); - if (!rng_base) - return -ENOMEM; - ixp4xx_rng_ops.priv = (unsigned long)rng_base; - err = hwrng_register(&ixp4xx_rng_ops); - if (err) - iounmap(rng_base); - - return err; -} - -static void __exit ixp4xx_rng_exit(void) -{ - void __iomem * rng_base = (void __iomem *)ixp4xx_rng_ops.priv; - - hwrng_unregister(&ixp4xx_rng_ops); - iounmap(rng_base); -} - -subsys_initcall(ixp4xx_rng_init); -module_exit(ixp4xx_rng_exit); - -MODULE_AUTHOR("Deepak Saxena "); -MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/omap-rng.c b/trunk/drivers/char/hw_random/omap-rng.c deleted file mode 100644 index 819516b35a79..000000000000 --- a/trunk/drivers/char/hw_random/omap-rng.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * driver/char/hw_random/omap-rng.c - * - * RNG driver for TI OMAP CPU family - * - * Author: Deepak Saxena - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * Mostly based on original driver: - * - * Copyright (C) 2005 Nokia Corporation - * Author: Juha Yrjᅵᅵ - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - * - * TODO: - * - * - Make status updated be interrupt driven so we don't poll - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define RNG_OUT_REG 0x00 /* Output register */ -#define RNG_STAT_REG 0x04 /* Status register - [0] = STAT_BUSY */ -#define RNG_ALARM_REG 0x24 /* Alarm register - [7:0] = ALARM_COUNTER */ -#define RNG_CONFIG_REG 0x28 /* Configuration register - [11:6] = RESET_COUNT - [5:3] = RING2_DELAY - [2:0] = RING1_DELAY */ -#define RNG_REV_REG 0x3c /* Revision register - [7:0] = REV_NB */ -#define RNG_MASK_REG 0x40 /* Mask and reset register - [2] = IT_EN - [1] = SOFTRESET - [0] = AUTOIDLE */ -#define RNG_SYSSTATUS 0x44 /* System status - [0] = RESETDONE */ - -static void __iomem *rng_base; -static struct clk *rng_ick; -static struct device *rng_dev; - -static u32 omap_rng_read_reg(int reg) -{ - return __raw_readl(rng_base + reg); -} - -static void omap_rng_write_reg(int reg, u32 val) -{ - __raw_writel(val, rng_base + reg); -} - -/* REVISIT: Does the status bit really work on 16xx? */ -static int omap_rng_data_present(struct hwrng *rng) -{ - return omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1; -} - -static int omap_rng_data_read(struct hwrng *rng, u32 *data) -{ - *data = omap_rng_read_reg(RNG_OUT_REG); - - return 4; -} - -static struct hwrng omap_rng_ops = { - .name = "omap", - .data_present = omap_rng_data_present, - .data_read = omap_rng_data_read, -}; - -static int __init omap_rng_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct resource *res, *mem; - int ret; - - /* - * A bit ugly, and it will never actually happen but there can - * be only one RNG and this catches any bork - */ - BUG_ON(rng_dev); - - if (cpu_is_omap24xx()) { - rng_ick = clk_get(NULL, "rng_ick"); - if (IS_ERR(rng_ick)) { - dev_err(dev, "Could not get rng_ick\n"); - ret = PTR_ERR(rng_ick); - return ret; - } - else { - clk_use(rng_ick); - } - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) - return -ENOENT; - - mem = request_mem_region(res->start, res->end - res->start + 1, - pdev->name); - if (mem == NULL) - return -EBUSY; - - dev_set_drvdata(dev, mem); - rng_base = (u32 __iomem *)io_p2v(res->start); - - ret = hwrng_register(&omap_rng_ops); - if (ret) { - release_resource(mem); - rng_base = NULL; - return ret; - } - - dev_info(dev, "OMAP Random Number Generator ver. %02x\n", - omap_rng_read_reg(RNG_REV_REG)); - omap_rng_write_reg(RNG_MASK_REG, 0x1); - - rng_dev = dev; - - return 0; -} - -static int __exit omap_rng_remove(struct device *dev) -{ - struct resource *mem = dev_get_drvdata(dev); - - hwrng_unregister(&omap_rng_ops); - - omap_rng_write_reg(RNG_MASK_REG, 0x0); - - if (cpu_is_omap24xx()) { - clk_unuse(rng_ick); - clk_put(rng_ick); - } - - release_resource(mem); - rng_base = NULL; - - return 0; -} - -#ifdef CONFIG_PM - -static int omap_rng_suspend(struct device *dev, pm_message_t message, u32 level) -{ - omap_rng_write_reg(RNG_MASK_REG, 0x0); - - return 0; -} - -static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level) -{ - omap_rng_write_reg(RNG_MASK_REG, 0x1); - - return 1; -} - -#else - -#define omap_rng_suspend NULL -#define omap_rng_resume NULL - -#endif - - -static struct device_driver omap_rng_driver = { - .name = "omap_rng", - .bus = &platform_bus_type, - .probe = omap_rng_probe, - .remove = __exit_p(omap_rng_remove), - .suspend = omap_rng_suspend, - .resume = omap_rng_resume -}; - -static int __init omap_rng_init(void) -{ - if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) - return -ENODEV; - - return driver_register(&omap_rng_driver); -} - -static void __exit omap_rng_exit(void) -{ - driver_unregister(&omap_rng_driver); -} - -module_init(omap_rng_init); -module_exit(omap_rng_exit); - -MODULE_AUTHOR("Deepak Saxena (and others)"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/hw_random/via-rng.c b/trunk/drivers/char/hw_random/via-rng.c deleted file mode 100644 index 0e786b617bb8..000000000000 --- a/trunk/drivers/char/hw_random/via-rng.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * RNG driver for VIA RNGs - * - * Copyright 2005 (c) MontaVista Software, Inc. - * - * with the majority of the code coming from: - * - * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG) - * (c) Copyright 2003 Red Hat Inc - * - * derived from - * - * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc - * - * derived from - * - * Hardware driver for Intel i810 Random Number Generator (RNG) - * Copyright 2000,2001 Jeff Garzik - * Copyright 2000,2001 Philipp Rumpf - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include - - -#define PFX KBUILD_MODNAME ": " - - -enum { - VIA_STRFILT_CNT_SHIFT = 16, - VIA_STRFILT_FAIL = (1 << 15), - VIA_STRFILT_ENABLE = (1 << 14), - VIA_RAWBITS_ENABLE = (1 << 13), - VIA_RNG_ENABLE = (1 << 6), - VIA_XSTORE_CNT_MASK = 0x0F, - - VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */ - VIA_RNG_CHUNK_4 = 0x01, /* 32 rand bits, 32 stored bits */ - VIA_RNG_CHUNK_4_MASK = 0xFFFFFFFF, - VIA_RNG_CHUNK_2 = 0x02, /* 16 rand bits, 32 stored bits */ - VIA_RNG_CHUNK_2_MASK = 0xFFFF, - VIA_RNG_CHUNK_1 = 0x03, /* 8 rand bits, 32 stored bits */ - VIA_RNG_CHUNK_1_MASK = 0xFF, -}; - -/* - * Investigate using the 'rep' prefix to obtain 32 bits of random data - * in one insn. The upside is potentially better performance. The - * downside is that the instruction becomes no longer atomic. Due to - * this, just like familiar issues with /dev/random itself, the worst - * case of a 'rep xstore' could potentially pause a cpu for an - * unreasonably long time. In practice, this condition would likely - * only occur when the hardware is failing. (or so we hope :)) - * - * Another possible performance boost may come from simply buffering - * until we have 4 bytes, thus returning a u32 at a time, - * instead of the current u8-at-a-time. - */ - -static inline u32 xstore(u32 *addr, u32 edx_in) -{ - u32 eax_out; - - asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" - :"=m"(*addr), "=a"(eax_out) - :"D"(addr), "d"(edx_in)); - - return eax_out; -} - -static int via_rng_data_present(struct hwrng *rng) -{ - u32 bytes_out; - u32 *via_rng_datum = (u32 *)(&rng->priv); - - /* We choose the recommended 1-byte-per-instruction RNG rate, - * for greater randomness at the expense of speed. Larger - * values 2, 4, or 8 bytes-per-instruction yield greater - * speed at lesser randomness. - * - * If you change this to another VIA_CHUNK_n, you must also - * change the ->n_bytes values in rng_vendor_ops[] tables. - * VIA_CHUNK_8 requires further code changes. - * - * A copy of MSR_VIA_RNG is placed in eax_out when xstore - * completes. - */ - - *via_rng_datum = 0; /* paranoia, not really necessary */ - bytes_out = xstore(via_rng_datum, VIA_RNG_CHUNK_1); - bytes_out &= VIA_XSTORE_CNT_MASK; - if (bytes_out == 0) - return 0; - return 1; -} - -static int via_rng_data_read(struct hwrng *rng, u32 *data) -{ - u32 via_rng_datum = (u32)rng->priv; - - *data = via_rng_datum; - - return 1; -} - -static int via_rng_init(struct hwrng *rng) -{ - u32 lo, hi, old_lo; - - /* Control the RNG via MSR. Tread lightly and pay very close - * close attention to values written, as the reserved fields - * are documented to be "undefined and unpredictable"; but it - * does not say to write them as zero, so I make a guess that - * we restore the values we find in the register. - */ - rdmsr(MSR_VIA_RNG, lo, hi); - - old_lo = lo; - lo &= ~(0x7f << VIA_STRFILT_CNT_SHIFT); - lo &= ~VIA_XSTORE_CNT_MASK; - lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE); - lo |= VIA_RNG_ENABLE; - - if (lo != old_lo) - wrmsr(MSR_VIA_RNG, lo, hi); - - /* perhaps-unnecessary sanity check; remove after testing if - unneeded */ - rdmsr(MSR_VIA_RNG, lo, hi); - if ((lo & VIA_RNG_ENABLE) == 0) { - printk(KERN_ERR PFX "cannot enable VIA C3 RNG, aborting\n"); - return -ENODEV; - } - - return 0; -} - - -static struct hwrng via_rng = { - .name = "via", - .init = via_rng_init, - .data_present = via_rng_data_present, - .data_read = via_rng_data_read, -}; - - -static int __init mod_init(void) -{ - int err; - - if (!cpu_has_xstore) - return -ENODEV; - printk(KERN_INFO "VIA RNG detected\n"); - err = hwrng_register(&via_rng); - if (err) { - printk(KERN_ERR PFX "RNG registering failed (%d)\n", - err); - goto out; - } -out: - return err; -} - -static void __exit mod_exit(void) -{ - hwrng_unregister(&via_rng); -} - -subsys_initcall(mod_init); -module_exit(mod_exit); - -MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index 9ab33c3d359f..03db1cb3fa95 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -305,7 +305,7 @@ static struct class *ip2_class; // Some functions to keep track of what irq's we have -static int +static int __init is_valid_irq(int irq) { int *i = Valid_Irqs; @@ -316,14 +316,14 @@ is_valid_irq(int irq) return (*i); } -static void +static void __init mark_requested_irq( char irq ) { rirqs[iindx++] = irq; } #ifdef MODULE -static int +static int __init clear_requested_irq( char irq ) { int i; @@ -337,7 +337,7 @@ clear_requested_irq( char irq ) } #endif -static int +static int __init have_requested_irq( char irq ) { // array init to zeros so 0 irq will not be requested as a side effect @@ -818,7 +818,7 @@ EXPORT_SYMBOL(ip2_loadmain); /* the board, the channel structures are initialized, and the board details */ /* are reported on the console. */ /******************************************************************************/ -static void +static void __init ip2_init_board( int boardnum ) { int i; @@ -961,7 +961,7 @@ ip2_init_board( int boardnum ) /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */ /* it returns the base address of the controller. */ /******************************************************************************/ -static unsigned short +static unsigned short __init find_eisa_board( int start_slot ) { int i, j; diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 83ed6ae466a5..9f2f8fdec69a 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -57,7 +57,8 @@ static int ipmi_init_msghandler(void); static int initialized = 0; #ifdef CONFIG_PROC_FS -static struct proc_dir_entry *proc_ipmi_root = NULL; +struct proc_dir_entry *proc_ipmi_root = NULL; +EXPORT_SYMBOL(proc_ipmi_root); #endif /* CONFIG_PROC_FS */ #define MAX_EVENTS_IN_QUEUE 25 @@ -935,8 +936,11 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) if (val) { /* Deliver any queued events. */ - list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) - list_move_tail(&msg->link, &msgs); + list_for_each_entry_safe(msg, msg2, &intf->waiting_events, + link) { + list_del(&msg->link); + list_add_tail(&msg->link, &msgs); + } intf->waiting_events_count = 0; } @@ -3673,7 +3677,7 @@ static void send_panic_events(char *str) } #endif /* CONFIG_IPMI_PANIC_EVENT */ -static int has_panicked = 0; +static int has_paniced = 0; static int panic_event(struct notifier_block *this, unsigned long event, @@ -3682,9 +3686,9 @@ static int panic_event(struct notifier_block *this, int i; ipmi_smi_t intf; - if (has_panicked) + if (has_paniced) return NOTIFY_DONE; - has_panicked = 1; + has_paniced = 1; /* For every registered interface, set it to run to completion. */ for (i = 0; i < MAX_IPMI_INTERFACES; i++) { diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 101c14b9b26d..02a7dd7a8a55 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -809,7 +809,7 @@ static int ipmi_thread(void *data) /* do nothing */ } else if (smi_result == SI_SM_CALL_WITH_DELAY) - schedule(); + udelay(1); else schedule_timeout_interruptible(1); } diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 8f8867170973..2d11ddd99e55 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -212,16 +212,24 @@ static int set_param_str(const char *val, struct kernel_param *kp) { action_fn fn = (action_fn) kp->arg; int rv = 0; - char *dup, *s; - - dup = kstrdup(val, GFP_KERNEL); - if (!dup) - return -ENOMEM; - - s = strstrip(dup); + const char *end; + char valcp[16]; + int len; + + /* Truncate leading and trailing spaces. */ + while (isspace(*val)) + val++; + end = val + strlen(val) - 1; + while ((end >= val) && isspace(*end)) + end--; + len = end - val + 1; + if (len > sizeof(valcp) - 1) + return -EINVAL; + memcpy(valcp, val, len); + valcp[len] = '\0'; down_read(®ister_sem); - rv = fn(s, NULL); + rv = fn(valcp, NULL); if (rv) goto out_unlock; @@ -231,7 +239,6 @@ static int set_param_str(const char *val, struct kernel_param *kp) out_unlock: up_read(®ister_sem); - kfree(dup); return rv; } diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index efaaa1937ab6..e9ebabaf8cb0 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -1145,7 +1145,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf, if (isicom_paranoia_check(port, tty->name, "isicom_write")) return 0; - if (!port->xmit_buf) + if (!tty || !port->xmit_buf) return 0; spin_lock_irqsave(&card->card_lock, flags); @@ -1180,7 +1180,7 @@ static void isicom_put_char(struct tty_struct *tty, unsigned char ch) if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) return; - if (!port->xmit_buf) + if (!tty || !port->xmit_buf) return; spin_lock_irqsave(&card->card_lock, flags); diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index 4bb3d2272604..5755b7e5f187 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -39,7 +39,6 @@ #include #include #include -#include static void kbd_disconnect(struct input_handle *handle); extern void ctrl_alt_del(void); @@ -151,7 +150,6 @@ unsigned char kbd_sysrq_xlate[KEY_MAX + 1] = "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ "\r\000/"; /* 0x60 - 0x6f */ static int sysrq_down; -static int sysrq_alt_use; #endif static int sysrq_alt; @@ -674,7 +672,7 @@ static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struc */ static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; + static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; value = ret_diacr[value]; k_deadunicode(vc, value, up_flag, regs); } @@ -711,8 +709,8 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) { - static const char pad_chars[] = "0123456789+-*/\015,.?()#"; - static const char app_map[] = "pqrstuvwxylSRQMnnmPQS"; + static const char *pad_chars = "0123456789+-*/\015,.?()#"; + static const char *app_map = "pqrstuvwxylSRQMnnmPQS"; if (up_flag) return; /* no action, if this is a key release */ @@ -1037,7 +1035,7 @@ static void kbd_refresh_leds(struct input_handle *handle) #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) -static const unsigned short x86_keycodes[256] = +static unsigned short x86_keycodes[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -1075,13 +1073,11 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, put_queue(vc, 0x1d | up_flag); put_queue(vc, 0x45 | up_flag); return 0; - case KEY_HANGEUL: - if (!up_flag) - put_queue(vc, 0xf2); + case KEY_HANGUEL: + if (!up_flag) put_queue(vc, 0xf1); return 0; case KEY_HANJA: - if (!up_flag) - put_queue(vc, 0xf1); + if (!up_flag) put_queue(vc, 0xf2); return 0; } @@ -1146,7 +1142,7 @@ static void kbd_keycode(unsigned int keycode, int down, kbd = kbd_table + fg_console; if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) - sysrq_alt = down ? keycode : 0; + sysrq_alt = down; #ifdef CONFIG_SPARC if (keycode == KEY_STOP) sparc_l1_a_state = down; @@ -1166,14 +1162,9 @@ static void kbd_keycode(unsigned int keycode, int down, #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) { - if (!sysrq_down) { - sysrq_down = down; - sysrq_alt_use = sysrq_alt; - } + sysrq_down = down; return; } - if (sysrq_down && !down && keycode == sysrq_alt_use) - sysrq_down = 0; if (sysrq_down && down && !rep) { handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty); return; diff --git a/trunk/drivers/char/mmtimer.c b/trunk/drivers/char/mmtimer.c index d65b3109318a..1b05fa688996 100644 --- a/trunk/drivers/char/mmtimer.c +++ b/trunk/drivers/char/mmtimer.c @@ -329,6 +329,7 @@ static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma) if (PAGE_SIZE > (1 << 16)) return -ENOSYS; + vma->vm_flags |= (VM_IO | VM_SHM | VM_LOCKED ); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); mmtimer_addr = __pa(RTC_COUNTER_ADDR); diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 01247cccb89f..f43c2e04eadd 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -301,7 +301,7 @@ static struct tty_operations moxa_ops = { .tiocmset = moxa_tiocmset, }; -static DEFINE_SPINLOCK(moxa_lock); +static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; #ifdef CONFIG_PCI static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 645d9d713aec..0fb2fb9fb024 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -9,7 +9,7 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +* (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -71,8 +71,8 @@ #define MXSERMAJOR 174 #define MXSERCUMAJOR 175 -#define MXSER_EVENT_TXLOW 1 -#define MXSER_EVENT_HANGUP 2 +#define MXSER_EVENT_TXLOW 1 +#define MXSER_EVENT_HANGUP 2 #define MXSER_BOARDS 4 /* Max. boards */ #define MXSER_PORTS 32 /* Max. ports */ @@ -92,8 +92,7 @@ #define UART_MCR_AFE 0x20 #define UART_LSR_SPECIAL 0x1E -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\ - IXON|IXOFF)) +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|IXON|IXOFF)) #define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) @@ -153,27 +152,27 @@ static char *mxser_brdname[] = { }; static int mxser_numports[] = { - 8, /* C168-ISA */ - 4, /* C104-ISA */ - 4, /* CI104J */ - 8, /* C168-PCI */ - 4, /* C104-PCI */ - 2, /* C102-ISA */ - 2, /* CI132 */ - 4, /* CI134 */ - 2, /* CP132 */ - 4, /* CP114 */ - 4, /* CT114 */ - 2, /* CP102 */ - 4, /* CP104U */ - 8, /* CP168U */ - 2, /* CP132U */ - 4, /* CP134U */ - 4, /* CP104JU */ - 8, /* RC7000 */ - 8, /* CP118U */ - 2, /* CP102UL */ - 2, /* CP102U */ + 8, // C168-ISA + 4, // C104-ISA + 4, // CI104J + 8, // C168-PCI + 4, // C104-PCI + 2, // C102-ISA + 2, // CI132 + 4, // CI134 + 2, // CP132 + 4, // CP114 + 4, // CT114 + 2, // CP102 + 4, // CP104U + 8, // CP168U + 2, // CP132U + 4, // CP134U + 4, // CP104JU + 8, // RC7000 + 8, // CP118U + 2, // CP102UL + 2, // CP102U }; #define UART_TYPE_NUM 2 @@ -183,7 +182,7 @@ static const unsigned int Gmoxa_uart_id[UART_TYPE_NUM] = { MOXA_MUST_MU860_HWID }; -/* This is only for PCI */ +// This is only for PCI #define UART_INFO_NUM 3 struct mxpciuart_info { int type; @@ -232,7 +231,7 @@ MODULE_DEVICE_TABLE(pci, mxser_pcibrds); typedef struct _moxa_pci_info { unsigned short busNum; unsigned short devNum; - struct pci_dev *pdev; /* add by Victor Yu. 06-23-2003 */ + struct pci_dev *pdev; // add by Victor Yu. 06-23-2003 } moxa_pci_info; static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 }; @@ -281,7 +280,6 @@ struct mxser_mon_ext { int fifo[32]; int iftype[32]; }; - struct mxser_hwconf { int board_type; int ports; @@ -292,9 +290,9 @@ struct mxser_hwconf { int ioaddr[MXSER_PORTS_PER_BOARD]; int baud_base[MXSER_PORTS_PER_BOARD]; moxa_pci_info pciInfo; - int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ - int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 09-04-2002 */ - int opmode_ioaddr[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 01-05-2004 */ + int IsMoxaMustChipFlag; // add by Victor Yu. 08-30-2002 + int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD]; // add by Victor Yu. 09-04-2002 + int opmode_ioaddr[MXSER_PORTS_PER_BOARD]; // add by Victor Yu. 01-05-2004 }; struct mxser_struct { @@ -336,9 +334,9 @@ struct mxser_struct { wait_queue_head_t delta_msr_wait; struct async_icount icount; /* kernel counters for the 4 input interrupts */ int timeout; - int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */ - int MaxCanSetBaudRate; /* add by Victor Yu. 09-04-2002 */ - int opmode_ioaddr; /* add by Victor Yu. 01-05-2004 */ + int IsMoxaMustChipFlag; // add by Victor Yu. 08-30-2002 + int MaxCanSetBaudRate; // add by Victor Yu. 09-04-2002 + int opmode_ioaddr; // add by Victor Yu. 01-05-2004 unsigned char stop_rx; unsigned char ldisc_stop_rx; long realbaud; @@ -347,6 +345,7 @@ struct mxser_struct { spinlock_t slock; }; + struct mxser_mstatus { tcflag_t cflag; int cts; @@ -359,7 +358,7 @@ static struct mxser_mstatus GMStatus[MXSER_PORTS]; static int mxserBoardCAP[MXSER_BOARDS] = { 0, 0, 0, 0 - /* 0x180, 0x280, 0x200, 0x320 */ + /* 0x180, 0x280, 0x200, 0x320 */ }; static struct tty_driver *mxvar_sdriver; @@ -387,7 +386,7 @@ static struct mxser_hwconf mxsercfg[MXSER_BOARDS]; static void mxser_getcfg(int board, struct mxser_hwconf *hwconf); static int mxser_init(void); -/* static void mxser_poll(unsigned long); */ +//static void mxser_poll(unsigned long); static int mxser_get_ISA_conf(int, struct mxser_hwconf *); static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); static void mxser_do_softint(void *); @@ -441,18 +440,18 @@ static int CheckIsMoxaMust(int io) SET_MOXA_MUST_XON1_VALUE(io, 0x11); if ((hwid = inb(io + UART_MCR)) != 0) { outb(oldmcr, io + UART_MCR); - return MOXA_OTHER_UART; + return (MOXA_OTHER_UART); } GET_MOXA_MUST_HARDWARE_ID(io, &hwid); for (i = 0; i < UART_TYPE_NUM; i++) { if (hwid == Gmoxa_uart_id[i]) - return (int)hwid; + return (int) hwid; } return MOXA_OTHER_UART; } -/* above is modified by Victor Yu. 08-15-2002 */ +// above is modified by Victor Yu. 08-15-2002 static struct tty_operations mxser_ops = { .open = mxser_open, @@ -505,6 +504,7 @@ static void __exit mxser_module_exit(void) else printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n"); + for (i = 0; i < MXSER_BOARDS; i++) { struct pci_dev *pdev; @@ -513,7 +513,7 @@ static void __exit mxser_module_exit(void) else { pdev = mxsercfg[i].pciInfo.pdev; free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]); - if (pdev != NULL) { /* PCI */ + if (pdev != NULL) { //PCI release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); } else { @@ -524,6 +524,7 @@ static void __exit mxser_module_exit(void) } if (verbose) printk(KERN_DEBUG "Done.\n"); + } static void process_txrx_fifo(struct mxser_struct *info) @@ -557,10 +558,8 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) n = board * MXSER_PORTS_PER_BOARD; info = &mxvar_table[n]; /*if (verbose) */ { - printk(KERN_DEBUG " ttyM%d - ttyM%d ", - n, n + hwconf->ports - 1); - printk(" max. baud rate = %d bps.\n", - hwconf->MaxCanSetBaudRate[0]); + printk(KERN_DEBUG " ttyM%d - ttyM%d ", n, n + hwconf->ports - 1); + printk(" max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]); } for (i = 0; i < hwconf->ports; i++, n++, info++) { @@ -569,12 +568,12 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) info->irq = hwconf->irq; info->vector = hwconf->vector; info->vectormask = hwconf->vector_mask; - info->opmode_ioaddr = hwconf->opmode_ioaddr[i]; /* add by Victor Yu. 01-05-2004 */ + info->opmode_ioaddr = hwconf->opmode_ioaddr[i]; // add by Victor Yu. 01-05-2004 info->stop_rx = 0; info->ldisc_stop_rx = 0; info->IsMoxaMustChipFlag = hwconf->IsMoxaMustChipFlag; - /* Enhance mode enabled here */ + //Enhance mode enabled here if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { ENABLE_MOXA_MUST_ENCHANCE_MODE(info->base); } @@ -607,25 +606,22 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) /* before set INT ISR, disable all int */ for (i = 0; i < hwconf->ports; i++) { - outb(inb(hwconf->ioaddr[i] + UART_IER) & 0xf0, - hwconf->ioaddr[i] + UART_IER); + outb(inb(hwconf->ioaddr[i] + UART_IER) & 0xf0, hwconf->ioaddr[i] + UART_IER); } n = board * MXSER_PORTS_PER_BOARD; info = &mxvar_table[n]; - retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info), - "mxser", info); + retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info), "mxser", info); if (retval) { - printk(KERN_ERR "Board %d: %s", - board, mxser_brdname[hwconf->board_type - 1]); - printk(" Request irq failed, IRQ (%d) may conflict with" - " another device.\n", info->irq); + printk(KERN_ERR "Board %d: %s", board, mxser_brdname[hwconf->board_type - 1]); + printk(" Request irq fail,IRQ (%d) may be conflit with another device.\n", info->irq); return retval; } return 0; } + static void mxser_getcfg(int board, struct mxser_hwconf *hwconf) { mxsercfg[board] = *hwconf; @@ -635,27 +631,26 @@ static void mxser_getcfg(int board, struct mxser_hwconf *hwconf) static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf) { int i, j; - /* unsigned int val; */ +// unsigned int val; unsigned int ioaddress; struct pci_dev *pdev = hwconf->pciInfo.pdev; - /* io address */ + //io address hwconf->board_type = board_type; hwconf->ports = mxser_numports[board_type - 1]; ioaddress = pci_resource_start(pdev, 2); - request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2), - "mxser(IO)"); + request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2), "mxser(IO)"); - for (i = 0; i < hwconf->ports; i++) + for (i = 0; i < hwconf->ports; i++) { hwconf->ioaddr[i] = ioaddress + 8 * i; + } - /* vector */ + //vector ioaddress = pci_resource_start(pdev, 3); - request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3), - "mxser(vector)"); + request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3), "mxser(vector)"); hwconf->vector = ioaddress; - /* irq */ + //irq hwconf->irq = hwconf->pciInfo.pdev->irq; hwconf->IsMoxaMustChipFlag = CheckIsMoxaMust(hwconf->ioaddr[0]); @@ -668,7 +663,7 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs if (Gpci_uart_info[j].type == hwconf->IsMoxaMustChipFlag) { hwconf->MaxCanSetBaudRate[i] = Gpci_uart_info[j].max_baud; - /* exception....CP-102 */ + //exception....CP-102 if (board_type == MXSER_BOARD_CP102) hwconf->MaxCanSetBaudRate[i] = 921600; break; @@ -683,15 +678,15 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs else hwconf->opmode_ioaddr[i] = ioaddress + 0x0c; } - outb(0, ioaddress + 4); /* default set to RS232 mode */ - outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ + outb(0, ioaddress + 4); // default set to RS232 mode + outb(0, ioaddress + 0x0c); //default set to RS232 mode } for (i = 0; i < hwconf->ports; i++) { hwconf->vector_mask |= (1 << i); hwconf->baud_base[i] = 921600; } - return 0; + return (0); } #endif @@ -712,8 +707,7 @@ static int mxser_init(void) mxsercfg[i].board_type = -1; } - printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", - MXSER_VERSION); + printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", MXSER_VERSION); /* Initialize the tty_driver structure */ memset(mxvar_sdriver, 0, sizeof(struct tty_driver)); @@ -725,7 +719,7 @@ static int mxser_init(void) mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; mxvar_sdriver->init_termios = tty_std_termios; - mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + mxvar_sdriver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(mxvar_sdriver, &mxser_ops); mxvar_sdriver->ttys = mxvar_tty; @@ -745,29 +739,23 @@ static int mxser_init(void) /* Start finding ISA boards here */ for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { int cap; - if (!(cap = mxserBoardCAP[b])) continue; retval = mxser_get_ISA_conf(cap, &hwconf); if (retval != 0) - printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", - mxser_brdname[hwconf.board_type - 1], ioaddr[b]); + printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", mxser_brdname[hwconf.board_type - 1], ioaddr[b]); if (retval <= 0) { if (retval == MXSER_ERR_IRQ) - printk(KERN_ERR "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_IRQ_CONFLIT) - printk(KERN_ERR "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_VECTOR) - printk(KERN_ERR "Invalid interrupt vector, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt vector,board not configured\n"); else if (retval == MXSER_ERR_IOADDR) - printk(KERN_ERR "Invalid I/O address, " - "board not configured\n"); + printk(KERN_ERR "Invalid I/O address,board not configured\n"); continue; } @@ -777,43 +765,35 @@ static int mxser_init(void) hwconf.pciInfo.pdev = NULL; mxser_getcfg(m, &hwconf); - /* - * init mxsercfg first, - * or mxsercfg data is not correct on ISR. - */ - /* mxser_initbrd will hook ISR. */ + //init mxsercfg first, or mxsercfg data is not correct on ISR. + //mxser_initbrd will hook ISR. if (mxser_initbrd(m, &hwconf) < 0) continue; + m++; } /* Start finding ISA boards from module arg */ for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { int cap; - if (!(cap = ioaddr[b])) continue; retval = mxser_get_ISA_conf(cap, &hwconf); if (retval != 0) - printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", - mxser_brdname[hwconf.board_type - 1], ioaddr[b]); + printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", mxser_brdname[hwconf.board_type - 1], ioaddr[b]); if (retval <= 0) { if (retval == MXSER_ERR_IRQ) - printk(KERN_ERR "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_IRQ_CONFLIT) - printk(KERN_ERR "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_VECTOR) - printk(KERN_ERR "Invalid interrupt vector, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt vector,board not configured\n"); else if (retval == MXSER_ERR_IOADDR) - printk(KERN_ERR "Invalid I/O address, " - "board not configured\n"); + printk(KERN_ERR "Invalid I/O address,board not configured\n"); continue; } @@ -823,11 +803,8 @@ static int mxser_init(void) hwconf.pciInfo.pdev = NULL; mxser_getcfg(m, &hwconf); - /* - * init mxsercfg first, - * or mxsercfg data is not correct on ISR. - */ - /* mxser_initbrd will hook ISR. */ + //init mxsercfg first, or mxsercfg data is not correct on ISR. + //mxser_initbrd will hook ISR. if (mxser_initbrd(m, &hwconf) < 0) continue; @@ -840,8 +817,7 @@ static int mxser_init(void) index = 0; b = 0; while (b < n) { - pdev = pci_find_device(mxser_pcibrds[b].vendor, - mxser_pcibrds[b].device, pdev); + pdev = pci_find_device(mxser_pcibrds[b].vendor, mxser_pcibrds[b].device, pdev); if (pdev == NULL) { b++; continue; @@ -849,48 +825,30 @@ static int mxser_init(void) hwconf.pciInfo.busNum = busnum = pdev->bus->number; hwconf.pciInfo.devNum = devnum = PCI_SLOT(pdev->devfn) << 3; hwconf.pciInfo.pdev = pdev; - printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n", - mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1], - busnum, devnum >> 3); + printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n", mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1], busnum, devnum >> 3); index++; - if (m >= MXSER_BOARDS) - printk(KERN_ERR - "Too many Smartio/Industio family boards find " - "(maximum %d), board not configured\n", - MXSER_BOARDS); - else { + if (m >= MXSER_BOARDS) { + printk(KERN_ERR "Too many Smartio/Industio family boards find (maximum %d),board not configured\n", MXSER_BOARDS); + } else { if (pci_enable_device(pdev)) { - printk(KERN_ERR "Moxa SmartI/O PCI enable " - "fail !\n"); + printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n"); continue; } - retval = mxser_get_PCI_conf(busnum, devnum, - (int)mxser_pcibrds[b].driver_data, - &hwconf); + retval = mxser_get_PCI_conf(busnum, devnum, (int) mxser_pcibrds[b].driver_data, &hwconf); if (retval < 0) { if (retval == MXSER_ERR_IRQ) - printk(KERN_ERR - "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_IRQ_CONFLIT) - printk(KERN_ERR - "Invalid interrupt number, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt number,board not configured\n"); else if (retval == MXSER_ERR_VECTOR) - printk(KERN_ERR - "Invalid interrupt vector, " - "board not configured\n"); + printk(KERN_ERR "Invalid interrupt vector,board not configured\n"); else if (retval == MXSER_ERR_IOADDR) - printk(KERN_ERR - "Invalid I/O address, " - "board not configured\n"); + printk(KERN_ERR "Invalid I/O address,board not configured\n"); continue; } mxser_getcfg(m, &hwconf); - /* init mxsercfg first, - * or mxsercfg data is not correct on ISR. - */ - /* mxser_initbrd will hook ISR. */ + //init mxsercfg first, or mxsercfg data is not correct on ISR. + //mxser_initbrd will hook ISR. if (mxser_initbrd(m, &hwconf) < 0) continue; m++; @@ -900,8 +858,7 @@ static int mxser_init(void) retval = tty_register_driver(mxvar_sdriver); if (retval) { - printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family" - " driver !\n"); + printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n"); put_tty_driver(mxvar_sdriver); for (i = 0; i < MXSER_BOARDS; i++) { @@ -909,7 +866,7 @@ static int mxser_init(void) continue; else { free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]); - /* todo: release io, vector */ + //todo: release io, vector } } return retval; @@ -920,7 +877,7 @@ static int mxser_init(void) static void mxser_do_softint(void *private_) { - struct mxser_struct *info = private_; + struct mxser_struct *info = (struct mxser_struct *) private_; struct tty_struct *tty; tty = info->tty; @@ -969,7 +926,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) return -ENODEV; info = mxvar_table + line; if (!info->base) - return -ENODEV; + return (-ENODEV); tty->driver_data = info; info->tty = tty; @@ -978,11 +935,11 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) */ retval = mxser_startup(info); if (retval) - return retval; + return (retval); retval = mxser_block_til_ready(tty, filp, info); if (retval) - return retval; + return (retval); info->count++; @@ -998,12 +955,11 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) info->pgrp = process_group(current); clear_bit(TTY_DONT_FLIP, &tty->flags); - /* - status = mxser_get_msr(info->base, 0, info->port); - mxser_check_modem_status(info, status); - */ + //status = mxser_get_msr(info->base, 0, info->port); + //mxser_check_modem_status(info, status); -/* unmark here for very high baud rate (ex. 921600 bps) used */ +/* unmark here for very high baud rate (ex. 921600 bps) used +*/ tty->low_latency = 1; return 0; } @@ -1016,7 +972,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) */ static void mxser_close(struct tty_struct *tty, struct file *filp) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long timeout; unsigned long flags; @@ -1041,13 +997,11 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) * one, we've got real problems, since it means the * serial port won't be shutdown. */ - printk(KERN_ERR "mxser_close: bad serial port count; " - "tty->count is 1, info->count is %d\n", info->count); + printk(KERN_ERR "mxser_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { - printk(KERN_ERR "mxser_close: bad serial port count for " - "ttys%d: %d\n", info->port, info->count); + printk(KERN_ERR "mxser_close: bad serial port count for ttys%d: %d\n", info->port, info->count); info->count = 0; } if (info->count) { @@ -1102,7 +1056,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) ld = tty_ldisc_ref(tty); if (ld) { - if (ld->flush_buffer) + if(ld->flush_buffer) ld->flush_buffer(tty); tty_ldisc_deref(ld); } @@ -1124,34 +1078,31 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) { int c, total = 0; - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; - if (!info->xmit_buf) - return 0; + if (!tty || !info->xmit_buf) + return (0); while (1) { - c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); spin_lock_irqsave(&info->slock, flags); - info->xmit_head = (info->xmit_head + c) & - (SERIAL_XMIT_SIZE - 1); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); info->xmit_cnt += c; spin_unlock_irqrestore(&info->slock, flags); buf += c; count -= c; total += c; + } if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - (info->IsMoxaMustChipFlag)) { + if (!tty->hw_stopped || (info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { spin_lock_irqsave(&info->slock, flags); info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); @@ -1163,10 +1114,10 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou static void mxser_put_char(struct tty_struct *tty, unsigned char ch) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; - if (!info->xmit_buf) + if (!tty || !info->xmit_buf) return; if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) @@ -1178,9 +1129,7 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch) info->xmit_cnt++; spin_unlock_irqrestore(&info->slock, flags); if (!tty->stopped && !(info->IER & UART_IER_THRI)) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - info->IsMoxaMustChipFlag) { + if (!tty->hw_stopped || (info->type == PORT_16550A) || info->IsMoxaMustChipFlag) { spin_lock_irqsave(&info->slock, flags); info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); @@ -1192,16 +1141,10 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch) static void mxser_flush_chars(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; - if (info->xmit_cnt <= 0 || - tty->stopped || - !info->xmit_buf || - (tty->hw_stopped && - (info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag) - )) + if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf || (tty->hw_stopped && (info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag))) return; spin_lock_irqsave(&info->slock, flags); @@ -1214,24 +1157,24 @@ static void mxser_flush_chars(struct tty_struct *tty) static int mxser_write_room(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; int ret; ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; if (ret < 0) ret = 0; - return ret; + return (ret); } static int mxser_chars_in_buffer(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; return info->xmit_cnt; } static void mxser_flush_buffer(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; char fcr; unsigned long flags; @@ -1241,8 +1184,7 @@ static void mxser_flush_buffer(struct tty_struct *tty) /* below added by shinhay */ fcr = inb(info->base + UART_FCR); - outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->base + UART_FCR); + outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), info->base + UART_FCR); outb(fcr, info->base + UART_FCR); spin_unlock_irqrestore(&info->slock, flags); @@ -1255,7 +1197,7 @@ static void mxser_flush_buffer(struct tty_struct *tty) static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; int retval; struct async_icount cprev, cnow; /* kernel counter temps */ struct serial_icounter_struct __user *p_cuser; @@ -1264,9 +1206,9 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c void __user *argp = (void __user *)arg; if (tty->index == MXSER_PORTS) - return mxser_ioctl_special(cmd, argp); + return (mxser_ioctl_special(cmd, argp)); - /* following add by Victor Yu. 01-05-2004 */ + // following add by Victor Yu. 01-05-2004 if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { int opmode, p; static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; @@ -1277,10 +1219,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c if (cmd == MOXA_SET_OP_MODE) { if (get_user(opmode, (int __user *) argp)) return -EFAULT; - if (opmode != RS232_MODE && - opmode != RS485_2WIRE_MODE && - opmode != RS422_MODE && - opmode != RS485_4WIRE_MODE) + if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && opmode != RS422_MODE && opmode != RS485_4WIRE_MODE) return -EFAULT; mask = ModeMask[p]; shiftbit = p * 2; @@ -1297,36 +1236,36 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c } return 0; } - /* above add by Victor Yu. 01-05-2004 */ + // above add by Victor Yu. 01-05-2004 if ((cmd != TIOCGSERIAL) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; + return (-EIO); } switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) - return retval; + return (retval); tty_wait_until_sent(tty, 0); if (!arg) mxser_send_break(info, HZ / 4); /* 1/4 second */ - return 0; + return (0); case TCSBRKP: /* support for POSIX tcsendbreak() */ retval = tty_check_change(tty); if (retval) - return retval; + return (retval); tty_wait_until_sent(tty, 0); mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); - return 0; + return (0); case TIOCGSOFTCAR: - return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); + return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); case TIOCSSOFTCAR: if (get_user(templ, (unsigned long __user *) argp)) return -EFAULT; arg = templ; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); - return 0; + return (0); case TIOCGSERIAL: return mxser_get_serial_info(info, argp); case TIOCSSERIAL: @@ -1339,7 +1278,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) * Caller should use TIOCGICOUNT to see which one it was */ - case TIOCMIWAIT: { + case TIOCMIWAIT:{ DECLARE_WAITQUEUE(wait, current); int ret; spin_lock_irqsave(&info->slock, flags); @@ -1353,14 +1292,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c spin_unlock_irqrestore(&info->slock, flags); set_current_state(TASK_INTERRUPTIBLE); - if (((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts))) { + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { ret = 0; break; } @@ -1406,18 +1338,21 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c put_user(cnow.dsr, &p_cuser->dsr); put_user(cnow.rng, &p_cuser->rng); put_user(cnow.dcd, &p_cuser->dcd); + +/* */ return 0; case MOXA_HighSpeedOn: - return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); - case MOXA_SDS_RSTICOUNTER: { + return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *) argp); + + case MOXA_SDS_RSTICOUNTER:{ info->mon_data.rxcnt = 0; info->mon_data.txcnt = 0; return 0; } -/* (above) added by James. */ +// (above) added by James. case MOXA_ASPP_SETBAUD:{ long baud; - if (get_user(baud, (long __user *)argp)) + if (get_user(baud, (long __user *) argp)) return -EFAULT; mxser_set_baud(info, baud); return 0; @@ -1442,10 +1377,9 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c return 0; } - case MOXA_ASPP_MON: { + case MOXA_ASPP_MON:{ int mcr, status; - - /* info->mon_data.ser_param = tty->termios->c_cflag; */ +// info->mon_data.ser_param = tty->termios->c_cflag; status = mxser_get_msr(info->base, 1, info->port, info); mxser_check_modem_status(info, status); @@ -1466,25 +1400,25 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c else info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; - if (copy_to_user(argp, &info->mon_data, - sizeof(struct mxser_mon))) + + if (copy_to_user(argp, &info->mon_data, sizeof(struct mxser_mon))) return -EFAULT; return 0; + } - case MOXA_ASPP_LSTATUS: { - if (copy_to_user(argp, &info->err_shadow, - sizeof(unsigned char))) + case MOXA_ASPP_LSTATUS:{ + if (copy_to_user(argp, &info->err_shadow, sizeof(unsigned char))) return -EFAULT; info->err_shadow = 0; return 0; + } - case MOXA_SET_BAUD_METHOD: { + case MOXA_SET_BAUD_METHOD:{ int method; - - if (get_user(method, (int __user *)argp)) + if (get_user(method, (int __user *) argp)) return -EFAULT; mxser_set_baud_method[info->port] = method; if (copy_to_user(argp, &method, sizeof(int))) @@ -1508,8 +1442,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) switch (cmd) { case MOXA_GET_CONF: - if (copy_to_user(argp, mxsercfg, - sizeof(struct mxser_hwconf) * 4)) + if (copy_to_user(argp, mxsercfg, sizeof(struct mxser_hwconf) * 4)) return -EFAULT; return 0; case MOXA_GET_MAJOR: @@ -1528,11 +1461,11 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) if (mxvar_table[i].base) result |= (1 << i); } - return put_user(result, (unsigned long __user *)argp); + return put_user(result, (unsigned long __user *) argp); case MOXA_GETDATACOUNT: if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) return -EFAULT; - return 0; + return (0); case MOXA_GETMSTATUS: for (i = 0; i < MXSER_PORTS; i++) { GMStatus[i].ri = 0; @@ -1565,26 +1498,22 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) else GMStatus[i].cts = 0; } - if (copy_to_user(argp, GMStatus, - sizeof(struct mxser_mstatus) * MXSER_PORTS)) + if (copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MXSER_PORTS)) return -EFAULT; return 0; - case MOXA_ASPP_MON_EXT: { + case MOXA_ASPP_MON_EXT:{ int status; int opmode, p; int shiftbit; unsigned cflag, iflag; for (i = 0; i < MXSER_PORTS; i++) { + if (!mxvar_table[i].base) continue; - status = mxser_get_msr(mxvar_table[i].base, 0, - i, &(mxvar_table[i])); - /* - mxser_check_modem_status(&mxvar_table[i], - status); - */ + status = mxser_get_msr(mxvar_table[i].base, 0, i, &(mxvar_table[i])); +// mxser_check_modem_status(&mxvar_table[i], status); if (status & UART_MSR_TERI) mxvar_table[i].icount.rng++; if (status & UART_MSR_DDSR) @@ -1649,76 +1578,75 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) return 0; } + static void mxser_stoprx(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; - /* unsigned long flags; */ + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; + //unsigned long flags; + info->ldisc_stop_rx = 1; if (I_IXOFF(tty)) { - /* MX_LOCK(&info->slock); */ - /* following add by Victor Yu. 09-02-2002 */ + + //MX_LOCK(&info->slock); + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag) { info->IER &= ~MOXA_MUST_RECV_ISR; outb(info->IER, info->base + UART_IER); } else { - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 + info->x_char = STOP_CHAR(tty); - /* mask by Victor Yu. 09-02-2002 */ - /* outb(info->IER, 0); */ + // outb(info->IER, 0); // mask by Victor Yu. 09-02-2002 outb(0, info->base + UART_IER); info->IER |= UART_IER_THRI; - /* force Tx interrupt */ - outb(info->IER, info->base + UART_IER); - } /* add by Victor Yu. 09-02-2002 */ - /* MX_UNLOCK(&info->slock); */ + outb(info->IER, info->base + UART_IER); /* force Tx interrupt */ + } // add by Victor Yu. 09-02-2002 + //MX_UNLOCK(&info->slock); } if (info->tty->termios->c_cflag & CRTSCTS) { - /* MX_LOCK(&info->slock); */ + //MX_LOCK(&info->slock); info->MCR &= ~UART_MCR_RTS; outb(info->MCR, info->base + UART_MCR); - /* MX_UNLOCK(&info->slock); */ + //MX_UNLOCK(&info->slock); } } static void mxser_startrx(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; - /* unsigned long flags; */ + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; + //unsigned long flags; info->ldisc_stop_rx = 0; if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; else { - /* MX_LOCK(&info->slock); */ + //MX_LOCK(&info->slock); - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag) { info->IER |= MOXA_MUST_RECV_ISR; outb(info->IER, info->base + UART_IER); } else { - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 info->x_char = START_CHAR(tty); - /* mask by Victor Yu. 09-02-2002 */ - /* outb(info->IER, 0); */ - /* add by Victor Yu. 09-02-2002 */ - outb(0, info->base + UART_IER); - /* force Tx interrupt */ - info->IER |= UART_IER_THRI; + // outb(info->IER, 0); // mask by Victor Yu. 09-02-2002 + outb(0, info->base + UART_IER); // add by Victor Yu. 09-02-2002 + info->IER |= UART_IER_THRI; /* force Tx interrupt */ outb(info->IER, info->base + UART_IER); - } /* add by Victor Yu. 09-02-2002 */ - /* MX_UNLOCK(&info->slock); */ + } // add by Victor Yu. 09-02-2002 + //MX_UNLOCK(&info->slock); } } if (info->tty->termios->c_cflag & CRTSCTS) { - /* MX_LOCK(&info->slock); */ + //MX_LOCK(&info->slock); info->MCR |= UART_MCR_RTS; outb(info->MCR, info->base + UART_MCR); - /* MX_UNLOCK(&info->slock); */ + //MX_UNLOCK(&info->slock); } } @@ -1728,53 +1656,48 @@ static void mxser_startrx(struct tty_struct *tty) */ static void mxser_throttle(struct tty_struct *tty) { - /* struct mxser_struct *info = tty->driver_data; */ - /* unsigned long flags; */ - - /* MX_LOCK(&info->slock); */ + //struct mxser_struct *info = (struct mxser_struct *)tty->driver_data; + //unsigned long flags; + //MX_LOCK(&info->slock); mxser_stoprx(tty); - /* MX_UNLOCK(&info->slock); */ + //MX_UNLOCK(&info->slock); } static void mxser_unthrottle(struct tty_struct *tty) { - /* struct mxser_struct *info = tty->driver_data; */ - /* unsigned long flags; */ - - /* MX_LOCK(&info->slock); */ + //struct mxser_struct *info = (struct mxser_struct *)tty->driver_data; + //unsigned long flags; + //MX_LOCK(&info->slock); mxser_startrx(tty); - /* MX_UNLOCK(&info->slock); */ + //MX_UNLOCK(&info->slock); } static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; - if ((tty->termios->c_cflag != old_termios->c_cflag) || - (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { + if ((tty->termios->c_cflag != old_termios->c_cflag) || (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { mxser_change_speed(info, old_termios); - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { + if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; mxser_start(tty); } } /* Handle sw stopped */ - if ((old_termios->c_iflag & IXON) && - !(tty->termios->c_iflag & IXON)) { + if ((old_termios->c_iflag & IXON) && !(tty->termios->c_iflag & IXON)) { tty->stopped = 0; - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag) { spin_lock_irqsave(&info->slock, flags); DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->base); spin_unlock_irqrestore(&info->slock, flags); } - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 mxser_start(tty); } @@ -1788,7 +1711,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termio */ static void mxser_stop(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; spin_lock_irqsave(&info->slock, flags); @@ -1801,7 +1724,7 @@ static void mxser_stop(struct tty_struct *tty) static void mxser_start(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; spin_lock_irqsave(&info->slock, flags); @@ -1817,7 +1740,7 @@ static void mxser_start(struct tty_struct *tty) */ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long orig_jiffies, char_time; int lsr; @@ -1854,8 +1777,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) if (!timeout || timeout > 2 * info->timeout) timeout = 2 * info->timeout; #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", - timeout, char_time); + printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); printk("jiff=%lu...", jiffies); #endif while (!((lsr = inb(info->base + UART_LSR)) & UART_LSR_TEMT)) { @@ -1881,7 +1803,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) */ void mxser_hangup(struct tty_struct *tty) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; mxser_flush_buffer(tty); mxser_shutdown(info); @@ -1893,26 +1815,24 @@ void mxser_hangup(struct tty_struct *tty) } -/* added by James 03-12-2004. */ +// added by James 03-12-2004. /* * mxser_rs_break() --- routine which turns the break handling on or off */ static void mxser_rs_break(struct tty_struct *tty, int break_state) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; spin_lock_irqsave(&info->slock, flags); if (break_state == -1) - outb(inb(info->base + UART_LCR) | UART_LCR_SBC, - info->base + UART_LCR); + outb(inb(info->base + UART_LCR) | UART_LCR_SBC, info->base + UART_LCR); else - outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC, - info->base + UART_LCR); + outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC, info->base + UART_LCR); spin_unlock_irqrestore(&info->slock, flags); } -/* (above) added by James. */ +// (above) added by James. /* @@ -1928,7 +1848,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) int handled = IRQ_NONE; port = NULL; - /* spin_lock(&gm_lock); */ + //spin_lock(&gm_lock); for (i = 0; i < MXSER_BOARDS; i++) { if (dev_id == &(mxvar_table[i * MXSER_PORTS_PER_BOARD])) { @@ -1937,25 +1857,29 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) } } - if (i == MXSER_BOARDS) + if (i == MXSER_BOARDS) { goto irq_stop; - if (port == 0) + } + if (port == 0) { goto irq_stop; + } max = mxser_numports[mxsercfg[i].board_type - 1]; while (1) { irqbits = inb(port->vector) & port->vectormask; - if (irqbits == port->vectormask) + if (irqbits == port->vectormask) { break; + } handled = IRQ_HANDLED; for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) { - if (irqbits == port->vectormask) + if (irqbits == port->vectormask) { break; + } if (bits & irqbits) continue; info = port + i; - /* following add by Victor Yu. 09-13-2002 */ + // following add by Victor Yu. 09-13-2002 iir = inb(info->base + UART_IIR); if (iir & UART_IIR_NO_INT) continue; @@ -1966,9 +1890,9 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) inb(info->base + UART_MSR); continue; } - /* above add by Victor Yu. 09-13-2002 */ + // above add by Victor Yu. 09-13-2002 /* - if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) { + if ( info->tty->flip.count < TTY_FLIPBUF_SIZE/4 ){ info->IER |= MOXA_MUST_RECV_ISR; outb(info->IER, info->base + UART_IER); } @@ -1984,15 +1908,18 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) status = inb(info->base + UART_LSR) & info->read_status_mask; */ - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 status = inb(info->base + UART_LSR); - if (status & UART_LSR_PE) + if (status & UART_LSR_PE) { info->err_shadow |= NPPI_NOTIFY_PARITY; - if (status & UART_LSR_FE) + } + if (status & UART_LSR_FE) { info->err_shadow |= NPPI_NOTIFY_FRAMING; - if (status & UART_LSR_OE) + } + if (status & UART_LSR_OE) { info->err_shadow |= NPPI_NOTIFY_HW_OVERRUN; + } if (status & UART_LSR_BI) info->err_shadow |= NPPI_NOTIFY_BREAK; @@ -2003,14 +1930,11 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) continue; } */ - if (iir == MOXA_MUST_IIR_GDA || - iir == MOXA_MUST_IIR_RDA || - iir == MOXA_MUST_IIR_RTO || - iir == MOXA_MUST_IIR_LSR) + if (iir == MOXA_MUST_IIR_GDA || iir == MOXA_MUST_IIR_RDA || iir == MOXA_MUST_IIR_RTO || iir == MOXA_MUST_IIR_LSR) mxser_receive_chars(info, &status); } else { - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 status &= info->read_status_mask; if (status & UART_LSR_DR) @@ -2020,13 +1944,13 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (msr & UART_MSR_ANY_DELTA) { mxser_check_modem_status(info, msr); } - /* following add by Victor Yu. 09-13-2002 */ + // following add by Victor Yu. 09-13-2002 if (info->IsMoxaMustChipFlag) { if ((iir == 0x02) && (status & UART_LSR_THRE)) { mxser_transmit_chars(info); } } else { - /* above add by Victor Yu. 09-13-2002 */ + // above add by Victor Yu. 09-13-2002 if (status & UART_LSR_THRE) { /* 8-2-99 by William @@ -2042,7 +1966,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs) } irq_stop: - /* spin_unlock(&gm_lock); */ + //spin_unlock(&gm_lock); return handled; } @@ -2060,58 +1984,56 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) recv_room = tty->receive_room; if ((recv_room == 0) && (!info->ldisc_stop_rx)) { - /* mxser_throttle(tty); */ + //mxser_throttle(tty); mxser_stoprx(tty); - /* return; */ + //return; } - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { if (*status & UART_LSR_SPECIAL) { goto intr_old; } - /* following add by Victor Yu. 02-11-2004 */ - if (info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID && - (*status & MOXA_MUST_LSR_RERR)) + // following add by Victor Yu. 02-11-2004 + if (info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID && (*status & MOXA_MUST_LSR_RERR)) goto intr_old; - /* above add by Victor Yu. 02-14-2004 */ + // above add by Victor Yu. 02-14-2004 if (*status & MOXA_MUST_LSR_RERR) goto intr_old; gdl = inb(info->base + MOXA_MUST_GDL_REGISTER); - /* add by Victor Yu. 02-11-2004 */ - if (info->IsMoxaMustChipFlag == MOXA_MUST_MU150_HWID) + if (info->IsMoxaMustChipFlag == MOXA_MUST_MU150_HWID) // add by Victor Yu. 02-11-2004 gdl &= MOXA_MUST_GDL_MASK; if (gdl >= recv_room) { if (!info->ldisc_stop_rx) { - /* mxser_throttle(tty); */ + //mxser_throttle(tty); mxser_stoprx(tty); } - /* return; */ + //return; } while (gdl--) { ch = inb(info->base + UART_RX); tty_insert_flip_char(tty, ch, 0); cnt++; /* - if ((cnt >= HI_WATER) && (info->stop_rx == 0)) { + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); - info->stop_rx = 1; + info->stop_rx=1; break; } */ } goto end_intr; } - intr_old: - /* above add by Victor Yu. 09-02-2002 */ +intr_old: + // above add by Victor Yu. 09-02-2002 do { if (max-- < 0) break; /* - if ((cnt >= HI_WATER) && (info->stop_rx == 0)) { + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2119,11 +2041,11 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) */ ch = inb(info->base + UART_RX); - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag && (*status & UART_LSR_OE) /*&& !(*status&UART_LSR_DR) */ ) outb(0x23, info->base + UART_FCR); *status &= info->read_status_mask; - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 if (*status & info->ignore_status_mask) { if (++ignored > 100) break; @@ -2158,7 +2080,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) cnt++; if (cnt >= recv_room) { if (!info->ldisc_stop_rx) { - /* mxser_throttle(tty); */ + //mxser_throttle(tty); mxser_stoprx(tty); } break; @@ -2166,20 +2088,21 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) } - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag) break; - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 /* mask by Victor Yu. 09-02-2002 *status = inb(info->base + UART_LSR) & info->read_status_mask; */ - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 *status = inb(info->base + UART_LSR); - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 } while (*status & UART_LSR_DR); -end_intr: /* add by Victor Yu. 09-02-2002 */ +end_intr: // add by Victor Yu. 09-02-2002 + mxvar_log.rxcnt[info->port] += cnt; info->mon_data.rxcnt += cnt; info->mon_data.up_rxcnt += cnt; @@ -2214,10 +2137,7 @@ static void mxser_transmit_chars(struct mxser_struct *info) return; } - if ((info->xmit_cnt <= 0) || info->tty->stopped || - (info->tty->hw_stopped && - (info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag))) { + if ((info->xmit_cnt <= 0) || info->tty->stopped || (info->tty->hw_stopped && (info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag))) { info->IER &= ~UART_IER_THRI; outb(info->IER, info->base + UART_IER); spin_unlock_irqrestore(&info->slock, flags); @@ -2227,18 +2147,17 @@ static void mxser_transmit_chars(struct mxser_struct *info) cnt = info->xmit_cnt; count = info->xmit_fifo_size; do { - outb(info->xmit_buf[info->xmit_tail++], - info->base + UART_TX); + outb(info->xmit_buf[info->xmit_tail++], info->base + UART_TX); info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1); if (--info->xmit_cnt <= 0) break; } while (--count > 0); mxvar_log.txcnt[info->port] += (cnt - info->xmit_cnt); -/* added by James 03-12-2004. */ +// added by James 03-12-2004. info->mon_data.txcnt += (cnt - info->xmit_cnt); info->mon_data.up_txcnt += (cnt - info->xmit_cnt); -/* (above) added by James. */ +// (above) added by James. /* added by casper 1/11/2000 */ info->icount.tx += (cnt - info->xmit_cnt); @@ -2269,6 +2188,7 @@ static void mxser_check_modem_status(struct mxser_struct *info, int status) info->mon_data.modem_status = status; wake_up_interruptible(&info->delta_msr_wait); + if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { if (status & UART_MSR_DCD) wake_up_interruptible(&info->open_wait); @@ -2280,8 +2200,7 @@ static void mxser_check_modem_status(struct mxser_struct *info, int status) if (status & UART_MSR_CTS) { info->tty->hw_stopped = 0; - if ((info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag)) { + if ((info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag)) { info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); } @@ -2290,8 +2209,7 @@ static void mxser_check_modem_status(struct mxser_struct *info, int status) } else { if (!(status & UART_MSR_CTS)) { info->tty->hw_stopped = 1; - if ((info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag)) { + if ((info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag)) { info->IER &= ~UART_IER_THRI; outb(info->IER, info->base + UART_IER); } @@ -2313,7 +2231,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, stru */ if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; + return (0); } if (tty->termios->c_cflag & CLOCAL) @@ -2336,8 +2254,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, stru info->blocked_open++; while (1) { spin_lock_irqsave(&info->slock, flags); - outb(inb(info->base + UART_MCR) | - UART_MCR_DTR | UART_MCR_RTS, info->base + UART_MCR); + outb(inb(info->base + UART_MCR) | UART_MCR_DTR | UART_MCR_RTS, info->base + UART_MCR); spin_unlock_irqrestore(&info->slock, flags); set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) { @@ -2347,9 +2264,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, stru retval = -ERESTARTSYS; break; } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || - (inb(info->base + UART_MSR) & UART_MSR_DCD))) + if (!(info->flags & ASYNC_CLOSING) && (do_clocal || (inb(info->base + UART_MSR) & UART_MSR_DCD))) break; if (signal_pending(current)) { retval = -ERESTARTSYS; @@ -2363,26 +2278,27 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, stru info->count++; info->blocked_open--; if (retval) - return retval; + return (retval); info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; + return (0); } static int mxser_startup(struct mxser_struct *info) { + unsigned long page; unsigned long flags; page = __get_free_page(GFP_KERNEL); if (!page) - return -ENOMEM; + return (-ENOMEM); spin_lock_irqsave(&info->slock, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); spin_unlock_irqrestore(&info->slock, flags); - return 0; + return (0); } if (!info->base || !info->type) { @@ -2390,7 +2306,7 @@ static int mxser_startup(struct mxser_struct *info) set_bit(TTY_IO_ERROR, &info->tty->flags); free_page(page); spin_unlock_irqrestore(&info->slock, flags); - return 0; + return (0); } if (info->xmit_buf) free_page(page); @@ -2402,12 +2318,9 @@ static int mxser_startup(struct mxser_struct *info) * (they will be reenabled in mxser_change_speed()) */ if (info->IsMoxaMustChipFlag) - outb((UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR); + outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR); else - outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->base + UART_FCR); + outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), info->base + UART_FCR); /* * At this point there's no way the LSR could still be 0xFF; @@ -2419,9 +2332,9 @@ static int mxser_startup(struct mxser_struct *info) if (capable(CAP_SYS_ADMIN)) { if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - return 0; + return (0); } else - return -ENODEV; + return (-ENODEV); } /* @@ -2443,12 +2356,12 @@ static int mxser_startup(struct mxser_struct *info) * Finally, enable interrupts */ info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - /* info->IER = UART_IER_RLSI | UART_IER_RDI; */ +// info->IER = UART_IER_RLSI | UART_IER_RDI; - /* following add by Victor Yu. 08-30-2002 */ + // following add by Victor Yu. 08-30-2002 if (info->IsMoxaMustChipFlag) info->IER |= MOXA_MUST_IER_EGDAI; - /* above add by Victor Yu. 08-30-2002 */ + // above add by Victor Yu. 08-30-2002 outb(info->IER, info->base + UART_IER); /* enable interrupts */ /* @@ -2470,7 +2383,7 @@ static int mxser_startup(struct mxser_struct *info) mxser_change_speed(info, NULL); info->flags |= ASYNC_INITIALIZED; - return 0; + return (0); } /* @@ -2508,15 +2421,12 @@ static void mxser_shutdown(struct mxser_struct *info) outb(info->MCR, info->base + UART_MCR); /* clear Rx/Tx FIFO's */ - /* following add by Victor Yu. 08-30-2002 */ + // following add by Victor Yu. 08-30-2002 if (info->IsMoxaMustChipFlag) - outb((UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR); + outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | MOXA_MUST_FCR_GDA_MODE_ENABLE), info->base + UART_FCR); else - /* above add by Victor Yu. 08-30-2002 */ - outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->base + UART_FCR); + // above add by Victor Yu. 08-30-2002 + outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), info->base + UART_FCR); /* read data port to reset things */ (void) inb(info->base + UART_RX); @@ -2526,10 +2436,11 @@ static void mxser_shutdown(struct mxser_struct *info) info->flags &= ~ASYNC_INITIALIZED; - /* following add by Victor Yu. 09-23-2002 */ - if (info->IsMoxaMustChipFlag) + // following add by Victor Yu. 09-23-2002 + if (info->IsMoxaMustChipFlag) { SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->base); - /* above add by Victor Yu. 09-23-2002 */ + } + // above add by Victor Yu. 09-23-2002 spin_unlock_irqrestore(&info->slock, flags); } @@ -2546,12 +2457,14 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter long baud; unsigned long flags; + if (!info->tty || !info->tty->termios) return ret; cflag = info->tty->termios->c_cflag; if (!(info->base)) return ret; + #ifndef B921600 #define B921600 (B460800 +1) #endif @@ -2646,8 +2559,9 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter cval |= 0x04; if (cflag & PARENB) cval |= UART_LCR_PARITY; - if (!(cflag & PARODD)) + if (!(cflag & PARODD)) { cval |= UART_LCR_EPAR; + } if (cflag & CMSPAR) cval |= UART_LCR_SPAR; @@ -2660,12 +2574,13 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter fcr = 0; } else { fcr = UART_FCR_ENABLE_FIFO; - /* following add by Victor Yu. 08-30-2002 */ + // following add by Victor Yu. 08-30-2002 if (info->IsMoxaMustChipFlag) { fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; SET_MOXA_MUST_FIFO_VALUE(info); } else { - /* above add by Victor Yu. 08-30-2002 */ + // above add by Victor Yu. 08-30-2002 + switch (info->rx_trigger) { case 1: fcr |= UART_FCR_TRIGGER_1; @@ -2691,24 +2606,22 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter info->IER |= UART_IER_MSI; if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { info->MCR |= UART_MCR_AFE; - /* status = mxser_get_msr(info->base, 0, info->port); */ -/* - save_flags(flags); + //status = mxser_get_msr(info->base, 0, info->port); +/* save_flags(flags); cli(); status = inb(baseaddr + UART_MSR); - restore_flags(flags); -*/ - /* mxser_check_modem_status(info, status); */ + restore_flags(flags);*/ + //mxser_check_modem_status(info, status); } else { - /* status = mxser_get_msr(info->base, 0, info->port); */ - /* MX_LOCK(&info->slock); */ + //status = mxser_get_msr(info->base, 0, info->port); + + //MX_LOCK(&info->slock); status = inb(info->base + UART_MSR); - /* MX_UNLOCK(&info->slock); */ + //MX_UNLOCK(&info->slock); if (info->tty->hw_stopped) { if (status & UART_MSR_CTS) { info->tty->hw_stopped = 0; - if ((info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag)) { + if ((info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag)) { info->IER |= UART_IER_THRI; outb(info->IER, info->base + UART_IER); } @@ -2717,8 +2630,7 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter } else { if (!(status & UART_MSR_CTS)) { info->tty->hw_stopped = 1; - if ((info->type != PORT_16550A) && - (!info->IsMoxaMustChipFlag)) { + if ((info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag)) { info->IER &= ~UART_IER_THRI; outb(info->IER, info->base + UART_IER); } @@ -2756,17 +2668,11 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter * overruns too. (For real raw support). */ if (I_IGNPAR(info->tty)) { - info->ignore_status_mask |= - UART_LSR_OE | - UART_LSR_PE | - UART_LSR_FE; - info->read_status_mask |= - UART_LSR_OE | - UART_LSR_PE | - UART_LSR_FE; + info->ignore_status_mask |= UART_LSR_OE | UART_LSR_PE | UART_LSR_FE; + info->read_status_mask |= UART_LSR_OE | UART_LSR_PE | UART_LSR_FE; } } - /* following add by Victor Yu. 09-02-2002 */ + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag) { spin_lock_irqsave(&info->slock, flags); SET_MOXA_MUST_XON1_VALUE(info->base, START_CHAR(info->tty)); @@ -2792,7 +2698,7 @@ static int mxser_change_speed(struct mxser_struct *info, struct termios *old_ter */ spin_unlock_irqrestore(&info->slock, flags); } - /* above add by Victor Yu. 09-02-2002 */ + // above add by Victor Yu. 09-02-2002 outb(fcr, info->base + UART_FCR); /* set fcr */ @@ -2823,8 +2729,10 @@ static int mxser_set_baud(struct mxser_struct *info, long newspd) quot = (2 * info->baud_base / 269); } else if (newspd) { quot = info->baud_base / newspd; + if (quot == 0) quot = 1; + } else { quot = 0; } @@ -2857,6 +2765,8 @@ static int mxser_set_baud(struct mxser_struct *info, long newspd) return ret; } + + /* * ------------------------------------------------------------ * friends of mxser_ioctl() @@ -2867,7 +2777,7 @@ static int mxser_get_serial_info(struct mxser_struct *info, struct serial_struct struct serial_struct tmp; if (!retinfo) - return -EFAULT; + return (-EFAULT); memset(&tmp, 0, sizeof(tmp)); tmp.type = info->type; tmp.line = info->port; @@ -2881,7 +2791,7 @@ static int mxser_get_serial_info(struct mxser_struct *info, struct serial_struct tmp.hub6 = 0; if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; - return 0; + return (0); } static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct __user *new_info) @@ -2891,37 +2801,29 @@ static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct int retval = 0; if (!new_info || !info->base) - return -EFAULT; + return (-EFAULT); if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) return -EFAULT; - if ((new_serial.irq != info->irq) || - (new_serial.port != info->base) || - (new_serial.custom_divisor != info->custom_divisor) || - (new_serial.baud_base != info->baud_base)) - return -EPERM; + if ((new_serial.irq != info->irq) || (new_serial.port != info->base) || (new_serial.custom_divisor != info->custom_divisor) || (new_serial.baud_base != info->baud_base)) + return (-EPERM); flags = info->flags & ASYNC_SPD_MASK; if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.baud_base != info->baud_base) || - (new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK))) - return -EPERM; - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); + if ((new_serial.baud_base != info->baud_base) || (new_serial.close_delay != info->close_delay) || ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK))) + return (-EPERM); + info->flags = ((info->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); } else { /* * OK, past this point, all the error checking has been done. * At this point, we start making changes..... */ - info->flags = ((info->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((info->flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); info->close_delay = new_serial.close_delay * HZ / 100; info->closing_wait = new_serial.closing_wait * HZ / 100; - info->tty->low_latency = - (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->tty->low_latency = 0; /* (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; */ + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->tty->low_latency = 0; //(info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; } /* added by casper, 3/17/2000, for mouse */ @@ -2929,6 +2831,7 @@ static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct process_txrx_fifo(info); + /* */ if (info->flags & ASYNC_INITIALIZED) { if (flags != (info->flags & ASYNC_SPD_MASK)) { mxser_change_speed(info, NULL); @@ -2936,7 +2839,7 @@ static int mxser_set_serial_info(struct mxser_struct *info, struct serial_struct } else { retval = mxser_startup(info); } - return retval; + return (retval); } /* @@ -2973,27 +2876,25 @@ static void mxser_send_break(struct mxser_struct *info, int duration) return; set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&info->slock, flags); - outb(inb(info->base + UART_LCR) | UART_LCR_SBC, - info->base + UART_LCR); + outb(inb(info->base + UART_LCR) | UART_LCR_SBC, info->base + UART_LCR); spin_unlock_irqrestore(&info->slock, flags); schedule_timeout(duration); spin_lock_irqsave(&info->slock, flags); - outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC, - info->base + UART_LCR); + outb(inb(info->base + UART_LCR) & ~UART_LCR_SBC, info->base + UART_LCR); spin_unlock_irqrestore(&info->slock, flags); } static int mxser_tiocmget(struct tty_struct *tty, struct file *file) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned char control, status; unsigned long flags; if (tty->index == MXSER_PORTS) - return -ENOIOCTLCMD; + return (-ENOIOCTLCMD); if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; + return (-EIO); control = info->MCR; @@ -3003,16 +2904,12 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) mxser_check_modem_status(info, status); spin_unlock_irqrestore(&info->slock, flags); return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | - ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | - ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | - ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | - ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | - ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); + ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); } static int mxser_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { - struct mxser_struct *info = tty->driver_data; + struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; unsigned long flags; @@ -3071,36 +2968,38 @@ static int mxser_get_ISA_conf(int cap, struct mxser_hwconf *hwconf) hwconf->board_type = MXSER_BOARD_CI104J; hwconf->ports = 4; } else - return 0; + return (0); irq = 0; if (hwconf->ports == 2) { irq = regs[9] & 0xF000; irq = irq | (irq >> 4); if (irq != (regs[9] & 0xFF00)) - return MXSER_ERR_IRQ_CONFLIT; + return (MXSER_ERR_IRQ_CONFLIT); } else if (hwconf->ports == 4) { irq = regs[9] & 0xF000; irq = irq | (irq >> 4); irq = irq | (irq >> 8); if (irq != regs[9]) - return MXSER_ERR_IRQ_CONFLIT; + return (MXSER_ERR_IRQ_CONFLIT); } else if (hwconf->ports == 8) { irq = regs[9] & 0xF000; irq = irq | (irq >> 4); irq = irq | (irq >> 8); if ((irq != regs[9]) || (irq != regs[10])) - return MXSER_ERR_IRQ_CONFLIT; + return (MXSER_ERR_IRQ_CONFLIT); } - if (!irq) - return MXSER_ERR_IRQ; - hwconf->irq = ((int)(irq & 0xF000) >> 12); + if (!irq) { + return (MXSER_ERR_IRQ); + } + hwconf->irq = ((int) (irq & 0xF000) >> 12); for (i = 0; i < 8; i++) hwconf->ioaddr[i] = (int) regs[i + 1] & 0xFFF8; - if ((regs[12] & 0x80) == 0) - return MXSER_ERR_VECTOR; - hwconf->vector = (int)regs[11]; /* interrupt vector */ + if ((regs[12] & 0x80) == 0) { + return (MXSER_ERR_VECTOR); + } + hwconf->vector = (int) regs[11]; /* interrupt vector */ if (id == 1) hwconf->vector_mask = 0x00FF; else @@ -3108,10 +3007,10 @@ static int mxser_get_ISA_conf(int cap, struct mxser_hwconf *hwconf) for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) { if (regs[12] & bits) { hwconf->baud_base[i] = 921600; - hwconf->MaxCanSetBaudRate[i] = 921600; /* add by Victor Yu. 09-04-2002 */ + hwconf->MaxCanSetBaudRate[i] = 921600; // add by Victor Yu. 09-04-2002 } else { hwconf->baud_base[i] = 115200; - hwconf->MaxCanSetBaudRate[i] = 115200; /* add by Victor Yu. 09-04-2002 */ + hwconf->MaxCanSetBaudRate[i] = 115200; // add by Victor Yu. 09-04-2002 } } scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB); @@ -3131,7 +3030,7 @@ static int mxser_get_ISA_conf(int cap, struct mxser_hwconf *hwconf) hwconf->ports = 4; request_region(hwconf->ioaddr[0], 8 * hwconf->ports, "mxser(IO)"); request_region(hwconf->vector, 1, "mxser(vector)"); - return hwconf->ports; + return (hwconf->ports); } #define CHIP_SK 0x01 /* Serial Data Clock in Eprom */ @@ -3154,7 +3053,7 @@ static int mxser_read_register(int port, unsigned short *regs) id = mxser_program_mode(port); if (id < 0) - return id; + return (id); for (i = 0; i < 14; i++) { k = (i & 0x3F) | 0x180; for (j = 0x100; j > 0; j >>= 1) { @@ -3167,7 +3066,7 @@ static int mxser_read_register(int port, unsigned short *regs) outb(CHIP_CS | CHIP_SK, port); /* A? bit of read */ } } - (void)inb(port); + (void) inb(port); value = 0; for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) { outb(CHIP_CS, port); @@ -3179,33 +3078,28 @@ static int mxser_read_register(int port, unsigned short *regs) outb(0, port); } mxser_normal_mode(port); - return id; + return (id); } static int mxser_program_mode(int port) { int id, i, j, n; - /* unsigned long flags; */ + //unsigned long flags; spin_lock(&gm_lock); outb(0, port); outb(0, port); outb(0, port); - (void)inb(port); - (void)inb(port); + (void) inb(port); + (void) inb(port); outb(0, port); - (void)inb(port); - /* restore_flags(flags); */ + (void) inb(port); + //restore_flags(flags); spin_unlock(&gm_lock); id = inb(port + 1) & 0x1F; - if ((id != C168_ASIC_ID) && - (id != C104_ASIC_ID) && - (id != C102_ASIC_ID) && - (id != CI132_ASIC_ID) && - (id != CI134_ASIC_ID) && - (id != CI104J_ASIC_ID)) - return -1; + if ((id != C168_ASIC_ID) && (id != C104_ASIC_ID) && (id != C102_ASIC_ID) && (id != CI132_ASIC_ID) && (id != CI134_ASIC_ID) && (id != CI104J_ASIC_ID)) + return (-1); for (i = 0, j = 0; i < 4; i++) { n = inb(port + 2); if (n == 'M') { @@ -3218,7 +3112,7 @@ static int mxser_program_mode(int port) } if (j != 2) id = -2; - return id; + return (id); } static void mxser_normal_mode(int port) @@ -3236,7 +3130,7 @@ static void mxser_normal_mode(int port) if ((n & 0x61) == 0x60) break; if ((n & 1) == 1) - (void)inb(port); + (void) inb(port); } outb(0x00, port + 4); } diff --git a/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index 203dc2b661d5..c48de09d68f0 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/drivers/char/n_r3964.c @@ -951,8 +951,7 @@ static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, { queue_the_message: - pMsg = kmalloc(sizeof(struct r3964_message), - error_code?GFP_ATOMIC:GFP_KERNEL); + pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL); TRACE_M("add_msg - kmalloc %p",pMsg); if(pMsg==NULL) { return; diff --git a/trunk/drivers/char/nsc_gpio.c b/trunk/drivers/char/nsc_gpio.c deleted file mode 100644 index 5b91e4e25641..000000000000 --- a/trunk/drivers/char/nsc_gpio.c +++ /dev/null @@ -1,142 +0,0 @@ -/* linux/drivers/char/nsc_gpio.c - - National Semiconductor common GPIO device-file/VFS methods. - Allows a user space process to control the GPIO pins. - - Copyright (c) 2001,2002 Christer Weinigel - Copyright (c) 2005 Jim Cromie -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NAME "nsc_gpio" - -void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index) -{ - /* retrieve current config w/o changing it */ - u32 config = amp->gpio_config(index, ~0, 0); - - /* user requested via 'v' command, so its INFO */ - dev_info(amp->dev, "io%02u: 0x%04x %s %s %s %s %s %s %s\tio:%d/%d\n", - index, config, - (config & 1) ? "OE" : "TS", /* output-enabled/tristate */ - (config & 2) ? "PP" : "OD", /* push pull / open drain */ - (config & 4) ? "PUE" : "PUD", /* pull up enabled/disabled */ - (config & 8) ? "LOCKED" : "", /* locked / unlocked */ - (config & 16) ? "LEVEL" : "EDGE",/* level/edge input */ - (config & 32) ? "HI" : "LO", /* trigger on rise/fall edge */ - (config & 64) ? "DEBOUNCE" : "", /* debounce */ - - amp->gpio_get(index), amp->gpio_current(index)); -} - -ssize_t nsc_gpio_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - unsigned m = iminor(file->f_dentry->d_inode); - struct nsc_gpio_ops *amp = file->private_data; - struct device *dev = amp->dev; - size_t i; - int err = 0; - - for (i = 0; i < len; ++i) { - char c; - if (get_user(c, data + i)) - return -EFAULT; - switch (c) { - case '0': - amp->gpio_set(m, 0); - break; - case '1': - amp->gpio_set(m, 1); - break; - case 'O': - dev_dbg(dev, "GPIO%d output enabled\n", m); - amp->gpio_config(m, ~1, 1); - break; - case 'o': - dev_dbg(dev, "GPIO%d output disabled\n", m); - amp->gpio_config(m, ~1, 0); - break; - case 'T': - dev_dbg(dev, "GPIO%d output is push pull\n", - m); - amp->gpio_config(m, ~2, 2); - break; - case 't': - dev_dbg(dev, "GPIO%d output is open drain\n", - m); - amp->gpio_config(m, ~2, 0); - break; - case 'P': - dev_dbg(dev, "GPIO%d pull up enabled\n", m); - amp->gpio_config(m, ~4, 4); - break; - case 'p': - dev_dbg(dev, "GPIO%d pull up disabled\n", m); - amp->gpio_config(m, ~4, 0); - break; - case 'v': - /* View Current pin settings */ - amp->gpio_dump(amp, m); - break; - case '\n': - /* end of settings string, do nothing */ - break; - default: - dev_err(dev, "io%2d bad setting: chr<0x%2x>\n", - m, (int)c); - err++; - } - } - if (err) - return -EINVAL; /* full string handled, report error */ - - return len; -} - -ssize_t nsc_gpio_read(struct file *file, char __user * buf, - size_t len, loff_t * ppos) -{ - unsigned m = iminor(file->f_dentry->d_inode); - int value; - struct nsc_gpio_ops *amp = file->private_data; - - value = amp->gpio_get(m); - if (put_user(value ? '1' : '0', buf)) - return -EFAULT; - - return 1; -} - -/* common file-ops routines for both scx200_gpio and pc87360_gpio */ -EXPORT_SYMBOL(nsc_gpio_write); -EXPORT_SYMBOL(nsc_gpio_read); -EXPORT_SYMBOL(nsc_gpio_dump); - -static int __init nsc_gpio_init(void) -{ - printk(KERN_DEBUG NAME " initializing\n"); - return 0; -} - -static void __exit nsc_gpio_cleanup(void) -{ - printk(KERN_DEBUG NAME " cleanup\n"); -} - -module_init(nsc_gpio_init); -module_exit(nsc_gpio_cleanup); - -MODULE_AUTHOR("Jim Cromie "); -MODULE_DESCRIPTION("NatSemi GPIO Common Methods"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/pc8736x_gpio.c b/trunk/drivers/char/pc8736x_gpio.c deleted file mode 100644 index 1c706ccfdbb3..000000000000 --- a/trunk/drivers/char/pc8736x_gpio.c +++ /dev/null @@ -1,340 +0,0 @@ -/* linux/drivers/char/pc8736x_gpio.c - - National Semiconductor PC8736x GPIO driver. Allows a user space - process to play with the GPIO pins. - - Copyright (c) 2005 Jim Cromie - - adapted from linux/drivers/char/scx200_gpio.c - Copyright (c) 2001,2002 Christer Weinigel , -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEVNAME "pc8736x_gpio" - -MODULE_AUTHOR("Jim Cromie "); -MODULE_DESCRIPTION("NatSemi PC-8736x GPIO Pin Driver"); -MODULE_LICENSE("GPL"); - -static int major; /* default to dynamic major */ -module_param(major, int, 0); -MODULE_PARM_DESC(major, "Major device number"); - -static DEFINE_MUTEX(pc8736x_gpio_config_lock); -static unsigned pc8736x_gpio_base; -static u8 pc8736x_gpio_shadow[4]; - -#define SIO_BASE1 0x2E /* 1st command-reg to check */ -#define SIO_BASE2 0x4E /* alt command-reg to check */ -#define SIO_BASE_OFFSET 0x20 - -#define SIO_SID 0x20 /* SuperI/O ID Register */ -#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */ - -#define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ - -#define PC8736X_GPIO_SIZE 16 - -#define SIO_UNIT_SEL 0x7 /* unit select reg */ -#define SIO_UNIT_ACT 0x30 /* unit enable */ -#define SIO_GPIO_UNIT 0x7 /* unit number of GPIO */ -#define SIO_VLM_UNIT 0x0D -#define SIO_TMS_UNIT 0x0E - -/* config-space addrs to read/write each unit's runtime addr */ -#define SIO_BASE_HADDR 0x60 -#define SIO_BASE_LADDR 0x61 - -/* GPIO config-space pin-control addresses */ -#define SIO_GPIO_PIN_SELECT 0xF0 -#define SIO_GPIO_PIN_CONFIG 0xF1 -#define SIO_GPIO_PIN_EVENT 0xF2 - -static unsigned char superio_cmd = 0; -static unsigned char selected_device = 0xFF; /* bogus start val */ - -/* GPIO port runtime access, functionality */ -static int port_offset[] = { 0, 4, 8, 10 }; /* non-uniform offsets ! */ -/* static int event_capable[] = { 1, 1, 0, 0 }; ports 2,3 are hobbled */ - -#define PORT_OUT 0 -#define PORT_IN 1 -#define PORT_EVT_EN 2 -#define PORT_EVT_STST 3 - -static struct platform_device *pdev; /* use in dev_*() */ - -static inline void superio_outb(int addr, int val) -{ - outb_p(addr, superio_cmd); - outb_p(val, superio_cmd + 1); -} - -static inline int superio_inb(int addr) -{ - outb_p(addr, superio_cmd); - return inb_p(superio_cmd + 1); -} - -static int pc8736x_superio_present(void) -{ - /* try the 2 possible values, read a hardware reg to verify */ - superio_cmd = SIO_BASE1; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - superio_cmd = SIO_BASE2; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - return 0; -} - -static void device_select(unsigned devldn) -{ - superio_outb(SIO_UNIT_SEL, devldn); - selected_device = devldn; -} - -static void select_pin(unsigned iminor) -{ - /* select GPIO port/pin from device minor number */ - device_select(SIO_GPIO_UNIT); - superio_outb(SIO_GPIO_PIN_SELECT, - ((iminor << 1) & 0xF0) | (iminor & 0x7)); -} - -static inline u32 pc8736x_gpio_configure_fn(unsigned index, u32 mask, u32 bits, - u32 func_slct) -{ - u32 config, new_config; - - mutex_lock(&pc8736x_gpio_config_lock); - - device_select(SIO_GPIO_UNIT); - select_pin(index); - - /* read current config value */ - config = superio_inb(func_slct); - - /* set new config */ - new_config = (config & mask) | bits; - superio_outb(func_slct, new_config); - - mutex_unlock(&pc8736x_gpio_config_lock); - - return config; -} - -static u32 pc8736x_gpio_configure(unsigned index, u32 mask, u32 bits) -{ - return pc8736x_gpio_configure_fn(index, mask, bits, - SIO_GPIO_PIN_CONFIG); -} - -static int pc8736x_gpio_get(unsigned minor) -{ - int port, bit, val; - - port = minor >> 3; - bit = minor & 7; - val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); - val >>= bit; - val &= 1; - - dev_dbg(&pdev->dev, "_gpio_get(%d from %x bit %d) == val %d\n", - minor, pc8736x_gpio_base + port_offset[port] + PORT_IN, bit, - val); - - return val; -} - -static void pc8736x_gpio_set(unsigned minor, int val) -{ - int port, bit, curval; - - minor &= 0x1f; - port = minor >> 3; - bit = minor & 7; - curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); - - dev_dbg(&pdev->dev, "addr:%x cur:%x bit-pos:%d cur-bit:%x + new:%d -> bit-new:%d\n", - pc8736x_gpio_base + port_offset[port] + PORT_OUT, - curval, bit, (curval & ~(1 << bit)), val, (val << bit)); - - val = (curval & ~(1 << bit)) | (val << bit); - - dev_dbg(&pdev->dev, "gpio_set(minor:%d port:%d bit:%d)" - " %2x -> %2x\n", minor, port, bit, curval, val); - - outb_p(val, pc8736x_gpio_base + port_offset[port] + PORT_OUT); - - curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); - val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); - - dev_dbg(&pdev->dev, "wrote %x, read: %x\n", curval, val); - pc8736x_gpio_shadow[port] = val; -} - -static void pc8736x_gpio_set_high(unsigned index) -{ - pc8736x_gpio_set(index, 1); -} - -static void pc8736x_gpio_set_low(unsigned index) -{ - pc8736x_gpio_set(index, 0); -} - -static int pc8736x_gpio_current(unsigned minor) -{ - int port, bit; - minor &= 0x1f; - port = minor >> 3; - bit = minor & 7; - return ((pc8736x_gpio_shadow[port] >> bit) & 0x01); -} - -static void pc8736x_gpio_change(unsigned index) -{ - pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); -} - -static struct nsc_gpio_ops pc8736x_access = { - .owner = THIS_MODULE, - .gpio_config = pc8736x_gpio_configure, - .gpio_dump = nsc_gpio_dump, - .gpio_get = pc8736x_gpio_get, - .gpio_set = pc8736x_gpio_set, - .gpio_set_high = pc8736x_gpio_set_high, - .gpio_set_low = pc8736x_gpio_set_low, - .gpio_change = pc8736x_gpio_change, - .gpio_current = pc8736x_gpio_current -}; - -static int pc8736x_gpio_open(struct inode *inode, struct file *file) -{ - unsigned m = iminor(inode); - file->private_data = &pc8736x_access; - - dev_dbg(&pdev->dev, "open %d\n", m); - - if (m > 63) - return -EINVAL; - return nonseekable_open(inode, file); -} - -static struct file_operations pc8736x_gpio_fops = { - .owner = THIS_MODULE, - .open = pc8736x_gpio_open, - .write = nsc_gpio_write, - .read = nsc_gpio_read, -}; - -static void __init pc8736x_init_shadow(void) -{ - int port; - - /* read the current values driven on the GPIO signals */ - for (port = 0; port < 4; ++port) - pc8736x_gpio_shadow[port] - = inb_p(pc8736x_gpio_base + port_offset[port] - + PORT_OUT); - -} - -static int __init pc8736x_gpio_init(void) -{ - int rc = 0; - - pdev = platform_device_alloc(DEVNAME, 0); - if (!pdev) - return -ENOMEM; - - rc = platform_device_add(pdev); - if (rc) { - rc = -ENODEV; - goto undo_platform_dev_alloc; - } - dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n"); - - if (!pc8736x_superio_present()) { - rc = -ENODEV; - dev_err(&pdev->dev, "no device found\n"); - goto undo_platform_dev_add; - } - pc8736x_access.dev = &pdev->dev; - - /* Verify that chip and it's GPIO unit are both enabled. - My BIOS does this, so I take minimum action here - */ - rc = superio_inb(SIO_CF1); - if (!(rc & 0x01)) { - rc = -ENODEV; - dev_err(&pdev->dev, "device not enabled\n"); - goto undo_platform_dev_add; - } - device_select(SIO_GPIO_UNIT); - if (!superio_inb(SIO_UNIT_ACT)) { - rc = -ENODEV; - dev_err(&pdev->dev, "GPIO unit not enabled\n"); - goto undo_platform_dev_add; - } - - /* read the GPIO unit base addr that chip responds to */ - pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8 - | superio_inb(SIO_BASE_LADDR)); - - if (!request_region(pc8736x_gpio_base, 16, DEVNAME)) { - rc = -ENODEV; - dev_err(&pdev->dev, "GPIO ioport %x busy\n", - pc8736x_gpio_base); - goto undo_platform_dev_add; - } - dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base); - - rc = register_chrdev(major, DEVNAME, &pc8736x_gpio_fops); - if (rc < 0) { - dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc); - goto undo_platform_dev_add; - } - if (!major) { - major = rc; - dev_dbg(&pdev->dev, "got dynamic major %d\n", major); - } - - pc8736x_init_shadow(); - return 0; - -undo_platform_dev_add: - platform_device_put(pdev); -undo_platform_dev_alloc: - kfree(pdev); - return rc; -} - -static void __exit pc8736x_gpio_cleanup(void) -{ - dev_dbg(&pdev->dev, " cleanup\n"); - - release_region(pc8736x_gpio_base, 16); - - unregister_chrdev(major, DEVNAME); -} - -EXPORT_SYMBOL(pc8736x_access); - -module_init(pc8736x_gpio_init); -module_exit(pc8736x_gpio_cleanup); diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 17bc8abd5df5..07213454c458 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -844,7 +844,7 @@ static int bh_action(MGSLPC_INFO *info) return rc; } -static void bh_handler(void* Context) +void bh_handler(void* Context) { MGSLPC_INFO *info = (MGSLPC_INFO*)Context; int action; @@ -888,7 +888,7 @@ static void bh_handler(void* Context) __FILE__,__LINE__,info->device_name); } -static void bh_transmit(MGSLPC_INFO *info) +void bh_transmit(MGSLPC_INFO *info) { struct tty_struct *tty = info->tty; if (debug_level >= DEBUG_LEVEL_BH) @@ -900,7 +900,7 @@ static void bh_transmit(MGSLPC_INFO *info) } } -static void bh_status(MGSLPC_INFO *info) +void bh_status(MGSLPC_INFO *info) { info->ri_chkcount = 0; info->dsr_chkcount = 0; @@ -1582,7 +1582,7 @@ static void mgslpc_put_char(struct tty_struct *tty, unsigned char ch) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char")) return; - if (!info->tx_buf) + if (!tty || !info->tx_buf) return; spin_lock_irqsave(&info->lock,flags); @@ -1649,7 +1649,7 @@ static int mgslpc_write(struct tty_struct * tty, __FILE__,__LINE__,info->device_name,count); if (mgslpc_paranoia_check(info, tty->name, "mgslpc_write") || - !info->tx_buf) + !tty || !info->tx_buf) goto cleanup; if (info->params.mode == MGSL_MODE_HDLC) { @@ -2305,7 +2305,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, return ioctl_common(info, cmd, arg); } -static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg) +int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg) { int error; struct mgsl_icount cnow; /* kernel counter temps */ @@ -2877,7 +2877,7 @@ static int mgslpc_read_proc(char *page, char **start, off_t off, int count, return ((count < begin+len-off) ? count : begin+len-off); } -static int rx_alloc_buffers(MGSLPC_INFO *info) +int rx_alloc_buffers(MGSLPC_INFO *info) { /* each buffer has header and data */ info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size; @@ -2900,13 +2900,13 @@ static int rx_alloc_buffers(MGSLPC_INFO *info) return 0; } -static void rx_free_buffers(MGSLPC_INFO *info) +void rx_free_buffers(MGSLPC_INFO *info) { kfree(info->rx_buf); info->rx_buf = NULL; } -static int claim_resources(MGSLPC_INFO *info) +int claim_resources(MGSLPC_INFO *info) { if (rx_alloc_buffers(info) < 0 ) { printk( "Cant allocate rx buffer %s\n", info->device_name); @@ -2916,7 +2916,7 @@ static int claim_resources(MGSLPC_INFO *info) return 0; } -static void release_resources(MGSLPC_INFO *info) +void release_resources(MGSLPC_INFO *info) { if (debug_level >= DEBUG_LEVEL_INFO) printk("release_resources(%s)\n", info->device_name); @@ -2928,7 +2928,7 @@ static void release_resources(MGSLPC_INFO *info) * * Arguments: info pointer to device instance data */ -static void mgslpc_add_device(MGSLPC_INFO *info) +void mgslpc_add_device(MGSLPC_INFO *info) { info->next_device = NULL; info->line = mgslpc_device_count; @@ -2964,7 +2964,7 @@ static void mgslpc_add_device(MGSLPC_INFO *info) #endif } -static void mgslpc_remove_device(MGSLPC_INFO *remove_info) +void mgslpc_remove_device(MGSLPC_INFO *remove_info) { MGSLPC_INFO *info = mgslpc_device_list; MGSLPC_INFO *last = NULL; @@ -3257,7 +3257,7 @@ static void loopback_enable(MGSLPC_INFO *info) write_reg(info, CHA + MODE, val); } -static void hdlc_mode(MGSLPC_INFO *info) +void hdlc_mode(MGSLPC_INFO *info) { unsigned char val; unsigned char clkmode, clksubmode; @@ -3497,7 +3497,7 @@ static void hdlc_mode(MGSLPC_INFO *info) rx_stop(info); } -static void rx_stop(MGSLPC_INFO *info) +void rx_stop(MGSLPC_INFO *info) { if (debug_level >= DEBUG_LEVEL_ISR) printk("%s(%d):rx_stop(%s)\n", @@ -3510,7 +3510,7 @@ static void rx_stop(MGSLPC_INFO *info) info->rx_overflow = 0; } -static void rx_start(MGSLPC_INFO *info) +void rx_start(MGSLPC_INFO *info) { if (debug_level >= DEBUG_LEVEL_ISR) printk("%s(%d):rx_start(%s)\n", @@ -3526,7 +3526,7 @@ static void rx_start(MGSLPC_INFO *info) info->rx_enabled = 1; } -static void tx_start(MGSLPC_INFO *info) +void tx_start(MGSLPC_INFO *info) { if (debug_level >= DEBUG_LEVEL_ISR) printk("%s(%d):tx_start(%s)\n", @@ -3564,7 +3564,7 @@ static void tx_start(MGSLPC_INFO *info) info->tx_enabled = 1; } -static void tx_stop(MGSLPC_INFO *info) +void tx_stop(MGSLPC_INFO *info) { if (debug_level >= DEBUG_LEVEL_ISR) printk("%s(%d):tx_stop(%s)\n", @@ -3578,7 +3578,7 @@ static void tx_stop(MGSLPC_INFO *info) /* Reset the adapter to a known state and prepare it for further use. */ -static void reset_device(MGSLPC_INFO *info) +void reset_device(MGSLPC_INFO *info) { /* power up both channels (set BIT7) */ write_reg(info, CHA + CCR0, 0x80); @@ -3628,7 +3628,7 @@ static void reset_device(MGSLPC_INFO *info) write_reg(info, IPC, 0x05); } -static void async_mode(MGSLPC_INFO *info) +void async_mode(MGSLPC_INFO *info) { unsigned char val; @@ -3799,7 +3799,7 @@ static void async_mode(MGSLPC_INFO *info) /* Set the HDLC idle mode for the transmitter. */ -static void tx_set_idle(MGSLPC_INFO *info) +void tx_set_idle(MGSLPC_INFO *info) { /* Note: ESCC2 only supports flags and one idle modes */ if (info->idle_mode == HDLC_TXIDLE_FLAGS) @@ -3810,7 +3810,7 @@ static void tx_set_idle(MGSLPC_INFO *info) /* get state of the V24 status (input) signals. */ -static void get_signals(MGSLPC_INFO *info) +void get_signals(MGSLPC_INFO *info) { unsigned char status = 0; @@ -3832,7 +3832,7 @@ static void get_signals(MGSLPC_INFO *info) /* Set the state of DTR and RTS based on contents of * serial_signals member of device extension. */ -static void set_signals(MGSLPC_INFO *info) +void set_signals(MGSLPC_INFO *info) { unsigned char val; @@ -3856,7 +3856,7 @@ static void set_signals(MGSLPC_INFO *info) set_reg_bits(info, CHA + PVR, PVR_DTR); } -static void rx_reset_buffers(MGSLPC_INFO *info) +void rx_reset_buffers(MGSLPC_INFO *info) { RXBUF *buf; int i; @@ -3875,7 +3875,7 @@ static void rx_reset_buffers(MGSLPC_INFO *info) * * Returns 1 if frame returned, otherwise 0 */ -static int rx_get_frame(MGSLPC_INFO *info) +int rx_get_frame(MGSLPC_INFO *info) { unsigned short status; RXBUF *buf; @@ -3961,7 +3961,7 @@ static int rx_get_frame(MGSLPC_INFO *info) return 1; } -static BOOLEAN register_test(MGSLPC_INFO *info) +BOOLEAN register_test(MGSLPC_INFO *info) { static unsigned char patterns[] = { 0x00, 0xff, 0xaa, 0x55, 0x69, 0x96, 0x0f }; @@ -3987,7 +3987,7 @@ static BOOLEAN register_test(MGSLPC_INFO *info) return rc; } -static BOOLEAN irq_test(MGSLPC_INFO *info) +BOOLEAN irq_test(MGSLPC_INFO *info) { unsigned long end_time; unsigned long flags; @@ -4022,7 +4022,7 @@ static BOOLEAN irq_test(MGSLPC_INFO *info) return info->irq_occurred ? TRUE : FALSE; } -static int adapter_test(MGSLPC_INFO *info) +int adapter_test(MGSLPC_INFO *info) { if (!register_test(info)) { info->init_error = DiagStatus_AddressFailure; @@ -4044,7 +4044,7 @@ static int adapter_test(MGSLPC_INFO *info) return 0; } -static void trace_block(MGSLPC_INFO *info,const char* data, int count, int xmit) +void trace_block(MGSLPC_INFO *info,const char* data, int count, int xmit) { int i; int linecount; @@ -4079,7 +4079,7 @@ static void trace_block(MGSLPC_INFO *info,const char* data, int count, int xmit) /* HDLC frame time out * update stats and do tx completion processing */ -static void tx_timeout(unsigned long context) +void tx_timeout(unsigned long context) { MGSLPC_INFO *info = (MGSLPC_INFO*)context; unsigned long flags; diff --git a/trunk/drivers/char/rio/riointr.c b/trunk/drivers/char/rio/riointr.c index 0bd09040a5c0..eec1fea0cb92 100644 --- a/trunk/drivers/char/rio/riointr.c +++ b/trunk/drivers/char/rio/riointr.c @@ -546,7 +546,7 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP) ** run out of space it will be set to the offset of the ** next byte to copy from the packet data area. The packet ** length field is decremented by the number of bytes that - ** we successfully removed from the packet. When this reaches + ** we succesfully removed from the packet. When this reaches ** zero, we reset the offset pointer to be zero, and free ** the packet from the front of the queue. */ diff --git a/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index 0708c5164c83..7edc6a4dbdc4 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/drivers/char/rocket.c @@ -324,15 +324,35 @@ static void rp_do_receive(struct r_port *info, CHANNEL_t * cp, unsigned int ChanStatus) { unsigned int CharNStat; - int ToRecv, wRecv, space; - unsigned char *cbuf; + int ToRecv, wRecv, space = 0, count; + unsigned char *cbuf, *chead; + char *fbuf, *fhead; + struct tty_ldisc *ld; + + ld = tty_ldisc_ref(tty); ToRecv = sGetRxCnt(cp); + space = tty->receive_room; + if (space > 2 * TTY_FLIPBUF_SIZE) + space = 2 * TTY_FLIPBUF_SIZE; + count = 0; #ifdef ROCKET_DEBUG_INTR - printk(KERN_INFO "rp_do_receive(%d)...", ToRecv); + printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space); #endif - if (ToRecv == 0) - return; + + /* + * determine how many we can actually read in. If we can't + * read any in then we have a software overrun condition. + */ + if (ToRecv > space) + ToRecv = space; + + ToRecv = tty_prepare_flip_string_flags(tty, &chead, &fhead, ToRecv); + if (ToRecv <= 0) + goto done; + + cbuf = chead; + fbuf = fhead; /* * if status indicates there are errored characters in the @@ -360,8 +380,6 @@ static void rp_do_receive(struct r_port *info, info->read_status_mask); #endif while (ToRecv) { - char flag; - CharNStat = sInW(sGetTxRxDataIO(cp)); #ifdef ROCKET_DEBUG_RECEIVE printk(KERN_INFO "%x...", CharNStat); @@ -374,16 +392,17 @@ static void rp_do_receive(struct r_port *info, } CharNStat &= info->read_status_mask; if (CharNStat & STMBREAKH) - flag = TTY_BREAK; + *fbuf++ = TTY_BREAK; else if (CharNStat & STMPARITYH) - flag = TTY_PARITY; + *fbuf++ = TTY_PARITY; else if (CharNStat & STMFRAMEH) - flag = TTY_FRAME; + *fbuf++ = TTY_FRAME; else if (CharNStat & STMRCVROVRH) - flag = TTY_OVERRUN; + *fbuf++ = TTY_OVERRUN; else - flag = TTY_NORMAL; - tty_insert_flip_char(tty, CharNStat & 0xff, flag); + *fbuf++ = TTY_NORMAL; + *cbuf++ = CharNStat & 0xff; + count++; ToRecv--; } @@ -403,23 +422,20 @@ static void rp_do_receive(struct r_port *info, * characters at time by doing repeated word IO * transfer. */ - space = tty_prepare_flip_string(tty, &cbuf, ToRecv); - if (space < ToRecv) { -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); -#endif - if (space <= 0) - return; - ToRecv = space; - } wRecv = ToRecv >> 1; if (wRecv) sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); if (ToRecv & 1) cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); + memset(fbuf, TTY_NORMAL, ToRecv); + cbuf += ToRecv; + fbuf += ToRecv; + count += ToRecv; } /* Push the data up to the tty layer */ - tty_flip_buffer_push(tty); + ld->receive_buf(tty, chead, fhead, count); +done: + tty_ldisc_deref(ld); } /* diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 0897b0c8d528..f6686fcce809 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -928,7 +928,7 @@ static int __init rtc_init(void) #ifdef __sparc__ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if(strcmp(edev->prom_node->name, "rtc") == 0) { + if(strcmp(edev->prom_name, "rtc") == 0) { rtc_port = edev->resource[0].start; rtc_irq = edev->irqs[0]; goto found; @@ -938,7 +938,7 @@ static int __init rtc_init(void) #ifdef __sparc_v9__ for_each_isa(isa_br) { for_each_isadev(isa_dev, isa_br) { - if (strcmp(isa_dev->prom_node->name, "rtc") == 0) { + if (strcmp(isa_dev->prom_name, "rtc") == 0) { rtc_port = isa_dev->resource.start; rtc_irq = isa_dev->irq; goto found; diff --git a/trunk/drivers/char/scx200_gpio.c b/trunk/drivers/char/scx200_gpio.c index 5a280a330401..664a6e97eb1a 100644 --- a/trunk/drivers/char/scx200_gpio.c +++ b/trunk/drivers/char/scx200_gpio.c @@ -1,4 +1,4 @@ -/* linux/drivers/char/scx200_gpio.c +/* linux/drivers/char/scx200_gpio.c National Semiconductor SCx200 GPIO driver. Allows a user space process to play with the GPIO pins. @@ -6,26 +6,17 @@ Copyright (c) 2001,2002 Christer Weinigel */ #include -#include #include #include #include #include #include -#include #include #include -#include -#include - #include -#include #define NAME "scx200_gpio" -#define DEVNAME NAME - -static struct platform_device *pdev; MODULE_AUTHOR("Christer Weinigel "); MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); @@ -35,23 +26,70 @@ static int major = 0; /* default to dynamic major */ module_param(major, int, 0); MODULE_PARM_DESC(major, "Major device number"); -struct nsc_gpio_ops scx200_access = { - .owner = THIS_MODULE, - .gpio_config = scx200_gpio_configure, - .gpio_dump = nsc_gpio_dump, - .gpio_get = scx200_gpio_get, - .gpio_set = scx200_gpio_set, - .gpio_set_high = scx200_gpio_set_high, - .gpio_set_low = scx200_gpio_set_low, - .gpio_change = scx200_gpio_change, - .gpio_current = scx200_gpio_current -}; +static ssize_t scx200_gpio_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + unsigned m = iminor(file->f_dentry->d_inode); + size_t i; + + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, data+i)) + return -EFAULT; + switch (c) + { + case '0': + scx200_gpio_set(m, 0); + break; + case '1': + scx200_gpio_set(m, 1); + break; + case 'O': + printk(KERN_INFO NAME ": GPIO%d output enabled\n", m); + scx200_gpio_configure(m, ~1, 1); + break; + case 'o': + printk(KERN_INFO NAME ": GPIO%d output disabled\n", m); + scx200_gpio_configure(m, ~1, 0); + break; + case 'T': + printk(KERN_INFO NAME ": GPIO%d output is push pull\n", m); + scx200_gpio_configure(m, ~2, 2); + break; + case 't': + printk(KERN_INFO NAME ": GPIO%d output is open drain\n", m); + scx200_gpio_configure(m, ~2, 0); + break; + case 'P': + printk(KERN_INFO NAME ": GPIO%d pull up enabled\n", m); + scx200_gpio_configure(m, ~4, 4); + break; + case 'p': + printk(KERN_INFO NAME ": GPIO%d pull up disabled\n", m); + scx200_gpio_configure(m, ~4, 0); + break; + } + } + + return len; +} + +static ssize_t scx200_gpio_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + unsigned m = iminor(file->f_dentry->d_inode); + int value; + + value = scx200_gpio_get(m); + if (put_user(value ? '1' : '0', buf)) + return -EFAULT; + + return 1; +} static int scx200_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); - file->private_data = &scx200_access; - if (m > 63) return -EINVAL; return nonseekable_open(inode, file); @@ -65,81 +103,47 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) static struct file_operations scx200_gpio_fops = { .owner = THIS_MODULE, - .write = nsc_gpio_write, - .read = nsc_gpio_read, + .write = scx200_gpio_write, + .read = scx200_gpio_read, .open = scx200_gpio_open, .release = scx200_gpio_release, }; -struct cdev *scx200_devices; -static int num_pins = 32; - static int __init scx200_gpio_init(void) { - int rc, i; - dev_t dev = MKDEV(major, 0); + int r; + + printk(KERN_DEBUG NAME ": NatSemi SCx200 GPIO Driver\n"); if (!scx200_gpio_present()) { - printk(KERN_ERR NAME ": no SCx200 gpio present\n"); + printk(KERN_ERR NAME ": no SCx200 gpio pins available\n"); return -ENODEV; } - /* support dev_dbg() with pdev->dev */ - pdev = platform_device_alloc(DEVNAME, 0); - if (!pdev) - return -ENOMEM; - - rc = platform_device_add(pdev); - if (rc) - goto undo_malloc; - - /* nsc_gpio uses dev_dbg(), so needs this */ - scx200_access.dev = &pdev->dev; - - if (major) - rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); - else { - rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); - major = MAJOR(dev); + r = register_chrdev(major, NAME, &scx200_gpio_fops); + if (r < 0) { + printk(KERN_ERR NAME ": unable to register character device\n"); + return r; } - if (rc < 0) { - dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); - goto undo_platform_device_add; + if (!major) { + major = r; + printk(KERN_DEBUG NAME ": got dynamic major %d\n", major); } - scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); - if (!scx200_devices) { - rc = -ENOMEM; - goto undo_chrdev_region; - } - for (i = 0; i < num_pins; i++) { - struct cdev *cdev = &scx200_devices[i]; - cdev_init(cdev, &scx200_gpio_fops); - cdev->owner = THIS_MODULE; - rc = cdev_add(cdev, MKDEV(major, i), 1); - /* tolerate 'minor' errors */ - if (rc) - dev_err(&pdev->dev, "Error %d on minor %d", rc, i); - } - - return 0; /* succeed */ -undo_chrdev_region: - unregister_chrdev_region(dev, num_pins); -undo_platform_device_add: - platform_device_put(pdev); -undo_malloc: - kfree(pdev); - return rc; + return 0; } static void __exit scx200_gpio_cleanup(void) { - kfree(scx200_devices); - unregister_chrdev_region(MKDEV(major, 0), num_pins); - platform_device_put(pdev); - platform_device_unregister(pdev); - /* kfree(pdev); */ + unregister_chrdev(major, NAME); } module_init(scx200_gpio_init); module_exit(scx200_gpio_cleanup); + +/* + Local variables: + compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" + c-basic-offset: 8 + End: +*/ diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index 43dfd8689dce..a90f5d97df35 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -512,7 +512,7 @@ static struct sonypi_device { #ifdef CONFIG_ACPI static struct acpi_device *sonypi_acpi_device; -static int acpi_driver_registered; +static int acpi_enabled; #endif static int sonypi_ec_write(u8 addr, u8 value) @@ -869,7 +869,7 @@ static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) sonypi_report_input_event(event); #ifdef CONFIG_ACPI - if (sonypi_acpi_device) + if (acpi_enabled) acpi_bus_generate_event(sonypi_acpi_device, 1, event); #endif @@ -1551,8 +1551,8 @@ static int __init sonypi_init(void) goto err_free_device; #ifdef CONFIG_ACPI - if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0) - acpi_driver_registered = 1; + if (acpi_bus_register_driver(&sonypi_acpi_driver) > 0) + acpi_enabled = 1; #endif return 0; @@ -1567,7 +1567,7 @@ static int __init sonypi_init(void) static void __exit sonypi_exit(void) { #ifdef CONFIG_ACPI - if (acpi_driver_registered) + if (acpi_enabled) acpi_bus_unregister_driver(&sonypi_acpi_driver); #endif platform_device_unregister(sonypi_platform_device); diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index d2d6b01dcd05..5343e9fc6ab7 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -1683,7 +1683,7 @@ static int sx_write(struct tty_struct * tty, bp = port_Board(port); - if (!port->xmit_buf || !tmp_buf) { + if (!tty || !port->xmit_buf || !tmp_buf) { func_exit(); return 0; } @@ -1733,7 +1733,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) return; } dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); - if (!port->xmit_buf) { + if (!tty || !port->xmit_buf) { func_exit(); return; } @@ -2477,7 +2477,7 @@ static int __init specialix_init(void) #endif for (i = 0; i < SX_NBOARD; i++) - spin_lock_init(&sx_board[i].lock); + sx_board[i].lock = SPIN_LOCK_UNLOCKED; if (sx_init_drivers()) { func_exit(); diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index bf361a5ba70d..a9c5a7230f89 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -140,6 +140,15 @@ static char *stl_drvversion = "5.6.0"; static struct tty_driver *stl_serial; +/* + * We will need to allocate a temporary write buffer for chars that + * come direct from user space. The problem is that a copy from user + * space might cause a page fault (typically on a system that is + * swapping!). All ports will share one buffer - since if the system + * is already swapping a shared buffer won't make things any worse. + */ +static char *stl_tmpwritebuf; + /* * Define a local default termios struct. All ports will be created * with this termios initially. Basically all it defines is a raw port @@ -353,14 +362,6 @@ static unsigned char stl_vecmap[] = { 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03 }; -/* - * Lock ordering is that you may not take stallion_lock holding - * brd_lock. - */ - -static spinlock_t brd_lock; /* Guard the board mapping */ -static spinlock_t stallion_lock; /* Guard the tty driver */ - /* * Set up enable and disable macros for the ECH boards. They require * the secondary io address space to be activated and deactivated. @@ -724,7 +725,17 @@ static struct class *stallion_class; static int __init stallion_module_init(void) { + unsigned long flags; + +#ifdef DEBUG + printk("init_module()\n"); +#endif + + save_flags(flags); + cli(); stl_init(); + restore_flags(flags); + return 0; } @@ -735,6 +746,7 @@ static void __exit stallion_module_exit(void) stlbrd_t *brdp; stlpanel_t *panelp; stlport_t *portp; + unsigned long flags; int i, j, k; #ifdef DEBUG @@ -744,6 +756,9 @@ static void __exit stallion_module_exit(void) printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, stl_drvversion); + save_flags(flags); + cli(); + /* * Free up all allocated resources used by the ports. This includes * memory and interrupts. As part of this process we will also do @@ -755,6 +770,7 @@ static void __exit stallion_module_exit(void) if (i) { printk("STALLION: failed to un-register tty driver, " "errno=%d\n", -i); + restore_flags(flags); return; } for (i = 0; i < 4; i++) { @@ -767,6 +783,8 @@ static void __exit stallion_module_exit(void) "errno=%d\n", -i); class_destroy(stallion_class); + kfree(stl_tmpwritebuf); + for (i = 0; (i < stl_nrbrds); i++) { if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) continue; @@ -796,6 +814,8 @@ static void __exit stallion_module_exit(void) kfree(brdp); stl_brds[i] = (stlbrd_t *) NULL; } + + restore_flags(flags); } module_init(stallion_module_init); @@ -928,7 +948,7 @@ static stlbrd_t *stl_allocbrd(void) brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); if (!brdp) { - printk("STALLION: failed to allocate memory (size=%Zd)\n", + printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t)); return NULL; } @@ -1046,17 +1066,16 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) rc = 0; doclocal = 0; - spin_lock_irqsave(&stallion_lock, flags); - if (portp->tty->termios->c_cflag & CLOCAL) doclocal++; + save_flags(flags); + cli(); portp->openwaitcnt++; if (! tty_hung_up_p(filp)) portp->refcount--; for (;;) { - /* Takes brd_lock internally */ stl_setsignals(portp, 1, 1); if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) { @@ -1074,14 +1093,13 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) rc = -ERESTARTSYS; break; } - /* FIXME */ interruptible_sleep_on(&portp->open_wait); } if (! tty_hung_up_p(filp)) portp->refcount++; portp->openwaitcnt--; - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return rc; } @@ -1101,15 +1119,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&stallion_lock, flags); + save_flags(flags); + cli(); if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return; } if ((tty->count == 1) && (portp->refcount != 1)) portp->refcount = 1; if (portp->refcount-- > 1) { - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return; } @@ -1123,18 +1142,11 @@ static void stl_close(struct tty_struct *tty, struct file *filp) * (The sc26198 has no "end-of-data" interrupt only empty FIFO) */ tty->closing = 1; - - spin_unlock_irqrestore(&stallion_lock, flags); - if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, portp->closing_wait); stl_waituntilsent(tty, (HZ / 2)); - - spin_lock_irqsave(&stallion_lock, flags); portp->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&stallion_lock, flags); - stl_disableintrs(portp); if (tty->termios->c_cflag & HUPCL) stl_setsignals(portp, 0, 0); @@ -1161,6 +1173,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&portp->close_wait); + restore_flags(flags); } /*****************************************************************************/ @@ -1182,6 +1195,9 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count (int) tty, (int) buf, count); #endif + if ((tty == (struct tty_struct *) NULL) || + (stl_tmpwritebuf == (char *) NULL)) + return 0; portp = tty->driver_data; if (portp == (stlport_t *) NULL) return 0; @@ -1286,6 +1302,11 @@ static void stl_flushchars(struct tty_struct *tty) if (portp->tx.buf == (char *) NULL) return; +#if 0 + if (tty->stopped || tty->hw_stopped || + (portp->tx.head == portp->tx.tail)) + return; +#endif stl_startrxtx(portp, -1, 1); } @@ -1956,14 +1977,12 @@ static int stl_eiointr(stlbrd_t *brdp) unsigned int iobase; int handled = 0; - spin_lock(&brd_lock); panelp = brdp->panels[0]; iobase = panelp->iobase; while (inb(brdp->iostatus) & EIO_INTRPEND) { handled = 1; (* panelp->isr)(panelp, iobase); } - spin_unlock(&brd_lock); return handled; } @@ -2149,7 +2168,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); if (!portp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlport_t)); + "(size=%d)\n", sizeof(stlport_t)); break; } @@ -2285,7 +2304,7 @@ static inline int stl_initeio(stlbrd_t *brdp) panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk(KERN_WARNING "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlpanel_t)); + "(size=%d)\n", sizeof(stlpanel_t)); return -ENOMEM; } @@ -2459,7 +2478,7 @@ static inline int stl_initech(stlbrd_t *brdp) panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlpanel_t)); + "(size=%d)\n", sizeof(stlpanel_t)); break; } panelp->magic = STL_PANELMAGIC; @@ -2860,7 +2879,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) portp->stats.lflags = 0; portp->stats.rxbuffered = 0; - spin_lock_irqsave(&stallion_lock, flags); + save_flags(flags); + cli(); if (portp->tty != (struct tty_struct *) NULL) { if (portp->tty->driver_data == portp) { portp->stats.ttystate = portp->tty->flags; @@ -2874,7 +2894,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) } } } - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); head = portp->tx.head; tail = portp->tx.tail; @@ -3035,6 +3055,14 @@ static int __init stl_init(void) if (!stl_serial) return -1; +/* + * Allocate a temporary write buffer. + */ + stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); + if (!stl_tmpwritebuf) + printk("STALLION: failed to allocate memory (size=%d)\n", + STL_TXBUFSIZE); + /* * Set up a character driver for per board stuff. This is mainly used * to do stats ioctls on the ports. @@ -3119,13 +3147,11 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) unsigned int gfrcr; int chipmask, i, j; int nrchips, uartaddr, ioaddr; - unsigned long flags; #ifdef DEBUG printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); #endif - spin_lock_irqsave(&brd_lock, flags); BRDENABLE(panelp->brdnr, panelp->pagenr); /* @@ -3163,7 +3189,6 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) } BRDDISABLE(panelp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); return chipmask; } @@ -3175,7 +3200,6 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) { - unsigned long flags; #ifdef DEBUG printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", (int) brdp, (int) panelp, (int) portp); @@ -3185,7 +3209,6 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po (portp == (stlport_t *) NULL)) return; - spin_lock_irqsave(&brd_lock, flags); portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); portp->uartaddr = (portp->portnr & 0x04) << 5; @@ -3196,7 +3219,6 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); portp->hwid = stl_cd1400getreg(portp, GFRCR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); } /*****************************************************************************/ @@ -3406,7 +3428,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); srer = stl_cd1400getreg(portp, SRER); @@ -3443,7 +3466,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) portp->sigs &= ~TIOCM_CD; stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3469,7 +3492,8 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) if (rts > 0) msvr2 = MSVR2_RTS; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); if (rts >= 0) @@ -3477,7 +3501,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) if (dtr >= 0) stl_cd1400setreg(portp, MSVR1, msvr1); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3496,13 +3520,14 @@ static int stl_cd1400getsignals(stlport_t *portp) printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); msvr1 = stl_cd1400getreg(portp, MSVR1); msvr2 = stl_cd1400getreg(portp, MSVR2); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); sigs = 0; sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; @@ -3544,14 +3569,15 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) ccr |= CCR_RXENABLE; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400ccrwait(portp); stl_cd1400setreg(portp, CCR, ccr); stl_cd1400ccrwait(portp); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3583,7 +3609,8 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) sreron |= SRER_RXDATA; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, @@ -3591,7 +3618,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) BRDDISABLE(portp->brdnr); if (tx > 0) set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3607,12 +3634,13 @@ static void stl_cd1400disableintrs(stlport_t *portp) #ifdef DEBUG printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, 0); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3625,7 +3653,8 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, @@ -3635,7 +3664,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) portp->brklen = len; if (len == 1) portp->stats.txbreaks++; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3659,7 +3688,8 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); @@ -3699,7 +3729,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3723,7 +3753,8 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); if (state) { @@ -3738,7 +3769,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) stl_cd1400ccrwait(portp); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3754,7 +3785,8 @@ static void stl_cd1400flush(stlport_t *portp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400ccrwait(portp); @@ -3762,7 +3794,7 @@ static void stl_cd1400flush(stlport_t *portp) stl_cd1400ccrwait(portp); portp->tx.tail = portp->tx.head; BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3801,7 +3833,6 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) (int) panelp, iobase); #endif - spin_lock(&brd_lock); outb(SVRR, iobase); svrtype = inb(iobase + EREG_DATA); if (panelp->nrports > 4) { @@ -3815,8 +3846,6 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) stl_cd1400txisr(panelp, iobase); else if (svrtype & SVRR_MDM) stl_cd1400mdmisr(panelp, iobase); - - spin_unlock(&brd_lock); } /*****************************************************************************/ @@ -4404,7 +4433,8 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IMR, 0); stl_sc26198updatereg(portp, MR0, mr0); @@ -4431,7 +4461,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) portp->imr = (portp->imr & ~imroff) | imron; stl_sc26198setreg(portp, IMR, portp->imr); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4461,12 +4491,13 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) else if (rts > 0) iopioron |= IPR_RTS; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IOPIOR, ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4485,11 +4516,12 @@ static int stl_sc26198getsignals(stlport_t *portp) printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); ipr = stl_sc26198getreg(portp, IPR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); sigs = 0; sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; @@ -4526,12 +4558,13 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) ccr |= CR_RXENABLE; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, SCCR, ccr); BRDDISABLE(portp->brdnr); portp->crenable = ccr; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4560,14 +4593,15 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IMR, imr); BRDDISABLE(portp->brdnr); portp->imr = imr; if (tx > 0) set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4584,12 +4618,13 @@ static void stl_sc26198disableintrs(stlport_t *portp) printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); portp->imr = 0; stl_sc26198setreg(portp, IMR, 0); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4602,7 +4637,8 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (len == 1) { stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); @@ -4611,7 +4647,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4636,7 +4672,8 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (state) { @@ -4682,7 +4719,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4707,7 +4744,8 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (state) { mr0 = stl_sc26198getreg(portp, MR0); @@ -4727,7 +4765,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) stl_sc26198setreg(portp, MR0, mr0); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4743,13 +4781,14 @@ static void stl_sc26198flush(stlport_t *portp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, SCCR, CR_TXRESET); stl_sc26198setreg(portp, SCCR, portp->crenable); BRDDISABLE(portp->brdnr); portp->tx.tail = portp->tx.head; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4776,11 +4815,12 @@ static int stl_sc26198datastate(stlport_t *portp) if (test_bit(ASYI_TXBUSY, &portp->istate)) return 1; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); sr = stl_sc26198getreg(portp, SR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); return (sr & SR_TXEMPTY) ? 0 : 1; } @@ -4838,8 +4878,6 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) stlport_t *portp; unsigned int iack; - spin_lock(&brd_lock); - /* * Work around bug in sc26198 chip... Cannot have A6 address * line of UART high, else iack will be returned as 0. @@ -4855,8 +4893,6 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) stl_sc26198txisr(portp); else stl_sc26198otherisr(portp, iack); - - spin_unlock(&brd_lock); } /*****************************************************************************/ diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index 76b9107f7f81..3b4747230270 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -2320,7 +2320,7 @@ static int sx_init_portstructs (int nboards, int nports) #ifdef NEW_WRITE_LOCKING port->gs.port_write_mutex = MUTEX; #endif - spin_lock_init(&port->gs.driver_lock); + port->gs.driver_lock = SPIN_LOCK_UNLOCKED; /* * Initializing wait queue */ diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 4e35d4181224..b4d1f4eea435 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -101,7 +101,6 @@ MODULE_LICENSE("GPL"); static struct pci_device_id pci_table[] = { {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {0,}, /* terminate list */ @@ -871,7 +870,7 @@ static int write(struct tty_struct *tty, goto cleanup; DBGINFO(("%s write count=%d\n", info->device_name, count)); - if (!info->tx_buf) + if (!tty || !info->tx_buf) goto cleanup; if (count > info->max_frame_size) { @@ -925,7 +924,7 @@ static void put_char(struct tty_struct *tty, unsigned char ch) if (sanity_check(info, tty->name, "put_char")) return; DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); - if (!info->tx_buf) + if (!tty || !info->tx_buf) return; spin_lock_irqsave(&info->lock,flags); if (!info->tx_active && (info->tx_count < info->max_frame_size)) @@ -2516,8 +2515,7 @@ static int set_txidle(struct slgt_info *info, int idle_mode) DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); spin_lock_irqsave(&info->lock,flags); info->idle_mode = idle_mode; - if (info->params.mode != MGSL_MODE_ASYNC) - tx_set_idle(info); + tx_set_idle(info); spin_unlock_irqrestore(&info->lock,flags); return 0; } @@ -3078,7 +3076,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, static int alloc_tmp_rbuf(struct slgt_info *info) { - info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); + info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL); if (info->tmp_rbuf == NULL) return -ENOMEM; return 0; @@ -3278,9 +3276,6 @@ static void add_device(struct slgt_info *info) case SYNCLINK_GT_DEVICE_ID: devstr = "GT"; break; - case SYNCLINK_GT2_DEVICE_ID: - devstr = "GT2"; - break; case SYNCLINK_GT4_DEVICE_ID: devstr = "GT4"; break; @@ -3358,9 +3353,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev) int i; int port_count = 1; - if (pdev->device == SYNCLINK_GT2_DEVICE_ID) - port_count = 2; - else if (pdev->device == SYNCLINK_GT4_DEVICE_ID) + if (pdev->device == SYNCLINK_GT4_DEVICE_ID) port_count = 4; /* allocate device instances for all ports */ @@ -3947,6 +3940,8 @@ static void async_mode(struct slgt_info *info) msc_set_vcr(info); + tx_set_idle(info); + /* SCR (serial control) * * 15 1=tx req on FIFO half empty @@ -4017,7 +4012,7 @@ static void hdlc_mode(struct slgt_info *info) case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; } - switch (info->params.crc_type & HDLC_CRC_MASK) + switch (info->params.crc_type) { case HDLC_CRC_16_CCITT: val |= BIT9; break; case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; @@ -4078,7 +4073,7 @@ static void hdlc_mode(struct slgt_info *info) case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; } - switch (info->params.crc_type & HDLC_CRC_MASK) + switch (info->params.crc_type) { case HDLC_CRC_16_CCITT: val |= BIT9; break; case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; @@ -4180,38 +4175,17 @@ static void hdlc_mode(struct slgt_info *info) */ static void tx_set_idle(struct slgt_info *info) { - unsigned char val; - unsigned short tcr; + unsigned char val = 0xff; - /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits - * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits - */ - tcr = rd_reg16(info, TCR); - if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) { - /* disable preamble, set idle size to 16 bits */ - tcr = (tcr & ~(BIT6 + BIT5)) | BIT4; - /* MSB of 16 bit idle specified in tx preamble register (TPR) */ - wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff)); - } else if (!(tcr & BIT6)) { - /* preamble is disabled, set idle size to 8 bits */ - tcr &= ~(BIT5 + BIT4); - } - wr_reg16(info, TCR, tcr); - - if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) { - /* LSB of custom tx idle specified in tx idle register */ - val = (unsigned char)(info->idle_mode & 0xff); - } else { - /* standard 8 bit idle patterns */ - switch(info->idle_mode) - { - case HDLC_TXIDLE_FLAGS: val = 0x7e; break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: - case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; - case HDLC_TXIDLE_ZEROS: - case HDLC_TXIDLE_SPACE: val = 0x00; break; - default: val = 0xff; - } + switch(info->idle_mode) + { + case HDLC_TXIDLE_FLAGS: val = 0x7e; break; + case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break; + case HDLC_TXIDLE_ZEROS: val = 0x00; break; + case HDLC_TXIDLE_ONES: val = 0xff; break; + case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; + case HDLC_TXIDLE_SPACE: val = 0x00; break; + case HDLC_TXIDLE_MARK: val = 0xff; break; } wr_reg8(info, TIR, val); @@ -4339,12 +4313,6 @@ static int rx_get_frame(struct slgt_info *info) unsigned long flags; struct tty_struct *tty = info->tty; unsigned char addr_field = 0xff; - unsigned int crc_size = 0; - - switch (info->params.crc_type & HDLC_CRC_MASK) { - case HDLC_CRC_16_CCITT: crc_size = 2; break; - case HDLC_CRC_32_CCITT: crc_size = 4; break; - } check_again: @@ -4389,7 +4357,7 @@ static int rx_get_frame(struct slgt_info *info) status = desc_status(info->rbufs[end]); /* ignore CRC bit if not using CRC (bit is undefined) */ - if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE) + if (info->params.crc_type == HDLC_CRC_NONE) status &= ~BIT1; if (framesize == 0 || @@ -4398,34 +4366,34 @@ static int rx_get_frame(struct slgt_info *info) goto check_again; } - if (framesize < (2 + crc_size) || status & BIT0) { - info->icount.rxshort++; + if (framesize < 2 || status & (BIT1+BIT0)) { + if (framesize < 2 || (status & BIT0)) + info->icount.rxshort++; + else + info->icount.rxcrc++; framesize = 0; - } else if (status & BIT1) { - info->icount.rxcrc++; - if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) - framesize = 0; - } #ifdef CONFIG_HDLC - if (framesize == 0) { - struct net_device_stats *stats = hdlc_stats(info->netdev); - stats->rx_errors++; - stats->rx_frame_errors++; - } + { + struct net_device_stats *stats = hdlc_stats(info->netdev); + stats->rx_errors++; + stats->rx_frame_errors++; + } #endif + } else { + /* adjust frame size for CRC, if any */ + if (info->params.crc_type == HDLC_CRC_16_CCITT) + framesize -= 2; + else if (info->params.crc_type == HDLC_CRC_32_CCITT) + framesize -= 4; + } DBGBH(("%s rx frame status=%04X size=%d\n", info->device_name, status, framesize)); DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx"); if (framesize) { - if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) { - framesize -= crc_size; - crc_size = 0; - } - - if (framesize > info->max_frame_size + crc_size) + if (framesize > info->max_frame_size) info->icount.rxlong++; else { /* copy dma buffer(s) to contiguous temp buffer */ @@ -4445,11 +4413,6 @@ static int rx_get_frame(struct slgt_info *info) i = 0; } - if (info->params.crc_type & HDLC_CRC_RETURN_EX) { - *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK; - framesize++; - } - #ifdef CONFIG_HDLC if (info->netcount) hdlcdev_rx(info,info->tmp_rbuf, framesize); @@ -4708,13 +4671,13 @@ static int loopback_test(struct slgt_info *info) static int adapter_test(struct slgt_info *info) { DBGINFO(("testing %s\n", info->device_name)); - if (register_test(info) < 0) { + if ((info->init_error = register_test(info)) < 0) { printk("register test failure %s addr=%08X\n", info->device_name, info->phys_reg_addr); - } else if (irq_test(info) < 0) { + } else if ((info->init_error = irq_test(info)) < 0) { printk("IRQ test failure %s IRQ=%d\n", info->device_name, info->irq_level); - } else if (loopback_test(info) < 0) { + } else if ((info->init_error = loopback_test(info)) < 0) { printk("loopback test failure %s\n", info->device_name); } return info->init_error; diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 21bf15ad9980..858740131115 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -988,7 +988,7 @@ static int write(struct tty_struct *tty, if (sanity_check(info, tty->name, "write")) goto cleanup; - if (!info->tx_buf) + if (!tty || !info->tx_buf) goto cleanup; if (info->params.mode == MGSL_MODE_HDLC) { @@ -1067,7 +1067,7 @@ static void put_char(struct tty_struct *tty, unsigned char ch) if (sanity_check(info, tty->name, "put_char")) return; - if (!info->tx_buf) + if (!tty || !info->tx_buf) return; spin_lock_irqsave(&info->lock,flags); diff --git a/trunk/drivers/char/tlclk.c b/trunk/drivers/char/tlclk.c index ef68d152d3e4..f58ad7f68267 100644 --- a/trunk/drivers/char/tlclk.c +++ b/trunk/drivers/char/tlclk.c @@ -343,7 +343,7 @@ static ssize_t store_received_ref_clk3b(struct device *d, val = (unsigned char)tmp; spin_lock_irqsave(&event_lock, flags); - SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1); + SET_PORT_BITS(TLCLK_REG1, 0xef, val << 1); spin_unlock_irqrestore(&event_lock, flags); return strnlen(buf, count); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index bd74e82d8a72..a88b94a82b14 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -2621,9 +2621,10 @@ int tty_ioctl(struct inode * inode, struct file * file, tty->driver->break_ctl(tty, 0); return 0; case TCSBRK: /* SVID version: non-zero arg --> no break */ - /* non-zero arg means wait for all output data - * to be sent (performed above) but don't send break. - * This is used by the tcdrain() termios function. + /* + * XXX is the above comment correct, or the + * code below correct? Is this ioctl used at + * all by anyone? */ if (!arg) return send_break(tty, 250); @@ -2960,14 +2961,12 @@ static struct class *tty_class; * This field is optional, if there is no known struct device for this * tty device it can be set to NULL safely. * - * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). - * * This call is required to be made to register an individual tty device if * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set. If that * bit is not set, this function should not be called. */ -struct class_device *tty_register_device(struct tty_driver *driver, - unsigned index, struct device *device) +void tty_register_device(struct tty_driver *driver, unsigned index, + struct device *device) { char name[64]; dev_t dev = MKDEV(driver->major, driver->minor_start) + index; @@ -2975,7 +2974,7 @@ struct class_device *tty_register_device(struct tty_driver *driver, if (index >= driver->num) { printk(KERN_ERR "Attempt to register invalid tty line number " " (%d).\n", index); - return ERR_PTR(-EINVAL); + return; } devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, @@ -2985,8 +2984,7 @@ struct class_device *tty_register_device(struct tty_driver *driver, pty_line_name(driver, index, name); else tty_line_name(driver, index, name); - - return class_device_create(tty_class, NULL, dev, device, "%s", name); + class_device_create(tty_class, NULL, dev, device, "%s", name); } /** diff --git a/trunk/drivers/char/viotape.c b/trunk/drivers/char/viotape.c index 11c7e9de5958..60aabdb4a046 100644 --- a/trunk/drivers/char/viotape.c +++ b/trunk/drivers/char/viotape.c @@ -989,7 +989,7 @@ static int viotape_remove(struct vio_dev *vdev) * support. */ static struct vio_device_id viotape_device_table[] __devinitdata = { - { "byte", "IBM,iSeries-viotape" }, + { "viotape", "" }, { "", "" } }; MODULE_DEVICE_TABLE(vio, viotape_device_table); diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 714d95ff2f1e..6c94879e0b99 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -98,22 +98,7 @@ #include #include -#define MAX_NR_CON_DRIVER 16 -#define CON_DRIVER_FLAG_MODULE 1 -#define CON_DRIVER_FLAG_INIT 2 - -struct con_driver { - const struct consw *con; - const char *desc; - struct class_device *class_dev; - int node; - int first; - int last; - int flag; -}; - -static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER]; const struct consw *conswitchp; /* A bitmap for codes <32. A bit of 1 indicates that the code @@ -2572,7 +2557,7 @@ static int __init con_init(void) { const char *display_desc = NULL; struct vc_data *vc; - unsigned int currcons = 0, i; + unsigned int currcons = 0; acquire_console_sem(); @@ -2584,22 +2569,6 @@ static int __init con_init(void) return 0; } - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - struct con_driver *con_driver = ®istered_con_driver[i]; - - if (con_driver->con == NULL) { - con_driver->con = conswitchp; - con_driver->desc = display_desc; - con_driver->flag = CON_DRIVER_FLAG_INIT; - con_driver->first = 0; - con_driver->last = MAX_NR_CONSOLES - 1; - break; - } - } - - for (i = 0; i < MAX_NR_CONSOLES; i++) - con_driver_map[i] = conswitchp; - init_timer(&console_timer); console_timer.function = blank_screen_t; if (blankinterval) { @@ -2687,53 +2656,38 @@ int __init vty_init(void) } #ifndef VT_SINGLE_DRIVER -#include -static struct class *vtconsole_class; +/* + * If we support more console drivers, this function is used + * when a driver wants to take over some existing consoles + * and become default driver for newly opened ones. + */ -static int bind_con_driver(const struct consw *csw, int first, int last, - int deflt) +int take_over_console(const struct consw *csw, int first, int last, int deflt) { - struct module *owner = csw->owner; - const char *desc = NULL; - struct con_driver *con_driver; - int i, j = -1, k = -1, retval = -ENODEV; + int i, j = -1; + const char *desc; + struct module *owner; + owner = csw->owner; if (!try_module_get(owner)) return -ENODEV; acquire_console_sem(); - /* check if driver is registered */ - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - con_driver = ®istered_con_driver[i]; - - if (con_driver->con == csw) { - desc = con_driver->desc; - retval = 0; - break; - } - } - - if (retval) - goto err; - - if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) { - csw->con_startup(); - con_driver->flag |= CON_DRIVER_FLAG_INIT; + desc = csw->con_startup(); + if (!desc) { + release_console_sem(); + module_put(owner); + return -ENODEV; } - if (deflt) { if (conswitchp) module_put(conswitchp->owner); - __module_get(owner); conswitchp = csw; } - first = max(first, con_driver->first); - last = min(last, con_driver->last); - for (i = first; i <= last; i++) { int old_was_color; struct vc_data *vc = vc_cons[i].d; @@ -2747,17 +2701,15 @@ static int bind_con_driver(const struct consw *csw, int first, int last, continue; j = i; - - if (CON_IS_VISIBLE(vc)) { - k = i; + if (CON_IS_VISIBLE(vc)) save_screen(vc); - } - old_was_color = vc->vc_can_do_color; vc->vc_sw->con_deinit(vc); vc->vc_origin = (unsigned long)vc->vc_screenbuf; + vc->vc_visible_origin = vc->vc_origin; + vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size; + vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x; visual_init(vc, i, 0); - set_origin(vc); update_attr(vc); /* If the console changed between mono <-> color, then @@ -2766,506 +2718,36 @@ static int bind_con_driver(const struct consw *csw, int first, int last, */ if (old_was_color != vc->vc_can_do_color) clear_buffer_attributes(vc); - } + if (CON_IS_VISIBLE(vc)) + update_screen(vc); + } printk("Console: switching "); if (!deflt) printk("consoles %d-%d ", first+1, last+1); - if (j >= 0) { - struct vc_data *vc = vc_cons[j].d; - + if (j >= 0) printk("to %s %s %dx%d\n", - vc->vc_can_do_color ? "colour" : "mono", - desc, vc->vc_cols, vc->vc_rows); - - if (k >= 0) { - vc = vc_cons[k].d; - update_screen(vc); - } - } else + vc_cons[j].d->vc_can_do_color ? "colour" : "mono", + desc, vc_cons[j].d->vc_cols, vc_cons[j].d->vc_rows); + else printk("to %s\n", desc); - retval = 0; -err: release_console_sem(); - module_put(owner); - return retval; -}; - -#ifdef CONFIG_VT_HW_CONSOLE_BINDING -static int con_is_graphics(const struct consw *csw, int first, int last) -{ - int i, retval = 0; - - for (i = first; i <= last; i++) { - struct vc_data *vc = vc_cons[i].d; - - if (vc && vc->vc_mode == KD_GRAPHICS) { - retval = 1; - break; - } - } - - return retval; -} - -static int unbind_con_driver(const struct consw *csw, int first, int last, - int deflt) -{ - struct module *owner = csw->owner; - const struct consw *defcsw = NULL; - struct con_driver *con_driver = NULL, *con_back = NULL; - int i, retval = -ENODEV; - - if (!try_module_get(owner)) - return -ENODEV; - - acquire_console_sem(); - - /* check if driver is registered and if it is unbindable */ - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - con_driver = ®istered_con_driver[i]; - - if (con_driver->con == csw && - con_driver->flag & CON_DRIVER_FLAG_MODULE) { - retval = 0; - break; - } - } - - if (retval) { - release_console_sem(); - goto err; - } - - retval = -ENODEV; - - /* check if backup driver exists */ - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - con_back = ®istered_con_driver[i]; - - if (con_back->con && - !(con_back->flag & CON_DRIVER_FLAG_MODULE)) { - defcsw = con_back->con; - retval = 0; - break; - } - } - - if (retval) { - release_console_sem(); - goto err; - } - - if (!con_is_bound(csw)) { - release_console_sem(); - goto err; - } - - first = max(first, con_driver->first); - last = min(last, con_driver->last); - - for (i = first; i <= last; i++) { - if (con_driver_map[i] == csw) { - module_put(csw->owner); - con_driver_map[i] = NULL; - } - } - - if (!con_is_bound(defcsw)) { - const struct consw *defconsw = conswitchp; - - defcsw->con_startup(); - con_back->flag |= CON_DRIVER_FLAG_INIT; - /* - * vgacon may change the default driver to point - * to dummycon, we restore it here... - */ - conswitchp = defconsw; - } - - if (!con_is_bound(csw)) - con_driver->flag &= ~CON_DRIVER_FLAG_INIT; - release_console_sem(); - /* ignore return value, binding should not fail */ - bind_con_driver(defcsw, first, last, deflt); -err: module_put(owner); - return retval; - -} - -static int vt_bind(struct con_driver *con) -{ - const struct consw *defcsw = NULL, *csw = NULL; - int i, more = 1, first = -1, last = -1, deflt = 0; - - if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) || - con_is_graphics(con->con, con->first, con->last)) - goto err; - - csw = con->con; - - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - struct con_driver *con = ®istered_con_driver[i]; - - if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) { - defcsw = con->con; - break; - } - } - - if (!defcsw) - goto err; - - while (more) { - more = 0; - - for (i = con->first; i <= con->last; i++) { - if (con_driver_map[i] == defcsw) { - if (first == -1) - first = i; - last = i; - more = 1; - } else if (first != -1) - break; - } - - if (first == 0 && last == MAX_NR_CONSOLES -1) - deflt = 1; - - if (first != -1) - bind_con_driver(csw, first, last, deflt); - - first = -1; - last = -1; - deflt = 0; - } - -err: - return 0; -} - -static int vt_unbind(struct con_driver *con) -{ - const struct consw *csw = NULL; - int i, more = 1, first = -1, last = -1, deflt = 0; - - if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) || - con_is_graphics(con->con, con->first, con->last)) - goto err; - - csw = con->con; - - while (more) { - more = 0; - - for (i = con->first; i <= con->last; i++) { - if (con_driver_map[i] == csw) { - if (first == -1) - first = i; - last = i; - more = 1; - } else if (first != -1) - break; - } - - if (first == 0 && last == MAX_NR_CONSOLES -1) - deflt = 1; - - if (first != -1) - unbind_con_driver(csw, first, last, deflt); - - first = -1; - last = -1; - deflt = 0; - } - -err: - return 0; -} -#else -static inline int vt_bind(struct con_driver *con) -{ - return 0; -} -static inline int vt_unbind(struct con_driver *con) -{ - return 0; -} -#endif /* CONFIG_VT_HW_CONSOLE_BINDING */ - -static ssize_t store_bind(struct class_device *class_device, - const char *buf, size_t count) -{ - struct con_driver *con = class_get_devdata(class_device); - int bind = simple_strtoul(buf, NULL, 0); - - if (bind) - vt_bind(con); - else - vt_unbind(con); - - return count; -} - -static ssize_t show_bind(struct class_device *class_device, char *buf) -{ - struct con_driver *con = class_get_devdata(class_device); - int bind = con_is_bound(con->con); - - return snprintf(buf, PAGE_SIZE, "%i\n", bind); -} - -static ssize_t show_name(struct class_device *class_device, char *buf) -{ - struct con_driver *con = class_get_devdata(class_device); - - return snprintf(buf, PAGE_SIZE, "%s %s\n", - (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)", - con->desc); - -} - -static struct class_device_attribute class_device_attrs[] = { - __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind), - __ATTR(name, S_IRUGO, show_name, NULL), -}; - -static int vtconsole_init_class_device(struct con_driver *con) -{ - int i; - - class_set_devdata(con->class_dev, con); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(con->class_dev, - &class_device_attrs[i]); - return 0; } -static void vtconsole_deinit_class_device(struct con_driver *con) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(con->class_dev, - &class_device_attrs[i]); -} - -/** - * con_is_bound - checks if driver is bound to the console - * @csw: console driver - * - * RETURNS: zero if unbound, nonzero if bound - * - * Drivers can call this and if zero, they should release - * all resources allocated on con_startup() - */ -int con_is_bound(const struct consw *csw) -{ - int i, bound = 0; - - for (i = 0; i < MAX_NR_CONSOLES; i++) { - if (con_driver_map[i] == csw) { - bound = 1; - break; - } - } - - return bound; -} -EXPORT_SYMBOL(con_is_bound); - -/** - * register_con_driver - register console driver to console layer - * @csw: console driver - * @first: the first console to take over, minimum value is 0 - * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 - * - * DESCRIPTION: This function registers a console driver which can later - * bind to a range of consoles specified by @first and @last. It will - * also initialize the console driver by calling con_startup(). - */ -int register_con_driver(const struct consw *csw, int first, int last) -{ - struct module *owner = csw->owner; - struct con_driver *con_driver; - const char *desc; - int i, retval = 0; - - if (!try_module_get(owner)) - return -ENODEV; - - acquire_console_sem(); - - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - con_driver = ®istered_con_driver[i]; - - /* already registered */ - if (con_driver->con == csw) - retval = -EINVAL; - } - - if (retval) - goto err; - - desc = csw->con_startup(); - - if (!desc) - goto err; - - retval = -EINVAL; - - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - con_driver = ®istered_con_driver[i]; - - if (con_driver->con == NULL) { - con_driver->con = csw; - con_driver->desc = desc; - con_driver->node = i; - con_driver->flag = CON_DRIVER_FLAG_MODULE | - CON_DRIVER_FLAG_INIT; - con_driver->first = first; - con_driver->last = last; - retval = 0; - break; - } - } - - if (retval) - goto err; - - con_driver->class_dev = class_device_create(vtconsole_class, NULL, - MKDEV(0, con_driver->node), - NULL, "vtcon%i", - con_driver->node); - - if (IS_ERR(con_driver->class_dev)) { - printk(KERN_WARNING "Unable to create class_device for %s; " - "errno = %ld\n", con_driver->desc, - PTR_ERR(con_driver->class_dev)); - con_driver->class_dev = NULL; - } else { - vtconsole_init_class_device(con_driver); - } -err: - release_console_sem(); - module_put(owner); - return retval; -} -EXPORT_SYMBOL(register_con_driver); - -/** - * unregister_con_driver - unregister console driver from console layer - * @csw: console driver - * - * DESCRIPTION: All drivers that registers to the console layer must - * call this function upon exit, or if the console driver is in a state - * where it won't be able to handle console services, such as the - * framebuffer console without loaded framebuffer drivers. - * - * The driver must unbind first prior to unregistration. - */ -int unregister_con_driver(const struct consw *csw) -{ - int i, retval = -ENODEV; - - acquire_console_sem(); - - /* cannot unregister a bound driver */ - if (con_is_bound(csw)) - goto err; - - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - struct con_driver *con_driver = ®istered_con_driver[i]; - - if (con_driver->con == csw && - con_driver->flag & CON_DRIVER_FLAG_MODULE) { - vtconsole_deinit_class_device(con_driver); - class_device_destroy(vtconsole_class, - MKDEV(0, con_driver->node)); - con_driver->con = NULL; - con_driver->desc = NULL; - con_driver->class_dev = NULL; - con_driver->node = 0; - con_driver->flag = 0; - con_driver->first = 0; - con_driver->last = 0; - retval = 0; - break; - } - } -err: - release_console_sem(); - return retval; -} -EXPORT_SYMBOL(unregister_con_driver); - -/* - * If we support more console drivers, this function is used - * when a driver wants to take over some existing consoles - * and become default driver for newly opened ones. - * - * take_over_console is basically a register followed by unbind - */ -int take_over_console(const struct consw *csw, int first, int last, int deflt) -{ - int err; - - err = register_con_driver(csw, first, last); - - if (!err) - bind_con_driver(csw, first, last, deflt); - - return err; -} - -/* - * give_up_console is a wrapper to unregister_con_driver. It will only - * work if driver is fully unbound. - */ void give_up_console(const struct consw *csw) -{ - unregister_con_driver(csw); -} - -static int __init vtconsole_class_init(void) { int i; - vtconsole_class = class_create(THIS_MODULE, "vtconsole"); - if (IS_ERR(vtconsole_class)) { - printk(KERN_WARNING "Unable to create vt console class; " - "errno = %ld\n", PTR_ERR(vtconsole_class)); - vtconsole_class = NULL; - } - - /* Add system drivers to sysfs */ - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { - struct con_driver *con = ®istered_con_driver[i]; - - if (con->con && !con->class_dev) { - con->class_dev = - class_device_create(vtconsole_class, NULL, - MKDEV(0, con->node), NULL, - "vtcon%i", con->node); - - if (IS_ERR(con->class_dev)) { - printk(KERN_WARNING "Unable to create " - "class_device for %s; errno = %ld\n", - con->desc, PTR_ERR(con->class_dev)); - con->class_dev = NULL; - } else { - vtconsole_init_class_device(con); - } + for(i = 0; i < MAX_NR_CONSOLES; i++) + if (con_driver_map[i] == csw) { + module_put(csw->owner); + con_driver_map[i] = NULL; } - } - - return 0; } -postcore_initcall(vtconsole_class_init); #endif diff --git a/trunk/drivers/clocksource/Makefile b/trunk/drivers/clocksource/Makefile deleted file mode 100644 index a52225470225..000000000000 --- a/trunk/drivers/clocksource/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o -obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o -obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c deleted file mode 100644 index 7ad3be8c0f49..000000000000 --- a/trunk/drivers/clocksource/acpi_pm.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * linux/drivers/clocksource/acpi_pm.c - * - * This file contains the ACPI PM based clocksource. - * - * This code was largely moved from the i386 timer_pm.c file - * which was (C) Dominik Brodowski 2003 - * and contained the following comments: - * - * Driver to use the Power Management Timer (PMTMR) available in some - * southbridges as primary timing source for the Linux kernel. - * - * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, - * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. - * - * This file is licensed under the GPL v2. - */ - -#include -#include -#include -#include -#include - -/* Number of PMTMR ticks expected during calibration run */ -#define PMTMR_TICKS_PER_SEC 3579545 - -/* - * The I/O port the PMTMR resides at. - * The location is detected during setup_arch(), - * in arch/i386/acpi/boot.c - */ -u32 pmtmr_ioport __read_mostly; - -#define ACPI_PM_MASK CLOCKSOURCE_MASK(24) /* limit it to 24 bits */ - -static inline u32 read_pmtmr(void) -{ - /* mask the output to 24 bits */ - return inl(pmtmr_ioport) & ACPI_PM_MASK; -} - -static cycle_t acpi_pm_read_verified(void) -{ - u32 v1 = 0, v2 = 0, v3 = 0; - - /* - * It has been reported that because of various broken - * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM clock - * source is not latched, you must read it multiple - * times to ensure a safe value is read: - */ - do { - v1 = read_pmtmr(); - v2 = read_pmtmr(); - v3 = read_pmtmr(); - } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2)); - - return (cycle_t)v2; -} - -static cycle_t acpi_pm_read(void) -{ - return (cycle_t)read_pmtmr(); -} - -static struct clocksource clocksource_acpi_pm = { - .name = "acpi_pm", - .rating = 200, - .read = acpi_pm_read, - .mask = (cycle_t)ACPI_PM_MASK, - .mult = 0, /*to be caluclated*/ - .shift = 22, - .is_continuous = 1, -}; - - -#ifdef CONFIG_PCI -static int acpi_pm_good; -static int __init acpi_pm_good_setup(char *__str) -{ - acpi_pm_good = 1; - return 1; -} -__setup("acpi_pm_good", acpi_pm_good_setup); - -static inline void acpi_pm_need_workaround(void) -{ - clocksource_acpi_pm.read = acpi_pm_read_verified; - clocksource_acpi_pm.rating = 110; -} - -/* - * PIIX4 Errata: - * - * The power management timer may return improper results when read. - * Although the timer value settles properly after incrementing, - * while incrementing there is a 3 ns window every 69.8 ns where the - * timer value is indeterminate (a 4.2% chance that the data will be - * incorrect when read). As a result, the ACPI free running count up - * timer specification is violated due to erroneous reads. - */ -static void __devinit acpi_pm_check_blacklist(struct pci_dev *dev) -{ - u8 rev; - - if (acpi_pm_good) - return; - - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - /* the bug has been fixed in PIIX4M */ - if (rev < 3) { - printk(KERN_WARNING "* Found PM-Timer Bug on the chipset." - " Due to workarounds for a bug,\n" - "* this clock source is slow. Consider trying" - " other clock sources\n"); - - acpi_pm_need_workaround(); - } -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - acpi_pm_check_blacklist); - -static void __devinit acpi_pm_check_graylist(struct pci_dev *dev) -{ - if (acpi_pm_good) - return; - - printk(KERN_WARNING "* The chipset may have PM-Timer Bug. Due to" - " workarounds for a bug,\n" - "* this clock source is slow. If you are sure your timer" - " does not have\n" - "* this bug, please use \"acpi_pm_good\" to disable the" - " workaround\n"); - - acpi_pm_need_workaround(); -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, - acpi_pm_check_graylist); -#endif - - -static int __init init_acpi_pm_clocksource(void) -{ - u32 value1, value2; - unsigned int i; - - if (!pmtmr_ioport) - return -ENODEV; - - clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, - clocksource_acpi_pm.shift); - - /* "verify" this timing source: */ - value1 = read_pmtmr(); - for (i = 0; i < 10000; i++) { - value2 = read_pmtmr(); - if (value2 == value1) - continue; - if (value2 > value1) - goto pm_good; - if ((value2 < value1) && ((value2) < 0xFFF)) - goto pm_good; - printk(KERN_INFO "PM-Timer had inconsistent results:" - " 0x%#x, 0x%#x - aborting.\n", value1, value2); - return -EINVAL; - } - printk(KERN_INFO "PM-Timer had no reasonable result:" - " 0x%#x - aborting.\n", value1); - return -ENODEV; - -pm_good: - return clocksource_register(&clocksource_acpi_pm); -} - -module_init(init_acpi_pm_clocksource); diff --git a/trunk/drivers/clocksource/cyclone.c b/trunk/drivers/clocksource/cyclone.c deleted file mode 100644 index bf4d3d50d1c4..000000000000 --- a/trunk/drivers/clocksource/cyclone.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "mach_timer.h" - -#define CYCLONE_CBAR_ADDR 0xFEB00CD0 /* base address ptr */ -#define CYCLONE_PMCC_OFFSET 0x51A0 /* offset to control register */ -#define CYCLONE_MPCS_OFFSET 0x51A8 /* offset to select register */ -#define CYCLONE_MPMC_OFFSET 0x51D0 /* offset to count register */ -#define CYCLONE_TIMER_FREQ 99780000 /* 100Mhz, but not really */ -#define CYCLONE_TIMER_MASK CLOCKSOURCE_MASK(32) /* 32 bit mask */ - -int use_cyclone = 0; -static void __iomem *cyclone_ptr; - -static cycle_t read_cyclone(void) -{ - return (cycle_t)readl(cyclone_ptr); -} - -static struct clocksource clocksource_cyclone = { - .name = "cyclone", - .rating = 250, - .read = read_cyclone, - .mask = CYCLONE_TIMER_MASK, - .mult = 10, - .shift = 0, - .is_continuous = 1, -}; - -static int __init init_cyclone_clocksource(void) -{ - unsigned long base; /* saved value from CBAR */ - unsigned long offset; - u32 __iomem* volatile cyclone_timer; /* Cyclone MPMC0 register */ - u32 __iomem* reg; - int i; - - /* make sure we're on a summit box: */ - if (!use_cyclone) - return -ENODEV; - - printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); - - /* find base address: */ - offset = CYCLONE_CBAR_ADDR; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); - return -ENODEV; - } - /* even on 64bit systems, this is only 32bits: */ - base = readl(reg); - if (!base) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); - return -ENODEV; - } - iounmap(reg); - - /* setup PMCC: */ - offset = base + CYCLONE_PMCC_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* setup MPCS: */ - offset = base + CYCLONE_MPCS_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* map in cyclone_timer: */ - offset = base + CYCLONE_MPMC_OFFSET; - cyclone_timer = ioremap_nocache(offset, sizeof(u64)); - if (!cyclone_timer) { - printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); - return -ENODEV; - } - - /* quick test to make sure its ticking: */ - for (i = 0; i < 3; i++){ - u32 old = readl(cyclone_timer); - int stall = 100; - - while (stall--) - barrier(); - - if (readl(cyclone_timer) == old) { - printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); - iounmap(cyclone_timer); - cyclone_timer = NULL; - return -ENODEV; - } - } - cyclone_ptr = cyclone_timer; - - /* sort out mult/shift values: */ - clocksource_cyclone.shift = 22; - clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ, - clocksource_cyclone.shift); - - return clocksource_register(&clocksource_cyclone); -} - -module_init(init_cyclone_clocksource); diff --git a/trunk/drivers/clocksource/scx200_hrt.c b/trunk/drivers/clocksource/scx200_hrt.c deleted file mode 100644 index d418b8297211..000000000000 --- a/trunk/drivers/clocksource/scx200_hrt.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2006 Jim Cromie - * - * This is a clocksource driver for the Geode SCx200's 1 or 27 MHz - * high-resolution timer. The Geode SC-1100 (at least) has a buggy - * time stamp counter (TSC), which loses time unless 'idle=poll' is - * given as a boot-arg. In its absence, the Generic Timekeeping code - * will detect and de-rate the bad TSC, allowing this timer to take - * over timekeeping duties. - * - * Based on work by John Stultz, and Ted Phelps (in a 2.6.12-rc6 patch) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#define NAME "scx200_hrt" - -static int mhz27; -module_param(mhz27, int, 0); /* load time only */ -MODULE_PARM_DESC(mhz27, "count at 27.0 MHz (default is 1.0 MHz)"); - -static int ppm; -module_param(ppm, int, 0); /* load time only */ -MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)"); - -/* HiRes Timer configuration register address */ -#define SCx200_TMCNFG_OFFSET (SCx200_TIMER_OFFSET + 5) - -/* and config settings */ -#define HR_TMEN (1 << 0) /* timer interrupt enable */ -#define HR_TMCLKSEL (1 << 1) /* 1|0 counts at 27|1 MHz */ -#define HR_TM27MPD (1 << 2) /* 1 turns off input clock (power-down) */ - -/* The base timer frequency, * 27 if selected */ -#define HRT_FREQ 1000000 - -static cycle_t read_hrt(void) -{ - /* Read the timer value */ - return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); -} - -#define HRT_SHIFT_1 22 -#define HRT_SHIFT_27 26 - -static struct clocksource cs_hrt = { - .name = "scx200_hrt", - .rating = 250, - .read = read_hrt, - .mask = CLOCKSOURCE_MASK(32), - .is_continuous = 1, - /* mult, shift are set based on mhz27 flag */ -}; - -static int __init init_hrt_clocksource(void) -{ - /* Make sure scx200 has initializedd the configuration block */ - if (!scx200_cb_present()) - return -ENODEV; - - /* Reserve the timer's ISA io-region for ourselves */ - if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET, - SCx200_TIMER_SIZE, - "NatSemi SCx200 High-Resolution Timer")) { - printk(KERN_WARNING NAME ": unable to lock timer region\n"); - return -ENODEV; - } - - /* write timer config */ - outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0, - scx200_cb_base + SCx200_TMCNFG_OFFSET); - - if (mhz27) { - cs_hrt.shift = HRT_SHIFT_27; - cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27, - cs_hrt.shift); - } else { - cs_hrt.shift = HRT_SHIFT_1; - cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm, - cs_hrt.shift); - } - printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n", - mhz27 ? "27":"1", ppm); - - return clocksource_register(&cs_hrt); -} - -module_init(init_hrt_clocksource); - -MODULE_AUTHOR("Jim Cromie "); -MODULE_DESCRIPTION("clocksource on SCx200 HiRes Timer"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index 498aa37bca22..4b4d7db1ff7b 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c index b49bacfd8de8..79d581c86520 100644 --- a/trunk/drivers/connector/connector.c +++ b/trunk/drivers/connector/connector.c @@ -121,7 +121,6 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) kfree_skb(skb); return -EINVAL; } -EXPORT_SYMBOL_GPL(cn_netlink_send); /* * Callback helper - queues work and setup destructor for given data. @@ -320,7 +319,6 @@ int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *)) return 0; } -EXPORT_SYMBOL_GPL(cn_add_callback); /* * Callback remove routing - removes callback @@ -337,7 +335,6 @@ void cn_del_callback(struct cb_id *id) cn_queue_del_callback(dev->cbdev, id); cn_notify(id, 1); } -EXPORT_SYMBOL_GPL(cn_del_callback); /* * Checks two connector's control messages to be the same. @@ -491,3 +488,7 @@ static void __devexit cn_fini(void) subsys_initcall(cn_init); module_exit(cn_fini); + +EXPORT_SYMBOL_GPL(cn_add_callback); +EXPORT_SYMBOL_GPL(cn_del_callback); +EXPORT_SYMBOL_GPL(cn_netlink_send); diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 35e0b9ceecf7..44d1eca83a72 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -1497,7 +1497,6 @@ int cpufreq_update_policy(unsigned int cpu) } EXPORT_SYMBOL(cpufreq_update_policy); -#ifdef CONFIG_HOTPLUG_CPU static int cpufreq_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -1533,11 +1532,10 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = +static struct notifier_block cpufreq_cpu_notifier = { .notifier_call = cpufreq_cpu_callback, }; -#endif /* CONFIG_HOTPLUG_CPU */ /********************************************************************* * REGISTER / UNREGISTER CPUFREQ DRIVER * @@ -1598,7 +1596,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) } if (!ret) { - register_hotcpu_notifier(&cpufreq_cpu_notifier); + register_cpu_notifier(&cpufreq_cpu_notifier); dprintk("driver %s up and running\n", driver_data->name); cpufreq_debug_enable_ratelimit(); } @@ -1630,7 +1628,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) dprintk("unregistering driver %s\n", driver->name); sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); - unregister_hotcpu_notifier(&cpufreq_cpu_notifier); + unregister_cpu_notifier(&cpufreq_cpu_notifier); spin_lock_irqsave(&cpufreq_driver_lock, flags); cpufreq_driver = NULL; diff --git a/trunk/drivers/cpufreq/cpufreq_conservative.c b/trunk/drivers/cpufreq/cpufreq_conservative.c index b3ebc8f01975..e07a35487bde 100644 --- a/trunk/drivers/cpufreq/cpufreq_conservative.c +++ b/trunk/drivers/cpufreq/cpufreq_conservative.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -73,14 +72,6 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); static unsigned int dbs_enable; /* number of CPUs using this policy */ -/* - * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug - * lock and dbs_mutex. cpu_hotplug lock should always be held before - * dbs_mutex. If any function that can potentially take cpu_hotplug lock - * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then - * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock - * is recursive for the same process. -Venki - */ static DEFINE_MUTEX (dbs_mutex); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); @@ -423,14 +414,12 @@ static void dbs_check_cpu(int cpu) static void do_dbs_timer(void *data) { int i; - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); for_each_online_cpu(i) dbs_check_cpu(i); schedule_delayed_work(&dbs_work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); } static inline void dbs_timer_init(void) @@ -525,7 +514,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target( @@ -536,7 +524,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); break; } return 0; diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index 693e540481b4..3e6ffcaa5af4 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -72,14 +71,6 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); static unsigned int dbs_enable; /* number of CPUs using this policy */ -/* - * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug - * lock and dbs_mutex. cpu_hotplug lock should always be held before - * dbs_mutex. If any function that can potentially take cpu_hotplug lock - * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then - * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock - * is recursive for the same process. -Venki - */ static DEFINE_MUTEX (dbs_mutex); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); @@ -372,14 +363,12 @@ static void dbs_check_cpu(int cpu) static void do_dbs_timer(void *data) { int i; - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); for_each_online_cpu(i) dbs_check_cpu(i); queue_delayed_work(dbs_workq, &dbs_work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); } static inline void dbs_timer_init(void) @@ -480,7 +469,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target( @@ -491,7 +479,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); break; } return 0; diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index 145061b8472a..c576c0b3f452 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -350,7 +350,7 @@ __init cpufreq_stats_init(void) return ret; } - register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + register_cpu_notifier(&cpufreq_stat_cpu_notifier); lock_cpu_hotplug(); for_each_online_cpu(cpu) { cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE, @@ -368,7 +368,7 @@ __exit cpufreq_stats_exit(void) CPUFREQ_POLICY_NOTIFIER); cpufreq_unregister_notifier(¬ifier_trans_block, CPUFREQ_TRANSITION_NOTIFIER); - unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + unregister_cpu_notifier(&cpufreq_stat_cpu_notifier); lock_cpu_hotplug(); for_each_online_cpu(cpu) { cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD, diff --git a/trunk/drivers/crypto/padlock-aes.c b/trunk/drivers/crypto/padlock-aes.c index 17ee684144f9..5158a9db4bc5 100644 --- a/trunk/drivers/crypto/padlock-aes.c +++ b/trunk/drivers/crypto/padlock-aes.c @@ -60,14 +60,15 @@ #define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) struct aes_ctx { + uint32_t e_data[AES_EXTENDED_KEY_SIZE]; + uint32_t d_data[AES_EXTENDED_KEY_SIZE]; struct { struct cword encrypt; struct cword decrypt; } cword; - u32 *D; + uint32_t *E; + uint32_t *D; int key_length; - u32 E[AES_EXTENDED_KEY_SIZE]; - u32 d_data[AES_EXTENDED_KEY_SIZE]; }; /* ====== Key management routines ====== */ @@ -281,20 +282,19 @@ aes_hw_extkey_available(uint8_t key_len) return 0; } -static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) +static inline struct aes_ctx *aes_ctx(void *ctx) { - unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm); unsigned long align = PADLOCK_ALIGNMENT; if (align <= crypto_tfm_ctx_alignment()) align = 1; - return (struct aes_ctx *)ALIGN(addr, align); + return (struct aes_ctx *)ALIGN((unsigned long)ctx, align); } -static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len, u32 *flags) +static int +aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags) { - struct aes_ctx *ctx = aes_ctx(tfm); + struct aes_ctx *ctx = aes_ctx(ctx_arg); const __le32 *key = (const __le32 *)in_key; uint32_t i, t, u, v, w; uint32_t P[AES_EXTENDED_KEY_SIZE]; @@ -312,7 +312,8 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, * itself we must supply the plain key for both encryption * and decryption. */ - ctx->D = ctx->E; + ctx->E = ctx->e_data; + ctx->D = ctx->e_data; E_KEY[0] = le32_to_cpu(key[0]); E_KEY[1] = le32_to_cpu(key[1]); @@ -413,22 +414,24 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, return iv; } -static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void +aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - struct aes_ctx *ctx = aes_ctx(tfm); + struct aes_ctx *ctx = aes_ctx(ctx_arg); padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1); } -static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +static void +aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - struct aes_ctx *ctx = aes_ctx(tfm); + struct aes_ctx *ctx = aes_ctx(ctx_arg); padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); } static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { - struct aes_ctx *ctx = aes_ctx(desc->tfm); + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE); return nbytes & ~(AES_BLOCK_SIZE - 1); @@ -437,7 +440,7 @@ static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { - struct aes_ctx *ctx = aes_ctx(desc->tfm); + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, nbytes / AES_BLOCK_SIZE); return nbytes & ~(AES_BLOCK_SIZE - 1); @@ -446,7 +449,7 @@ static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { - struct aes_ctx *ctx = aes_ctx(desc->tfm); + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); u8 *iv; iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info, @@ -459,7 +462,7 @@ static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { - struct aes_ctx *ctx = aes_ctx(desc->tfm); + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt, nbytes / AES_BLOCK_SIZE); return nbytes & ~(AES_BLOCK_SIZE - 1); diff --git a/trunk/drivers/dma/ioatdma.c b/trunk/drivers/dma/ioatdma.c index 2801d14a5e42..0fdf7fbd6495 100644 --- a/trunk/drivers/dma/ioatdma.c +++ b/trunk/drivers/dma/ioatdma.c @@ -824,9 +824,10 @@ static int __init ioat_init_module(void) { /* it's currently unsafe to unload this module */ /* if forced, worst case is that rmmod hangs */ - __unsafe(THIS_MODULE); + if (THIS_MODULE != NULL) + THIS_MODULE->unsafe = 1; - pci_module_init(&ioat_pci_drv); + return pci_module_init(&ioat_pci_drv); } module_init(ioat_init_module); diff --git a/trunk/drivers/firmware/Kconfig b/trunk/drivers/firmware/Kconfig index 731c3d5da0dc..1e371a510dd2 100644 --- a/trunk/drivers/firmware/Kconfig +++ b/trunk/drivers/firmware/Kconfig @@ -6,7 +6,8 @@ menu "Firmware Drivers" config EDD - tristate "BIOS Enhanced Disk Drive calls determine boot disk" + tristate "BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)" + depends on EXPERIMENTAL depends on !IA64 help Say Y or M here if you want to enable BIOS Enhanced Disk Drive diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index b9e3886d9e16..948bd7e1445a 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -255,15 +255,10 @@ void __init dmi_scan_machine(void) /** * dmi_check_system - check system DMI data * @list: array of dmi_system_id structures to match against - * All non-null elements of the list must match - * their slot's (field index's) data (i.e., each - * list string must be a substring of the specified - * DMI slot's string data) to be considered a - * successful match. * * Walk the blacklist table running matching functions until someone * returns non zero or we hit the end. Callback function is called for - * each successful match. Returns the number of matches. + * each successfull match. Returns the number of matches. */ int dmi_check_system(struct dmi_system_id *list) { @@ -292,7 +287,7 @@ EXPORT_SYMBOL(dmi_check_system); /** * dmi_get_system_info - return DMI data value - * @field: data index (see enum dmi_field) + * @field: data index (see enum dmi_filed) * * Returns one DMI data value, can be used to perform * complex DMI data checks. @@ -306,13 +301,13 @@ EXPORT_SYMBOL(dmi_get_system_info); /** * dmi_find_device - find onboard device by type/name * @type: device type or %DMI_DEV_TYPE_ANY to match all device types - * @name: device name string or %NULL to match all + * @desc: device name string or %NULL to match all * @from: previous device found in search, or %NULL for new search. * * Iterates through the list of known onboard devices. If a device is * found with a matching @vendor and @device, a pointer to its device * structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. + * A new search is initiated by passing %NULL to the @from argument. * If @from is not %NULL, searches continue from next device. */ struct dmi_device * dmi_find_device(int type, const char *name, diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 0e31a0c496e8..99cdc612d2c6 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -1,5 +1,5 @@ # -# Hardware monitoring chip drivers configuration +# I2C Sensor chip drivers configuration # menu "Hardware Monitoring support" @@ -16,10 +16,6 @@ config HWMON should say Y here and also to the specific driver(s) for your sensors chip(s) below. - To find out which specific driver(s) you need, use the - sensors-detect script from the lm_sensors package. Read - for details. - This support can also be built as a module. If so, the module will be called hwmon. @@ -27,18 +23,6 @@ config HWMON_VID tristate default n -config SENSORS_ABITUGURU - tristate "Abit uGuru" - depends on HWMON && EXPERIMENTAL - help - If you say yes here you get support for the Abit uGuru chips - sensor part. The voltage and frequency control parts of the Abit - uGuru are not supported. The Abit uGuru chip can be found on Abit - uGuru featuring motherboards (most modern Abit motherboards). - - This driver can also be built as a module. If so, the module - will be called abituguru. - config SENSORS_ADM1021 tristate "Analog Devices ADM1021 and compatibles" depends on HWMON && I2C @@ -204,16 +188,6 @@ config SENSORS_LM63 This driver can also be built as a module. If so, the module will be called lm63. -config SENSORS_LM70 - tristate "National Semiconductor LM70" - depends on HWMON && SPI_MASTER && EXPERIMENTAL - help - If you say yes here you get support for the National Semiconductor - LM70 digital temperature sensor chip. - - This driver can also be built as a module. If so, the module - will be called lm70. - config SENSORS_LM75 tristate "National Semiconductor LM75 and compatibles" depends on HWMON && I2C @@ -262,11 +236,11 @@ config SENSORS_LM80 will be called lm80. config SENSORS_LM83 - tristate "National Semiconductor LM83 and compatibles" + tristate "National Semiconductor LM83" depends on HWMON && I2C help If you say yes here you get support for National Semiconductor - LM82 and LM83 sensor chips. + LM83 sensor chips. This driver can also be built as a module. If so, the module will be called lm83. @@ -359,32 +333,11 @@ config SENSORS_SMSC47M1 help If you say yes here you get support for the integrated fan monitoring and control capabilities of the SMSC LPC47B27x, - LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and - LPC47M997 chips. - - The temperature and voltage sensor features of the LPC47M192 - and LPC47M997 are supported by another driver, select also - "SMSC LPC47M192 and compatibles" below for those. + LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. This driver can also be built as a module. If so, the module will be called smsc47m1. -config SENSORS_SMSC47M192 - tristate "SMSC LPC47M192 and compatibles" - depends on HWMON && I2C && EXPERIMENTAL - select HWMON_VID - help - If you say yes here you get support for the temperature and - voltage sensors of the SMSC LPC47M192 and LPC47M997 chips. - - The fan monitoring and control capabilities of these chips - are supported by another driver, select - "SMSC LPC47M10x and compatibles" above. You need both drivers - if you want fan control and voltage/temperature sensor support. - - This driver can also be built as a module. If so, the module - will be called smsc47m192. - config SENSORS_SMSC47B397 tristate "SMSC LPC47B397-NC" depends on HWMON && I2C && EXPERIMENTAL @@ -432,16 +385,6 @@ config SENSORS_W83781D This driver can also be built as a module. If so, the module will be called w83781d. -config SENSORS_W83791D - tristate "Winbond W83791D" - depends on HWMON && I2C && EXPERIMENTAL - select HWMON_VID - help - If you say yes here you get support for the Winbond W83791D chip. - - This driver can also be built as a module. If so, the module - will be called w83791d. - config SENSORS_W83792D tristate "Winbond W83792D" depends on HWMON && I2C && EXPERIMENTAL diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index 31415843a91a..fbdb8d911a72 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -10,9 +10,7 @@ obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83781D) += w83781d.o -obj-$(CONFIG_SENSORS_W83791D) += w83791d.o -obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o @@ -28,7 +26,6 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_LM63) += lm63.o -obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM75) += lm75.o obj-$(CONFIG_SENSORS_LM77) += lm77.o obj-$(CONFIG_SENSORS_LM78) += lm78.o @@ -43,7 +40,6 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o -obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o diff --git a/trunk/drivers/hwmon/abituguru.c b/trunk/drivers/hwmon/abituguru.c deleted file mode 100644 index 59122cc0a50a..000000000000 --- a/trunk/drivers/hwmon/abituguru.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* - abituguru.c Copyright (c) 2005-2006 Hans de Goede - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - This driver supports the sensor part of the custom Abit uGuru chip found - on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM / - etc voltage & frequency control is not supported! -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Banks */ -#define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ -#define ABIT_UGURU_SENSOR_BANK1 0x21 /* 16x volt and temp */ -#define ABIT_UGURU_FAN_PWM 0x24 /* 3x 5 bytes */ -#define ABIT_UGURU_SENSOR_BANK2 0x26 /* fans */ -/* max nr of sensors in bank1, a bank1 sensor can be in, temp or nc */ -#define ABIT_UGURU_MAX_BANK1_SENSORS 16 -/* Warning if you increase one of the 2 MAX defines below to 10 or higher you - should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! */ -/* max nr of sensors in bank2, currently mb's with max 6 fans are known */ -#define ABIT_UGURU_MAX_BANK2_SENSORS 6 -/* max nr of pwm outputs, currently mb's with max 5 pwm outputs are known */ -#define ABIT_UGURU_MAX_PWMS 5 -/* uGuru sensor bank 1 flags */ /* Alarm if: */ -#define ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */ -#define ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */ -#define ABIT_UGURU_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */ -#define ABIT_UGURU_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */ -#define ABIT_UGURU_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */ -#define ABIT_UGURU_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */ -/* uGuru sensor bank 2 flags */ /* Alarm if: */ -#define ABIT_UGURU_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */ -/* uGuru sensor bank common flags */ -#define ABIT_UGURU_BEEP_ENABLE 0x08 /* beep if alarm */ -#define ABIT_UGURU_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */ -/* uGuru fan PWM (speed control) flags */ -#define ABIT_UGURU_FAN_PWM_ENABLE 0x80 /* enable speed control */ -/* Values used for conversion */ -#define ABIT_UGURU_FAN_MAX 15300 /* RPM */ -/* Bank1 sensor types */ -#define ABIT_UGURU_IN_SENSOR 0 -#define ABIT_UGURU_TEMP_SENSOR 1 -#define ABIT_UGURU_NC 2 -/* Timeouts / Retries, if these turn out to need a lot of fiddling we could - convert them to params. */ -/* 250 was determined by trial and error, 200 works most of the time, but not - always. I assume this is cpu-speed independent, since the ISA-bus and not - the CPU should be the bottleneck. Note that 250 sometimes is still not - enough (only reported on AN7 mb) this is handled by a higher layer. */ -#define ABIT_UGURU_WAIT_TIMEOUT 250 -/* Normally all expected status in abituguru_ready, are reported after the - first read, but sometimes not and we need to poll, 5 polls was not enough - 50 sofar is. */ -#define ABIT_UGURU_READY_TIMEOUT 50 -/* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ -#define ABIT_UGURU_MAX_RETRIES 3 -#define ABIT_UGURU_RETRY_DELAY (HZ/5) -/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is an error */ -#define ABIT_UGURU_MAX_TIMEOUTS 2 -/* utility macros */ -#define ABIT_UGURU_NAME "abituguru" -#define ABIT_UGURU_DEBUG(level, format, arg...) \ - if (level <= verbose) \ - printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) -/* Macros to help calculate the sysfs_names array length */ -/* sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, - in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 */ -#define ABITUGURU_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14) -/* sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0, - temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 */ -#define ABITUGURU_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16) -/* sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0, - fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 */ -#define ABITUGURU_FAN_NAMES_LENGTH (11 + 9 + 11 + 18 + 10 + 14) -/* sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0, - pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 */ -#define ABITUGURU_PWM_NAMES_LENGTH (12 + 24 + 2 * 21 + 2 * 22) -/* IN_NAMES_LENGTH > TEMP_NAMES_LENGTH so assume all bank1 sensors are in */ -#define ABITUGURU_SYSFS_NAMES_LENGTH ( \ - ABIT_UGURU_MAX_BANK1_SENSORS * ABITUGURU_IN_NAMES_LENGTH + \ - ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \ - ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH) - -/* All the macros below are named identical to the oguru and oguru2 programs - reverse engineered by Olle Sandberg, hence the names might not be 100% - logical. I could come up with better names, but I prefer keeping the names - identical so that this driver can be compared with his work more easily. */ -/* Two i/o-ports are used by uGuru */ -#define ABIT_UGURU_BASE 0x00E0 -/* Used to tell uGuru what to read and to read the actual data */ -#define ABIT_UGURU_CMD 0x00 -/* Mostly used to check if uGuru is busy */ -#define ABIT_UGURU_DATA 0x04 -#define ABIT_UGURU_REGION_LENGTH 5 -/* uGuru status' */ -#define ABIT_UGURU_STATUS_WRITE 0x00 /* Ready to be written */ -#define ABIT_UGURU_STATUS_READ 0x01 /* Ready to be read */ -#define ABIT_UGURU_STATUS_INPUT 0x08 /* More input */ -#define ABIT_UGURU_STATUS_READY 0x09 /* Ready to be written */ - -/* Constants */ -/* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */ -static const int abituguru_bank1_max_value[2] = { 3494, 255000 }; -/* Min / Max allowed values for sensor2 (fan) alarm threshold, these values - correspond to 300-3000 RPM */ -static const u8 abituguru_bank2_min_threshold = 5; -static const u8 abituguru_bank2_max_threshold = 50; -/* Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4 - are temperature trip points. */ -static const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 }; -/* Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a - special case the minium allowed pwm% setting for this is 30% (77) on - some MB's this special case is handled in the code! */ -static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 }; -static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 }; - - -/* Insmod parameters */ -static int force; -module_param(force, bool, 0); -MODULE_PARM_DESC(force, "Set to one to force detection."); -static int fan_sensors; -module_param(fan_sensors, int, 0); -MODULE_PARM_DESC(fan_sensors, "Number of fan sensors on the uGuru " - "(0 = autodetect)"); -static int pwms; -module_param(pwms, int, 0); -MODULE_PARM_DESC(pwms, "Number of PWMs on the uGuru " - "(0 = autodetect)"); - -/* Default verbose is 2, since this driver is still in the testing phase */ -static int verbose = 2; -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" - " 0 normal output\n" - " 1 + verbose error reporting\n" - " 2 + sensors type probing info\n" - " 3 + retryable error reporting"); - - -/* For the Abit uGuru, we need to keep some data in memory. - The structure is dynamically allocated, at the same time when a new - abituguru device is allocated. */ -struct abituguru_data { - struct class_device *class_dev; /* hwmon registered device */ - struct mutex update_lock; /* protect access to data and uGuru */ - unsigned long last_updated; /* In jiffies */ - unsigned short addr; /* uguru base address */ - char uguru_ready; /* is the uguru in ready state? */ - unsigned char update_timeouts; /* number of update timeouts since last - successful update */ - - /* The sysfs attr and their names are generated automatically, for bank1 - we cannot use a predefined array because we don't know beforehand - of a sensor is a volt or a temp sensor, for bank2 and the pwms its - easier todo things the same way. For in sensors we have 9 (temp 7) - sysfs entries per sensor, for bank2 and pwms 6. */ - struct sensor_device_attribute_2 sysfs_attr[ - ABIT_UGURU_MAX_BANK1_SENSORS * 9 + - ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6]; - /* Buffer to store the dynamically generated sysfs names */ - char sysfs_names[ABITUGURU_SYSFS_NAMES_LENGTH]; - - /* Bank 1 data */ - /* number of and addresses of [0] in, [1] temp sensors */ - u8 bank1_sensors[2]; - u8 bank1_address[2][ABIT_UGURU_MAX_BANK1_SENSORS]; - u8 bank1_value[ABIT_UGURU_MAX_BANK1_SENSORS]; - /* This array holds 3 entries per sensor for the bank 1 sensor settings - (flags, min, max for voltage / flags, warn, shutdown for temp). */ - u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3]; - /* Maximum value for each sensor used for scaling in mV/millidegrees - Celsius. */ - int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS]; - - /* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */ - u8 bank2_sensors; /* actual number of bank2 sensors found */ - u8 bank2_value[ABIT_UGURU_MAX_BANK2_SENSORS]; - u8 bank2_settings[ABIT_UGURU_MAX_BANK2_SENSORS][2]; /* flags, min */ - - /* Alarms 2 bytes for bank1, 1 byte for bank2 */ - u8 alarms[3]; - - /* Fan PWM (speed control) 5 bytes per PWM */ - u8 pwms; /* actual number of pwms found */ - u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5]; -}; - -/* wait till the uguru is in the specified state */ -static int abituguru_wait(struct abituguru_data *data, u8 state) -{ - int timeout = ABIT_UGURU_WAIT_TIMEOUT; - - while (inb_p(data->addr + ABIT_UGURU_DATA) != state) { - timeout--; - if (timeout == 0) - return -EBUSY; - } - return 0; -} - -/* Put the uguru in ready for input state */ -static int abituguru_ready(struct abituguru_data *data) -{ - int timeout = ABIT_UGURU_READY_TIMEOUT; - - if (data->uguru_ready) - return 0; - - /* Reset? / Prepare for next read/write cycle */ - outb(0x00, data->addr + ABIT_UGURU_DATA); - - /* Wait till the uguru is ready */ - if (abituguru_wait(data, ABIT_UGURU_STATUS_READY)) { - ABIT_UGURU_DEBUG(1, - "timeout exceeded waiting for ready state\n"); - return -EIO; - } - - /* Cmd port MUST be read now and should contain 0xAC */ - while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { - timeout--; - if (timeout == 0) { - ABIT_UGURU_DEBUG(1, - "CMD reg does not hold 0xAC after ready command\n"); - return -EIO; - } - } - - /* After this the ABIT_UGURU_DATA port should contain - ABIT_UGURU_STATUS_INPUT */ - timeout = ABIT_UGURU_READY_TIMEOUT; - while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) { - timeout--; - if (timeout == 0) { - ABIT_UGURU_DEBUG(1, - "state != more input after ready command\n"); - return -EIO; - } - } - - data->uguru_ready = 1; - return 0; -} - -/* Send the bank and then sensor address to the uGuru for the next read/write - cycle. This function gets called as the first part of a read/write by - abituguru_read and abituguru_write. This function should never be - called by any other function. */ -static int abituguru_send_address(struct abituguru_data *data, - u8 bank_addr, u8 sensor_addr, int retries) -{ - /* assume the caller does error handling itself if it has not requested - any retries, and thus be quiet. */ - int report_errors = retries; - - for (;;) { - /* Make sure the uguru is ready and then send the bank address, - after this the uguru is no longer "ready". */ - if (abituguru_ready(data) != 0) - return -EIO; - outb(bank_addr, data->addr + ABIT_UGURU_DATA); - data->uguru_ready = 0; - - /* Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again - and send the sensor addr */ - if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) { - if (retries) { - ABIT_UGURU_DEBUG(3, "timeout exceeded " - "waiting for more input state, %d " - "tries remaining\n", retries); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(ABIT_UGURU_RETRY_DELAY); - retries--; - continue; - } - if (report_errors) - ABIT_UGURU_DEBUG(1, "timeout exceeded " - "waiting for more input state " - "(bank: %d)\n", (int)bank_addr); - return -EBUSY; - } - outb(sensor_addr, data->addr + ABIT_UGURU_CMD); - return 0; - } -} - -/* Read count bytes from sensor sensor_addr in bank bank_addr and store the - result in buf, retry the send address part of the read retries times. */ -static int abituguru_read(struct abituguru_data *data, - u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries) -{ - int i; - - /* Send the address */ - i = abituguru_send_address(data, bank_addr, sensor_addr, retries); - if (i) - return i; - - /* And read the data */ - for (i = 0; i < count; i++) { - if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { - ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " - "read state (bank: %d, sensor: %d)\n", - (int)bank_addr, (int)sensor_addr); - break; - } - buf[i] = inb(data->addr + ABIT_UGURU_CMD); - } - - /* Last put the chip back in ready state */ - abituguru_ready(data); - - return i; -} - -/* Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send - address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. */ -static int abituguru_write(struct abituguru_data *data, - u8 bank_addr, u8 sensor_addr, u8 *buf, int count) -{ - int i; - - /* Send the address */ - i = abituguru_send_address(data, bank_addr, sensor_addr, - ABIT_UGURU_MAX_RETRIES); - if (i) - return i; - - /* And write the data */ - for (i = 0; i < count; i++) { - if (abituguru_wait(data, ABIT_UGURU_STATUS_WRITE)) { - ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " - "write state (bank: %d, sensor: %d)\n", - (int)bank_addr, (int)sensor_addr); - break; - } - outb(buf[i], data->addr + ABIT_UGURU_CMD); - } - - /* Now we need to wait till the chip is ready to be read again, - don't ask why */ - if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { - ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state " - "after write (bank: %d, sensor: %d)\n", (int)bank_addr, - (int)sensor_addr); - return -EIO; - } - - /* Cmd port MUST be read now and should contain 0xAC */ - if (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { - ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after write " - "(bank: %d, sensor: %d)\n", (int)bank_addr, - (int)sensor_addr); - return -EIO; - } - - /* Last put the chip back in ready state */ - abituguru_ready(data); - - return i; -} - -/* Detect sensor type. Temp and Volt sensors are enabled with - different masks and will ignore enable masks not meant for them. - This enables us to test what kind of sensor we're dealing with. - By setting the alarm thresholds so that we will always get an - alarm for sensor type X and then enabling the sensor as sensor type - X, if we then get an alarm it is a sensor of type X. */ -static int __devinit -abituguru_detect_bank1_sensor_type(struct abituguru_data *data, - u8 sensor_addr) -{ - u8 val, buf[3]; - int ret = ABIT_UGURU_NC; - - /* First read the sensor and the current settings */ - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val, - 1, ABIT_UGURU_MAX_RETRIES) != 1) - return -ENODEV; - - /* Test val is sane / usable for sensor type detection. */ - if ((val < 10u) || (val > 240u)) { - printk(KERN_WARNING ABIT_UGURU_NAME - ": bank1-sensor: %d reading (%d) too close to limits, " - "unable to determine sensor type, skipping sensor\n", - (int)sensor_addr, (int)val); - /* assume no sensor is there for sensors for which we can't - determine the sensor type because their reading is too close - to their limits, this usually means no sensor is there. */ - return ABIT_UGURU_NC; - } - - ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); - /* Volt sensor test, enable volt low alarm, set min value ridicously - high. If its a volt sensor this should always give us an alarm. */ - buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; - buf[1] = 245; - buf[2] = 250; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - buf, 3) != 3) - return -ENODEV; - /* Now we need 20 ms to give the uguru time to read the sensors - and raise a voltage alarm */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/50); - /* Check for alarm and check the alarm is a volt low alarm. */ - if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) - return -ENODEV; - if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, - sensor_addr, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) - return -ENODEV; - if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { - /* Restore original settings */ - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, - sensor_addr, - data->bank1_settings[sensor_addr], - 3) != 3) - return -ENODEV; - ABIT_UGURU_DEBUG(2, " found volt sensor\n"); - return ABIT_UGURU_IN_SENSOR; - } else - ABIT_UGURU_DEBUG(2, " alarm raised during volt " - "sensor test, but volt low flag not set\n"); - } else - ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " - "test\n"); - - /* Temp sensor test, enable sensor as a temp sensor, set beep value - ridicously low (but not too low, otherwise uguru ignores it). - If its a temp sensor this should always give us an alarm. */ - buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE; - buf[1] = 5; - buf[2] = 10; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - buf, 3) != 3) - return -ENODEV; - /* Now we need 50 ms to give the uguru time to read the sensors - and raise a temp alarm */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/20); - /* Check for alarm and check the alarm is a temp high alarm. */ - if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) - return -ENODEV; - if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, - sensor_addr, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) - return -ENODEV; - if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { - ret = ABIT_UGURU_TEMP_SENSOR; - ABIT_UGURU_DEBUG(2, " found temp sensor\n"); - } else - ABIT_UGURU_DEBUG(2, " alarm raised during temp " - "sensor test, but temp high flag not set\n"); - } else - ABIT_UGURU_DEBUG(2, " alarm not raised during temp sensor " - "test\n"); - - /* Restore original settings */ - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - data->bank1_settings[sensor_addr], 3) != 3) - return -ENODEV; - - return ret; -} - -/* These functions try to find out how many sensors there are in bank2 and how - many pwms there are. The purpose of this is to make sure that we don't give - the user the possibility to change settings for non-existent sensors / pwm. - The uGuru will happily read / write whatever memory happens to be after the - memory storing the PWM settings when reading/writing to a PWM which is not - there. Notice even if we detect a PWM which doesn't exist we normally won't - write to it, unless the user tries to change the settings. - - Although the uGuru allows reading (settings) from non existing bank2 - sensors, my version of the uGuru does seem to stop writing to them, the - write function above aborts in this case with: - "CMD reg does not hold 0xAC after write" - - Notice these 2 tests are non destructive iow read-only tests, otherwise - they would defeat their purpose. Although for the bank2_sensors detection a - read/write test would be feasible because of the reaction above, I've - however opted to stay on the safe side. */ -static void __devinit -abituguru_detect_no_bank2_sensors(struct abituguru_data *data) -{ - int i; - - if (fan_sensors) { - data->bank2_sensors = fan_sensors; - ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of " - "\"fan_sensors\" module param\n", - (int)data->bank2_sensors); - return; - } - - ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n"); - for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { - /* 0x89 are the known used bits: - -0x80 enable shutdown - -0x08 enable beep - -0x01 enable alarm - All other bits should be 0, but on some motherboards - 0x40 (bit 6) is also high for some of the fans?? */ - if (data->bank2_settings[i][0] & ~0xC9) { - ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " - "to be a fan sensor: settings[0] = %02X\n", - i, (unsigned int)data->bank2_settings[i][0]); - break; - } - - /* check if the threshold is within the allowed range */ - if (data->bank2_settings[i][1] < - abituguru_bank2_min_threshold) { - ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " - "to be a fan sensor: the threshold (%d) is " - "below the minimum (%d)\n", i, - (int)data->bank2_settings[i][1], - (int)abituguru_bank2_min_threshold); - break; - } - if (data->bank2_settings[i][1] > - abituguru_bank2_max_threshold) { - ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " - "to be a fan sensor: the threshold (%d) is " - "above the maximum (%d)\n", i, - (int)data->bank2_settings[i][1], - (int)abituguru_bank2_max_threshold); - break; - } - } - - data->bank2_sensors = i; - ABIT_UGURU_DEBUG(2, " found: %d fan sensors\n", - (int)data->bank2_sensors); -} - -static void __devinit -abituguru_detect_no_pwms(struct abituguru_data *data) -{ - int i, j; - - if (pwms) { - data->pwms = pwms; - ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of " - "\"pwms\" module param\n", (int)data->pwms); - return; - } - - ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n"); - for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { - /* 0x80 is the enable bit and the low - nibble is which temp sensor to use, - the other bits should be 0 */ - if (data->pwm_settings[i][0] & ~0x8F) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " - "to be a pwm channel: settings[0] = %02X\n", - i, (unsigned int)data->pwm_settings[i][0]); - break; - } - - /* the low nibble must correspond to one of the temp sensors - we've found */ - for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; - j++) { - if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] == - (data->pwm_settings[i][0] & 0x0F)) - break; - } - if (j == data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " - "to be a pwm channel: %d is not a valid temp " - "sensor address\n", i, - data->pwm_settings[i][0] & 0x0F); - break; - } - - /* check if all other settings are within the allowed range */ - for (j = 1; j < 5; j++) { - u8 min; - /* special case pwm1 min pwm% */ - if ((i == 0) && ((j == 1) || (j == 2))) - min = 77; - else - min = abituguru_pwm_min[j]; - if (data->pwm_settings[i][j] < min) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does " - "not seem to be a pwm channel: " - "setting %d (%d) is below the minimum " - "value (%d)\n", i, j, - (int)data->pwm_settings[i][j], - (int)min); - goto abituguru_detect_no_pwms_exit; - } - if (data->pwm_settings[i][j] > abituguru_pwm_max[j]) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does " - "not seem to be a pwm channel: " - "setting %d (%d) is above the maximum " - "value (%d)\n", i, j, - (int)data->pwm_settings[i][j], - (int)abituguru_pwm_max[j]); - goto abituguru_detect_no_pwms_exit; - } - } - - /* check that min temp < max temp and min pwm < max pwm */ - if (data->pwm_settings[i][1] >= data->pwm_settings[i][2]) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " - "to be a pwm channel: min pwm (%d) >= " - "max pwm (%d)\n", i, - (int)data->pwm_settings[i][1], - (int)data->pwm_settings[i][2]); - break; - } - if (data->pwm_settings[i][3] >= data->pwm_settings[i][4]) { - ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " - "to be a pwm channel: min temp (%d) >= " - "max temp (%d)\n", i, - (int)data->pwm_settings[i][3], - (int)data->pwm_settings[i][4]); - break; - } - } - -abituguru_detect_no_pwms_exit: - data->pwms = i; - ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms); -} - -/* Following are the sysfs callback functions. These functions expect: - sensor_device_attribute_2->index: sensor address/offset in the bank - sensor_device_attribute_2->nr: register offset, bitmask or NA. */ -static struct abituguru_data *abituguru_update_device(struct device *dev); - -static ssize_t show_bank1_value(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = abituguru_update_device(dev); - if (!data) - return -EIO; - return sprintf(buf, "%d\n", (data->bank1_value[attr->index] * - data->bank1_max_value[attr->index] + 128) / 255); -} - -static ssize_t show_bank1_setting(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", - (data->bank1_settings[attr->index][attr->nr] * - data->bank1_max_value[attr->index] + 128) / 255); -} - -static ssize_t show_bank2_value(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = abituguru_update_device(dev); - if (!data) - return -EIO; - return sprintf(buf, "%d\n", (data->bank2_value[attr->index] * - ABIT_UGURU_FAN_MAX + 128) / 255); -} - -static ssize_t show_bank2_setting(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", - (data->bank2_settings[attr->index][attr->nr] * - ABIT_UGURU_FAN_MAX + 128) / 255); -} - -static ssize_t store_bank1_setting(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - u8 val = (simple_strtoul(buf, NULL, 10) * 255 + - data->bank1_max_value[attr->index]/2) / - data->bank1_max_value[attr->index]; - ssize_t ret = count; - - mutex_lock(&data->update_lock); - if (data->bank1_settings[attr->index][attr->nr] != val) { - u8 orig_val = data->bank1_settings[attr->index][attr->nr]; - data->bank1_settings[attr->index][attr->nr] = val; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, - attr->index, data->bank1_settings[attr->index], - 3) <= attr->nr) { - data->bank1_settings[attr->index][attr->nr] = orig_val; - ret = -EIO; - } - } - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t store_bank2_setting(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - u8 val = (simple_strtoul(buf, NULL, 10)*255 + ABIT_UGURU_FAN_MAX/2) / - ABIT_UGURU_FAN_MAX; - ssize_t ret = count; - - /* this check can be done before taking the lock */ - if ((val < abituguru_bank2_min_threshold) || - (val > abituguru_bank2_max_threshold)) - return -EINVAL; - - mutex_lock(&data->update_lock); - if (data->bank2_settings[attr->index][attr->nr] != val) { - u8 orig_val = data->bank2_settings[attr->index][attr->nr]; - data->bank2_settings[attr->index][attr->nr] = val; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2, - attr->index, data->bank2_settings[attr->index], - 2) <= attr->nr) { - data->bank2_settings[attr->index][attr->nr] = orig_val; - ret = -EIO; - } - } - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t show_bank1_alarm(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = abituguru_update_device(dev); - if (!data) - return -EIO; - /* See if the alarm bit for this sensor is set, and if the - alarm matches the type of alarm we're looking for (for volt - it can be either low or high). The type is stored in a few - readonly bits in the settings part of the relevant sensor. - The bitmask of the type is passed to us in attr->nr. */ - if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) && - (data->bank1_settings[attr->index][0] & attr->nr)) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static ssize_t show_bank2_alarm(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = abituguru_update_device(dev); - if (!data) - return -EIO; - if (data->alarms[2] & (0x01 << attr->index)) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static ssize_t show_bank1_mask(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - if (data->bank1_settings[attr->index][0] & attr->nr) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static ssize_t show_bank2_mask(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - if (data->bank2_settings[attr->index][0] & attr->nr) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static ssize_t store_bank1_mask(struct device *dev, - struct device_attribute *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - int mask = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; - u8 orig_val; - - mutex_lock(&data->update_lock); - orig_val = data->bank1_settings[attr->index][0]; - - if (mask) - data->bank1_settings[attr->index][0] |= attr->nr; - else - data->bank1_settings[attr->index][0] &= ~attr->nr; - - if ((data->bank1_settings[attr->index][0] != orig_val) && - (abituguru_write(data, - ABIT_UGURU_SENSOR_BANK1 + 2, attr->index, - data->bank1_settings[attr->index], 3) < 1)) { - data->bank1_settings[attr->index][0] = orig_val; - ret = -EIO; - } - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t store_bank2_mask(struct device *dev, - struct device_attribute *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - int mask = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; - u8 orig_val; - - mutex_lock(&data->update_lock); - orig_val = data->bank2_settings[attr->index][0]; - - if (mask) - data->bank2_settings[attr->index][0] |= attr->nr; - else - data->bank2_settings[attr->index][0] &= ~attr->nr; - - if ((data->bank2_settings[attr->index][0] != orig_val) && - (abituguru_write(data, - ABIT_UGURU_SENSOR_BANK2 + 2, attr->index, - data->bank2_settings[attr->index], 2) < 1)) { - data->bank2_settings[attr->index][0] = orig_val; - ret = -EIO; - } - mutex_unlock(&data->update_lock); - return ret; -} - -/* Fan PWM (speed control) */ -static ssize_t show_pwm_setting(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", data->pwm_settings[attr->index][attr->nr] * - abituguru_pwm_settings_multiplier[attr->nr]); -} - -static ssize_t store_pwm_setting(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - u8 min, val = (simple_strtoul(buf, NULL, 10) + - abituguru_pwm_settings_multiplier[attr->nr]/2) / - abituguru_pwm_settings_multiplier[attr->nr]; - ssize_t ret = count; - - /* special case pwm1 min pwm% */ - if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2))) - min = 77; - else - min = abituguru_pwm_min[attr->nr]; - - /* this check can be done before taking the lock */ - if ((val < min) || (val > abituguru_pwm_max[attr->nr])) - return -EINVAL; - - mutex_lock(&data->update_lock); - /* this check needs to be done after taking the lock */ - if ((attr->nr & 1) && - (val >= data->pwm_settings[attr->index][attr->nr + 1])) - ret = -EINVAL; - else if (!(attr->nr & 1) && - (val <= data->pwm_settings[attr->index][attr->nr - 1])) - ret = -EINVAL; - else if (data->pwm_settings[attr->index][attr->nr] != val) { - u8 orig_val = data->pwm_settings[attr->index][attr->nr]; - data->pwm_settings[attr->index][attr->nr] = val; - if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, - attr->index, data->pwm_settings[attr->index], - 5) <= attr->nr) { - data->pwm_settings[attr->index][attr->nr] = - orig_val; - ret = -EIO; - } - } - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t show_pwm_sensor(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - int i; - /* We need to walk to the temp sensor addresses to find what - the userspace id of the configured temp sensor is. */ - for (i = 0; i < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; i++) - if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][i] == - (data->pwm_settings[attr->index][0] & 0x0F)) - return sprintf(buf, "%d\n", i+1); - - return -ENXIO; -} - -static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10) - 1; - ssize_t ret = count; - - mutex_lock(&data->update_lock); - if (val < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) { - u8 orig_val = data->pwm_settings[attr->index][0]; - u8 address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val]; - data->pwm_settings[attr->index][0] &= 0xF0; - data->pwm_settings[attr->index][0] |= address; - if (data->pwm_settings[attr->index][0] != orig_val) { - if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, - attr->index, - data->pwm_settings[attr->index], - 5) < 1) { - data->pwm_settings[attr->index][0] = orig_val; - ret = -EIO; - } - } - } - else - ret = -EINVAL; - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t show_pwm_enable(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - int res = 0; - if (data->pwm_settings[attr->index][0] & ABIT_UGURU_FAN_PWM_ENABLE) - res = 2; - return sprintf(buf, "%d\n", res); -} - -static ssize_t store_pwm_enable(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct abituguru_data *data = dev_get_drvdata(dev); - u8 orig_val, user_val = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; - - mutex_lock(&data->update_lock); - orig_val = data->pwm_settings[attr->index][0]; - switch (user_val) { - case 0: - data->pwm_settings[attr->index][0] &= - ~ABIT_UGURU_FAN_PWM_ENABLE; - break; - case 2: - data->pwm_settings[attr->index][0] |= - ABIT_UGURU_FAN_PWM_ENABLE; - break; - default: - ret = -EINVAL; - } - if ((data->pwm_settings[attr->index][0] != orig_val) && - (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, - attr->index, data->pwm_settings[attr->index], - 5) < 1)) { - data->pwm_settings[attr->index][0] = orig_val; - ret = -EIO; - } - mutex_unlock(&data->update_lock); - return ret; -} - -static ssize_t show_name(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - return sprintf(buf, "%s\n", ABIT_UGURU_NAME); -} - -/* Sysfs attr templates, the real entries are generated automatically. */ -static const -struct sensor_device_attribute_2 abituguru_sysfs_bank1_templ[2][9] = { - { - SENSOR_ATTR_2(in%d_input, 0444, show_bank1_value, NULL, 0, 0), - SENSOR_ATTR_2(in%d_min, 0644, show_bank1_setting, - store_bank1_setting, 1, 0), - SENSOR_ATTR_2(in%d_min_alarm, 0444, show_bank1_alarm, NULL, - ABIT_UGURU_VOLT_LOW_ALARM_FLAG, 0), - SENSOR_ATTR_2(in%d_max, 0644, show_bank1_setting, - store_bank1_setting, 2, 0), - SENSOR_ATTR_2(in%d_max_alarm, 0444, show_bank1_alarm, NULL, - ABIT_UGURU_VOLT_HIGH_ALARM_FLAG, 0), - SENSOR_ATTR_2(in%d_beep, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), - SENSOR_ATTR_2(in%d_shutdown, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), - SENSOR_ATTR_2(in%d_min_alarm_enable, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_VOLT_LOW_ALARM_ENABLE, 0), - SENSOR_ATTR_2(in%d_max_alarm_enable, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE, 0), - }, { - SENSOR_ATTR_2(temp%d_input, 0444, show_bank1_value, NULL, 0, 0), - SENSOR_ATTR_2(temp%d_alarm, 0444, show_bank1_alarm, NULL, - ABIT_UGURU_TEMP_HIGH_ALARM_FLAG, 0), - SENSOR_ATTR_2(temp%d_max, 0644, show_bank1_setting, - store_bank1_setting, 1, 0), - SENSOR_ATTR_2(temp%d_crit, 0644, show_bank1_setting, - store_bank1_setting, 2, 0), - SENSOR_ATTR_2(temp%d_beep, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), - SENSOR_ATTR_2(temp%d_shutdown, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), - SENSOR_ATTR_2(temp%d_alarm_enable, 0644, show_bank1_mask, - store_bank1_mask, ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE, 0), - } -}; - -static const struct sensor_device_attribute_2 abituguru_sysfs_fan_templ[6] = { - SENSOR_ATTR_2(fan%d_input, 0444, show_bank2_value, NULL, 0, 0), - SENSOR_ATTR_2(fan%d_alarm, 0444, show_bank2_alarm, NULL, 0, 0), - SENSOR_ATTR_2(fan%d_min, 0644, show_bank2_setting, - store_bank2_setting, 1, 0), - SENSOR_ATTR_2(fan%d_beep, 0644, show_bank2_mask, - store_bank2_mask, ABIT_UGURU_BEEP_ENABLE, 0), - SENSOR_ATTR_2(fan%d_shutdown, 0644, show_bank2_mask, - store_bank2_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), - SENSOR_ATTR_2(fan%d_alarm_enable, 0644, show_bank2_mask, - store_bank2_mask, ABIT_UGURU_FAN_LOW_ALARM_ENABLE, 0), -}; - -static const struct sensor_device_attribute_2 abituguru_sysfs_pwm_templ[6] = { - SENSOR_ATTR_2(pwm%d_enable, 0644, show_pwm_enable, - store_pwm_enable, 0, 0), - SENSOR_ATTR_2(pwm%d_auto_channels_temp, 0644, show_pwm_sensor, - store_pwm_sensor, 0, 0), - SENSOR_ATTR_2(pwm%d_auto_point1_pwm, 0644, show_pwm_setting, - store_pwm_setting, 1, 0), - SENSOR_ATTR_2(pwm%d_auto_point2_pwm, 0644, show_pwm_setting, - store_pwm_setting, 2, 0), - SENSOR_ATTR_2(pwm%d_auto_point1_temp, 0644, show_pwm_setting, - store_pwm_setting, 3, 0), - SENSOR_ATTR_2(pwm%d_auto_point2_temp, 0644, show_pwm_setting, - store_pwm_setting, 4, 0), -}; - -static struct sensor_device_attribute_2 abituguru_sysfs_attr[] = { - SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), -}; - -static int __devinit abituguru_probe(struct platform_device *pdev) -{ - struct abituguru_data *data; - int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; - char *sysfs_filename; - - /* El weirdo probe order, to keep the sysfs order identical to the - BIOS and window-appliction listing order. */ - const u8 probe_order[ABIT_UGURU_MAX_BANK1_SENSORS] = { - 0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02, - 0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C }; - - if (!(data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL))) - return -ENOMEM; - - data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; - mutex_init(&data->update_lock); - platform_set_drvdata(pdev, data); - - /* See if the uGuru is ready */ - if (inb_p(data->addr + ABIT_UGURU_DATA) == ABIT_UGURU_STATUS_INPUT) - data->uguru_ready = 1; - - /* Completely read the uGuru this has 2 purposes: - - testread / see if one really is there. - - make an in memory copy of all the uguru settings for future use. */ - if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, - data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_probe_error; - - for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, i, - &data->bank1_value[i], 1, - ABIT_UGURU_MAX_RETRIES) != 1) - goto abituguru_probe_error; - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1+1, i, - data->bank1_settings[i], 3, - ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_probe_error; - } - /* Note: We don't know how many bank2 sensors / pwms there really are, - but in order to "detect" this we need to read the maximum amount - anyways. If we read sensors/pwms not there we'll just read crap - this can't hurt. We need the detection because we don't want - unwanted writes, which will hurt! */ - for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, - &data->bank2_value[i], 1, - ABIT_UGURU_MAX_RETRIES) != 1) - goto abituguru_probe_error; - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2+1, i, - data->bank2_settings[i], 2, - ABIT_UGURU_MAX_RETRIES) != 2) - goto abituguru_probe_error; - } - for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { - if (abituguru_read(data, ABIT_UGURU_FAN_PWM, i, - data->pwm_settings[i], 5, - ABIT_UGURU_MAX_RETRIES) != 5) - goto abituguru_probe_error; - } - data->last_updated = jiffies; - - /* Detect sensor types and fill the sysfs attr for bank1 */ - sysfs_attr_i = 0; - sysfs_filename = data->sysfs_names; - sysfs_names_free = ABITUGURU_SYSFS_NAMES_LENGTH; - for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - res = abituguru_detect_bank1_sensor_type(data, probe_order[i]); - if (res < 0) - goto abituguru_probe_error; - if (res == ABIT_UGURU_NC) - continue; - - /* res 1 (temp) sensors have 7 sysfs entries, 0 (in) 9 */ - for (j = 0; j < (res ? 7 : 9); j++) { - used = snprintf(sysfs_filename, sysfs_names_free, - abituguru_sysfs_bank1_templ[res][j].dev_attr. - attr.name, data->bank1_sensors[res] + res) - + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_bank1_templ[res][j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; - data->sysfs_attr[sysfs_attr_i].index = probe_order[i]; - sysfs_filename += used; - sysfs_names_free -= used; - sysfs_attr_i++; - } - data->bank1_max_value[probe_order[i]] = - abituguru_bank1_max_value[res]; - data->bank1_address[res][data->bank1_sensors[res]] = - probe_order[i]; - data->bank1_sensors[res]++; - } - /* Detect number of sensors and fill the sysfs attr for bank2 (fans) */ - abituguru_detect_no_bank2_sensors(data); - for (i = 0; i < data->bank2_sensors; i++) { - for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_fan_templ); j++) { - used = snprintf(sysfs_filename, sysfs_names_free, - abituguru_sysfs_fan_templ[j].dev_attr.attr.name, - i + 1) + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_fan_templ[j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; - data->sysfs_attr[sysfs_attr_i].index = i; - sysfs_filename += used; - sysfs_names_free -= used; - sysfs_attr_i++; - } - } - /* Detect number of sensors and fill the sysfs attr for pwms */ - abituguru_detect_no_pwms(data); - for (i = 0; i < data->pwms; i++) { - for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_pwm_templ); j++) { - used = snprintf(sysfs_filename, sysfs_names_free, - abituguru_sysfs_pwm_templ[j].dev_attr.attr.name, - i + 1) + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_pwm_templ[j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; - data->sysfs_attr[sysfs_attr_i].index = i; - sysfs_filename += used; - sysfs_names_free -= used; - sysfs_attr_i++; - } - } - /* Fail safe check, this should never happen! */ - if (sysfs_names_free < 0) { - printk(KERN_ERR ABIT_UGURU_NAME ": Fatal error ran out of " - "space for sysfs attr names. This should never " - "happen please report to the abituguru maintainer " - "(see MAINTAINERS)\n"); - res = -ENAMETOOLONG; - goto abituguru_probe_error; - } - printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n"); - - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { - res = PTR_ERR(data->class_dev); - goto abituguru_probe_error; - } - for (i = 0; i < sysfs_attr_i; i++) - device_create_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); - for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) - device_create_file(&pdev->dev, - &abituguru_sysfs_attr[i].dev_attr); - - return 0; - -abituguru_probe_error: - kfree(data); - return res; -} - -static int __devexit abituguru_remove(struct platform_device *pdev) -{ - struct abituguru_data *data = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - hwmon_device_unregister(data->class_dev); - kfree(data); - - return 0; -} - -static struct abituguru_data *abituguru_update_device(struct device *dev) -{ - int i, err; - struct abituguru_data *data = dev_get_drvdata(dev); - /* fake a complete successful read if no update necessary. */ - char success = 1; - - mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ)) { - success = 0; - if ((err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, - data->alarms, 3, 0)) != 3) - goto LEAVE_UPDATE; - for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK1, i, - &data->bank1_value[i], 1, 0)) != 1) - goto LEAVE_UPDATE; - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK1 + 1, i, - data->bank1_settings[i], 3, 0)) != 3) - goto LEAVE_UPDATE; - } - for (i = 0; i < data->bank2_sensors; i++) - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK2, i, - &data->bank2_value[i], 1, 0)) != 1) - goto LEAVE_UPDATE; - /* success! */ - success = 1; - data->update_timeouts = 0; -LEAVE_UPDATE: - /* handle timeout condition */ - if (err == -EBUSY) { - /* No overflow please */ - if (data->update_timeouts < 255u) - data->update_timeouts++; - if (data->update_timeouts <= ABIT_UGURU_MAX_TIMEOUTS) { - ABIT_UGURU_DEBUG(3, "timeout exceeded, will " - "try again next update\n"); - /* Just a timeout, fake a successful read */ - success = 1; - } else - ABIT_UGURU_DEBUG(1, "timeout exceeded %d " - "times waiting for more input state\n", - (int)data->update_timeouts); - } - /* On success set last_updated */ - if (success) - data->last_updated = jiffies; - } - mutex_unlock(&data->update_lock); - - if (success) - return data; - else - return NULL; -} - -static struct platform_driver abituguru_driver = { - .driver = { - .owner = THIS_MODULE, - .name = ABIT_UGURU_NAME, - }, - .probe = abituguru_probe, - .remove = __devexit_p(abituguru_remove), -}; - -static int __init abituguru_detect(void) -{ - /* See if there is an uguru there. After a reboot uGuru will hold 0x00 - at DATA and 0xAC, when this driver has already been loaded once - DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either - scenario but some will hold 0x00. - Some uGuru's initally hold 0x09 at DATA and will only hold 0x08 - after reading CMD first, so CMD must be read first! */ - u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD); - u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA); - if (((data_val == 0x00) || (data_val == 0x08)) && - ((cmd_val == 0x00) || (cmd_val == 0xAC))) - return ABIT_UGURU_BASE; - - ABIT_UGURU_DEBUG(2, "no Abit uGuru found, data = 0x%02X, cmd = " - "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); - - if (force) { - printk(KERN_INFO ABIT_UGURU_NAME ": Assuming Abit uGuru is " - "present because of \"force\" parameter\n"); - return ABIT_UGURU_BASE; - } - - /* No uGuru found */ - return -ENODEV; -} - -static struct platform_device *abituguru_pdev; - -static int __init abituguru_init(void) -{ - int address, err; - struct resource res = { .flags = IORESOURCE_IO }; - - address = abituguru_detect(); - if (address < 0) - return address; - - err = platform_driver_register(&abituguru_driver); - if (err) - goto exit; - - abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address); - if (!abituguru_pdev) { - printk(KERN_ERR ABIT_UGURU_NAME - ": Device allocation failed\n"); - err = -ENOMEM; - goto exit_driver_unregister; - } - - res.start = address; - res.end = address + ABIT_UGURU_REGION_LENGTH - 1; - res.name = ABIT_UGURU_NAME; - - err = platform_device_add_resources(abituguru_pdev, &res, 1); - if (err) { - printk(KERN_ERR ABIT_UGURU_NAME - ": Device resource addition failed (%d)\n", err); - goto exit_device_put; - } - - err = platform_device_add(abituguru_pdev); - if (err) { - printk(KERN_ERR ABIT_UGURU_NAME - ": Device addition failed (%d)\n", err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(abituguru_pdev); -exit_driver_unregister: - platform_driver_unregister(&abituguru_driver); -exit: - return err; -} - -static void __exit abituguru_exit(void) -{ - platform_device_unregister(abituguru_pdev); - platform_driver_unregister(&abituguru_driver); -} - -MODULE_AUTHOR("Hans de Goede "); -MODULE_DESCRIPTION("Abit uGuru Sensor device"); -MODULE_LICENSE("GPL"); - -module_init(abituguru_init); -module_exit(abituguru_exit); diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index facc1ccb8338..65b2709f750c 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -341,7 +341,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index fd72440faf76..885465df6e6a 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -99,6 +99,10 @@ superio_exit(int base) #define ADDR_REG_OFFSET 0 #define DATA_REG_OFFSET 1 +static struct resource f71805f_resource __initdata = { + .flags = IORESOURCE_IO, +}; + /* * Registers */ @@ -778,11 +782,6 @@ static struct platform_driver f71805f_driver = { static int __init f71805f_device_add(unsigned short address) { - struct resource res = { - .start = address, - .end = address + REGION_LENGTH - 1, - .flags = IORESOURCE_IO, - }; int err; pdev = platform_device_alloc(DRVNAME, address); @@ -792,8 +791,10 @@ static int __init f71805f_device_add(unsigned short address) goto exit; } - res.name = pdev->name; - err = platform_device_add_resources(pdev, &res, 1); + f71805f_resource.start = address; + f71805f_resource.end = address + REGION_LENGTH - 1; + f71805f_resource.name = pdev->name; + err = platform_device_add_resources(pdev, &f71805f_resource, 1); if (err) { printk(KERN_ERR DRVNAME ": Device resource addition failed " "(%d)\n", err); diff --git a/trunk/drivers/hwmon/hdaps.c b/trunk/drivers/hwmon/hdaps.c index 42b632889dd8..1659f6c41458 100644 --- a/trunk/drivers/hwmon/hdaps.c +++ b/trunk/drivers/hwmon/hdaps.c @@ -41,7 +41,7 @@ #define HDAPS_PORT_STATE 0x1611 /* device state */ #define HDAPS_PORT_YPOS 0x1612 /* y-axis position */ #define HDAPS_PORT_XPOS 0x1614 /* x-axis position */ -#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in Celsius */ +#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in celcius */ #define HDAPS_PORT_YVAR 0x1617 /* y-axis variance (what is this?) */ #define HDAPS_PORT_XVAR 0x1619 /* x-axis variance (what is this?) */ #define HDAPS_PORT_TEMP2 0x161b /* device temperature (again?) */ @@ -522,15 +522,13 @@ static int __init hdaps_init(void) { int ret; - /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match - "ThinkPad T42p", so the order of the entries matters */ + /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ struct dmi_system_id hdaps_whitelist[] = { HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), /* R52 (1846AQG) */ HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), @@ -538,9 +536,9 @@ static int __init hdaps_init(void) HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), + HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"), { .ident = NULL } }; diff --git a/trunk/drivers/hwmon/hwmon-vid.c b/trunk/drivers/hwmon/hwmon-vid.c index a6764ff00803..a74a44f16f51 100644 --- a/trunk/drivers/hwmon/hwmon-vid.c +++ b/trunk/drivers/hwmon/hwmon-vid.c @@ -58,20 +58,11 @@ doesn't seem to be any named specification for these. The conversion tables are detailed directly in the various Pentium M datasheets: http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm - - The 14 specification corresponds to Intel Core series. There - doesn't seem to be any named specification for these. The conversion - tables are detailed directly in the various Pentium Core datasheets: - http://www.intel.com/design/mobile/datashts/309221.htm - - The 110 (VRM 11) specification corresponds to Intel Conroe based series. - http://www.intel.com/design/processor/applnots/313214.htm */ /* vrm is the VRM/VRD document version multiplied by 10. - val is the 4-bit or more VID code. - Returned value is in mV to avoid floating point in the kernel. - Some VID have some bits in uV scale, this is rounded to mV */ + val is the 4-, 5- or 6-bit VID code. + Returned value is in mV to avoid floating point in the kernel. */ int vid_from_reg(int val, u8 vrm) { int vid; @@ -79,36 +70,26 @@ int vid_from_reg(int val, u8 vrm) switch(vrm) { case 100: /* VRD 10.0 */ - /* compute in uV, round to mV */ - val &= 0x3f; if((val & 0x1f) == 0x1f) return 0; if((val & 0x1f) <= 0x09 || val == 0x0a) - vid = 1087500 - (val & 0x1f) * 25000; + vid = 10875 - (val & 0x1f) * 250; else - vid = 1862500 - (val & 0x1f) * 25000; + vid = 18625 - (val & 0x1f) * 250; if(val & 0x20) - vid -= 12500; - return((vid + 500) / 1000); + vid -= 125; + vid /= 10; /* only return 3 dec. places for now */ + return vid; - case 110: /* Intel Conroe */ - /* compute in uV, round to mV */ - val &= 0xff; - if(((val & 0x7e) == 0xfe) || (!(val & 0x7e))) - return 0; - return((1600000 - (val - 2) * 6250 + 500) / 1000); case 24: /* Opteron processor */ - val &= 0x1f; return(val == 0x1f ? 0 : 1550 - val * 25); case 91: /* VRM 9.1 */ case 90: /* VRM 9.0 */ - val &= 0x1f; return(val == 0x1f ? 0 : 1850 - val * 25); case 85: /* VRM 8.5 */ - val &= 0x1f; return((val & 0x10 ? 25 : 0) + ((val & 0x0f) > 0x04 ? 2050 : 1250) - ((val & 0x0f) * 50)); @@ -117,21 +98,14 @@ int vid_from_reg(int val, u8 vrm) val &= 0x0f; /* fall through */ case 82: /* VRM 8.2 */ - val &= 0x1f; return(val == 0x1f ? 0 : val & 0x10 ? 5100 - (val) * 100 : 2050 - (val) * 50); case 17: /* Intel IMVP-II */ - val &= 0x1f; return(val & 0x10 ? 975 - (val & 0xF) * 25 : 1750 - val * 50); case 13: - val &= 0x3f; - return(1708 - val * 16); - case 14: /* Intel Core */ - /* compute in uV, round to mV */ - val &= 0x7f; - return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000); + return(1708 - (val & 0x3f) * 16); default: /* report 0 for unknown */ printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); return 0; @@ -164,8 +138,6 @@ static struct vrm_model vrm_models[] = { {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ - {X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */ - {X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */ {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ diff --git a/trunk/drivers/hwmon/lm70.c b/trunk/drivers/hwmon/lm70.c deleted file mode 100644 index 6ba84731b9cd..000000000000 --- a/trunk/drivers/hwmon/lm70.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * lm70.c - * - * The LM70 is a temperature sensor chip from National Semiconductor (NS). - * Copyright (C) 2006 Kaiwan N Billimoria - * - * The LM70 communicates with a host processor via an SPI/Microwire Bus - * interface. The complete datasheet is available at National's website - * here: - * http://www.national.com/pf/LM/LM70.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "lm70" - -struct lm70 { - struct class_device *cdev; - struct semaphore sem; -}; - -/* sysfs hook function */ -static ssize_t lm70_sense_temp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct spi_device *spi = to_spi_device(dev); - int status, val; - u8 rxbuf[2]; - s16 raw=0; - struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); - - if (down_interruptible(&p_lm70->sem)) - return -ERESTARTSYS; - - /* - * spi_read() requires a DMA-safe buffer; so we use - * spi_write_then_read(), transmitting 0 bytes. - */ - status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2); - if (status < 0) { - printk(KERN_WARNING - "spi_write_then_read failed with status %d\n", status); - goto out; - } - dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]); - - raw = (rxbuf[1] << 8) + rxbuf[0]; - dev_dbg(dev, "raw=0x%x\n", raw); - - /* - * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's - * complement value. Only the MSB 11 bits (1 sign + 10 temperature - * bits) are meaningful; the LSB 5 bits are to be discarded. - * See the datasheet. - * - * Further, each bit represents 0.25 degrees Celsius; so, multiply - * by 0.25. Also multiply by 1000 to represent in millidegrees - * Celsius. - * So it's equivalent to multiplying by 0.25 * 1000 = 250. - */ - val = ((int)raw/32) * 250; - status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */ -out: - up(&p_lm70->sem); - return status; -} - -static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); - -/*----------------------------------------------------------------------*/ - -static int __devinit lm70_probe(struct spi_device *spi) -{ - struct lm70 *p_lm70; - int status; - - p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); - if (!p_lm70) - return -ENOMEM; - - init_MUTEX(&p_lm70->sem); - - /* sysfs hook */ - p_lm70->cdev = hwmon_device_register(&spi->dev); - if (IS_ERR(p_lm70->cdev)) { - dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); - status = PTR_ERR(p_lm70->cdev); - goto out_dev_reg_failed; - } - dev_set_drvdata(&spi->dev, p_lm70); - - if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) { - dev_dbg(&spi->dev, "device_create_file failure.\n"); - goto out_dev_create_file_failed; - } - - return 0; - -out_dev_create_file_failed: - hwmon_device_unregister(p_lm70->cdev); -out_dev_reg_failed: - dev_set_drvdata(&spi->dev, NULL); - kfree(p_lm70); - return status; -} - -static int __exit lm70_remove(struct spi_device *spi) -{ - struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); - - device_remove_file(&spi->dev, &dev_attr_temp1_input); - hwmon_device_unregister(p_lm70->cdev); - dev_set_drvdata(&spi->dev, NULL); - kfree(p_lm70); - - return 0; -} - -static struct spi_driver lm70_driver = { - .driver = { - .name = "lm70", - .owner = THIS_MODULE, - }, - .probe = lm70_probe, - .remove = __devexit_p(lm70_remove), -}; - -static int __init init_lm70(void) -{ - return spi_register_driver(&lm70_driver); -} - -static void __exit cleanup_lm70(void) -{ - spi_unregister_driver(&lm70_driver); -} - -module_init(init_lm70); -module_exit(cleanup_lm70); - -MODULE_AUTHOR("Kaiwan N Billimoria"); -MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/lm78.c b/trunk/drivers/hwmon/lm78.c index a6ce7abf8602..94be3d797e61 100644 --- a/trunk/drivers/hwmon/lm78.c +++ b/trunk/drivers/hwmon/lm78.c @@ -358,7 +358,7 @@ static ssize_t show_fan_div(struct device *dev, char *buf, int nr) /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/lm80.c b/trunk/drivers/hwmon/lm80.c index b4ccdfc01203..f72120d08c4c 100644 --- a/trunk/drivers/hwmon/lm80.c +++ b/trunk/drivers/hwmon/lm80.c @@ -253,7 +253,7 @@ set_fan(min2, fan_min[1], LM80_REG_FAN_MIN(2), fan_div[1]); /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/lm83.c b/trunk/drivers/hwmon/lm83.c index 2137d7879df6..aac4ec2bf694 100644 --- a/trunk/drivers/hwmon/lm83.c +++ b/trunk/drivers/hwmon/lm83.c @@ -12,10 +12,6 @@ * Since the datasheet omits to give the chip stepping code, I give it * here: 0x03 (at register 0xff). * - * Also supports the LM82 temp sensor, which is basically a stripped down - * model of the LM83. Datasheet is here: - * http://www.national.com/pf/LM/LM82.html - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -56,7 +52,7 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, * Insmod parameters */ -I2C_CLIENT_INSMOD_2(lm83, lm82); +I2C_CLIENT_INSMOD_1(lm83); /* * The LM83 registers @@ -287,9 +283,6 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) if (man_id == 0x01) { /* National Semiconductor */ if (chip_id == 0x03) { kind = lm83; - } else - if (chip_id == 0x01) { - kind = lm82; } } @@ -303,9 +296,6 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) if (kind == lm83) { name = "lm83"; - } else - if (kind == lm82) { - name = "lm82"; } /* We can fill in the remaining client fields */ @@ -329,46 +319,32 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_detach; } - /* - * The LM82 can only monitor one external diode which is - * at the same register as the LM83 temp3 entry - so we - * declare 1 and 3 common, and then 2 and 4 only for the LM83. - */ - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); - + device_create_file(&new_client->dev, + &sensor_dev_attr_temp4_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_max.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); - + device_create_file(&new_client->dev, + &sensor_dev_attr_temp4_max.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr); + device_create_file(&new_client->dev, + &sensor_dev_attr_temp2_crit.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr); - + device_create_file(&new_client->dev, + &sensor_dev_attr_temp4_crit.dev_attr); device_create_file(&new_client->dev, &dev_attr_alarms); - if (kind == lm83) { - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_input.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_max.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_crit.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_crit.dev_attr); - } - return 0; exit_detach: diff --git a/trunk/drivers/hwmon/lm87.c b/trunk/drivers/hwmon/lm87.c index e6c1b638c971..e229daf666de 100644 --- a/trunk/drivers/hwmon/lm87.c +++ b/trunk/drivers/hwmon/lm87.c @@ -421,7 +421,7 @@ static void set_fan_min(struct device *dev, const char *buf, int nr) /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan clock divider. This follows the principle - of least surprise; the user doesn't expect the fan minimum to change just + of least suprise; the user doesn't expect the fan minimum to change just because the divider changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/sis5595.c b/trunk/drivers/hwmon/sis5595.c index 063f71c5f07e..6f3fda73f70c 100644 --- a/trunk/drivers/hwmon/sis5595.c +++ b/trunk/drivers/hwmon/sis5595.c @@ -380,7 +380,7 @@ static ssize_t show_fan_div(struct device *dev, char *buf, int nr) /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index 825e8f72698f..7732aec54594 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -207,7 +207,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan clock divider. This follows the principle - of least surprise; the user doesn't expect the fan minimum to change just + of least suprise; the user doesn't expect the fan minimum to change just because the divider changed. */ static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/smsc47m192.c b/trunk/drivers/hwmon/smsc47m192.c deleted file mode 100644 index bdc4570acf9a..000000000000 --- a/trunk/drivers/hwmon/smsc47m192.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - smsc47m192.c - Support for hardware monitoring block of - SMSC LPC47M192 and LPC47M997 Super I/O chips - - Copyright (C) 2006 Hartmut Rick - - Derived from lm78.c and other chip drivers. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(smsc47m192); - -/* SMSC47M192 registers */ -#define SMSC47M192_REG_IN(nr) ((nr)<6 ? (0x20 + (nr)) : \ - (0x50 + (nr) - 6)) -#define SMSC47M192_REG_IN_MAX(nr) ((nr)<6 ? (0x2b + (nr) * 2) : \ - (0x54 + (((nr) - 6) * 2))) -#define SMSC47M192_REG_IN_MIN(nr) ((nr)<6 ? (0x2c + (nr) * 2) : \ - (0x55 + (((nr) - 6) * 2))) -static u8 SMSC47M192_REG_TEMP[3] = { 0x27, 0x26, 0x52 }; -static u8 SMSC47M192_REG_TEMP_MAX[3] = { 0x39, 0x37, 0x58 }; -static u8 SMSC47M192_REG_TEMP_MIN[3] = { 0x3A, 0x38, 0x59 }; -#define SMSC47M192_REG_TEMP_OFFSET(nr) ((nr)==2 ? 0x1e : 0x1f) -#define SMSC47M192_REG_ALARM1 0x41 -#define SMSC47M192_REG_ALARM2 0x42 -#define SMSC47M192_REG_VID 0x47 -#define SMSC47M192_REG_VID4 0x49 -#define SMSC47M192_REG_CONFIG 0x40 -#define SMSC47M192_REG_SFR 0x4f -#define SMSC47M192_REG_COMPANY_ID 0x3e -#define SMSC47M192_REG_VERSION 0x3f - -/* generalised scaling with integer rounding */ -static inline int SCALE(long val, int mul, int div) -{ - if (val < 0) - return (val * mul - div / 2) / div; - else - return (val * mul + div / 2) / div; -} - -/* Conversions */ - -/* smsc47m192 internally scales voltage measurements */ -static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 }; - -static inline unsigned int IN_FROM_REG(u8 reg, int n) -{ - return SCALE(reg, nom_mv[n], 192); -} - -static inline u8 IN_TO_REG(unsigned long val, int n) -{ - return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255); -} - -/* TEMP: 0.001 degC units (-128C to +127C) - REG: 1C/bit, two's complement */ -static inline s8 TEMP_TO_REG(int val) -{ - return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000); -} - -static inline int TEMP_FROM_REG(s8 val) -{ - return val * 1000; -} - -struct smsc47m192_data { - struct i2c_client client; - struct class_device *class_dev; - struct semaphore update_lock; - char valid; /* !=0 if following fields are valid */ - unsigned long last_updated; /* In jiffies */ - - u8 in[8]; /* Register value */ - u8 in_max[8]; /* Register value */ - u8 in_min[8]; /* Register value */ - s8 temp[3]; /* Register value */ - s8 temp_max[3]; /* Register value */ - s8 temp_min[3]; /* Register value */ - s8 temp_offset[3]; /* Register value */ - u16 alarms; /* Register encoding, combined */ - u8 vid; /* Register encoding, combined */ - u8 vrm; -}; - -static int smsc47m192_attach_adapter(struct i2c_adapter *adapter); -static int smsc47m192_detect(struct i2c_adapter *adapter, int address, - int kind); -static int smsc47m192_detach_client(struct i2c_client *client); -static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); - -static struct i2c_driver smsc47m192_driver = { - .driver = { - .name = "smsc47m192", - }, - .attach_adapter = smsc47m192_attach_adapter, - .detach_client = smsc47m192_detach_client, -}; - -/* Voltages */ -static ssize_t show_in(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr)); -} - -static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr)); -} - -static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr)); -} - -static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - - down(&data->update_lock); - data->in_min[nr] = IN_TO_REG(val, nr); - i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), - data->in_min[nr]); - up(&data->update_lock); - return count; -} - -static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - - down(&data->update_lock); - data->in_max[nr] = IN_TO_REG(val, nr); - i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), - data->in_max[nr]); - up(&data->update_lock); - return count; -} - -#define show_in_offset(offset) \ -static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in, NULL, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in_min, set_in_min, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in_max, set_in_max, offset); - -show_in_offset(0) -show_in_offset(1) -show_in_offset(2) -show_in_offset(3) -show_in_offset(4) -show_in_offset(5) -show_in_offset(6) -show_in_offset(7) - -/* Temperatures */ -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); -} - -static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); -} - -static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); -} - -static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - - down(&data->update_lock); - data->temp_min[nr] = TEMP_TO_REG(val); - i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], - data->temp_min[nr]); - up(&data->update_lock); - return count; -} - -static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - - down(&data->update_lock); - data->temp_max[nr] = TEMP_TO_REG(val); - i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], - data->temp_max[nr]); - up(&data->update_lock); - return count; -} - -static ssize_t show_temp_offset(struct device *dev, struct device_attribute - *attr, char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr])); -} - -static ssize_t set_temp_offset(struct device *dev, struct device_attribute - *attr, const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); - long val = simple_strtol(buf, NULL, 10); - - down(&data->update_lock); - data->temp_offset[nr] = TEMP_TO_REG(val); - if (nr>1) - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); - else if (data->temp_offset[nr] != 0) { - /* offset[0] and offset[1] share the same register, - SFR bit 4 activates offset[0] */ - i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, - (sfr & 0xef) | (nr==0 ? 0x10 : 0)); - data->temp_offset[1-nr] = 0; - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); - } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_TEMP_OFFSET(nr), 0); - up(&data->update_lock); - return count; -} - -#define show_temp_index(index) \ -static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, \ - show_temp, NULL, index-1); \ -static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO | S_IWUSR, \ - show_temp_min, set_temp_min, index-1); \ -static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO | S_IWUSR, \ - show_temp_max, set_temp_max, index-1); \ -static SENSOR_DEVICE_ATTR(temp##index##_offset, S_IRUGO | S_IWUSR, \ - show_temp_offset, set_temp_offset, index-1); - -show_temp_index(1) -show_temp_index(2) -show_temp_index(3) - -/* VID */ -static ssize_t show_vid(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); -} -static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); - -static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%d\n", data->vrm); -} - -static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - data->vrm = simple_strtoul(buf, NULL, 10); - return count; -} -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); - -/* Alarms */ -static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct smsc47m192_data *data = smsc47m192_update_device(dev); - return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0); -} - -static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); -static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); -static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); -static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000); -static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000); -static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); -static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); -static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); -static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 0x0008); -static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 0x0100); -static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200); -static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400); -static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800); - -/* This function is called when: - * smsc47m192_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and smsc47m192_driver is still present) */ -static int smsc47m192_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, smsc47m192_detect); -} - -static void smsc47m192_init_client(struct i2c_client *client) -{ - int i; - u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); - u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); - - /* select cycle mode (pause 1 sec between updates) */ - i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, - (sfr & 0xfd) | 0x02); - if (!(config & 0x01)) { - /* initialize alarm limits */ - for (i=0; i<8; i++) { - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_IN_MIN(i), 0); - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_IN_MAX(i), 0xff); - } - for (i=0; i<3; i++) { - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_TEMP_MIN[i], 0x80); - i2c_smbus_write_byte_data(client, - SMSC47M192_REG_TEMP_MAX[i], 0x7f); - } - - /* start monitoring */ - i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG, - (config & 0xf7) | 0x01); - } -} - -/* This function is called by i2c_probe */ -static int smsc47m192_detect(struct i2c_adapter *adapter, int address, - int kind) -{ - struct i2c_client *client; - struct smsc47m192_data *data; - int err = 0; - int version, config; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &smsc47m192_driver; - - if (kind == 0) - kind = smsc47m192; - - /* Detection criteria from sensors_detect script */ - if (kind < 0) { - if (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_COMPANY_ID) == 0x55 - && ((version = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_VERSION)) & 0xf0) == 0x20 - && (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_VID) & 0x70) == 0x00 - && (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_VID4) & 0xfe) == 0x80) { - dev_info(&adapter->dev, - "found SMSC47M192 or SMSC47M997, " - "version 2, stepping A%d\n", version & 0x0f); - } else { - dev_dbg(&adapter->dev, - "SMSC47M192 detection failed at 0x%02x\n", - address); - goto exit_free; - } - } - - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); - data->vrm = vid_which_vrm(); - init_MUTEX(&data->update_lock); - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; - - /* Initialize the SMSC47M192 chip */ - smsc47m192_init_client(client); - - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_detach; - } - - device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr); - - /* Pin 110 is either in4 (+12V) or VID4 */ - config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); - if (!(config & 0x20)) { - device_create_file(&client->dev, - &sensor_dev_attr_in4_input.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_max.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_alarm.dev_attr); - } - device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp1_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp2_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp2_input_fault.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp3_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp3_input_fault.dev_attr); - device_create_file(&client->dev, &dev_attr_cpu0_vid); - device_create_file(&client->dev, &dev_attr_vrm); - - return 0; - -exit_detach: - i2c_detach_client(client); -exit_free: - kfree(data); -exit: - return err; -} - -static int smsc47m192_detach_client(struct i2c_client *client) -{ - struct smsc47m192_data *data = i2c_get_clientdata(client); - int err; - - hwmon_device_unregister(data->class_dev); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(data); - - return 0; -} - -static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct smsc47m192_data *data = i2c_get_clientdata(client); - int i, config; - - down(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); - - dev_dbg(&client->dev, "Starting smsc47m192 update\n"); - - for (i = 0; i <= 7; i++) { - data->in[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_IN(i)); - data->in_min[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_IN_MIN(i)); - data->in_max[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_IN_MAX(i)); - } - for (i = 0; i < 3; i++) { - data->temp[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_TEMP[i]); - data->temp_max[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_TEMP_MAX[i]); - data->temp_min[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_TEMP_MIN[i]); - } - for (i = 1; i < 3; i++) - data->temp_offset[i] = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_TEMP_OFFSET(i)); - /* first offset is temp_offset[0] if SFR bit 4 is set, - temp_offset[1] otherwise */ - if (sfr & 0x10) { - data->temp_offset[0] = data->temp_offset[1]; - data->temp_offset[1] = 0; - } else - data->temp_offset[0] = 0; - - data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID) - & 0x0f; - config = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_CONFIG); - if (config & 0x20) - data->vid |= (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_VID4) & 0x01) << 4; - data->alarms = i2c_smbus_read_byte_data(client, - SMSC47M192_REG_ALARM1) | - (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_ALARM2) << 8); - - data->last_updated = jiffies; - data->valid = 1; - } - - up(&data->update_lock); - - return data; -} - -static int __init smsc47m192_init(void) -{ - return i2c_add_driver(&smsc47m192_driver); -} - -static void __exit smsc47m192_exit(void) -{ - i2c_del_driver(&smsc47m192_driver); -} - -MODULE_AUTHOR("Hartmut Rick "); -MODULE_DESCRIPTION("SMSC47M192 driver"); -MODULE_LICENSE("GPL"); - -module_init(smsc47m192_init); -module_exit(smsc47m192_exit); diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 40301bc6ce18..b6bd5685fd38 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -30,7 +30,10 @@ Supports the following chips: Chip #vin #fan #pwm #temp chip_id man_id - w83627ehf 10 5 - 3 0x88 0x5ca3 + w83627ehf - 5 - 3 0x88 0x5ca3 + + This is a preliminary version of the driver, only supporting the + fan and temperature inputs. The chip does much more than that. */ #include @@ -118,14 +121,6 @@ superio_exit(void) static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; -/* The W83627EHF registers for nr=7,8,9 are in bank 5 */ -#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ - (0x554 + (((nr) - 7) * 2))) -#define W83627EHF_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ - (0x555 + (((nr) - 7) * 2))) -#define W83627EHF_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ - (0x550 + (nr) - 7)) - #define W83627EHF_REG_TEMP1 0x27 #define W83627EHF_REG_TEMP1_HYST 0x3a #define W83627EHF_REG_TEMP1_OVER 0x39 @@ -141,10 +136,6 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 }; #define W83627EHF_REG_DIODE 0x59 #define W83627EHF_REG_SMI_OVT 0x4C -#define W83627EHF_REG_ALARM1 0x459 -#define W83627EHF_REG_ALARM2 0x45A -#define W83627EHF_REG_ALARM3 0x45B - /* * Conversions */ @@ -181,20 +172,6 @@ temp1_to_reg(int temp) return (temp + 500) / 1000; } -/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ - -static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; - -static inline long in_from_reg(u8 reg, u8 nr) -{ - return reg * scale_in[nr]; -} - -static inline u8 in_to_reg(u32 val, u8 nr) -{ - return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 255); -} - /* * Data structures and manipulation thereof */ @@ -209,9 +186,6 @@ struct w83627ehf_data { unsigned long last_updated; /* In jiffies */ /* Register values */ - u8 in[10]; /* Register value */ - u8 in_max[10]; /* Register value */ - u8 in_min[10]; /* Register value */ u8 fan[5]; u8 fan_min[5]; u8 fan_div[5]; @@ -222,7 +196,6 @@ struct w83627ehf_data { s16 temp[2]; s16 temp_max[2]; s16 temp_max_hyst[2]; - u32 alarms; }; static inline int is_word_sized(u16 reg) @@ -376,16 +349,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) data->fan_div[3] |= (i >> 5) & 0x04; } - /* Measured voltages and limits */ - for (i = 0; i < 10; i++) { - data->in[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN(i)); - data->in_min[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN_MIN(i)); - data->in_max[i] = w83627ehf_read_value(client, - W83627EHF_REG_IN_MAX(i)); - } - /* Measured fan speeds and limits */ for (i = 0; i < 5; i++) { if (!(data->has_fan & (1 << i))) @@ -432,13 +395,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) W83627EHF_REG_TEMP_HYST[i]); } - data->alarms = w83627ehf_read_value(client, - W83627EHF_REG_ALARM1) | - (w83627ehf_read_value(client, - W83627EHF_REG_ALARM2) << 8) | - (w83627ehf_read_value(client, - W83627EHF_REG_ALARM3) << 16); - data->last_updated = jiffies; data->valid = 1; } @@ -450,109 +406,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) /* * Sysfs callback functions */ -#define show_in_reg(reg) \ -static ssize_t \ -show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct w83627ehf_data *data = w83627ehf_update_device(dev); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ - return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ -} -show_in_reg(in) -show_in_reg(in_min) -show_in_reg(in_max) - -#define store_in_reg(REG, reg) \ -static ssize_t \ -store_in_##reg (struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83627ehf_data *data = i2c_get_clientdata(client); \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ - int nr = sensor_attr->index; \ - u32 val = simple_strtoul(buf, NULL, 10); \ - \ - mutex_lock(&data->update_lock); \ - data->in_##reg[nr] = in_to_reg(val, nr); \ - w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ - data->in_##reg[nr]); \ - mutex_unlock(&data->update_lock); \ - return count; \ -} - -store_in_reg(MIN, min) -store_in_reg(MAX, max) - -static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct w83627ehf_data *data = w83627ehf_update_device(dev); - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - return sprintf(buf, "%u\n", (data->alarms >> nr) & 0x01); -} - -static struct sensor_device_attribute sda_in_input[] = { - SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), - SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), - SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), - SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), - SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), - SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), - SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), - SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), - SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), -}; - -static struct sensor_device_attribute sda_in_alarm[] = { - SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), - SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), - SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), - SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), - SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), - SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21), - SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20), - SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16), - SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17), - SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19), -}; - -static struct sensor_device_attribute sda_in_min[] = { - SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), - SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), - SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), - SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), - SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), - SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), - SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), - SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), - SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), - SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), -}; - -static struct sensor_device_attribute sda_in_max[] = { - SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), - SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), - SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), - SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), - SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), - SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), - SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), - SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), - SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), - SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), -}; - -static void device_create_file_in(struct device *dev, int i) -{ - device_create_file(dev, &sda_in_input[i].dev_attr); - device_create_file(dev, &sda_in_alarm[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); -} #define show_fan_reg(reg) \ static ssize_t \ @@ -652,14 +505,6 @@ static struct sensor_device_attribute sda_fan_input[] = { SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), }; -static struct sensor_device_attribute sda_fan_alarm[] = { - SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), - SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), - SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11), - SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10), - SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23), -}; - static struct sensor_device_attribute sda_fan_min[] = { SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 0), @@ -684,7 +529,6 @@ static struct sensor_device_attribute sda_fan_div[] = { static void device_create_file_fan(struct device *dev, int i) { device_create_file(dev, &sda_fan_input[i].dev_attr); - device_create_file(dev, &sda_fan_alarm[i].dev_attr); device_create_file(dev, &sda_fan_div[i].dev_attr); device_create_file(dev, &sda_fan_min[i].dev_attr); } @@ -772,9 +616,6 @@ static struct sensor_device_attribute sda_temp[] = { store_temp_max_hyst, 0), SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, store_temp_max_hyst, 1), - SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), - SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), - SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), }; /* @@ -864,9 +705,6 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) goto exit_detach; } - for (i = 0; i < 10; i++) - device_create_file_in(dev, i); - for (i = 0; i < 5; i++) { if (data->has_fan & (1 << i)) device_create_file_fan(dev, i); diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index 79368d53c363..71fb7f1af8f5 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -781,7 +781,7 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index 7be469ed0f8f..e4c700356c44 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -630,7 +630,7 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c deleted file mode 100644 index eec43abd57fb..000000000000 --- a/trunk/drivers/hwmon/w83791d.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - w83791d.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - - Copyright (C) 2006 Charles Spirakis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83791d 10 5 3 3 0x71 0x5ca3 yes no - - The w83791d chip appears to be part way between the 83781d and the - 83792d. Thus, this file is derived from both the w83792d.c and - w83781d.c files, but its output is more along the lines of the - 83781d (which means there are no changes to the user-mode sensors - program which treats the 83791d as an 83781d). -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUMBER_OF_VIN 10 -#define NUMBER_OF_FANIN 5 -#define NUMBER_OF_TEMPIN 3 - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(w83791d); -I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " - "{bus, clientaddr, subclientaddr1, subclientaddr2}"); - -static int reset; -module_param(reset, bool, 0); -MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset"); - -static int init; -module_param(init, bool, 0); -MODULE_PARM_DESC(init, "Set to one to force extra software initialization"); - -/* The W83791D registers */ -static const u8 W83791D_REG_IN[NUMBER_OF_VIN] = { - 0x20, /* VCOREA in DataSheet */ - 0x21, /* VINR0 in DataSheet */ - 0x22, /* +3.3VIN in DataSheet */ - 0x23, /* VDD5V in DataSheet */ - 0x24, /* +12VIN in DataSheet */ - 0x25, /* -12VIN in DataSheet */ - 0x26, /* -5VIN in DataSheet */ - 0xB0, /* 5VSB in DataSheet */ - 0xB1, /* VBAT in DataSheet */ - 0xB2 /* VINR1 in DataSheet */ -}; - -static const u8 W83791D_REG_IN_MAX[NUMBER_OF_VIN] = { - 0x2B, /* VCOREA High Limit in DataSheet */ - 0x2D, /* VINR0 High Limit in DataSheet */ - 0x2F, /* +3.3VIN High Limit in DataSheet */ - 0x31, /* VDD5V High Limit in DataSheet */ - 0x33, /* +12VIN High Limit in DataSheet */ - 0x35, /* -12VIN High Limit in DataSheet */ - 0x37, /* -5VIN High Limit in DataSheet */ - 0xB4, /* 5VSB High Limit in DataSheet */ - 0xB6, /* VBAT High Limit in DataSheet */ - 0xB8 /* VINR1 High Limit in DataSheet */ -}; -static const u8 W83791D_REG_IN_MIN[NUMBER_OF_VIN] = { - 0x2C, /* VCOREA Low Limit in DataSheet */ - 0x2E, /* VINR0 Low Limit in DataSheet */ - 0x30, /* +3.3VIN Low Limit in DataSheet */ - 0x32, /* VDD5V Low Limit in DataSheet */ - 0x34, /* +12VIN Low Limit in DataSheet */ - 0x36, /* -12VIN Low Limit in DataSheet */ - 0x38, /* -5VIN Low Limit in DataSheet */ - 0xB5, /* 5VSB Low Limit in DataSheet */ - 0xB7, /* VBAT Low Limit in DataSheet */ - 0xB9 /* VINR1 Low Limit in DataSheet */ -}; -static const u8 W83791D_REG_FAN[NUMBER_OF_FANIN] = { - 0x28, /* FAN 1 Count in DataSheet */ - 0x29, /* FAN 2 Count in DataSheet */ - 0x2A, /* FAN 3 Count in DataSheet */ - 0xBA, /* FAN 4 Count in DataSheet */ - 0xBB, /* FAN 5 Count in DataSheet */ -}; -static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = { - 0x3B, /* FAN 1 Count Low Limit in DataSheet */ - 0x3C, /* FAN 2 Count Low Limit in DataSheet */ - 0x3D, /* FAN 3 Count Low Limit in DataSheet */ - 0xBC, /* FAN 4 Count Low Limit in DataSheet */ - 0xBD, /* FAN 5 Count Low Limit in DataSheet */ -}; - -static const u8 W83791D_REG_FAN_CFG[2] = { - 0x84, /* FAN 1/2 configuration */ - 0x95, /* FAN 3 configuration */ -}; - -static const u8 W83791D_REG_FAN_DIV[3] = { - 0x47, /* contains FAN1 and FAN2 Divisor */ - 0x4b, /* contains FAN3 Divisor */ - 0x5C, /* contains FAN4 and FAN5 Divisor */ -}; - -#define W83791D_REG_BANK 0x4E -#define W83791D_REG_TEMP2_CONFIG 0xC2 -#define W83791D_REG_TEMP3_CONFIG 0xCA - -static const u8 W83791D_REG_TEMP1[3] = { - 0x27, /* TEMP 1 in DataSheet */ - 0x39, /* TEMP 1 Over in DataSheet */ - 0x3A, /* TEMP 1 Hyst in DataSheet */ -}; - -static const u8 W83791D_REG_TEMP_ADD[2][6] = { - {0xC0, /* TEMP 2 in DataSheet */ - 0xC1, /* TEMP 2(0.5 deg) in DataSheet */ - 0xC5, /* TEMP 2 Over High part in DataSheet */ - 0xC6, /* TEMP 2 Over Low part in DataSheet */ - 0xC3, /* TEMP 2 Thyst High part in DataSheet */ - 0xC4}, /* TEMP 2 Thyst Low part in DataSheet */ - {0xC8, /* TEMP 3 in DataSheet */ - 0xC9, /* TEMP 3(0.5 deg) in DataSheet */ - 0xCD, /* TEMP 3 Over High part in DataSheet */ - 0xCE, /* TEMP 3 Over Low part in DataSheet */ - 0xCB, /* TEMP 3 Thyst High part in DataSheet */ - 0xCC} /* TEMP 3 Thyst Low part in DataSheet */ -}; - -#define W83791D_REG_BEEP_CONFIG 0x4D - -static const u8 W83791D_REG_BEEP_CTRL[3] = { - 0x56, /* BEEP Control Register 1 */ - 0x57, /* BEEP Control Register 2 */ - 0xA3, /* BEEP Control Register 3 */ -}; - -#define W83791D_REG_CONFIG 0x40 -#define W83791D_REG_VID_FANDIV 0x47 -#define W83791D_REG_DID_VID4 0x49 -#define W83791D_REG_WCHIPID 0x58 -#define W83791D_REG_CHIPMAN 0x4F -#define W83791D_REG_PIN 0x4B -#define W83791D_REG_I2C_SUBADDR 0x4A - -#define W83791D_REG_ALARM1 0xA9 /* realtime status register1 */ -#define W83791D_REG_ALARM2 0xAA /* realtime status register2 */ -#define W83791D_REG_ALARM3 0xAB /* realtime status register3 */ - -#define W83791D_REG_VBAT 0x5D -#define W83791D_REG_I2C_ADDR 0x48 - -/* The SMBus locks itself. The Winbond W83791D has a bank select register - (index 0x4e), but the driver only accesses registers in bank 0. Since - we don't switch banks, we don't need any special code to handle - locking access between bank switches */ -static inline int w83791d_read(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -/* The analog voltage inputs have 16mV LSB. Since the sysfs output is - in mV as would be measured on the chip input pin, need to just - multiply/divide by 16 to translate from/to register values. */ -#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8) / 16), 0, 255)) -#define IN_FROM_REG(val) ((val) * 16) - -static u8 fan_to_reg(long rpm, int div) -{ - if (rpm == 0) - return 255; - rpm = SENSORS_LIMIT(rpm, 1, 1000000); - return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); -} - -#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ - ((val) == 255 ? 0 : \ - 1350000 / ((val) * (div)))) - -/* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */ -#define TEMP1_FROM_REG(val) ((val) * 1000) -#define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \ - (val) >= 127000 ? 127 : \ - (val) < 0 ? ((val) - 500) / 1000 : \ - ((val) + 500) / 1000) - -/* for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius - Assumes the top 8 bits are the integral amount and the bottom 8 bits - are the fractional amount. Since we only have 0.5 degree resolution, - the bottom 7 bits will always be zero */ -#define TEMP23_FROM_REG(val) ((val) / 128 * 500) -#define TEMP23_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ - (val) >= 127500 ? 0x7F80 : \ - (val) < 0 ? ((val) - 250) / 500 * 128 : \ - ((val) + 250) / 500 * 128) - - -#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) -#define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff) - -#define DIV_FROM_REG(val) (1 << (val)) - -static u8 div_to_reg(int nr, long val) -{ - int i; - int max; - - /* first three fan's divisor max out at 8, rest max out at 128 */ - max = (nr < 3) ? 8 : 128; - val = SENSORS_LIMIT(val, 1, max) >> 1; - for (i = 0; i < 7; i++) { - if (val == 0) - break; - val >>= 1; - } - return (u8) i; -} - -struct w83791d_data { - struct i2c_client client; - struct class_device *class_dev; - struct mutex update_lock; - - char valid; /* !=0 if following fields are valid */ - unsigned long last_updated; /* In jiffies */ - - /* array of 2 pointers to subclients */ - struct i2c_client *lm75[2]; - - /* volts */ - u8 in[NUMBER_OF_VIN]; /* Register value */ - u8 in_max[NUMBER_OF_VIN]; /* Register value */ - u8 in_min[NUMBER_OF_VIN]; /* Register value */ - - /* fans */ - u8 fan[NUMBER_OF_FANIN]; /* Register value */ - u8 fan_min[NUMBER_OF_FANIN]; /* Register value */ - u8 fan_div[NUMBER_OF_FANIN]; /* Register encoding, shifted right */ - - /* Temperature sensors */ - - s8 temp1[3]; /* current, over, thyst */ - s16 temp_add[2][3]; /* fixed point value. Top 8 bits are the - integral part, bottom 8 bits are the - fractional part. We only use the top - 9 bits as the resolution is only - to the 0.5 degree C... - two sensors with three values - (cur, over, hyst) */ - - /* Misc */ - u32 alarms; /* realtime status register encoding,combined */ - u8 beep_enable; /* Global beep enable */ - u32 beep_mask; /* Mask off specific beeps */ - u8 vid; /* Register encoding, combined */ - u8 vrm; /* hwmon-vid */ -}; - -static int w83791d_attach_adapter(struct i2c_adapter *adapter); -static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind); -static int w83791d_detach_client(struct i2c_client *client); - -static int w83791d_read(struct i2c_client *client, u8 register); -static int w83791d_write(struct i2c_client *client, u8 register, u8 value); -static struct w83791d_data *w83791d_update_device(struct device *dev); - -#ifdef DEBUG -static void w83791d_print_debug(struct w83791d_data *data, struct device *dev); -#endif - -static void w83791d_init_client(struct i2c_client *client); - -static struct i2c_driver w83791d_driver = { - .driver = { - .name = "w83791d", - }, - .attach_adapter = w83791d_attach_adapter, - .detach_client = w83791d_detach_client, -}; - -/* following are the sysfs callback functions */ -#define show_in_reg(reg) \ -static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct sensor_device_attribute *sensor_attr = \ - to_sensor_dev_attr(attr); \ - struct w83791d_data *data = w83791d_update_device(dev); \ - int nr = sensor_attr->index; \ - return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \ -} - -show_in_reg(in); -show_in_reg(in_min); -show_in_reg(in_max); - -#define store_in_reg(REG, reg) \ -static ssize_t store_in_##reg(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct sensor_device_attribute *sensor_attr = \ - to_sensor_dev_attr(attr); \ - struct i2c_client *client = to_i2c_client(dev); \ - struct w83791d_data *data = i2c_get_clientdata(client); \ - unsigned long val = simple_strtoul(buf, NULL, 10); \ - int nr = sensor_attr->index; \ - \ - mutex_lock(&data->update_lock); \ - data->in_##reg[nr] = IN_TO_REG(val); \ - w83791d_write(client, W83791D_REG_IN_##REG[nr], data->in_##reg[nr]); \ - mutex_unlock(&data->update_lock); \ - \ - return count; \ -} -store_in_reg(MIN, min); -store_in_reg(MAX, max); - -static struct sensor_device_attribute sda_in_input[] = { - SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), - SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), - SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), - SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), - SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), - SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), - SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), - SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), - SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), -}; - -static struct sensor_device_attribute sda_in_min[] = { - SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), - SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), - SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), - SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), - SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), - SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), - SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), - SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), - SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), - SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), -}; - -static struct sensor_device_attribute sda_in_max[] = { - SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), - SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), - SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), - SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), - SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), - SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), - SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), - SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), - SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), - SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), -}; - -#define show_fan_reg(reg) \ -static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct sensor_device_attribute *sensor_attr = \ - to_sensor_dev_attr(attr); \ - struct w83791d_data *data = w83791d_update_device(dev); \ - int nr = sensor_attr->index; \ - return sprintf(buf,"%d\n", \ - FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ -} - -show_fan_reg(fan); -show_fan_reg(fan_min); - -static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - int nr = sensor_attr->index; - - mutex_lock(&data->update_lock); - data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr])); - w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr])); -} - -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least suprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ -static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - int nr = sensor_attr->index; - unsigned long min; - u8 tmp_fan_div; - u8 fan_div_reg; - int indx = 0; - u8 keep_mask = 0; - u8 new_shift = 0; - - /* Save fan_min */ - min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); - - mutex_lock(&data->update_lock); - data->fan_div[nr] = div_to_reg(nr, simple_strtoul(buf, NULL, 10)); - - switch (nr) { - case 0: - indx = 0; - keep_mask = 0xcf; - new_shift = 4; - break; - case 1: - indx = 0; - keep_mask = 0x3f; - new_shift = 6; - break; - case 2: - indx = 1; - keep_mask = 0x3f; - new_shift = 6; - break; - case 3: - indx = 2; - keep_mask = 0xf8; - new_shift = 0; - break; - case 4: - indx = 2; - keep_mask = 0x8f; - new_shift = 4; - break; -#ifdef DEBUG - default: - dev_warn(dev, "store_fan_div: Unexpected nr seen: %d\n", nr); - count = -EINVAL; - goto err_exit; -#endif - } - - fan_div_reg = w83791d_read(client, W83791D_REG_FAN_DIV[indx]) - & keep_mask; - tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask; - - w83791d_write(client, W83791D_REG_FAN_DIV[indx], - fan_div_reg | tmp_fan_div); - - /* Restore fan_min */ - data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); - w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); - -#ifdef DEBUG -err_exit: -#endif - mutex_unlock(&data->update_lock); - - return count; -} - -static struct sensor_device_attribute sda_fan_input[] = { - SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), - SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), - SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), - SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), - SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), -}; - -static struct sensor_device_attribute sda_fan_min[] = { - SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, - show_fan_min, store_fan_min, 0), - SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, - show_fan_min, store_fan_min, 1), - SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, - show_fan_min, store_fan_min, 2), - SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, - show_fan_min, store_fan_min, 3), - SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, - show_fan_min, store_fan_min, 4), -}; - -static struct sensor_device_attribute sda_fan_div[] = { - SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, - show_fan_div, store_fan_div, 0), - SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, - show_fan_div, store_fan_div, 1), - SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, - show_fan_div, store_fan_div, 2), - SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, - show_fan_div, store_fan_div, 3), - SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, - show_fan_div, store_fan_div, 4), -}; - -/* read/write the temperature1, includes measured value and limits */ -static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[attr->index])); -} - -static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - int nr = attr->index; - - mutex_lock(&data->update_lock); - data->temp1[nr] = TEMP1_TO_REG(val); - w83791d_write(client, W83791D_REG_TEMP1[nr], data->temp1[nr]); - mutex_unlock(&data->update_lock); - return count; -} - -/* read/write temperature2-3, includes measured value and limits */ -static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct w83791d_data *data = w83791d_update_device(dev); - int nr = attr->nr; - int index = attr->index; - return sprintf(buf, "%d\n", TEMP23_FROM_REG(data->temp_add[nr][index])); -} - -static ssize_t store_temp23(struct device *dev, - struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - int nr = attr->nr; - int index = attr->index; - - mutex_lock(&data->update_lock); - data->temp_add[nr][index] = TEMP23_TO_REG(val); - w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2], - data->temp_add[nr][index] >> 8); - w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2 + 1], - data->temp_add[nr][index] & 0x80); - mutex_unlock(&data->update_lock); - - return count; -} - -static struct sensor_device_attribute_2 sda_temp_input[] = { - SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0), - SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0), - SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0), -}; - -static struct sensor_device_attribute_2 sda_temp_max[] = { - SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, - show_temp1, store_temp1, 0, 1), - SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, - show_temp23, store_temp23, 0, 1), - SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, - show_temp23, store_temp23, 1, 1), -}; - -static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { - SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, - show_temp1, store_temp1, 0, 2), - SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, - show_temp23, store_temp23, 0, 2), - SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, - show_temp23, store_temp23, 1, 2), -}; - - -/* get reatime status of all sensors items: voltage, temp, fan */ -static ssize_t show_alarms_reg(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%u\n", data->alarms); -} - -static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); - -/* Beep control */ - -#define GLOBAL_BEEP_ENABLE_SHIFT 15 -#define GLOBAL_BEEP_ENABLE_MASK (1 << GLOBAL_BEEP_ENABLE_SHIFT) - -static ssize_t show_beep_enable(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%d\n", data->beep_enable); -} - -static ssize_t show_beep_mask(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%d\n", BEEP_MASK_FROM_REG(data->beep_mask)); -} - - -static ssize_t store_beep_mask(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - int i; - - mutex_lock(&data->update_lock); - - /* The beep_enable state overrides any enabling request from - the masks */ - data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK; - data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT); - - val = data->beep_mask; - - for (i = 0; i < 3; i++) { - w83791d_write(client, W83791D_REG_BEEP_CTRL[i], (val & 0xff)); - val >>= 8; - } - - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t store_beep_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); - - mutex_lock(&data->update_lock); - - data->beep_enable = val ? 1 : 0; - - /* Keep the full mask value in sync with the current enable */ - data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK; - data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT); - - /* The global control is in the second beep control register - so only need to update that register */ - val = (data->beep_mask >> 8) & 0xff; - - w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val); - - mutex_unlock(&data->update_lock); - - return count; -} - -static struct sensor_device_attribute sda_beep_ctrl[] = { - SENSOR_ATTR(beep_enable, S_IRUGO | S_IWUSR, - show_beep_enable, store_beep_enable, 0), - SENSOR_ATTR(beep_mask, S_IRUGO | S_IWUSR, - show_beep_mask, store_beep_mask, 1) -}; - -/* cpu voltage regulation information */ -static ssize_t show_vid_reg(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); -} - -static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); - -static ssize_t show_vrm_reg(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct w83791d_data *data = w83791d_update_device(dev); - return sprintf(buf, "%d\n", data->vrm); -} - -static ssize_t store_vrm_reg(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - - /* No lock needed as vrm is internal to the driver - (not read from a chip register) and so is not - updated in w83791d_update_device() */ - data->vrm = val; - - return count; -} - -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); - -/* This function is called when: - * w83791d_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and w83791d_driver is still present) */ -static int w83791d_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83791d_detect); -} - - -static int w83791d_create_subclient(struct i2c_adapter *adapter, - struct i2c_client *client, int addr, - struct i2c_client **sub_cli) -{ - int err; - struct i2c_client *sub_client; - - (*sub_cli) = sub_client = - kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(sub_client)) { - return -ENOMEM; - } - sub_client->addr = 0x48 + addr; - i2c_set_clientdata(sub_client, NULL); - sub_client->adapter = adapter; - sub_client->driver = &w83791d_driver; - strlcpy(sub_client->name, "w83791d subclient", I2C_NAME_SIZE); - if ((err = i2c_attach_client(sub_client))) { - dev_err(&client->dev, "subclient registration " - "at address 0x%x failed\n", sub_client->addr); - kfree(sub_client); - return err; - } - return 0; -} - - -static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, - int kind, struct i2c_client *client) -{ - struct w83791d_data *data = i2c_get_clientdata(client); - int i, id, err; - u8 val; - - id = i2c_adapter_id(adapter); - if (force_subclients[0] == id && force_subclients[1] == address) { - for (i = 2; i <= 3; i++) { - if (force_subclients[i] < 0x48 || - force_subclients[i] > 0x4f) { - dev_err(&client->dev, - "invalid subclient " - "address %d; must be 0x48-0x4f\n", - force_subclients[i]); - err = -ENODEV; - goto error_sc_0; - } - } - w83791d_write(client, W83791D_REG_I2C_SUBADDR, - (force_subclients[2] & 0x07) | - ((force_subclients[3] & 0x07) << 4)); - } - - val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); - if (!(val & 0x08)) { - err = w83791d_create_subclient(adapter, client, - val & 0x7, &data->lm75[0]); - if (err < 0) - goto error_sc_0; - } - if (!(val & 0x80)) { - if ((data->lm75[0] != NULL) && - ((val & 0x7) == ((val >> 4) & 0x7))) { - dev_err(&client->dev, - "duplicate addresses 0x%x, " - "use force_subclient\n", - data->lm75[0]->addr); - err = -ENODEV; - goto error_sc_1; - } - err = w83791d_create_subclient(adapter, client, - (val >> 4) & 0x7, &data->lm75[1]); - if (err < 0) - goto error_sc_1; - } - - return 0; - -/* Undo inits in case of errors */ - -error_sc_1: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } -error_sc_0: - return err; -} - - -static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct device *dev; - struct w83791d_data *data; - int i, val1, val2; - int err = 0; - const char *client_name = ""; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - goto error0; - } - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access w83791d_{read,write}_value. */ - if (!(data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL))) { - err = -ENOMEM; - goto error0; - } - - client = &data->client; - dev = &client->dev; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &w83791d_driver; - mutex_init(&data->update_lock); - - /* Now, we do the remaining detection. */ - - /* The w83791d may be stuck in some other bank than bank 0. This may - make reading other information impossible. Specify a force=... - parameter, and the Winbond will be reset to the right bank. */ - if (kind < 0) { - if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) { - dev_dbg(dev, "Detection failed at step 1\n"); - goto error1; - } - val1 = w83791d_read(client, W83791D_REG_BANK); - val2 = w83791d_read(client, W83791D_REG_CHIPMAN); - /* Check for Winbond ID if in bank 0 */ - if (!(val1 & 0x07)) { - /* yes it is Bank0 */ - if (((!(val1 & 0x80)) && (val2 != 0xa3)) || - ((val1 & 0x80) && (val2 != 0x5c))) { - dev_dbg(dev, "Detection failed at step 2\n"); - goto error1; - } - } - /* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR - should match */ - if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) { - dev_dbg(dev, "Detection failed at step 3\n"); - goto error1; - } - } - - /* We either have a force parameter or we have reason to - believe it is a Winbond chip. Either way, we want bank 0 and - Vendor ID high byte */ - val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78; - w83791d_write(client, W83791D_REG_BANK, val1 | 0x80); - - /* Verify it is a Winbond w83791d */ - if (kind <= 0) { - /* get vendor ID */ - val2 = w83791d_read(client, W83791D_REG_CHIPMAN); - if (val2 != 0x5c) { /* the vendor is NOT Winbond */ - dev_dbg(dev, "Detection failed at step 4\n"); - goto error1; - } - val1 = w83791d_read(client, W83791D_REG_WCHIPID); - if (val1 == 0x71) { - kind = w83791d; - } else { - if (kind == 0) - dev_warn(dev, - "w83791d: Ignoring 'force' parameter " - "for unknown chip at adapter %d, " - "address 0x%02x\n", - i2c_adapter_id(adapter), address); - goto error1; - } - } - - if (kind == w83791d) { - client_name = "w83791d"; - } else { - dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?", - kind); - goto error1; - } - -#ifdef DEBUG - val1 = w83791d_read(client, W83791D_REG_DID_VID4); - dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", - (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); -#endif - - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, client_name, I2C_NAME_SIZE); - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto error1; - - if ((err = w83791d_detect_subclients(adapter, address, kind, client))) - goto error2; - - /* Initialize the chip */ - w83791d_init_client(client); - - /* If the fan_div is changed, make sure there is a rational - fan_min in place */ - for (i = 0; i < NUMBER_OF_FANIN; i++) { - data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]); - } - - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto error3; - } - - for (i = 0; i < NUMBER_OF_VIN; i++) { - device_create_file(dev, &sda_in_input[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); - } - - for (i = 0; i < NUMBER_OF_FANIN; i++) { - device_create_file(dev, &sda_fan_input[i].dev_attr); - device_create_file(dev, &sda_fan_div[i].dev_attr); - device_create_file(dev, &sda_fan_min[i].dev_attr); - } - - for (i = 0; i < NUMBER_OF_TEMPIN; i++) { - device_create_file(dev, &sda_temp_input[i].dev_attr); - device_create_file(dev, &sda_temp_max[i].dev_attr); - device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); - } - - device_create_file(dev, &dev_attr_alarms); - - for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) { - device_create_file(dev, &sda_beep_ctrl[i].dev_attr); - } - - device_create_file(dev, &dev_attr_cpu0_vid); - device_create_file(dev, &dev_attr_vrm); - - return 0; - -error3: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } - if (data->lm75[1] != NULL) { - i2c_detach_client(data->lm75[1]); - kfree(data->lm75[1]); - } -error2: - i2c_detach_client(client); -error1: - kfree(data); -error0: - return err; -} - -static int w83791d_detach_client(struct i2c_client *client) -{ - struct w83791d_data *data = i2c_get_clientdata(client); - int err; - - /* main client */ - if (data) - hwmon_device_unregister(data->class_dev); - - if ((err = i2c_detach_client(client))) - return err; - - /* main client */ - if (data) - kfree(data); - /* subclient */ - else - kfree(client); - - return 0; -} - -static void w83791d_init_client(struct i2c_client *client) -{ - struct w83791d_data *data = i2c_get_clientdata(client); - u8 tmp; - u8 old_beep; - - /* The difference between reset and init is that reset - does a hard reset of the chip via index 0x40, bit 7, - but init simply forces certain registers to have "sane" - values. The hope is that the BIOS has done the right - thing (which is why the default is reset=0, init=0), - but if not, reset is the hard hammer and init - is the soft mallet both of which are trying to whack - things into place... - NOTE: The data sheet makes a distinction between - "power on defaults" and "reset by MR". As far as I can tell, - the hard reset puts everything into a power-on state so I'm - not sure what "reset by MR" means or how it can happen. - */ - if (reset || init) { - /* keep some BIOS settings when we... */ - old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG); - - if (reset) { - /* ... reset the chip and ... */ - w83791d_write(client, W83791D_REG_CONFIG, 0x80); - } - - /* ... disable power-on abnormal beep */ - w83791d_write(client, W83791D_REG_BEEP_CONFIG, old_beep | 0x80); - - /* disable the global beep (not done by hard reset) */ - tmp = w83791d_read(client, W83791D_REG_BEEP_CTRL[1]); - w83791d_write(client, W83791D_REG_BEEP_CTRL[1], tmp & 0xef); - - if (init) { - /* Make sure monitoring is turned on for add-ons */ - tmp = w83791d_read(client, W83791D_REG_TEMP2_CONFIG); - if (tmp & 1) { - w83791d_write(client, W83791D_REG_TEMP2_CONFIG, - tmp & 0xfe); - } - - tmp = w83791d_read(client, W83791D_REG_TEMP3_CONFIG); - if (tmp & 1) { - w83791d_write(client, W83791D_REG_TEMP3_CONFIG, - tmp & 0xfe); - } - - /* Start monitoring */ - tmp = w83791d_read(client, W83791D_REG_CONFIG) & 0xf7; - w83791d_write(client, W83791D_REG_CONFIG, tmp | 0x01); - } - } - - data->vrm = vid_which_vrm(); -} - -static struct w83791d_data *w83791d_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83791d_data *data = i2c_get_clientdata(client); - int i, j; - u8 reg_array_tmp[3]; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + (HZ * 3)) - || !data->valid) { - dev_dbg(dev, "Starting w83791d device update\n"); - - /* Update the voltages measured value and limits */ - for (i = 0; i < NUMBER_OF_VIN; i++) { - data->in[i] = w83791d_read(client, - W83791D_REG_IN[i]); - data->in_max[i] = w83791d_read(client, - W83791D_REG_IN_MAX[i]); - data->in_min[i] = w83791d_read(client, - W83791D_REG_IN_MIN[i]); - } - - /* Update the fan counts and limits */ - for (i = 0; i < NUMBER_OF_FANIN; i++) { - /* Update the Fan measured value and limits */ - data->fan[i] = w83791d_read(client, - W83791D_REG_FAN[i]); - data->fan_min[i] = w83791d_read(client, - W83791D_REG_FAN_MIN[i]); - } - - /* Update the fan divisor */ - for (i = 0; i < 3; i++) { - reg_array_tmp[i] = w83791d_read(client, - W83791D_REG_FAN_DIV[i]); - } - data->fan_div[0] = (reg_array_tmp[0] >> 4) & 0x03; - data->fan_div[1] = (reg_array_tmp[0] >> 6) & 0x03; - data->fan_div[2] = (reg_array_tmp[1] >> 6) & 0x03; - data->fan_div[3] = reg_array_tmp[2] & 0x07; - data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; - - /* Update the first temperature sensor */ - for (i = 0; i < 3; i++) { - data->temp1[i] = w83791d_read(client, - W83791D_REG_TEMP1[i]); - } - - /* Update the rest of the temperature sensors */ - for (i = 0; i < 2; i++) { - for (j = 0; j < 3; j++) { - data->temp_add[i][j] = - (w83791d_read(client, - W83791D_REG_TEMP_ADD[i][j * 2]) << 8) | - w83791d_read(client, - W83791D_REG_TEMP_ADD[i][j * 2 + 1]); - } - } - - /* Update the realtime status */ - data->alarms = - w83791d_read(client, W83791D_REG_ALARM1) + - (w83791d_read(client, W83791D_REG_ALARM2) << 8) + - (w83791d_read(client, W83791D_REG_ALARM3) << 16); - - /* Update the beep configuration information */ - data->beep_mask = - w83791d_read(client, W83791D_REG_BEEP_CTRL[0]) + - (w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) + - (w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16); - - data->beep_enable = - (data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01; - - /* Update the cpu voltage information */ - i = w83791d_read(client, W83791D_REG_VID_FANDIV); - data->vid = i & 0x0f; - data->vid |= (w83791d_read(client, W83791D_REG_DID_VID4) & 0x01) - << 4; - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - -#ifdef DEBUG - w83791d_print_debug(data, dev); -#endif - - return data; -} - -#ifdef DEBUG -static void w83791d_print_debug(struct w83791d_data *data, struct device *dev) -{ - int i = 0, j = 0; - - dev_dbg(dev, "======Start of w83791d debug values======\n"); - dev_dbg(dev, "%d set of Voltages: ===>\n", NUMBER_OF_VIN); - for (i = 0; i < NUMBER_OF_VIN; i++) { - dev_dbg(dev, "vin[%d] is: 0x%02x\n", i, data->in[i]); - dev_dbg(dev, "vin[%d] min is: 0x%02x\n", i, data->in_min[i]); - dev_dbg(dev, "vin[%d] max is: 0x%02x\n", i, data->in_max[i]); - } - dev_dbg(dev, "%d set of Fan Counts/Divisors: ===>\n", NUMBER_OF_FANIN); - for (i = 0; i < NUMBER_OF_FANIN; i++) { - dev_dbg(dev, "fan[%d] is: 0x%02x\n", i, data->fan[i]); - dev_dbg(dev, "fan[%d] min is: 0x%02x\n", i, data->fan_min[i]); - dev_dbg(dev, "fan_div[%d] is: 0x%02x\n", i, data->fan_div[i]); - } - - /* temperature math is signed, but only print out the - bits that matter */ - dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN); - for (i = 0; i < 3; i++) { - dev_dbg(dev, "temp1[%d] is: 0x%02x\n", i, (u8) data->temp1[i]); - } - for (i = 0; i < 2; i++) { - for (j = 0; j < 3; j++) { - dev_dbg(dev, "temp_add[%d][%d] is: 0x%04x\n", i, j, - (u16) data->temp_add[i][j]); - } - } - - dev_dbg(dev, "Misc Information: ===>\n"); - dev_dbg(dev, "alarm is: 0x%08x\n", data->alarms); - dev_dbg(dev, "beep_mask is: 0x%08x\n", data->beep_mask); - dev_dbg(dev, "beep_enable is: %d\n", data->beep_enable); - dev_dbg(dev, "vid is: 0x%02x\n", data->vid); - dev_dbg(dev, "vrm is: 0x%02x\n", data->vrm); - dev_dbg(dev, "=======End of w83791d debug values========\n"); - dev_dbg(dev, "\n"); -} -#endif - -static int __init sensors_w83791d_init(void) -{ - return i2c_add_driver(&w83791d_driver); -} - -static void __exit sensors_w83791d_exit(void) -{ - i2c_del_driver(&w83791d_driver); -} - -MODULE_AUTHOR("Charles Spirakis "); -MODULE_DESCRIPTION("W83791D driver"); -MODULE_LICENSE("GPL"); - -module_init(sensors_w83791d_init); -module_exit(sensors_w83791d_exit); diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index e407c74bda35..958602e28412 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -250,6 +250,8 @@ FAN_TO_REG(long rpm, int div) : (val)) / 1000, 0, 0xff)) #define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00) +#define PWM_FROM_REG(val) (val) +#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) #define DIV_FROM_REG(val) (1 << (val)) static inline u8 @@ -289,6 +291,7 @@ struct w83792d_data { u8 pwm[7]; /* We only consider the first 3 set of pwm, although 792 chip has 7 set of pwm. */ u8 pwmenable[3]; + u8 pwm_mode[7]; /* indicates PWM or DC mode: 1->PWM; 0->DC */ u32 alarms; /* realtime status register encoding,combined */ u8 chassis; /* Chassis status */ u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */ @@ -372,10 +375,8 @@ static ssize_t store_in_##reg (struct device *dev, \ u32 val; \ \ val = simple_strtoul(buf, NULL, 10); \ - mutex_lock(&data->update_lock); \ data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \ w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \ - mutex_unlock(&data->update_lock); \ \ return count; \ } @@ -442,11 +443,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, u32 val; val = simple_strtoul(buf, NULL, 10); - mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); - mutex_unlock(&data->update_lock); return count; } @@ -463,7 +462,7 @@ show_fan_div(struct device *dev, struct device_attribute *attr, /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just + least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, @@ -479,7 +478,6 @@ store_fan_div(struct device *dev, struct device_attribute *attr, u8 tmp_fan_div; /* Save fan_min */ - mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); @@ -495,7 +493,6 @@ store_fan_div(struct device *dev, struct device_attribute *attr, /* Restore fan_min */ data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); - mutex_unlock(&data->update_lock); return count; } @@ -550,11 +547,10 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr, s32 val; val = simple_strtol(buf, NULL, 10); - mutex_lock(&data->update_lock); + data->temp1[nr] = TEMP1_TO_REG(val); w83792d_write_value(client, W83792D_REG_TEMP1[nr], data->temp1[nr]); - mutex_unlock(&data->update_lock); return count; } @@ -584,14 +580,13 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr, s32 val; val = simple_strtol(buf, NULL, 10); - mutex_lock(&data->update_lock); + data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val); data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val); w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index], data->temp_add[nr][index]); w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1], data->temp_add[nr][index+1]); - mutex_unlock(&data->update_lock); return count; } @@ -632,7 +627,7 @@ show_pwm(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf, "%d\n", (data->pwm[nr] & 0x0f) << 4); + return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1])); } static ssize_t @@ -664,16 +659,14 @@ store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; + int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255) >> 4; + u32 val; - mutex_lock(&data->update_lock); - val |= w83792d_read_value(client, W83792D_REG_PWM[nr]) & 0xf0; - data->pwm[nr] = val; + val = simple_strtoul(buf, NULL, 10); + data->pwm[nr] = PWM_TO_REG(val); w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]); - mutex_unlock(&data->update_lock); return count; } @@ -690,10 +683,6 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp; val = simple_strtoul(buf, NULL, 10); - if (val < 1 || val > 3) - return -EINVAL; - - mutex_lock(&data->update_lock); switch (val) { case 1: data->pwmenable[nr] = 0; /* manual mode */ @@ -704,6 +693,8 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, case 3: data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */ break; + default: + return -EINVAL; } cfg1_tmp = data->pwmenable[0]; cfg2_tmp = (data->pwmenable[1]) << 2; @@ -711,15 +702,14 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0; fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp; w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp); - mutex_unlock(&data->update_lock); return count; } static struct sensor_device_attribute sda_pwm[] = { - SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), - SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), - SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), + SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), + SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), + SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), }; static struct sensor_device_attribute sda_pwm_enable[] = { SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, @@ -738,7 +728,7 @@ show_pwm_mode(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf, "%d\n", data->pwm[nr] >> 7); + return sprintf(buf, "%d\n", data->pwm_mode[nr-1]); } static ssize_t @@ -746,35 +736,29 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - int nr = sensor_attr->index; + int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); u32 val; + u8 pwm_mode_mask = 0; val = simple_strtoul(buf, NULL, 10); - if (val != 0 && val != 1) - return -EINVAL; - - mutex_lock(&data->update_lock); - data->pwm[nr] = w83792d_read_value(client, W83792D_REG_PWM[nr]); - if (val) { /* PWM mode */ - data->pwm[nr] |= 0x80; - } else { /* DC mode */ - data->pwm[nr] &= 0x7f; - } - w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]); - mutex_unlock(&data->update_lock); + data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1); + pwm_mode_mask = w83792d_read_value(client, + W83792D_REG_PWM[nr]) & 0x7f; + w83792d_write_value(client, W83792D_REG_PWM[nr], + ((data->pwm_mode[nr]) << 7) | pwm_mode_mask); return count; } static struct sensor_device_attribute sda_pwm_mode[] = { SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, - show_pwm_mode, store_pwm_mode, 0), - SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, store_pwm_mode, 1), - SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, + SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, store_pwm_mode, 2), + SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, + show_pwm_mode, store_pwm_mode, 3), }; @@ -805,13 +789,12 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr, u8 temp1 = 0, temp2 = 0; val = simple_strtoul(buf, NULL, 10); - mutex_lock(&data->update_lock); + data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); temp1 = ((data->chassis_clear) << 7) & 0x80; temp2 = w83792d_read_value(client, W83792D_REG_CHASSIS_CLR) & 0x7f; w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2); - mutex_unlock(&data->update_lock); return count; } @@ -844,12 +827,10 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr, val = simple_strtoul(buf, NULL, 10); target_tmp = val; target_tmp = target_tmp & 0x7f; - mutex_lock(&data->update_lock); target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80; data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255); w83792d_write_value(client, W83792D_REG_THERMAL[nr], (data->thermal_cruise[nr]) | target_mask); - mutex_unlock(&data->update_lock); return count; } @@ -886,7 +867,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr, u8 tol_tmp, tol_mask; val = simple_strtoul(buf, NULL, 10); - mutex_lock(&data->update_lock); tol_mask = w83792d_read_value(client, W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0); tol_tmp = SENSORS_LIMIT(val, 0, 15); @@ -897,7 +877,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr, } w83792d_write_value(client, W83792D_REG_TOLERANCE[nr], tol_mask | tol_tmp); - mutex_unlock(&data->update_lock); return count; } @@ -936,13 +915,11 @@ store_sf2_point(struct device *dev, struct device_attribute *attr, u8 mask_tmp = 0; val = simple_strtoul(buf, NULL, 10); - mutex_lock(&data->update_lock); data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127); mask_tmp = w83792d_read_value(client, W83792D_REG_POINTS[index][nr]) & 0x80; w83792d_write_value(client, W83792D_REG_POINTS[index][nr], mask_tmp|data->sf2_points[index][nr]); - mutex_unlock(&data->update_lock); return count; } @@ -1002,7 +979,6 @@ store_sf2_level(struct device *dev, struct device_attribute *attr, u8 mask_tmp=0, level_tmp=0; val = simple_strtoul(buf, NULL, 10); - mutex_lock(&data->update_lock); data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15); mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr]) & ((nr==3) ? 0xf0 : 0x0f); @@ -1012,7 +988,6 @@ store_sf2_level(struct device *dev, struct device_attribute *attr, level_tmp = data->sf2_levels[index][nr] << 4; } w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp); - mutex_unlock(&data->update_lock); return count; } @@ -1398,7 +1373,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); int i, j; - u8 reg_array_tmp[4], reg_tmp; + u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp; mutex_lock(&data->update_lock); @@ -1427,8 +1402,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) data->fan_min[i] = w83792d_read_value(client, W83792D_REG_FAN_MIN[i]); /* Update the PWM/DC Value and PWM/DC flag */ - data->pwm[i] = w83792d_read_value(client, + pwm_array_tmp[i] = w83792d_read_value(client, W83792D_REG_PWM[i]); + data->pwm[i] = pwm_array_tmp[i] & 0x0f; + data->pwm_mode[i] = pwm_array_tmp[i] >> 7; } reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); @@ -1536,6 +1513,7 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]); dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]); + dev_dbg(dev, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]); } dev_dbg(dev, "3 set of Temperatures: =====>\n"); for (i=0; i<3; i++) { diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 884320e70403..d6d44946a283 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -163,7 +163,7 @@ config I2C_PXA_SLAVE I2C bus. config I2C_PIIX4 - tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" + tristate "Intel PIIX4" depends on I2C && PCI help If you say yes to this option, support will be included for the Intel @@ -172,9 +172,6 @@ config I2C_PIIX4 of Broadcom): Intel PIIX4 Intel 440MX - ATI IXP200 - ATI IXP300 - ATI IXP400 Serverworks OSB4 Serverworks CSB5 Serverworks CSB6 @@ -255,12 +252,12 @@ config I2C_POWERMAC will be called i2c-powermac. config I2C_MPC - tristate "MPC107/824x/85xx/52xx/86xx" + tristate "MPC107/824x/85xx/52xx" depends on I2C && PPC32 help If you say yes to this option, support will be included for the built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and - MPC85xx/MPC8641 family processors. The driver may also work on 52xx + MPC85xx family processors. The driver may also work on 52xx family processors, though interrupts are known not to work. This driver can also be built as a module. If so, the module @@ -276,17 +273,6 @@ config I2C_NFORCE2 This driver can also be built as a module. If so, the module will be called i2c-nforce2. -config I2C_OCORES - tristate "OpenCores I2C Controller" - depends on I2C && EXPERIMENTAL - help - If you say yes to this option, support will be included for the - OpenCores I2C controller. For details see - http://www.opencores.org/projects.cgi/web/i2c/overview - - This driver can also be built as a module. If so, the module - will be called i2c-ocores. - config I2C_PARPORT tristate "Parallel port adapter" depends on I2C && PARPORT @@ -514,7 +500,6 @@ config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" depends on I2C select I2C_ALGOPCA - default n help This driver supports ISA boards using the Philips PCA 9564 Parallel bus to I2C bus controller @@ -522,11 +507,6 @@ config I2C_PCA_ISA This driver can also be built as a module. If so, the module will be called i2c-pca-isa. - This device is almost undetectable and using this driver on a - system which doesn't have this device will result in long - delays when I2C/SMBus chip drivers are loaded (e.g. at boot - time). If unsure, say N. - config I2C_MV64XXX tristate "Marvell mv64xxx I2C Controller" depends on I2C && MV64X60 && EXPERIMENTAL diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index ac56df53155b..b44831dff683 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o -obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 8b46ef7d9ff8..dfca74933625 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -1,5 +1,5 @@ /* - i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware + i801.c - Part of lm_sensors, Linux kernel modules for hardware monitoring Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , and Mark D. Studebaker @@ -36,7 +36,7 @@ This driver supports several versions of Intel's I/O Controller Hubs (ICH). For SMBus support, they are similar to the PIIX4 and are part of Intel's '810' and other chipsets. - See the file Documentation/i2c/busses/i2c-i801 for details. + See the doc/busses/i2c-i801 file for details. I2C Block Read and Process Call are not supported. */ @@ -66,8 +66,9 @@ #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ /* PCI Address Constants */ -#define SMBBAR 4 +#define SMBBA 0x020 #define SMBHSTCFG 0x040 +#define SMBREV 0x008 /* Host configuration bits for SMBHSTCFG */ #define SMBHSTCFG_HST_EN 1 @@ -91,16 +92,92 @@ #define I801_START 0x40 #define I801_PEC_EN 0x80 /* ICH4 only */ +/* insmod parameters */ + +/* If force_addr is set to anything different from 0, we forcibly enable + the I801 at the given address. VERY DANGEROUS! */ +static u16 force_addr; +module_param(force_addr, ushort, 0); +MODULE_PARM_DESC(force_addr, + "Forcibly enable the I801 at the given address. " + "EXTREMELY DANGEROUS!"); static int i801_transaction(void); static int i801_block_transaction(union i2c_smbus_data *data, char read_write, int command, int hwpec); -static unsigned long i801_smba; +static unsigned short i801_smba; static struct pci_driver i801_driver; static struct pci_dev *I801_dev; static int isich4; +static int i801_setup(struct pci_dev *dev) +{ + int error_return = 0; + unsigned char temp; + + /* Note: we keep on searching until we have found 'function 3' */ + if(PCI_FUNC(dev->devfn) != 3) + return -ENODEV; + + I801_dev = dev; + if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || + (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || + (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) + isich4 = 1; + else + isich4 = 0; + + /* Determine the address of the SMBus areas */ + if (force_addr) { + i801_smba = force_addr & 0xfff0; + } else { + pci_read_config_word(I801_dev, SMBBA, &i801_smba); + i801_smba &= 0xfff0; + if(i801_smba == 0) { + dev_err(&dev->dev, "SMB base address uninitialized " + "- upgrade BIOS or use force_addr=0xaddr\n"); + return -ENODEV; + } + } + + if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { + dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", + i801_smba); + error_return = -EBUSY; + goto END; + } + + pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); + temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ + pci_write_config_byte(I801_dev, SMBHSTCFG, temp); + + /* If force_addr is set, we program the new address here. Just to make + sure, we disable the device first. */ + if (force_addr) { + pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe); + pci_write_config_word(I801_dev, SMBBA, i801_smba); + pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01); + dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to " + "new address %04x!\n", i801_smba); + } else if ((temp & 1) == 0) { + pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1); + dev_warn(&dev->dev, "enabling SMBus device\n"); + } + + if (temp & 0x02) + dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n"); + else + dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); + + pci_read_config_byte(I801_dev, SMBREV, &temp); + dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); + dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); + +END: + return error_return; +} + static int i801_transaction(void) { int temp; @@ -257,8 +334,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, /* We will always wait for a fraction of a second! */ timeout = 0; do { - msleep(1); temp = inb_p(SMBHSTSTS); + msleep(1); } while ((!(temp & 0x80)) && (timeout++ < MAX_TIMEOUT)); @@ -316,8 +393,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, /* wait for INTR bit as advised by Intel */ timeout = 0; do { - msleep(1); temp = inb_p(SMBHSTSTS); + msleep(1); } while ((!(temp & 0x02)) && (timeout++ < MAX_TIMEOUT)); @@ -464,80 +541,25 @@ MODULE_DEVICE_TABLE (pci, i801_ids); static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) { - unsigned char temp; - int err; - - I801_dev = dev; - if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || - (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || - (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) - isich4 = 1; - else - isich4 = 0; - err = pci_enable_device(dev); - if (err) { - dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", - err); - goto exit; + if (i801_setup(dev)) { + dev_warn(&dev->dev, + "I801 not detected, module not inserted.\n"); + return -ENODEV; } - /* Determine the address of the SMBus area */ - i801_smba = pci_resource_start(dev, SMBBAR); - if (!i801_smba) { - dev_err(&dev->dev, "SMBus base address uninitialized, " - "upgrade BIOS\n"); - err = -ENODEV; - goto exit; - } - - err = pci_request_region(dev, SMBBAR, i801_driver.name); - if (err) { - dev_err(&dev->dev, "Failed to request SMBus region " - "0x%lx-0x%lx\n", i801_smba, - pci_resource_end(dev, SMBBAR)); - goto exit; - } - - pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); - temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ - if (!(temp & SMBHSTCFG_HST_EN)) { - dev_info(&dev->dev, "Enabling SMBus device\n"); - temp |= SMBHSTCFG_HST_EN; - } - pci_write_config_byte(I801_dev, SMBHSTCFG, temp); - - if (temp & SMBHSTCFG_SMB_SMI_EN) - dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); - else - dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); - /* set up the driverfs linkage to our parent device */ i801_adapter.dev.parent = &dev->dev; snprintf(i801_adapter.name, I2C_NAME_SIZE, - "SMBus I801 adapter at %04lx", i801_smba); - err = i2c_add_adapter(&i801_adapter); - if (err) { - dev_err(&dev->dev, "Failed to add SMBus adapter\n"); - goto exit_release; - } - return 0; - -exit_release: - pci_release_region(dev, SMBBAR); -exit: - return err; + "SMBus I801 adapter at %04x", i801_smba); + return i2c_add_adapter(&i801_adapter); } static void __devexit i801_remove(struct pci_dev *dev) { i2c_del_adapter(&i801_adapter); - pci_release_region(dev, SMBBAR); - /* - * do not call pci_disable_device(dev) since it can cause hard hangs on - * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) - */ + release_region(i801_smba, (isich4 ? 16 : 8)); } static struct pci_driver i801_driver = { diff --git a/trunk/drivers/i2c/busses/i2c-nforce2.c b/trunk/drivers/i2c/busses/i2c-nforce2.c index 604b49e22df1..2d80eb26f688 100644 --- a/trunk/drivers/i2c/busses/i2c-nforce2.c +++ b/trunk/drivers/i2c/busses/i2c-nforce2.c @@ -31,8 +31,6 @@ nForce3 250Gb MCP 00E4 nForce4 MCP 0052 nForce4 MCP-04 0034 - nForce4 MCP51 0264 - nForce4 MCP55 0368 This driver supports the 2 SMBuses that are included in the MCP of the nForce2/3/4 chipsets. @@ -66,7 +64,6 @@ struct nforce2_smbus { /* * nVidia nForce2 SMBus control register definitions - * (Newer incarnations use standard BARs 4 and 5 instead) */ #define NFORCE_PCI_SMB1 0x50 #define NFORCE_PCI_SMB2 0x54 @@ -262,8 +259,6 @@ static struct pci_device_id nforce2_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, { 0 } }; @@ -271,29 +266,19 @@ static struct pci_device_id nforce2_ids[] = { MODULE_DEVICE_TABLE (pci, nforce2_ids); -static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, - int alt_reg, struct nforce2_smbus *smbus, const char *name) +static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, + struct nforce2_smbus *smbus, char *name) { + u16 iobase; int error; - smbus->base = pci_resource_start(dev, bar); - if (smbus->base) { - smbus->size = pci_resource_len(dev, bar); - } else { - /* Older incarnations of the device used non-standard BARs */ - u16 iobase; - - if (pci_read_config_word(dev, alt_reg, &iobase) - != PCIBIOS_SUCCESSFUL) { - dev_err(&dev->dev, "Error reading PCI config for %s\n", - name); - return -1; - } - - smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; - smbus->size = 8; + if (pci_read_config_word(dev, reg, &iobase) != PCIBIOS_SUCCESSFUL) { + dev_err(&smbus->adapter.dev, "Error reading PCI config for %s\n", name); + return -1; } - smbus->dev = dev; + smbus->dev = dev; + smbus->base = iobase & 0xfffc; + smbus->size = 8; if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", @@ -328,13 +313,12 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ pci_set_drvdata(dev, smbuses); /* SMBus adapter 1 */ - res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); + res1 = nforce2_probe_smb (dev, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); if (res1 < 0) { dev_err(&dev->dev, "Error probing SMB1.\n"); smbuses[0].base = 0; /* to have a check value */ } - /* SMBus adapter 2 */ - res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); + res2 = nforce2_probe_smb (dev, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); if (res2 < 0) { dev_err(&dev->dev, "Error probing SMB2.\n"); smbuses[1].base = 0; /* to have a check value */ diff --git a/trunk/drivers/i2c/busses/i2c-ocores.c b/trunk/drivers/i2c/busses/i2c-ocores.c deleted file mode 100644 index 592824087c49..000000000000 --- a/trunk/drivers/i2c/busses/i2c-ocores.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * i2c-ocores.c: I2C bus driver for OpenCores I2C controller - * (http://www.opencores.org/projects.cgi/web/i2c/overview). - * - * Peter Korsgaard - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct ocores_i2c { - void __iomem *base; - int regstep; - wait_queue_head_t wait; - struct i2c_adapter adap; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ -}; - -/* registers */ -#define OCI2C_PRELOW 0 -#define OCI2C_PREHIGH 1 -#define OCI2C_CONTROL 2 -#define OCI2C_DATA 3 -#define OCI2C_CMD 4 /* write only */ -#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ - -#define OCI2C_CTRL_IEN 0x40 -#define OCI2C_CTRL_EN 0x80 - -#define OCI2C_CMD_START 0x91 -#define OCI2C_CMD_STOP 0x41 -#define OCI2C_CMD_READ 0x21 -#define OCI2C_CMD_WRITE 0x11 -#define OCI2C_CMD_READ_ACK 0x21 -#define OCI2C_CMD_READ_NACK 0x29 -#define OCI2C_CMD_IACK 0x01 - -#define OCI2C_STAT_IF 0x01 -#define OCI2C_STAT_TIP 0x02 -#define OCI2C_STAT_ARBLOST 0x20 -#define OCI2C_STAT_BUSY 0x40 -#define OCI2C_STAT_NACK 0x80 - -#define STATE_DONE 0 -#define STATE_START 1 -#define STATE_WRITE 2 -#define STATE_READ 3 -#define STATE_ERROR 4 - -static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) -{ - iowrite8(value, i2c->base + reg * i2c->regstep); -} - -static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) -{ - return ioread8(i2c->base + reg * i2c->regstep); -} - -static void ocores_process(struct ocores_i2c *i2c) -{ - struct i2c_msg *msg = i2c->msg; - u8 stat = oc_getreg(i2c, OCI2C_STATUS); - - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { - /* stop has been sent */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - wake_up(&i2c->wait); - return; - } - - /* error? */ - if (stat & OCI2C_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; - } - - if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { - i2c->state = - (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - - if (stat & OCI2C_STAT_NACK) { - i2c->state = STATE_ERROR; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; - } - } else - msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); - - /* end of msg? */ - if (i2c->pos == msg->len) { - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { /* end? */ - /* send start? */ - if (!(msg->flags & I2C_M_NOSTART)) { - u8 addr = (msg->addr << 1); - - if (msg->flags & I2C_M_RD) - addr |= 1; - - i2c->state = STATE_START; - - oc_setreg(i2c, OCI2C_DATA, addr); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - return; - } else - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } else { - i2c->state = STATE_DONE; - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; - } - } - - if (i2c->state == STATE_READ) { - oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? - OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); - } else { - oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); - } -} - -static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs) -{ - struct ocores_i2c *i2c = dev_id; - - ocores_process(i2c); - - return IRQ_HANDLED; -} - -static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - struct ocores_i2c *i2c = i2c_get_adapdata(adap); - - i2c->msg = msgs; - i2c->pos = 0; - i2c->nmsgs = num; - i2c->state = STATE_START; - - oc_setreg(i2c, OCI2C_DATA, - (i2c->msg->addr << 1) | - ((i2c->msg->flags & I2C_M_RD) ? 1:0)); - - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - - if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; -} - -static void ocores_init(struct ocores_i2c *i2c, - struct ocores_i2c_platform_data *pdata) -{ - int prescale; - u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); - - /* make sure the device is disabled */ - oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - prescale = (pdata->clock_khz / (5*100)) - 1; - oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); - oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); - - /* Init the device */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); - oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); -} - - -static u32 ocores_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static struct i2c_algorithm ocores_algorithm = { - .master_xfer = ocores_xfer, - .functionality = ocores_func, -}; - -static struct i2c_adapter ocores_adapter = { - .owner = THIS_MODULE, - .name = "i2c-ocores", - .class = I2C_CLASS_HWMON, - .algo = &ocores_algorithm, -}; - - -static int __devinit ocores_i2c_probe(struct platform_device *pdev) -{ - struct ocores_i2c *i2c; - struct ocores_i2c_platform_data *pdata; - struct resource *res, *res2; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) - return -ENODEV; - - pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data; - if (!pdata) - return -ENODEV; - - i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); - if (!i2c) - return -ENOMEM; - - if (!request_mem_region(res->start, res->end - res->start + 1, - pdev->name)) { - dev_err(&pdev->dev, "Memory region busy\n"); - ret = -EBUSY; - goto request_mem_failed; - } - - i2c->base = ioremap(res->start, res->end - res->start + 1); - if (!i2c->base) { - dev_err(&pdev->dev, "Unable to map registers\n"); - ret = -EIO; - goto map_failed; - } - - i2c->regstep = pdata->regstep; - ocores_init(i2c, pdata); - - init_waitqueue_head(&i2c->wait); - ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); - if (ret) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto request_irq_failed; - } - - /* hook up driver to tree */ - platform_set_drvdata(pdev, i2c); - i2c->adap = ocores_adapter; - i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - - /* add i2c adapter to i2c tree */ - ret = i2c_add_adapter(&i2c->adap); - if (ret) { - dev_err(&pdev->dev, "Failed to add adapter\n"); - goto add_adapter_failed; - } - - return 0; - -add_adapter_failed: - free_irq(res2->start, i2c); -request_irq_failed: - iounmap(i2c->base); -map_failed: - release_mem_region(res->start, res->end - res->start + 1); -request_mem_failed: - kfree(i2c); - - return ret; -} - -static int __devexit ocores_i2c_remove(struct platform_device* pdev) -{ - struct ocores_i2c *i2c = platform_get_drvdata(pdev); - struct resource *res; - - /* disable i2c logic */ - oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) - & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - - /* remove adapter & data */ - i2c_del_adapter(&i2c->adap); - platform_set_drvdata(pdev, NULL); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) - free_irq(res->start, i2c); - - iounmap(i2c->base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, res->end - res->start + 1); - - kfree(i2c); - - return 0; -} - -static struct platform_driver ocores_i2c_driver = { - .probe = ocores_i2c_probe, - .remove = __devexit_p(ocores_i2c_remove), - .driver = { - .owner = THIS_MODULE, - .name = "ocores-i2c", - }, -}; - -static int __init ocores_i2c_init(void) -{ - return platform_driver_register(&ocores_i2c_driver); -} - -static void __exit ocores_i2c_exit(void) -{ - platform_driver_unregister(&ocores_i2c_driver); -} - -module_init(ocores_i2c_init); -module_exit(ocores_i2c_exit); - -MODULE_AUTHOR("Peter Korsgaard "); -MODULE_DESCRIPTION("OpenCores I2C bus driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/i2c/busses/i2c-piix4.c b/trunk/drivers/i2c/busses/i2c-piix4.c index 8f2f65b793b9..d9c7c00e71f9 100644 --- a/trunk/drivers/i2c/busses/i2c-piix4.c +++ b/trunk/drivers/i2c/busses/i2c-piix4.c @@ -102,6 +102,13 @@ MODULE_PARM_DESC(force_addr, "Forcibly enable the PIIX4 at the given address. " "EXTREMELY DANGEROUS!"); +/* If fix_hstcfg is set to anything different from 0, we reset one of the + registers to be a valid value. */ +static int fix_hstcfg; +module_param (fix_hstcfg, int, 0); +MODULE_PARM_DESC(fix_hstcfg, + "Fix config register. Needed on some boards (Force CPCI735)."); + static int piix4_transaction(void); static unsigned short piix4_smba; @@ -130,7 +137,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, /* Don't access SMBus on IBM systems which get corrupted eeproms */ if (dmi_check_system(piix4_dmi_table) && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { - dev_err(&PIIX4_dev->dev, "IBM system detected; this module " + dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module " "may corrupt your serial eeprom! Refusing to load " "module!\n"); return -EPERM; @@ -159,6 +166,22 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); + /* Some BIOS will set up the chipset incorrectly and leave a register + in an undefined state (causing I2C to act very strangely). */ + if (temp & 0x02) { + if (fix_hstcfg) { + dev_info(&PIIX4_dev->dev, "Working around buggy BIOS " + "(I2C)\n"); + temp &= 0xfd; + pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp); + } else { + dev_info(&PIIX4_dev->dev, "Unusual config register " + "value\n"); + dev_info(&PIIX4_dev->dev, "Try using fix_hstcfg=1 if " + "you experience problems\n"); + } + } + /* If force_addr is set, we program the new address here. Just to make sure, we disable the PIIX4 first. */ if (force_addr) { @@ -191,7 +214,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, } } - if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2)) + if ((temp & 0x0E) == 8) dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); else if ((temp & 0x0E) == 0) dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); @@ -390,12 +413,6 @@ static struct i2c_adapter piix4_adapter = { static struct pci_device_id piix4_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), .driver_data = 3 }, - { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS), - .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS), - .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS), - .driver_data = 0 }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), .driver_data = 0 }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), diff --git a/trunk/drivers/i2c/busses/scx200_acb.c b/trunk/drivers/i2c/busses/scx200_acb.c index 22a3eda04166..766cc969c4d0 100644 --- a/trunk/drivers/i2c/busses/scx200_acb.c +++ b/trunk/drivers/i2c/busses/scx200_acb.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -84,10 +85,6 @@ struct scx200_acb_iface { u8 *ptr; char needs_reset; unsigned len; - - /* PCI device info */ - struct pci_dev *pdev; - int bar; }; /* Register Definitions */ @@ -384,7 +381,7 @@ static struct i2c_algorithm scx200_acb_algorithm = { static struct scx200_acb_iface *scx200_acb_list; static DECLARE_MUTEX(scx200_acb_list_mutex); -static __init int scx200_acb_probe(struct scx200_acb_iface *iface) +static int scx200_acb_probe(struct scx200_acb_iface *iface) { u8 val; @@ -420,16 +417,17 @@ static __init int scx200_acb_probe(struct scx200_acb_iface *iface) return 0; } -static __init struct scx200_acb_iface *scx200_create_iface(const char *text, - int index) +static int __init scx200_acb_create(const char *text, int base, int index) { struct scx200_acb_iface *iface; struct i2c_adapter *adapter; + int rc; iface = kzalloc(sizeof(*iface), GFP_KERNEL); if (!iface) { printk(KERN_ERR NAME ": can't allocate memory\n"); - return NULL; + rc = -ENOMEM; + goto errout; } adapter = &iface->adapter; @@ -442,27 +440,26 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, mutex_init(&iface->mutex); - return iface; -} - -static int __init scx200_acb_create(struct scx200_acb_iface *iface) -{ - struct i2c_adapter *adapter; - int rc; - - adapter = &iface->adapter; + if (!request_region(base, 8, adapter->name)) { + printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", + base, base + 8-1); + rc = -EBUSY; + goto errout_free; + } + iface->base = base; rc = scx200_acb_probe(iface); if (rc) { printk(KERN_WARNING NAME ": probe failed\n"); - return rc; + goto errout_release; } scx200_acb_reset(iface); if (i2c_add_adapter(adapter) < 0) { printk(KERN_ERR NAME ": failed to register\n"); - return -ENODEV; + rc = -ENODEV; + goto errout_release; } down(&scx200_acb_list_mutex); @@ -471,148 +468,64 @@ static int __init scx200_acb_create(struct scx200_acb_iface *iface) up(&scx200_acb_list_mutex); return 0; -} - -static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, - int bar) -{ - struct scx200_acb_iface *iface; - int rc; - - iface = scx200_create_iface(text, 0); - - if (iface == NULL) - return -ENOMEM; - - iface->pdev = pdev; - iface->bar = bar; - - pci_enable_device_bars(iface->pdev, 1 << iface->bar); - - rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); - - if (rc != 0) { - printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", - iface->bar); - goto errout_free; - } - - iface->base = pci_resource_start(iface->pdev, iface->bar); - rc = scx200_acb_create(iface); - - if (rc == 0) - return 0; - - pci_release_region(iface->pdev, iface->bar); - pci_dev_put(iface->pdev); - errout_free: - kfree(iface); - return rc; -} - -static int __init scx200_create_isa(const char *text, unsigned long base, - int index) -{ - struct scx200_acb_iface *iface; - int rc; - - iface = scx200_create_iface(text, index); - - if (iface == NULL) - return -ENOMEM; - - if (request_region(base, 8, iface->adapter.name) == 0) { - printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", - base, base + 8 - 1); - rc = -EBUSY; - goto errout_free; - } - - iface->base = base; - rc = scx200_acb_create(iface); - if (rc == 0) - return 0; - - release_region(base, 8); + errout_release: + release_region(iface->base, 8); errout_free: kfree(iface); + errout: return rc; } -/* Driver data is an index into the scx200_data array that indicates - * the name and the BAR where the I/O address resource is located. ISA - * devices are flagged with a bar value of -1 */ - -static struct pci_device_id scx200_pci[] = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), - .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), - .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), - .driver_data = 1 }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), - .driver_data = 2 } +static struct pci_device_id scx200[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, + { }, }; -static struct { - const char *name; - int bar; -} scx200_data[] = { - { "SCx200", -1 }, - { "CS5535", 0 }, - { "CS5536", 0 } +static struct pci_device_id divil_pci[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, + { } /* NULL entry */ }; -static __init int scx200_scan_pci(void) +#define MSR_LBAR_SMB 0x5140000B + +static __init int scx200_add_cs553x(void) { - int data, dev; - int rc = -ENODEV; - struct pci_dev *pdev; - - for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { - pdev = pci_get_device(scx200_pci[dev].vendor, - scx200_pci[dev].device, NULL); - - if (pdev == NULL) - continue; - - data = scx200_pci[dev].driver_data; - - /* if .bar is greater or equal to zero, this is a - * PCI device - otherwise, we assume - that the ports are ISA based - */ - - if (scx200_data[data].bar >= 0) - rc = scx200_create_pci(scx200_data[data].name, pdev, - scx200_data[data].bar); - else { - int i; - - for (i = 0; i < MAX_DEVICES; ++i) { - if (base[i] == 0) - continue; - - rc = scx200_create_isa(scx200_data[data].name, - base[i], - i); - } - } + u32 low, hi; + u32 smb_base; - break; + /* Grab & reserve the SMB I/O range */ + rdmsr(MSR_LBAR_SMB, low, hi); + + /* Check the IO mask and whether SMB is enabled */ + if (hi != 0x0000F001) { + printk(KERN_WARNING NAME ": SMBus not enabled\n"); + return -ENODEV; } - return rc; + /* SMBus IO size is 8 bytes */ + smb_base = low & 0x0000FFF8; + + return scx200_acb_create("CS5535", smb_base, 0); } static int __init scx200_acb_init(void) { - int rc; + int i; + int rc = -ENODEV; pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); - rc = scx200_scan_pci(); + /* Verify that this really is a SCx200 processor */ + if (pci_dev_present(scx200)) { + for (i = 0; i < MAX_DEVICES; ++i) { + if (base[i] > 0) + rc = scx200_acb_create("SCx200", base[i], i); + } + } else if (pci_dev_present(divil_pci)) + rc = scx200_add_cs553x(); /* If at least one bus was created, init must succeed */ if (scx200_acb_list) @@ -630,14 +543,7 @@ static void __exit scx200_acb_cleanup(void) up(&scx200_acb_list_mutex); i2c_del_adapter(&iface->adapter); - - if (iface->pdev) { - pci_release_region(iface->pdev, iface->bar); - pci_dev_put(iface->pdev); - } - else - release_region(iface->base, 8); - + release_region(iface->base, 8); kfree(iface); down(&scx200_acb_list_mutex); } diff --git a/trunk/drivers/i2c/chips/Kconfig b/trunk/drivers/i2c/chips/Kconfig index 87ee3ce58618..7aa5c38f0855 100644 --- a/trunk/drivers/i2c/chips/Kconfig +++ b/trunk/drivers/i2c/chips/Kconfig @@ -39,7 +39,6 @@ config SENSORS_EEPROM config SENSORS_PCF8574 tristate "Philips PCF8574 and PCF8574A" depends on I2C && EXPERIMENTAL - default n help If you say yes here you get support for Philips PCF8574 and PCF8574A chips. @@ -47,9 +46,6 @@ config SENSORS_PCF8574 This driver can also be built as a module. If so, the module will be called pcf8574. - These devices are hard to detect and rarely found on mainstream - hardware. If unsure, say N. - config SENSORS_PCA9539 tristate "Philips PCA9539 16-bit I/O port" depends on I2C && EXPERIMENTAL @@ -63,16 +59,12 @@ config SENSORS_PCA9539 config SENSORS_PCF8591 tristate "Philips PCF8591" depends on I2C && EXPERIMENTAL - default n help If you say yes here you get support for Philips PCF8591 chips. This driver can also be built as a module. If so, the module will be called pcf8591. - These devices are hard to detect and rarely found on mainstream - hardware. If unsure, say N. - config ISP1301_OMAP tristate "Philips ISP1301 with OMAP OTG" depends on I2C && ARCH_OMAP_OTG diff --git a/trunk/drivers/i2c/chips/m41t00.c b/trunk/drivers/i2c/chips/m41t00.c index 2dd0a34d9472..99ab4ec34390 100644 --- a/trunk/drivers/i2c/chips/m41t00.c +++ b/trunk/drivers/i2c/chips/m41t00.c @@ -1,9 +1,11 @@ /* - * I2C client/driver for the ST M41T00 family of i2c rtc chips. + * drivers/i2c/chips/m41t00.c + * + * I2C client/driver for the ST M41T00 Real-Time Clock chip. * * Author: Mark A. Greer * - * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under + * 2005 (c) MontaVista Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program * is licensed "as is" without any warranty of any kind, whether express * or implied. @@ -11,6 +13,9 @@ /* * This i2c client/driver wedges between the drivers/char/genrtc.c RTC * interface and the SMBus interface of the i2c subsystem. + * It would be more efficient to use i2c msgs/i2c_transfer directly but, as + * recommened in .../Documentation/i2c/writing-clients section + * "Sending and receiving", using SMBus level communication is preferred. */ #include @@ -19,110 +24,56 @@ #include #include #include +#include #include -#include -#include + #include #include +#define M41T00_DRV_NAME "m41t00" + +static DEFINE_MUTEX(m41t00_mutex); + static struct i2c_driver m41t00_driver; static struct i2c_client *save_client; static unsigned short ignore[] = { I2C_CLIENT_END }; -static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_addr, - .probe = ignore, - .ignore = ignore, -}; - -struct m41t00_chip_info { - u8 type; - char *name; - u8 read_limit; - u8 sec; /* Offsets for chip regs */ - u8 min; - u8 hour; - u8 day; - u8 mon; - u8 year; - u8 alarm_mon; - u8 alarm_hour; - u8 sqw; - u8 sqw_freq; + .normal_i2c = normal_addr, + .probe = ignore, + .ignore = ignore, }; -static struct m41t00_chip_info m41t00_chip_info_tbl[] = { - { - .type = M41T00_TYPE_M41T00, - .name = "m41t00", - .read_limit = 5, - .sec = 0, - .min = 1, - .hour = 2, - .day = 4, - .mon = 5, - .year = 6, - }, - { - .type = M41T00_TYPE_M41T81, - .name = "m41t81", - .read_limit = 1, - .sec = 1, - .min = 2, - .hour = 3, - .day = 5, - .mon = 6, - .year = 7, - .alarm_mon = 0xa, - .alarm_hour = 0xc, - .sqw = 0x13, - }, - { - .type = M41T00_TYPE_M41T85, - .name = "m41t85", - .read_limit = 1, - .sec = 1, - .min = 2, - .hour = 3, - .day = 5, - .mon = 6, - .year = 7, - .alarm_mon = 0xa, - .alarm_hour = 0xc, - .sqw = 0x13, - }, -}; -static struct m41t00_chip_info *m41t00_chip; - ulong m41t00_get_rtc_time(void) { - s32 sec, min, hour, day, mon, year; - s32 sec1, min1, hour1, day1, mon1, year1; - u8 reads = 0; - u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */ - struct i2c_msg msgs[] = { - { - .addr = save_client->addr, - .flags = 0, - .len = 1, - .buf = msgbuf, - }, - { - .addr = save_client->addr, - .flags = I2C_M_RD, - .len = 8, - .buf = buf, - }, - }; + s32 sec, min, hour, day, mon, year; + s32 sec1, min1, hour1, day1, mon1, year1; + ulong limit = 10; sec = min = hour = day = mon = year = 0; + sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; + mutex_lock(&m41t00_mutex); do { - if (i2c_transfer(save_client->adapter, msgs, 2) < 0) - goto read_err; + if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) + && ((min = i2c_smbus_read_byte_data(save_client, 1)) + >= 0) + && ((hour = i2c_smbus_read_byte_data(save_client, 2)) + >= 0) + && ((day = i2c_smbus_read_byte_data(save_client, 4)) + >= 0) + && ((mon = i2c_smbus_read_byte_data(save_client, 5)) + >= 0) + && ((year = i2c_smbus_read_byte_data(save_client, 6)) + >= 0) + && ((sec == sec1) && (min == min1) && (hour == hour1) + && (day == day1) && (mon == mon1) + && (year == year1))) + + break; sec1 = sec; min1 = min; @@ -130,88 +81,69 @@ m41t00_get_rtc_time(void) day1 = day; mon1 = mon; year1 = year; + } while (--limit > 0); + mutex_unlock(&m41t00_mutex); + + if (limit == 0) { + dev_warn(&save_client->dev, + "m41t00: can't read rtc chip\n"); + sec = min = hour = day = mon = year = 0; + } + + sec &= 0x7f; + min &= 0x7f; + hour &= 0x3f; + day &= 0x3f; + mon &= 0x1f; + year &= 0xff; - sec = buf[m41t00_chip->sec] & 0x7f; - min = buf[m41t00_chip->min] & 0x7f; - hour = buf[m41t00_chip->hour] & 0x3f; - day = buf[m41t00_chip->day] & 0x3f; - mon = buf[m41t00_chip->mon] & 0x1f; - year = buf[m41t00_chip->year]; - } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1) - || (min != min1) || (hour != hour1) || (day != day1) - || (mon != mon1) || (year != year1))); - - if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1) - || (hour != hour1) || (day != day1) || (mon != mon1) - || (year != year1))) - goto read_err; - - sec = BCD2BIN(sec); - min = BCD2BIN(min); - hour = BCD2BIN(hour); - day = BCD2BIN(day); - mon = BCD2BIN(mon); - year = BCD2BIN(year); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); year += 1900; if (year < 1970) year += 100; return mktime(year, mon, day, hour, min, sec); - -read_err: - dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n"); - return 0; } -EXPORT_SYMBOL_GPL(m41t00_get_rtc_time); static void m41t00_set(void *arg) { struct rtc_time tm; - int nowtime = *(int *)arg; - s32 sec, min, hour, day, mon, year; - u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 }; - struct i2c_msg msgs[] = { - { - .addr = save_client->addr, - .flags = 0, - .len = 1, - .buf = msgbuf, - }, - { - .addr = save_client->addr, - .flags = I2C_M_RD, - .len = 8, - .buf = buf, - }, - }; + ulong nowtime = *(ulong *)arg; to_tm(nowtime, &tm); tm.tm_year = (tm.tm_year - 1900) % 100; - sec = BIN2BCD(tm.tm_sec); - min = BIN2BCD(tm.tm_min); - hour = BIN2BCD(tm.tm_hour); - day = BIN2BCD(tm.tm_mday); - mon = BIN2BCD(tm.tm_mon); - year = BIN2BCD(tm.tm_year); - - /* Read reg values into buf[0..7]/wbuf[1..8] */ - if (i2c_transfer(save_client->adapter, msgs, 2) < 0) { - dev_err(&save_client->dev, "m41t00_set: Read error\n"); - return; - } - - wbuf[0] = 0; /* offset into rtc's regs */ - buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f); - buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f); - buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f); - buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f); - buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f); - - if (i2c_master_send(save_client, wbuf, 9) < 0) - dev_err(&save_client->dev, "m41t00_set: Write error\n"); + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + + mutex_lock(&m41t00_mutex); + if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) + || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) + < 0)) + + dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); + + mutex_unlock(&m41t00_mutex); + return; } static ulong new_time; @@ -230,48 +162,6 @@ m41t00_set_rtc_time(ulong nowtime) return 0; } -EXPORT_SYMBOL_GPL(m41t00_set_rtc_time); - -/* - ***************************************************************************** - * - * platform_data Driver Interface - * - ***************************************************************************** - */ -static int __init -m41t00_platform_probe(struct platform_device *pdev) -{ - struct m41t00_platform_data *pdata; - int i; - - if (pdev && (pdata = pdev->dev.platform_data)) { - normal_addr[0] = pdata->i2c_addr; - - for (i=0; itype) { - m41t00_chip = &m41t00_chip_info_tbl[i]; - m41t00_chip->sqw_freq = pdata->sqw_freq; - return 0; - } - } - return -ENODEV; -} - -static int __exit -m41t00_platform_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver m41t00_platform_driver = { - .probe = m41t00_platform_probe, - .remove = m41t00_platform_remove, - .driver = { - .owner = THIS_MODULE, - .name = M41T00_DRV_NAME, - }, -}; /* ***************************************************************************** @@ -286,71 +176,23 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) struct i2c_client *client; int rc; - if (!i2c_check_functionality(adap, I2C_FUNC_I2C - | I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (!client) return -ENOMEM; - strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE); + strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); client->addr = addr; client->adapter = adap; client->driver = &m41t00_driver; - if ((rc = i2c_attach_client(client))) - goto attach_err; - - if (m41t00_chip->type != M41T00_TYPE_M41T00) { - /* If asked, disable SQW, set SQW frequency & re-enable */ - if (m41t00_chip->sqw_freq) - if (((rc = i2c_smbus_read_byte_data(client, - m41t00_chip->alarm_mon)) < 0) - || ((rc = i2c_smbus_write_byte_data(client, - m41t00_chip->alarm_mon, rc & ~0x40)) <0) - || ((rc = i2c_smbus_write_byte_data(client, - m41t00_chip->sqw, - m41t00_chip->sqw_freq)) < 0) - || ((rc = i2c_smbus_write_byte_data(client, - m41t00_chip->alarm_mon, rc | 0x40)) <0)) - goto sqw_err; - - /* Make sure HT (Halt Update) bit is cleared */ - if ((rc = i2c_smbus_read_byte_data(client, - m41t00_chip->alarm_hour)) < 0) - goto ht_err; - - if (rc & 0x40) - if ((rc = i2c_smbus_write_byte_data(client, - m41t00_chip->alarm_hour, rc & ~0x40))<0) - goto ht_err; + if ((rc = i2c_attach_client(client)) != 0) { + kfree(client); + return rc; } - /* Make sure ST (stop) bit is cleared */ - if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0) - goto st_err; - - if (rc & 0x80) - if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec, - rc & ~0x80)) < 0) - goto st_err; - - m41t00_wq = create_singlethread_workqueue(m41t00_chip->name); + m41t00_wq = create_singlethread_workqueue("m41t00"); save_client = client; return 0; - -st_err: - dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n"); - goto attach_err; -ht_err: - dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n"); - goto attach_err; -sqw_err: - dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n"); -attach_err: - kfree(client); - return rc; } static int @@ -362,7 +204,7 @@ m41t00_attach(struct i2c_adapter *adap) static int m41t00_detach(struct i2c_client *client) { - int rc; + int rc; if ((rc = i2c_detach_client(client)) == 0) { kfree(client); @@ -383,18 +225,14 @@ static struct i2c_driver m41t00_driver = { static int __init m41t00_init(void) { - int rc; - - if (!(rc = platform_driver_register(&m41t00_platform_driver))) - rc = i2c_add_driver(&m41t00_driver); - return rc; + return i2c_add_driver(&m41t00_driver); } static void __exit m41t00_exit(void) { i2c_del_driver(&m41t00_driver); - platform_driver_unregister(&m41t00_platform_driver); + return; } module_init(m41t00_init); diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index a45155f799d4..45e2cdf54736 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) } s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, - u8 length, const u8 *values) + u8 length, u8 *values) { union i2c_smbus_data data; @@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val } s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, - u8 length, const u8 *values) + u8 length, u8 *values) { union i2c_smbus_data data; diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 58ccddd5c237..ed7eed388bae 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -426,7 +426,10 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) /* register this i2c device with the driver core */ i2c_dev->adap = adap; - dev = &adap->dev; + if (adap->dev.parent == &platform_bus) + dev = &adap->dev; + else + dev = adap->dev.parent; i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, MKDEV(I2C_MAJOR, i2c_dev->minor), dev, "i2c-%d", i2c_dev->minor); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 99fa42402e71..b4a41d6d0714 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -395,8 +395,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, * we cannot reliably check if drive can auto-close */ if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) - break; - log = 1; + log = 0; break; case UNIT_ATTENTION: /* @@ -418,11 +417,6 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *failed_command, struct request_sense *sense) { - unsigned long sector; - unsigned long bio_sectors; - unsigned long valid; - struct cdrom_info *info = drive->driver_data; - if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -435,37 +429,6 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, if (sense->sense_key == 0x05 && sense->asc == 0x24) return; - if (sense->error_code == 0x70) { /* Current Error */ - switch(sense->sense_key) { - case MEDIUM_ERROR: - case VOLUME_OVERFLOW: - case ILLEGAL_REQUEST: - if (!sense->valid) - break; - if (failed_command == NULL || - !blk_fs_request(failed_command)) - break; - sector = (sense->information[0] << 24) | - (sense->information[1] << 16) | - (sense->information[2] << 8) | - (sense->information[3]); - - bio_sectors = bio_sectors(failed_command->bio); - if (bio_sectors < 4) - bio_sectors = 4; - if (drive->queue->hardsect_size == 2048) - sector <<= 2; /* Device sector size is 2K */ - sector &= ~(bio_sectors -1); - valid = (sector - failed_command->sector) << 9; - - if (valid < 0) - valid = 0; - if (sector < get_capacity(info->disk) && - drive->probed_capacity - sector < 4 * 75) { - set_capacity(info->disk, sector); - } - } - } #if VERBOSE_IDE_CD_ERRORS { int i; @@ -646,23 +609,17 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) sense = failed->sense; failed->sense_len = rq->sense_len; } - cdrom_analyze_sense_data(drive, failed, sense); + /* * now end failed request */ - if (blk_fs_request(failed)) { - if (ide_end_dequeued_request(drive, failed, 0, - failed->hard_nr_sectors)) - BUG(); - } else { - spin_lock_irqsave(&ide_lock, flags); - end_that_request_chunk(failed, 0, - failed->data_len); - end_that_request_last(failed, 0); - spin_unlock_irqrestore(&ide_lock, flags); - } - } else - cdrom_analyze_sense_data(drive, NULL, sense); + spin_lock_irqsave(&ide_lock, flags); + end_that_request_chunk(failed, 0, failed->data_len); + end_that_request_last(failed, 0); + spin_unlock_irqrestore(&ide_lock, flags); + } + + cdrom_analyze_sense_data(drive, failed, sense); } if (!rq->current_nr_sectors && blk_fs_request(rq)) @@ -676,13 +633,6 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) ide_end_request(drive, uptodate, nsectors); } -static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat) -{ - if (stat & 0x80) - return; - ide_dump_status(drive, msg, stat); -} - /* Returns 0 if the request should be continued. Returns 1 if the request was ended. */ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) @@ -811,16 +761,16 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) sense_key == DATA_PROTECT) { /* No point in retrying after an illegal request or data protect error.*/ - ide_dump_status_no_sense (drive, "command error", stat); + ide_dump_status (drive, "command error", stat); do_end_request = 1; } else if (sense_key == MEDIUM_ERROR) { /* No point in re-trying a zillion times on a bad * sector... If we got here the error is not correctable */ - ide_dump_status_no_sense (drive, "media error (bad sector)", stat); + ide_dump_status (drive, "media error (bad sector)", stat); do_end_request = 1; } else if (sense_key == BLANK_CHECK) { /* Disk appears blank ?? */ - ide_dump_status_no_sense (drive, "media error (blank)", stat); + ide_dump_status (drive, "media error (blank)", stat); do_end_request = 1; } else if ((err & ~ABRT_ERR) != 0) { /* Go to the default handler @@ -832,27 +782,13 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) do_end_request = 1; } - /* End a request through request sense analysis when we have - sense data. We need this in order to perform end of media - processing */ - - if (do_end_request) { - if (stat & ERR_STAT) { - unsigned long flags; - spin_lock_irqsave(&ide_lock, flags); - blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; - spin_unlock_irqrestore(&ide_lock, flags); - - cdrom_queue_request_sense(drive, rq->sense, rq); - } else - cdrom_end_request(drive, 0); - } else { - /* If we got a CHECK_CONDITION status, - queue a request sense command. */ - if (stat & ERR_STAT) - cdrom_queue_request_sense(drive, NULL, NULL); - } + if (do_end_request) + cdrom_end_request(drive, 0); + + /* If we got a CHECK_CONDITION status, + queue a request sense command. */ + if ((stat & ERR_STAT) != 0) + cdrom_queue_request_sense(drive, NULL, NULL); } else { blk_dump_rq_flags(rq, "ide-cd: bad rq"); cdrom_end_request(drive, 0); @@ -1515,12 +1451,9 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) } else { confused: printk (KERN_ERR "%s: cdrom_pc_intr: The drive " - "appears confused (ireason = 0x%02x). " - "Trying to recover by ending request.\n", + "appears confused (ireason = 0x%02x)\n", drive->name, ireason); rq->flags |= REQ_FAILED; - cdrom_end_request(drive, 0); - return ide_stopped; } /* Now we wait for another interrupt. */ @@ -1555,7 +1488,8 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) } -static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) +static +int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) { struct request_sense sense; int retries = 10; @@ -1788,7 +1722,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); return ide_started; @@ -2283,9 +2218,6 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) toc->capacity = 0x1fffff; set_capacity(info->disk, toc->capacity * sectors_per_frame); - /* Save a private copy of te TOC capacity for error handling */ - drive->probed_capacity = toc->capacity * sectors_per_frame; - blk_queue_hardsect_size(drive->queue, sectors_per_frame << SECTOR_BITS); @@ -2408,7 +2340,6 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) if (!stat && (last_written > toc->capacity)) { toc->capacity = last_written; set_capacity(info->disk, toc->capacity * sectors_per_frame); - drive->probed_capacity = toc->capacity * sectors_per_frame; } /* Remember that we've read this stuff. */ @@ -2765,11 +2696,14 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) * any other way to detect this... */ if (sense.sense_key == NOT_READY) { - if (sense.asc == 0x3a && sense.ascq == 1) - return CDS_NO_DISC; - else - return CDS_TRAY_OPEN; + if (sense.asc == 0x3a) { + if (sense.ascq == 1) + return CDS_NO_DISC; + else if (sense.ascq == 0 || sense.ascq == 2) + return CDS_TRAY_OPEN; + } } + return CDS_DRIVE_NOT_READY; } diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index f033d732f387..a5017de72da5 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -37,7 +37,7 @@ * Version 1.15 convert all calls to ide_raw_taskfile * since args will return register content. * Version 1.16 added suspend-resume-checkpower - * Version 1.17 do flush on standby, do flush on ATA < ATA6 + * Version 1.17 do flush on standy, do flush on ATA < ATA6 * fix wcache setup. */ diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index 783a2475ee8b..c481be8b807f 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -206,7 +206,8 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq) ide_hwif_t *hwif = HWIF(drive); struct scatterlist *sg = hwif->sg_table; - BUG_ON((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256); + if ((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256) + BUG(); ide_map_sg(drive, rq); @@ -946,7 +947,8 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p } printk("\n"); - BUG_ON(!hwif->dma_master); + if (!(hwif->dma_master)) + BUG(); } EXPORT_SYMBOL_GPL(ide_setup_dma); diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index 4656587aa2f7..a53e3ce4a142 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -898,7 +898,8 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) "to send us more data than expected " "- discarding data\n"); idefloppy_discard_data(drive,bcount.all); - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, @@ -931,7 +932,8 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) pc->actually_transferred += bcount.all; pc->current_position += bcount.all; - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ return ide_started; } @@ -958,7 +960,8 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) "issuing a packet command\n"); return ide_do_reset(drive); } - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); /* Set the interrupt routine */ ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Send the actual packet */ @@ -1014,7 +1017,8 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) * 40 and 50msec work well. idefloppy_pc_intr will not be actually * used until after the packet is moved in about 50 msec. */ - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &idefloppy_pc_intr, /* service routine for packet command */ floppy->ticks, /* wait this long before "failing" */ @@ -1284,7 +1288,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n", rq->rq_status, - rq->rq_disk ? rq->rq_disk->disk_name : "?", + rq->rq_disk ? rq->rq_disk->disk_name ? "?", rq->flags, rq->errors); debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, " "current_nr_sectors: %d\n", (long)rq->sector, diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 935cb2583770..c01615dec202 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -142,41 +142,38 @@ enum { static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 stat, u8 error) { - struct request_pm_state *pm = rq->end_io_data; - if (drive->media != ide_disk) return; - switch (pm->pm_step) { + switch (rq->pm->pm_step) { case ide_pm_flush_cache: /* Suspend step 1 (flush cache) complete */ - if (pm->pm_state == PM_EVENT_FREEZE) - pm->pm_step = ide_pm_state_completed; + if (rq->pm->pm_state == PM_EVENT_FREEZE) + rq->pm->pm_step = ide_pm_state_completed; else - pm->pm_step = idedisk_pm_standby; + rq->pm->pm_step = idedisk_pm_standby; break; case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ - pm->pm_step = ide_pm_state_completed; + rq->pm->pm_step = ide_pm_state_completed; break; case idedisk_pm_idle: /* Resume step 1 (idle) complete */ - pm->pm_step = ide_pm_restore_dma; + rq->pm->pm_step = ide_pm_restore_dma; break; } } static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->end_io_data; ide_task_t *args = rq->special; memset(args, 0, sizeof(*args)); if (drive->media != ide_disk) { /* skip idedisk_pm_idle for ATAPI devices */ - if (pm->pm_step == idedisk_pm_idle) - pm->pm_step = ide_pm_restore_dma; + if (rq->pm->pm_step == idedisk_pm_idle) + rq->pm->pm_step = ide_pm_restore_dma; } - switch (pm->pm_step) { + switch (rq->pm->pm_step) { case ide_pm_flush_cache: /* Suspend step 1 (flush cache) */ if (drive->media != ide_disk) break; @@ -218,67 +215,10 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * drive->hwif->ide_dma_check(drive); break; } - pm->pm_step = ide_pm_state_completed; + rq->pm->pm_step = ide_pm_state_completed; return ide_stopped; } -/** - * ide_end_dequeued_request - complete an IDE I/O - * @drive: IDE device for the I/O - * @uptodate: - * @nr_sectors: number of sectors completed - * - * Complete an I/O that is no longer on the request queue. This - * typically occurs when we pull the request and issue a REQUEST_SENSE. - * We must still finish the old request but we must not tamper with the - * queue in the meantime. - * - * NOTE: This path does not handle barrier, but barrier is not supported - * on ide-cd anyway. - */ - -int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, - int uptodate, int nr_sectors) -{ - unsigned long flags; - int ret = 1; - - spin_lock_irqsave(&ide_lock, flags); - - BUG_ON(!(rq->flags & REQ_STARTED)); - - /* - * if failfast is set on a request, override number of sectors and - * complete the whole request right now - */ - if (blk_noretry_request(rq) && end_io_error(uptodate)) - nr_sectors = rq->hard_nr_sectors; - - if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors) - rq->errors = -EIO; - - /* - * decide whether to reenable DMA -- 3 is a random magic for now, - * if we DMA timeout more than 3 times, just stay in PIO - */ - if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { - drive->state = 0; - HWGROUP(drive)->hwif->ide_dma_on(drive); - } - - if (!end_that_request_first(rq, uptodate, nr_sectors)) { - add_disk_randomness(rq->rq_disk); - if (blk_rq_tagged(rq)) - blk_queue_end_tag(drive->queue, rq); - end_that_request_last(rq, uptodate); - ret = 0; - } - spin_unlock_irqrestore(&ide_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(ide_end_dequeued_request); - - /** * ide_complete_pm_request - end the current Power Management request * @drive: target drive @@ -422,13 +362,12 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) } } } else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->end_io_data; #ifdef DEBUG_PM printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n", drive->name, rq->pm->pm_step, stat, err); #endif ide_complete_power_step(drive, rq, stat, err); - if (pm->pm_step == ide_pm_state_completed) + if (rq->pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return; } @@ -932,39 +871,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, return ide_stopped; } -static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->end_io_data; - - if (blk_pm_suspend_request(rq) && - pm->pm_step == ide_pm_state_start_suspend) - /* Mark drive blocked when starting the suspend sequence. */ - drive->blocked = 1; - else if (blk_pm_resume_request(rq) && - pm->pm_step == ide_pm_state_start_resume) { - /* - * The first thing we do on wakeup is to wait for BSY bit to - * go away (with a looong timeout) as a drive on this hwif may - * just be POSTing itself. - * We do that before even selecting as the "other" device on - * the bus may be broken enough to walk on our toes at this - * point. - */ - int rc; -#ifdef DEBUG_PM - printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); -#endif - rc = ide_wait_not_busy(HWIF(drive), 35000); - if (rc) - printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); - SELECT_DRIVE(drive); - HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); - rc = ide_wait_not_busy(HWIF(drive), 100000); - if (rc) - printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); - } -} - /** * start_request - start of I/O and command issuing for IDE * @@ -1003,8 +909,33 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (block == 0 && drive->remap_0_to_1 == 1) block = 1; /* redirect MBR access to EZ-Drive partn table */ - if (blk_pm_request(rq)) - ide_check_pm_state(drive, rq); + if (blk_pm_suspend_request(rq) && + rq->pm->pm_step == ide_pm_state_start_suspend) + /* Mark drive blocked when starting the suspend sequence. */ + drive->blocked = 1; + else if (blk_pm_resume_request(rq) && + rq->pm->pm_step == ide_pm_state_start_resume) { + /* + * The first thing we do on wakeup is to wait for BSY bit to + * go away (with a looong timeout) as a drive on this hwif may + * just be POSTing itself. + * We do that before even selecting as the "other" device on + * the bus may be broken enough to walk on our toes at this + * point. + */ + int rc; +#ifdef DEBUG_PM + printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); +#endif + rc = ide_wait_not_busy(HWIF(drive), 35000); + if (rc) + printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); + SELECT_DRIVE(drive); + HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); + rc = ide_wait_not_busy(HWIF(drive), 10000); + if (rc) + printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); + } SELECT_DRIVE(drive); if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { @@ -1019,14 +950,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) else if (rq->flags & REQ_DRIVE_TASKFILE) return execute_drive_cmd(drive, rq); else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->end_io_data; #ifdef DEBUG_PM printk("%s: start_power_step(step: %d)\n", drive->name, rq->pm->pm_step); #endif startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && - pm->pm_step == ide_pm_state_completed) + rq->pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return startstop; } @@ -1665,7 +1595,7 @@ irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs) * Initialize a request before we fill it in and send it down to * ide_do_drive_cmd. Commands must be set up by this function. Right * now it doesn't do a lot, but if that changes abusers will have a - * nasty surprise. + * nasty suprise. */ void ide_init_drive_cmd (struct request *rq) diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 97a49e77a8f1..b72dde70840a 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -939,7 +939,8 @@ void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *ha spin_lock_irqsave(&ide_lock, flags); - BUG_ON(hwgroup->handler); + if(hwgroup->handler) + BUG(); hwgroup->handler = handler; hwgroup->expiry = expiry; hwgroup->timer.expires = jiffies + timeout; @@ -980,7 +981,8 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) printk("%s: ATAPI reset complete\n", drive->name); } else { if (time_before(jiffies, hwgroup->poll_timeout)) { - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; @@ -1019,7 +1021,8 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) if (!OK_STAT(tmp = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { if (time_before(jiffies, hwgroup->poll_timeout)) { - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; @@ -1135,7 +1138,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) hwgroup = HWGROUP(drive); /* We must not reset with running handlers */ - BUG_ON(hwgroup->handler != NULL); + if(hwgroup->handler != NULL) + BUG(); /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->media != ide_disk && !do_not_try_atapi) { diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 7ddb11828731..41d46dbe6c24 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -164,7 +164,8 @@ u8 ide_rate_filter (u8 mode, u8 speed) // printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed); /* So that we remember to update this if new modes appear */ - BUG_ON(mode > 4); + if (mode > 4) + BUG(); return min(speed, speed_max[mode]); #else /* !CONFIG_BLK_DEV_IDEDMA */ return min(speed, (u8)XFER_PIO_4); @@ -485,7 +486,7 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) unsigned long flags; u8 err = 0; - local_irq_save(flags); + local_irq_set(flags); printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); if (stat & BUSY_STAT) printk("Busy "); @@ -567,7 +568,7 @@ static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) status.all = stat; error.all = 0; - local_irq_save(flags); + local_irq_set(flags); printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); if (status.b.bsy) printk("Busy "); diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c index 09f3a7dab28a..f04791a58df0 100644 --- a/trunk/drivers/ide/ide-tape.c +++ b/trunk/drivers/ide/ide-tape.c @@ -2646,23 +2646,21 @@ static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape) return __idetape_kmalloc_stage(tape, 0, 0); } -static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n) +static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n) { struct idetape_bh *bh = tape->bh; int count; - int ret = 0; while (n) { #if IDETAPE_DEBUG_BUGS if (bh == NULL) { printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_copy_stage_from_user\n"); - return 1; + return; } #endif /* IDETAPE_DEBUG_BUGS */ count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), (unsigned int)n); - if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count)) - ret = 1; + copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count); n -= count; atomic_add(count, &bh->b_count); buf += count; @@ -2673,26 +2671,23 @@ static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t * } } tape->bh = bh; - return ret; } -static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n) +static void idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n) { struct idetape_bh *bh = tape->bh; int count; - int ret = 0; while (n) { #if IDETAPE_DEBUG_BUGS if (bh == NULL) { printk(KERN_ERR "ide-tape: bh == NULL in " "idetape_copy_stage_to_user\n"); - return 1; + return; } #endif /* IDETAPE_DEBUG_BUGS */ count = min(tape->b_count, n); - if (copy_to_user(buf, tape->b_data, count)) - ret = 1; + copy_to_user(buf, tape->b_data, count); n -= count; tape->b_data += count; tape->b_count -= count; @@ -2705,7 +2700,6 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i } } } - return ret; } static void idetape_init_merge_stage (idetape_tape_t *tape) @@ -3725,7 +3719,6 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, struct ide_tape_obj *tape = ide_tape_f(file); ide_drive_t *drive = tape->drive; ssize_t bytes_read,temp, actually_read = 0, rc; - ssize_t ret = 0; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 3) @@ -3744,8 +3737,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, return (0); if (tape->merge_stage_size) { actually_read = min((unsigned int)(tape->merge_stage_size), (unsigned int)count); - if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, actually_read)) - ret = -EFAULT; + idetape_copy_stage_to_user(tape, buf, tape->merge_stage, actually_read); buf += actually_read; tape->merge_stage_size -= actually_read; count -= actually_read; @@ -3754,8 +3746,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, bytes_read = idetape_add_chrdev_read_request(drive, tape->capabilities.ctl); if (bytes_read <= 0) goto finish; - if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, bytes_read)) - ret = -EFAULT; + idetape_copy_stage_to_user(tape, buf, tape->merge_stage, bytes_read); buf += bytes_read; count -= bytes_read; actually_read += bytes_read; @@ -3765,8 +3756,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, if (bytes_read <= 0) goto finish; temp = min((unsigned long)count, (unsigned long)bytes_read); - if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, temp)) - ret = -EFAULT; + idetape_copy_stage_to_user(tape, buf, tape->merge_stage, temp); actually_read += temp; tape->merge_stage_size = bytes_read-temp; } @@ -3779,8 +3769,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, idetape_space_over_filemarks(drive, MTFSF, 1); return 0; } - - return (ret) ? ret : actually_read; + return actually_read; } static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, @@ -3788,8 +3777,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, { struct ide_tape_obj *tape = ide_tape_f(file); ide_drive_t *drive = tape->drive; - ssize_t actually_written = 0; - ssize_t ret = 0; + ssize_t retval, actually_written = 0; /* The drive is write protected. */ if (tape->write_prot) @@ -3825,7 +3813,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, * some drives (Seagate STT3401A) will return an error. */ if (drive->dsc_overlap) { - ssize_t retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh); + retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh); if (retval < 0) { __idetape_kfree_stage(tape->merge_stage); tape->merge_stage = NULL; @@ -3846,14 +3834,12 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, } #endif /* IDETAPE_DEBUG_BUGS */ actually_written = min((unsigned int)(tape->stage_size - tape->merge_stage_size), (unsigned int)count); - if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written)) - ret = -EFAULT; + idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written); buf += actually_written; tape->merge_stage_size += actually_written; count -= actually_written; if (tape->merge_stage_size == tape->stage_size) { - ssize_t retval; tape->merge_stage_size = 0; retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl); if (retval <= 0) @@ -3861,9 +3847,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, } } while (count >= tape->stage_size) { - ssize_t retval; - if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, tape->stage_size)) - ret = -EFAULT; + idetape_copy_stage_from_user(tape, tape->merge_stage, buf, tape->stage_size); buf += tape->stage_size; count -= tape->stage_size; retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl); @@ -3873,11 +3857,10 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, } if (count) { actually_written += count; - if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, count)) - ret = -EFAULT; + idetape_copy_stage_from_user(tape, tape->merge_stage, buf, count); tape->merge_stage_size += count; } - return (ret) ? ret : actually_written; + return (actually_written); } static int idetape_write_filemark (ide_drive_t *drive) diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index a839b2a8f6f4..9233b8109a0f 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -196,7 +196,8 @@ ide_startstop_t set_geometry_intr (ide_drive_t *drive) if (stat & (ERR_STAT|DRQ_STAT)) return ide_error(drive, "set_geometry_intr", stat); - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); return ide_started; } diff --git a/trunk/drivers/ide/ide-timing.h b/trunk/drivers/ide/ide-timing.h index c0864b1e9228..2fcfac6e967a 100644 --- a/trunk/drivers/ide/ide-timing.h +++ b/trunk/drivers/ide/ide-timing.h @@ -219,12 +219,6 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing if (!(s = ide_timing_find_mode(speed))) return -EINVAL; -/* - * Copy the timing from the table. - */ - - *t = *s; - /* * If the drive is an EIDE drive, it can tell us it needs extended * PIO/MWDMA cycle timing. @@ -253,7 +247,7 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing * Convert the timing to bus clock counts. */ - ide_timing_quantize(t, t, T, UT); + ide_timing_quantize(s, t, T, UT); /* * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 59fe358048b3..3fdab563fec2 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -726,7 +726,6 @@ void ide_setup_ports ( hw_regs_t *hw, { int i; - memset(hw, 0, sizeof(hw_regs_t)); for (i = 0; i < IDE_NR_PORTS; i++) { if (offsets[i] == -1) { switch(i) { @@ -1226,7 +1225,7 @@ static int generic_ide_suspend(struct device *dev, pm_message_t state) memset(&args, 0, sizeof(args)); rq.flags = REQ_PM_SUSPEND; rq.special = &args; - rq.end_io_data = &rqpm; + rq.pm = &rqpm; rqpm.pm_step = ide_pm_state_start_suspend; rqpm.pm_state = state.event; @@ -1245,7 +1244,7 @@ static int generic_ide_resume(struct device *dev) memset(&args, 0, sizeof(args)); rq.flags = REQ_PM_RESUME; rq.special = &args; - rq.end_io_data = &rqpm; + rq.pm = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; @@ -1367,7 +1366,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ide_abort(drive, "drive reset"); - BUG_ON(HWGROUP(drive)->handler); + if(HWGROUP(drive)->handler) + BUG(); /* Ensure nothing gets queued after we drop the lock. Reset will clear the busy */ diff --git a/trunk/drivers/ide/legacy/q40ide.c b/trunk/drivers/ide/legacy/q40ide.c index 434a94faa3b7..2a78b792f7fb 100644 --- a/trunk/drivers/ide/legacy/q40ide.c +++ b/trunk/drivers/ide/legacy/q40ide.c @@ -80,7 +80,6 @@ void q40_ide_setup_ports ( hw_regs_t *hw, { int i; - memset(hw, 0, sizeof(hw_regs_t)); for (i = 0; i < IDE_NR_PORTS; i++) { /* BIG FAT WARNING: assumption: only DATA port is ever used in 16 bit mode */ diff --git a/trunk/drivers/ide/pci/amd74xx.c b/trunk/drivers/ide/pci/amd74xx.c index 85007cb12c52..b22ee5462318 100644 --- a/trunk/drivers/ide/pci/amd74xx.c +++ b/trunk/drivers/ide/pci/amd74xx.c @@ -74,8 +74,6 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, { 0 } }; @@ -490,9 +488,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), - /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), - /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), - /* 19 */ DECLARE_AMD_DEV("AMD5536"), + /* 17 */ DECLARE_AMD_DEV("AMD5536"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -529,9 +525,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 22d17548ecdb..7ce5bf783688 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -370,6 +370,7 @@ static int config_chipset_for_dma (ide_drive_t *drive) if (!(speed)) { /* restore original pci-config space */ pci_write_config_dword(dev, drive_pci, drive_conf); + hwif->tuneproc(drive, 5); return 0; } @@ -414,6 +415,8 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) if (drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); +// struct pci_dev *dev = hwif->pci_dev; +// unsgned long high_16 = pci_resource_start(dev, 4); unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u32 word_count = 0; @@ -433,6 +436,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) { if (drive->addressing == 1) { ide_hwif_t *hwif = HWIF(drive); +// unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u8 clock = 0; @@ -449,6 +453,8 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); +// struct pci_dev *dev = hwif->pci_dev; +// unsigned long high_16 = pci_resource_start(dev, 4); unsigned long high_16 = hwif->dma_master; u8 dma_stat = hwif->INB(hwif->dma_status); u8 sc1d = hwif->INB((high_16 + 0x001d)); @@ -486,7 +492,12 @@ static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) static void pdc202xx_reset_host (ide_hwif_t *hwif) { +#ifdef CONFIG_BLK_DEV_IDEDMA +// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); unsigned long high_16 = hwif->dma_master; +#else /* !CONFIG_BLK_DEV_IDEDMA */ + unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); +#endif /* CONFIG_BLK_DEV_IDEDMA */ u8 udma_speed_flag = hwif->INB(high_16|0x001f); hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f)); @@ -539,6 +550,31 @@ static void pdc202xx_reset (ide_drive_t *drive) #endif } +/* + * Since SUN Cobalt is attempting to do this operation, I should disclose + * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date + * HOTSWAP ATA Infrastructure. + */ +static int pdc202xx_tristate (ide_drive_t * drive, int state) +{ + ide_hwif_t *hwif = HWIF(drive); +// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); + unsigned long high_16 = hwif->dma_master; + u8 sc1f = hwif->INB(high_16|0x001f); + + if (!hwif) + return -EINVAL; + +// hwif->bus_state = state; + + if (state) { + hwif->OUTB(sc1f | 0x08, (high_16|0x001f)); + } else { + hwif->OUTB(sc1f & ~0x08, (high_16|0x001f)); + } + return 0; +} + static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) { if (dev->resource[PCI_ROM_RESOURCE].start) { @@ -588,8 +624,10 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->tuneproc = &config_chipset_for_pio; hwif->quirkproc = &pdc202xx_quirkproc; - if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) + if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { + hwif->busproc = &pdc202xx_tristate; hwif->resetproc = &pdc202xx_reset; + } hwif->speedproc = &pdc202xx_tune_chipset; diff --git a/trunk/drivers/ide/pci/piix.c b/trunk/drivers/ide/pci/piix.c index 7fac6f57b5d6..e9b83e1a3028 100644 --- a/trunk/drivers/ide/pci/piix.c +++ b/trunk/drivers/ide/pci/piix.c @@ -222,8 +222,6 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) unsigned long flags; u16 master_data; u8 slave_data; - static DEFINE_SPINLOCK(tune_lock); - /* ISP RTC */ u8 timings[][2] = { { 0, 0 }, { 0, 0 }, @@ -232,13 +230,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) { 2, 3 }, }; pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - - /* - * Master vs slave is synchronized above us but the slave register is - * shared by the two hwifs so the corner case of two slave timeouts in - * parallel must be locked. - */ - spin_lock_irqsave(&tune_lock, flags); + spin_lock_irqsave(&ide_lock, flags); pci_read_config_word(dev, master_port, &master_data); if (is_slave) { master_data = master_data | 0x4000; @@ -258,7 +250,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) pci_write_config_word(dev, master_port, master_data); if (is_slave) pci_write_config_byte(dev, slave_port, slave_data); - spin_unlock_irqrestore(&tune_lock, flags); + spin_unlock_irqrestore(&ide_lock, flags); } /** diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index e125032bb403..27c9eb989a9a 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -723,12 +723,6 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { int ioc4_ide_attach_one(struct ioc4_driver_data *idd) { - /* PCI-RT does not bring out IDE connection. - * Do not attach to this particular IOC4. - */ - if (idd->idd_variant == IOC4_VARIANT_PCI_RT) - return 0; - return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipsets[idd->idd_pci_id->driver_data]); } diff --git a/trunk/drivers/ide/pci/trm290.c b/trunk/drivers/ide/pci/trm290.c index fe80295974e1..c26c8ca90dd4 100644 --- a/trunk/drivers/ide/pci/trm290.c +++ b/trunk/drivers/ide/pci/trm290.c @@ -183,7 +183,8 @@ static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) { ide_hwif_t *hwif = HWIF(drive); - BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */ + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ + BUG(); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ hwif->OUTB(command, IDE_COMMAND_REG); diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c index 2d5b57be98c3..5bda15904a08 100644 --- a/trunk/drivers/ieee1394/eth1394.c +++ b/trunk/drivers/ieee1394/eth1394.c @@ -1074,7 +1074,8 @@ static inline int update_partial_datagram(struct list_head *pdgl, struct list_he /* Move list entry to beginnig of list so that oldest partial * datagrams percolate to the end of the list */ - list_move(lh, pdgl); + list_del(lh); + list_add(lh, pdgl); return 0; } diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c index ad49c040b674..2d47b11777a5 100644 --- a/trunk/drivers/ieee1394/hosts.c +++ b/trunk/drivers/ieee1394/hosts.c @@ -103,7 +103,7 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data) * driver specific parts, enable the controller and make it available * to the general subsystem using hpsb_add_host(). * - * Return Value: a pointer to the &hpsb_host if successful, %NULL if + * Return Value: a pointer to the &hpsb_host if succesful, %NULL if * no memory was available. */ static DEFINE_MUTEX(host_num_alloc); diff --git a/trunk/drivers/ieee1394/ieee1394_core.h b/trunk/drivers/ieee1394/ieee1394_core.h index 0ecbf335c64f..e7b55e895f50 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.h +++ b/trunk/drivers/ieee1394/ieee1394_core.h @@ -139,7 +139,7 @@ int hpsb_bus_reset(struct hpsb_host *host); /* * Hand over received selfid packet to the core. Complement check (second - * quadlet is complement of first) is expected to be done and successful. + * quadlet is complement of first) is expected to be done and succesful. */ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid); diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 50c71e17de73..948f1b8c4238 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -8,7 +8,6 @@ * directory of the kernel sources for details. */ -#include #include #include #include @@ -335,12 +334,10 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribut static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL); -/* tlabels_free, tlabels_allocations, tlabels_mask are read non-atomically - * here, therefore displayed values may be occasionally wrong. */ static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf) { struct node_entry *ne = container_of(dev, struct node_entry, device); - return sprintf(buf, "%d\n", 64 - bitmap_weight(ne->tpool->pool, 64)); + return sprintf(buf, "%d\n", atomic_read(&ne->tpool->count.count) + 1); } static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL); diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index 571ea68c0cf2..20ce539580f1 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -132,7 +132,8 @@ static void free_pending_request(struct pending_request *req) static void __queue_complete_req(struct pending_request *req) { struct file_info *fi = req->file_info; - list_move_tail(&req->list, &fi->req_complete); + list_del(&req->list); + list_add_tail(&req->list, &fi->req_complete); up(&fi->complete_sem); wake_up_interruptible(&fi->poll_wait_complete); diff --git a/trunk/drivers/infiniband/Kconfig b/trunk/drivers/infiniband/Kconfig index 69a53d476b5b..ba2d6505e9a4 100644 --- a/trunk/drivers/infiniband/Kconfig +++ b/trunk/drivers/infiniband/Kconfig @@ -41,6 +41,4 @@ source "drivers/infiniband/ulp/ipoib/Kconfig" source "drivers/infiniband/ulp/srp/Kconfig" -source "drivers/infiniband/ulp/iser/Kconfig" - endmenu diff --git a/trunk/drivers/infiniband/Makefile b/trunk/drivers/infiniband/Makefile index c7ff58c1d0e5..eea27322a22d 100644 --- a/trunk/drivers/infiniband/Makefile +++ b/trunk/drivers/infiniband/Makefile @@ -3,4 +3,3 @@ obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ obj-$(CONFIG_IPATH_CORE) += hw/ipath/ obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ -obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/ diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 863f64befc7c..a76834edf608 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -476,7 +476,7 @@ static inline int cma_zero_addr(struct sockaddr *addr) else { ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr; return (ip6->s6_addr32[0] | ip6->s6_addr32[1] | - ip6->s6_addr32[2] | ip6->s6_addr32[3]) == 0; + ip6->s6_addr32[3] | ip6->s6_addr32[4]) == 0; } } diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index 5ed4dab52a6f..b38e02a5db35 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -1775,9 +1775,11 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr) { mad_send_wr->timeout = 0; - if (mad_send_wr->refcount == 1) - list_move_tail(&mad_send_wr->agent_list, + if (mad_send_wr->refcount == 1) { + list_del(&mad_send_wr->agent_list); + list_add_tail(&mad_send_wr->agent_list, &mad_send_wr->mad_agent_priv->done_list); + } } static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, @@ -2096,7 +2098,8 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv, queued_send_wr = container_of(mad_list, struct ib_mad_send_wr_private, mad_list); - list_move_tail(&mad_list->list, &send_queue->list); + list_del(&mad_list->list); + list_add_tail(&mad_list->list, &send_queue->list); } spin_unlock_irqrestore(&send_queue->lock, flags); diff --git a/trunk/drivers/infiniband/core/mad_rmpp.c b/trunk/drivers/infiniband/core/mad_rmpp.c index ebcd5b181770..d4704e054e30 100644 --- a/trunk/drivers/infiniband/core/mad_rmpp.c +++ b/trunk/drivers/infiniband/core/mad_rmpp.c @@ -665,7 +665,8 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, goto out; mad_send_wr->refcount++; - list_move_tail(&mad_send_wr->agent_list, + list_del(&mad_send_wr->agent_list); + list_add_tail(&mad_send_wr->agent_list, &mad_send_wr->mad_agent_priv->send_list); } out: diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index a908a7bdcd7f..76bf61e9b552 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -1530,6 +1530,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, out_put: put_qp_read(qp); +out: while (wr) { if (is_ud && wr->wr.ud.ah) put_ah_read(wr->wr.ud.ah); @@ -1538,7 +1539,6 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, wr = next; } -out: kfree(user_wr); return ret ? ret : in_len; diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index e725cccc7cde..5ec2d49e9bb6 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -188,6 +188,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_ah_idr, uobj); ib_destroy_ah(ah); + list_del(&uobj->list); kfree(uobj); } @@ -199,6 +200,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_qp_idr, uobj); ib_uverbs_detach_umcast(qp, uqp); ib_destroy_qp(qp); + list_del(&uobj->list); ib_uverbs_release_uevent(file, &uqp->uevent); kfree(uqp); } @@ -211,6 +213,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_cq_idr, uobj); ib_destroy_cq(cq); + list_del(&uobj->list); ib_uverbs_release_ucq(file, ev_file, ucq); kfree(ucq); } @@ -222,6 +225,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_srq_idr, uobj); ib_destroy_srq(srq); + list_del(&uobj->list); ib_uverbs_release_uevent(file, uevent); kfree(uevent); } @@ -239,6 +243,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, memobj = container_of(uobj, struct ib_umem_object, uobject); ib_umem_release_on_close(mrdev, &memobj->umem); + list_del(&uobj->list); kfree(memobj); } @@ -247,6 +252,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_pd_idr, uobj); ib_dealloc_pd(pd); + list_del(&uobj->list); kfree(uobj); } @@ -815,12 +821,11 @@ static void ib_uverbs_remove_one(struct ib_device *device) kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); } -static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data, - struct vfsmount *mnt) +static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data) { return get_sb_pseudo(fs_type, "infinibandevent:", NULL, - INFINIBANDEVENTFS_MAGIC, mnt); + INFINIBANDEVENTFS_MAGIC); } static struct file_system_type uverbs_event_fs = { diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index 63de3046aff3..e274120567e1 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -542,14 +542,13 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, return ret; } -static int ipathfs_get_sb(struct file_system_type *fs_type, int flags, - const char *dev_name, void *data, struct vfsmount *mnt) +static struct super_block *ipathfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) { - int ret = get_sb_single(fs_type, flags, data, - ipathfs_fill_super, mnt); - if (ret >= 0) - ipath_super = mnt->mnt_sb; - return ret; + ipath_super = get_sb_single(fs_type, flags, data, + ipathfs_fill_super); + return ipath_super; } static void ipathfs_kill_super(struct super_block *s) diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ab40488182b3..216471fa01cc 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -864,7 +864,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) if (mcast) { /* Destroy the send only entry */ - list_move_tail(&mcast->list, &remove_list); + list_del(&mcast->list); + list_add_tail(&mcast->list, &remove_list); rb_replace_node(&mcast->rb_node, &nmcast->rb_node, @@ -889,7 +890,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) rb_erase(&mcast->rb_node, &priv->multicast_tree); /* Move to the remove list */ - list_move_tail(&mcast->list, &remove_list); + list_del(&mcast->list); + list_add_tail(&mcast->list, &remove_list); } } diff --git a/trunk/drivers/infiniband/ulp/iser/Kconfig b/trunk/drivers/infiniband/ulp/iser/Kconfig deleted file mode 100644 index fead87d1eff9..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config INFINIBAND_ISER - tristate "ISCSI RDMA Protocol" - depends on INFINIBAND && SCSI - select SCSI_ISCSI_ATTRS - ---help--- - Support for the ISCSI RDMA Protocol over InfiniBand. This - allows you to access storage devices that speak ISER/ISCSI - over InfiniBand. - - The ISER protocol is defined by IETF. - See . diff --git a/trunk/drivers/infiniband/ulp/iser/Makefile b/trunk/drivers/infiniband/ulp/iser/Makefile deleted file mode 100644 index fe6cd15f2317..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_INFINIBAND_ISER) += ib_iser.o - -ib_iser-y := iser_verbs.o iser_initiator.o iser_memory.o \ - iscsi_iser.o diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c deleted file mode 100644 index 4c3f2de2a06e..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ /dev/null @@ -1,790 +0,0 @@ -/* - * iSCSI Initiator over iSER Data-Path - * - * Copyright (C) 2004 Dmitry Yusupov - * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 Mike Christie - * Copyright (c) 2005, 2006 Voltaire, Inc. All rights reserved. - * maintained by openib-general@openib.org - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Credits: - * Christoph Hellwig - * FUJITA Tomonori - * Arne Redlich - * Zhenyu Wang - * Modified by: - * Erez Zilber - * - * - * $Id: iscsi_iser.c 6965 2006-05-07 11:36:20Z ogerlitz $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "iscsi_iser.h" - -static unsigned int iscsi_max_lun = 512; -module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); - -int iser_debug_level = 0; - -MODULE_DESCRIPTION("iSER (iSCSI Extensions for RDMA) Datamover " - "v" DRV_VER " (" DRV_DATE ")"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_AUTHOR("Alex Nezhinsky, Dan Bar Dov, Or Gerlitz"); - -module_param_named(debug_level, iser_debug_level, int, 0644); -MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:disabled)"); - -struct iser_global ig; - -void -iscsi_iser_recv(struct iscsi_conn *conn, - struct iscsi_hdr *hdr, char *rx_data, int rx_data_len) -{ - int rc = 0; - uint32_t ret_itt; - int datalen; - int ahslen; - - /* verify PDU length */ - datalen = ntoh24(hdr->dlength); - if (datalen != rx_data_len) { - printk(KERN_ERR "iscsi_iser: datalen %d (hdr) != %d (IB) \n", - datalen, rx_data_len); - rc = ISCSI_ERR_DATALEN; - goto error; - } - - /* read AHS */ - ahslen = hdr->hlength * 4; - - /* verify itt (itt encoding: age+cid+itt) */ - rc = iscsi_verify_itt(conn, hdr, &ret_itt); - - if (!rc) - rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len); - - if (rc && rc != ISCSI_ERR_NO_SCSI_CMD) - goto error; - - return; -error: - iscsi_conn_failure(conn, rc); -} - - -/** - * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands - * - **/ -static void -iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) -{ - struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct scsi_cmnd *sc = ctask->sc; - - iser_ctask->command_sent = 0; - iser_ctask->iser_conn = iser_conn; - - if (sc->sc_data_direction == DMA_TO_DEVICE) { - BUG_ON(ctask->total_length == 0); - /* bytes to be sent via RDMA operations */ - iser_ctask->rdma_data_count = ctask->total_length - - ctask->imm_count - - ctask->unsol_count; - - debug_scsi("cmd [itt %x total %d imm %d unsol_data %d " - "rdma_data %d]\n", - ctask->itt, ctask->total_length, ctask->imm_count, - ctask->unsol_count, iser_ctask->rdma_data_count); - } else - /* bytes to be sent via RDMA operations */ - iser_ctask->rdma_data_count = ctask->total_length; - - iser_ctask_rdma_init(iser_ctask); -} - -/** - * iscsi_mtask_xmit - xmit management(immediate) task - * @conn: iscsi connection - * @mtask: task management task - * - * Notes: - * The function can return -EAGAIN in which case caller must - * call it again later, or recover. '0' return code means successful - * xmit. - * - **/ -static int -iscsi_iser_mtask_xmit(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) -{ - int error = 0; - - debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt); - - error = iser_send_control(conn, mtask); - - /* since iser xmits control with zero copy, mtasks can not be recycled - * right after sending them. - * The recycling scheme is based on whether a response is expected - * - if yes, the mtask is recycled at iscsi_complete_pdu - * - if no, the mtask is recycled at iser_snd_completion - */ - if (error && error != -EAGAIN) - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - - return error; -} - -static int -iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) -{ - struct iscsi_data hdr; - int error = 0; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - - /* Send data-out PDUs while there's still unsolicited data to send */ - while (ctask->unsol_count > 0) { - iscsi_prep_unsolicit_data_pdu(ctask, &hdr, - iser_ctask->rdma_data_count); - - debug_scsi("Sending data-out: itt 0x%x, data count %d\n", - hdr.itt, ctask->data_count); - - /* the buffer description has been passed with the command */ - /* Send the command */ - error = iser_send_data_out(conn, ctask, &hdr); - if (error) { - ctask->unsol_datasn--; - goto iscsi_iser_ctask_xmit_unsol_data_exit; - } - ctask->unsol_count -= ctask->data_count; - debug_scsi("Need to send %d more as data-out PDUs\n", - ctask->unsol_count); - } - -iscsi_iser_ctask_xmit_unsol_data_exit: - return error; -} - -static int -iscsi_iser_ctask_xmit(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) -{ - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - int error = 0; - - debug_scsi("ctask deq [cid %d itt 0x%x]\n", - conn->id, ctask->itt); - - /* - * serialize with TMF AbortTask - */ - if (ctask->mtask) - return error; - - /* Send the cmd PDU */ - if (!iser_ctask->command_sent) { - error = iser_send_command(conn, ctask); - if (error) - goto iscsi_iser_ctask_xmit_exit; - iser_ctask->command_sent = 1; - } - - /* Send unsolicited data-out PDU(s) if necessary */ - if (ctask->unsol_count) - error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask); - - iscsi_iser_ctask_xmit_exit: - if (error && error != -EAGAIN) - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - return error; -} - -static void -iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) -{ - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - - if (iser_ctask->status == ISER_TASK_STATUS_STARTED) { - iser_ctask->status = ISER_TASK_STATUS_COMPLETED; - iser_ctask_rdma_finalize(iser_ctask); - } -} - -static struct iser_conn * -iscsi_iser_ib_conn_lookup(__u64 ep_handle) -{ - struct iser_conn *ib_conn; - struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle; - - mutex_lock(&ig.connlist_mutex); - list_for_each_entry(ib_conn, &ig.connlist, conn_list) { - if (ib_conn == uib_conn) { - mutex_unlock(&ig.connlist_mutex); - return ib_conn; - } - } - mutex_unlock(&ig.connlist_mutex); - iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle); - return NULL; -} - -static struct iscsi_cls_conn * -iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) -{ - struct iscsi_conn *conn; - struct iscsi_cls_conn *cls_conn; - struct iscsi_iser_conn *iser_conn; - - cls_conn = iscsi_conn_setup(cls_session, conn_idx); - if (!cls_conn) - return NULL; - conn = cls_conn->dd_data; - - /* - * due to issues with the login code re iser sematics - * this not set in iscsi_conn_setup - FIXME - */ - conn->max_recv_dlength = 128; - - iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL); - if (!iser_conn) - goto conn_alloc_fail; - - /* currently this is the only field which need to be initiated */ - rwlock_init(&iser_conn->lock); - - conn->dd_data = iser_conn; - iser_conn->iscsi_conn = conn; - - return cls_conn; - -conn_alloc_fail: - iscsi_conn_teardown(cls_conn); - return NULL; -} - -static void -iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_iser_conn *iser_conn = conn->dd_data; - - iscsi_conn_teardown(cls_conn); - kfree(iser_conn); -} - -static int -iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, - struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, - int is_leading) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_iser_conn *iser_conn; - struct iser_conn *ib_conn; - int error; - - error = iscsi_conn_bind(cls_session, cls_conn, is_leading); - if (error) - return error; - - /* the transport ep handle comes from user space so it must be - * verified against the global ib connections list */ - ib_conn = iscsi_iser_ib_conn_lookup(transport_eph); - if (!ib_conn) { - iser_err("can't bind eph %llx\n", - (unsigned long long)transport_eph); - return -EINVAL; - } - /* binds the iSER connection retrieved from the previously - * connected ep_handle to the iSCSI layer connection. exchanges - * connection pointers */ - iser_err("binding iscsi conn %p to iser_conn %p\n",conn,ib_conn); - iser_conn = conn->dd_data; - ib_conn->iser_conn = iser_conn; - iser_conn->ib_conn = ib_conn; - - conn->recv_lock = &iser_conn->lock; - - return 0; -} - -static int -iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - int err; - - err = iscsi_conn_start(cls_conn); - if (err) - return err; - - return iser_conn_set_full_featured_mode(conn); -} - -static void -iscsi_iser_conn_terminate(struct iscsi_conn *conn) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iser_conn *ib_conn = iser_conn->ib_conn; - - BUG_ON(!ib_conn); - /* starts conn teardown process, waits until all previously * - * posted buffers get flushed, deallocates all conn resources */ - iser_conn_terminate(ib_conn); - iser_conn->ib_conn = NULL; - conn->recv_lock = NULL; -} - - -static struct iscsi_transport iscsi_iser_transport; - -static struct iscsi_cls_session * -iscsi_iser_session_create(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - uint32_t initial_cmdsn, uint32_t *hostno) -{ - struct iscsi_cls_session *cls_session; - struct iscsi_session *session; - int i; - uint32_t hn; - struct iscsi_cmd_task *ctask; - struct iscsi_mgmt_task *mtask; - struct iscsi_iser_cmd_task *iser_ctask; - struct iser_desc *desc; - - cls_session = iscsi_session_setup(iscsit, scsit, - sizeof(struct iscsi_iser_cmd_task), - sizeof(struct iser_desc), - initial_cmdsn, &hn); - if (!cls_session) - return NULL; - - *hostno = hn; - session = class_to_transport_session(cls_session); - - /* libiscsi setup itts, data and pool so just set desc fields */ - for (i = 0; i < session->cmds_max; i++) { - ctask = session->cmds[i]; - iser_ctask = ctask->dd_data; - ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header; - } - - for (i = 0; i < session->mgmtpool_max; i++) { - mtask = session->mgmt_cmds[i]; - desc = mtask->dd_data; - mtask->hdr = &desc->iscsi_header; - desc->data = mtask->data; - } - - return cls_session; -} - -static int -iscsi_iser_conn_set_param(struct iscsi_cls_conn *cls_conn, - enum iscsi_param param, uint32_t value) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_session *session = conn->session; - - spin_lock_bh(&session->lock); - if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && - conn->stop_stage != STOP_CONN_RECOVER) { - printk(KERN_ERR "iscsi_iser: can not change parameter [%d]\n", - param); - spin_unlock_bh(&session->lock); - return 0; - } - spin_unlock_bh(&session->lock); - - switch (param) { - case ISCSI_PARAM_MAX_RECV_DLENGTH: - /* TBD */ - break; - case ISCSI_PARAM_MAX_XMIT_DLENGTH: - conn->max_xmit_dlength = value; - break; - case ISCSI_PARAM_HDRDGST_EN: - if (value) { - printk(KERN_ERR "DataDigest wasn't negotiated to None"); - return -EPROTO; - } - break; - case ISCSI_PARAM_DATADGST_EN: - if (value) { - printk(KERN_ERR "DataDigest wasn't negotiated to None"); - return -EPROTO; - } - break; - case ISCSI_PARAM_INITIAL_R2T_EN: - session->initial_r2t_en = value; - break; - case ISCSI_PARAM_IMM_DATA_EN: - session->imm_data_en = value; - break; - case ISCSI_PARAM_FIRST_BURST: - session->first_burst = value; - break; - case ISCSI_PARAM_MAX_BURST: - session->max_burst = value; - break; - case ISCSI_PARAM_PDU_INORDER_EN: - session->pdu_inorder_en = value; - break; - case ISCSI_PARAM_DATASEQ_INORDER_EN: - session->dataseq_inorder_en = value; - break; - case ISCSI_PARAM_ERL: - session->erl = value; - break; - case ISCSI_PARAM_IFMARKER_EN: - if (value) { - printk(KERN_ERR "IFMarker wasn't negotiated to No"); - return -EPROTO; - } - break; - case ISCSI_PARAM_OFMARKER_EN: - if (value) { - printk(KERN_ERR "OFMarker wasn't negotiated to No"); - return -EPROTO; - } - break; - default: - break; - } - - return 0; -} - -static int -iscsi_iser_session_get_param(struct iscsi_cls_session *cls_session, - enum iscsi_param param, uint32_t *value) -{ - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); - - switch (param) { - case ISCSI_PARAM_INITIAL_R2T_EN: - *value = session->initial_r2t_en; - break; - case ISCSI_PARAM_MAX_R2T: - *value = session->max_r2t; - break; - case ISCSI_PARAM_IMM_DATA_EN: - *value = session->imm_data_en; - break; - case ISCSI_PARAM_FIRST_BURST: - *value = session->first_burst; - break; - case ISCSI_PARAM_MAX_BURST: - *value = session->max_burst; - break; - case ISCSI_PARAM_PDU_INORDER_EN: - *value = session->pdu_inorder_en; - break; - case ISCSI_PARAM_DATASEQ_INORDER_EN: - *value = session->dataseq_inorder_en; - break; - case ISCSI_PARAM_ERL: - *value = session->erl; - break; - case ISCSI_PARAM_IFMARKER_EN: - *value = 0; - break; - case ISCSI_PARAM_OFMARKER_EN: - *value = 0; - break; - default: - return ISCSI_ERR_PARAM_NOT_FOUND; - } - - return 0; -} - -static int -iscsi_iser_conn_get_param(struct iscsi_cls_conn *cls_conn, - enum iscsi_param param, uint32_t *value) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - - switch(param) { - case ISCSI_PARAM_MAX_RECV_DLENGTH: - *value = conn->max_recv_dlength; - break; - case ISCSI_PARAM_MAX_XMIT_DLENGTH: - *value = conn->max_xmit_dlength; - break; - case ISCSI_PARAM_HDRDGST_EN: - *value = 0; - break; - case ISCSI_PARAM_DATADGST_EN: - *value = 0; - break; - /*case ISCSI_PARAM_TARGET_RECV_DLENGTH: - *value = conn->target_recv_dlength; - break; - case ISCSI_PARAM_INITIATOR_RECV_DLENGTH: - *value = conn->initiator_recv_dlength; - break;*/ - default: - return ISCSI_ERR_PARAM_NOT_FOUND; - } - - return 0; -} - - -static void -iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - - stats->txdata_octets = conn->txdata_octets; - stats->rxdata_octets = conn->rxdata_octets; - stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; - stats->dataout_pdus = conn->dataout_pdus_cnt; - stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; - stats->datain_pdus = conn->datain_pdus_cnt; /* always 0 */ - stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ - stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; - stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; - stats->custom_length = 3; - strcpy(stats->custom[0].desc, "qp_tx_queue_full"); - stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ - strcpy(stats->custom[1].desc, "fmr_map_not_avail"); - stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; - strcpy(stats->custom[2].desc, "eh_abort_cnt"); - stats->custom[2].value = conn->eh_abort_cnt; -} - -static int -iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking, - __u64 *ep_handle) -{ - int err; - struct iser_conn *ib_conn; - - err = iser_conn_init(&ib_conn); - if (err) - goto out; - - err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking); - if (!err) - *ep_handle = (__u64)(unsigned long)ib_conn; - -out: - return err; -} - -static int -iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) -{ - struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); - int rc; - - if (!ib_conn) - return -EINVAL; - - rc = wait_event_interruptible_timeout(ib_conn->wait, - ib_conn->state == ISER_CONN_UP, - msecs_to_jiffies(timeout_ms)); - - /* if conn establishment failed, return error code to iscsi */ - if (!rc && - (ib_conn->state == ISER_CONN_TERMINATING || - ib_conn->state == ISER_CONN_DOWN)) - rc = -1; - - iser_err("ib conn %p rc = %d\n", ib_conn, rc); - - if (rc > 0) - return 1; /* success, this is the equivalent of POLLOUT */ - else if (!rc) - return 0; /* timeout */ - else - return rc; /* signal */ -} - -static void -iscsi_iser_ep_disconnect(__u64 ep_handle) -{ - struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); - - if (!ib_conn) - return; - - iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state); - - iser_conn_terminate(ib_conn); -} - -static struct scsi_host_template iscsi_iser_sht = { - .name = "iSCSI Initiator over iSER, v." DRV_VER, - .queuecommand = iscsi_queuecommand, - .can_queue = ISCSI_XMIT_CMDS_MAX - 1, - .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, - .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN, - .eh_abort_handler = iscsi_eh_abort, - .eh_host_reset_handler = iscsi_eh_host_reset, - .use_clustering = DISABLE_CLUSTERING, - .proc_name = "iscsi_iser", - .this_id = -1, -}; - -static struct iscsi_transport iscsi_iser_transport = { - .owner = THIS_MODULE, - .name = "iser", - .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T, - .param_mask = ISCSI_MAX_RECV_DLENGTH | - ISCSI_MAX_XMIT_DLENGTH | - ISCSI_HDRDGST_EN | - ISCSI_DATADGST_EN | - ISCSI_INITIAL_R2T_EN | - ISCSI_MAX_R2T | - ISCSI_IMM_DATA_EN | - ISCSI_FIRST_BURST | - ISCSI_MAX_BURST | - ISCSI_PDU_INORDER_EN | - ISCSI_DATASEQ_INORDER_EN, - .host_template = &iscsi_iser_sht, - .conndata_size = sizeof(struct iscsi_conn), - .max_lun = ISCSI_ISER_MAX_LUN, - .max_cmd_len = ISCSI_ISER_MAX_CMD_LEN, - /* session management */ - .create_session = iscsi_iser_session_create, - .destroy_session = iscsi_session_teardown, - /* connection management */ - .create_conn = iscsi_iser_conn_create, - .bind_conn = iscsi_iser_conn_bind, - .destroy_conn = iscsi_iser_conn_destroy, - .set_param = iscsi_iser_conn_set_param, - .get_conn_param = iscsi_iser_conn_get_param, - .get_session_param = iscsi_iser_session_get_param, - .start_conn = iscsi_iser_conn_start, - .stop_conn = iscsi_conn_stop, - /* these are called as part of conn recovery */ - .suspend_conn_recv = NULL, /* FIXME is/how this relvant to iser? */ - .terminate_conn = iscsi_iser_conn_terminate, - /* IO */ - .send_pdu = iscsi_conn_send_pdu, - .get_stats = iscsi_iser_conn_get_stats, - .init_cmd_task = iscsi_iser_cmd_init, - .xmit_cmd_task = iscsi_iser_ctask_xmit, - .xmit_mgmt_task = iscsi_iser_mtask_xmit, - .cleanup_cmd_task = iscsi_iser_cleanup_ctask, - /* recovery */ - .session_recovery_timedout = iscsi_session_recovery_timedout, - - .ep_connect = iscsi_iser_ep_connect, - .ep_poll = iscsi_iser_ep_poll, - .ep_disconnect = iscsi_iser_ep_disconnect -}; - -static int __init iser_init(void) -{ - int err; - - iser_dbg("Starting iSER datamover...\n"); - - if (iscsi_max_lun < 1) { - printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); - return -EINVAL; - } - - iscsi_iser_transport.max_lun = iscsi_max_lun; - - memset(&ig, 0, sizeof(struct iser_global)); - - ig.desc_cache = kmem_cache_create("iser_descriptors", - sizeof (struct iser_desc), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (ig.desc_cache == NULL) - return -ENOMEM; - - /* device init is called only after the first addr resolution */ - mutex_init(&ig.device_list_mutex); - INIT_LIST_HEAD(&ig.device_list); - mutex_init(&ig.connlist_mutex); - INIT_LIST_HEAD(&ig.connlist); - - if (!iscsi_register_transport(&iscsi_iser_transport)) { - iser_err("iscsi_register_transport failed\n"); - err = -EINVAL; - goto register_transport_failure; - } - - return 0; - -register_transport_failure: - kmem_cache_destroy(ig.desc_cache); - - return err; -} - -static void __exit iser_exit(void) -{ - iser_dbg("Removing iSER datamover...\n"); - iscsi_unregister_transport(&iscsi_iser_transport); - kmem_cache_destroy(ig.desc_cache); -} - -module_init(iser_init); -module_exit(iser_exit); diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h deleted file mode 100644 index 3350ba690cfe..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * iSER transport for the Open iSCSI Initiator & iSER transport internals - * - * Copyright (C) 2004 Dmitry Yusupov - * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 Mike Christie - * based on code maintained by open-iscsi@googlegroups.com - * - * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. - * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: iscsi_iser.h 7051 2006-05-10 12:29:11Z ogerlitz $ - */ -#ifndef __ISCSI_ISER_H__ -#define __ISCSI_ISER_H__ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define DRV_NAME "iser" -#define PFX DRV_NAME ": " -#define DRV_VER "0.1" -#define DRV_DATE "May 7th, 2006" - -#define iser_dbg(fmt, arg...) \ - do { \ - if (iser_debug_level > 0) \ - printk(KERN_DEBUG PFX "%s:" fmt,\ - __func__ , ## arg); \ - } while (0) - -#define iser_err(fmt, arg...) \ - do { \ - printk(KERN_ERR PFX "%s:" fmt, \ - __func__ , ## arg); \ - } while (0) - - /* support upto 512KB in one RDMA */ -#define ISCSI_ISER_SG_TABLESIZE (0x80000 >> PAGE_SHIFT) -#define ISCSI_ISER_MAX_LUN 256 -#define ISCSI_ISER_MAX_CMD_LEN 16 - -/* QP settings */ -/* Maximal bounds on received asynchronous PDUs */ -#define ISER_MAX_RX_MISC_PDUS 4 /* NOOP_IN(2) , ASYNC_EVENT(2) */ - -#define ISER_MAX_TX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), * - * SCSI_TMFUNC(2), LOGOUT(1) */ - -#define ISER_QP_MAX_RECV_DTOS (ISCSI_XMIT_CMDS_MAX + \ - ISER_MAX_RX_MISC_PDUS + \ - ISER_MAX_TX_MISC_PDUS) - -/* the max TX (send) WR supported by the iSER QP is defined by * - * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect * - * to have at max for SCSI command. The tx posting & completion handling code * - * supports -EAGAIN scheme where tx is suspended till the QP has room for more * - * send WR. D=8 comes from 64K/8K */ - -#define ISER_INFLIGHT_DATAOUTS 8 - -#define ISER_QP_MAX_REQ_DTOS (ISCSI_XMIT_CMDS_MAX * \ - (1 + ISER_INFLIGHT_DATAOUTS) + \ - ISER_MAX_TX_MISC_PDUS + \ - ISER_MAX_RX_MISC_PDUS) - -#define ISER_VER 0x10 -#define ISER_WSV 0x08 -#define ISER_RSV 0x04 - -struct iser_hdr { - u8 flags; - u8 rsvd[3]; - __be32 write_stag; /* write rkey */ - __be64 write_va; - __be32 read_stag; /* read rkey */ - __be64 read_va; -} __attribute__((packed)); - - -/* Length of an object name string */ -#define ISER_OBJECT_NAME_SIZE 64 - -enum iser_ib_conn_state { - ISER_CONN_INIT, /* descriptor allocd, no conn */ - ISER_CONN_PENDING, /* in the process of being established */ - ISER_CONN_UP, /* up and running */ - ISER_CONN_TERMINATING, /* in the process of being terminated */ - ISER_CONN_DOWN, /* shut down */ - ISER_CONN_STATES_NUM -}; - -enum iser_task_status { - ISER_TASK_STATUS_INIT = 0, - ISER_TASK_STATUS_STARTED, - ISER_TASK_STATUS_COMPLETED -}; - -enum iser_data_dir { - ISER_DIR_IN = 0, /* to initiator */ - ISER_DIR_OUT, /* from initiator */ - ISER_DIRS_NUM -}; - -struct iser_data_buf { - void *buf; /* pointer to the sg list */ - unsigned int size; /* num entries of this sg */ - unsigned long data_len; /* total data len */ - unsigned int dma_nents; /* returned by dma_map_sg */ - char *copy_buf; /* allocated copy buf for SGs unaligned * - * for rdma which are copied */ - struct scatterlist sg_single; /* SG-ified clone of a non SG SC or * - * unaligned SG */ - }; - -/* fwd declarations */ -struct iser_device; -struct iscsi_iser_conn; -struct iscsi_iser_cmd_task; - -struct iser_mem_reg { - u32 lkey; - u32 rkey; - u64 va; - u64 len; - void *mem_h; -}; - -struct iser_regd_buf { - struct iser_mem_reg reg; /* memory registration info */ - void *virt_addr; - struct iser_device *device; /* device->device for dma_unmap */ - dma_addr_t dma_addr; /* if non zero, addr for dma_unmap */ - enum dma_data_direction direction; /* direction for dma_unmap */ - unsigned int data_size; - atomic_t ref_count; /* refcount, freed when dec to 0 */ -}; - -#define MAX_REGD_BUF_VECTOR_LEN 2 - -struct iser_dto { - struct iscsi_iser_cmd_task *ctask; - struct iscsi_iser_conn *conn; - int notify_enable; - - /* vector of registered buffers */ - unsigned int regd_vector_len; - struct iser_regd_buf *regd[MAX_REGD_BUF_VECTOR_LEN]; - - /* offset into the registered buffer may be specified */ - unsigned int offset[MAX_REGD_BUF_VECTOR_LEN]; - - /* a smaller size may be specified, if 0, then full size is used */ - unsigned int used_sz[MAX_REGD_BUF_VECTOR_LEN]; -}; - -enum iser_desc_type { - ISCSI_RX, - ISCSI_TX_CONTROL , - ISCSI_TX_SCSI_COMMAND, - ISCSI_TX_DATAOUT -}; - -struct iser_desc { - struct iser_hdr iser_header; - struct iscsi_hdr iscsi_header; - struct iser_regd_buf hdr_regd_buf; - void *data; /* used by RX & TX_CONTROL */ - struct iser_regd_buf data_regd_buf; /* used by RX & TX_CONTROL */ - enum iser_desc_type type; - struct iser_dto dto; -}; - -struct iser_device { - struct ib_device *ib_device; - struct ib_pd *pd; - struct ib_cq *cq; - struct ib_mr *mr; - struct tasklet_struct cq_tasklet; - struct list_head ig_list; /* entry in ig devices list */ - int refcount; -}; - -struct iser_conn { - struct iscsi_iser_conn *iser_conn; /* iser conn for upcalls */ - enum iser_ib_conn_state state; /* rdma connection state */ - spinlock_t lock; /* used for state changes */ - struct iser_device *device; /* device context */ - struct rdma_cm_id *cma_id; /* CMA ID */ - struct ib_qp *qp; /* QP */ - struct ib_fmr_pool *fmr_pool; /* pool of IB FMRs */ - int disc_evt_flag; /* disconn event delivered */ - wait_queue_head_t wait; /* waitq for conn/disconn */ - atomic_t post_recv_buf_count; /* posted rx count */ - atomic_t post_send_buf_count; /* posted tx count */ - struct work_struct comperror_work; /* conn term sleepable ctx*/ - char name[ISER_OBJECT_NAME_SIZE]; - struct iser_page_vec *page_vec; /* represents SG to fmr maps* - * maps serialized as tx is*/ - struct list_head conn_list; /* entry in ig conn list */ -}; - -struct iscsi_iser_conn { - struct iscsi_conn *iscsi_conn;/* ptr to iscsi conn */ - struct iser_conn *ib_conn; /* iSER IB conn */ - - rwlock_t lock; -}; - -struct iscsi_iser_cmd_task { - struct iser_desc desc; - struct iscsi_iser_conn *iser_conn; - int rdma_data_count;/* RDMA bytes */ - enum iser_task_status status; - int command_sent; /* set if command sent */ - int dir[ISER_DIRS_NUM]; /* set if dir use*/ - struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ - struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ - struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ -}; - -struct iser_page_vec { - u64 *pages; - int length; - int offset; - int data_size; -}; - -struct iser_global { - struct mutex device_list_mutex;/* */ - struct list_head device_list; /* all iSER devices */ - struct mutex connlist_mutex; - struct list_head connlist; /* all iSER IB connections */ - - kmem_cache_t *desc_cache; -}; - -extern struct iser_global ig; -extern int iser_debug_level; - -/* allocate connection resources needed for rdma functionality */ -int iser_conn_set_full_featured_mode(struct iscsi_conn *conn); - -int iser_send_control(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); - -int iser_send_command(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); - -int iser_send_data_out(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask, - struct iscsi_data *hdr); - -void iscsi_iser_recv(struct iscsi_conn *conn, - struct iscsi_hdr *hdr, - char *rx_data, - int rx_data_len); - -int iser_conn_init(struct iser_conn **ib_conn); - -void iser_conn_terminate(struct iser_conn *ib_conn); - -void iser_conn_release(struct iser_conn *ib_conn); - -void iser_rcv_completion(struct iser_desc *desc, - unsigned long dto_xfer_len); - -void iser_snd_completion(struct iser_desc *desc); - -void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *ctask); - -void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask); - -void iser_dto_buffs_release(struct iser_dto *dto); - -int iser_regd_buff_release(struct iser_regd_buf *regd_buf); - -void iser_reg_single(struct iser_device *device, - struct iser_regd_buf *regd_buf, - enum dma_data_direction direction); - -int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask, - enum iser_data_dir cmd_dir); - -void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask, - enum iser_data_dir cmd_dir); - -int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask, - enum iser_data_dir cmd_dir); - -int iser_connect(struct iser_conn *ib_conn, - struct sockaddr_in *src_addr, - struct sockaddr_in *dst_addr, - int non_blocking); - -int iser_reg_page_vec(struct iser_conn *ib_conn, - struct iser_page_vec *page_vec, - struct iser_mem_reg *mem_reg); - -void iser_unreg_mem(struct iser_mem_reg *mem_reg); - -int iser_post_recv(struct iser_desc *rx_desc); -int iser_post_send(struct iser_desc *tx_desc); - -int iser_conn_state_comp(struct iser_conn *ib_conn, - enum iser_ib_conn_state comp); -#endif diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c deleted file mode 100644 index ccf56f6f7236..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: iser_initiator.c 6964 2006-05-07 11:11:43Z ogerlitz $ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iscsi_iser.h" - -/* Constant PDU lengths calculations */ -#define ISER_TOTAL_HEADERS_LEN (sizeof (struct iser_hdr) + \ - sizeof (struct iscsi_hdr)) - -/* iser_dto_add_regd_buff - increments the reference count for * - * the registered buffer & adds it to the DTO object */ -static void iser_dto_add_regd_buff(struct iser_dto *dto, - struct iser_regd_buf *regd_buf, - unsigned long use_offset, - unsigned long use_size) -{ - int add_idx; - - atomic_inc(®d_buf->ref_count); - - add_idx = dto->regd_vector_len; - dto->regd[add_idx] = regd_buf; - dto->used_sz[add_idx] = use_size; - dto->offset[add_idx] = use_offset; - - dto->regd_vector_len++; -} - -static int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask, - struct iser_data_buf *data, - enum iser_data_dir iser_dir, - enum dma_data_direction dma_dir) -{ - struct device *dma_device; - - iser_ctask->dir[iser_dir] = 1; - dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device; - - data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir); - if (data->dma_nents == 0) { - iser_err("dma_map_sg failed!!!\n"); - return -EINVAL; - } - return 0; -} - -static void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask) -{ - struct device *dma_device; - struct iser_data_buf *data; - - dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device; - - if (iser_ctask->dir[ISER_DIR_IN]) { - data = &iser_ctask->data[ISER_DIR_IN]; - dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE); - } - - if (iser_ctask->dir[ISER_DIR_OUT]) { - data = &iser_ctask->data[ISER_DIR_OUT]; - dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE); - } -} - -/* Register user buffer memory and initialize passive rdma - * dto descriptor. Total data size is stored in - * iser_ctask->data[ISER_DIR_IN].data_len - */ -static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask, - unsigned int edtl) - -{ - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct iser_regd_buf *regd_buf; - int err; - struct iser_hdr *hdr = &iser_ctask->desc.iser_header; - struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN]; - - err = iser_dma_map_task_data(iser_ctask, - buf_in, - ISER_DIR_IN, - DMA_FROM_DEVICE); - if (err) - return err; - - if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) { - iser_err("Total data length: %ld, less than EDTL: " - "%d, in READ cmd BHS itt: %d, conn: 0x%p\n", - iser_ctask->data[ISER_DIR_IN].data_len, edtl, - ctask->itt, iser_ctask->iser_conn); - return -EINVAL; - } - - err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN); - if (err) { - iser_err("Failed to set up Data-IN RDMA\n"); - return err; - } - regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN]; - - hdr->flags |= ISER_RSV; - hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey); - hdr->read_va = cpu_to_be64(regd_buf->reg.va); - - iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n", - ctask->itt, regd_buf->reg.rkey, - (unsigned long long)regd_buf->reg.va); - - return 0; -} - -/* Register user buffer memory and initialize passive rdma - * dto descriptor. Total data size is stored in - * ctask->data[ISER_DIR_OUT].data_len - */ -static int -iser_prepare_write_cmd(struct iscsi_cmd_task *ctask, - unsigned int imm_sz, - unsigned int unsol_sz, - unsigned int edtl) -{ - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct iser_regd_buf *regd_buf; - int err; - struct iser_dto *send_dto = &iser_ctask->desc.dto; - struct iser_hdr *hdr = &iser_ctask->desc.iser_header; - struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT]; - - err = iser_dma_map_task_data(iser_ctask, - buf_out, - ISER_DIR_OUT, - DMA_TO_DEVICE); - if (err) - return err; - - if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) { - iser_err("Total data length: %ld, less than EDTL: %d, " - "in WRITE cmd BHS itt: %d, conn: 0x%p\n", - iser_ctask->data[ISER_DIR_OUT].data_len, - edtl, ctask->itt, ctask->conn); - return -EINVAL; - } - - err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT); - if (err != 0) { - iser_err("Failed to register write cmd RDMA mem\n"); - return err; - } - - regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT]; - - if (unsol_sz < edtl) { - hdr->flags |= ISER_WSV; - hdr->write_stag = cpu_to_be32(regd_buf->reg.rkey); - hdr->write_va = cpu_to_be64(regd_buf->reg.va + unsol_sz); - - iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X " - "VA:%#llX + unsol:%d\n", - ctask->itt, regd_buf->reg.rkey, - (unsigned long long)regd_buf->reg.va, unsol_sz); - } - - if (imm_sz > 0) { - iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n", - ctask->itt, imm_sz); - iser_dto_add_regd_buff(send_dto, - regd_buf, - 0, - imm_sz); - } - - return 0; -} - -/** - * iser_post_receive_control - allocates, initializes and posts receive DTO. - */ -static int iser_post_receive_control(struct iscsi_conn *conn) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iser_desc *rx_desc; - struct iser_regd_buf *regd_hdr; - struct iser_regd_buf *regd_data; - struct iser_dto *recv_dto = NULL; - struct iser_device *device = iser_conn->ib_conn->device; - int rx_data_size, err = 0; - - rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO); - if (rx_desc == NULL) { - iser_err("Failed to alloc desc for post recv\n"); - return -ENOMEM; - } - rx_desc->type = ISCSI_RX; - - /* for the login sequence we must support rx of upto 8K; login is done - * after conn create/bind (connect) and conn stop/bind (reconnect), - * what's common for both schemes is that the connection is not started - */ - if (conn->c_stage != ISCSI_CONN_STARTED) - rx_data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; - else /* FIXME till user space sets conn->max_recv_dlength correctly */ - rx_data_size = 128; - - rx_desc->data = kmalloc(rx_data_size, GFP_NOIO); - if (rx_desc->data == NULL) { - iser_err("Failed to alloc data buf for post recv\n"); - err = -ENOMEM; - goto post_rx_kmalloc_failure; - } - - recv_dto = &rx_desc->dto; - recv_dto->conn = iser_conn; - recv_dto->regd_vector_len = 0; - - regd_hdr = &rx_desc->hdr_regd_buf; - memset(regd_hdr, 0, sizeof(struct iser_regd_buf)); - regd_hdr->device = device; - regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */ - regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN; - - iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE); - - iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0); - - regd_data = &rx_desc->data_regd_buf; - memset(regd_data, 0, sizeof(struct iser_regd_buf)); - regd_data->device = device; - regd_data->virt_addr = rx_desc->data; - regd_data->data_size = rx_data_size; - - iser_reg_single(device, regd_data, DMA_FROM_DEVICE); - - iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0); - - err = iser_post_recv(rx_desc); - if (!err) - return 0; - - /* iser_post_recv failed */ - iser_dto_buffs_release(recv_dto); - kfree(rx_desc->data); -post_rx_kmalloc_failure: - kmem_cache_free(ig.desc_cache, rx_desc); - return err; -} - -/* creates a new tx descriptor and adds header regd buffer */ -static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn, - struct iser_desc *tx_desc) -{ - struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf; - struct iser_dto *send_dto = &tx_desc->dto; - - memset(regd_hdr, 0, sizeof(struct iser_regd_buf)); - regd_hdr->device = iser_conn->ib_conn->device; - regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */ - regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN; - - send_dto->conn = iser_conn; - send_dto->notify_enable = 1; - send_dto->regd_vector_len = 0; - - memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr)); - tx_desc->iser_header.flags = ISER_VER; - - iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0); -} - -/** - * iser_conn_set_full_featured_mode - (iSER API) - */ -int iser_conn_set_full_featured_mode(struct iscsi_conn *conn) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - - int i; - /* no need to keep it in a var, we are after login so if this should - * be negotiated, by now the result should be available here */ - int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS; - - iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num); - - /* Check that there is no posted recv or send buffers left - */ - /* they must be consumed during the login phase */ - BUG_ON(atomic_read(&iser_conn->ib_conn->post_recv_buf_count) != 0); - BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); - - /* Initial post receive buffers */ - for (i = 0; i < initial_post_recv_bufs_num; i++) { - if (iser_post_receive_control(conn) != 0) { - iser_err("Failed to post recv bufs at:%d conn:0x%p\n", - i, conn); - return -ENOMEM; - } - } - iser_dbg("Posted %d post recv bufs, conn:0x%p\n", i, conn); - return 0; -} - -static int -iser_check_xmit(struct iscsi_conn *conn, void *task) -{ - int rc = 0; - struct iscsi_iser_conn *iser_conn = conn->dd_data; - - write_lock_bh(conn->recv_lock); - if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == - ISER_QP_MAX_REQ_DTOS) { - iser_dbg("%ld can't xmit task %p, suspending tx\n",jiffies,task); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - rc = -EAGAIN; - } - write_unlock_bh(conn->recv_lock); - return rc; -} - - -/** - * iser_send_command - send command PDU - */ -int iser_send_command(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct iser_dto *send_dto = NULL; - unsigned long edtl; - int err = 0; - struct iser_data_buf *data_buf; - - struct iscsi_cmd *hdr = ctask->hdr; - struct scsi_cmnd *sc = ctask->sc; - - if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { - iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); - return -EPERM; - } - if (iser_check_xmit(conn, ctask)) - return -EAGAIN; - - edtl = ntohl(hdr->data_length); - - /* build the tx desc regd header and add it to the tx desc dto */ - iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND; - send_dto = &iser_ctask->desc.dto; - send_dto->ctask = iser_ctask; - iser_create_send_desc(iser_conn, &iser_ctask->desc); - - if (hdr->flags & ISCSI_FLAG_CMD_READ) - data_buf = &iser_ctask->data[ISER_DIR_IN]; - else - data_buf = &iser_ctask->data[ISER_DIR_OUT]; - - if (sc->use_sg) { /* using a scatter list */ - data_buf->buf = sc->request_buffer; - data_buf->size = sc->use_sg; - } else if (sc->request_bufflen) { - /* using a single buffer - convert it into one entry SG */ - sg_init_one(&data_buf->sg_single, - sc->request_buffer, sc->request_bufflen); - data_buf->buf = &data_buf->sg_single; - data_buf->size = 1; - } - - data_buf->data_len = sc->request_bufflen; - - if (hdr->flags & ISCSI_FLAG_CMD_READ) { - err = iser_prepare_read_cmd(ctask, edtl); - if (err) - goto send_command_error; - } - if (hdr->flags & ISCSI_FLAG_CMD_WRITE) { - err = iser_prepare_write_cmd(ctask, - ctask->imm_count, - ctask->imm_count + - ctask->unsol_count, - edtl); - if (err) - goto send_command_error; - } - - iser_reg_single(iser_conn->ib_conn->device, - send_dto->regd[0], DMA_TO_DEVICE); - - if (iser_post_receive_control(conn) != 0) { - iser_err("post_recv failed!\n"); - err = -ENOMEM; - goto send_command_error; - } - - iser_ctask->status = ISER_TASK_STATUS_STARTED; - - err = iser_post_send(&iser_ctask->desc); - if (!err) - return 0; - -send_command_error: - iser_dto_buffs_release(send_dto); - iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err); - return err; -} - -/** - * iser_send_data_out - send data out PDU - */ -int iser_send_data_out(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask, - struct iscsi_data *hdr) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct iser_desc *tx_desc = NULL; - struct iser_dto *send_dto = NULL; - unsigned long buf_offset; - unsigned long data_seg_len; - unsigned int itt; - int err = 0; - - if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { - iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); - return -EPERM; - } - - if (iser_check_xmit(conn, ctask)) - return -EAGAIN; - - itt = ntohl(hdr->itt); - data_seg_len = ntoh24(hdr->dlength); - buf_offset = ntohl(hdr->offset); - - iser_dbg("%s itt %d dseg_len %d offset %d\n", - __func__,(int)itt,(int)data_seg_len,(int)buf_offset); - - tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO); - if (tx_desc == NULL) { - iser_err("Failed to alloc desc for post dataout\n"); - return -ENOMEM; - } - - tx_desc->type = ISCSI_TX_DATAOUT; - memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr)); - - /* build the tx desc regd header and add it to the tx desc dto */ - send_dto = &tx_desc->dto; - send_dto->ctask = iser_ctask; - iser_create_send_desc(iser_conn, tx_desc); - - iser_reg_single(iser_conn->ib_conn->device, - send_dto->regd[0], DMA_TO_DEVICE); - - /* all data was registered for RDMA, we can use the lkey */ - iser_dto_add_regd_buff(send_dto, - &iser_ctask->rdma_regd[ISER_DIR_OUT], - buf_offset, - data_seg_len); - - if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) { - iser_err("Offset:%ld & DSL:%ld in Data-Out " - "inconsistent with total len:%ld, itt:%d\n", - buf_offset, data_seg_len, - iser_ctask->data[ISER_DIR_OUT].data_len, itt); - err = -EINVAL; - goto send_data_out_error; - } - iser_dbg("data-out itt: %d, offset: %ld, sz: %ld\n", - itt, buf_offset, data_seg_len); - - - err = iser_post_send(tx_desc); - if (!err) - return 0; - -send_data_out_error: - iser_dto_buffs_release(send_dto); - kmem_cache_free(ig.desc_cache, tx_desc); - iser_err("conn %p failed err %d\n",conn, err); - return err; -} - -int iser_send_control(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) -{ - struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iser_desc *mdesc = mtask->dd_data; - struct iser_dto *send_dto = NULL; - unsigned int itt; - unsigned long data_seg_len; - int err = 0; - unsigned char opcode; - struct iser_regd_buf *regd_buf; - struct iser_device *device; - - if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { - iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); - return -EPERM; - } - - if (iser_check_xmit(conn,mtask)) - return -EAGAIN; - - /* build the tx desc regd header and add it to the tx desc dto */ - mdesc->type = ISCSI_TX_CONTROL; - send_dto = &mdesc->dto; - send_dto->ctask = NULL; - iser_create_send_desc(iser_conn, mdesc); - - device = iser_conn->ib_conn->device; - - iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE); - - itt = ntohl(mtask->hdr->itt); - opcode = mtask->hdr->opcode & ISCSI_OPCODE_MASK; - data_seg_len = ntoh24(mtask->hdr->dlength); - - if (data_seg_len > 0) { - regd_buf = &mdesc->data_regd_buf; - memset(regd_buf, 0, sizeof(struct iser_regd_buf)); - regd_buf->device = device; - regd_buf->virt_addr = mtask->data; - regd_buf->data_size = mtask->data_count; - iser_reg_single(device, regd_buf, - DMA_TO_DEVICE); - iser_dto_add_regd_buff(send_dto, regd_buf, - 0, - data_seg_len); - } - - if (iser_post_receive_control(conn) != 0) { - iser_err("post_rcv_buff failed!\n"); - err = -ENOMEM; - goto send_control_error; - } - - err = iser_post_send(mdesc); - if (!err) - return 0; - -send_control_error: - iser_dto_buffs_release(send_dto); - iser_err("conn %p failed err %d\n",conn, err); - return err; -} - -/** - * iser_rcv_dto_completion - recv DTO completion - */ -void iser_rcv_completion(struct iser_desc *rx_desc, - unsigned long dto_xfer_len) -{ - struct iser_dto *dto = &rx_desc->dto; - struct iscsi_iser_conn *conn = dto->conn; - struct iscsi_session *session = conn->iscsi_conn->session; - struct iscsi_cmd_task *ctask; - struct iscsi_iser_cmd_task *iser_ctask; - struct iscsi_hdr *hdr; - char *rx_data = NULL; - int rx_data_len = 0; - unsigned int itt; - unsigned char opcode; - - hdr = &rx_desc->iscsi_header; - - iser_dbg("op 0x%x itt 0x%x\n", hdr->opcode,hdr->itt); - - if (dto_xfer_len > ISER_TOTAL_HEADERS_LEN) { /* we have data */ - rx_data_len = dto_xfer_len - ISER_TOTAL_HEADERS_LEN; - rx_data = dto->regd[1]->virt_addr; - rx_data += dto->offset[1]; - } - - opcode = hdr->opcode & ISCSI_OPCODE_MASK; - - if (opcode == ISCSI_OP_SCSI_CMD_RSP) { - itt = hdr->itt & ISCSI_ITT_MASK; /* mask out cid and age bits */ - if (!(itt < session->cmds_max)) - iser_err("itt can't be matched to task!!!" - "conn %p opcode %d cmds_max %d itt %d\n", - conn->iscsi_conn,opcode,session->cmds_max,itt); - /* use the mapping given with the cmds array indexed by itt */ - ctask = (struct iscsi_cmd_task *)session->cmds[itt]; - iser_ctask = ctask->dd_data; - iser_dbg("itt %d ctask %p\n",itt,ctask); - iser_ctask->status = ISER_TASK_STATUS_COMPLETED; - iser_ctask_rdma_finalize(iser_ctask); - } - - iser_dto_buffs_release(dto); - - iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len); - - kfree(rx_desc->data); - kmem_cache_free(ig.desc_cache, rx_desc); - - /* decrementing conn->post_recv_buf_count only --after-- freeing the * - * task eliminates the need to worry on tasks which are completed in * - * parallel to the execution of iser_conn_term. So the code that waits * - * for the posted rx bufs refcount to become zero handles everything */ - atomic_dec(&conn->ib_conn->post_recv_buf_count); -} - -void iser_snd_completion(struct iser_desc *tx_desc) -{ - struct iser_dto *dto = &tx_desc->dto; - struct iscsi_iser_conn *iser_conn = dto->conn; - struct iscsi_conn *conn = iser_conn->iscsi_conn; - struct iscsi_mgmt_task *mtask; - - iser_dbg("Initiator, Data sent dto=0x%p\n", dto); - - iser_dto_buffs_release(dto); - - if (tx_desc->type == ISCSI_TX_DATAOUT) - kmem_cache_free(ig.desc_cache, tx_desc); - - atomic_dec(&iser_conn->ib_conn->post_send_buf_count); - - write_lock(conn->recv_lock); - if (conn->suspend_tx) { - iser_dbg("%ld resuming tx\n",jiffies); - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - scsi_queue_work(conn->session->host, &conn->xmitwork); - } - write_unlock(conn->recv_lock); - - if (tx_desc->type == ISCSI_TX_CONTROL) { - /* this arithmetic is legal by libiscsi dd_data allocation */ - mtask = (void *) ((long)(void *)tx_desc - - sizeof(struct iscsi_mgmt_task)); - if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { - struct iscsi_session *session = conn->session; - - spin_lock(&conn->session->lock); - list_del(&mtask->running); - __kfifo_put(session->mgmtpool.queue, (void*)&mtask, - sizeof(void*)); - spin_unlock(&session->lock); - } - } -} - -void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask) - -{ - iser_ctask->status = ISER_TASK_STATUS_INIT; - - iser_ctask->dir[ISER_DIR_IN] = 0; - iser_ctask->dir[ISER_DIR_OUT] = 0; - - iser_ctask->data[ISER_DIR_IN].data_len = 0; - iser_ctask->data[ISER_DIR_OUT].data_len = 0; - - memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0, - sizeof(struct iser_regd_buf)); - memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0, - sizeof(struct iser_regd_buf)); -} - -void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask) -{ - int deferred; - - /* if we were reading, copy back to unaligned sglist, - * anyway dma_unmap and free the copy - */ - if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) - iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN); - if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) - iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT); - - if (iser_ctask->dir[ISER_DIR_IN]) { - deferred = iser_regd_buff_release - (&iser_ctask->rdma_regd[ISER_DIR_IN]); - if (deferred) { - iser_err("References remain for BUF-IN rdma reg\n"); - BUG(); - } - } - - if (iser_ctask->dir[ISER_DIR_OUT]) { - deferred = iser_regd_buff_release - (&iser_ctask->rdma_regd[ISER_DIR_OUT]); - if (deferred) { - iser_err("References remain for BUF-OUT rdma reg\n"); - BUG(); - } - } - - iser_dma_unmap_task_data(iser_ctask); -} - -void iser_dto_buffs_release(struct iser_dto *dto) -{ - int i; - - for (i = 0; i < dto->regd_vector_len; i++) - iser_regd_buff_release(dto->regd[i]); -} - diff --git a/trunk/drivers/infiniband/ulp/iser/iser_memory.c b/trunk/drivers/infiniband/ulp/iser/iser_memory.c deleted file mode 100644 index 31950a522a1c..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/iser_memory.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: iser_memory.c 6964 2006-05-07 11:11:43Z ogerlitz $ - */ -#include -#include -#include -#include -#include -#include -#include - -#include "iscsi_iser.h" - -#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */ -/** - * Decrements the reference count for the - * registered buffer & releases it - * - * returns 0 if released, 1 if deferred - */ -int iser_regd_buff_release(struct iser_regd_buf *regd_buf) -{ - struct device *dma_device; - - if ((atomic_read(®d_buf->ref_count) == 0) || - atomic_dec_and_test(®d_buf->ref_count)) { - /* if we used the dma mr, unreg is just NOP */ - if (regd_buf->reg.rkey != 0) - iser_unreg_mem(®d_buf->reg); - - if (regd_buf->dma_addr) { - dma_device = regd_buf->device->ib_device->dma_device; - dma_unmap_single(dma_device, - regd_buf->dma_addr, - regd_buf->data_size, - regd_buf->direction); - } - /* else this regd buf is associated with task which we */ - /* dma_unmap_single/sg later */ - return 0; - } else { - iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf); - return 1; - } -} - -/** - * iser_reg_single - fills registered buffer descriptor with - * registration information - */ -void iser_reg_single(struct iser_device *device, - struct iser_regd_buf *regd_buf, - enum dma_data_direction direction) -{ - dma_addr_t dma_addr; - - dma_addr = dma_map_single(device->ib_device->dma_device, - regd_buf->virt_addr, - regd_buf->data_size, direction); - BUG_ON(dma_mapping_error(dma_addr)); - - regd_buf->reg.lkey = device->mr->lkey; - regd_buf->reg.rkey = 0; /* indicate there's no need to unreg */ - regd_buf->reg.len = regd_buf->data_size; - regd_buf->reg.va = dma_addr; - - regd_buf->dma_addr = dma_addr; - regd_buf->direction = direction; -} - -/** - * iser_start_rdma_unaligned_sg - */ -int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, - enum iser_data_dir cmd_dir) -{ - int dma_nents; - struct device *dma_device; - char *mem = NULL; - struct iser_data_buf *data = &iser_ctask->data[cmd_dir]; - unsigned long cmd_data_len = data->data_len; - - if (cmd_data_len > ISER_KMALLOC_THRESHOLD) - mem = (void *)__get_free_pages(GFP_NOIO, - long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); - else - mem = kmalloc(cmd_data_len, GFP_NOIO); - - if (mem == NULL) { - iser_err("Failed to allocate mem size %d %d for copying sglist\n", - data->size,(int)cmd_data_len); - return -ENOMEM; - } - - if (cmd_dir == ISER_DIR_OUT) { - /* copy the unaligned sg the buffer which is used for RDMA */ - struct scatterlist *sg = (struct scatterlist *)data->buf; - int i; - char *p, *from; - - for (p = mem, i = 0; i < data->size; i++) { - from = kmap_atomic(sg[i].page, KM_USER0); - memcpy(p, - from + sg[i].offset, - sg[i].length); - kunmap_atomic(from, KM_USER0); - p += sg[i].length; - } - } - - sg_init_one(&iser_ctask->data_copy[cmd_dir].sg_single, mem, cmd_data_len); - iser_ctask->data_copy[cmd_dir].buf = - &iser_ctask->data_copy[cmd_dir].sg_single; - iser_ctask->data_copy[cmd_dir].size = 1; - - iser_ctask->data_copy[cmd_dir].copy_buf = mem; - - dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device; - - if (cmd_dir == ISER_DIR_OUT) - dma_nents = dma_map_sg(dma_device, - &iser_ctask->data_copy[cmd_dir].sg_single, - 1, DMA_TO_DEVICE); - else - dma_nents = dma_map_sg(dma_device, - &iser_ctask->data_copy[cmd_dir].sg_single, - 1, DMA_FROM_DEVICE); - - BUG_ON(dma_nents == 0); - - iser_ctask->data_copy[cmd_dir].dma_nents = dma_nents; - return 0; -} - -/** - * iser_finalize_rdma_unaligned_sg - */ -void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, - enum iser_data_dir cmd_dir) -{ - struct device *dma_device; - struct iser_data_buf *mem_copy; - unsigned long cmd_data_len; - - dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device; - mem_copy = &iser_ctask->data_copy[cmd_dir]; - - if (cmd_dir == ISER_DIR_OUT) - dma_unmap_sg(dma_device, &mem_copy->sg_single, 1, - DMA_TO_DEVICE); - else - dma_unmap_sg(dma_device, &mem_copy->sg_single, 1, - DMA_FROM_DEVICE); - - if (cmd_dir == ISER_DIR_IN) { - char *mem; - struct scatterlist *sg; - unsigned char *p, *to; - unsigned int sg_size; - int i; - - /* copy back read RDMA to unaligned sg */ - mem = mem_copy->copy_buf; - - sg = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf; - sg_size = iser_ctask->data[ISER_DIR_IN].size; - - for (p = mem, i = 0; i < sg_size; i++){ - to = kmap_atomic(sg[i].page, KM_SOFTIRQ0); - memcpy(to + sg[i].offset, - p, - sg[i].length); - kunmap_atomic(to, KM_SOFTIRQ0); - p += sg[i].length; - } - } - - cmd_data_len = iser_ctask->data[cmd_dir].data_len; - - if (cmd_data_len > ISER_KMALLOC_THRESHOLD) - free_pages((unsigned long)mem_copy->copy_buf, - long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); - else - kfree(mem_copy->copy_buf); - - mem_copy->copy_buf = NULL; -} - -/** - * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses - * and returns the length of resulting physical address array (may be less than - * the original due to possible compaction). - * - * we build a "page vec" under the assumption that the SG meets the RDMA - * alignment requirements. Other then the first and last SG elements, all - * the "internal" elements can be compacted into a list whose elements are - * dma addresses of physical pages. The code supports also the weird case - * 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 scatterlist *sg = (struct scatterlist *)data->buf; - dma_addr_t first_addr, last_addr, page; - int start_aligned, end_aligned; - unsigned int cur_page = 0; - unsigned long total_sz = 0; - int i; - - /* compute the offset of first element */ - page_vec->offset = (u64) sg[0].offset; - - for (i = 0; i < data->dma_nents; i++) { - total_sz += sg_dma_len(&sg[i]); - - first_addr = sg_dma_address(&sg[i]); - last_addr = first_addr + sg_dma_len(&sg[i]); - - start_aligned = !(first_addr & ~PAGE_MASK); - end_aligned = !(last_addr & ~PAGE_MASK); - - /* continue to collect page fragments till aligned or SG ends */ - while (!end_aligned && (i + 1 < data->dma_nents)) { - i++; - total_sz += sg_dma_len(&sg[i]); - last_addr = sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]); - end_aligned = !(last_addr & ~PAGE_MASK); - } - - first_addr = first_addr & PAGE_MASK; - - for (page = first_addr; page < last_addr; page += PAGE_SIZE) - page_vec->pages[cur_page++] = page; - - } - 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 MASK_4K ((1UL << 12) - 1) /* 0xFFF */ -#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & MASK_4K) == 0) - -/** - * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned - * for RDMA sub-list of a scatter-gather list of memory buffers, and returns - * 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 scatterlist *sg; - dma_addr_t end_addr, next_addr; - int i, cnt; - unsigned int ret_len = 0; - - sg = (struct scatterlist *)data->buf; - - for (cnt = 0, i = 0; i < data->dma_nents; i++, cnt++) { - /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX " - "offset: %ld sz: %ld\n", i, - (unsigned long)page_to_phys(sg[i].page), - (unsigned long)sg[i].offset, - (unsigned long)sg[i].length); */ - end_addr = sg_dma_address(&sg[i]) + - sg_dma_len(&sg[i]); - /* iser_dbg("Checking sg iobuf end address " - "0x%08lX\n", end_addr); */ - if (i + 1 < data->dma_nents) { - next_addr = sg_dma_address(&sg[i+1]); - /* are i, i+1 fragments of the same page? */ - if (end_addr == next_addr) - continue; - else if (!IS_4K_ALIGNED(end_addr)) { - ret_len = cnt + 1; - break; - } - } - } - if (i == data->dma_nents) - ret_len = cnt; /* loop ended */ - iser_dbg("Found %d aligned entries out of %d in sg:0x%p\n", - ret_len, data->dma_nents, data); - return ret_len; -} - -static void iser_data_buf_dump(struct iser_data_buf *data) -{ - struct scatterlist *sg = (struct scatterlist *)data->buf; - int i; - - for (i = 0; i < data->size; i++) - iser_err("sg[%d] dma_addr:0x%lX page:0x%p " - "off:%d sz:%d dma_len:%d\n", - i, (unsigned long)sg_dma_address(&sg[i]), - sg[i].page, sg[i].offset, - sg[i].length,sg_dma_len(&sg[i])); -} - -static void iser_dump_page_vec(struct iser_page_vec *page_vec) -{ - int i; - - iser_err("page vec length %d data size %d\n", - page_vec->length, page_vec->data_size); - for (i = 0; i < page_vec->length; i++) - iser_err("%d %lx\n",i,(unsigned long)page_vec->pages[i]); -} - -static void iser_page_vec_build(struct iser_data_buf *data, - struct iser_page_vec *page_vec) -{ - int page_vec_len = 0; - - page_vec->length = 0; - page_vec->offset = 0; - - iser_dbg("Translating sg sz: %d\n", data->dma_nents); - page_vec_len = iser_sg_to_page_vec(data,page_vec); - iser_dbg("sg len %d page_vec_len %d\n", data->dma_nents,page_vec_len); - - page_vec->length = page_vec_len; - - if (page_vec_len * PAGE_SIZE < page_vec->data_size) { - iser_err("page_vec too short to hold this SG\n"); - iser_data_buf_dump(data); - iser_dump_page_vec(page_vec); - BUG(); - } -} - -/** - * iser_reg_rdma_mem - Registers memory intended for RDMA, - * obtaining rkey and va - * - * returns 0 on success, errno code on failure - */ -int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, - enum iser_data_dir cmd_dir) -{ - struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; - struct iser_data_buf *mem = &iser_ctask->data[cmd_dir]; - struct iser_regd_buf *regd_buf; - int aligned_len; - int err; - - regd_buf = &iser_ctask->rdma_regd[cmd_dir]; - - aligned_len = iser_data_buf_aligned_len(mem); - if (aligned_len != mem->size) { - iser_err("rdma alignment violation %d/%d aligned\n", - aligned_len, mem->size); - iser_data_buf_dump(mem); - /* allocate copy buf, if we are writing, copy the */ - /* unaligned scatterlist, dma map the copy */ - if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0) - return -ENOMEM; - mem = &iser_ctask->data_copy[cmd_dir]; - } - - iser_page_vec_build(mem, ib_conn->page_vec); - err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, ®d_buf->reg); - if (err) - return err; - - /* take a reference on this regd buf such that it will not be released * - * (eg in send dto completion) before we get the scsi response */ - atomic_inc(®d_buf->ref_count); - return 0; -} diff --git a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c deleted file mode 100644 index ff117bbf81b4..000000000000 --- a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved. - * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $ - */ -#include -#include -#include -#include -#include -#include - -#include "iscsi_iser.h" - -#define ISCSI_ISER_MAX_CONN 8 -#define ISER_MAX_CQ_LEN ((ISER_QP_MAX_RECV_DTOS + \ - ISER_QP_MAX_REQ_DTOS) * \ - ISCSI_ISER_MAX_CONN) - -static void iser_cq_tasklet_fn(unsigned long data); -static void iser_cq_callback(struct ib_cq *cq, void *cq_context); -static void iser_comp_error_worker(void *data); - -static void iser_cq_event_callback(struct ib_event *cause, void *context) -{ - iser_err("got cq event %d \n", cause->event); -} - -static void iser_qp_event_callback(struct ib_event *cause, void *context) -{ - iser_err("got qp event %d\n",cause->event); -} - -/** - * iser_create_device_ib_res - creates Protection Domain (PD), Completion - * Queue (CQ), DMA Memory Region (DMA MR) with the device associated with - * the adapator. - * - * returns 0 on success, -1 on failure - */ -static int iser_create_device_ib_res(struct iser_device *device) -{ - device->pd = ib_alloc_pd(device->ib_device); - if (IS_ERR(device->pd)) - goto pd_err; - - device->cq = ib_create_cq(device->ib_device, - iser_cq_callback, - iser_cq_event_callback, - (void *)device, - ISER_MAX_CQ_LEN); - if (IS_ERR(device->cq)) - goto cq_err; - - if (ib_req_notify_cq(device->cq, IB_CQ_NEXT_COMP)) - goto cq_arm_err; - - tasklet_init(&device->cq_tasklet, - iser_cq_tasklet_fn, - (unsigned long)device); - - device->mr = ib_get_dma_mr(device->pd, - IB_ACCESS_LOCAL_WRITE); - if (IS_ERR(device->mr)) - goto dma_mr_err; - - return 0; - -dma_mr_err: - tasklet_kill(&device->cq_tasklet); -cq_arm_err: - ib_destroy_cq(device->cq); -cq_err: - ib_dealloc_pd(device->pd); -pd_err: - iser_err("failed to allocate an IB resource\n"); - return -1; -} - -/** - * iser_free_device_ib_res - destory/dealloc/dereg the DMA MR, - * CQ and PD created with the device associated with the adapator. - */ -static void iser_free_device_ib_res(struct iser_device *device) -{ - BUG_ON(device->mr == NULL); - - tasklet_kill(&device->cq_tasklet); - - (void)ib_dereg_mr(device->mr); - (void)ib_destroy_cq(device->cq); - (void)ib_dealloc_pd(device->pd); - - device->mr = NULL; - device->cq = NULL; - device->pd = NULL; -} - -/** - * iser_create_ib_conn_res - Creates FMR pool and Queue-Pair (QP) - * - * returns 0 on success, -1 on failure - */ -static int iser_create_ib_conn_res(struct iser_conn *ib_conn) -{ - struct iser_device *device; - struct ib_qp_init_attr init_attr; - int ret; - struct ib_fmr_pool_param params; - - BUG_ON(ib_conn->device == NULL); - - device = ib_conn->device; - - ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + - (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), - GFP_KERNEL); - if (!ib_conn->page_vec) { - ret = -ENOMEM; - goto alloc_err; - } - ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); - - params.page_shift = PAGE_SHIFT; - /* when the first/last SG element are not start/end * - * page aligned, the map whould be of N+1 pages */ - params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1; - /* make the pool size twice the max number of SCSI commands * - * the ML is expected to queue, watermark for unmap at 50% */ - params.pool_size = ISCSI_XMIT_CMDS_MAX * 2; - params.dirty_watermark = ISCSI_XMIT_CMDS_MAX; - params.cache = 0; - params.flush_function = NULL; - params.access = (IB_ACCESS_LOCAL_WRITE | - IB_ACCESS_REMOTE_WRITE | - IB_ACCESS_REMOTE_READ); - - ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); - if (IS_ERR(ib_conn->fmr_pool)) { - ret = PTR_ERR(ib_conn->fmr_pool); - goto fmr_pool_err; - } - - memset(&init_attr, 0, sizeof init_attr); - - init_attr.event_handler = iser_qp_event_callback; - init_attr.qp_context = (void *)ib_conn; - init_attr.send_cq = device->cq; - init_attr.recv_cq = device->cq; - init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; - init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; - init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN; - init_attr.cap.max_recv_sge = 2; - init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; - init_attr.qp_type = IB_QPT_RC; - - ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); - if (ret) - goto qp_err; - - ib_conn->qp = ib_conn->cma_id->qp; - iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n", - ib_conn, ib_conn->cma_id, - ib_conn->fmr_pool, ib_conn->cma_id->qp); - return ret; - -qp_err: - (void)ib_destroy_fmr_pool(ib_conn->fmr_pool); -fmr_pool_err: - kfree(ib_conn->page_vec); -alloc_err: - iser_err("unable to alloc mem or create resource, err %d\n", ret); - return ret; -} - -/** - * releases the FMR pool, QP and CMA ID objects, returns 0 on success, - * -1 on failure - */ -static int iser_free_ib_conn_res(struct iser_conn *ib_conn) -{ - BUG_ON(ib_conn == NULL); - - iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n", - ib_conn, ib_conn->cma_id, - ib_conn->fmr_pool, ib_conn->qp); - - /* qp is created only once both addr & route are resolved */ - if (ib_conn->fmr_pool != NULL) - ib_destroy_fmr_pool(ib_conn->fmr_pool); - - if (ib_conn->qp != NULL) - rdma_destroy_qp(ib_conn->cma_id); - - if (ib_conn->cma_id != NULL) - rdma_destroy_id(ib_conn->cma_id); - - ib_conn->fmr_pool = NULL; - ib_conn->qp = NULL; - ib_conn->cma_id = NULL; - kfree(ib_conn->page_vec); - - return 0; -} - -/** - * based on the resolved device node GUID see if there already allocated - * device for this device. If there's no such, create one. - */ -static -struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) -{ - struct list_head *p_list; - struct iser_device *device = NULL; - - mutex_lock(&ig.device_list_mutex); - - p_list = ig.device_list.next; - while (p_list != &ig.device_list) { - device = list_entry(p_list, struct iser_device, ig_list); - /* find if there's a match using the node GUID */ - if (device->ib_device->node_guid == cma_id->device->node_guid) - break; - } - - if (device == NULL) { - device = kzalloc(sizeof *device, GFP_KERNEL); - if (device == NULL) - goto out; - /* assign this device to the device */ - device->ib_device = cma_id->device; - /* init the device and link it into ig device list */ - if (iser_create_device_ib_res(device)) { - kfree(device); - device = NULL; - goto out; - } - list_add(&device->ig_list, &ig.device_list); - } -out: - BUG_ON(device == NULL); - device->refcount++; - mutex_unlock(&ig.device_list_mutex); - return device; -} - -/* if there's no demand for this device, release it */ -static void iser_device_try_release(struct iser_device *device) -{ - mutex_lock(&ig.device_list_mutex); - device->refcount--; - iser_err("device %p refcount %d\n",device,device->refcount); - if (!device->refcount) { - iser_free_device_ib_res(device); - list_del(&device->ig_list); - kfree(device); - } - mutex_unlock(&ig.device_list_mutex); -} - -int iser_conn_state_comp(struct iser_conn *ib_conn, - enum iser_ib_conn_state comp) -{ - int ret; - - spin_lock_bh(&ib_conn->lock); - ret = (ib_conn->state == comp); - spin_unlock_bh(&ib_conn->lock); - return ret; -} - -static int iser_conn_state_comp_exch(struct iser_conn *ib_conn, - enum iser_ib_conn_state comp, - enum iser_ib_conn_state exch) -{ - int ret; - - spin_lock_bh(&ib_conn->lock); - if ((ret = (ib_conn->state == comp))) - ib_conn->state = exch; - spin_unlock_bh(&ib_conn->lock); - return ret; -} - -/** - * triggers start of the disconnect procedures and wait for them to be done - */ -void iser_conn_terminate(struct iser_conn *ib_conn) -{ - int err = 0; - - /* change the ib conn state only if the conn is UP, however always call - * rdma_disconnect since this is the only way to cause the CMA to change - * the QP state to ERROR - */ - - iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, ISER_CONN_TERMINATING); - err = rdma_disconnect(ib_conn->cma_id); - if (err) - iser_err("Failed to disconnect, conn: 0x%p err %d\n", - ib_conn,err); - - wait_event_interruptible(ib_conn->wait, - ib_conn->state == ISER_CONN_DOWN); - - iser_conn_release(ib_conn); -} - -static void iser_connect_error(struct rdma_cm_id *cma_id) -{ - struct iser_conn *ib_conn; - ib_conn = (struct iser_conn *)cma_id->context; - - ib_conn->state = ISER_CONN_DOWN; - wake_up_interruptible(&ib_conn->wait); -} - -static void iser_addr_handler(struct rdma_cm_id *cma_id) -{ - struct iser_device *device; - struct iser_conn *ib_conn; - int ret; - - device = iser_device_find_by_ib_device(cma_id); - ib_conn = (struct iser_conn *)cma_id->context; - ib_conn->device = device; - - ret = rdma_resolve_route(cma_id, 1000); - if (ret) { - iser_err("resolve route failed: %d\n", ret); - iser_connect_error(cma_id); - } - return; -} - -static void iser_route_handler(struct rdma_cm_id *cma_id) -{ - struct rdma_conn_param conn_param; - int ret; - - ret = iser_create_ib_conn_res((struct iser_conn *)cma_id->context); - if (ret) - goto failure; - - iser_dbg("path.mtu is %d setting it to %d\n", - cma_id->route.path_rec->mtu, IB_MTU_1024); - - /* we must set the MTU to 1024 as this is what the target is assuming */ - if (cma_id->route.path_rec->mtu > IB_MTU_1024) - cma_id->route.path_rec->mtu = IB_MTU_1024; - - memset(&conn_param, 0, sizeof conn_param); - conn_param.responder_resources = 4; - conn_param.initiator_depth = 1; - conn_param.retry_count = 7; - conn_param.rnr_retry_count = 6; - - ret = rdma_connect(cma_id, &conn_param); - if (ret) { - iser_err("failure connecting: %d\n", ret); - goto failure; - } - - return; -failure: - iser_connect_error(cma_id); -} - -static void iser_connected_handler(struct rdma_cm_id *cma_id) -{ - struct iser_conn *ib_conn; - - ib_conn = (struct iser_conn *)cma_id->context; - ib_conn->state = ISER_CONN_UP; - wake_up_interruptible(&ib_conn->wait); -} - -static void iser_disconnected_handler(struct rdma_cm_id *cma_id) -{ - struct iser_conn *ib_conn; - - ib_conn = (struct iser_conn *)cma_id->context; - ib_conn->disc_evt_flag = 1; - - /* getting here when the state is UP means that the conn is being * - * terminated asynchronously from the iSCSI layer's perspective. */ - if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, - ISER_CONN_TERMINATING)) - iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn, - ISCSI_ERR_CONN_FAILED); - - /* Complete the termination process if no posts are pending */ - if ((atomic_read(&ib_conn->post_recv_buf_count) == 0) && - (atomic_read(&ib_conn->post_send_buf_count) == 0)) { - ib_conn->state = ISER_CONN_DOWN; - wake_up_interruptible(&ib_conn->wait); - } -} - -static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) -{ - int ret = 0; - - iser_err("event %d conn %p id %p\n",event->event,cma_id->context,cma_id); - - switch (event->event) { - case RDMA_CM_EVENT_ADDR_RESOLVED: - iser_addr_handler(cma_id); - break; - case RDMA_CM_EVENT_ROUTE_RESOLVED: - iser_route_handler(cma_id); - break; - case RDMA_CM_EVENT_ESTABLISHED: - iser_connected_handler(cma_id); - break; - case RDMA_CM_EVENT_ADDR_ERROR: - case RDMA_CM_EVENT_ROUTE_ERROR: - case RDMA_CM_EVENT_CONNECT_ERROR: - case RDMA_CM_EVENT_UNREACHABLE: - case RDMA_CM_EVENT_REJECTED: - iser_err("event: %d, error: %d\n", event->event, event->status); - iser_connect_error(cma_id); - break; - case RDMA_CM_EVENT_DISCONNECTED: - iser_disconnected_handler(cma_id); - break; - case RDMA_CM_EVENT_DEVICE_REMOVAL: - BUG(); - break; - case RDMA_CM_EVENT_CONNECT_RESPONSE: - BUG(); - break; - case RDMA_CM_EVENT_CONNECT_REQUEST: - default: - break; - } - return ret; -} - -int iser_conn_init(struct iser_conn **ibconn) -{ - struct iser_conn *ib_conn; - - ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL); - if (!ib_conn) { - iser_err("can't alloc memory for struct iser_conn\n"); - return -ENOMEM; - } - ib_conn->state = ISER_CONN_INIT; - init_waitqueue_head(&ib_conn->wait); - atomic_set(&ib_conn->post_recv_buf_count, 0); - atomic_set(&ib_conn->post_send_buf_count, 0); - INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker, - ib_conn); - INIT_LIST_HEAD(&ib_conn->conn_list); - spin_lock_init(&ib_conn->lock); - - *ibconn = ib_conn; - return 0; -} - - /** - * starts the process of connecting to the target - * sleeps untill the connection is established or rejected - */ -int iser_connect(struct iser_conn *ib_conn, - struct sockaddr_in *src_addr, - struct sockaddr_in *dst_addr, - int non_blocking) -{ - struct sockaddr *src, *dst; - int err = 0; - - sprintf(ib_conn->name,"%d.%d.%d.%d:%d", - NIPQUAD(dst_addr->sin_addr.s_addr), dst_addr->sin_port); - - /* the device is known only --after-- address resolution */ - ib_conn->device = NULL; - - iser_err("connecting to: %d.%d.%d.%d, port 0x%x\n", - NIPQUAD(dst_addr->sin_addr), dst_addr->sin_port); - - ib_conn->state = ISER_CONN_PENDING; - - ib_conn->cma_id = rdma_create_id(iser_cma_handler, - (void *)ib_conn, - RDMA_PS_TCP); - if (IS_ERR(ib_conn->cma_id)) { - err = PTR_ERR(ib_conn->cma_id); - iser_err("rdma_create_id failed: %d\n", err); - goto id_failure; - } - - src = (struct sockaddr *)src_addr; - dst = (struct sockaddr *)dst_addr; - err = rdma_resolve_addr(ib_conn->cma_id, src, dst, 1000); - if (err) { - iser_err("rdma_resolve_addr failed: %d\n", err); - goto addr_failure; - } - - if (!non_blocking) { - wait_event_interruptible(ib_conn->wait, - (ib_conn->state != ISER_CONN_PENDING)); - - if (ib_conn->state != ISER_CONN_UP) { - err = -EIO; - goto connect_failure; - } - } - - mutex_lock(&ig.connlist_mutex); - list_add(&ib_conn->conn_list, &ig.connlist); - mutex_unlock(&ig.connlist_mutex); - return 0; - -id_failure: - ib_conn->cma_id = NULL; -addr_failure: - ib_conn->state = ISER_CONN_DOWN; -connect_failure: - iser_conn_release(ib_conn); - return err; -} - -/** - * Frees all conn objects and deallocs conn descriptor - */ -void iser_conn_release(struct iser_conn *ib_conn) -{ - struct iser_device *device = ib_conn->device; - - BUG_ON(ib_conn->state != ISER_CONN_DOWN); - - mutex_lock(&ig.connlist_mutex); - list_del(&ib_conn->conn_list); - mutex_unlock(&ig.connlist_mutex); - - iser_free_ib_conn_res(ib_conn); - ib_conn->device = NULL; - /* on EVENT_ADDR_ERROR there's no device yet for this conn */ - if (device != NULL) - iser_device_try_release(device); - kfree(ib_conn); -} - - -/** - * iser_reg_page_vec - Register physical memory - * - * returns: 0 on success, errno code on failure - */ -int iser_reg_page_vec(struct iser_conn *ib_conn, - struct iser_page_vec *page_vec, - struct iser_mem_reg *mem_reg) -{ - struct ib_pool_fmr *mem; - u64 io_addr; - u64 *page_list; - int status; - - page_list = page_vec->pages; - io_addr = page_list[0]; - - mem = ib_fmr_pool_map_phys(ib_conn->fmr_pool, - page_list, - page_vec->length, - &io_addr); - - if (IS_ERR(mem)) { - status = (int)PTR_ERR(mem); - iser_err("ib_fmr_pool_map_phys failed: %d\n", status); - return status; - } - - mem_reg->lkey = mem->fmr->lkey; - mem_reg->rkey = mem->fmr->rkey; - mem_reg->len = page_vec->length * PAGE_SIZE; - mem_reg->va = io_addr; - mem_reg->mem_h = (void *)mem; - - mem_reg->va += page_vec->offset; - mem_reg->len = page_vec->data_size; - - iser_dbg("PHYSICAL Mem.register, [PHYS p_array: 0x%p, sz: %d, " - "entry[0]: (0x%08lx,%ld)] -> " - "[lkey: 0x%08X mem_h: 0x%p va: 0x%08lX sz: %ld]\n", - page_vec, page_vec->length, - (unsigned long)page_vec->pages[0], - (unsigned long)page_vec->data_size, - (unsigned int)mem_reg->lkey, mem_reg->mem_h, - (unsigned long)mem_reg->va, (unsigned long)mem_reg->len); - return 0; -} - -/** - * Unregister (previosuly registered) memory. - */ -void iser_unreg_mem(struct iser_mem_reg *reg) -{ - int ret; - - iser_dbg("PHYSICAL Mem.Unregister mem_h %p\n",reg->mem_h); - - ret = ib_fmr_pool_unmap((struct ib_pool_fmr *)reg->mem_h); - if (ret) - iser_err("ib_fmr_pool_unmap failed %d\n", ret); - - reg->mem_h = NULL; -} - -/** - * iser_dto_to_iov - builds IOV from a dto descriptor - */ -static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len) -{ - int i; - struct ib_sge *sge; - struct iser_regd_buf *regd_buf; - - if (dto->regd_vector_len > iov_len) { - iser_err("iov size %d too small for posting dto of len %d\n", - iov_len, dto->regd_vector_len); - BUG(); - } - - for (i = 0; i < dto->regd_vector_len; i++) { - sge = &iov[i]; - regd_buf = dto->regd[i]; - - sge->addr = regd_buf->reg.va; - sge->length = regd_buf->reg.len; - sge->lkey = regd_buf->reg.lkey; - - if (dto->used_sz[i] > 0) /* Adjust size */ - sge->length = dto->used_sz[i]; - - /* offset and length should not exceed the regd buf length */ - if (sge->length + dto->offset[i] > regd_buf->reg.len) { - iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:" - "%ld in dto:0x%p [%d], va:0x%08lX\n", - (unsigned long)sge->length, dto->offset[i], - (unsigned long)regd_buf->reg.len, dto, i, - (unsigned long)sge->addr); - BUG(); - } - - sge->addr += dto->offset[i]; /* Adjust offset */ - } -} - -/** - * iser_post_recv - Posts a receive buffer. - * - * returns 0 on success, -1 on failure - */ -int iser_post_recv(struct iser_desc *rx_desc) -{ - int ib_ret, ret_val = 0; - struct ib_recv_wr recv_wr, *recv_wr_failed; - struct ib_sge iov[2]; - struct iser_conn *ib_conn; - struct iser_dto *recv_dto = &rx_desc->dto; - - /* Retrieve conn */ - ib_conn = recv_dto->conn->ib_conn; - - iser_dto_to_iov(recv_dto, iov, 2); - - recv_wr.next = NULL; - recv_wr.sg_list = iov; - recv_wr.num_sge = recv_dto->regd_vector_len; - recv_wr.wr_id = (unsigned long)rx_desc; - - atomic_inc(&ib_conn->post_recv_buf_count); - ib_ret = ib_post_recv(ib_conn->qp, &recv_wr, &recv_wr_failed); - if (ib_ret) { - iser_err("ib_post_recv failed ret=%d\n", ib_ret); - atomic_dec(&ib_conn->post_recv_buf_count); - ret_val = -1; - } - - return ret_val; -} - -/** - * iser_start_send - Initiate a Send DTO operation - * - * returns 0 on success, -1 on failure - */ -int iser_post_send(struct iser_desc *tx_desc) -{ - int ib_ret, ret_val = 0; - struct ib_send_wr send_wr, *send_wr_failed; - struct ib_sge iov[MAX_REGD_BUF_VECTOR_LEN]; - struct iser_conn *ib_conn; - struct iser_dto *dto = &tx_desc->dto; - - ib_conn = dto->conn->ib_conn; - - iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN); - - send_wr.next = NULL; - send_wr.wr_id = (unsigned long)tx_desc; - send_wr.sg_list = iov; - send_wr.num_sge = dto->regd_vector_len; - send_wr.opcode = IB_WR_SEND; - send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0; - - atomic_inc(&ib_conn->post_send_buf_count); - - ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed); - if (ib_ret) { - iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n", - dto, dto->regd_vector_len); - iser_err("ib_post_send failed, ret:%d\n", ib_ret); - atomic_dec(&ib_conn->post_send_buf_count); - ret_val = -1; - } - - return ret_val; -} - -static void iser_comp_error_worker(void *data) -{ - struct iser_conn *ib_conn = data; - - /* getting here when the state is UP means that the conn is being * - * terminated asynchronously from the iSCSI layer's perspective. */ - if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, - ISER_CONN_TERMINATING)) - iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn, - ISCSI_ERR_CONN_FAILED); - - /* complete the termination process if disconnect event was delivered * - * note there are no more non completed posts to the QP */ - if (ib_conn->disc_evt_flag) { - ib_conn->state = ISER_CONN_DOWN; - wake_up_interruptible(&ib_conn->wait); - } -} - -static void iser_handle_comp_error(struct iser_desc *desc) -{ - struct iser_dto *dto = &desc->dto; - struct iser_conn *ib_conn = dto->conn->ib_conn; - - iser_dto_buffs_release(dto); - - if (desc->type == ISCSI_RX) { - kfree(desc->data); - kmem_cache_free(ig.desc_cache, desc); - atomic_dec(&ib_conn->post_recv_buf_count); - } else { /* type is TX control/command/dataout */ - if (desc->type == ISCSI_TX_DATAOUT) - kmem_cache_free(ig.desc_cache, desc); - atomic_dec(&ib_conn->post_send_buf_count); - } - - if (atomic_read(&ib_conn->post_recv_buf_count) == 0 && - atomic_read(&ib_conn->post_send_buf_count) == 0) - schedule_work(&ib_conn->comperror_work); -} - -static void iser_cq_tasklet_fn(unsigned long data) -{ - struct iser_device *device = (struct iser_device *)data; - struct ib_cq *cq = device->cq; - struct ib_wc wc; - struct iser_desc *desc; - unsigned long xfer_len; - - while (ib_poll_cq(cq, 1, &wc) == 1) { - desc = (struct iser_desc *) (unsigned long) wc.wr_id; - BUG_ON(desc == NULL); - - if (wc.status == IB_WC_SUCCESS) { - if (desc->type == ISCSI_RX) { - xfer_len = (unsigned long)wc.byte_len; - iser_rcv_completion(desc, xfer_len); - } else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */ - iser_snd_completion(desc); - } else { - iser_err("comp w. error op %d status %d\n",desc->type,wc.status); - iser_handle_comp_error(desc); - } - } - /* #warning "it is assumed here that arming CQ only once its empty" * - * " would not cause interrupts to be missed" */ - ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); -} - -static void iser_cq_callback(struct ib_cq *cq, void *cq_context) -{ - struct iser_device *device = (struct iser_device *)cq_context; - - tasklet_schedule(&device->cq_tasklet); -} diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index a29d5ceb00cf..ba325f16d077 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -78,19 +78,14 @@ static int evdev_fasync(int fd, struct file *file, int on) { int retval; struct evdev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); - return retval < 0 ? retval : 0; } -static int evdev_flush(struct file *file, fl_owner_t id) +static int evdev_flush(struct file * file) { struct evdev_list *list = file->private_data; - - if (!list->evdev->exist) - return -ENODEV; - + if (!list->evdev->exist) return -ENODEV; return input_flush_device(&list->evdev->handle, file); } @@ -305,7 +300,6 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count static unsigned int evdev_poll(struct file *file, poll_table *wait) { struct evdev_list *list = file->private_data; - poll_wait(file, &list->evdev->wait, wait); return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index a90486f5e491..3038c268917d 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -28,6 +28,20 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input core"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(input_allocate_device); +EXPORT_SYMBOL(input_register_device); +EXPORT_SYMBOL(input_unregister_device); +EXPORT_SYMBOL(input_register_handler); +EXPORT_SYMBOL(input_unregister_handler); +EXPORT_SYMBOL(input_grab_device); +EXPORT_SYMBOL(input_release_device); +EXPORT_SYMBOL(input_open_device); +EXPORT_SYMBOL(input_close_device); +EXPORT_SYMBOL(input_accept_process); +EXPORT_SYMBOL(input_flush_device); +EXPORT_SYMBOL(input_event); +EXPORT_SYMBOL_GPL(input_class); + #define INPUT_DEVICES 256 static LIST_HEAD(input_dev_list); @@ -49,13 +63,11 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in case EV_SYN: switch (code) { case SYN_CONFIG: - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; case SYN_REPORT: - if (dev->sync) - return; + if (dev->sync) return; dev->sync = 1; break; } @@ -124,8 +136,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (code > MSC_MAX || !test_bit(code, dev->mscbit)) return; - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; @@ -135,9 +146,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in return; change_bit(code, dev->led); - - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; @@ -149,25 +158,21 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (!!test_bit(code, dev->snd) != !!value) change_bit(code, dev->snd); - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; case EV_REP: - if (code > REP_MAX || value < 0 || dev->rep[code] == value) - return; + if (code > REP_MAX || value < 0 || dev->rep[code] == value) return; dev->rep[code] = value; - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; case EV_FF: - if (dev->event) - dev->event(dev, type, code, value); + if (dev->event) dev->event(dev, type, code, value); break; } @@ -181,7 +186,6 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (handle->open) handle->handler->event(handle, type, code, value); } -EXPORT_SYMBOL(input_event); static void input_repeat_key(unsigned long data) { @@ -204,7 +208,6 @@ int input_accept_process(struct input_handle *handle, struct file *file) return 0; } -EXPORT_SYMBOL(input_accept_process); int input_grab_device(struct input_handle *handle) { @@ -214,14 +217,12 @@ int input_grab_device(struct input_handle *handle) handle->dev->grab = handle; return 0; } -EXPORT_SYMBOL(input_grab_device); void input_release_device(struct input_handle *handle) { if (handle->dev->grab == handle) handle->dev->grab = NULL; } -EXPORT_SYMBOL(input_release_device); int input_open_device(struct input_handle *handle) { @@ -244,7 +245,6 @@ int input_open_device(struct input_handle *handle) return err; } -EXPORT_SYMBOL(input_open_device); int input_flush_device(struct input_handle* handle, struct file* file) { @@ -253,7 +253,6 @@ int input_flush_device(struct input_handle* handle, struct file* file) return 0; } -EXPORT_SYMBOL(input_flush_device); void input_close_device(struct input_handle *handle) { @@ -269,7 +268,6 @@ void input_close_device(struct input_handle *handle) mutex_unlock(&dev->mutex); } -EXPORT_SYMBOL(input_close_device); static void input_link_handle(struct input_handle *handle) { @@ -337,11 +335,9 @@ static inline void input_wakeup_procfs_readers(void) static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) { int state = input_devices_state; - poll_wait(file, &input_devices_poll_wait, wait); if (state != input_devices_state) return POLLIN | POLLRDNORM; - return 0; } @@ -633,7 +629,7 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) len = input_print_modalias(buf, PAGE_SIZE, id, 1); - return min_t(int, len, PAGE_SIZE); + return max_t(int, len, PAGE_SIZE); } static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); @@ -866,7 +862,6 @@ struct class input_class = { .release = input_dev_release, .uevent = input_dev_uevent, }; -EXPORT_SYMBOL_GPL(input_class); struct input_dev *input_allocate_device(void) { @@ -877,27 +872,12 @@ struct input_dev *input_allocate_device(void) dev->dynalloc = 1; dev->cdev.class = &input_class; class_device_initialize(&dev->cdev); - mutex_init(&dev->mutex); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); } return dev; } -EXPORT_SYMBOL(input_allocate_device); - -void input_free_device(struct input_dev *dev) -{ - if (dev) { - - mutex_lock(&dev->mutex); - dev->name = dev->phys = dev->uniq = NULL; - mutex_unlock(&dev->mutex); - - input_put_device(dev); - } -} -EXPORT_SYMBOL(input_free_device); int input_register_device(struct input_dev *dev) { @@ -915,6 +895,7 @@ int input_register_device(struct input_dev *dev) return -EINVAL; } + mutex_init(&dev->mutex); set_bit(EV_SYN, dev->evbit); /* @@ -975,14 +956,12 @@ int input_register_device(struct input_dev *dev) fail1: class_device_del(&dev->cdev); return error; } -EXPORT_SYMBOL(input_register_device); void input_unregister_device(struct input_dev *dev) { - struct list_head *node, *next; + struct list_head * node, * next; - if (!dev) - return; + if (!dev) return; del_timer_sync(&dev->timer); @@ -998,16 +977,10 @@ void input_unregister_device(struct input_dev *dev) sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); - - mutex_lock(&dev->mutex); - dev->name = dev->phys = dev->uniq = NULL; - mutex_unlock(&dev->mutex); - class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); } -EXPORT_SYMBOL(input_unregister_device); void input_register_handler(struct input_handler *handler) { @@ -1015,8 +988,7 @@ void input_register_handler(struct input_handler *handler) struct input_handle *handle; struct input_device_id *id; - if (!handler) - return; + if (!handler) return; INIT_LIST_HEAD(&handler->h_list); @@ -1033,11 +1005,10 @@ void input_register_handler(struct input_handler *handler) input_wakeup_procfs_readers(); } -EXPORT_SYMBOL(input_register_handler); void input_unregister_handler(struct input_handler *handler) { - struct list_head *node, *next; + struct list_head * node, * next; list_for_each_safe(node, next, &handler->h_list) { struct input_handle * handle = to_handle_h(node); @@ -1053,7 +1024,6 @@ void input_unregister_handler(struct input_handler *handler) input_wakeup_procfs_readers(); } -EXPORT_SYMBOL(input_unregister_handler); static int input_open_file(struct inode *inode, struct file *file) { diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index d67157513bf7..949bdcef8c2b 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -81,7 +81,10 @@ static int joydev_correct(int value, struct js_corr *corr) return 0; } - return value < -32767 ? -32767 : (value > 32767 ? 32767 : value); + if (value < -32767) return -32767; + if (value > 32767) return 32767; + + return value; } static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) @@ -93,8 +96,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne switch (type) { case EV_KEY: - if (code < BTN_MISC || value == 2) - return; + if (code < BTN_MISC || value == 2) return; event.type = JS_EVENT_BUTTON; event.number = joydev->keymap[code - BTN_MISC]; event.value = value; @@ -104,8 +106,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne event.type = JS_EVENT_AXIS; event.number = joydev->absmap[code]; event.value = joydev_correct(value, joydev->corr + event.number); - if (event.value == joydev->abs[event.number]) - return; + if (event.value == joydev->abs[event.number]) return; joydev->abs[event.number] = event.value; break; @@ -133,9 +134,7 @@ static int joydev_fasync(int fd, struct file *file, int on) { int retval; struct joydev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); - return retval < 0 ? retval : 0; } @@ -223,12 +222,12 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo return sizeof(struct JS_DATA_TYPE); } - if (list->startup == joydev->nabs + joydev->nkey && - list->head == list->tail && (file->f_flags & O_NONBLOCK)) - return -EAGAIN; + if (list->startup == joydev->nabs + joydev->nkey + && list->head == list->tail && (file->f_flags & O_NONBLOCK)) + return -EAGAIN; retval = wait_event_interruptible(list->joydev->wait, - !list->joydev->exist || + !list->joydev->exist || list->startup < joydev->nabs + joydev->nkey || list->head != list->tail); @@ -277,9 +276,8 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo static unsigned int joydev_poll(struct file *file, poll_table *wait) { struct joydev_list *list = file->private_data; - poll_wait(file, &list->joydev->wait, wait); - return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? + return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); } @@ -293,26 +291,20 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u case JS_SET_CAL: return copy_from_user(&joydev->glue.JS_CORR, argp, sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; - case JS_GET_CAL: return copy_to_user(argp, &joydev->glue.JS_CORR, sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; - case JS_SET_TIMEOUT: return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); - case JS_GET_TIMEOUT: return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); case JSIOCGVERSION: return put_user(JS_VERSION, (__u32 __user *) argp); - case JSIOCGAXES: return put_user(joydev->nabs, (__u8 __user *) argp); - case JSIOCGBUTTONS: return put_user(joydev->nkey, (__u8 __user *) argp); - case JSIOCSCORR: if (copy_from_user(joydev->corr, argp, sizeof(joydev->corr[0]) * joydev->nabs)) @@ -322,49 +314,38 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); } return 0; - case JSIOCGCORR: return copy_to_user(argp, joydev->corr, sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; - case JSIOCSAXMAP: if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) return -EFAULT; for (i = 0; i < joydev->nabs; i++) { - if (joydev->abspam[i] > ABS_MAX) - return -EINVAL; + if (joydev->abspam[i] > ABS_MAX) return -EINVAL; joydev->absmap[joydev->abspam[i]] = i; } return 0; - case JSIOCGAXMAP: return copy_to_user(argp, joydev->abspam, sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; - case JSIOCSBTNMAP: if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) return -EFAULT; for (i = 0; i < joydev->nkey; i++) { - if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) - return -EINVAL; + if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; } return 0; - case JSIOCGBTNMAP: return copy_to_user(argp, joydev->keypam, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; - default: if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { int len; - if (!dev->name) - return 0; + if (!dev->name) return 0; len = strlen(dev->name) + 1; - if (len > _IOC_SIZE(cmd)) - len = _IOC_SIZE(cmd); - if (copy_to_user(argp, dev->name, len)) - return -EFAULT; + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + if (copy_to_user(argp, dev->name, len)) return -EFAULT; return len; } } @@ -381,9 +362,7 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo struct JS_DATA_SAVE_TYPE_32 ds32; int err; - if (!joydev->exist) - return -ENODEV; - + if (!joydev->exist) return -ENODEV; switch(cmd) { case JS_SET_TIMELIMIT: err = get_user(tmp32, (s32 __user *) arg); @@ -416,7 +395,8 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo ds32.JS_SAVE = joydev->glue.JS_SAVE; ds32.JS_CORR = joydev->glue.JS_CORR; - err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0; + err = copy_to_user(argp, &ds32, + sizeof(ds32)) ? -EFAULT : 0; break; default: @@ -432,8 +412,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct joydev *joydev = list->joydev; void __user *argp = (void __user *)arg; - if (!joydev->exist) - return -ENODEV; + if (!joydev->exist) return -ENODEV; switch(cmd) { case JS_SET_TIMELIMIT: @@ -567,8 +546,8 @@ static struct input_device_id joydev_blacklist[] = { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, .evbit = { BIT(EV_KEY) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, - }, /* Avoid itouchpads, touchscreens and tablets */ - { } /* Terminating entry */ + }, /* Avoid itouchpads, touchscreens and tablets */ + { }, /* Terminating entry */ }; static struct input_device_id joydev_ids[] = { @@ -587,7 +566,7 @@ static struct input_device_id joydev_ids[] = { .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_THROTTLE) }, }, - { } /* Terminating entry */ + { }, /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, joydev_ids); @@ -600,7 +579,7 @@ static struct input_handler joydev_handler = { .minor = JOYDEV_MINOR_BASE, .name = "joydev", .id_table = joydev_ids, - .blacklist = joydev_blacklist, + .blacklist = joydev_blacklist, }; static int __init joydev_init(void) diff --git a/trunk/drivers/input/joystick/a3d.c b/trunk/drivers/input/joystick/a3d.c index b11a4bbc84c4..4612d13ea756 100644 --- a/trunk/drivers/input/joystick/a3d.c +++ b/trunk/drivers/input/joystick/a3d.c @@ -306,7 +306,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, a3d_poll); gameport_set_poll_interval(gameport, 20); - snprintf(a3d->phys, sizeof(a3d->phys), "%s/input0", gameport->phys); + sprintf(a3d->phys, "%s/input0", gameport->phys); input_dev->name = a3d_names[a3d->mode]; input_dev->phys = a3d->phys; diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index 01dc0b195d59..3121961e3e7c 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -408,23 +408,21 @@ static void analog_calibrate_timer(struct analog_port *port) static void analog_name(struct analog *analog) { - snprintf(analog->name, sizeof(analog->name), "Analog %d-axis %d-button", - hweight8(analog->mask & ANALOG_AXES_STD), - hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + - hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); + sprintf(analog->name, "Analog %d-axis %d-button", + hweight8(analog->mask & ANALOG_AXES_STD), + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + + hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); if (analog->mask & ANALOG_HATS_ALL) - snprintf(analog->name, sizeof(analog->name), "%s %d-hat", - analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); + sprintf(analog->name, "%s %d-hat", + analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); if (analog->mask & ANALOG_HAT_FCS) - strlcat(analog->name, " FCS", sizeof(analog->name)); + strcat(analog->name, " FCS"); if (analog->mask & ANALOG_ANY_CHF) - strlcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF", - sizeof(analog->name)); + strcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); - strlcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick", - sizeof(analog->name)); + strcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick"); } /* @@ -437,8 +435,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i int i, j, t, v, w, x, y, z; analog_name(analog); - snprintf(analog->phys, sizeof(analog->phys), - "%s/input%d", port->gameport->phys, index); + sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; analog->dev = input_dev = input_allocate_device(); diff --git a/trunk/drivers/input/joystick/cobra.c b/trunk/drivers/input/joystick/cobra.c index d5e42eb88a20..1909f7ef340c 100644 --- a/trunk/drivers/input/joystick/cobra.c +++ b/trunk/drivers/input/joystick/cobra.c @@ -202,8 +202,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail3; } - snprintf(cobra->phys[i], sizeof(cobra->phys[i]), - "%s/input%d", gameport->phys, i); + sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i); input_dev->name = "Creative Labs Blaster GamePad Cobra"; input_dev->phys = cobra->phys[i]; diff --git a/trunk/drivers/input/joystick/db9.c b/trunk/drivers/input/joystick/db9.c index 6f31f054d1bb..e61894685cb1 100644 --- a/trunk/drivers/input/joystick/db9.c +++ b/trunk/drivers/input/joystick/db9.c @@ -620,8 +620,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_unreg_devs; } - snprintf(db9->phys[i], sizeof(db9->phys[i]), - "%s/input%d", db9->pd->port->name, i); + sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i); input_dev->name = db9_mode->name; input_dev->phys = db9->phys[i]; diff --git a/trunk/drivers/input/joystick/gamecon.c b/trunk/drivers/input/joystick/gamecon.c index fe12aa37393d..ecbdb6b9bbd6 100644 --- a/trunk/drivers/input/joystick/gamecon.c +++ b/trunk/drivers/input/joystick/gamecon.c @@ -761,8 +761,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) if (!pads[i]) continue; - snprintf(gc->phys[i], sizeof(gc->phys[i]), - "%s/input%d", gc->pd->port->name, i); + sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); err = gc_setup_pad(gc, i, pads[i]); if (err) goto err_unreg_devs; diff --git a/trunk/drivers/input/joystick/gf2k.c b/trunk/drivers/input/joystick/gf2k.c index e4a699f6ec87..8a3ad455eb38 100644 --- a/trunk/drivers/input/joystick/gf2k.c +++ b/trunk/drivers/input/joystick/gf2k.c @@ -298,7 +298,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) gameport_set_poll_handler(gameport, gf2k_poll); gameport_set_poll_interval(gameport, 20); - snprintf(gf2k->phys, sizeof(gf2k->phys), "%s/input0", gameport->phys); + sprintf(gf2k->phys, "%s/input0", gameport->phys); gf2k->length = gf2k_lens[gf2k->id]; diff --git a/trunk/drivers/input/joystick/grip.c b/trunk/drivers/input/joystick/grip.c index 17a90c436de8..20cb98ac2d79 100644 --- a/trunk/drivers/input/joystick/grip.c +++ b/trunk/drivers/input/joystick/grip.c @@ -354,8 +354,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) goto fail3; } - snprintf(grip->phys[i], sizeof(grip->phys[i]), - "%s/input%d", gameport->phys, i); + sprintf(grip->phys[i], "%s/input%d", gameport->phys, i); input_dev->name = grip_name[grip->mode[i]]; input_dev->phys = grip->phys[i]; diff --git a/trunk/drivers/input/joystick/guillemot.c b/trunk/drivers/input/joystick/guillemot.c index 840ed9b512b2..6e2c721c26ba 100644 --- a/trunk/drivers/input/joystick/guillemot.c +++ b/trunk/drivers/input/joystick/guillemot.c @@ -222,7 +222,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * gameport_set_poll_handler(gameport, guillemot_poll); gameport_set_poll_interval(gameport, 20); - snprintf(guillemot->phys, sizeof(guillemot->phys), "%s/input0", gameport->phys); + sprintf(guillemot->phys, "%s/input0", gameport->phys); guillemot->type = guillemot_type + i; input_dev->name = guillemot_type[i].name; diff --git a/trunk/drivers/input/joystick/iforce/iforce-ff.c b/trunk/drivers/input/joystick/iforce/iforce-ff.c index 50c90765aee1..2b8e8456c9fa 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-ff.c +++ b/trunk/drivers/input/joystick/iforce/iforce-ff.c @@ -47,7 +47,7 @@ static int make_magnitude_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOSPC; + return -ENOMEM; } mutex_unlock(&iforce->mem_mutex); } @@ -80,7 +80,7 @@ static int make_period_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOSPC; + return -ENOMEM; } mutex_unlock(&iforce->mem_mutex); } @@ -120,7 +120,7 @@ static int make_envelope_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOSPC; + return -ENOMEM; } mutex_unlock(&iforce->mem_mutex); } @@ -157,7 +157,7 @@ static int make_condition_modifier(struct iforce* iforce, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { mutex_unlock(&iforce->mem_mutex); - return -ENOSPC; + return -ENOMEM; } mutex_unlock(&iforce->mem_mutex); } diff --git a/trunk/drivers/input/joystick/iforce/iforce-main.c b/trunk/drivers/input/joystick/iforce/iforce-main.c index 6d99e3c37884..ab0a26b924ca 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-main.c +++ b/trunk/drivers/input/joystick/iforce/iforce-main.c @@ -86,7 +86,7 @@ static struct iforce_device iforce_device[] = { static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct iforce* iforce = dev->private; + struct iforce* iforce = (struct iforce*)(dev->private); unsigned char data[3]; if (type != EV_FF) @@ -138,7 +138,7 @@ static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned */ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) { - struct iforce* iforce = dev->private; + struct iforce* iforce = (struct iforce*)(dev->private); int id; int ret; int is_update; @@ -218,7 +218,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) */ static int iforce_erase_effect(struct input_dev *dev, int effect_id) { - struct iforce* iforce = dev->private; + struct iforce* iforce = (struct iforce*)(dev->private); int err = 0; struct iforce_core_effect* core_effect; diff --git a/trunk/drivers/input/joystick/interact.c b/trunk/drivers/input/joystick/interact.c index bbfeb9c59b87..c4ed01758226 100644 --- a/trunk/drivers/input/joystick/interact.c +++ b/trunk/drivers/input/joystick/interact.c @@ -251,7 +251,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d gameport_set_poll_handler(gameport, interact_poll); gameport_set_poll_interval(gameport, 20); - snprintf(interact->phys, sizeof(interact->phys), "%s/input0", gameport->phys); + sprintf(interact->phys, "%s/input0", gameport->phys); interact->type = i; interact->length = interact_type[i].length; diff --git a/trunk/drivers/input/joystick/magellan.c b/trunk/drivers/input/joystick/magellan.c index 168b1061a03b..ca3cc2319d6a 100644 --- a/trunk/drivers/input/joystick/magellan.c +++ b/trunk/drivers/input/joystick/magellan.c @@ -162,7 +162,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) goto fail; magellan->dev = input_dev; - snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); + sprintf(magellan->phys, "%s/input0", serio->phys); input_dev->name = "LogiCad3D Magellan / SpaceMouse"; input_dev->phys = magellan->phys; diff --git a/trunk/drivers/input/joystick/sidewinder.c b/trunk/drivers/input/joystick/sidewinder.c index e58b22c018e4..95c0de7964a0 100644 --- a/trunk/drivers/input/joystick/sidewinder.c +++ b/trunk/drivers/input/joystick/sidewinder.c @@ -541,7 +541,7 @@ static void sw_print_packet(char *name, int length, unsigned char *buf, char bit * Unfortunately I don't know how to do this for the other SW types. */ -static void sw_3dp_id(unsigned char *buf, char *comment, size_t size) +static void sw_3dp_id(unsigned char *buf, char *comment) { int i; char pnp[8], rev[9]; @@ -554,7 +554,7 @@ static void sw_3dp_id(unsigned char *buf, char *comment, size_t size) pnp[7] = rev[8] = 0; - snprintf(comment, size, " [PnP %d.%02d id %s rev %s]", + sprintf(comment, " [PnP %d.%02d id %s rev %s]", (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | /* Two 6-bit values */ sw_get_bits(buf, 16, 6, 1)) / 100, (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | @@ -695,7 +695,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sw->type = SW_ID_FFP; sprintf(comment, " [AC %s]", sw_get_bits(idbuf,38,1,3) ? "off" : "on"); } else - sw->type = SW_ID_PP; + sw->type = SW_ID_PP; break; case 66: sw->bits = 3; @@ -703,8 +703,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) sw->length = 22; case 64: sw->type = SW_ID_3DP; - if (j == 160) - sw_3dp_id(idbuf, comment, sizeof(comment)); + if (j == 160) sw_3dp_id(idbuf, comment); break; } } @@ -734,10 +733,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < sw->number; i++) { int bits, code; - snprintf(sw->name, sizeof(sw->name), - "Microsoft SideWinder %s", sw_name[sw->type]); - snprintf(sw->phys[i], sizeof(sw->phys[i]), - "%s/input%d", gameport->phys, i); + sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); + sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); sw->dev[i] = input_dev = input_allocate_device(); if (!input_dev) { diff --git a/trunk/drivers/input/joystick/spaceball.c b/trunk/drivers/input/joystick/spaceball.c index 75eb5ca59992..d6f8db8ec3fd 100644 --- a/trunk/drivers/input/joystick/spaceball.c +++ b/trunk/drivers/input/joystick/spaceball.c @@ -220,7 +220,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) goto fail; spaceball->dev = input_dev; - snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); + sprintf(spaceball->phys, "%s/input0", serio->phys); input_dev->name = spaceball_names[id]; input_dev->phys = spaceball->phys; diff --git a/trunk/drivers/input/joystick/spaceorb.c b/trunk/drivers/input/joystick/spaceorb.c index 3e2782e79834..7c123a01c58e 100644 --- a/trunk/drivers/input/joystick/spaceorb.c +++ b/trunk/drivers/input/joystick/spaceorb.c @@ -177,7 +177,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) goto fail; spaceorb->dev = input_dev; - snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); + sprintf(spaceorb->phys, "%s/input0", serio->phys); input_dev->name = "SpaceTec SpaceOrb 360 / Avenger"; input_dev->phys = spaceorb->phys; diff --git a/trunk/drivers/input/joystick/stinger.c b/trunk/drivers/input/joystick/stinger.c index 011ec4858e15..0a9ed1d30636 100644 --- a/trunk/drivers/input/joystick/stinger.c +++ b/trunk/drivers/input/joystick/stinger.c @@ -148,7 +148,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) goto fail; stinger->dev = input_dev; - snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); + sprintf(stinger->phys, "%s/serio0", serio->phys); input_dev->name = "Gravis Stinger"; input_dev->phys = stinger->phys; diff --git a/trunk/drivers/input/joystick/twidjoy.c b/trunk/drivers/input/joystick/twidjoy.c index 076f237d9654..7f8b0093c5bc 100644 --- a/trunk/drivers/input/joystick/twidjoy.c +++ b/trunk/drivers/input/joystick/twidjoy.c @@ -199,7 +199,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) goto fail; twidjoy->dev = input_dev; - snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); + sprintf(twidjoy->phys, "%s/input0", serio->phys); input_dev->name = "Handykey Twiddler"; input_dev->phys = twidjoy->phys; diff --git a/trunk/drivers/input/joystick/warrior.c b/trunk/drivers/input/joystick/warrior.c index f9c1a03214eb..1849b176cf18 100644 --- a/trunk/drivers/input/joystick/warrior.c +++ b/trunk/drivers/input/joystick/warrior.c @@ -154,7 +154,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) goto fail; warrior->dev = input_dev; - snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); + sprintf(warrior->phys, "%s/input0", serio->phys); input_dev->name = "Logitech WingMan Warrior"; input_dev->phys = warrior->phys; diff --git a/trunk/drivers/input/keyboard/amikbd.c b/trunk/drivers/input/keyboard/amikbd.c index f1f9db9d282c..4c8fb1f8631f 100644 --- a/trunk/drivers/input/keyboard/amikbd.c +++ b/trunk/drivers/input/keyboard/amikbd.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -46,7 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Amiga keyboard driver"); MODULE_LICENSE("GPL"); -static unsigned char amikbd_keycode[0x78] __initdata = { +static unsigned char amikbd_keycode[0x78] = { [0] = KEY_GRAVE, [1] = KEY_1, [2] = KEY_2, @@ -171,9 +170,12 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) scancode >>= 1; if (scancode < 0x78) { /* scancodes < 0x78 are keys */ + + scancode = amikbd_keycode[scancode]; + input_regs(amikbd_dev, fp); - if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ + if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(amikbd_dev, scancode, 1); input_report_key(amikbd_dev, scancode, 0); } else { @@ -189,7 +191,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp) static int __init amikbd_init(void) { - int i, j; + int i; if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) return -EIO; @@ -212,26 +214,14 @@ static int __init amikbd_init(void) amikbd_dev->id.version = 0x0100; amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + amikbd_dev->keycode = amikbd_keycode; + amikbd_dev->keycodesize = sizeof(unsigned char); + amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode); for (i = 0; i < 0x78; i++) - set_bit(i, amikbd_dev->keybit); - - for (i = 0; i < MAX_NR_KEYMAPS; i++) { - static u_short temp_map[NR_KEYS] __initdata; - if (!key_maps[i]) - continue; - memset(temp_map, 0, sizeof(temp_map)); - for (j = 0; j < 0x78; j++) { - if (!amikbd_keycode[j]) - continue; - temp_map[j] = key_maps[i][amikbd_keycode[j]]; - } - for (j = 0; j < NR_KEYS; j++) { - if (!temp_map[j]) - temp_map[j] = 0xf200; - } - memcpy(key_maps[i], temp_map, sizeof(temp_map)); - } + if (amikbd_keycode[i]) + set_bit(amikbd_keycode[i], amikbd_dev->keybit); + ciaa.cra &= ~0x41; /* serial data in, turn off TA */ request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index ffde8f86e0fb..fad04b66d268 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -55,7 +55,7 @@ static int atkbd_softraw = 1; module_param_named(softraw, atkbd_softraw, bool, 0); MODULE_PARM_DESC(softraw, "Use software generated rawmode"); -static int atkbd_scroll; +static int atkbd_scroll = 0; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); @@ -150,8 +150,8 @@ static unsigned char atkbd_unxlate_table[128] = { #define ATKBD_RET_EMUL0 0xe0 #define ATKBD_RET_EMUL1 0xe1 #define ATKBD_RET_RELEASE 0xf0 -#define ATKBD_RET_HANJA 0xf1 -#define ATKBD_RET_HANGEUL 0xf2 +#define ATKBD_RET_HANGUEL 0xf1 +#define ATKBD_RET_HANJA 0xf2 #define ATKBD_RET_ERR 0xff #define ATKBD_KEY_UNKNOWN 0 @@ -170,13 +170,6 @@ static unsigned char atkbd_unxlate_table[128] = { #define ATKBD_LED_EVENT_BIT 0 #define ATKBD_REP_EVENT_BIT 1 -#define ATKBD_XL_ERR 0x01 -#define ATKBD_XL_BAT 0x02 -#define ATKBD_XL_ACK 0x04 -#define ATKBD_XL_NAK 0x08 -#define ATKBD_XL_HANGEUL 0x10 -#define ATKBD_XL_HANJA 0x20 - static struct { unsigned char keycode; unsigned char set2; @@ -218,7 +211,8 @@ struct atkbd { unsigned char emul; unsigned char resend; unsigned char release; - unsigned long xl_bit; + unsigned char bat_xl; + unsigned char err_xl; unsigned int last; unsigned long time; @@ -251,65 +245,17 @@ ATKBD_DEFINE_ATTR(set); ATKBD_DEFINE_ATTR(softrepeat); ATKBD_DEFINE_ATTR(softraw); -static const unsigned int xl_table[] = { - ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, - ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, -}; - -/* - * Checks if we should mangle the scancode to extract 'release' bit - * in translated mode. - */ -static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) -{ - int i; - - if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) - return 0; - - for (i = 0; i < ARRAY_SIZE(xl_table); i++) - if (code == xl_table[i]) - return test_bit(i, &xl_bit); - - return 1; -} -/* - * Calculates new value of xl_bit so the driver can distinguish - * between make/break pair of scancodes for select keys and PS/2 - * protocol responses. - */ -static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(xl_table); i++) { - if (!((code ^ xl_table[i]) & 0x7f)) { - if (code & 0x80) - __clear_bit(i, &atkbd->xl_bit); - else - __set_bit(i, &atkbd->xl_bit); - break; - } - } -} - -/* - * Encode the scancode, 0xe0 prefix, and high bit into a single integer, - * keeping kernel 2.4 compatibility for set 2 - */ -static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code) +static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) { - if (atkbd->set == 3) { - if (atkbd->emul == 1) - code |= 0x100; - } else { - code = (code & 0x7f) | ((code & 0x80) << 1); - if (atkbd->emul == 1) - code |= 0x80; - } - - return code; + input_regs(dev, regs); + if (value == 3) { + input_report_key(dev, code, 1); + input_sync(dev); + input_report_key(dev, code, 0); + } else + input_event(dev, EV_KEY, code, value); + input_sync(dev); } /* @@ -321,11 +267,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct atkbd *atkbd = serio_get_drvdata(serio); - struct input_dev *dev = atkbd->dev; unsigned int code = data; - int scroll = 0, hscroll = 0, click = -1, add_release_event = 0; + int scroll = 0, hscroll = 0, click = -1; int value; - unsigned char keycode; #ifdef ATKBD_DEBUG printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); @@ -354,17 +298,25 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, if (!atkbd->enabled) goto out; - input_event(dev, EV_MSC, MSC_RAW, code); + input_event(atkbd->dev, EV_MSC, MSC_RAW, code); if (atkbd->translated) { - if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { + if (atkbd->emul || + (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && + code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA && + (code != ATKBD_RET_ERR || atkbd->err_xl) && + (code != ATKBD_RET_BAT || atkbd->bat_xl))) { atkbd->release = code >> 7; code &= 0x7f; } - if (!atkbd->emul) - atkbd_calculate_xl_bit(atkbd, data); + if (!atkbd->emul) { + if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) + atkbd->bat_xl = !(data >> 7); + if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) + atkbd->err_xl = !(data >> 7); + } } switch (code) { @@ -381,48 +333,47 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, case ATKBD_RET_RELEASE: atkbd->release = 1; goto out; - case ATKBD_RET_ACK: - case ATKBD_RET_NAK: - printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " - "Some program might be trying access hardware directly.\n", - data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); + case ATKBD_RET_HANGUEL: + atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3); goto out; - case ATKBD_RET_HANGEUL: case ATKBD_RET_HANJA: - /* - * These keys do not report release and thus need to be - * flagged properly - */ - add_release_event = 1; - break; + atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); + goto out; case ATKBD_RET_ERR: printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); goto out; } - code = atkbd_compat_scancode(atkbd, code); - - if (atkbd->emul && --atkbd->emul) - goto out; - - keycode = atkbd->keycode[code]; + if (atkbd->set != 3) + code = (code & 0x7f) | ((code & 0x80) << 1); + if (atkbd->emul) { + if (--atkbd->emul) + goto out; + code |= (atkbd->set != 3) ? 0x80 : 0x100; + } - if (keycode != ATKBD_KEY_NULL) - input_event(dev, EV_MSC, MSC_SCAN, code); + if (atkbd->keycode[code] != ATKBD_KEY_NULL) + input_event(atkbd->dev, EV_MSC, MSC_SCAN, code); - switch (keycode) { + switch (atkbd->keycode[code]) { case ATKBD_KEY_NULL: break; case ATKBD_KEY_UNKNOWN: - printk(KERN_WARNING - "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", - atkbd->release ? "released" : "pressed", - atkbd->translated ? "translated" : "raw", - atkbd->set, code, serio->phys); - printk(KERN_WARNING - "atkbd.c: Use 'setkeycodes %s%02x ' to make it known.\n", - code & 0x80 ? "e0" : "", code & 0x7f); - input_sync(dev); + if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) { + printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, " + "like XFree86, might be trying access hardware directly.\n", + data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); + } else { + printk(KERN_WARNING "atkbd.c: Unknown key %s " + "(%s set %d, code %#x on %s).\n", + atkbd->release ? "released" : "pressed", + atkbd->translated ? "translated" : "raw", + atkbd->set, code, serio->phys); + printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x ' " + "to make it known.\n", + code & 0x80 ? "e0" : "", code & 0x7f); + } + input_sync(atkbd->dev); break; case ATKBD_SCR_1: scroll = 1 - atkbd->release * 2; @@ -446,35 +397,33 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, hscroll = 1; break; default: - if (atkbd->release) { - value = 0; - atkbd->last = 0; - } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { - /* Workaround Toshiba laptop multiple keypress */ - value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; - } else { - value = 1; - atkbd->last = code; - atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; + value = atkbd->release ? 0 : + (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key))); + + switch (value) { /* Workaround Toshiba laptop multiple keypress */ + case 0: + atkbd->last = 0; + break; + case 1: + atkbd->last = code; + atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2; + break; + case 2: + if (!time_after(jiffies, atkbd->time) && atkbd->last == code) + value = 1; + break; } - input_regs(dev, regs); - input_report_key(dev, keycode, value); - input_sync(dev); - - if (value && add_release_event) { - input_report_key(dev, keycode, 0); - input_sync(dev); - } + atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value); } if (atkbd->scroll) { - input_regs(dev, regs); + input_regs(atkbd->dev, regs); if (click != -1) - input_report_key(dev, BTN_MIDDLE, click); - input_report_rel(dev, REL_WHEEL, scroll); - input_report_rel(dev, REL_HWHEEL, hscroll); - input_sync(dev); + input_report_key(atkbd->dev, BTN_MIDDLE, click); + input_report_rel(atkbd->dev, REL_WHEEL, scroll); + input_report_rel(atkbd->dev, REL_HWHEEL, hscroll); + input_sync(atkbd->dev); } atkbd->release = 0; @@ -815,9 +764,6 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode; } - - atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANGEUL)] = KEY_HANGUEL; - atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANJA)] = KEY_HANJA; } /* @@ -830,15 +776,12 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) int i; if (atkbd->extra) - snprintf(atkbd->name, sizeof(atkbd->name), - "AT Set 2 Extra keyboard"); + sprintf(atkbd->name, "AT Set 2 Extra keyboard"); else - snprintf(atkbd->name, sizeof(atkbd->name), - "AT %s Set %d keyboard", - atkbd->translated ? "Translated" : "Raw", atkbd->set); + sprintf(atkbd->name, "AT %s Set %d keyboard", + atkbd->translated ? "Translated" : "Raw", atkbd->set); - snprintf(atkbd->phys, sizeof(atkbd->phys), - "%s/input0", atkbd->ps2dev.serio->phys); + sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys); input_dev->name = atkbd->name; input_dev->phys = atkbd->phys; diff --git a/trunk/drivers/input/keyboard/lkkbd.c b/trunk/drivers/input/keyboard/lkkbd.c index 5174224cadb4..77c4d9669ad0 100644 --- a/trunk/drivers/input/keyboard/lkkbd.c +++ b/trunk/drivers/input/keyboard/lkkbd.c @@ -384,21 +384,18 @@ lkkbd_detection_done (struct lkkbd *lk) */ switch (lk->id[4]) { case 1: - strlcpy (lk->name, "DEC LK201 keyboard", - sizeof (lk->name)); + sprintf (lk->name, "DEC LK201 keyboard"); if (lk201_compose_is_alt) lk->keycode[0xb1] = KEY_LEFTALT; break; case 2: - strlcpy (lk->name, "DEC LK401 keyboard", - sizeof (lk->name)); + sprintf (lk->name, "DEC LK401 keyboard"); break; default: - strlcpy (lk->name, "Unknown DEC keyboard", - sizeof (lk->name)); + sprintf (lk->name, "Unknown DEC keyboard"); printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " "please report to Jan-Benedict Glaw " "\n", lk->phys); diff --git a/trunk/drivers/input/keyboard/newtonkbd.c b/trunk/drivers/input/keyboard/newtonkbd.c index 40a3f551247e..d10983c521e6 100644 --- a/trunk/drivers/input/keyboard/newtonkbd.c +++ b/trunk/drivers/input/keyboard/newtonkbd.c @@ -96,7 +96,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) nkbd->serio = serio; nkbd->dev = input_dev; - snprintf(nkbd->phys, sizeof(nkbd->phys), "%s/input0", serio->phys); + sprintf(nkbd->phys, "%s/input0", serio->phys); memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode)); input_dev->name = "Newton Keyboard"; diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index 9dbd7b85686d..b15b6d8d4f83 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -263,7 +263,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) goto fail; } - snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); + sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type); memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); input_dev->name = sunkbd->name; diff --git a/trunk/drivers/input/keyboard/xtkbd.c b/trunk/drivers/input/keyboard/xtkbd.c index 0821d53cf0c1..4135e3e16c51 100644 --- a/trunk/drivers/input/keyboard/xtkbd.c +++ b/trunk/drivers/input/keyboard/xtkbd.c @@ -100,7 +100,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) xtkbd->serio = serio; xtkbd->dev = input_dev; - snprintf(xtkbd->phys, sizeof(xtkbd->phys), "%s/input0", serio->phys); + sprintf(xtkbd->phys, "%s/input0", serio->phys); memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode)); input_dev->name = "XT Keyboard"; diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index a6dfc7455733..4bad588d0e5d 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -26,7 +26,7 @@ config INPUT_PCSPKR config INPUT_SPARCSPKR tristate "SPARC Speaker support" - depends on PCI && SPARC64 + depends on PCI && SPARC help Say Y here if you want the standard Speaker on Sparc PCI systems to be used for bells and whistles. diff --git a/trunk/drivers/input/misc/sparcspkr.c b/trunk/drivers/input/misc/sparcspkr.c index 42c11fbf3c79..f0fd2c4740f1 100644 --- a/trunk/drivers/input/misc/sparcspkr.c +++ b/trunk/drivers/input/misc/sparcspkr.c @@ -2,7 +2,7 @@ * Driver for PC-speaker like devices found on various Sparc systems. * * Copyright (c) 2002 Vojtech Pavlik - * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net) + * Copyright (c) 2002 David S. Miller (davem@redhat.com) */ #include #include @@ -13,23 +13,21 @@ #include #include +#ifdef CONFIG_SPARC64 #include +#endif -MODULE_AUTHOR("David S. Miller "); +MODULE_AUTHOR("David S. Miller "); MODULE_DESCRIPTION("Sparc Speaker beeper driver"); MODULE_LICENSE("GPL"); -struct sparcspkr_state { - const char *name; - unsigned long iobase; - int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); - spinlock_t lock; - struct input_dev *input_dev; -}; +const char *beep_name; +static unsigned long beep_iobase; +static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); +static DEFINE_SPINLOCK(beep_lock); static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -45,24 +43,24 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in if (value > 20 && value < 32767) count = 1193182 / value; - spin_lock_irqsave(&state->lock, flags); + spin_lock_irqsave(&beep_lock, flags); /* EBUS speaker only has on/off state, the frequency does not * appear to be programmable. */ - if (state->iobase & 0x2UL) - outb(!!count, state->iobase); + if (beep_iobase & 0x2UL) + outb(!!count, beep_iobase); else - outl(!!count, state->iobase); + outl(!!count, beep_iobase); - spin_unlock_irqrestore(&state->lock, flags); + spin_unlock_irqrestore(&beep_lock, flags); return 0; } +#ifdef CONFIG_SPARC64 static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -78,29 +76,29 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int if (value > 20 && value < 32767) count = 1193182 / value; - spin_lock_irqsave(&state->lock, flags); + spin_lock_irqsave(&beep_lock, flags); if (count) { /* enable counter 2 */ - outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61); + outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61); /* set command for counter 2, 2 byte write */ - outb(0xB6, state->iobase + 0x43); + outb(0xB6, beep_iobase + 0x43); /* select desired HZ */ - outb(count & 0xff, state->iobase + 0x42); - outb((count >> 8) & 0xff, state->iobase + 0x42); + outb(count & 0xff, beep_iobase + 0x42); + outb((count >> 8) & 0xff, beep_iobase + 0x42); } else { /* disable counter 2 */ - outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61); + outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61); } - spin_unlock_irqrestore(&state->lock, flags); + spin_unlock_irqrestore(&beep_lock, flags); return 0; } +#endif -static int __devinit sparcspkr_probe(struct device *dev) +static int __devinit sparcspkr_probe(struct platform_device *dev) { - struct sparcspkr_state *state = dev_get_drvdata(dev); struct input_dev *input_dev; int error; @@ -108,18 +106,18 @@ static int __devinit sparcspkr_probe(struct device *dev) if (!input_dev) return -ENOMEM; - input_dev->name = state->name; + input_dev->name = beep_name; input_dev->phys = "sparc/input0"; input_dev->id.bustype = BUS_ISA; input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->cdev.dev = dev; + input_dev->cdev.dev = &dev->dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - input_dev->event = state->event; + input_dev->event = beep_event; error = input_register_device(input_dev); if (error) { @@ -127,137 +125,111 @@ static int __devinit sparcspkr_probe(struct device *dev) return error; } - state->input_dev = input_dev; + platform_set_drvdata(dev, input_dev); return 0; } -static int __devexit sparcspkr_remove(struct of_device *dev) +static int __devexit sparcspkr_remove(struct platform_device *dev) { - struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); - struct input_dev *input_dev = state->input_dev; - - /* turn off the speaker */ - state->event(input_dev, EV_SND, SND_BELL, 0); + struct input_dev *input_dev = platform_get_drvdata(dev); input_unregister_device(input_dev); - - dev_set_drvdata(&dev->dev, NULL); - kfree(state); - - return 0; -} - -static int sparcspkr_shutdown(struct of_device *dev) -{ - struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); - struct input_dev *input_dev = state->input_dev; - + platform_set_drvdata(dev, NULL); /* turn off the speaker */ - state->event(input_dev, EV_SND, SND_BELL, 0); + beep_event(NULL, EV_SND, SND_BELL, 0); return 0; } -static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match) +static void sparcspkr_shutdown(struct platform_device *dev) { - struct linux_ebus_device *edev = to_ebus_device(&dev->dev); - struct sparcspkr_state *state; - int err; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->name = "Sparc EBUS Speaker"; - state->iobase = edev->resource[0].start; - state->event = ebus_spkr_event; - spin_lock_init(&state->lock); - - dev_set_drvdata(&dev->dev, state); - - err = sparcspkr_probe(&dev->dev); - if (err) { - dev_set_drvdata(&dev->dev, NULL); - kfree(state); - } - - return 0; + /* turn off the speaker */ + beep_event(NULL, EV_SND, SND_BELL, 0); } -static struct of_device_id ebus_beep_match[] = { - { - .name = "beep", +static struct platform_driver sparcspkr_platform_driver = { + .driver = { + .name = "sparcspkr", + .owner = THIS_MODULE, }, - {}, -}; - -static struct of_platform_driver ebus_beep_driver = { - .name = "beep", - .match_table = ebus_beep_match, - .probe = ebus_beep_probe, - .remove = sparcspkr_remove, + .probe = sparcspkr_probe, + .remove = __devexit_p(sparcspkr_remove), .shutdown = sparcspkr_shutdown, }; -static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sparc_isa_device *idev = to_isa_device(&dev->dev); - struct sparcspkr_state *state; - int err; +static struct platform_device *sparcspkr_platform_device; - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return -ENOMEM; - - state->name = "Sparc ISA Speaker"; - state->iobase = idev->resource.start; - state->event = isa_spkr_event; - spin_lock_init(&state->lock); +static int __init sparcspkr_drv_init(void) +{ + int error; - dev_set_drvdata(&dev->dev, state); + error = platform_driver_register(&sparcspkr_platform_driver); + if (error) + return error; - err = sparcspkr_probe(&dev->dev); - if (err) { - dev_set_drvdata(&dev->dev, NULL); - kfree(state); + sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1); + if (!sparcspkr_platform_device) { + error = -ENOMEM; + goto err_unregister_driver; } + error = platform_device_add(sparcspkr_platform_device); + if (error) + goto err_free_device; + return 0; -} -static struct of_device_id isa_beep_match[] = { - { - .name = "dma", - }, - {}, -}; + err_free_device: + platform_device_put(sparcspkr_platform_device); + err_unregister_driver: + platform_driver_unregister(&sparcspkr_platform_driver); -static struct of_platform_driver isa_beep_driver = { - .name = "beep", - .match_table = isa_beep_match, - .probe = isa_beep_probe, - .remove = sparcspkr_remove, - .shutdown = sparcspkr_shutdown, -}; + return error; +} static int __init sparcspkr_init(void) { - int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type); - - if (!err) { - err = of_register_driver(&isa_beep_driver, &isa_bus_type); - if (err) - of_unregister_driver(&ebus_beep_driver); + struct linux_ebus *ebus; + struct linux_ebus_device *edev; +#ifdef CONFIG_SPARC64 + struct sparc_isa_bridge *isa_br; + struct sparc_isa_device *isa_dev; +#endif + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "beep")) { + beep_name = "Sparc EBUS Speaker"; + beep_event = ebus_spkr_event; + beep_iobase = edev->resource[0].start; + return sparcspkr_drv_init(); + } + } + } +#ifdef CONFIG_SPARC64 + for_each_isa(isa_br) { + for_each_isadev(isa_dev, isa_br) { + /* A hack, the beep device's base lives in + * the DMA isa node. + */ + if (!strcmp(isa_dev->prom_name, "dma")) { + beep_name = "Sparc ISA Speaker"; + beep_event = isa_spkr_event, + beep_iobase = isa_dev->resource.start; + return sparcspkr_drv_init(); + } + } } +#endif - return err; + return -ENODEV; } static void __exit sparcspkr_exit(void) { - of_unregister_driver(&ebus_beep_driver); - of_unregister_driver(&isa_beep_driver); + platform_device_unregister(sparcspkr_platform_device); + platform_driver_unregister(&sparcspkr_platform_driver); } module_init(sparcspkr_init); diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index 070d75330afd..a0e2e797c6d5 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -470,7 +470,7 @@ int alps_init(struct psmouse *psmouse) dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); } - snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); + sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys); dev2->phys = priv->phys; dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; dev2->id.bustype = BUS_I8042; diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 8bc9f51ae6c2..136321a2cfdb 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -150,20 +150,9 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg */ if (psmouse->type == PSMOUSE_IMEX) { - switch (packet[3] & 0xC0) { - case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ - input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); - break; - case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ - input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); - break; - case 0x00: - case 0xC0: - input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); - input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); - input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); - break; - } + input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); + input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); + input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); } /* @@ -477,25 +466,9 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) if (param[0] != 4) return -1; -/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ - param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - param[0] = 80; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - param[0] = 40; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - - param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - param[0] = 60; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - if (set_properties) { set_bit(BTN_MIDDLE, psmouse->dev->keybit); set_bit(REL_WHEEL, psmouse->dev->relbit); - set_bit(REL_HWHEEL, psmouse->dev->relbit); set_bit(BTN_SIDE, psmouse->dev->keybit); set_bit(BTN_EXTRA, psmouse->dev->keybit); @@ -1084,8 +1057,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto if (psmouse->resync_time && psmouse->poll(psmouse)) psmouse->resync_time = 0; - snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", - psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); + sprintf(psmouse->devname, "%s %s %s", + psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); input_dev->name = psmouse->devname; input_dev->phys = psmouse->phys; @@ -1126,7 +1099,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) ps2_init(&psmouse->ps2dev, serio); INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); psmouse->dev = input_dev; - snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); + sprintf(psmouse->phys, "%s/input0", serio->phys); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index a89742431717..2f9a04ae725f 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -254,7 +254,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) goto fail; sermouse->dev = input_dev; - snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); + sprintf(sermouse->phys, "%s/input0", serio->phys); sermouse->type = serio->id.proto; input_dev->name = sermouse_protocols[sermouse->type]; diff --git a/trunk/drivers/input/mouse/vsxxxaa.c b/trunk/drivers/input/mouse/vsxxxaa.c index 7b85bc21ae4a..36e9442a16b2 100644 --- a/trunk/drivers/input/mouse/vsxxxaa.c +++ b/trunk/drivers/input/mouse/vsxxxaa.c @@ -153,25 +153,22 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse) { switch (mouse->type) { case 0x02: - strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse", - sizeof (mouse->name)); + sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse"); break; case 0x04: - strlcpy (mouse->name, "DEC VSXXX-AB digitizer", - sizeof (mouse->name)); + sprintf (mouse->name, "DEC VSXXX-AB digitizer"); break; default: - snprintf (mouse->name, sizeof (mouse->name), - "unknown DEC pointer device (type = 0x%02x)", - mouse->type); + sprintf (mouse->name, "unknown DEC pointer device " + "(type = 0x%02x)", mouse->type); break; } - printk (KERN_INFO - "Found %s version 0x%02x from country 0x%02x on port %s\n", - mouse->name, mouse->version, mouse->country, mouse->phys); + printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x " + "on port %s\n", mouse->name, mouse->version, + mouse->country, mouse->phys); } /* @@ -506,9 +503,8 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) mouse->dev = input_dev; mouse->serio = serio; - strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", - sizeof (mouse->name)); - snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys); + sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); + sprintf (mouse->phys, "%s/input0", serio->phys); input_dev->name = mouse->name; input_dev->phys = mouse->phys; diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index eb721b11ff37..b685a507955d 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -123,9 +123,7 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous if (mousedev->touch) { size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) - size = 256 * 2; - + if (size == 0) size = 256 * 2; switch (code) { case ABS_X: fx(0) = value; @@ -157,24 +155,18 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, switch (code) { case ABS_X: size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) - size = xres ? : 1; - if (value > dev->absmax[ABS_X]) - value = dev->absmax[ABS_X]; - if (value < dev->absmin[ABS_X]) - value = dev->absmin[ABS_X]; + if (size == 0) size = xres ? : 1; + if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; + if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; mousedev->packet.abs_event = 1; break; case ABS_Y: size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; - if (size == 0) - size = yres ? : 1; - if (value > dev->absmax[ABS_Y]) - value = dev->absmax[ABS_Y]; - if (value < dev->absmin[ABS_Y]) - value = dev->absmin[ABS_Y]; + if (size == 0) size = yres ? : 1; + if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; + if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; mousedev->packet.abs_event = 1; break; @@ -210,7 +202,7 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int case BTN_SIDE: index = 3; break; case BTN_4: case BTN_EXTRA: index = 4; break; - default: return; + default: return; } if (value) { @@ -293,9 +285,10 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) mousedev->touch = mousedev->pkt_count = 0; mousedev->frac_dx = 0; mousedev->frac_dy = 0; - - } else if (!mousedev->touch) - mousedev->touch = jiffies; + } + else + if (!mousedev->touch) + mousedev->touch = jiffies; } static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) @@ -334,7 +327,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig mousedev->pkt_count++; /* Input system eats duplicate events, but we need all of them * to do correct averaging so apply present one forward - */ + */ fx(0) = fx(1); fy(0) = fy(1); } @@ -353,9 +346,7 @@ static int mousedev_fasync(int fd, struct file *file, int on) { int retval; struct mousedev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); - return retval < 0 ? retval : 0; } @@ -516,16 +507,14 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si list->imexseq = 0; list->mode = MOUSEDEV_EMUL_EXPS; } - } else - list->imexseq = 0; + } else list->imexseq = 0; if (c == mousedev_imps_seq[list->impsseq]) { if (++list->impsseq == MOUSEDEV_SEQ_LEN) { list->impsseq = 0; list->mode = MOUSEDEV_EMUL_IMPS; } - } else - list->impsseq = 0; + } else list->impsseq = 0; list->ps2[0] = 0xfa; @@ -609,7 +598,6 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co static unsigned int mousedev_poll(struct file *file, poll_table *wait) { struct mousedev_list *list = file->private_data; - poll_wait(file, &list->mousedev->wait, wait); return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); diff --git a/trunk/drivers/input/serio/i8042-sparcio.h b/trunk/drivers/input/serio/i8042-sparcio.h index 6d66351805a2..ed9446f6d7e3 100644 --- a/trunk/drivers/input/serio/i8042-sparcio.h +++ b/trunk/drivers/input/serio/i8042-sparcio.h @@ -74,7 +74,7 @@ static int __init i8042_platform_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "8042")) + if (!strcmp(edev->prom_name, "8042")) goto edev_found; } } @@ -82,14 +82,14 @@ static int __init i8042_platform_init(void) edev_found: for_each_edevchild(edev, child) { - if (!strcmp(child->prom_node->name, OBP_PS2KBD_NAME1) || - !strcmp(child->prom_node->name, OBP_PS2KBD_NAME2)) { + if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) || + !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) { i8042_kbd_irq = child->irqs[0]; kbd_iobase = ioremap(child->resource[0].start, 8); } - if (!strcmp(child->prom_node->name, OBP_PS2MS_NAME1) || - !strcmp(child->prom_node->name, OBP_PS2MS_NAME2)) + if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) || + !strcmp(child->prom_name, OBP_PS2MS_NAME2)) i8042_aux_irq = child->irqs[0]; } if (i8042_kbd_irq == -1 || diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 386023c594d7..161afddd0f44 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -773,7 +773,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->last_msg = m; - if (request_irq(spi->irq, ads7846_irq, SA_TRIGGER_FALLING, + if (request_irq(spi->irq, ads7846_irq, + SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, spi->dev.driver->name, ts)) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); err = -EBUSY; diff --git a/trunk/drivers/input/touchscreen/gunze.c b/trunk/drivers/input/touchscreen/gunze.c index b769b21973b7..466da190ceec 100644 --- a/trunk/drivers/input/touchscreen/gunze.c +++ b/trunk/drivers/input/touchscreen/gunze.c @@ -129,7 +129,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) gunze->serio = serio; gunze->dev = input_dev; - snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); + sprintf(gunze->phys, "%s/input0", serio->phys); input_dev->private = gunze; input_dev->name = "Gunze AHL-51S TouchScreen"; diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c index 2de2139f2fed..a18d56bdafd9 100644 --- a/trunk/drivers/input/touchscreen/h3600_ts_input.c +++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c @@ -363,7 +363,7 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) ts->serio = serio; ts->dev = input_dev; - snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys); + sprintf(ts->phys, "%s/input0", serio->phys); input_dev->name = "H3600 TouchScreen"; input_dev->phys = ts->phys; @@ -399,14 +399,16 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, - SA_SHIRQ | SA_INTERRUPT, "h3600_action", &ts->dev)) { + SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, + "h3600_action", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); err = -EBUSY; goto fail2; } if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, - SA_SHIRQ | SA_INTERRUPT, "h3600_suspend", &ts->dev)) { + SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, + "h3600_suspend", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); err = -EBUSY; goto fail3; diff --git a/trunk/drivers/input/touchscreen/mtouch.c b/trunk/drivers/input/touchscreen/mtouch.c index 8647a905df80..1d0d37eeef6e 100644 --- a/trunk/drivers/input/touchscreen/mtouch.c +++ b/trunk/drivers/input/touchscreen/mtouch.c @@ -143,7 +143,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) mtouch->serio = serio; mtouch->dev = input_dev; - snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); + sprintf(mtouch->phys, "%s/input0", serio->phys); input_dev->private = mtouch; input_dev->name = "MicroTouch Serial TouchScreen"; diff --git a/trunk/drivers/input/tsdev.c b/trunk/drivers/input/tsdev.c index 5f9ecad2ca75..d678d144bbf8 100644 --- a/trunk/drivers/input/tsdev.c +++ b/trunk/drivers/input/tsdev.c @@ -35,7 +35,7 @@ * e-mail - mail your message to . */ -#define TSDEV_MINOR_BASE 128 +#define TSDEV_MINOR_BASE 128 #define TSDEV_MINORS 32 /* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */ #define TSDEV_MINOR_MASK 15 @@ -230,7 +230,6 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, static unsigned int tsdev_poll(struct file *file, poll_table * wait) { struct tsdev_list *list = file->private_data; - poll_wait(file, &list->tsdev->wait, wait); return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); @@ -249,13 +248,11 @@ static int tsdev_ioctl(struct inode *inode, struct file *file, sizeof (struct ts_calibration))) retval = -EFAULT; break; - case TS_SET_CAL: if (copy_from_user (&tsdev->cal, (void __user *)arg, sizeof (struct ts_calibration))) retval = -EFAULT; break; - default: retval = -EINVAL; break; @@ -287,11 +284,9 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, case ABS_X: tsdev->x = value; break; - case ABS_Y: tsdev->y = value; break; - case ABS_PRESSURE: if (value > handle->dev->absmax[ABS_PRESSURE]) value = handle->dev->absmax[ABS_PRESSURE]; @@ -312,7 +307,6 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, else if (tsdev->x > xres) tsdev->x = xres; break; - case REL_Y: tsdev->y += value; if (tsdev->y < 0) @@ -329,7 +323,6 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, case 0: tsdev->pressure = 0; break; - case 1: if (!tsdev->pressure) tsdev->pressure = 1; @@ -377,8 +370,9 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, struct class_device *cdev; int minor, delta; - for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); - if (minor >= TSDEV_MINORS / 2) { + for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor]; + minor++); + if (minor >= TSDEV_MINORS/2) { printk(KERN_ERR "tsdev: You have way too many touchscreens\n"); return NULL; @@ -450,22 +444,22 @@ static struct input_device_id tsdev_ids[] = { .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, .relbit = { BIT(REL_X) | BIT(REL_Y) }, - }, /* A mouse like device, at least one button, two relative axes */ + },/* A mouse like device, at least one button, two relative axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, - }, /* A tablet like device, at least touch detection, two absolute axes */ + },/* A tablet like device, at least touch detection, two absolute axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .evbit = { BIT(EV_ABS) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) }, - }, /* A tablet like device with several gradations of pressure */ + },/* A tablet like device with several gradations of pressure */ - {} /* Terminating entry */ + {},/* Terminating entry */ }; MODULE_DEVICE_TABLE(input, tsdev_ids); diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 2e541fa02024..173c899a1fb4 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -87,11 +87,6 @@ struct capincci; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE struct capiminor; -struct datahandle_queue { - struct list_head list; - u16 datahandle; -}; - struct capiminor { struct list_head list; struct capincci *nccip; @@ -114,9 +109,12 @@ struct capiminor { int outbytes; /* transmit path */ - struct list_head ackqueue; + struct datahandle_queue { + struct datahandle_queue *next; + u16 datahandle; + } *ackqueue; int nack; - spinlock_t ackqlock; + }; #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ @@ -158,54 +156,48 @@ static LIST_HEAD(capiminor_list); static int capincci_add_ack(struct capiminor *mp, u16 datahandle) { - struct datahandle_queue *n; - unsigned long flags; + struct datahandle_queue *n, **pp; n = kmalloc(sizeof(*n), GFP_ATOMIC); - if (unlikely(!n)) { - printk(KERN_ERR "capi: alloc datahandle failed\n"); - return -1; + if (!n) { + printk(KERN_ERR "capi: alloc datahandle failed\n"); + return -1; } + n->next = NULL; n->datahandle = datahandle; - INIT_LIST_HEAD(&n->list); - spin_lock_irqsave(&mp->ackqlock, flags); - list_add_tail(&n->list, &mp->ackqueue); + for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) ; + *pp = n; mp->nack++; - spin_unlock_irqrestore(&mp->ackqlock, flags); return 0; } static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) { - struct datahandle_queue *p, *tmp; - unsigned long flags; + struct datahandle_queue **pp, *p; - spin_lock_irqsave(&mp->ackqlock, flags); - list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { - if (p->datahandle == datahandle) { - list_del(&p->list); + for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) { + if ((*pp)->datahandle == datahandle) { + p = *pp; + *pp = (*pp)->next; kfree(p); mp->nack--; - spin_unlock_irqrestore(&mp->ackqlock, flags); return 0; } } - spin_unlock_irqrestore(&mp->ackqlock, flags); return -1; } static void capiminor_del_all_ack(struct capiminor *mp) { - struct datahandle_queue *p, *tmp; - unsigned long flags; + struct datahandle_queue **pp, *p; - spin_lock_irqsave(&mp->ackqlock, flags); - list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { - list_del(&p->list); + pp = &mp->ackqueue; + while (*pp) { + p = *pp; + *pp = (*pp)->next; kfree(p); mp->nack--; } - spin_unlock_irqrestore(&mp->ackqlock, flags); } @@ -228,8 +220,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) mp->ncci = ncci; mp->msgid = 0; atomic_set(&mp->ttyopencount,0); - INIT_LIST_HEAD(&mp->ackqueue); - spin_lock_init(&mp->ackqlock); skb_queue_head_init(&mp->inqueue); skb_queue_head_init(&mp->outqueue); diff --git a/trunk/drivers/isdn/capi/capifs.c b/trunk/drivers/isdn/capi/capifs.c index 9ea6bd0ddc35..0a37aded4b54 100644 --- a/trunk/drivers/isdn/capi/capifs.c +++ b/trunk/drivers/isdn/capi/capifs.c @@ -121,10 +121,10 @@ capifs_fill_super(struct super_block *s, void *data, int silent) return -ENOMEM; } -static int capifs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +static struct super_block *capifs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) { - return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt); + return get_sb_single(fs_type, flags, data, capifs_fill_super); } static struct file_system_type capifs_fs_type = { diff --git a/trunk/drivers/isdn/divert/isdn_divert.c b/trunk/drivers/isdn/divert/isdn_divert.c index 1f5ebe9ee72c..f1a1f9a9b88e 100644 --- a/trunk/drivers/isdn/divert/isdn_divert.c +++ b/trunk/drivers/isdn/divert/isdn_divert.c @@ -592,7 +592,7 @@ static int put_address(char *st, u_char *p, int len) } /* put_address */ /*************************************/ -/* report a successful interrogation */ +/* report a succesfull interrogation */ /*************************************/ static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) { char *src = ic->parm.dss1_io.data; diff --git a/trunk/drivers/isdn/gigaset/bas-gigaset.c b/trunk/drivers/isdn/gigaset/bas-gigaset.c index 8a45715dd4c1..eb41aba3ddef 100644 --- a/trunk/drivers/isdn/gigaset/bas-gigaset.c +++ b/trunk/drivers/isdn/gigaset/bas-gigaset.c @@ -65,22 +65,23 @@ static struct usb_device_id gigaset_table [] = { MODULE_DEVICE_TABLE(usb, gigaset_table); -/*======================= local function prototypes ==========================*/ +/*======================= local function prototypes =============================*/ -/* function called if a new device belonging to this driver is connected */ +/* This function is called if a new device is connected to the USB port. It + * checks whether this new device belongs to this driver. + */ static int gigaset_probe(struct usb_interface *interface, const struct usb_device_id *id); /* Function will be called if the device is unplugged */ static void gigaset_disconnect(struct usb_interface *interface); -static int atread_submit(struct cardstate *, int); +static void read_ctrl_callback(struct urb *, struct pt_regs *); static void stopurbs(struct bas_bc_state *); -static int req_submit(struct bc_state *, int, int, int); static int atwrite_submit(struct cardstate *, unsigned char *, int); static int start_cbsend(struct cardstate *); -/*============================================================================*/ +/*==============================================================================*/ struct bas_cardstate { struct usb_device *udev; /* USB device pointer */ @@ -90,7 +91,6 @@ struct bas_cardstate { struct urb *urb_ctrl; /* control pipe default URB */ struct usb_ctrlrequest dr_ctrl; struct timer_list timer_ctrl; /* control request timeout */ - int retry_ctrl; struct timer_list timer_atrdy; /* AT command ready timeout */ struct urb *urb_cmd_out; /* for sending AT commands */ @@ -307,7 +307,6 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) * hang up any existing connection because of an unrecoverable error * This function may be called from any context and takes care of scheduling * the necessary actions for execution outside of interrupt context. - * cs->lock must not be held. * argument: * B channel control structure */ @@ -326,17 +325,14 @@ static inline void error_hangup(struct bc_state *bcs) /* error_reset * reset Gigaset device because of an unrecoverable error - * This function may be called from any context, and takes care of + * This function may be called from any context, and should take care of * scheduling the necessary actions for execution outside of interrupt context. - * cs->lock must not be held. + * Right now, it just generates a kernel message calling for help. * argument: * controller state structure */ static inline void error_reset(struct cardstate *cs) { - /* close AT command channel to recover (ignore errors) */ - req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); - //FIXME try to recover without bothering the user dev_err(cs->dev, "unrecoverable error - please disconnect Gigaset base to reset\n"); @@ -407,30 +403,14 @@ static void cmd_in_timeout(unsigned long data) { struct cardstate *cs = (struct cardstate *) data; struct bas_cardstate *ucs = cs->hw.bas; - int rc; if (!ucs->rcvbuf_size) { gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); return; } - if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: timeout, retry %d\n", - ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - } else { - dev_err(cs->dev, - "control read: timeout, giving up after %d tries\n", - ucs->retry_cmd_in); - } - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - error_reset(cs); + dev_err(cs->dev, "timeout reading AT response\n"); + error_reset(cs); //FIXME retry? } /* set/clear bits in base connection state, return previous state @@ -448,96 +428,6 @@ inline static int update_basstate(struct bas_cardstate *ucs, return state; } -/* read_ctrl_callback - * USB completion handler for control pipe input - * called by the USB subsystem in interrupt context - * parameter: - * urb USB request block - * urb->context = inbuf structure for controller state - */ -static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) -{ - struct inbuf_t *inbuf = urb->context; - struct cardstate *cs = inbuf->cs; - struct bas_cardstate *ucs = cs->hw.bas; - int have_data = 0; - unsigned numbytes; - int rc; - - update_basstate(ucs, 0, BS_ATRDPEND); - - if (!ucs->rcvbuf_size) { - dev_warn(cs->dev, "%s: no receive in progress\n", __func__); - return; - } - - del_timer(&ucs->timer_cmd_in); - - switch (urb->status) { - case 0: /* normal completion */ - numbytes = urb->actual_length; - if (unlikely(numbytes != ucs->rcvbuf_size)) { - dev_warn(cs->dev, - "control read: received %d chars, expected %d\n", - numbytes, ucs->rcvbuf_size); - if (numbytes > ucs->rcvbuf_size) - numbytes = ucs->rcvbuf_size; - } - - /* copy received bytes to inbuf */ - have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); - - if (unlikely(numbytes < ucs->rcvbuf_size)) { - /* incomplete - resubmit for remaining bytes */ - ucs->rcvbuf_size -= numbytes; - ucs->retry_cmd_in = 0; - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - error_reset(cs); - } - break; - - case -ENOENT: /* cancelled */ - case -ECONNRESET: /* cancelled (async) */ - case -EINPROGRESS: /* pending */ - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - /* no action necessary */ - gig_dbg(DEBUG_USBREQ, "%s: %s", - __func__, get_usb_statmsg(urb->status)); - break; - - default: /* severe trouble */ - dev_warn(cs->dev, "control read: %s\n", - get_usb_statmsg(urb->status)); - if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: retry %d\n", - ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - } else { - dev_err(cs->dev, - "control read: giving up after %d tries\n", - ucs->retry_cmd_in); - } - error_reset(cs); - } - - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - if (have_data) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(cs); - } -} - /* atread_submit * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout * parameters: @@ -576,7 +466,7 @@ static int atread_submit(struct cardstate *cs, int timeout) if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { update_basstate(ucs, 0, BS_ATRDPEND); dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", - get_usb_rcmsg(ret)); + get_usb_statmsg(ret)); return ret; } @@ -721,12 +611,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; - if (rc != -ENODEV) { + if (rc != -ENODEV) //FIXME corrective action? - spin_unlock_irqrestore(&cs->lock, flags); error_reset(cs); - break; - } } spin_unlock_irqrestore(&cs->lock, flags); break; @@ -756,6 +643,97 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) } } +/* read_ctrl_callback + * USB completion handler for control pipe input + * called by the USB subsystem in interrupt context + * parameter: + * urb USB request block + * urb->context = inbuf structure for controller state + */ +static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) +{ + struct inbuf_t *inbuf = urb->context; + struct cardstate *cs = inbuf->cs; + struct bas_cardstate *ucs = cs->hw.bas; + int have_data = 0; + unsigned numbytes; + int rc; + + update_basstate(ucs, 0, BS_ATRDPEND); + + if (!ucs->rcvbuf_size) { + dev_warn(cs->dev, "%s: no receive in progress\n", __func__); + return; + } + + del_timer(&ucs->timer_cmd_in); + + switch (urb->status) { + case 0: /* normal completion */ + numbytes = urb->actual_length; + if (unlikely(numbytes == 0)) { + dev_warn(cs->dev, + "control read: empty block received\n"); + goto retry; + } + if (unlikely(numbytes != ucs->rcvbuf_size)) { + dev_warn(cs->dev, + "control read: received %d chars, expected %d\n", + numbytes, ucs->rcvbuf_size); + if (numbytes > ucs->rcvbuf_size) + numbytes = ucs->rcvbuf_size; + } + + /* copy received bytes to inbuf */ + have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); + + if (unlikely(numbytes < ucs->rcvbuf_size)) { + /* incomplete - resubmit for remaining bytes */ + ucs->rcvbuf_size -= numbytes; + ucs->retry_cmd_in = 0; + goto retry; + } + break; + + case -ENOENT: /* cancelled */ + case -ECONNRESET: /* cancelled (async) */ + case -EINPROGRESS: /* pending */ + case -ENODEV: /* device removed */ + case -ESHUTDOWN: /* device shut down */ + /* no action necessary */ + gig_dbg(DEBUG_USBREQ, "%s: %s", + __func__, get_usb_statmsg(urb->status)); + break; + + default: /* severe trouble */ + dev_warn(cs->dev, "control read: %s\n", + get_usb_statmsg(urb->status)); + retry: + if (ucs->retry_cmd_in++ < BAS_RETRY) { + dev_notice(cs->dev, "control read: retry %d\n", + ucs->retry_cmd_in); + rc = atread_submit(cs, BAS_TIMEOUT); + if (rc >= 0 || rc == -ENODEV) + /* resubmitted or disconnected */ + /* - bypass regular exit block */ + return; + } else { + dev_err(cs->dev, + "control read: giving up after %d tries\n", + ucs->retry_cmd_in); + } + error_reset(cs); + } + + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + if (have_data) { + gig_dbg(DEBUG_INTR, "%s-->BH", __func__); + gigaset_schedule_event(cs); + } +} + /* read_iso_callback * USB completion handler for B channel isochronous input * called by the USB subsystem in interrupt context @@ -1400,7 +1378,6 @@ static void req_timeout(unsigned long data) case HD_CLOSE_B1CHANNEL: dev_err(bcs->cs->dev, "timeout closing channel %d\n", bcs->channel + 1); - error_reset(bcs->cs); break; default: @@ -1419,61 +1396,22 @@ static void req_timeout(unsigned long data) static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) { struct bas_cardstate *ucs = urb->context; - int rc; unsigned long flags; - /* check status */ - switch (urb->status) { - case 0: /* normal completion */ - spin_lock_irqsave(&ucs->lock, flags); - switch (ucs->pending) { - case HD_DEVICE_INIT_ACK: /* no reply expected */ - del_timer(&ucs->timer_ctrl); - ucs->pending = 0; - break; - } - spin_unlock_irqrestore(&ucs->lock, flags); - return; - - case -ENOENT: /* cancelled */ - case -ECONNRESET: /* cancelled (async) */ - case -EINPROGRESS: /* pending */ - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - /* ignore silently */ - gig_dbg(DEBUG_USBREQ, "%s: %s", - __func__, get_usb_statmsg(urb->status)); + spin_lock_irqsave(&ucs->lock, flags); + if (urb->status && ucs->pending) { + dev_err(&ucs->interface->dev, + "control request 0x%02x failed: %s\n", + ucs->pending, get_usb_statmsg(urb->status)); + del_timer(&ucs->timer_ctrl); + ucs->pending = 0; + } + /* individual handling of specific request types */ + switch (ucs->pending) { + case HD_DEVICE_INIT_ACK: /* no reply expected */ + ucs->pending = 0; break; - - default: /* any failure */ - if (++ucs->retry_ctrl > BAS_RETRY) { - dev_err(&ucs->interface->dev, - "control request 0x%02x failed: %s\n", - ucs->dr_ctrl.bRequest, - get_usb_statmsg(urb->status)); - break; /* give up */ - } - dev_notice(&ucs->interface->dev, - "control request 0x%02x: %s, retry %d\n", - ucs->dr_ctrl.bRequest, get_usb_statmsg(urb->status), - ucs->retry_ctrl); - /* urb->dev is clobbered by USB subsystem */ - urb->dev = ucs->udev; - rc = usb_submit_urb(urb, SLAB_ATOMIC); - if (unlikely(rc)) { - dev_err(&ucs->interface->dev, - "could not resubmit request 0x%02x: %s\n", - ucs->dr_ctrl.bRequest, get_usb_rcmsg(rc)); - break; - } - /* resubmitted */ - return; } - - /* failed, clear pending request */ - spin_lock_irqsave(&ucs->lock, flags); - del_timer(&ucs->timer_ctrl); - ucs->pending = 0; spin_unlock_irqrestore(&ucs->lock, flags); } @@ -1517,11 +1455,9 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) usb_sndctrlpipe(ucs->udev, 0), (unsigned char*) &ucs->dr_ctrl, NULL, 0, write_ctrl_callback, ucs); - ucs->retry_ctrl = 0; - ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC); - if (unlikely(ret)) { + if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", - req, get_usb_rcmsg(ret)); + req, get_usb_statmsg(ret)); spin_unlock_irqrestore(&ucs->lock, flags); return ret; } diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index 2a56bf33a673..e55767b2ccd3 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -460,9 +460,6 @@ void gigaset_freecs(struct cardstate *cs) switch (cs->cs_init) { default: - /* clear device sysfs */ - gigaset_free_dev_sysfs(cs); - gigaset_if_free(cs); gig_dbg(DEBUG_INIT, "clearing hw"); @@ -702,7 +699,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->open_count = 0; cs->dev = NULL; cs->tty = NULL; - cs->class = NULL; cs->cidmode = cidmode != 0; //if(onechannel) { //FIXME @@ -764,9 +760,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, gigaset_if_init(cs); - /* set up device sysfs */ - gigaset_init_dev_sysfs(cs); - spin_lock_irqsave(&cs->lock, flags); cs->running = 1; spin_unlock_irqrestore(&cs->lock, flags); @@ -909,6 +902,9 @@ int gigaset_start(struct cardstate *cs) wait_event(cs->waitqueue, !cs->waiting); + /* set up device sysfs */ + gigaset_init_dev_sysfs(cs); + mutex_unlock(&cs->mutex); return 1; @@ -973,6 +969,9 @@ void gigaset_stop(struct cardstate *cs) //FIXME } + /* clear device sysfs */ + gigaset_free_dev_sysfs(cs); + cleanup_cs(cs); exit: @@ -981,7 +980,7 @@ void gigaset_stop(struct cardstate *cs) EXPORT_SYMBOL_GPL(gigaset_stop); static LIST_HEAD(drivers); -static DEFINE_SPINLOCK(driver_lock); +static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; struct cardstate *gigaset_get_cs_by_id(int id) { diff --git a/trunk/drivers/isdn/gigaset/ev-layer.c b/trunk/drivers/isdn/gigaset/ev-layer.c index 44f02dbd1111..18e05c09b71c 100644 --- a/trunk/drivers/isdn/gigaset/ev-layer.c +++ b/trunk/drivers/isdn/gigaset/ev-layer.c @@ -1262,8 +1262,7 @@ static void do_action(int action, struct cardstate *cs, break; case ACT_HUPMODEM: /* send "+++" (hangup in unimodem mode) */ - if (cs->connected) - cs->ops->write_cmd(cs, "+++", 3, NULL); + cs->ops->write_cmd(cs, "+++", 3, NULL); break; case ACT_RING: /* get fresh AT state structure for new CID */ @@ -1295,6 +1294,7 @@ static void do_action(int action, struct cardstate *cs, break; case ACT_ICALL: handle_icall(cs, bcs, p_at_state); + at_state = *p_at_state; break; case ACT_FAILSDOWN: dev_warn(cs->dev, "Could not shut down the device.\n"); @@ -1334,8 +1334,10 @@ static void do_action(int action, struct cardstate *cs, */ at_state->pending_commands |= PC_DLE0; atomic_set(&cs->commands_pending, 1); - } else + } else { disconnect(p_at_state); + at_state = *p_at_state; + } break; case ACT_FAKEDLE0: at_state->int_var[VAR_ZDLE] = 0; @@ -1352,8 +1354,10 @@ static void do_action(int action, struct cardstate *cs, at_state->cid = -1; if (bcs && cs->onechannel) at_state->pending_commands |= PC_DLE0; - else + else { disconnect(p_at_state); + at_state = *p_at_state; + } schedule_init(cs, MS_RECOVER); break; case ACT_FAILDLE0: @@ -1406,6 +1410,7 @@ static void do_action(int action, struct cardstate *cs, case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL processing */ disconnect(p_at_state); + at_state = *p_at_state; break; case ACT_ABORTDIAL: /* error/timeout during dial preparation */ diff --git a/trunk/drivers/isdn/gigaset/gigaset.h b/trunk/drivers/isdn/gigaset/gigaset.h index 8d63d822104f..22b9693f7c0a 100644 --- a/trunk/drivers/isdn/gigaset/gigaset.h +++ b/trunk/drivers/isdn/gigaset/gigaset.h @@ -445,7 +445,6 @@ struct cardstate { struct gigaset_driver *driver; unsigned minor_index; struct device *dev; - struct class_device *class; const struct gigaset_ops *ops; diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index 74fd234956c8..08e4c4eea14d 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/drivers/isdn/gigaset/interface.c @@ -625,14 +625,7 @@ void gigaset_if_init(struct cardstate *cs) return; tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); - cs->class = tty_register_device(drv->tty, cs->minor_index, NULL); - - if (!IS_ERR(cs->class)) - class_set_devdata(cs->class, cs); - else { - warn("could not register device to the tty subsystem"); - cs->class = NULL; - } + tty_register_device(drv->tty, cs->minor_index, NULL); } void gigaset_if_free(struct cardstate *cs) @@ -645,7 +638,6 @@ void gigaset_if_free(struct cardstate *cs) tasklet_disable(&cs->if_wake_tasklet); tasklet_kill(&cs->if_wake_tasklet); - cs->class = NULL; tty_unregister_device(drv->tty, cs->minor_index); } diff --git a/trunk/drivers/isdn/gigaset/proc.c b/trunk/drivers/isdn/gigaset/proc.c index 9ae3a7f3e7b3..d267a636b53c 100644 --- a/trunk/drivers/isdn/gigaset/proc.c +++ b/trunk/drivers/isdn/gigaset/proc.c @@ -16,11 +16,12 @@ #include "gigaset.h" #include -static ssize_t show_cidmode(struct class_device *class, char *buf) +static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, + char *buf) { int ret; unsigned long flags; - struct cardstate *cs = class_get_devdata(class); + struct cardstate *cs = dev_get_drvdata(dev); spin_lock_irqsave(&cs->lock, flags); ret = sprintf(buf, "%u\n", cs->cidmode); @@ -29,10 +30,10 @@ static ssize_t show_cidmode(struct class_device *class, char *buf) return ret; } -static ssize_t set_cidmode(struct class_device *class, +static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct cardstate *cs = class_get_devdata(class); + struct cardstate *cs = dev_get_drvdata(dev); long int value; char *end; @@ -64,24 +65,18 @@ static ssize_t set_cidmode(struct class_device *class, return count; } -static CLASS_DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); +static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); /* free sysfs for device */ void gigaset_free_dev_sysfs(struct cardstate *cs) { - if (!cs->class) - return; - gig_dbg(DEBUG_INIT, "removing sysfs entries"); - class_device_remove_file(cs->class, &class_device_attr_cidmode); + device_remove_file(cs->dev, &dev_attr_cidmode); } /* initialize sysfs for device */ void gigaset_init_dev_sysfs(struct cardstate *cs) { - if (!cs->class) - return; - gig_dbg(DEBUG_INIT, "setting up sysfs"); - class_device_create_file(cs->class, &class_device_attr_cidmode); + device_create_file(cs->dev, &dev_attr_cidmode); } diff --git a/trunk/drivers/isdn/hisax/q931.c b/trunk/drivers/isdn/hisax/q931.c index aacbf0d14b64..abecabf8c271 100644 --- a/trunk/drivers/isdn/hisax/q931.c +++ b/trunk/drivers/isdn/hisax/q931.c @@ -1402,12 +1402,12 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) } /* No, locate it in the table */ if (cset == 0) { - for (i = 0; i < IESIZE_NI1; i++) + for (i = 0; i < IESIZE; i++) if (*buf == ielist_ni1[i].nr) break; /* When not found, give appropriate msg */ - if (i != IESIZE_NI1) { + if (i != IESIZE) { dp += sprintf(dp, " %s\n", ielist_ni1[i].descr); dp += ielist_ni1[i].f(dp, buf); } else diff --git a/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index b26e509ec759..22759c01746a 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/drivers/isdn/i4l/isdn_common.c @@ -933,7 +933,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) count_put = count_pull; if(count_put > 1) tty_insert_flip_string(tty, skb->data, count_put - 1); - last = skb->data[count_put - 1]; + last = skb->data[count_put] - 1; len -= count_put; #ifdef CONFIG_ISDN_AUDIO } @@ -1177,8 +1177,9 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off goto out; } chidx = isdn_minor2chan(minor); - while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) + while (isdn_writebuf_stub(drvidx, chidx, buf, count) != count) interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); + retval = count; goto out; } if (minor <= ISDN_MINOR_CTRLMAX) { @@ -1950,10 +1951,9 @@ isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len) struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC); if (!skb) - return -ENOMEM; + return 0; skb_reserve(skb, hl); - if (copy_from_user(skb_put(skb, len), buf, len)) - return -EFAULT; + copy_from_user(skb_put(skb, len), buf, len); ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); if (ret <= 0) dev_kfree_skb(skb); diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index 433389daedb2..2ac90242d263 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -82,7 +82,7 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) int l = skb->len; unsigned char *dp = skb->data; while (--l) { - if (*dp == DLE) + if (*skb->data == DLE) tty_insert_flip_char(tty, DLE, 0); tty_insert_flip_char(tty, *dp++, 0); } diff --git a/trunk/drivers/isdn/sc/ioctl.c b/trunk/drivers/isdn/sc/ioctl.c index 57c4ab96d136..f4f71226a078 100644 --- a/trunk/drivers/isdn/sc/ioctl.c +++ b/trunk/drivers/isdn/sc/ioctl.c @@ -97,7 +97,6 @@ int sc_ioctl(int card, scs_ioctl *data) case SCIOCSTART: { - kfree(rcvmsg); pr_debug("%s: SCIOSTART: ioctl received\n", sc_adapter[card]->devicename); if(sc_adapter[card]->EngineUp) { diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 96509989e921..626506234b76 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -63,12 +63,6 @@ config LEDS_S3C24XX This option enables support for LEDs connected to GPIO lines on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. -config LEDS_AMS_DELTA - tristate "LED Support for the Amstrad Delta (E3)" - depends LEDS_CLASS && MACH_AMS_DELTA - help - This option enables support for the LEDs on Amstrad Delta (E3). - comment "LED Triggers" config LEDS_TRIGGERS @@ -93,14 +87,5 @@ config LEDS_TRIGGER_IDE_DISK This allows LEDs to be controlled by IDE disk activity. If unsure, say Y. -config LEDS_TRIGGER_HEARTBEAT - tristate "LED Heartbeat Trigger" - depends LEDS_TRIGGERS - help - This allows LEDs to be controlled by a CPU load average. - The flash frequency is a hyperbolic function of the 1-minute - load average. - If unsure, say Y. - endmenu diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index 88d3b6eaa6a2..40f042633bf5 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -11,9 +11,7 @@ obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o -obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o -obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o diff --git a/trunk/drivers/leds/led-core.c b/trunk/drivers/leds/led-core.c index 9b015f9af351..fe6541326c71 100644 --- a/trunk/drivers/leds/led-core.c +++ b/trunk/drivers/leds/led-core.c @@ -18,7 +18,7 @@ #include #include "leds.h" -DEFINE_RWLOCK(leds_list_lock); +rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); diff --git a/trunk/drivers/leds/led-triggers.c b/trunk/drivers/leds/led-triggers.c index 1b1ce6523960..5e2cd8be1191 100644 --- a/trunk/drivers/leds/led-triggers.c +++ b/trunk/drivers/leds/led-triggers.c @@ -26,7 +26,7 @@ /* * Nests outside led_cdev->trigger_lock */ -static DEFINE_RWLOCK(triggers_list_lock); +static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; static LIST_HEAD(trigger_list); ssize_t led_trigger_store(struct class_device *dev, const char *buf, diff --git a/trunk/drivers/leds/leds-ams-delta.c b/trunk/drivers/leds/leds-ams-delta.c deleted file mode 100644 index e9f06116c4d7..000000000000 --- a/trunk/drivers/leds/leds-ams-delta.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * LEDs driver for Amstrad Delta (E3) - * - * Copyright (C) 2006 Jonathan McDowell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Our context - */ -struct ams_delta_led { - struct led_classdev cdev; - u8 bitmask; -}; - -static void ams_delta_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct ams_delta_led *led_dev = - container_of(led_cdev, struct ams_delta_led, cdev); - - if (value) - ams_delta_latch1_write(led_dev->bitmask, led_dev->bitmask); - else - ams_delta_latch1_write(led_dev->bitmask, 0); -} - -static struct ams_delta_led ams_delta_leds[] = { - { - .cdev = { - .name = "ams-delta:camera", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_CAMERA, - }, - { - .cdev = { - .name = "ams-delta:advert", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_ADVERT, - }, - { - .cdev = { - .name = "ams-delta:email", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_EMAIL, - }, - { - .cdev = { - .name = "ams-delta:handsfree", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_HANDSFREE, - }, - { - .cdev = { - .name = "ams-delta:voicemail", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_VOICEMAIL, - }, - { - .cdev = { - .name = "ams-delta:voice", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_VOICE, - }, -}; - -#ifdef CONFIG_PM -static int ams_delta_led_suspend(struct platform_device *dev, - pm_message_t state) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) - led_classdev_suspend(&ams_delta_leds[i].cdev); - - return 0; -} - -static int ams_delta_led_resume(struct platform_device *dev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) - led_classdev_resume(&ams_delta_leds[i].cdev); - - return 0; -} -#else -#define ams_delta_led_suspend NULL -#define ams_delta_led_resume NULL -#endif - -static int ams_delta_led_probe(struct platform_device *pdev) -{ - int i; - int ret; - - for (i = ret = 0; ret >= 0 && i < ARRAY_SIZE(ams_delta_leds); i++) { - ret = led_classdev_register(&pdev->dev, - &ams_delta_leds[i].cdev); - } - - if (ret < 0 && i > 1) { - for (i = i - 2; i >= 0; i--) - led_classdev_unregister(&ams_delta_leds[i].cdev); - } - - return ret; -} - -static int ams_delta_led_remove(struct platform_device *pdev) -{ - int i; - - for (i = ARRAY_SIZE(ams_delta_leds) - 1; i >= 0; i--) - led_classdev_unregister(&ams_delta_leds[i].cdev); - - return 0; -} - -static struct platform_driver ams_delta_led_driver = { - .probe = ams_delta_led_probe, - .remove = ams_delta_led_remove, - .suspend = ams_delta_led_suspend, - .resume = ams_delta_led_resume, - .driver = { - .name = "ams-delta-led", - }, -}; - -static int __init ams_delta_led_init(void) -{ - return platform_driver_register(&ams_delta_led_driver); -} - -static void __exit ams_delta_led_exit(void) -{ - return platform_driver_unregister(&ams_delta_led_driver); -} - -module_init(ams_delta_led_init); -module_exit(ams_delta_led_exit); - -MODULE_AUTHOR("Jonathan McDowell "); -MODULE_DESCRIPTION("Amstrad Delta LED driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/ledtrig-heartbeat.c b/trunk/drivers/leds/ledtrig-heartbeat.c deleted file mode 100644 index 4bf8cec8b8c1..000000000000 --- a/trunk/drivers/leds/ledtrig-heartbeat.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * LED Heartbeat Trigger - * - * Copyright (C) 2006 Atsushi Nemoto - * - * Based on Richard Purdie's ledtrig-timer.c and some arch's - * CONFIG_HEARTBEAT code. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include "leds.h" - -struct heartbeat_trig_data { - unsigned int phase; - unsigned int period; - struct timer_list timer; -}; - -static void led_heartbeat_function(unsigned long data) -{ - struct led_classdev *led_cdev = (struct led_classdev *) data; - struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; - unsigned long brightness = LED_OFF; - unsigned long delay = 0; - - /* acts like an actual heart beat -- ie thump-thump-pause... */ - switch (heartbeat_data->phase) { - case 0: - /* - * The hyperbolic function below modifies the - * heartbeat period length in dependency of the - * current (1min) load. It goes through the points - * f(0)=1260, f(1)=860, f(5)=510, f(inf)->300. - */ - heartbeat_data->period = 300 + - (6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT)); - heartbeat_data->period = - msecs_to_jiffies(heartbeat_data->period); - delay = msecs_to_jiffies(70); - heartbeat_data->phase++; - brightness = LED_FULL; - break; - case 1: - delay = heartbeat_data->period / 4 - msecs_to_jiffies(70); - heartbeat_data->phase++; - break; - case 2: - delay = msecs_to_jiffies(70); - heartbeat_data->phase++; - brightness = LED_FULL; - break; - default: - delay = heartbeat_data->period - heartbeat_data->period / 4 - - msecs_to_jiffies(70); - heartbeat_data->phase = 0; - break; - } - - led_set_brightness(led_cdev, brightness); - mod_timer(&heartbeat_data->timer, jiffies + delay); -} - -static void heartbeat_trig_activate(struct led_classdev *led_cdev) -{ - struct heartbeat_trig_data *heartbeat_data; - - heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); - if (!heartbeat_data) - return; - - led_cdev->trigger_data = heartbeat_data; - setup_timer(&heartbeat_data->timer, - led_heartbeat_function, (unsigned long) led_cdev); - heartbeat_data->phase = 0; - led_heartbeat_function(heartbeat_data->timer.data); -} - -static void heartbeat_trig_deactivate(struct led_classdev *led_cdev) -{ - struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; - - if (heartbeat_data) { - del_timer_sync(&heartbeat_data->timer); - kfree(heartbeat_data); - } -} - -static struct led_trigger heartbeat_led_trigger = { - .name = "heartbeat", - .activate = heartbeat_trig_activate, - .deactivate = heartbeat_trig_deactivate, -}; - -static int __init heartbeat_trig_init(void) -{ - return led_trigger_register(&heartbeat_led_trigger); -} - -static void __exit heartbeat_trig_exit(void) -{ - led_trigger_unregister(&heartbeat_led_trigger); -} - -module_init(heartbeat_trig_init); -module_exit(heartbeat_trig_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Heartbeat LED trigger"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index 37cd6ee4586b..12ad462737ba 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -99,22 +99,17 @@ config PMAC_MEDIABAY devices are not fully supported in the bay as I never had one to try with +# made a separate option since backlight may end up beeing used +# on non-powerbook machines (but only on PMU based ones AFAIK) config PMAC_BACKLIGHT bool "Backlight control for LCD screens" depends on ADB_PMU && (BROKEN || !PPC64) help - Say Y here to enable Macintosh specific extensions of the generic - backlight code. With this enabled, the brightness keys on older - PowerBooks will be enabled so you can change the screen brightness. - Newer models should use an userspace daemon like pbbuttonsd. - -config PMAC_BACKLIGHT_LEGACY - bool "Provide legacy ioctl's on /dev/pmu for the backlight" - depends on PMAC_BACKLIGHT && (BROKEN || !PPC64) - help - Say Y if you want to enable legacy ioctl's on /dev/pmu. This is for - programs which use this old interface. New and updated programs - should use the backlight classes in sysfs. + Say Y here to build in code to manage the LCD backlight on a + Macintosh PowerBook. With this code, the backlight will be turned + on and off appropriately on power-management and lid-open/lid-closed + events; also, the PowerBook button device will be enabled so you can + change the screen brightness. config ADB_MACIO bool "Include MacIO (CHRP) ADB driver" @@ -176,7 +171,6 @@ config THERM_PM72 config WINDFARM tristate "New PowerMac thermal control infrastructure" - depends on PPC config WINDFARM_PM81 tristate "Support for thermal management on iMac G5" diff --git a/trunk/drivers/macintosh/Makefile b/trunk/drivers/macintosh/Makefile index 45a268f8047e..6081acdea404 100644 --- a/trunk/drivers/macintosh/Makefile +++ b/trunk/drivers/macintosh/Makefile @@ -11,8 +11,7 @@ obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o obj-$(CONFIG_INPUT_ADBHID) += adbhid.o obj-$(CONFIG_ANSLCD) += ans-lcd.o -obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o -obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o +obj-$(CONFIG_ADB_PMU) += via-pmu.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o obj-$(CONFIG_PMAC_SMU) += smu.o diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index cbfbbe2b150a..394334ec5765 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -179,7 +179,7 @@ u8 adb_to_linux_keycodes[128] = { /* 0x65 */ KEY_F9, /* 67 */ /* 0x66 */ KEY_HANJA, /* 123 */ /* 0x67 */ KEY_F11, /* 87 */ - /* 0x68 */ KEY_HANGEUL, /* 122 */ + /* 0x68 */ KEY_HANGUEL, /* 122 */ /* 0x69 */ KEY_SYSRQ, /* 99 */ /* 0x6a */ 0, /* 0x6b */ KEY_SCROLLLOCK, /* 70 */ @@ -503,7 +503,9 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto case 0x1f: /* Powerbook button device */ { int down = (data[1] == (data[1] & 0xf)); - +#ifdef CONFIG_PMAC_BACKLIGHT + int backlight = get_backlight_level(); +#endif /* * XXX: Where is the contrast control for the passive? * -- Cort @@ -528,17 +530,29 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto case 0xa: /* brightness decrease */ #ifdef CONFIG_PMAC_BACKLIGHT - if (!disable_kernel_backlight && down) - pmac_backlight_key_down(); -#endif + if (!disable_kernel_backlight) { + if (down && backlight >= 0) { + if (backlight > BACKLIGHT_OFF) + set_backlight_level(backlight-1); + else + set_backlight_level(BACKLIGHT_OFF); + } + } +#endif /* CONFIG_PMAC_BACKLIGHT */ input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); break; case 0x9: /* brightness increase */ #ifdef CONFIG_PMAC_BACKLIGHT - if (!disable_kernel_backlight && down) - pmac_backlight_key_up(); -#endif + if (!disable_kernel_backlight) { + if (down && backlight >= 0) { + if (backlight < BACKLIGHT_MAX) + set_backlight_level(backlight+1); + else + set_backlight_level(BACKLIGHT_MAX); + } + } +#endif /* CONFIG_PMAC_BACKLIGHT */ input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); break; diff --git a/trunk/drivers/macintosh/via-pmu-backlight.c b/trunk/drivers/macintosh/via-pmu-backlight.c deleted file mode 100644 index b42d05f2aaff..000000000000 --- a/trunk/drivers/macintosh/via-pmu-backlight.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Backlight code for via-pmu - * - * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. - * Copyright (C) 2001-2002 Benjamin Herrenschmidt - * Copyright (C) 2006 Michael Hanselmann - * - */ - -#include -#include -#include -#include -#include - -#define MAX_PMU_LEVEL 0xFF - -static struct device_node *vias; -static struct backlight_properties pmu_backlight_data; - -static int pmu_backlight_get_level_brightness(struct fb_info *info, - int level) -{ - int pmulevel; - - /* Get and convert the value */ - mutex_lock(&info->bl_mutex); - pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL; - mutex_unlock(&info->bl_mutex); - - if (pmulevel < 0) - pmulevel = 0; - else if (pmulevel > MAX_PMU_LEVEL) - pmulevel = MAX_PMU_LEVEL; - - return pmulevel; -} - -static int pmu_backlight_update_status(struct backlight_device *bd) -{ - struct fb_info *info = class_get_devdata(&bd->class_dev); - struct adb_request req; - int pmulevel, level = bd->props->brightness; - - if (vias == NULL) - return -ENODEV; - - if (bd->props->power != FB_BLANK_UNBLANK || - bd->props->fb_blank != FB_BLANK_UNBLANK) - level = 0; - - pmulevel = pmu_backlight_get_level_brightness(info, level); - - pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); - pmu_wait_complete(&req); - - pmu_request(&req, NULL, 2, PMU_POWER_CTRL, - PMU_POW_BACKLIGHT | (level > 0 ? PMU_POW_ON : PMU_POW_OFF)); - pmu_wait_complete(&req); - - return 0; -} - -static int pmu_backlight_get_brightness(struct backlight_device *bd) -{ - return bd->props->brightness; -} - -static struct backlight_properties pmu_backlight_data = { - .owner = THIS_MODULE, - .get_brightness = pmu_backlight_get_brightness, - .update_status = pmu_backlight_update_status, - .max_brightness = (FB_BACKLIGHT_LEVELS - 1), -}; - -void __init pmu_backlight_init(struct device_node *in_vias) -{ - struct backlight_device *bd; - struct fb_info *info; - char name[10]; - int level, autosave; - - vias = in_vias; - - /* Special case for the old PowerBook since I can't test on it */ - autosave = - machine_is_compatible("AAPL,3400/2400") || - machine_is_compatible("AAPL,3500"); - - if (!autosave && - !pmac_has_backlight_type("pmu") && - !machine_is_compatible("AAPL,PowerBook1998") && - !machine_is_compatible("PowerBook1,1")) - return; - - /* Actually, this is a hack, but I don't know of a better way - * to get the first framebuffer device. - */ - info = registered_fb[0]; - if (!info) { - printk("pmubl: No framebuffer found\n"); - goto error; - } - - snprintf(name, sizeof(name), "pmubl%d", info->node); - - bd = backlight_device_register(name, info, &pmu_backlight_data); - if (IS_ERR(bd)) { - printk("pmubl: Backlight registration failed\n"); - goto error; - } - - mutex_lock(&info->bl_mutex); - info->bl_dev = bd; - fb_bl_default_curve(info, 0x7F, 0x46, 0x0E); - mutex_unlock(&info->bl_mutex); - - level = pmu_backlight_data.max_brightness; - - if (autosave) { - /* read autosaved value if available */ - struct adb_request req; - pmu_request(&req, NULL, 2, 0xd9, 0); - pmu_wait_complete(&req); - - mutex_lock(&info->bl_mutex); - level = pmac_backlight_curve_lookup(info, - (req.reply[0] >> 4) * - pmu_backlight_data.max_brightness / 15); - mutex_unlock(&info->bl_mutex); - } - - up(&bd->sem); - bd->props->brightness = level; - bd->props->power = FB_BLANK_UNBLANK; - bd->props->update_status(bd); - down(&bd->sem); - - mutex_lock(&pmac_backlight_mutex); - if (!pmac_backlight) - pmac_backlight = bd; - mutex_unlock(&pmac_backlight_mutex); - - printk("pmubl: Backlight initialized (%s)\n", name); - - return; - -error: - return; -} diff --git a/trunk/drivers/macintosh/via-pmu-event.c b/trunk/drivers/macintosh/via-pmu-event.c deleted file mode 100644 index 25cd56542328..000000000000 --- a/trunk/drivers/macintosh/via-pmu-event.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * via-pmu event device for reporting some events that come through the PMU - * - * Copyright 2006 Johannes Berg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include -#include -#include "via-pmu-event.h" - -static struct input_dev *pmu_input_dev; - -static int __init via_pmu_event_init(void) -{ - int err; - - /* do other models report button/lid status? */ - if (pmu_get_model() != PMU_KEYLARGO_BASED) - return -ENODEV; - - pmu_input_dev = input_allocate_device(); - if (!pmu_input_dev) - return -ENOMEM; - - pmu_input_dev->name = "PMU"; - pmu_input_dev->id.bustype = BUS_HOST; - pmu_input_dev->id.vendor = 0x0001; - pmu_input_dev->id.product = 0x0001; - pmu_input_dev->id.version = 0x0100; - - set_bit(EV_KEY, pmu_input_dev->evbit); - set_bit(EV_SW, pmu_input_dev->evbit); - set_bit(KEY_POWER, pmu_input_dev->keybit); - set_bit(SW_LID, pmu_input_dev->swbit); - - err = input_register_device(pmu_input_dev); - if (err) - input_free_device(pmu_input_dev); - return err; -} - -void via_pmu_event(int key, int down) -{ - - if (unlikely(!pmu_input_dev)) - return; - - switch (key) { - case PMU_EVT_POWER: - input_report_key(pmu_input_dev, KEY_POWER, down); - break; - case PMU_EVT_LID: - input_report_switch(pmu_input_dev, SW_LID, down); - break; - default: - /* no such key handled */ - return; - } - - input_sync(pmu_input_dev); -} - -late_initcall(via_pmu_event_init); diff --git a/trunk/drivers/macintosh/via-pmu-event.h b/trunk/drivers/macintosh/via-pmu-event.h deleted file mode 100644 index 72c54de408e8..000000000000 --- a/trunk/drivers/macintosh/via-pmu-event.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __VIA_PMU_EVENT_H -#define __VIA_PMU_EVENT_H - -#define PMU_EVT_POWER 0 -#define PMU_EVT_LID 1 -extern void via_pmu_event(int key, int down); - -#endif /* __VIA_PMU_EVENT_H */ diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index 1ab4f16c08b9..0b5ff553e39a 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -69,8 +69,6 @@ #include #endif -#include "via-pmu-event.h" - /* Some compile options */ #undef SUSPEND_USES_PMU #define DEBUG_SLEEP @@ -146,6 +144,7 @@ static int data_index; static int data_len; static volatile int adb_int_pending; static volatile int disable_poll; +static struct adb_request bright_req_1, bright_req_2; static struct device_node *vias; static int pmu_kind = PMU_UNKNOWN; static int pmu_fully_inited = 0; @@ -162,7 +161,7 @@ static int drop_interrupts; #if defined(CONFIG_PM) && defined(CONFIG_PPC32) static int option_lid_wakeup = 1; #endif /* CONFIG_PM && CONFIG_PPC32 */ -#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) +#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT) static int sleep_in_progress; #endif static unsigned long async_req_locks; @@ -209,6 +208,10 @@ static int proc_get_info(char *page, char **start, off_t off, int count, int *eof, void *data); static int proc_get_irqstats(char *page, char **start, off_t off, int count, int *eof, void *data); +#ifdef CONFIG_PMAC_BACKLIGHT +static int pmu_set_backlight_level(int level, void* data); +static int pmu_set_backlight_enable(int on, int level, void* data); +#endif /* CONFIG_PMAC_BACKLIGHT */ static void pmu_pass_intr(unsigned char *data, int len); static int proc_get_batt(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -289,6 +292,13 @@ static char *pbook_type[] = { "Core99" }; +#ifdef CONFIG_PMAC_BACKLIGHT +static struct backlight_controller pmu_backlight_controller = { + pmu_set_backlight_enable, + pmu_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ + int __init find_via_pmu(void) { u64 taddr; @@ -407,6 +417,8 @@ static int __init via_pmu_start(void) if (vias == NULL) return -ENODEV; + bright_req_1.complete = 1; + bright_req_2.complete = 1; batt_req.complete = 1; #ifndef CONFIG_PPC_MERGE @@ -471,9 +483,9 @@ static int __init via_pmu_dev_init(void) return -ENODEV; #ifdef CONFIG_PMAC_BACKLIGHT - /* Initialize backlight */ - pmu_backlight_init(vias); -#endif + /* Enable backlight */ + register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); +#endif /* CONFIG_PMAC_BACKLIGHT */ #ifdef CONFIG_PPC32 if (machine_is_compatible("AAPL,3400/2400") || @@ -1412,7 +1424,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) #ifdef CONFIG_INPUT_ADBHID if (!disable_kernel_backlight) #endif /* CONFIG_INPUT_ADBHID */ - pmac_backlight_set_legacy_brightness(data[1] >> 4); + set_backlight_level(data[1] >> 4); #endif /* CONFIG_PMAC_BACKLIGHT */ } /* Tick interrupt */ @@ -1429,12 +1441,6 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) if (pmu_battery_count) query_battery_state(); pmu_pass_intr(data, len); - /* len == 6 is probably a bad check. But how do I - * know what PMU versions send what events here? */ - if (len == 6) { - via_pmu_event(PMU_EVT_POWER, !!(data[1]&8)); - via_pmu_event(PMU_EVT_LID, data[1]&1); - } } else { pmu_pass_intr(data, len); } @@ -1668,6 +1674,61 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) return IRQ_NONE; } +#ifdef CONFIG_PMAC_BACKLIGHT +static int backlight_to_bright[] = { + 0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e, + 0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e +}; + +static int +pmu_set_backlight_enable(int on, int level, void* data) +{ + struct adb_request req; + + if (vias == NULL) + return -ENODEV; + + if (on) { + pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, + backlight_to_bright[level]); + pmu_wait_complete(&req); + } + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF)); + pmu_wait_complete(&req); + + return 0; +} + +static void +pmu_bright_complete(struct adb_request *req) +{ + if (req == &bright_req_1) + clear_bit(1, &async_req_locks); + if (req == &bright_req_2) + clear_bit(2, &async_req_locks); +} + +static int +pmu_set_backlight_level(int level, void* data) +{ + if (vias == NULL) + return -ENODEV; + + if (test_and_set_bit(1, &async_req_locks)) + return -EAGAIN; + pmu_request(&bright_req_1, pmu_bright_complete, 2, PMU_BACKLIGHT_BRIGHT, + backlight_to_bright[level]); + if (test_and_set_bit(2, &async_req_locks)) + return -EAGAIN; + pmu_request(&bright_req_2, pmu_bright_complete, 2, PMU_POWER_CTRL, + PMU_POW_BACKLIGHT | (level > BACKLIGHT_OFF ? + PMU_POW_ON : PMU_POW_OFF)); + + return 0; +} +#endif /* CONFIG_PMAC_BACKLIGHT */ + void pmu_enable_irled(int on) { @@ -2084,8 +2145,9 @@ pmac_suspend_devices(void) return -EBUSY; } - /* Wait for completion of async requests */ - while (!batt_req.complete) + /* Wait for completion of async backlight requests */ + while (!bright_req_1.complete || !bright_req_2.complete || + !batt_req.complete) pmu_poll(); /* Giveup the lazy FPU & vec so we don't have to back them @@ -2206,7 +2268,7 @@ static int powerbook_sleep_grackle(void) _set_L2CR(save_l2cr); /* Restore userland MMU context */ - set_context(current->active_mm->context.id, current->active_mm->pgd); + set_context(current->active_mm->context, current->active_mm->pgd); /* Power things up */ pmu_unlock(); @@ -2304,7 +2366,7 @@ powerbook_sleep_Core99(void) _set_L3CR(save_l3cr); /* Restore userland MMU context */ - set_context(current->active_mm->context.id, current->active_mm->pgd); + set_context(current->active_mm->context, current->active_mm->pgd); /* Tell PMU we are ready */ pmu_unlock(); @@ -2616,34 +2678,26 @@ pmu_ioctl(struct inode * inode, struct file *filp, return put_user(1, argp); #endif /* CONFIG_PM && CONFIG_PPC32 */ -#ifdef CONFIG_PMAC_BACKLIGHT_LEGACY - /* Compatibility ioctl's for backlight */ +#ifdef CONFIG_PMAC_BACKLIGHT + /* Backlight should have its own device or go via + * the fbdev + */ case PMU_IOC_GET_BACKLIGHT: - { - int brightness; - if (sleep_in_progress) return -EBUSY; - - brightness = pmac_backlight_get_legacy_brightness(); - if (brightness < 0) - return brightness; - else - return put_user(brightness, argp); - - } + error = get_backlight_level(); + if (error < 0) + return error; + return put_user(error, argp); case PMU_IOC_SET_BACKLIGHT: { - int brightness; - + __u32 value; if (sleep_in_progress) return -EBUSY; - - error = get_user(brightness, argp); - if (error) - return error; - - return pmac_backlight_set_legacy_brightness(brightness); + error = get_user(value, argp); + if (!error) + error = set_backlight_level(value); + break; } #ifdef CONFIG_INPUT_ADBHID case PMU_IOC_GRAB_BACKLIGHT: { @@ -2659,7 +2713,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, return 0; } #endif /* CONFIG_INPUT_ADBHID */ -#endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ +#endif /* CONFIG_PMAC_BACKLIGHT */ case PMU_IOC_GET_MODEL: return put_user(pmu_kind, argp); case PMU_IOC_HAS_ADB: diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index bf869ed03eed..ac25a48362ac 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -90,7 +90,7 @@ config MD_RAID10 depends on BLK_DEV_MD && EXPERIMENTAL ---help--- RAID-10 provides a combination of striping (RAID-0) and - mirroring (RAID-1) with easier configuration and more flexible + mirroring (RAID-1) with easier configuration and more flexable layout. Unlike RAID-0, but like RAID-1, RAID-10 requires all devices to be the same size (or at least, only as much as the smallest device @@ -104,8 +104,8 @@ config MD_RAID10 If unsure, say Y. -config MD_RAID456 - tristate "RAID-4/RAID-5/RAID-6 mode" +config MD_RAID5 + tristate "RAID-4/RAID-5 mode" depends on BLK_DEV_MD ---help--- A RAID-5 set of N drives with a capacity of C MB per drive provides @@ -116,28 +116,20 @@ config MD_RAID456 while a RAID-5 set distributes the parity across the drives in one of the available parity distribution methods. - A RAID-6 set of N drives with a capacity of C MB per drive - provides the capacity of C * (N - 2) MB, and protects - against a failure of any two drives. For a given sector - (row) number, (N - 2) drives contain data sectors, and two - drives contains two independent redundancy syndromes. Like - RAID-5, RAID-6 distributes the syndromes across the drives - in one of the available parity distribution methods. - Information about Software RAID on Linux is contained in the Software-RAID mini-HOWTO, available from . There you will also learn where to get the supporting user space utilities raidtools. - If you want to use such a RAID-4/RAID-5/RAID-6 set, say Y. To + If you want to use such a RAID-4/RAID-5 set, say Y. To compile this code as a module, choose M here: the module - will be called raid456. + will be called raid5. If unsure, say Y. config MD_RAID5_RESHAPE bool "Support adding drives to a raid-5 array (experimental)" - depends on MD_RAID456 && EXPERIMENTAL + depends on MD_RAID5 && EXPERIMENTAL ---help--- A RAID-5 set can be expanded by adding extra drives. This requires "restriping" the array which means (almost) every @@ -147,7 +139,7 @@ config MD_RAID5_RESHAPE is online. However it is still EXPERIMENTAL code. It should work, but please be sure that you have backups. - You will need mdadm version 2.4.1 or later to use this + You will need mdadm verion 2.4.1 or later to use this feature safely. During the early stage of reshape there is a critical section where live data is being over-written. A crash during this time needs extra care for recovery. The @@ -162,6 +154,28 @@ config MD_RAID5_RESHAPE There should be enough spares already present to make the new array workable. +config MD_RAID6 + tristate "RAID-6 mode" + depends on BLK_DEV_MD + ---help--- + A RAID-6 set of N drives with a capacity of C MB per drive + provides the capacity of C * (N - 2) MB, and protects + against a failure of any two drives. For a given sector + (row) number, (N - 2) drives contain data sectors, and two + drives contains two independent redundancy syndromes. Like + RAID-5, RAID-6 distributes the syndromes across the drives + in one of the available parity distribution methods. + + RAID-6 requires mdadm-1.5.0 or later, available at: + + ftp://ftp.kernel.org/pub/linux/utils/raid/mdadm/ + + If you want to use such a RAID-6 set, say Y. To compile + this code as a module, choose M here: the module will be + called raid6. + + If unsure, say Y. + config MD_MULTIPATH tristate "Multipath I/O support" depends on BLK_DEV_MD @@ -221,7 +235,7 @@ config DM_SNAPSHOT tristate "Snapshot target (EXPERIMENTAL)" depends on BLK_DEV_DM && EXPERIMENTAL ---help--- - Allow volume managers to take writable snapshots of a device. + Allow volume managers to take writeable snapshots of a device. config DM_MIRROR tristate "Mirror target (EXPERIMENTAL)" diff --git a/trunk/drivers/md/Makefile b/trunk/drivers/md/Makefile index 34957a68d921..d3efedf6a6ad 100644 --- a/trunk/drivers/md/Makefile +++ b/trunk/drivers/md/Makefile @@ -8,7 +8,7 @@ dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-mirror-objs := dm-log.o dm-raid1.o md-mod-objs := md.o bitmap.o -raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \ +raid6-objs := raid6main.o raid6algos.o raid6recov.o raid6tables.o \ raid6int1.o raid6int2.o raid6int4.o \ raid6int8.o raid6int16.o raid6int32.o \ raid6altivec1.o raid6altivec2.o raid6altivec4.o \ @@ -25,7 +25,8 @@ obj-$(CONFIG_MD_LINEAR) += linear.o obj-$(CONFIG_MD_RAID0) += raid0.o obj-$(CONFIG_MD_RAID1) += raid1.o obj-$(CONFIG_MD_RAID10) += raid10.o -obj-$(CONFIG_MD_RAID456) += raid456.o xor.o +obj-$(CONFIG_MD_RAID5) += raid5.o xor.o +obj-$(CONFIG_MD_RAID6) += raid6.o xor.o obj-$(CONFIG_MD_MULTIPATH) += multipath.o obj-$(CONFIG_MD_FAULTY) += faulty.o obj-$(CONFIG_BLK_DEV_MD) += md-mod.o diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index ebbd2d856256..f8ffaee20ff8 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -7,6 +7,7 @@ * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.: * - added disk storage for bitmap * - changes to allow various bitmap chunk sizes + * - added bitmap daemon (to asynchronously clear bitmap bits from disk) */ /* @@ -14,6 +15,9 @@ * * flush after percent set rather than just time based. (maybe both). * wait if count gets too high, wake when it drops to half. + * allow bitmap to be mirrored with superblock (before or after...) + * allow hot-add to re-instate a current device. + * allow hot-add of bitmap after quiessing device */ #include @@ -68,6 +72,24 @@ static inline char * bmname(struct bitmap *bitmap) } +/* + * test if the bitmap is active + */ +int bitmap_active(struct bitmap *bitmap) +{ + unsigned long flags; + int res = 0; + + if (!bitmap) + return res; + spin_lock_irqsave(&bitmap->lock, flags); + res = bitmap->flags & BITMAP_ACTIVE; + spin_unlock_irqrestore(&bitmap->lock, flags); + return res; +} + +#define WRITE_POOL_SIZE 256 + /* * just a placeholder - calls kmalloc for bitmap pages */ @@ -247,8 +269,6 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { page->index = index; - attach_page_buffers(page, NULL); /* so that free_buffer will - * quietly no-op */ return page; } } @@ -280,132 +300,77 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai */ static int write_page(struct bitmap *bitmap, struct page *page, int wait) { - struct buffer_head *bh; + int ret = -ENOMEM; if (bitmap->file == NULL) return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); - bh = page_buffers(page); + flush_dcache_page(page); /* make sure visible to anyone reading the file */ - while (bh && bh->b_blocknr) { - atomic_inc(&bitmap->pending_writes); - set_buffer_locked(bh); - set_buffer_mapped(bh); - submit_bh(WRITE, bh); - bh = bh->b_this_page; + if (wait) + lock_page(page); + else { + if (TestSetPageLocked(page)) + return -EAGAIN; /* already locked */ + if (PageWriteback(page)) { + unlock_page(page); + return -EAGAIN; + } } - if (wait) { - wait_event(bitmap->write_wait, - atomic_read(&bitmap->pending_writes)==0); - return (bitmap->flags & BITMAP_WRITE_ERROR) ? -EIO : 0; + ret = page->mapping->a_ops->prepare_write(bitmap->file, page, 0, PAGE_SIZE); + if (!ret) + ret = page->mapping->a_ops->commit_write(bitmap->file, page, 0, + PAGE_SIZE); + if (ret) { + unlock_page(page); + return ret; } - return 0; -} -static void end_bitmap_write(struct buffer_head *bh, int uptodate) -{ - struct bitmap *bitmap = bh->b_private; - unsigned long flags; - - if (!uptodate) { - spin_lock_irqsave(&bitmap->lock, flags); - bitmap->flags |= BITMAP_WRITE_ERROR; - spin_unlock_irqrestore(&bitmap->lock, flags); - } - if (atomic_dec_and_test(&bitmap->pending_writes)) - wake_up(&bitmap->write_wait); -} - -/* copied from buffer.c */ -static void -__clear_page_buffers(struct page *page) -{ - ClearPagePrivate(page); - set_page_private(page, 0); - page_cache_release(page); -} -static void free_buffers(struct page *page) -{ - struct buffer_head *bh = page_buffers(page); - - while (bh) { - struct buffer_head *next = bh->b_this_page; - free_buffer_head(bh); - bh = next; + set_page_dirty(page); /* force it to be written out */ + + if (!wait) { + /* add to list to be waited for by daemon */ + struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO); + item->page = page; + get_page(page); + spin_lock(&bitmap->write_lock); + list_add(&item->list, &bitmap->complete_pages); + spin_unlock(&bitmap->write_lock); + md_wakeup_thread(bitmap->writeback_daemon); } - __clear_page_buffers(page); - put_page(page); + return write_one_page(page, wait); } -/* read a page from a file. - * We both read the page, and attach buffers to the page to record the - * address of each block (using bmap). These addresses will be used - * to write the block later, completely bypassing the filesystem. - * This usage is similar to how swap files are handled, and allows us - * to write to a file with no concerns of memory allocation failing. - */ +/* read a page from a file, pinning it into cache, and return bytes_read */ static struct page *read_page(struct file *file, unsigned long index, - struct bitmap *bitmap, - unsigned long count) + unsigned long *bytes_read) { + struct inode *inode = file->f_mapping->host; struct page *page = NULL; - struct inode *inode = file->f_dentry->d_inode; - struct buffer_head *bh; - sector_t block; + loff_t isize = i_size_read(inode); + unsigned long end_index = isize >> PAGE_SHIFT; PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE, (unsigned long long)index << PAGE_SHIFT); - page = alloc_page(GFP_KERNEL); - if (!page) - page = ERR_PTR(-ENOMEM); + page = read_cache_page(inode->i_mapping, index, + (filler_t *)inode->i_mapping->a_ops->readpage, file); if (IS_ERR(page)) goto out; - - bh = alloc_page_buffers(page, 1<i_blkbits, 0); - if (!bh) { + wait_on_page_locked(page); + if (!PageUptodate(page) || PageError(page)) { put_page(page); - page = ERR_PTR(-ENOMEM); + page = ERR_PTR(-EIO); goto out; } - attach_page_buffers(page, bh); - block = index << (PAGE_SHIFT - inode->i_blkbits); - while (bh) { - if (count == 0) - bh->b_blocknr = 0; - else { - bh->b_blocknr = bmap(inode, block); - if (bh->b_blocknr == 0) { - /* Cannot use this file! */ - free_buffers(page); - page = ERR_PTR(-EINVAL); - goto out; - } - bh->b_bdev = inode->i_sb->s_bdev; - if (count < (1<i_blkbits)) - count = 0; - else - count -= (1<i_blkbits); - - bh->b_end_io = end_bitmap_write; - bh->b_private = bitmap; - atomic_inc(&bitmap->pending_writes); - set_buffer_locked(bh); - set_buffer_mapped(bh); - submit_bh(READ, bh); - } - block++; - bh = bh->b_this_page; - } - page->index = index; - wait_event(bitmap->write_wait, - atomic_read(&bitmap->pending_writes)==0); - if (bitmap->flags & BITMAP_WRITE_ERROR) { - free_buffers(page); - page = ERR_PTR(-EIO); - } + if (index > end_index) /* we have read beyond EOF */ + *bytes_read = 0; + else if (index == end_index) /* possible short read */ + *bytes_read = isize & ~PAGE_MASK; + else + *bytes_read = PAGE_SIZE; /* got a full page */ out: if (IS_ERR(page)) printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n", @@ -476,14 +441,16 @@ static int bitmap_read_sb(struct bitmap *bitmap) char *reason = NULL; bitmap_super_t *sb; unsigned long chunksize, daemon_sleep, write_behind; + unsigned long bytes_read; unsigned long long events; int err = -EINVAL; /* page 0 is the superblock, read it... */ if (bitmap->file) - bitmap->sb_page = read_page(bitmap->file, 0, bitmap, PAGE_SIZE); + bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); else { bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); + bytes_read = PAGE_SIZE; } if (IS_ERR(bitmap->sb_page)) { err = PTR_ERR(bitmap->sb_page); @@ -493,6 +460,13 @@ static int bitmap_read_sb(struct bitmap *bitmap) sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); + if (bytes_read < sizeof(*sb)) { /* short read */ + printk(KERN_INFO "%s: bitmap file superblock truncated\n", + bmname(bitmap)); + err = -ENOSPC; + goto out; + } + chunksize = le32_to_cpu(sb->chunksize); daemon_sleep = le32_to_cpu(sb->daemon_sleep); write_behind = le32_to_cpu(sb->write_behind); @@ -576,6 +550,7 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, spin_unlock_irqrestore(&bitmap->lock, flags); return; } + get_page(bitmap->sb_page); spin_unlock_irqrestore(&bitmap->lock, flags); sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); switch (op) { @@ -586,6 +561,7 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, default: BUG(); } kunmap_atomic(sb, KM_USER0); + put_page(bitmap->sb_page); } /* @@ -638,17 +614,48 @@ static void bitmap_file_unmap(struct bitmap *bitmap) while (pages--) if (map[pages]->index != 0) /* 0 is sb_page, release it below */ - free_buffers(map[pages]); + put_page(map[pages]); kfree(map); kfree(attr); - if (sb_page) - free_buffers(sb_page); + safe_put_page(sb_page); +} + +static void bitmap_stop_daemon(struct bitmap *bitmap); + +/* dequeue the next item in a page list -- don't call from irq context */ +static struct page_list *dequeue_page(struct bitmap *bitmap) +{ + struct page_list *item = NULL; + struct list_head *head = &bitmap->complete_pages; + + spin_lock(&bitmap->write_lock); + if (list_empty(head)) + goto out; + item = list_entry(head->prev, struct page_list, list); + list_del(head->prev); +out: + spin_unlock(&bitmap->write_lock); + return item; +} + +static void drain_write_queues(struct bitmap *bitmap) +{ + struct page_list *item; + + while ((item = dequeue_page(bitmap))) { + /* don't bother to wait */ + put_page(item->page); + mempool_free(item, bitmap->write_pool); + } + + wake_up(&bitmap->write_wait); } static void bitmap_file_put(struct bitmap *bitmap) { struct file *file; + struct inode *inode; unsigned long flags; spin_lock_irqsave(&bitmap->lock, flags); @@ -656,14 +663,17 @@ static void bitmap_file_put(struct bitmap *bitmap) bitmap->file = NULL; spin_unlock_irqrestore(&bitmap->lock, flags); - if (file) - wait_event(bitmap->write_wait, - atomic_read(&bitmap->pending_writes)==0); + bitmap_stop_daemon(bitmap); + + drain_write_queues(bitmap); + bitmap_file_unmap(bitmap); if (file) { - struct inode *inode = file->f_dentry->d_inode; - invalidate_inode_pages(inode->i_mapping); + inode = file->f_mapping->host; + spin_lock(&inode->i_lock); + atomic_set(&inode->i_writecount, 1); /* allow writes again */ + spin_unlock(&inode->i_lock); fput(file); } } @@ -698,27 +708,26 @@ static void bitmap_file_kick(struct bitmap *bitmap) } enum bitmap_page_attr { - BITMAP_PAGE_DIRTY = 0, // there are set bits that need to be synced - BITMAP_PAGE_CLEAN = 1, // there are bits that might need to be cleared - BITMAP_PAGE_NEEDWRITE=2, // there are cleared bits that need to be synced + BITMAP_PAGE_DIRTY = 1, // there are set bits that need to be synced + BITMAP_PAGE_CLEAN = 2, // there are bits that might need to be cleared + BITMAP_PAGE_NEEDWRITE=4, // there are cleared bits that need to be synced }; static inline void set_page_attr(struct bitmap *bitmap, struct page *page, enum bitmap_page_attr attr) { - __set_bit((page->index<<2) + attr, bitmap->filemap_attr); + bitmap->filemap_attr[page->index] |= attr; } static inline void clear_page_attr(struct bitmap *bitmap, struct page *page, enum bitmap_page_attr attr) { - __clear_bit((page->index<<2) + attr, bitmap->filemap_attr); + bitmap->filemap_attr[page->index] &= ~attr; } -static inline unsigned long test_page_attr(struct bitmap *bitmap, struct page *page, - enum bitmap_page_attr attr) +static inline unsigned long get_page_attr(struct bitmap *bitmap, struct page *page) { - return test_bit((page->index<<2) + attr, bitmap->filemap_attr); + return bitmap->filemap_attr[page->index]; } /* @@ -742,6 +751,11 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) page = filemap_get_page(bitmap, chunk); bit = file_page_offset(chunk); + + /* make sure the page stays cached until it gets written out */ + if (! (get_page_attr(bitmap, page) & BITMAP_PAGE_DIRTY)) + get_page(page); + /* set the bit */ kaddr = kmap_atomic(page, KM_USER0); if (bitmap->flags & BITMAP_HOSTENDIAN) @@ -761,8 +775,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) * sync the dirty pages of the bitmap file to disk */ int bitmap_unplug(struct bitmap *bitmap) { - unsigned long i, flags; - int dirty, need_write; + unsigned long i, attr, flags; struct page *page; int wait = 0; int err; @@ -779,26 +792,35 @@ int bitmap_unplug(struct bitmap *bitmap) return 0; } page = bitmap->filemap[i]; - dirty = test_page_attr(bitmap, page, BITMAP_PAGE_DIRTY); - need_write = test_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + attr = get_page_attr(bitmap, page); clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY); clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); - if (dirty) + if ((attr & BITMAP_PAGE_DIRTY)) wait = 1; spin_unlock_irqrestore(&bitmap->lock, flags); - if (dirty | need_write) + if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) { err = write_page(bitmap, page, 0); + if (err == -EAGAIN) { + if (attr & BITMAP_PAGE_DIRTY) + err = write_page(bitmap, page, 1); + else + err = 0; + } + if (err) + return 1; + } } if (wait) { /* if any writes were performed, we need to wait on them */ - if (bitmap->file) - wait_event(bitmap->write_wait, - atomic_read(&bitmap->pending_writes)==0); - else + if (bitmap->file) { + spin_lock_irq(&bitmap->write_lock); + wait_event_lock_irq(bitmap->write_wait, + list_empty(&bitmap->complete_pages), bitmap->write_lock, + wake_up_process(bitmap->writeback_daemon->tsk)); + spin_unlock_irq(&bitmap->write_lock); + } else md_super_wait(bitmap->mddev); } - if (bitmap->flags & BITMAP_WRITE_ERROR) - bitmap_file_kick(bitmap); return 0; } @@ -820,7 +842,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) struct page *page = NULL, *oldpage = NULL; unsigned long num_pages, bit_cnt = 0; struct file *file; - unsigned long bytes, offset; + unsigned long bytes, offset, dummy; int outofdate; int ret = -ENOSPC; void *paddr; @@ -857,12 +879,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) if (!bitmap->filemap) goto out; - /* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */ - bitmap->filemap_attr = kzalloc( - (((num_pages*4/8)+sizeof(unsigned long)-1) - /sizeof(unsigned long)) - *sizeof(unsigned long), - GFP_KERNEL); + bitmap->filemap_attr = kzalloc(sizeof(long) * num_pages, GFP_KERNEL); if (!bitmap->filemap_attr) goto out; @@ -873,12 +890,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) index = file_page_index(i); bit = file_page_offset(i); if (index != oldindex) { /* this is a new page, read it in */ - int count; /* unmap the old page, we're done with it */ - if (index == num_pages-1) - count = bytes - index * PAGE_SIZE; - else - count = PAGE_SIZE; if (index == 0) { /* * if we're here then the superblock page @@ -888,7 +900,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) page = bitmap->sb_page; offset = sizeof(bitmap_super_t); } else if (file) { - page = read_page(file, index, bitmap, count); + page = read_page(file, index, &dummy); offset = 0; } else { page = read_sb_page(bitmap->mddev, bitmap->offset, index); @@ -959,11 +971,12 @@ void bitmap_write_all(struct bitmap *bitmap) /* We don't actually write all bitmap blocks here, * just flag them as needing to be written */ - int i; - for (i=0; i < bitmap->file_pages; i++) - set_page_attr(bitmap, bitmap->filemap[i], - BITMAP_PAGE_NEEDWRITE); + unsigned long chunks = bitmap->chunks; + unsigned long bytes = (chunks+7)/8 + sizeof(bitmap_super_t); + unsigned long num_pages = (bytes + PAGE_SIZE-1) / PAGE_SIZE; + while (num_pages--) + bitmap->filemap_attr[num_pages] |= BITMAP_PAGE_NEEDWRITE; } @@ -994,6 +1007,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) struct page *page = NULL, *lastpage = NULL; int err = 0; int blocks; + int attr; void *paddr; if (bitmap == NULL) @@ -1015,34 +1029,43 @@ int bitmap_daemon_work(struct bitmap *bitmap) if (page != lastpage) { /* skip this page unless it's marked as needing cleaning */ - if (!test_page_attr(bitmap, page, BITMAP_PAGE_CLEAN)) { - int need_write = test_page_attr(bitmap, page, - BITMAP_PAGE_NEEDWRITE); - if (need_write) + if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { + if (attr & BITMAP_PAGE_NEEDWRITE) { + get_page(page); clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); - + } spin_unlock_irqrestore(&bitmap->lock, flags); - if (need_write) { + if (attr & BITMAP_PAGE_NEEDWRITE) { switch (write_page(bitmap, page, 0)) { + case -EAGAIN: + set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + break; case 0: break; default: bitmap_file_kick(bitmap); } + put_page(page); } continue; } /* grab the new page, sync and release the old */ + get_page(page); if (lastpage != NULL) { - if (test_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE)) { + if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); err = write_page(bitmap, lastpage, 0); + if (err == -EAGAIN) { + err = 0; + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + } } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); } + put_page(lastpage); if (err) bitmap_file_kick(bitmap); } else @@ -1084,19 +1107,131 @@ int bitmap_daemon_work(struct bitmap *bitmap) /* now sync the final page */ if (lastpage != NULL) { spin_lock_irqsave(&bitmap->lock, flags); - if (test_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE)) { + if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); err = write_page(bitmap, lastpage, 0); + if (err == -EAGAIN) { + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + err = 0; + } } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); } + + put_page(lastpage); } return err; } +static void daemon_exit(struct bitmap *bitmap, mdk_thread_t **daemon) +{ + mdk_thread_t *dmn; + unsigned long flags; + + /* if no one is waiting on us, we'll free the md thread struct + * and exit, otherwise we let the waiter clean things up */ + spin_lock_irqsave(&bitmap->lock, flags); + if ((dmn = *daemon)) { /* no one is waiting, cleanup and exit */ + *daemon = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + kfree(dmn); + complete_and_exit(NULL, 0); /* do_exit not exported */ + } + spin_unlock_irqrestore(&bitmap->lock, flags); +} + +static void bitmap_writeback_daemon(mddev_t *mddev) +{ + struct bitmap *bitmap = mddev->bitmap; + struct page *page; + struct page_list *item; + int err = 0; + + if (signal_pending(current)) { + printk(KERN_INFO + "%s: bitmap writeback daemon got signal, exiting...\n", + bmname(bitmap)); + err = -EINTR; + goto out; + } + if (bitmap == NULL) + /* about to be stopped. */ + return; + + PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); + /* wait on bitmap page writebacks */ + while ((item = dequeue_page(bitmap))) { + page = item->page; + mempool_free(item, bitmap->write_pool); + PRINTK("wait on page writeback: %p\n", page); + wait_on_page_writeback(page); + PRINTK("finished page writeback: %p\n", page); + + err = PageError(page); + put_page(page); + if (err) { + printk(KERN_WARNING "%s: bitmap file writeback " + "failed (page %lu): %d\n", + bmname(bitmap), page->index, err); + bitmap_file_kick(bitmap); + goto out; + } + } + out: + wake_up(&bitmap->write_wait); + if (err) { + printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", + bmname(bitmap), err); + daemon_exit(bitmap, &bitmap->writeback_daemon); + } +} + +static mdk_thread_t *bitmap_start_daemon(struct bitmap *bitmap, + void (*func)(mddev_t *), char *name) +{ + mdk_thread_t *daemon; + char namebuf[32]; + +#ifdef INJECT_FATAL_FAULT_2 + daemon = NULL; +#else + sprintf(namebuf, "%%s_%s", name); + daemon = md_register_thread(func, bitmap->mddev, namebuf); +#endif + if (!daemon) { + printk(KERN_ERR "%s: failed to start bitmap daemon\n", + bmname(bitmap)); + return ERR_PTR(-ECHILD); + } + + md_wakeup_thread(daemon); /* start it running */ + + PRINTK("%s: %s daemon (pid %d) started...\n", + bmname(bitmap), name, daemon->tsk->pid); + + return daemon; +} + +static void bitmap_stop_daemon(struct bitmap *bitmap) +{ + /* the daemon can't stop itself... it'll just exit instead... */ + if (bitmap->writeback_daemon && ! IS_ERR(bitmap->writeback_daemon) && + current->pid != bitmap->writeback_daemon->tsk->pid) { + mdk_thread_t *daemon; + unsigned long flags; + + spin_lock_irqsave(&bitmap->lock, flags); + daemon = bitmap->writeback_daemon; + bitmap->writeback_daemon = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + if (daemon && ! IS_ERR(daemon)) + md_unregister_thread(daemon); /* destroy the thread */ + } +} + static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, sector_t offset, int *blocks, int create) @@ -1365,6 +1500,8 @@ static void bitmap_free(struct bitmap *bitmap) /* free all allocated memory */ + mempool_destroy(bitmap->write_pool); + if (bp) /* deallocate the page memory */ for (k = 0; k < pages; k++) if (bp[k].map && !bp[k].hijacked) @@ -1412,20 +1549,20 @@ int bitmap_create(mddev_t *mddev) return -ENOMEM; spin_lock_init(&bitmap->lock); - atomic_set(&bitmap->pending_writes, 0); - init_waitqueue_head(&bitmap->write_wait); - bitmap->mddev = mddev; + spin_lock_init(&bitmap->write_lock); + INIT_LIST_HEAD(&bitmap->complete_pages); + init_waitqueue_head(&bitmap->write_wait); + bitmap->write_pool = mempool_create_kmalloc_pool(WRITE_POOL_SIZE, + sizeof(struct page_list)); + err = -ENOMEM; + if (!bitmap->write_pool) + goto error; + bitmap->file = file; bitmap->offset = mddev->bitmap_offset; - if (file) { - get_file(file); - do_sync_file_range(file, 0, LLONG_MAX, - SYNC_FILE_RANGE_WAIT_BEFORE | - SYNC_FILE_RANGE_WRITE | - SYNC_FILE_RANGE_WAIT_AFTER); - } + if (file) get_file(file); /* read superblock from bitmap file (this sets bitmap->chunksize) */ err = bitmap_read_sb(bitmap); if (err) @@ -1457,6 +1594,8 @@ int bitmap_create(mddev_t *mddev) if (!bitmap->bp) goto error; + bitmap->flags |= BITMAP_ACTIVE; + /* now that we have some pages available, initialize the in-memory * bitmap from the on-disk bitmap */ start = 0; @@ -1474,6 +1613,15 @@ int bitmap_create(mddev_t *mddev) mddev->bitmap = bitmap; + if (file) + /* kick off the bitmap writeback daemon */ + bitmap->writeback_daemon = + bitmap_start_daemon(bitmap, + bitmap_writeback_daemon, + "bitmap_wb"); + + if (IS_ERR(bitmap->writeback_daemon)) + return PTR_ERR(bitmap->writeback_daemon); mddev->thread->timeout = bitmap->daemon_sleep * HZ; return bitmap_update_sb(bitmap); @@ -1490,3 +1638,4 @@ EXPORT_SYMBOL(bitmap_start_sync); EXPORT_SYMBOL(bitmap_end_sync); EXPORT_SYMBOL(bitmap_unplug); EXPORT_SYMBOL(bitmap_close_sync); +EXPORT_SYMBOL(bitmap_daemon_work); diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index 6022ed12a795..61a590bb6241 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -20,7 +20,7 @@ #include "dm.h" -#define DM_MSG_PREFIX "crypt" +#define PFX "crypt: " /* * per bio private data @@ -125,19 +125,19 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, u8 *salt; if (opts == NULL) { - ti->error = "Digest algorithm missing for ESSIV mode"; + ti->error = PFX "Digest algorithm missing for ESSIV mode"; return -EINVAL; } /* Hash the cipher key with the given hash algorithm */ hash_tfm = crypto_alloc_tfm(opts, CRYPTO_TFM_REQ_MAY_SLEEP); if (hash_tfm == NULL) { - ti->error = "Error initializing ESSIV hash"; + ti->error = PFX "Error initializing ESSIV hash"; return -EINVAL; } if (crypto_tfm_alg_type(hash_tfm) != CRYPTO_ALG_TYPE_DIGEST) { - ti->error = "Expected digest algorithm for ESSIV hash"; + ti->error = PFX "Expected digest algorithm for ESSIV hash"; crypto_free_tfm(hash_tfm); return -EINVAL; } @@ -145,7 +145,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, saltsize = crypto_tfm_alg_digestsize(hash_tfm); salt = kmalloc(saltsize, GFP_KERNEL); if (salt == NULL) { - ti->error = "Error kmallocing salt storage in ESSIV"; + ti->error = PFX "Error kmallocing salt storage in ESSIV"; crypto_free_tfm(hash_tfm); return -ENOMEM; } @@ -159,20 +159,20 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, CRYPTO_TFM_MODE_ECB | CRYPTO_TFM_REQ_MAY_SLEEP); if (essiv_tfm == NULL) { - ti->error = "Error allocating crypto tfm for ESSIV"; + ti->error = PFX "Error allocating crypto tfm for ESSIV"; kfree(salt); return -EINVAL; } if (crypto_tfm_alg_blocksize(essiv_tfm) != crypto_tfm_alg_ivsize(cc->tfm)) { - ti->error = "Block size of ESSIV cipher does " + ti->error = PFX "Block size of ESSIV cipher does " "not match IV size of block cipher"; crypto_free_tfm(essiv_tfm); kfree(salt); return -EINVAL; } if (crypto_cipher_setkey(essiv_tfm, salt, saltsize) < 0) { - ti->error = "Failed to set key for ESSIV cipher"; + ti->error = PFX "Failed to set key for ESSIV cipher"; crypto_free_tfm(essiv_tfm); kfree(salt); return -EINVAL; @@ -521,7 +521,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) unsigned long long tmpll; if (argc != 5) { - ti->error = "Not enough arguments"; + ti->error = PFX "Not enough arguments"; return -EINVAL; } @@ -532,21 +532,21 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) ivmode = strsep(&ivopts, ":"); if (tmp) - DMWARN("Unexpected additional cipher options"); + DMWARN(PFX "Unexpected additional cipher options"); key_size = strlen(argv[1]) >> 1; cc = kmalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL); if (cc == NULL) { ti->error = - "Cannot allocate transparent encryption context"; + PFX "Cannot allocate transparent encryption context"; return -ENOMEM; } cc->key_size = key_size; if ((!key_size && strcmp(argv[1], "-") != 0) || (key_size && crypt_decode_key(cc->key, argv[1], key_size) < 0)) { - ti->error = "Error decoding key"; + ti->error = PFX "Error decoding key"; goto bad1; } @@ -562,22 +562,22 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) else if (strcmp(chainmode, "ecb") == 0) crypto_flags = CRYPTO_TFM_MODE_ECB; else { - ti->error = "Unknown chaining mode"; + ti->error = PFX "Unknown chaining mode"; goto bad1; } if (crypto_flags != CRYPTO_TFM_MODE_ECB && !ivmode) { - ti->error = "This chaining mode requires an IV mechanism"; + ti->error = PFX "This chaining mode requires an IV mechanism"; goto bad1; } tfm = crypto_alloc_tfm(cipher, crypto_flags | CRYPTO_TFM_REQ_MAY_SLEEP); if (!tfm) { - ti->error = "Error allocating crypto tfm"; + ti->error = PFX "Error allocating crypto tfm"; goto bad1; } if (crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER) { - ti->error = "Expected cipher algorithm"; + ti->error = PFX "Expected cipher algorithm"; goto bad2; } @@ -595,7 +595,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) else if (strcmp(ivmode, "essiv") == 0) cc->iv_gen_ops = &crypt_iv_essiv_ops; else { - ti->error = "Invalid IV mode"; + ti->error = PFX "Invalid IV mode"; goto bad2; } @@ -610,7 +610,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) else { cc->iv_size = 0; if (cc->iv_gen_ops) { - DMWARN("Selected cipher does not support IVs"); + DMWARN(PFX "Selected cipher does not support IVs"); if (cc->iv_gen_ops->dtr) cc->iv_gen_ops->dtr(cc); cc->iv_gen_ops = NULL; @@ -619,36 +619,36 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool); if (!cc->io_pool) { - ti->error = "Cannot allocate crypt io mempool"; + ti->error = PFX "Cannot allocate crypt io mempool"; goto bad3; } cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); if (!cc->page_pool) { - ti->error = "Cannot allocate page mempool"; + ti->error = PFX "Cannot allocate page mempool"; goto bad4; } if (tfm->crt_cipher.cit_setkey(tfm, cc->key, key_size) < 0) { - ti->error = "Error setting key"; + ti->error = PFX "Error setting key"; goto bad5; } if (sscanf(argv[2], "%llu", &tmpll) != 1) { - ti->error = "Invalid iv_offset sector"; + ti->error = PFX "Invalid iv_offset sector"; goto bad5; } cc->iv_offset = tmpll; if (sscanf(argv[4], "%llu", &tmpll) != 1) { - ti->error = "Invalid device sector"; + ti->error = PFX "Invalid device sector"; goto bad5; } cc->start = tmpll; if (dm_get_device(ti, argv[3], cc->start, ti->len, dm_table_get_mode(ti->table), &cc->dev)) { - ti->error = "Device lookup failed"; + ti->error = PFX "Device lookup failed"; goto bad5; } @@ -657,7 +657,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) *(ivopts - 1) = ':'; cc->iv_mode = kmalloc(strlen(ivmode) + 1, GFP_KERNEL); if (!cc->iv_mode) { - ti->error = "Error kmallocing iv_mode string"; + ti->error = PFX "Error kmallocing iv_mode string"; goto bad5; } strcpy(cc->iv_mode, ivmode); @@ -918,13 +918,13 @@ static int __init dm_crypt_init(void) _kcryptd_workqueue = create_workqueue("kcryptd"); if (!_kcryptd_workqueue) { r = -ENOMEM; - DMERR("couldn't create kcryptd"); + DMERR(PFX "couldn't create kcryptd"); goto bad1; } r = dm_register_target(&crypt_target); if (r < 0) { - DMERR("register failed %d", r); + DMERR(PFX "register failed %d", r); goto bad2; } @@ -942,7 +942,7 @@ static void __exit dm_crypt_exit(void) int r = dm_unregister_target(&crypt_target); if (r < 0) - DMERR("unregister failed %d", r); + DMERR(PFX "unregister failed %d", r); destroy_workqueue(_kcryptd_workqueue); kmem_cache_destroy(_crypt_io_pool); diff --git a/trunk/drivers/md/dm-emc.c b/trunk/drivers/md/dm-emc.c index 2a374ccb30dd..c7067674dcb7 100644 --- a/trunk/drivers/md/dm-emc.c +++ b/trunk/drivers/md/dm-emc.c @@ -12,8 +12,6 @@ #include #include -#define DM_MSG_PREFIX "multipath emc" - struct emc_handler { spinlock_t lock; @@ -68,7 +66,7 @@ static struct bio *get_failover_bio(struct path *path, unsigned data_size) bio = bio_alloc(GFP_ATOMIC, 1); if (!bio) { - DMERR("get_failover_bio: bio_alloc() failed."); + DMERR("dm-emc: get_failover_bio: bio_alloc() failed."); return NULL; } @@ -80,13 +78,13 @@ static struct bio *get_failover_bio(struct path *path, unsigned data_size) page = alloc_page(GFP_ATOMIC); if (!page) { - DMERR("get_failover_bio: alloc_page() failed."); + DMERR("dm-emc: get_failover_bio: alloc_page() failed."); bio_put(bio); return NULL; } if (bio_add_page(bio, page, data_size, 0) != data_size) { - DMERR("get_failover_bio: alloc_page() failed."); + DMERR("dm-emc: get_failover_bio: alloc_page() failed."); __free_page(page); bio_put(bio); return NULL; @@ -105,7 +103,7 @@ static struct request *get_failover_req(struct emc_handler *h, /* FIXME: Figure out why it fails with GFP_ATOMIC. */ rq = blk_get_request(q, WRITE, __GFP_WAIT); if (!rq) { - DMERR("get_failover_req: blk_get_request failed"); + DMERR("dm-emc: get_failover_req: blk_get_request failed"); return NULL; } @@ -162,7 +160,7 @@ static struct request *emc_trespass_get(struct emc_handler *h, bio = get_failover_bio(path, data_size); if (!bio) { - DMERR("emc_trespass_get: no bio"); + DMERR("dm-emc: emc_trespass_get: no bio"); return NULL; } @@ -175,7 +173,7 @@ static struct request *emc_trespass_get(struct emc_handler *h, /* get request for block layer packet command */ rq = get_failover_req(h, bio, path); if (!rq) { - DMERR("emc_trespass_get: no rq"); + DMERR("dm-emc: emc_trespass_get: no rq"); free_bio(bio); return NULL; } @@ -202,18 +200,18 @@ static void emc_pg_init(struct hw_handler *hwh, unsigned bypassed, * initial state passed into us and then get an update here. */ if (!q) { - DMINFO("emc_pg_init: no queue"); + DMINFO("dm-emc: emc_pg_init: no queue"); goto fail_path; } /* FIXME: The request should be pre-allocated. */ rq = emc_trespass_get(hwh->context, path); if (!rq) { - DMERR("emc_pg_init: no rq"); + DMERR("dm-emc: emc_pg_init: no rq"); goto fail_path; } - DMINFO("emc_pg_init: sending switch-over command"); + DMINFO("dm-emc: emc_pg_init: sending switch-over command"); elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); return; @@ -243,18 +241,18 @@ static int emc_create(struct hw_handler *hwh, unsigned argc, char **argv) hr = 0; short_trespass = 0; } else if (argc != 2) { - DMWARN("incorrect number of arguments"); + DMWARN("dm-emc hwhandler: incorrect number of arguments"); return -EINVAL; } else { if ((sscanf(argv[0], "%u", &short_trespass) != 1) || (short_trespass > 1)) { - DMWARN("invalid trespass mode selected"); + DMWARN("dm-emc: invalid trespass mode selected"); return -EINVAL; } if ((sscanf(argv[1], "%u", &hr) != 1) || (hr > 1)) { - DMWARN("invalid honor reservation flag selected"); + DMWARN("dm-emc: invalid honor reservation flag selected"); return -EINVAL; } } @@ -266,14 +264,14 @@ static int emc_create(struct hw_handler *hwh, unsigned argc, char **argv) hwh->context = h; if ((h->short_trespass = short_trespass)) - DMWARN("short trespass command will be send"); + DMWARN("dm-emc: short trespass command will be send"); else - DMWARN("long trespass command will be send"); + DMWARN("dm-emc: long trespass command will be send"); if ((h->hr = hr)) - DMWARN("honor reservation bit will be set"); + DMWARN("dm-emc: honor reservation bit will be set"); else - DMWARN("honor reservation bit will not be set (default)"); + DMWARN("dm-emc: honor reservation bit will not be set (default)"); return 0; } @@ -338,9 +336,9 @@ static int __init dm_emc_init(void) int r = dm_register_hw_handler(&emc_hwh); if (r < 0) - DMERR("register failed %d", r); + DMERR("emc: register failed %d", r); - DMINFO("version 0.0.3 loaded"); + DMINFO("dm-emc version 0.0.3 loaded"); return r; } @@ -350,7 +348,7 @@ static void __exit dm_emc_exit(void) int r = dm_unregister_hw_handler(&emc_hwh); if (r < 0) - DMERR("unregister failed %d", r); + DMERR("emc: unregister failed %d", r); } module_init(dm_emc_init); diff --git a/trunk/drivers/md/dm-exception-store.c b/trunk/drivers/md/dm-exception-store.c index d12379b5cdb5..cc07bbebbb16 100644 --- a/trunk/drivers/md/dm-exception-store.c +++ b/trunk/drivers/md/dm-exception-store.c @@ -16,8 +16,6 @@ #include #include -#define DM_MSG_PREFIX "snapshots" - /*----------------------------------------------------------------- * Persistent snapshots, by persistent we mean that the snapshot * will survive a reboot. @@ -93,6 +91,7 @@ struct pstore { struct dm_snapshot *snap; /* up pointer to my snapshot */ int version; int valid; + uint32_t chunk_size; uint32_t exceptions_per_area; /* @@ -134,7 +133,7 @@ static int alloc_area(struct pstore *ps) int r = -ENOMEM; size_t len; - len = ps->snap->chunk_size << SECTOR_SHIFT; + len = ps->chunk_size << SECTOR_SHIFT; /* * Allocate the chunk_size block of memory that will hold @@ -161,8 +160,8 @@ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw) unsigned long bits; where.bdev = ps->snap->cow->bdev; - where.sector = ps->snap->chunk_size * chunk; - where.count = ps->snap->chunk_size; + where.sector = ps->chunk_size * chunk; + where.count = ps->chunk_size; return dm_io_sync_vm(1, &where, rw, ps->area, &bits); } @@ -189,7 +188,7 @@ static int area_io(struct pstore *ps, uint32_t area, int rw) static int zero_area(struct pstore *ps, uint32_t area) { - memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT); + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); return area_io(ps, area, WRITE); } @@ -197,7 +196,6 @@ static int read_header(struct pstore *ps, int *new_snapshot) { int r; struct disk_header *dh; - chunk_t chunk_size; r = chunk_io(ps, 0, READ); if (r) @@ -212,29 +210,8 @@ static int read_header(struct pstore *ps, int *new_snapshot) *new_snapshot = 0; ps->valid = le32_to_cpu(dh->valid); ps->version = le32_to_cpu(dh->version); - chunk_size = le32_to_cpu(dh->chunk_size); - if (ps->snap->chunk_size != chunk_size) { - DMWARN("chunk size %llu in device metadata overrides " - "table chunk size of %llu.", - (unsigned long long)chunk_size, - (unsigned long long)ps->snap->chunk_size); - - /* We had a bogus chunk_size. Fix stuff up. */ - dm_io_put(sectors_to_pages(ps->snap->chunk_size)); - free_area(ps); - - ps->snap->chunk_size = chunk_size; - ps->snap->chunk_mask = chunk_size - 1; - ps->snap->chunk_shift = ffs(chunk_size) - 1; - - r = alloc_area(ps); - if (r) - return r; - - r = dm_io_get(sectors_to_pages(chunk_size)); - if (r) - return r; - } + ps->chunk_size = le32_to_cpu(dh->chunk_size); + } else { DMWARN("Invalid/corrupt snapshot"); r = -ENXIO; @@ -247,13 +224,13 @@ static int write_header(struct pstore *ps) { struct disk_header *dh; - memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT); + memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); dh = (struct disk_header *) ps->area; dh->magic = cpu_to_le32(SNAP_MAGIC); dh->valid = cpu_to_le32(ps->valid); dh->version = cpu_to_le32(ps->version); - dh->chunk_size = cpu_to_le32(ps->snap->chunk_size); + dh->chunk_size = cpu_to_le32(ps->chunk_size); return chunk_io(ps, 0, WRITE); } @@ -388,7 +365,7 @@ static void persistent_destroy(struct exception_store *store) { struct pstore *ps = get_info(store); - dm_io_put(sectors_to_pages(ps->snap->chunk_size)); + dm_io_put(sectors_to_pages(ps->chunk_size)); vfree(ps->callbacks); free_area(ps); kfree(ps); @@ -406,16 +383,6 @@ static int persistent_read_metadata(struct exception_store *store) if (r) return r; - /* - * Now we know correct chunk_size, complete the initialisation. - */ - ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) / - sizeof(struct disk_exception); - ps->callbacks = dm_vcalloc(ps->exceptions_per_area, - sizeof(*ps->callbacks)); - if (!ps->callbacks) - return -ENOMEM; - /* * Do we need to setup a new snapshot ? */ @@ -566,6 +533,9 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) ps->snap = store->snap; ps->valid = 1; ps->version = SNAPSHOT_DISK_VERSION; + ps->chunk_size = chunk_size; + ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) / + sizeof(struct disk_exception); ps->next_free = 2; /* skipping the header and first area */ ps->current_committed = 0; @@ -573,9 +543,18 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) if (r) goto bad; + /* + * Allocate space for all the callbacks. + */ ps->callback_count = 0; atomic_set(&ps->pending_count, 0); - ps->callbacks = NULL; + ps->callbacks = dm_vcalloc(ps->exceptions_per_area, + sizeof(*ps->callbacks)); + + if (!ps->callbacks) { + r = -ENOMEM; + goto bad; + } store->destroy = persistent_destroy; store->read_metadata = persistent_read_metadata; diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index 3edb3477f987..8edd6435414d 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. - * Copyright (C) 2004 - 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 - 2005 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -19,7 +19,6 @@ #include -#define DM_MSG_PREFIX "ioctl" #define DM_DRIVER_EMAIL "dm-devel@redhat.com" /*----------------------------------------------------------------- @@ -49,7 +48,7 @@ struct vers_iter { static struct list_head _name_buckets[NUM_BUCKETS]; static struct list_head _uuid_buckets[NUM_BUCKETS]; -static void dm_hash_remove_all(int keep_open_devices); +static void dm_hash_remove_all(void); /* * Guards access to both hash tables. @@ -74,7 +73,7 @@ static int dm_hash_init(void) static void dm_hash_exit(void) { - dm_hash_remove_all(0); + dm_hash_remove_all(); devfs_remove(DM_DIR); } @@ -103,10 +102,8 @@ static struct hash_cell *__get_name_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _name_buckets + h, name_list) - if (!strcmp(hc->name, str)) { - dm_get(hc->md); + if (!strcmp(hc->name, str)) return hc; - } return NULL; } @@ -117,10 +114,8 @@ static struct hash_cell *__get_uuid_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _uuid_buckets + h, uuid_list) - if (!strcmp(hc->uuid, str)) { - dm_get(hc->md); + if (!strcmp(hc->uuid, str)) return hc; - } return NULL; } @@ -196,7 +191,7 @@ static int unregister_with_devfs(struct hash_cell *hc) */ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) { - struct hash_cell *cell, *hc; + struct hash_cell *cell; /* * Allocate the new cells. @@ -209,19 +204,14 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi * Insert the cell into both hash tables. */ down_write(&_hash_lock); - hc = __get_name_cell(name); - if (hc) { - dm_put(hc->md); + if (__get_name_cell(name)) goto bad; - } list_add(&cell->name_list, _name_buckets + hash_str(name)); if (uuid) { - hc = __get_uuid_cell(uuid); - if (hc) { + if (__get_uuid_cell(uuid)) { list_del(&cell->name_list); - dm_put(hc->md); goto bad; } list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); @@ -261,41 +251,19 @@ static void __hash_remove(struct hash_cell *hc) free_cell(hc); } -static void dm_hash_remove_all(int keep_open_devices) +static void dm_hash_remove_all(void) { - int i, dev_skipped, dev_removed; + int i; struct hash_cell *hc; struct list_head *tmp, *n; 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); - - if (keep_open_devices && - dm_lock_for_deletion(hc->md)) { - dev_skipped++; - continue; - } __hash_remove(hc); - dev_removed = 1; } } - - /* - * 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); } @@ -321,7 +289,6 @@ static int dm_hash_rename(const char *old, const char *new) if (hc) { DMWARN("asked to rename to an already existing name %s -> %s", old, new); - dm_put(hc->md); up_write(&_hash_lock); kfree(new_name); return -EBUSY; @@ -361,7 +328,6 @@ static int dm_hash_rename(const char *old, const char *new) dm_table_put(table); } - dm_put(hc->md); up_write(&_hash_lock); kfree(old_name); return 0; @@ -378,7 +344,7 @@ typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size); static int remove_all(struct dm_ioctl *param, size_t param_size) { - dm_hash_remove_all(1); + dm_hash_remove_all(); param->data_size = 0; return 0; } @@ -558,6 +524,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) { struct gendisk *disk = dm_disk(md); struct dm_table *table; + struct block_device *bdev; param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | DM_ACTIVE_PRESENT_FLAG); @@ -567,12 +534,20 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); - /* - * Yes, this will be out of date by the time it gets back - * to userland, but it is still very useful for - * debugging. - */ - param->open_count = dm_open_count(md); + if (!(param->flags & DM_SKIP_BDGET_FLAG)) { + bdev = bdget_disk(disk, 0); + if (!bdev) + return -ENXIO; + + /* + * Yes, this will be out of date by the time it gets back + * to userland, but it is still very useful for + * debugging. + */ + param->open_count = bdev->bd_openers; + bdput(bdev); + } else + param->open_count = -1; if (disk->policy) param->flags |= DM_READONLY_FLAG; @@ -592,7 +567,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) static int dev_create(struct dm_ioctl *param, size_t param_size) { - int r, m = DM_ANY_MINOR; + int r; struct mapped_device *md; r = check_name(param->name); @@ -600,9 +575,10 @@ static int dev_create(struct dm_ioctl *param, size_t param_size) return r; if (param->flags & DM_PERSISTENT_DEV_FLAG) - m = MINOR(huge_decode_dev(param->dev)); + r = dm_create_with_minor(MINOR(huge_decode_dev(param->dev)), &md); + else + r = dm_create(&md); - r = dm_create(m, &md); if (r) return r; @@ -635,8 +611,10 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) return __get_name_cell(param->name); md = dm_get_md(huge_decode_dev(param->dev)); - if (md) + if (md) { mdptr = dm_get_mdptr(md); + dm_put(md); + } return mdptr; } @@ -650,6 +628,7 @@ static struct mapped_device *find_device(struct dm_ioctl *param) hc = __find_device_hash_cell(param); if (hc) { md = hc->md; + dm_get(md); /* * Sneakily write in both the name and the uuid @@ -674,8 +653,6 @@ static struct mapped_device *find_device(struct dm_ioctl *param) static int dev_remove(struct dm_ioctl *param, size_t param_size) { struct hash_cell *hc; - struct mapped_device *md; - int r; down_write(&_hash_lock); hc = __find_device_hash_cell(param); @@ -686,22 +663,8 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) return -ENXIO; } - md = hc->md; - - /* - * Ensure the device is not open and nothing further can open it. - */ - r = dm_lock_for_deletion(md); - if (r) { - DMWARN("unable to remove open device %s", hc->name); - up_write(&_hash_lock); - dm_put(md); - return r; - } - __hash_remove(hc); up_write(&_hash_lock); - dm_put(md); param->data_size = 0; return 0; } @@ -827,6 +790,7 @@ static int do_resume(struct dm_ioctl *param) } md = hc->md; + dm_get(md); new_map = hc->new_map; hc->new_map = NULL; @@ -1114,7 +1078,6 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) { int r; struct hash_cell *hc; - struct mapped_device *md; down_write(&_hash_lock); @@ -1133,9 +1096,7 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) param->flags &= ~DM_INACTIVE_PRESENT_FLAG; r = __dev_status(hc->md, param); - md = hc->md; up_write(&_hash_lock); - dm_put(md); return r; } diff --git a/trunk/drivers/md/dm-linear.c b/trunk/drivers/md/dm-linear.c index 47b3c62bbdb8..daf586c0898d 100644 --- a/trunk/drivers/md/dm-linear.c +++ b/trunk/drivers/md/dm-linear.c @@ -12,8 +12,6 @@ #include #include -#define DM_MSG_PREFIX "linear" - /* * Linear: maps a linear range of a device. */ @@ -31,7 +29,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) unsigned long long tmp; if (argc != 2) { - ti->error = "Invalid argument count"; + ti->error = "dm-linear: Invalid argument count"; return -EINVAL; } @@ -113,7 +111,7 @@ int __init dm_linear_init(void) int r = dm_register_target(&linear_target); if (r < 0) - DMERR("register failed %d", r); + DMERR("linear: register failed %d", r); return r; } @@ -123,5 +121,5 @@ void dm_linear_exit(void) int r = dm_unregister_target(&linear_target); if (r < 0) - DMERR("unregister failed %d", r); + DMERR("linear: unregister failed %d", r); } diff --git a/trunk/drivers/md/dm-log.c b/trunk/drivers/md/dm-log.c index 64b764bd02cc..d73779a42417 100644 --- a/trunk/drivers/md/dm-log.c +++ b/trunk/drivers/md/dm-log.c @@ -12,8 +12,6 @@ #include "dm-log.h" #include "dm-io.h" -#define DM_MSG_PREFIX "mirror log" - static LIST_HEAD(_log_types); static DEFINE_SPINLOCK(_lock); @@ -157,6 +155,8 @@ struct log_c { struct io_region header_location; struct log_header *disk_header; + + struct io_region bits_location; }; /* @@ -240,22 +240,44 @@ static inline int write_header(struct log_c *log) log->disk_header, &ebits); } +/*---------------------------------------------------------------- + * Bits IO + *--------------------------------------------------------------*/ +static int read_bits(struct log_c *log) +{ + int r; + unsigned long ebits; + + r = dm_io_sync_vm(1, &log->bits_location, READ, + log->clean_bits, &ebits); + if (r) + return r; + + return 0; +} + +static int write_bits(struct log_c *log) +{ + unsigned long ebits; + return dm_io_sync_vm(1, &log->bits_location, WRITE, + log->clean_bits, &ebits); +} + /*---------------------------------------------------------------- * core log constructor/destructor * * argv contains region_size followed optionally by [no]sync *--------------------------------------------------------------*/ #define BYTE_SHIFT 3 -static int create_log_context(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv, - struct dm_dev *dev) +static int core_ctr(struct dirty_log *log, struct dm_target *ti, + unsigned int argc, char **argv) { enum sync sync = DEFAULTSYNC; struct log_c *lc; uint32_t region_size; unsigned int region_count; - size_t bitset_size, buf_size; + size_t bitset_size; if (argc < 1 || argc > 2) { DMWARN("wrong number of arguments to mirror log"); @@ -297,53 +319,22 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, * Work out how many "unsigned long"s we need to hold the bitset. */ bitset_size = dm_round_up(region_count, - sizeof(*lc->clean_bits) << BYTE_SHIFT); + sizeof(unsigned long) << BYTE_SHIFT); bitset_size >>= BYTE_SHIFT; - lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits); - - /* - * Disk log? - */ - if (!dev) { - lc->clean_bits = vmalloc(bitset_size); - if (!lc->clean_bits) { - DMWARN("couldn't allocate clean bitset"); - kfree(lc); - return -ENOMEM; - } - lc->disk_header = NULL; - } else { - lc->log_dev = dev; - lc->header_location.bdev = lc->log_dev->bdev; - lc->header_location.sector = 0; - - /* - * Buffer holds both header and bitset. - */ - buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) + - bitset_size, ti->limits.hardsect_size); - lc->header_location.count = buf_size >> SECTOR_SHIFT; - - lc->disk_header = vmalloc(buf_size); - if (!lc->disk_header) { - DMWARN("couldn't allocate disk log buffer"); - kfree(lc); - return -ENOMEM; - } - - lc->clean_bits = (void *)lc->disk_header + - (LOG_OFFSET << SECTOR_SHIFT); + lc->bitset_uint32_count = bitset_size / 4; + lc->clean_bits = vmalloc(bitset_size); + if (!lc->clean_bits) { + DMWARN("couldn't allocate clean bitset"); + kfree(lc); + return -ENOMEM; } - memset(lc->clean_bits, -1, bitset_size); lc->sync_bits = vmalloc(bitset_size); if (!lc->sync_bits) { DMWARN("couldn't allocate sync bitset"); - if (!dev) - vfree(lc->clean_bits); - vfree(lc->disk_header); + vfree(lc->clean_bits); kfree(lc); return -ENOMEM; } @@ -354,38 +345,23 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, if (!lc->recovering_bits) { DMWARN("couldn't allocate sync bitset"); vfree(lc->sync_bits); - if (!dev) - vfree(lc->clean_bits); - vfree(lc->disk_header); + vfree(lc->clean_bits); kfree(lc); return -ENOMEM; } memset(lc->recovering_bits, 0, bitset_size); lc->sync_search = 0; log->context = lc; - return 0; } -static int core_ctr(struct dirty_log *log, struct dm_target *ti, - unsigned int argc, char **argv) -{ - return create_log_context(log, ti, argc, argv, NULL); -} - -static void destroy_log_context(struct log_c *lc) -{ - vfree(lc->sync_bits); - vfree(lc->recovering_bits); - kfree(lc); -} - static void core_dtr(struct dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; - vfree(lc->clean_bits); - destroy_log_context(lc); + vfree(lc->sync_bits); + vfree(lc->recovering_bits); + kfree(lc); } /*---------------------------------------------------------------- @@ -397,6 +373,8 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, unsigned int argc, char **argv) { int r; + size_t size; + struct log_c *lc; struct dm_dev *dev; if (argc < 2 || argc > 3) { @@ -409,22 +387,49 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, if (r) return r; - r = create_log_context(log, ti, argc - 1, argv + 1, dev); + r = core_ctr(log, ti, argc - 1, argv + 1); if (r) { dm_put_device(ti, dev); return r; } + lc = (struct log_c *) log->context; + lc->log_dev = dev; + + /* setup the disk header fields */ + lc->header_location.bdev = lc->log_dev->bdev; + lc->header_location.sector = 0; + lc->header_location.count = 1; + + /* + * We can't read less than this amount, even though we'll + * not be using most of this space. + */ + lc->disk_header = vmalloc(1 << SECTOR_SHIFT); + if (!lc->disk_header) + goto bad; + + /* setup the disk bitset fields */ + lc->bits_location.bdev = lc->log_dev->bdev; + lc->bits_location.sector = LOG_OFFSET; + + size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t), + 1 << SECTOR_SHIFT); + lc->bits_location.count = size >> SECTOR_SHIFT; return 0; + + bad: + dm_put_device(ti, lc->log_dev); + core_dtr(log); + return -ENOMEM; } static void disk_dtr(struct dirty_log *log) { struct log_c *lc = (struct log_c *) log->context; - dm_put_device(lc->ti, lc->log_dev); vfree(lc->disk_header); - destroy_log_context(lc); + core_dtr(log); } static int count_bits32(uint32_t *addr, unsigned size) @@ -449,7 +454,12 @@ static int disk_resume(struct dirty_log *log) if (r) return r; - /* set or clear any new bits -- device has grown */ + /* read the bits */ + r = read_bits(lc); + if (r) + return r; + + /* set or clear any new bits */ if (lc->sync == NOSYNC) for (i = lc->header.nr_regions; i < lc->region_count; i++) /* FIXME: amazingly inefficient */ @@ -459,14 +469,15 @@ static int disk_resume(struct dirty_log *log) /* FIXME: amazingly inefficient */ log_clear_bit(lc, lc->clean_bits, i); - /* clear any old bits -- device has shrunk */ - for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++) - log_clear_bit(lc, lc->clean_bits, i); - /* copy clean across to sync */ memcpy(lc->sync_bits, lc->clean_bits, size); lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count); + /* write the bits */ + r = write_bits(lc); + if (r) + return r; + /* set the correct number of regions in the header */ lc->header.nr_regions = lc->region_count; @@ -507,7 +518,7 @@ static int disk_flush(struct dirty_log *log) if (!lc->touched) return 0; - r = write_header(lc); + r = write_bits(lc); if (!r) lc->touched = 0; diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 217615b33223..1816f30678ed 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -21,7 +21,6 @@ #include #include -#define DM_MSG_PREFIX "multipath" #define MESG_STR(x) x, sizeof(x) /* Path properties */ @@ -447,6 +446,8 @@ struct param { char *error; }; +#define ESTR(s) ("dm-multipath: " s) + static int read_param(struct param *param, char *str, unsigned *v, char **error) { if (!str || @@ -494,12 +495,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, unsigned ps_argc; static struct param _params[] = { - {0, 1024, "invalid number of path selector args"}, + {0, 1024, ESTR("invalid number of path selector args")}, }; pst = dm_get_path_selector(shift(as)); if (!pst) { - ti->error = "unknown path selector type"; + ti->error = ESTR("unknown path selector type"); return -EINVAL; } @@ -510,7 +511,7 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, r = pst->create(&pg->ps, ps_argc, as->argv); if (r) { dm_put_path_selector(pst); - ti->error = "path selector constructor failed"; + ti->error = ESTR("path selector constructor failed"); return r; } @@ -528,7 +529,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, /* we need at least a path arg */ if (as->argc < 1) { - ti->error = "no device given"; + ti->error = ESTR("no device given"); return NULL; } @@ -539,7 +540,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, r = dm_get_device(ti, shift(as), ti->begin, ti->len, dm_table_get_mode(ti->table), &p->path.dev); if (r) { - ti->error = "error getting device"; + ti->error = ESTR("error getting device"); goto bad; } @@ -561,8 +562,8 @@ static struct priority_group *parse_priority_group(struct arg_set *as, struct dm_target *ti) { static struct param _params[] = { - {1, 1024, "invalid number of paths"}, - {0, 1024, "invalid number of selector args"} + {1, 1024, ESTR("invalid number of paths")}, + {0, 1024, ESTR("invalid number of selector args")} }; int r; @@ -571,13 +572,13 @@ static struct priority_group *parse_priority_group(struct arg_set *as, if (as->argc < 2) { as->argc = 0; - ti->error = "not enough priority group aruments"; + ti->error = ESTR("not enough priority group aruments"); return NULL; } pg = alloc_priority_group(); if (!pg) { - ti->error = "couldn't allocate priority group"; + ti->error = ESTR("couldn't allocate priority group"); return NULL; } pg->m = m; @@ -632,7 +633,7 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m, unsigned hw_argc; static struct param _params[] = { - {0, 1024, "invalid number of hardware handler args"}, + {0, 1024, ESTR("invalid number of hardware handler args")}, }; r = read_param(_params, shift(as), &hw_argc, &ti->error); @@ -644,14 +645,14 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m, hwht = dm_get_hw_handler(shift(as)); if (!hwht) { - ti->error = "unknown hardware handler type"; + ti->error = ESTR("unknown hardware handler type"); return -EINVAL; } r = hwht->create(&m->hw_handler, hw_argc - 1, as->argv); if (r) { dm_put_hw_handler(hwht); - ti->error = "hardware handler constructor failed"; + ti->error = ESTR("hardware handler constructor failed"); return r; } @@ -668,7 +669,7 @@ static int parse_features(struct arg_set *as, struct multipath *m, unsigned argc; static struct param _params[] = { - {0, 1, "invalid number of feature args"}, + {0, 1, ESTR("invalid number of feature args")}, }; r = read_param(_params, shift(as), &argc, &ti->error); @@ -691,8 +692,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, { /* target parameters */ static struct param _params[] = { - {1, 1024, "invalid number of priority groups"}, - {1, 1024, "invalid initial priority group number"}, + {1, 1024, ESTR("invalid number of priority groups")}, + {1, 1024, ESTR("invalid initial priority group number")}, }; int r; @@ -706,7 +707,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, m = alloc_multipath(); if (!m) { - ti->error = "can't allocate multipath"; + ti->error = ESTR("can't allocate multipath"); return -EINVAL; } @@ -745,7 +746,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, } if (pg_count != m->nr_priority_groups) { - ti->error = "priority group count mismatch"; + ti->error = ESTR("priority group count mismatch"); r = -EINVAL; goto bad; } @@ -806,7 +807,7 @@ static int fail_path(struct pgpath *pgpath) if (!pgpath->path.is_active) goto out; - DMWARN("Failing path %s.", pgpath->path.dev->name); + DMWARN("dm-multipath: Failing path %s.", pgpath->path.dev->name); pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path); pgpath->path.is_active = 0; @@ -1249,7 +1250,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) r = dm_get_device(ti, argv[1], ti->begin, ti->len, dm_table_get_mode(ti->table), &dev); if (r) { - DMWARN("message: error getting device %s", + DMWARN("dm-multipath message: error getting device %s", argv[1]); return -EINVAL; } @@ -1308,7 +1309,7 @@ static int __init dm_multipath_init(void) return -ENOMEM; } - DMINFO("version %u.%u.%u loaded", + DMINFO("dm-multipath version %u.%u.%u loaded", multipath_target.version[0], multipath_target.version[1], multipath_target.version[2]); diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index be48cedf986b..d12cf3e5e076 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -20,8 +20,6 @@ #include #include -#define DM_MSG_PREFIX "raid1" - static struct workqueue_struct *_kmirrord_wq; static struct work_struct _kmirrord_work; @@ -108,42 +106,12 @@ struct region { struct bio_list delayed_bios; }; - -/*----------------------------------------------------------------- - * Mirror set structures. - *---------------------------------------------------------------*/ -struct mirror { - atomic_t error_count; - struct dm_dev *dev; - sector_t offset; -}; - -struct mirror_set { - struct dm_target *ti; - struct list_head list; - struct region_hash rh; - struct kcopyd_client *kcopyd_client; - - spinlock_t lock; /* protects the next two lists */ - struct bio_list reads; - struct bio_list writes; - - /* recovery */ - region_t nr_regions; - int in_sync; - - struct mirror *default_mirror; /* Default mirror */ - - unsigned int nr_mirrors; - struct mirror mirror[0]; -}; - /* * Conversion fns */ static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio) { - return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift; + return bio->bi_sector >> rh->region_shift; } static inline sector_t region_to_sector(struct region_hash *rh, region_t region) @@ -490,9 +458,11 @@ static int __rh_recovery_prepare(struct region_hash *rh) /* Already quiesced ? */ if (atomic_read(®->pending)) list_del_init(®->list); - else - list_move(®->list, &rh->quiesced_regions); + else { + list_del_init(®->list); + list_add(®->list, &rh->quiesced_regions); + } spin_unlock_irq(&rh->region_lock); return 1; @@ -571,6 +541,35 @@ static void rh_start_recovery(struct region_hash *rh) wake(); } +/*----------------------------------------------------------------- + * Mirror set structures. + *---------------------------------------------------------------*/ +struct mirror { + atomic_t error_count; + struct dm_dev *dev; + sector_t offset; +}; + +struct mirror_set { + struct dm_target *ti; + struct list_head list; + struct region_hash rh; + struct kcopyd_client *kcopyd_client; + + spinlock_t lock; /* protects the next two lists */ + struct bio_list reads; + struct bio_list writes; + + /* recovery */ + region_t nr_regions; + int in_sync; + + struct mirror *default_mirror; /* Default mirror */ + + unsigned int nr_mirrors; + struct mirror mirror[0]; +}; + /* * Every mirror should look like this one. */ @@ -604,7 +603,7 @@ static void recovery_complete(int read_err, unsigned int write_err, struct region *reg = (struct region *) context; /* FIXME: better error handling */ - rh_recovery_end(reg, !(read_err || write_err)); + rh_recovery_end(reg, read_err || write_err); } static int recover(struct mirror_set *ms, struct region *reg) @@ -894,7 +893,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, ms = kmalloc(len, GFP_KERNEL); if (!ms) { - ti->error = "Cannot allocate mirror context"; + ti->error = "dm-mirror: Cannot allocate mirror context"; return NULL; } @@ -908,7 +907,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, ms->default_mirror = &ms->mirror[DEFAULT_MIRROR]; if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) { - ti->error = "Error creating dirty region hash"; + ti->error = "dm-mirror: Error creating dirty region hash"; kfree(ms); return NULL; } @@ -938,14 +937,14 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti, unsigned long long offset; if (sscanf(argv[1], "%llu", &offset) != 1) { - ti->error = "Invalid offset"; + ti->error = "dm-mirror: Invalid offset"; return -EINVAL; } if (dm_get_device(ti, argv[0], offset, ti->len, dm_table_get_mode(ti->table), &ms->mirror[mirror].dev)) { - ti->error = "Device lookup failure"; + ti->error = "dm-mirror: Device lookup failure"; return -ENXIO; } @@ -982,30 +981,30 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti, struct dirty_log *dl; if (argc < 2) { - ti->error = "Insufficient mirror log arguments"; + ti->error = "dm-mirror: Insufficient mirror log arguments"; return NULL; } if (sscanf(argv[1], "%u", ¶m_count) != 1) { - ti->error = "Invalid mirror log argument count"; + ti->error = "dm-mirror: Invalid mirror log argument count"; return NULL; } *args_used = 2 + param_count; if (argc < *args_used) { - ti->error = "Insufficient mirror log arguments"; + ti->error = "dm-mirror: Insufficient mirror log arguments"; return NULL; } dl = dm_create_dirty_log(argv[0], ti, param_count, argv + 2); if (!dl) { - ti->error = "Error creating mirror dirty log"; + ti->error = "dm-mirror: Error creating mirror dirty log"; return NULL; } if (!_check_region_size(ti, dl->type->get_region_size(dl))) { - ti->error = "Invalid region size"; + ti->error = "dm-mirror: Invalid region size"; dm_destroy_dirty_log(dl); return NULL; } @@ -1039,7 +1038,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || nr_mirrors < 2 || nr_mirrors > KCOPYD_MAX_REGIONS + 1) { - ti->error = "Invalid number of mirrors"; + ti->error = "dm-mirror: Invalid number of mirrors"; dm_destroy_dirty_log(dl); return -EINVAL; } @@ -1047,7 +1046,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) argv++, argc--; if (argc != nr_mirrors * 2) { - ti->error = "Wrong number of mirror arguments"; + ti->error = "dm-mirror: Wrong number of mirror arguments"; dm_destroy_dirty_log(dl); return -EINVAL; } @@ -1116,7 +1115,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, struct mirror *m; struct mirror_set *ms = ti->private; - map_context->ll = bio_to_region(&ms->rh, bio); + map_context->ll = bio->bi_sector >> ms->rh.region_shift; if (rw == WRITE) { queue_bio(ms, bio, rw); @@ -1222,7 +1221,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type, static struct target_type mirror_target = { .name = "mirror", - .version = {1, 0, 2}, + .version = {1, 0, 1}, .module = THIS_MODULE, .ctr = mirror_ctr, .dtr = mirror_dtr, diff --git a/trunk/drivers/md/dm-round-robin.c b/trunk/drivers/md/dm-round-robin.c index c5a16c550122..d0024865a789 100644 --- a/trunk/drivers/md/dm-round-robin.c +++ b/trunk/drivers/md/dm-round-robin.c @@ -14,8 +14,6 @@ #include -#define DM_MSG_PREFIX "multipath round-robin" - /*----------------------------------------------------------------- * Path-handling code, paths are held in lists *---------------------------------------------------------------*/ @@ -193,9 +191,9 @@ static int __init dm_rr_init(void) int r = dm_register_path_selector(&rr_ps); if (r < 0) - DMERR("register failed %d", r); + DMERR("round-robin: register failed %d", r); - DMINFO("version 1.0.0 loaded"); + DMINFO("dm-round-robin version 1.0.0 loaded"); return r; } diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index 8eea0ddbf5ec..08312b46463a 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -23,8 +23,6 @@ #include "dm-bio-list.h" #include "kcopyd.h" -#define DM_MSG_PREFIX "snapshots" - /* * The percentage increment we will wake up users at */ @@ -119,7 +117,7 @@ static int init_origin_hash(void) _origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), GFP_KERNEL); if (!_origins) { - DMERR("unable to allocate memory"); + DMERR("Device mapper: Snapshot: unable to allocate memory"); return -ENOMEM; } @@ -414,7 +412,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) int blocksize; if (argc < 4) { - ti->error = "requires exactly 4 arguments"; + ti->error = "dm-snapshot: requires exactly 4 arguments"; r = -EINVAL; goto bad1; } @@ -532,7 +530,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) } ti->private = s; - ti->split_io = s->chunk_size; + ti->split_io = chunk_size; return 0; @@ -1129,7 +1127,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv) struct dm_dev *dev; if (argc != 1) { - ti->error = "origin: incorrect number of arguments"; + ti->error = "dm-origin: incorrect number of arguments"; return -EINVAL; } @@ -1206,7 +1204,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, static struct target_type origin_target = { .name = "snapshot-origin", - .version = {1, 4, 0}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = origin_ctr, .dtr = origin_dtr, @@ -1217,7 +1215,7 @@ static struct target_type origin_target = { static struct target_type snapshot_target = { .name = "snapshot", - .version = {1, 4, 0}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, @@ -1238,7 +1236,7 @@ static int __init dm_snapshot_init(void) r = dm_register_target(&origin_target); if (r < 0) { - DMERR("Origin target register failed %d", r); + DMERR("Device mapper: Origin: register failed %d\n", r); goto bad1; } diff --git a/trunk/drivers/md/dm-stripe.c b/trunk/drivers/md/dm-stripe.c index 6c29fcecd892..08328a8f5a3c 100644 --- a/trunk/drivers/md/dm-stripe.c +++ b/trunk/drivers/md/dm-stripe.c @@ -12,8 +12,6 @@ #include #include -#define DM_MSG_PREFIX "striped" - struct stripe { struct dm_dev *dev; sector_t physical_start; @@ -80,19 +78,19 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) unsigned int i; if (argc < 2) { - ti->error = "Not enough arguments"; + ti->error = "dm-stripe: Not enough arguments"; return -EINVAL; } stripes = simple_strtoul(argv[0], &end, 10); if (*end) { - ti->error = "Invalid stripe count"; + ti->error = "dm-stripe: Invalid stripe count"; return -EINVAL; } chunk_size = simple_strtoul(argv[1], &end, 10); if (*end) { - ti->error = "Invalid chunk_size"; + ti->error = "dm-stripe: Invalid chunk_size"; return -EINVAL; } @@ -101,19 +99,19 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) */ if (!chunk_size || (chunk_size & (chunk_size - 1)) || (chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) { - ti->error = "Invalid chunk size"; + ti->error = "dm-stripe: Invalid chunk size"; return -EINVAL; } if (ti->len & (chunk_size - 1)) { - ti->error = "Target length not divisible by " + ti->error = "dm-stripe: Target length not divisible by " "chunk size"; return -EINVAL; } width = ti->len; if (sector_div(width, stripes)) { - ti->error = "Target length not divisible by " + ti->error = "dm-stripe: Target length not divisible by " "number of stripes"; return -EINVAL; } @@ -122,14 +120,14 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) * Do we have enough arguments for that many stripes ? */ if (argc != (2 + 2 * stripes)) { - ti->error = "Not enough destinations " + ti->error = "dm-stripe: Not enough destinations " "specified"; return -EINVAL; } sc = alloc_context(stripes); if (!sc) { - ti->error = "Memory allocation for striped context " + ti->error = "dm-stripe: Memory allocation for striped context " "failed"; return -ENOMEM; } @@ -151,7 +149,8 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = get_stripe(ti, sc, i, argv); if (r < 0) { - ti->error = "Couldn't parse stripe destination"; + ti->error = "dm-stripe: Couldn't parse stripe " + "destination"; while (i--) dm_put_device(ti, sc->stripe[i].dev); kfree(sc); @@ -228,7 +227,7 @@ int __init dm_stripe_init(void) r = dm_register_target(&stripe_target); if (r < 0) - DMWARN("target registration failed"); + DMWARN("striped target registration failed"); return r; } @@ -236,7 +235,7 @@ int __init dm_stripe_init(void) void dm_stripe_exit(void) { if (dm_unregister_target(&stripe_target)) - DMWARN("target unregistration failed"); + DMWARN("striped target unregistration failed"); return; } diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index 75fe9493e6af..8f56a54cf0ce 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -17,8 +17,6 @@ #include #include -#define DM_MSG_PREFIX "table" - #define MAX_DEPTH 16 #define NODE_SIZE L1_CACHE_BYTES #define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) @@ -239,44 +237,6 @@ int dm_table_create(struct dm_table **result, int mode, return 0; } -int dm_create_error_table(struct dm_table **result, struct mapped_device *md) -{ - struct dm_table *t; - sector_t dev_size = 1; - int r; - - /* - * Find current size of device. - * Default to 1 sector if inactive. - */ - t = dm_get_table(md); - if (t) { - dev_size = dm_table_get_size(t); - dm_table_put(t); - } - - r = dm_table_create(&t, FMODE_READ, 1, md); - if (r) - return r; - - r = dm_table_add_target(t, "error", 0, dev_size, NULL); - if (r) - goto out; - - r = dm_table_complete(t); - if (r) - goto out; - - *result = t; - -out: - if (r) - dm_table_put(t); - - return r; -} -EXPORT_SYMBOL_GPL(dm_create_error_table); - static void free_devices(struct list_head *devices) { struct list_head *tmp, *next; @@ -630,12 +590,6 @@ int dm_split_args(int *argc, char ***argvp, char *input) unsigned array_size = 0; *argc = 0; - - if (!input) { - *argvp = NULL; - return 0; - } - argv = realloc_argv(&array_size, argv); if (!argv) return -ENOMEM; @@ -717,14 +671,15 @@ int dm_table_add_target(struct dm_table *t, const char *type, memset(tgt, 0, sizeof(*tgt)); if (!len) { - DMERR("%s: zero-length target", dm_device_name(t->md)); + tgt->error = "zero-length target"; + DMERR("%s", tgt->error); return -EINVAL; } tgt->type = dm_get_target_type(type); if (!tgt->type) { - DMERR("%s: %s: unknown target type", dm_device_name(t->md), - type); + tgt->error = "unknown target type"; + DMERR("%s", tgt->error); return -EINVAL; } @@ -761,7 +716,7 @@ int dm_table_add_target(struct dm_table *t, const char *type, return 0; bad: - DMERR("%s: %s: %s", dm_device_name(t->md), type, tgt->error); + DMERR("%s", tgt->error); dm_put_target_type(tgt->type); return r; } @@ -847,7 +802,7 @@ sector_t dm_table_get_size(struct dm_table *t) struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index) { - if (index >= t->num_targets) + if (index > t->num_targets) return NULL; return t->targets + index; diff --git a/trunk/drivers/md/dm-target.c b/trunk/drivers/md/dm-target.c index 477a041a41cf..64fd8e79ea4c 100644 --- a/trunk/drivers/md/dm-target.c +++ b/trunk/drivers/md/dm-target.c @@ -12,8 +12,6 @@ #include #include -#define DM_MSG_PREFIX "target" - struct tt_internal { struct target_type tt; diff --git a/trunk/drivers/md/dm-zero.c b/trunk/drivers/md/dm-zero.c index ea569f7348d2..51c0639b2487 100644 --- a/trunk/drivers/md/dm-zero.c +++ b/trunk/drivers/md/dm-zero.c @@ -10,15 +10,13 @@ #include #include -#define DM_MSG_PREFIX "zero" - /* * Construct a dummy mapping that only returns zeros */ static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv) { if (argc != 0) { - ti->error = "No arguments required"; + ti->error = "dm-zero: No arguments required"; return -EINVAL; } @@ -62,7 +60,7 @@ static int __init dm_zero_init(void) int r = dm_register_target(&zero_target); if (r < 0) - DMERR("register failed %d", r); + DMERR("zero: register failed %d", r); return r; } @@ -72,7 +70,7 @@ static void __exit dm_zero_exit(void) int r = dm_unregister_target(&zero_target); if (r < 0) - DMERR("unregister failed %d", r); + DMERR("zero: unregister failed %d", r); } module_init(dm_zero_init) diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 3ed2e53b9eb6..4d710b7a133b 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -21,14 +21,11 @@ #include #include -#define DM_MSG_PREFIX "core" - static const char *_name = DM_NAME; static unsigned int major = 0; static unsigned int _major = 0; -static DEFINE_SPINLOCK(_minor_lock); /* * One of these is allocated per bio. */ @@ -52,28 +49,23 @@ struct target_io { union map_info *dm_get_mapinfo(struct bio *bio) { - if (bio && bio->bi_private) - return &((struct target_io *)bio->bi_private)->info; - return NULL; + if (bio && bio->bi_private) + return &((struct target_io *)bio->bi_private)->info; + return NULL; } -#define MINOR_ALLOCED ((void *)-1) - /* * Bits for the md->flags field. */ #define DMF_BLOCK_IO 0 #define DMF_SUSPENDED 1 #define DMF_FROZEN 2 -#define DMF_FREEING 3 -#define DMF_DELETING 4 struct mapped_device { struct rw_semaphore io_lock; struct semaphore suspend_lock; rwlock_t map_lock; atomic_t holders; - atomic_t open_count; unsigned long flags; @@ -226,25 +218,9 @@ static int dm_blk_open(struct inode *inode, struct file *file) { struct mapped_device *md; - spin_lock(&_minor_lock); - md = inode->i_bdev->bd_disk->private_data; - if (!md) - goto out; - - if (test_bit(DMF_FREEING, &md->flags) || - test_bit(DMF_DELETING, &md->flags)) { - md = NULL; - goto out; - } - dm_get(md); - atomic_inc(&md->open_count); - -out: - spin_unlock(&_minor_lock); - - return md ? 0 : -ENXIO; + return 0; } static int dm_blk_close(struct inode *inode, struct file *file) @@ -252,35 +228,10 @@ static int dm_blk_close(struct inode *inode, struct file *file) struct mapped_device *md; md = inode->i_bdev->bd_disk->private_data; - atomic_dec(&md->open_count); dm_put(md); return 0; } -int dm_open_count(struct mapped_device *md) -{ - return atomic_read(&md->open_count); -} - -/* - * Guarantees nothing is using the device before it's deleted. - */ -int dm_lock_for_deletion(struct mapped_device *md) -{ - int r = 0; - - spin_lock(&_minor_lock); - - if (dm_open_count(md)) - r = -EBUSY; - else - set_bit(DMF_DELETING, &md->flags); - - spin_unlock(&_minor_lock); - - return r; -} - static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) { struct mapped_device *md = bdev->bd_disk->private_data; @@ -505,8 +456,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, if (r > 0) { /* the bio has been remapped so dispatch it */ - blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, sector, + blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, + tio->io->bio->bi_bdev->bd_dev, sector, clone->bi_sector); generic_make_request(clone); @@ -793,39 +744,43 @@ static int dm_any_congested(void *congested_data, int bdi_bits) /*----------------------------------------------------------------- * An IDR is used to keep track of allocated minor numbers. *---------------------------------------------------------------*/ +static DEFINE_MUTEX(_minor_lock); static DEFINE_IDR(_minor_idr); -static void free_minor(int minor) +static void free_minor(unsigned int minor) { - spin_lock(&_minor_lock); + mutex_lock(&_minor_lock); idr_remove(&_minor_idr, minor); - spin_unlock(&_minor_lock); + mutex_unlock(&_minor_lock); } /* * See if the device with a specific minor # is free. */ -static int specific_minor(struct mapped_device *md, int minor) +static int specific_minor(struct mapped_device *md, unsigned int minor) { int r, m; if (minor >= (1 << MINORBITS)) return -EINVAL; - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) - return -ENOMEM; - - spin_lock(&_minor_lock); + mutex_lock(&_minor_lock); if (idr_find(&_minor_idr, minor)) { r = -EBUSY; goto out; } - r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m); - if (r) + r = idr_pre_get(&_minor_idr, GFP_KERNEL); + if (!r) { + r = -ENOMEM; + goto out; + } + + r = idr_get_new_above(&_minor_idr, md, minor, &m); + if (r) { goto out; + } if (m != minor) { idr_remove(&_minor_idr, m); @@ -834,21 +789,24 @@ static int specific_minor(struct mapped_device *md, int minor) } out: - spin_unlock(&_minor_lock); + mutex_unlock(&_minor_lock); return r; } -static int next_free_minor(struct mapped_device *md, int *minor) +static int next_free_minor(struct mapped_device *md, unsigned int *minor) { - int r, m; + int r; + unsigned int m; - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) - return -ENOMEM; + mutex_lock(&_minor_lock); - spin_lock(&_minor_lock); + r = idr_pre_get(&_minor_idr, GFP_KERNEL); + if (!r) { + r = -ENOMEM; + goto out; + } - r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); + r = idr_get_new(&_minor_idr, md, &m); if (r) { goto out; } @@ -862,7 +820,7 @@ static int next_free_minor(struct mapped_device *md, int *minor) *minor = m; out: - spin_unlock(&_minor_lock); + mutex_unlock(&_minor_lock); return r; } @@ -871,25 +829,18 @@ static struct block_device_operations dm_blk_dops; /* * Allocate and initialise a blank device with a given minor. */ -static struct mapped_device *alloc_dev(int minor) +static struct mapped_device *alloc_dev(unsigned int minor, int persistent) { int r; struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); - void *old_md; if (!md) { DMWARN("unable to allocate device, out of memory."); return NULL; } - if (!try_module_get(THIS_MODULE)) - goto bad0; - /* get a minor number for the dev */ - if (minor == DM_ANY_MINOR) - r = next_free_minor(md, &minor); - else - r = specific_minor(md, minor); + r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor); if (r < 0) goto bad1; @@ -898,7 +849,6 @@ static struct mapped_device *alloc_dev(int minor) init_MUTEX(&md->suspend_lock); rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); - atomic_set(&md->open_count, 0); atomic_set(&md->event_nr, 0); md->queue = blk_alloc_queue(GFP_KERNEL); @@ -925,10 +875,6 @@ static struct mapped_device *alloc_dev(int minor) if (!md->disk) goto bad4; - atomic_set(&md->pending, 0); - init_waitqueue_head(&md->wait); - init_waitqueue_head(&md->eventq); - md->disk->major = _major; md->disk->first_minor = minor; md->disk->fops = &dm_blk_dops; @@ -938,12 +884,9 @@ static struct mapped_device *alloc_dev(int minor) add_disk(md->disk); format_dev_t(md->name, MKDEV(_major, minor)); - /* Populate the mapping, nobody knows we exist yet */ - spin_lock(&_minor_lock); - old_md = idr_replace(&_minor_idr, md, minor); - spin_unlock(&_minor_lock); - - BUG_ON(old_md != MINOR_ALLOCED); + atomic_set(&md->pending, 0); + init_waitqueue_head(&md->wait); + init_waitqueue_head(&md->eventq); return md; @@ -955,15 +898,13 @@ static struct mapped_device *alloc_dev(int minor) blk_cleanup_queue(md->queue); free_minor(minor); bad1: - module_put(THIS_MODULE); - bad0: kfree(md); return NULL; } static void free_dev(struct mapped_device *md) { - int minor = md->disk->first_minor; + unsigned int minor = md->disk->first_minor; if (md->suspended_bdev) { thaw_bdev(md->suspended_bdev, NULL); @@ -973,14 +914,8 @@ static void free_dev(struct mapped_device *md) mempool_destroy(md->io_pool); del_gendisk(md->disk); free_minor(minor); - - spin_lock(&_minor_lock); - md->disk->private_data = NULL; - spin_unlock(&_minor_lock); - put_disk(md->disk); blk_cleanup_queue(md->queue); - module_put(THIS_MODULE); kfree(md); } @@ -1049,11 +984,12 @@ static void __unbind(struct mapped_device *md) /* * Constructor for a new device. */ -int dm_create(int minor, struct mapped_device **result) +static int create_aux(unsigned int minor, int persistent, + struct mapped_device **result) { struct mapped_device *md; - md = alloc_dev(minor); + md = alloc_dev(minor, persistent); if (!md) return -ENXIO; @@ -1061,6 +997,16 @@ int dm_create(int minor, struct mapped_device **result) return 0; } +int dm_create(struct mapped_device **result) +{ + return create_aux(0, 0, result); +} + +int dm_create_with_minor(unsigned int minor, struct mapped_device **result) +{ + return create_aux(minor, 1, result); +} + static struct mapped_device *dm_find_md(dev_t dev) { struct mapped_device *md; @@ -1069,18 +1015,13 @@ static struct mapped_device *dm_find_md(dev_t dev) if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) return NULL; - spin_lock(&_minor_lock); + mutex_lock(&_minor_lock); md = idr_find(&_minor_idr, minor); - if (md && (md == MINOR_ALLOCED || - (dm_disk(md)->first_minor != minor) || - test_bit(DMF_FREEING, &md->flags))) { + if (!md || (dm_disk(md)->first_minor != minor)) md = NULL; - goto out; - } -out: - spin_unlock(&_minor_lock); + mutex_unlock(&_minor_lock); return md; } @@ -1110,23 +1051,12 @@ void dm_get(struct mapped_device *md) atomic_inc(&md->holders); } -const char *dm_device_name(struct mapped_device *md) -{ - return md->name; -} -EXPORT_SYMBOL_GPL(dm_device_name); - void dm_put(struct mapped_device *md) { struct dm_table *map; - BUG_ON(test_bit(DMF_FREEING, &md->flags)); - - if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { + if (atomic_dec_and_test(&md->holders)) { map = dm_get_table(md); - idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); - set_bit(DMF_FREEING, &md->flags); - spin_unlock(&_minor_lock); if (!dm_suspended(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); diff --git a/trunk/drivers/md/dm.h b/trunk/drivers/md/dm.h index 3c03c0ecab7e..fd90bc8f9e45 100644 --- a/trunk/drivers/md/dm.h +++ b/trunk/drivers/md/dm.h @@ -2,7 +2,7 @@ * Internal header file for device mapper * * Copyright (C) 2001, 2002 Sistina Software - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. * * This file is released under the LGPL. */ @@ -17,10 +17,9 @@ #include #define DM_NAME "device-mapper" - -#define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) -#define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) -#define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) +#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x) +#define DMERR(f, x...) printk(KERN_ERR DM_NAME ": " f "\n" , ## x) +#define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x) #define DMEMIT(x...) sz += ((sz >= maxlen) ? \ 0 : scnprintf(result + sz, maxlen - sz, x)) @@ -40,16 +39,83 @@ struct dm_dev { }; struct dm_table; +struct mapped_device; + +/*----------------------------------------------------------------- + * Functions for manipulating a struct mapped_device. + * Drop the reference with dm_put when you finish with the object. + *---------------------------------------------------------------*/ +int dm_create(struct mapped_device **md); +int dm_create_with_minor(unsigned int minor, struct mapped_device **md); +void dm_set_mdptr(struct mapped_device *md, void *ptr); +void *dm_get_mdptr(struct mapped_device *md); +struct mapped_device *dm_get_md(dev_t dev); + +/* + * Reference counting for md. + */ +void dm_get(struct mapped_device *md); +void dm_put(struct mapped_device *md); + +/* + * A device can still be used while suspended, but I/O is deferred. + */ +int dm_suspend(struct mapped_device *md, int with_lockfs); +int dm_resume(struct mapped_device *md); + +/* + * The device must be suspended before calling this method. + */ +int dm_swap_table(struct mapped_device *md, struct dm_table *t); + +/* + * Drop a reference on the table when you've finished with the + * result. + */ +struct dm_table *dm_get_table(struct mapped_device *md); + +/* + * Event functions. + */ +uint32_t dm_get_event_nr(struct mapped_device *md); +int dm_wait_event(struct mapped_device *md, int event_nr); + +/* + * Info functions. + */ +struct gendisk *dm_disk(struct mapped_device *md); +int dm_suspended(struct mapped_device *md); + +/* + * Geometry functions. + */ +int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); +int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); /*----------------------------------------------------------------- - * Internal table functions. + * Functions for manipulating a table. Tables are also reference + * counted. *---------------------------------------------------------------*/ +int dm_table_create(struct dm_table **result, int mode, + unsigned num_targets, struct mapped_device *md); + +void dm_table_get(struct dm_table *t); +void dm_table_put(struct dm_table *t); + +int dm_table_add_target(struct dm_table *t, const char *type, + sector_t start, sector_t len, char *params); +int dm_table_complete(struct dm_table *t); void dm_table_event_callback(struct dm_table *t, void (*fn)(void *), void *context); +void dm_table_event(struct dm_table *t); +sector_t dm_table_get_size(struct dm_table *t); struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index); struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector); void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); +unsigned int dm_table_get_num_targets(struct dm_table *t); struct list_head *dm_table_get_devices(struct dm_table *t); +int dm_table_get_mode(struct dm_table *t); +struct mapped_device *dm_table_get_md(struct dm_table *t); void dm_table_presuspend_targets(struct dm_table *t); void dm_table_postsuspend_targets(struct dm_table *t); void dm_table_resume_targets(struct dm_table *t); @@ -67,6 +133,7 @@ void dm_put_target_type(struct target_type *t); int dm_target_iterate(void (*iter_func)(struct target_type *tt, void *param), void *param); + /*----------------------------------------------------------------- * Useful inlines. *---------------------------------------------------------------*/ @@ -124,7 +191,5 @@ void dm_stripe_exit(void); void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); union map_info *dm_get_mapinfo(struct bio *bio); -int dm_open_count(struct mapped_device *md); -int dm_lock_for_deletion(struct mapped_device *md); #endif diff --git a/trunk/drivers/md/kcopyd.c b/trunk/drivers/md/kcopyd.c index 73ab875fb158..72480a48d88b 100644 --- a/trunk/drivers/md/kcopyd.c +++ b/trunk/drivers/md/kcopyd.c @@ -314,7 +314,7 @@ static void complete_io(unsigned long error, void *context) if (error) { if (job->rw == WRITE) - job->write_err |= error; + job->write_err &= error; else job->read_err = 1; @@ -460,7 +460,7 @@ static void segment_complete(int read_err, job->read_err = 1; if (write_err) - job->write_err |= write_err; + job->write_err &= write_err; /* * Only dispatch more work if there hasn't been an error. diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index ff83c9b5979e..777585458c85 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -111,7 +111,7 @@ static int linear_issue_flush(request_queue_t *q, struct gendisk *disk, return ret; } -static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) +static int linear_run (mddev_t *mddev) { linear_conf_t *conf; dev_info_t **table; @@ -121,21 +121,20 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) sector_t curr_offset; struct list_head *tmp; - conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), + conf = kzalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t), GFP_KERNEL); if (!conf) - return NULL; - + goto out; mddev->private = conf; cnt = 0; - conf->array_size = 0; + mddev->array_size = 0; ITERATE_RDEV(mddev,rdev,tmp) { int j = rdev->raid_disk; dev_info_t *disk = conf->disks + j; - if (j < 0 || j > raid_disks || disk->rdev) { + if (j < 0 || j > mddev->raid_disks || disk->rdev) { printk("linear: disk numbering problem. Aborting!\n"); goto out; } @@ -153,11 +152,11 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); disk->size = rdev->size; - conf->array_size += rdev->size; + mddev->array_size += rdev->size; cnt++; } - if (cnt != raid_disks) { + if (cnt != mddev->raid_disks) { printk("linear: not enough drives present. Aborting!\n"); goto out; } @@ -201,7 +200,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) unsigned round; unsigned long base; - sz = conf->array_size >> conf->preshift; + sz = mddev->array_size >> conf->preshift; sz += 1; /* force round-up */ base = conf->hash_spacing >> conf->preshift; round = sector_div(sz, base); @@ -248,56 +247,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) BUG_ON(table - conf->hash_table > nb_zone); - return conf; - -out: - kfree(conf); - return NULL; -} - -static int linear_run (mddev_t *mddev) -{ - linear_conf_t *conf; - - conf = linear_conf(mddev, mddev->raid_disks); - - if (!conf) - return 1; - mddev->private = conf; - mddev->array_size = conf->array_size; - blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); mddev->queue->unplug_fn = linear_unplug; mddev->queue->issue_flush_fn = linear_issue_flush; return 0; -} - -static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev) -{ - /* Adding a drive to a linear array allows the array to grow. - * It is permitted if the new drive has a matching superblock - * already on it, with raid_disk equal to raid_disks. - * It is achieved by creating a new linear_private_data structure - * and swapping it in in-place of the current one. - * The current one is never freed until the array is stopped. - * This avoids races. - */ - linear_conf_t *newconf; - - if (rdev->raid_disk != mddev->raid_disks) - return -EINVAL; - newconf = linear_conf(mddev,mddev->raid_disks+1); - - if (!newconf) - return -ENOMEM; - - newconf->prev = mddev_to_conf(mddev); - mddev->private = newconf; - mddev->raid_disks++; - mddev->array_size = newconf->array_size; - set_capacity(mddev->gendisk, mddev->array_size << 1); - return 0; +out: + kfree(conf); + return 1; } static int linear_stop (mddev_t *mddev) @@ -305,12 +262,8 @@ static int linear_stop (mddev_t *mddev) linear_conf_t *conf = mddev_to_conf(mddev); blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ - do { - linear_conf_t *t = conf->prev; - kfree(conf->hash_table); - kfree(conf); - conf = t; - } while (conf); + kfree(conf->hash_table); + kfree(conf); return 0; } @@ -407,7 +360,6 @@ static struct mdk_personality linear_personality = .run = linear_run, .stop = linear_stop, .status = linear_status, - .hot_add_disk = linear_add, }; static int __init linear_init (void) diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 306268ec99ff..f19b874753a9 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -44,7 +44,6 @@ #include #include #include -#include #include @@ -73,10 +72,6 @@ static void autostart_arrays (int part); static LIST_HEAD(pers_list); static DEFINE_SPINLOCK(pers_lock); -static void md_print_devices(void); - -#define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } - /* * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' * is 1000 KB/sec, so the extra system load does not show up that much. @@ -175,7 +170,7 @@ EXPORT_SYMBOL_GPL(md_new_event); /* Alternate version that can be called from interrupts * when calling sysfs_notify isn't needed. */ -static void md_new_event_inintr(mddev_t *mddev) +void md_new_event_inintr(mddev_t *mddev) { atomic_inc(&md_event_count); wake_up(&md_event_waiters); @@ -737,7 +732,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) { mdp_disk_t *desc; mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); - __u64 ev1 = md_event(sb); rdev->raid_disk = -1; rdev->flags = 0; @@ -754,7 +748,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->layout = sb->layout; mddev->raid_disks = sb->raid_disks; mddev->size = sb->size; - mddev->events = ev1; + mddev->events = md_event(sb); mddev->bitmap_offset = 0; mddev->default_bitmap_offset = MD_SB_BYTES >> 9; @@ -803,6 +797,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) } else if (mddev->pers == NULL) { /* Insist on good event counter while assembling */ + __u64 ev1 = md_event(sb); ++ev1; if (ev1 < mddev->events) return -EINVAL; @@ -810,21 +805,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) /* if adding to array with a bitmap, then we can accept an * older device ... but not too old. */ + __u64 ev1 = md_event(sb); if (ev1 < mddev->bitmap->events_cleared) return 0; - } else { - if (ev1 < mddev->events) - /* just a hot-add of a new device, leave raid_disk at -1 */ - return 0; - } + } else /* just a hot-add of a new device, leave raid_disk at -1 */ + return 0; if (mddev->level != LEVEL_MULTIPATH) { desc = sb->disks + rdev->desc_nr; if (desc->state & (1<flags); - else if (desc->state & (1<raid_disk < mddev->raid_disks */) { + else if (desc->state & (1<raid_disk < mddev->raid_disks) { set_bit(In_sync, &rdev->flags); rdev->raid_disk = desc->raid_disk; } @@ -1107,7 +1100,6 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) { struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); - __u64 ev1 = le64_to_cpu(sb->events); rdev->raid_disk = -1; rdev->flags = 0; @@ -1123,7 +1115,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->layout = le32_to_cpu(sb->layout); mddev->raid_disks = le32_to_cpu(sb->raid_disks); mddev->size = le64_to_cpu(sb->size)/2; - mddev->events = ev1; + mddev->events = le64_to_cpu(sb->events); mddev->bitmap_offset = 0; mddev->default_bitmap_offset = 1024 >> 9; @@ -1157,6 +1149,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling */ + __u64 ev1 = le64_to_cpu(sb->events); ++ev1; if (ev1 < mddev->events) return -EINVAL; @@ -1164,13 +1157,12 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) /* If adding to array with a bitmap, then we can accept an * older device, but not too old. */ + __u64 ev1 = le64_to_cpu(sb->events); if (ev1 < mddev->bitmap->events_cleared) return 0; - } else { - if (ev1 < mddev->events) - /* just a hot-add of a new device, leave raid_disk at -1 */ - return 0; - } + } else /* just a hot-add of a new device, leave raid_disk at -1 */ + return 0; + if (mddev->level != LEVEL_MULTIPATH) { int role; rdev->desc_nr = le32_to_cpu(sb->dev_number); @@ -1182,11 +1174,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) set_bit(Faulty, &rdev->flags); break; default: - if ((le32_to_cpu(sb->feature_map) & - MD_FEATURE_RECOVERY_OFFSET)) - rdev->recovery_offset = le64_to_cpu(sb->recovery_offset); - else - set_bit(In_sync, &rdev->flags); + set_bit(In_sync, &rdev->flags); rdev->raid_disk = role; break; } @@ -1210,7 +1198,6 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->feature_map = 0; sb->pad0 = 0; - sb->recovery_offset = cpu_to_le64(0); memset(sb->pad1, 0, sizeof(sb->pad1)); memset(sb->pad2, 0, sizeof(sb->pad2)); memset(sb->pad3, 0, sizeof(sb->pad3)); @@ -1231,14 +1218,6 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); } - - if (rdev->raid_disk >= 0 && - !test_bit(In_sync, &rdev->flags) && - rdev->recovery_offset > 0) { - sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET); - sb->recovery_offset = cpu_to_le64(rdev->recovery_offset); - } - if (mddev->reshape_position != MaxSector) { sb->feature_map |= cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE); sb->reshape_position = cpu_to_le64(mddev->reshape_position); @@ -1263,12 +1242,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->dev_roles[i] = cpu_to_le16(0xfffe); else if (test_bit(In_sync, &rdev2->flags)) sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); - else if (rdev2->raid_disk >= 0 && rdev2->recovery_offset > 0) - sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); else sb->dev_roles[i] = cpu_to_le16(0xffff); } + sb->recovery_offset = cpu_to_le64(0); /* not supported yet */ sb->sb_csum = calc_sb_1_csum(sb); } @@ -1529,7 +1507,7 @@ static void print_rdev(mdk_rdev_t *rdev) printk(KERN_INFO "md: no rdev superblock!\n"); } -static void md_print_devices(void) +void md_print_devices(void) { struct list_head *tmp, *tmp2; mdk_rdev_t *rdev; @@ -1558,30 +1536,15 @@ static void md_print_devices(void) } -static void sync_sbs(mddev_t * mddev, int nospares) +static void sync_sbs(mddev_t * mddev) { - /* Update each superblock (in-memory image), but - * if we are allowed to, skip spares which already - * have the right event counter, or have one earlier - * (which would mean they aren't being marked as dirty - * with the rest of the array) - */ mdk_rdev_t *rdev; struct list_head *tmp; ITERATE_RDEV(mddev,rdev,tmp) { - if (rdev->sb_events == mddev->events || - (nospares && - rdev->raid_disk < 0 && - (rdev->sb_events&1)==0 && - rdev->sb_events+1 == mddev->events)) { - /* Don't update this superblock */ - rdev->sb_loaded = 2; - } else { - super_types[mddev->major_version]. - sync_super(mddev, rdev); - rdev->sb_loaded = 1; - } + super_types[mddev->major_version]. + sync_super(mddev, rdev); + rdev->sb_loaded = 1; } } @@ -1591,42 +1554,12 @@ void md_update_sb(mddev_t * mddev) struct list_head *tmp; mdk_rdev_t *rdev; int sync_req; - int nospares = 0; repeat: spin_lock_irq(&mddev->write_lock); sync_req = mddev->in_sync; mddev->utime = get_seconds(); - if (mddev->sb_dirty == 3) - /* just a clean<-> dirty transition, possibly leave spares alone, - * though if events isn't the right even/odd, we will have to do - * spares after all - */ - nospares = 1; - - /* If this is just a dirty<->clean transition, and the array is clean - * and 'events' is odd, we can roll back to the previous clean state */ - if (mddev->sb_dirty == 3 - && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events & 1)) - mddev->events--; - else { - /* otherwise we have to go forward and ... */ - mddev->events ++; - if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */ - /* .. if the array isn't clean, insist on an odd 'events' */ - if ((mddev->events&1)==0) { - mddev->events++; - nospares = 0; - } - } else { - /* otherwise insist on an even 'events' (for clean states) */ - if ((mddev->events&1)) { - mddev->events++; - nospares = 0; - } - } - } + mddev->events ++; if (!mddev->events) { /* @@ -1638,7 +1571,7 @@ void md_update_sb(mddev_t * mddev) mddev->events --; } mddev->sb_dirty = 2; - sync_sbs(mddev, nospares); + sync_sbs(mddev); /* * do not write anything to disk if using @@ -1660,8 +1593,6 @@ void md_update_sb(mddev_t * mddev) ITERATE_RDEV(mddev,rdev,tmp) { char b[BDEVNAME_SIZE]; dprintk(KERN_INFO "md: "); - if (rdev->sb_loaded != 1) - continue; /* no noise on spare devices */ if (test_bit(Faulty, &rdev->flags)) dprintk("(skipping faulty "); @@ -1673,7 +1604,6 @@ void md_update_sb(mddev_t * mddev) dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", bdevname(rdev->bdev,b), (unsigned long long)rdev->sb_offset); - rdev->sb_events = mddev->events; } else dprintk(")\n"); @@ -1737,10 +1667,6 @@ state_show(mdk_rdev_t *rdev, char *page) len += sprintf(page+len, "%sin_sync",sep); sep = ","; } - if (test_bit(WriteMostly, &rdev->flags)) { - len += sprintf(page+len, "%swrite_mostly",sep); - sep = ","; - } if (!test_bit(Faulty, &rdev->flags) && !test_bit(In_sync, &rdev->flags)) { len += sprintf(page+len, "%sspare", sep); @@ -1749,40 +1675,8 @@ state_show(mdk_rdev_t *rdev, char *page) return len+sprintf(page+len, "\n"); } -static ssize_t -state_store(mdk_rdev_t *rdev, const char *buf, size_t len) -{ - /* can write - * faulty - simulates and error - * remove - disconnects the device - * writemostly - sets write_mostly - * -writemostly - clears write_mostly - */ - int err = -EINVAL; - if (cmd_match(buf, "faulty") && rdev->mddev->pers) { - md_error(rdev->mddev, rdev); - err = 0; - } else if (cmd_match(buf, "remove")) { - if (rdev->raid_disk >= 0) - err = -EBUSY; - else { - mddev_t *mddev = rdev->mddev; - kick_rdev_from_array(rdev); - md_update_sb(mddev); - md_new_event(mddev); - err = 0; - } - } else if (cmd_match(buf, "writemostly")) { - set_bit(WriteMostly, &rdev->flags); - err = 0; - } else if (cmd_match(buf, "-writemostly")) { - clear_bit(WriteMostly, &rdev->flags); - err = 0; - } - return err ? err : len; -} static struct rdev_sysfs_entry -rdev_state = __ATTR(state, 0644, state_show, state_store); +rdev_state = __ATTR_RO(state); static ssize_t super_show(mdk_rdev_t *rdev, char *page) @@ -1979,7 +1873,6 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi rdev->desc_nr = -1; rdev->flags = 0; rdev->data_offset = 0; - rdev->sb_events = 0; atomic_set(&rdev->nr_pending, 0); atomic_set(&rdev->read_errors, 0); atomic_set(&rdev->corrected_errors, 0); @@ -2084,54 +1977,6 @@ static void analyze_sbs(mddev_t * mddev) } -static ssize_t -safe_delay_show(mddev_t *mddev, char *page) -{ - int msec = (mddev->safemode_delay*1000)/HZ; - return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); -} -static ssize_t -safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) -{ - int scale=1; - int dot=0; - int i; - unsigned long msec; - char buf[30]; - char *e; - /* remove a period, and count digits after it */ - if (len >= sizeof(buf)) - return -EINVAL; - strlcpy(buf, cbuf, len); - buf[len] = 0; - for (i=0; isafemode_delay = 0; - else { - mddev->safemode_delay = (msec*HZ)/1000; - if (mddev->safemode_delay == 0) - mddev->safemode_delay = 1; - } - return len; -} -static struct md_sysfs_entry md_safe_delay = -__ATTR(safe_mode_delay, 0644,safe_delay_show, safe_delay_store); - static ssize_t level_show(mddev_t *mddev, char *page) { @@ -2167,32 +2012,6 @@ level_store(mddev_t *mddev, const char *buf, size_t len) static struct md_sysfs_entry md_level = __ATTR(level, 0644, level_show, level_store); - -static ssize_t -layout_show(mddev_t *mddev, char *page) -{ - /* just a number, not meaningful for all levels */ - return sprintf(page, "%d\n", mddev->layout); -} - -static ssize_t -layout_store(mddev_t *mddev, const char *buf, size_t len) -{ - char *e; - unsigned long n = simple_strtoul(buf, &e, 10); - if (mddev->pers) - return -EBUSY; - - if (!*buf || (*e && *e != '\n')) - return -EINVAL; - - mddev->layout = n; - return len; -} -static struct md_sysfs_entry md_layout = -__ATTR(layout, 0655, layout_show, layout_store); - - static ssize_t raid_disks_show(mddev_t *mddev, char *page) { @@ -2247,200 +2066,6 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len) static struct md_sysfs_entry md_chunk_size = __ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store); -static ssize_t -resync_start_show(mddev_t *mddev, char *page) -{ - return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp); -} - -static ssize_t -resync_start_store(mddev_t *mddev, const char *buf, size_t len) -{ - /* can only set chunk_size if array is not yet active */ - char *e; - unsigned long long n = simple_strtoull(buf, &e, 10); - - if (mddev->pers) - return -EBUSY; - if (!*buf || (*e && *e != '\n')) - return -EINVAL; - - mddev->recovery_cp = n; - return len; -} -static struct md_sysfs_entry md_resync_start = -__ATTR(resync_start, 0644, resync_start_show, resync_start_store); - -/* - * The array state can be: - * - * clear - * No devices, no size, no level - * Equivalent to STOP_ARRAY ioctl - * inactive - * May have some settings, but array is not active - * all IO results in error - * When written, doesn't tear down array, but just stops it - * suspended (not supported yet) - * All IO requests will block. The array can be reconfigured. - * Writing this, if accepted, will block until array is quiessent - * readonly - * no resync can happen. no superblocks get written. - * write requests fail - * read-auto - * like readonly, but behaves like 'clean' on a write request. - * - * clean - no pending writes, but otherwise active. - * When written to inactive array, starts without resync - * If a write request arrives then - * if metadata is known, mark 'dirty' and switch to 'active'. - * if not known, block and switch to write-pending - * If written to an active array that has pending writes, then fails. - * active - * fully active: IO and resync can be happening. - * When written to inactive array, starts with resync - * - * write-pending - * clean, but writes are blocked waiting for 'active' to be written. - * - * active-idle - * like active, but no writes have been seen for a while (100msec). - * - */ -enum array_state { clear, inactive, suspended, readonly, read_auto, clean, active, - write_pending, active_idle, bad_word}; -static char *array_states[] = { - "clear", "inactive", "suspended", "readonly", "read-auto", "clean", "active", - "write-pending", "active-idle", NULL }; - -static int match_word(const char *word, char **list) -{ - int n; - for (n=0; list[n]; n++) - if (cmd_match(word, list[n])) - break; - return n; -} - -static ssize_t -array_state_show(mddev_t *mddev, char *page) -{ - enum array_state st = inactive; - - if (mddev->pers) - switch(mddev->ro) { - case 1: - st = readonly; - break; - case 2: - st = read_auto; - break; - case 0: - if (mddev->in_sync) - st = clean; - else if (mddev->safemode) - st = active_idle; - else - st = active; - } - else { - if (list_empty(&mddev->disks) && - mddev->raid_disks == 0 && - mddev->size == 0) - st = clear; - else - st = inactive; - } - return sprintf(page, "%s\n", array_states[st]); -} - -static int do_md_stop(mddev_t * mddev, int ro); -static int do_md_run(mddev_t * mddev); -static int restart_array(mddev_t *mddev); - -static ssize_t -array_state_store(mddev_t *mddev, const char *buf, size_t len) -{ - int err = -EINVAL; - enum array_state st = match_word(buf, array_states); - switch(st) { - case bad_word: - break; - case clear: - /* stopping an active array */ - if (mddev->pers) { - if (atomic_read(&mddev->active) > 1) - return -EBUSY; - err = do_md_stop(mddev, 0); - } - break; - case inactive: - /* stopping an active array */ - if (mddev->pers) { - if (atomic_read(&mddev->active) > 1) - return -EBUSY; - err = do_md_stop(mddev, 2); - } - break; - case suspended: - break; /* not supported yet */ - case readonly: - if (mddev->pers) - err = do_md_stop(mddev, 1); - else { - mddev->ro = 1; - err = do_md_run(mddev); - } - break; - case read_auto: - /* stopping an active array */ - if (mddev->pers) { - err = do_md_stop(mddev, 1); - if (err == 0) - mddev->ro = 2; /* FIXME mark devices writable */ - } else { - mddev->ro = 2; - err = do_md_run(mddev); - } - break; - case clean: - if (mddev->pers) { - restart_array(mddev); - spin_lock_irq(&mddev->write_lock); - if (atomic_read(&mddev->writes_pending) == 0) { - mddev->in_sync = 1; - mddev->sb_dirty = 1; - } - spin_unlock_irq(&mddev->write_lock); - } else { - mddev->ro = 0; - mddev->recovery_cp = MaxSector; - err = do_md_run(mddev); - } - break; - case active: - if (mddev->pers) { - restart_array(mddev); - mddev->sb_dirty = 0; - wake_up(&mddev->sb_wait); - err = 0; - } else { - mddev->ro = 0; - err = do_md_run(mddev); - } - break; - case write_pending: - case active_idle: - /* these cannot be set */ - break; - } - if (err) - return err; - else - return len; -} -static struct md_sysfs_entry md_array_state = __ATTR(array_state, 0644, array_state_show, array_state_store); - static ssize_t null_show(mddev_t *mddev, char *page) { @@ -2803,15 +2428,11 @@ __ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); static struct attribute *md_default_attrs[] = { &md_level.attr, - &md_layout.attr, &md_raid_disks.attr, &md_chunk_size.attr, &md_size.attr, - &md_resync_start.attr, &md_metadata.attr, &md_new_device.attr, - &md_safe_delay.attr, - &md_array_state.attr, NULL, }; @@ -2932,6 +2553,8 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) return NULL; } +void md_wakeup_thread(mdk_thread_t *thread); + static void md_safemode_timeout(unsigned long data) { mddev_t *mddev = (mddev_t *) data; @@ -3085,7 +2708,7 @@ static int do_md_run(mddev_t * mddev) mddev->safemode = 0; mddev->safemode_timer.function = md_safemode_timeout; mddev->safemode_timer.data = (unsigned long) mddev; - mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ + mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ mddev->in_sync = 1; ITERATE_RDEV(mddev,rdev,tmp) @@ -3113,36 +2736,6 @@ static int do_md_run(mddev_t * mddev) mddev->queue->queuedata = mddev; mddev->queue->make_request_fn = mddev->pers->make_request; - /* If there is a partially-recovered drive we need to - * start recovery here. If we leave it to md_check_recovery, - * it will remove the drives and not do the right thing - */ - if (mddev->degraded) { - struct list_head *rtmp; - int spares = 0; - ITERATE_RDEV(mddev,rdev,rtmp) - if (rdev->raid_disk >= 0 && - !test_bit(In_sync, &rdev->flags) && - !test_bit(Faulty, &rdev->flags)) - /* complete an interrupted recovery */ - spares++; - if (spares && mddev->pers->sync_request) { - mddev->recovery = 0; - set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); - mddev->sync_thread = md_register_thread(md_do_sync, - mddev, - "%s_resync"); - if (!mddev->sync_thread) { - printk(KERN_ERR "%s: could not start resync" - " thread...\n", - mdname(mddev)); - /* leave the spares where they are, it shouldn't hurt */ - mddev->recovery = 0; - } else - md_wakeup_thread(mddev->sync_thread); - } - } - mddev->changed = 1; md_new_event(mddev); return 0; @@ -3176,47 +2769,18 @@ static int restart_array(mddev_t *mddev) */ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); - md_wakeup_thread(mddev->sync_thread); err = 0; - } else + } else { + printk(KERN_ERR "md: %s has no personality assigned.\n", + mdname(mddev)); err = -EINVAL; + } out: return err; } -/* similar to deny_write_access, but accounts for our holding a reference - * to the file ourselves */ -static int deny_bitmap_write_access(struct file * file) -{ - struct inode *inode = file->f_mapping->host; - - spin_lock(&inode->i_lock); - if (atomic_read(&inode->i_writecount) > 1) { - spin_unlock(&inode->i_lock); - return -ETXTBSY; - } - atomic_set(&inode->i_writecount, -1); - spin_unlock(&inode->i_lock); - - return 0; -} - -static void restore_bitmap_write_access(struct file *file) -{ - struct inode *inode = file->f_mapping->host; - - spin_lock(&inode->i_lock); - atomic_set(&inode->i_writecount, 1); - spin_unlock(&inode->i_lock); -} - -/* mode: - * 0 - completely stop and dis-assemble array - * 1 - switch to readonly - * 2 - stop but do not disassemble array - */ -static int do_md_stop(mddev_t * mddev, int mode) +static int do_md_stop(mddev_t * mddev, int ro) { int err = 0; struct gendisk *disk = mddev->gendisk; @@ -3228,7 +2792,6 @@ static int do_md_stop(mddev_t * mddev, int mode) } if (mddev->sync_thread) { - set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); set_bit(MD_RECOVERY_INTR, &mddev->recovery); md_unregister_thread(mddev->sync_thread); mddev->sync_thread = NULL; @@ -3238,15 +2801,12 @@ static int do_md_stop(mddev_t * mddev, int mode) invalidate_partition(disk, 0); - switch(mode) { - case 1: /* readonly */ + if (ro) { err = -ENXIO; if (mddev->ro==1) goto out; mddev->ro = 1; - break; - case 0: /* disassemble */ - case 2: /* stop */ + } else { bitmap_flush(mddev); md_super_wait(mddev); if (mddev->ro) @@ -3261,20 +2821,19 @@ static int do_md_stop(mddev_t * mddev, int mode) if (mddev->ro) mddev->ro = 0; } - if (!mddev->in_sync || mddev->sb_dirty) { + if (!mddev->in_sync) { /* mark array as shutdown cleanly */ mddev->in_sync = 1; md_update_sb(mddev); } - if (mode == 1) + if (ro) set_disk_ro(disk, 1); - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } /* * Free resources if final stop */ - if (mode == 0) { + if (!ro) { mdk_rdev_t *rdev; struct list_head *tmp; struct gendisk *disk; @@ -3282,7 +2841,7 @@ static int do_md_stop(mddev_t * mddev, int mode) bitmap_destroy(mddev); if (mddev->bitmap_file) { - restore_bitmap_write_access(mddev->bitmap_file); + atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); fput(mddev->bitmap_file); mddev->bitmap_file = NULL; } @@ -3298,15 +2857,11 @@ static int do_md_stop(mddev_t * mddev, int mode) export_array(mddev); mddev->array_size = 0; - mddev->size = 0; - mddev->raid_disks = 0; - mddev->recovery_cp = 0; - disk = mddev->gendisk; if (disk) set_capacity(disk, 0); mddev->changed = 1; - } else if (mddev->pers) + } else printk(KERN_INFO "md: %s switched to read-only mode.\n", mdname(mddev)); err = 0; @@ -3709,17 +3264,6 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) rdev->raid_disk = -1; err = bind_rdev_to_array(rdev, mddev); - if (!err && !mddev->pers->hot_remove_disk) { - /* If there is hot_add_disk but no hot_remove_disk - * then added disks for geometry changes, - * and should be added immediately. - */ - super_types[mddev->major_version]. - validate_super(mddev, rdev); - err = mddev->pers->hot_add_disk(mddev, rdev); - if (err) - unbind_rdev_from_array(rdev); - } if (err) export_rdev(rdev); @@ -3890,6 +3434,23 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) return err; } +/* similar to deny_write_access, but accounts for our holding a reference + * to the file ourselves */ +static int deny_bitmap_write_access(struct file * file) +{ + struct inode *inode = file->f_mapping->host; + + spin_lock(&inode->i_lock); + if (atomic_read(&inode->i_writecount) > 1) { + spin_unlock(&inode->i_lock); + return -ETXTBSY; + } + atomic_set(&inode->i_writecount, -1); + spin_unlock(&inode->i_lock); + + return 0; +} + static int set_bitmap_file(mddev_t *mddev, int fd) { int err; @@ -3930,17 +3491,12 @@ static int set_bitmap_file(mddev_t *mddev, int fd) mddev->pers->quiesce(mddev, 1); if (fd >= 0) err = bitmap_create(mddev); - if (fd < 0 || err) { + if (fd < 0 || err) bitmap_destroy(mddev); - fd = -1; /* make sure to put the file */ - } mddev->pers->quiesce(mddev, 0); - } - if (fd < 0) { - if (mddev->bitmap_file) { - restore_bitmap_write_access(mddev->bitmap_file); + } else if (fd < 0) { + if (mddev->bitmap_file) fput(mddev->bitmap_file); - } mddev->bitmap_file = NULL; } @@ -4421,6 +3977,11 @@ static int md_ioctl(struct inode *inode, struct file *file, goto done_unlock; default: + if (_IOC_TYPE(cmd) == MD_MAJOR) + printk(KERN_WARNING "md: %s(pid %d) used" + " obsolete MD ioctl, upgrade your" + " software to use new ictls.\n", + current->comm, current->pid); err = -EINVAL; goto abort_unlock; } @@ -5025,7 +4586,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) spin_lock_irq(&mddev->write_lock); if (mddev->in_sync) { mddev->in_sync = 0; - mddev->sb_dirty = 3; + mddev->sb_dirty = 1; md_wakeup_thread(mddev->thread); } spin_unlock_irq(&mddev->write_lock); @@ -5038,7 +4599,7 @@ void md_write_end(mddev_t *mddev) if (atomic_dec_and_test(&mddev->writes_pending)) { if (mddev->safemode == 2) md_wakeup_thread(mddev->thread); - else if (mddev->safemode_delay) + else mod_timer(&mddev->safemode_timer, jiffies + mddev->safemode_delay); } } @@ -5059,14 +4620,10 @@ void md_do_sync(mddev_t *mddev) struct list_head *tmp; sector_t last_check; int skipped = 0; - struct list_head *rtmp; - mdk_rdev_t *rdev; /* just incase thread restarts... */ if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) return; - if (mddev->ro) /* never try to sync a read-only array */ - return; /* we overload curr_resync somewhat here. * 0 == not engaged in resync at all @@ -5125,30 +4682,17 @@ void md_do_sync(mddev_t *mddev) } } while (mddev->curr_resync < 2); - j = 0; if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { /* resync follows the size requested by the personality, * which defaults to physical size, but can be virtual size */ max_sectors = mddev->resync_max_sectors; mddev->resync_mismatches = 0; - /* we don't use the checkpoint if there's a bitmap */ - if (!mddev->bitmap && - !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) - j = mddev->recovery_cp; } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) max_sectors = mddev->size << 1; - else { + else /* recovery follows the physical size of devices */ max_sectors = mddev->size << 1; - j = MaxSector; - ITERATE_RDEV(mddev,rdev,rtmp) - if (rdev->raid_disk >= 0 && - !test_bit(Faulty, &rdev->flags) && - !test_bit(In_sync, &rdev->flags) && - rdev->recovery_offset < j) - j = rdev->recovery_offset; - } printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev)); printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:" @@ -5158,7 +4702,12 @@ void md_do_sync(mddev_t *mddev) speed_max(mddev)); is_mddev_idle(mddev); /* this also initializes IO event counters */ - + /* we don't use the checkpoint if there's a bitmap */ + if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap + && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) + j = mddev->recovery_cp; + else + j = 0; io_sectors = 0; for (m = 0; m < SYNC_MARKS; m++) { mark[m] = jiffies; @@ -5279,28 +4828,15 @@ void md_do_sync(mddev_t *mddev) if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && - mddev->curr_resync > 2) { - if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { - if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { - if (mddev->curr_resync >= mddev->recovery_cp) { - printk(KERN_INFO - "md: checkpointing recovery of %s.\n", - mdname(mddev)); - mddev->recovery_cp = mddev->curr_resync; - } - } else - mddev->recovery_cp = MaxSector; - } else { - if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) - mddev->curr_resync = MaxSector; - ITERATE_RDEV(mddev,rdev,rtmp) - if (rdev->raid_disk >= 0 && - !test_bit(Faulty, &rdev->flags) && - !test_bit(In_sync, &rdev->flags) && - rdev->recovery_offset < mddev->curr_resync) - rdev->recovery_offset = mddev->curr_resync; - mddev->sb_dirty = 1; - } + mddev->curr_resync > 2 && + mddev->curr_resync >= mddev->recovery_cp) { + if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { + printk(KERN_INFO + "md: checkpointing recovery of %s.\n", + mdname(mddev)); + mddev->recovery_cp = mddev->curr_resync; + } else + mddev->recovery_cp = MaxSector; } skip: @@ -5372,7 +4908,7 @@ void md_check_recovery(mddev_t *mddev) if (mddev->safemode && !atomic_read(&mddev->writes_pending) && !mddev->in_sync && mddev->recovery_cp == MaxSector) { mddev->in_sync = 1; - mddev->sb_dirty = 3; + mddev->sb_dirty = 1; } if (mddev->safemode == 1) mddev->safemode = 0; @@ -5421,8 +4957,6 @@ void md_check_recovery(mddev_t *mddev) clear_bit(MD_RECOVERY_INTR, &mddev->recovery); clear_bit(MD_RECOVERY_DONE, &mddev->recovery); - if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) - goto unlock; /* no recovery is running. * remove any failed drives, then * add spares if possible. @@ -5445,7 +4979,6 @@ void md_check_recovery(mddev_t *mddev) ITERATE_RDEV(mddev,rdev,rtmp) if (rdev->raid_disk < 0 && !test_bit(Faulty, &rdev->flags)) { - rdev->recovery_offset = 0; if (mddev->pers->hot_add_disk(mddev,rdev)) { char nm[20]; sprintf(nm, "rd%d", rdev->raid_disk); @@ -5683,6 +5216,7 @@ EXPORT_SYMBOL(md_write_end); EXPORT_SYMBOL(md_register_thread); EXPORT_SYMBOL(md_unregister_thread); EXPORT_SYMBOL(md_wakeup_thread); +EXPORT_SYMBOL(md_print_devices); EXPORT_SYMBOL(md_check_recovery); MODULE_LICENSE("GPL"); MODULE_ALIAS("md"); diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index cead918578a7..4070eff6f0f8 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -374,26 +374,26 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int * already. */ if (atomic_dec_and_test(&r1_bio->remaining)) { - if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) + if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { reschedule_retry(r1_bio); - else { - /* it really is the end of this request */ - if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { - /* free extra copy of the data pages */ - int i = bio->bi_vcnt; - while (i--) - safe_put_page(bio->bi_io_vec[i].bv_page); - } - /* clear the bitmap if all writes complete successfully */ - bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, - r1_bio->sectors, - !test_bit(R1BIO_Degraded, &r1_bio->state), - behind); - md_write_end(r1_bio->mddev); - raid_end_bio_io(r1_bio); + goto out; } + /* it really is the end of this request */ + if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { + /* free extra copy of the data pages */ + int i = bio->bi_vcnt; + while (i--) + safe_put_page(bio->bi_io_vec[i].bv_page); + } + /* clear the bitmap if all writes complete successfully */ + bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, + r1_bio->sectors, + !test_bit(R1BIO_Degraded, &r1_bio->state), + behind); + md_write_end(r1_bio->mddev); + raid_end_bio_io(r1_bio); } - + out: if (to_put) bio_put(to_put); @@ -1625,12 +1625,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* before building a request, check if we can skip these blocks.. * This call the bitmap_start_sync doesn't actually record anything */ - if (mddev->bitmap == NULL && - mddev->recovery_cp == MaxSector && - conf->fullsync == 0) { - *skipped = 1; - return max_sector - sector_nr; - } if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { /* We can skip this block, and probably several more */ @@ -1894,8 +1888,7 @@ static int run(mddev_t *mddev) disk = conf->mirrors + i; - if (!disk->rdev || - !test_bit(In_sync, &disk->rdev->flags)) { + if (!disk->rdev) { disk->head_position = 0; mddev->degraded++; } diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 7f636283a1ba..1440935414e6 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -29,7 +29,6 @@ * raid_disks * near_copies (stored in low byte of layout) * far_copies (stored in second byte of layout) - * far_offset (stored in bit 16 of layout ) * * The data to be stored is divided into chunks using chunksize. * Each device is divided into far_copies sections. @@ -37,14 +36,10 @@ * near_copies copies of each chunk is stored (each on a different drive). * The starting device for each section is offset near_copies from the starting * device of the previous section. - * Thus they are (near_copies*far_copies) of each chunk, and each is on a different + * Thus there are (near_copies*far_copies) of each chunk, and each is on a different * drive. * near_copies and far_copies must be at least one, and their product is at most * raid_disks. - * - * If far_offset is true, then the far_copies are handled a bit differently. - * The copies are still in different stripes, but instead of be very far apart - * on disk, there are adjacent stripes. */ /* @@ -362,7 +357,8 @@ static int raid10_end_write_request(struct bio *bio, unsigned int bytes_done, in * With this layout, and block is never stored twice on the one device. * * raid10_find_phys finds the sector offset of a given virtual sector - * on each device that it is on. + * on each device that it is on. If a block isn't on a device, + * that entry in the array is set to MaxSector. * * raid10_find_virt does the reverse mapping, from a device and a * sector offset to a virtual address @@ -385,8 +381,6 @@ static void raid10_find_phys(conf_t *conf, r10bio_t *r10bio) chunk *= conf->near_copies; stripe = chunk; dev = sector_div(stripe, conf->raid_disks); - if (conf->far_offset) - stripe *= conf->far_copies; sector += stripe << conf->chunk_shift; @@ -420,24 +414,16 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev) { sector_t offset, chunk, vchunk; - offset = sector & conf->chunk_mask; - if (conf->far_offset) { - int fc; - chunk = sector >> conf->chunk_shift; - fc = sector_div(chunk, conf->far_copies); - dev -= fc * conf->near_copies; - if (dev < 0) - dev += conf->raid_disks; - } else { - while (sector > conf->stride) { - sector -= conf->stride; - if (dev < conf->near_copies) - dev += conf->raid_disks - conf->near_copies; - else - dev -= conf->near_copies; - } - chunk = sector >> conf->chunk_shift; + while (sector > conf->stride) { + sector -= conf->stride; + if (dev < conf->near_copies) + dev += conf->raid_disks - conf->near_copies; + else + dev -= conf->near_copies; } + + offset = sector & conf->chunk_mask; + chunk = sector >> conf->chunk_shift; vchunk = chunk * conf->raid_disks + dev; sector_div(vchunk, conf->near_copies); return (vchunk << conf->chunk_shift) + offset; @@ -914,12 +900,9 @@ static void status(struct seq_file *seq, mddev_t *mddev) seq_printf(seq, " %dK chunks", mddev->chunk_size/1024); if (conf->near_copies > 1) seq_printf(seq, " %d near-copies", conf->near_copies); - if (conf->far_copies > 1) { - if (conf->far_offset) - seq_printf(seq, " %d offset-copies", conf->far_copies); - else - seq_printf(seq, " %d far-copies", conf->far_copies); - } + if (conf->far_copies > 1) + seq_printf(seq, " %d far-copies", conf->far_copies); + seq_printf(seq, " [%d/%d] [", conf->raid_disks, conf->working_disks); for (i = 0; i < conf->raid_disks; i++) @@ -1932,7 +1915,7 @@ static int run(mddev_t *mddev) mirror_info_t *disk; mdk_rdev_t *rdev; struct list_head *tmp; - int nc, fc, fo; + int nc, fc; sector_t stride, size; if (mddev->chunk_size == 0) { @@ -1942,9 +1925,8 @@ static int run(mddev_t *mddev) nc = mddev->layout & 255; fc = (mddev->layout >> 8) & 255; - fo = mddev->layout & (1<<16); if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks || - (mddev->layout >> 17)) { + (mddev->layout >> 16)) { printk(KERN_ERR "raid10: %s: unsupported raid10 layout: 0x%8x\n", mdname(mddev), mddev->layout); goto out; @@ -1976,16 +1958,12 @@ static int run(mddev_t *mddev) conf->near_copies = nc; conf->far_copies = fc; conf->copies = nc*fc; - conf->far_offset = fo; conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1; conf->chunk_shift = ffz(~mddev->chunk_size) - 9; - if (fo) - conf->stride = 1 << conf->chunk_shift; - else { - stride = mddev->size >> (conf->chunk_shift-1); - sector_div(stride, fc); - conf->stride = stride << conf->chunk_shift; - } + stride = mddev->size >> (conf->chunk_shift-1); + sector_div(stride, fc); + conf->stride = stride << conf->chunk_shift; + conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc, r10bio_pool_free, conf); if (!conf->r10bio_pool) { @@ -2037,8 +2015,7 @@ static int run(mddev_t *mddev) disk = conf->mirrors + i; - if (!disk->rdev || - !test_bit(In_sync, &rdev->flags)) { + if (!disk->rdev) { disk->head_position = 0; mddev->degraded++; } @@ -2060,13 +2037,7 @@ static int run(mddev_t *mddev) /* * Ok, everything is just fine now */ - if (conf->far_offset) { - size = mddev->size >> (conf->chunk_shift-1); - size *= conf->raid_disks; - size <<= conf->chunk_shift; - sector_div(size, conf->far_copies); - } else - size = conf->stride * conf->raid_disks; + size = conf->stride * conf->raid_disks; sector_div(size, conf->near_copies); mddev->array_size = size/2; mddev->resync_max_sectors = size; @@ -2079,7 +2050,7 @@ static int run(mddev_t *mddev) * maybe... */ { - int stripe = conf->raid_disks * (mddev->chunk_size / PAGE_SIZE); + int stripe = conf->raid_disks * mddev->chunk_size / PAGE_SIZE; stripe /= conf->near_copies; if (mddev->queue->backing_dev_info.ra_pages < 2* stripe) mddev->queue->backing_dev_info.ra_pages = 2* stripe; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index f920e50ea124..31843604049c 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2,11 +2,8 @@ * raid5.c : Multiple Devices driver for Linux * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman * Copyright (C) 1999, 2000 Ingo Molnar - * Copyright (C) 2002, 2003 H. Peter Anvin * - * RAID-4/5/6 management functions. - * Thanks to Penguin Computing for making the RAID-6 development possible - * by donating a test server! + * RAID-5 management functions. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +19,11 @@ #include #include #include +#include #include #include #include #include -#include "raid6.h" #include @@ -71,16 +68,6 @@ #define __inline__ #endif -#if !RAID6_USE_EMPTY_ZERO_PAGE -/* In .bss so it's zeroed */ -const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); -#endif - -static inline int raid6_next_disk(int disk, int raid_disks) -{ - disk++; - return (disk < raid_disks) ? disk : 0; -} static void print_raid5_conf (raid5_conf_t *conf); static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) @@ -117,7 +104,7 @@ static void release_stripe(struct stripe_head *sh) { raid5_conf_t *conf = sh->raid_conf; unsigned long flags; - + spin_lock_irqsave(&conf->device_lock, flags); __release_stripe(conf, sh); spin_unlock_irqrestore(&conf->device_lock, flags); @@ -130,7 +117,7 @@ static inline void remove_hash(struct stripe_head *sh) hlist_del_init(&sh->hash); } -static inline void insert_hash(raid5_conf_t *conf, struct stripe_head *sh) +static void insert_hash(raid5_conf_t *conf, struct stripe_head *sh) { struct hlist_head *hp = stripe_hash(conf, sh->sector); @@ -203,7 +190,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int (unsigned long long)sh->sector); remove_hash(sh); - + sh->sector = sector; sh->pd_idx = pd_idx; sh->state = 0; @@ -282,9 +269,8 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector } else { if (!test_bit(STRIPE_HANDLE, &sh->state)) atomic_inc(&conf->active_stripes); - if (list_empty(&sh->lru)) - BUG(); - list_del_init(&sh->lru); + if (!list_empty(&sh->lru)) + list_del_init(&sh->lru); } } } while (sh == NULL); @@ -335,9 +321,10 @@ static int grow_stripes(raid5_conf_t *conf, int num) return 1; conf->slab_cache = sc; conf->pool_size = devs; - while (num--) + while (num--) { if (!grow_one_stripe(conf)) return 1; + } return 0; } @@ -644,7 +631,8 @@ static void raid5_build_block (struct stripe_head *sh, int i) dev->req.bi_private = sh; dev->flags = 0; - dev->sector = compute_blocknr(sh, i); + if (i != sh->pd_idx) + dev->sector = compute_blocknr(sh, i); } static void error(mddev_t *mddev, mdk_rdev_t *rdev) @@ -671,7 +659,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) " Operation continuing on %d devices\n", bdevname(rdev->bdev,b), conf->working_disks); } -} +} /* * Input: a 'big' sector number, @@ -709,12 +697,9 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, /* * Select the parity disk based on the user selected algorithm. */ - switch(conf->level) { - case 4: + if (conf->level == 4) *pd_idx = data_disks; - break; - case 5: - switch (conf->algorithm) { + else switch (conf->algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: *pd_idx = data_disks - stripe % raid_disks; if (*dd_idx >= *pd_idx) @@ -736,39 +721,6 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, default: printk(KERN_ERR "raid5: unsupported algorithm %d\n", conf->algorithm); - } - break; - case 6: - - /**** FIX THIS ****/ - switch (conf->algorithm) { - case ALGORITHM_LEFT_ASYMMETRIC: - *pd_idx = raid_disks - 1 - (stripe % raid_disks); - if (*pd_idx == raid_disks-1) - (*dd_idx)++; /* Q D D D P */ - else if (*dd_idx >= *pd_idx) - (*dd_idx) += 2; /* D D P Q D */ - break; - case ALGORITHM_RIGHT_ASYMMETRIC: - *pd_idx = stripe % raid_disks; - if (*pd_idx == raid_disks-1) - (*dd_idx)++; /* Q D D D P */ - else if (*dd_idx >= *pd_idx) - (*dd_idx) += 2; /* D D P Q D */ - break; - case ALGORITHM_LEFT_SYMMETRIC: - *pd_idx = raid_disks - 1 - (stripe % raid_disks); - *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; - break; - case ALGORITHM_RIGHT_SYMMETRIC: - *pd_idx = stripe % raid_disks; - *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; - break; - default: - printk (KERN_CRIT "raid6: unsupported algorithm %d\n", - conf->algorithm); - } - break; } /* @@ -790,17 +742,12 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) int chunk_number, dummy1, dummy2, dd_idx = i; sector_t r_sector; - chunk_offset = sector_div(new_sector, sectors_per_chunk); stripe = new_sector; BUG_ON(new_sector != stripe); - if (i == sh->pd_idx) - return 0; - switch(conf->level) { - case 4: break; - case 5: - switch (conf->algorithm) { + + switch (conf->algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: case ALGORITHM_RIGHT_ASYMMETRIC: if (i > sh->pd_idx) @@ -814,37 +761,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) break; default: printk(KERN_ERR "raid5: unsupported algorithm %d\n", - conf->algorithm); - } - break; - case 6: - data_disks = raid_disks - 2; - if (i == raid6_next_disk(sh->pd_idx, raid_disks)) - return 0; /* It is the Q disk */ - switch (conf->algorithm) { - case ALGORITHM_LEFT_ASYMMETRIC: - case ALGORITHM_RIGHT_ASYMMETRIC: - if (sh->pd_idx == raid_disks-1) - i--; /* Q D D D P */ - else if (i > sh->pd_idx) - i -= 2; /* D D P Q D */ - break; - case ALGORITHM_LEFT_SYMMETRIC: - case ALGORITHM_RIGHT_SYMMETRIC: - if (sh->pd_idx == raid_disks-1) - i--; /* Q D D D P */ - else { - /* D D P Q D */ - if (i < sh->pd_idx) - i += raid_disks; - i -= (sh->pd_idx + 2); - } - break; - default: - printk (KERN_CRIT "raid6: unsupported algorithm %d\n", conf->algorithm); - } - break; } chunk_number = stripe * data_disks + i; @@ -861,11 +778,10 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) /* - * Copy data between a page in the stripe cache, and one or more bion - * The page could align with the middle of the bio, or there could be - * several bion, each with several bio_vecs, which cover part of the page - * Multiple bion are linked together on bi_next. There may be extras - * at the end of this list. We ignore them. + * Copy data between a page in the stripe cache, and a bio. + * There are no alignment or size guarantees between the page or the + * bio except that there is some overlap. + * All iovecs in the bio must be considered. */ static void copy_data(int frombio, struct bio *bio, struct page *page, @@ -894,7 +810,7 @@ static void copy_data(int frombio, struct bio *bio, if (len > 0 && page_offset + len > STRIPE_SIZE) clen = STRIPE_SIZE - page_offset; else clen = len; - + if (clen > 0) { char *ba = __bio_kmap_atomic(bio, i, KM_USER0); if (frombio) @@ -946,14 +862,14 @@ static void compute_block(struct stripe_head *sh, int dd_idx) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); } -static void compute_parity5(struct stripe_head *sh, int method) +static void compute_parity(struct stripe_head *sh, int method) { raid5_conf_t *conf = sh->raid_conf; int i, pd_idx = sh->pd_idx, disks = sh->disks, count; void *ptr[MAX_XOR_BLOCKS]; struct bio *chosen; - PRINTK("compute_parity5, stripe %llu, method %d\n", + PRINTK("compute_parity, stripe %llu, method %d\n", (unsigned long long)sh->sector, method); count = 1; @@ -1040,195 +956,9 @@ static void compute_parity5(struct stripe_head *sh, int method) clear_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); } -static void compute_parity6(struct stripe_head *sh, int method) -{ - raid6_conf_t *conf = sh->raid_conf; - int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = conf->raid_disks, count; - struct bio *chosen; - /**** FIX THIS: This could be very bad if disks is close to 256 ****/ - void *ptrs[disks]; - - qd_idx = raid6_next_disk(pd_idx, disks); - d0_idx = raid6_next_disk(qd_idx, disks); - - PRINTK("compute_parity, stripe %llu, method %d\n", - (unsigned long long)sh->sector, method); - - switch(method) { - case READ_MODIFY_WRITE: - BUG(); /* READ_MODIFY_WRITE N/A for RAID-6 */ - case RECONSTRUCT_WRITE: - for (i= disks; i-- ;) - if ( i != pd_idx && i != qd_idx && sh->dev[i].towrite ) { - chosen = sh->dev[i].towrite; - sh->dev[i].towrite = NULL; - - if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) - wake_up(&conf->wait_for_overlap); - - if (sh->dev[i].written) BUG(); - sh->dev[i].written = chosen; - } - break; - case CHECK_PARITY: - BUG(); /* Not implemented yet */ - } - - for (i = disks; i--;) - if (sh->dev[i].written) { - sector_t sector = sh->dev[i].sector; - struct bio *wbi = sh->dev[i].written; - while (wbi && wbi->bi_sector < sector + STRIPE_SECTORS) { - copy_data(1, wbi, sh->dev[i].page, sector); - wbi = r5_next_bio(wbi, sector); - } - - set_bit(R5_LOCKED, &sh->dev[i].flags); - set_bit(R5_UPTODATE, &sh->dev[i].flags); - } - -// switch(method) { -// case RECONSTRUCT_WRITE: -// case CHECK_PARITY: -// case UPDATE_PARITY: - /* Note that unlike RAID-5, the ordering of the disks matters greatly. */ - /* FIX: Is this ordering of drives even remotely optimal? */ - count = 0; - i = d0_idx; - do { - ptrs[count++] = page_address(sh->dev[i].page); - if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags)) - printk("block %d/%d not uptodate on parity calc\n", i,count); - i = raid6_next_disk(i, disks); - } while ( i != d0_idx ); -// break; -// } - - raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs); - - switch(method) { - case RECONSTRUCT_WRITE: - set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); - set_bit(R5_UPTODATE, &sh->dev[qd_idx].flags); - set_bit(R5_LOCKED, &sh->dev[pd_idx].flags); - set_bit(R5_LOCKED, &sh->dev[qd_idx].flags); - break; - case UPDATE_PARITY: - set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); - set_bit(R5_UPTODATE, &sh->dev[qd_idx].flags); - break; - } -} - - -/* Compute one missing block */ -static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero) -{ - raid6_conf_t *conf = sh->raid_conf; - int i, count, disks = conf->raid_disks; - void *ptr[MAX_XOR_BLOCKS], *p; - int pd_idx = sh->pd_idx; - int qd_idx = raid6_next_disk(pd_idx, disks); - - PRINTK("compute_block_1, stripe %llu, idx %d\n", - (unsigned long long)sh->sector, dd_idx); - - if ( dd_idx == qd_idx ) { - /* We're actually computing the Q drive */ - compute_parity6(sh, UPDATE_PARITY); - } else { - ptr[0] = page_address(sh->dev[dd_idx].page); - if (!nozero) memset(ptr[0], 0, STRIPE_SIZE); - count = 1; - for (i = disks ; i--; ) { - if (i == dd_idx || i == qd_idx) - continue; - p = page_address(sh->dev[i].page); - if (test_bit(R5_UPTODATE, &sh->dev[i].flags)) - ptr[count++] = p; - else - printk("compute_block() %d, stripe %llu, %d" - " not present\n", dd_idx, - (unsigned long long)sh->sector, i); - - check_xor(); - } - if (count != 1) - xor_block(count, STRIPE_SIZE, ptr); - if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); - else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); - } -} - -/* Compute two missing blocks */ -static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2) -{ - raid6_conf_t *conf = sh->raid_conf; - int i, count, disks = conf->raid_disks; - int pd_idx = sh->pd_idx; - int qd_idx = raid6_next_disk(pd_idx, disks); - int d0_idx = raid6_next_disk(qd_idx, disks); - int faila, failb; - - /* faila and failb are disk numbers relative to d0_idx */ - /* pd_idx become disks-2 and qd_idx become disks-1 */ - faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx; - failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx; - - BUG_ON(faila == failb); - if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; } - - PRINTK("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n", - (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb); - - if ( failb == disks-1 ) { - /* Q disk is one of the missing disks */ - if ( faila == disks-2 ) { - /* Missing P+Q, just recompute */ - compute_parity6(sh, UPDATE_PARITY); - return; - } else { - /* We're missing D+Q; recompute D from P */ - compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0); - compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */ - return; - } - } - - /* We're missing D+P or D+D; build pointer table */ - { - /**** FIX THIS: This could be very bad if disks is close to 256 ****/ - void *ptrs[disks]; - - count = 0; - i = d0_idx; - do { - ptrs[count++] = page_address(sh->dev[i].page); - i = raid6_next_disk(i, disks); - if (i != dd_idx1 && i != dd_idx2 && - !test_bit(R5_UPTODATE, &sh->dev[i].flags)) - printk("compute_2 with missing block %d/%d\n", count, i); - } while ( i != d0_idx ); - - if ( failb == disks-2 ) { - /* We're missing D+P. */ - raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs); - } else { - /* We're missing D+D. */ - raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs); - } - - /* Both the above update both missing blocks */ - set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags); - set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags); - } -} - - - /* * Each stripe/dev can have one or more bion attached. - * toread/towrite point to the first in a chain. + * toread/towrite point to the first in a chain. * The bi_next chain must be in order. */ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite) @@ -1301,13 +1031,6 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in static void end_reshape(raid5_conf_t *conf); -static int page_is_zero(struct page *p) -{ - char *a = page_address(p); - return ((*(u32*)a) == 0 && - memcmp(a, a+4, STRIPE_SIZE-4)==0); -} - static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) { int sectors_per_chunk = conf->chunk_size >> 9; @@ -1339,7 +1062,7 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) * */ -static void handle_stripe5(struct stripe_head *sh) +static void handle_stripe(struct stripe_head *sh) { raid5_conf_t *conf = sh->raid_conf; int disks = sh->disks; @@ -1671,7 +1394,7 @@ static void handle_stripe5(struct stripe_head *sh) if (locked == 0 && (rcw == 0 ||rmw == 0) && !test_bit(STRIPE_BIT_DELAY, &sh->state)) { PRINTK("Computing parity...\n"); - compute_parity5(sh, rcw==0 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE); + compute_parity(sh, rcw==0 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE); /* now every locked buffer is ready to be written */ for (i=disks; i--;) if (test_bit(R5_LOCKED, &sh->dev[i].flags)) { @@ -1698,10 +1421,13 @@ static void handle_stripe5(struct stripe_head *sh) !test_bit(STRIPE_INSYNC, &sh->state)) { set_bit(STRIPE_HANDLE, &sh->state); if (failed == 0) { + char *pagea; BUG_ON(uptodate != disks); - compute_parity5(sh, CHECK_PARITY); + compute_parity(sh, CHECK_PARITY); uptodate--; - if (page_is_zero(sh->dev[sh->pd_idx].page)) { + pagea = page_address(sh->dev[sh->pd_idx].page); + if ((*(u32*)pagea) == 0 && + !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { /* parity is correct (on disc, not in buffer any more) */ set_bit(STRIPE_INSYNC, &sh->state); } else { @@ -1761,7 +1487,7 @@ static void handle_stripe5(struct stripe_head *sh) /* Need to write out all blocks after computing parity */ sh->disks = conf->raid_disks; sh->pd_idx = stripe_to_pdidx(sh->sector, conf, conf->raid_disks); - compute_parity5(sh, RECONSTRUCT_WRITE); + compute_parity(sh, RECONSTRUCT_WRITE); for (i= conf->raid_disks; i--;) { set_bit(R5_LOCKED, &sh->dev[i].flags); locked++; @@ -1889,630 +1615,67 @@ static void handle_stripe5(struct stripe_head *sh) } } -static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) +static void raid5_activate_delayed(raid5_conf_t *conf) { - raid6_conf_t *conf = sh->raid_conf; - int disks = conf->raid_disks; - struct bio *return_bi= NULL; - struct bio *bi; - int i; - int syncing; - int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0; - int non_overwrite = 0; - int failed_num[2] = {0, 0}; - struct r5dev *dev, *pdev, *qdev; - int pd_idx = sh->pd_idx; - int qd_idx = raid6_next_disk(pd_idx, disks); - int p_failed, q_failed; - - PRINTK("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d, qd_idx=%d\n", - (unsigned long long)sh->sector, sh->state, atomic_read(&sh->count), - pd_idx, qd_idx); + if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) { + while (!list_empty(&conf->delayed_list)) { + struct list_head *l = conf->delayed_list.next; + struct stripe_head *sh; + sh = list_entry(l, struct stripe_head, lru); + list_del_init(l); + clear_bit(STRIPE_DELAYED, &sh->state); + if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + atomic_inc(&conf->preread_active_stripes); + list_add_tail(&sh->lru, &conf->handle_list); + } + } +} - spin_lock(&sh->lock); - clear_bit(STRIPE_HANDLE, &sh->state); - clear_bit(STRIPE_DELAYED, &sh->state); +static void activate_bit_delay(raid5_conf_t *conf) +{ + /* device_lock is held */ + struct list_head head; + list_add(&head, &conf->bitmap_list); + list_del_init(&conf->bitmap_list); + while (!list_empty(&head)) { + struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru); + list_del_init(&sh->lru); + atomic_inc(&sh->count); + __release_stripe(conf, sh); + } +} - syncing = test_bit(STRIPE_SYNCING, &sh->state); - /* Now to look around and see what can be done */ +static void unplug_slaves(mddev_t *mddev) +{ + raid5_conf_t *conf = mddev_to_conf(mddev); + int i; rcu_read_lock(); - for (i=disks; i--; ) { - mdk_rdev_t *rdev; - dev = &sh->dev[i]; - clear_bit(R5_Insync, &dev->flags); - - PRINTK("check %d: state 0x%lx read %p write %p written %p\n", - i, dev->flags, dev->toread, dev->towrite, dev->written); - /* maybe we can reply to a read */ - if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread) { - struct bio *rbi, *rbi2; - PRINTK("Return read for disc %d\n", i); - spin_lock_irq(&conf->device_lock); - rbi = dev->toread; - dev->toread = NULL; - if (test_and_clear_bit(R5_Overlap, &dev->flags)) - wake_up(&conf->wait_for_overlap); - spin_unlock_irq(&conf->device_lock); - while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) { - copy_data(0, rbi, dev->page, dev->sector); - rbi2 = r5_next_bio(rbi, dev->sector); - spin_lock_irq(&conf->device_lock); - if (--rbi->bi_phys_segments == 0) { - rbi->bi_next = return_bi; - return_bi = rbi; - } - spin_unlock_irq(&conf->device_lock); - rbi = rbi2; - } - } + for (i=0; iraid_disks; i++) { + mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { + request_queue_t *r_queue = bdev_get_queue(rdev->bdev); - /* now count some things */ - if (test_bit(R5_LOCKED, &dev->flags)) locked++; - if (test_bit(R5_UPTODATE, &dev->flags)) uptodate++; + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + if (r_queue->unplug_fn) + r_queue->unplug_fn(r_queue); - if (dev->toread) to_read++; - if (dev->towrite) { - to_write++; - if (!test_bit(R5_OVERWRITE, &dev->flags)) - non_overwrite++; - } - if (dev->written) written++; - rdev = rcu_dereference(conf->disks[i].rdev); - if (!rdev || !test_bit(In_sync, &rdev->flags)) { - /* The ReadError flag will just be confusing now */ - clear_bit(R5_ReadError, &dev->flags); - clear_bit(R5_ReWrite, &dev->flags); + rdev_dec_pending(rdev, mddev); + rcu_read_lock(); } - if (!rdev || !test_bit(In_sync, &rdev->flags) - || test_bit(R5_ReadError, &dev->flags)) { - if ( failed < 2 ) - failed_num[failed] = i; - failed++; - } else - set_bit(R5_Insync, &dev->flags); } rcu_read_unlock(); - PRINTK("locked=%d uptodate=%d to_read=%d" - " to_write=%d failed=%d failed_num=%d,%d\n", - locked, uptodate, to_read, to_write, failed, - failed_num[0], failed_num[1]); - /* check if the array has lost >2 devices and, if so, some requests might - * need to be failed - */ - if (failed > 2 && to_read+to_write+written) { - for (i=disks; i--; ) { - int bitmap_end = 0; - - if (test_bit(R5_ReadError, &sh->dev[i].flags)) { - mdk_rdev_t *rdev; - rcu_read_lock(); - rdev = rcu_dereference(conf->disks[i].rdev); - if (rdev && test_bit(In_sync, &rdev->flags)) - /* multiple read failures in one stripe */ - md_error(conf->mddev, rdev); - rcu_read_unlock(); - } +} - spin_lock_irq(&conf->device_lock); - /* fail all writes first */ - bi = sh->dev[i].towrite; - sh->dev[i].towrite = NULL; - if (bi) { to_write--; bitmap_end = 1; } +static void raid5_unplug_device(request_queue_t *q) +{ + mddev_t *mddev = q->queuedata; + raid5_conf_t *conf = mddev_to_conf(mddev); + unsigned long flags; - if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) - wake_up(&conf->wait_for_overlap); - - while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ - struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); - clear_bit(BIO_UPTODATE, &bi->bi_flags); - if (--bi->bi_phys_segments == 0) { - md_write_end(conf->mddev); - bi->bi_next = return_bi; - return_bi = bi; - } - bi = nextbi; - } - /* and fail all 'written' */ - bi = sh->dev[i].written; - sh->dev[i].written = NULL; - if (bi) bitmap_end = 1; - while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) { - struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector); - clear_bit(BIO_UPTODATE, &bi->bi_flags); - if (--bi->bi_phys_segments == 0) { - md_write_end(conf->mddev); - bi->bi_next = return_bi; - return_bi = bi; - } - bi = bi2; - } - - /* fail any reads if this device is non-operational */ - if (!test_bit(R5_Insync, &sh->dev[i].flags) || - test_bit(R5_ReadError, &sh->dev[i].flags)) { - bi = sh->dev[i].toread; - sh->dev[i].toread = NULL; - if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) - wake_up(&conf->wait_for_overlap); - if (bi) to_read--; - while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ - struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); - clear_bit(BIO_UPTODATE, &bi->bi_flags); - if (--bi->bi_phys_segments == 0) { - bi->bi_next = return_bi; - return_bi = bi; - } - bi = nextbi; - } - } - spin_unlock_irq(&conf->device_lock); - if (bitmap_end) - bitmap_endwrite(conf->mddev->bitmap, sh->sector, - STRIPE_SECTORS, 0, 0); - } - } - if (failed > 2 && syncing) { - md_done_sync(conf->mddev, STRIPE_SECTORS,0); - clear_bit(STRIPE_SYNCING, &sh->state); - syncing = 0; - } - - /* - * might be able to return some write requests if the parity blocks - * are safe, or on a failed drive - */ - pdev = &sh->dev[pd_idx]; - p_failed = (failed >= 1 && failed_num[0] == pd_idx) - || (failed >= 2 && failed_num[1] == pd_idx); - qdev = &sh->dev[qd_idx]; - q_failed = (failed >= 1 && failed_num[0] == qd_idx) - || (failed >= 2 && failed_num[1] == qd_idx); - - if ( written && - ( p_failed || ((test_bit(R5_Insync, &pdev->flags) - && !test_bit(R5_LOCKED, &pdev->flags) - && test_bit(R5_UPTODATE, &pdev->flags))) ) && - ( q_failed || ((test_bit(R5_Insync, &qdev->flags) - && !test_bit(R5_LOCKED, &qdev->flags) - && test_bit(R5_UPTODATE, &qdev->flags))) ) ) { - /* any written block on an uptodate or failed drive can be - * returned. Note that if we 'wrote' to a failed drive, - * it will be UPTODATE, but never LOCKED, so we don't need - * to test 'failed' directly. - */ - for (i=disks; i--; ) - if (sh->dev[i].written) { - dev = &sh->dev[i]; - if (!test_bit(R5_LOCKED, &dev->flags) && - test_bit(R5_UPTODATE, &dev->flags) ) { - /* We can return any write requests */ - int bitmap_end = 0; - struct bio *wbi, *wbi2; - PRINTK("Return write for stripe %llu disc %d\n", - (unsigned long long)sh->sector, i); - spin_lock_irq(&conf->device_lock); - wbi = dev->written; - dev->written = NULL; - while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) { - wbi2 = r5_next_bio(wbi, dev->sector); - if (--wbi->bi_phys_segments == 0) { - md_write_end(conf->mddev); - wbi->bi_next = return_bi; - return_bi = wbi; - } - wbi = wbi2; - } - if (dev->towrite == NULL) - bitmap_end = 1; - spin_unlock_irq(&conf->device_lock); - if (bitmap_end) - bitmap_endwrite(conf->mddev->bitmap, sh->sector, - STRIPE_SECTORS, - !test_bit(STRIPE_DEGRADED, &sh->state), 0); - } - } - } - - /* Now we might consider reading some blocks, either to check/generate - * parity, or to satisfy requests - * or to load a block that is being partially written. - */ - if (to_read || non_overwrite || (to_write && failed) || (syncing && (uptodate < disks))) { - for (i=disks; i--;) { - dev = &sh->dev[i]; - if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && - (dev->toread || - (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || - syncing || - (failed >= 1 && (sh->dev[failed_num[0]].toread || to_write)) || - (failed >= 2 && (sh->dev[failed_num[1]].toread || to_write)) - ) - ) { - /* we would like to get this block, possibly - * by computing it, but we might not be able to - */ - if (uptodate == disks-1) { - PRINTK("Computing stripe %llu block %d\n", - (unsigned long long)sh->sector, i); - compute_block_1(sh, i, 0); - uptodate++; - } else if ( uptodate == disks-2 && failed >= 2 ) { - /* Computing 2-failure is *very* expensive; only do it if failed >= 2 */ - int other; - for (other=disks; other--;) { - if ( other == i ) - continue; - if ( !test_bit(R5_UPTODATE, &sh->dev[other].flags) ) - break; - } - BUG_ON(other < 0); - PRINTK("Computing stripe %llu blocks %d,%d\n", - (unsigned long long)sh->sector, i, other); - compute_block_2(sh, i, other); - uptodate += 2; - } else if (test_bit(R5_Insync, &dev->flags)) { - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantread, &dev->flags); -#if 0 - /* if I am just reading this block and we don't have - a failed drive, or any pending writes then sidestep the cache */ - if (sh->bh_read[i] && !sh->bh_read[i]->b_reqnext && - ! syncing && !failed && !to_write) { - sh->bh_cache[i]->b_page = sh->bh_read[i]->b_page; - sh->bh_cache[i]->b_data = sh->bh_read[i]->b_data; - } -#endif - locked++; - PRINTK("Reading block %d (sync=%d)\n", - i, syncing); - } - } - } - set_bit(STRIPE_HANDLE, &sh->state); - } - - /* now to consider writing and what else, if anything should be read */ - if (to_write) { - int rcw=0, must_compute=0; - for (i=disks ; i--;) { - dev = &sh->dev[i]; - /* Would I have to read this buffer for reconstruct_write */ - if (!test_bit(R5_OVERWRITE, &dev->flags) - && i != pd_idx && i != qd_idx - && (!test_bit(R5_LOCKED, &dev->flags) -#if 0 - || sh->bh_page[i] != bh->b_page -#endif - ) && - !test_bit(R5_UPTODATE, &dev->flags)) { - if (test_bit(R5_Insync, &dev->flags)) rcw++; - else { - PRINTK("raid6: must_compute: disk %d flags=%#lx\n", i, dev->flags); - must_compute++; - } - } - } - PRINTK("for sector %llu, rcw=%d, must_compute=%d\n", - (unsigned long long)sh->sector, rcw, must_compute); - set_bit(STRIPE_HANDLE, &sh->state); - - if (rcw > 0) - /* want reconstruct write, but need to get some data */ - for (i=disks; i--;) { - dev = &sh->dev[i]; - if (!test_bit(R5_OVERWRITE, &dev->flags) - && !(failed == 0 && (i == pd_idx || i == qd_idx)) - && !test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && - test_bit(R5_Insync, &dev->flags)) { - if (test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) - { - PRINTK("Read_old stripe %llu block %d for Reconstruct\n", - (unsigned long long)sh->sector, i); - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantread, &dev->flags); - locked++; - } else { - PRINTK("Request delayed stripe %llu block %d for Reconstruct\n", - (unsigned long long)sh->sector, i); - set_bit(STRIPE_DELAYED, &sh->state); - set_bit(STRIPE_HANDLE, &sh->state); - } - } - } - /* now if nothing is locked, and if we have enough data, we can start a write request */ - if (locked == 0 && rcw == 0 && - !test_bit(STRIPE_BIT_DELAY, &sh->state)) { - if ( must_compute > 0 ) { - /* We have failed blocks and need to compute them */ - switch ( failed ) { - case 0: BUG(); - case 1: compute_block_1(sh, failed_num[0], 0); break; - case 2: compute_block_2(sh, failed_num[0], failed_num[1]); break; - default: BUG(); /* This request should have been failed? */ - } - } - - PRINTK("Computing parity for stripe %llu\n", (unsigned long long)sh->sector); - compute_parity6(sh, RECONSTRUCT_WRITE); - /* now every locked buffer is ready to be written */ - for (i=disks; i--;) - if (test_bit(R5_LOCKED, &sh->dev[i].flags)) { - PRINTK("Writing stripe %llu block %d\n", - (unsigned long long)sh->sector, i); - locked++; - set_bit(R5_Wantwrite, &sh->dev[i].flags); - } - /* after a RECONSTRUCT_WRITE, the stripe MUST be in-sync */ - set_bit(STRIPE_INSYNC, &sh->state); - - if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { - atomic_dec(&conf->preread_active_stripes); - if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) - md_wakeup_thread(conf->mddev->thread); - } - } - } - - /* maybe we need to check and possibly fix the parity for this stripe - * Any reads will already have been scheduled, so we just see if enough data - * is available - */ - if (syncing && locked == 0 && !test_bit(STRIPE_INSYNC, &sh->state)) { - int update_p = 0, update_q = 0; - struct r5dev *dev; - - set_bit(STRIPE_HANDLE, &sh->state); - - BUG_ON(failed>2); - BUG_ON(uptodate < disks); - /* Want to check and possibly repair P and Q. - * However there could be one 'failed' device, in which - * case we can only check one of them, possibly using the - * other to generate missing data - */ - - /* If !tmp_page, we cannot do the calculations, - * but as we have set STRIPE_HANDLE, we will soon be called - * by stripe_handle with a tmp_page - just wait until then. - */ - if (tmp_page) { - if (failed == q_failed) { - /* The only possible failed device holds 'Q', so it makes - * sense to check P (If anything else were failed, we would - * have used P to recreate it). - */ - compute_block_1(sh, pd_idx, 1); - if (!page_is_zero(sh->dev[pd_idx].page)) { - compute_block_1(sh,pd_idx,0); - update_p = 1; - } - } - if (!q_failed && failed < 2) { - /* q is not failed, and we didn't use it to generate - * anything, so it makes sense to check it - */ - memcpy(page_address(tmp_page), - page_address(sh->dev[qd_idx].page), - STRIPE_SIZE); - compute_parity6(sh, UPDATE_PARITY); - if (memcmp(page_address(tmp_page), - page_address(sh->dev[qd_idx].page), - STRIPE_SIZE)!= 0) { - clear_bit(STRIPE_INSYNC, &sh->state); - update_q = 1; - } - } - if (update_p || update_q) { - conf->mddev->resync_mismatches += STRIPE_SECTORS; - if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) - /* don't try to repair!! */ - update_p = update_q = 0; - } - - /* now write out any block on a failed drive, - * or P or Q if they need it - */ - - if (failed == 2) { - dev = &sh->dev[failed_num[1]]; - locked++; - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantwrite, &dev->flags); - } - if (failed >= 1) { - dev = &sh->dev[failed_num[0]]; - locked++; - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantwrite, &dev->flags); - } - - if (update_p) { - dev = &sh->dev[pd_idx]; - locked ++; - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantwrite, &dev->flags); - } - if (update_q) { - dev = &sh->dev[qd_idx]; - locked++; - set_bit(R5_LOCKED, &dev->flags); - set_bit(R5_Wantwrite, &dev->flags); - } - clear_bit(STRIPE_DEGRADED, &sh->state); - - set_bit(STRIPE_INSYNC, &sh->state); - } - } - - if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { - md_done_sync(conf->mddev, STRIPE_SECTORS,1); - clear_bit(STRIPE_SYNCING, &sh->state); - } - - /* If the failed drives are just a ReadError, then we might need - * to progress the repair/check process - */ - if (failed <= 2 && ! conf->mddev->ro) - for (i=0; idev[failed_num[i]]; - if (test_bit(R5_ReadError, &dev->flags) - && !test_bit(R5_LOCKED, &dev->flags) - && test_bit(R5_UPTODATE, &dev->flags) - ) { - if (!test_bit(R5_ReWrite, &dev->flags)) { - set_bit(R5_Wantwrite, &dev->flags); - set_bit(R5_ReWrite, &dev->flags); - set_bit(R5_LOCKED, &dev->flags); - } else { - /* let's read it back */ - set_bit(R5_Wantread, &dev->flags); - set_bit(R5_LOCKED, &dev->flags); - } - } - } - spin_unlock(&sh->lock); - - while ((bi=return_bi)) { - int bytes = bi->bi_size; - - return_bi = bi->bi_next; - bi->bi_next = NULL; - bi->bi_size = 0; - bi->bi_end_io(bi, bytes, 0); - } - for (i=disks; i-- ;) { - int rw; - struct bio *bi; - mdk_rdev_t *rdev; - if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags)) - rw = 1; - else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags)) - rw = 0; - else - continue; - - bi = &sh->dev[i].req; - - bi->bi_rw = rw; - if (rw) - bi->bi_end_io = raid5_end_write_request; - else - bi->bi_end_io = raid5_end_read_request; - - rcu_read_lock(); - rdev = rcu_dereference(conf->disks[i].rdev); - if (rdev && test_bit(Faulty, &rdev->flags)) - rdev = NULL; - if (rdev) - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - - if (rdev) { - if (syncing) - md_sync_acct(rdev->bdev, STRIPE_SECTORS); - - bi->bi_bdev = rdev->bdev; - PRINTK("for %llu schedule op %ld on disc %d\n", - (unsigned long long)sh->sector, bi->bi_rw, i); - atomic_inc(&sh->count); - bi->bi_sector = sh->sector + rdev->data_offset; - bi->bi_flags = 1 << BIO_UPTODATE; - bi->bi_vcnt = 1; - bi->bi_max_vecs = 1; - bi->bi_idx = 0; - bi->bi_io_vec = &sh->dev[i].vec; - bi->bi_io_vec[0].bv_len = STRIPE_SIZE; - bi->bi_io_vec[0].bv_offset = 0; - bi->bi_size = STRIPE_SIZE; - bi->bi_next = NULL; - if (rw == WRITE && - test_bit(R5_ReWrite, &sh->dev[i].flags)) - atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); - generic_make_request(bi); - } else { - if (rw == 1) - set_bit(STRIPE_DEGRADED, &sh->state); - PRINTK("skip op %ld on disc %d for sector %llu\n", - bi->bi_rw, i, (unsigned long long)sh->sector); - clear_bit(R5_LOCKED, &sh->dev[i].flags); - set_bit(STRIPE_HANDLE, &sh->state); - } - } -} - -static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) -{ - if (sh->raid_conf->level == 6) - handle_stripe6(sh, tmp_page); - else - handle_stripe5(sh); -} - - - -static void raid5_activate_delayed(raid5_conf_t *conf) -{ - if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) { - while (!list_empty(&conf->delayed_list)) { - struct list_head *l = conf->delayed_list.next; - struct stripe_head *sh; - sh = list_entry(l, struct stripe_head, lru); - list_del_init(l); - clear_bit(STRIPE_DELAYED, &sh->state); - if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) - atomic_inc(&conf->preread_active_stripes); - list_add_tail(&sh->lru, &conf->handle_list); - } - } -} - -static void activate_bit_delay(raid5_conf_t *conf) -{ - /* device_lock is held */ - struct list_head head; - list_add(&head, &conf->bitmap_list); - list_del_init(&conf->bitmap_list); - while (!list_empty(&head)) { - struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru); - list_del_init(&sh->lru); - atomic_inc(&sh->count); - __release_stripe(conf, sh); - } -} - -static void unplug_slaves(mddev_t *mddev) -{ - raid5_conf_t *conf = mddev_to_conf(mddev); - int i; - - rcu_read_lock(); - for (i=0; iraid_disks; i++) { - mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); - if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { - request_queue_t *r_queue = bdev_get_queue(rdev->bdev); - - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - - if (r_queue->unplug_fn) - r_queue->unplug_fn(r_queue); - - rdev_dec_pending(rdev, mddev); - rcu_read_lock(); - } - } - rcu_read_unlock(); -} - -static void raid5_unplug_device(request_queue_t *q) -{ - mddev_t *mddev = q->queuedata; - raid5_conf_t *conf = mddev_to_conf(mddev); - unsigned long flags; - - spin_lock_irqsave(&conf->device_lock, flags); + spin_lock_irqsave(&conf->device_lock, flags); if (blk_remove_plug(q)) { conf->seq_flush++; @@ -2590,7 +1753,7 @@ static int make_request(request_queue_t *q, struct bio * bi) for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); - int disks, data_disks; + int disks; retry: prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); @@ -2618,9 +1781,7 @@ static int make_request(request_queue_t *q, struct bio * bi) } spin_unlock_irq(&conf->device_lock); } - data_disks = disks - conf->max_degraded; - - new_sector = raid5_compute_sector(logical_sector, disks, data_disks, + new_sector = raid5_compute_sector(logical_sector, disks, disks - 1, &dd_idx, &pd_idx, conf); PRINTK("raid5: make_request, sector %llu logical %llu\n", (unsigned long long)new_sector, @@ -2672,7 +1833,7 @@ static int make_request(request_queue_t *q, struct bio * bi) } finish_wait(&conf->wait_for_overlap, &w); raid5_plug_device(conf); - handle_stripe(sh, NULL); + handle_stripe(sh); release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ @@ -2688,7 +1849,7 @@ static int make_request(request_queue_t *q, struct bio * bi) if (remaining == 0) { int bytes = bi->bi_size; - if ( rw == WRITE ) + if ( bio_data_dir(bi) == WRITE ) md_write_end(mddev); bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); @@ -2696,142 +1857,17 @@ static int make_request(request_queue_t *q, struct bio * bi) return 0; } -static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped) -{ - /* reshaping is quite different to recovery/resync so it is - * handled quite separately ... here. - * - * On each call to sync_request, we gather one chunk worth of - * destination stripes and flag them as expanding. - * Then we find all the source stripes and request reads. - * As the reads complete, handle_stripe will copy the data - * into the destination stripe and release that stripe. - */ - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; - struct stripe_head *sh; - int pd_idx; - sector_t first_sector, last_sector; - int raid_disks; - int data_disks; - int i; - int dd_idx; - sector_t writepos, safepos, gap; - - if (sector_nr == 0 && - conf->expand_progress != 0) { - /* restarting in the middle, skip the initial sectors */ - sector_nr = conf->expand_progress; - sector_div(sector_nr, conf->raid_disks-1); - *skipped = 1; - return sector_nr; - } - - /* we update the metadata when there is more than 3Meg - * in the block range (that is rather arbitrary, should - * probably be time based) or when the data about to be - * copied would over-write the source of the data at - * the front of the range. - * i.e. one new_stripe forward from expand_progress new_maps - * to after where expand_lo old_maps to - */ - writepos = conf->expand_progress + - conf->chunk_size/512*(conf->raid_disks-1); - sector_div(writepos, conf->raid_disks-1); - safepos = conf->expand_lo; - sector_div(safepos, conf->previous_raid_disks-1); - gap = conf->expand_progress - conf->expand_lo; - - if (writepos >= safepos || - gap > (conf->raid_disks-1)*3000*2 /*3Meg*/) { - /* Cannot proceed until we've updated the superblock... */ - wait_event(conf->wait_for_overlap, - atomic_read(&conf->reshape_stripes)==0); - mddev->reshape_position = conf->expand_progress; - mddev->sb_dirty = 1; - md_wakeup_thread(mddev->thread); - wait_event(mddev->sb_wait, mddev->sb_dirty == 0 || - kthread_should_stop()); - spin_lock_irq(&conf->device_lock); - conf->expand_lo = mddev->reshape_position; - spin_unlock_irq(&conf->device_lock); - wake_up(&conf->wait_for_overlap); - } - - for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) { - int j; - int skipped = 0; - pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks); - sh = get_active_stripe(conf, sector_nr+i, - conf->raid_disks, pd_idx, 0); - set_bit(STRIPE_EXPANDING, &sh->state); - atomic_inc(&conf->reshape_stripes); - /* If any of this stripe is beyond the end of the old - * array, then we need to zero those blocks - */ - for (j=sh->disks; j--;) { - sector_t s; - if (j == sh->pd_idx) - continue; - s = compute_blocknr(sh, j); - if (s < (mddev->array_size<<1)) { - skipped = 1; - continue; - } - memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE); - set_bit(R5_Expanded, &sh->dev[j].flags); - set_bit(R5_UPTODATE, &sh->dev[j].flags); - } - if (!skipped) { - set_bit(STRIPE_EXPAND_READY, &sh->state); - set_bit(STRIPE_HANDLE, &sh->state); - } - release_stripe(sh); - } - spin_lock_irq(&conf->device_lock); - conf->expand_progress = (sector_nr + i)*(conf->raid_disks-1); - spin_unlock_irq(&conf->device_lock); - /* Ok, those stripe are ready. We can start scheduling - * reads on the source stripes. - * The source stripes are determined by mapping the first and last - * block on the destination stripes. - */ - raid_disks = conf->previous_raid_disks; - data_disks = raid_disks - 1; - first_sector = - raid5_compute_sector(sector_nr*(conf->raid_disks-1), - raid_disks, data_disks, - &dd_idx, &pd_idx, conf); - last_sector = - raid5_compute_sector((sector_nr+conf->chunk_size/512) - *(conf->raid_disks-1) -1, - raid_disks, data_disks, - &dd_idx, &pd_idx, conf); - if (last_sector >= (mddev->size<<1)) - last_sector = (mddev->size<<1)-1; - while (first_sector <= last_sector) { - pd_idx = stripe_to_pdidx(first_sector, conf, conf->previous_raid_disks); - sh = get_active_stripe(conf, first_sector, - conf->previous_raid_disks, pd_idx, 0); - set_bit(STRIPE_EXPAND_SOURCE, &sh->state); - set_bit(STRIPE_HANDLE, &sh->state); - release_stripe(sh); - first_sector += STRIPE_SECTORS; - } - return conf->chunk_size>>9; -} - /* FIXME go_faster isn't used */ -static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { raid5_conf_t *conf = (raid5_conf_t *) mddev->private; struct stripe_head *sh; int pd_idx; + sector_t first_sector, last_sector; int raid_disks = conf->raid_disks; - int data_disks = raid_disks - conf->max_degraded; + int data_disks = raid_disks-1; sector_t max_sector = mddev->size << 1; int sync_blocks; - int still_degraded = 0; - int i; if (sector_nr >= max_sector) { /* just being told to finish up .. nothing much to do */ @@ -2844,22 +1880,134 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski if (mddev->curr_resync < max_sector) /* aborted */ bitmap_end_sync(mddev->bitmap, mddev->curr_resync, &sync_blocks, 1); - else /* completed sync */ + else /* compelted sync */ conf->fullsync = 0; bitmap_close_sync(mddev->bitmap); return 0; } - if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) - return reshape_request(mddev, sector_nr, skipped); - - /* if there is too many failed drives and we are trying + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { + /* reshaping is quite different to recovery/resync so it is + * handled quite separately ... here. + * + * On each call to sync_request, we gather one chunk worth of + * destination stripes and flag them as expanding. + * Then we find all the source stripes and request reads. + * As the reads complete, handle_stripe will copy the data + * into the destination stripe and release that stripe. + */ + int i; + int dd_idx; + sector_t writepos, safepos, gap; + + if (sector_nr == 0 && + conf->expand_progress != 0) { + /* restarting in the middle, skip the initial sectors */ + sector_nr = conf->expand_progress; + sector_div(sector_nr, conf->raid_disks-1); + *skipped = 1; + return sector_nr; + } + + /* we update the metadata when there is more than 3Meg + * in the block range (that is rather arbitrary, should + * probably be time based) or when the data about to be + * copied would over-write the source of the data at + * the front of the range. + * i.e. one new_stripe forward from expand_progress new_maps + * to after where expand_lo old_maps to + */ + writepos = conf->expand_progress + + conf->chunk_size/512*(conf->raid_disks-1); + sector_div(writepos, conf->raid_disks-1); + safepos = conf->expand_lo; + sector_div(safepos, conf->previous_raid_disks-1); + gap = conf->expand_progress - conf->expand_lo; + + if (writepos >= safepos || + gap > (conf->raid_disks-1)*3000*2 /*3Meg*/) { + /* Cannot proceed until we've updated the superblock... */ + wait_event(conf->wait_for_overlap, + atomic_read(&conf->reshape_stripes)==0); + mddev->reshape_position = conf->expand_progress; + mddev->sb_dirty = 1; + md_wakeup_thread(mddev->thread); + wait_event(mddev->sb_wait, mddev->sb_dirty == 0 || + kthread_should_stop()); + spin_lock_irq(&conf->device_lock); + conf->expand_lo = mddev->reshape_position; + spin_unlock_irq(&conf->device_lock); + wake_up(&conf->wait_for_overlap); + } + + for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) { + int j; + int skipped = 0; + pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks); + sh = get_active_stripe(conf, sector_nr+i, + conf->raid_disks, pd_idx, 0); + set_bit(STRIPE_EXPANDING, &sh->state); + atomic_inc(&conf->reshape_stripes); + /* If any of this stripe is beyond the end of the old + * array, then we need to zero those blocks + */ + for (j=sh->disks; j--;) { + sector_t s; + if (j == sh->pd_idx) + continue; + s = compute_blocknr(sh, j); + if (s < (mddev->array_size<<1)) { + skipped = 1; + continue; + } + memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE); + set_bit(R5_Expanded, &sh->dev[j].flags); + set_bit(R5_UPTODATE, &sh->dev[j].flags); + } + if (!skipped) { + set_bit(STRIPE_EXPAND_READY, &sh->state); + set_bit(STRIPE_HANDLE, &sh->state); + } + release_stripe(sh); + } + spin_lock_irq(&conf->device_lock); + conf->expand_progress = (sector_nr + i)*(conf->raid_disks-1); + spin_unlock_irq(&conf->device_lock); + /* Ok, those stripe are ready. We can start scheduling + * reads on the source stripes. + * The source stripes are determined by mapping the first and last + * block on the destination stripes. + */ + raid_disks = conf->previous_raid_disks; + data_disks = raid_disks - 1; + first_sector = + raid5_compute_sector(sector_nr*(conf->raid_disks-1), + raid_disks, data_disks, + &dd_idx, &pd_idx, conf); + last_sector = + raid5_compute_sector((sector_nr+conf->chunk_size/512) + *(conf->raid_disks-1) -1, + raid_disks, data_disks, + &dd_idx, &pd_idx, conf); + if (last_sector >= (mddev->size<<1)) + last_sector = (mddev->size<<1)-1; + while (first_sector <= last_sector) { + pd_idx = stripe_to_pdidx(first_sector, conf, conf->previous_raid_disks); + sh = get_active_stripe(conf, first_sector, + conf->previous_raid_disks, pd_idx, 0); + set_bit(STRIPE_EXPAND_SOURCE, &sh->state); + set_bit(STRIPE_HANDLE, &sh->state); + release_stripe(sh); + first_sector += STRIPE_SECTORS; + } + return conf->chunk_size>>9; + } + /* if there is 1 or more failed drives and we are trying * to resync, then assert that we are finished, because there is * nothing we can do. */ - if (mddev->degraded >= conf->max_degraded && - test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { + if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { sector_t rv = (mddev->size << 1) - sector_nr; *skipped = 1; return rv; @@ -2878,26 +2026,17 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski if (sh == NULL) { sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0); /* make sure we don't swamp the stripe cache if someone else - * is trying to get access + * is trying to get access */ schedule_timeout_uninterruptible(1); } - /* Need to check if array will still be degraded after recovery/resync - * We don't need to check the 'failed' flag as when that gets set, - * recovery aborts. - */ - for (i=0; iraid_disks; i++) - if (conf->disks[i].rdev == NULL) - still_degraded = 1; - - bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); - - spin_lock(&sh->lock); + bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0); + spin_lock(&sh->lock); set_bit(STRIPE_SYNCING, &sh->state); clear_bit(STRIPE_INSYNC, &sh->state); spin_unlock(&sh->lock); - handle_stripe(sh, NULL); + handle_stripe(sh); release_stripe(sh); return STRIPE_SECTORS; @@ -2952,7 +2091,7 @@ static void raid5d (mddev_t *mddev) spin_unlock_irq(&conf->device_lock); handled++; - handle_stripe(sh, conf->spare_page); + handle_stripe(sh); release_stripe(sh); spin_lock_irq(&conf->device_lock); @@ -3042,8 +2181,8 @@ static int run(mddev_t *mddev) struct disk_info *disk; struct list_head *tmp; - if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { - printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n", + if (mddev->level != 5 && mddev->level != 4) { + printk(KERN_ERR "raid5: %s: raid level not set to 4/5 (%d)\n", mdname(mddev), mddev->level); return -EIO; } @@ -3112,11 +2251,6 @@ static int run(mddev_t *mddev) if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) goto abort; - if (mddev->level == 6) { - conf->spare_page = alloc_page(GFP_KERNEL); - if (!conf->spare_page) - goto abort; - } spin_lock_init(&conf->device_lock); init_waitqueue_head(&conf->wait_for_stripe); init_waitqueue_head(&conf->wait_for_overlap); @@ -3148,16 +2282,12 @@ static int run(mddev_t *mddev) } /* - * 0 for a fully functional array, 1 or 2 for a degraded array. + * 0 for a fully functional array, 1 for a degraded array. */ mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks; conf->mddev = mddev; conf->chunk_size = mddev->chunk_size; conf->level = mddev->level; - if (conf->level == 6) - conf->max_degraded = 2; - else - conf->max_degraded = 1; conf->algorithm = mddev->layout; conf->max_nr_stripes = NR_STRIPES; conf->expand_progress = mddev->reshape_position; @@ -3166,11 +2296,6 @@ static int run(mddev_t *mddev) mddev->size &= ~(mddev->chunk_size/1024 -1); mddev->resync_max_sectors = mddev->size << 1; - if (conf->level == 6 && conf->raid_disks < 4) { - printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", - mdname(mddev), conf->raid_disks); - goto abort; - } if (!conf->chunk_size || conf->chunk_size % 4) { printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", conf->chunk_size, mdname(mddev)); @@ -3182,14 +2307,14 @@ static int run(mddev_t *mddev) conf->algorithm, mdname(mddev)); goto abort; } - if (mddev->degraded > conf->max_degraded) { + if (mddev->degraded > 1) { printk(KERN_ERR "raid5: not enough operational devices for %s" " (%d/%d failed)\n", mdname(mddev), conf->failed_disks, conf->raid_disks); goto abort; } - if (mddev->degraded > 0 && + if (mddev->degraded == 1 && mddev->recovery_cp != MaxSector) { if (mddev->ok_start_degraded) printk(KERN_WARNING @@ -3254,12 +2379,11 @@ static int run(mddev_t *mddev) } /* read-ahead size must cover two whole stripes, which is - * 2 * (datadisks) * chunksize where 'n' is the number of raid devices + * 2 * (n-1) * chunksize where 'n' is the number of raid devices */ { - int data_disks = conf->previous_raid_disks - conf->max_degraded; - int stripe = data_disks * - (mddev->chunk_size / PAGE_SIZE); + int stripe = (mddev->raid_disks-1) * mddev->chunk_size + / PAGE_SIZE; if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) mddev->queue->backing_dev_info.ra_pages = 2 * stripe; } @@ -3269,14 +2393,12 @@ static int run(mddev_t *mddev) mddev->queue->unplug_fn = raid5_unplug_device; mddev->queue->issue_flush_fn = raid5_issue_flush; - mddev->array_size = mddev->size * (conf->previous_raid_disks - - conf->max_degraded); + mddev->array_size = mddev->size * (conf->previous_raid_disks - 1); return 0; abort: if (conf) { print_raid5_conf(conf); - safe_put_page(conf->spare_page); kfree(conf->disks); kfree(conf->stripe_hashtbl); kfree(conf); @@ -3305,23 +2427,23 @@ static int stop(mddev_t *mddev) } #if RAID5_DEBUG -static void print_sh (struct seq_file *seq, struct stripe_head *sh) +static void print_sh (struct stripe_head *sh) { int i; - seq_printf(seq, "sh %llu, pd_idx %d, state %ld.\n", - (unsigned long long)sh->sector, sh->pd_idx, sh->state); - seq_printf(seq, "sh %llu, count %d.\n", - (unsigned long long)sh->sector, atomic_read(&sh->count)); - seq_printf(seq, "sh %llu, ", (unsigned long long)sh->sector); + printk("sh %llu, pd_idx %d, state %ld.\n", + (unsigned long long)sh->sector, sh->pd_idx, sh->state); + printk("sh %llu, count %d.\n", + (unsigned long long)sh->sector, atomic_read(&sh->count)); + printk("sh %llu, ", (unsigned long long)sh->sector); for (i = 0; i < sh->disks; i++) { - seq_printf(seq, "(cache%d: %p %ld) ", - i, sh->dev[i].page, sh->dev[i].flags); + printk("(cache%d: %p %ld) ", + i, sh->dev[i].page, sh->dev[i].flags); } - seq_printf(seq, "\n"); + printk("\n"); } -static void printall (struct seq_file *seq, raid5_conf_t *conf) +static void printall (raid5_conf_t *conf) { struct stripe_head *sh; struct hlist_node *hn; @@ -3332,7 +2454,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf) hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) { if (sh->raid_conf != conf) continue; - print_sh(seq, sh); + print_sh(sh); } } spin_unlock_irq(&conf->device_lock); @@ -3352,8 +2474,9 @@ static void status (struct seq_file *seq, mddev_t *mddev) test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_"); seq_printf (seq, "]"); #if RAID5_DEBUG - seq_printf (seq, "\n"); - printall(seq, conf); +#define D(x) \ + seq_printf (seq, "<"#x":%d>", atomic_read(&conf->x)) + printall(conf); #endif } @@ -3437,20 +2560,14 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) int disk; struct disk_info *p; - if (mddev->degraded > conf->max_degraded) + if (mddev->degraded > 1) /* no point adding a device */ return 0; /* - * find the disk ... but prefer rdev->saved_raid_disk - * if possible. + * find the disk ... */ - if (rdev->saved_raid_disk >= 0 && - conf->disks[rdev->saved_raid_disk].rdev == NULL) - disk = rdev->saved_raid_disk; - else - disk = 0; - for ( ; disk < conf->raid_disks; disk++) + for (disk=0; disk < conf->raid_disks; disk++) if ((p=conf->disks + disk)->rdev == NULL) { clear_bit(In_sync, &rdev->flags); rdev->raid_disk = disk; @@ -3473,10 +2590,8 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) * any io in the removed space completes, but it hardly seems * worth it. */ - raid5_conf_t *conf = mddev_to_conf(mddev); - sectors &= ~((sector_t)mddev->chunk_size/512 - 1); - mddev->array_size = (sectors * (mddev->raid_disks-conf->max_degraded))>>1; + mddev->array_size = (sectors * (mddev->raid_disks-1))>>1; set_capacity(mddev->gendisk, mddev->array_size << 1); mddev->changed = 1; if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) { @@ -3565,7 +2680,6 @@ static int raid5_start_reshape(mddev_t *mddev) set_bit(In_sync, &rdev->flags); conf->working_disks++; added_devices++; - rdev->recovery_offset = 0; sprintf(nm, "rd%d", rdev->raid_disk); sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); } else @@ -3617,17 +2731,6 @@ static void end_reshape(raid5_conf_t *conf) conf->expand_progress = MaxSector; spin_unlock_irq(&conf->device_lock); conf->mddev->reshape_position = MaxSector; - - /* read-ahead size must cover two whole stripes, which is - * 2 * (datadisks) * chunksize where 'n' is the number of raid devices - */ - { - int data_disks = conf->previous_raid_disks - conf->max_degraded; - int stripe = data_disks * - (conf->mddev->chunk_size / PAGE_SIZE); - if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe) - conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe; - } } } @@ -3659,23 +2762,6 @@ static void raid5_quiesce(mddev_t *mddev, int state) } } -static struct mdk_personality raid6_personality = -{ - .name = "raid6", - .level = 6, - .owner = THIS_MODULE, - .make_request = make_request, - .run = run, - .stop = stop, - .status = status, - .error_handler = error, - .hot_add_disk = raid5_add_disk, - .hot_remove_disk= raid5_remove_disk, - .spare_active = raid5_spare_active, - .sync_request = sync_request, - .resize = raid5_resize, - .quiesce = raid5_quiesce, -}; static struct mdk_personality raid5_personality = { .name = "raid5", @@ -3718,12 +2804,6 @@ static struct mdk_personality raid4_personality = static int __init raid5_init(void) { - int e; - - e = raid6_select_algo(); - if ( e ) - return e; - register_md_personality(&raid6_personality); register_md_personality(&raid5_personality); register_md_personality(&raid4_personality); return 0; @@ -3731,7 +2811,6 @@ static int __init raid5_init(void) static void raid5_exit(void) { - unregister_md_personality(&raid6_personality); unregister_md_personality(&raid5_personality); unregister_md_personality(&raid4_personality); } @@ -3744,10 +2823,3 @@ MODULE_ALIAS("md-raid5"); MODULE_ALIAS("md-raid4"); MODULE_ALIAS("md-level-5"); MODULE_ALIAS("md-level-4"); -MODULE_ALIAS("md-personality-8"); /* RAID6 */ -MODULE_ALIAS("md-raid6"); -MODULE_ALIAS("md-level-6"); - -/* This used to be two separate modules, they were: */ -MODULE_ALIAS("raid5"); -MODULE_ALIAS("raid6"); diff --git a/trunk/drivers/md/raid6algos.c b/trunk/drivers/md/raid6algos.c index 926576156578..51c63c0cf1c9 100644 --- a/trunk/drivers/md/raid6algos.c +++ b/trunk/drivers/md/raid6algos.c @@ -139,14 +139,15 @@ int __init raid6_select_algo(void) } } - if (best) { + if ( best ) printk("raid6: using algorithm %s (%ld MB/s)\n", best->name, (bestperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); - raid6_call = *best; - } else + else printk("raid6: Yikes! No algorithm found!\n"); + raid6_call = *best; + free_pages((unsigned long)syndromes, 1); return best ? 0 : -EINVAL; diff --git a/trunk/drivers/md/raid6main.c b/trunk/drivers/md/raid6main.c new file mode 100644 index 000000000000..bc69355e0100 --- /dev/null +++ b/trunk/drivers/md/raid6main.c @@ -0,0 +1,2427 @@ +/* + * raid6main.c : Multiple Devices driver for Linux + * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman + * Copyright (C) 1999, 2000 Ingo Molnar + * Copyright (C) 2002, 2003 H. Peter Anvin + * + * RAID-6 management functions. This code is derived from raid5.c. + * Last merge from raid5.c bkcvs version 1.79 (kernel 2.6.1). + * + * Thanks to Penguin Computing for making the RAID-6 development possible + * by donating a test server! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * You should have received a copy of the GNU General Public License + * (for example /usr/src/linux/COPYING); if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include "raid6.h" + +#include + +/* + * Stripe cache + */ + +#define NR_STRIPES 256 +#define STRIPE_SIZE PAGE_SIZE +#define STRIPE_SHIFT (PAGE_SHIFT - 9) +#define STRIPE_SECTORS (STRIPE_SIZE>>9) +#define IO_THRESHOLD 1 +#define NR_HASH (PAGE_SIZE / sizeof(struct hlist_head)) +#define HASH_MASK (NR_HASH - 1) + +#define stripe_hash(conf, sect) (&((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])) + +/* bio's attached to a stripe+device for I/O are linked together in bi_sector + * order without overlap. There may be several bio's per stripe+device, and + * a bio could span several devices. + * When walking this list for a particular stripe+device, we must never proceed + * beyond a bio that extends past this device, as the next bio might no longer + * be valid. + * This macro is used to determine the 'next' bio in the list, given the sector + * of the current stripe+device + */ +#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL) +/* + * The following can be used to debug the driver + */ +#define RAID6_DEBUG 0 /* Extremely verbose printk */ +#define RAID6_PARANOIA 1 /* Check spinlocks */ +#define RAID6_DUMPSTATE 0 /* Include stripe cache state in /proc/mdstat */ +#if RAID6_PARANOIA && defined(CONFIG_SMP) +# define CHECK_DEVLOCK() assert_spin_locked(&conf->device_lock) +#else +# define CHECK_DEVLOCK() +#endif + +#define PRINTK(x...) ((void)(RAID6_DEBUG && printk(KERN_DEBUG x))) +#if RAID6_DEBUG +#undef inline +#undef __inline__ +#define inline +#define __inline__ +#endif + +#if !RAID6_USE_EMPTY_ZERO_PAGE +/* In .bss so it's zeroed */ +const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); +#endif + +static inline int raid6_next_disk(int disk, int raid_disks) +{ + disk++; + return (disk < raid_disks) ? disk : 0; +} + +static void print_raid6_conf (raid6_conf_t *conf); + +static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh) +{ + if (atomic_dec_and_test(&sh->count)) { + BUG_ON(!list_empty(&sh->lru)); + BUG_ON(atomic_read(&conf->active_stripes)==0); + if (test_bit(STRIPE_HANDLE, &sh->state)) { + if (test_bit(STRIPE_DELAYED, &sh->state)) + list_add_tail(&sh->lru, &conf->delayed_list); + else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && + conf->seq_write == sh->bm_seq) + list_add_tail(&sh->lru, &conf->bitmap_list); + else { + clear_bit(STRIPE_BIT_DELAY, &sh->state); + list_add_tail(&sh->lru, &conf->handle_list); + } + md_wakeup_thread(conf->mddev->thread); + } else { + if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { + atomic_dec(&conf->preread_active_stripes); + if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) + md_wakeup_thread(conf->mddev->thread); + } + list_add_tail(&sh->lru, &conf->inactive_list); + atomic_dec(&conf->active_stripes); + if (!conf->inactive_blocked || + atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4)) + wake_up(&conf->wait_for_stripe); + } + } +} +static void release_stripe(struct stripe_head *sh) +{ + raid6_conf_t *conf = sh->raid_conf; + unsigned long flags; + + spin_lock_irqsave(&conf->device_lock, flags); + __release_stripe(conf, sh); + spin_unlock_irqrestore(&conf->device_lock, flags); +} + +static inline void remove_hash(struct stripe_head *sh) +{ + PRINTK("remove_hash(), stripe %llu\n", (unsigned long long)sh->sector); + + hlist_del_init(&sh->hash); +} + +static inline void insert_hash(raid6_conf_t *conf, struct stripe_head *sh) +{ + struct hlist_head *hp = stripe_hash(conf, sh->sector); + + PRINTK("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector); + + CHECK_DEVLOCK(); + hlist_add_head(&sh->hash, hp); +} + + +/* find an idle stripe, make sure it is unhashed, and return it. */ +static struct stripe_head *get_free_stripe(raid6_conf_t *conf) +{ + struct stripe_head *sh = NULL; + struct list_head *first; + + CHECK_DEVLOCK(); + if (list_empty(&conf->inactive_list)) + goto out; + first = conf->inactive_list.next; + sh = list_entry(first, struct stripe_head, lru); + list_del_init(first); + remove_hash(sh); + atomic_inc(&conf->active_stripes); +out: + return sh; +} + +static void shrink_buffers(struct stripe_head *sh, int num) +{ + struct page *p; + int i; + + for (i=0; idev[i].page; + if (!p) + continue; + sh->dev[i].page = NULL; + put_page(p); + } +} + +static int grow_buffers(struct stripe_head *sh, int num) +{ + int i; + + for (i=0; idev[i].page = page; + } + return 0; +} + +static void raid6_build_block (struct stripe_head *sh, int i); + +static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx) +{ + raid6_conf_t *conf = sh->raid_conf; + int disks = conf->raid_disks, i; + + BUG_ON(atomic_read(&sh->count) != 0); + BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); + + CHECK_DEVLOCK(); + PRINTK("init_stripe called, stripe %llu\n", + (unsigned long long)sh->sector); + + remove_hash(sh); + + sh->sector = sector; + sh->pd_idx = pd_idx; + sh->state = 0; + + for (i=disks; i--; ) { + struct r5dev *dev = &sh->dev[i]; + + if (dev->toread || dev->towrite || dev->written || + test_bit(R5_LOCKED, &dev->flags)) { + PRINTK("sector=%llx i=%d %p %p %p %d\n", + (unsigned long long)sh->sector, i, dev->toread, + dev->towrite, dev->written, + test_bit(R5_LOCKED, &dev->flags)); + BUG(); + } + dev->flags = 0; + raid6_build_block(sh, i); + } + insert_hash(conf, sh); +} + +static struct stripe_head *__find_stripe(raid6_conf_t *conf, sector_t sector) +{ + struct stripe_head *sh; + struct hlist_node *hn; + + CHECK_DEVLOCK(); + PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector); + hlist_for_each_entry (sh, hn, stripe_hash(conf, sector), hash) + if (sh->sector == sector) + return sh; + PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector); + return NULL; +} + +static void unplug_slaves(mddev_t *mddev); + +static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector, + int pd_idx, int noblock) +{ + struct stripe_head *sh; + + PRINTK("get_stripe, sector %llu\n", (unsigned long long)sector); + + spin_lock_irq(&conf->device_lock); + + do { + wait_event_lock_irq(conf->wait_for_stripe, + conf->quiesce == 0, + conf->device_lock, /* nothing */); + sh = __find_stripe(conf, sector); + if (!sh) { + if (!conf->inactive_blocked) + sh = get_free_stripe(conf); + if (noblock && sh == NULL) + break; + if (!sh) { + conf->inactive_blocked = 1; + wait_event_lock_irq(conf->wait_for_stripe, + !list_empty(&conf->inactive_list) && + (atomic_read(&conf->active_stripes) + < (conf->max_nr_stripes *3/4) + || !conf->inactive_blocked), + conf->device_lock, + unplug_slaves(conf->mddev); + ); + conf->inactive_blocked = 0; + } else + init_stripe(sh, sector, pd_idx); + } else { + if (atomic_read(&sh->count)) { + BUG_ON(!list_empty(&sh->lru)); + } else { + if (!test_bit(STRIPE_HANDLE, &sh->state)) + atomic_inc(&conf->active_stripes); + BUG_ON(list_empty(&sh->lru)); + list_del_init(&sh->lru); + } + } + } while (sh == NULL); + + if (sh) + atomic_inc(&sh->count); + + spin_unlock_irq(&conf->device_lock); + return sh; +} + +static int grow_one_stripe(raid6_conf_t *conf) +{ + struct stripe_head *sh; + sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); + if (!sh) + return 0; + memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev)); + sh->raid_conf = conf; + spin_lock_init(&sh->lock); + + if (grow_buffers(sh, conf->raid_disks)) { + shrink_buffers(sh, conf->raid_disks); + kmem_cache_free(conf->slab_cache, sh); + return 0; + } + /* we just created an active stripe so... */ + atomic_set(&sh->count, 1); + atomic_inc(&conf->active_stripes); + INIT_LIST_HEAD(&sh->lru); + release_stripe(sh); + return 1; +} + +static int grow_stripes(raid6_conf_t *conf, int num) +{ + kmem_cache_t *sc; + int devs = conf->raid_disks; + + sprintf(conf->cache_name[0], "raid6/%s", mdname(conf->mddev)); + + sc = kmem_cache_create(conf->cache_name[0], + sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev), + 0, 0, NULL, NULL); + if (!sc) + return 1; + conf->slab_cache = sc; + while (num--) + if (!grow_one_stripe(conf)) + return 1; + return 0; +} + +static int drop_one_stripe(raid6_conf_t *conf) +{ + struct stripe_head *sh; + spin_lock_irq(&conf->device_lock); + sh = get_free_stripe(conf); + spin_unlock_irq(&conf->device_lock); + if (!sh) + return 0; + BUG_ON(atomic_read(&sh->count)); + shrink_buffers(sh, conf->raid_disks); + kmem_cache_free(conf->slab_cache, sh); + atomic_dec(&conf->active_stripes); + return 1; +} + +static void shrink_stripes(raid6_conf_t *conf) +{ + while (drop_one_stripe(conf)) + ; + + if (conf->slab_cache) + kmem_cache_destroy(conf->slab_cache); + conf->slab_cache = NULL; +} + +static int raid6_end_read_request(struct bio * bi, unsigned int bytes_done, + int error) +{ + struct stripe_head *sh = bi->bi_private; + raid6_conf_t *conf = sh->raid_conf; + int disks = conf->raid_disks, i; + int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); + + if (bi->bi_size) + return 1; + + for (i=0 ; idev[i].req) + break; + + PRINTK("end_read_request %llu/%d, count: %d, uptodate %d.\n", + (unsigned long long)sh->sector, i, atomic_read(&sh->count), + uptodate); + if (i == disks) { + BUG(); + return 0; + } + + if (uptodate) { +#if 0 + struct bio *bio; + unsigned long flags; + spin_lock_irqsave(&conf->device_lock, flags); + /* we can return a buffer if we bypassed the cache or + * if the top buffer is not in highmem. If there are + * multiple buffers, leave the extra work to + * handle_stripe + */ + buffer = sh->bh_read[i]; + if (buffer && + (!PageHighMem(buffer->b_page) + || buffer->b_page == bh->b_page ) + ) { + sh->bh_read[i] = buffer->b_reqnext; + buffer->b_reqnext = NULL; + } else + buffer = NULL; + spin_unlock_irqrestore(&conf->device_lock, flags); + if (sh->bh_page[i]==bh->b_page) + set_buffer_uptodate(bh); + if (buffer) { + if (buffer->b_page != bh->b_page) + memcpy(buffer->b_data, bh->b_data, bh->b_size); + buffer->b_end_io(buffer, 1); + } +#else + set_bit(R5_UPTODATE, &sh->dev[i].flags); +#endif + if (test_bit(R5_ReadError, &sh->dev[i].flags)) { + printk(KERN_INFO "raid6: read error corrected!!\n"); + clear_bit(R5_ReadError, &sh->dev[i].flags); + clear_bit(R5_ReWrite, &sh->dev[i].flags); + } + if (atomic_read(&conf->disks[i].rdev->read_errors)) + atomic_set(&conf->disks[i].rdev->read_errors, 0); + } else { + int retry = 0; + clear_bit(R5_UPTODATE, &sh->dev[i].flags); + atomic_inc(&conf->disks[i].rdev->read_errors); + if (conf->mddev->degraded) + printk(KERN_WARNING "raid6: read error not correctable.\n"); + else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) + /* Oh, no!!! */ + printk(KERN_WARNING "raid6: read error NOT corrected!!\n"); + else if (atomic_read(&conf->disks[i].rdev->read_errors) + > conf->max_nr_stripes) + printk(KERN_WARNING + "raid6: Too many read errors, failing device.\n"); + else + retry = 1; + if (retry) + set_bit(R5_ReadError, &sh->dev[i].flags); + else { + clear_bit(R5_ReadError, &sh->dev[i].flags); + clear_bit(R5_ReWrite, &sh->dev[i].flags); + md_error(conf->mddev, conf->disks[i].rdev); + } + } + rdev_dec_pending(conf->disks[i].rdev, conf->mddev); +#if 0 + /* must restore b_page before unlocking buffer... */ + if (sh->bh_page[i] != bh->b_page) { + bh->b_page = sh->bh_page[i]; + bh->b_data = page_address(bh->b_page); + clear_buffer_uptodate(bh); + } +#endif + clear_bit(R5_LOCKED, &sh->dev[i].flags); + set_bit(STRIPE_HANDLE, &sh->state); + release_stripe(sh); + return 0; +} + +static int raid6_end_write_request (struct bio *bi, unsigned int bytes_done, + int error) +{ + struct stripe_head *sh = bi->bi_private; + raid6_conf_t *conf = sh->raid_conf; + int disks = conf->raid_disks, i; + unsigned long flags; + int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); + + if (bi->bi_size) + return 1; + + for (i=0 ; idev[i].req) + break; + + PRINTK("end_write_request %llu/%d, count %d, uptodate: %d.\n", + (unsigned long long)sh->sector, i, atomic_read(&sh->count), + uptodate); + if (i == disks) { + BUG(); + return 0; + } + + spin_lock_irqsave(&conf->device_lock, flags); + if (!uptodate) + md_error(conf->mddev, conf->disks[i].rdev); + + rdev_dec_pending(conf->disks[i].rdev, conf->mddev); + + clear_bit(R5_LOCKED, &sh->dev[i].flags); + set_bit(STRIPE_HANDLE, &sh->state); + __release_stripe(conf, sh); + spin_unlock_irqrestore(&conf->device_lock, flags); + return 0; +} + + +static sector_t compute_blocknr(struct stripe_head *sh, int i); + +static void raid6_build_block (struct stripe_head *sh, int i) +{ + struct r5dev *dev = &sh->dev[i]; + int pd_idx = sh->pd_idx; + int qd_idx = raid6_next_disk(pd_idx, sh->raid_conf->raid_disks); + + bio_init(&dev->req); + dev->req.bi_io_vec = &dev->vec; + dev->req.bi_vcnt++; + dev->req.bi_max_vecs++; + dev->vec.bv_page = dev->page; + dev->vec.bv_len = STRIPE_SIZE; + dev->vec.bv_offset = 0; + + dev->req.bi_sector = sh->sector; + dev->req.bi_private = sh; + + dev->flags = 0; + if (i != pd_idx && i != qd_idx) + dev->sector = compute_blocknr(sh, i); +} + +static void error(mddev_t *mddev, mdk_rdev_t *rdev) +{ + char b[BDEVNAME_SIZE]; + raid6_conf_t *conf = (raid6_conf_t *) mddev->private; + PRINTK("raid6: error called\n"); + + if (!test_bit(Faulty, &rdev->flags)) { + mddev->sb_dirty = 1; + if (test_bit(In_sync, &rdev->flags)) { + conf->working_disks--; + mddev->degraded++; + conf->failed_disks++; + clear_bit(In_sync, &rdev->flags); + /* + * if recovery was running, make sure it aborts. + */ + set_bit(MD_RECOVERY_ERR, &mddev->recovery); + } + set_bit(Faulty, &rdev->flags); + printk (KERN_ALERT + "raid6: Disk failure on %s, disabling device." + " Operation continuing on %d devices\n", + bdevname(rdev->bdev,b), conf->working_disks); + } +} + +/* + * Input: a 'big' sector number, + * Output: index of the data and parity disk, and the sector # in them. + */ +static sector_t raid6_compute_sector(sector_t r_sector, unsigned int raid_disks, + unsigned int data_disks, unsigned int * dd_idx, + unsigned int * pd_idx, raid6_conf_t *conf) +{ + long stripe; + unsigned long chunk_number; + unsigned int chunk_offset; + sector_t new_sector; + int sectors_per_chunk = conf->chunk_size >> 9; + + /* First compute the information on this sector */ + + /* + * Compute the chunk number and the sector offset inside the chunk + */ + chunk_offset = sector_div(r_sector, sectors_per_chunk); + chunk_number = r_sector; + if ( r_sector != chunk_number ) { + printk(KERN_CRIT "raid6: ERROR: r_sector = %llu, chunk_number = %lu\n", + (unsigned long long)r_sector, (unsigned long)chunk_number); + BUG(); + } + + /* + * 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; + + /* + * Select the parity disk based on the user selected algorithm. + */ + + /**** FIX THIS ****/ + switch (conf->algorithm) { + case ALGORITHM_LEFT_ASYMMETRIC: + *pd_idx = raid_disks - 1 - (stripe % raid_disks); + if (*pd_idx == raid_disks-1) + (*dd_idx)++; /* Q D D D P */ + else if (*dd_idx >= *pd_idx) + (*dd_idx) += 2; /* D D P Q D */ + break; + case ALGORITHM_RIGHT_ASYMMETRIC: + *pd_idx = stripe % raid_disks; + if (*pd_idx == raid_disks-1) + (*dd_idx)++; /* Q D D D P */ + else if (*dd_idx >= *pd_idx) + (*dd_idx) += 2; /* D D P Q D */ + break; + case ALGORITHM_LEFT_SYMMETRIC: + *pd_idx = raid_disks - 1 - (stripe % raid_disks); + *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; + break; + case ALGORITHM_RIGHT_SYMMETRIC: + *pd_idx = stripe % raid_disks; + *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; + break; + default: + printk (KERN_CRIT "raid6: unsupported algorithm %d\n", + conf->algorithm); + } + + PRINTK("raid6: chunk_number = %lu, pd_idx = %u, dd_idx = %u\n", + chunk_number, *pd_idx, *dd_idx); + + /* + * Finally, compute the new sector number + */ + new_sector = (sector_t) stripe * sectors_per_chunk + chunk_offset; + return new_sector; +} + + +static sector_t compute_blocknr(struct stripe_head *sh, int i) +{ + raid6_conf_t *conf = sh->raid_conf; + int raid_disks = conf->raid_disks, data_disks = raid_disks - 2; + sector_t new_sector = sh->sector, check; + int sectors_per_chunk = conf->chunk_size >> 9; + sector_t stripe; + int chunk_offset; + int chunk_number, dummy1, dummy2, dd_idx = i; + sector_t r_sector; + int i0 = i; + + chunk_offset = sector_div(new_sector, sectors_per_chunk); + stripe = new_sector; + if ( new_sector != stripe ) { + printk(KERN_CRIT "raid6: ERROR: new_sector = %llu, stripe = %lu\n", + (unsigned long long)new_sector, (unsigned long)stripe); + BUG(); + } + + switch (conf->algorithm) { + case ALGORITHM_LEFT_ASYMMETRIC: + case ALGORITHM_RIGHT_ASYMMETRIC: + if (sh->pd_idx == raid_disks-1) + i--; /* Q D D D P */ + else if (i > sh->pd_idx) + i -= 2; /* D D P Q D */ + break; + case ALGORITHM_LEFT_SYMMETRIC: + case ALGORITHM_RIGHT_SYMMETRIC: + if (sh->pd_idx == raid_disks-1) + i--; /* Q D D D P */ + else { + /* D D P Q D */ + if (i < sh->pd_idx) + i += raid_disks; + i -= (sh->pd_idx + 2); + } + break; + default: + printk (KERN_CRIT "raid6: unsupported algorithm %d\n", + conf->algorithm); + } + + PRINTK("raid6: compute_blocknr: pd_idx = %u, i0 = %u, i = %u\n", sh->pd_idx, i0, i); + + chunk_number = stripe * data_disks + i; + r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; + + check = raid6_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); + if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { + printk(KERN_CRIT "raid6: compute_blocknr: map not correct\n"); + return 0; + } + return r_sector; +} + + + +/* + * Copy data between a page in the stripe cache, and one or more bion + * The page could align with the middle of the bio, or there could be + * several bion, each with several bio_vecs, which cover part of the page + * Multiple bion are linked together on bi_next. There may be extras + * at the end of this list. We ignore them. + */ +static void copy_data(int frombio, struct bio *bio, + struct page *page, + sector_t sector) +{ + char *pa = page_address(page); + struct bio_vec *bvl; + int i; + int page_offset; + + if (bio->bi_sector >= sector) + page_offset = (signed)(bio->bi_sector - sector) * 512; + else + page_offset = (signed)(sector - bio->bi_sector) * -512; + bio_for_each_segment(bvl, bio, i) { + int len = bio_iovec_idx(bio,i)->bv_len; + int clen; + int b_offset = 0; + + if (page_offset < 0) { + b_offset = -page_offset; + page_offset += b_offset; + len -= b_offset; + } + + if (len > 0 && page_offset + len > STRIPE_SIZE) + clen = STRIPE_SIZE - page_offset; + else clen = len; + + if (clen > 0) { + char *ba = __bio_kmap_atomic(bio, i, KM_USER0); + if (frombio) + memcpy(pa+page_offset, ba+b_offset, clen); + else + memcpy(ba+b_offset, pa+page_offset, clen); + __bio_kunmap_atomic(ba, KM_USER0); + } + if (clen < len) /* hit end of page */ + break; + page_offset += len; + } +} + +#define check_xor() do { \ + if (count == MAX_XOR_BLOCKS) { \ + xor_block(count, STRIPE_SIZE, ptr); \ + count = 1; \ + } \ + } while(0) + +/* Compute P and Q syndromes */ +static void compute_parity(struct stripe_head *sh, int method) +{ + raid6_conf_t *conf = sh->raid_conf; + int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = conf->raid_disks, count; + struct bio *chosen; + /**** FIX THIS: This could be very bad if disks is close to 256 ****/ + void *ptrs[disks]; + + qd_idx = raid6_next_disk(pd_idx, disks); + d0_idx = raid6_next_disk(qd_idx, disks); + + PRINTK("compute_parity, stripe %llu, method %d\n", + (unsigned long long)sh->sector, method); + + switch(method) { + case READ_MODIFY_WRITE: + BUG(); /* READ_MODIFY_WRITE N/A for RAID-6 */ + case RECONSTRUCT_WRITE: + for (i= disks; i-- ;) + if ( i != pd_idx && i != qd_idx && sh->dev[i].towrite ) { + chosen = sh->dev[i].towrite; + sh->dev[i].towrite = NULL; + + if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) + wake_up(&conf->wait_for_overlap); + + BUG_ON(sh->dev[i].written); + sh->dev[i].written = chosen; + } + break; + case CHECK_PARITY: + BUG(); /* Not implemented yet */ + } + + for (i = disks; i--;) + if (sh->dev[i].written) { + sector_t sector = sh->dev[i].sector; + struct bio *wbi = sh->dev[i].written; + while (wbi && wbi->bi_sector < sector + STRIPE_SECTORS) { + copy_data(1, wbi, sh->dev[i].page, sector); + wbi = r5_next_bio(wbi, sector); + } + + set_bit(R5_LOCKED, &sh->dev[i].flags); + set_bit(R5_UPTODATE, &sh->dev[i].flags); + } + +// switch(method) { +// case RECONSTRUCT_WRITE: +// case CHECK_PARITY: +// case UPDATE_PARITY: + /* Note that unlike RAID-5, the ordering of the disks matters greatly. */ + /* FIX: Is this ordering of drives even remotely optimal? */ + count = 0; + i = d0_idx; + do { + ptrs[count++] = page_address(sh->dev[i].page); + if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags)) + printk("block %d/%d not uptodate on parity calc\n", i,count); + i = raid6_next_disk(i, disks); + } while ( i != d0_idx ); +// break; +// } + + raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs); + + switch(method) { + case RECONSTRUCT_WRITE: + set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); + set_bit(R5_UPTODATE, &sh->dev[qd_idx].flags); + set_bit(R5_LOCKED, &sh->dev[pd_idx].flags); + set_bit(R5_LOCKED, &sh->dev[qd_idx].flags); + break; + case UPDATE_PARITY: + set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); + set_bit(R5_UPTODATE, &sh->dev[qd_idx].flags); + break; + } +} + +/* Compute one missing block */ +static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero) +{ + raid6_conf_t *conf = sh->raid_conf; + int i, count, disks = conf->raid_disks; + void *ptr[MAX_XOR_BLOCKS], *p; + int pd_idx = sh->pd_idx; + int qd_idx = raid6_next_disk(pd_idx, disks); + + PRINTK("compute_block_1, stripe %llu, idx %d\n", + (unsigned long long)sh->sector, dd_idx); + + if ( dd_idx == qd_idx ) { + /* We're actually computing the Q drive */ + compute_parity(sh, UPDATE_PARITY); + } else { + ptr[0] = page_address(sh->dev[dd_idx].page); + if (!nozero) memset(ptr[0], 0, STRIPE_SIZE); + count = 1; + for (i = disks ; i--; ) { + if (i == dd_idx || i == qd_idx) + continue; + p = page_address(sh->dev[i].page); + if (test_bit(R5_UPTODATE, &sh->dev[i].flags)) + ptr[count++] = p; + else + printk("compute_block() %d, stripe %llu, %d" + " not present\n", dd_idx, + (unsigned long long)sh->sector, i); + + check_xor(); + } + if (count != 1) + xor_block(count, STRIPE_SIZE, ptr); + if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); + else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); + } +} + +/* Compute two missing blocks */ +static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2) +{ + raid6_conf_t *conf = sh->raid_conf; + int i, count, disks = conf->raid_disks; + int pd_idx = sh->pd_idx; + int qd_idx = raid6_next_disk(pd_idx, disks); + int d0_idx = raid6_next_disk(qd_idx, disks); + int faila, failb; + + /* faila and failb are disk numbers relative to d0_idx */ + /* pd_idx become disks-2 and qd_idx become disks-1 */ + faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx; + failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx; + + BUG_ON(faila == failb); + if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; } + + PRINTK("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n", + (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb); + + if ( failb == disks-1 ) { + /* Q disk is one of the missing disks */ + if ( faila == disks-2 ) { + /* Missing P+Q, just recompute */ + compute_parity(sh, UPDATE_PARITY); + return; + } else { + /* We're missing D+Q; recompute D from P */ + compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0); + compute_parity(sh, UPDATE_PARITY); /* Is this necessary? */ + return; + } + } + + /* We're missing D+P or D+D; build pointer table */ + { + /**** FIX THIS: This could be very bad if disks is close to 256 ****/ + void *ptrs[disks]; + + count = 0; + i = d0_idx; + do { + ptrs[count++] = page_address(sh->dev[i].page); + i = raid6_next_disk(i, disks); + if (i != dd_idx1 && i != dd_idx2 && + !test_bit(R5_UPTODATE, &sh->dev[i].flags)) + printk("compute_2 with missing block %d/%d\n", count, i); + } while ( i != d0_idx ); + + if ( failb == disks-2 ) { + /* We're missing D+P. */ + raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs); + } else { + /* We're missing D+D. */ + raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs); + } + + /* Both the above update both missing blocks */ + set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags); + set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags); + } +} + + +/* + * Each stripe/dev can have one or more bion attached. + * toread/towrite point to the first in a chain. + * The bi_next chain must be in order. + */ +static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite) +{ + struct bio **bip; + raid6_conf_t *conf = sh->raid_conf; + int firstwrite=0; + + PRINTK("adding bh b#%llu to stripe s#%llu\n", + (unsigned long long)bi->bi_sector, + (unsigned long long)sh->sector); + + + spin_lock(&sh->lock); + spin_lock_irq(&conf->device_lock); + if (forwrite) { + bip = &sh->dev[dd_idx].towrite; + if (*bip == NULL && sh->dev[dd_idx].written == NULL) + firstwrite = 1; + } else + bip = &sh->dev[dd_idx].toread; + while (*bip && (*bip)->bi_sector < bi->bi_sector) { + if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector) + goto overlap; + bip = &(*bip)->bi_next; + } + if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9)) + goto overlap; + + BUG_ON(*bip && bi->bi_next && (*bip) != bi->bi_next); + if (*bip) + bi->bi_next = *bip; + *bip = bi; + bi->bi_phys_segments ++; + spin_unlock_irq(&conf->device_lock); + spin_unlock(&sh->lock); + + PRINTK("added bi b#%llu to stripe s#%llu, disk %d.\n", + (unsigned long long)bi->bi_sector, + (unsigned long long)sh->sector, dd_idx); + + if (conf->mddev->bitmap && firstwrite) { + sh->bm_seq = conf->seq_write; + bitmap_startwrite(conf->mddev->bitmap, sh->sector, + STRIPE_SECTORS, 0); + set_bit(STRIPE_BIT_DELAY, &sh->state); + } + + if (forwrite) { + /* check if page is covered */ + sector_t sector = sh->dev[dd_idx].sector; + for (bi=sh->dev[dd_idx].towrite; + sector < sh->dev[dd_idx].sector + STRIPE_SECTORS && + bi && bi->bi_sector <= sector; + bi = r5_next_bio(bi, sh->dev[dd_idx].sector)) { + if (bi->bi_sector + (bi->bi_size>>9) >= sector) + sector = bi->bi_sector + (bi->bi_size>>9); + } + if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS) + set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags); + } + return 1; + + overlap: + set_bit(R5_Overlap, &sh->dev[dd_idx].flags); + spin_unlock_irq(&conf->device_lock); + spin_unlock(&sh->lock); + return 0; +} + + +static int page_is_zero(struct page *p) +{ + char *a = page_address(p); + return ((*(u32*)a) == 0 && + memcmp(a, a+4, STRIPE_SIZE-4)==0); +} +/* + * handle_stripe - do things to a stripe. + * + * We lock the stripe and then examine the state of various bits + * to see what needs to be done. + * Possible results: + * return some read request which now have data + * return some write requests which are safely on disc + * schedule a read on some buffers + * schedule a write of some buffers + * return confirmation of parity correctness + * + * Parity calculations are done inside the stripe lock + * buffers are taken off read_list or write_list, and bh_cache buffers + * get BH_Lock set before the stripe lock is released. + * + */ + +static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) +{ + raid6_conf_t *conf = sh->raid_conf; + int disks = conf->raid_disks; + struct bio *return_bi= NULL; + struct bio *bi; + int i; + int syncing; + int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0; + int non_overwrite = 0; + int failed_num[2] = {0, 0}; + struct r5dev *dev, *pdev, *qdev; + int pd_idx = sh->pd_idx; + int qd_idx = raid6_next_disk(pd_idx, disks); + int p_failed, q_failed; + + PRINTK("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d, qd_idx=%d\n", + (unsigned long long)sh->sector, sh->state, atomic_read(&sh->count), + pd_idx, qd_idx); + + spin_lock(&sh->lock); + clear_bit(STRIPE_HANDLE, &sh->state); + clear_bit(STRIPE_DELAYED, &sh->state); + + syncing = test_bit(STRIPE_SYNCING, &sh->state); + /* Now to look around and see what can be done */ + + rcu_read_lock(); + for (i=disks; i--; ) { + mdk_rdev_t *rdev; + dev = &sh->dev[i]; + clear_bit(R5_Insync, &dev->flags); + + PRINTK("check %d: state 0x%lx read %p write %p written %p\n", + i, dev->flags, dev->toread, dev->towrite, dev->written); + /* maybe we can reply to a read */ + if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread) { + struct bio *rbi, *rbi2; + PRINTK("Return read for disc %d\n", i); + spin_lock_irq(&conf->device_lock); + rbi = dev->toread; + dev->toread = NULL; + if (test_and_clear_bit(R5_Overlap, &dev->flags)) + wake_up(&conf->wait_for_overlap); + spin_unlock_irq(&conf->device_lock); + while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) { + copy_data(0, rbi, dev->page, dev->sector); + rbi2 = r5_next_bio(rbi, dev->sector); + spin_lock_irq(&conf->device_lock); + if (--rbi->bi_phys_segments == 0) { + rbi->bi_next = return_bi; + return_bi = rbi; + } + spin_unlock_irq(&conf->device_lock); + rbi = rbi2; + } + } + + /* now count some things */ + if (test_bit(R5_LOCKED, &dev->flags)) locked++; + if (test_bit(R5_UPTODATE, &dev->flags)) uptodate++; + + + if (dev->toread) to_read++; + if (dev->towrite) { + to_write++; + if (!test_bit(R5_OVERWRITE, &dev->flags)) + non_overwrite++; + } + if (dev->written) written++; + rdev = rcu_dereference(conf->disks[i].rdev); + if (!rdev || !test_bit(In_sync, &rdev->flags)) { + /* The ReadError flag will just be confusing now */ + clear_bit(R5_ReadError, &dev->flags); + clear_bit(R5_ReWrite, &dev->flags); + } + if (!rdev || !test_bit(In_sync, &rdev->flags) + || test_bit(R5_ReadError, &dev->flags)) { + if ( failed < 2 ) + failed_num[failed] = i; + failed++; + } else + set_bit(R5_Insync, &dev->flags); + } + rcu_read_unlock(); + PRINTK("locked=%d uptodate=%d to_read=%d" + " to_write=%d failed=%d failed_num=%d,%d\n", + locked, uptodate, to_read, to_write, failed, + failed_num[0], failed_num[1]); + /* check if the array has lost >2 devices and, if so, some requests might + * need to be failed + */ + if (failed > 2 && to_read+to_write+written) { + for (i=disks; i--; ) { + int bitmap_end = 0; + + if (test_bit(R5_ReadError, &sh->dev[i].flags)) { + mdk_rdev_t *rdev; + rcu_read_lock(); + rdev = rcu_dereference(conf->disks[i].rdev); + if (rdev && test_bit(In_sync, &rdev->flags)) + /* multiple read failures in one stripe */ + md_error(conf->mddev, rdev); + rcu_read_unlock(); + } + + spin_lock_irq(&conf->device_lock); + /* fail all writes first */ + bi = sh->dev[i].towrite; + sh->dev[i].towrite = NULL; + if (bi) { to_write--; bitmap_end = 1; } + + if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) + wake_up(&conf->wait_for_overlap); + + while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ + struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); + clear_bit(BIO_UPTODATE, &bi->bi_flags); + if (--bi->bi_phys_segments == 0) { + md_write_end(conf->mddev); + bi->bi_next = return_bi; + return_bi = bi; + } + bi = nextbi; + } + /* and fail all 'written' */ + bi = sh->dev[i].written; + sh->dev[i].written = NULL; + if (bi) bitmap_end = 1; + while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) { + struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector); + clear_bit(BIO_UPTODATE, &bi->bi_flags); + if (--bi->bi_phys_segments == 0) { + md_write_end(conf->mddev); + bi->bi_next = return_bi; + return_bi = bi; + } + bi = bi2; + } + + /* fail any reads if this device is non-operational */ + if (!test_bit(R5_Insync, &sh->dev[i].flags) || + test_bit(R5_ReadError, &sh->dev[i].flags)) { + bi = sh->dev[i].toread; + sh->dev[i].toread = NULL; + if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) + wake_up(&conf->wait_for_overlap); + if (bi) to_read--; + while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ + struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); + clear_bit(BIO_UPTODATE, &bi->bi_flags); + if (--bi->bi_phys_segments == 0) { + bi->bi_next = return_bi; + return_bi = bi; + } + bi = nextbi; + } + } + spin_unlock_irq(&conf->device_lock); + if (bitmap_end) + bitmap_endwrite(conf->mddev->bitmap, sh->sector, + STRIPE_SECTORS, 0, 0); + } + } + if (failed > 2 && syncing) { + md_done_sync(conf->mddev, STRIPE_SECTORS,0); + clear_bit(STRIPE_SYNCING, &sh->state); + syncing = 0; + } + + /* + * might be able to return some write requests if the parity blocks + * are safe, or on a failed drive + */ + pdev = &sh->dev[pd_idx]; + p_failed = (failed >= 1 && failed_num[0] == pd_idx) + || (failed >= 2 && failed_num[1] == pd_idx); + qdev = &sh->dev[qd_idx]; + q_failed = (failed >= 1 && failed_num[0] == qd_idx) + || (failed >= 2 && failed_num[1] == qd_idx); + + if ( written && + ( p_failed || ((test_bit(R5_Insync, &pdev->flags) + && !test_bit(R5_LOCKED, &pdev->flags) + && test_bit(R5_UPTODATE, &pdev->flags))) ) && + ( q_failed || ((test_bit(R5_Insync, &qdev->flags) + && !test_bit(R5_LOCKED, &qdev->flags) + && test_bit(R5_UPTODATE, &qdev->flags))) ) ) { + /* any written block on an uptodate or failed drive can be + * returned. Note that if we 'wrote' to a failed drive, + * it will be UPTODATE, but never LOCKED, so we don't need + * to test 'failed' directly. + */ + for (i=disks; i--; ) + if (sh->dev[i].written) { + dev = &sh->dev[i]; + if (!test_bit(R5_LOCKED, &dev->flags) && + test_bit(R5_UPTODATE, &dev->flags) ) { + /* We can return any write requests */ + int bitmap_end = 0; + struct bio *wbi, *wbi2; + PRINTK("Return write for stripe %llu disc %d\n", + (unsigned long long)sh->sector, i); + spin_lock_irq(&conf->device_lock); + wbi = dev->written; + dev->written = NULL; + while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) { + wbi2 = r5_next_bio(wbi, dev->sector); + if (--wbi->bi_phys_segments == 0) { + md_write_end(conf->mddev); + wbi->bi_next = return_bi; + return_bi = wbi; + } + wbi = wbi2; + } + if (dev->towrite == NULL) + bitmap_end = 1; + spin_unlock_irq(&conf->device_lock); + if (bitmap_end) + bitmap_endwrite(conf->mddev->bitmap, sh->sector, + STRIPE_SECTORS, + !test_bit(STRIPE_DEGRADED, &sh->state), 0); + } + } + } + + /* Now we might consider reading some blocks, either to check/generate + * parity, or to satisfy requests + * or to load a block that is being partially written. + */ + if (to_read || non_overwrite || (to_write && failed) || (syncing && (uptodate < disks))) { + for (i=disks; i--;) { + dev = &sh->dev[i]; + if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && + (dev->toread || + (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || + syncing || + (failed >= 1 && (sh->dev[failed_num[0]].toread || to_write)) || + (failed >= 2 && (sh->dev[failed_num[1]].toread || to_write)) + ) + ) { + /* we would like to get this block, possibly + * by computing it, but we might not be able to + */ + if (uptodate == disks-1) { + PRINTK("Computing stripe %llu block %d\n", + (unsigned long long)sh->sector, i); + compute_block_1(sh, i, 0); + uptodate++; + } else if ( uptodate == disks-2 && failed >= 2 ) { + /* Computing 2-failure is *very* expensive; only do it if failed >= 2 */ + int other; + for (other=disks; other--;) { + if ( other == i ) + continue; + if ( !test_bit(R5_UPTODATE, &sh->dev[other].flags) ) + break; + } + BUG_ON(other < 0); + PRINTK("Computing stripe %llu blocks %d,%d\n", + (unsigned long long)sh->sector, i, other); + compute_block_2(sh, i, other); + uptodate += 2; + } else if (test_bit(R5_Insync, &dev->flags)) { + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantread, &dev->flags); +#if 0 + /* if I am just reading this block and we don't have + a failed drive, or any pending writes then sidestep the cache */ + if (sh->bh_read[i] && !sh->bh_read[i]->b_reqnext && + ! syncing && !failed && !to_write) { + sh->bh_cache[i]->b_page = sh->bh_read[i]->b_page; + sh->bh_cache[i]->b_data = sh->bh_read[i]->b_data; + } +#endif + locked++; + PRINTK("Reading block %d (sync=%d)\n", + i, syncing); + } + } + } + set_bit(STRIPE_HANDLE, &sh->state); + } + + /* now to consider writing and what else, if anything should be read */ + if (to_write) { + int rcw=0, must_compute=0; + for (i=disks ; i--;) { + dev = &sh->dev[i]; + /* Would I have to read this buffer for reconstruct_write */ + if (!test_bit(R5_OVERWRITE, &dev->flags) + && i != pd_idx && i != qd_idx + && (!test_bit(R5_LOCKED, &dev->flags) +#if 0 + || sh->bh_page[i] != bh->b_page +#endif + ) && + !test_bit(R5_UPTODATE, &dev->flags)) { + if (test_bit(R5_Insync, &dev->flags)) rcw++; + else { + PRINTK("raid6: must_compute: disk %d flags=%#lx\n", i, dev->flags); + must_compute++; + } + } + } + PRINTK("for sector %llu, rcw=%d, must_compute=%d\n", + (unsigned long long)sh->sector, rcw, must_compute); + set_bit(STRIPE_HANDLE, &sh->state); + + if (rcw > 0) + /* want reconstruct write, but need to get some data */ + for (i=disks; i--;) { + dev = &sh->dev[i]; + if (!test_bit(R5_OVERWRITE, &dev->flags) + && !(failed == 0 && (i == pd_idx || i == qd_idx)) + && !test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && + test_bit(R5_Insync, &dev->flags)) { + if (test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + { + PRINTK("Read_old stripe %llu block %d for Reconstruct\n", + (unsigned long long)sh->sector, i); + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantread, &dev->flags); + locked++; + } else { + PRINTK("Request delayed stripe %llu block %d for Reconstruct\n", + (unsigned long long)sh->sector, i); + set_bit(STRIPE_DELAYED, &sh->state); + set_bit(STRIPE_HANDLE, &sh->state); + } + } + } + /* now if nothing is locked, and if we have enough data, we can start a write request */ + if (locked == 0 && rcw == 0 && + !test_bit(STRIPE_BIT_DELAY, &sh->state)) { + if ( must_compute > 0 ) { + /* We have failed blocks and need to compute them */ + switch ( failed ) { + case 0: BUG(); + case 1: compute_block_1(sh, failed_num[0], 0); break; + case 2: compute_block_2(sh, failed_num[0], failed_num[1]); break; + default: BUG(); /* This request should have been failed? */ + } + } + + PRINTK("Computing parity for stripe %llu\n", (unsigned long long)sh->sector); + compute_parity(sh, RECONSTRUCT_WRITE); + /* now every locked buffer is ready to be written */ + for (i=disks; i--;) + if (test_bit(R5_LOCKED, &sh->dev[i].flags)) { + PRINTK("Writing stripe %llu block %d\n", + (unsigned long long)sh->sector, i); + locked++; + set_bit(R5_Wantwrite, &sh->dev[i].flags); + } + /* after a RECONSTRUCT_WRITE, the stripe MUST be in-sync */ + set_bit(STRIPE_INSYNC, &sh->state); + + if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { + atomic_dec(&conf->preread_active_stripes); + if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) + md_wakeup_thread(conf->mddev->thread); + } + } + } + + /* maybe we need to check and possibly fix the parity for this stripe + * Any reads will already have been scheduled, so we just see if enough data + * is available + */ + if (syncing && locked == 0 && !test_bit(STRIPE_INSYNC, &sh->state)) { + int update_p = 0, update_q = 0; + struct r5dev *dev; + + set_bit(STRIPE_HANDLE, &sh->state); + + BUG_ON(failed>2); + BUG_ON(uptodate < disks); + /* Want to check and possibly repair P and Q. + * However there could be one 'failed' device, in which + * case we can only check one of them, possibly using the + * other to generate missing data + */ + + /* If !tmp_page, we cannot do the calculations, + * but as we have set STRIPE_HANDLE, we will soon be called + * by stripe_handle with a tmp_page - just wait until then. + */ + if (tmp_page) { + if (failed == q_failed) { + /* The only possible failed device holds 'Q', so it makes + * sense to check P (If anything else were failed, we would + * have used P to recreate it). + */ + compute_block_1(sh, pd_idx, 1); + if (!page_is_zero(sh->dev[pd_idx].page)) { + compute_block_1(sh,pd_idx,0); + update_p = 1; + } + } + if (!q_failed && failed < 2) { + /* q is not failed, and we didn't use it to generate + * anything, so it makes sense to check it + */ + memcpy(page_address(tmp_page), + page_address(sh->dev[qd_idx].page), + STRIPE_SIZE); + compute_parity(sh, UPDATE_PARITY); + if (memcmp(page_address(tmp_page), + page_address(sh->dev[qd_idx].page), + STRIPE_SIZE)!= 0) { + clear_bit(STRIPE_INSYNC, &sh->state); + update_q = 1; + } + } + if (update_p || update_q) { + conf->mddev->resync_mismatches += STRIPE_SECTORS; + if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) + /* don't try to repair!! */ + update_p = update_q = 0; + } + + /* now write out any block on a failed drive, + * or P or Q if they need it + */ + + if (failed == 2) { + dev = &sh->dev[failed_num[1]]; + locked++; + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantwrite, &dev->flags); + } + if (failed >= 1) { + dev = &sh->dev[failed_num[0]]; + locked++; + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantwrite, &dev->flags); + } + + if (update_p) { + dev = &sh->dev[pd_idx]; + locked ++; + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantwrite, &dev->flags); + } + if (update_q) { + dev = &sh->dev[qd_idx]; + locked++; + set_bit(R5_LOCKED, &dev->flags); + set_bit(R5_Wantwrite, &dev->flags); + } + clear_bit(STRIPE_DEGRADED, &sh->state); + + set_bit(STRIPE_INSYNC, &sh->state); + } + } + + if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { + md_done_sync(conf->mddev, STRIPE_SECTORS,1); + clear_bit(STRIPE_SYNCING, &sh->state); + } + + /* If the failed drives are just a ReadError, then we might need + * to progress the repair/check process + */ + if (failed <= 2 && ! conf->mddev->ro) + for (i=0; idev[failed_num[i]]; + if (test_bit(R5_ReadError, &dev->flags) + && !test_bit(R5_LOCKED, &dev->flags) + && test_bit(R5_UPTODATE, &dev->flags) + ) { + if (!test_bit(R5_ReWrite, &dev->flags)) { + set_bit(R5_Wantwrite, &dev->flags); + set_bit(R5_ReWrite, &dev->flags); + set_bit(R5_LOCKED, &dev->flags); + } else { + /* let's read it back */ + set_bit(R5_Wantread, &dev->flags); + set_bit(R5_LOCKED, &dev->flags); + } + } + } + spin_unlock(&sh->lock); + + while ((bi=return_bi)) { + int bytes = bi->bi_size; + + return_bi = bi->bi_next; + bi->bi_next = NULL; + bi->bi_size = 0; + bi->bi_end_io(bi, bytes, 0); + } + for (i=disks; i-- ;) { + int rw; + struct bio *bi; + mdk_rdev_t *rdev; + if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags)) + rw = 1; + else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags)) + rw = 0; + else + continue; + + bi = &sh->dev[i].req; + + bi->bi_rw = rw; + if (rw) + bi->bi_end_io = raid6_end_write_request; + else + bi->bi_end_io = raid6_end_read_request; + + rcu_read_lock(); + rdev = rcu_dereference(conf->disks[i].rdev); + if (rdev && test_bit(Faulty, &rdev->flags)) + rdev = NULL; + if (rdev) + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + + if (rdev) { + if (syncing) + md_sync_acct(rdev->bdev, STRIPE_SECTORS); + + bi->bi_bdev = rdev->bdev; + PRINTK("for %llu schedule op %ld on disc %d\n", + (unsigned long long)sh->sector, bi->bi_rw, i); + atomic_inc(&sh->count); + bi->bi_sector = sh->sector + rdev->data_offset; + bi->bi_flags = 1 << BIO_UPTODATE; + bi->bi_vcnt = 1; + bi->bi_max_vecs = 1; + bi->bi_idx = 0; + bi->bi_io_vec = &sh->dev[i].vec; + bi->bi_io_vec[0].bv_len = STRIPE_SIZE; + bi->bi_io_vec[0].bv_offset = 0; + bi->bi_size = STRIPE_SIZE; + bi->bi_next = NULL; + if (rw == WRITE && + test_bit(R5_ReWrite, &sh->dev[i].flags)) + atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); + generic_make_request(bi); + } else { + if (rw == 1) + set_bit(STRIPE_DEGRADED, &sh->state); + PRINTK("skip op %ld on disc %d for sector %llu\n", + bi->bi_rw, i, (unsigned long long)sh->sector); + clear_bit(R5_LOCKED, &sh->dev[i].flags); + set_bit(STRIPE_HANDLE, &sh->state); + } + } +} + +static void raid6_activate_delayed(raid6_conf_t *conf) +{ + if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) { + while (!list_empty(&conf->delayed_list)) { + struct list_head *l = conf->delayed_list.next; + struct stripe_head *sh; + sh = list_entry(l, struct stripe_head, lru); + list_del_init(l); + clear_bit(STRIPE_DELAYED, &sh->state); + if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + atomic_inc(&conf->preread_active_stripes); + list_add_tail(&sh->lru, &conf->handle_list); + } + } +} + +static void activate_bit_delay(raid6_conf_t *conf) +{ + /* device_lock is held */ + struct list_head head; + list_add(&head, &conf->bitmap_list); + list_del_init(&conf->bitmap_list); + while (!list_empty(&head)) { + struct stripe_head *sh = list_entry(head.next, struct stripe_head, lru); + list_del_init(&sh->lru); + atomic_inc(&sh->count); + __release_stripe(conf, sh); + } +} + +static void unplug_slaves(mddev_t *mddev) +{ + raid6_conf_t *conf = mddev_to_conf(mddev); + int i; + + rcu_read_lock(); + for (i=0; iraid_disks; i++) { + mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { + request_queue_t *r_queue = bdev_get_queue(rdev->bdev); + + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + + if (r_queue->unplug_fn) + r_queue->unplug_fn(r_queue); + + rdev_dec_pending(rdev, mddev); + rcu_read_lock(); + } + } + rcu_read_unlock(); +} + +static void raid6_unplug_device(request_queue_t *q) +{ + mddev_t *mddev = q->queuedata; + raid6_conf_t *conf = mddev_to_conf(mddev); + unsigned long flags; + + spin_lock_irqsave(&conf->device_lock, flags); + + if (blk_remove_plug(q)) { + conf->seq_flush++; + raid6_activate_delayed(conf); + } + md_wakeup_thread(mddev->thread); + + spin_unlock_irqrestore(&conf->device_lock, flags); + + unplug_slaves(mddev); +} + +static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk, + sector_t *error_sector) +{ + mddev_t *mddev = q->queuedata; + raid6_conf_t *conf = mddev_to_conf(mddev); + int i, ret = 0; + + rcu_read_lock(); + for (i=0; iraid_disks && ret == 0; i++) { + mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + if (rdev && !test_bit(Faulty, &rdev->flags)) { + struct block_device *bdev = rdev->bdev; + request_queue_t *r_queue = bdev_get_queue(bdev); + + if (!r_queue->issue_flush_fn) + ret = -EOPNOTSUPP; + else { + atomic_inc(&rdev->nr_pending); + rcu_read_unlock(); + ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, + error_sector); + rdev_dec_pending(rdev, mddev); + rcu_read_lock(); + } + } + } + rcu_read_unlock(); + return ret; +} + +static inline void raid6_plug_device(raid6_conf_t *conf) +{ + spin_lock_irq(&conf->device_lock); + blk_plug_device(conf->mddev->queue); + spin_unlock_irq(&conf->device_lock); +} + +static int make_request (request_queue_t *q, struct bio * bi) +{ + mddev_t *mddev = q->queuedata; + raid6_conf_t *conf = mddev_to_conf(mddev); + const unsigned int raid_disks = conf->raid_disks; + const unsigned int data_disks = raid_disks - 2; + unsigned int dd_idx, pd_idx; + sector_t new_sector; + sector_t logical_sector, last_sector; + struct stripe_head *sh; + const int rw = bio_data_dir(bi); + + if (unlikely(bio_barrier(bi))) { + bio_endio(bi, bi->bi_size, -EOPNOTSUPP); + return 0; + } + + md_write_start(mddev, bi); + + disk_stat_inc(mddev->gendisk, ios[rw]); + disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi)); + + logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1); + last_sector = bi->bi_sector + (bi->bi_size>>9); + + bi->bi_next = NULL; + bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ + + for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { + DEFINE_WAIT(w); + + new_sector = raid6_compute_sector(logical_sector, + raid_disks, data_disks, &dd_idx, &pd_idx, conf); + + PRINTK("raid6: make_request, sector %llu logical %llu\n", + (unsigned long long)new_sector, + (unsigned long long)logical_sector); + + retry: + prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); + sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK)); + if (sh) { + if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) { + /* Add failed due to overlap. Flush everything + * and wait a while + */ + raid6_unplug_device(mddev->queue); + release_stripe(sh); + schedule(); + goto retry; + } + finish_wait(&conf->wait_for_overlap, &w); + raid6_plug_device(conf); + handle_stripe(sh, NULL); + release_stripe(sh); + } else { + /* cannot get stripe for read-ahead, just give-up */ + clear_bit(BIO_UPTODATE, &bi->bi_flags); + finish_wait(&conf->wait_for_overlap, &w); + break; + } + + } + spin_lock_irq(&conf->device_lock); + if (--bi->bi_phys_segments == 0) { + int bytes = bi->bi_size; + + if (rw == WRITE ) + md_write_end(mddev); + bi->bi_size = 0; + bi->bi_end_io(bi, bytes, 0); + } + spin_unlock_irq(&conf->device_lock); + return 0; +} + +/* FIXME go_faster isn't used */ +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) +{ + raid6_conf_t *conf = (raid6_conf_t *) mddev->private; + struct stripe_head *sh; + int sectors_per_chunk = conf->chunk_size >> 9; + sector_t x; + unsigned long stripe; + int chunk_offset; + int dd_idx, pd_idx; + sector_t first_sector; + int raid_disks = conf->raid_disks; + int data_disks = raid_disks - 2; + sector_t max_sector = mddev->size << 1; + int sync_blocks; + int still_degraded = 0; + int i; + + if (sector_nr >= max_sector) { + /* just being told to finish up .. nothing much to do */ + unplug_slaves(mddev); + + if (mddev->curr_resync < max_sector) /* aborted */ + bitmap_end_sync(mddev->bitmap, mddev->curr_resync, + &sync_blocks, 1); + else /* completed sync */ + conf->fullsync = 0; + bitmap_close_sync(mddev->bitmap); + + return 0; + } + /* if there are 2 or more failed drives and we are trying + * to resync, then assert that we are finished, because there is + * nothing we can do. + */ + if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { + sector_t rv = (mddev->size << 1) - sector_nr; + *skipped = 1; + return rv; + } + if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && + !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && + !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { + /* we can skip this block, and probably more */ + sync_blocks /= STRIPE_SECTORS; + *skipped = 1; + return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ + } + + x = sector_nr; + chunk_offset = sector_div(x, sectors_per_chunk); + stripe = x; + BUG_ON(x != stripe); + + first_sector = raid6_compute_sector((sector_t)stripe*data_disks*sectors_per_chunk + + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf); + sh = get_active_stripe(conf, sector_nr, pd_idx, 1); + if (sh == NULL) { + sh = get_active_stripe(conf, sector_nr, pd_idx, 0); + /* make sure we don't swamp the stripe cache if someone else + * is trying to get access + */ + schedule_timeout_uninterruptible(1); + } + /* Need to check if array will still be degraded after recovery/resync + * We don't need to check the 'failed' flag as when that gets set, + * recovery aborts. + */ + for (i=0; iraid_disks; i++) + if (conf->disks[i].rdev == NULL) + still_degraded = 1; + + bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); + + spin_lock(&sh->lock); + set_bit(STRIPE_SYNCING, &sh->state); + clear_bit(STRIPE_INSYNC, &sh->state); + spin_unlock(&sh->lock); + + handle_stripe(sh, NULL); + release_stripe(sh); + + return STRIPE_SECTORS; +} + +/* + * This is our raid6 kernel thread. + * + * We scan the hash table for stripes which can be handled now. + * During the scan, completed stripes are saved for us by the interrupt + * handler, so that they will not have to wait for our next wakeup. + */ +static void raid6d (mddev_t *mddev) +{ + struct stripe_head *sh; + raid6_conf_t *conf = mddev_to_conf(mddev); + int handled; + + PRINTK("+++ raid6d active\n"); + + md_check_recovery(mddev); + + handled = 0; + spin_lock_irq(&conf->device_lock); + while (1) { + struct list_head *first; + + if (conf->seq_flush - conf->seq_write > 0) { + int seq = conf->seq_flush; + spin_unlock_irq(&conf->device_lock); + bitmap_unplug(mddev->bitmap); + spin_lock_irq(&conf->device_lock); + conf->seq_write = seq; + activate_bit_delay(conf); + } + + if (list_empty(&conf->handle_list) && + atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD && + !blk_queue_plugged(mddev->queue) && + !list_empty(&conf->delayed_list)) + raid6_activate_delayed(conf); + + if (list_empty(&conf->handle_list)) + break; + + first = conf->handle_list.next; + sh = list_entry(first, struct stripe_head, lru); + + list_del_init(first); + atomic_inc(&sh->count); + BUG_ON(atomic_read(&sh->count)!= 1); + spin_unlock_irq(&conf->device_lock); + + handled++; + handle_stripe(sh, conf->spare_page); + release_stripe(sh); + + spin_lock_irq(&conf->device_lock); + } + PRINTK("%d stripes handled\n", handled); + + spin_unlock_irq(&conf->device_lock); + + unplug_slaves(mddev); + + PRINTK("--- raid6d inactive\n"); +} + +static ssize_t +raid6_show_stripe_cache_size(mddev_t *mddev, char *page) +{ + raid6_conf_t *conf = mddev_to_conf(mddev); + if (conf) + return sprintf(page, "%d\n", conf->max_nr_stripes); + else + return 0; +} + +static ssize_t +raid6_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) +{ + raid6_conf_t *conf = mddev_to_conf(mddev); + char *end; + int new; + if (len >= PAGE_SIZE) + return -EINVAL; + if (!conf) + return -ENODEV; + + new = simple_strtoul(page, &end, 10); + if (!*page || (*end && *end != '\n') ) + return -EINVAL; + if (new <= 16 || new > 32768) + return -EINVAL; + while (new < conf->max_nr_stripes) { + if (drop_one_stripe(conf)) + conf->max_nr_stripes--; + else + break; + } + while (new > conf->max_nr_stripes) { + if (grow_one_stripe(conf)) + conf->max_nr_stripes++; + else break; + } + return len; +} + +static struct md_sysfs_entry +raid6_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR, + raid6_show_stripe_cache_size, + raid6_store_stripe_cache_size); + +static ssize_t +stripe_cache_active_show(mddev_t *mddev, char *page) +{ + raid6_conf_t *conf = mddev_to_conf(mddev); + if (conf) + return sprintf(page, "%d\n", atomic_read(&conf->active_stripes)); + else + return 0; +} + +static struct md_sysfs_entry +raid6_stripecache_active = __ATTR_RO(stripe_cache_active); + +static struct attribute *raid6_attrs[] = { + &raid6_stripecache_size.attr, + &raid6_stripecache_active.attr, + NULL, +}; +static struct attribute_group raid6_attrs_group = { + .name = NULL, + .attrs = raid6_attrs, +}; + +static int run(mddev_t *mddev) +{ + raid6_conf_t *conf; + int raid_disk, memory; + mdk_rdev_t *rdev; + struct disk_info *disk; + struct list_head *tmp; + + if (mddev->level != 6) { + PRINTK("raid6: %s: raid level not set to 6 (%d)\n", mdname(mddev), mddev->level); + return -EIO; + } + + mddev->private = kzalloc(sizeof (raid6_conf_t), GFP_KERNEL); + if ((conf = mddev->private) == NULL) + goto abort; + conf->disks = kzalloc(mddev->raid_disks * sizeof(struct disk_info), + GFP_KERNEL); + if (!conf->disks) + goto abort; + + conf->mddev = mddev; + + if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) + goto abort; + + conf->spare_page = alloc_page(GFP_KERNEL); + if (!conf->spare_page) + goto abort; + + spin_lock_init(&conf->device_lock); + init_waitqueue_head(&conf->wait_for_stripe); + init_waitqueue_head(&conf->wait_for_overlap); + INIT_LIST_HEAD(&conf->handle_list); + INIT_LIST_HEAD(&conf->delayed_list); + INIT_LIST_HEAD(&conf->bitmap_list); + INIT_LIST_HEAD(&conf->inactive_list); + atomic_set(&conf->active_stripes, 0); + atomic_set(&conf->preread_active_stripes, 0); + + PRINTK("raid6: run(%s) called.\n", mdname(mddev)); + + ITERATE_RDEV(mddev,rdev,tmp) { + raid_disk = rdev->raid_disk; + if (raid_disk >= mddev->raid_disks + || raid_disk < 0) + continue; + disk = conf->disks + raid_disk; + + disk->rdev = rdev; + + if (test_bit(In_sync, &rdev->flags)) { + char b[BDEVNAME_SIZE]; + printk(KERN_INFO "raid6: device %s operational as raid" + " disk %d\n", bdevname(rdev->bdev,b), + raid_disk); + conf->working_disks++; + } + } + + conf->raid_disks = mddev->raid_disks; + + /* + * 0 for a fully functional array, 1 or 2 for a degraded array. + */ + mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks; + conf->mddev = mddev; + conf->chunk_size = mddev->chunk_size; + conf->level = mddev->level; + conf->algorithm = mddev->layout; + conf->max_nr_stripes = NR_STRIPES; + + /* device size must be a multiple of chunk size */ + mddev->size &= ~(mddev->chunk_size/1024 -1); + mddev->resync_max_sectors = mddev->size << 1; + + if (conf->raid_disks < 4) { + printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", + mdname(mddev), conf->raid_disks); + goto abort; + } + if (!conf->chunk_size || conf->chunk_size % 4) { + printk(KERN_ERR "raid6: invalid chunk size %d for %s\n", + conf->chunk_size, mdname(mddev)); + goto abort; + } + if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) { + printk(KERN_ERR + "raid6: unsupported parity algorithm %d for %s\n", + conf->algorithm, mdname(mddev)); + goto abort; + } + if (mddev->degraded > 2) { + printk(KERN_ERR "raid6: not enough operational devices for %s" + " (%d/%d failed)\n", + mdname(mddev), conf->failed_disks, conf->raid_disks); + goto abort; + } + + if (mddev->degraded > 0 && + mddev->recovery_cp != MaxSector) { + if (mddev->ok_start_degraded) + printk(KERN_WARNING "raid6: starting dirty degraded array:%s" + "- data corruption possible.\n", + mdname(mddev)); + else { + printk(KERN_ERR "raid6: cannot start dirty degraded array" + " for %s\n", mdname(mddev)); + goto abort; + } + } + + { + mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6"); + if (!mddev->thread) { + printk(KERN_ERR + "raid6: couldn't allocate thread for %s\n", + mdname(mddev)); + goto abort; + } + } + + memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + + conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; + if (grow_stripes(conf, conf->max_nr_stripes)) { + printk(KERN_ERR + "raid6: couldn't allocate %dkB for buffers\n", memory); + shrink_stripes(conf); + md_unregister_thread(mddev->thread); + goto abort; + } else + printk(KERN_INFO "raid6: allocated %dkB for %s\n", + memory, mdname(mddev)); + + if (mddev->degraded == 0) + printk(KERN_INFO "raid6: raid level %d set %s active with %d out of %d" + " devices, algorithm %d\n", conf->level, mdname(mddev), + mddev->raid_disks-mddev->degraded, mddev->raid_disks, + conf->algorithm); + else + printk(KERN_ALERT "raid6: raid level %d set %s active with %d" + " out of %d devices, algorithm %d\n", conf->level, + mdname(mddev), mddev->raid_disks - mddev->degraded, + mddev->raid_disks, conf->algorithm); + + print_raid6_conf(conf); + + /* read-ahead size must cover two whole stripes, which is + * 2 * (n-2) * chunksize where 'n' is the number of raid devices + */ + { + int stripe = (mddev->raid_disks-2) * mddev->chunk_size + / PAGE_SIZE; + if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) + mddev->queue->backing_dev_info.ra_pages = 2 * stripe; + } + + /* Ok, everything is just fine now */ + sysfs_create_group(&mddev->kobj, &raid6_attrs_group); + + mddev->array_size = mddev->size * (mddev->raid_disks - 2); + + mddev->queue->unplug_fn = raid6_unplug_device; + mddev->queue->issue_flush_fn = raid6_issue_flush; + return 0; +abort: + if (conf) { + print_raid6_conf(conf); + safe_put_page(conf->spare_page); + kfree(conf->stripe_hashtbl); + kfree(conf->disks); + kfree(conf); + } + mddev->private = NULL; + printk(KERN_ALERT "raid6: failed to run raid set %s\n", mdname(mddev)); + return -EIO; +} + + + +static int stop (mddev_t *mddev) +{ + raid6_conf_t *conf = (raid6_conf_t *) mddev->private; + + md_unregister_thread(mddev->thread); + mddev->thread = NULL; + shrink_stripes(conf); + kfree(conf->stripe_hashtbl); + blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ + sysfs_remove_group(&mddev->kobj, &raid6_attrs_group); + kfree(conf); + mddev->private = NULL; + return 0; +} + +#if RAID6_DUMPSTATE +static void print_sh (struct seq_file *seq, struct stripe_head *sh) +{ + int i; + + seq_printf(seq, "sh %llu, pd_idx %d, state %ld.\n", + (unsigned long long)sh->sector, sh->pd_idx, sh->state); + seq_printf(seq, "sh %llu, count %d.\n", + (unsigned long long)sh->sector, atomic_read(&sh->count)); + seq_printf(seq, "sh %llu, ", (unsigned long long)sh->sector); + for (i = 0; i < sh->raid_conf->raid_disks; i++) { + seq_printf(seq, "(cache%d: %p %ld) ", + i, sh->dev[i].page, sh->dev[i].flags); + } + seq_printf(seq, "\n"); +} + +static void printall (struct seq_file *seq, raid6_conf_t *conf) +{ + struct stripe_head *sh; + struct hlist_node *hn; + int i; + + spin_lock_irq(&conf->device_lock); + for (i = 0; i < NR_HASH; i++) { + sh = conf->stripe_hashtbl[i]; + hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) { + if (sh->raid_conf != conf) + continue; + print_sh(seq, sh); + } + } + spin_unlock_irq(&conf->device_lock); +} +#endif + +static void status (struct seq_file *seq, mddev_t *mddev) +{ + raid6_conf_t *conf = (raid6_conf_t *) mddev->private; + int i; + + seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout); + seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks); + for (i = 0; i < conf->raid_disks; i++) + seq_printf (seq, "%s", + conf->disks[i].rdev && + test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_"); + seq_printf (seq, "]"); +#if RAID6_DUMPSTATE + seq_printf (seq, "\n"); + printall(seq, conf); +#endif +} + +static void print_raid6_conf (raid6_conf_t *conf) +{ + int i; + struct disk_info *tmp; + + printk("RAID6 conf printout:\n"); + if (!conf) { + printk("(conf==NULL)\n"); + return; + } + printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks, + conf->working_disks, conf->failed_disks); + + for (i = 0; i < conf->raid_disks; i++) { + char b[BDEVNAME_SIZE]; + tmp = conf->disks + i; + if (tmp->rdev) + printk(" disk %d, o:%d, dev:%s\n", + i, !test_bit(Faulty, &tmp->rdev->flags), + bdevname(tmp->rdev->bdev,b)); + } +} + +static int raid6_spare_active(mddev_t *mddev) +{ + int i; + raid6_conf_t *conf = mddev->private; + struct disk_info *tmp; + + for (i = 0; i < conf->raid_disks; i++) { + tmp = conf->disks + i; + if (tmp->rdev + && !test_bit(Faulty, &tmp->rdev->flags) + && !test_bit(In_sync, &tmp->rdev->flags)) { + mddev->degraded--; + conf->failed_disks--; + conf->working_disks++; + set_bit(In_sync, &tmp->rdev->flags); + } + } + print_raid6_conf(conf); + return 0; +} + +static int raid6_remove_disk(mddev_t *mddev, int number) +{ + raid6_conf_t *conf = mddev->private; + int err = 0; + mdk_rdev_t *rdev; + struct disk_info *p = conf->disks + number; + + print_raid6_conf(conf); + rdev = p->rdev; + if (rdev) { + if (test_bit(In_sync, &rdev->flags) || + atomic_read(&rdev->nr_pending)) { + err = -EBUSY; + goto abort; + } + p->rdev = NULL; + synchronize_rcu(); + if (atomic_read(&rdev->nr_pending)) { + /* lost the race, try later */ + err = -EBUSY; + p->rdev = rdev; + } + } + +abort: + + print_raid6_conf(conf); + return err; +} + +static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) +{ + raid6_conf_t *conf = mddev->private; + int found = 0; + int disk; + struct disk_info *p; + + if (mddev->degraded > 2) + /* no point adding a device */ + return 0; + /* + * find the disk ... but prefer rdev->saved_raid_disk + * if possible. + */ + if (rdev->saved_raid_disk >= 0 && + conf->disks[rdev->saved_raid_disk].rdev == NULL) + disk = rdev->saved_raid_disk; + else + disk = 0; + for ( ; disk < mddev->raid_disks; disk++) + if ((p=conf->disks + disk)->rdev == NULL) { + clear_bit(In_sync, &rdev->flags); + rdev->raid_disk = disk; + found = 1; + if (rdev->saved_raid_disk != disk) + conf->fullsync = 1; + rcu_assign_pointer(p->rdev, rdev); + break; + } + print_raid6_conf(conf); + return found; +} + +static int raid6_resize(mddev_t *mddev, sector_t sectors) +{ + /* no resync is happening, and there is enough space + * on all devices, so we can resize. + * We need to make sure resync covers any new space. + * If the array is shrinking we should possibly wait until + * any io in the removed space completes, but it hardly seems + * worth it. + */ + sectors &= ~((sector_t)mddev->chunk_size/512 - 1); + mddev->array_size = (sectors * (mddev->raid_disks-2))>>1; + set_capacity(mddev->gendisk, mddev->array_size << 1); + mddev->changed = 1; + if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) { + mddev->recovery_cp = mddev->size << 1; + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + } + mddev->size = sectors /2; + mddev->resync_max_sectors = sectors; + return 0; +} + +static void raid6_quiesce(mddev_t *mddev, int state) +{ + raid6_conf_t *conf = mddev_to_conf(mddev); + + switch(state) { + case 1: /* stop all writes */ + spin_lock_irq(&conf->device_lock); + conf->quiesce = 1; + wait_event_lock_irq(conf->wait_for_stripe, + atomic_read(&conf->active_stripes) == 0, + conf->device_lock, /* nothing */); + spin_unlock_irq(&conf->device_lock); + break; + + case 0: /* re-enable writes */ + spin_lock_irq(&conf->device_lock); + conf->quiesce = 0; + wake_up(&conf->wait_for_stripe); + spin_unlock_irq(&conf->device_lock); + break; + } +} + +static struct mdk_personality raid6_personality = +{ + .name = "raid6", + .level = 6, + .owner = THIS_MODULE, + .make_request = make_request, + .run = run, + .stop = stop, + .status = status, + .error_handler = error, + .hot_add_disk = raid6_add_disk, + .hot_remove_disk= raid6_remove_disk, + .spare_active = raid6_spare_active, + .sync_request = sync_request, + .resize = raid6_resize, + .quiesce = raid6_quiesce, +}; + +static int __init raid6_init(void) +{ + int e; + + e = raid6_select_algo(); + if ( e ) + return e; + + return register_md_personality(&raid6_personality); +} + +static void raid6_exit (void) +{ + unregister_md_personality(&raid6_personality); +} + +module_init(raid6_init); +module_exit(raid6_exit); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("md-personality-8"); /* RAID6 */ +MODULE_ALIAS("md-raid6"); +MODULE_ALIAS("md-level-6"); diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig index ef52e6da01ed..344d83aae3ec 100644 --- a/trunk/drivers/media/Kconfig +++ b/trunk/drivers/media/Kconfig @@ -25,7 +25,7 @@ config VIDEO_DEV module will be called videodev. config VIDEO_V4L1 - bool "Enable Video For Linux API 1 (DEPRECATED)" + boolean "Enable Video For Linux API 1 (DEPRECATED)" depends on VIDEO_DEV select VIDEO_V4L1_COMPAT default y @@ -36,7 +36,7 @@ config VIDEO_V4L1 If you are unsure as to whether this is required, answer Y. config VIDEO_V4L1_COMPAT - bool "Enable Video For Linux API 1 compatible Layer" + boolean "Enable Video For Linux API 1 compatible Layer" depends on VIDEO_DEV default y ---help--- diff --git a/trunk/drivers/media/common/Makefile b/trunk/drivers/media/common/Makefile index 8e7448230643..61b89617a967 100644 --- a/trunk/drivers/media/common/Makefile +++ b/trunk/drivers/media/common/Makefile @@ -1,5 +1,5 @@ saa7146-objs := saa7146_i2c.o saa7146_core.o -saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o +saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o ir-common-objs := ir-functions.o ir-keymaps.o obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o diff --git a/trunk/drivers/media/common/ir-functions.c b/trunk/drivers/media/common/ir-functions.c index 8eaa88fd8b9b..397cff8b345b 100644 --- a/trunk/drivers/media/common/ir-functions.c +++ b/trunk/drivers/media/common/ir-functions.c @@ -269,3 +269,4 @@ EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); * c-basic-offset: 8 * End: */ + diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index ca98d9478947..a294d5c2c73f 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -618,7 +618,7 @@ IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_em_terratec); -IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { +IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { [ 0x3a ] = KEY_0, [ 0x31 ] = KEY_1, [ 0x32 ] = KEY_2, @@ -670,7 +670,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { [ 0x27 ] = KEY_RECORD, }; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); +EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb); IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { [ 0x0f ] = KEY_0, @@ -1263,51 +1263,34 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { [ 0x0f ] = KEY_9, [ 0x00 ] = KEY_POWER, - [ 0x1b ] = KEY_AUDIO, /* Audio Source */ - [ 0x02 ] = KEY_TUNER, /* TV/FM, not on Y0400052 */ - [ 0x1e ] = KEY_VIDEO, /* Video Source */ - [ 0x16 ] = KEY_INFO, /* Display information */ + [ 0x02 ] = KEY_TUNER, /* TV/FM */ + [ 0x1e ] = KEY_VIDEO, [ 0x04 ] = KEY_VOLUMEUP, [ 0x08 ] = KEY_VOLUMEDOWN, [ 0x0c ] = KEY_CHANNELUP, [ 0x10 ] = KEY_CHANNELDOWN, [ 0x03 ] = KEY_ZOOM, /* fullscreen */ - [ 0x1f ] = KEY_TEXT, /* closed caption/teletext */ + [ 0x1f ] = KEY_SUBTITLE, /* closed caption/teletext */ [ 0x20 ] = KEY_SLEEP, - [ 0x29 ] = KEY_CLEAR, /* boss key */ [ 0x14 ] = KEY_MUTE, [ 0x2b ] = KEY_RED, [ 0x2c ] = KEY_GREEN, [ 0x2d ] = KEY_YELLOW, [ 0x2e ] = KEY_BLUE, - [ 0x18 ] = KEY_KPPLUS, /* fine tune + , not on Y040052 */ - [ 0x19 ] = KEY_KPMINUS, /* fine tune - , not on Y040052 */ - [ 0x2a ] = KEY_MEDIA, /* PIP (Picture in picture */ + [ 0x18 ] = KEY_KPPLUS, /* fine tune + */ + [ 0x19 ] = KEY_KPMINUS, /* fine tune - */ [ 0x21 ] = KEY_DOT, [ 0x13 ] = KEY_ENTER, - [ 0x11 ] = KEY_LAST, /* Recall (last channel */ - [ 0x22 ] = KEY_PREVIOUS, + [ 0x22 ] = KEY_BACK, [ 0x23 ] = KEY_PLAYPAUSE, [ 0x24 ] = KEY_NEXT, - [ 0x25 ] = KEY_ARCHIVE, /* Time Shifting */ [ 0x26 ] = KEY_STOP, - [ 0x27 ] = KEY_RECORD, - [ 0x28 ] = KEY_SAVE, /* Screenshot */ - [ 0x2f ] = KEY_MENU, - [ 0x30 ] = KEY_CANCEL, - [ 0x31 ] = KEY_CHANNEL, /* Channel Surf */ - [ 0x32 ] = KEY_SUBTITLE, - [ 0x33 ] = KEY_LANGUAGE, - [ 0x34 ] = KEY_REWIND, - [ 0x35 ] = KEY_FASTFORWARD, - [ 0x36 ] = KEY_TV, - [ 0x37 ] = KEY_RADIO, /* FM */ - [ 0x38 ] = KEY_DVD + [ 0x27 ] = KEY_RECORD }; EXPORT_SYMBOL_GPL(ir_codes_winfast); -IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { +IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { [ 0x59 ] = KEY_MUTE, [ 0x4a ] = KEY_POWER, @@ -1365,7 +1348,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { [ 0x0a ] = KEY_BACKSPACE, }; -EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); +EXPORT_SYMBOL_GPL(ir_codes_pinnacle); /* Hauppauge: the newer, gray remotes (seems there are multiple * slightly different versions), shipped with cx88+ivtv cards. @@ -1430,46 +1413,3 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); -IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = { - [ 0x1d ] = KEY_SWITCHVIDEOMODE, /* switch inputs */ - [ 0x2a ] = KEY_FRONT, - - [ 0x3e ] = KEY_1, - [ 0x02 ] = KEY_2, - [ 0x06 ] = KEY_3, - [ 0x0a ] = KEY_4, - [ 0x0e ] = KEY_5, - [ 0x12 ] = KEY_6, - [ 0x16 ] = KEY_7, - [ 0x1a ] = KEY_8, - [ 0x1e ] = KEY_9, - [ 0x3a ] = KEY_0, - [ 0x22 ] = KEY_NUMLOCK, /* -/-- */ - [ 0x20 ] = KEY_REFRESH, - - [ 0x03 ] = KEY_BRIGHTNESSDOWN, - [ 0x28 ] = KEY_AUDIO, - [ 0x3c ] = KEY_UP, - [ 0x3f ] = KEY_LEFT, - [ 0x2e ] = KEY_MUTE, - [ 0x3b ] = KEY_RIGHT, - [ 0x00 ] = KEY_DOWN, - [ 0x07 ] = KEY_BRIGHTNESSUP, - [ 0x2c ] = KEY_TEXT, - - [ 0x37 ] = KEY_RECORD, - [ 0x17 ] = KEY_PLAY, - [ 0x13 ] = KEY_PAUSE, - [ 0x26 ] = KEY_STOP, - [ 0x18 ] = KEY_FASTFORWARD, - [ 0x14 ] = KEY_REWIND, - [ 0x33 ] = KEY_ZOOM, - [ 0x32 ] = KEY_KEYBOARD, - [ 0x30 ] = KEY_GOTO, /* Pointing arrow */ - [ 0x36 ] = KEY_MACRO, /* Maximize/Minimize (yellow) */ - [ 0x0b ] = KEY_RADIO, - [ 0x10 ] = KEY_POWER, - -}; - -EXPORT_SYMBOL_GPL(ir_codes_npgtech); diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index 0027acc5b8e9..523ab3851c7b 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -501,7 +501,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) return 0; } -EXPORT_SYMBOL_GPL(saa7146_vv_init); int saa7146_vv_release(struct saa7146_dev* dev) { @@ -516,7 +515,6 @@ int saa7146_vv_release(struct saa7146_dev* dev) return 0; } -EXPORT_SYMBOL_GPL(saa7146_vv_release); int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, char *name, int type) @@ -555,7 +553,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, *vid = vfd; return 0; } -EXPORT_SYMBOL_GPL(saa7146_register_device); int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) { @@ -574,7 +571,6 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev return 0; } -EXPORT_SYMBOL_GPL(saa7146_unregister_device); static int __init saa7146_vv_init_module(void) { diff --git a/trunk/drivers/media/common/saa7146_hlp.c b/trunk/drivers/media/common/saa7146_hlp.c index 2092e6c33dd2..33bec8a6843b 100644 --- a/trunk/drivers/media/common/saa7146_hlp.c +++ b/trunk/drivers/media/common/saa7146_hlp.c @@ -641,7 +641,6 @@ void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sy vv->current_hps_source = source; vv->current_hps_sync = sync; } -EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync); int saa7146_enable_overlay(struct saa7146_fh *fh) { diff --git a/trunk/drivers/media/common/saa7146_video.c b/trunk/drivers/media/common/saa7146_video.c index 8393d472d3b8..e7079d1bd537 100644 --- a/trunk/drivers/media/common/saa7146_video.c +++ b/trunk/drivers/media/common/saa7146_video.c @@ -318,7 +318,6 @@ int saa7146_start_preview(struct saa7146_fh *fh) return 0; } -EXPORT_SYMBOL_GPL(saa7146_start_preview); int saa7146_stop_preview(struct saa7146_fh *fh) { @@ -353,7 +352,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh) return 0; } -EXPORT_SYMBOL_GPL(saa7146_stop_preview); static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) { diff --git a/trunk/drivers/media/common/saa7146_vv_ksyms.c b/trunk/drivers/media/common/saa7146_vv_ksyms.c new file mode 100644 index 000000000000..62226eb4753b --- /dev/null +++ b/trunk/drivers/media/common/saa7146_vv_ksyms.c @@ -0,0 +1,12 @@ +#include +#include + +EXPORT_SYMBOL_GPL(saa7146_start_preview); +EXPORT_SYMBOL_GPL(saa7146_stop_preview); + +EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync); +EXPORT_SYMBOL_GPL(saa7146_register_device); +EXPORT_SYMBOL_GPL(saa7146_unregister_device); + +EXPORT_SYMBOL_GPL(saa7146_vv_init); +EXPORT_SYMBOL_GPL(saa7146_vv_release); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 3be87c72e37b..9c7f122826e0 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -14,7 +14,6 @@ #include "stv0297.h" #include "mt312.h" #include "lgdt330x.h" -#include "lg_h06xf.h" #include "dvb-pll.h" /* lnb control */ @@ -167,12 +166,11 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, return 0; } -static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) { u8 buf[4]; u32 div; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct flexcop_device *fc = fe->dvb->priv; div = params->frequency / 125; @@ -183,11 +181,8 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv if (params->frequency < 1500000) buf[3] |= 0x10; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) { + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; - } return 0; } @@ -246,6 +241,7 @@ static struct stv0299_config samsung_tbmu24112_config = { .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, + .pll_set = samsung_tbmu24112_pll_set, }; /* dvb-t mt352 */ @@ -268,14 +264,11 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) return 0; } -static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) +static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { u32 div; unsigned char bs = 0; - if (buf_len < 5) - return -EINVAL; - #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; @@ -283,18 +276,19 @@ static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_fro if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; - pllbuf[0] = 0x61; + pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */ pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = 0xcc; pllbuf[4] = bs; - return 5; + return 0; } static struct mt352_config samsung_tdtc9251dh0_config = { .demod_address = 0x0f, .demod_init = samsung_tdtc9251dh0_demod_init, + .pll_set = samsung_tdtc9251dh0_pll_set, }; static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) @@ -303,21 +297,56 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir return request_firmware(fw, name, fc->dev); } -static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int lgdt3303_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params) { struct flexcop_device *fc = fe->dvb->priv; - return lg_h06xf_pll_set(fe, &fc->i2c_adap, params); + u8 buf[4]; + struct i2c_msg msg = + { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 }; + int err; + + dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0); + dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", + __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); + if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { + printk(KERN_WARNING "lgdt3303: %s error " + "(addr %02x <- %02x, err = %i)\n", + __FUNCTION__, buf[0], buf[1], err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + buf[0] = 0x86 | 0x18; + buf[1] = 0x50; + msg.len = 2; + if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { + printk(KERN_WARNING "lgdt3303: %s error " + "(addr %02x <- %02x, err = %i)\n", + __FUNCTION__, buf[0], buf[1], err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + return 0; } static struct lgdt330x_config air2pc_atsc_hd5000_config = { .demod_address = 0x59, .demod_chip = LGDT3303, .serial_mpeg = 0x04, + .pll_set = lgdt3303_pll_set, .clock_polarity_flip = 1, }; static struct nxt200x_config samsung_tbmv_config = { .demod_address = 0x0a, + .pll_address = 0xc2, + .pll_desc = &dvb_pll_samsung_tbmv, }; static struct bcm3510_config air2pc_atsc_first_gen_config = { @@ -325,7 +354,7 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = { .request_firmware = flexcop_fe_request_firmware, }; -static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { u8 buf[4]; u32 div; @@ -342,8 +371,6 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, if (params->frequency < 1550000) buf[3] |= 0x02; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -352,52 +379,9 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, static struct mt312_config skystar23_samsung_tbdu18132_config = { .demod_address = 0x0e, + .pll_set = skystar23_samsung_tbdu18132_pll_set, }; -static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct flexcop_device *fc = fe->dvb->priv; - u8 buf[4]; - u16 div; - int ret; - -/* 62.5 kHz * 10 */ -#define REF_FREQ 625 -#define FREQ_OFFSET 36125 - - div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz - - buf[0] = (u8)( div >> 8) & 0x7f; - buf[1] = (u8) div & 0xff; - -/* F(osc) = N * Reference Freq. (62.5 kHz) - * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8 - * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0 - * byte 4 : 1 * * AGD R3 R2 R1 R0 - * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1 - * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ - buf[2] = 0x95; - -// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 -// 47 - 153 0 * 0 0 0 0 0 1 0x01 -// 153 - 430 0 * 0 0 0 0 1 0 0x02 -// 430 - 822 0 * 0 0 1 0 0 0 0x08 -// 822 - 862 1 * 0 0 1 0 0 0 0x88 - - if (fep->frequency <= 153000000) buf[3] = 0x01; - else if (fep->frequency <= 430000000) buf[3] = 0x02; - else if (fep->frequency <= 822000000) buf[3] = 0x08; - else buf[3] = 0x88; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); - ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3); - deb_tuner("tuner write returned: %d\n",ret); - - return 0; -} static u8 alps_tdee4_stv0297_inittab[] = { 0x80, 0x01, @@ -506,9 +490,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; + ops = fc->fe->ops; ops->set_voltage = flexcop_set_voltage; @@ -521,19 +503,16 @@ int flexcop_frontend_init(struct flexcop_device *fc) /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { fc->dev_type = FC_AIR_DVB; - fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); } else /* try the air atsc 2nd generation (nxt2002) */ if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { fc->dev_type = FC_AIR_ATSC2; - dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv); info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); } else /* try the air atsc 3nd generation (lgdt3303) */ if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { fc->dev_type = FC_AIR_ATSC3; - fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); } else /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ @@ -544,14 +523,11 @@ int flexcop_frontend_init(struct flexcop_device *fc) /* try the cable dvb (stv0297) */ if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { fc->dev_type = FC_CABLE; - fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); } else /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; + ops = fc->fe->ops; ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; ops->diseqc_send_burst = flexcop_diseqc_send_burst; @@ -571,7 +547,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) } else { if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { err("frontend registration failed!"); - ops = &fc->fe->ops; + ops = fc->fe->ops; if (ops->release != NULL) ops->release(fc->fe); fc->fe = NULL; diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index f04041702191..9bc40bdcc282 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -242,16 +242,19 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) return ret; - if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { - flexcop_dma_free(&fc_pci->dma[0]); - return ret; - } + if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) + goto dma1_free; flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); fc_pci->init_state |= FC_PCI_DMA_INIT; + goto success; +dma1_free: + flexcop_dma_free(&fc_pci->dma[0]); + +success: return ret; } @@ -300,7 +303,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) spin_lock_init(&fc_pci->irq_lock); fc_pci->init_state |= FC_PCI_INIT; - return ret; + goto success; err_pci_iounmap: pci_iounmap(fc_pci->pdev, fc_pci->io_mem); @@ -309,6 +312,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) pci_release_regions(fc_pci->pdev); err_pci_disable_device: pci_disable_device(fc_pci->pdev); + +success: return ret; } @@ -373,14 +378,14 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); - return ret; - + goto success; err_fc_exit: flexcop_device_exit(fc); err_pci_exit: flexcop_pci_exit(fc_pci); err_kfree: flexcop_device_kfree(fc); +success: return ret; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c index 515954f96c9a..06ec9fff0ec1 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c @@ -433,10 +433,11 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); - return 0; - + ret = 0; + goto success; urb_error: flexcop_usb_transfer_exit(fc_usb); +success: return ret; } @@ -514,14 +515,15 @@ static int flexcop_usb_probe(struct usb_interface *intf, goto err_fc_exit; info("%s successfully initialized and connected.",DRIVER_NAME); - return 0; - + ret = 0; + goto success; err_fc_exit: flexcop_device_exit(fc); err_usb_exit: flexcop_usb_exit(fc_usb); err_kfree: flexcop_device_kfree(fc); +success: return ret; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop.c b/trunk/drivers/media/dvb/b2c2/flexcop.c index 29ec4183118e..56ba52470676 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop.c @@ -67,7 +67,7 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) static int flexcop_dvb_init(struct flexcop_device *fc) { int ret; - if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) { + if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) { err("error registering DVB adapter"); return ret; } @@ -116,7 +116,7 @@ static int flexcop_dvb_init(struct flexcop_device *fc) dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); fc->init_state |= FC_STATE_DVB_INIT; - return 0; + goto success; err_connect_frontend: fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); @@ -129,6 +129,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc) err_dmx: dvb_unregister_adapter(&fc->dvb_adapter); return ret; + +success: + return 0; } static void flexcop_dvb_exit(struct flexcop_device *fc) @@ -276,10 +279,11 @@ int flexcop_device_initialize(struct flexcop_device *fc) flexcop_device_name(fc,"initialization of","complete"); - return 0; - + ret = 0; + goto success; error: flexcop_device_exit(fc); +success: return ret; } EXPORT_SYMBOL(flexcop_device_initialize); diff --git a/trunk/drivers/media/dvb/bt8xx/bt878.c b/trunk/drivers/media/dvb/bt8xx/bt878.c index 761fa6e7d762..5500f8a0ffe2 100644 --- a/trunk/drivers/media/dvb/bt8xx/bt878.c +++ b/trunk/drivers/media/dvb/bt8xx/bt878.c @@ -63,6 +63,8 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); int bt878_num; struct bt878 bt878[BT878_MAX]; +EXPORT_SYMBOL(bt878_debug); +EXPORT_SYMBOL(bt878_verbose); EXPORT_SYMBOL(bt878_num); EXPORT_SYMBOL(bt878); @@ -391,9 +393,7 @@ static struct cards card_list[] __devinitdata = { { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, - { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, - { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, - + { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, { 0, -1, NULL } }; @@ -417,11 +417,6 @@ static int __devinit bt878_probe(struct pci_dev *dev, printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", bt878_num); - if (bt878_num >= BT878_MAX) { - printk(KERN_ERR "bt878: Too many devices inserted\n"); - result = -ENOMEM; - goto fail0; - } if (pci_enable_device(dev)) return -EIO; diff --git a/trunk/drivers/media/dvb/bt8xx/dst.c b/trunk/drivers/media/dvb/bt8xx/dst.c index d687a14ec0a7..1cfa5e5035d8 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst.c +++ b/trunk/drivers/media/dvb/bt8xx/dst.c @@ -38,10 +38,6 @@ static unsigned int dst_addons; module_param(dst_addons, int, 0644); MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); -static unsigned int dst_algo; -module_param(dst_algo, int, 0644); -MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); - #define HAS_LOCK 1 #define ATTEMPT_TUNE 2 #define HAS_POWER 4 @@ -51,24 +47,20 @@ MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); #define DST_INFO 2 #define DST_DEBUG 3 -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > DST_ERROR) && (x > y)) \ - printk(KERN_ERR "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_INFO) && (x > y)) \ - printk(KERN_INFO "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ##arg); \ - } \ +#define dprintk(x, y, z, format, arg...) do { \ + if (z) { \ + if ((x > DST_ERROR) && (x > y)) \ + printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ + else if ((x > DST_NOTICE) && (x > y)) \ + printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ + else if ((x > DST_INFO) && (x > y)) \ + printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ + else if ((x > DST_DEBUG) && (x > y)) \ + printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ + } else { \ + if (x > y) \ + printk(format, ##arg); \ + } \ } while(0) @@ -118,7 +110,7 @@ int dst_gpio_inb(struct dst_state *state, u8 *result) *result = 0; if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); + dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err); return -EREMOTEIO; } *result = (u8) rd_packet.rd.value; @@ -371,17 +363,6 @@ static int dst_set_freq(struct dst_state *state, u32 freq) state->tx_tuna[2] = (freq >> 16) & 0xff; state->tx_tuna[3] = (freq >> 8) & 0xff; state->tx_tuna[4] = (u8) freq; - } else if (state->dst_type == DST_TYPE_IS_ATSC) { - freq = freq / 1000; - if (freq < 51000 || freq > 858000) - return -EINVAL; - state->tx_tuna[2] = (freq >> 16) & 0xff; - state->tx_tuna[3] = (freq >> 8) & 0xff; - state->tx_tuna[4] = (u8) freq; - state->tx_tuna[5] = 0x00; /* ATSC */ - state->tx_tuna[6] = 0x00; - if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) - state->tx_tuna[7] = 0x00; /* Digital */ } else return -EINVAL; @@ -466,41 +447,29 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) } dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); srate /= 1000; - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_SYMDIV) { - sval = srate; - sval <<= 20; - do_div(sval, 88000); - symcalc = (u32) sval; - dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); - state->tx_tuna[5] = (u8) (symcalc >> 12); - state->tx_tuna[6] = (u8) (symcalc >> 4); - state->tx_tuna[7] = (u8) (symcalc << 4); - } else { - state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; - state->tx_tuna[6] = (u8) (srate >> 8); - state->tx_tuna[7] = (u8) srate; - } - state->tx_tuna[8] &= ~0x20; - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { - if (srate > 8000) - state->tx_tuna[8] |= 0x20; - } - } else if (state->dst_type == DST_TYPE_IS_CABLE) { - dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); - if (!strncmp(state->fw_name, "DCTNEW", 6)) { - state->tx_tuna[5] = (u8) (srate >> 8); - state->tx_tuna[6] = (u8) srate; - state->tx_tuna[7] = 0x00; - } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { - state->tx_tuna[5] = 0x00; - state->tx_tuna[6] = (u8) (srate >> 8); - state->tx_tuna[7] = (u8) srate; - } + if (state->type_flags & DST_TYPE_HAS_SYMDIV) { + sval = srate; + sval <<= 20; + do_div(sval, 88000); + symcalc = (u32) sval; + dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); + state->tx_tuna[5] = (u8) (symcalc >> 12); + state->tx_tuna[6] = (u8) (symcalc >> 4); + state->tx_tuna[7] = (u8) (symcalc << 4); + } else { + state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; + state->tx_tuna[6] = (u8) (srate >> 8); + state->tx_tuna[7] = (u8) srate; + } + state->tx_tuna[8] &= ~0x20; + if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { + if (srate > 8000) + state->tx_tuna[8] |= 0x20; } return 0; } + static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) { if (state->dst_type != DST_TYPE_IS_CABLE) @@ -521,10 +490,7 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio state->tx_tuna[8] = 0x80; break; case QAM_256: - if (!strncmp(state->fw_name, "DCTNEW", 6)) - state->tx_tuna[8] = 0xff; - else if (!strncmp(state->fw_name, "DCT-CI", 6)) - state->tx_tuna[8] = 0x00; + state->tx_tuna[8] = 0x00; break; case QPSK: case QAM_AUTO: @@ -557,19 +523,13 @@ u8 dst_check_sum(u8 *buf, u32 len) } EXPORT_SYMBOL(dst_check_sum); -static void dst_type_flags_print(struct dst_state *state) +static void dst_type_flags_print(u32 type_flags) { - u32 type_flags = state->type_flags; - dprintk(verbose, DST_ERROR, 0, "DST type flags :"); - if (type_flags & DST_TYPE_HAS_TS188) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); - if (type_flags & DST_TYPE_HAS_NEWTUNE_2) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); + if (type_flags & DST_TYPE_HAS_NEWTUNE) + dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); if (type_flags & DST_TYPE_HAS_TS204) dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); - if (type_flags & DST_TYPE_HAS_VLF) - dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); if (type_flags & DST_TYPE_HAS_SYMDIV) dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); if (type_flags & DST_TYPE_HAS_FW_1) @@ -582,7 +542,7 @@ static void dst_type_flags_print(struct dst_state *state) } -static int dst_type_print(struct dst_state *state, u8 type) +static int dst_type_print(u8 type) { char *otype; switch (type) { @@ -598,10 +558,6 @@ static int dst_type_print(struct dst_state *state, u8 type) otype = "cable"; break; - case DST_TYPE_IS_ATSC: - otype = "atsc"; - break; - default: dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); return -EINVAL; @@ -611,127 +567,6 @@ static int dst_type_print(struct dst_state *state, u8 type) return 0; } -struct tuner_types tuner_list[] = { - { - .tuner_type = TUNER_TYPE_L64724, - .tuner_name = "L 64724", - .board_name = "UNKNOWN", - .fw_name = "UNKNOWN" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1020", - .fw_name = "DST-MOT" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1020", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_MB86A15, - .tuner_name = "MB 86A15", - .board_name = "VP1022", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_MB86A15, - .tuner_name = "MB 86A15", - .board_name = "VP1025", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1030", - .fw_name = "DST-CI" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1030", - .fw_name = "DSTMCI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2021", - .fw_name = "DCTNEW" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2030", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2031", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2040", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3020", - .fw_name = "DTTFTA" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3021", - .fw_name = "DTTFTA" - }, - - { - .tuner_type = TUNER_TYPE_TDA10046, - .tuner_name = "TDA10046", - .board_name = "VP3040", - .fw_name = "DTT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3051", - .fw_name = "DTTNXT" - }, - - { - .tuner_type = TUNER_TYPE_NXT200x, - .tuner_name = "NXT200x", - .board_name = "VP3220", - .fw_name = "ATSCDI" - }, - - { - .tuner_type = TUNER_TYPE_NXT200x, - .tuner_name = "NXT200x", - .board_name = "VP3250", - .fw_name = "ATSCAD" - }, -}; - /* Known cards list Satellite @@ -773,8 +608,7 @@ static struct dst_types dst_tlist[] = { .offset = 0, .dst_type = DST_TYPE_IS_SAT, .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, - .dst_feature = 0, - .tuner_type = 0 + .dst_feature = 0 }, /* obsolete */ { @@ -782,17 +616,15 @@ static struct dst_types dst_tlist[] = { .offset = 0, .dst_type = DST_TYPE_IS_SAT, .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 + .dst_feature = 0 }, /* obsolete */ { .device_id = "DST-030", .offset = 0, .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, + .dst_feature = 0 }, /* obsolete */ { @@ -801,8 +633,7 @@ static struct dst_types dst_tlist[] = { .dst_type = DST_TYPE_IS_SAT, .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 - | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, - .tuner_type = TUNER_TYPE_MULTI + | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO }, { @@ -810,63 +641,57 @@ static struct dst_types dst_tlist[] = { .offset = 0, .dst_type = DST_TYPE_IS_SAT, .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 + .dst_feature = 0 }, /* obsolete */ { .device_id = "DST-CI", .offset = 1, .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, + .dst_feature = DST_TYPE_HAS_CA }, /* An OEM board */ { .device_id = "DSTMCI", .offset = 1, .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 - | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, - .tuner_type = TUNER_TYPE_MULTI + | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC }, { .device_id = "DSTFCI", .offset = 1, .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, + .dst_feature = 0 }, /* unknown to vendor */ { .device_id = "DCT-CI", .offset = 1, .dst_type = DST_TYPE_IS_CABLE, - .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 + | DST_TYPE_HAS_FW_2, + .dst_feature = DST_TYPE_HAS_CA }, { .device_id = "DCTNEW", .offset = 1, .dst_type = DST_TYPE_IS_CABLE, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, - .dst_feature = 0, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD, + .dst_feature = 0 }, { .device_id = "DTT-CI", .offset = 1, .dst_type = DST_TYPE_IS_TERR, - .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, + .dst_feature = DST_TYPE_HAS_CA }, { @@ -874,8 +699,7 @@ static struct dst_types dst_tlist[] = { .offset = 1, .dst_type = DST_TYPE_IS_TERR, .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = 0, - .tuner_type = 0 + .dst_feature = 0 }, { @@ -883,8 +707,7 @@ static struct dst_types dst_tlist[] = { .offset = 1, .dst_type = DST_TYPE_IS_TERR, .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = DST_TYPE_HAS_ANALOG, - .tuner_type = 0 + .dst_feature = DST_TYPE_HAS_ANALOG }, { @@ -892,17 +715,15 @@ static struct dst_types dst_tlist[] = { .offset = 1, .dst_type = DST_TYPE_IS_ATSC, .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = 0, - .tuner_type = 0 + .dst_feature = 0 }, { .device_id = "ATSCAD", .offset = 1, .dst_type = DST_TYPE_IS_ATSC, - .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, - .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, - .tuner_type = 0 + .type_flags = DST_TYPE_HAS_FW_2, + .dst_feature = 0 }, { } @@ -947,9 +768,6 @@ static int dst_fw_ver(struct dst_state *state) static int dst_card_type(struct dst_state *state) { - int j; - struct tuner_types *p_tuner_list = NULL; - u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; get_type[7] = dst_check_sum(get_type, 7); if (dst_command(state, get_type, 8) < 0) { @@ -957,17 +775,9 @@ static int dst_card_type(struct dst_state *state) return -1; } memset(&state->card_info, '\0', 8); - memcpy(&state->card_info, &state->rxbuffer, 7); + memcpy(&state->card_info, &state->rxbuffer, 8); dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); - for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { - if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { - state->tuner_type = p_tuner_list->tuner_type; - dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", - p_tuner_list->tuner_name, p_tuner_list->tuner_type); - } - } - return 0; } @@ -980,64 +790,12 @@ static int dst_get_vendor(struct dst_state *state) return -1; } memset(&state->vendor, '\0', 8); - memcpy(&state->vendor, &state->rxbuffer, 7); + memcpy(&state->vendor, &state->rxbuffer, 8); dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); return 0; } -static void debug_dst_buffer(struct dst_state *state) -{ - int i; - - if (verbose > 2) { - printk("%s: [", __func__); - for (i = 0; i < 8; i++) - printk(" %02x", state->rxbuffer[i]); - printk("]\n"); - } -} - -static int dst_check_stv0299(struct dst_state *state) -{ - u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_stv0299[7] = dst_check_sum(check_stv0299, 7); - if (dst_command(state, check_stv0299, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); - return -1; - } - debug_dst_buffer(state); - - if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { - dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); - state->tuner_type = TUNER_TYPE_STV0299; - return 0; - } - - return -1; -} - -static int dst_check_mb86a15(struct dst_state *state) -{ - u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); - if (dst_command(state, check_mb86a15, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); - return -1; - } - debug_dst_buffer(state); - - if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); - state->tuner_type = TUNER_TYPE_MB86A15; - return 0; - } - - return -1; -} - static int dst_get_tuner_info(struct dst_state *state) { u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -1045,59 +803,60 @@ static int dst_get_tuner_info(struct dst_state *state) get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); - dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { - if (dst_command(state, get_tuner_1, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); - goto force; + if (dst_command(state, get_tuner_2, 8) < 0) { + dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + return -1; } } else { - if (dst_command(state, get_tuner_2, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); - goto force; + if (dst_command(state, get_tuner_1, 8) < 0) { + dprintk(verbose, DST_INFO, 1, "Unsupported Command"); + return -1; } } memset(&state->board_info, '\0', 8); memcpy(&state->board_info, &state->rxbuffer, 8); if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { - dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); - } - if (state->board_info[0] == 0xbc) { - if (state->type_flags != DST_TYPE_IS_ATSC) - state->type_flags |= DST_TYPE_HAS_TS188; - else - state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; - - if (state->board_info[1] == 0x01) { - state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; - dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); + if (state->board_info[1] == 0x0b) { + if (state->type_flags & DST_TYPE_HAS_TS204) + state->type_flags &= ~DST_TYPE_HAS_TS204; + state->type_flags |= DST_TYPE_HAS_NEWTUNE; + dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); + } else { + if (state->type_flags & DST_TYPE_HAS_NEWTUNE) + state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; + state->type_flags |= DST_TYPE_HAS_TS204; + dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); + } + } else { + if (state->board_info[0] == 0xbc) { + if (state->type_flags & DST_TYPE_HAS_TS204) + state->type_flags &= ~DST_TYPE_HAS_TS204; + state->type_flags |= DST_TYPE_HAS_NEWTUNE; + dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); + + } else if (state->board_info[0] == 0xcc) { + if (state->type_flags & DST_TYPE_HAS_NEWTUNE) + state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; + state->type_flags |= DST_TYPE_HAS_TS204; + dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); } } return 0; -force: - if (!strncmp(state->fw_name, "DCT-CI", 6)) { - state->type_flags |= DST_TYPE_HAS_TS204; - dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); - } - - return -1; } static int dst_get_device_id(struct dst_state *state) { u8 reply; - int i, j; - struct dst_types *p_dst_type = NULL; - struct tuner_types *p_tuner_list = NULL; - + int i; + struct dst_types *p_dst_type; u8 use_dst_type = 0; u32 use_type_flags = 0; static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; - state->tuner_type = 0; device_type[7] = dst_check_sum(device_type, 7); if (write_dst(state, device_type, FIXED_COMM)) @@ -1129,34 +888,8 @@ static int dst_get_device_id(struct dst_state *state) /* Card capabilities */ state->dst_hw_cap = p_dst_type->dst_feature; - dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); - strncpy(&state->fw_name[0], p_dst_type->device_id, 6); - /* Multiple tuners */ - if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { - switch (use_dst_type) { - case DST_TYPE_IS_SAT: - /* STV0299 check */ - if (dst_check_stv0299(state) < 0) { - dprintk(verbose, DST_ERROR, 1, "Unsupported"); - state->tuner_type = TUNER_TYPE_MB86A15; - } - break; - default: - break; - } - if (dst_check_mb86a15(state) < 0) - dprintk(verbose, DST_ERROR, 1, "Unsupported"); - /* Single tuner */ - } else { - state->tuner_type = p_dst_type->tuner_type; - } - for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { - if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && - p_tuner_list->tuner_type == state->tuner_type) { - dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", - p_dst_type->device_id, p_tuner_list->tuner_name); - } - } + dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id); + break; } } @@ -1167,10 +900,10 @@ static int dst_get_device_id(struct dst_state *state) use_dst_type = DST_TYPE_IS_SAT; use_type_flags = DST_TYPE_HAS_SYMDIV; } - dst_type_print(state, use_dst_type); + dst_type_print(use_dst_type); state->type_flags = use_type_flags; state->dst_type = use_dst_type; - dst_type_flags_print(state); + dst_type_flags_print(state->type_flags); return 0; } @@ -1178,15 +911,15 @@ static int dst_get_device_id(struct dst_state *state) static int dst_probe(struct dst_state *state) { mutex_init(&state->dst_mutex); - if (dst_addons & DST_TYPE_HAS_CA) { - if ((rdc_8820_reset(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); - return -1; - } + if ((rdc_8820_reset(state)) < 0) { + dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); + return -1; + } + if (dst_addons & DST_TYPE_HAS_CA) msleep(4000); - } else { + else msleep(100); - } + if ((dst_comm_init(state)) < 0) { dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); return -1; @@ -1198,6 +931,7 @@ static int dst_probe(struct dst_state *state) } if (dst_get_mac(state) < 0) { dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); + return 0; } if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { if (dst_get_tuner_info(state) < 0) @@ -1314,10 +1048,6 @@ static int dst_get_signal(struct dst_state *state) state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; state->decode_strength = state->rxbuffer[4] << 8; state->decode_snr = state->rxbuffer[3] << 8; - } else if (state->dst_type == DST_TYPE_IS_ATSC) { - state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; - state->decode_strength = state->rxbuffer[4] << 8; - state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; } state->cur_jiff = jiffies; } @@ -1348,9 +1078,8 @@ static int dst_get_tuna(struct dst_state *state) state->diseq_flags &= ~(HAS_LOCK); if (!dst_wait_dst_ready(state, NO_DELAY)) return -EIO; - if ((state->type_flags & DST_TYPE_HAS_VLF) && - !(state->dst_type == DST_TYPE_IS_ATSC)) - + if (state->type_flags & DST_TYPE_HAS_NEWTUNE) + /* how to get variable length reply ???? */ retval = read_dst(state, state->rx_tuna, 10); else retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); @@ -1358,10 +1087,7 @@ static int dst_get_tuna(struct dst_state *state) dprintk(verbose, DST_DEBUG, 1, "read not successful"); return retval; } - if ((state->type_flags & DST_TYPE_HAS_VLF) && - !(state->dst_type == DST_TYPE_IS_CABLE) && - !(state->dst_type == DST_TYPE_IS_ATSC)) { - + if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { dprintk(verbose, DST_INFO, 1, "checksum failure ? "); return -EIO; @@ -1407,10 +1133,7 @@ static int dst_write_tuna(struct dvb_frontend *fe) dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); goto error; } -// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { - if ((state->type_flags & DST_TYPE_HAS_VLF) && - (!(state->dst_type == DST_TYPE_IS_ATSC))) { - + if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); retval = write_dst(state, &state->tx_tuna[0], 10); } else { @@ -1466,12 +1189,9 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd if (state->dst_type != DST_TYPE_IS_SAT) return 0; - if (cmd->msg_len > 0 && cmd->msg_len < 5) - memcpy(&paket[3], cmd->msg, cmd->msg_len); - else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) - memcpy(&paket[2], cmd->msg, cmd->msg_len); - else + if (cmd->msg_len == 0 || cmd->msg_len > 4) return -EINVAL; + memcpy(&paket[3], cmd->msg, cmd->msg_len); paket[7] = dst_check_sum(&paket[0], 7); dst_command(state, paket, 8); return 0; @@ -1567,9 +1287,8 @@ static int dst_init(struct dvb_frontend *fe) static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; + static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; state->inversion = INVERSION_OFF; state->voltage = SEC_VOLTAGE_13; @@ -1579,13 +1298,11 @@ static int dst_init(struct dvb_frontend *fe) state->bandwidth = BANDWIDTH_7_MHZ; state->cur_jiff = jiffies; if (state->dst_type == DST_TYPE_IS_SAT) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); + memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); else if (state->dst_type == DST_TYPE_IS_TERR) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); + memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); else if (state->dst_type == DST_TYPE_IS_CABLE) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); - else if (state->dst_type == DST_TYPE_IS_ATSC) - memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); + memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); return 0; } @@ -1624,36 +1341,7 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } -static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct dst_state *state = fe->demodulator_priv; - - if (p != NULL) { - dst_set_freq(state, p->frequency); - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); - - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); - dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); - - } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); - else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); - } - dst_write_tuna(fe); - } - - return 0; -} - -static int dst_tune_frontend(struct dvb_frontend* fe, +static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* p, unsigned int mode_flags, int *delay, @@ -1690,11 +1378,6 @@ static int dst_tune_frontend(struct dvb_frontend* fe, return 0; } -static int dst_get_tuning_algo(struct dvb_frontend *fe) -{ - return dst_algo; -} - static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct dst_state *state = fe->demodulator_priv; @@ -1725,7 +1408,6 @@ static void dst_release(struct dvb_frontend *fe) static struct dvb_frontend_ops dst_dvbt_ops; static struct dvb_frontend_ops dst_dvbs_ops; static struct dvb_frontend_ops dst_dvbc_ops; -static struct dvb_frontend_ops dst_atsc_ops; struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) { @@ -1735,25 +1417,24 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad return NULL; } /* determine settings based on type */ - /* create dvb_frontend */ switch (state->dst_type) { case DST_TYPE_IS_TERR: - memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_CABLE: - memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); break; case DST_TYPE_IS_SAT: - memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); - break; - case DST_TYPE_IS_ATSC: - memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); break; default: dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); kfree(state); return NULL; } + + /* create dvb_frontend */ + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return state; /* Manu (DST is a card not a frontend) */ @@ -1774,10 +1455,8 @@ static struct dvb_frontend_ops dst_dvbt_ops = { .release = dst_release, .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, + .tune = dst_set_frontend, .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, @@ -1800,10 +1479,8 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .release = dst_release, .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, + .tune = dst_set_frontend, .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, @@ -1829,38 +1506,13 @@ static struct dvb_frontend_ops dst_dvbc_ops = { .release = dst_release, .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, - .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, - .read_status = dst_read_status, - .read_signal_strength = dst_read_signal_strength, - .read_snr = dst_read_snr, -}; - -static struct dvb_frontend_ops dst_atsc_ops = { - .info = { - .name = "DST ATSC", - .type = FE_ATSC, - .frequency_stepsize = 62500, - .frequency_min = 510000000, - .frequency_max = 858000000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .release = dst_release, - .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, + .tune = dst_set_frontend, .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, }; -MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); +MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); MODULE_AUTHOR("Jamie Honan, Manu Abraham"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/bt8xx/dst_ca.c b/trunk/drivers/media/dvb/bt8xx/dst_ca.c index fa923b9b346e..f6b49a801eba 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_ca.c +++ b/trunk/drivers/media/dvb/bt8xx/dst_ca.c @@ -68,13 +68,6 @@ static int ca_set_pid(void) return -EOPNOTSUPP; } -static void put_command_and_length(u8 *data, int command, int length) -{ - data[0] = (command >> 16) & 0xff; - data[1] = (command >> 8) & 0xff; - data[2] = command & 0xff; - data[3] = length; -} static void put_checksum(u8 *check_string, int length) { @@ -131,18 +124,15 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, u8 dst_ca_comm_err = 0; while (dst_ca_comm_err < RETRIES) { + dst_comm_init(state); dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); if (dst_ci_command(state, data, ca_string, len, read)) { // If error dst_error_recovery(state); dst_ca_comm_err++; // work required here. - } else { - break; } + break; } - if(dst_ca_comm_err == RETRIES) - return -1; - return 0; } @@ -150,7 +140,6 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, static int ca_get_app_info(struct dst_state *state) { - int length, str_length; static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; put_checksum(&command[0], command[0]); @@ -165,68 +154,6 @@ static int ca_get_app_info(struct dst_state *state) (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); - // Transform dst message to correct application_info message - length = state->messages[5]; - str_length = length - 6; - if (str_length < 0) { - str_length = 0; - dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering."); - } - - // First, the command and length fields - put_command_and_length(&state->messages[0], CA_APP_INFO, length); - - // Copy application_type, application_manufacturer and manufacturer_code - memcpy(&state->messages[4], &state->messages[7], 5); - - // Set string length and copy string - state->messages[9] = str_length; - memcpy(&state->messages[10], &state->messages[12], str_length); - - return 0; -} - -static int ca_get_ca_info(struct dst_state *state) -{ - int srcPtr, dstPtr, i, num_ids; - static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff}; - const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7; - - put_checksum(&slot_command[0], slot_command[0]); - if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; - } - dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); - - // Print raw data - dprintk(verbose, DST_CA_INFO, 0, " DST data = ["); - for (i = 0; i < state->messages[0] + 1; i++) { - dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]); - } - dprintk(verbose, DST_CA_INFO, 0, "]\n"); - - // Set the command and length of the output - num_ids = state->messages[in_num_ids_pos]; - if (num_ids >= 100) { - num_ids = 100; - dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering."); - } - put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2); - - dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = ["); - srcPtr = in_system_id_pos; - dstPtr = out_system_id_pos; - for(i = 0; i < num_ids; i++) { - dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]); - // Append to output - state->messages[dstPtr + 0] = state->messages[srcPtr + 0]; - state->messages[dstPtr + 1] = state->messages[srcPtr + 1]; - srcPtr += 2; - dstPtr += 2; - } - dprintk(verbose, DST_CA_INFO, 0, "]\n"); - return 0; } @@ -247,7 +174,7 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); - for (i = 0; i < slot_cap[0] + 1; i++) + for (i = 0; i < 8; i++) dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); dprintk(verbose, DST_CA_INFO, 0, "\n"); @@ -333,11 +260,6 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) return -EFAULT; break; - case CA_INFO: - memcpy(p_ca_message->msg, state->messages, 128); - if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) - return -EFAULT; - break; } } @@ -380,7 +302,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l rdc_reset_state(state); return -1; } - dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); + dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes."); return 0; } @@ -418,7 +340,6 @@ static int debug_string(u8 *msg, u32 length, u32 offset) return 0; } - static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) { u32 length = 0; @@ -534,16 +455,6 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, } dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); break; - case CA_INFO_ENQUIRY: - dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); - - if ((ca_get_ca_info(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); - break; } } free_mem_and_exit: @@ -562,15 +473,18 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd void __user *arg = (void __user *)ioctl_arg; int result = 0; - p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); - p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); - p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); - if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { + if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); - result = -ENOMEM; - goto free_mem_and_exit; + return -ENOMEM; + } + if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { + dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); + return -ENOMEM; + } + if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { + dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); + return -ENOMEM; } - /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ switch (cmd) { case CA_SEND_MSG: @@ -668,7 +582,7 @@ static int dst_ca_release(struct inode *inode, struct file *file) static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) { - ssize_t bytes_read = 0; + int bytes_read = 0; dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); diff --git a/trunk/drivers/media/dvb/bt8xx/dst_common.h b/trunk/drivers/media/dvb/bt8xx/dst_common.h index 0677b047b3a7..51d4e043716c 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_common.h +++ b/trunk/drivers/media/dvb/bt8xx/dst_common.h @@ -42,7 +42,7 @@ #define DST_TYPE_IS_CABLE 2 #define DST_TYPE_IS_ATSC 3 -#define DST_TYPE_HAS_TS188 1 +#define DST_TYPE_HAS_NEWTUNE 1 #define DST_TYPE_HAS_TS204 2 #define DST_TYPE_HAS_SYMDIV 4 #define DST_TYPE_HAS_FW_1 8 @@ -52,9 +52,6 @@ #define DST_TYPE_HAS_OBS_REGS 128 #define DST_TYPE_HAS_INC_COUNT 256 #define DST_TYPE_HAS_MULTI_FE 512 -#define DST_TYPE_HAS_NEWTUNE_2 1024 -#define DST_TYPE_HAS_DBOARD 2048 -#define DST_TYPE_HAS_VLF 4096 /* Card capability list */ @@ -67,20 +64,6 @@ #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ #define DST_TYPE_HAS_SESSION 128 -#define TUNER_TYPE_MULTI 1 -#define TUNER_TYPE_UNKNOWN 2 -/* DVB-S */ -#define TUNER_TYPE_L64724 4 -#define TUNER_TYPE_STV0299 8 -#define TUNER_TYPE_MB86A15 16 - -/* DVB-T */ -#define TUNER_TYPE_TDA10046 32 - -/* ATSC */ -#define TUNER_TYPE_NXT200x 64 - - #define RDC_8820_PIO_0_DISABLE 0 #define RDC_8820_PIO_0_ENABLE 1 #define RDC_8820_INT 2 @@ -101,6 +84,8 @@ struct dst_state { struct bt878* bt; + struct dvb_frontend_ops ops; + /* configuration settings */ const struct dst_config* config; @@ -136,17 +121,8 @@ struct dst_state { u8 card_info[8]; u8 vendor[8]; u8 board_info[8]; - u32 tuner_type; - char *tuner_name; - struct mutex dst_mutex; - u8 fw_name[8]; -}; -struct tuner_types { - u32 tuner_type; - char *tuner_name; - char *board_name; - char *fw_name; + struct mutex dst_mutex; }; struct dst_types { @@ -155,7 +131,6 @@ struct dst_types { u8 dst_type; u32 type_flags; u32 dst_feature; - u32 tuner_type; }; struct dst_config diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index b715b972d2fc..ccc7b2eb4a2d 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -147,15 +147,12 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) return 0; } -static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { u32 div; unsigned char bs = 0; unsigned char cp = 0; - if (buf_len < 5) - return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; if (params->frequency < 542000000) @@ -172,25 +169,22 @@ static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_f else bs = 0x08; - pllbuf[0] = 0x60; + pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = cp; pllbuf[4] = bs; - return 5; + return 0; } static struct mt352_config thomson_dtt7579_config = { .demod_address = 0x0f, .demod_init = thomson_dtt7579_demod_init, + .pll_set = thomson_dtt7579_pll_set, }; -static struct zl10353_config thomson_dtt7579_zl10353_config = { - .demod_address = 0x0f, -}; - -static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { u32 freq = params->frequency; @@ -243,7 +237,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend return 0; } -static int pinnsat_tuner_init(struct dvb_frontend* fe) +static int pinnsat_pll_init(struct dvb_frontend* fe) { struct dvb_bt8xx_card *card = fe->dvb->priv; @@ -253,7 +247,7 @@ static int pinnsat_tuner_init(struct dvb_frontend* fe) return 0; } -static int pinnsat_tuner_sleep(struct dvb_frontend* fe) +static int pinnsat_pll_sleep(struct dvb_frontend* fe) { struct dvb_bt8xx_card *card = fe->dvb->priv; @@ -264,9 +258,12 @@ static int pinnsat_tuner_sleep(struct dvb_frontend* fe) static struct cx24110_config pctvsat_config = { .demod_address = 0x55, + .pll_init = pinnsat_pll_init, + .pll_set = cx24108_pll_set, + .pll_sleep = pinnsat_pll_sleep, }; -static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 cfg, cpump, band_select; @@ -300,8 +297,6 @@ static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct data[2] = ((div >> 10) & 0x60) | cfg; data[3] = (cpump << 6) | band_select; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(card->i2c_adapter, &msg, 1); return (div * 166666 - 36000000); } @@ -315,6 +310,7 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s static struct sp887x_config microtune_mt7202dtf_config = { .demod_address = 0x70, + .pll_set = microtune_mt7202dtf_pll_set, .request_firmware = microtune_mt7202dtf_request_firmware, }; @@ -341,14 +337,12 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) return 0; } -static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { u32 div; unsigned char bs = 0; unsigned char cp = 0; - if (buf_len < 5) return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; if (params->frequency < 150000000) @@ -389,18 +383,19 @@ static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, else bs = 0x08; - pllbuf[0] = 0x61; + pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = cp; pllbuf[4] = bs; - return 5; + return 0; } static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { .demod_address = 0x0f, .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, + .pll_set = advbt771_samsung_tdtc9251dh0_pll_set, }; static struct dst_config dst_config = { @@ -460,7 +455,7 @@ static struct or51211_config or51211_config = { .sleep = or51211_sleep, }; -static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 buf[4]; @@ -483,8 +478,6 @@ static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dv else return -EINVAL; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(card->i2c_adapter, &msg, 1); return 0; } @@ -492,6 +485,7 @@ static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dv static struct nxt6000_config vp3021_alps_tded4_config = { .demod_address = 0x0a, .clock_inversion = 1, + .pll_set = vp3021_alps_tded4_pll_set, }; static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) @@ -512,17 +506,14 @@ static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) return 0; } -static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { u32 div; struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; - if (buf_len < 5) - return -EINVAL; - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - pllbuf[0] = 0x61; + pllbuf[0] = 0xc2; pllbuf[1] = (div >> 8) & 0x7F; pllbuf[2] = div & 0xFF; pllbuf[3] = 0x85; @@ -539,7 +530,7 @@ static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb if (op->bandwidth == 8) pllbuf[4] |= 0x04; - return 5; + return 0; } static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) @@ -566,18 +557,43 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) static struct mt352_config digitv_alps_tded4_config = { .demod_address = 0x0a, .demod_init = digitv_alps_tded4_demod_init, + .pll_set = digitv_alps_tded4_pll_set, }; -static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; - return lg_h06xf_pll_set(fe, card->i2c_adapter, params); + u8 buf[4]; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; + int err; + + dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0); + dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", + __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); + if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) { + printk(KERN_WARNING "dvb-bt8xx: %s error " + "(addr %02x <- %02x, err = %i)\n", + __FUNCTION__, buf[0], buf[1], err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + /* Set the Auxiliary Byte. */ + buf[2] &= ~0x20; + buf[2] |= 0x18; + buf[3] = 0x50; + i2c_transfer(card->i2c_adapter, &msg, 1); + + return 0; } static struct lgdt330x_config tdvs_tua6034_config = { .demod_address = 0x0e, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ + .pll_set = tdvs_tua6034_pll_set, }; static void lgdt330x_reset(struct dvb_bt8xx_card *bt) @@ -601,25 +617,17 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) switch(type) { case BTTV_BOARD_DVICO_DVBT_LITE: card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); - - if (card->fe == NULL) - card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, - card->i2c_adapter); - if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; - card->fe->ops.info.frequency_min = 174000000; - card->fe->ops.info.frequency_max = 862000000; + card->fe->ops->info.frequency_min = 174000000; + card->fe->ops->info.frequency_max = 862000000; } break; case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: lgdt330x_reset(card); card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); - if (card->fe != NULL) { - card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params; + if (card->fe != NULL) dprintk ("dvb_bt8xx: lgdt330x detected\n"); - } break; case BTTV_BOARD_NEBULA_DIGITV: @@ -632,7 +640,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) digitv_alps_tded4_reset(card); card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); if (card->fe != NULL) { - card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); break; } @@ -641,25 +648,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) digitv_alps_tded4_reset(card); card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); - if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; + if (card->fe != NULL) dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); - } break; case BTTV_BOARD_AVDVBT_761: card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); - if (card->fe) { - card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; - } break; case BTTV_BOARD_AVDVBT_771: card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; - card->fe->ops.info.frequency_min = 174000000; - card->fe->ops.info.frequency_max = 862000000; + card->fe->ops->info.frequency_min = 174000000; + card->fe->ops->info.frequency_max = 862000000; } break; @@ -686,11 +687,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) case BTTV_BOARD_PINNACLESAT: card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); - if (card->fe) { - card->fe->ops.tuner_ops.init = pinnsat_tuner_init; - card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; - card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; - } break; case BTTV_BOARD_PC_HDTV: @@ -707,8 +703,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) else if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { printk("dvb-bt8xx: Frontend registration failed!\n"); - if (card->fe->ops.release) - card->fe->ops.release(card->fe); + if (card->fe->ops->release) + card->fe->ops->release(card->fe); card->fe = NULL; } } @@ -717,7 +713,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) { int result; - if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) { + if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); return result; } diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 4745a9017a19..00dd9fa54c82 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.h @@ -37,8 +37,6 @@ #include "cx24110.h" #include "or51211.h" #include "lgdt330x.h" -#include "lg_h06xf.h" -#include "zl10353.h" struct dvb_bt8xx_card { struct mutex lock; diff --git a/trunk/drivers/media/dvb/cinergyT2/Kconfig b/trunk/drivers/media/dvb/cinergyT2/Kconfig index b5cdd57ec6f5..6018fcdba1e6 100644 --- a/trunk/drivers/media/dvb/cinergyT2/Kconfig +++ b/trunk/drivers/media/dvb/cinergyT2/Kconfig @@ -64,7 +64,7 @@ config DVB_CINERGYT2_QUERY_INTERVAL config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE bool "Register the onboard IR Remote Control Receiver as Input Device" depends on DVB_CINERGYT2_TUNING - default y + default "yes" help Enable this option if you want to use the onboard Infrared Remote Control Receiver as Linux-Input device. diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 1b8953600425..9325d039ea65 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -544,19 +544,15 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - unsigned int mask = 0; if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; poll_wait(file, &cinergyt2->poll_wq, wait); - if (cinergyt2->pending_fe_events != 0) - mask |= (POLLIN | POLLRDNORM | POLLPRI); - mutex_unlock(&cinergyt2->sem); - return mask; + return (POLLIN | POLLRDNORM | POLLPRI); } @@ -906,7 +902,7 @@ static int cinergyt2_probe (struct usb_interface *intf, return -ENOMEM; } - if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) { + if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { kfree(cinergyt2); return err; } diff --git a/trunk/drivers/media/dvb/dvb-core/Makefile b/trunk/drivers/media/dvb/dvb-core/Makefile index 11054657fdb5..7adb50c1e8eb 100644 --- a/trunk/drivers/media/dvb/dvb-core/Makefile +++ b/trunk/drivers/media/dvb/dvb-core/Makefile @@ -2,8 +2,8 @@ # Makefile for the kernel DVB device drivers. # -dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_frontend.o \ - dvb_net.o dvb_ringbuffer.o dvb_math.o +dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ + dvb_ca_en50221.o dvb_frontend.o \ + dvb_net.o dvb_ringbuffer.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/trunk/drivers/media/dvb/dvb-core/dmxdev.c b/trunk/drivers/media/dvb/dvb-core/dmxdev.c index 988499dfddf8..04578df3f249 100644 --- a/trunk/drivers/media/dvb/dvb-core/dmxdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dmxdev.c @@ -872,6 +872,9 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, mutex_unlock(&dmxdevfilter->mutex); break; + case DMX_GET_EVENT: + break; + case DMX_GET_PES_PIDS: if (!dmxdev->demux->get_pes_pids) { ret = -EINVAL; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 2a03bf53cb29..00347a750681 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1060,18 +1060,8 @@ static int dvb_ca_en50221_thread(void *data) break; case DVB_CA_SLOTSTATE_VALIDATE: - if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - int status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - + if (dvb_ca_en50221_parse_attributes(ca, slot) + != 0) { printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; @@ -1118,17 +1108,6 @@ static int dvb_ca_en50221_thread(void *data) case DVB_CA_SLOTSTATE_LINKINIT: if (dvb_ca_en50221_link_init(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - int status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; dvb_ca_en50221_thread_update_delay(ca); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c index fcff5eab21a3..83ec5e06c482 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_demux.c @@ -473,7 +473,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) goto bailout; } memcpy(&demux->tsbuf[i], buf, j); - if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { + if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) { memcpy(tmppack, demux->tsbuf, 188); if (tmppack[0] == 0xB8) tmppack[0] = 0x47; @@ -484,7 +484,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } while (p < count) { - if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { + if ((buf[p] == 0x47) | (buf[p] == 0xB8)) { if (count - p >= 204) { memcpy(tmppack, &buf[p], 188); if (tmppack[0] == 0xB8) diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 5e8bb41a088b..a051790161b0 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AU module_param(dvb_override_tune_delay, int, 0644); MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); module_param(dvb_powerdown_on_sleep, int, 0644); -MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); +MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); #define dprintk if (dvb_frontend_debug) printk @@ -72,8 +72,6 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volt #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) - -#define FE_ALGO_HW 1 /* * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. @@ -153,8 +151,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) sizeof (struct dvb_frontend_parameters)); if (status & FE_HAS_LOCK) - if (fe->ops.get_frontend) - fe->ops.get_frontend(fe, &e->parameters); + if (fe->ops->get_frontend) + fe->ops->get_frontend(fe, &e->parameters); events->eventw = wp; @@ -213,15 +211,10 @@ static void dvb_frontend_init(struct dvb_frontend *fe) { dprintk ("DVB: initialising frontend %i (%s)...\n", fe->dvb->num, - fe->ops.info.name); - - if (fe->ops.init) - fe->ops.init(fe); - if (fe->ops.tuner_ops.init) { - fe->ops.tuner_ops.init(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } + fe->ops->info.name); + + if (fe->ops->init) + fe->ops->init(fe); } void dvb_frontend_reinitialise(struct dvb_frontend *fe) @@ -266,7 +259,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra u32 original_frequency = fepriv->parameters.frequency; /* are we using autoinversion? */ - autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && + autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && (fepriv->parameters.inversion == INVERSION_AUTO)); /* setup parameters correctly */ @@ -336,8 +329,8 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra fepriv->parameters.frequency += fepriv->lnb_drift; if (autoinversion) fepriv->parameters.inversion = fepriv->inversion; - if (fe->ops.set_frontend) - fe->ops.set_frontend(fe, &fepriv->parameters); + if (fe->ops->set_frontend) + fe->ops->set_frontend(fe, &fepriv->parameters); fepriv->parameters.frequency = original_frequency; fepriv->parameters.inversion = original_inversion; @@ -361,8 +354,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) /* in SCAN mode, we just set the frontend when asked and leave it alone */ if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { if (fepriv->state & FESTATE_RETUNE) { - if (fe->ops.set_frontend) - fe->ops.set_frontend(fe, &fepriv->parameters); + if (fe->ops->set_frontend) + fe->ops->set_frontend(fe, &fepriv->parameters); fepriv->state = FESTATE_TUNED; } fepriv->delay = 3*HZ; @@ -374,8 +367,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) if (fepriv->state & FESTATE_RETUNE) { s = 0; } else { - if (fe->ops.read_status) - fe->ops.read_status(fe, &s); + if (fe->ops->read_status) + fe->ops->read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); fepriv->status = s; @@ -388,7 +381,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) fepriv->state = FESTATE_TUNED; /* if we're tuned, then we have determined the correct inversion */ - if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && + if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && (fepriv->parameters.inversion == INVERSION_AUTO)) { fepriv->parameters.inversion = fepriv->inversion; } @@ -412,7 +405,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) /* don't actually do anything if we're in the LOSTLOCK state, * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ if ((fepriv->state & FESTATE_LOSTLOCK) && - (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { + (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); return; } @@ -547,45 +540,39 @@ static int dvb_frontend_thread(void *data) if (fepriv->reinitialise) { dvb_frontend_init(fe); if (fepriv->tone != -1) { - fe->ops.set_tone(fe, fepriv->tone); + fe->ops->set_tone(fe, fepriv->tone); } if (fepriv->voltage != -1) { - fe->ops.set_voltage(fe, fepriv->voltage); + fe->ops->set_voltage(fe, fepriv->voltage); } fepriv->reinitialise = 0; } /* do an iteration of the tuning loop */ - if (fe->ops.get_frontend_algo) { - if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) { - /* have we been asked to retune? */ - params = NULL; - if (fepriv->state & FESTATE_RETUNE) { - params = &fepriv->parameters; - fepriv->state = FESTATE_TUNED; - } + if (fe->ops->tune) { + /* have we been asked to retune? */ + params = NULL; + if (fepriv->state & FESTATE_RETUNE) { + params = &fepriv->parameters; + fepriv->state = FESTATE_TUNED; + } - fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); - if (s != fepriv->status) { - dvb_frontend_add_event(fe, s); - fepriv->status = s; - } + fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); + if (s != fepriv->status) { + dvb_frontend_add_event(fe, s); + fepriv->status = s; } - } else + } else { dvb_frontend_swzigzag(fe); + } } if (dvb_shutdown_timeout) { if (dvb_powerdown_on_sleep) - if (fe->ops.set_voltage) - fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); - if (fe->ops.tuner_ops.sleep) { - fe->ops.tuner_ops.sleep(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.sleep) - fe->ops.sleep(fe); + if (fe->ops->set_voltage) + fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF); + if (fe->ops->sleep) + fe->ops->sleep(fe); } fepriv->thread_pid = 0; @@ -737,7 +724,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, switch (cmd) { case FE_GET_INFO: { struct dvb_frontend_info* info = parg; - memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); + memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't * do it, it is done for it. */ @@ -757,58 +744,58 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; } - if (fe->ops.read_status) - err = fe->ops.read_status(fe, status); + if (fe->ops->read_status) + err = fe->ops->read_status(fe, status); break; } case FE_READ_BER: - if (fe->ops.read_ber) - err = fe->ops.read_ber(fe, (__u32*) parg); + if (fe->ops->read_ber) + err = fe->ops->read_ber(fe, (__u32*) parg); break; case FE_READ_SIGNAL_STRENGTH: - if (fe->ops.read_signal_strength) - err = fe->ops.read_signal_strength(fe, (__u16*) parg); + if (fe->ops->read_signal_strength) + err = fe->ops->read_signal_strength(fe, (__u16*) parg); break; case FE_READ_SNR: - if (fe->ops.read_snr) - err = fe->ops.read_snr(fe, (__u16*) parg); + if (fe->ops->read_snr) + err = fe->ops->read_snr(fe, (__u16*) parg); break; case FE_READ_UNCORRECTED_BLOCKS: - if (fe->ops.read_ucblocks) - err = fe->ops.read_ucblocks(fe, (__u32*) parg); + if (fe->ops->read_ucblocks) + err = fe->ops->read_ucblocks(fe, (__u32*) parg); break; case FE_DISEQC_RESET_OVERLOAD: - if (fe->ops.diseqc_reset_overload) { - err = fe->ops.diseqc_reset_overload(fe); + if (fe->ops->diseqc_reset_overload) { + err = fe->ops->diseqc_reset_overload(fe); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } break; case FE_DISEQC_SEND_MASTER_CMD: - if (fe->ops.diseqc_send_master_cmd) { - err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); + if (fe->ops->diseqc_send_master_cmd) { + err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } break; case FE_DISEQC_SEND_BURST: - if (fe->ops.diseqc_send_burst) { - err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); + if (fe->ops->diseqc_send_burst) { + err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } break; case FE_SET_TONE: - if (fe->ops.set_tone) { - err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg); + if (fe->ops->set_tone) { + err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); fepriv->tone = (fe_sec_tone_mode_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; @@ -816,8 +803,8 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; case FE_SET_VOLTAGE: - if (fe->ops.set_voltage) { - err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg); + if (fe->ops->set_voltage) { + err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); fepriv->voltage = (fe_sec_voltage_t) parg; fepriv->state = FESTATE_DISEQC; fepriv->status = 0; @@ -825,11 +812,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; case FE_DISHNETWORK_SEND_LEGACY_CMD: - if (fe->ops.dishnetwork_send_legacy_command) { - err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg); + if (fe->ops->dishnetwork_send_legacy_command) { + err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; - } else if (fe->ops.set_voltage) { + } else if (fe->ops->set_voltage) { /* * NOTE: This is a fallback condition. Some frontends * (stv0299 for instance) take longer than 8msec to @@ -859,7 +846,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, /* before sending a command, initialize by sending * a 32ms 18V to the switch */ - fe->ops.set_voltage(fe, SEC_VOLTAGE_18); + fe->ops->set_voltage(fe, SEC_VOLTAGE_18); dvb_frontend_sleep_until(&nexttime, 32000); for (i = 0; i < 9; i++) { @@ -867,7 +854,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, do_gettimeofday(&tv[i + 1]); if ((cmd & 0x01) != last) { /* set voltage to (last ? 13V : 18V) */ - fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); + fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); last = (last) ? 0 : 1; } cmd = cmd >> 1; @@ -887,13 +874,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; case FE_DISEQC_RECV_SLAVE_REPLY: - if (fe->ops.diseqc_recv_slave_reply) - err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); + if (fe->ops->diseqc_recv_slave_reply) + err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); break; case FE_ENABLE_HIGH_LNB_VOLTAGE: - if (fe->ops.enable_high_lnb_voltage) - err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); + if (fe->ops->enable_high_lnb_voltage) + err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); break; case FE_SET_FRONTEND: { @@ -911,7 +898,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, fepriv->parameters.inversion = INVERSION_AUTO; fetunesettings.parameters.inversion = INVERSION_AUTO; } - if (fe->ops.info.type == FE_OFDM) { + if (fe->ops->info.type == FE_OFDM) { /* without hierachical coding code_rate_LP is irrelevant, * so we tolerate the otherwise invalid FEC_NONE setting */ if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && @@ -920,13 +907,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, } /* get frontend-specific tuning settings */ - if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { + if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) { fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; fepriv->max_drift = fetunesettings.max_drift; fepriv->step_size = fetunesettings.step_size; } else { /* default values */ - switch(fe->ops.info.type) { + switch(fe->ops->info.type) { case FE_QPSK: fepriv->min_delay = HZ/20; fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; @@ -941,13 +928,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_OFDM: fepriv->min_delay = HZ/20; - fepriv->step_size = fe->ops.info.frequency_stepsize * 2; - fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; + fepriv->step_size = fe->ops->info.frequency_stepsize * 2; + fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1; break; case FE_ATSC: - fepriv->min_delay = HZ/20; - fepriv->step_size = 0; - fepriv->max_drift = 0; + printk("dvb-core: FE_ATSC not handled yet.\n"); break; } } @@ -967,9 +952,9 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; case FE_GET_FRONTEND: - if (fe->ops.get_frontend) { + if (fe->ops->get_frontend) { memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); - err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); + err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); } break; @@ -1082,7 +1067,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, printk ("DVB: registering frontend %i (%s)...\n", fe->dvb->num, - fe->ops.info.name); + fe->ops->info.name); dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND); @@ -1100,15 +1085,10 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) mutex_lock(&frontend_mutex); dvb_unregister_device (fepriv->dvbdev); dvb_frontend_stop (fe); - if (fe->ops.tuner_ops.release) { - fe->ops.tuner_ops.release(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.release) - fe->ops.release(fe); + if (fe->ops->release) + fe->ops->release(fe); else - printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name); + printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); /* fe is invalid now */ kfree(fepriv); mutex_unlock(&frontend_mutex); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h index 2887e2b862a4..5926a3b745c9 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -49,44 +49,6 @@ struct dvb_frontend_tune_settings { struct dvb_frontend; -struct dvb_tuner_info { - char name[128]; - - u32 frequency_min; - u32 frequency_max; - u32 frequency_step; - - u32 bandwidth_min; - u32 bandwidth_max; - u32 bandwidth_step; -}; - -struct dvb_tuner_ops { - - struct dvb_tuner_info info; - - int (*release)(struct dvb_frontend *fe); - int (*init)(struct dvb_frontend *fe); - int (*sleep)(struct dvb_frontend *fe); - - /** This is for simple PLLs - set all parameters in one go. */ - int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); - - /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ - int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); - - int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); - int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); - -#define TUNER_STATUS_LOCKED 1 - int (*get_status)(struct dvb_frontend *fe, u32 *status); - - /** These are provided seperately from set_params in order to facilitate silicon - * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ - int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); - int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); -}; - struct dvb_frontend_ops { struct dvb_frontend_info info; @@ -102,8 +64,6 @@ struct dvb_frontend_ops { unsigned int mode_flags, int *delay, fe_status_t *status); - /* get frontend tuning algorithm from the module */ - int (*get_frontend_algo)(struct dvb_frontend *fe); /* these two are only used for the swzigzag code */ int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); @@ -126,8 +86,6 @@ struct dvb_frontend_ops { int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); - - struct dvb_tuner_ops tuner_ops; }; #define MAX_EVENT 8 @@ -142,10 +100,9 @@ struct dvb_fe_events { }; struct dvb_frontend { - struct dvb_frontend_ops ops; + struct dvb_frontend_ops* ops; struct dvb_adapter *dvb; void* demodulator_priv; - void* tuner_priv; void* frontend_priv; void* misc_priv; }; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_math.c b/trunk/drivers/media/dvb/dvb-core/dvb_math.c deleted file mode 100644 index beb7c93aa6cb..000000000000 --- a/trunk/drivers/media/dvb/dvb-core/dvb_math.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * dvb-math provides some complex fixed-point math - * operations shared between the dvb related stuff - * - * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include "dvb_math.h" - -static const unsigned short logtable[256] = { - 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7, - 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508, - 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6, - 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37, - 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f, - 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41, - 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1, - 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142, - 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68, - 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355, - 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c, - 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490, - 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3, - 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507, - 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe, - 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca, - 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c, - 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7, - 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c, - 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c, - 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a, - 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065, - 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730, - 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc, - 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469, - 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9, - 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c, - 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765, - 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83, - 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387, - 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973, - 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 -}; - -unsigned int intlog2(u32 value) -{ - /** - * returns: log2(value) * 2^24 - * wrong result if value = 0 (log2(0) is undefined) - */ - unsigned int msb; - unsigned int logentry; - unsigned int significand; - unsigned int interpolation; - - if (unlikely(value == 0)) { - WARN_ON(1); - return 0; - } - - /* first detect the msb (count begins at 0) */ - msb = fls(value) - 1; - - /** - * now we use a logtable after the following method: - * - * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24 - * where x = msb and therefore 1 <= y < 2 - * first y is determined by shifting the value left - * so that msb is bit 31 - * 0x00231f56 -> 0x8C7D5800 - * the result is y * 2^31 -> "significand" - * then the highest 9 bits are used for a table lookup - * the highest bit is discarded because it's always set - * the highest nine bits in our example are 100011000 - * so we would use the entry 0x18 - */ - significand = value << (31 - msb); - logentry = (significand >> 23) & 0xff; - - /** - * last step we do is interpolation because of the - * limitations of the log table the error is that part of - * the significand which isn't used for lookup then we - * compute the ratio between the error and the next table entry - * and interpolate it between the log table entry used and the - * next one the biggest error possible is 0x7fffff - * (in our example it's 0x7D5800) - * needed value for next table entry is 0x800000 - * so the interpolation is - * (error / 0x800000) * (logtable_next - logtable_current) - * in the implementation the division is moved to the end for - * better accuracy there is also an overflow correction if - * logtable_next is 256 - */ - interpolation = ((significand & 0x7fffff) * - ((logtable[(logentry + 1) & 0xff] - - logtable[logentry]) & 0xffff)) >> 15; - - /* now we return the result */ - return ((msb << 24) + (logtable[logentry] << 8) + interpolation); -} -EXPORT_SYMBOL(intlog2); - -unsigned int intlog10(u32 value) -{ - /** - * returns: log10(value) * 2^24 - * wrong result if value = 0 (log10(0) is undefined) - */ - u64 log; - - if (unlikely(value == 0)) { - WARN_ON(1); - return 0; - } - - log = intlog2(value); - - /** - * we use the following method: - * log10(x) = log2(x) * log10(2) - */ - - return (log * 646456993) >> 31; -} -EXPORT_SYMBOL(intlog10); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_math.h b/trunk/drivers/media/dvb/dvb-core/dvb_math.h deleted file mode 100644 index aecc867e9404..000000000000 --- a/trunk/drivers/media/dvb/dvb-core/dvb_math.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * dvb-math provides some complex fixed-point math - * operations shared between the dvb related stuff - * - * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __DVB_MATH_H -#define __DVB_MATH_H - -#include - -/** - * computes log2 of a value; the result is shifted left by 24 bits - * - * to use rational values you can use the following method: - * intlog2(value) = intlog2(value * 2^x) - x * 2^24 - * - * example: intlog2(8) will give 3 << 24 = 3 * 2^24 - * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 - * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 - * - * @param value The value (must be != 0) - * @return log2(value) * 2^24 - */ -extern unsigned int intlog2(u32 value); - -/** - * computes log10 of a value; the result is shifted left by 24 bits - * - * to use rational values you can use the following method: - * intlog10(value) = intlog10(value * 10^x) - x * 2^24 - * - * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 - * due to the implementation intlog10(1000) might be not exactly 3 * 2^24 - * - * look at intlog2 for similar examples - * - * @param value The value (must be != 0) - * @return log10(value) * 2^24 - */ -extern unsigned int intlog10(u32 value); - -#endif diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_net.c b/trunk/drivers/media/dvb/dvb-core/dvb_net.c index 8859ab74f0fe..9fd87521a163 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_net.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_net.c @@ -12,7 +12,7 @@ * Hilmar Linder * and Wolfram Stering * - * ULE Decaps according to RFC 4326. + * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -42,9 +42,6 @@ * Bugfixes and robustness improvements. * Filtering on dest MAC addresses, if present (D-Bit = 0) * ULE_DEBUG compile-time option. - * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by - * Christian Praehauser , - * Paris Lodron University of Salzburg. */ /* @@ -52,6 +49,9 @@ * * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. * + * TS_FEED callback is called once for every single TS cell although it is + * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()). + * */ #include @@ -89,9 +89,6 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) #ifdef ULE_DEBUG -#define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" -#define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5] - #define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) static void hexdump( const unsigned char *buf, unsigned short len ) @@ -217,8 +214,6 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, #define ULE_TEST 0 #define ULE_BRIDGED 1 -#define ULE_OPTEXTHDR_PADDING 0 - static int ule_test_sndu( struct dvb_net_priv *p ) { return -1; @@ -226,28 +221,14 @@ static int ule_test_sndu( struct dvb_net_priv *p ) static int ule_bridged_sndu( struct dvb_net_priv *p ) { - struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr; - if(ntohs(hdr->h_proto) < 1536) { - int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data); - /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */ - if(framelen != ntohs(hdr->h_proto)) { - return -1; - } - } - /* Note: - * From RFC4326: - * "A bridged SNDU is a Mandatory Extension Header of Type 1. - * It must be the final (or only) extension header specified in the header chain of a SNDU." - * The 'ule_bridged' flag will cause the extension header processing loop to terminate. + /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt. + * This has to be the last extension header, otherwise it won't work. + * Blame the authors! */ p->ule_bridged = 1; return 0; } -static int ule_exthdr_padding(struct dvb_net_priv *p) -{ - return 0; -} /** Handle ULE extension headers. * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. @@ -261,8 +242,7 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; /* Table of optional extension header handlers. The header type is the index. */ - static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = - { [0] = ule_exthdr_padding, [1] = NULL, }; + static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, }; int ext_len = 0; unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; @@ -273,31 +253,25 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) /* Mandatory extension header */ if (ule_mandatory_ext_handlers[htype]) { ext_len = ule_mandatory_ext_handlers[htype]( p ); - if(ext_len >= 0) { - p->ule_next_hdr += ext_len; - if (!p->ule_bridged) { - p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr); - p->ule_next_hdr += 2; - } else { - p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); - /* This assures the extension handling loop will terminate. */ - } + p->ule_next_hdr += ext_len; + if (! p->ule_bridged) { + p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); + p->ule_next_hdr += 2; + } else { + p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) ); + /* This assures the extension handling loop will terminate. */ } - // else: extension handler failed or SNDU should be discarded } else ext_len = -1; /* SNDU has to be discarded. */ } else { /* Optional extension header. Calculate the length. */ - ext_len = hlen << 1; + ext_len = hlen << 2; /* Process the optional extension header according to its type. */ if (ule_optional_ext_handlers[htype]) (void)ule_optional_ext_handlers[htype]( p ); p->ule_next_hdr += ext_len; - p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) ); - /* - * note: the length of the next header type is included in the - * length of THIS optional extension header - */ + p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); + p->ule_next_hdr += 2; } return ext_len; @@ -310,14 +284,8 @@ static int handle_ule_extensions( struct dvb_net_priv *p ) p->ule_next_hdr = p->ule_skb->data; do { l = handle_one_ule_extension( p ); - if (l < 0) - return l; /* Stop extension header processing and discard SNDU. */ + if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */ total_ext_len += l; -#ifdef ULE_DEBUG - dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, " - "l=%i, total_ext_len=%i\n", p->ule_next_hdr, - (int) p->ule_sndu_type, l, total_ext_len); -#endif } while (p->ule_sndu_type < 1536); @@ -387,8 +355,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_skb) { dev_kfree_skb( priv->ule_skb ); /* Prepare for next SNDU. */ - priv->stats.rx_errors++; - priv->stats.rx_frame_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; } reset_ule(priv); priv->need_pusi = 1; @@ -428,25 +396,27 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } } + /* Check continuity counter. */ if (new_ts) { - /* Check continuity counter. */ if ((ts[3] & 0x0F) == priv->tscc) priv->tscc = (priv->tscc + 1) & 0x0F; else { /* TS discontinuity handling: */ printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " - "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); + "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { dev_kfree_skb( priv->ule_skb ); /* Prepare for next SNDU. */ // reset_ule(priv); moved to below. - priv->stats.rx_errors++; - priv->stats.rx_frame_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; } reset_ule(priv); /* skip to next PUSI. */ priv->need_pusi = 1; + ts += TS_SZ; + priv->ts_count++; continue; } /* If we still have an incomplete payload, but PUSI is @@ -455,7 +425,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * cells (continuity counter wrap). */ if (ts[1] & TS_PUSI) { if (! priv->need_pusi) { - if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { + if (*from_where > 181) { /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ printk(KERN_WARNING "%lu: Invalid pointer " "field: %u.\n", priv->ts_count, *from_where); @@ -468,6 +438,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } reset_ule(priv); priv->need_pusi = 1; + ts += TS_SZ; + priv->ts_count++; continue; } /* Skip pointer field (we're processing a @@ -480,8 +452,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_sndu_remain > 183) { /* Current SNDU lacks more data than there could be available in the * current TS cell. */ - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++; printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); @@ -520,11 +492,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) } else priv->ule_dbit = 0; - if (priv->ule_sndu_len < 5) { + if (priv->ule_sndu_len > 32763) { printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; priv->ule_sndu_len = 0; priv->need_pusi = 1; new_ts = 1; @@ -638,103 +608,58 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) ule_dump = 1; #endif - priv->stats.rx_errors++; - priv->stats.rx_crc_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++; dev_kfree_skb(priv->ule_skb); } else { /* CRC32 verified OK. */ - u8 dest_addr[ETH_ALEN]; - static const u8 bc_addr[ETH_ALEN] = - { [ 0 ... ETH_ALEN-1] = 0xff }; - - /* CRC32 was OK. Remove it from skb. */ - priv->ule_skb->tail -= 4; - priv->ule_skb->len -= 4; - - if (!priv->ule_dbit) { - /* - * The destination MAC address is the - * next data in the skb. It comes - * before any extension headers. - * - * Check if the payload of this SNDU - * should be passed up the stack. - */ - register int drop = 0; - if (priv->rx_mode != RX_MODE_PROMISC) { - if (priv->ule_skb->data[0] & 0x01) { - /* multicast or broadcast */ - if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) { - /* multicast */ - if (priv->rx_mode == RX_MODE_MULTI) { - int i; - for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++) - ; - if (i == priv->multi_num) - drop = 1; - } else if (priv->rx_mode != RX_MODE_ALL_MULTI) - drop = 1; /* no broadcast; */ - /* else: all multicast mode: accept all multicast packets */ - } - /* else: broadcast */ - } - else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN)) - drop = 1; - /* else: destination address matches the MAC address of our receiver device */ - } - /* else: promiscious mode; pass everything up the stack */ - - if (drop) { -#ifdef ULE_DEBUG - dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n", - MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr)); -#endif - dev_kfree_skb(priv->ule_skb); - goto sndu_done; - } - else - { - memcpy(dest_addr, priv->ule_skb->data, ETH_ALEN); - skb_pull(priv->ule_skb, ETH_ALEN); - } - } - /* Handle ULE Extension Headers. */ if (priv->ule_sndu_type < 1536) { /* There is an extension header. Handle it accordingly. */ - int l = handle_ule_extensions(priv); + int l = handle_ule_extensions( priv ); if (l < 0) { /* Mandatory extension header unknown or TEST SNDU. Drop it. */ // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); - dev_kfree_skb(priv->ule_skb); + dev_kfree_skb( priv->ule_skb ); goto sndu_done; } - skb_pull(priv->ule_skb, l); + skb_pull( priv->ule_skb, l ); } - /* - * Construct/assure correct ethernet header. - * Note: in bridged mode (priv->ule_bridged != - * 0) we already have the (original) ethernet - * header at the start of the payload (after - * optional dest. address and any extension - * headers). - */ - - if (!priv->ule_bridged) { - skb_push(priv->ule_skb, ETH_HLEN); - ethh = (struct ethhdr *)priv->ule_skb->data; - if (!priv->ule_dbit) { - /* dest_addr buffer is only valid if priv->ule_dbit == 0 */ - memcpy(ethh->h_dest, dest_addr, ETH_ALEN); - memset(ethh->h_source, 0, ETH_ALEN); - } - else /* zeroize source and dest */ - memset( ethh, 0, ETH_ALEN*2 ); + /* CRC32 was OK. Remove it from skb. */ + priv->ule_skb->tail -= 4; + priv->ule_skb->len -= 4; - ethh->h_proto = htons(priv->ule_sndu_type); + /* Filter on receiver's destination MAC address, if present. */ + if (!priv->ule_dbit) { + /* The destination MAC address is the next data in the skb. */ + if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) { + /* MAC addresses don't match. Drop SNDU. */ + // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" ); + dev_kfree_skb( priv->ule_skb ); + goto sndu_done; + } + if (! priv->ule_bridged) { + skb_push( priv->ule_skb, ETH_ALEN + 2 ); + ethh = (struct ethhdr *)priv->ule_skb->data; + memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN ); + memset( ethh->h_source, 0, ETH_ALEN ); + ethh->h_proto = htons( priv->ule_sndu_type ); + } else { + /* Skip the Receiver destination MAC address. */ + skb_pull( priv->ule_skb, ETH_ALEN ); + } + } else { + if (! priv->ule_bridged) { + skb_push( priv->ule_skb, ETH_HLEN ); + ethh = (struct ethhdr *)priv->ule_skb->data; + memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN ); + memset( ethh->h_source, 0, ETH_ALEN ); + ethh->h_proto = htons( priv->ule_sndu_type ); + } else { + /* skb is in correct state; nothing to do. */ + } } - /* else: skb is in correct state; nothing to do. */ priv->ule_bridged = 0; /* Stuff into kernel's protocol stack. */ @@ -743,8 +668,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) * receive the packet anyhow. */ /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) priv->ule_skb->pkt_type = PACKET_HOST; */ - priv->stats.rx_packets++; - priv->stats.rx_bytes += priv->ule_skb->len; + ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++; + ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len; netif_rx(priv->ule_skb); } sndu_done: @@ -1019,7 +944,7 @@ static int dvb_net_feed_start(struct net_device *dev) dprintk("%s: start filtering\n", __FUNCTION__); priv->secfeed->start_filtering(priv->secfeed); } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { - struct timespec timeout = { 0, 10000000 }; // 10 msec + struct timespec timeout = { 0, 30000000 }; // 30 msec /* we have payloads encapsulated in TS */ dprintk("%s: alloc tsfeed\n", __FUNCTION__); @@ -1031,13 +956,10 @@ static int dvb_net_feed_start(struct net_device *dev) /* Set netdevice pointer for ts decaps callback. */ priv->tsfeed->priv = (void *)dev; - ret = priv->tsfeed->set(priv->tsfeed, - priv->pid, /* pid */ - TS_PACKET, /* type */ - DMX_TS_PES_OTHER, /* pes type */ + ret = priv->tsfeed->set(priv->tsfeed, priv->pid, + TS_PACKET, DMX_TS_PES_OTHER, 32768, /* circular buffer size */ - timeout /* timeout */ - ); + timeout); if (ret < 0) { printk("%s: could not set ts feed\n", dev->name); diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index 134c2bbbeeb5..3852430d0260 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -236,7 +236,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, "dvb/adapter%d/%s%d", adap->num, dnames[type], id); class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), - adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); + NULL, "dvb%d.%s%d", adap->num, dnames[type], id); dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, nums2minor(adap->num, type, id), @@ -285,7 +285,7 @@ static int dvbdev_get_free_adapter_num (void) } -int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device) +int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module) { int num; @@ -306,7 +306,6 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu adap->num = num; adap->name = name; adap->module = module; - adap->device = device; list_add_tail (&adap->list_head, &dvb_adapter_list); diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.h b/trunk/drivers/media/dvb/dvb-core/dvbdev.h index d7a976d040d7..74ed5853f0fb 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.h +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.h @@ -51,8 +51,6 @@ struct dvb_adapter { u8 proposed_mac [6]; void* priv; - struct device *device; - struct module *module; }; @@ -78,7 +76,7 @@ struct dvb_device { }; -extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device); +extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module); extern int dvb_unregister_adapter (struct dvb_adapter *adap); extern int dvb_register_device (struct dvb_adapter *adap, diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index 3bc6722a6443..e388fb1567d6 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -88,7 +88,6 @@ config DVB_USB_CXUSB select DVB_CX22702 select DVB_LGDT330X select DVB_MT352 - select DVB_ZL10353 help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -131,15 +130,6 @@ config DVB_USB_VP702X DVB-S USB2.0 receivers. -config DVB_USB_GP8PSK - tristate "GENPIX 8PSK->USB module support" - depends on DVB_USB - help - Say Y here to support the - GENPIX 8psk module - - DVB-S USB2.0 receivers. - config DVB_USB_NOVA_T_USB2 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" depends on DVB_USB diff --git a/trunk/drivers/media/dvb/dvb-usb/Makefile b/trunk/drivers/media/dvb/dvb-usb/Makefile index 9643f56c7fe9..2dc9aad9681e 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Makefile +++ b/trunk/drivers/media/dvb/dvb-usb/Makefile @@ -7,9 +7,6 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o -dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o -obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o - dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.c b/trunk/drivers/media/dvb/dvb-usb/cxusb.c index ae23bdde42a8..1f0d3e995c8d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cxusb.c +++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.c @@ -27,10 +27,8 @@ #include "cx22702.h" #include "lgdt330x.h" -#include "lg_h06xf.h" #include "mt352.h" #include "mt352_priv.h" -#include "zl10353.h" /* debug */ int dvb_usb_cxusb_debug; @@ -324,37 +322,32 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) return 0; } -static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_device *d = fe->dvb->priv; - return lg_h06xf_pll_set(fe, &d->i2c_adap, fep); -} - static struct cx22702_config cxusb_cx22702_config = { .demod_address = 0x63, .output_mode = CX22702_PARALLEL_OUTPUT, + + .pll_init = dvb_usb_pll_init_i2c, + .pll_set = dvb_usb_pll_set_i2c, }; static struct lgdt330x_config cxusb_lgdt3303_config = { .demod_address = 0x0e, .demod_chip = LGDT3303, + .pll_set = dvb_usb_pll_set_i2c, }; static struct mt352_config cxusb_dee1601_config = { .demod_address = 0x0f, .demod_init = cxusb_dee1601_demod_init, + .pll_set = dvb_usb_pll_set, }; -static struct zl10353_config cxusb_zl10353_dee1601_config = { - .demod_address = 0x0f, -}; - -static struct mt352_config cxusb_mt352_config = { +struct mt352_config cxusb_mt352_config = { /* used in both lgz201 and th7579 */ .demod_address = 0x0f, .demod_init = cxusb_mt352_demod_init, + .pll_set = dvb_usb_pll_set, }; /* Callbacks for DVB USB */ @@ -364,10 +357,17 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) d->pll_addr = 0x61; memcpy(d->pll_init, bpll, 4); d->pll_desc = &dvb_pll_fmd1216me; + return 0; +} - d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; - d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; - +static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) +{ + u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; + /* bpll[2] : unset bit 3, set bits 4&5 + bpll[3] : 0x50 - digital, 0x20 - analog */ + d->pll_addr = 0x61; + memcpy(d->pll_init, bpll, 4); + d->pll_desc = &dvb_pll_tdvs_tua6034; return 0; } @@ -375,7 +375,6 @@ static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) { d->pll_addr = 0x61; d->pll_desc = &dvb_pll_thomson_dtt7579; - d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; return 0; } @@ -383,7 +382,6 @@ static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d) { d->pll_addr = 0x61; d->pll_desc = &dvb_pll_lg_z201; - d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; return 0; } @@ -391,13 +389,6 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d) { d->pll_addr = 0x60; d->pll_desc = &dvb_pll_thomson_dtt7579; - d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; - return 0; -} - -static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d) -{ - d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params; return 0; } @@ -448,8 +439,7 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); - if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) || - ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL)) + if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) return 0; return -EIO; @@ -565,7 +555,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { .streaming_ctrl = cxusb_streaming_ctrl, .power_ctrl = cxusb_bluebird_power_ctrl, .frontend_attach = cxusb_lgdt3303_frontend_attach, - .tuner_attach = cxusb_lgdt3303_tuner_attach, + .tuner_attach = cxusb_lgh064f_tuner_attach, .i2c_algo = &cxusb_i2c_algo, diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c index abd75b4a350d..2d52b76671d3 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -173,10 +173,11 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) struct dib3000_config demod_cfg; struct dibusb_state *st = d->priv; + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; + for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { - d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; - d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; return 0; } @@ -189,10 +190,6 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) { d->pll_addr = 0x60; d->pll_desc = &dvb_pll_env57h1xd5; - - d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; - d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; - return 0; } EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c index f4c45f386ebc..dd5a13195886 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -20,12 +20,11 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) struct dibusb_state *st = d->priv; demod_cfg.demod_address = 0x8; + demod_cfg.pll_set = dvb_usb_pll_set_i2c; + demod_cfg.pll_init = dvb_usb_pll_init_i2c; - if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { - d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; - d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; + if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) return -ENODEV; - } d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; diff --git a/trunk/drivers/media/dvb/dvb-usb/digitv.c b/trunk/drivers/media/dvb/dvb-usb/digitv.c index c14d9efb48fd..91136c00ce9d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/digitv.c +++ b/trunk/drivers/media/dvb/dvb-usb/digitv.c @@ -112,30 +112,27 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe) static struct mt352_config digitv_mt352_config = { .demod_init = digitv_mt352_demod_init, + .pll_set = dvb_usb_pll_set, }; -static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { struct dvb_usb_device *d = fe->dvb->priv; u8 b[5]; - dvb_usb_tuner_calc_regs(fe,fep,b, 5); + dvb_usb_pll_set(fe,fep,b); return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); } static struct nxt6000_config digitv_nxt6000_config = { .clock_inversion = 1, + .pll_set = digitv_nxt6000_pll_set, }; static int digitv_frontend_attach(struct dvb_usb_device *d) { - if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) { - d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; + if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL || + (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) return 0; - } - if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { - d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; - return 0; - } return -EIO; } diff --git a/trunk/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/trunk/drivers/media/dvb/dvb-usb/dtt200u-fe.c index 17413adec7a1..cd21ddbfd054 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -18,6 +18,7 @@ struct dtt200u_fe_state { struct dvb_frontend_parameters fep; struct dvb_frontend frontend; + struct dvb_frontend_ops ops; }; static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) @@ -162,13 +163,16 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) deb_info("attaching frontend dtt200u\n"); state->d = d; + memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); - memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; - return &state->frontend; + goto success; error: return NULL; +success: + return &state->frontend; } static struct dvb_frontend_ops dtt200u_fe_ops = { diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index ec631708c394..6fa92100248b 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -82,7 +82,7 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) int ret; if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, - d->owner, &d->udev->dev)) < 0) { + d->owner)) < 0) { deb_info("dvb_register_adapter failed: error %d", ret); goto err; } @@ -121,15 +121,16 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); - d->state |= DVB_USB_STATE_DVB; - return 0; - + goto success; err_dmx_dev: dvb_dmx_release(&d->demux); err_dmx: dvb_unregister_adapter(&d->dvb_adap); err: return ret; +success: + d->state |= DVB_USB_STATE_DVB; + return 0; } int dvb_usb_dvb_exit(struct dvb_usb_device *d) @@ -183,13 +184,13 @@ int dvb_usb_fe_init(struct dvb_usb_device* d) /* re-assign sleep and wakeup functions */ if (d->fe != NULL) { - d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; - d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; + d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; + d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; if (dvb_register_frontend(&d->dvb_adap, d->fe)) { err("Frontend registration failed."); - if (d->fe->ops.release) - d->fe->ops.release(d->fe); + if (d->fe->ops->release) + d->fe->ops->release(d->fe); d->fe = NULL; return -ENODEV; } diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 6b611a725093..9b254532af4d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -46,7 +46,7 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d) return 0; } -int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) +int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) { struct dvb_usb_device *d = fe->dvb->priv; struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; @@ -63,8 +63,6 @@ int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], d->pll_init[2],d->pll_init[3]); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { err("tuner i2c write failed for pll_init."); ret = -EREMOTEIO; @@ -75,42 +73,38 @@ int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) d->tuner_pass_ctrl(fe,0,d->pll_addr); return ret; } -EXPORT_SYMBOL(dvb_usb_tuner_init_i2c); +EXPORT_SYMBOL(dvb_usb_pll_init_i2c); -int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len) +int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) { struct dvb_usb_device *d = fe->dvb->priv; - if (buf_len != 5) - return -EINVAL; if (d->pll_desc == NULL) return 0; deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); - b[0] = d->pll_addr; + b[0] = d->pll_addr << 1; dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); - return 5; + return 0; } -EXPORT_SYMBOL(dvb_usb_tuner_calc_regs); +EXPORT_SYMBOL(dvb_usb_pll_set); -int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { struct dvb_usb_device *d = fe->dvb->priv; int ret = 0; u8 b[5]; struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; - dvb_usb_tuner_calc_regs(fe,fep,b,5); + dvb_usb_pll_set(fe,fep,b); if (d->tuner_pass_ctrl) d->tuner_pass_ctrl(fe,1,d->pll_addr); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { err("tuner i2c write failed for pll_set."); ret = -EREMOTEIO; @@ -122,4 +116,4 @@ int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_pa return ret; } -EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c); +EXPORT_SYMBOL(dvb_usb_pll_set_i2c); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 95698918bc11..cb239049b098 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -31,7 +31,6 @@ #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 -#define USB_VID_GENPIX 0x09c0 /* Product IDs */ #define USB_PID_ADSTECH_USB2_COLD 0xa333 @@ -105,6 +104,5 @@ #define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_400E 0x020f -#define USB_PID_GENPIX_8PSK_COLD 0x0200 -#define USB_PID_GENPIX_8PSK_WARM 0x0201 + #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h index 4cf9f89c51bf..fead958a57e3 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -330,9 +330,9 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); /* commonly used pll init and set functions */ -extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *); -extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len); -extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); +extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); +extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); +extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); /* commonly used firmware download types and function */ struct hexline { diff --git a/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c deleted file mode 100644 index 6ccbdc9cd772..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ /dev/null @@ -1,272 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk USB2.0 DVB-S module - * - * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "gp8psk.h" - -struct gp8psk_fe_state { - struct dvb_frontend fe; - - struct dvb_usb_device *d; - - u16 snr; - - unsigned long next_snr_check; -}; - -static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - u8 lock; - - if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1)) - return -EINVAL; - - if (lock) - *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; - else - *status = 0; - - return 0; -} - -/* not supported by this Frontend */ -static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - (void) fe; - *ber = 0; - return 0; -} - -/* not supported by this Frontend */ -static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - (void) fe; - *unc = 0; - return 0; -} - -static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - u8 buf[2]; - - if (time_after(jiffies,st->next_snr_check)) { - gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2); - *snr = (int)(buf[1]) << 8 | buf[0]; - /* snr is reported in dBu*256 */ - /* snr / 38.4 ~= 100% strength */ - /* snr * 17 returns 100% strength as 65535 */ - if (*snr <= 3855) - *snr = (*snr<<4) + *snr; // snr * 17 - else - *snr = 65535; - st->next_snr_check = jiffies + (10*HZ)/1000; - } else { - *snr = st->snr; - } - return 0; -} - -static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - return gp8psk_fe_read_snr(fe, strength); -} - -static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct gp8psk_fe_state *state = fe->demodulator_priv; - u8 cmd[10]; - u32 freq = fep->frequency * 1000; - - cmd[4] = freq & 0xff; - cmd[5] = (freq >> 8) & 0xff; - cmd[6] = (freq >> 16) & 0xff; - cmd[7] = (freq >> 24) & 0xff; - - switch(fe->ops.info.type) { - case FE_QPSK: - cmd[0] = fep->u.qpsk.symbol_rate & 0xff; - cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff; - cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff; - cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff; - cmd[8] = ADV_MOD_DVB_QPSK; - cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/ - break; - default: - // other modes are unsuported right now - cmd[0] = 0; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[8] = 0; - cmd[9] = 0; - break; - } - - gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10); - - state->next_snr_check = jiffies; - - return 0; -} - -static int gp8psk_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - - -static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - - deb_fe("%s\n",__FUNCTION__); - - if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, - m->msg, m->msg_len)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, - fe_sec_mini_cmd_t burst) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - u8 cmd; - - deb_fe("%s\n",__FUNCTION__); - - /* These commands are certainly wrong */ - cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; - - if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0, - &cmd, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - - if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE, - (tone == SEC_TONE_ON), 0, NULL, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - - if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, - voltage == SEC_VOLTAGE_18, 0, NULL, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - u8 cmd = sw_cmd & 0x7f; - - if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0, - NULL, 0)) { - return -EINVAL; - } - if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), - 0, NULL, 0)) { - return -EINVAL; - } - - return 0; -} - -static void gp8psk_fe_release(struct dvb_frontend* fe) -{ - struct gp8psk_fe_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops gp8psk_fe_ops; - -struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d) -{ - struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); - if (s == NULL) - goto error; - - s->d = d; - memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - - goto success; -error: - return NULL; -success: - return &s->fe; -} - - -static struct dvb_frontend_ops gp8psk_fe_ops = { - .info = { - .name = "Genpix 8psk-USB DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 100, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = gp8psk_fe_release, - - .init = NULL, - .sleep = NULL, - - .set_frontend = gp8psk_fe_set_frontend, - .get_frontend = gp8psk_fe_get_frontend, - .get_tune_settings = gp8psk_fe_get_tune_settings, - - .read_status = gp8psk_fe_read_status, - .read_ber = gp8psk_fe_read_ber, - .read_signal_strength = gp8psk_fe_read_signal_strength, - .read_snr = gp8psk_fe_read_snr, - .read_ucblocks = gp8psk_fe_read_unc_blocks, - - .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg, - .diseqc_send_burst = gp8psk_fe_send_diseqc_burst, - .set_tone = gp8psk_fe_set_tone, - .set_voltage = gp8psk_fe_set_voltage, - .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, -}; diff --git a/trunk/drivers/media/dvb/dvb-usb/gp8psk.c b/trunk/drivers/media/dvb/dvb-usb/gp8psk.c deleted file mode 100644 index 9a98f3fdae31..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/gp8psk.c +++ /dev/null @@ -1,256 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk USB2.0 DVB-S module - * - * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "gp8psk.h" - -/* debug */ -static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; -int dvb_usb_gp8psk_debug; -module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) -{ - int ret = 0,try = 0; - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - while (ret >= 0 && ret != blen && try < 3) { - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, - value,index,b,blen, - 2000); - deb_info("reading number %d (ret: %d)\n",try,ret); - try++; - } - - if (ret < 0 || ret != blen) { - warn("usb in operation failed."); - ret = -EIO; - } else - ret = 0; - - deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - mutex_unlock(&d->usb_mutex); - - return ret; -} - -int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, - u16 index, u8 *b, int blen) -{ - int ret; - - deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - if (usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 2000) != blen) { - warn("usb out operation failed."); - ret = -EIO; - } else - ret = 0; - mutex_unlock(&d->usb_mutex); - - return ret; -} - -static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) -{ - int ret; - const struct firmware *fw = NULL; - u8 *ptr, *buf; - if ((ret = request_firmware(&fw, bcm4500_firmware, - &d->udev->dev)) != 0) { - err("did not find the bcm4500 firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", - bcm4500_firmware,ret); - return ret; - } - - ret = -EINVAL; - - if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) - goto out_rel_fw; - - info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware); - - ptr = fw->data; - buf = kmalloc(512, GFP_KERNEL | GFP_DMA); - - while (ptr[0] != 0xff) { - u16 buflen = ptr[0] + 4; - if (ptr + buflen >= fw->data + fw->size) { - err("failed to load bcm4500 firmware."); - goto out_free; - } - memcpy(buf, ptr, buflen); - if (dvb_usb_generic_write(d, buf, buflen)) { - err("failed to load bcm4500 firmware."); - goto out_free; - } - ptr += buflen; - } - - ret = 0; - -out_free: - kfree(buf); -out_rel_fw: - release_firmware(fw); - - return ret; -} - -static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 status, buf; - if (onoff) { - gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); - if (! (status & 0x01)) /* started */ - if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1)) - return -EINVAL; - - if (! (status & 0x02)) /* BCM4500 firmware loaded */ - if(gp8psk_load_bcm4500fw(d)) - return EINVAL; - - if (! (status & 0x04)) /* LNB Power */ - if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, - &buf, 1)) - return EINVAL; - - /* Set DVB mode */ - if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) - return -EINVAL; - gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); - } else { - /* Turn off LNB power */ - if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) - return EINVAL; - /* Turn off 8psk power */ - if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) - return -EINVAL; - - } - return 0; -} - - -static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff) -{ - return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0); -} - -static int gp8psk_frontend_attach(struct dvb_usb_device *d) -{ - d->fe = gp8psk_fe_attach(d); - - return 0; -} - -static struct dvb_usb_properties gp8psk_properties; - -static int gp8psk_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL); -} - -static struct usb_device_id gp8psk_usb_table [] = { - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) }, - { 0 }, -}; -MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); - -static struct dvb_usb_properties gp8psk_properties = { - .caps = 0, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-gp8psk-01.fw", - - .streaming_ctrl = gp8psk_streaming_ctrl, - .power_ctrl = gp8psk_power_ctrl, - .frontend_attach = gp8psk_frontend_attach, - - .generic_bulk_ctrl_endpoint = 0x01, - /* parameter for the MPEG2-data transfer */ - .urb = { - .type = DVB_USB_BULK, - .count = 7, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - - .num_device_descs = 1, - .devices = { - { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver", - .cold_ids = { &gp8psk_usb_table[0], NULL }, - .warm_ids = { &gp8psk_usb_table[1], NULL }, - }, - { 0 }, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver gp8psk_usb_driver = { - .name = "dvb_usb_gp8psk", - .probe = gp8psk_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = gp8psk_usb_table, -}; - -/* module stuff */ -static int __init gp8psk_usb_module_init(void) -{ - int result; - if ((result = usb_register(&gp8psk_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit gp8psk_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&gp8psk_usb_driver); -} - -module_init(gp8psk_usb_module_init); -module_exit(gp8psk_usb_module_exit); - -MODULE_AUTHOR("Alan Nisota "); -MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-usb/gp8psk.h b/trunk/drivers/media/dvb/dvb-usb/gp8psk.h deleted file mode 100644 index 3eba7061011c..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/gp8psk.h +++ /dev/null @@ -1,79 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk USB2.0 DVB-S module - * - * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_GP8PSK_H_ -#define _DVB_USB_GP8PSK_H_ - -#define DVB_USB_LOG_PREFIX "gp8psk" -#include "dvb-usb.h" - -extern int dvb_usb_gp8psk_debug; -#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args) -#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args) -/* gp8psk commands */ - -/* Twinhan Vendor requests */ -#define TH_COMMAND_IN 0xC0 -#define TH_COMMAND_OUT 0xC1 - -/* command bytes */ -#define GET_8PSK_CONFIG 0x80 -#define SET_8PSK_CONFIG 0x81 -#define ARM_TRANSFER 0x85 -#define TUNE_8PSK 0x86 -#define GET_SIGNAL_STRENGTH 0x87 -#define LOAD_BCM4500 0x88 -#define BOOT_8PSK 0x89 -#define START_INTERSIL 0x8A -#define SET_LNB_VOLTAGE 0x8B -#define SET_22KHZ_TONE 0x8C -#define SEND_DISEQC_COMMAND 0x8D -#define SET_DVB_MODE 0x8E -#define SET_DN_SWITCH 0x8F -#define GET_SIGNAL_LOCK 0x90 - -/* Satellite modulation modes */ -#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ -#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ -#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ -#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ - -#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ -#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ -#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ -#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ -#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ -#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ - -#define GET_USB_SPEED 0x07 - #define USB_SPEED_LOW 0 - #define USB_SPEED_FULL 1 - #define USB_SPEED_HIGH 2 - -#define RESET_FX2 0x13 - -#define FW_VERSION_READ 0x0B -#define VENDOR_STRING_READ 0x0C -#define PRODUCT_STRING_READ 0x0D -#define FW_BCD_VERSION_READ 0x14 - -extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); -extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); -extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, - u16 index, u8 *b, int blen); - -#endif diff --git a/trunk/drivers/media/dvb/dvb-usb/umt-010.c b/trunk/drivers/media/dvb/dvb-usb/umt-010.c index 97d74da0dad8..14f1911c79bb 100644 --- a/trunk/drivers/media/dvb/dvb-usb/umt-010.c +++ b/trunk/drivers/media/dvb/dvb-usb/umt-010.c @@ -57,6 +57,7 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d) memset(&umt_config,0,sizeof(struct mt352_config)); umt_config.demod_init = umt_mt352_demod_init; umt_config.demod_address = 0xf; + umt_config.pll_set = dvb_usb_pll_set; d->fe = mt352_attach(&umt_config, &d->i2c_adap); @@ -67,7 +68,6 @@ static int umt_tuner_attach (struct dvb_usb_device *d) { d->pll_addr = 0x61; d->pll_desc = &dvb_pll_tua6034; - d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; return 0; } diff --git a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c index d4da494132ec..2a89f8c5da99 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -287,16 +287,17 @@ struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) goto error; s->d = d; - - memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops)); + s->fe.ops = &vp702x_fe_ops; s->fe.demodulator_priv = s; s->lnb_buf[1] = SET_LNB_POWER; s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ - return &s->fe; + goto success; error: return NULL; +success: + return &s->fe; } diff --git a/trunk/drivers/media/dvb/dvb-usb/vp7045-fe.c b/trunk/drivers/media/dvb/dvb-usb/vp7045-fe.c index 8452eef90322..9999336aeeb6 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/vp7045-fe.c @@ -23,6 +23,8 @@ struct vp7045_fe_state { struct dvb_frontend fe; + struct dvb_frontend_ops ops; + struct dvb_usb_device *d; }; @@ -149,12 +151,15 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) goto error; s->d = d; - memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); + s->fe.ops = &s->ops; s->fe.demodulator_priv = s; - return &s->fe; + goto success; error: return NULL; +success: + return &s->fe; } diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index 0ef361f0309b..37d5e0af1683 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -157,7 +157,7 @@ config DVB_STV0297 help A DVB-C tuner module. Say Y when you want to support this frontend. -comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" +comment "ATSC (North American/Korean Terresterial DTV) frontends" depends on DVB_CORE config DVB_NXT200X @@ -216,20 +216,4 @@ config DVB_LGDT330X An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. - -comment "Miscellaneous devices" - depends on DVB_CORE - -config DVB_LNBP21 - tristate "LNBP21 SEC controller" - depends on DVB_CORE - help - An SEC control chip. - -config DVB_ISL6421 - tristate "ISL6421 SEC controller" - depends on DVB_CORE - help - An SEC control chip. - endmenu diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile index 5222245c7f59..d09b6071fbaf 100644 --- a/trunk/drivers/media/dvb/frontends/Makefile +++ b/trunk/drivers/media/dvb/frontends/Makefile @@ -31,5 +31,3 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_CX24123) += cx24123.o -obj-$(CONFIG_DVB_LNBP21) += lnbp21.o -obj-$(CONFIG_DVB_ISL6421) += isl6421.o diff --git a/trunk/drivers/media/dvb/frontends/bcm3510.c b/trunk/drivers/media/dvb/frontends/bcm3510.c index baeb311de893..1708a1d4893e 100644 --- a/trunk/drivers/media/dvb/frontends/bcm3510.c +++ b/trunk/drivers/media/dvb/frontends/bcm3510.c @@ -48,6 +48,7 @@ struct bcm3510_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct bcm3510_config* config; struct dvb_frontend frontend; @@ -790,9 +791,10 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, state->config = config; state->i2c = i2c; + memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); /* create dvb_frontend */ - memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; mutex_init(&state->hab_mutex); diff --git a/trunk/drivers/media/dvb/frontends/bsbe1.h b/trunk/drivers/media/dvb/frontends/bsbe1.h index d8f65738e5d2..78573b22ada9 100644 --- a/trunk/drivers/media/dvb/frontends/bsbe1.h +++ b/trunk/drivers/media/dvb/frontends/bsbe1.h @@ -89,13 +89,12 @@ static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra return 0; } -static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) { int ret; u8 data[4]; u32 div; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - struct i2c_adapter *i2c = fe->tuner_priv; if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; @@ -106,8 +105,6 @@ static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); ret = i2c_transfer(i2c, &msg, 1); return (ret != 1) ? -EIO : 0; } @@ -120,6 +117,7 @@ static struct stv0299_config alps_bsbe1_config = { .skip_reinit = 0, .min_delay_ms = 100, .set_symbol_rate = alps_bsbe1_set_symbol_rate, + .pll_set = alps_bsbe1_pll_set, }; #endif diff --git a/trunk/drivers/media/dvb/frontends/bsru6.h b/trunk/drivers/media/dvb/frontends/bsru6.h index e231cd84b3a1..2a5366ce79cc 100644 --- a/trunk/drivers/media/dvb/frontends/bsru6.h +++ b/trunk/drivers/media/dvb/frontends/bsru6.h @@ -101,12 +101,11 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra return 0; } -static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) { u8 buf[4]; u32 div; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct i2c_adapter *i2c = fe->tuner_priv; if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; @@ -120,8 +119,6 @@ static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_front if (params->frequency > 1530000) buf[3] = 0xc0; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; return 0; @@ -137,6 +134,7 @@ static struct stv0299_config alps_bsru6_config = { .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = alps_bsru6_set_symbol_rate, + .pll_set = alps_bsru6_pll_set, }; #endif diff --git a/trunk/drivers/media/dvb/frontends/cx22700.c b/trunk/drivers/media/dvb/frontends/cx22700.c index 3c7c09a362b2..755f774f6b7d 100644 --- a/trunk/drivers/media/dvb/frontends/cx22700.c +++ b/trunk/drivers/media/dvb/frontends/cx22700.c @@ -34,6 +34,8 @@ struct cx22700_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + const struct cx22700_config* config; struct dvb_frontend frontend; @@ -245,6 +247,12 @@ static int cx22700_init (struct dvb_frontend* fe) cx22700_writereg (state, 0x00, 0x01); + if (state->config->pll_init) { + cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ + state->config->pll_init(fe); + cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ + } + return 0; } @@ -325,11 +333,9 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ cx22700_writereg (state, 0x00, 0x00); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - + cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ + state->config->pll_set(fe, p); + cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ cx22700_set_inversion (state, p->inversion); cx22700_set_tps (state, &p->u.ofdm); cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ @@ -347,17 +353,6 @@ static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par return cx22700_get_tps (state, &p->u.ofdm); } -static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct cx22700_state* state = fe->demodulator_priv; - - if (enable) { - return cx22700_writereg(state, 0x0a, 0x00); - } else { - return cx22700_writereg(state, 0x0a, 0x01); - } -} - static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { fesettings->min_delay_ms = 150; @@ -386,12 +381,13 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if (cx22700_readreg(state, 0x07) < 0) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -417,7 +413,6 @@ static struct dvb_frontend_ops cx22700_ops = { .release = cx22700_release, .init = cx22700_init, - .i2c_gate_ctrl = cx22700_i2c_gate_ctrl, .set_frontend = cx22700_set_frontend, .get_frontend = cx22700_get_frontend, diff --git a/trunk/drivers/media/dvb/frontends/cx22700.h b/trunk/drivers/media/dvb/frontends/cx22700.h index dcd8979c1a15..c9145b45874b 100644 --- a/trunk/drivers/media/dvb/frontends/cx22700.h +++ b/trunk/drivers/media/dvb/frontends/cx22700.h @@ -29,6 +29,10 @@ struct cx22700_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, diff --git a/trunk/drivers/media/dvb/frontends/cx22702.c b/trunk/drivers/media/dvb/frontends/cx22702.c index 4106d46c957f..0fc899f81c5e 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.c +++ b/trunk/drivers/media/dvb/frontends/cx22702.c @@ -40,6 +40,8 @@ struct cx22702_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + /* configuration settings */ const struct cx22702_config* config; @@ -209,10 +211,22 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet u8 val; struct cx22702_state* state = fe->demodulator_priv; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + /* set PLL */ + cx22702_i2c_gate_ctrl(fe, 1); + if (state->config->pll_set) { + state->config->pll_set(fe, p); + } else if (state->config->pll_desc) { + u8 pllbuf[4]; + struct i2c_msg msg = { .addr = state->config->pll_address, + .buf = pllbuf, .len = 4 }; + dvb_pll_configure(state->config->pll_desc, pllbuf, + p->frequency, + p->u.ofdm.bandwidth); + i2c_transfer(state->i2c, &msg, 1); + } else { + BUG(); } + cx22702_i2c_gate_ctrl(fe, 0); /* set inversion */ cx22702_set_inversion (state, p->inversion); @@ -344,6 +358,10 @@ static int cx22702_init (struct dvb_frontend* fe) cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); + /* init PLL */ + if (state->config->pll_init) + state->config->pll_init(fe); + cx22702_i2c_gate_ctrl(fe, 0); return 0; @@ -477,6 +495,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); state->prevUCBlocks = 0; /* check if the demod is there */ @@ -484,7 +503,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -511,7 +530,6 @@ static struct dvb_frontend_ops cx22702_ops = { .release = cx22702_release, .init = cx22702_init, - .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, .set_frontend = cx22702_set_tps, .get_frontend = cx22702_get_frontend, @@ -522,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = { .read_signal_strength = cx22702_read_signal_strength, .read_snr = cx22702_read_snr, .read_ucblocks = cx22702_read_ucblocks, + .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, }; module_param(debug, int, 0644); diff --git a/trunk/drivers/media/dvb/frontends/cx22702.h b/trunk/drivers/media/dvb/frontends/cx22702.h index 7f2f241e5d44..5633976a58f1 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.h +++ b/trunk/drivers/media/dvb/frontends/cx22702.h @@ -39,6 +39,13 @@ struct cx22702_config #define CX22702_PARALLEL_OUTPUT 0 #define CX22702_SERIAL_OUTPUT 1 u8 output_mode; + + /* PLL maintenance */ + u8 pll_address; + struct dvb_pll_desc *pll_desc; + + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, diff --git a/trunk/drivers/media/dvb/frontends/cx24110.c b/trunk/drivers/media/dvb/frontends/cx24110.c index ce3c7398bac9..f3edf8b517dd 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.c +++ b/trunk/drivers/media/dvb/frontends/cx24110.c @@ -36,6 +36,8 @@ struct cx24110_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + const struct cx24110_config* config; struct dvb_frontend frontend; @@ -248,7 +250,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; int i; - dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); +dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); if (srate>90999000UL/2) srate=90999000UL/2; if (srate<500000) @@ -364,6 +366,17 @@ static int cx24110_initfe(struct dvb_frontend* fe) cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); }; + if (state->config->pll_init) state->config->pll_init(fe); + + return 0; +} + +static int cx24110_sleep(struct dvb_frontend *fe) +{ + struct cx24110_state *state = fe->demodulator_priv; + + if (state->config->pll_sleep) + return state->config->pll_sleep(fe); return 0; } @@ -535,12 +548,7 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24110_state *state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - + state->config->pll_set(fe, p); cx24110_set_inversion (state, p->inversion); cx24110_set_fec (state, p->u.qpsk.fec_inner); cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); @@ -604,6 +612,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); state->lastber = 0; state->lastbler = 0; state->lastesn0 = 0; @@ -613,7 +622,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, if ((ret != 0x5a) && (ret != 0x69)) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -642,6 +651,7 @@ static struct dvb_frontend_ops cx24110_ops = { .release = cx24110_release, .init = cx24110_initfe, + .sleep = cx24110_sleep, .set_frontend = cx24110_set_frontend, .get_frontend = cx24110_get_frontend, .read_status = cx24110_read_status, diff --git a/trunk/drivers/media/dvb/frontends/cx24110.h b/trunk/drivers/media/dvb/frontends/cx24110.h index b354a64e0e74..609ac642b406 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.h +++ b/trunk/drivers/media/dvb/frontends/cx24110.h @@ -31,6 +31,11 @@ struct cx24110_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*pll_sleep)(struct dvb_frontend* fe); }; extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, diff --git a/trunk/drivers/media/dvb/frontends/cx24123.c b/trunk/drivers/media/dvb/frontends/cx24123.c index f2f795cba56a..691dc840dcc0 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.c +++ b/trunk/drivers/media/dvb/frontends/cx24123.c @@ -41,12 +41,14 @@ static int debug; struct cx24123_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct cx24123_config* config; struct dvb_frontend frontend; u32 lastber; u16 snr; + u8 lnbreg; /* Some PLL specifics for tuning */ u32 VCAarg; @@ -247,6 +249,29 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data) return 0; } +static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) +{ + u8 buf[] = { reg, data }; + /* fixme: put the intersil addr int the config */ + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; + int err; + + if (debug>1) + printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n", + __FUNCTION__,reg, data); + + if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { + printk("%s: writelnbreg error (err == %i, reg == 0x%02x," + " data == 0x%02x)\n", __FUNCTION__, err, reg, data); + return -EREMOTEIO; + } + + /* cache the write, no way to read back */ + state->lnbreg = data; + + return 0; +} + static int cx24123_readreg(struct cx24123_state* state, u8 reg) { int ret; @@ -270,6 +295,11 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg) return b1[0]; } +static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) +{ + return state->lnbreg; +} + static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) { u8 nom_reg = cx24123_readreg(state, 0x0e); @@ -428,8 +458,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) u8 pll_mult; /* check if symbol rate is within limits */ - if ((srate > state->frontend.ops.info.symbol_rate_max) || - (srate < state->frontend.ops.info.symbol_rate_min)) + if ((srate > state->ops.info.symbol_rate_max) || + (srate < state->ops.info.symbol_rate_min)) return -EOPNOTSUPP;; /* choose the sampling rate high enough for the required operation, @@ -657,6 +687,13 @@ static int cx24123_initfe(struct dvb_frontend* fe) for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); + if (state->config->pll_init) + state->config->pll_init(fe); + + /* Configure the LNB for 14V */ + if (state->config->use_isl6421) + cx24123_writelnbreg(state, 0x0, 0x2a); + return 0; } @@ -665,18 +702,50 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage struct cx24123_state *state = fe->demodulator_priv; u8 val; - val = cx24123_readreg(state, 0x29) & ~0x40; + switch (state->config->use_isl6421) { - switch (voltage) { - case SEC_VOLTAGE_13: - dprintk("%s: setting voltage 13V\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val | 0x80); - case SEC_VOLTAGE_18: - dprintk("%s: setting voltage 18V\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val & 0x7f); - default: - return -EINVAL; - }; + case 1: + + val = cx24123_readlnbreg(state, 0x0); + + switch (voltage) { + case SEC_VOLTAGE_13: + dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); + return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ + case SEC_VOLTAGE_18: + dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); + return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ + case SEC_VOLTAGE_OFF: + dprintk("%s: isl5421 voltage off\n",__FUNCTION__); + return cx24123_writelnbreg(state, 0x0, val & 0x30); + default: + return -EINVAL; + }; + + case 0: + + val = cx24123_readreg(state, 0x29); + + switch (voltage) { + case SEC_VOLTAGE_13: + dprintk("%s: setting voltage 13V\n", __FUNCTION__); + if (state->config->enable_lnb_voltage) + state->config->enable_lnb_voltage(fe, 1); + return cx24123_writereg(state, 0x29, val | 0x80); + case SEC_VOLTAGE_18: + dprintk("%s: setting voltage 18V\n", __FUNCTION__); + if (state->config->enable_lnb_voltage) + state->config->enable_lnb_voltage(fe, 1); + return cx24123_writereg(state, 0x29, val & 0x7f); + case SEC_VOLTAGE_OFF: + dprintk("%s: setting voltage off\n", __FUNCTION__); + if (state->config->enable_lnb_voltage) + state->config->enable_lnb_voltage(fe, 0); + return 0; + default: + return -EINVAL; + }; + } return 0; } @@ -697,20 +766,27 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) { struct cx24123_state *state = fe->demodulator_priv; - int i, val, tone; + int i, val; dprintk("%s:\n",__FUNCTION__); - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); + /* check if continuous tone has been stopped */ + if (state->config->use_isl6421) + val = cx24123_readlnbreg(state, 0x00) & 0x10; + else + val = cx24123_readreg(state, 0x29) & 0x10; + + + if (val) { + printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); + return -ENOTSUPP; + } /* wait for diseqc queue ready */ cx24123_wait_for_diseqc(state); /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); + cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); for (i = 0; i < cmd->msg_len; i++) cx24123_writereg(state, 0x2C + i, cmd->msg[i]); @@ -721,33 +797,36 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma /* wait for diseqc message to finish sending */ cx24123_wait_for_diseqc(state); - /* restart continuous tone if enabled */ - if (tone & 0x10) { - cx24123_writereg(state, 0x29, tone & ~0x40); - } - return 0; } static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) { struct cx24123_state *state = fe->demodulator_priv; - int val, tone; + int val; dprintk("%s:\n", __FUNCTION__); - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); + /* check if continuous tone has been stoped */ + if (state->config->use_isl6421) + val = cx24123_readlnbreg(state, 0x00) & 0x10; + else + val = cx24123_readreg(state, 0x29) & 0x10; + + + if (val) { + printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); + return -ENOTSUPP; + } - /* wait for diseqc queue ready */ cx24123_wait_for_diseqc(state); /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4); - msleep(30); + val = cx24123_readreg(state, 0x2a) & 0xf8; + cx24123_writereg(state, 0x2a, val | 0x04); + val = cx24123_readreg(state, 0x29); + if (burst == SEC_MINI_A) cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); else if (burst == SEC_MINI_B) @@ -756,12 +835,7 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t return -EINVAL; cx24123_wait_for_diseqc(state); - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); - /* restart continuous tone if enabled */ - if (tone & 0x10) { - cx24123_writereg(state, 0x29, tone & ~0x40); - } return 0; } @@ -902,21 +976,38 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) struct cx24123_state *state = fe->demodulator_priv; u8 val; - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); + switch (state->config->use_isl6421) { + case 1: - val = cx24123_readreg(state, 0x29) & ~0x40; + val = cx24123_readlnbreg(state, 0x0); + + switch (tone) { + case SEC_TONE_ON: + dprintk("%s: isl6421 sec tone on\n",__FUNCTION__); + return cx24123_writelnbreg(state, 0x0, val | 0x10); + case SEC_TONE_OFF: + dprintk("%s: isl6421 sec tone off\n",__FUNCTION__); + return cx24123_writelnbreg(state, 0x0, val & 0x2f); + default: + printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); + return -EINVAL; + } - switch (tone) { - case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val | 0x10); - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__FUNCTION__); - return cx24123_writereg(state, 0x29, val & 0xef); - default: - printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); - return -EINVAL; + case 0: + + val = cx24123_readreg(state, 0x29); + + switch (tone) { + case SEC_TONE_ON: + dprintk("%s: setting tone on\n", __FUNCTION__); + return cx24123_writereg(state, 0x29, val | 0x10); + case SEC_TONE_OFF: + dprintk("%s: setting tone off\n",__FUNCTION__); + return cx24123_writereg(state, 0x29, val & 0xef); + default: + printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); + return -EINVAL; + } } return 0; @@ -949,8 +1040,10 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); state->lastber = 0; state->snr = 0; + state->lnbreg = 0; state->VCAarg = 0; state->VGAarg = 0; state->bandselectarg = 0; @@ -966,7 +1059,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/cx24123.h b/trunk/drivers/media/dvb/frontends/cx24123.h index 9606f825935c..0c922b5e9263 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.h +++ b/trunk/drivers/media/dvb/frontends/cx24123.h @@ -28,8 +28,21 @@ struct cx24123_config /* the demodulator's i2c address */ u8 demod_address; + /* + cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip + for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits + from register 0x29 of the CX24123 demodulator + */ + int use_isl6421; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + /* Need to set device param for start_dma */ int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); + + void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); }; extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, diff --git a/trunk/drivers/media/dvb/frontends/dib3000-common.h b/trunk/drivers/media/dvb/frontends/dib3000-common.h index be1c0d3e1389..c31d6df15472 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000-common.h +++ b/trunk/drivers/media/dvb/frontends/dib3000-common.h @@ -38,6 +38,8 @@ struct dib3000_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + /* configuration settings */ struct dib3000_config config; diff --git a/trunk/drivers/media/dvb/frontends/dib3000.h b/trunk/drivers/media/dvb/frontends/dib3000.h index ec927628d273..2d5475b5c063 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000.h +++ b/trunk/drivers/media/dvb/frontends/dib3000.h @@ -30,6 +30,10 @@ struct dib3000_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance and the i2c address of the PLL */ + int (*pll_init)(struct dvb_frontend *fe); + int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params); }; struct dib_fe_xfer_ops diff --git a/trunk/drivers/media/dvb/frontends/dib3000mb.c b/trunk/drivers/media/dvb/frontends/dib3000mb.c index 7c6dc7e30900..ae589adb1c0a 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mb.c +++ b/trunk/drivers/media/dvb/frontends/dib3000mb.c @@ -60,9 +60,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, fe_code_rate_t fe_cr = FEC_NONE; int search_state, seq; - if (tuner && fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (tuner && state->config.pll_set) { + state->config.pll_set(fe, fep); deb_setf("bandwidth: "); switch (ofdm->bandwidth) { @@ -387,6 +386,9 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); + if (state->config.pll_init) + state->config.pll_init(fe); + return 0; } @@ -705,6 +707,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, /* setup the state */ state->i2c = i2c; memcpy(&state->config,config,sizeof(struct dib3000_config)); + memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); /* check for the correct demod */ if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) @@ -714,7 +717,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; /* set the xfer operations */ diff --git a/trunk/drivers/media/dvb/frontends/dib3000mc.c b/trunk/drivers/media/dvb/frontends/dib3000mc.c index 6c3be2529980..3b303dbb6156 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mc.c +++ b/trunk/drivers/media/dvb/frontends/dib3000mc.c @@ -462,9 +462,8 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, int search_state,auto_val; u16 val; - if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (tuner && state->config.pll_set) { /* initial call from dvb */ + state->config.pll_set(fe,fep); state->last_tuned_freq = fep->frequency; // if (!scanboost) { @@ -643,6 +642,9 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); + if (state->config.pll_init) + state->config.pll_init(fe); + deb_info("init end\n"); return 0; } @@ -837,6 +839,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, /* setup the state */ state->i2c = i2c; memcpy(&state->config,config,sizeof(struct dib3000_config)); + memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); /* check for the correct demod */ if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) @@ -856,7 +859,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; /* set the xfer operations */ @@ -873,7 +876,6 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, kfree(state); return NULL; } -EXPORT_SYMBOL(dib3000mc_attach); static struct dvb_frontend_ops dib3000mc_ops = { @@ -912,3 +914,5 @@ static struct dvb_frontend_ops dib3000mc_ops = { MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(dib3000mc_attach); diff --git a/trunk/drivers/media/dvb/frontends/dvb-pll.c b/trunk/drivers/media/dvb/frontends/dvb-pll.c index a189683454b7..791706ec1da3 100644 --- a/trunk/drivers/media/dvb/frontends/dvb-pll.c +++ b/trunk/drivers/media/dvb/frontends/dvb-pll.c @@ -227,10 +227,10 @@ struct dvb_pll_desc dvb_pll_tua6034 = { EXPORT_SYMBOL(dvb_pll_tua6034); /* Infineon TUA6034 - * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F + * used in LG TDVS H061F and LG TDVS H062F */ -struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { - .name = "LG TDVS-H06xF", +struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { + .name = "LG/Infineon TUA6034", .min = 54000000, .max = 863000000, .count = 3, @@ -240,7 +240,7 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { { 999999999, 44000000, 62500, 0xce, 0x04 }, }, }; -EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); +EXPORT_SYMBOL(dvb_pll_tdvs_tua6034); /* Philips FMD1216ME * used in Medion Hybrid PCMCIA card and USB Box @@ -419,19 +419,6 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { }; EXPORT_SYMBOL(dvb_pll_thomson_fe6600); -struct dvb_pll_priv { - /* i2c details */ - int pll_i2c_address; - struct i2c_adapter *i2c; - - /* the PLL descriptor */ - struct dvb_pll_desc *pll_desc; - - /* cached frequency/bandwidth */ - u32 frequency; - u32 bandwidth; -}; - /* ----------------------------------------------------------- */ /* code */ @@ -456,8 +443,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, if (debug) printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", desc->name, freq, bandwidth, i, desc->count); - if (i == desc->count) - return -EINVAL; + BUG_ON(i == desc->count); div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; buf[0] = div >> 8; @@ -476,163 +462,6 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, } EXPORT_SYMBOL(dvb_pll_configure); -static int dvb_pll_release(struct dvb_frontend *fe) -{ - if (fe->tuner_priv) - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int dvb_pll_sleep(struct dvb_frontend *fe) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - u8 buf[4]; - struct i2c_msg msg = - { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; - int i; - int result; - - for (i = 0; i < priv->pll_desc->count; i++) { - if (priv->pll_desc->entries[i].limit == 0) - break; - } - if (i == priv->pll_desc->count) - return 0; - - buf[0] = 0; - buf[1] = 0; - buf[2] = priv->pll_desc->entries[i].config; - buf[3] = priv->pll_desc->entries[i].cb; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - - return 0; -} - -static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - u8 buf[4]; - struct i2c_msg msg = - { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; - int result; - u32 div; - int i; - u32 bandwidth = 0; - - if (priv->i2c == NULL) - return -EINVAL; - - // DVBT bandwidth only just now - if (fe->ops.info.type == FE_OFDM) { - bandwidth = params->u.ofdm.bandwidth; - } - - if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0) - return result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - - // calculate the frequency we set it to - for (i = 0; i < priv->pll_desc->count; i++) { - if (params->frequency > priv->pll_desc->entries[i].limit) - continue; - break; - } - div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; - priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; - priv->bandwidth = bandwidth; - - return 0; -} - -static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - int result; - u32 div; - int i; - u32 bandwidth = 0; - - if (buf_len < 5) - return -EINVAL; - - // DVBT bandwidth only just now - if (fe->ops.info.type == FE_OFDM) { - bandwidth = params->u.ofdm.bandwidth; - } - - if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0) - return result; - buf[0] = priv->pll_i2c_address; - - // calculate the frequency we set it to - for (i = 0; i < priv->pll_desc->count; i++) { - if (params->frequency > priv->pll_desc->entries[i].limit) - continue; - break; - } - div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; - priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; - priv->bandwidth = bandwidth; - - return 5; -} - -static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *bandwidth = priv->bandwidth; - return 0; -} - -static struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_pll_release, - .sleep = dvb_pll_sleep, - .set_params = dvb_pll_set_params, - .calc_regs = dvb_pll_calc_regs, - .get_frequency = dvb_pll_get_frequency, - .get_bandwidth = dvb_pll_get_bandwidth, -}; - -int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) -{ - struct dvb_pll_priv *priv = NULL; - - priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - priv->pll_i2c_address = pll_addr; - priv->i2c = i2c; - priv->pll_desc = desc; - - memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops)); - strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); - fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; - - fe->tuner_priv = priv; - return 0; -} -EXPORT_SYMBOL(dvb_pll_attach); - MODULE_DESCRIPTION("dvb pll library"); MODULE_AUTHOR("Gerd Knorr"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/dvb-pll.h b/trunk/drivers/media/dvb/frontends/dvb-pll.h index 66361cd18807..2b8461784989 100644 --- a/trunk/drivers/media/dvb/frontends/dvb-pll.h +++ b/trunk/drivers/media/dvb/frontends/dvb-pll.h @@ -5,9 +5,6 @@ #ifndef __DVB_PLL_H__ #define __DVB_PLL_H__ -#include -#include "dvb_frontend.h" - struct dvb_pll_desc { char *name; u32 min; @@ -34,7 +31,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1; extern struct dvb_pll_desc dvb_pll_tua6010xs; extern struct dvb_pll_desc dvb_pll_env57h1xd5; extern struct dvb_pll_desc dvb_pll_tua6034; -extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf; +extern struct dvb_pll_desc dvb_pll_tdvs_tua6034; extern struct dvb_pll_desc dvb_pll_tda665x; extern struct dvb_pll_desc dvb_pll_fmd1216me; extern struct dvb_pll_desc dvb_pll_tded4; @@ -47,18 +44,7 @@ extern struct dvb_pll_desc dvb_pll_philips_td1316; extern struct dvb_pll_desc dvb_pll_thomson_fe6600; -extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, +int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, u32 freq, int bandwidth); -/** - * Attach a dvb-pll to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param pll_addr i2c address of the PLL (if used). - * @param i2c i2c adapter to use (set to NULL if not used). - * @param desc dvb_pll_desc to use. - * @return 0 on success, nonzero on failure. - */ -extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); - #endif diff --git a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c index 6271b1e7f6ab..645946a992d9 100644 --- a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.c @@ -30,6 +30,7 @@ struct dvb_dummy_fe_state { + struct dvb_frontend_ops ops; struct dvb_frontend frontend; }; @@ -76,11 +77,6 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - if (fe->ops->tuner_ops->set_params) { - fe->ops->tuner_ops->set_params(fe, p); - if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); - } - return 0; } @@ -120,8 +116,11 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); if (state == NULL) goto error; + /* setup the state */ + memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); + /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -140,8 +139,11 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach() state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); if (state == NULL) goto error; + /* setup the state */ + memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); + /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -160,8 +162,11 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach() state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); if (state == NULL) goto error; + /* setup the state */ + memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); + /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/isl6421.c b/trunk/drivers/media/dvb/frontends/isl6421.c deleted file mode 100644 index 58c34db31071..000000000000 --- a/trunk/drivers/media/dvb/frontends/isl6421.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "isl6421.h" - -struct isl6421 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - u8 i2c_addr; - void (*release_chain)(struct dvb_frontend* fe); -}; - -static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6421->config |= ISL6421_EN1; - break; - case SEC_VOLTAGE_18: - isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); - break; - default: - return -EINVAL; - }; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - if (arg) - isl6421->config |= ISL6421_LLC1; - else - isl6421->config &= ~ISL6421_LLC1; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void isl6421_release(struct dvb_frontend *fe) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; - - /* power off */ - isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data & call next release routine */ - fe->ops.release = isl6421->release_chain; - kfree(fe->misc_priv); - fe->misc_priv = NULL; - if (fe->ops.release) - fe->ops.release(fe); -} - -int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); - if (!isl6421) - return -ENOMEM; - - /* default configuration */ - isl6421->config = ISL6421_ISEL1; - isl6421->i2c = i2c; - isl6421->i2c_addr = i2c_addr; - fe->misc_priv = isl6421; - - /* bits which should be forced to '1' */ - isl6421->override_or = override_set; - - /* bits which should be forced to '0' */ - isl6421->override_and = ~override_clear; - - /* detect if it is present or not */ - if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(isl6421); - fe->misc_priv = NULL; - return -EIO; - } - - /* install release callback */ - isl6421->release_chain = fe->ops.release; - fe->ops.release = isl6421_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6421_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; - - return 0; -} -EXPORT_SYMBOL(isl6421_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); -MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/isl6421.h b/trunk/drivers/media/dvb/frontends/isl6421.h deleted file mode 100644 index 675f80a19b99..000000000000 --- a/trunk/drivers/media/dvb/frontends/isl6421.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _ISL6421_H -#define _ISL6421_H - -#include - -/* system register bits */ -#define ISL6421_OLF1 0x01 -#define ISL6421_EN1 0x02 -#define ISL6421_VSEL1 0x04 -#define ISL6421_LLC1 0x08 -#define ISL6421_ENT1 0x10 -#define ISL6421_ISEL1 0x20 -#define ISL6421_DCL 0x40 - -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear); - -#endif diff --git a/trunk/drivers/media/dvb/frontends/l64781.c b/trunk/drivers/media/dvb/frontends/l64781.c index f3bc82e44a28..1c7c91224472 100644 --- a/trunk/drivers/media/dvb/frontends/l64781.c +++ b/trunk/drivers/media/dvb/frontends/l64781.c @@ -32,6 +32,7 @@ struct l64781_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct l64781_config* config; struct dvb_frontend frontend; @@ -140,10 +141,7 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa u8 val0x06; int bw = p->bandwidth - BANDWIDTH_8_MHZ; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + state->config->pll_set(fe, param); if (param->inversion != INVERSION_ON && param->inversion != INVERSION_OFF) @@ -465,6 +463,8 @@ static int l64781_init(struct dvb_frontend* fe) /* Everything is two's complement, soft bit and CSI_OUT too */ l64781_writereg (state, 0x1e, 0x09); + if (state->config->pll_init) state->config->pll_init(fe); + /* delay a bit after first init attempt */ if (state->first) { state->first = 0; @@ -508,6 +508,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); state->first = 1; /** @@ -553,7 +554,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/l64781.h b/trunk/drivers/media/dvb/frontends/l64781.h index 83b8bc210274..947f65f87465 100644 --- a/trunk/drivers/media/dvb/frontends/l64781.h +++ b/trunk/drivers/media/dvb/frontends/l64781.h @@ -29,6 +29,10 @@ struct l64781_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; diff --git a/trunk/drivers/media/dvb/frontends/lg_h06xf.h b/trunk/drivers/media/dvb/frontends/lg_h06xf.h deleted file mode 100644 index 754d51d11120..000000000000 --- a/trunk/drivers/media/dvb/frontends/lg_h06xf.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _LG_H06XF_H_ -#define _LG_H06XF_H_ -#include "dvb-pll.h" - -static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, - struct dvb_frontend_parameters* params) -{ - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, - .buf = buf, .len = sizeof(buf) }; - int err; - - dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "lg_h06xf: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, buf[0], buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - /* Set the Auxiliary Byte. */ - buf[0] = buf[2]; - buf[0] &= ~0x20; - buf[0] |= 0x18; - buf[1] = 0x50; - msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "lg_h06xf: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, buf[0], buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} -#endif diff --git a/trunk/drivers/media/dvb/frontends/lgdt330x.c b/trunk/drivers/media/dvb/frontends/lgdt330x.c index 6e8ad176e1a1..4691ac54bc1d 100644 --- a/trunk/drivers/media/dvb/frontends/lgdt330x.c +++ b/trunk/drivers/media/dvb/frontends/lgdt330x.c @@ -29,7 +29,6 @@ * DViCO FusionHDTV 5 Lite * DViCO FusionHDTV 5 USB Gold * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) - * pcHDTV HD5500 * * TODO: * signal strength always returns 0. @@ -60,6 +59,7 @@ if (debug) printk(KERN_DEBUG "lgdt330x: " args); \ struct lgdt330x_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* Configuration settings */ const struct lgdt330x_config* config; @@ -399,10 +399,8 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, } /* Tune to the specified frequency */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + if (state->config->pll_set) + state->config->pll_set(fe, param); /* Keep track of the new frequency */ /* FIXME this is the wrong way to do this... */ @@ -674,7 +672,6 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) if (state->current_modulation == VSB_8) { - i2c_read_demod_bytes(state, 0x6e, buf, 5); /* Phase Tracker Mean-Square Error Register for VSB */ noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; } else { @@ -724,19 +721,16 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, /* Setup the state */ state->config = config; state->i2c = i2c; - - /* Create dvb_frontend */ switch (config->demod_chip) { case LGDT3302: - memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); break; case LGDT3303: - memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); break; default: goto error; } - state->frontend.demodulator_priv = state; /* Verify communication with demod chip */ if (i2c_read_demod_bytes(state, 2, buf, 1)) @@ -745,6 +739,9 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, state->current_frequency = -1; state->current_modulation = -1; + /* Create dvb_frontend */ + state->frontend.ops = &state->ops; + state->frontend.demodulator_priv = state; return &state->frontend; error: diff --git a/trunk/drivers/media/dvb/frontends/lgdt330x.h b/trunk/drivers/media/dvb/frontends/lgdt330x.h index bad903c6f0f8..2a6529cccf1a 100644 --- a/trunk/drivers/media/dvb/frontends/lgdt330x.h +++ b/trunk/drivers/media/dvb/frontends/lgdt330x.h @@ -43,6 +43,7 @@ struct lgdt330x_config /* PLL interface */ int (*pll_rf_set) (struct dvb_frontend* fe, int index); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); /* Need to set device param for start_dma */ int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.c b/trunk/drivers/media/dvb/frontends/lnbp21.c deleted file mode 100644 index e933edc8dd29..000000000000 --- a/trunk/drivers/media/dvb/frontends/lnbp21.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * lnbp21.h - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "lnbp21.h" - -struct lnbp21 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - void (*release_chain)(struct dvb_frontend* fe); -}; - -static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - lnbp21->config |= LNBP21_EN; - break; - case SEC_VOLTAGE_18: - lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); - break; - default: - return -EINVAL; - }; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - if (arg) - lnbp21->config |= LNBP21_LLC; - else - lnbp21->config &= ~LNBP21_LLC; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void lnbp21_release(struct dvb_frontend *fe) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - - /* LNBP power off */ - lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data & call next release routine */ - fe->ops.release = lnbp21->release_chain; - kfree(fe->misc_priv); - fe->misc_priv = NULL; - if (fe->ops.release) - fe->ops.release(fe); -} - -int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) -{ - struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); - if (!lnbp21) - return -ENOMEM; - - /* default configuration */ - lnbp21->config = LNBP21_ISEL; - lnbp21->i2c = i2c; - fe->misc_priv = lnbp21; - - /* bits which should be forced to '1' */ - lnbp21->override_or = override_set; - - /* bits which should be forced to '0' */ - lnbp21->override_and = ~override_clear; - - /* detect if it is present or not */ - if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(lnbp21); - fe->misc_priv = NULL; - return -EIO; - } - - /* install release callback */ - lnbp21->release_chain = fe->ops.release; - fe->ops.release = lnbp21_release; - - /* override frontend ops */ - fe->ops.set_voltage = lnbp21_set_voltage; - fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - - return 0; -} -EXPORT_SYMBOL(lnbp21_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); -MODULE_AUTHOR("Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.h b/trunk/drivers/media/dvb/frontends/lnbp21.h index 047a4ab68c01..0dcbe61b61b1 100644 --- a/trunk/drivers/media/dvb/frontends/lnbp21.h +++ b/trunk/drivers/media/dvb/frontends/lnbp21.h @@ -27,7 +27,7 @@ #ifndef _LNBP21_H #define _LNBP21_H -/* system register bits */ +/* system register */ #define LNBP21_OLF 0x01 #define LNBP21_OTF 0x02 #define LNBP21_EN 0x04 @@ -37,9 +37,103 @@ #define LNBP21_ISEL 0x40 #define LNBP21_PCL 0x80 -#include +struct lnbp21 { + u8 config; + u8 override_or; + u8 override_and; + struct i2c_adapter *i2c; + void (*release_chain)(struct dvb_frontend* fe); +}; -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); +static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, + .buf = &lnbp21->config, + .len = sizeof(lnbp21->config) }; + + lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); + + switch(voltage) { + case SEC_VOLTAGE_OFF: + break; + case SEC_VOLTAGE_13: + lnbp21->config |= LNBP21_EN; + break; + case SEC_VOLTAGE_18: + lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); + break; + default: + return -EINVAL; + }; + + lnbp21->config |= lnbp21->override_or; + lnbp21->config &= lnbp21->override_and; + + return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; +} + +static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) +{ + struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, + .buf = &lnbp21->config, + .len = sizeof(lnbp21->config) }; + + if (arg) + lnbp21->config |= LNBP21_LLC; + else + lnbp21->config &= ~LNBP21_LLC; + + lnbp21->config |= lnbp21->override_or; + lnbp21->config &= lnbp21->override_and; + + return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; +} + +static void lnbp21_exit(struct dvb_frontend *fe) +{ + struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; + + /* LNBP power off */ + lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); + + /* free data & call next release routine */ + fe->ops->release = lnbp21->release_chain; + kfree(fe->misc_priv); + fe->misc_priv = NULL; + if (fe->ops->release) + fe->ops->release(fe); +} + +static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) +{ + struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); + + if (!lnbp21) + return -ENOMEM; + + /* default configuration */ + lnbp21->config = LNBP21_ISEL; + + /* bits which should be forced to '1' */ + lnbp21->override_or = override_set; + + /* bits which should be forced to '0' */ + lnbp21->override_and = ~override_clear; + + /* install release callback */ + lnbp21->release_chain = fe->ops->release; + fe->ops->release = lnbp21_exit; + + /* override frontend ops */ + fe->ops->set_voltage = lnbp21_set_voltage; + fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; + + lnbp21->i2c = i2c; + fe->misc_priv = lnbp21; + + return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); +} #endif diff --git a/trunk/drivers/media/dvb/frontends/mt312.c b/trunk/drivers/media/dvb/frontends/mt312.c index 1ef821825641..d3aea83cf218 100644 --- a/trunk/drivers/media/dvb/frontends/mt312.c +++ b/trunk/drivers/media/dvb/frontends/mt312.c @@ -39,6 +39,7 @@ struct mt312_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct mt312_config* config; struct dvb_frontend frontend; @@ -276,6 +277,12 @@ static int mt312_initfe(struct dvb_frontend* fe) if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) return ret; + if (state->config->pll_init) { + mt312_writereg(state, GPP_CTRL, 0x40); + state->config->pll_init(fe); + mt312_writereg(state, GPP_CTRL, 0x00); + } + return 0; } @@ -470,16 +477,16 @@ static int mt312_set_frontend(struct dvb_frontend* fe, dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); - if ((p->frequency < fe->ops.info.frequency_min) - || (p->frequency > fe->ops.info.frequency_max)) + if ((p->frequency < fe->ops->info.frequency_min) + || (p->frequency > fe->ops->info.frequency_max)) return -EINVAL; if ((p->inversion < INVERSION_OFF) || (p->inversion > INVERSION_ON)) return -EINVAL; - if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) - || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) + if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min) + || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max)) return -EINVAL; if ((p->u.qpsk.fec_inner < FEC_NONE) @@ -522,10 +529,9 @@ static int mt312_set_frontend(struct dvb_frontend* fe, return -EINVAL; } - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + mt312_writereg(state, GPP_CTRL, 0x40); + state->config->pll_set(fe, p); + mt312_writereg(state, GPP_CTRL, 0x00); /* sr = (u16)(sr * 256.0 / 1000000.0) */ sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); @@ -572,17 +578,6 @@ static int mt312_get_frontend(struct dvb_frontend* fe, return 0; } -static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct mt312_state* state = fe->demodulator_priv; - - if (enable) { - return mt312_writereg(state, GPP_CTRL, 0x40); - } else { - return mt312_writereg(state, GPP_CTRL, 0x00); - } -} - static int mt312_sleep(struct dvb_frontend* fe) { struct mt312_state *state = fe->demodulator_priv; @@ -638,7 +633,6 @@ static struct dvb_frontend_ops vp310_mt312_ops = { .init = mt312_initfe, .sleep = mt312_sleep, - .i2c_gate_ctrl = mt312_i2c_gate_ctrl, .set_frontend = mt312_set_frontend, .get_frontend = mt312_get_frontend, @@ -669,22 +663,19 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if (mt312_readreg(state, ID, &state->id) < 0) goto error; - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - switch (state->id) { case ID_VP310: - strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); + strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); state->frequency = 90; break; case ID_MT312: - strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); + strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); state->frequency = 60; break; default: @@ -692,6 +683,9 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, goto error; } + /* create dvb_frontend */ + state->frontend.ops = &state->ops; + state->frontend.demodulator_priv = state; return &state->frontend; error: diff --git a/trunk/drivers/media/dvb/frontends/mt312.h b/trunk/drivers/media/dvb/frontends/mt312.h index 666a1bd1c244..074d844f0139 100644 --- a/trunk/drivers/media/dvb/frontends/mt312.h +++ b/trunk/drivers/media/dvb/frontends/mt312.h @@ -32,6 +32,10 @@ struct mt312_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, diff --git a/trunk/drivers/media/dvb/frontends/mt352.c b/trunk/drivers/media/dvb/frontends/mt352.c index 5de7376c94ce..aaaec909ddf8 100644 --- a/trunk/drivers/media/dvb/frontends/mt352.c +++ b/trunk/drivers/media/dvb/frontends/mt352.c @@ -45,6 +45,7 @@ struct mt352_state { struct i2c_adapter* i2c; struct dvb_frontend frontend; + struct dvb_frontend_ops ops; /* configuration settings */ struct mt352_config config; @@ -285,25 +286,16 @@ static int mt352_set_parameters(struct dvb_frontend* fe, mt352_calc_nominal_rate(state, op->bandwidth, buf+4); mt352_calc_input_freq(state, buf+6); + state->config.pll_set(fe, param, buf+8); + mt352_write(fe, buf, sizeof(buf)); if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - mt352_write(fe, buf, 8); + /* start decoding */ mt352_write(fe, fsm_go, 2); } else { - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); - buf[8] <<= 1; - mt352_write(fe, buf, sizeof(buf)); - mt352_write(fe, tuner_go, 2); - } + /* start tuning */ + mt352_write(fe, tuner_go, 2); } - return 0; } @@ -549,12 +541,13 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config, /* setup the state */ state->i2c = i2c; memcpy(&state->config,config,sizeof(struct mt352_config)); + memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/mt352.h b/trunk/drivers/media/dvb/frontends/mt352.h index 9e7ff4b8fe5f..03040cd595bb 100644 --- a/trunk/drivers/media/dvb/frontends/mt352.h +++ b/trunk/drivers/media/dvb/frontends/mt352.h @@ -49,6 +49,12 @@ struct mt352_config /* Initialise the demodulator and PLL. Cannot be NULL */ int (*demod_init)(struct dvb_frontend* fe); + + /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings. + * byte0: Set to pll i2c address (nonlinux; left shifted by 1) + * byte1-4: PLL configuration. + */ + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf); }; extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, diff --git a/trunk/drivers/media/dvb/frontends/nxt200x.c b/trunk/drivers/media/dvb/frontends/nxt200x.c index 55671cb5255e..9e3535394509 100644 --- a/trunk/drivers/media/dvb/frontends/nxt200x.c +++ b/trunk/drivers/media/dvb/frontends/nxt200x.c @@ -55,6 +55,7 @@ struct nxt200x_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct nxt200x_config* config; struct dvb_frontend frontend; @@ -332,17 +333,17 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) dprintk("%s\n", __FUNCTION__); - dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); + dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. * direct write is required for Philips TUV1236D and ALPS TDHU2 */ switch (state->demod_chip) { case NXT2004: - if (i2c_writebytes(state, data[0], data+1, 4)) + if (i2c_writebytes(state, state->config->pll_address, data, 4)) printk(KERN_WARNING "nxt200x: error writing to tuner\n"); /* wait until we have a lock */ while (count < 20) { - i2c_readbytes(state, data[0], &buf, 1); + i2c_readbytes(state, state->config->pll_address, &buf, 1); if (buf & 0x40) return 0; msleep(100); @@ -360,10 +361,10 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) nxt200x_writebytes(state, 0x34, &buf, 1); /* write actual tuner bytes */ - nxt200x_writebytes(state, 0x36, data+1, 4); + nxt200x_writebytes(state, 0x36, data, 4); /* set tuner i2c address */ - buf = data[0] << 1; + buf = state->config->pll_address; nxt200x_writebytes(state, 0x35, &buf, 1); /* write UC Opmode to begin transfer */ @@ -533,7 +534,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[5]; + u8 buf[4]; /* stop the micro first */ nxt200x_microcontroller_stop(state); @@ -547,9 +548,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, } /* get tuning information */ - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); - } + dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0); /* set additional params */ switch (p->u.vsb.modulation) { @@ -1160,6 +1159,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; /* read card id */ @@ -1198,7 +1198,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/nxt200x.h b/trunk/drivers/media/dvb/frontends/nxt200x.h index 34d61735845b..1d9d70bc37ef 100644 --- a/trunk/drivers/media/dvb/frontends/nxt200x.h +++ b/trunk/drivers/media/dvb/frontends/nxt200x.h @@ -38,6 +38,10 @@ struct nxt200x_config /* the demodulator's i2c address */ u8 demod_address; + /* tuner information */ + u8 pll_address; + struct dvb_pll_desc *pll_desc; + /* used to set pll input */ int (*set_pll_input)(u8* buf, int input); diff --git a/trunk/drivers/media/dvb/frontends/nxt6000.c b/trunk/drivers/media/dvb/frontends/nxt6000.c index d313d7dcf386..a16eeba0020d 100644 --- a/trunk/drivers/media/dvb/frontends/nxt6000.c +++ b/trunk/drivers/media/dvb/frontends/nxt6000.c @@ -33,6 +33,7 @@ struct nxt6000_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct nxt6000_config* config; struct dvb_frontend frontend; @@ -206,6 +207,12 @@ static void nxt6000_setup(struct dvb_frontend* fe) nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); nxt6000_writereg(state, TS_FORMAT, 0); + + if (state->config->pll_init) { + nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ + state->config->pll_init(fe); + nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ + } } static void nxt6000_dump_status(struct nxt6000_state *state) @@ -462,10 +469,9 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par struct nxt6000_state* state = fe->demodulator_priv; int result; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ + state->config->pll_set(fe, param); + nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) return result; @@ -526,17 +532,6 @@ static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron return 0; } -static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - if (enable) { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); - } else { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); - } -} - static struct dvb_frontend_ops nxt6000_ops; struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, @@ -551,12 +546,13 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -588,7 +584,6 @@ static struct dvb_frontend_ops nxt6000_ops = { .release = nxt6000_release, .init = nxt6000_init, - .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl, .get_tune_settings = nxt6000_fe_get_tune_settings, diff --git a/trunk/drivers/media/dvb/frontends/nxt6000.h b/trunk/drivers/media/dvb/frontends/nxt6000.h index 117031d11708..b7d9bead3002 100644 --- a/trunk/drivers/media/dvb/frontends/nxt6000.h +++ b/trunk/drivers/media/dvb/frontends/nxt6000.h @@ -31,6 +31,10 @@ struct nxt6000_config /* should clock inversion be used? */ u8 clock_inversion:1; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, diff --git a/trunk/drivers/media/dvb/frontends/or51132.c b/trunk/drivers/media/dvb/frontends/or51132.c index d20ab30c1e83..80e0f28127b7 100644 --- a/trunk/drivers/media/dvb/frontends/or51132.c +++ b/trunk/drivers/media/dvb/frontends/or51132.c @@ -54,6 +54,7 @@ static int debug; struct or51132_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* Configuration settings */ const struct or51132_config* config; @@ -105,8 +106,9 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware { struct or51132_state* state = fe->demodulator_priv; static u8 run_buf[] = {0x7F,0x01}; - u8 rec_buf[8]; - u8 cmd_buf[3]; + static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; + u8 rec_buf[14]; + u8 cmd_buf[14]; u32 firmwareAsize, firmwareBsize; int i,ret; @@ -155,6 +157,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x10; cmd_buf[1] = 0x10; cmd_buf[2] = 0x00; + cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { @@ -164,6 +167,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x04; cmd_buf[1] = 0x17; + cmd_buf[2] = 0x00; + cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { @@ -173,6 +178,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x00; cmd_buf[1] = 0x00; + cmd_buf[2] = 0x00; + cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { @@ -182,11 +189,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware for(i=0;i<4;i++) { msleep(20); /* 20ms */ - /* Once upon a time, this command might have had something - to do with getting the firmware version, but it's - not used anymore: - {0x04,0x00,0x30,0x00,i+1} */ - /* Read 8 bytes, two bytes at a time */ + get_ver_buf[4] = i+1; if ((ret = i2c_readbytes(state,state->config->demod_address, &rec_buf[i*2],2))) { printk(KERN_WARNING @@ -205,6 +208,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware cmd_buf[0] = 0x10; cmd_buf[1] = 0x00; cmd_buf[2] = 0x00; + cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { @@ -239,7 +243,7 @@ static int or51132_sleep(struct dvb_frontend* fe) static int or51132_setmode(struct dvb_frontend* fe) { struct or51132_state* state = fe->demodulator_priv; - unsigned char cmd_buf[3]; + unsigned char cmd_buf[4]; dprintk("setmode %d\n",(int)state->current_modulation); /* set operation mode in Receiver 1 register; */ @@ -259,6 +263,7 @@ static int or51132_setmode(struct dvb_frontend* fe) default: printk("setmode:Modulation set to unsupported value\n"); }; + cmd_buf[3] = 0x00; if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { printk(KERN_WARNING "or51132: set_mode error 1\n"); @@ -296,6 +301,7 @@ static int or51132_setmode(struct dvb_frontend* fe) default: printk("setmode: Modulation set to unsupported value\n"); }; + cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { @@ -307,65 +313,52 @@ static int or51132_setmode(struct dvb_frontend* fe) return 0; } -/* Some modulations use the same firmware. This classifies modulations - by the firmware they use. */ -#define MOD_FWCLASS_UNKNOWN 0 -#define MOD_FWCLASS_VSB 1 -#define MOD_FWCLASS_QAM 2 -static int modulation_fw_class(fe_modulation_t modulation) -{ - switch(modulation) { - case VSB_8: - return MOD_FWCLASS_VSB; - case QAM_AUTO: - case QAM_64: - case QAM_256: - return MOD_FWCLASS_QAM; - default: - return MOD_FWCLASS_UNKNOWN; - } -} - static int or51132_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) { int ret; + u8 buf[4]; struct or51132_state* state = fe->demodulator_priv; const struct firmware *fw; - const char *fwname; - int clock_mode; - - /* Upload new firmware only if we need a different one */ - if (modulation_fw_class(state->current_modulation) != - modulation_fw_class(param->u.vsb.modulation)) { - switch(modulation_fw_class(param->u.vsb.modulation)) { - case MOD_FWCLASS_VSB: - dprintk("set_parameters VSB MODE\n"); - fwname = OR51132_VSB_FIRMWARE; + /* Change only if we are actually changing the modulation */ + if (state->current_modulation != param->u.vsb.modulation) { + switch(param->u.vsb.modulation) { + case VSB_8: + dprintk("set_parameters VSB MODE\n"); + printk("or51132: Waiting for firmware upload(%s)...\n", + OR51132_VSB_FIRMWARE); + ret = request_firmware(&fw, OR51132_VSB_FIRMWARE, + &state->i2c->dev); + if (ret){ + printk(KERN_WARNING "or51132: No firmware up" + "loaded(timeout or file not found?)\n"); + return ret; + } /* Set non-punctured clock for VSB */ - clock_mode = 0; + state->config->set_ts_params(fe, 0); break; - case MOD_FWCLASS_QAM: + case QAM_AUTO: + case QAM_64: + case QAM_256: dprintk("set_parameters QAM MODE\n"); - fwname = OR51132_QAM_FIRMWARE; - + printk("or51132: Waiting for firmware upload(%s)...\n", + OR51132_QAM_FIRMWARE); + ret = request_firmware(&fw, OR51132_QAM_FIRMWARE, + &state->i2c->dev); + if (ret){ + printk(KERN_WARNING "or51132: No firmware up" + "loaded(timeout or file not found?)\n"); + return ret; + } /* Set punctured clock for QAM */ - clock_mode = 1; + state->config->set_ts_params(fe, 1); break; default: - printk("or51132: Modulation type(%d) UNSUPPORTED\n", + printk("or51132:Modulation type(%d) UNSUPPORTED\n", param->u.vsb.modulation); return -1; - } - printk("or51132: Waiting for firmware upload(%s)...\n", - fwname); - ret = request_firmware(&fw, fwname, &state->i2c->dev); - if (ret) { - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); - return ret; - } + }; ret = or51132_load_firmware(fe, fw); release_firmware(fw); if (ret) { @@ -374,18 +367,18 @@ static int or51132_set_parameters(struct dvb_frontend* fe, return ret; } printk("or51132: Firmware upload complete.\n"); - state->config->set_ts_params(fe, clock_mode); - } - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { + state->current_modulation = param->u.vsb.modulation; or51132_setmode(fe); } - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + dvb_pll_configure(state->config->pll_desc, buf, + param->frequency, 0); + dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " + "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); + if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) + printk(KERN_WARNING "or51132: set_parameters error " + "writing to tuner\n"); /* Set to current mode */ or51132_setmode(fe); @@ -395,44 +388,6 @@ static int or51132_set_parameters(struct dvb_frontend* fe, return 0; } -static int or51132_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct or51132_state* state = fe->demodulator_priv; - u8 buf[2]; - - /* Receiver Status */ - buf[0]=0x04; - buf[1]=0x00; - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,buf,2)) { - printk(KERN_WARNING "or51132: get_parameters write error\n"); - return -EREMOTEIO; - } - msleep(30); /* 30ms */ - if (i2c_readbytes(state,state->config->demod_address,buf,2)) { - printk(KERN_WARNING "or51132: get_parameters read error\n"); - return -EREMOTEIO; - } - switch(buf[0]) { - case 0x06: param->u.vsb.modulation = VSB_8; break; - case 0x43: param->u.vsb.modulation = QAM_64; break; - case 0x45: param->u.vsb.modulation = QAM_256; break; - default: - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", - buf[0]); - return -EREMOTEIO; - } - - /* FIXME: Read frequency from frontend, take AFC into account */ - param->frequency = state->current_frequency; - - /* FIXME: How to read inversion setting? Receiver 6 register? */ - param->inversion = INVERSION_AUTO; - - return 0; -} - static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) { struct or51132_state* state = fe->demodulator_priv; @@ -617,11 +572,12 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, /* Setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); state->current_frequency = -1; state->current_modulation = -1; /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -634,7 +590,7 @@ static struct dvb_frontend_ops or51132_ops = { .info = { .name = "Oren OR51132 VSB/QAM Frontend", - .type = FE_ATSC, + .type = FE_ATSC, .frequency_min = 44000000, .frequency_max = 958000000, .frequency_stepsize = 166666, @@ -650,7 +606,6 @@ static struct dvb_frontend_ops or51132_ops = { .sleep = or51132_sleep, .set_frontend = or51132_set_parameters, - .get_frontend = or51132_get_parameters, .get_tune_settings = or51132_get_tune_settings, .read_status = or51132_read_status, diff --git a/trunk/drivers/media/dvb/frontends/or51132.h b/trunk/drivers/media/dvb/frontends/or51132.h index 89658883abf5..622cdd18381b 100644 --- a/trunk/drivers/media/dvb/frontends/or51132.h +++ b/trunk/drivers/media/dvb/frontends/or51132.h @@ -29,6 +29,8 @@ struct or51132_config { /* The demodulator's i2c address */ u8 demod_address; + u8 pll_address; + struct dvb_pll_desc *pll_desc; /* Need to set device param for start_dma */ int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); diff --git a/trunk/drivers/media/dvb/frontends/or51211.c b/trunk/drivers/media/dvb/frontends/or51211.c index 26bed616fabe..7c3aed1f546b 100644 --- a/trunk/drivers/media/dvb/frontends/or51211.c +++ b/trunk/drivers/media/dvb/frontends/or51211.c @@ -54,6 +54,7 @@ static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC struct or51211_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* Configuration settings */ const struct or51211_config* config; @@ -584,11 +585,12 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, /* Setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); state->initialized = 0; state->current_frequency = 0; /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/s5h1420.c b/trunk/drivers/media/dvb/frontends/s5h1420.c index 2c2c344c4c64..d69477596921 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1420.c +++ b/trunk/drivers/media/dvb/frontends/s5h1420.c @@ -38,6 +38,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. struct s5h1420_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct s5h1420_config* config; struct dvb_frontend frontend; @@ -583,6 +584,7 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct s5h1420_state* state = fe->demodulator_priv; int frequency_delta; struct dvb_frontend_tune_settings fesettings; + u32 tmp; /* check if we should do a fast-tune */ memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); @@ -594,17 +596,10 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, (state->fec_inner == p->u.qpsk.fec_inner) && (state->symbol_rate == p->u.qpsk.symbol_rate)) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - u32 tmp; - fe->ops.tuner_ops.get_frequency(fe, &tmp); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (state->config->pll_set) { + s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); + state->config->pll_set(fe, p, &tmp); s5h1420_setfreqoffset(state, p->frequency - tmp); - } else { - s5h1420_setfreqoffset(state, 0); } return 0; } @@ -651,9 +646,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); /* set tuner PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (state->config->pll_set) { + s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); + state->config->pll_set(fe, p, &tmp); s5h1420_setfreqoffset(state, 0); } @@ -713,17 +708,6 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe, return 0; } -static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - if (enable) { - return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); - } else { - return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); - } -} - static int s5h1420_init (struct dvb_frontend* fe) { struct s5h1420_state* state = fe->demodulator_priv; @@ -733,6 +717,13 @@ static int s5h1420_init (struct dvb_frontend* fe) msleep(10); s5h1420_reset(state); + /* init PLL */ + if (state->config->pll_init) { + s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); + state->config->pll_init(fe); + s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); + } + return 0; } @@ -765,6 +756,7 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); state->postlocked = 0; state->fclk = 88000000; state->tunedfreq = 0; @@ -777,7 +769,7 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -808,7 +800,6 @@ static struct dvb_frontend_ops s5h1420_ops = { .init = s5h1420_init, .sleep = s5h1420_sleep, - .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl, .set_frontend = s5h1420_set_frontend, .get_frontend = s5h1420_get_frontend, diff --git a/trunk/drivers/media/dvb/frontends/s5h1420.h b/trunk/drivers/media/dvb/frontends/s5h1420.h index 4e39015fa67e..73296f13c324 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1420.h +++ b/trunk/drivers/media/dvb/frontends/s5h1420.h @@ -32,6 +32,10 @@ struct s5h1420_config /* does the inversion require inversion? */ u8 invert:1; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout); }; extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, diff --git a/trunk/drivers/media/dvb/frontends/sp8870.c b/trunk/drivers/media/dvb/frontends/sp8870.c index 44ec5b9a4695..73829e647e50 100644 --- a/trunk/drivers/media/dvb/frontends/sp8870.c +++ b/trunk/drivers/media/dvb/frontends/sp8870.c @@ -44,6 +44,8 @@ struct sp8870_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; + const struct sp8870_config* config; struct dvb_frontend frontend; @@ -260,10 +262,9 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, sp8870_microcontroller_stop(state); // set tuner parameters - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + sp8870_writereg(state, 0x206, 0x001); + state->config->pll_set(fe, p); + sp8870_writereg(state, 0x206, 0x000); // sample rate correction bit [23..17] sp8870_writereg(state, 0x0319, 0x000A); @@ -348,6 +349,13 @@ static int sp8870_init (struct dvb_frontend* fe) sp8870_writereg(state, 0x0D00, 0x010); sp8870_writereg(state, 0x0D01, 0x000); + /* setup PLL */ + if (state->config->pll_init) { + sp8870_writereg(state, 0x206, 0x001); + state->config->pll_init(fe); + sp8870_writereg(state, 0x206, 0x000); + } + return 0; } @@ -533,17 +541,6 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend return 0; } -static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct sp8870_state* state = fe->demodulator_priv; - - if (enable) { - return sp8870_writereg(state, 0x206, 0x001); - } else { - return sp8870_writereg(state, 0x206, 0x000); - } -} - static void sp8870_release(struct dvb_frontend* fe) { struct sp8870_state* state = fe->demodulator_priv; @@ -564,13 +561,14 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; /* check if the demod is there */ if (sp8870_readreg(state, 0x0200) < 0) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -599,7 +597,6 @@ static struct dvb_frontend_ops sp8870_ops = { .init = sp8870_init, .sleep = sp8870_sleep, - .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, .set_frontend = sp8870_set_frontend, .get_tune_settings = sp8870_get_tune_settings, diff --git a/trunk/drivers/media/dvb/frontends/sp8870.h b/trunk/drivers/media/dvb/frontends/sp8870.h index 93afbb969d6b..f3b555dbc960 100644 --- a/trunk/drivers/media/dvb/frontends/sp8870.h +++ b/trunk/drivers/media/dvb/frontends/sp8870.h @@ -31,6 +31,10 @@ struct sp8870_config /* the demodulator's i2c address */ u8 demod_address; + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + /* request firmware for device */ int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; diff --git a/trunk/drivers/media/dvb/frontends/sp887x.c b/trunk/drivers/media/dvb/frontends/sp887x.c index b0a2b02f6608..eb8a602198ca 100644 --- a/trunk/drivers/media/dvb/frontends/sp887x.c +++ b/trunk/drivers/media/dvb/frontends/sp887x.c @@ -24,6 +24,7 @@ struct sp887x_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct sp887x_config* config; struct dvb_frontend frontend; @@ -207,6 +208,15 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware /* bit 0x010: enable data valid signal */ sp887x_writereg(state, 0xd00, 0x010); sp887x_writereg(state, 0x0d1, 0x000); + + /* setup the PLL */ + if (state->config->pll_init) { + sp887x_writereg(state, 0x206, 0x001); + state->config->pll_init(fe); + sp887x_writereg(state, 0x206, 0x000); + } + + printk ("done.\n"); return 0; }; @@ -352,16 +362,9 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, sp887x_microcontroller_stop(state); /* setup the PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - fe->ops.tuner_ops.get_frequency(fe, &actual_freq); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } else { - actual_freq = p->frequency; - } + sp887x_writereg(state, 0x206, 0x001); + actual_freq = state->config->pll_set(fe, p); + sp887x_writereg(state, 0x206, 0x000); /* read status reg in order to clear demodulator_priv; - - if (enable) { - return sp887x_writereg(state, 0x206, 0x001); - } else { - return sp887x_writereg(state, 0x206, 0x000); - } -} - static int sp887x_sleep(struct dvb_frontend* fe) { struct sp887x_state* state = fe->demodulator_priv; @@ -563,13 +555,14 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; /* check if the demod is there */ if (sp887x_readreg(state, 0x0200) < 0) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -596,7 +589,6 @@ static struct dvb_frontend_ops sp887x_ops = { .init = sp887x_init, .sleep = sp887x_sleep, - .i2c_gate_ctrl = sp887x_i2c_gate_ctrl, .set_frontend = sp887x_setup_frontend_parameters, .get_tune_settings = sp887x_get_tune_settings, diff --git a/trunk/drivers/media/dvb/frontends/sp887x.h b/trunk/drivers/media/dvb/frontends/sp887x.h index c44b0ebdf1e2..6a05d8f8e8cc 100644 --- a/trunk/drivers/media/dvb/frontends/sp887x.h +++ b/trunk/drivers/media/dvb/frontends/sp887x.h @@ -13,6 +13,12 @@ struct sp887x_config /* the demodulator's i2c address */ u8 demod_address; + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + + /* this should return the actual frequency tuned to */ + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + /* request firmware for device */ int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); }; diff --git a/trunk/drivers/media/dvb/frontends/stv0297.c b/trunk/drivers/media/dvb/frontends/stv0297.c index 1ca64249010c..eb15676d374f 100644 --- a/trunk/drivers/media/dvb/frontends/stv0297.c +++ b/trunk/drivers/media/dvb/frontends/stv0297.c @@ -32,6 +32,7 @@ struct stv0297_state { struct i2c_adapter *i2c; + struct dvb_frontend_ops ops; const struct stv0297_config *config; struct dvb_frontend frontend; @@ -67,25 +68,19 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg) int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; + struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = + 1}, + {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} + }; // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } + if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + return -1; + } + if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + return -1; } return b1[0]; @@ -112,20 +107,13 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len }; // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } + if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + return -1; + } + if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + return -1; } return 0; @@ -288,14 +276,12 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers return 0; } -static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +int stv0297_enable_plli2c(struct dvb_frontend *fe) { struct stv0297_state *state = fe->demodulator_priv; - if (enable) { - stv0297_writereg(state, 0x87, 0x78); - stv0297_writereg(state, 0x86, 0xc8); - } + stv0297_writereg(state, 0x87, 0x78); + stv0297_writereg(state, 0x86, 0xc8); return 0; } @@ -310,6 +296,9 @@ static int stv0297_init(struct dvb_frontend *fe) stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); msleep(200); + if (state->config->pll_init) + state->config->pll_init(fe); + return 0; } @@ -400,7 +389,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par case QAM_32: case QAM_64: delay = 100; - sweeprate = 1000; + sweeprate = 1500; break; case QAM_128: @@ -432,10 +421,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par } stv0297_init(fe); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + state->config->pll_set(fe, p); /* clear software interrupts */ stv0297_writereg(state, 0x82, 0x0); @@ -648,6 +634,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); state->base_freq = 0; /* check if the demod is there */ @@ -655,7 +642,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -681,7 +668,6 @@ static struct dvb_frontend_ops stv0297_ops = { .init = stv0297_init, .sleep = stv0297_sleep, - .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, .set_frontend = stv0297_set_frontend, .get_frontend = stv0297_get_frontend, @@ -698,3 +684,4 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); MODULE_LICENSE("GPL"); EXPORT_SYMBOL(stv0297_attach); +EXPORT_SYMBOL(stv0297_enable_plli2c); diff --git a/trunk/drivers/media/dvb/frontends/stv0297.h b/trunk/drivers/media/dvb/frontends/stv0297.h index 1da5384fb985..9e53f019db71 100644 --- a/trunk/drivers/media/dvb/frontends/stv0297.h +++ b/trunk/drivers/media/dvb/frontends/stv0297.h @@ -38,11 +38,13 @@ struct stv0297_config /* does the "inversion" need inverted? */ u8 invert:1; - /* set to 1 if the device requires an i2c STOP during reading */ - u8 stop_during_read:1; + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, struct i2c_adapter* i2c); +extern int stv0297_enable_plli2c(struct dvb_frontend* fe); #endif // STV0297_H diff --git a/trunk/drivers/media/dvb/frontends/stv0299.c b/trunk/drivers/media/dvb/frontends/stv0299.c index 96648a75440d..5bcd00f792e6 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.c +++ b/trunk/drivers/media/dvb/frontends/stv0299.c @@ -56,6 +56,7 @@ struct stv0299_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct stv0299_config* config; struct dvb_frontend frontend; @@ -130,6 +131,13 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len return ret == 2 ? 0 : ret; } +int stv0299_enable_plli2c (struct dvb_frontend* fe) +{ + struct stv0299_state* state = fe->demodulator_priv; + + return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ +} + static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -449,6 +457,12 @@ static int stv0299_init (struct dvb_frontend* fe) for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); + if (state->config->pll_init) { + stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ + state->config->pll_init(fe, state->i2c); + stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ + } + return 0; } @@ -546,10 +560,9 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par if (state->config->invert) invval = (~invval) & 1; stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ + state->config->pll_set(fe, state->i2c, p); + stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ stv0299_set_FEC (state, p->u.qpsk.fec_inner); stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); @@ -598,19 +611,6 @@ static int stv0299_sleep(struct dvb_frontend* fe) return 0; } -static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (enable) { - stv0299_writeregI(state, 0x05, 0xb5); - } else { - stv0299_writeregI(state, 0x05, 0x35); - } - udelay(1); - return 0; -} - static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { struct stv0299_state* state = fe->demodulator_priv; @@ -647,6 +647,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->tuner_frequency = 0; state->symbol_rate = 0; @@ -663,7 +664,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, if (id != 0xa1 && id != 0x80) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -694,7 +695,6 @@ static struct dvb_frontend_ops stv0299_ops = { .init = stv0299_init, .sleep = stv0299_sleep, - .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, .set_frontend = stv0299_set_frontend, .get_frontend = stv0299_get_frontend, @@ -721,8 +721,9 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " - "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); + "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(stv0299_enable_plli2c); EXPORT_SYMBOL(stv0299_writereg); EXPORT_SYMBOL(stv0299_attach); diff --git a/trunk/drivers/media/dvb/frontends/stv0299.h b/trunk/drivers/media/dvb/frontends/stv0299.h index 1504828e4232..32c87b4c2f13 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.h +++ b/trunk/drivers/media/dvb/frontends/stv0299.h @@ -87,9 +87,14 @@ struct stv0299_config /* Set the symbol rate */ int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c); + int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params); }; extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); +extern int stv0299_enable_plli2c (struct dvb_frontend* fe); extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c); diff --git a/trunk/drivers/media/dvb/frontends/tda10021.c b/trunk/drivers/media/dvb/frontends/tda10021.c index e83ff2104c9b..21255cac9793 100644 --- a/trunk/drivers/media/dvb/frontends/tda10021.c +++ b/trunk/drivers/media/dvb/frontends/tda10021.c @@ -36,6 +36,7 @@ struct tda10021_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct tda10021_config* config; struct dvb_frontend frontend; @@ -89,14 +90,6 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data) -{ - struct tda10021_state* state = fe->demodulator_priv; - - return tda10021_writereg(state, reg, data); -} -EXPORT_SYMBOL(tda10021_write_byte); - static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) { u8 b0 [] = { reg }; @@ -232,6 +225,13 @@ static int tda10021_init (struct dvb_frontend *fe) //Activate PLL tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); + + if (state->config->pll_init) { + lock_tuner(state); + state->config->pll_init(fe); + unlock_tuner(state); + } + return 0; } @@ -259,10 +259,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + lock_tuner(state); + state->config->pll_set(fe, p); + unlock_tuner(state); tda10021_set_symbolrate (state, p->u.qam.symbol_rate); tda10021_writereg (state, 0x34, state->pwm); @@ -377,18 +376,6 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa return 0; } -static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10021_state* state = fe->demodulator_priv; - - if (enable) { - lock_tuner(state); - } else { - unlock_tuner(state); - } - return 0; -} - static int tda10021_sleep(struct dvb_frontend* fe) { struct tda10021_state* state = fe->demodulator_priv; @@ -420,6 +407,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); state->pwm = pwm; state->reg0 = tda10021_inittab[0]; @@ -427,7 +415,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -460,7 +448,6 @@ static struct dvb_frontend_ops tda10021_ops = { .init = tda10021_init, .sleep = tda10021_sleep, - .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, .set_frontend = tda10021_set_parameters, .get_frontend = tda10021_get_frontend, diff --git a/trunk/drivers/media/dvb/frontends/tda10021.h b/trunk/drivers/media/dvb/frontends/tda10021.h index b1df4259bee9..53be939e8c55 100644 --- a/trunk/drivers/media/dvb/frontends/tda10021.h +++ b/trunk/drivers/media/dvb/frontends/tda10021.h @@ -30,11 +30,13 @@ struct tda10021_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, struct i2c_adapter* i2c, u8 pwm); -extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data); - #endif // TDA10021_H diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.c b/trunk/drivers/media/dvb/frontends/tda1004x.c index 59a2ed614fca..b83dafa4e12c 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.c +++ b/trunk/drivers/media/dvb/frontends/tda1004x.c @@ -47,6 +47,7 @@ enum tda1004x_demod { struct tda1004x_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; const struct tda1004x_config* config; struct dvb_frontend frontend; @@ -599,6 +600,13 @@ static int tda10045_init(struct dvb_frontend* fe) tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC + // Init the PLL + if (state->config->pll_init) { + tda1004x_enable_tuner_i2c(state); + state->config->pll_init(fe); + tda1004x_disable_tuner_i2c(state); + } + // tda setup tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream @@ -627,6 +635,16 @@ static int tda10046_init(struct dvb_frontend* fe) return -EIO; } + // Init the tuner PLL + if (state->config->pll_init) { + tda1004x_enable_tuner_i2c(state); + if (state->config->pll_init(fe)) { + printk(KERN_ERR "tda1004x: pll init failed\n"); + return -EIO; + } + tda1004x_disable_tuner_i2c(state); + } + // tda setup tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream @@ -694,10 +712,12 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, } // set frequency - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + tda1004x_enable_tuner_i2c(state); + if (state->config->pll_set(fe, fe_params)) { + printk(KERN_ERR "tda1004x: pll set failed\n"); + return -EIO; } + tda1004x_disable_tuner_i2c(state); // Hardcoded to use auto as much as possible on the TDA10045 as it // is very unreliable if AUTO mode is _not_ used. @@ -1163,6 +1183,16 @@ static int tda1004x_sleep(struct dvb_frontend* fe) break; case TDA1004X_DEMOD_TDA10046: + if (state->config->pll_sleep != NULL) { + tda1004x_enable_tuner_i2c(state); + state->config->pll_sleep(fe); + if (state->config->if_freq != TDA10046_FREQ_052) { + /* special hack for Philips EUROPA Based boards: + * keep the I2c bridge open for tuner access in analog mode + */ + tda1004x_disable_tuner_i2c(state); + } + } /* set outputs to tristate */ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); @@ -1172,17 +1202,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe) return 0; } -static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - if (enable) { - return tda1004x_enable_tuner_i2c(state); - } else { - return tda1004x_disable_tuner_i2c(state); - } -} - static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) { fesettings->min_delay_ms = 800; @@ -1216,7 +1235,6 @@ static struct dvb_frontend_ops tda10045_ops = { .init = tda10045_init, .sleep = tda1004x_sleep, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, .set_frontend = tda1004x_set_fe, .get_frontend = tda1004x_get_fe, @@ -1242,6 +1260,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ @@ -1251,7 +1270,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } @@ -1274,7 +1293,6 @@ static struct dvb_frontend_ops tda10046_ops = { .init = tda10046_init, .sleep = tda1004x_sleep, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, .set_frontend = tda1004x_set_fe, .get_frontend = tda1004x_get_fe, @@ -1300,6 +1318,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ @@ -1309,7 +1328,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.h b/trunk/drivers/media/dvb/frontends/tda1004x.h index b877b23ed734..cc0c4af64067 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.h +++ b/trunk/drivers/media/dvb/frontends/tda1004x.h @@ -66,6 +66,11 @@ struct tda1004x_config /* AGC configuration */ enum tda10046_agc agc_config; + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + void (*pll_sleep)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + /* request firmware for device */ /* set this to NULL if the card has a firmware EEPROM */ int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); diff --git a/trunk/drivers/media/dvb/frontends/tda8083.c b/trunk/drivers/media/dvb/frontends/tda8083.c index 3aa45ebbac3d..91baa9cedd79 100644 --- a/trunk/drivers/media/dvb/frontends/tda8083.c +++ b/trunk/drivers/media/dvb/frontends/tda8083.c @@ -37,6 +37,7 @@ struct tda8083_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct tda8083_config* config; struct dvb_frontend frontend; @@ -292,11 +293,7 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct tda8083_state* state = fe->demodulator_priv; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - + state->config->pll_set(fe, p); tda8083_set_inversion (state, p->inversion); tda8083_set_fec (state, p->u.qpsk.fec_inner); tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); @@ -337,6 +334,8 @@ static int tda8083_init(struct dvb_frontend* fe) for (i=0; i<44; i++) tda8083_writereg (state, i, tda8083_init_tab[i]); + if (state->config->pll_init) state->config->pll_init(fe); + tda8083_writereg (state, 0x00, 0x3c); tda8083_writereg (state, 0x00, 0x04); @@ -396,12 +395,13 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/tda8083.h b/trunk/drivers/media/dvb/frontends/tda8083.h index e7a48f61ea2c..466663307bf1 100644 --- a/trunk/drivers/media/dvb/frontends/tda8083.h +++ b/trunk/drivers/media/dvb/frontends/tda8083.h @@ -33,6 +33,10 @@ struct tda8083_config { /* the demodulator's i2c address */ u8 demod_address; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, diff --git a/trunk/drivers/media/dvb/frontends/ves1820.c b/trunk/drivers/media/dvb/frontends/ves1820.c index 6bffe85c161c..ad8647a3c85e 100644 --- a/trunk/drivers/media/dvb/frontends/ves1820.c +++ b/trunk/drivers/media/dvb/frontends/ves1820.c @@ -35,6 +35,7 @@ struct ves1820_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct ves1820_config* config; struct dvb_frontend frontend; @@ -203,6 +204,9 @@ static int ves1820_init(struct dvb_frontend* fe) ves1820_writereg(state, 0x34, state->pwm); + if (state->config->pll_init) + state->config->pll_init(fe); + return 0; } @@ -219,11 +223,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p if (real_qam < 0 || real_qam > 4) return -EINVAL; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - + state->config->pll_set(fe, p); ves1820_set_symbolrate(state, p->u.qam.symbol_rate); ves1820_writereg(state, 0x34, state->pwm); @@ -380,6 +380,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, goto error; /* setup the state */ + memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); state->reg0 = ves1820_inittab[0]; state->config = config; state->i2c = i2c; @@ -392,12 +393,12 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, if (verbose) printk("ves1820: pwm=0x%02x\n", state->pwm); + state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ + state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ + /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ - state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; - return &state->frontend; error: diff --git a/trunk/drivers/media/dvb/frontends/ves1820.h b/trunk/drivers/media/dvb/frontends/ves1820.h index 520f09522fbb..355f130b1be8 100644 --- a/trunk/drivers/media/dvb/frontends/ves1820.h +++ b/trunk/drivers/media/dvb/frontends/ves1820.h @@ -39,6 +39,10 @@ struct ves1820_config /* SELAGC control */ u8 selagc:1; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, diff --git a/trunk/drivers/media/dvb/frontends/ves1x93.c b/trunk/drivers/media/dvb/frontends/ves1x93.c index 54d7b07571b8..821df8e839d0 100644 --- a/trunk/drivers/media/dvb/frontends/ves1x93.c +++ b/trunk/drivers/media/dvb/frontends/ves1x93.c @@ -36,6 +36,7 @@ struct ves1x93_state { struct i2c_adapter* i2c; + struct dvb_frontend_ops ops; /* configuration settings */ const struct ves1x93_config* config; struct dvb_frontend frontend; @@ -277,6 +278,12 @@ static int ves1x93_init (struct dvb_frontend* fe) } } + if (state->config->pll_init) { + ves1x93_writereg(state, 0x00, 0x11); + state->config->pll_init(fe); + ves1x93_writereg(state, 0x00, 0x01); + } + return 0; } @@ -388,10 +395,9 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct ves1x93_state* state = fe->demodulator_priv; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } + ves1x93_writereg(state, 0x00, 0x11); + state->config->pll_set(fe, p); + ves1x93_writereg(state, 0x00, 0x01); ves1x93_set_inversion (state, p->inversion); ves1x93_set_fec (state, p->u.qpsk.fec_inner); ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); @@ -436,17 +442,6 @@ static void ves1x93_release(struct dvb_frontend* fe) kfree(state); } -static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - if (enable) { - return ves1x93_writereg(state, 0x00, 0x11); - } else { - return ves1x93_writereg(state, 0x00, 0x01); - } -} - static struct dvb_frontend_ops ves1x93_ops; struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, @@ -462,6 +457,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, /* setup the state */ state->config = config; state->i2c = i2c; + memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); state->inversion = INVERSION_OFF; /* check if the demod is there + identify it */ @@ -496,7 +492,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; @@ -527,7 +523,6 @@ static struct dvb_frontend_ops ves1x93_ops = { .init = ves1x93_init, .sleep = ves1x93_sleep, - .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, .set_frontend = ves1x93_set_frontend, .get_frontend = ves1x93_get_frontend, diff --git a/trunk/drivers/media/dvb/frontends/ves1x93.h b/trunk/drivers/media/dvb/frontends/ves1x93.h index ba88ae0855c9..1627e37c57a4 100644 --- a/trunk/drivers/media/dvb/frontends/ves1x93.h +++ b/trunk/drivers/media/dvb/frontends/ves1x93.h @@ -38,6 +38,10 @@ struct ves1x93_config /* should PWM be inverted? */ u8 invert_pwm:1; + + /* PLL maintenance */ + int (*pll_init)(struct dvb_frontend* fe); + int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, diff --git a/trunk/drivers/media/dvb/frontends/zl10353.c b/trunk/drivers/media/dvb/frontends/zl10353.c index 2b95e8b6cd39..d7d9f59d76d2 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.c +++ b/trunk/drivers/media/dvb/frontends/zl10353.c @@ -34,6 +34,7 @@ struct zl10353_state { struct i2c_adapter *i2c; struct dvb_frontend frontend; + struct dvb_frontend_ops ops; struct zl10353_config config; }; @@ -125,7 +126,6 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { struct zl10353_state *state = fe->demodulator_priv; - u8 pllbuf[6] = { 0x67 }; /* These settings set "auto-everything" and start the FSM. */ @@ -142,30 +142,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, 0x66, 0xE9); zl10353_single_write(fe, 0x62, 0x0A); - // if there is no attached secondary tuner, we call set_params to program - // a potential tuner attached somewhere else - if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - } - - // if pllbuf is defined, retrieve the settings - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5); - pllbuf[1] <<= 1; - } else { - // fake pllbuf settings - pllbuf[1] = 0x61 << 1; - pllbuf[2] = 0; - pllbuf[3] = 0; - pllbuf[3] = 0; - pllbuf[4] = 0; - } - - // there is no call to _just_ start decoding, so we send the pllbuf anyway - // even if there isn't a PLL attached to the secondary bus + state->config.pll_set(fe, param, pllbuf + 1); zl10353_write(fe, pllbuf, sizeof(pllbuf)); zl10353_single_write(fe, 0x70, 0x01); @@ -277,13 +254,14 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, /* setup the state */ state->i2c = i2c; memcpy(&state->config, config, sizeof(struct zl10353_config)); + memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); /* check if the demod is there */ if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) goto error; /* create dvb_frontend */ - memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; diff --git a/trunk/drivers/media/dvb/frontends/zl10353.h b/trunk/drivers/media/dvb/frontends/zl10353.h index 9770cb840cfc..5cc4ae718d8c 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.h +++ b/trunk/drivers/media/dvb/frontends/zl10353.h @@ -29,8 +29,10 @@ struct zl10353_config /* demodulator's I2C address */ u8 demod_address; - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; + /* function which configures the PLL buffer (for secondary I2C + * connected tuner) or tunes the PLL (for direct connected tuner) */ + int (*pll_set)(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params, u8 *pllbuf); }; extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, diff --git a/trunk/drivers/media/dvb/pluto2/pluto2.c b/trunk/drivers/media/dvb/pluto2/pluto2.c index acabea0793b6..1c5316e209ef 100644 --- a/trunk/drivers/media/dvb/pluto2/pluto2.c +++ b/trunk/drivers/media/dvb/pluto2/pluto2.c @@ -424,8 +424,8 @@ static inline u32 divide(u32 numerator, u32 denominator) } /* LG Innotek TDTE-E001P (Infineon TUA6034) */ -static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) +static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) { struct pluto *pluto = frontend_to_pluto(fe); struct i2c_msg msg; @@ -473,8 +473,6 @@ static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, msg.buf = buf; msg.len = sizeof(buf); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); if (ret < 0) return ret; @@ -499,6 +497,8 @@ static struct tda1004x_config pluto2_fe_config __devinitdata = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, + .pll_set = lg_tdtpe001p_pll_set, + .pll_sleep = NULL, .request_firmware = pluto2_request_firmware, }; @@ -511,12 +511,11 @@ static int __devinit frontend_init(struct pluto *pluto) dev_err(&pluto->pdev->dev, "could not attach frontend\n"); return -ENODEV; } - pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); if (ret < 0) { - if (pluto->fe->ops.release) - pluto->fe->ops.release(pluto->fe); + if (pluto->fe->ops->release) + pluto->fe->ops->release(pluto->fe); return ret; } @@ -648,7 +647,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, goto err_pluto_hw_exit; /* dvb */ - ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev); + ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE); if (ret < 0) goto err_i2c_bit_del_bus; diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index 987881fa988c..b5ac7dfde52f 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -10,7 +10,6 @@ config DVB_AV7110 select DVB_SP8870 select DVB_STV0297 select DVB_L64781 - select DVB_LNBP21 help Support for SAA7146 and AV7110 based DVB cards as produced by Fujitsu-Siemens, Technotrend, Hauppauge and others. @@ -68,7 +67,6 @@ config DVB_BUDGET select DVB_TDA8083 select DVB_TDA10021 select DVB_S5H1420 - select DVB_LNBP21 help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard @@ -86,7 +84,6 @@ config DVB_BUDGET_CI select DVB_STV0297 select DVB_STV0299 select DVB_TDA1004X - select DVB_LNBP21 help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard diff --git a/trunk/drivers/media/dvb/ttpci/Makefile b/trunk/drivers/media/dvb/ttpci/Makefile index aa85ecdc6c80..a690730ac39d 100644 --- a/trunk/drivers/media/dvb/ttpci/Makefile +++ b/trunk/drivers/media/dvb/ttpci/Makefile @@ -15,9 +15,9 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ hostprogs-y := fdump -ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y) -$(obj)/av7110.o: $(obj)/av7110_firm.h +ifdef CONFIG_DVB_AV7110_FIRMWARE +$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h -$(obj)/av7110_firm.h: $(obj)/fdump +$(obj)/av7110_firm.h: $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ endif diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 7a5c99c200e8..d028245c8eed 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -152,9 +152,13 @@ static void init_av7110_av(struct av7110 *av7110) /* remaining inits according to card and frontend type */ av7110->analog_tuner_flags = 0; av7110->current_input = 0; - if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) + if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) { + printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n", + av7110->dvb_adapter.num); + av7110->adac_type = DVB_ADAC_MSP34x5; av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on - if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { + } + else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", av7110->dvb_adapter.num); av7110->adac_type = DVB_ADAC_CRYSTAL; @@ -1548,7 +1552,7 @@ static int get_firmware(struct av7110* av7110) #endif -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = (struct av7110*) fe->dvb->priv; u8 pwr = 0; @@ -1571,8 +1575,6 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front // NOTE: since we're using a prescaler of 2, we set the // divisor frequency to 62.5kHz and divide by 125 above - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -1582,9 +1584,10 @@ static struct ves1x93_config alps_bsrv2_config = { .demod_address = 0x08, .xin = 90100000UL, .invert_pwm = 0, + .pll_set = alps_bsrv2_pll_set, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; u32 div; @@ -1598,8 +1601,6 @@ static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = 0x85 | ((div >> 10) & 0x60); data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -1610,12 +1611,14 @@ static struct ves1820_config alps_tdbe2_config = { .xin = 57840000UL, .invert = 1, .selagc = VES1820_SELAGC_SIGNAMPERR, + .pll_set = alps_tdbe2_pll_set, }; -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int grundig_29504_451_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; u32 div; @@ -1628,8 +1631,6 @@ static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dv data[2] = 0x8e; data[3] = 0x00; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -1637,11 +1638,13 @@ static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dv static struct tda8083_config grundig_29504_451_config = { .demod_address = 0x68, + .pll_set = grundig_29504_451_pll_set, }; -static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int philips_cd1516_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; u32 div; @@ -1656,8 +1659,6 @@ static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_f data[2] = 0x8e; data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -1668,11 +1669,12 @@ static struct ves1820_config philips_cd1516_config = { .xin = 57840000UL, .invert = 1, .selagc = VES1820_SELAGC_SIGNAMPERR, + .pll_set = philips_cd1516_pll_set, }; -static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; u32 div, pwr; @@ -1691,8 +1693,6 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = 0x85; data[3] = pwr << 6; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -1708,6 +1708,7 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir static struct sp8870_config alps_tdlb7_config = { .demod_address = 0x71, + .pll_set = alps_tdlb7_pll_set, .request_firmware = alps_tdlb7_request_firmware, }; @@ -1805,7 +1806,7 @@ static u8 nexusca_stv0297_inittab[] = { 0xff, 0xff, }; -static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = fe->dvb->priv; u32 div; @@ -1831,8 +1832,7 @@ static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_ else return -EINVAL; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + stv0297_enable_plli2c(fe); if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { printk("nexusca: pll transfer failed!\n"); return -EIO; @@ -1840,8 +1840,8 @@ static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_ // wait for PLL lock for(i = 0; i < 20; i++) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + + stv0297_enable_plli2c(fe); if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) if (data[0] & 0x40) break; msleep(10); @@ -1855,12 +1855,12 @@ static struct stv0297_config nexusca_stv0297_config = { .demod_address = 0x1C, .inittab = nexusca_stv0297_inittab, .invert = 1, - .stop_during_read = 1, + .pll_set = nexusca_stv0297_pll_set, }; -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) +static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct av7110* av7110 = (struct av7110*) fe->dvb->priv; u32 div; @@ -1887,14 +1887,13 @@ static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dv data[2] = ((div >> 10) & 0x60) | cfg; data[3] = (cpump << 6) | band_select; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } static struct l64781_config grundig_29504_401_config = { .demod_address = 0x55, + .pll_set = grundig_29504_401_pll_set, }; @@ -2080,9 +2079,6 @@ static int frontend_init(struct av7110 *av7110) case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; - } break; } @@ -2095,10 +2091,9 @@ static int frontend_init(struct av7110 *av7110) // try the ALPS BSRV2 first of all av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; av7110->recover = dvb_s_recover; break; } @@ -2106,12 +2101,9 @@ static int frontend_init(struct av7110 *av7110) // try the ALPS BSRU6 now av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - av7110->fe->tuner_priv = &av7110->i2c_adap; - - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; av7110->recover = dvb_s_recover; break; } @@ -2119,10 +2111,9 @@ static int frontend_init(struct av7110 *av7110) // Try the grundig 29504-451 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; av7110->recover = dvb_s_recover; break; } @@ -2133,17 +2124,11 @@ static int frontend_init(struct av7110 *av7110) /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; - } break; case 0x0003: /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - } break; } break; @@ -2152,27 +2137,20 @@ static int frontend_init(struct av7110 *av7110) // ALPS TDLB7 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params; - } break; case 0x0002: // Hauppauge/TT DVB-C premium rev2.X av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - } break; case 0x0004: // Galaxis DVB-S rev1.3 /* ALPS BSRV2 */ av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; av7110->recover = dvb_s_recover; } break; @@ -2181,10 +2159,9 @@ static int frontend_init(struct av7110 *av7110) /* Grundig 29504-451 */ av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; av7110->recover = dvb_s_recover; } break; @@ -2192,17 +2169,12 @@ static int frontend_init(struct av7110 *av7110) case 0x0008: // Hauppauge/TT DVB-T av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - } break; case 0x000A: // Hauppauge/TT Nexus-CA rev1.X av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; - /* set TDA9819 into DVB mode */ saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) @@ -2217,16 +2189,13 @@ static int frontend_init(struct av7110 *av7110) /* ALPS BSBE1 */ av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - av7110->fe->tuner_priv = &av7110->i2c_adap; - - if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) { + if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { printk("dvb-ttpci: LNBP21 not found!\n"); - if (av7110->fe->ops.release) - av7110->fe->ops.release(av7110->fe); + if (av7110->fe->ops->release) + av7110->fe->ops->release(av7110->fe); av7110->fe = NULL; } else { - av7110->fe->ops.dishnetwork_send_legacy_command = NULL; + av7110->fe->ops->dishnetwork_send_legacy_command = NULL; av7110->recover = dvb_s_recover; } } @@ -2243,21 +2212,21 @@ static int frontend_init(struct av7110 *av7110) av7110->dev->pci->subsystem_vendor, av7110->dev->pci->subsystem_device); } else { - FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init); - FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) - FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); + FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init); + FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status); + FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); + FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); + FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); + FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); + FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) + FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); + FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); if (ret < 0) { printk("av7110: Frontend registration failed!\n"); - if (av7110->fe->ops.release) - av7110->fe->ops.release(av7110->fe); + if (av7110->fe->ops->release) + av7110->fe->ops->release(av7110->fe); av7110->fe = NULL; } } @@ -2444,7 +2413,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, goto err_kfree_0; ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, - THIS_MODULE, &dev->pci->dev); + THIS_MODULE); if (ret < 0) goto err_put_firmware_1; diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index 0f3a044aeb17..2eff09f638d3 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -318,17 +318,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ return 0; - - case DVB_ADAC_MSP34x5: - vol = (volleft > volright) ? volleft : volright; - val = (vol * 0x73 / 255) << 8; - if (vol > 0) - balance = ((volright - volleft) * 127) / vol; - msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ - return 0; } - return 0; } @@ -1277,32 +1267,23 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, switch(av7110->audiostate.channel_select) { case AUDIO_STEREO: ret = audcom(av7110, AUDIO_CMD_STEREO); - if (!ret) { + if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x49); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); - } break; case AUDIO_MONO_LEFT: ret = audcom(av7110, AUDIO_CMD_MONO_L); - if (!ret) { + if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x4a); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); - } break; case AUDIO_MONO_RIGHT: ret = audcom(av7110, AUDIO_CMD_MONO_R); - if (!ret) { + if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x45); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); - } break; default: diff --git a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c index 64055461559d..603a22e4bfe2 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c @@ -42,18 +42,7 @@ int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) { u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; - struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg }; - - switch (av7110->adac_type) { - case DVB_ADAC_MSP34x0: - msgs.addr = 0x40; - break; - case DVB_ADAC_MSP34x5: - msgs.addr = 0x42; - break; - default: - return 0; - } + struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg }; if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", @@ -68,23 +57,10 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; u8 msg2[2]; struct i2c_msg msgs[2] = { - { .flags = 0 , .len = 3, .buf = msg1 }, - { .flags = I2C_M_RD, .len = 2, .buf = msg2 } + { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 }, + { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 } }; - switch (av7110->adac_type) { - case DVB_ADAC_MSP34x0: - msgs[0].addr = 0x40; - msgs[1].addr = 0x40; - break; - case DVB_ADAC_MSP34x5: - msgs[0].addr = 0x42; - msgs[1].addr = 0x42; - break; - default: - return 0; - } - if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", av7110->dvb_adapter.num, reg); @@ -702,23 +678,17 @@ int av7110_init_analog_module(struct av7110 *av7110) { u16 version1, version2; - if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 && - i2c_writereg(av7110, 0x80, 0x0, 0) == 1) { - printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_MSP34x0; - } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 && - i2c_writereg(av7110, 0x84, 0x0, 0) == 1) { - printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3415\n", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_MSP34x5; - } else + if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1 + || i2c_writereg(av7110, 0x80, 0x0, 0) != 1) return -ENODEV; + printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", + av7110->dvb_adapter.num); + av7110->adac_type = DVB_ADAC_MSP34x0; msleep(100); // the probing above resets the msp... msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); - dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n", + dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n", av7110->dvb_adapter.num, version1, version2); msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone @@ -727,7 +697,7 @@ int av7110_init_analog_module(struct av7110 *av7110) msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume - msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART + msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { INFO(("saa7113 not accessible.\n")); diff --git a/trunk/drivers/media/dvb/ttpci/budget-av.c b/trunk/drivers/media/dvb/ttpci/budget-av.c index 6163cb03b8f4..8a7cd7d505cf 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-av.c +++ b/trunk/drivers/media/dvb/ttpci/budget-av.c @@ -50,12 +50,6 @@ #define DEBICICAM 0x02420000 -#define SLOTSTATUS_NONE 1 -#define SLOTSTATUS_PRESENT 2 -#define SLOTSTATUS_RESET 4 -#define SLOTSTATUS_READY 8 -#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) - struct budget_av { struct budget budget; struct video_device *vd; @@ -64,15 +58,8 @@ struct budget_av { struct tasklet_struct ciintf_irq_tasklet; int slot_status; struct dvb_ca_en50221 ca; - u8 reinitialise_demod:1; - u8 tda10021_poclkp:1; - u8 tda10021_ts_enabled; - int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); }; -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); - - /* GPIO Connections: * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory @@ -142,10 +129,9 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad udelay(1); result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 1\n"); - } + + if (result == -ETIMEDOUT) + budget_av->slot_status = 0; return result; } @@ -161,10 +147,9 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a udelay(1); result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 2\n"); - } + + if (result == -ETIMEDOUT) + budget_av->slot_status = 0; return result; } @@ -180,11 +165,9 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre udelay(1); result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); - if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) { - ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 3\n"); - return -ETIMEDOUT; - } + + if (result == -ETIMEDOUT) + budget_av->slot_status = 0; return result; } @@ -200,10 +183,9 @@ static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addr udelay(1); result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 5\n"); - } + + if (result == -ETIMEDOUT) + budget_av->slot_status = 0; return result; } @@ -211,12 +193,12 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) { struct budget_av *budget_av = (struct budget_av *) ca->data; struct saa7146_dev *saa = budget_av->budget.dev; + int timeout = 50; // 5 seconds (4.4.6 Ready) if (slot != 0) return -EINVAL; dprintk(1, "ciintf_slot_reset\n"); - budget_av->slot_status = SLOTSTATUS_RESET; saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ @@ -226,17 +208,20 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) msleep(20); /* 20 ms Vcc settling time */ saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - msleep(20); - /* reinitialise the frontend if necessary */ - if (budget_av->reinitialise_demod) - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); + /* This should have been based on pin 16 READY of the pcmcia port, + * but AFAICS it is not routed to the saa7146 */ + while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) + msleep(100); + + /* reinitialise the frontend */ + dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); - /* set tda10021 back to original clock configuration on reset */ - if (budget_av->tda10021_poclkp) { - tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); - budget_av->tda10021_ts_enabled = 0; + if (timeout <= 0) + { + printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ + return -ETIMEDOUT; } return 0; @@ -253,13 +238,7 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) dprintk(1, "ciintf_slot_shutdown\n"); ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - budget_av->slot_status = SLOTSTATUS_NONE; - - /* set tda10021 back to original clock configuration when cam removed */ - if (budget_av->tda10021_poclkp) { - tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); - budget_av->tda10021_ts_enabled = 0; - } + budget_av->slot_status = 0; return 0; } @@ -274,13 +253,6 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); - - /* tda10021 seems to need a different TS clock config when data is routed to the CAM */ - if (budget_av->tda10021_poclkp) { - tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); - budget_av->tda10021_ts_enabled = 1; - } - return 0; } @@ -288,61 +260,50 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open { struct budget_av *budget_av = (struct budget_av *) ca->data; struct saa7146_dev *saa = budget_av->budget.dev; - int result; + int cam_present = 0; if (slot != 0) return -EINVAL; - /* test the card detect line - needs to be done carefully - * since it never goes high for some CAMs on this interface (e.g. topuptv) */ - if (budget_av->slot_status == SLOTSTATUS_NONE) { + if (!budget_av->slot_status) + { + // first of all test the card detect line saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); udelay(1); - if (saa7146_read(saa, PSR) & MASK_06) { - if (budget_av->slot_status == SLOTSTATUS_NONE) { - budget_av->slot_status = SLOTSTATUS_PRESENT; - printk(KERN_INFO "budget-av: cam inserted A\n"); - } + if (saa7146_read(saa, PSR) & MASK_06) + { + cam_present = 1; } saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - } - /* We also try and read from IO memory to work round the above detection bug. If - * there is no CAM, we will get a timeout. Only done if there is no cam - * present, since this test actually breaks some cams :( - * - * if the CI interface is not open, we also do the above test since we - * don't care if the cam has problems - we'll be resetting it on open() anyway */ - if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); - if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { - budget_av->slot_status = SLOTSTATUS_PRESENT; - printk(KERN_INFO "budget-av: cam inserted B\n"); - } else if (result < 0) { - if (budget_av->slot_status != SLOTSTATUS_NONE) { - ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 5\n"); - return 0; + // that is unreliable however, so try and read from IO memory + if (!cam_present) + { + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); + if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) + { + cam_present = 1; } } - } - /* read from attribute memory in reset/ready state to know when the CAM is ready */ - if (budget_av->slot_status == SLOTSTATUS_RESET) { - result = ciintf_read_attribute_mem(ca, slot, 0); - if (result == 0x1d) { - budget_av->slot_status = SLOTSTATUS_READY; + // did we find something? + if (cam_present) { + printk(KERN_INFO "budget-av: cam inserted\n"); + budget_av->slot_status = 1; } - } - - /* work out correct return code */ - if (budget_av->slot_status != SLOTSTATUS_NONE) { - if (budget_av->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; + } else if (!open) { + saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); + if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) + { + printk(KERN_INFO "budget-av: cam ejected\n"); + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ + budget_av->slot_status = 0; } - return DVB_CA_EN50221_POLL_CAM_PRESENT; } + + if (budget_av->slot_status == 1) + return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; + return 0; } @@ -372,8 +333,6 @@ static int ciintf_init(struct budget_av *budget_av) budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; budget_av->ca.poll_slot_status = ciintf_poll_slot_status; budget_av->ca.data = budget_av; - budget_av->budget.ci_present = 1; - budget_av->slot_status = SLOTSTATUS_NONE; if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, &budget_av->ca, 0, 1)) != 0) { @@ -382,6 +341,7 @@ static int ciintf_init(struct budget_av *budget_av) } printk(KERN_INFO "budget-av: ci interface initialised.\n"); + budget_av->budget.ci_present = 1; return 0; error: @@ -512,12 +472,12 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra return 0; } -static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct dvb_frontend_parameters *params) { u32 div; u8 buf[4]; - struct budget *budget = (struct budget *) fe->dvb->priv; struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; if ((params->frequency < 950000) || (params->frequency > 2150000)) @@ -541,9 +501,7 @@ static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, else if (params->frequency < 2150000) buf[3] |= 0xC0; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; return 0; } @@ -551,8 +509,9 @@ static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, #define MIN2(a,b) ((a) < (b) ? (a) : (b)) #define MIN3(a,b,c) MIN2(MIN2(a,b),c) -static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct dvb_frontend_parameters *params) { u8 reg0 [2] = { 0x00, 0x00 }; u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; @@ -562,7 +521,6 @@ static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe, int R, A, N, P, M; struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; int freq = params->frequency; - struct budget *budget = (struct budget *) fe->dvb->priv; first_ZF = (freq) / 1000; @@ -662,25 +620,21 @@ static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe, reg0[1] |= 0x03; /* already enabled - do not reenable i2c repeater or TX fails */ - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); msg.buf = reg0; msg.len = sizeof(reg0); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + stv0299_enable_plli2c(fe); msg.buf = reg1; msg.len = sizeof(reg1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + stv0299_enable_plli2c(fe); msg.buf = reg2; msg.len = sizeof(reg2); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; return 0; @@ -738,6 +692,7 @@ static struct stv0299_config typhoon_config = { .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, + .pll_set = philips_su1278_ty_ci_pll_set, }; @@ -751,6 +706,7 @@ static struct stv0299_config cinergy_1200s_config = { .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, + .pll_set = philips_su1278_ty_ci_pll_set, }; static struct stv0299_config cinergy_1200s_1894_0010_config = { @@ -763,9 +719,10 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, + .pll_set = philips_su1278sh2_tua6100_pll_set, }; -static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget *budget = (struct budget *) fe->dvb->priv; u8 buf[4]; @@ -781,8 +738,6 @@ static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f buf[3] = (params->frequency < 150000000 ? 0x01 : params->frequency < 445000000 ? 0x02 : 0x04); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; @@ -790,20 +745,19 @@ static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f static struct tda10021_config philips_cu1216_config = { .demod_address = 0x0c, + .pll_set = philips_cu1216_pll_set, }; -static int philips_tu1216_tuner_init(struct dvb_frontend *fe) +static int philips_tu1216_pll_init(struct dvb_frontend *fe) { struct budget *budget = (struct budget *) fe->dvb->priv; static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -811,7 +765,7 @@ static int philips_tu1216_tuner_init(struct dvb_frontend *fe) return 0; } -static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget *budget = (struct budget *) fe->dvb->priv; u8 tuner_buf[4]; @@ -885,8 +839,6 @@ static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_f tuner_buf[2] = 0xca; tuner_buf[3] = (cp << 5) | (filter << 3) | band; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) return -EIO; @@ -910,6 +862,9 @@ static struct tda1004x_config philips_tu1216_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, + .pll_init = philips_tu1216_pll_init, + .pll_set = philips_tu1216_pll_set, + .pll_sleep = NULL, .request_firmware = philips_tu1216_request_firmware, }; @@ -956,13 +911,13 @@ static u8 philips_sd1878_inittab[] = { 0xff, 0xff }; -static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct dvb_frontend_parameters *params) { u8 buf[4]; int rc; struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; - struct budget *budget = (struct budget *) fe->dvb->priv; if((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; @@ -971,9 +926,7 @@ static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe, params->frequency, 0); if(rc < 0) return rc; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) + if(i2c_transfer(i2c, &tuner_msg, 1) != 1) return -EIO; return 0; @@ -1016,7 +969,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, static struct stv0299_config philips_sd1878_config = { .demod_address = 0x68, - .inittab = philips_sd1878_inittab, + .inittab = philips_sd1878_inittab, .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, @@ -1024,6 +977,7 @@ static struct stv0299_config philips_sd1878_config = { .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, + .pll_set = philips_sd1878_tda8261_pll_set, }; static u8 read_pwm(struct budget_av *budget_av) @@ -1049,7 +1003,6 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBS_TV_STAR 0x0014 #define SUBID_DVBS_TV_STAR_CI 0x0016 -#define SUBID_DVBS_EASYWATCH_1 0x001a #define SUBID_DVBS_EASYWATCH 0x001e #define SUBID_DVBC_KNC1 0x0020 #define SUBID_DVBC_KNC1_PLUS 0x0021 @@ -1059,36 +1012,17 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBT_KNC1 0x0030 #define SUBID_DVBT_CINERGY1200 0x1157 - -static int tda10021_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct budget_av* budget_av = fe->dvb->priv; - int result; - - result = budget_av->tda10021_set_frontend(fe, p); - if (budget_av->tda10021_ts_enabled) { - tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); - } else { - tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); - } - - return result; -} - static void frontend_init(struct budget_av *budget_av) { struct saa7146_dev * saa = budget_av->budget.dev; struct dvb_frontend * fe = NULL; - /* Enable / PowerON Frontend */ - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); - - /* additional setup necessary for the PLUS cards */ switch (saa->pci->subsystem_device) { case SUBID_DVBS_KNC1_PLUS: case SUBID_DVBC_KNC1_PLUS: case SUBID_DVBT_KNC1_PLUS: + // Enable / PowerON Frontend + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); break; } @@ -1096,19 +1030,12 @@ static void frontend_init(struct budget_av *budget_av) switch (saa->pci->subsystem_device) { case SUBID_DVBS_KNC1: - case SUBID_DVBS_EASYWATCH_1: if (saa->pci->subsystem_vendor == 0x1894) { fe = stv0299_attach(&cinergy_1200s_1894_0010_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params; - } } else { fe = stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } } break; @@ -1118,53 +1045,41 @@ static void frontend_init(struct budget_av *budget_av) case SUBID_DVBS_EASYWATCH: fe = stv0299_attach(&philips_sd1878_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params; - } break; case SUBID_DVBS_KNC1_PLUS: case SUBID_DVBS_TYPHOON: fe = stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } break; case SUBID_DVBS_CINERGY1200: fe = stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } break; case SUBID_DVBC_KNC1: case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBC_CINERGY1200: - budget_av->reinitialise_demod = 1; fe = tda10021_attach(&philips_cu1216_config, &budget_av->budget.i2c_adap, read_pwm(budget_av)); - if (fe) { - budget_av->tda10021_poclkp = 1; - budget_av->tda10021_set_frontend = fe->ops.set_frontend; - fe->ops.set_frontend = tda10021_set_frontend; - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } break; case SUBID_DVBT_KNC1: case SUBID_DVBT_KNC1_PLUS: + fe = tda10046_attach(&philips_tu1216_config, + &budget_av->budget.i2c_adap); + break; + + case SUBID_DVBC_CINERGY1200: + fe = tda10021_attach(&philips_cu1216_config, + &budget_av->budget.i2c_adap, + read_pwm(budget_av)); + break; + case SUBID_DVBT_CINERGY1200: - budget_av->reinitialise_demod = 1; fe = tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.init = philips_tu1216_tuner_init; - fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; - } break; } @@ -1183,8 +1098,8 @@ static void frontend_init(struct budget_av *budget_av) if (dvb_register_frontend(&budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) { printk(KERN_ERR "budget-av: Frontend registration failed!\n"); - if (budget_av->budget.dvb_frontend->ops.release) - budget_av->budget.dvb_frontend->ops.release(budget_av->budget.dvb_frontend); + if (budget_av->budget.dvb_frontend->ops->release) + budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); budget_av->budget.dvb_frontend = NULL; } } @@ -1378,7 +1293,6 @@ MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); @@ -1395,7 +1309,6 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), - MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index 4b966eea3834..e64a609cf4ff 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -620,10 +620,10 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, return 0; } -static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct dvb_frontend_parameters *params) { - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u32 div; u8 buf[4]; struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; @@ -649,9 +649,7 @@ static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, else if (params->frequency < 2150000) buf[3] |= 0xC0; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; return 0; } @@ -667,11 +665,12 @@ static struct stv0299_config philips_su1278_tt_config = { .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 50, .set_symbol_rate = philips_su1278_tt_set_symbol_rate, + .pll_set = philips_su1278_tt_pll_set, }; -static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) +static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) { struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; @@ -680,8 +679,6 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) sizeof(td1316_init) }; // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -690,18 +687,14 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) tuner_msg.addr = 0x65; tuner_msg.buf = disable_mc44BC374c; tuner_msg.len = sizeof(disable_mc44BC374c); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); } return 0; } -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u8 tuner_buf[4]; @@ -777,8 +770,6 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb tuner_buf[2] = 0xca; tuner_buf[3] = (cp << 5) | (filter << 3) | band; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) return -EIO; @@ -802,10 +793,13 @@ static struct tda1004x_config philips_tdm1316l_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, + .pll_init = philips_tdm1316l_pll_init, + .pll_set = philips_tdm1316l_pll_set, + .pll_sleep = NULL, .request_firmware = philips_tdm1316l_request_firmware, }; -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; u8 tuner_buf[5]; @@ -863,15 +857,13 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc tuner_buf[3] = (cp << 5) | (filter << 3) | band; tuner_buf[4] = 0x80; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + stv0297_enable_plli2c(fe); if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(50); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); + stv0297_enable_plli2c(fe); if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) return -EIO; @@ -977,7 +969,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = { .demod_address = 0x1c, .inittab = dvbc_philips_tdm1316l_inittab, .invert = 0, - .stop_during_read = 1, + .pll_set = dvbc_philips_tdm1316l_pll_set, }; @@ -990,8 +982,6 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; break; } break; @@ -1000,7 +990,6 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; break; } break; @@ -1010,7 +999,6 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; break; } break; @@ -1020,8 +1008,6 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; break; } break; @@ -1031,8 +1017,6 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; break; } break; @@ -1040,14 +1024,11 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x1017: // TT S-1500 PCI budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; - - budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { + budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; + if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { printk("%s: No LNBP21 found!\n", __FUNCTION__); - if (budget_ci->budget.dvb_frontend->ops.release) - budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); + if (budget_ci->budget.dvb_frontend->ops->release) + budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } } @@ -1065,8 +1046,8 @@ static void frontend_init(struct budget_ci *budget_ci) if (dvb_register_frontend (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { printk("budget-ci: Frontend registration failed!\n"); - if (budget_ci->budget.dvb_frontend->ops.release) - budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); + if (budget_ci->budget.dvb_frontend->ops->release) + budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } } diff --git a/trunk/drivers/media/dvb/ttpci/budget-core.c b/trunk/drivers/media/dvb/ttpci/budget-core.c index e4cf7775e07f..ea2066d461fc 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-core.c +++ b/trunk/drivers/media/dvb/ttpci/budget-core.c @@ -400,9 +400,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, budget->dev->name, budget->buffer_width, budget->buffer_height); printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); - if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { - return ret; - } + dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner); /* set dd1 stream a & b */ saa7146_write(dev, DD1_STREAM_B, 0x00000000); diff --git a/trunk/drivers/media/dvb/ttpci/budget-patch.c b/trunk/drivers/media/dvb/ttpci/budget-patch.c index ee60ce90a400..1b3aaac5e763 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-patch.c +++ b/trunk/drivers/media/dvb/ttpci/budget-patch.c @@ -258,7 +258,7 @@ static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_c return 0; } -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; u8 pwr = 0; @@ -281,10 +281,7 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front // NOTE: since we're using a prescaler of 2, we set the // divisor frequency to 62.5kHz and divide by 125 above - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) - return -EIO; + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } @@ -292,9 +289,10 @@ static struct ves1x93_config alps_bsrv2_config = { .demod_address = 0x08, .xin = 90100000UL, .invert_pwm = 0, + .pll_set = alps_bsrv2_pll_set, }; -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; u32 div; @@ -307,15 +305,13 @@ static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dv data[2] = 0x8e; data[3] = 0x00; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) - return -EIO; + if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } static struct tda8083_config grundig_29504_451_config = { .demod_address = 0x68, + .pll_set = grundig_29504_451_pll_set, }; static void frontend_init(struct budget_patch* budget) @@ -327,32 +323,27 @@ static void frontend_init(struct budget_patch* budget) // try the ALPS BSRV2 first of all budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_patch_set_tone; + budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; + budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst; + budget->dvb_frontend->ops->set_tone = budget_patch_set_tone; break; } // try the ALPS BSRU6 now budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; + budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; + budget->dvb_frontend->ops->set_tone = budget_set_tone; break; } // Try the grundig 29504-451 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; + budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; + budget->dvb_frontend->ops->set_tone = budget_set_tone; break; } break; @@ -367,8 +358,8 @@ static void frontend_init(struct budget_patch* budget) } else { if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { printk("budget-av: Frontend registration failed!\n"); - if (budget->dvb_frontend->ops.release) - budget->dvb_frontend->ops.release(budget->dvb_frontend); + if (budget->dvb_frontend->ops->release) + budget->dvb_frontend->ops->release(budget->dvb_frontend); budget->dvb_frontend = NULL; } } diff --git a/trunk/drivers/media/dvb/ttpci/budget.c b/trunk/drivers/media/dvb/ttpci/budget.c index 35761f13c12b..c23c02d95641 100644 --- a/trunk/drivers/media/dvb/ttpci/budget.c +++ b/trunk/drivers/media/dvb/ttpci/budget.c @@ -186,7 +186,7 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m return 0; } -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; u8 pwr = 0; @@ -209,8 +209,6 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front // NOTE: since we're using a prescaler of 2, we set the // divisor frequency to 62.5kHz and divide by 125 above - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } @@ -220,9 +218,10 @@ static struct ves1x93_config alps_bsrv2_config = .demod_address = 0x08, .xin = 90100000UL, .invert_pwm = 0, + .pll_set = alps_bsrv2_pll_set, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; @@ -236,8 +235,6 @@ static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = 0x85 | ((div >> 10) & 0x60); data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } @@ -247,9 +244,10 @@ static struct ves1820_config alps_tdbe2_config = { .xin = 57840000UL, .invert = 1, .selagc = VES1820_SELAGC_SIGNAMPERR, + .pll_set = alps_tdbe2_pll_set, }; -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; @@ -276,17 +274,16 @@ static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dv data[2] = ((div >> 10) & 0x60) | cfg; data[3] = (cpump << 6) | band_select; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } static struct l64781_config grundig_29504_401_config = { .demod_address = 0x55, + .pll_set = grundig_29504_401_pll_set, }; -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; @@ -299,17 +296,16 @@ static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dv data[2] = 0x8e; data[3] = 0x00; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } static struct tda8083_config grundig_29504_451_config = { .demod_address = 0x68, + .pll_set = grundig_29504_451_pll_set, }; -static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout) { struct budget* budget = (struct budget*) fe->dvb->priv; u32 div; @@ -330,16 +326,16 @@ static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend else data[3] = 0xc0; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + *freqout = div * 1000; return 0; } static struct s5h1420_config s5h1420_config = { .demod_address = 0x53, .invert = 1, + .pll_set = s5h1420_pll_set, }; static u8 read_pwm(struct budget* budget) @@ -363,21 +359,18 @@ static void frontend_init(struct budget *budget) // try the ALPS BSRV2 first of all budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; + budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; + budget->dvb_frontend->ops->set_tone = budget_set_tone; break; } // try the ALPS BSRU6 now budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; + budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; + budget->dvb_frontend->ops->set_tone = budget_set_tone; break; } break; @@ -385,45 +378,35 @@ static void frontend_init(struct budget *budget) case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - break; - } + if (budget->dvb_frontend) break; break; case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - break; - } + if (budget->dvb_frontend) break; break; case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; + budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; + budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; } break; case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; + budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; + budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; } break; case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; - if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { + if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { printk("%s: No LNBP21 found!\n", __FUNCTION__); goto error_out; } @@ -445,8 +428,8 @@ static void frontend_init(struct budget *budget) error_out: printk("budget: Frontend registration failed!\n"); - if (budget->dvb_frontend->ops.release) - budget->dvb_frontend->ops.release(budget->dvb_frontend); + if (budget->dvb_frontend->ops->release) + budget->dvb_frontend->ops->release(budget->dvb_frontend); budget->dvb_frontend = NULL; return; } diff --git a/trunk/drivers/media/dvb/ttusb-budget/Kconfig b/trunk/drivers/media/dvb/ttusb-budget/Kconfig index 92c7cdcf8981..914587d52b57 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/Kconfig +++ b/trunk/drivers/media/dvb/ttusb-budget/Kconfig @@ -6,8 +6,6 @@ config DVB_TTUSB_BUDGET select DVB_VES1820 select DVB_TDA8083 select DVB_STV0299 - select DVB_STV0297 - select DVB_LNBP21 help Support for external USB adapters designed by Technotrend and produced by Hauppauge, shipped under the brand name 'Nova-USB'. diff --git a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 14559ef6153c..6ceae38125c7 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -30,8 +30,6 @@ #include "tda1004x.h" #include "stv0299.h" #include "tda8083.h" -#include "stv0297.h" -#include "lnbp21.h" #include #include @@ -488,6 +486,31 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe, } #endif +static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +{ + struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; + int ret; + u8 data[1]; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; + + switch(voltage) { + case SEC_VOLTAGE_OFF: + data[0] = 0x00; + break; + case SEC_VOLTAGE_13: + data[0] = 0x44; + break; + case SEC_VOLTAGE_18: + data[0] = 0x4c; + break; + default: + return -EINVAL; + }; + + ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1); + return (ret != 1) ? -EIO : 0; +} + static int ttusb_update_lnb(struct ttusb *ttusb) { u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, @@ -1025,7 +1048,7 @@ static u32 functionality(struct i2c_adapter *adapter) -static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 data[4]; @@ -1039,21 +1062,20 @@ static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = ((div >> 10) & 0x60) | 0x85; data[3] = params->frequency < 592000000 ? 0x40 : 0x80; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; return 0; } static struct cx22700_config alps_tdmb7_config = { .demod_address = 0x43, + .pll_set = alps_tdmb7_pll_set, }; -static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) +static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; @@ -1061,8 +1083,6 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -1070,8 +1090,6 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) tuner_msg.addr = 0x65; tuner_msg.buf = disable_mc44BC374c; tuner_msg.len = sizeof(disable_mc44BC374c); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); } @@ -1079,7 +1097,7 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) return 0; } -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 tuner_buf[4]; @@ -1139,8 +1157,6 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb tuner_buf[2] = 0xca; tuner_buf[3] = (cp << 5) | (filter << 3) | band; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; @@ -1160,6 +1176,8 @@ static struct tda1004x_config philips_tdm1316l_config = { .demod_address = 0x8, .invert = 1, .invert_oclk = 0, + .pll_init = philips_tdm1316l_pll_init, + .pll_set = philips_tdm1316l_pll_set, .request_firmware = philips_tdm1316l_request_firmware, }; @@ -1281,7 +1299,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 return 0; } -static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 buf[4]; @@ -1304,9 +1322,7 @@ static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_ if (ttusb->revision == TTUSB_REV_2_2) buf[3] |= 0x20; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO; return 0; @@ -1322,9 +1338,10 @@ static struct stv0299_config alps_stv0299_config = { .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = alps_stv0299_set_symbol_rate, + .pll_set = philips_tsa5059_pll_set, }; -static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; u8 buf[4]; @@ -1338,8 +1355,6 @@ static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *f buf[2] = 0x8e; buf[3] = 0x00; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; @@ -1349,9 +1364,10 @@ static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *f static struct tda8083_config ttusb_novas_grundig_29504_491_config = { .demod_address = 0x68, + .pll_set = ttusb_novas_grundig_29504_491_pll_set, }; -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct ttusb* ttusb = fe->dvb->priv; u32 div; @@ -1365,8 +1381,6 @@ static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_front data[2] = 0x85 | ((div >> 10) & 0x60); data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; @@ -1379,6 +1393,7 @@ static struct ves1820_config alps_tdbe2_config = { .xin = 57840000UL, .invert = 1, .selagc = VES1820_SELAGC_SIGNAMPERR, + .pll_set = alps_tdbe2_pll_set, }; static u8 read_pwm(struct ttusb* ttusb) @@ -1395,174 +1410,6 @@ static u8 read_pwm(struct ttusb* ttusb) } -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv; - u8 tuner_buf[5]; - struct i2c_msg tuner_msg = {.addr = 0x60, - .flags = 0, - .buf = tuner_buf, - .len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency; - if (tuner_frequency < 87000000) {return -EINVAL;} - else if (tuner_frequency < 130000000) {cp = 3; band = 1;} - else if (tuner_frequency < 160000000) {cp = 5; band = 1;} - else if (tuner_frequency < 200000000) {cp = 6; band = 1;} - else if (tuner_frequency < 290000000) {cp = 3; band = 2;} - else if (tuner_frequency < 420000000) {cp = 5; band = 2;} - else if (tuner_frequency < 480000000) {cp = 6; band = 2;} - else if (tuner_frequency < 620000000) {cp = 3; band = 4;} - else if (tuner_frequency < 830000000) {cp = 5; band = 4;} - else if (tuner_frequency < 895000000) {cp = 7; band = 4;} - else {return -EINVAL;} - - // assume PLL filter should always be 8MHz for the moment. - filter = 1; - - // calculate divisor - // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz - tuner_frequency = ((params->frequency + 36125000) / 62500); - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xc8; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - tuner_buf[4] = 0x80; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { - printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n"); - return -EIO; - } - - msleep(50); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { - printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n"); - return -EIO; - } - - msleep(1); - - return 0; -} - -static u8 dvbc_philips_tdm1316l_inittab[] = { - 0x80, 0x21, - 0x80, 0x20, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x20, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0xff, - 0x4b, 0x7f, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x00, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x00, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x4b, - 0xc1, 0x00, - 0xc2, 0x00, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x38, - 0x62, 0x0a, - 0x53, 0x13, - 0x59, 0x08, - 0x55, 0x00, - 0x56, 0x40, - 0x57, 0x08, - 0x58, 0x3d, - 0x88, 0x10, - 0xa0, 0x00, - 0xa0, 0x00, - 0xa0, 0x00, - 0xa0, 0x04, - 0xff, 0xff, -}; - -static struct stv0297_config dvbc_philips_tdm1316l_config = { - .demod_address = 0x1c, - .inittab = dvbc_philips_tdm1316l_inittab, - .invert = 0, -}; - static void frontend_init(struct ttusb* ttusb) { switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { @@ -1570,13 +1417,11 @@ static void frontend_init(struct ttusb* ttusb) // try the stv0299 based first ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params; - if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 alps_stv0299_config.inittab = alps_bsbe1_inittab; - lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0); + ttusb->fe->ops->set_voltage = lnbp21_set_voltage; } else { // ALPS BSRU6 - ttusb->fe->ops.set_voltage = ttusb_set_voltage; + ttusb->fe->ops->set_voltage = ttusb_set_voltage; } break; } @@ -1584,41 +1429,28 @@ static void frontend_init(struct ttusb* ttusb) // Grundig 29504-491 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params; - ttusb->fe->ops.set_voltage = ttusb_set_voltage; + ttusb->fe->ops->set_voltage = ttusb_set_voltage; break; } + break; case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - break; - } - - ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; + if (ttusb->fe != NULL) break; - } break; case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) // try the ALPS TDMB7 first ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params; + if (ttusb->fe != NULL) break; - } // Philips td1316 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; + if (ttusb->fe != NULL) break; - } break; } @@ -1629,8 +1461,8 @@ static void frontend_init(struct ttusb* ttusb) } else { if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { printk("dvb-ttusb-budget: Frontend registration failed!\n"); - if (ttusb->fe->ops.release) - ttusb->fe->ops.release(ttusb->fe); + if (ttusb->fe->ops->release) + ttusb->fe->ops->release(ttusb->fe); ttusb->fe = NULL; } } @@ -1675,7 +1507,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i mutex_unlock(&ttusb->semi2c); - if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) { + if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { ttusb_free_iso_urbs(ttusb); kfree(ttusb); return result; diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 6c1cb770bcf5..44dea3211848 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1432,7 +1432,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); if ((result = dvb_register_adapter(&dec->adapter, - dec->model_name, THIS_MODULE, &dec->udev->dev)) < 0) { + dec->model_name, THIS_MODULE)) < 0) { printk("%s: dvb_register_adapter failed: error %d\n", __FUNCTION__, result); @@ -1657,8 +1657,8 @@ static int ttusb_dec_probe(struct usb_interface *intf, } else { if (dvb_register_frontend(&dec->adapter, dec->fe)) { printk("budget-ci: Frontend registration failed!\n"); - if (dec->fe->ops.release) - dec->fe->ops.release(dec->fe); + if (dec->fe->ops->release) + dec->fe->ops->release(dec->fe); dec->fe = NULL; } } diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 42f39a89bc4d..a5a46175fa09 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -28,6 +28,8 @@ struct ttusbdecfe_state { + struct dvb_frontend_ops ops; + /* configuration settings */ const struct ttusbdecfe_config* config; @@ -201,9 +203,10 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf /* setup the state */ state->config = config; + memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } @@ -223,9 +226,10 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf state->config = config; state->voltage = 0; state->hi_band = 0; + memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index de3128a31de8..3fff75763693 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -136,7 +136,7 @@ config RADIO_GEMTEK_PCI Choose Y here if you have this PCI FM radio card. In order to control your radio card, you will need to use programs - that are compatible with the Video for Linux API. Information on + that are compatible with the Video for Linux API. Information on this API and pointers to "v4l" programs may be found at . diff --git a/trunk/drivers/media/radio/Makefile b/trunk/drivers/media/radio/Makefile index e95b6805e002..8b351945d066 100644 --- a/trunk/drivers/media/radio/Makefile +++ b/trunk/drivers/media/radio/Makefile @@ -20,5 +20,3 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o - -EXTRA_CFLAGS += -Isound diff --git a/trunk/drivers/media/radio/miropcm20-radio.c b/trunk/drivers/media/radio/miropcm20-radio.c index c4312fa0e2f5..dc292da2605f 100644 --- a/trunk/drivers/media/radio/miropcm20-radio.c +++ b/trunk/drivers/media/radio/miropcm20-radio.c @@ -16,14 +16,13 @@ /* What ever you think about the ACI, version 0x07 is not very well! * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono - * conditions... Robert + * conditions... Robert */ #include #include #include -#include -#include "oss/aci.h" +#include "../../../sound/oss/aci.h" #include "miropcm20-rds-core.h" static int radio_nr = -1; @@ -124,7 +123,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, struct video_device *dev = video_devdata(file); struct pcm20_device *pcm20 = dev->priv; int i; - + switch(cmd) { case VIDIOCGCAP: @@ -140,7 +139,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=87*16000; v->rangehigh=108*16000; @@ -173,7 +172,7 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, return i; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags=VIDEO_AUDIO_MUTABLE; @@ -184,12 +183,12 @@ static int pcm20_do_ioctl(struct inode *inode, struct file *file, v->mode|=VIDEO_SOUND_MONO; /* v->step=2048; */ strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); @@ -238,7 +237,7 @@ static int __init pcm20_init(void) { if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1) goto video_register_device; - + if(attach_aci_rds()<0) goto attach_aci_rds; diff --git a/trunk/drivers/media/radio/miropcm20-rds-core.c b/trunk/drivers/media/radio/miropcm20-rds-core.c index 9428d8b2642c..b602c73e2309 100644 --- a/trunk/drivers/media/radio/miropcm20-rds-core.c +++ b/trunk/drivers/media/radio/miropcm20-rds-core.c @@ -21,7 +21,7 @@ #include #include -#include "oss/aci.h" +#include "../../../sound/oss/aci.h" #include "miropcm20-rds-core.h" #define DEBUG 0 @@ -33,24 +33,24 @@ static struct mutex aci_rds_mutex; #define RDS_BUSYMASK 0x10 /* Bit 4 */ #define RDS_CLOCKMASK 0x08 /* Bit 3 */ -#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) +#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1) #if DEBUG static void print_matrix(char array[], unsigned int length) { - int i, j; - - for (i=0; i=0; j--) { - printk("%d", (array[i] >> j) & 0x1); - } - if (i%8 == 0) - printk(" byte-border\n"); - else - printk("\n"); - } + int i, j; + + for (i=0; i=0; j--) { + printk("%d", (array[i] >> j) & 0x1); + } + if (i%8 == 0) + printk(" byte-border\n"); + else + printk("\n"); + } } #endif /* DEBUG */ @@ -114,7 +114,7 @@ static int rds_write(unsigned char cmd) { unsigned char sendbuffer[8]; int i; - + if (byte2trans(cmd, sendbuffer, 8) != 0){ return -1; } else { @@ -151,7 +151,7 @@ static int rds_read(unsigned char databuffer[], int datasize) I have to waitread() here */ if (rds_waitread() < 0) return -1; - + memset(databuffer, 0, datasize); for (i=0; i< READSIZE; i++) @@ -194,7 +194,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize) ret = 0; mutex_unlock(&aci_rds_mutex); - + return ret; } EXPORT_SYMBOL(aci_rds_cmd); diff --git a/trunk/drivers/media/radio/miropcm20-rds.c b/trunk/drivers/media/radio/miropcm20-rds.c index 87b37b7691da..e09214082e01 100644 --- a/trunk/drivers/media/radio/miropcm20-rds.c +++ b/trunk/drivers/media/radio/miropcm20-rds.c @@ -48,7 +48,7 @@ static int rds_f_release(struct inode *in, struct file *fi) static void print_matrix(char *ch, char out[]) { - int j; + int j; for (j=7; j>=0; j--) { out[7-j] = ((*ch >> j) & 0x1) + '0'; diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index df22a582e7a2..557fb5c4af38 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -24,7 +24,7 @@ * out(port, start_increasing_volume); * wait(a_wee_while); * out(port, stop_changing_the_volume); - * + * */ #include /* Modules */ @@ -34,7 +34,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_RTRACK_PORT */ #include /* Lock for the I/O */ @@ -42,7 +41,7 @@ #define CONFIG_RADIO_RTRACK_PORT -1 #endif -static int io = CONFIG_RADIO_RTRACK_PORT; +static int io = CONFIG_RADIO_RTRACK_PORT; static int radio_nr = -1; static struct mutex lock; @@ -94,12 +93,12 @@ static int rt_setvol(struct rt_device *dev, int vol) int i; mutex_lock(&lock); - + if(vol == dev->curvol) { /* requested volume = current */ if (dev->muted) { /* user is unmuting the card */ dev->muted = 0; outb (0xd8, io); /* enable card */ - } + } mutex_unlock(&lock); return 0; } @@ -115,10 +114,10 @@ static int rt_setvol(struct rt_device *dev, int vol) dev->muted = 0; if(vol > dev->curvol) - for(i = dev->curvol; i < vol; i++) + for(i = dev->curvol; i < vol; i++) rt_incvol(); else - for(i = dev->curvol; i > vol; i--) + for(i = dev->curvol; i > vol; i--) rt_decvol(); dev->curvol = vol; @@ -126,7 +125,7 @@ static int rt_setvol(struct rt_device *dev, int vol) return 0; } -/* the 128+64 on these outb's is to keep the volume stable while tuning +/* the 128+64 on these outb's is to keep the volume stable while tuning * without them, the volume _will_ creep up with each frequency change * and bit 4 (+16) is to keep the signal strength meter enabled */ @@ -141,7 +140,7 @@ static void send_0_byte(int port, struct rt_device *dev) outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ outb_p(128+64+16+8+2+1, port); /* clock */ } - sleep_delay(1000); + sleep_delay(1000); } static void send_1_byte(int port, struct rt_device *dev) @@ -149,13 +148,13 @@ static void send_1_byte(int port, struct rt_device *dev) if ((dev->curvol == 0) || (dev->muted)) { outb_p(128+64+16+4 +1, port); /* wr-enable+data high */ outb_p(128+64+16+4+2+1, port); /* clock */ - } + } else { outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */ outb_p(128+64+16+8+4+2+1, port); /* clock */ } - sleep_delay(1000); + sleep_delay(1000); } static int rt_setfreq(struct rt_device *dev, unsigned long freq) @@ -168,9 +167,9 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) freq += 171200; /* Add 10.7 MHz IF */ freq /= 800; /* Convert to 50 kHz units */ - + mutex_lock(&lock); /* Stop other ops interfering */ - + send_0_byte (io, dev); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ @@ -196,7 +195,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) outb (0xd0, io); /* volume steady + sigstr */ else outb (0xd8, io); /* volume steady + sigstr + on */ - + mutex_unlock(&lock); return 0; @@ -214,7 +213,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct rt_device *rt=dev->priv; - + switch(cmd) { case VIDIOCGCAP: @@ -230,7 +229,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=(87*16000); v->rangehigh=(108*16000); @@ -262,21 +261,21 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; v->volume=rt->curvol * 6554; v->step=6554; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) rt_mute(rt); else rt_setvol(rt,v->volume/6554); @@ -299,7 +298,7 @@ static struct file_operations rtrack_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, .release = video_exclusive_release, - .ioctl = rt_ioctl, + .ioctl = rt_ioctl, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -321,14 +320,14 @@ static int __init rtrack_init(void) return -EINVAL; } - if (!request_region(io, 2, "rtrack")) + if (!request_region(io, 2, "rtrack")) { printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); return -EBUSY; } rtrack_radio.priv=&rtrack_unit; - + if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io, 2); @@ -337,10 +336,10 @@ static int __init rtrack_init(void) printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); /* Set up the I/O locking */ - + mutex_init(&lock); - - /* mute card - prevents noisy bootups */ + + /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0x48, io); /* volume down but still "on" */ diff --git a/trunk/drivers/media/radio/radio-aztech.c b/trunk/drivers/media/radio/radio-aztech.c index 95e6322133ee..83bdae23417d 100644 --- a/trunk/drivers/media/radio/radio-aztech.c +++ b/trunk/drivers/media/radio/radio-aztech.c @@ -1,11 +1,11 @@ -/* radio-aztech.c - Aztech radio card driver for Linux 2.2 +/* radio-aztech.c - Aztech radio card driver for Linux 2.2 * - * Adapted to support the Video for Linux API by + * Adapted to support the Video for Linux API by * Russell Kroll . Based on original tuner code by: * * Quay Ly * Donald Song - * Jason Lewis (jlewis@twilight.vtc.vsc.edu) + * Jason Lewis (jlewis@twilight.vtc.vsc.edu) * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) * William McGrath (wmcgrath@twilight.vtc.vsc.edu) * @@ -31,7 +31,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_AZTECH_PORT */ /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -40,7 +39,7 @@ #define CONFIG_RADIO_AZTECH_PORT -1 #endif -static int io = CONFIG_RADIO_AZTECH_PORT; +static int io = CONFIG_RADIO_AZTECH_PORT; static int radio_nr = -1; static int radio_wait_time = 1000; static struct mutex lock; @@ -54,15 +53,15 @@ struct az_device static int volconvert(int level) { - level>>=14; /* Map 16bits down to 2 bit */ - level&=3; - + level>>=14; /* Map 16bits down to 2 bit */ + level&=3; + /* convert to card-friendly values */ - switch (level) + switch (level) { - case 0: + case 0: return 0; - case 1: + case 1: return 1; case 2: return 4; @@ -122,9 +121,9 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) frequency += 171200; /* Add 10.7 MHz IF */ frequency /= 800; /* Convert to 50 kHz units */ - + mutex_lock(&lock); - + send_0_byte (dev); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ @@ -152,7 +151,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) udelay (radio_wait_time); outb_p(128+64+volconvert(dev->curvol), io); - + mutex_unlock(&lock); return 0; @@ -163,7 +162,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; - + switch(cmd) { case VIDIOCGCAP: @@ -179,7 +178,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=(87*16000); v->rangehigh=(108*16000); @@ -212,7 +211,7 @@ static int az_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; @@ -223,17 +222,17 @@ static int az_do_ioctl(struct inode *inode, struct file *file, v->volume=az->curvol; v->step=16384; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; az->curvol=v->volume; az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) az_setvol(az,0); else az_setvol(az,az->curvol); @@ -278,7 +277,7 @@ static int __init aztech_init(void) return -EINVAL; } - if (!request_region(io, 2, "aztech")) + if (!request_region(io, 2, "aztech")) { printk(KERN_ERR "aztech: port 0x%x already in use\n", io); return -EBUSY; @@ -286,13 +285,13 @@ static int __init aztech_init(void) mutex_init(&lock); aztech_radio.priv=&aztech_unit; - + if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io,2); return -EINVAL; } - + printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); /* mute card - prevents noisy bootups */ outb (0, io); diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index 8641aec7baf8..f1b5ac81e9d2 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -8,7 +8,7 @@ * Russell Kroll (rkroll@exploits.org) * Quay Ly * Donald Song - * Jason Lewis (jlewis@twilight.vtc.vsc.edu) + * Jason Lewis (jlewis@twilight.vtc.vsc.edu) * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) * William McGrath (wmcgrath@twilight.vtc.vsc.edu) * @@ -34,7 +34,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include #include @@ -56,29 +55,29 @@ static int cadet_probe(void); /* * Signal Strength Threshold Values - * The V4L API spec does not define any particular unit for the signal + * The V4L API spec does not define any particular unit for the signal * strength value. These values are in microvolts of RF at the tuner's input. */ static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; static int cadet_getrds(void) { - int rdsstat=0; + int rdsstat=0; spin_lock(&cadet_io_lock); - outb(3,io); /* Select Decoder Control/Status */ + outb(3,io); /* Select Decoder Control/Status */ outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */ spin_unlock(&cadet_io_lock); - + msleep(100); - spin_lock(&cadet_io_lock); - outb(3,io); /* Select Decoder Control/Status */ + spin_lock(&cadet_io_lock); + outb(3,io); /* Select Decoder Control/Status */ if((inb(io+1)&0x80)!=0) { - rdsstat|=VIDEO_TUNER_RDS_ON; + rdsstat|=VIDEO_TUNER_RDS_ON; } if((inb(io+1)&0x10)!=0) { - rdsstat|=VIDEO_TUNER_MBS_ON; + rdsstat|=VIDEO_TUNER_MBS_ON; } spin_unlock(&cadet_io_lock); return rdsstat; @@ -87,49 +86,49 @@ static int cadet_getrds(void) static int cadet_getstereo(void) { int ret = 0; - if(curtuner != 0) /* Only FM has stereo capability! */ - return 0; + if(curtuner != 0) /* Only FM has stereo capability! */ + return 0; spin_lock(&cadet_io_lock); - outb(7,io); /* Select tuner control */ + outb(7,io); /* Select tuner control */ if( (inb(io+1) & 0x40) == 0) - ret = 1; - spin_unlock(&cadet_io_lock); - return ret; + ret = 1; + spin_unlock(&cadet_io_lock); + return ret; } static unsigned cadet_gettune(void) { - int curvol,i; + int curvol,i; unsigned fifo=0; - /* - * Prepare for read - */ + /* + * Prepare for read + */ spin_lock(&cadet_io_lock); - - outb(7,io); /* Select tuner control */ - curvol=inb(io+1); /* Save current volume/mute setting */ - outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ + + outb(7,io); /* Select tuner control */ + curvol=inb(io+1); /* Save current volume/mute setting */ + outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ tunestat=0xffff; - /* - * Read the shift register - */ - for(i=0;i<25;i++) { - fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); - if(i<24) { - outb(0x01,io+1); + /* + * Read the shift register + */ + for(i=0;i<25;i++) { + fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); + if(i<24) { + outb(0x01,io+1); tunestat&=inb(io+1); - outb(0x00,io+1); - } - } - - /* - * Restore volume/mute setting - */ - outb(curvol,io+1); + outb(0x00,io+1); + } + } + + /* + * Restore volume/mute setting + */ + outb(curvol,io+1); spin_unlock(&cadet_io_lock); return fifo; @@ -137,43 +136,43 @@ static unsigned cadet_gettune(void) static unsigned cadet_getfreq(void) { - int i; - unsigned freq=0,test,fifo=0; + int i; + unsigned freq=0,test,fifo=0; /* * Read current tuning */ fifo=cadet_gettune(); - /* - * Convert to actual frequency - */ + /* + * Convert to actual frequency + */ if(curtuner==0) { /* FM */ - test=12500; - for(i=0;i<14;i++) { - if((fifo&0x01)!=0) { - freq+=test; - } - test=test<<1; - fifo=fifo>>1; - } - freq-=10700000; /* IF frequency is 10.7 MHz */ - freq=(freq*16)/1000000; /* Make it 1/16 MHz */ + test=12500; + for(i=0;i<14;i++) { + if((fifo&0x01)!=0) { + freq+=test; + } + test=test<<1; + fifo=fifo>>1; + } + freq-=10700000; /* IF frequency is 10.7 MHz */ + freq=(freq*16)/1000000; /* Make it 1/16 MHz */ } if(curtuner==1) { /* AM */ - freq=((fifo&0x7fff)-2010)*16; + freq=((fifo&0x7fff)-2010)*16; } - return freq; + return freq; } static void cadet_settune(unsigned fifo) { - int i; - unsigned test; + int i; + unsigned test; spin_lock(&cadet_io_lock); - + outb(7,io); /* Select tuner control */ /* * Write the shift register @@ -184,7 +183,7 @@ static void cadet_settune(unsigned fifo) outb(7,io); /* Select tuner control */ outb(test,io+1); /* Initialize for write */ for(i=0;i<25;i++) { - test|=0x01; /* Toggle SCK High */ + test|=0x01; /* Toggle SCK High */ outb(test,io+1); test&=0xfe; /* Toggle SCK Low */ outb(test,io+1); @@ -197,57 +196,57 @@ static void cadet_settune(unsigned fifo) static void cadet_setfreq(unsigned freq) { - unsigned fifo; - int i,j,test; - int curvol; + unsigned fifo; + int i,j,test; + int curvol; - /* - * Formulate a fifo command - */ + /* + * Formulate a fifo command + */ fifo=0; if(curtuner==0) { /* FM */ - test=102400; - freq=(freq*1000)/16; /* Make it kHz */ - freq+=10700; /* IF is 10700 kHz */ - for(i=0;i<14;i++) { - fifo=fifo<<1; - if(freq>=test) { - fifo|=0x01; - freq-=test; - } - test=test>>1; - } + test=102400; + freq=(freq*1000)/16; /* Make it kHz */ + freq+=10700; /* IF is 10700 kHz */ + for(i=0;i<14;i++) { + fifo=fifo<<1; + if(freq>=test) { + fifo|=0x01; + freq-=test; + } + test=test>>1; + } } if(curtuner==1) { /* AM */ - fifo=(freq/16)+2010; /* Make it kHz */ + fifo=(freq/16)+2010; /* Make it kHz */ fifo|=0x100000; /* Select AM Band */ } - /* - * Save current volume/mute setting - */ + /* + * Save current volume/mute setting + */ spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ - curvol=inb(io+1); - spin_unlock(&cadet_io_lock); + curvol=inb(io+1); + spin_unlock(&cadet_io_lock); /* * Tune the card */ for(j=3;j>-1;j--) { - cadet_settune(fifo|(j<<16)); - - spin_lock(&cadet_io_lock); + cadet_settune(fifo|(j<<16)); + + spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ outb(curvol,io+1); spin_unlock(&cadet_io_lock); - + msleep(100); cadet_gettune(); if((tunestat & 0x40) == 0) { /* Tuned */ - sigstrength=sigtable[curtuner][j]; + sigstrength=sigtable[curtuner][j]; return; } } @@ -258,28 +257,28 @@ static void cadet_setfreq(unsigned freq) static int cadet_getvol(void) { int ret = 0; - + spin_lock(&cadet_io_lock); - - outb(7,io); /* Select tuner control */ - if((inb(io + 1) & 0x20) != 0) - ret = 0xffff; - - spin_unlock(&cadet_io_lock); - return ret; + + outb(7,io); /* Select tuner control */ + if((inb(io + 1) & 0x20) != 0) + ret = 0xffff; + + spin_unlock(&cadet_io_lock); + return ret; } static void cadet_setvol(int vol) { spin_lock(&cadet_io_lock); - outb(7,io); /* Select tuner control */ - if(vol>0) - outb(0x20,io+1); - else - outb(0x00,io+1); + outb(7,io); /* Select tuner control */ + if(vol>0) + outb(0x20,io+1); + else + outb(0x00,io+1); spin_unlock(&cadet_io_lock); -} +} static void cadet_handler(unsigned long data) { @@ -289,15 +288,15 @@ static void cadet_handler(unsigned long data) if(spin_trylock(&cadet_io_lock)) { - outb(0x3,io); /* Select RDS Decoder Control */ + outb(0x3,io); /* Select RDS Decoder Control */ if((inb(io+1)&0x20)!=0) { - printk(KERN_CRIT "cadet: RDS fifo overflow\n"); + printk(KERN_CRIT "cadet: RDS fifo overflow\n"); } outb(0x80,io); /* Select RDS fifo */ while((inb(io)&0x80)!=0) { - rdsbuf[rdsin]=inb(io+1); + rdsbuf[rdsin]=inb(io+1); if(rdsin==rdsout) - printk(KERN_WARNING "cadet: RDS buffer overflow\n"); + printk(KERN_WARNING "cadet: RDS buffer overflow\n"); else rdsin++; } @@ -308,9 +307,9 @@ static void cadet_handler(unsigned long data) * Service pending read */ if( rdsin!=rdsout) - wake_up_interruptible(&read_queue); + wake_up_interruptible(&read_queue); - /* + /* * Clean up and exit */ init_timer(&readtimer); @@ -325,12 +324,12 @@ static void cadet_handler(unsigned long data) static ssize_t cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { - int i=0; + int i=0; unsigned char readbuf[RDS_BUFFER]; - if(rdsstat==0) { + if(rdsstat==0) { spin_lock(&cadet_io_lock); - rdsstat=1; + rdsstat=1; outb(0x80,io); /* Select RDS fifo */ spin_unlock(&cadet_io_lock); init_timer(&readtimer); @@ -340,15 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, add_timer(&readtimer); } if(rdsin==rdsout) { - if (file->f_flags & O_NONBLOCK) - return -EWOULDBLOCK; - interruptible_sleep_on(&read_queue); - } + if (file->f_flags & O_NONBLOCK) + return -EWOULDBLOCK; + interruptible_sleep_on(&read_queue); + } while( ituner) { - case 0: - strcpy(v->name,"FM"); - v->rangelow=1400; /* 87.5 MHz */ - v->rangehigh=1728; /* 108.0 MHz */ - v->flags=0; - v->mode=0; - v->mode|=VIDEO_MODE_AUTO; - v->signal=sigstrength; - if(cadet_getstereo()==1) { - v->flags|=VIDEO_TUNER_STEREO_ON; - } + case 0: + strcpy(v->name,"FM"); + v->rangelow=1400; /* 87.5 MHz */ + v->rangehigh=1728; /* 108.0 MHz */ + v->flags=0; + v->mode=0; + v->mode|=VIDEO_MODE_AUTO; + v->signal=sigstrength; + if(cadet_getstereo()==1) { + v->flags|=VIDEO_TUNER_STEREO_ON; + } v->flags|=cadet_getrds(); - break; - case 1: - strcpy(v->name,"AM"); - v->rangelow=8320; /* 520 kHz */ - v->rangehigh=26400; /* 1650 kHz */ - v->flags=0; - v->flags|=VIDEO_TUNER_LOW; - v->mode=0; - v->mode|=VIDEO_MODE_AUTO; - v->signal=sigstrength; - break; + break; + case 1: + strcpy(v->name,"AM"); + v->rangelow=8320; /* 520 kHz */ + v->rangehigh=26400; /* 1650 kHz */ + v->flags=0; + v->flags|=VIDEO_TUNER_LOW; + v->mode=0; + v->mode|=VIDEO_MODE_AUTO; + v->signal=sigstrength; + break; } return 0; } @@ -408,49 +407,49 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file, if((v->tuner<0)||(v->tuner>1)) { return -EINVAL; } - curtuner=v->tuner; + curtuner=v->tuner; return 0; } case VIDIOCGFREQ: { - unsigned long *freq = arg; + unsigned long *freq = arg; *freq = cadet_getfreq(); return 0; } case VIDIOCSFREQ: { - unsigned long *freq = arg; + unsigned long *freq = arg; if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { - return -EINVAL; + return -EINVAL; } if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { - return -EINVAL; + return -EINVAL; } cadet_setfreq(*freq); return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; if(cadet_getstereo()==0) { - v->mode=VIDEO_SOUND_MONO; + v->mode=VIDEO_SOUND_MONO; } else { v->mode=VIDEO_SOUND_STEREO; } v->volume=cadet_getvol(); v->step=0xffff; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; cadet_setvol(v->volume); - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) cadet_setvol(0); else cadet_setvol(0xffff); @@ -540,16 +539,16 @@ static struct pnp_driver cadet_pnp_driver = { static int cadet_probe(void) { - static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; + static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; int i; for(i=0;i<8;i++) { - io=iovals[i]; + io=iovals[i]; if (request_region(io, 2, "cadet-probe")) { - cadet_setfreq(1410); + cadet_setfreq(1410); if(cadet_getfreq()==1410) { release_region(io, 2); - return io; + return io; } release_region(io, 2); } @@ -557,7 +556,7 @@ static int cadet_probe(void) return -1; } -/* +/* * io should only be set if the user has used something like * isapnp (the userspace program) to initialize this card for us */ @@ -565,7 +564,7 @@ static int cadet_probe(void) static int __init cadet_init(void) { spin_lock_init(&cadet_io_lock); - + /* * If a probe was requested then probe ISAPnP first (safest) */ @@ -580,12 +579,12 @@ static int __init cadet_init(void) /* * Else we bail out */ - - if(io < 0) { -#ifdef MODULE + + if(io < 0) { +#ifdef MODULE printk(KERN_ERR "You must set an I/O address with io=0x???\n"); #endif - goto fail; + goto fail; } if (!request_region(io,2,"cadet")) goto fail; diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c index 9f249e7e60c9..8e499b8f64c7 100644 --- a/trunk/drivers/media/radio/radio-gemtek-pci.c +++ b/trunk/drivers/media/radio/radio-gemtek-pci.c @@ -1,6 +1,6 @@ /* *************************************************************************** - * + * * radio-gemtek-pci.c - Gemtek PCI Radio driver * (C) 2001 Vladimir Shebordaev * @@ -31,7 +31,7 @@ * radio device driver. * * Please, let me know if this piece of code was useful :) - * + * * TODO: multiple device support and portability were not tested * *************************************************************************** @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -70,18 +69,18 @@ #define TRUE (1) #endif -#ifndef FALSE +#ifndef FALSE #define FALSE (0) #endif struct gemtek_pci_card { struct video_device *videodev; - + u32 iobase; u32 length; u8 chiprev; u16 model; - + u32 current_frequency; u8 mute; }; @@ -97,7 +96,7 @@ static inline u8 gemtek_pci_out( u16 value, u32 port ) return (u8)value; } -#define _b0( v ) *((u8 *)&v) +#define _b0( v ) *((u8 *)&v) static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) { register u8 byte = *last_byte; @@ -105,7 +104,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) if ( !value ) { if ( !keep ) value = (u16)port; - byte &= 0xfd; + byte &= 0xfd; } else byte |= 2; @@ -117,7 +116,7 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) byte &= 0xfe; _b0( value ) = byte; outw( value, port ); - + *last_byte = byte; } @@ -194,13 +193,13 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, c->audios = 1; strcpy( c->name, "Gemtek PCI Radio" ); return 0; - } + } case VIDIOCGTUNER: { struct video_tuner *t = arg; - if ( t->tuner ) + if ( t->tuner ) return -EINVAL; t->rangelow = GEMTEK_PCI_RANGE_LOW; @@ -229,7 +228,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, case VIDIOCSFREQ: { unsigned long *freq = arg; - + if ( (*freq < GEMTEK_PCI_RANGE_LOW) || (*freq > GEMTEK_PCI_RANGE_HIGH) ) return -EINVAL; @@ -240,9 +239,9 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, return 0; } - + case VIDIOCGAUDIO: - { + { struct video_audio *a = arg; memset( a, 0, sizeof( *a ) ); @@ -250,17 +249,17 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, a->volume = 1; a->step = 65535; strcpy( a->name, "Radio" ); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *a = arg; - if ( a->audio ) + if ( a->audio ) return -EINVAL; - if ( a->flags & VIDEO_AUDIO_MUTE ) + if ( a->flags & VIDEO_AUDIO_MUTE ) gemtek_pci_mute( card ); else gemtek_pci_unmute( card ); @@ -324,9 +323,9 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci return -ENOMEM; } - if ( pci_enable_device( pci_dev ) ) + if ( pci_enable_device( pci_dev ) ) goto err_pci; - + card->iobase = pci_resource_start( pci_dev, 0 ); card->length = pci_resource_len( pci_dev, 0 ); @@ -339,7 +338,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci pci_read_config_word( pci_dev, PCI_SUBSYSTEM_ID, &card->model ); pci_set_drvdata( pci_dev, card ); - + if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { printk( KERN_ERR "gemtek_pci: out of memory\n" ); goto err_video; @@ -355,7 +354,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci devradio->priv = card; gemtek_pci_mute( card ); - printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", + printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", card->chiprev, card->iobase, card->iobase + card->length - 1 ); return 0; @@ -365,7 +364,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci err_pci: kfree( card ); - return -ENODEV; + return -ENODEV; } static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) @@ -376,12 +375,12 @@ static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) kfree( card->videodev ); release_region( card->iobase, card->length ); - + if ( mx ) gemtek_pci_mute( card ); kfree( card ); - + pci_set_drvdata( pci_dev, NULL ); } diff --git a/trunk/drivers/media/radio/radio-gemtek.c b/trunk/drivers/media/radio/radio-gemtek.c index 162f37d8bf96..47173be97b9f 100644 --- a/trunk/drivers/media/radio/radio-gemtek.c +++ b/trunk/drivers/media/radio/radio-gemtek.c @@ -6,7 +6,7 @@ * Besides the protocol changes, this is mostly a copy of: * * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff - * + * * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood * Converted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll @@ -22,7 +22,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_GEMTEK_PORT */ #include @@ -30,7 +29,7 @@ #define CONFIG_RADIO_GEMTEK_PORT -1 #endif -static int io = CONFIG_RADIO_GEMTEK_PORT; +static int io = CONFIG_RADIO_GEMTEK_PORT; static int radio_nr = -1; static spinlock_t lock; @@ -49,7 +48,7 @@ struct gemtek_device */ static void gemtek_mute(struct gemtek_device *dev) { - if(dev->muted) + if(dev->muted) return; spin_lock(&lock); outb(0x10, io); @@ -95,20 +94,20 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) freq /= 100000; spin_lock(&lock); - + /* 2 start bits */ outb_p(0x03, io); udelay(5); outb_p(0x07, io); udelay(5); - /* 28 frequency bits (lsb first) */ + /* 28 frequency bits (lsb first) */ for (i = 0; i < 14; i++) if (freq & (1 << i)) one(); else zero(); - /* 36 unknown bits */ + /* 36 unknown bits */ for (i = 0; i < 11; i++) zero(); one(); @@ -124,7 +123,7 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) udelay(5); spin_unlock(&lock); - + return 0; } @@ -160,7 +159,7 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=87*16000; v->rangehigh=108*16000; @@ -194,25 +193,25 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags|=VIDEO_AUDIO_MUTABLE; v->volume=1; v->step=65535; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) gemtek_mute(rt); else - gemtek_unmute(rt); + gemtek_unmute(rt); return 0; } @@ -255,14 +254,14 @@ static int __init gemtek_init(void) return -EINVAL; } - if (!request_region(io, 4, "gemtek")) + if (!request_region(io, 4, "gemtek")) { printk(KERN_ERR "gemtek: port 0x%x already in use\n", io); return -EBUSY; } gemtek_radio.priv=&gemtek_unit; - + if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io, 4); @@ -275,7 +274,7 @@ static int __init gemtek_init(void) /* this is _maybe_ unnecessary */ outb(0x01, io); - /* mute card - prevents noisy bootups */ + /* mute card - prevents noisy bootups */ gemtek_unit.muted = 0; gemtek_mute(&gemtek_unit); diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c index fcfa6c9fe225..39c1d9118636 100644 --- a/trunk/drivers/media/radio/radio-maestro.c +++ b/trunk/drivers/media/radio/radio-maestro.c @@ -2,7 +2,7 @@ * (c) 2000 A. Tlalka, atlka@pg.gda.pl * Notes on the hardware * - * + Frequency control is done digitally + * + Frequency control is done digitally * + No volume control - only mute/unmute - you have to use Aux line volume * control on Maestro card to set the volume * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after @@ -26,7 +26,7 @@ #include #include #include -#include + #define DRIVER_VERSION "0.05" @@ -103,7 +103,7 @@ static struct video_device maestro_radio = { struct radio_device { u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ muted, /* VIDEO_AUDIO_MUTE */ - stereo, /* VIDEO_TUNER_STEREO_ON */ + stereo, /* VIDEO_TUNER_STEREO_ON */ tuned; /* signal strength (0 or 0xffff) */ struct mutex lock; }; @@ -122,14 +122,14 @@ static u32 radio_bits_get(struct radio_device *dev) for (l=24;l--;) { outw(STR_CLK, io); /* HI state */ udelay(2); - if(!l) + if(!l) dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; outw(0, io); /* LO state */ udelay(2); data <<= 1; /* shift data */ rdata = inw(io); if(!l) - dev->stereo = rdata & STR_MOST ? + dev->stereo = rdata & STR_MOST ? 0 : VIDEO_TUNER_STEREO_ON; else if(rdata & STR_DATA) diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c index f93d7afe7304..f0bf47bcb64c 100644 --- a/trunk/drivers/media/radio/radio-maxiradio.c +++ b/trunk/drivers/media/radio/radio-maxiradio.c @@ -1,15 +1,15 @@ -/* - * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux +/* + * Guillemot Maxi Radio FM 2000 PCI radio card driver for Linux * (C) 2001 Dimitromanolakis Apostolos * * Based in the radio Maestro PCI driver. Actually it uses the same chip * for radio but different pci controller. * * I didn't have any specs I reversed engineered the protocol from - * the windows driver (radio.dll). + * the windows driver (radio.dll). * * The card uses the TEA5757 chip that includes a search function but it - * is useless as I haven't found any way to read back the frequency. If + * is useless as I haven't found any way to read back the frequency. If * anybody does please mail me. * * For the pdf file see: @@ -24,7 +24,7 @@ * - tiding up * - removed support for multiple devices as it didn't work anyway * - * BUGS: + * BUGS: * - card unmutes if you change frequency * */ @@ -41,7 +41,6 @@ #include #include -#include /* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ #define DRIVER_VERSION "0.75" @@ -81,7 +80,7 @@ static struct file_operations maxiradio_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, .release = video_exclusive_release, - .ioctl = radio_ioctl, + .ioctl = radio_ioctl, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -98,11 +97,11 @@ static struct radio_device { __u16 io, /* base of radio io */ muted, /* VIDEO_AUDIO_MUTE */ - stereo, /* VIDEO_TUNER_STEREO_ON */ + stereo, /* VIDEO_TUNER_STEREO_ON */ tuned; /* signal strength (0 or 0xffff) */ - + unsigned long freq; - + struct mutex lock; } radio_unit = {0, 0, 0, 0, }; @@ -115,7 +114,7 @@ static void outbit(unsigned long bit, __u16 io) outb( power|wren|data|clk ,io); udelay(4); outb( power|wren|data ,io); udelay(4); } - else + else { outb( power|wren ,io); udelay(4); outb( power|wren|clk ,io); udelay(4); @@ -133,12 +132,12 @@ static void set_freq(__u16 io, __u32 data) { unsigned long int si; int bl; - + /* TEA5757 shift register bits (see pdf) */ - outbit(0,io); // 24 search + outbit(0,io); // 24 search outbit(1,io); // 23 search up/down - + outbit(0,io); // 22 stereo/mono outbit(0,io); // 21 band @@ -146,24 +145,24 @@ static void set_freq(__u16 io, __u32 data) outbit(0,io); // 19 port ? outbit(0,io); // 18 port ? - + outbit(0,io); // 17 search level outbit(0,io); // 16 search level - + si = 0x8000; for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } - + outb(power,io); } static int get_stereo(__u16 io) -{ +{ outb(power,io); udelay(4); return !(inb(io) & mo_st); } static int get_tune(__u16 io) -{ +{ outb(power+clk,io); udelay(4); return !(inb(io) & mo_st); } @@ -178,7 +177,7 @@ static inline int radio_function(struct inode *inode, struct file *file, switch(cmd) { case VIDIOCGCAP: { struct video_capability *v = arg; - + memset(v,0,sizeof(*v)); strcpy(v->name, "Maxi Radio FM2000 radio"); v->type=VID_TYPE_TUNER; @@ -187,22 +186,22 @@ static inline int radio_function(struct inode *inode, struct file *file, } case VIDIOCGTUNER: { struct video_tuner *v = arg; - + if(v->tuner) return -EINVAL; - + card->stereo = 0xffff * get_stereo(card->io); card->tuned = 0xffff * get_tune(card->io); - + v->flags = VIDEO_TUNER_LOW | card->stereo; v->signal = card->tuned; - + strcpy(v->name, "FM"); - + v->rangelow = FREQ_LO; v->rangehigh = FREQ_HI; v->mode = VIDEO_MODE_AUTO; - + return 0; } case VIDIOCSTUNER: { @@ -213,13 +212,13 @@ static inline int radio_function(struct inode *inode, struct file *file, } case VIDIOCGFREQ: { unsigned long *freq = arg; - + *freq = card->freq; return 0; } case VIDIOCSFREQ: { unsigned long *freq = arg; - + if (*freq < FREQ_LO || *freq > FREQ_HI) return -EINVAL; card->freq = *freq; @@ -227,18 +226,18 @@ static inline int radio_function(struct inode *inode, struct file *file, msleep(125); return 0; } - case VIDIOCGAUDIO: { + case VIDIOCGAUDIO: { struct video_audio *v = arg; memset(v,0,sizeof(*v)); strcpy(v->name, "Radio"); v->flags=VIDEO_AUDIO_MUTABLE | card->muted; v->mode=VIDEO_SOUND_STEREO; - return 0; + return 0; } - + case VIDIOCSAUDIO: { struct video_audio *v = arg; - + if(v->audio) return -EINVAL; card->muted = v->flags & VIDEO_AUDIO_MUTE; @@ -250,13 +249,13 @@ static inline int radio_function(struct inode *inode, struct file *file, } case VIDIOCGUNIT: { struct video_unit *v = arg; - + v->video=VIDEO_NO_UNIT; v->vbi=VIDEO_NO_UNIT; v->radio=dev->minor; v->audio=0; v->teletext=VIDEO_NO_UNIT; - return 0; + return 0; } default: return -ENOIOCTLCMD; } @@ -268,7 +267,7 @@ static int radio_ioctl(struct inode *inode, struct file *file, struct video_device *dev = video_devdata(file); struct radio_device *card=dev->priv; int ret; - + mutex_lock(&card->lock); ret = video_usercopy(inode, file, cmd, arg, radio_function); mutex_unlock(&card->lock); @@ -283,21 +282,21 @@ MODULE_LICENSE("GPL"); static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { if(!request_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { - printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); - goto err_out; + pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { + printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); + goto err_out; } if (pci_enable_device(pdev)) - goto err_out_free_region; + goto err_out_free_region; radio_unit.io = pci_resource_start(pdev, 0); mutex_init(&radio_unit.lock); maxiradio_radio.priv = &radio_unit; if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { - printk("radio-maxiradio: can't register device!"); - goto err_out_free_region; + printk("radio-maxiradio: can't register device!"); + goto err_out_free_region; } printk(KERN_INFO "radio-maxiradio: version " diff --git a/trunk/drivers/media/radio/radio-rtrack2.c b/trunk/drivers/media/radio/radio-rtrack2.c index 5b68ac4c7322..28a47c9e7a81 100644 --- a/trunk/drivers/media/radio/radio-rtrack2.c +++ b/trunk/drivers/media/radio/radio-rtrack2.c @@ -1,5 +1,5 @@ /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff - * + * * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood * Converted to new API by Alan Cox * Various bugfixes and enhancements by Russell Kroll @@ -15,7 +15,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_RTRACK2_PORT */ #include @@ -23,7 +22,7 @@ #define CONFIG_RADIO_RTRACK2_PORT -1 #endif -static int io = CONFIG_RADIO_RTRACK2_PORT; +static int io = CONFIG_RADIO_RTRACK2_PORT; static int radio_nr = -1; static spinlock_t lock; @@ -39,7 +38,7 @@ struct rt_device static void rt_mute(struct rt_device *dev) { - if(dev->muted) + if(dev->muted) return; spin_lock(&lock); outb(1, io); @@ -59,14 +58,14 @@ static void rt_unmute(struct rt_device *dev) static void zero(void) { - outb_p(1, io); + outb_p(1, io); outb_p(3, io); outb_p(1, io); } static void one(void) { - outb_p(5, io); + outb_p(5, io); outb_p(7, io); outb_p(5, io); } @@ -76,7 +75,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) int i; freq = freq / 200 + 856; - + spin_lock(&lock); outb_p(0xc8, io); @@ -95,7 +94,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq) outb_p(0xc8, io); if (!dev->muted) outb_p(0, io); - + spin_unlock(&lock); return 0; } @@ -128,7 +127,7 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=88*16000; v->rangehigh=108*16000; @@ -160,25 +159,25 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags|=VIDEO_AUDIO_MUTABLE; v->volume=1; v->step=65535; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) rt_mute(rt); else - rt_unmute(rt); + rt_unmute(rt); return 0; } @@ -220,7 +219,7 @@ static int __init rtrack2_init(void) printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); return -EINVAL; } - if (!request_region(io, 4, "rtrack2")) + if (!request_region(io, 4, "rtrack2")) { printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); return -EBUSY; @@ -228,16 +227,16 @@ static int __init rtrack2_init(void) rtrack2_radio.priv=&rtrack2_unit; - spin_lock_init(&lock); + spin_lock_init(&lock); if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io, 4); return -EINVAL; } - + printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n"); - /* mute card - prevents noisy bootups */ + /* mute card - prevents noisy bootups */ outb(1, io); rtrack2_unit.muted = 1; diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c index efee6e339d15..53073b424107 100644 --- a/trunk/drivers/media/radio/radio-sf16fmi.c +++ b/trunk/drivers/media/radio/radio-sf16fmi.c @@ -12,7 +12,7 @@ * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); * No volume control - only mute/unmute - you have to use line volume * control on SB-part of SF16FMI - * + * */ #include /* __setup */ @@ -21,7 +21,6 @@ #include /* request_region */ #include /* udelay */ #include /* kernel radio structs */ -#include #include #include /* outb, outb_p */ #include /* copy to/from user */ @@ -30,19 +29,19 @@ struct fmi_device { int port; - int curvol; /* 1 or 0 */ - unsigned long curfreq; /* freq in kHz */ - __u32 flags; + int curvol; /* 1 or 0 */ + unsigned long curfreq; /* freq in kHz */ + __u32 flags; }; -static int io = -1; +static int io = -1; static int radio_nr = -1; static struct pnp_dev *dev = NULL; static struct mutex lock; /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ /* It is only useful to give freq in intervall of 800 (=0.05Mhz), - * other bits will be truncated, e.g 92.7400016 -> 92.7, but + * other bits will be truncated, e.g 92.7400016 -> 92.7, but * 92.7400017 -> 92.75 */ #define RSF16_ENCODE(x) ((x)/800+214) @@ -52,7 +51,7 @@ static struct mutex lock; static void outbits(int bits, unsigned int data, int port) { while(bits--) { - if(data & 1) { + if(data & 1) { outb(5, port); udelay(6); outb(7, port); @@ -102,7 +101,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) int res; int myport = dev->port; - + mutex_lock(&lock); val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ outb(val, myport); @@ -110,7 +109,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) msleep(143); /* was schedule_timeout(HZ/7) */ res = (int)inb(myport+1); outb(val, myport); - + mutex_unlock(&lock); return (res & 2) ? 0 : 0xFFFF; } @@ -120,7 +119,7 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct fmi_device *fmi=dev->priv; - + switch(cmd) { case VIDIOCGCAP: @@ -175,18 +174,18 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; /*rounding in steps of 800 to match th freq that will be used */ - fmi->curfreq = (*freq/800)*800; + fmi->curfreq = (*freq/800)*800; fmi_setfreq(fmi); return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0,sizeof(*v)); v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); strcpy(v->name, "Radio"); v->mode=VIDEO_SOUND_STEREO; - return 0; + return 0; } case VIDIOCSAUDIO: { @@ -194,19 +193,19 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, if(v->audio) return -EINVAL; fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; - fmi->curvol ? + fmi->curvol ? fmi_unmute(fmi->port) : fmi_mute(fmi->port); return 0; } - case VIDIOCGUNIT: + case VIDIOCGUNIT: { - struct video_unit *v = arg; + struct video_unit *v = arg; v->video=VIDEO_NO_UNIT; v->vbi=VIDEO_NO_UNIT; v->radio=dev->minor; v->audio=0; /* How do we find out this??? */ v->teletext=VIDEO_NO_UNIT; - return 0; + return 0; } default: return -ENOIOCTLCMD; @@ -296,14 +295,14 @@ static int __init fmi_init(void) fmi_unit.curfreq = 0; fmi_unit.flags = VIDEO_TUNER_LOW; fmi_radio.priv = &fmi_unit; - + mutex_init(&lock); - + if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { release_region(io, 2); return -EINVAL; } - + printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); /* mute card - prevents noisy bootups */ fmi_mute(io); diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index 3483b2c7bc9d..bcebd8cb19ad 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -19,7 +19,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include static struct mutex lock; @@ -203,7 +202,7 @@ static int fmr2_setvolume(struct fmr2_device *dev) } static int fmr2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) + unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct fmr2_device *fmr2 = dev->priv; @@ -345,7 +344,7 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, } static int fmr2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); } diff --git a/trunk/drivers/media/radio/radio-terratec.c b/trunk/drivers/media/radio/radio-terratec.c index dfba4ae596cd..fcfde2e4f195 100644 --- a/trunk/drivers/media/radio/radio-terratec.c +++ b/trunk/drivers/media/radio/radio-terratec.c @@ -2,11 +2,11 @@ * (c) 1999 R. Offermanns (rolf@offermanns.de) * based on the aimslab radio driver from M. Kirkwood * many thanks to Michael Becker and Friedhelm Birth (from TerraTec) - * + * * * History: * 1999-05-21 First preview release - * + * * Notes on the hardware: * There are two "main" chips on the card: * - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf) @@ -20,7 +20,7 @@ * (as soon i have understand how to get started :) * If you can help me out with that, please contact me!! * - * + * */ #include /* Modules */ @@ -30,7 +30,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_TERRATEC_PORT */ #include @@ -50,7 +49,7 @@ #define WRT_EN 0x10 /*******************************************************************/ -static int io = CONFIG_RADIO_TERRATEC_PORT; +static int io = CONFIG_RADIO_TERRATEC_PORT; static int radio_nr = -1; static spinlock_t lock; @@ -89,15 +88,15 @@ static void tt_mute(struct tt_device *dev) static int tt_setvol(struct tt_device *dev, int vol) { - + // printk(KERN_ERR "setvol called, vol = %d\n", vol); if(vol == dev->curvol) { /* requested volume = current */ if (dev->muted) { /* user is unmuting the card */ dev->muted = 0; cardWriteVol(vol); /* enable card */ - } - + } + return 0; } @@ -108,9 +107,9 @@ static int tt_setvol(struct tt_device *dev, int vol) } dev->muted = 0; - + cardWriteVol(vol); - + dev->curvol = vol; return 0; @@ -122,13 +121,13 @@ static int tt_setvol(struct tt_device *dev, int vol) /* many more or less strange things are going on here, but hey, it works :) */ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) -{ +{ int freq; int i; int p; int temp; long rest; - + unsigned char buffer[25]; /* we have to bit shift 25 registers */ freq = freq1/160; /* convert the freq. to a nice to handle value */ for(i=24;i>-1;i--) @@ -143,9 +142,9 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) { if (rest%temp == rest) buffer[i] = 0; - else + else { - buffer[i] = 1; + buffer[i] = 1; rest = rest-temp; } i--; @@ -154,10 +153,10 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) } spin_lock(&lock); - + for (i=24;i>-1;i--) /* bit shift the values to the radiocard */ { - if (buffer[i]==1) + if (buffer[i]==1) { outb(WRT_EN|DATA, BASEPORT); outb(WRT_EN|DATA|CLK_ON , BASEPORT); @@ -169,11 +168,11 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1) outb(WRT_EN|0x00|CLK_ON , BASEPORT); } } - outb(0x00, BASEPORT); - + outb(0x00, BASEPORT); + spin_unlock(&lock); - - return 0; + + return 0; } static int tt_getsigstr(struct tt_device *dev) /* TODO */ @@ -191,7 +190,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, { struct video_device *dev = video_devdata(file); struct tt_device *tt=dev->priv; - + switch(cmd) { case VIDIOCGCAP: @@ -207,7 +206,7 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=(87*16000); v->rangehigh=(108*16000); @@ -239,21 +238,21 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; v->volume=tt->curvol * 6554; v->step=6554; strcpy(v->name, "Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) + if(v->flags&VIDEO_AUDIO_MUTE) tt_mute(tt); else tt_setvol(tt,v->volume/6554); @@ -297,25 +296,25 @@ static int __init terratec_init(void) printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (!request_region(io, 2, "terratec")) + if (!request_region(io, 2, "terratec")) { printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); return -EBUSY; } terratec_radio.priv=&terratec_unit; - + spin_lock_init(&lock); - + if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) { release_region(io,2); return -EINVAL; } - + printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n"); - /* mute card - prevents noisy bootups */ + /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ cardWriteVol(0); @@ -335,7 +334,7 @@ static void __exit terratec_cleanup_module(void) { video_unregister_device(&terratec_radio); release_region(io,2); - printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); + printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); } module_init(terratec_init); diff --git a/trunk/drivers/media/radio/radio-trust.c b/trunk/drivers/media/radio/radio-trust.c index 8da4badc22b4..5a099a50d4d0 100644 --- a/trunk/drivers/media/radio/radio-trust.c +++ b/trunk/drivers/media/radio/radio-trust.c @@ -1,14 +1,14 @@ -/* radio-trust.c - Trust FM Radio card driver for Linux 2.2 +/* radio-trust.c - Trust FM Radio card driver for Linux 2.2 * by Eric Lammerts * * Based on radio-aztech.c. Original notes: * - * Adapted to support the Video for Linux API by + * Adapted to support the Video for Linux API by * Russell Kroll . Based on original tuner code by: * * Quay Ly * Donald Song - * Jason Lewis (jlewis@twilight.vtc.vsc.edu) + * Jason Lewis (jlewis@twilight.vtc.vsc.edu) * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) * William McGrath (wmcgrath@twilight.vtc.vsc.edu) * @@ -22,7 +22,6 @@ #include #include #include -#include #include /* CONFIG_RADIO_TRUST_PORT */ /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -31,7 +30,7 @@ #define CONFIG_RADIO_TRUST_PORT -1 #endif -static int io = CONFIG_RADIO_TRUST_PORT; +static int io = CONFIG_RADIO_TRUST_PORT; static int radio_nr = -1; static int ioval = 0xf; static __u16 curvol; @@ -136,7 +135,7 @@ static void tr_setmute(int mute) static int tr_getsigstr(void) { int i, v; - + for(i = 0, v = 0; i < 100; i++) v |= inb(io); return (v & 1)? 0 : 0xffff; } @@ -176,7 +175,7 @@ static int tr_do_ioctl(struct inode *inode, struct file *file, { struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow = 87500 * 16; @@ -212,28 +211,28 @@ static int tr_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOCGAUDIO: - { + { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | - VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; + VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; v->volume = curvol * 2048; v->step = 2048; v->bass = curbass * 4370; v->treble = curtreble * 4370; - + strcpy(v->name, "Trust FM Radio"); - return 0; + return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; - if(v->audio) + if(v->audio) return -EINVAL; - tr_setvol(v->volume); + tr_setvol(v->volume); tr_setbass(v->bass); tr_settreble(v->treble); tr_setstereo(v->mode & VIDEO_SOUND_STEREO); @@ -293,7 +292,7 @@ static int __init trust_init(void) write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ - tr_setvol(0x8000); + tr_setvol(0x8000); tr_setbass(0x8000); tr_settreble(0x8000); tr_setstereo(1); diff --git a/trunk/drivers/media/radio/radio-typhoon.c b/trunk/drivers/media/radio/radio-typhoon.c index edd012288669..e50955836d6b 100644 --- a/trunk/drivers/media/radio/radio-typhoon.c +++ b/trunk/drivers/media/radio/radio-typhoon.c @@ -36,7 +36,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_TYPHOON_* */ #define BANNER "Typhoon Radio Card driver v0.1\n" @@ -362,8 +361,8 @@ static int __init typhoon_init(void) #ifdef CONFIG_RADIO_TYPHOON_PROC_FS if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, - typhoon_get_info)) - printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); + typhoon_get_info)) + printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); #endif return 0; diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c index 59b86a6b4b0e..7bf1a4264891 100644 --- a/trunk/drivers/media/radio/radio-zoltrix.c +++ b/trunk/drivers/media/radio/radio-zoltrix.c @@ -1,7 +1,7 @@ /* zoltrix radio plus driver for Linux radio support * (c) 1998 C. van Schaik * - * BUGS + * BUGS * Due to the inconsistency in reading from the signal flags * it is difficult to get an accurate tuned signal. * @@ -14,7 +14,7 @@ * * 1999-05-06 - (C. van Schaik) * - Make signal strength and stereo scans - * kinder to cpu while in delay + * kinder to cpu while in delay * 1999-01-05 - (C. van Schaik) * - Changed tuning to 1/160Mhz accuracy * - Added stereo support @@ -33,7 +33,6 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ -#include #include /* CONFIG_RADIO_ZOLTRIX_PORT */ #ifndef CONFIG_RADIO_ZOLTRIX_PORT @@ -106,7 +105,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) i = 45; mutex_lock(&dev->lock); - + outb(0, io); outb(0, io); inb(io + 3); /* Zoltrix needs to be read to confirm */ @@ -140,8 +139,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) udelay(1000); inb(io+2); - udelay(1000); - + udelay(1000); + if (dev->muted) { outb(0, io); @@ -149,12 +148,12 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq) inb(io + 3); udelay(1000); } - + mutex_unlock(&dev->lock); - + if(!dev->muted) { - zol_setvol(dev, dev->curvol); + zol_setvol(dev, dev->curvol); } return 0; } @@ -175,14 +174,14 @@ static int zol_getsigstr(struct zol_device *dev) b = inb(io); mutex_unlock(&dev->lock); - + if (a != b) return (0); - if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ + if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ || (a == 0xef)) /* with a binary scanner on the card io */ return (1); - return (0); + return (0); } static int zol_is_stereo (struct zol_device *dev) @@ -190,7 +189,7 @@ static int zol_is_stereo (struct zol_device *dev) int x1, x2; mutex_lock(&dev->lock); - + outb(0x00, io); outb(dev->curvol, io); msleep(20); @@ -200,7 +199,7 @@ static int zol_is_stereo (struct zol_device *dev) x2 = inb(io); mutex_unlock(&dev->lock); - + if ((x1 == x2) && (x1 == 0xcf)) return 1; return 0; @@ -227,7 +226,7 @@ static int zol_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGTUNER: { struct video_tuner *v = arg; - if (v->tuner) + if (v->tuner) return -EINVAL; strcpy(v->name, "FM"); v->rangelow = (int) (88.0 * 16000); @@ -352,7 +351,7 @@ static int __init zoltrix_init(void) printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); mutex_init(&zoltrix_unit.lock); - + /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 6d532f170ce5..6b4197018561 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -224,12 +224,6 @@ config VIDEO_ZORAN_LML33R10 support for the Linux Media Labs LML33R10 MJPEG capture/playback card. -config VIDEO_ZORAN_AVS6EYES - tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1 - help - Support for the AverMedia 6 Eyes video surveillance card. - config VIDEO_ZR36120 tristate "Zoran ZR36120/36125 Video For Linux" depends on PCI && I2C && VIDEO_V4L1 && BROKEN @@ -312,6 +306,17 @@ config VIDEO_HEXIUM_GEMINI source "drivers/media/video/cx88/Kconfig" +config VIDEO_OVCAMCHIP + tristate "OmniVision Camera Chip support" + depends on I2C && VIDEO_V4L1 + ---help--- + Support for the OmniVision OV6xxx and OV7xxx series of camera chips. + This driver is intended to be used with the ov511 and w9968cf USB + camera drivers. + + To compile this driver as a module, choose M here: the + module will be called ovcamchip. + config VIDEO_M32R_AR tristate "AR devices" depends on M32R && VIDEO_V4L1 @@ -352,15 +357,6 @@ config VIDEO_CS53L32A To compile this driver as a module, choose M here: the module will be called cs53l32a. -config VIDEO_TLV320AIC23B - tristate "Texas Instruments TLV320AIC23B audio codec" - depends on VIDEO_DEV && I2C && EXPERIMENTAL - ---help--- - Support for the Texas Instruments TLV320AIC23B audio codec. - - To compile this driver as a module, choose M here: the - module will be called tlv320aic23b. - config VIDEO_WM8775 tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" depends on VIDEO_DEV && I2C && EXPERIMENTAL @@ -381,25 +377,13 @@ config VIDEO_WM8739 To compile this driver as a module, choose M here: the module will be called wm8739. -config VIDEO_CX2341X - tristate "Conexant CX2341x MPEG encoders" - depends on VIDEO_V4L2 && EXPERIMENTAL - ---help--- - Support for the Conexant CX23416 MPEG encoders - and CX23415 MPEG encoder/decoders. - - This module currently supports the encoding functions only. - - To compile this driver as a module, choose M here: the - module will be called cx2341x. - source "drivers/media/video/cx25840/Kconfig" config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders" - depends on VIDEO_DEV && I2C && EXPERIMENTAL + tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)" + depends on VIDEO_V4L1 && I2C && EXPERIMENTAL ---help--- - Support for the Philips SAA7113/4/5 video decoders. + Old support for the Philips SAA7113/4 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. @@ -445,8 +429,6 @@ endmenu # encoder / decoder chips menu "V4L USB devices" depends on USB && VIDEO_DEV -source "drivers/media/video/pvrusb2/Kconfig" - source "drivers/media/video/em28xx/Kconfig" config USB_DSBR @@ -465,35 +447,6 @@ source "drivers/media/video/usbvideo/Kconfig" source "drivers/media/video/et61x251/Kconfig" -config VIDEO_OVCAMCHIP - tristate "OmniVision Camera Chip support" - depends on I2C && VIDEO_V4L1 - ---help--- - Support for the OmniVision OV6xxx and OV7xxx series of camera chips. - This driver is intended to be used with the ov511 and w9968cf USB - camera drivers. - - To compile this driver as a module, choose M here: the - module will be called ovcamchip. - -config USB_W9968CF - tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on USB && VIDEO_V4L1 && I2C - select VIDEO_OVCAMCHIP - ---help--- - Say Y here if you want support for cameras based on OV681 or - Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. - - This driver has an optional plugin, which is distributed as a - separate module only (released under GPL). It allows to use higher - resolutions and framerates, but cannot be included in the official - Linux kernel for performance purposes. - - See for more info. - - To compile this driver as a module, choose M here: the - module will be called w9968cf. - config USB_OV511 tristate "USB OV511 Camera support" depends on USB && VIDEO_V4L1 @@ -530,6 +483,24 @@ config USB_STV680 To compile this driver as a module, choose M here: the module will be called stv680. +config USB_W9968CF + tristate "USB W996[87]CF JPEG Dual Mode Camera support" + depends on USB && VIDEO_V4L1 && I2C + select VIDEO_OVCAMCHIP + ---help--- + Say Y here if you want support for cameras based on OV681 or + Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. + + This driver has an optional plugin, which is distributed as a + separate module only (released under GPL). It allows to use higher + resolutions and framerates, but cannot be included in the official + Linux kernel for performance purposes. + + See for more info. + + To compile this driver as a module, choose M here: the + module will be called w9968cf. + source "drivers/media/video/zc0301/Kconfig" source "drivers/media/video/pwc/Kconfig" diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index 353d61cfac1b..e5bf2687b76d 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -6,7 +6,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ - mt20xx.o tda8290.o tea5767.o tda9887.o + mt20xx.o tda8290.o tea5767.o msp3400-objs := msp3400-driver.o msp3400-kthreads.o @@ -33,7 +33,6 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \ zr36016.o obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o -obj-$(CONFIG_VIDEO_ZORAN_AVS6EYES) += bt866.o ks0127.o zr36060.o obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_PLANB) += planb.o @@ -47,10 +46,8 @@ obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ obj-$(CONFIG_VIDEO_CX88) += cx88/ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o -obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o -obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o obj-$(CONFIG_VIDEO_WM8775) += wm8775.o obj-$(CONFIG_VIDEO_WM8739) += wm8739.o obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ @@ -61,7 +58,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o -obj-$(CONFIG_VIDEO_TUNER) += tuner.o +obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o obj-$(CONFIG_VIDEO_BUF) += video-buf.o obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o @@ -74,7 +71,6 @@ obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o -obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_USB_DABUSB) += dabusb.o obj-$(CONFIG_USB_DSBR) += dsbr100.o diff --git a/trunk/drivers/media/video/arv.c b/trunk/drivers/media/video/arv.c index 6e08e32346eb..dbe025170599 100644 --- a/trunk/drivers/media/video/arv.c +++ b/trunk/drivers/media/video/arv.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -213,7 +212,7 @@ void init_iic(void) ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ - /* I2C CLK */ + /* I2C CLK */ /* 50MH-100k */ if (freq == 75) { ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ diff --git a/trunk/drivers/media/video/bt866.c b/trunk/drivers/media/video/bt866.c deleted file mode 100644 index 05e42bbcfc3d..000000000000 --- a/trunk/drivers/media/video/bt866.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - bt866 - BT866 Digital Video Encoder (Rockwell Part) - - Copyright (C) 1999 Mike Bernson - Copyright (C) 1998 Dave Perks - - Modifications for LML33/DC10plus unified driver - Copyright (C) 2000 Serguei Miridonov - - This code was modify/ported from the saa7111 driver written - by Dave Perks. - - This code was adapted for the bt866 by Christer Weinigel and ported - to 2.6 by Martin Samuelsson. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -MODULE_LICENSE("GPL"); - -#define BT866_DEVNAME "bt866" -#define I2C_BT866 0x88 - -MODULE_LICENSE("GPL"); - -#define DEBUG(x) /* Debug driver */ - -/* ----------------------------------------------------------------------- */ - -struct bt866 { - struct i2c_client *i2c; - int addr; - unsigned char reg[128]; - - int norm; - int enable; - int bright; - int contrast; - int hue; - int sat; -}; - -static int bt866_write(struct bt866 *dev, - unsigned char subaddr, unsigned char data); - -static int bt866_do_command(struct bt866 *encoder, - unsigned int cmd, void *arg) -{ - switch (cmd) { - case ENCODER_GET_CAPABILITIES: - { - struct video_encoder_capability *cap = arg; - - DEBUG(printk - (KERN_INFO "%s: get capabilities\n", - encoder->i2c->name)); - - cap->flags - = VIDEO_ENCODER_PAL - | VIDEO_ENCODER_NTSC - | VIDEO_ENCODER_CCIR; - cap->inputs = 2; - cap->outputs = 1; - } - break; - - case ENCODER_SET_NORM: - { - int *iarg = arg; - - DEBUG(printk(KERN_INFO "%s: set norm %d\n", - encoder->i2c->name, *iarg)); - - switch (*iarg) { - - case VIDEO_MODE_NTSC: - break; - - case VIDEO_MODE_PAL: - break; - - default: - return -EINVAL; - - } - encoder->norm = *iarg; - } - break; - - case ENCODER_SET_INPUT: - { - int *iarg = arg; - static const __u8 init[] = { - 0xc8, 0xcc, /* CRSCALE */ - 0xca, 0x91, /* CBSCALE */ - 0xcc, 0x24, /* YC16 | OSDNUM */ - 0xda, 0x00, /* */ - 0xdc, 0x24, /* SETMODE | PAL */ - 0xde, 0x02, /* EACTIVE */ - - /* overlay colors */ - 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ - 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ - 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ - 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ - 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ - 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ - 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ - 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ - - 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ - 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ - 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ - 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ - 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ - 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ - 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ - 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ - }; - int i; - u8 val; - - for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(encoder, init[i], init[i+1]); - - val = encoder->reg[0xdc]; - - if (*iarg == 0) - val |= 0x40; /* CBSWAP */ - else - val &= ~0x40; /* !CBSWAP */ - - bt866_write(encoder, 0xdc, val); - - val = encoder->reg[0xcc]; - if (*iarg == 2) - val |= 0x01; /* OSDBAR */ - else - val &= ~0x01; /* !OSDBAR */ - bt866_write(encoder, 0xcc, val); - - DEBUG(printk(KERN_INFO "%s: set input %d\n", - encoder->i2c->name, *iarg)); - - switch (*iarg) { - case 0: - break; - case 1: - break; - default: - return -EINVAL; - - } - } - break; - - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - DEBUG(printk(KERN_INFO "%s: set output %d\n", - encoder->i2c->name, *iarg)); - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - } - break; - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - encoder->enable = !!*iarg; - - DEBUG(printk - (KERN_INFO "%s: enable output %d\n", - encoder->i2c->name, encoder->enable)); - } - break; - - case 4711: - { - int *iarg = arg; - __u8 val; - - printk("bt866: square = %d\n", *iarg); - - val = encoder->reg[0xdc]; - if (*iarg) - val |= 1; /* SQUARE */ - else - val &= ~1; /* !SQUARE */ - bt866_write(encoder, 0xdc, val); - break; - } - - default: - return -EINVAL; - } - - return 0; -} - -static int bt866_write(struct bt866 *encoder, - unsigned char subaddr, unsigned char data) -{ - unsigned char buffer[2]; - int err; - - buffer[0] = subaddr; - buffer[1] = data; - - encoder->reg[subaddr] = data; - - DEBUG(printk - ("%s: write 0x%02X = 0x%02X\n", - encoder->i2c->name, subaddr, data)); - - for (err = 0; err < 3;) { - if (i2c_master_send(encoder->i2c, buffer, 2) == 2) - break; - err++; - printk(KERN_WARNING "%s: I/O error #%d " - "(write 0x%02x/0x%02x)\n", - encoder->i2c->name, err, encoder->addr, subaddr); - schedule_timeout_interruptible(HZ/10); - } - if (err == 3) { - printk(KERN_WARNING "%s: giving up\n", - encoder->i2c->name); - return -1; - } - - return 0; -} - -static int bt866_attach(struct i2c_adapter *adapter); -static int bt866_detach(struct i2c_client *client); -static int bt866_command(struct i2c_client *client, - unsigned int cmd, void *arg); - - -/* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END}; -static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; - -static struct i2c_client_address_data addr_data = { - normal_i2c, - probe, - ignore, -}; - -static struct i2c_driver i2c_driver_bt866 = { - .driver.name = BT866_DEVNAME, - .id = I2C_DRIVERID_BT866, - .attach_adapter = bt866_attach, - .detach_client = bt866_detach, - .command = bt866_command -}; - - -static struct i2c_client bt866_client_tmpl = -{ - .name = "(nil)", - .addr = 0, - .adapter = NULL, - .driver = &i2c_driver_bt866, - .usage_count = 0 -}; - -static int bt866_found_proc(struct i2c_adapter *adapter, - int addr, int kind) -{ - struct bt866 *encoder; - struct i2c_client *client; - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &bt866_client_tmpl, sizeof(*client)); - - encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); - return -ENOMEM; - } - - i2c_set_clientdata(client, encoder); - client->adapter = adapter; - client->addr = addr; - sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id); - - encoder->i2c = client; - encoder->addr = addr; - //encoder->encoder_type = ENCODER_TYPE_UNKNOWN; - - /* initialize */ - - i2c_attach_client(client); - - return 0; -} - -static int bt866_attach(struct i2c_adapter *adapter) -{ - if (adapter->id == I2C_HW_B_ZR36067) - return i2c_probe(adapter, &addr_data, bt866_found_proc); - return 0; -} - -static int bt866_detach(struct i2c_client *client) -{ - struct bt866 *encoder = i2c_get_clientdata(client); - - i2c_detach_client(client); - kfree(encoder); - kfree(client); - - return 0; -} - -static int bt866_command(struct i2c_client *client, - unsigned int cmd, void *arg) -{ - struct bt866 *encoder = i2c_get_clientdata(client); - return bt866_do_command(encoder, cmd, arg); -} - -static int __devinit bt866_init(void) -{ - i2c_add_driver(&i2c_driver_bt866); - return 0; -} - -static void __devexit bt866_exit(void) -{ - i2c_del_driver(&i2c_driver_bt866); -} - -module_init(bt866_init); -module_exit(bt866_exit); diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index e68a6d2fff24..2b64aa835b42 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -269,7 +269,7 @@ static struct CARD { { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, - { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, + { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, @@ -309,7 +309,6 @@ static struct CARD { { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, - { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, { 0, -1, NULL } }; @@ -1904,7 +1903,7 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY2x0] = { - .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ + .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ .video_inputs = 2, .audio_inputs = 1, .tuner = -1, @@ -2746,7 +2745,7 @@ struct tvcard bttv_tvcards[] = { /* Michael Krufky */ .name = "DViCO FusionHDTV 5 Lite", .tuner = 0, - .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ + .tuner_type = TUNER_LG_TDVS_H062F, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .video_inputs = 3, @@ -2763,7 +2762,7 @@ struct tvcard bttv_tvcards[] = { }, /* ---- card 0x88---------------------------------- */ [BTTV_BOARD_ACORP_Y878F] = { - /* Mauro Carvalho Chehab */ + /* Mauro Carvalho Chehab */ .name = "Acorp Y878F", .video_inputs = 3, .audio_inputs = 1, @@ -3791,7 +3790,6 @@ static void __devinit osprey_eeprom(struct bttv *btv) break; case 0x0060: case 0x0070: - case 0x00A0: btv->c.type = BTTV_BOARD_OSPREY2x0; /* enable output on select control lines */ gpio_inout(0xffffff,0x000303); @@ -4848,7 +4846,7 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) * * The IVC120G security card has 4 i2c controlled TDA8540 matrix * swichers to provide 16 channels to MUX0. The TDA8540's have - * 4 independent outputs and as such the IVC120G also has the + * 4 indepedant outputs and as such the IVC120G also has the * optional "Monitor Out" bus. This allows the card to be looking * at one input while the monitor is looking at another. * diff --git a/trunk/drivers/media/video/bt8xx/bttv-gpio.c b/trunk/drivers/media/video/bt8xx/bttv-gpio.c index ba081f6f8c82..c4d5e2b70c28 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-gpio.c +++ b/trunk/drivers/media/video/bt8xx/bttv-gpio.c @@ -118,6 +118,20 @@ int bttv_sub_del_devices(struct bttv_core *core) return 0; } +void bttv_gpio_irq(struct bttv_core *core) +{ + struct bttv_sub_driver *drv; + struct bttv_sub_device *dev; + struct list_head *item; + + list_for_each(item,&core->subs) { + dev = list_entry(item,struct bttv_sub_device,list); + drv = to_bttv_sub_drv(dev->dev.driver); + if (drv && drv->gpio_irq) + drv->gpio_irq(dev); + } +} + /* ----------------------------------------------------------------------- */ /* external: sub-driver register/unregister */ diff --git a/trunk/drivers/media/video/bt8xx/bttv-input.c b/trunk/drivers/media/video/bt8xx/bttv-input.c index b41f81d2372c..69efa0e5174d 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-input.c +++ b/trunk/drivers/media/video/bt8xx/bttv-input.c @@ -355,7 +355,7 @@ int bttv_input_init(struct bttv *btv) if (ir->rc5_gpio) { u32 gpio; - /* enable remote irq */ + /* enable remote irq */ bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); gpio = bttv_gpio_read(&btv->c); bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); diff --git a/trunk/drivers/media/video/bt8xx/bttv.h b/trunk/drivers/media/video/bt8xx/bttv.h index f9c9e3c4d111..3a23265c1538 100644 --- a/trunk/drivers/media/video/bt8xx/bttv.h +++ b/trunk/drivers/media/video/bt8xx/bttv.h @@ -350,6 +350,7 @@ struct bttv_sub_driver { char wanted[BUS_ID_SIZE]; int (*probe)(struct bttv_sub_device *sub); void (*remove)(struct bttv_sub_device *sub); + void (*gpio_irq)(struct bttv_sub_device *sub); }; #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) diff --git a/trunk/drivers/media/video/bt8xx/bttvp.h b/trunk/drivers/media/video/bt8xx/bttvp.h index d2956010f763..ee989d2e15d9 100644 --- a/trunk/drivers/media/video/bt8xx/bttvp.h +++ b/trunk/drivers/media/video/bt8xx/bttvp.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -215,6 +214,7 @@ extern struct videobuf_queue_ops bttv_vbi_qops; extern struct bus_type bttv_sub_bus_type; int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_del_devices(struct bttv_core *core); +void bttv_gpio_irq(struct bttv_core *core); /* ---------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/bw-qcam.c b/trunk/drivers/media/video/bw-qcam.c index 7d0b6e59c6e2..cf61c590f4ad 100644 --- a/trunk/drivers/media/video/bw-qcam.c +++ b/trunk/drivers/media/video/bw-qcam.c @@ -73,7 +73,6 @@ OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include #include #include @@ -760,7 +759,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file, { struct video_picture *p = arg; if(p->palette!=VIDEO_PALETTE_GREY) - return -EINVAL; + return -EINVAL; if(p->depth!=4 && p->depth!=6) return -EINVAL; diff --git a/trunk/drivers/media/video/c-qcam.c b/trunk/drivers/media/video/c-qcam.c index a3989bd2f81b..22a7386bbea6 100644 --- a/trunk/drivers/media/video/c-qcam.c +++ b/trunk/drivers/media/video/c-qcam.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c index 95c5aceecc5b..85d84e89d8f4 100644 --- a/trunk/drivers/media/video/cpia.c +++ b/trunk/drivers/media/video/cpia.c @@ -47,6 +47,13 @@ #include "cpia.h" +#ifdef CONFIG_VIDEO_CPIA_PP +extern int cpia_pp_init(void); +#endif +#ifdef CONFIG_VIDEO_CPIA_USB +extern int cpia_usb_init(void); +#endif + static int video_nr = -1; #ifdef MODULE @@ -60,10 +67,10 @@ MODULE_SUPPORTED_DEVICE("video"); static unsigned short colorspace_conv; module_param(colorspace_conv, ushort, 0444); MODULE_PARM_DESC(colorspace_conv, - " Colorspace conversion:" - "\n 0 = disable, 1 = enable" - "\n Default value is 0" - ); + " Colorspace conversion:" + "\n 0 = disable, 1 = enable" + "\n Default value is 0" + ); #define ABOUT "V4L-Driver for Vision CPiA based cameras" @@ -4040,6 +4047,13 @@ static int __init cpia_init(void) proc_cpia_create(); #endif +#ifdef CONFIG_VIDEO_CPIA_PP + cpia_pp_init(); +#endif +#ifdef CONFIG_VIDEO_CPIA_USB + cpia_usb_init(); +#endif + return 0; } diff --git a/trunk/drivers/media/video/cpia.h b/trunk/drivers/media/video/cpia.h index 6eaa692021c5..dde27a6a4a09 100644 --- a/trunk/drivers/media/video/cpia.h +++ b/trunk/drivers/media/video/cpia.h @@ -45,7 +45,6 @@ #include #include -#include #include #include #include @@ -248,7 +247,7 @@ enum v4l_camstates { struct cam_data { struct list_head cam_data_list; - struct mutex busy_lock; /* guard against SMP multithreading */ + struct mutex busy_lock; /* guard against SMP multithreading */ struct cpia_camera_ops *ops; /* lowlevel driver operations */ void *lowlevel_data; /* private data for lowlevel driver */ u8 *raw_image; /* buffer for raw image data */ diff --git a/trunk/drivers/media/video/cpia2/cpia2.h b/trunk/drivers/media/video/cpia2/cpia2.h index c5ecb2be5f93..1764991b0ac9 100644 --- a/trunk/drivers/media/video/cpia2/cpia2.h +++ b/trunk/drivers/media/video/cpia2/cpia2.h @@ -33,7 +33,6 @@ #include #include -#include #include #include diff --git a/trunk/drivers/media/video/cpia2/cpia2_v4l.c b/trunk/drivers/media/video/cpia2/cpia2_v4l.c index d129db57fcd4..481e178ef56d 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_v4l.c +++ b/trunk/drivers/media/video/cpia2/cpia2_v4l.c @@ -343,9 +343,7 @@ static int cpia2_close(struct inode *inode, struct file *file) cpia2_free_buffers(cam); if (!cam->present) { video_unregister_device(dev); - mutex_unlock(&cam->busy_lock); kfree(cam); - return 0; } } @@ -1169,9 +1167,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) } else { if(cam->params.flicker_control.cam_register & CPIA2_VP_FLICKER_MODES_50HZ) { - mode = FLICKER_50; + mode = FLICKER_50; } else { - mode = FLICKER_60; + mode = FLICKER_60; } } for(i=0; i - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_DESCRIPTION("cx23415/6 driver"); -MODULE_AUTHOR("Hans Verkuil"); -MODULE_LICENSE("GPL"); - -static int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -const u32 cx2341x_mpeg_ctrls[] = { - V4L2_CID_MPEG_CLASS, - V4L2_CID_MPEG_STREAM_TYPE, - V4L2_CID_MPEG_STREAM_VBI_FMT, - V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, - V4L2_CID_MPEG_AUDIO_ENCODING, - V4L2_CID_MPEG_AUDIO_L2_BITRATE, - V4L2_CID_MPEG_AUDIO_MODE, - V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, - V4L2_CID_MPEG_AUDIO_EMPHASIS, - V4L2_CID_MPEG_AUDIO_CRC, - V4L2_CID_MPEG_VIDEO_ENCODING, - V4L2_CID_MPEG_VIDEO_ASPECT, - V4L2_CID_MPEG_VIDEO_B_FRAMES, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - V4L2_CID_MPEG_VIDEO_PULLDOWN, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_BITRATE, - V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, - V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, - V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, - V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, - V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, - V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, - V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, - V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, - V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, - V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, - V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, - V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, - 0 -}; - - -/* Map the control ID to the correct field in the cx2341x_mpeg_params - struct. Return -EINVAL if the ID is unknown, else return 0. */ -static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params, - struct v4l2_ext_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - ctrl->value = params->audio_sampling_freq; - break; - case V4L2_CID_MPEG_AUDIO_ENCODING: - ctrl->value = params->audio_encoding; - break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - ctrl->value = params->audio_l2_bitrate; - break; - case V4L2_CID_MPEG_AUDIO_MODE: - ctrl->value = params->audio_mode; - break; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - ctrl->value = params->audio_mode_extension; - break; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - ctrl->value = params->audio_emphasis; - break; - case V4L2_CID_MPEG_AUDIO_CRC: - ctrl->value = params->audio_crc; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - ctrl->value = params->video_encoding; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->video_aspect; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - ctrl->value = params->video_b_frames; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = params->video_gop_size; - break; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - ctrl->value = params->video_gop_closure; - break; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: - ctrl->value = params->video_pulldown; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = params->video_bitrate_mode; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = params->video_bitrate; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = params->video_bitrate_peak; - break; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: - ctrl->value = params->video_temporal_decimation; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = params->stream_type; - break; - case V4L2_CID_MPEG_STREAM_VBI_FMT: - ctrl->value = params->stream_vbi_fmt; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - ctrl->value = params->video_spatial_filter_mode; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: - ctrl->value = params->video_spatial_filter; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - ctrl->value = params->video_luma_spatial_filter_type; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - ctrl->value = params->video_chroma_spatial_filter_type; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - ctrl->value = params->video_temporal_filter_mode; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: - ctrl->value = params->video_temporal_filter; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - ctrl->value = params->video_median_filter_type; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: - ctrl->value = params->video_luma_median_filter_top; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: - ctrl->value = params->video_luma_median_filter_bottom; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: - ctrl->value = params->video_chroma_median_filter_top; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: - ctrl->value = params->video_chroma_median_filter_bottom; - break; - default: - return -EINVAL; - } - return 0; -} - -/* Map the control ID to the correct field in the cx2341x_mpeg_params - struct. Return -EINVAL if the ID is unknown, else return 0. */ -static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, - struct v4l2_ext_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - params->audio_sampling_freq = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_ENCODING: - params->audio_encoding = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - params->audio_l2_bitrate = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_MODE: - params->audio_mode = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - params->audio_mode_extension = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - params->audio_emphasis = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_CRC: - params->audio_crc = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - params->video_aspect = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: { - int b = ctrl->value + 1; - int gop = params->video_gop_size; - params->video_b_frames = ctrl->value; - params->video_gop_size = b * ((gop + b - 1) / b); - /* Max GOP size = 34 */ - while (params->video_gop_size > 34) - params->video_gop_size -= b; - break; - } - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: { - int b = params->video_b_frames + 1; - int gop = ctrl->value; - params->video_gop_size = b * ((gop + b - 1) / b); - /* Max GOP size = 34 */ - while (params->video_gop_size > 34) - params->video_gop_size -= b; - ctrl->value = params->video_gop_size; - break; - } - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - params->video_gop_closure = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: - params->video_pulldown = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - /* MPEG-1 only allows CBR */ - if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 && - ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) - return -EINVAL; - params->video_bitrate_mode = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - params->video_bitrate = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - params->video_bitrate_peak = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: - params->video_temporal_decimation = ctrl->value; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - params->stream_type = ctrl->value; - params->video_encoding = - (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS || - params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ? - V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2; - if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) { - /* MPEG-1 implies CBR */ - params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; - } - break; - case V4L2_CID_MPEG_STREAM_VBI_FMT: - params->stream_vbi_fmt = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - params->video_spatial_filter_mode = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: - params->video_spatial_filter = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - params->video_luma_spatial_filter_type = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - params->video_chroma_spatial_filter_type = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - params->video_temporal_filter_mode = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: - params->video_temporal_filter = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - params->video_median_filter_type = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: - params->video_luma_median_filter_top = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: - params->video_luma_median_filter_bottom = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: - params->video_chroma_median_filter_top = ctrl->value; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: - params->video_chroma_median_filter_bottom = ctrl->value; - break; - default: - return -EINVAL; - } - return 0; -} - -static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) -{ - const char *name; - - qctrl->flags = 0; - switch (qctrl->id) { - /* MPEG controls */ - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - name = "Spatial Filter Mode"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: - name = "Spatial Filter"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - name = "Spatial Luma Filter Type"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - name = "Spatial Chroma Filter Type"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - name = "Temporal Filter Mode"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: - name = "Temporal Filter"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - name = "Median Filter Type"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: - name = "Median Luma Filter Maximum"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: - name = "Median Luma Filter Minimum"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: - name = "Median Chroma Filter Maximum"; - break; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: - name = "Median Chroma Filter Minimum"; - break; - - default: - return v4l2_ctrl_query_fill(qctrl, min, max, step, def); - } - switch (qctrl->id) { - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - qctrl->type = V4L2_CTRL_TYPE_MENU; - min = 0; - step = 1; - break; - default: - qctrl->type = V4L2_CTRL_TYPE_INTEGER; - break; - } - switch (qctrl->id) { - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - qctrl->flags |= V4L2_CTRL_FLAG_UPDATE; - break; - } - qctrl->minimum = min; - qctrl->maximum = max; - qctrl->step = step; - qctrl->default_value = def; - qctrl->reserved[0] = qctrl->reserved[1] = 0; - snprintf(qctrl->name, sizeof(qctrl->name), name); - return 0; -} - -int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl) -{ - int err; - - switch (qctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2); - - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_L2_BITRATE_192K, - V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, - V4L2_MPEG_AUDIO_L2_BITRATE_224K); - - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - return -EINVAL; - - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - err = v4l2_ctrl_query_fill_std(qctrl); - if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return err; - - case V4L2_CID_MPEG_VIDEO_ENCODING: - /* this setting is read-only for the cx2341x since the - V4L2_CID_MPEG_STREAM_TYPE really determines the - MPEG-1/2 setting */ - err = v4l2_ctrl_query_fill_std(qctrl); - if (err == 0) - qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - return err; - - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - err = v4l2_ctrl_query_fill_std(qctrl); - if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return err; - - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - err = v4l2_ctrl_query_fill_std(qctrl); - if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return err; - - case V4L2_CID_MPEG_STREAM_VBI_FMT: - if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI) - return v4l2_ctrl_query_fill_std(qctrl); - return cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_VBI_FMT_NONE, - V4L2_MPEG_STREAM_VBI_FMT_NONE, 1, - V4L2_MPEG_STREAM_VBI_FMT_NONE); - - /* CX23415/6 specific */ - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - return cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1, - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL); - - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: - cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF); - if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1, - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF); - if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - return cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1, - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL); - - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: - cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - return cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF); - - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - - default: - return v4l2_ctrl_query_fill_std(qctrl); - - } -} - -const char **cx2341x_ctrl_get_menu(u32 id) -{ - static const char *mpeg_stream_type[] = { - "MPEG-2 Program Stream", - "", - "MPEG-1 System Stream", - "MPEG-2 DVD-compatible Stream", - "MPEG-1 VCD-compatible Stream", - "MPEG-2 SVCD-compatible Stream", - NULL - }; - - static const char *cx2341x_video_spatial_filter_mode_menu[] = { - "Manual", - "Auto", - NULL - }; - - static const char *cx2341x_video_luma_spatial_filter_type_menu[] = { - "Off", - "1D Horizontal", - "1D Vertical", - "2D H/V Separable", - "2D Symmetric non-separable", - NULL - }; - - static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = { - "Off", - "1D Horizontal", - NULL - }; - - static const char *cx2341x_video_temporal_filter_mode_menu[] = { - "Manual", - "Auto", - NULL - }; - - static const char *cx2341x_video_median_filter_type_menu[] = { - "Off", - "Horizontal", - "Vertical", - "Horizontal/Vertical", - "Diagonal", - NULL - }; - - switch (id) { - case V4L2_CID_MPEG_STREAM_TYPE: - return mpeg_stream_type; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - return NULL; - case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: - return cx2341x_video_spatial_filter_mode_menu; - case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE: - return cx2341x_video_luma_spatial_filter_type_menu; - case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE: - return cx2341x_video_chroma_spatial_filter_type_menu; - case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE: - return cx2341x_video_temporal_filter_mode_menu; - case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE: - return cx2341x_video_median_filter_type_menu; - default: - return v4l2_ctrl_get_menu(id); - } -} - -static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) -{ - params->audio_properties = (params->audio_sampling_freq << 0) | - ((3 - params->audio_encoding) << 2) | - ((1 + params->audio_l2_bitrate) << 4) | - (params->audio_mode << 8) | - (params->audio_mode_extension << 10) | - (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ? - 3 : - params->audio_emphasis) << 12) | - (params->audio_crc << 14); -} - -int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, - struct v4l2_ext_controls *ctrls, unsigned int cmd) -{ - int err = 0; - int i; - - if (cmd == VIDIOC_G_EXT_CTRLS) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = cx2341x_get_ctrl(params, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - struct v4l2_queryctrl qctrl; - const char **menu_items = NULL; - - qctrl.id = ctrl->id; - err = cx2341x_ctrl_query(params, &qctrl); - if (err) - break; - if (qctrl.type == V4L2_CTRL_TYPE_MENU) - menu_items = cx2341x_ctrl_get_menu(qctrl.id); - err = v4l2_ctrl_check(ctrl, &qctrl, menu_items); - if (err) - break; - err = cx2341x_set_ctrl(params, ctrl); - if (err) - break; - } - if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && - params->video_bitrate_peak < params->video_bitrate) { - err = -ERANGE; - ctrls->error_idx = ctrls->count; - } - if (err) { - ctrls->error_idx = i; - } - else { - cx2341x_calc_audio_properties(params); - } - return err; -} - -void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p) -{ - static struct cx2341x_mpeg_params default_params = { - /* misc */ - .capabilities = 0, - .port = CX2341X_PORT_MEMORY, - .width = 720, - .height = 480, - .is_50hz = 0, - - /* stream */ - .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE, - - /* audio */ - .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, - .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K, - .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO, - .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, - .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, - .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE, - - /* video */ - .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2, - .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, - .video_b_frames = 2, - .video_gop_size = 12, - .video_gop_closure = 1, - .video_pulldown = 0, - .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - .video_bitrate = 6000000, - .video_bitrate_peak = 8000000, - .video_temporal_decimation = 0, - - /* encoding filters */ - .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, - .video_spatial_filter = 0, - .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR, - .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, - .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, - .video_temporal_filter = 0, - .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, - .video_luma_median_filter_top = 255, - .video_luma_median_filter_bottom = 0, - .video_chroma_median_filter_top = 255, - .video_chroma_median_filter_bottom = 0, - }; - - *p = default_params; - cx2341x_calc_audio_properties(p); -} - -static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...) -{ - u32 data[CX2341X_MBOX_MAX_DATA]; - va_list vargs; - int i; - - va_start(vargs, args); - - for (i = 0; i < args; i++) { - data[i] = va_arg(vargs, int); - } - va_end(vargs); - return func(priv, cmd, args, 0, data); -} - -int cx2341x_update(void *priv, cx2341x_mbox_func func, - const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new) -{ - static int mpeg_stream_type[] = { - 0, /* MPEG-2 PS */ - 1, /* MPEG-2 TS */ - 2, /* MPEG-1 SS */ - 14, /* DVD */ - 11, /* VCD */ - 12, /* SVCD */ - }; - - int err = 0; - - cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0); - - if (old == NULL || old->is_50hz != new->is_50hz) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz); - if (err) return err; - } - - if (old == NULL || old->width != new->width || old->height != new->height || - old->video_encoding != new->video_encoding) { - u16 w = new->width; - u16 h = new->height; - - if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) { - w /= 2; - h /= 2; - } - err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w); - if (err) return err; - } - - if (old == NULL || old->stream_type != new->stream_type) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]); - if (err) return err; - } - if (old == NULL || old->video_aspect != new->video_aspect) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect); - if (err) return err; - } - if (old == NULL || old->video_b_frames != new->video_b_frames || - old->video_gop_size != new->video_gop_size) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2, - new->video_gop_size, new->video_b_frames + 1); - if (err) return err; - } - if (old == NULL || old->video_gop_closure != new->video_gop_closure) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure); - if (err) return err; - } - if (old == NULL || old->video_pulldown != new->video_pulldown) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_3_2_PULLDOWN, 1, new->video_pulldown); - if (err) return err; - } - if (old == NULL || old->audio_properties != new->audio_properties) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties); - if (err) return err; - } - if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode || - old->video_bitrate != new->video_bitrate || - old->video_bitrate_peak != new->video_bitrate_peak) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5, - new->video_bitrate_mode, new->video_bitrate, - new->video_bitrate_peak / 400, 0, 0); - if (err) return err; - } - if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode || - old->video_temporal_filter_mode != new->video_temporal_filter_mode || - old->video_median_filter_type != new->video_median_filter_type) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2, - new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1), - new->video_median_filter_type); - if (err) return err; - } - if (old == NULL || - old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom || - old->video_luma_median_filter_top != new->video_luma_median_filter_top || - old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom || - old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4, - new->video_luma_median_filter_bottom, - new->video_luma_median_filter_top, - new->video_chroma_median_filter_bottom, - new->video_chroma_median_filter_top); - if (err) return err; - } - if (old == NULL || - old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type || - old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2, - new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type); - if (err) return err; - } - if (old == NULL || - old->video_spatial_filter != new->video_spatial_filter || - old->video_temporal_filter != new->video_temporal_filter) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2, - new->video_spatial_filter, new->video_temporal_filter); - if (err) return err; - } - if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) { - err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1, - new->video_temporal_decimation); - if (err) return err; - } - return 0; -} - -static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id) -{ - const char **menu = cx2341x_ctrl_get_menu(id); - struct v4l2_ext_control ctrl; - - if (menu == NULL) - goto invalid; - ctrl.id = id; - if (cx2341x_get_ctrl(p, &ctrl)) - goto invalid; - while (ctrl.value-- && *menu) menu++; - if (*menu == NULL) - goto invalid; - return *menu; - -invalid: - return ""; -} - -void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) -{ - int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - - /* Stream */ - printk(KERN_INFO "%s: Stream: %s\n", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); - - /* Video */ - printk(KERN_INFO "%s: Video: %dx%d, %d fps\n", - prefix, - p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), - p->is_50hz ? 25 : 30); - printk(KERN_INFO "%s: Video: %s, %s, %s, %d", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), - cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), - cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), - p->video_bitrate); - if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { - printk(", Peak %d", p->video_bitrate_peak); - } - printk("\n"); - printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", - prefix, - p->video_gop_size, p->video_b_frames, - p->video_gop_closure ? "" : "No ", - p->video_pulldown ? "" : "No "); - if (p->video_temporal_decimation) { - printk(KERN_INFO "%s: Video: Temporal Decimation %d\n", - prefix, p->video_temporal_decimation); - } - - /* Audio */ - printk(KERN_INFO "%s: Audio: %s, %s, %s, %s", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE)); - if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) { - printk(", %s", - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION)); - } - printk(", %s, %s\n", - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS), - cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); - - /* Encoding filters */ - printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), - cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), - cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), - p->video_spatial_filter); - printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), - p->video_temporal_filter); - printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", - prefix, - cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), - p->video_luma_median_filter_bottom, - p->video_luma_median_filter_top, - p->video_chroma_median_filter_bottom, - p->video_chroma_median_filter_top); -} - -EXPORT_SYMBOL(cx2341x_fill_defaults); -EXPORT_SYMBOL(cx2341x_ctrl_query); -EXPORT_SYMBOL(cx2341x_ctrl_get_menu); -EXPORT_SYMBOL(cx2341x_ext_ctrls); -EXPORT_SYMBOL(cx2341x_update); -EXPORT_SYMBOL(cx2341x_log_status); -EXPORT_SYMBOL(cx2341x_mpeg_ctrls); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ - diff --git a/trunk/drivers/media/video/cx25840/cx25840-audio.c b/trunk/drivers/media/video/cx25840/cx25840-audio.c index f897c1ebd5f3..9a4b813152e5 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-audio.c +++ b/trunk/drivers/media/video/cx25840/cx25840-audio.c @@ -30,6 +30,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) if (freq != 32000 && freq != 44100 && freq != 48000) return -EINVAL; + /* assert soft reset */ + cx25840_and_or(client, 0x810, ~0x1, 0x01); + /* common for all inputs and rates */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ cx25840_write(client, 0x127, 0x50); @@ -43,9 +46,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0xee39bb01); - if (state->is_cx25836) - break; - /* src3/4/6_ctl = 0x0801f77f */ cx25840_write4(client, 0x900, 0x7ff70108); cx25840_write4(client, 0x904, 0x7ff70108); @@ -59,9 +59,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0xd66bec00); - if (state->is_cx25836) - break; - /* src3/4/6_ctl = 0x08016d59 */ cx25840_write4(client, 0x900, 0x596d0108); cx25840_write4(client, 0x904, 0x596d0108); @@ -75,9 +72,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0xe5d69800); - if (state->is_cx25836) - break; - /* src3/4/6_ctl = 0x08014faa */ cx25840_write4(client, 0x900, 0xaa4f0108); cx25840_write4(client, 0x904, 0xaa4f0108); @@ -93,9 +87,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0x69082a01); - if (state->is_cx25836) - break; - /* src1_ctl = 0x08010000 */ cx25840_write4(client, 0x8f8, 0x00000108); @@ -115,9 +106,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0xd66bec00); - if (state->is_cx25836) - break; - /* src1_ctl = 0x08010000 */ cx25840_write4(client, 0x8f8, 0xcd600108); @@ -134,9 +122,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* AUX_PLL_FRAC */ cx25840_write4(client, 0x110, 0xe5d69800); - if (state->is_cx25836) - break; - /* src1_ctl = 0x08010000 */ cx25840_write4(client, 0x8f8, 0x00800108); @@ -148,6 +133,9 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) } } + /* deassert soft reset */ + cx25840_and_or(client, 0x810, ~0x1, 0x00); + state->audclk_freq = freq; return 0; @@ -160,10 +148,6 @@ void cx25840_audio_set_path(struct i2c_client *client) /* stop microcontroller */ cx25840_and_or(client, 0x803, ~0x10, 0); - /* assert soft reset */ - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 0x01); - /* Mute everything to prevent the PFFT! */ cx25840_write(client, 0x8d3, 0x1f); @@ -177,19 +161,13 @@ void cx25840_audio_set_path(struct i2c_client *client) } else { /* Set Path1 to Analog Demod Main Channel */ cx25840_write4(client, 0x8d0, 0x7038061f); - } - set_audclk_freq(client, state->audclk_freq); - - /* deassert soft reset */ - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 0x00); - - if (state->aud_input != CX25840_AUDIO_SERIAL) { /* When the microcontroller detects the * audio format, it will unmute the lines */ cx25840_and_or(client, 0x803, ~0x10, 0x10); } + + set_audclk_freq(client, state->audclk_freq); } static int get_volume(struct i2c_client *client) @@ -313,25 +291,11 @@ static void set_mute(struct i2c_client *client, int mute) int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) { - struct cx25840_state *state = i2c_get_clientdata(client); struct v4l2_control *ctrl = arg; - int retval; switch (cmd) { case VIDIOC_INT_AUDIO_CLOCK_FREQ: - if (state->aud_input != CX25840_AUDIO_SERIAL) { - cx25840_and_or(client, 0x803, ~0x10, 0); - cx25840_write(client, 0x8d3, 0x1f); - } - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 1); - retval = set_audclk_freq(client, *(u32 *)arg); - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 0); - if (state->aud_input != CX25840_AUDIO_SERIAL) { - cx25840_and_or(client, 0x803, ~0x10, 0x10); - } - return retval; + return set_audclk_freq(client, *(u32 *)arg); case VIDIOC_G_CTRL: switch (ctrl->id) { diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index 5c2036b40ea1..a961bb2ab0fd 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -10,9 +10,6 @@ * * VBI support by Hans Verkuil . * - * NTSC sliced VBI support by Christopher Neufeld - * with additional fixes by Hans Verkuil . - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -46,7 +43,7 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -int cx25840_debug; +static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); @@ -108,7 +105,7 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr) (buffer[2] << 8) | buffer[3]; } -int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, +int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, u8 or_value) { return cx25840_write(client, addr, @@ -120,8 +117,7 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, enum cx25840_audio_input aud_input); -static void log_audio_status(struct i2c_client *client); -static void log_video_status(struct i2c_client *client); +static void log_status(struct i2c_client *client); /* ----------------------------------------------------------------------- */ @@ -151,33 +147,6 @@ static void init_dll2(struct i2c_client *client) cx25840_write(client, 0x15d, 0xe1); } -static void cx25836_initialize(struct i2c_client *client) -{ - /* reset configuration is described on page 3-77 of the CX25836 datasheet */ - /* 2. */ - cx25840_and_or(client, 0x000, ~0x01, 0x01); - cx25840_and_or(client, 0x000, ~0x01, 0x00); - /* 3a. */ - cx25840_and_or(client, 0x15a, ~0x70, 0x00); - /* 3b. */ - cx25840_and_or(client, 0x15b, ~0x1e, 0x06); - /* 3c. */ - cx25840_and_or(client, 0x159, ~0x02, 0x02); - /* 3d. */ - /* There should be a 10-us delay here, but since the - i2c bus already has a 10-us delay we don't need to do - anything */ - /* 3e. */ - cx25840_and_or(client, 0x159, ~0x02, 0x00); - /* 3f. */ - cx25840_and_or(client, 0x159, ~0xc0, 0xc0); - /* 3g. */ - cx25840_and_or(client, 0x159, ~0x01, 0x00); - cx25840_and_or(client, 0x159, ~0x01, 0x01); - /* 3h. */ - cx25840_and_or(client, 0x15b, ~0x1e, 0x10); -} - static void cx25840_initialize(struct i2c_client *client, int loadfw) { struct cx25840_state *state = i2c_get_clientdata(client); @@ -251,7 +220,17 @@ static void input_change(struct i2c_client *client) cx25840_and_or(client, 0x401, ~0x60, 0); cx25840_and_or(client, 0x401, ~0x60, 0x60); - if (std & V4L2_STD_525_60) { + /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC + instead of V4L2_STD_PAL. Someone needs to test this. */ + if (std & V4L2_STD_PAL) { + /* Follow tuner change procedure for PAL */ + cx25840_write(client, 0x808, 0xff); + cx25840_write(client, 0x80b, 0x10); + } else if (std & V4L2_STD_SECAM) { + /* Select autodetect for SECAM */ + cx25840_write(client, 0x808, 0xff); + cx25840_write(client, 0x80b, 0x10); + } else if (std & V4L2_STD_NTSC) { /* Certain Hauppauge PVR150 models have a hardware bug that causes audio to drop out. For these models the audio standard must be set explicitly. @@ -270,14 +249,6 @@ static void input_change(struct i2c_client *client) cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); } cx25840_write(client, 0x80b, 0x00); - } else if (std & V4L2_STD_PAL) { - /* Follow tuner change procedure for PAL */ - cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); - } else if (std & V4L2_STD_SECAM) { - /* Select autodetect for SECAM */ - cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); } if (cx25840_read(client, 0x803) & 0x10) { @@ -348,10 +319,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp state->vid_input = vid_input; state->aud_input = aud_input; - if (!state->is_cx25836) { - cx25840_audio_set_path(client); - input_change(client); - } + cx25840_audio_set_path(client); + input_change(client); return 0; } @@ -385,8 +354,6 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) } } - v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); - /* Follow step 9 of section 3.16 in the cx25840 datasheet. Without this PAL may display a vertical ghosting effect. This happens for example with the Yuan MPC622. */ @@ -403,7 +370,6 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) { - struct cx25840_state *state = i2c_get_clientdata(client); /* check VID_FMT_SEL first */ u8 fmt = cx25840_read(client, 0x400) & 0xf; @@ -417,7 +383,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) { /* if the audio std is A2-M, then this is the South Korean NTSC standard */ - if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2) + if (cx25840_read(client, 0x805) == 2) return V4L2_STD_NTSC_M_KR; return V4L2_STD_NTSC_M; } @@ -490,8 +456,6 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) - return -EINVAL; return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); default: @@ -526,8 +490,6 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) - return -EINVAL; return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); default: return -EINVAL; @@ -617,6 +579,91 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) /* ----------------------------------------------------------------------- */ +static struct v4l2_queryctrl cx25840_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 58880, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Balance", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BASS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + }, { + .id = V4L2_CID_AUDIO_TREBLE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + }, +}; + +/* ----------------------------------------------------------------------- */ + static int cx25840_command(struct i2c_client *client, unsigned int cmd, void *arg) { @@ -659,8 +706,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_STREAMON: v4l_dbg(1, cx25840_debug, client, "enable output\n"); - cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c); - cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07); + cx25840_write(client, 0x115, 0x8c); + cx25840_write(client, 0x116, 0x07); break; case VIDIOC_STREAMOFF: @@ -670,9 +717,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; case VIDIOC_LOG_STATUS: - log_video_status(client); - if (!state->is_cx25836) - log_audio_status(client); + log_status(client); break; case VIDIOC_G_CTRL: @@ -684,29 +729,13 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; + int i; - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill_std(qc); - default: - break; - } - if (state->is_cx25836) - return -EINVAL; - - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) + if (qc->id && qc->id == cx25840_qctrl[i].id) { + memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); + return 0; + } return -EINVAL; } @@ -731,41 +760,31 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return set_input(client, route->input, state->aud_input); case VIDIOC_INT_G_AUDIO_ROUTING: - if (state->is_cx25836) - return -EINVAL; route->input = state->aud_input; route->output = 0; break; case VIDIOC_INT_S_AUDIO_ROUTING: - if (state->is_cx25836) - return -EINVAL; return set_input(client, state->vid_input, route->input); case VIDIOC_S_FREQUENCY: - if (!state->is_cx25836) { - input_change(client); - } + input_change(client); break; case VIDIOC_G_TUNER: { - u8 vpres = cx25840_read(client, 0x40e) & 0x20; - u8 mode; + u8 mode = cx25840_read(client, 0x804); + u8 vpres = cx25840_read(client, 0x80a) & 0x10; int val = 0; if (state->radio) break; - vt->signal = vpres ? 0xffff : 0x0; - if (state->is_cx25836) - break; - vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - mode = cx25840_read(client, 0x804); + vt->signal = vpres ? 0xffff : 0x0; /* get rxsubchans and audmode */ if ((mode & 0xf) == 1) @@ -785,7 +804,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, } case VIDIOC_S_TUNER: - if (state->radio || state->is_cx25836) + if (state->radio) break; switch (vt->audmode) { @@ -827,14 +846,12 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return set_v4lfmt(client, (struct v4l2_format *)arg); case VIDIOC_INT_RESET: - if (state->is_cx25836) - cx25836_initialize(client); - else - cx25840_initialize(client, 0); + cx25840_initialize(client, 0); break; case VIDIOC_INT_G_CHIP_IDENT: - *(enum v4l2_chip_ident *)arg = state->id; + *(enum v4l2_chip_ident *)arg = + V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf); break; default: @@ -853,7 +870,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, { struct i2c_client *client; struct cx25840_state *state; - enum v4l2_chip_ident id; u16 device_id; /* Check if the adapter supports the needed features @@ -862,11 +878,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return 0; - state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL); - if (state == 0) + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == 0) return -ENOMEM; - client = &state->c; client->addr = address; client->adapter = adapter; client->driver = &i2c_driver_cx25840; @@ -878,18 +893,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, device_id |= cx25840_read(client, 0x100); /* The high byte of the device ID should be - * 0x83 for the cx2583x and 0x84 for the cx2584x */ - if ((device_id & 0xff00) == 0x8300) { - id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; - state->is_cx25836 = 1; - } - else if ((device_id & 0xff00) == 0x8400) { - id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); - state->is_cx25836 = 0; - } - else { + * 0x84 if chip is present */ + if ((device_id & 0xff00) != 0x8400) { v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); - kfree(state); + kfree(client); return 0; } @@ -898,19 +905,21 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, address << 1, adapter->name); + state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL); + if (state == NULL) { + kfree(client); + return -ENOMEM; + } + i2c_set_clientdata(client, state); + memset(state, 0, sizeof(struct cx25840_state)); state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; state->pvr150_workaround = 0; state->audmode = V4L2_TUNER_MODE_LANG1; - state->vbi_line_offset = 8; - state->id = id; - if (state->is_cx25836) - cx25836_initialize(client); - else - cx25840_initialize(client, 1); + cx25840_initialize(client, 1); i2c_attach_client(client); @@ -935,6 +944,7 @@ static int cx25840_detach_client(struct i2c_client *client) } kfree(state); + kfree(client); return 0; } @@ -967,7 +977,7 @@ module_exit(m__exit); /* ----------------------------------------------------------------------- */ -static void log_video_status(struct i2c_client *client) +static void log_status(struct i2c_client *client) { static const char *const fmt_strs[] = { "0x0", @@ -979,36 +989,9 @@ static void log_video_status(struct i2c_client *client) }; struct cx25840_state *state = i2c_get_clientdata(client); + u8 microctrl_vidfmt = cx25840_read(client, 0x80a); u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; u8 gen_stat1 = cx25840_read(client, 0x40d); - u8 gen_stat2 = cx25840_read(client, 0x40e); - int vid_input = state->vid_input; - - v4l_info(client, "Video signal: %spresent\n", - (gen_stat2 & 0x20) ? "" : "not "); - v4l_info(client, "Detected format: %s\n", - fmt_strs[gen_stat1 & 0xf]); - - v4l_info(client, "Specified standard: %s\n", - vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); - - if (vid_input >= CX25840_COMPOSITE1 && - vid_input <= CX25840_COMPOSITE8) { - v4l_info(client, "Specified video input: Composite %d\n", - vid_input - CX25840_COMPOSITE1 + 1); - } else { - v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", - (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); - } - - v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); -} - -/* ----------------------------------------------------------------------- */ - -static void log_audio_status(struct i2c_client *client) -{ - struct cx25840_state *state = i2c_get_clientdata(client); u8 download_ctl = cx25840_read(client, 0x803); u8 mod_det_stat0 = cx25840_read(client, 0x804); u8 mod_det_stat1 = cx25840_read(client, 0x805); @@ -1016,9 +999,15 @@ static void log_audio_status(struct i2c_client *client) u8 pref_mode = cx25840_read(client, 0x809); u8 afc0 = cx25840_read(client, 0x80b); u8 mute_ctl = cx25840_read(client, 0x8d3); + int vid_input = state->vid_input; int aud_input = state->aud_input; char *p; + v4l_info(client, "Video signal: %spresent\n", + (microctrl_vidfmt & 0x10) ? "" : "not "); + v4l_info(client, "Detected format: %s\n", + fmt_strs[gen_stat1 & 0xf]); + switch (mod_det_stat0) { case 0x00: p = "mono"; break; case 0x01: p = "stereo"; break; @@ -1118,12 +1107,25 @@ static void log_audio_status(struct i2c_client *client) v4l_info(client, "Configured audio system: %s\n", p); } + v4l_info(client, "Specified standard: %s\n", + vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); + + if (vid_input >= CX25840_COMPOSITE1 && + vid_input <= CX25840_COMPOSITE8) { + v4l_info(client, "Specified video input: Composite %d\n", + vid_input - CX25840_COMPOSITE1 + 1); + } else { + v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", + (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); + } if (aud_input) { v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); } else { v4l_info(client, "Specified audio input: External\n"); } + v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); + switch (pref_mode & 0xf) { case 0: p = "mono/language A"; break; case 1: p = "language B"; break; diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.h b/trunk/drivers/media/video/cx25840/cx25840-core.h index 28049064dd7d..1736929fc204 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.h +++ b/trunk/drivers/media/video/cx25840/cx25840-core.h @@ -24,8 +24,6 @@ #include #include -extern int cx25840_debug; - /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is present in Hauppauge PVR-150 (and possibly PVR-500) cards that have certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The @@ -35,16 +33,12 @@ extern int cx25840_debug; #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) struct cx25840_state { - struct i2c_client c; int pvr150_workaround; int radio; enum cx25840_video_input vid_input; enum cx25840_audio_input aud_input; u32 audclk_freq; int audmode; - int vbi_line_offset; - enum v4l2_chip_ident id; - int is_cx25836; }; /* ----------------------------------------------------------------------- */ @@ -53,7 +47,7 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value); int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); u8 cx25840_read(struct i2c_client *client, u16 addr); u32 cx25840_read4(struct i2c_client *client, u16 addr); -int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); +int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value); v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client); /* ----------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c index 6cc8bf215e85..57feca288d2b 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c +++ b/trunk/drivers/media/video/cx25840/cx25840-vbi.c @@ -84,140 +84,67 @@ static int decode_vps(u8 * dst, u8 * p) void cx25840_vbi_setup(struct i2c_client *client) { - struct cx25840_state *state = i2c_get_clientdata(client); v4l2_std_id std = cx25840_get_v4lstd(client); - int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; - int luma_lpf,uv_lpf, comb; - u32 pll_int,pll_frac,pll_post; - /* datasheet startup, step 8d */ if (std & ~V4L2_STD_NTSC) { + /* datasheet startup, step 8d */ cx25840_write(client, 0x49f, 0x11); - } else { - cx25840_write(client, 0x49f, 0x14); - } - if (std & V4L2_STD_625_50) { - hblank=0x084; - hactive=0x2d0; - burst=0x5d; - vblank=0x024; - vactive=0x244; - vblank656=0x28; - src_decimation=0x21f; + cx25840_write(client, 0x470, 0x84); + cx25840_write(client, 0x471, 0x00); + cx25840_write(client, 0x472, 0x2d); + cx25840_write(client, 0x473, 0x5d); + + cx25840_write(client, 0x474, 0x24); + cx25840_write(client, 0x475, 0x40); + cx25840_write(client, 0x476, 0x24); + cx25840_write(client, 0x477, 0x28); + + cx25840_write(client, 0x478, 0x1f); + cx25840_write(client, 0x479, 0x02); - luma_lpf=2; if (std & V4L2_STD_SECAM) { - uv_lpf=0; - comb=0; - sc=0x0a425f; - } else { - uv_lpf=1; - comb=0x20; - sc=0x0a8263; - } - } else { - hactive=720; - hblank=122; - vactive=487; - luma_lpf=1; - uv_lpf=1; - - src_decimation=0x21f; - if (std == V4L2_STD_PAL_M) { - vblank=20; - vblank656=24; - burst=0x61; - comb=0x20; - - sc=555452; + cx25840_write(client, 0x47a, 0x80); + cx25840_write(client, 0x47b, 0x00); + cx25840_write(client, 0x47c, 0x5f); + cx25840_write(client, 0x47d, 0x42); } else { - vblank=26; - vblank656=26; - burst=0x5b; - comb=0x66; - sc=556063; + cx25840_write(client, 0x47a, 0x90); + cx25840_write(client, 0x47b, 0x20); + cx25840_write(client, 0x47c, 0x63); + cx25840_write(client, 0x47d, 0x82); } - } - - /* DEBUG: Displays configured PLL frequency */ - pll_int=cx25840_read(client, 0x108); - pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff; - pll_post=cx25840_read(client, 0x109); - v4l_dbg(1, cx25840_debug, client, - "PLL regs = int: %u, frac: %u, post: %u\n", - pll_int,pll_frac,pll_post); - - if (pll_post) { - int fin, fsc; - int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L; - - pll/=pll_post; - v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", - pll/1000000, pll%1000000); - v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", - pll/8000000, (pll/8)%1000000); - - fin=((u64)src_decimation*pll)>>12; - v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = " - "%d.%06d MHz\n", - fin/1000000,fin%1000000); - - fsc= (((u64)sc)*pll) >> 24L; - v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = " - "%d.%06d MHz\n", - fsc/1000000,fsc%1000000); - - v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " - "vblank %i , vactive %i, vblank656 %i, src_dec %i," - "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," - " sc 0x%06x\n", - hblank, hactive, vblank, vactive, vblank656, - src_decimation, burst, luma_lpf, uv_lpf, comb, sc); - } - - /* Sets horizontal blanking delay and active lines */ - cx25840_write(client, 0x470, hblank); - cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4))); - cx25840_write(client, 0x472, hactive>>4); - /* Sets burst gate delay */ - cx25840_write(client, 0x473, burst); - - /* Sets vertical blanking delay and active duration */ - cx25840_write(client, 0x474, vblank); - cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4))); - cx25840_write(client, 0x476, vactive>>4); - cx25840_write(client, 0x477, vblank656); - - /* Sets src decimation rate */ - cx25840_write(client, 0x478, 0xff&src_decimation); - cx25840_write(client, 0x479, 0xff&(src_decimation>>8)); + cx25840_write(client, 0x47e, 0x0a); + cx25840_write(client, 0x47f, 0x01); + } else { + /* datasheet startup, step 8d */ + cx25840_write(client, 0x49f, 0x14); - /* Sets Luma and UV Low pass filters */ - cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30)); + cx25840_write(client, 0x470, 0x7a); + cx25840_write(client, 0x471, 0x00); + cx25840_write(client, 0x472, 0x2d); + cx25840_write(client, 0x473, 0x5b); - /* Enables comb filters */ - cx25840_write(client, 0x47b, comb); + cx25840_write(client, 0x474, 0x1a); + cx25840_write(client, 0x475, 0x70); + cx25840_write(client, 0x476, 0x1e); + cx25840_write(client, 0x477, 0x1e); - /* Sets SC Step*/ - cx25840_write(client, 0x47c, sc); - cx25840_write(client, 0x47d, 0xff&sc>>8); - cx25840_write(client, 0x47e, 0xff&sc>>16); + cx25840_write(client, 0x478, 0x1f); + cx25840_write(client, 0x479, 0x02); + cx25840_write(client, 0x47a, 0x50); + cx25840_write(client, 0x47b, 0x66); - /* Sets VBI parameters */ - if (std & V4L2_STD_625_50) { - cx25840_write(client, 0x47f, 0x01); - state->vbi_line_offset = 5; - } else { + cx25840_write(client, 0x47c, 0x1f); + cx25840_write(client, 0x47d, 0x7c); + cx25840_write(client, 0x47e, 0x08); cx25840_write(client, 0x47f, 0x00); - state->vbi_line_offset = 8; } } int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) { - struct cx25840_state *state = i2c_get_clientdata(client); struct v4l2_format *fmt; struct v4l2_sliced_vbi_format *svbi; @@ -255,7 +182,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) case VIDIOC_S_FMT: { - int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); + int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); int vbi_offset = is_pal ? 1 : 0; int i, x; u8 lcr[24]; @@ -284,7 +211,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) cx25840_vbi_setup(client); /* Sliced VBI */ - cx25840_write(client, 0x404, 0x32); /* Ancillary data */ + cx25840_write(client, 0x404, 0x36); /* Ancillery data */ cx25840_write(client, 0x406, 0x13); cx25840_write(client, 0x47f, vbi_offset); @@ -321,18 +248,8 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) } } - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) { - cx25840_write(client, i, lcr[6 + x]); - } - } - else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) { - cx25840_write(client, i, lcr[9 + x]); - } - for (i = 0x431; i <= 0x434; i++) { - cx25840_write(client, i, 0); - } + for (x = 1, i = 0x424; i <= 0x434; i++, x++) { + cx25840_write(client, i, lcr[6 + x]); } cx25840_write(client, 0x43c, 0x16); @@ -340,7 +257,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) if (is_pal) { cx25840_write(client, 0x474, 0x2a); } else { - cx25840_write(client, 0x474, 0x22); + cx25840_write(client, 0x474, 0x1a + 6); } break; } @@ -361,7 +278,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) id1 = p[-1]; id2 = p[0] & 0xf; l = p[2] & 0x3f; - l += state->vbi_line_offset; + l += 5; p += 4; switch (id2) { diff --git a/trunk/drivers/media/video/cx88/Kconfig b/trunk/drivers/media/video/cx88/Kconfig index 80e23ee9801c..630273992a41 100644 --- a/trunk/drivers/media/video/cx88/Kconfig +++ b/trunk/drivers/media/video/cx88/Kconfig @@ -35,25 +35,13 @@ config VIDEO_CX88_ALSA To compile this driver as a module, choose M here: the module will be called cx88-alsa. -config VIDEO_CX88_BLACKBIRD - tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" - depends on VIDEO_CX88 - select VIDEO_CX2341X - ---help--- - This adds support for MPEG encoder cards based on the - Blackbird reference design, using the Conexant 2388x - and 23416 chips. - - To compile this driver as a module, choose M here: the - module will be called cx88-blackbird. - config VIDEO_CX88_DVB tristate "DVB/ATSC Support for cx2388x based TV cards" depends on VIDEO_CX88 && DVB_CORE select VIDEO_BUF_DVB ---help--- This adds support for DVB/ATSC cards based on the - Conexant 2388x chip. + Connexant 2388x chip. To compile this driver as a module, choose M here: the module will be called cx88-dvb. @@ -73,7 +61,6 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_LGDT330X select DVB_NXT200X select DVB_CX24123 - select DVB_ISL6421 ---help--- This builds cx88-dvb with all currently supported frontend demodulators. If you wish to tweak your configuration, and @@ -152,7 +139,6 @@ config VIDEO_CX88_DVB_CX24123 default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_CX24123 - select DVB_ISL6421 ---help--- This adds DVB-S support for cards based on the Connexant 2388x chip and the CX24123 demodulator. diff --git a/trunk/drivers/media/video/cx88/Makefile b/trunk/drivers/media/video/cx88/Makefile index 352b919f30c4..0dcd09b9b727 100644 --- a/trunk/drivers/media/video/cx88/Makefile +++ b/trunk/drivers/media/video/cx88/Makefile @@ -3,10 +3,9 @@ cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ cx8800-objs := cx88-video.o cx88-vbi.o cx8802-objs := cx88-mpeg.o -obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o -obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o -obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o +obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o +obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o EXTRA_CFLAGS += -Idrivers/media/video diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index 2194cbeca33b..320b3d9384ba 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -4,7 +4,7 @@ * PCI function #1 of the cx2388x. * * (c) 2005,2006 Ricardo Cerqueira - * (c) 2005 Mauro Carvalho Chehab + * (c) 2005 Mauro Carvalho Chehab * Based on a dummy cx88 module by Gerd Knorr * Based on dummy.c by Jaroslav Kysela * @@ -111,7 +111,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); MODULE_AUTHOR("Ricardo Cerqueira"); -MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," "{{Conexant,23882}," @@ -696,6 +696,7 @@ static int __devinit snd_cx88_create(struct snd_card *card, chip->irq = -1; spin_lock_init(&chip->reg_lock); + cx88_reset(core); chip->core = core; /* get irq */ diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index 4ff81582ec56..e100d8ef369a 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -30,10 +30,9 @@ #include #include #include -#include -#include #include "cx88.h" +#include MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); MODULE_AUTHOR("Jelle Foks , Gerd Knorr [SuSE Labs]"); @@ -54,6 +53,7 @@ static LIST_HEAD(cx8802_devlist); /* ------------------------------------------------------------------ */ +#define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin" #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 /* defines below are from ivtv-driver.h */ @@ -63,6 +63,8 @@ static LIST_HEAD(cx8802_devlist); /* Firmware API commands */ #define IVTV_API_STD_TIMEOUT 500 +#define BLACKBIRD_API_PING 0x80 +#define BLACKBIRD_API_BEGIN_CAPTURE 0x81 enum blackbird_capture_type { BLACKBIRD_MPEG_CAPTURE, BLACKBIRD_RAW_CAPTURE, @@ -76,29 +78,205 @@ enum blackbird_capture_bits { BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08, BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10 }; +#define BLACKBIRD_API_END_CAPTURE 0x82 enum blackbird_capture_end { BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */ BLACKBIRD_END_NOW, /* stop immediately, no irq */ }; +#define BLACKBIRD_API_SET_AUDIO_ID 0x89 +#define BLACKBIRD_API_SET_VIDEO_ID 0x8B +#define BLACKBIRD_API_SET_PCR_ID 0x8D +#define BLACKBIRD_API_SET_FRAMERATE 0x8F enum blackbird_framerate { BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */ BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */ }; +#define BLACKBIRD_API_SET_RESOLUTION 0x91 +#define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95 +enum blackbird_video_bitrate_type { + BLACKBIRD_VIDEO_VBR, + BLACKBIRD_VIDEO_CBR +}; +#define BLACKBIRD_PEAK_RATE_DIVISOR 400 +enum blackbird_mux_rate { + BLACKBIRD_MUX_RATE_DEFAULT, + /* dvd mux rate: multiply by 400 to get the actual rate */ + BLACKBIRD_MUX_RATE_DVD = 25200 +}; +#define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97 +#define BLACKBIRD_API_SET_ASPECT_RATIO 0x99 +enum blackbird_aspect_ratio { + BLACKBIRD_ASPECT_RATIO_FORBIDDEN, + BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, + BLACKBIRD_ASPECT_RATIO_4_3, + BLACKBIRD_ASPECT_RATIO_16_9, + BLACKBIRD_ASPECT_RATIO_221_100, + BLACKBIRD_ASPECT_RATIO_RESERVED +}; +#define BLACKBIRD_API_SET_DNR_MODE 0x9B +enum blackbird_dnr_bits { + BLACKBIRD_DNR_BITS_MANUAL, + BLACKBIRD_DNR_BITS_AUTO_SPATIAL, + BLACKBIRD_DNR_BITS_AUTO_TEMPORAL, + BLACKBIRD_DNR_BITS_AUTO +}; +enum blackbird_median_filter { + BLACKBIRD_MEDIAN_FILTER_DISABLED, + BLACKBIRD_MEDIAN_FILTER_HORIZONTAL, + BLACKBIRD_MEDIAN_FILTER_VERTICAL, + BLACKBIRD_MEDIAN_FILTER_HV, + BLACKBIRD_MEDIAN_FILTER_DIAGONAL +}; +#define BLACKBIRD_API_SET_MANUAL_DNR 0x9D +#define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F +#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1 +enum blackbird_spatial_filter_luma { + BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT, + BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */ + BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */ +}; +enum blackbird_spatial_filter_chroma { + BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED, + BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */ +}; +#define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1 +enum blackbird_pulldown { + BLACKBIRD_3_2_PULLDOWN_DISABLED, + BLACKBIRD_3_2_PULLDOWN_ENABLED +}; +#define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7 +enum blackbird_vbi_line_bits { + BLACKBIRD_VBI_LINE_BITS_TOP_FIELD, + BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31), + BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF +}; +enum blackbird_vbi_line { + BLACKBIRD_VBI_LINE_DISABLED, + BLACKBIRD_VBI_LINE_ENABLED +}; +enum blackbird_vbi_slicing { + BLACKBIRD_VBI_SLICING_NONE, + BLACKBIRD_VBI_SLICING_CLOSED_CAPTION +}; +#define BLACKBIRD_API_SET_STREAM_TYPE 0xB9 +enum blackbird_stream_type { + BLACKBIRD_STREAM_PROGRAM, + BLACKBIRD_STREAM_TRANSPORT, + BLACKBIRD_STREAM_MPEG1, + BLACKBIRD_STREAM_PES_AV, + BLACKBIRD_STREAM_UNKNOWN4, + BLACKBIRD_STREAM_PES_VIDEO, + BLACKBIRD_STREAM_UNKNOWN6, + BLACKBIRD_STREAM_PES_AUDIO, + BLACKBIRD_STREAM_UNKNOWN8, + BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */ + BLACKBIRD_STREAM_DVD, + BLACKBIRD_STREAM_VCD, + BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */ +}; +#define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB enum blackbird_stream_port { BLACKBIRD_OUTPUT_PORT_MEMORY, BLACKBIRD_OUTPUT_PORT_STREAMING, BLACKBIRD_OUTPUT_PORT_SERIAL }; +#define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD +enum blackbird_audio_bits_sample_rate { + BLACKBIRD_AUDIO_BITS_44100HZ, + BLACKBIRD_AUDIO_BITS_48000HZ, + BLACKBIRD_AUDIO_BITS_32000HZ, + BLACKBIRD_AUDIO_BITS_RESERVED_HZ, +}; +enum blackbird_audio_bits_encoding { + BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2, + BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2, +}; +enum blackbird_audio_bits_bitrate_layer_1 { + BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT, + BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4, + BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4, +}; +enum blackbird_audio_bits_bitrate_layer_2 { + BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT, + BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4, + BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4, +}; +enum blackbird_audio_bits_mode { + BLACKBIRD_AUDIO_BITS_STEREO, + BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8, + BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8, + BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8, +}; +enum blackbird_audio_bits_mode_extension { + BLACKBIRD_AUDIO_BITS_BOUND_4, + BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10, + BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10, + BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10, +}; +enum blackbird_audio_bits_emphasis { + BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE, + BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12, + BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12, + BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12, +}; +enum blackbird_audio_bits_crc { + BLACKBIRD_AUDIO_BITS_CRC_OFF, + BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14, +}; +enum blackbird_audio_bits_copyright { + BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF, + BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15, +}; +enum blackbird_audio_bits_original { + BLACKBIRD_AUDIO_BITS_COPY, + BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16, +}; +#define BLACKBIRD_API_HALT 0xC3 +#define BLACKBIRD_API_GET_VERSION 0xC4 +#define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5 +enum blackbird_gop_closure { + BLACKBIRD_GOP_CLOSURE_OFF, + BLACKBIRD_GOP_CLOSURE_ON, +}; +#define BLACKBIRD_API_DATA_XFER_STATUS 0xC6 enum blackbird_data_xfer_status { BLACKBIRD_MORE_BUFFERS_FOLLOW, BLACKBIRD_LAST_BUFFER, }; +#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7 enum blackbird_picture_mask { BLACKBIRD_PICTURE_MASK_NONE, BLACKBIRD_PICTURE_MASK_I_FRAMES, BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3, BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7, }; +#define BLACKBIRD_API_SET_VBI_PARAMS 0xC8 enum blackbird_vbi_mode_bits { BLACKBIRD_VBI_BITS_SLICED, BLACKBIRD_VBI_BITS_RAW, @@ -110,23 +288,33 @@ enum blackbird_vbi_insertion_bits { BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, }; +#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9 enum blackbird_dma_unit { BLACKBIRD_DMA_BYTES, BLACKBIRD_DMA_FRAMES, }; +#define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA +#define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB enum blackbird_dma_transfer_status_bits { BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01, BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04, BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10, }; +#define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC +#define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD +#define BLACKBIRD_API_SET_FRAMESKIP 0xD0 +#define BLACKBIRD_API_PAUSE 0xD2 enum blackbird_pause { BLACKBIRD_PAUSE_ENCODING, BLACKBIRD_RESUME_ENCODING, }; +#define BLACKBIRD_API_REFRESH_INPUT 0xD3 +#define BLACKBIRD_API_SET_COPYRIGHT 0xD4 enum blackbird_copyright { BLACKBIRD_COPYRIGHT_OFF, BLACKBIRD_COPYRIGHT_ON, }; +#define BLACKBIRD_API_SET_NOTIFICATION 0xD5 enum blackbird_notification_type { BLACKBIRD_NOTIFICATION_REFRESH, }; @@ -137,6 +325,7 @@ enum blackbird_notification_status { enum blackbird_notification_mailbox { BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1, }; +#define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6 enum blackbird_field1_lines { BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */ BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */ @@ -147,10 +336,12 @@ enum blackbird_field2_lines { BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */ BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */ }; +#define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7 enum blackbird_custom_data_type { BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, BLACKBIRD_CUSTOM_PRIVATE_PACKET, }; +#define BLACKBIRD_API_MUTE_VIDEO 0xD9 enum blackbird_mute { BLACKBIRD_UNMUTE, BLACKBIRD_MUTE, @@ -165,6 +356,7 @@ enum blackbird_mute_video_shift { BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16, BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24, }; +#define BLACKBIRD_API_MUTE_AUDIO 0xDA /* Registers */ #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) @@ -306,12 +498,15 @@ static int register_read(struct cx88_core *core, u32 address, u32 *value) /* ------------------------------------------------------------------ */ -static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]) +/* We don't need to call the API often, so using just one mailbox will probably suffice */ +static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, + u32 inputcnt, u32 outputcnt, ...) { - struct cx8802_dev *dev = priv; unsigned long timeout; u32 value, flag, retval; int i; + va_list args; + va_start(args, outputcnt); dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); @@ -335,11 +530,12 @@ static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 dat /* write command + args + fill remaining with zeros */ memory_write(dev->core, dev->mailbox + 1, command); /* command code */ memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */ - for (i = 0; i < in; i++) { - memory_write(dev->core, dev->mailbox + 4 + i, data[i]); - dprintk(1, "API Input %d = %d\n", i, data[i]); + for (i = 0; i < inputcnt ; i++) { + value = va_arg(args, int); + memory_write(dev->core, dev->mailbox + 4 + i, value); + dprintk(1, "API Input %d = %d\n", i, value); } - for (; i < CX2341X_MBOX_MAX_DATA; i++) + for (; i < 16 ; i++) memory_write(dev->core, dev->mailbox + 4 + i, 0); flag |= 3; /* tell 'em we're done writing */ @@ -359,10 +555,12 @@ static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 dat } /* read output values */ - for (i = 0; i < out; i++) { - memory_read(dev->core, dev->mailbox + 4 + i, data + i); - dprintk(1, "API Output %d = %d\n", i, data[i]); + for (i = 0; i < outputcnt ; i++) { + int *vptr = va_arg(args, int *); + memory_read(dev->core, dev->mailbox + 4 + i, vptr); + dprintk(1, "API Output %d = %d\n", i, *vptr); } + va_end(args); memory_read(dev->core, dev->mailbox + 2, &retval); dprintk(1, "API result = %d\n",retval); @@ -371,29 +569,7 @@ static int blackbird_mbox_func(void *priv, int command, int in, int out, u32 dat memory_write(dev->core, dev->mailbox, flag); return retval; } -/* ------------------------------------------------------------------ */ - -/* We don't need to call the API often, so using just one mailbox will probably suffice */ -static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command, - u32 inputcnt, u32 outputcnt, ...) -{ - u32 data[CX2341X_MBOX_MAX_DATA]; - va_list vargs; - int i, err; - - va_start(vargs, outputcnt); - for (i = 0; i < inputcnt; i++) { - data[i] = va_arg(vargs, int); - } - err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data); - for (i = 0; i < outputcnt; i++) { - int *vptr = va_arg(vargs, int *); - *vptr = data[i]; - } - va_end(vargs); - return err; -} static int blackbird_find_mailbox(struct cx8802_dev *dev) { @@ -438,13 +614,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) if (retval < 0) dprintk(0, "Error with register_write\n"); - retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, + retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME, &dev->pci->dev); if (retval != 0) { dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", - CX2341X_FIRM_ENC_FILENAME); + BLACKBIRD_FIRM_ENC_FILENAME); dprintk(0, "Please fix your hotplug setup, the board will " "not work without firmware loaded!\n"); return -1; @@ -510,19 +686,12 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M *DB: "DirectBurn" */ -static void blackbird_codec_settings(struct cx8802_dev *dev) -{ - /* assign frame size */ - blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - dev->height, dev->width); - - dev->params.width = dev->width; - dev->params.height = dev->height; - dev->params.is_50hz = (dev->core->tvnorm->id & V4L2_STD_625_50) != 0; - - cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params); -} - +static struct blackbird_dnr default_dnr_params = { + .mode = BLACKBIRD_DNR_BITS_MANUAL, + .type = BLACKBIRD_MEDIAN_FILTER_DISABLED, + .spatial = 0, + .temporal = 0 +}; static struct v4l2_mpeg_compression default_mpeg_params = { .st_type = V4L2_MPEG_PS_2, .st_bitrate = { @@ -543,7 +712,7 @@ static struct v4l2_mpeg_compression default_mpeg_params = { .target = 224, .max = 224 }, - .au_sample_rate = 48000, + .au_sample_rate = 44100, .au_pesid = 0, .vi_type = V4L2_MPEG_VI_2, .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3, @@ -554,13 +723,524 @@ static struct v4l2_mpeg_compression default_mpeg_params = { .max = 6000 }, .vi_frame_rate = 25, - .vi_frames_per_gop = 12, + .vi_frames_per_gop = 15, .vi_bframes_count = 2, .vi_pesid = 0, - .closed_gops = 1, + .closed_gops = 0, .pulldown = 0 }; +static enum blackbird_stream_type mpeg_stream_types[] = { + [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1, + [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM, + [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT, + [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD, +}; +static enum blackbird_aspect_ratio mpeg_stream_ratios[] = { + [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, + [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3, + [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9, + [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100, +}; +static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = { + [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR, + [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR, + [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR, +}; +/* find the best layer I/II bitrate to fit a given numeric value */ +struct bitrate_bits { + u32 bits; /* layer bits for the best fit */ + u32 rate; /* actual numeric value for the layer best fit */ +}; +struct bitrate_approximation { + u32 target; /* numeric value of the rate we want */ + struct bitrate_bits layer[2]; +}; +static struct bitrate_approximation mpeg_audio_bitrates[] = { + /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */ + { 0, { { 0, 0, }, { 0, 0, }, }, }, + { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, }, + { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, }, + { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, }, + { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, }, + { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, }, + { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, }, + { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, }, + { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, }, + { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, }, + { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, }, + { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, }, + { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, }, + { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, + { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, + { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, + { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, + { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, + { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, +}; +static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates); + +static void blackbird_set_default_params(struct cx8802_dev *dev) +{ + struct v4l2_mpeg_compression *params = &dev->params; + u32 au_params; + + /* assign stream type */ + if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) + params->st_type = V4L2_MPEG_PS_2; + if( params->st_type == V4L2_MPEG_SS_1 ) + params->vi_type = V4L2_MPEG_VI_1; + else + params->vi_type = V4L2_MPEG_VI_2; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); + + /* assign framerate */ + if( params->vi_frame_rate <= 25 ) + { + params->vi_frame_rate = 25; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); + } + else + { + params->vi_frame_rate = 30; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); + } + + /* assign aspect ratio */ + if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) + params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); + + /* assign gop properties */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); + + /* assign gop closure */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); + + /* assign 3 2 pulldown */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); + + /* make sure the params are within bounds */ + if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->vi_bitrate.mode = V4L2_BITRATE_NONE; + if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->vi_bitrate.mode = V4L2_BITRATE_NONE; + if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->au_bitrate.mode = V4L2_BITRATE_NONE; + + /* assign audio properties */ + /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ + au_params = BLACKBIRD_AUDIO_BITS_STEREO | + /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ + BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | + BLACKBIRD_AUDIO_BITS_CRC_OFF | + BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | + BLACKBIRD_AUDIO_BITS_COPY | + 0; + if( params->au_sample_rate <= 32000 ) + { + params->au_sample_rate = 32000; + au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; + } + else if( params->au_sample_rate <= 44100 ) + { + params->au_sample_rate = 44100; + au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; + } + else + { + params->au_sample_rate = 48000; + au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; + } + if( params->au_type == V4L2_MPEG_AU_2_I ) + { + au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; + } + else + { + /* TODO: try to handle the other formats more gracefully */ + params->au_type = V4L2_MPEG_AU_2_II; + au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; + } + if( params->au_bitrate.mode ) + { + int layer; + + if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) + params->au_bitrate.max = params->vi_bitrate.target; + else + params->au_bitrate.target = params->vi_bitrate.max; + + layer = params->au_type; + if( params->au_bitrate.target == 0 ) + { + /* TODO: use the minimum possible bitrate instead of 0 ? */ + au_params |= 0; + } + else if( params->au_bitrate.target >= + mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) + { + /* clamp the bitrate to the max supported by the standard */ + params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; + params->au_bitrate.max = params->au_bitrate.target; + au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; + } + else + { + /* round up to the nearest supported bitrate */ + int i; + for(i = 1; i < BITRATES_SIZE; i++) + { + if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && + params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) + { + params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; + params->au_bitrate.max = params->au_bitrate.target; + au_params |= mpeg_audio_bitrates[i].layer[layer].bits; + break; + } + } + } + } + else + { + /* TODO: ??? */ + params->au_bitrate.target = params->au_bitrate.max = 0; + au_params |= 0; + } + blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); + + /* assign bitrates */ + if( params->vi_bitrate.mode ) + { + /* bitrate is set, let's figure out the cbr/vbr mess */ + if( params->vi_bitrate.max < params->vi_bitrate.target ) + { + if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) + params->vi_bitrate.max = params->vi_bitrate.target; + else + params->vi_bitrate.target = params->vi_bitrate.max; + } + } + else + { + if( params->st_bitrate.max < params->st_bitrate.target ) + { + if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) + params->st_bitrate.target = params->st_bitrate.max; + else + params->st_bitrate.max = params->st_bitrate.target; + } + /* calculate vi_bitrate = st_bitrate - au_bitrate */ + params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; + params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; + } + blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, + mpeg_video_bitrates[params->vi_bitrate.mode], + params->vi_bitrate.target * 1000, /* kbps -> bps */ + params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ + BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ + + /* TODO: implement the stream ID stuff: + ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, + ps_size, au_pesid, vi_pesid + */ +} +#define CHECK_PARAM( name ) ( dev->params.name != params->name ) +#define IF_PARAM( name ) if( CHECK_PARAM( name ) ) +#define UPDATE_PARAM( name ) dev->params.name = params->name +void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params) +{ + u32 au_params; + + /* assign stream type */ + if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) + params->st_type = V4L2_MPEG_PS_2; + if( params->st_type == V4L2_MPEG_SS_1 ) + params->vi_type = V4L2_MPEG_VI_1; + else + params->vi_type = V4L2_MPEG_VI_2; + if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) ) + { + UPDATE_PARAM( st_type ); + UPDATE_PARAM( vi_type ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); + } + + /* assign framerate */ + if( params->vi_frame_rate <= 25 ) + params->vi_frame_rate = 25; + else + params->vi_frame_rate = 30; + IF_PARAM( vi_frame_rate ) + { + UPDATE_PARAM( vi_frame_rate ); + if( params->vi_frame_rate == 25 ) + blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); + else + blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); + } + + /* assign aspect ratio */ + if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) + params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; + IF_PARAM( vi_aspect_ratio ) + { + UPDATE_PARAM( vi_aspect_ratio ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); + } + + /* assign gop properties */ + if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) ) + { + UPDATE_PARAM( vi_frames_per_gop ); + UPDATE_PARAM( vi_bframes_count ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); + } + + /* assign gop closure */ + IF_PARAM( closed_gops ) + { + UPDATE_PARAM( closed_gops ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); + } + + /* assign 3 2 pulldown */ + IF_PARAM( pulldown ) + { + UPDATE_PARAM( pulldown ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); + } + + /* make sure the params are within bounds */ + if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->vi_bitrate.mode = V4L2_BITRATE_NONE; + if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->vi_bitrate.mode = V4L2_BITRATE_NONE; + if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) + params->au_bitrate.mode = V4L2_BITRATE_NONE; + + /* assign audio properties */ + /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ + au_params = BLACKBIRD_AUDIO_BITS_STEREO | + /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ + BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | + BLACKBIRD_AUDIO_BITS_CRC_OFF | + BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | + BLACKBIRD_AUDIO_BITS_COPY | + 0; + if( params->au_sample_rate < 32000 ) + { + params->au_sample_rate = 32000; + au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; + } + else if( params->au_sample_rate < 44100 ) + { + params->au_sample_rate = 44100; + au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; + } + else + { + params->au_sample_rate = 48000; + au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; + } + if( params->au_type == V4L2_MPEG_AU_2_I ) + { + au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; + } + else + { + /* TODO: try to handle the other formats more gracefully */ + params->au_type = V4L2_MPEG_AU_2_II; + au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; + } + if( params->au_bitrate.mode ) + { + int layer; + + if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) + params->au_bitrate.max = params->vi_bitrate.target; + else + params->au_bitrate.target = params->vi_bitrate.max; + + layer = params->au_type; + if( params->au_bitrate.target == 0 ) + { + /* TODO: use the minimum possible bitrate instead of 0 ? */ + au_params |= 0; + } + else if( params->au_bitrate.target >= + mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) + { + /* clamp the bitrate to the max supported by the standard */ + params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; + params->au_bitrate.max = params->au_bitrate.target; + au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; + } + else + { + /* round up to the nearest supported bitrate */ + int i; + for(i = 1; i < BITRATES_SIZE; i++) + { + if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && + params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) + { + params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; + params->au_bitrate.max = params->au_bitrate.target; + au_params |= mpeg_audio_bitrates[i].layer[layer].bits; + break; + } + } + } + } + else + { + /* TODO: ??? */ + params->au_bitrate.target = params->au_bitrate.max = 0; + au_params |= 0; + } + if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate ) + || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max ) + || CHECK_PARAM( au_bitrate.target ) + ) + { + UPDATE_PARAM( au_type ); + UPDATE_PARAM( au_sample_rate ); + UPDATE_PARAM( au_bitrate ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); + } + + /* assign bitrates */ + if( params->vi_bitrate.mode ) + { + /* bitrate is set, let's figure out the cbr/vbr mess */ + if( params->vi_bitrate.max < params->vi_bitrate.target ) + { + if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) + params->vi_bitrate.max = params->vi_bitrate.target; + else + params->vi_bitrate.target = params->vi_bitrate.max; + } + } + else + { + if( params->st_bitrate.max < params->st_bitrate.target ) + { + if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) + params->st_bitrate.target = params->st_bitrate.max; + else + params->st_bitrate.max = params->st_bitrate.target; + } + /* calculate vi_bitrate = st_bitrate - au_bitrate */ + params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; + params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; + } + UPDATE_PARAM( st_bitrate ); + if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max ) + || CHECK_PARAM( vi_bitrate.target ) + ) + { + UPDATE_PARAM( vi_bitrate ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, + mpeg_video_bitrates[params->vi_bitrate.mode], + params->vi_bitrate.target * 1000, /* kbps -> bps */ + params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ + BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ + } + + /* TODO: implement the stream ID stuff: + ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, + ps_size, au_pesid, vi_pesid + */ + UPDATE_PARAM( ts_pid_pmt ); + UPDATE_PARAM( ts_pid_audio ); + UPDATE_PARAM( ts_pid_video ); + UPDATE_PARAM( ts_pid_pcr ); + UPDATE_PARAM( ps_size ); + UPDATE_PARAM( au_pesid ); + UPDATE_PARAM( vi_pesid ); +} + +static void blackbird_set_default_dnr_params(struct cx8802_dev *dev) +{ + /* assign dnr filter mode */ + if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO ) + dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL; + if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) + dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, + dev->dnr_params.mode, + dev->dnr_params.type + ); + + /* assign dnr filter props*/ + if( dev->dnr_params.spatial > 15 ) + dev->dnr_params.spatial = 15; + if( dev->dnr_params.temporal > 31 ) + dev->dnr_params.temporal = 31; + blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, + dev->dnr_params.spatial, + dev->dnr_params.temporal + ); +} +#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name ) +#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name +void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params) +{ + /* assign dnr filter mode */ + /* clamp values */ + if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO ) + dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL; + if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) + dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED; + /* check if the params actually changed */ + if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) ) + { + UPDATE_DNR_PARAM( mode ); + UPDATE_DNR_PARAM( type ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type); + } + + /* assign dnr filter props*/ + if( dnr_params->spatial > 15 ) + dnr_params->spatial = 15; + if( dnr_params->temporal > 31 ) + dnr_params->temporal = 31; + if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) ) + { + UPDATE_DNR_PARAM( spatial ); + UPDATE_DNR_PARAM( temporal ); + blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal); + } +} + +static void blackbird_codec_settings(struct cx8802_dev *dev) +{ + + /* assign output port */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ + + /* assign frame size */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, + dev->height, dev->width); + + /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); + + /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ + blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, + BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, + BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ + ); + + /* assign frame drop rate */ + /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ + + blackbird_set_default_params(dev); + blackbird_set_default_dnr_params(dev); +} + static int blackbird_initialize_codec(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; @@ -568,7 +1248,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) int retval; dprintk(1,"Initialize codec\n"); - retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ + retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ if (retval < 0) { /* ping was not successful, reset and upload firmware */ cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ @@ -583,13 +1263,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) if (dev->mailbox < 0) return -1; - retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ + retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */ if (retval < 0) { dprintk(0, "ERROR: Firmware ping failed!\n"); return -1; } - retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); + retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version); if (retval < 0) { dprintk(0, "ERROR: Firmware get encoder version failed!\n"); return -1; @@ -609,35 +1289,35 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */ - blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, + blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0, BLACKBIRD_FIELD1_SAA7115, - BLACKBIRD_FIELD2_SAA7115 + BLACKBIRD_FIELD1_SAA7115 ); /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */ - blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, + blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0, BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); /* initialize the video input */ - blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); + blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); msleep(1); - blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); + blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); msleep(1); - blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); + blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); msleep(1); /* start capturing to the host interface */ - /* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */ - blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, + /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */ + blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, BLACKBIRD_MPEG_CAPTURE, BLACKBIRD_RAW_BITS_NONE ); msleep(10); - blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0); + blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); return 0; } @@ -805,74 +1485,27 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_mpeg_compression *f = arg; - printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. " - "Replace with VIDIOC_G_EXT_CTRLS!"); - memcpy(f,&default_mpeg_params,sizeof(*f)); + memcpy(f,&dev->params,sizeof(*f)); return 0; } case VIDIOC_S_MPEGCOMP: - printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. " - "Replace with VIDIOC_S_EXT_CTRLS!"); - return 0; - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *f = arg; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - return cx2341x_ext_ctrls(&dev->params, f, cmd); - } - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: { - struct v4l2_ext_controls *f = arg; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - p = dev->params; - err = cx2341x_ext_ctrls(&p, f, cmd); - if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) { - err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p); - dev->params = p; - } - return err; - } - case VIDIOC_S_FREQUENCY: - { - blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - BLACKBIRD_END_NOW, - BLACKBIRD_MPEG_CAPTURE, - BLACKBIRD_RAW_BITS_NONE); - - cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); + struct v4l2_mpeg_compression *f = arg; - blackbird_initialize_codec(dev); - cx88_set_scale(dev->core, dev->width, dev->height, - fh->mpegq.field); - return 0; - } - case VIDIOC_LOG_STATUS: - { - char name[32 + 2]; - - snprintf(name, sizeof(name), "%s/2", core->name); - printk("%s/2: ============ START LOG STATUS ============\n", - core->name); - cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0); - cx2341x_log_status(&dev->params, name); - printk("%s/2: ============= END LOG STATUS =============\n", - core->name); + blackbird_set_params(dev, f); return 0; } default: - return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); + return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); } return 0; } +int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); +unsigned int (*cx88_ioctl_translator)(unsigned int cmd); + static unsigned int mpeg_translate_ioctl(unsigned int cmd) { return cmd; @@ -881,8 +1514,8 @@ static unsigned int mpeg_translate_ioctl(unsigned int cmd) static int mpeg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - cmd = mpeg_translate_ioctl( cmd ); - return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); + cmd = cx88_ioctl_translator( cmd ); + return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook); } static int mpeg_open(struct inode *inode, struct file *file) @@ -929,14 +1562,13 @@ static int mpeg_release(struct inode *inode, struct file *file) { struct cx8802_fh *fh = file->private_data; - /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ - blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, + /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ + blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, BLACKBIRD_MPEG_CAPTURE, BLACKBIRD_RAW_BITS_NONE ); - cx8802_cancel_buffers(fh->dev); /* stop mpeg capture */ if (fh->mpegq.streaming) videobuf_streamoff(&fh->mpegq); @@ -1051,13 +1683,19 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, dev->core = core; dev->width = 720; dev->height = 576; - cx2341x_fill_defaults(&dev->params); - dev->params.port = CX2341X_PORT_STREAMING; + memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); + memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); + + if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) { + + if (core->tuner_formats & V4L2_STD_525_60) { + dev->height = 480; + dev->params.vi_frame_rate = 30; + } else { + dev->height = 576; + dev->params.vi_frame_rate = 25; + } - if (core->tvnorm->id & V4L2_STD_525_60) { - dev->height = 480; - } else { - dev->height = 576; } err = cx8802_init_common(dev); @@ -1128,6 +1766,8 @@ static int blackbird_init(void) printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif + cx88_ioctl_hook = mpeg_do_ioctl; + cx88_ioctl_translator = mpeg_translate_ioctl; return pci_register_driver(&blackbird_pci_driver); } @@ -1139,6 +1779,11 @@ static void blackbird_fini(void) module_init(blackbird_init); module_exit(blackbird_fini); +EXPORT_SYMBOL(cx88_ioctl_hook); +EXPORT_SYMBOL(cx88_ioctl_translator); +EXPORT_SYMBOL(blackbird_set_params); +EXPORT_SYMBOL(blackbird_set_dnr_params); + /* ----------------------------------------------------------- */ /* * Local variables: diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index f9d68f20dc88..f80154b87d22 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -114,7 +114,7 @@ struct cx88_board cx88_boards[] = { .radio = { .type = CX88_RADIO, .gpio0 = 0xff10, - }, + }, }, [CX88_BOARD_ATI_WONDER_PRO] = { .name = "ATI TV Wonder Pro", @@ -267,7 +267,7 @@ struct cx88_board cx88_boards[] = { .gpio1 = 0x00007004, .gpio2 = 0x0035d700, .gpio3 = 0x02000000, - }, + }, }, [CX88_BOARD_LEADTEK_PVR2000] = { // gpio values for PAL version from regspy by DScaler @@ -413,7 +413,7 @@ struct cx88_board cx88_boards[] = { .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0x000027df, - },{ + },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0x000027df, @@ -536,7 +536,7 @@ struct cx88_board cx88_boards[] = { .type = CX88_VMUX_COMPOSITE1, .vmux = 1, .gpio0 = 0x000027df, - },{ + },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, .gpio0 = 0x000027df, @@ -759,7 +759,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = { .name = "DViCO FusionHDTV 5 Gold", - .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H062F */ + .tuner_type = TUNER_LG_TDVS_H062F, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1050,7 +1050,11 @@ struct cx88_board cx88_boards[] = { .dvb = 1, }, [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { - /* FIXME: Audio not working for s-video / composite inputs. */ + /* FIXME: Standard video using the cx88 broadcast decoder is + * working, but blackbird isn't working yet, audio is only + * working correctly for television mode. S-Video and Composite + * are working for video-only, so I have them disabled for now. + */ .name = "KWorld HardwareMpegTV XPert", .tuner_type = TUNER_PHILIPS_TDA8290, .radio_type = UNSET, @@ -1061,21 +1065,12 @@ struct cx88_board cx88_boards[] = { .vmux = 0, .gpio0 = 0x3de2, .gpio2 = 0x00ff, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x3de6, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x3de6, }}, .radio = { .type = CX88_RADIO, .gpio0 = 0x3de6, .gpio2 = 0x00ff, }, - .blackbird = 1, }, [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = { .name = "DViCO FusionHDTV DVB-T Hybrid", @@ -1098,102 +1093,7 @@ struct cx88_board cx88_boards[] = { }}, .dvb = 1, }, - [CX88_BOARD_PCHDTV_HD5500] = { - .name = "pcHDTV HD5500 HDTV", - .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x87fd, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x87f9, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x87f9, - }}, - .dvb = 1, - }, - [CX88_BOARD_KWORLD_MCE200_DELUXE] = { - /* FIXME: tested TV input only, disabled composite, - svideo and radio until they can be tested also. */ - .name = "Kworld MCE 200 Deluxe", - .tuner_type = TUNER_TENA_9533_DI, - .radio_type = UNSET, - .tda9887_conf = TDA9887_PRESENT, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x0000BDE6 - }}, - .blackbird = 1, - }, - [CX88_BOARD_PIXELVIEW_PLAYTV_P7000] = { - /* FIXME: SVideo, Composite and FM inputs are untested */ - .name = "PixelView PlayTV P7000", - .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | - TDA9887_PORT2_ACTIVE, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x5da6, - }}, - .blackbird = 1, - }, - [CX88_BOARD_NPGTECH_REALTV_TOP10FM] = { - .name = "NPG Tech Real TV FM Top 10", - .tuner_type = TUNER_TNF_5335MF, /* Actually a TNF9535 */ - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x0788, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x078b, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x078b, - }}, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x074a, - }, - }, - [CX88_BOARD_WINFAST_DTV2000H] = { - /* video inputs and radio still in testing */ - .name = "WinFast DTV2000 H", - .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x00017304, - .gpio1 = 0x00008203, - .gpio2 = 0x00017304, - .gpio3 = 0x02000000, - }}, - .dvb = 1, - }, + }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -1411,34 +1311,6 @@ struct cx88_subid cx88_subids[] = { .subvendor = 0x18ac, .subdevice = 0xdb44, .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID, - },{ - .subvendor = 0x7063, - .subdevice = 0x5500, - .card = CX88_BOARD_PCHDTV_HD5500, - },{ - .subvendor = 0x17de, - .subdevice = 0x0841, - .card = CX88_BOARD_KWORLD_MCE200_DELUXE, - },{ - .subvendor = 0x1822, - .subdevice = 0x0019, - .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO, - },{ - .subvendor = 0x1554, - .subdevice = 0x4813, - .card = CX88_BOARD_PIXELVIEW_PLAYTV_P7000, - },{ - .subvendor = 0x14f1, - .subdevice = 0x0842, - .card = CX88_BOARD_NPGTECH_REALTV_TOP10FM, - },{ - .subvendor = 0x107d, - .subdevice = 0x665e, - .card = CX88_BOARD_WINFAST_DTV2000H, - },{ - .subvendor = 0x18ac, - .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */ - .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, }, }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); @@ -1700,6 +1572,11 @@ void cx88_card_setup(struct cx88_core *core) /* ------------------------------------------------------------------ */ EXPORT_SYMBOL(cx88_boards); +EXPORT_SYMBOL(cx88_bcount); +EXPORT_SYMBOL(cx88_subids); +EXPORT_SYMBOL(cx88_idcount); +EXPORT_SYMBOL(cx88_card_list); +EXPORT_SYMBOL(cx88_card_setup); /* * Local variables: diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index 26f4c0fb8c36..e1092d5d4628 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -677,7 +677,7 @@ static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm) { - return (norm->id & V4L2_STD_625_50) ? 511 : 400; + return (norm->id & V4L2_STD_625_50) ? 511 : 288; } int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, @@ -932,9 +932,9 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm) htotal, cx_read(MO_HTOTAL), (u32)tmp64); cx_write(MO_HTOTAL, htotal); - // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes - // the effective vbi offset ~244 samples, the same as the Bt8x8 - cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm)); + // vbi stuff + cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */ + norm_vbipack(norm))); // this is needed as well to set all tvnorm parameter cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED); @@ -1181,6 +1181,8 @@ EXPORT_SYMBOL(cx88_set_scale); EXPORT_SYMBOL(cx88_vdev_init); EXPORT_SYMBOL(cx88_core_get); EXPORT_SYMBOL(cx88_core_put); +EXPORT_SYMBOL(cx88_start_audio_dma); +EXPORT_SYMBOL(cx88_stop_audio_dma); /* * Local variables: diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index dce1feddd55d..3619a449aefd 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -51,7 +51,6 @@ #endif #ifdef HAVE_LGDT330X # include "lgdt330x.h" -# include "lg_h06xf.h" #endif #ifdef HAVE_NXT200X # include "nxt200x.h" @@ -59,7 +58,6 @@ #ifdef HAVE_CX24123 # include "cx24123.h" #endif -#include "isl6421.h" MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); MODULE_AUTHOR("Chris Pascoe "); @@ -115,6 +113,21 @@ static struct videobuf_queue_ops dvb_qops = { /* ------------------------------------------------------------------ */ +#if defined(HAVE_MT352) || defined(HAVE_ZL10353) +static int zarlink_pll_set(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params, + u8 *pllbuf) +{ + struct cx8802_dev *dev = fe->dvb->priv; + + pllbuf[0] = dev->core->pll_addr << 1; + dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, + params->frequency, + params->u.ofdm.bandwidth); + return 0; +} +#endif + #ifdef HAVE_MT352 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) { @@ -183,16 +196,19 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) static struct mt352_config dvico_fusionhdtv = { .demod_address = 0x0F, .demod_init = dvico_fusionhdtv_demod_init, + .pll_set = zarlink_pll_set, }; static struct mt352_config dntv_live_dvbt_config = { .demod_address = 0x0f, .demod_init = dntv_live_dvbt_demod_init, + .pll_set = zarlink_pll_set, }; static struct mt352_config dvico_fusionhdtv_dual = { .demod_address = 0x0F, .demod_init = dvico_dual_demod_init, + .pll_set = zarlink_pll_set, }; #ifdef HAVE_VP3054_I2C @@ -230,8 +246,6 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe) .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; int err; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { if (err < 0) return err; @@ -242,14 +256,14 @@ static int philips_fmd1216_pll_init(struct dvb_frontend *fe) return 0; } -static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) +static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params, + u8* pllbuf) { struct cx8802_dev *dev= fe->dvb->priv; - u8 buf[4]; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, - .buf = buf, .len = 4 }; + .buf = pllbuf+1, .len = 4 }; int err; /* Switch PLL to DVB mode */ @@ -258,16 +272,14 @@ static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, return err; /* Tune PLL */ - dvb_pll_configure(dev->core->pll_desc, buf, + pllbuf[0] = dev->core->pll_addr << 1; + dvb_pll_configure(dev->core->pll_desc, pllbuf+1, params->frequency, params->u.ofdm.bandwidth); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, dev->core->pll_addr, buf[0], err); + __FUNCTION__, pllbuf[0], pllbuf[1], err); if (err < 0) return err; else @@ -281,27 +293,27 @@ static struct mt352_config dntv_live_dvbt_pro_config = { .demod_address = 0x0f, .no_tuner = 1, .demod_init = dntv_live_dvbt_pro_demod_init, + .pll_set = dntv_live_dvbt_pro_pll_set, }; #endif #endif #ifdef HAVE_ZL10353 -static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) +static int dvico_hybrid_tune_pll(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params, + u8 *pllbuf) { - u8 pllbuf[4]; struct cx8802_dev *dev= fe->dvb->priv; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, - .buf = pllbuf, .len = 4 }; + .buf = pllbuf + 1, .len = 4 }; int err; - dvb_pll_configure(dev->core->pll_desc, pllbuf, + pllbuf[0] = dev->core->pll_addr << 1; + dvb_pll_configure(dev->core->pll_desc, pllbuf + 1, params->frequency, params->u.ofdm.bandwidth); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", @@ -317,11 +329,12 @@ static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe, static struct zl10353_config dvico_fusionhdtv_hybrid = { .demod_address = 0x0F, - .no_tuner = 1, + .pll_set = dvico_hybrid_tune_pll, }; static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { .demod_address = 0x0F, + .pll_set = zarlink_pll_set, }; #endif @@ -329,15 +342,21 @@ static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { static struct cx22702_config connexant_refboard_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, + .pll_address = 0x60, + .pll_desc = &dvb_pll_thomson_dtt7579, }; static struct cx22702_config hauppauge_novat_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, + .pll_address = 0x61, + .pll_desc = &dvb_pll_thomson_dtt759x, }; static struct cx22702_config hauppauge_hvr1100_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, + .pll_address = 0x61, + .pll_desc = &dvb_pll_fmd1216me, }; #endif @@ -352,13 +371,15 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, + .pll_address = 0x61, + .pll_desc = &dvb_pll_thomson_dtt761x, .set_ts_params = or51132_set_ts_param, }; #endif #ifdef HAVE_LGDT330X -static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) +static int lgdt330x_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params) { /* FIXME make this routine use the tuner-simple code. * It could probably be shared with a number of ATSC @@ -371,12 +392,12 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; int err; + /* Put the analog decoder in standby to keep it quiet */ + cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); + dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", @@ -386,21 +407,16 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, else return -EREMOTEIO; } + if (core->tuner_type == TUNER_LG_TDVS_H062F) { + /* Set the Auxiliary Byte. */ + buf[2] &= ~0x20; + buf[2] |= 0x18; + buf[3] = 0x50; + i2c_transfer(&core->i2c_adap, &msg, 1); + } return 0; } -static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) -{ - struct cx8802_dev *dev= fe->dvb->priv; - struct cx88_core *core = dev->core; - - /* Put the analog decoder in standby to keep it quiet */ - cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); - - return lg_h06xf_pll_set(fe, &core->i2c_adap, params); -} - static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) { struct cx8802_dev *dev= fe->dvb->priv; @@ -428,6 +444,7 @@ static struct lgdt330x_config fusionhdtv_3_gold = { .demod_address = 0x0e, .demod_chip = LGDT3302, .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ + .pll_set = lgdt330x_pll_set, .set_ts_params = lgdt330x_set_ts_param, }; @@ -435,13 +452,7 @@ static struct lgdt330x_config fusionhdtv_5_gold = { .demod_address = 0x0e, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ - .set_ts_params = lgdt330x_set_ts_param, -}; - -static struct lgdt330x_config pchdtv_hd5500 = { - .demod_address = 0x59, - .demod_chip = LGDT3303, - .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ + .pll_set = lgdt330x_pll_set, .set_ts_params = lgdt330x_set_ts_param, }; #endif @@ -466,6 +477,8 @@ static int nxt200x_set_pll_input(u8* buf, int input) static struct nxt200x_config ati_hdtvwonder = { .demod_address = 0x0a, + .pll_address = 0x61, + .pll_desc = &dvb_pll_tuv1236d, .set_pll_input = nxt200x_set_pll_input, .set_ts_params = nxt200x_set_ts_param, }; @@ -480,30 +493,28 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe, return 0; } -static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; - if (voltage == SEC_VOLTAGE_OFF) { - cx_write(MO_GP0_IO, 0x000006fB); - } else { + if (on) cx_write(MO_GP0_IO, 0x000006f9); - } - - if (core->prev_set_voltage) - return core->prev_set_voltage(fe, voltage); - return 0; + else + cx_write(MO_GP0_IO, 0x000006fB); } static struct cx24123_config hauppauge_novas_config = { .demod_address = 0x55, + .use_isl6421 = 1, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config kworld_dvbs_100_config = { .demod_address = 0x15, + .use_isl6421 = 0, .set_ts_params = cx24123_set_ts_param, + .enable_lnb_voltage = cx24123_enable_lnb_voltage, }; #endif @@ -519,11 +530,6 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt759x); - } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: @@ -531,92 +537,44 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x60, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt7579); - } break; - case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_fmd1216me); - } break; #endif #if defined(HAVE_MT352) || defined(HAVE_ZL10353) case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: + dev->core->pll_addr = 0x60; + dev->core->pll_desc = &dvb_pll_thomson_dtt7579; #ifdef HAVE_MT352 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x60, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt7579); + if (dev->dvb.frontend != NULL) break; - } #endif #ifdef HAVE_ZL10353 /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x60, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt7579); - } -#endif - break; - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: -#ifdef HAVE_MT352 - /* The tin box says DEE1601, but it seems to be DTT7579 - * compatible, with a slightly different MT352 AGC gain. */ - dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, - &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt7579); - break; - } -#endif -#ifdef HAVE_ZL10353 - /* ZL10353 replaces MT352 on later cards */ - dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1, - &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt7579); - } #endif break; #endif /* HAVE_MT352 || HAVE_ZL10353 */ #ifdef HAVE_MT352 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: + dev->core->pll_addr = 0x61; + dev->core->pll_desc = &dvb_pll_lg_z201; dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_lg_z201); - } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: + dev->core->pll_addr = 0x61; + dev->core->pll_desc = &dvb_pll_unknown_1; dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_unknown_1); - } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #ifdef HAVE_VP3054_I2C @@ -624,13 +582,18 @@ static int dvb_register(struct cx8802_dev *dev) dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, &((struct vp3054_i2c_state *)dev->card_priv)->adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; - } #else printk("%s: built without vp3054 support\n", dev->core->name); #endif break; + case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: + /* The tin box says DEE1601, but it seems to be DTT7579 + * compatible, with a slightly different MT352 AGC gain. */ + dev->core->pll_addr = 0x61; + dev->core->pll_desc = &dvb_pll_thomson_dtt7579; + dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, + &dev->core->i2c_adap); + break; #endif #ifdef HAVE_ZL10353 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: @@ -638,20 +601,12 @@ static int dvb_register(struct cx8802_dev *dev) dev->core->pll_desc = &dvb_pll_thomson_fe6600; dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = dvico_hybrid_tuner_set_params; - } break; #endif #ifdef HAVE_OR51132 case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_thomson_dtt761x); - } break; #endif #ifdef HAVE_LGDT330X @@ -672,9 +627,6 @@ static int dvb_register(struct cx8802_dev *dev) dev->core->pll_desc = &dvb_pll_microtune_4042; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; - } } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: @@ -691,9 +643,6 @@ static int dvb_register(struct cx8802_dev *dev) dev->core->pll_desc = &dvb_pll_thomson_dtt761x; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; - } } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: @@ -706,28 +655,10 @@ static int dvb_register(struct cx8802_dev *dev) mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); + dev->core->pll_addr = 0x61; + dev->core->pll_desc = &dvb_pll_tdvs_tua6034; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; - } - } - break; - case CX88_BOARD_PCHDTV_HD5500: - dev->ts_gen_cntrl = 0x08; - { - /* Do a hardware reset of chip before using it. */ - struct cx88_core *core = dev->core; - - cx_clear(MO_GP0_IO, 1); - mdelay(100); - cx_set(MO_GP0_IO, 1); - mdelay(200); - dev->dvb.frontend = lgdt330x_attach(&pchdtv_hd5500, - &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; - } } break; #endif @@ -735,11 +666,6 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, &dev->core->i2c_adap); - if (dev->dvb.frontend != NULL) { - dvb_pll_attach(dev->dvb.frontend, 0x61, - &dev->core->i2c_adap, - &dvb_pll_tuv1236d); - } break; #endif #ifdef HAVE_CX24123 @@ -747,18 +673,10 @@ static int dvb_register(struct cx8802_dev *dev) case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, &dev->core->i2c_adap); - if (dev->dvb.frontend) { - isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap, - 0x08, 0x00, 0x00); - } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, &dev->core->i2c_adap); - if (dev->dvb.frontend) { - dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; - dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; - } break; #endif default: @@ -772,15 +690,15 @@ static int dvb_register(struct cx8802_dev *dev) } if (dev->core->pll_desc) { - dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; - dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; + dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min; + dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max; } /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); /* register everything */ - return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); + return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); } /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/cx88/cx88-i2c.c b/trunk/drivers/media/video/cx88/cx88-i2c.c index 70663805cc30..f720901e9638 100644 --- a/trunk/drivers/media/video/cx88/cx88-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-i2c.c @@ -138,13 +138,13 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) return; if (core->dvbdev) { - if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) - core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); + if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) + core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); i2c_clients_command(&core->i2c_adap, cmd, arg); - if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) - core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); + if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) + core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); } else i2c_clients_command(&core->i2c_adap, cmd, arg); } @@ -234,6 +234,7 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) /* ----------------------------------------------------------------------- */ EXPORT_SYMBOL(cx88_call_i2c_clients); +EXPORT_SYMBOL(cx88_i2c_init); /* * Local variables: diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index 72b630a91f41..78a63b7dd380 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -70,33 +70,14 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); static void cx88_ir_handle_key(struct cx88_IR *ir) { struct cx88_core *core = ir->core; - u32 gpio, data, auxgpio; + u32 gpio, data; /* read gpio value */ gpio = cx_read(ir->gpio_addr); - if (core->board == CX88_BOARD_NPGTECH_REALTV_TOP10FM) { - /* This board apparently uses a combination of 2 GPIO - to represent the keys. Additionally, the second GPIO - can be used for parity. - - Example: - - for key "5" - gpio = 0x758, auxgpio = 0xe5 or 0xf5 - for key "Power" - gpio = 0x758, auxgpio = 0xed or 0xfd - */ - - auxgpio = cx_read(MO_GP1_IO); - /* Take out the parity part */ - gpio+=(gpio & 0x7fd) + (auxgpio & 0xef); - } else - auxgpio = gpio; - if (ir->polling) { - if (ir->last_gpio == auxgpio) + if (ir->last_gpio == gpio) return; - ir->last_gpio = auxgpio; + ir->last_gpio = gpio; } /* extract data */ @@ -191,13 +172,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir_type = IR_TYPE_RC5; ir->sampling = 1; break; - case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_WINFAST2000XP_EXPERT: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; ir->mask_keyup = 0x100; - ir->polling = 50; /* ms */ + ir->polling = 1; /* ms */ break; case CX88_BOARD_IODATA_GVBCTV7E: ir_codes = ir_codes_iodata_bctv7e; @@ -248,12 +228,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir_type = IR_TYPE_PD; ir->sampling = 0xff00; /* address */ break; - case CX88_BOARD_NPGTECH_REALTV_TOP10FM: - ir_codes = ir_codes_npgtech; - ir->gpio_addr = MO_GP0_IO; - ir->mask_keycode = 0xfa; - ir->polling = 50; /* ms */ - break; } if (NULL == ir_codes) { diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index a9d7795a8e14..7d16888b4a86 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, { struct cx88_core *core = dev->core; - dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); + dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], @@ -76,7 +76,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev, case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: - case CX88_BOARD_PCHDTV_HD5500: cx_write(TS_SOP_STAT, 1<<13); break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: @@ -110,7 +109,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, q->count = 1; /* enable irqs */ - dprintk( 1, "setting the interrupt mask\n" ); + dprintk( 0, "setting the interrupt mask\n" ); cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); cx_set(MO_TS_INTMSK, 0x1f0011); @@ -123,7 +122,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, static int cx8802_stop_dma(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - dprintk( 1, "cx8802_stop_dma\n" ); + dprintk( 0, "cx8802_stop_dma\n" ); /* stop dma */ cx_clear(MO_TS_DMACNTRL, 0x11); @@ -143,43 +142,10 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, struct cx88_buffer *buf; struct list_head *item; - dprintk( 1, "cx8802_restart_queue\n" ); + dprintk( 0, "cx8802_restart_queue\n" ); if (list_empty(&q->active)) { - struct cx88_buffer *prev; - prev = NULL; - - dprintk(1, "cx8802_restart_queue: queue is empty\n" ); - - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); - if (NULL == prev) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue,&q->active); - cx8802_start_dma(dev, q, buf); - buf->vb.state = STATE_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(1,"[%p/%d] restart_queue - first active\n", - buf,buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = STATE_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(1,"[%p/%d] restart_queue - move to active\n", - buf,buf->vb.i); - } else { - return 0; - } - prev = buf; - } + dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); return 0; } @@ -238,13 +204,13 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); if (list_empty(&cx88q->active)) { - dprintk( 1, "queue is empty - first active\n" ); + dprintk( 0, "queue is empty - first active\n" ); list_add_tail(&buf->vb.queue,&cx88q->active); cx8802_start_dma(dev, cx88q, buf); buf->vb.state = STATE_ACTIVE; buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(1,"[%p/%d] %s - first active\n", + dprintk(0,"[%p/%d] %s - first active\n", buf, buf->vb.i, __FUNCTION__); } else { @@ -278,7 +244,7 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) } if (restart) { - dprintk(1, "restarting queue\n" ); + dprintk(0, "restarting queue\n" ); cx8802_restart_queue(dev,q); } spin_unlock_irqrestore(&dev->slock,flags); diff --git a/trunk/drivers/media/video/cx88/cx88-tvaudio.c b/trunk/drivers/media/video/cx88/cx88-tvaudio.c index 5785c3481579..641a0c5a6490 100644 --- a/trunk/drivers/media/video/cx88/cx88-tvaudio.c +++ b/trunk/drivers/media/video/cx88/cx88-tvaudio.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include "cx88.h" @@ -138,28 +137,21 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) { u32 volume; -#ifndef CONFIG_VIDEO_CX88_ALSA +#ifndef USING_CX88_ALSA /* restart dma; This avoids buzz in NICAM and is good in others */ cx88_stop_audio_dma(core); #endif cx_write(AUD_RATE_THRES_DMD, 0x000000C0); -#ifndef CONFIG_VIDEO_CX88_ALSA +#ifndef USING_CX88_ALSA cx88_start_audio_dma(core); #endif if (cx88_boards[core->board].blackbird) { /* sets sound input from external adc */ - switch (core->board) { - case CX88_BOARD_HAUPPAUGE_ROSLYN: - case CX88_BOARD_KWORLD_MCE200_DELUXE: - case CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT: - case CX88_BOARD_PIXELVIEW_PLAYTV_P7000: - case CX88_BOARD_ASUS_PVR_416: + if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) cx_clear(AUD_CTL, EN_I2SIN_ENABLE); - break; - default: + else cx_set(AUD_CTL, EN_I2SIN_ENABLE); - } cx_write(AUD_I2SINPUTCNTL, 4); cx_write(AUD_BAUDRATE, 1); @@ -726,7 +718,7 @@ static void set_audio_standard_FM(struct cx88_core *core, /* ----------------------------------------------------------- */ -static int cx88_detect_nicam(struct cx88_core *core) +int cx88_detect_nicam(struct cx88_core *core) { int i, j = 0; diff --git a/trunk/drivers/media/video/cx88/cx88-vbi.c b/trunk/drivers/media/video/cx88/cx88-vbi.c index aa2a69770098..846faadc9f1c 100644 --- a/trunk/drivers/media/video/cx88/cx88-vbi.c +++ b/trunk/drivers/media/video/cx88/cx88-vbi.c @@ -34,8 +34,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f) if (dev->core->tvnorm->id & V4L2_STD_525_60) { /* ntsc */ f->fmt.vbi.sampling_rate = 28636363; - f->fmt.vbi.start[0] = 10; - f->fmt.vbi.start[1] = 273; + f->fmt.vbi.start[0] = 10 -1; + f->fmt.vbi.start[1] = 273 -1; } else if (dev->core->tvnorm->id & V4L2_STD_625_50) { /* pal */ diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index dcda5291b990..694d1d80ff3f 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -494,7 +494,8 @@ static int restart_video_queue(struct cx8800_dev *dev, return 0; buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); + list_del(&buf->vb.queue); + list_add_tail(&buf->vb.queue,&q->active); start_video_dma(dev, q, buf); buf->vb.state = STATE_ACTIVE; buf->count = q->count++; @@ -505,7 +506,8 @@ static int restart_video_queue(struct cx8800_dev *dev, } else if (prev->vb.width == buf->vb.width && prev->vb.height == buf->vb.height && prev->fmt == buf->fmt) { - list_move_tail(&buf->vb.queue, &q->active); + list_del(&buf->vb.queue); + list_add_tail(&buf->vb.queue,&q->active); buf->vb.state = STATE_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index 9a9a0fc7a41a..326a25f147f6 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -25,11 +25,9 @@ #include #include -#include #include #include #include -#include #include #include "btcx-risc.h" @@ -37,7 +35,7 @@ #include #include -#define CX88_VERSION_CODE KERNEL_VERSION(0,0,6) +#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) #ifndef TRUE # define TRUE (1==1) @@ -191,11 +189,6 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 #define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45 #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46 -#define CX88_BOARD_PCHDTV_HD5500 47 -#define CX88_BOARD_KWORLD_MCE200_DELUXE 48 -#define CX88_BOARD_PIXELVIEW_PLAYTV_P7000 49 -#define CX88_BOARD_NPGTECH_REALTV_TOP10FM 50 -#define CX88_BOARD_WINFAST_DTV2000H 51 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -303,7 +296,6 @@ struct cx88_core { /* config info -- dvb */ struct dvb_pll_desc *pll_desc; unsigned int pll_addr; - int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); /* state info */ struct task_struct *kthread; @@ -399,6 +391,14 @@ struct cx8802_suspend_state { int disabled; }; +/* TODO: move this to struct v4l2_mpeg_compression ? */ +struct blackbird_dnr { + u32 mode; + u32 type; + u32 spatial; + u32 temporal; +}; + struct cx8802_dev { struct cx88_core *core; spinlock_t slock; @@ -432,7 +432,8 @@ struct cx8802_dev { unsigned char ts_gen_cntrl; /* mpeg params */ - struct cx2341x_mpeg_params params; + struct v4l2_mpeg_compression params; + struct blackbird_dnr dnr_params; }; /* ----------------------------------------------------------- */ @@ -563,6 +564,7 @@ void cx88_newstation(struct cx88_core *core); void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); int cx88_audio_thread(void *data); +int cx88_detect_nicam(struct cx88_core *core); /* ----------------------------------------------------------- */ /* cx88-input.c */ @@ -591,6 +593,16 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl); +/* ----------------------------------------------------------- */ +/* cx88-blackbird.c */ +extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); +extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); +void blackbird_set_params(struct cx8802_dev *dev, + struct v4l2_mpeg_compression *params); +void blackbird_set_dnr_params(struct cx8802_dev *dev, + struct blackbird_dnr* dnr_params); + /* * Local variables: * c-basic-offset: 8 diff --git a/trunk/drivers/media/video/dsbr100.c b/trunk/drivers/media/video/dsbr100.c index f7e33f9ee8e9..3b4e9985c3d7 100644 --- a/trunk/drivers/media/video/dsbr100.c +++ b/trunk/drivers/media/video/dsbr100.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index ed882ebc7b95..3ba3439db580 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include #include @@ -48,11 +46,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -66,11 +64,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -84,11 +82,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -102,15 +100,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = 2, .amux = 1, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -124,15 +122,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = 2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -148,11 +146,11 @@ struct em28xx_board em28xx_boards[] = { /*FIXME: S-Video not tested */ .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, + .vmux = 0, .amux = MSP_INPUT_DEFAULT, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, + .vmux = 2, .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), }}, @@ -167,15 +165,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7114, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE4, + .vmux = 4, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -190,15 +188,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = 2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -213,15 +211,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = 2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -236,15 +234,15 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = 2, .amux = 0, },{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -256,11 +254,11 @@ struct em28xx_board em28xx_boards[] = { .decoder = EM28XX_SAA7113, .input = {{ .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = 0, .amux = 1, },{ .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = 9, .amux = 1, }}, }, @@ -326,4 +324,8 @@ void em28xx_card_setup(struct em28xx *dev) } } +EXPORT_SYMBOL(em28xx_boards); +EXPORT_SYMBOL(em28xx_bcount); +EXPORT_SYMBOL(em28xx_id_table); + MODULE_DEVICE_TABLE (usb, em28xx_id_table); diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c index 4350cc75b025..e5ee8bceb210 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-core.c +++ b/trunk/drivers/media/video/em28xx/em28xx-core.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify @@ -317,8 +317,8 @@ int em28xx_outfmt_set_yuv422(struct em28xx *dev) return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); } -static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, - u8 ymin, u8 ymax) +int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, + u8 ymax) { em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); @@ -328,7 +328,7 @@ static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); } -static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, +int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, u16 width, u16 height) { u8 cwidth = width; @@ -345,7 +345,7 @@ static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); } -static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) +int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) { u8 mode; /* the em2800 scaler only supports scaling down to 50% */ @@ -534,7 +534,7 @@ static inline void em28xx_isoc_video_copy(struct em28xx *dev, * em28xx_isoIrq() * handles the incoming isoc urbs and fills the frames from our inqueue */ -static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) +void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) { struct em28xx *dev = urb->context; int i, status; diff --git a/trunk/drivers/media/video/em28xx/em28xx-i2c.c b/trunk/drivers/media/video/em28xx/em28xx-i2c.c index d829d8f8c1f6..5b6cece37aee 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-i2c.c +++ b/trunk/drivers/media/video/em28xx/em28xx-i2c.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify @@ -399,6 +399,17 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } +#ifndef I2C_PEC +static void inc_use(struct i2c_adapter *adap) +{ + MOD_INC_USE_COUNT; +} + +static void dec_use(struct i2c_adapter *adap) +{ + MOD_DEC_USE_COUNT; +} +#endif static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) { @@ -425,19 +436,9 @@ static int attach_inform(struct i2c_client *client) struct em28xx *dev = client->adapter->algo_data; switch (client->addr << 1) { - case 0x43: - case 0x4b: - { - struct tuner_setup tun_setup; - - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; - tun_setup.type = TUNER_TDA9887; - tun_setup.addr = client->addr; - - em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); + case 0x86: em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); break; - } case 0x42: dprintk1(1,"attach_inform: saa7114 detected.\n"); break; @@ -463,7 +464,6 @@ static int attach_inform(struct i2c_client *client) case 0xba: dprintk1(1,"attach_inform: tvp5150 detected.\n"); break; - default: dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); dev->tuner_addr = client->addr; @@ -480,7 +480,12 @@ static struct i2c_algorithm em28xx_algo = { }; static struct i2c_adapter em28xx_adap_template = { +#ifdef I2C_PEC .owner = THIS_MODULE, +#else + .inc_use = inc_use, + .dec_use = dec_use, +#endif .class = I2C_CLASS_TV_ANALOG, .name = "em28xx", .id = I2C_HW_B_EM28XX, diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c index 3ffb5684f127..31e89e4f18be 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-input.c +++ b/trunk/drivers/media/video/em28xx/em28xx-input.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer This program is free software; you can redistribute it and/or modify @@ -105,7 +105,7 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -static int get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { unsigned char buf[3]; @@ -148,8 +148,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); break; case (EM2820_BOARD_PINNACLE_USB_2): - ir->ir_codes = ir_codes_pinnacle_grey; - ir->get_key = get_key_pinnacle_usb_grey; + ir->ir_codes = ir_codes_em_pinnacle_usb; + ir->get_key = get_key_pinnacle_usb; snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); break; case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index 9286090817cd..cf7cdf9ef617 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -3,7 +3,7 @@ Copyright (C) 2005 Ludovico Cavedon Markus Rechberger - Mauro Carvalho Chehab + Mauro Carvalho Chehab Sascha Sommer Some parts based on SN9C10x PC Camera Controllers GPL driver made @@ -42,7 +42,7 @@ #define DRIVER_AUTHOR "Ludovico Cavedon , " \ "Markus Rechberger , " \ - "Mauro Carvalho Chehab , " \ + "Mauro Carvalho Chehab , " \ "Sascha Sommer " #define DRIVER_NAME "em28xx" @@ -170,12 +170,8 @@ static int em28xx_config(struct em28xx *dev) static void em28xx_config_i2c(struct em28xx *dev) { struct v4l2_frequency f; - struct v4l2_routing route; - - route.input = INPUT(dev->ctl_input)->vmux; - route.output = 0; em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL); - em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); + em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input); em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); /* configure tuner */ @@ -210,19 +206,19 @@ static void em28xx_empty_framequeues(struct em28xx *dev) static void video_mux(struct em28xx *dev, int index) { - int ainput; - struct v4l2_routing route; + int input, ainput; - route.input = INPUT(index)->vmux; - route.output = 0; + input = INPUT(index)->vmux; dev->ctl_input = index; dev->ctl_ainput = INPUT(index)->amux; - em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); + em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input); - em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,route.input,dev->ctl_ainput); + em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); if (dev->has_msp34xx) { + struct v4l2_routing route; + if (dev->i2s_speed) em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); route.input = dev->ctl_ainput; diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h index d8fcc9e17ac0..e1ddc2f27a21 100644 --- a/trunk/drivers/media/video/em28xx/em28xx.h +++ b/trunk/drivers/media/video/em28xx/em28xx.h @@ -3,7 +3,7 @@ Copyright (C) 2005 Markus Rechberger Ludovico Cavedon - Mauro Carvalho Chehab + Mauro Carvalho Chehab Based on the em2800 driver from Sascha Sommer @@ -319,7 +319,13 @@ int em28xx_audio_analog_set(struct em28xx *dev); int em28xx_colorlevels_set_default(struct em28xx *dev); int em28xx_capture_start(struct em28xx *dev, int start); int em28xx_outfmt_set_yuv422(struct em28xx *dev); +int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, + u8 ymax); +int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, + u16 width, u16 height); +int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v); int em28xx_resolution_set(struct em28xx *dev); +void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs); int em28xx_init_isoc(struct em28xx *dev); void em28xx_uninit_isoc(struct em28xx *dev); int em28xx_set_alternate(struct em28xx *dev); diff --git a/trunk/drivers/media/video/et61x251/et61x251_core.c b/trunk/drivers/media/video/et61x251/et61x251_core.c index 8992b6e62b9f..dfc9dd732c9d 100644 --- a/trunk/drivers/media/video/et61x251/et61x251_core.c +++ b/trunk/drivers/media/video/et61x251/et61x251_core.c @@ -2341,9 +2341,11 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_CTRL: return et61x251_vidioc_g_ctrl(cam, arg); + case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: return et61x251_vidioc_s_ctrl(cam, arg); + case VIDIOC_CROPCAP_OLD: case VIDIOC_CROPCAP: return et61x251_vidioc_cropcap(cam, arg); @@ -2390,6 +2392,7 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_PARM: return et61x251_vidioc_g_parm(cam, arg); + case VIDIOC_S_PARM_OLD: case VIDIOC_S_PARM: return et61x251_vidioc_s_parm(cam, arg); diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c index fba30a40e9c6..7e66d83fe0ce 100644 --- a/trunk/drivers/media/video/ir-kbd-i2c.c +++ b/trunk/drivers/media/video/ir-kbd-i2c.c @@ -150,11 +150,12 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -/* Common (grey or coloured) pinnacle PCTV remote handling +/* The new pinnacle PCTV remote (with the colored buttons) * + * Ricardo Cerqueira */ -static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, - int parity_offset, int marker, int code_modulo) + +int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { unsigned char b[4]; unsigned int start = 0,parity = 0,code = 0; @@ -166,9 +167,9 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, } for (start = 0; start<4; start++) { - if (b[start] == marker) { - code=b[(start+parity_offset+1)%4]; - parity=b[(start+parity_offset)%4]; + if (b[start] == 0x80) { + code=b[(start+3)%4]; + parity=b[(start+2)%4]; } } @@ -180,14 +181,16 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, if (ir->old == parity) return 0; + ir->old = parity; - /* drop special codes when a key is held down a long time for the grey controller - In this case, the second bit of the code is asserted */ - if (marker == 0xfe && (code & 0x40)) - return 0; + /* Reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ - code %= code_modulo; + code %= 0x88; *ir_raw = code; *ir_key = code; @@ -197,40 +200,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, return 1; } -/* The grey pinnacle PCTV remote - * - * There are one issue with this remote: - * - I2c packet does not change when the same key is pressed quickly. The workaround - * is to hold down each key for about half a second, so that another code is generated - * in the i2c packet, and the function can distinguish key presses. - * - * Sylvain Pasche - */ -int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - - return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); -} - -EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); - - -/* The new pinnacle PCTV remote (with the colored buttons) - * - * Ricardo Cerqueira - */ -int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE - * - * this is the only value that results in 42 unique - * codes < 128 - */ - - return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); -} - -EXPORT_SYMBOL_GPL(get_key_pinnacle_color); +EXPORT_SYMBOL_GPL(get_key_pinnacle); /* ----------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/ks0127.c b/trunk/drivers/media/video/ks0127.c deleted file mode 100644 index 3bf7ac4f5288..000000000000 --- a/trunk/drivers/media/video/ks0127.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * Video Capture Driver (Video for Linux 1/2) - * for the Matrox Marvel G200,G400 and Rainbow Runner-G series - * - * This module is an interface to the KS0127 video decoder chip. - * - * Copyright (C) 1999 Ryan Drake - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - ***************************************************************************** - * - * Modified and extended by - * Mike Bernson - * Gerard v.d. Horst - * Leon van Stuivenberg - * Gernot Ziegler - * - * Version History: - * V1.0 Ryan Drake Initial version by Ryan Drake - * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard - */ - -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "ks0127.h" - -#include -#include - -#define dprintk if (debug) printk - -/* i2c identification */ -#define I2C_KS0127_ADDON 0xD8 -#define I2C_KS0127_ONBOARD 0xDA - -#define KS_TYPE_UNKNOWN 0 -#define KS_TYPE_0122S 1 -#define KS_TYPE_0127 2 -#define KS_TYPE_0127B 3 - -/* ks0127 control registers */ -#define KS_STAT 0x00 -#define KS_CMDA 0x01 -#define KS_CMDB 0x02 -#define KS_CMDC 0x03 -#define KS_CMDD 0x04 -#define KS_HAVB 0x05 -#define KS_HAVE 0x06 -#define KS_HS1B 0x07 -#define KS_HS1E 0x08 -#define KS_HS2B 0x09 -#define KS_HS2E 0x0a -#define KS_AGC 0x0b -#define KS_HXTRA 0x0c -#define KS_CDEM 0x0d -#define KS_PORTAB 0x0e -#define KS_LUMA 0x0f -#define KS_CON 0x10 -#define KS_BRT 0x11 -#define KS_CHROMA 0x12 -#define KS_CHROMB 0x13 -#define KS_DEMOD 0x14 -#define KS_SAT 0x15 -#define KS_HUE 0x16 -#define KS_VERTIA 0x17 -#define KS_VERTIB 0x18 -#define KS_VERTIC 0x19 -#define KS_HSCLL 0x1a -#define KS_HSCLH 0x1b -#define KS_VSCLL 0x1c -#define KS_VSCLH 0x1d -#define KS_OFMTA 0x1e -#define KS_OFMTB 0x1f -#define KS_VBICTL 0x20 -#define KS_CCDAT2 0x21 -#define KS_CCDAT1 0x22 -#define KS_VBIL30 0x23 -#define KS_VBIL74 0x24 -#define KS_VBIL118 0x25 -#define KS_VBIL1512 0x26 -#define KS_TTFRAM 0x27 -#define KS_TESTA 0x28 -#define KS_UVOFFH 0x29 -#define KS_UVOFFL 0x2a -#define KS_UGAIN 0x2b -#define KS_VGAIN 0x2c -#define KS_VAVB 0x2d -#define KS_VAVE 0x2e -#define KS_CTRACK 0x2f -#define KS_POLCTL 0x30 -#define KS_REFCOD 0x31 -#define KS_INVALY 0x32 -#define KS_INVALU 0x33 -#define KS_INVALV 0x34 -#define KS_UNUSEY 0x35 -#define KS_UNUSEU 0x36 -#define KS_UNUSEV 0x37 -#define KS_USRSAV 0x38 -#define KS_USREAV 0x39 -#define KS_SHS1A 0x3a -#define KS_SHS1B 0x3b -#define KS_SHS1C 0x3c -#define KS_CMDE 0x3d -#define KS_VSDEL 0x3e -#define KS_CMDF 0x3f -#define KS_GAMMA0 0x40 -#define KS_GAMMA1 0x41 -#define KS_GAMMA2 0x42 -#define KS_GAMMA3 0x43 -#define KS_GAMMA4 0x44 -#define KS_GAMMA5 0x45 -#define KS_GAMMA6 0x46 -#define KS_GAMMA7 0x47 -#define KS_GAMMA8 0x48 -#define KS_GAMMA9 0x49 -#define KS_GAMMA10 0x4a -#define KS_GAMMA11 0x4b -#define KS_GAMMA12 0x4c -#define KS_GAMMA13 0x4d -#define KS_GAMMA14 0x4e -#define KS_GAMMA15 0x4f -#define KS_GAMMA16 0x50 -#define KS_GAMMA17 0x51 -#define KS_GAMMA18 0x52 -#define KS_GAMMA19 0x53 -#define KS_GAMMA20 0x54 -#define KS_GAMMA21 0x55 -#define KS_GAMMA22 0x56 -#define KS_GAMMA23 0x57 -#define KS_GAMMA24 0x58 -#define KS_GAMMA25 0x59 -#define KS_GAMMA26 0x5a -#define KS_GAMMA27 0x5b -#define KS_GAMMA28 0x5c -#define KS_GAMMA29 0x5d -#define KS_GAMMA30 0x5e -#define KS_GAMMA31 0x5f -#define KS_GAMMAD0 0x60 -#define KS_GAMMAD1 0x61 -#define KS_GAMMAD2 0x62 -#define KS_GAMMAD3 0x63 -#define KS_GAMMAD4 0x64 -#define KS_GAMMAD5 0x65 -#define KS_GAMMAD6 0x66 -#define KS_GAMMAD7 0x67 -#define KS_GAMMAD8 0x68 -#define KS_GAMMAD9 0x69 -#define KS_GAMMAD10 0x6a -#define KS_GAMMAD11 0x6b -#define KS_GAMMAD12 0x6c -#define KS_GAMMAD13 0x6d -#define KS_GAMMAD14 0x6e -#define KS_GAMMAD15 0x6f -#define KS_GAMMAD16 0x70 -#define KS_GAMMAD17 0x71 -#define KS_GAMMAD18 0x72 -#define KS_GAMMAD19 0x73 -#define KS_GAMMAD20 0x74 -#define KS_GAMMAD21 0x75 -#define KS_GAMMAD22 0x76 -#define KS_GAMMAD23 0x77 -#define KS_GAMMAD24 0x78 -#define KS_GAMMAD25 0x79 -#define KS_GAMMAD26 0x7a -#define KS_GAMMAD27 0x7b -#define KS_GAMMAD28 0x7c -#define KS_GAMMAD29 0x7d -#define KS_GAMMAD30 0x7e -#define KS_GAMMAD31 0x7f - - -/**************************************************************************** -* mga_dev : represents one ks0127 chip. -****************************************************************************/ - -struct adjust { - int contrast; - int bright; - int hue; - int ugain; - int vgain; -}; - -struct ks0127 { - struct i2c_client *client; - unsigned char addr; - int format_width; - int format_height; - int cap_width; - int cap_height; - int norm; - int ks_type; - u8 regs[256]; -}; - - -static int debug; /* insmod parameter */ - -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug output"); -MODULE_LICENSE("GPL"); - -static u8 reg_defaults[64]; - - - -static void init_reg_defaults(void) -{ - u8 *table = reg_defaults; - - table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ - table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ - table[KS_CMDC] = 0x00; /* Test options */ - /* clock & input select, write 1 to PORTA */ - table[KS_CMDD] = 0x01; - table[KS_HAVB] = 0x00; /* HAV Start Control */ - table[KS_HAVE] = 0x00; /* HAV End Control */ - table[KS_HS1B] = 0x10; /* HS1 Start Control */ - table[KS_HS1E] = 0x00; /* HS1 End Control */ - table[KS_HS2B] = 0x00; /* HS2 Start Control */ - table[KS_HS2E] = 0x00; /* HS2 End Control */ - table[KS_AGC] = 0x53; /* Manual setting for AGC */ - table[KS_HXTRA] = 0x00; /* Extra Bits for HAV and HS1/2 */ - table[KS_CDEM] = 0x00; /* Chroma Demodulation Control */ - table[KS_PORTAB] = 0x0f; /* port B is input, port A output GPPORT */ - table[KS_LUMA] = 0x01; /* Luma control */ - table[KS_CON] = 0x00; /* Contrast Control */ - table[KS_BRT] = 0x00; /* Brightness Control */ - table[KS_CHROMA] = 0x2a; /* Chroma control A */ - table[KS_CHROMB] = 0x90; /* Chroma control B */ - table[KS_DEMOD] = 0x00; /* Chroma Demodulation Control & Status */ - table[KS_SAT] = 0x00; /* Color Saturation Control*/ - table[KS_HUE] = 0x00; /* Hue Control */ - table[KS_VERTIA] = 0x00; /* Vertical Processing Control A */ - /* Vertical Processing Control B, luma 1 line delayed */ - table[KS_VERTIB] = 0x12; - table[KS_VERTIC] = 0x0b; /* Vertical Processing Control C */ - table[KS_HSCLL] = 0x00; /* Horizontal Scaling Ratio Low */ - table[KS_HSCLH] = 0x00; /* Horizontal Scaling Ratio High */ - table[KS_VSCLL] = 0x00; /* Vertical Scaling Ratio Low */ - table[KS_VSCLH] = 0x00; /* Vertical Scaling Ratio High */ - /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */ - table[KS_OFMTA] = 0x30; - table[KS_OFMTB] = 0x00; /* Output Control B */ - /* VBI Decoder Control; 4bit fmt: avoid Y overflow */ - table[KS_VBICTL] = 0x5d; - table[KS_CCDAT2] = 0x00; /* Read Only register */ - table[KS_CCDAT1] = 0x00; /* Read Only register */ - table[KS_VBIL30] = 0xa8; /* VBI data decoding options */ - table[KS_VBIL74] = 0xaa; /* VBI data decoding options */ - table[KS_VBIL118] = 0x2a; /* VBI data decoding options */ - table[KS_VBIL1512] = 0x00; /* VBI data decoding options */ - table[KS_TTFRAM] = 0x00; /* Teletext frame alignment pattern */ - table[KS_TESTA] = 0x00; /* test register, shouldn't be written */ - table[KS_UVOFFH] = 0x00; /* UV Offset Adjustment High */ - table[KS_UVOFFL] = 0x00; /* UV Offset Adjustment Low */ - table[KS_UGAIN] = 0x00; /* U Component Gain Adjustment */ - table[KS_VGAIN] = 0x00; /* V Component Gain Adjustment */ - table[KS_VAVB] = 0x07; /* VAV Begin */ - table[KS_VAVE] = 0x00; /* VAV End */ - table[KS_CTRACK] = 0x00; /* Chroma Tracking Control */ - table[KS_POLCTL] = 0x41; /* Timing Signal Polarity Control */ - table[KS_REFCOD] = 0x80; /* Reference Code Insertion Control */ - table[KS_INVALY] = 0x10; /* Invalid Y Code */ - table[KS_INVALU] = 0x80; /* Invalid U Code */ - table[KS_INVALV] = 0x80; /* Invalid V Code */ - table[KS_UNUSEY] = 0x10; /* Unused Y Code */ - table[KS_UNUSEU] = 0x80; /* Unused U Code */ - table[KS_UNUSEV] = 0x80; /* Unused V Code */ - table[KS_USRSAV] = 0x00; /* reserved */ - table[KS_USREAV] = 0x00; /* reserved */ - table[KS_SHS1A] = 0x00; /* User Defined SHS1 A */ - /* User Defined SHS1 B, ALT656=1 on 0127B */ - table[KS_SHS1B] = 0x80; - table[KS_SHS1C] = 0x00; /* User Defined SHS1 C */ - table[KS_CMDE] = 0x00; /* Command Register E */ - table[KS_VSDEL] = 0x00; /* VS Delay Control */ - /* Command Register F, update -immediately- */ - /* (there might come no vsync)*/ - table[KS_CMDF] = 0x02; -} - - -/* We need to manually read because of a bug in the KS0127 chip. - * - * An explanation from kayork@mail.utexas.edu: - * - * During I2C reads, the KS0127 only samples for a stop condition - * during the place where the acknoledge bit should be. Any standard - * I2C implementation (correctly) throws in another clock transition - * at the 9th bit, and the KS0127 will not recognize the stop condition - * and will continue to clock out data. - * - * So we have to do the read ourself. Big deal. - workaround in i2c-algo-bit - */ - - -static u8 ks0127_read(struct ks0127 *ks, u8 reg) -{ - struct i2c_client *c = ks->client; - char val = 0; - struct i2c_msg msgs[] = { - {c->addr, 0, sizeof(reg), ®}, - {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; - int ret; - - ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret != ARRAY_SIZE(msgs)) - dprintk("ks0127_write error\n"); - - return val; -} - - -static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) -{ - char msg[] = {reg, val}; - - if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) - dprintk("ks0127_write error\n"); - - ks->regs[reg] = val; -} - - -/* generic bit-twiddling */ -static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) -{ - u8 val = ks->regs[reg]; - val = (val & and_v) | or_v; - ks0127_write(ks, reg, val); -} - - - -/**************************************************************************** -* ks0127 private api -****************************************************************************/ -static void ks0127_reset(struct ks0127* ks) -{ - int i; - u8 *table = reg_defaults; - - ks->ks_type = KS_TYPE_UNKNOWN; - - dprintk("ks0127: reset\n"); - msleep(1); - - /* initialize all registers to known values */ - /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ - - for(i = 1; i < 33; i++) - ks0127_write(ks, i, table[i]); - - for(i = 35; i < 40; i++) - ks0127_write(ks, i, table[i]); - - for(i = 41; i < 56; i++) - ks0127_write(ks, i, table[i]); - - for(i = 58; i < 64; i++) - ks0127_write(ks, i, table[i]); - - - if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { - ks->ks_type = KS_TYPE_0122S; - dprintk("ks0127: ks0122s Found\n"); - return; - } - - switch(ks0127_read(ks, KS_CMDE) & 0x0f) { - - case 0: - ks->ks_type = KS_TYPE_0127; - dprintk("ks0127: ks0127 found\n"); - break; - - case 9: - ks->ks_type = KS_TYPE_0127B; - dprintk("ks0127: ks0127B Revision A found\n"); - break; - - default: - dprintk("ks0127: unknown revision\n"); - break; - } -} - -static int ks0127_command(struct i2c_client *client, - unsigned int cmd, void *arg) -{ - struct ks0127 *ks = i2c_get_clientdata(client); - - int *iarg = (int*)arg; - - int status; - - if (!ks) - return -ENODEV; - - switch (cmd) { - - case DECODER_INIT: - dprintk("ks0127: command DECODER_INIT\n"); - ks0127_reset(ks); - break; - - case DECODER_SET_INPUT: - switch(*iarg) { - case KS_INPUT_COMPOSITE_1: - case KS_INPUT_COMPOSITE_2: - case KS_INPUT_COMPOSITE_3: - case KS_INPUT_COMPOSITE_4: - case KS_INPUT_COMPOSITE_5: - case KS_INPUT_COMPOSITE_6: - dprintk("ks0127: command DECODER_SET_INPUT %d: " - "Composite\n", *iarg); - /* autodetect 50/60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); - /* VSE=0 */ - ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); - /* set input line */ - ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); - /* non-freerunning mode */ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); - /* analog input */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); - /* enable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); - /* chroma trap, HYBWR=1 */ - ks0127_and_or(ks, KS_LUMA, 0x00, - (reg_defaults[KS_LUMA])|0x0c); - /* scaler fullbw, luma comb off */ - ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); - /* manual chroma comb .25 .5 .25 */ - ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); - - /* chroma path delay */ - ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); - - ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); - break; - - case KS_INPUT_SVIDEO_1: - case KS_INPUT_SVIDEO_2: - case KS_INPUT_SVIDEO_3: - dprintk("ks0127: command DECODER_SET_INPUT %d: " - "S-Video\n", *iarg); - /* autodetect 50/60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); - /* VSE=0 */ - ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); - /* set input line */ - ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); - /* non-freerunning mode */ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); - /* analog input */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); - /* enable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); - ks0127_and_or(ks, KS_LUMA, 0x00, - reg_defaults[KS_LUMA]); - /* disable luma comb */ - ks0127_and_or(ks, KS_VERTIA, 0x08, - (reg_defaults[KS_VERTIA]&0xf0)|0x01); - ks0127_and_or(ks, KS_VERTIC, 0x0f, - reg_defaults[KS_VERTIC]&0xf0); - - ks0127_and_or(ks, KS_CHROMB, 0x0f, - reg_defaults[KS_CHROMB]&0xf0); - - ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); - break; - - case KS_INPUT_YUV656: - dprintk("ks0127: command DECODER_SET_INPUT 15: " - "YUV656\n"); - if (ks->norm == VIDEO_MODE_NTSC || - ks->norm == KS_STD_PAL_M) - /* force 60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); - else - /* force 50 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); - - ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ - /* set input line and VALIGN */ - ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); - /* freerunning mode, */ - /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); - /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); - /* disable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); - /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ - ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); - ks0127_and_or(ks, KS_VERTIC, 0x0f, - reg_defaults[KS_VERTIC]&0xf0); - - /* scaler fullbw, luma comb off */ - ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); - - ks0127_and_or(ks, KS_CHROMB, 0x0f, - reg_defaults[KS_CHROMB]&0xf0); - - ks0127_and_or(ks, KS_CON, 0x00, 0x00); - ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ - /* spec: 229 (e5) */ - ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); - ks0127_and_or(ks, KS_HUE, 0x00, 0); - - ks0127_and_or(ks, KS_UGAIN, 0x00, 238); - ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); - - /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ - ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); - ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); - break; - - default: - dprintk("ks0127: command DECODER_SET_INPUT: " - "Unknown input %d\n", *iarg); - break; - } - - /* hack: CDMLPF sometimes spontaneously switches on; */ - /* force back off */ - ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); - break; - - case DECODER_SET_OUTPUT: - switch(*iarg) { - case KS_OUTPUT_YUV656E: - dprintk("ks0127: command DECODER_SET_OUTPUT: " - "OUTPUT_YUV656E (Missing)\n"); - return -EINVAL; - break; - - case KS_OUTPUT_EXV: - dprintk("ks0127: command DECODER_SET_OUTPUT: " - "OUTPUT_EXV\n"); - ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); - break; - } - break; - - case DECODER_SET_NORM: //sam This block mixes old and new norm names... - /* Set to automatic SECAM/Fsc mode */ - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); - - ks->norm = *iarg; - switch(*iarg) - { - /* this is untested !! */ - /* It just detects PAL_N/NTSC_M (no special frequencies) */ - /* And you have to set the standard a second time afterwards */ - case VIDEO_MODE_AUTO: - dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); - - /* The chip determines the format */ - /* based on the current field rate */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); - /* This is wrong for PAL ! As I said, */ - /* you need to set the standard once again !! */ - ks->format_height = 240; - ks->format_width = 704; - break; - - case VIDEO_MODE_NTSC: - dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); - ks->format_height = 240; - ks->format_width = 704; - break; - - case KS_STD_NTSC_N: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "NTSC_N (fixme)\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); - ks->format_height = 240; - ks->format_width = 704; - break; - - case VIDEO_MODE_PAL: - dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); - ks->format_height = 290; - ks->format_width = 704; - break; - - case KS_STD_PAL_M: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "PAL_M (fixme)\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); - ks->format_height = 290; - ks->format_width = 704; - break; - - case VIDEO_MODE_SECAM: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "SECAM\n"); - ks->format_height = 290; - ks->format_width = 704; - - /* set to secam autodetection */ - ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); - schedule_timeout_interruptible(HZ/10+1); - - /* did it autodetect? */ - if (ks0127_read(ks, KS_DEMOD) & 0x40) - break; - - /* force to secam mode */ - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); - break; - - default: - dprintk("ks0127: command DECODER_SET_NORM: " - "Unknown norm %d\n", *iarg); - break; - } - break; - - case DECODER_SET_PICTURE: - dprintk("ks0127: command DECODER_SET_PICTURE " - "not yet supported (fixme)\n"); - return -EINVAL; - - //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? - //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_AGC_MODE: - //sam todo: KS0127_SET_AGC: - //sam todo: KS0127_SET_CHROMA_MODE: - //sam todo: KS0127_SET_PIXCLK_MODE: - //sam todo: KS0127_SET_GAMMA_MODE: - //sam todo: KS0127_SET_UGAIN: - //sam todo: KS0127_SET_VGAIN: - //sam todo: KS0127_SET_INVALY: - //sam todo: KS0127_SET_INVALU: - //sam todo: KS0127_SET_INVALV: - //sam todo: KS0127_SET_UNUSEY: - //sam todo: KS0127_SET_UNUSEU: - //sam todo: KS0127_SET_UNUSEV: - //sam todo: KS0127_SET_VSALIGN_MODE: - - case DECODER_ENABLE_OUTPUT: - { - - int *iarg = arg; - int enable = (*iarg != 0); - if (enable) { - dprintk("ks0127: command " - "DECODER_ENABLE_OUTPUT on " - "(%d)\n", enable); - /* All output pins on */ - ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); - /* Obey the OEN pin */ - ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); - } else { - dprintk("ks0127: command " - "DECODER_ENABLE_OUTPUT off " - "(%d)\n", enable); - /* Video output pins off */ - ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); - /* Ignore the OEN pin */ - ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); - } - } - break; - - //sam todo: KS0127_SET_OUTPUT_MODE: - //sam todo: KS0127_SET_WIDTH: - //sam todo: KS0127_SET_HEIGHT: - //sam todo: KS0127_SET_HSCALE: - - case DECODER_GET_STATUS: - dprintk("ks0127: command DECODER_GET_STATUS\n"); - *iarg = 0; - status = ks0127_read(ks, KS_STAT); - if (!(status & 0x20)) /* NOVID not set */ - *iarg = (*iarg & DECODER_STATUS_GOOD); - if ((status & 0x01)) /* CLOCK set */ - *iarg = (*iarg & DECODER_STATUS_COLOR); - if ((status & 0x08)) /* PALDET set */ - *iarg = (*iarg & DECODER_STATUS_PAL); - else - *iarg = (*iarg & DECODER_STATUS_NTSC); - break; - - //Catch any unknown command - default: - dprintk("ks0127: command unknown: %04X\n", cmd); - return -EINVAL; - } - return 0; -} - - - - -static int ks0127_probe(struct i2c_adapter *adapter); -static int ks0127_detach(struct i2c_client *client); -static int ks0127_command(struct i2c_client *client, - unsigned int cmd, void *arg); - - - -/* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, - I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; -static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static struct i2c_client_address_data addr_data = { - normal_i2c, - probe, - ignore, -}; - -static struct i2c_driver i2c_driver_ks0127 = { - .driver.name = "ks0127", - .id = I2C_DRIVERID_KS0127, - .attach_adapter = ks0127_probe, - .detach_client = ks0127_detach, - .command = ks0127_command -}; - -static struct i2c_client ks0127_client_tmpl = -{ - .name = "(ks0127 unset)", - .addr = 0, - .adapter = NULL, - .driver = &i2c_driver_ks0127, - .usage_count = 0 -}; - -static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) -{ - struct ks0127 *ks; - struct i2c_client *client; - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &ks0127_client_tmpl, sizeof(*client)); - - ks = kzalloc(sizeof(*ks), GFP_KERNEL); - if (ks == NULL) { - kfree(client); - return -ENOMEM; - } - - i2c_set_clientdata(client, ks); - client->adapter = adapter; - client->addr = addr; - sprintf(client->name, "ks0127-%02x", adapter->id); - - ks->client = client; - ks->addr = addr; - ks->ks_type = KS_TYPE_UNKNOWN; - - /* power up */ - ks0127_write(ks, KS_CMDA, 0x2c); - mdelay(10); - - /* reset the device */ - ks0127_reset(ks); - printk(KERN_INFO "ks0127: attach: %s video decoder\n", - ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); - - i2c_attach_client(client); - return 0; -} - - -static int ks0127_probe(struct i2c_adapter *adapter) -{ - if (adapter->id == I2C_HW_B_ZR36067) - return i2c_probe(adapter, &addr_data, ks0127_found_proc); - return 0; -} - -static int ks0127_detach(struct i2c_client *client) -{ - struct ks0127 *ks = i2c_get_clientdata(client); - - ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ - ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ - - i2c_detach_client(client); - kfree(ks); - kfree(client); - - dprintk("ks0127: detach\n"); - return 0; -} - - -static int __devinit ks0127_init_module(void) -{ - init_reg_defaults(); - i2c_add_driver(&i2c_driver_ks0127); - return 0; -} - -static void __devexit ks0127_cleanup_module(void) -{ - i2c_del_driver(&i2c_driver_ks0127); -} - - -module_init(ks0127_init_module); -module_exit(ks0127_cleanup_module); diff --git a/trunk/drivers/media/video/ks0127.h b/trunk/drivers/media/video/ks0127.h deleted file mode 100644 index 1ec578833aea..000000000000 --- a/trunk/drivers/media/video/ks0127.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Video Capture Driver ( Video for Linux 1/2 ) - * for the Matrox Marvel G200,G400 and Rainbow Runner-G series - * - * This module is an interface to the KS0127 video decoder chip. - * - * Copyright (C) 1999 Ryan Drake - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef KS0127_H -#define KS0127_H - -#include - -/* input channels */ -#define KS_INPUT_COMPOSITE_1 0 -#define KS_INPUT_COMPOSITE_2 1 -#define KS_INPUT_COMPOSITE_3 2 -#define KS_INPUT_COMPOSITE_4 4 -#define KS_INPUT_COMPOSITE_5 5 -#define KS_INPUT_COMPOSITE_6 6 - -#define KS_INPUT_SVIDEO_1 8 -#define KS_INPUT_SVIDEO_2 9 -#define KS_INPUT_SVIDEO_3 10 - -#define KS_INPUT_YUV656 15 -#define KS_INPUT_COUNT 10 - -/* output channels */ -#define KS_OUTPUT_YUV656E 0 -#define KS_OUTPUT_EXV 1 - -/* video standards */ -#define KS_STD_NTSC_N 112 /* 50 Hz NTSC */ -#define KS_STD_PAL_M 113 /* 60 Hz PAL */ - -#endif /* KS0127_H */ - diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c index f68ca7d9f531..850bee97090c 100644 --- a/trunk/drivers/media/video/meye.c +++ b/trunk/drivers/media/video/meye.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -1683,13 +1682,13 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) static void meye_vm_open(struct vm_area_struct *vma) { - long idx = (long)vma->vm_private_data; + int idx = (int)vma->vm_private_data; meye.vma_use_count[idx]++; } static void meye_vm_close(struct vm_area_struct *vma) { - long idx = (long)vma->vm_private_data; + int idx = (int)vma->vm_private_data; meye.vma_use_count[idx]--; } diff --git a/trunk/drivers/media/video/msp3400-driver.c b/trunk/drivers/media/video/msp3400-driver.c index dbb75a7db199..b806999d6e0f 100644 --- a/trunk/drivers/media/video/msp3400-driver.c +++ b/trunk/drivers/media/video/msp3400-driver.c @@ -385,6 +385,67 @@ static int msp_mode_v4l1_to_v4l2(int mode) return V4L2_TUNER_MODE_MONO; } +static struct v4l2_queryctrl msp_qctrl_std[] = { + { + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 58880, + .flags = 0, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, +}; + +static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { + { + .id = V4L2_CID_AUDIO_BALANCE, + .name = "Balance", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .flags = 0, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_BASS, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_TREBLE, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_LOUDNESS, + .name = "Loudness", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, +}; + + static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) { struct msp_state *state = i2c_get_clientdata(client); @@ -613,31 +674,22 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) int sc1_out = rt->output & 0xf; int sc2_out = (rt->output >> 4) & 0xf; u16 val, reg; - int i; - int extern_input = 1; if (state->routing.input == rt->input && state->routing.output == rt->output) break; state->routing = *rt; - /* check if the tuner input is used */ - for (i = 0; i < 5; i++) { - if (((rt->input >> (4 + i * 4)) & 0xf) == 0) - extern_input = 0; - } - if (extern_input) - state->mode = MSP_MODE_EXTERN; - else - state->mode = MSP_MODE_AM_DETECT; msp_set_scart(client, sc_in, 0); msp_set_scart(client, sc1_out, 1); msp_set_scart(client, sc2_out, 2); msp_set_audmode(client); reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; val = msp_read_dem(client, reg); - msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); - /* wake thread when a new input is chosen */ - msp_wake_thread(client); + if (tuner != ((val >> 8) & 1)) { + msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); + /* wake thread when a new tuner input is chosen */ + msp_wake_thread(client); + } break; } @@ -692,25 +744,21 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; + int i; - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill_std(qc); - default: - break; - } + for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) + if (qc->id && qc->id == msp_qctrl_std[i].id) { + memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); + return 0; + } if (!state->has_sound_processing) return -EINVAL; - switch (qc->id) { - case V4L2_CID_AUDIO_LOUDNESS: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) + if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { + memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); + return 0; + } + return -EINVAL; } case VIDIOC_G_CTRL: @@ -746,9 +794,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) case MSP_MODE_EXTERN: p = "External input"; break; default: p = "unknown"; break; } - if (state->mode == MSP_MODE_EXTERN) { - v4l_info(client, "Mode: %s\n", p); - } else if (state->opmode == OPMODE_MANUAL) { + if (state->opmode == OPMODE_MANUAL) { v4l_info(client, "Mode: %s (%s%s)\n", p, (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); diff --git a/trunk/drivers/media/video/msp3400-kthreads.c b/trunk/drivers/media/video/msp3400-kthreads.c index f2fd9195b3ac..633a10213789 100644 --- a/trunk/drivers/media/video/msp3400-kthreads.c +++ b/trunk/drivers/media/video/msp3400-kthreads.c @@ -244,21 +244,19 @@ static void msp3400c_set_audmode(struct i2c_client *client) the hardware does not support SAP. So the rxsubchans combination of STEREO | LANG2 does not occur. */ - if (state->mode != MSP_MODE_EXTERN) { - /* switch to mono if only mono is available */ - if (state->rxsubchans == V4L2_TUNER_SUB_MONO) - audmode = V4L2_TUNER_MODE_MONO; - /* if bilingual */ - else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { - /* and mono or stereo, then fallback to lang1 */ - if (audmode == V4L2_TUNER_MODE_MONO || - audmode == V4L2_TUNER_MODE_STEREO) - audmode = V4L2_TUNER_MODE_LANG1; - } - /* if stereo, and audmode is not mono, then switch to stereo */ - else if (audmode != V4L2_TUNER_MODE_MONO) - audmode = V4L2_TUNER_MODE_STEREO; + /* switch to mono if only mono is available */ + if (state->rxsubchans == V4L2_TUNER_SUB_MONO) + audmode = V4L2_TUNER_MODE_MONO; + /* if bilingual */ + else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { + /* and mono or stereo, then fallback to lang1 */ + if (audmode == V4L2_TUNER_MODE_MONO || + audmode == V4L2_TUNER_MODE_STEREO) + audmode = V4L2_TUNER_MODE_LANG1; } + /* if stereo, and audmode is not mono, then switch to stereo */ + else if (audmode != V4L2_TUNER_MODE_MONO) + audmode = V4L2_TUNER_MODE_STEREO; /* switch demodulator */ switch (state->mode) { @@ -483,7 +481,6 @@ int msp3400c_thread(void *data) /* no carrier scan, just unmute */ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); state->scan_in_progress = 0; - state->rxsubchans = V4L2_TUNER_SUB_STEREO; msp_set_audio(client); continue; } @@ -950,14 +947,6 @@ int msp34xxg_thread(void *data) if (kthread_should_stop()) break; - if (state->mode == MSP_MODE_EXTERN) { - /* no carrier scan needed, just unmute */ - v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n"); - state->scan_in_progress = 0; - msp_set_audio(client); - continue; - } - /* setup the chip*/ msp34xxg_reset(client); state->std = state->radio ? 0x40 : msp_standard; @@ -989,11 +978,6 @@ int msp34xxg_thread(void *data) v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n", msp_standard_std_name(state->std), state->std); - if (state->std == 9) { - /* AM NICAM mode */ - msp_write_dsp(client, 0x0e, 0x7c00); - } - /* unmute: dispatch sound to scart output, set scart volume */ msp_set_audio(client); diff --git a/trunk/drivers/media/video/ov511.c b/trunk/drivers/media/video/ov511.c index a988df226aab..fdc8e3f13937 100644 --- a/trunk/drivers/media/video/ov511.c +++ b/trunk/drivers/media/video/ov511.c @@ -3239,7 +3239,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); if (frame->scanstate == STATE_LINES) { - int nextf; + int nextf; frame->grabstate = FRAME_DONE; wake_up_interruptible(&frame->wq); @@ -3405,7 +3405,7 @@ ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); if (frame->scanstate == STATE_LINES) { - int nextf; + int nextf; frame->grabstate = FRAME_DONE; wake_up_interruptible(&frame->wq); diff --git a/trunk/drivers/media/video/ov511.h b/trunk/drivers/media/video/ov511.h index 68b082bcee1d..12b3d51e1c34 100644 --- a/trunk/drivers/media/video/ov511.h +++ b/trunk/drivers/media/video/ov511.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/planb.c b/trunk/drivers/media/video/planb.c index 3484e36b6801..d9e3cada52f4 100644 --- a/trunk/drivers/media/video/planb.c +++ b/trunk/drivers/media/video/planb.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/pms.c b/trunk/drivers/media/video/pms.c index 5d681fa8bcb1..09835ca098b1 100644 --- a/trunk/drivers/media/video/pms.c +++ b/trunk/drivers/media/video/pms.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -805,7 +804,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file, struct video_picture *p = arg; if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16) ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15))) - return -EINVAL; + return -EINVAL; pd->picture= *p; /* diff --git a/trunk/drivers/media/video/pvrusb2/Kconfig b/trunk/drivers/media/video/pvrusb2/Kconfig deleted file mode 100644 index 7e727fe14b32..000000000000 --- a/trunk/drivers/media/video/pvrusb2/Kconfig +++ /dev/null @@ -1,62 +0,0 @@ -config VIDEO_PVRUSB2 - tristate "Hauppauge WinTV-PVR USB2 support" - depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL - select FW_LOADER - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_CX2341X - select VIDEO_SAA711X - select VIDEO_MSP3400 - ---help--- - This is a video4linux driver for Conexant 23416 based - usb2 personal video recorder devices. - - To compile this driver as a module, choose M here: the - module will be called pvrusb2 - -config VIDEO_PVRUSB2_24XXX - bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series" - depends on VIDEO_PVRUSB2 && EXPERIMENTAL - select VIDEO_CX25840 - select VIDEO_WM8775 - ---help--- - This option enables inclusion of additional logic to operate - newer WinTV-PVR USB2 devices whose model number is of the - form "24xxx" (leading prefix of "24" followed by 3 digits). - To see if you may need this option, examine the white - sticker on the underside of your device. Enabling this - option will not harm support for older devices, however it - is a separate option because of the experimental nature of - this new feature. - - If you are in doubt, say N. - - Note: This feature is _very_ experimental. You have been - warned. - -config VIDEO_PVRUSB2_SYSFS - bool "pvrusb2 sysfs support (EXPERIMENTAL)" - default y - depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL - ---help--- - This option enables the operation of a sysfs based - interface for query and control of the pvrusb2 driver. - - This is not generally needed for v4l applications, - although certain applications are optimized to take - advantage of this feature. - - If you are in doubt, say Y. - - Note: This feature is experimental and subject to change. - -config VIDEO_PVRUSB2_DEBUGIFC - bool "pvrusb2 debug interface" - depends on VIDEO_PVRUSB2_SYSFS - ---help--- - This option enables the inclusion of a debug interface - in the pvrusb2 driver, hosted through sysfs. - - You do not need to select this option unless you plan - on debugging the driver or performing a manual firmware - extraction. diff --git a/trunk/drivers/media/video/pvrusb2/Makefile b/trunk/drivers/media/video/pvrusb2/Makefile deleted file mode 100644 index fed603ad0a67..000000000000 --- a/trunk/drivers/media/video/pvrusb2/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o -obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o - -obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \ - pvrusb2-cx2584x-v4l.o \ - pvrusb2-wm8775.o - -pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ - pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ - pvrusb2-encoder.o pvrusb2-video-v4l.o \ - pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \ - pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ - pvrusb2-ctrl.o pvrusb2-std.o \ - pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ - $(obj-pvrusb2-24xxx-y) \ - $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) - -obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c deleted file mode 100644 index 313d2dcf9e4b..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-audio.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - -struct pvr2_msp3400_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - struct pvr2_audio_stat astat; - unsigned long stale_mask; -}; - - -/* This function selects the correct audio input source */ -static void set_stereo(struct pvr2_msp3400_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo"); - - if (hdw->input_val == PVR2_CVAL_INPUT_TV) { - struct v4l2_tuner vt; - memset(&vt,0,sizeof(vt)); - vt.audmode = hdw->audiomode_val; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt); - } - - route.input = MSP_INPUT_DEFAULT; - route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - break; - case PVR2_CVAL_INPUT_RADIO: - /* Assume that msp34xx also handle FM decoding, in which case - we're still using the tuner. */ - /* HV: actually it is more likely to be the SCART2 input if - the ivtv experience is any indication. */ - route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - /* SCART 1 input */ - route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - - -static int check_stereo(struct pvr2_msp3400_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return (hdw->input_dirty || - hdw->audiomode_dirty); -} - - -struct pvr2_msp3400_ops { - void (*update)(struct pvr2_msp3400_handler *); - int (*check)(struct pvr2_msp3400_handler *); -}; - - -static const struct pvr2_msp3400_ops msp3400_ops[] = { - { .update = set_stereo, .check = check_stereo}, -}; - - -static int msp3400_check(struct pvr2_msp3400_handler *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (msp3400_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void msp3400_update(struct pvr2_msp3400_handler *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - msp3400_ops[idx].update(ctxt); - } -} - - -/* This reads back the current signal type */ -static int get_audio_status(struct pvr2_msp3400_handler *ctxt) -{ - struct v4l2_tuner vt; - int stat; - - memset(&vt,0,sizeof(vt)); - stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (stat < 0) return stat; - - ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0; - ctxt->hdw->flag_bilingual = - (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0; - return 0; -} - - -static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->audio_stat = 0; - kfree(ctxt); -} - - -static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2"); -} - - -const static struct pvr2_i2c_handler_functions msp3400_funcs = { - .detach = (void (*)(void *))pvr2_msp3400_detach, - .check = (int (*)(void *))msp3400_check, - .update = (void (*)(void *))msp3400_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe, -}; - - -int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_msp3400_handler *ctxt; - if (hdw->audio_stat) return 0; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &msp3400_funcs; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->astat.ctxt = ctxt; - ctxt->astat.status = (int (*)(void *))get_audio_status; - ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach; - ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/ - sizeof(msp3400_ops[0]))) - 1; - cp->handler = &ctxt->i2c_handler; - hdw->audio_stat = &ctxt->astat; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", - cp->client->addr); - return !0; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h deleted file mode 100644 index 536339b68843..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_AUDIO_H -#define __PVRUSB2_AUDIO_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_AUDIO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c deleted file mode 100644 index 40dc59871a45..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-context.h" -#include "pvrusb2-io.h" -#include "pvrusb2-ioread.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - - -static void pvr2_context_destroy(struct pvr2_context *mp) -{ - if (mp->hdw) pvr2_hdw_destroy(mp->hdw); - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); - flush_workqueue(mp->workqueue); - destroy_workqueue(mp->workqueue); - kfree(mp); -} - - -static void pvr2_context_trigger_poll(struct pvr2_context *mp) -{ - queue_work(mp->workqueue,&mp->workpoll); -} - - -static void pvr2_context_poll(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - pvr2_hdw_poll(mp->hdw); - } while (0); pvr2_context_exit(mp); -} - - -static void pvr2_context_setup(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - if (!pvr2_hdw_dev_ok(mp->hdw)) break; - pvr2_hdw_setup(mp->hdw); - pvr2_hdw_setup_poll_trigger( - mp->hdw, - (void (*)(void *))pvr2_context_trigger_poll, - mp); - if (!pvr2_hdw_dev_ok(mp->hdw)) break; - if (!pvr2_hdw_init_ok(mp->hdw)) break; - mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); - if (mp->setup_func) { - mp->setup_func(mp); - } - } while (0); pvr2_context_exit(mp); -} - - -struct pvr2_context *pvr2_context_create( - struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)) -{ - struct pvr2_context *mp = 0; - mp = kmalloc(sizeof(*mp),GFP_KERNEL); - if (!mp) goto done; - memset(mp,0,sizeof(*mp)); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); - mp->setup_func = setup_func; - mutex_init(&mp->mutex); - mp->hdw = pvr2_hdw_create(intf,devid); - if (!mp->hdw) { - pvr2_context_destroy(mp); - mp = 0; - goto done; - } - - mp->workqueue = create_singlethread_workqueue("pvrusb2"); - INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp); - INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp); - queue_work(mp->workqueue,&mp->workinit); - done: - return mp; -} - - -void pvr2_context_enter(struct pvr2_context *mp) -{ - mutex_lock(&mp->mutex); - pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp); -} - - -void pvr2_context_exit(struct pvr2_context *mp) -{ - int destroy_flag = 0; - if (!(mp->mc_first || !mp->disconnect_flag)) { - destroy_flag = !0; - } - pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp); - mutex_unlock(&mp->mutex); - if (destroy_flag) pvr2_context_destroy(mp); -} - - -static void pvr2_context_run_checks(struct pvr2_context *mp) -{ - struct pvr2_channel *ch1,*ch2; - for (ch1 = mp->mc_first; ch1; ch1 = ch2) { - ch2 = ch1->mc_next; - if (ch1->check_func) { - ch1->check_func(ch1); - } - } -} - - -void pvr2_context_disconnect(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - pvr2_hdw_disconnect(mp->hdw); - mp->disconnect_flag = !0; - pvr2_context_run_checks(mp); - } while (0); pvr2_context_exit(mp); -} - - -void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) -{ - cp->hdw = mp->hdw; - cp->mc_head = mp; - cp->mc_next = 0; - cp->mc_prev = mp->mc_last; - if (mp->mc_last) { - mp->mc_last->mc_next = cp; - } else { - mp->mc_first = cp; - } - mp->mc_last = cp; -} - - -static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp) -{ - if (!cp->stream) return; - pvr2_stream_kill(cp->stream->stream); - cp->stream->user = 0; - cp->stream = 0; -} - - -void pvr2_channel_done(struct pvr2_channel *cp) -{ - struct pvr2_context *mp = cp->mc_head; - pvr2_channel_disclaim_stream(cp); - if (cp->mc_next) { - cp->mc_next->mc_prev = cp->mc_prev; - } else { - mp->mc_last = cp->mc_prev; - } - if (cp->mc_prev) { - cp->mc_prev->mc_next = cp->mc_next; - } else { - mp->mc_first = cp->mc_next; - } - cp->hdw = 0; -} - - -int pvr2_channel_claim_stream(struct pvr2_channel *cp, - struct pvr2_context_stream *sp) -{ - int code = 0; - pvr2_context_enter(cp->mc_head); do { - if (sp == cp->stream) break; - if (sp->user) { - code = -EBUSY; - break; - } - pvr2_channel_disclaim_stream(cp); - if (!sp) break; - sp->user = cp; - cp->stream = sp; - } while (0); pvr2_context_exit(cp->mc_head); - return code; -} - - -// This is the marker for the real beginning of a legitimate mpeg2 stream. -static char stream_sync_key[] = { - 0x00, 0x00, 0x01, 0xba, -}; - -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *sp) -{ - struct pvr2_ioread *cp; - cp = pvr2_ioread_create(); - if (!cp) return 0; - pvr2_ioread_setup(cp,sp->stream); - pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key)); - return cp; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h deleted file mode 100644 index 6327fa1f7e4f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_BASE_H -#define __PVRUSB2_BASE_H - -#include -#include -#include - -struct pvr2_hdw; /* hardware interface - defined elsewhere */ -struct pvr2_stream; /* stream interface - defined elsewhere */ - -struct pvr2_context; /* All central state */ -struct pvr2_channel; /* One I/O pathway to a user */ -struct pvr2_context_stream; /* Wrapper for a stream */ -struct pvr2_crit_reg; /* Critical region pointer */ -struct pvr2_ioread; /* Low level stream structure */ - -struct pvr2_context_stream { - struct pvr2_channel *user; - struct pvr2_stream *stream; -}; - -struct pvr2_context { - struct pvr2_channel *mc_first; - struct pvr2_channel *mc_last; - struct pvr2_hdw *hdw; - struct pvr2_context_stream video_stream; - struct mutex mutex; - int disconnect_flag; - - /* Called after pvr2_context initialization is complete */ - void (*setup_func)(struct pvr2_context *); - - /* Work queue overhead for out-of-line processing */ - struct workqueue_struct *workqueue; - struct work_struct workinit; - struct work_struct workpoll; -}; - -struct pvr2_channel { - struct pvr2_context *mc_head; - struct pvr2_channel *mc_next; - struct pvr2_channel *mc_prev; - struct pvr2_context_stream *stream; - struct pvr2_hdw *hdw; - void (*check_func)(struct pvr2_channel *); -}; - -void pvr2_context_enter(struct pvr2_context *); -void pvr2_context_exit(struct pvr2_context *); - -struct pvr2_context *pvr2_context_create(struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)); -void pvr2_context_disconnect(struct pvr2_context *); - -void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); -void pvr2_channel_done(struct pvr2_channel *); -int pvr2_channel_claim_stream(struct pvr2_channel *, - struct pvr2_context_stream *); -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *); - - -#endif /* __PVRUSB2_CONTEXT_H */ -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c deleted file mode 100644 index d5df9fbeba2f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-ctrl.h" -#include "pvrusb2-hdw-internal.h" -#include -#include -#include - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) -{ - return pvr2_ctrl_set_mask_value(cptr,~0,val); -} - - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->set_value != 0) { - if (cptr->info->type == pvr2_ctl_bitmask) { - mask &= cptr->info->def.type_bitmask.valid_bits; - } else if (cptr->info->type == pvr2_ctl_int) { - if (val < cptr->info->def.type_int.min_value) { - break; - } - if (val > cptr->info->def.type_int.max_value) { - break; - } - } else if (cptr->info->type == pvr2_ctl_enum) { - if (val >= cptr->info->def.type_enum.count) { - break; - } - } else if (cptr->info->type != pvr2_ctl_bool) { - break; - } - ret = cptr->info->set_value(cptr,mask,val); - } else { - ret = -EPERM; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = cptr->info->get_value(cptr,valptr); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) -{ - if (!cptr) return pvr2_ctl_int; - return cptr->info->type; -} - - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.max_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.min_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->default_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - ret = cptr->info->def.type_enum.count; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_bitmask) { - ret = cptr->info->def.type_bitmask.valid_bits; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->name; -} - - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->desc; -} - - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, - char *bptr,unsigned int bmax, - unsigned int *blen) -{ - int ret = -EINVAL; - if (!cptr) return 0; - *blen = 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - const char **names; - names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { - if (names[val]) { - *blen = scnprintf( - bptr,bmax,"%s", - names[val]); - } else { - *blen = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - const char **names; - unsigned int idx; - int msk; - names = cptr->info->def.type_bitmask.bit_names; - val &= cptr->info->def.type_bitmask.valid_bits; - for (idx = 0, msk = 1; val; idx++, msk <<= 1) { - if (val & msk) { - *blen = scnprintf(bptr,bmax,"%s", - names[idx]); - ret = 0; - break; - } - } - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->v4l_id; -} - - -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) -{ - unsigned int flags = 0; - - if (cptr->info->get_v4lflags) { - flags = cptr->info->get_v4lflags(cptr); - } - - if (cptr->info->set_value) { - flags &= ~V4L2_CTRL_FLAG_READ_ONLY; - } else { - flags |= V4L2_CTRL_FLAG_READ_ONLY; - } - - return flags; -} - - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->set_value != 0; -} - - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - if (!cptr->info->val_to_sym) return 0; - if (!cptr->info->sym_to_val) return 0; - return !0; -} - - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->val_to_sym) return -EINVAL; - return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, - const char *buf,unsigned int len, - int *maskptr,int *valptr) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->sym_to_val) return -EINVAL; - return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); -} - - -static unsigned int gen_bitmask_string(int msk,int val,int msk_only, - const char **names, - char *ptr,unsigned int len) -{ - unsigned int idx; - long sm,um; - int spcFl; - unsigned int uc,cnt; - const char *idStr; - - spcFl = 0; - uc = 0; - um = 0; - for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { - if (sm & msk) { - msk &= ~sm; - idStr = names[idx]; - if (idStr) { - cnt = scnprintf(ptr,len,"%s%s%s", - (spcFl ? " " : ""), - (msk_only ? "" : - ((val & sm) ? "+" : "-")), - idStr); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else { - um |= sm; - } - } - } - if (um) { - if (msk_only) { - cnt = scnprintf(ptr,len,"%s0x%lx", - (spcFl ? " " : ""), - um); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & ~val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & ~val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } - } - return uc; -} - - -static const char *boolNames[] = { - "false", - "true", - "no", - "yes", -}; - - -static int parse_token(const char *ptr,unsigned int len, - int *valptr, - const char **names,unsigned int namecnt) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - int negfl; - char *p2; - *valptr = 0; - if (!names) namecnt = 0; - for (idx = 0; idx < namecnt; idx++) { - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = idx; - return 0; - } - negfl = 0; - if ((*ptr == '-') || (*ptr == '+')) { - negfl = (*ptr == '-'); - ptr++; len--; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (negfl) *valptr = -(*valptr); - if (*p2) return -EINVAL; - return 1; -} - - -static int parse_mtoken(const char *ptr,unsigned int len, - int *valptr, - const char **names,int valid_bits) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - char *p2; - int msk; - *valptr = 0; - for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { - if (!msk & valid_bits) continue; - valid_bits &= ~msk; - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = msk; - return 0; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (*p2) return -EINVAL; - return 0; -} - - -static int parse_tlist(const char *ptr,unsigned int len, - int *maskptr,int *valptr, - const char **names,int valid_bits) -{ - unsigned int cnt; - int mask,val,kv,mode,ret; - mask = 0; - val = 0; - ret = 0; - while (len) { - cnt = 0; - while ((cnt < len) && - ((ptr[cnt] <= 32) || - (ptr[cnt] >= 127))) cnt++; - ptr += cnt; - len -= cnt; - mode = 0; - if ((*ptr == '-') || (*ptr == '+')) { - mode = (*ptr == '-') ? -1 : 1; - ptr++; - len--; - } - cnt = 0; - while (cnt < len) { - if (ptr[cnt] <= 32) break; - if (ptr[cnt] >= 127) break; - cnt++; - } - if (!cnt) break; - if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { - ret = -EINVAL; - break; - } - ptr += cnt; - len -= cnt; - switch (mode) { - case 0: - mask = valid_bits; - val |= kv; - break; - case -1: - mask |= kv; - val &= ~kv; - break; - case 1: - mask |= kv; - val |= kv; - break; - default: - break; - } - } - *maskptr = mask; - *valptr = val; - return ret; -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, - const char *ptr,unsigned int len, - int *maskptr,int *valptr) -{ - int ret = -EINVAL; - unsigned int cnt; - - *maskptr = 0; - *valptr = 0; - - cnt = 0; - while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; - len -= cnt; ptr += cnt; - cnt = 0; - while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || - (ptr[len-(cnt+1)] >= 127))) cnt++; - len -= cnt; - - if (!len) return -EINVAL; - - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = parse_token(ptr,len,valptr,0,0); - if ((ret >= 0) && - ((*valptr < cptr->info->def.type_int.min_value) || - (*valptr > cptr->info->def.type_int.max_value))) { - ret = -ERANGE; - } - if (maskptr) *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bool) { - ret = parse_token( - ptr,len,valptr,boolNames, - sizeof(boolNames)/sizeof(boolNames[0])); - if (ret == 1) { - *valptr = *valptr ? !0 : 0; - } else if (ret == 0) { - *valptr = (*valptr & 1) ? !0 : 0; - } - if (maskptr) *maskptr = 1; - } else if (cptr->info->type == pvr2_ctl_enum) { - ret = parse_token( - ptr,len,valptr, - cptr->info->def.type_enum.value_names, - cptr->info->def.type_enum.count); - if ((ret >= 0) && - ((*valptr < 0) || - (*valptr >= cptr->info->def.type_enum.count))) { - ret = -ERANGE; - } - if (maskptr) *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bitmask) { - ret = parse_tlist( - ptr,len,maskptr,valptr, - cptr->info->def.type_bitmask.bit_names, - cptr->info->def.type_bitmask.valid_bits); - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret = -EINVAL; - - *len = 0; - if (cptr->info->type == pvr2_ctl_int) { - *len = scnprintf(buf,maxlen,"%d",val); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_bool) { - *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_enum) { - const char **names; - names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { - if (names[val]) { - *len = scnprintf( - buf,maxlen,"%s", - names[val]); - } else { - *len = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - *len = gen_bitmask_string( - val & mask & cptr->info->def.type_bitmask.valid_bits, - ~0,!0, - cptr->info->def.type_bitmask.bit_names, - buf,maxlen); - } - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, - buf,maxlen,len); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h deleted file mode 100644 index c1680053cd64..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_CTRL_H -#define __PVRUSB2_CTRL_H - -struct pvr2_ctrl; - -enum pvr2_ctl_type { - pvr2_ctl_int = 0, - pvr2_ctl_enum = 1, - pvr2_ctl_bitmask = 2, - pvr2_ctl_bool = 3, -}; - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val); - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val); - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr); - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *); - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *); - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *); - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *); - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *); - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *); - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *); - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int, - unsigned int *); - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *); - -/* Return V4L flags value for control (or zero if there is no v4l control - actually under this control) */ -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *); - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *); - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *); - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value - must already be - inside of critical region. */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -#endif /* __PVRUSB2_CTRL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c deleted file mode 100644 index 27eadaff75a0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - - This source file is specifically designed to interface with the - cx2584x, in kernels 2.6.16 or newer. - -*/ - -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -struct pvr2_v4l_cx2584x { - struct pvr2_i2c_handler handler; - struct pvr2_decoder_ctrl ctrl; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - - memset(&route,0,sizeof(route)); - - switch(hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - vid_input = CX25840_COMPOSITE7; - aud_input = CX25840_AUDIO8; - break; - case PVR2_CVAL_INPUT_COMPOSITE: - vid_input = CX25840_COMPOSITE3; - aud_input = CX25840_AUDIO_SERIAL; - break; - case PVR2_CVAL_INPUT_SVIDEO: - vid_input = CX25840_SVIDEO1; - aud_input = CX25840_AUDIO_SERIAL; - break; - case PVR2_CVAL_INPUT_RADIO: - default: - // Just set it to be composite input for now... - vid_input = CX25840_COMPOSITE3; - aud_input = CX25840_AUDIO_SERIAL; - break; - } - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", - vid_input,aud_input); - route.input = (u32)vid_input; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); - route.input = (u32)aud_input; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - - -static int check_input(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -static void set_audio(struct pvr2_v4l_cx2584x *ctxt) -{ - u32 val; - struct pvr2_hdw *hdw = ctxt->hdw; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); -} - - -static int check_audio(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->srate_dirty != 0; -} - - -struct pvr2_v4l_cx2584x_ops { - void (*update)(struct pvr2_v4l_cx2584x *); - int (*check)(struct pvr2_v4l_cx2584x *); -}; - - -static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { - { .update = set_input, .check = check_input}, - { .update = set_audio, .check = check_audio}, -}; - - -static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->decoder_ctrl = 0; - kfree(ctxt); -} - - -static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (decoder_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - decoder_ops[idx].update(ctxt); - } -} - - -static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl); - pvr2_v4l2_cmd_stream(ctxt->client,fl); -} - - -static int decoder_detect(struct pvr2_i2c_client *cp) -{ - int ret; - /* Attempt to query the decoder - let's see if it will answer */ - struct v4l2_queryctrl qc; - - memset(&qc,0,sizeof(qc)); - - qc.id = V4L2_CID_BRIGHTNESS; - - ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc); - return ret == 0; /* Return true if it answered */ -} - - -static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt) -{ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (ret < 0) return -EINVAL; - return vt.signal ? 1 : 0; -} - - -static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l"); -} - - -static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) -{ - int ret; - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))decoder_detach, - .check = (int (*)(void *))decoder_check, - .update = (void (*)(void *))decoder_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, -}; - - -int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, - struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_cx2584x *ctxt; - - if (hdw->decoder_ctrl) return 0; - if (cp->handler) return 0; - if (!decoder_detect(cp)) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->ctrl.ctxt = ctxt; - ctxt->ctrl.detach = (void (*)(void *))decoder_detach; - ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; - ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; - ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ - sizeof(decoder_ops[0]))) - 1; - hdw->decoder_ctrl = &ctxt->ctrl; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h deleted file mode 100644 index 54b2844e7a71..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_CX2584X_V4L_H -#define __PVRUSB2_CX2584X_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles combined device audio & video processing. - This interface is used internally by the driver; higher level code - should only interact through the interface provided by - pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_CX2584X_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h deleted file mode 100644 index d95a8588e4f8..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEBUG_H -#define __PVRUSB2_DEBUG_H - -extern int pvrusb2_debug; - -#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0) - -/* These are listed in *rough* order of decreasing usefulness and - increasing noise level. */ -#define PVR2_TRACE_INFO (1 << 0) // Normal messages -#define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages -#define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors -#define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app -#define PVR2_TRACE_INIT (1 << 4) // misc initialization steps -#define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop -#define PVR2_TRACE_CTL (1 << 6) // commit of control changes -#define PVR2_TRACE_DEBUG (1 << 7) // Temporary debug code -#define PVR2_TRACE_EEPROM (1 << 8) // eeprom parsing / report -#define PVR2_TRACE_STRUCT (1 << 9) // internal struct creation -#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close -#define PVR2_TRACE_CREG (1 << 11) // Main critical region entry / exit -#define PVR2_TRACE_SYSFS (1 << 12) // Sysfs driven I/O -#define PVR2_TRACE_FIRMWARE (1 << 13) // firmware upload actions -#define PVR2_TRACE_CHIPS (1 << 14) // chip broadcast operation -#define PVR2_TRACE_I2C (1 << 15) // I2C related stuff -#define PVR2_TRACE_I2C_CMD (1 << 16) // Software commands to I2C modules -#define PVR2_TRACE_I2C_CORE (1 << 17) // I2C core debugging -#define PVR2_TRACE_I2C_TRAF (1 << 18) // I2C traffic through the adapter -#define PVR2_TRACE_V4LIOCTL (1 << 19) // v4l ioctl details -#define PVR2_TRACE_ENCODER (1 << 20) // mpeg2 encoder operation -#define PVR2_TRACE_BUF_POOL (1 << 21) // Track buffer pool management -#define PVR2_TRACE_BUF_FLOW (1 << 22) // Track buffer flow in system -#define PVR2_TRACE_DATA_FLOW (1 << 23) // Track data flow -#define PVR2_TRACE_DEBUGIFC (1 << 24) // Debug interface actions -#define PVR2_TRACE_GPIO (1 << 25) // GPIO state bit changes - - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c deleted file mode 100644 index 586900e365ff..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include "pvrusb2-debugifc.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-i2c-core.h" - -struct debugifc_mask_item { - const char *name; - unsigned long msk; -}; - -static struct debugifc_mask_item mask_items[] = { - {"ENC_FIRMWARE",(1<= 2) && (buf[0] == '0') && - ((buf[1] == 'x') || (buf[1] == 'X'))) { - radix = 16; - count -= 2; - buf += 2; - } else if ((count >= 1) && (buf[0] == '0')) { - radix = 8; - } - - while (count--) { - ch = *buf++; - if ((ch >= '0') && (ch <= '9')) { - val = ch - '0'; - } else if ((ch >= 'a') && (ch <= 'f')) { - val = ch - 'a' + 10; - } else if ((ch >= 'A') && (ch <= 'F')) { - val = ch - 'A' + 10; - } else { - return -EINVAL; - } - if (val >= radix) return -EINVAL; - result *= radix; - result += val; - } - *num_ptr = result; - return 0; -} - - -static int debugifc_match_keyword(const char *buf,unsigned int count, - const char *keyword) -{ - unsigned int kl; - if (!keyword) return 0; - kl = strlen(keyword); - if (kl != count) return 0; - return !memcmp(buf,keyword,kl); -} - - -static unsigned long debugifc_find_mask(const char *buf,unsigned int count) -{ - struct debugifc_mask_item *mip; - unsigned int idx; - for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { - mip = mask_items + idx; - if (debugifc_match_keyword(buf,count,mip->name)) { - return mip->msk; - } - } - return 0; -} - - -static int debugifc_print_mask(char *buf,unsigned int sz, - unsigned long msk,unsigned long val) -{ - struct debugifc_mask_item *mip; - unsigned int idx; - int bcnt = 0; - int ccnt; - for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { - mip = mask_items + idx; - if (!(mip->msk & msk)) continue; - ccnt = scnprintf(buf,sz,"%s%c%s", - (bcnt ? " " : ""), - ((mip->msk & val) ? '+' : '-'), - mip->name); - sz -= ccnt; - buf += ccnt; - bcnt += ccnt; - } - return bcnt; -} - -static unsigned int debugifc_parse_subsys_mask(const char *buf, - unsigned int count, - unsigned long *mskPtr, - unsigned long *valPtr) -{ - const char *wptr; - unsigned int consume_cnt = 0; - unsigned int scnt; - unsigned int wlen; - int mode; - unsigned long m1,msk,val; - - msk = 0; - val = 0; - - while (count) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) break; - consume_cnt += scnt; count -= scnt; buf += scnt; - if (!wptr) break; - - mode = 0; - if (wlen) switch (wptr[0]) { - case '+': - wptr++; - wlen--; - break; - case '-': - mode = 1; - wptr++; - wlen--; - break; - } - if (!wlen) continue; - m1 = debugifc_find_mask(wptr,wlen); - if (!m1) break; - msk |= m1; - if (!mode) val |= m1; - } - *mskPtr = msk; - *valPtr = val; - return consume_cnt; -} - - -int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - struct pvr2_hdw_debug_info dbg; - - pvr2_hdw_get_debug_info(hdw,&dbg); - - ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s", - (dbg.big_lock_held ? "held" : "free"), - (dbg.ctl_lock_held ? "held" : "free")); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - if (dbg.ctl_lock_held) { - ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d" - " cmd_wlen=%d cmd_rlen=%d" - " wpend=%d rpend=%d tmout=%d rstatus=%d" - " wstatus=%d", - dbg.cmd_debug_state,dbg.cmd_code, - dbg.cmd_debug_write_len, - dbg.cmd_debug_read_len, - dbg.cmd_debug_write_pend, - dbg.cmd_debug_read_pend, - dbg.cmd_debug_timeout, - dbg.cmd_debug_rstatus, - dbg.cmd_debug_wstatus); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - } - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf( - buf,acnt,"driver flags: %s %s %s\n", - (dbg.flag_init_ok ? "initialized" : "uninitialized"), - (dbg.flag_ok ? "ok" : "fail"), - (dbg.flag_disconnected ? "disconnected" : "connected")); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = pvr2_i2c_report(hdw,buf,acnt); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - return bcnt; -} - - -int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, - char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - unsigned long msk; - int ret; - u32 gpio_dir,gpio_in,gpio_out; - - ret = pvr2_hdw_is_hsm(hdw); - ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", - (ret < 0 ? "FAIL" : (ret ? "high" : "full"))); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - gpio_dir = 0; gpio_in = 0; gpio_out = 0; - pvr2_hdw_gpio_get_dir(hdw,&gpio_dir); - pvr2_hdw_gpio_get_out(hdw,&gpio_out); - pvr2_hdw_gpio_get_in(hdw,&gpio_in); - ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n", - gpio_dir,gpio_in,gpio_out); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - ccnt = scnprintf(buf,acnt,"Streaming is %s\n", - pvr2_hdw_get_streaming(hdw) ? "on" : "off"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - msk = pvr2_hdw_subsys_get(hdw); - ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,~msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - msk = pvr2_hdw_subsys_stream_get(hdw); - ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - return bcnt; -} - - -int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - const char *wptr; - unsigned int wlen; - unsigned int scnt; - - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return 0; - count -= scnt; buf += scnt; - if (!wptr) return 0; - - pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr); - if (debugifc_match_keyword(wptr,wlen,"reset")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"cpu")) { - pvr2_hdw_cpureset_assert(hdw,!0); - pvr2_hdw_cpureset_assert(hdw,0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"bus")) { - pvr2_hdw_device_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"soft")) { - return pvr2_hdw_cmd_powerup(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"deep")) { - return pvr2_hdw_cmd_deep_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { - return pvr2_upload_firmware2(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { - return pvr2_hdw_cmd_decoder_reset(hdw); - } - return -EINVAL; - } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) { - unsigned long msk = 0; - unsigned long val = 0; - if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc parse error on subsys mask"); - return -EINVAL; - } - pvr2_hdw_subsys_bit_chg(hdw,msk,val); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) { - unsigned long msk = 0; - unsigned long val = 0; - if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc parse error on stream mask"); - return -EINVAL; - } - pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"fetch")) { - pvr2_hdw_cpufw_set_enabled(hdw,!0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"done")) { - pvr2_hdw_cpufw_set_enabled(hdw,0); - return 0; - } else { - return -EINVAL; - } - } else if (debugifc_match_keyword(wptr,wlen,"gpio")) { - int dir_fl = 0; - int ret; - u32 msk,val; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"dir")) { - dir_fl = !0; - } else if (!debugifc_match_keyword(wptr,wlen,"out")) { - return -EINVAL; - } - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - ret = debugifc_parse_unsigned_number(wptr,wlen,&msk); - if (ret) return ret; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (wptr) { - ret = debugifc_parse_unsigned_number(wptr,wlen,&val); - if (ret) return ret; - } else { - val = msk; - msk = 0xffffffff; - } - if (dir_fl) { - ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val); - } else { - ret = pvr2_hdw_gpio_chg_out(hdw,msk,val); - } - return ret; - } - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr); - return -EINVAL; -} - - -int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - unsigned int bcnt = 0; - int ret; - - while (count) { - for (bcnt = 0; bcnt < count; bcnt++) { - if (buf[bcnt] == '\n') break; - } - - ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt); - if (ret < 0) return ret; - if (bcnt < count) bcnt++; - buf += bcnt; - count -= bcnt; - } - - return 0; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h deleted file mode 100644 index 990b02d35d36..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEBUGIFC_H -#define __PVRUSB2_DEBUGIFC_H - -struct pvr2_hdw; - -/* Non-intrusively print some useful debugging info from inside the - driver. This should work even if the driver appears to be - wedged. */ -int pvr2_debugifc_print_info(struct pvr2_hdw *, - char *buf_ptr,unsigned int buf_size); - -/* Print general status of driver. This will also trigger a probe of - the USB link. Unlike print_info(), this one synchronizes with the - driver so the information should be self-consistent (but it will - hang if the driver is wedged). */ -int pvr2_debugifc_print_status(struct pvr2_hdw *, - char *buf_ptr,unsigned int buf_size); - -/* Parse a string command into a driver action. */ -int pvr2_debugifc_docmd(struct pvr2_hdw *, - const char *buf_ptr,unsigned int buf_size); - -#endif /* __PVRUSB2_DEBUGIFC_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c deleted file mode 100644 index 9686569a11f6..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2.h" -#include "pvrusb2-util.h" -#include "pvrusb2-demod.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - - -struct pvr2_demod_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - int type_update_fl; -}; - - -static void set_config(struct pvr2_demod_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - int cfg = 0; - - switch (hdw->tuner_type) { - case TUNER_PHILIPS_FM1216ME_MK3: - case TUNER_PHILIPS_FM1236_MK3: - cfg = TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE; - break; - default: - break; - } - pvr2_trace(PVR2_TRACE_CHIPS,"i2c demod set_config(0x%x)",cfg); - pvr2_i2c_client_cmd(ctxt->client,TDA9887_SET_CONFIG,&cfg); - ctxt->type_update_fl = 0; -} - - -static int demod_check(struct pvr2_demod_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - if (hdw->tuner_updated) ctxt->type_update_fl = !0; - return ctxt->type_update_fl != 0; -} - - -static void demod_update(struct pvr2_demod_handler *ctxt) -{ - if (ctxt->type_update_fl) set_config(ctxt); -} - - -static void demod_detach(struct pvr2_demod_handler *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static unsigned int demod_describe(struct pvr2_demod_handler *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-demod"); -} - - -const static struct pvr2_i2c_handler_functions tuner_funcs = { - .detach = (void (*)(void *))demod_detach, - .check = (int (*)(void *))demod_check, - .update = (void (*)(void *))demod_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))demod_describe, -}; - - -int pvr2_i2c_demod_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_demod_handler *ctxt; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &tuner_funcs; - ctxt->type_update_fl = !0; - ctxt->client = cp; - ctxt->hdw = hdw; - cp->handler = &ctxt->i2c_handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tda9887 V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h deleted file mode 100644 index 4c4e40ffbf03..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEMOD_H -#define __PVRUSB2_DEMOD_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_demod_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_DEMOD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c deleted file mode 100644 index 94d383ff9889..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - -#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) - - - -/* - - Read and analyze data in the eeprom. Use tveeprom to figure out - the packet structure, since this is another Hauppauge device and - internally it has a family resemblence to ivtv-type devices - -*/ - -#include - -/* We seem to only be interested in the last 128 bytes of the EEPROM */ -#define EEPROM_SIZE 128 - -/* Grab EEPROM contents, needed for direct method. */ -static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[2]; - u8 *eeprom; - u8 iadd[2]; - u8 addr; - u16 eepromSize; - unsigned int offs; - int ret; - int mode16 = 0; - unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); - if (!eeprom) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); - return 0; - } - - trace_eeprom("Value for eeprom addr from controller was 0x%x", - hdw->eeprom_addr); - addr = hdw->eeprom_addr; - /* Seems that if the high bit is set, then the *real* eeprom - address is shifted right now bit position (noticed this in - newer PVR USB2 hardware) */ - if (addr & 0x80) addr >>= 1; - - /* FX2 documentation states that a 16bit-addressed eeprom is - expected if the I2C address is an odd number (yeah, this is - strange but it's what they do) */ - mode16 = (addr & 1); - eepromSize = (mode16 ? 4096 : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, - mode16 ? 16 : 8); - - msg[0].addr = addr; - msg[0].flags = 0; - msg[0].len = mode16 ? 2 : 1; - msg[0].buf = iadd; - msg[1].addr = addr; - msg[1].flags = I2C_M_RD; - - /* We have to do the actual eeprom data fetch ourselves, because - (1) we're only fetching part of the eeprom, and (2) if we were - getting the whole thing our I2C driver can't grab it in one - pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); - for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { - pcnt = 16; - if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + (eepromSize - EEPROM_SIZE); - if (mode16) { - iadd[0] = offs >> 8; - iadd[1] = offs; - } else { - iadd[0] = offs; - } - msg[1].len = pcnt; - msg[1].buf = eeprom+tcnt; - if ((ret = i2c_transfer( - &hdw->i2c_adap, - msg,sizeof(msg)/sizeof(msg[0]))) != 2) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "eeprom fetch set offs err=%d",ret); - kfree(eeprom); - return 0; - } - } - return eeprom; -} - - -/* Directly call eeprom analysis function within tveeprom. */ -int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) -{ - u8 *eeprom; - struct tveeprom tvdata; - - memset(&tvdata,0,sizeof(tvdata)); - - eeprom = pvr2_eeprom_fetch(hdw); - if (!eeprom) return -EINVAL; - - { - struct i2c_client fake_client; - /* Newer version expects a useless client interface */ - fake_client.addr = hdw->eeprom_addr; - fake_client.adapter = &hdw->i2c_adap; - tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); - } - - trace_eeprom("eeprom assumed v4l tveeprom module"); - trace_eeprom("eeprom direct call results:"); - trace_eeprom("has_radio=%d",tvdata.has_radio); - trace_eeprom("tuner_type=%d",tvdata.tuner_type); - trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats); - trace_eeprom("audio_processor=%d",tvdata.audio_processor); - trace_eeprom("model=%d",tvdata.model); - trace_eeprom("revision=%d",tvdata.revision); - trace_eeprom("serial_number=%d",tvdata.serial_number); - trace_eeprom("rev_str=%s",tvdata.rev_str); - hdw->tuner_type = tvdata.tuner_type; - hdw->serial_number = tvdata.serial_number; - hdw->std_mask_eeprom = tvdata.tuner_formats; - - kfree(eeprom); - - return 0; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h deleted file mode 100644 index 84242975dea7..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_EEPROM_H -#define __PVRUSB2_EEPROM_H - -struct pvr2_hdw; - -int pvr2_eeprom_analyze(struct pvr2_hdw *); - -#endif /* __PVRUSB2_EEPROM_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c deleted file mode 100644 index 2cc31695b435..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include // for linux/firmware.h -#include -#include "pvrusb2-util.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - - - -/* Firmware mailbox flags - definitions found from ivtv */ -#define IVTV_MBOX_FIRMWARE_DONE 0x00000004 -#define IVTV_MBOX_DRIVER_DONE 0x00000002 -#define IVTV_MBOX_DRIVER_BUSY 0x00000001 - - -static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, - const u32 *data, unsigned int dlen) -{ - unsigned int idx; - int ret; - unsigned int offs = 0; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x01. Remaining 32 bit words are - spread out into chunks of 7 bytes each, little-endian ordered, - offset at zero within each 2 blank bytes following and a - single byte that is 0x44 plus the offset of the word. Repeat - request for additional words, with offset adjusted - accordingly. - - */ - while (dlen) { - chunkCnt = 8; - if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = 0x01; - for (idx = 0; idx < chunkCnt; idx++) { - hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs; - PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7), - data[idx]); - } - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,1+(chunkCnt*7), - 0,0); - if (ret) return ret; - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl, - u32 *data, unsigned int dlen) -{ - unsigned int idx; - int ret; - unsigned int offs = 0; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x02 (status check) or 0x28 (read - back block of 32 bit words). Next 6 bytes must be zero, - followed by a single byte of 0x44+offset for portion to be - read. Returned data is packed set of 32 bits words that were - read. - - */ - - while (dlen) { - chunkCnt = 16; - if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28; - hdw->cmd_buffer[7] = 0x44 + offs; - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,8, - hdw->cmd_buffer,chunkCnt * 4); - if (ret) return ret; - - for (idx = 0; idx < chunkCnt; idx++) { - data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4); - } - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -/* This prototype is set up to be compatible with the - cx2341x_mbox_func prototype in cx2341x.h, which should be in - kernels 2.6.18 or later. We do this so that we can enable - cx2341x.ko to write to our encoder (by handing it a pointer to this - function). For earlier kernels this doesn't really matter. */ -static int pvr2_encoder_cmd(void *ctxt, - int cmd, - int arg_cnt_send, - int arg_cnt_recv, - u32 *argp) -{ - unsigned int poll_count; - int ret = 0; - unsigned int idx; - /* These sizes look to be limited by the FX2 firmware implementation */ - u32 wrData[16]; - u32 rdData[16]; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt; - - - /* - - The encoder seems to speak entirely using blocks 32 bit words. - In ivtv driver terms, this is a mailbox which we populate with - data and watch what the hardware does with it. The first word - is a set of flags used to control the transaction, the second - word is the command to execute, the third byte is zero (ivtv - driver suggests that this is some kind of return value), and - the fourth byte is a specified timeout (windows driver always - uses 0x00060000 except for one case when it is zero). All - successive words are the argument words for the command. - - First, write out the entire set of words, with the first word - being zero. - - Next, write out just the first word again, but set it to - IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which - probably means "go"). - - Next, read back 16 words as status. Check the first word, - which should have IVTV_MBOX_FIRMWARE_DONE set. If however - that bit is not set, then the command isn't done so repeat the - read. - - Next, read back 32 words and compare with the original - arugments. Hopefully they will match. - - Finally, write out just the first word again, but set it to - 0x0 this time (which probably means "idle"). - - */ - - if (arg_cnt_send > (sizeof(wrData)/sizeof(wrData[0]))-4) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many input arguments" - " (was given %u limit %u)", - arg_cnt_send, - (unsigned int)(sizeof(wrData)/sizeof(wrData[0])) - 4); - return -EINVAL; - } - - if (arg_cnt_recv > (sizeof(rdData)/sizeof(rdData[0]))-4) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many return arguments" - " (was given %u limit %u)", - arg_cnt_recv, - (unsigned int)(sizeof(rdData)/sizeof(rdData[0])) - 4); - return -EINVAL; - } - - - LOCK_TAKE(hdw->ctl_lock); do { - - wrData[0] = 0; - wrData[1] = cmd; - wrData[2] = 0; - wrData[3] = 0x00060000; - for (idx = 0; idx < arg_cnt_send; idx++) { - wrData[idx+4] = argp[idx]; - } - for (; idx < (sizeof(wrData)/sizeof(wrData[0]))-4; idx++) { - wrData[idx+4] = 0; - } - - ret = pvr2_encoder_write_words(hdw,wrData,idx); - if (ret) break; - wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY; - ret = pvr2_encoder_write_words(hdw,wrData,1); - if (ret) break; - poll_count = 0; - while (1) { - if (poll_count < 10000000) poll_count++; - ret = pvr2_encoder_read_words(hdw,!0,rdData,1); - if (ret) break; - if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) { - break; - } - if (poll_count == 100) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** device's encoder" - " appears to be stuck" - " (status=0%08x)",rdData[0]); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder command: 0x%02x",cmd); - for (idx = 4; idx < arg_cnt_send; idx++) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder arg%d: 0x%08x", - idx-3,wrData[idx]); - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up waiting." - " It is likely that" - " this is a bad idea..."); - ret = -EBUSY; - break; - } - } - if (ret) break; - wrData[0] = 0x7; - ret = pvr2_encoder_read_words( - hdw,0,rdData, - sizeof(rdData)/sizeof(rdData[0])); - if (ret) break; - for (idx = 0; idx < arg_cnt_recv; idx++) { - argp[idx] = rdData[idx+4]; - } - - wrData[0] = 0x0; - ret = pvr2_encoder_write_words(hdw,wrData,1); - if (ret) break; - - } while(0); LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, - int args, ...) -{ - va_list vl; - unsigned int idx; - u32 data[12]; - - if (args > sizeof(data)/sizeof(data[0])) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many arguments" - " (was given %u limit %u)", - args,(unsigned int)(sizeof(data)/sizeof(data[0]))); - return -EINVAL; - } - - va_start(vl, args); - for (idx = 0; idx < args; idx++) { - data[idx] = va_arg(vl, u32); - } - va_end(vl); - - return pvr2_encoder_cmd(hdw,cmd,args,0,data); -} - -int pvr2_encoder_configure(struct pvr2_hdw *hdw) -{ - int ret; - pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" - " (cx2341x module)"); - hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; - hdw->enc_ctl_state.width = hdw->res_hor_val; - hdw->enc_ctl_state.height = hdw->res_ver_val; - hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & - (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? - 0 : 1); - - ret = 0; - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, - 0xf0, 0xf0); - - /* setup firmware to notify us about some events (don't know why...) */ - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, - 0, 0, 0x10000000, 0xffffffff); - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_VBI_LINE, 5, - 0xffffffff,0,0,0,0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to configure cx32416"); - return ret; - } - - ret = cx2341x_update(hdw,pvr2_encoder_cmd, - (hdw->enc_cur_valid ? &hdw->enc_cur_state : 0), - &hdw->enc_ctl_state); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Error from cx2341x module code=%d",ret); - return ret; - } - - ret = 0; - - if (!ret) ret = pvr2_encoder_vcmd( - hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to initialize cx32416 video input"); - return ret; - } - - hdw->subsys_enabled_mask |= (1<enc_cur_state,&hdw->enc_ctl_state, - sizeof(struct cx2341x_mpeg_params)); - hdw->enc_cur_valid = !0; - return 0; -} - - -int pvr2_encoder_start(struct pvr2_hdw *hdw) -{ - int status; - - /* unmask some interrupts */ - pvr2_write_register(hdw, 0x0048, 0xbfffffff); - - /* change some GPIO data */ - pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481); - pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); - - if (hdw->config == pvr2_config_vbi) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0x01,0x14); - } else if (hdw->config == pvr2_config_mpeg) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - } else { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - } - if (!status) { - hdw->subsys_enabled_mask |= (1<config == pvr2_config_vbi) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0x01,0x14); - } else if (hdw->config == pvr2_config_mpeg) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - } else { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - } - - /* change some GPIO data */ - /* Note: Bit d7 of dir appears to control the LED. So we shut it - off here. */ - pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); - pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); - - if (!status) { - hdw->subsys_enabled_mask &= ~(1< - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_ENCODER_H -#define __PVRUSB2_ENCODER_H - -struct pvr2_hdw; - -int pvr2_encoder_configure(struct pvr2_hdw *); -int pvr2_encoder_start(struct pvr2_hdw *); -int pvr2_encoder_stop(struct pvr2_hdw *); - -#endif /* __PVRUSB2_ENCODER_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h deleted file mode 100644 index ba2afbfe32c5..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_HDW_INTERNAL_H -#define __PVRUSB2_HDW_INTERNAL_H - -/* - - This header sets up all the internal structures and definitions needed to - track and coordinate the driver's interaction with the hardware. ONLY - source files which actually implement part of that whole circus should be - including this header. Higher levels, like the external layers to the - various public APIs (V4L, sysfs, etc) should NOT ever include this - private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder, - etc will include this, but pvrusb2-v4l should not. - -*/ - -#include -#include -#include -#include -#include "pvrusb2-hdw.h" -#include "pvrusb2-io.h" -#include - -/* Legal values for the SRATE state variable */ -#define PVR2_CVAL_SRATE_48 0 -#define PVR2_CVAL_SRATE_44_1 1 - -/* Legal values for the AUDIOBITRATE state variable */ -#define PVR2_CVAL_AUDIOBITRATE_384 0 -#define PVR2_CVAL_AUDIOBITRATE_320 1 -#define PVR2_CVAL_AUDIOBITRATE_256 2 -#define PVR2_CVAL_AUDIOBITRATE_224 3 -#define PVR2_CVAL_AUDIOBITRATE_192 4 -#define PVR2_CVAL_AUDIOBITRATE_160 5 -#define PVR2_CVAL_AUDIOBITRATE_128 6 -#define PVR2_CVAL_AUDIOBITRATE_112 7 -#define PVR2_CVAL_AUDIOBITRATE_96 8 -#define PVR2_CVAL_AUDIOBITRATE_80 9 -#define PVR2_CVAL_AUDIOBITRATE_64 10 -#define PVR2_CVAL_AUDIOBITRATE_56 11 -#define PVR2_CVAL_AUDIOBITRATE_48 12 -#define PVR2_CVAL_AUDIOBITRATE_32 13 -#define PVR2_CVAL_AUDIOBITRATE_VBR 14 - -/* Legal values for the AUDIOEMPHASIS state variable */ -#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0 -#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1 -#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2 - -/* Legal values for PVR2_CID_HSM */ -#define PVR2_CVAL_HSM_FAIL 0 -#define PVR2_CVAL_HSM_FULL 1 -#define PVR2_CVAL_HSM_HIGH 2 - -#define PVR2_VID_ENDPOINT 0x84 -#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */ -#define PVR2_VBI_ENDPOINT 0x88 - -#define PVR2_CTL_BUFFSIZE 64 - -#define FREQTABLE_SIZE 500 - -#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) -#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) - -struct pvr2_decoder; - -typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); -typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); -typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *); -typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val); -typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val, - char *,unsigned int,unsigned int *); -typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *, - const char *,unsigned int, - int *mskp,int *valp); -typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *); - -/* This structure describes a specific control. A table of these is set up - in pvrusb2-hdw.c. */ -struct pvr2_ctl_info { - /* Control's name suitable for use as an identifier */ - const char *name; - - /* Short description of control */ - const char *desc; - - /* Control's implementation */ - pvr2_ctlf_get_value get_value; /* Get its value */ - pvr2_ctlf_set_value set_value; /* Set its value */ - pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */ - pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */ - pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */ - pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */ - pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */ - - /* Control's type (int, enum, bitmask) */ - enum pvr2_ctl_type type; - - /* Associated V4L control ID, if any */ - int v4l_id; - - /* Associated driver internal ID, if any */ - int internal_id; - - /* Don't implicitly initialize this control's value */ - int skip_init; - - /* Starting value for this control */ - int default_value; - - /* Type-specific control information */ - union { - struct { /* Integer control */ - long min_value; /* lower limit */ - long max_value; /* upper limit */ - } type_int; - struct { /* enumerated control */ - unsigned int count; /* enum value count */ - const char **value_names; /* symbol names */ - } type_enum; - struct { /* bitmask control */ - unsigned int valid_bits; /* bits in use */ - const char **bit_names; /* symbol name/bit */ - } type_bitmask; - } def; -}; - - -/* Same as pvr2_ctl_info, but includes storage for the control description */ -#define PVR2_CTLD_INFO_DESC_SIZE 32 -struct pvr2_ctld_info { - struct pvr2_ctl_info info; - char desc[PVR2_CTLD_INFO_DESC_SIZE]; -}; - -struct pvr2_ctrl { - const struct pvr2_ctl_info *info; - struct pvr2_hdw *hdw; -}; - - -struct pvr2_audio_stat { - void *ctxt; - void (*detach)(void *); - int (*status)(void *); -}; - -struct pvr2_decoder_ctrl { - void *ctxt; - void (*detach)(void *); - void (*enable)(void *,int); - int (*tuned)(void *); - void (*force_reset)(void *); -}; - -#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */ -#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */ -#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */ -#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */ - -#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\ - PVR2_I2C_PEND_CLIENT |\ - PVR2_I2C_PEND_REFRESH |\ - PVR2_I2C_PEND_STALE) - -/* Disposition of firmware1 loading situation */ -#define FW1_STATE_UNKNOWN 0 -#define FW1_STATE_MISSING 1 -#define FW1_STATE_FAILED 2 -#define FW1_STATE_RELOAD 3 -#define FW1_STATE_OK 4 - -/* Known major hardware variants, keyed from device ID */ -#define PVR2_HDW_TYPE_29XXX 0 -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -#define PVR2_HDW_TYPE_24XXX 1 -#endif - -typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); -#define PVR2_I2C_FUNC_CNT 128 - -/* This structure contains all state data directly needed to - manipulate the hardware (as opposed to complying with a kernel - interface) */ -struct pvr2_hdw { - /* Underlying USB device handle */ - struct usb_device *usb_dev; - struct usb_interface *usb_intf; - - /* Device type, one of PVR2_HDW_TYPE_xxxxx */ - unsigned int hdw_type; - - /* Video spigot */ - struct pvr2_stream *vid_stream; - - /* Mutex for all hardware state control */ - struct mutex big_lock_mutex; - int big_lock_held; /* For debugging */ - - void (*poll_trigger_func)(void *); - void *poll_trigger_data; - - char name[32]; - - /* I2C stuff */ - struct i2c_adapter i2c_adap; - struct i2c_algorithm i2c_algo; - pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; - int i2c_cx25840_hack_state; - int i2c_linked; - unsigned int i2c_pend_types; /* Which types of update are needed */ - unsigned long i2c_pend_mask; /* Change bits we need to scan */ - unsigned long i2c_stale_mask; /* Pending broadcast change bits */ - unsigned long i2c_active_mask; /* All change bits currently in use */ - struct list_head i2c_clients; - struct mutex i2c_list_lock; - - /* Frequency table */ - unsigned int freqTable[FREQTABLE_SIZE]; - unsigned int freqProgSlot; - unsigned int freqSlot; - - /* Stuff for handling low level control interaction with device */ - struct mutex ctl_lock_mutex; - int ctl_lock_held; /* For debugging */ - struct urb *ctl_write_urb; - struct urb *ctl_read_urb; - unsigned char *ctl_write_buffer; - unsigned char *ctl_read_buffer; - volatile int ctl_write_pend_flag; - volatile int ctl_read_pend_flag; - volatile int ctl_timeout_flag; - struct completion ctl_done; - unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE]; - int cmd_debug_state; // Low level command debugging info - unsigned char cmd_debug_code; // - unsigned int cmd_debug_write_len; // - unsigned int cmd_debug_read_len; // - - int flag_ok; // device in known good state - int flag_disconnected; // flag_ok == 0 due to disconnect - int flag_init_ok; // true if structure is fully initialized - int flag_streaming_enabled; // true if streaming should be on - int fw1_state; // current situation with fw1 - - int flag_decoder_is_tuned; - - struct pvr2_decoder_ctrl *decoder_ctrl; - - // CPU firmware info (used to help find / save firmware data) - char *fw_buffer; - unsigned int fw_size; - - // Which subsystem pieces have been enabled / configured - unsigned long subsys_enabled_mask; - - // Which subsystems are manipulated to enable streaming - unsigned long subsys_stream_mask; - - // True if there is a request to trigger logging of state in each - // module. - int log_requested; - - /* Tuner / frequency control stuff */ - unsigned int tuner_type; - int tuner_updated; - unsigned int freqVal; - int freqDirty; - - /* Video standard handling */ - v4l2_std_id std_mask_eeprom; // Hardware supported selections - v4l2_std_id std_mask_avail; // Which standards we may select from - v4l2_std_id std_mask_cur; // Currently selected standard(s) - unsigned int std_enum_cnt; // # of enumerated standards - int std_enum_cur; // selected standard enumeration value - int std_dirty; // True if std_mask_cur has changed - struct pvr2_ctl_info std_info_enum; - struct pvr2_ctl_info std_info_avail; - struct pvr2_ctl_info std_info_cur; - struct v4l2_standard *std_defs; - const char **std_enum_names; - - // Generated string names, one per actual V4L2 standard - const char *std_mask_ptrs[32]; - char std_mask_names[32][10]; - - int unit_number; /* ID for driver instance */ - unsigned long serial_number; /* ID for hardware itself */ - - /* Minor number used by v4l logic (yes, this is a hack, as there should - be no v4l junk here). Probably a better way to do this. */ - int v4l_minor_number; - - /* Location of eeprom or a negative number if none */ - int eeprom_addr; - - enum pvr2_config config; - - /* Information about what audio signal we're hearing */ - int flag_stereo; - int flag_bilingual; - struct pvr2_audio_stat *audio_stat; - - /* Control state needed for cx2341x module */ - struct cx2341x_mpeg_params enc_cur_state; - struct cx2341x_mpeg_params enc_ctl_state; - /* True if an encoder attribute has changed */ - int enc_stale; - /* True if enc_cur_state is valid */ - int enc_cur_valid; - - /* Control state */ -#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty - VCREATE_DATA(brightness); - VCREATE_DATA(contrast); - VCREATE_DATA(saturation); - VCREATE_DATA(hue); - VCREATE_DATA(volume); - VCREATE_DATA(balance); - VCREATE_DATA(bass); - VCREATE_DATA(treble); - VCREATE_DATA(mute); - VCREATE_DATA(input); - VCREATE_DATA(audiomode); - VCREATE_DATA(res_hor); - VCREATE_DATA(res_ver); - VCREATE_DATA(srate); -#undef VCREATE_DATA - - struct pvr2_ctld_info *mpeg_ctrl_info; - - struct pvr2_ctrl *controls; - unsigned int control_cnt; -}; - -int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); - -unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *); - -void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); -void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val); - -void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); -void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); - -int pvr2_i2c_basic_op(struct pvr2_hdw *,u8 i2c_addr, - u8 *wdata,u16 wlen, - u8 *rdata,u16 rlen); - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c deleted file mode 100644 index 643c471375da..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ /dev/null @@ -1,3120 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include "pvrusb2.h" -#include "pvrusb2-std.h" -#include "pvrusb2-util.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-debug.h" - -struct usb_device_id pvr2_device_table[] = { - [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, -#endif - { } -}; - -MODULE_DEVICE_TABLE(usb, pvr2_device_table); - -static const char *pvr2_device_names[] = { - [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx", -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx", -#endif -}; - -struct pvr2_string_table { - const char **lst; - unsigned int cnt; -}; - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -// Names of other client modules to request for 24xxx model hardware -static const char *pvr2_client_24xxx[] = { - "cx25840", - "tuner", - "tda9887", - "wm8775", -}; -#endif - -// Names of other client modules to request for 29xxx model hardware -static const char *pvr2_client_29xxx[] = { - "msp3400", - "saa7115", - "tuner", - "tda9887", -}; - -static struct pvr2_string_table pvr2_client_lists[] = { - [PVR2_HDW_TYPE_29XXX] = { - pvr2_client_29xxx, - sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]), - }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { - pvr2_client_24xxx, - sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]), - }, -#endif -}; - -static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; -DECLARE_MUTEX(pvr2_unit_sem); - -static int ctlchg = 0; -static int initusbreset = 1; -static int procreload = 0; -static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; -static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int init_pause_msec = 0; - -module_param(ctlchg, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); -module_param(init_pause_msec, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay"); -module_param(initusbreset, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe"); -module_param(procreload, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(procreload, - "Attempt init failure recovery with firmware reload"); -module_param_array(tuner, int, NULL, 0444); -MODULE_PARM_DESC(tuner,"specify installed tuner type"); -module_param_array(video_std, int, NULL, 0444); -MODULE_PARM_DESC(video_std,"specify initial video standard"); -module_param_array(tolerance, int, NULL, 0444); -MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); - -#define PVR2_CTL_WRITE_ENDPOINT 0x01 -#define PVR2_CTL_READ_ENDPOINT 0x81 - -#define PVR2_GPIO_IN 0x9008 -#define PVR2_GPIO_OUT 0x900c -#define PVR2_GPIO_DIR 0x9020 - -#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__) - -#define PVR2_FIRMWARE_ENDPOINT 0x02 - -/* size of a firmware chunk */ -#define FIRMWARE_CHUNK_SIZE 0x2000 - -/* Define the list of additional controls we'll dynamically construct based - on query of the cx2341x module. */ -struct pvr2_mpeg_ids { - const char *strid; - int id; -}; -static const struct pvr2_mpeg_ids mpeg_ids[] = { - { - .strid = "audio_layer", - .id = V4L2_CID_MPEG_AUDIO_ENCODING, - },{ - .strid = "audio_bitrate", - .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE, - },{ - /* Already using audio_mode elsewhere :-( */ - .strid = "mpeg_audio_mode", - .id = V4L2_CID_MPEG_AUDIO_MODE, - },{ - .strid = "mpeg_audio_mode_extension", - .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, - },{ - .strid = "audio_emphasis", - .id = V4L2_CID_MPEG_AUDIO_EMPHASIS, - },{ - .strid = "audio_crc", - .id = V4L2_CID_MPEG_AUDIO_CRC, - },{ - .strid = "video_aspect", - .id = V4L2_CID_MPEG_VIDEO_ASPECT, - },{ - .strid = "video_b_frames", - .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, - },{ - .strid = "video_gop_size", - .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, - },{ - .strid = "video_gop_closure", - .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - },{ - .strid = "video_pulldown", - .id = V4L2_CID_MPEG_VIDEO_PULLDOWN, - },{ - .strid = "video_bitrate_mode", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - },{ - .strid = "video_bitrate", - .id = V4L2_CID_MPEG_VIDEO_BITRATE, - },{ - .strid = "video_bitrate_peak", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - },{ - .strid = "video_temporal_decimation", - .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, - },{ - .strid = "stream_type", - .id = V4L2_CID_MPEG_STREAM_TYPE, - },{ - .strid = "video_spatial_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, - },{ - .strid = "video_spatial_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, - },{ - .strid = "video_luma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_chroma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_temporal_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, - },{ - .strid = "video_temporal_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, - },{ - .strid = "video_median_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, - },{ - .strid = "video_luma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_luma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, - },{ - .strid = "video_chroma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_chroma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, - } -}; -#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0])) - -static const char *control_values_srate[] = { - [PVR2_CVAL_SRATE_48] = "48KHz", - [PVR2_CVAL_SRATE_44_1] = "44.1KHz", -}; - - - - -static const char *control_values_input[] = { - [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ - [PVR2_CVAL_INPUT_RADIO] = "radio", - [PVR2_CVAL_INPUT_SVIDEO] = "s-video", - [PVR2_CVAL_INPUT_COMPOSITE] = "composite", -}; - - -static const char *control_values_audiomode[] = { - [V4L2_TUNER_MODE_MONO] = "Mono", - [V4L2_TUNER_MODE_STEREO] = "Stereo", - [V4L2_TUNER_MODE_LANG1] = "Lang1", - [V4L2_TUNER_MODE_LANG2] = "Lang2", - [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2", -}; - - -static const char *control_values_hsm[] = { - [PVR2_CVAL_HSM_FAIL] = "Fail", - [PVR2_CVAL_HSM_HIGH] = "High", - [PVR2_CVAL_HSM_FULL] = "Full", -}; - - -static const char *control_values_subsystem[] = { - [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware", - [PVR2_SUBSYS_B_ENC_CFG] = "enc_config", - [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run", - [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run", - [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", -}; - - -static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { - *vp = hdw->freqTable[hdw->freqProgSlot-1]; - } else { - *vp = 0; - } - return 0; -} - -static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { - hdw->freqTable[hdw->freqProgSlot-1] = v; - } - return 0; -} - -static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqProgSlot; - return 0; -} - -static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((v >= 0) && (v <= FREQTABLE_SIZE)) { - hdw->freqProgSlot = v; - } - return 0; -} - -static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqSlot; - return 0; -} - -static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v) -{ - unsigned freq = 0; - struct pvr2_hdw *hdw = cptr->hdw; - hdw->freqSlot = v; - if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) { - freq = hdw->freqTable[hdw->freqSlot-1]; - } - if (freq && (freq != hdw->freqVal)) { - hdw->freqVal = freq; - hdw->freqDirty = !0; - } - return 0; -} - -static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqVal; - return 0; -} - -static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->freqDirty != 0; -} - -static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->freqDirty = 0; -} - -static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - hdw->freqVal = v; - hdw->freqDirty = !0; - hdw->freqSlot = 0; - return 0; -} - -static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->enc_stale != 0; -} - -static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->enc_stale = 0; -} - -static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) -{ - int ret; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, - VIDIOC_G_EXT_CTRLS); - if (ret) return ret; - *vp = c1.value; - return 0; -} - -static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) -{ - int ret; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - c1.value = v; - ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, - VIDIOC_S_EXT_CTRLS); - if (ret) return ret; - cptr->hdw->enc_stale = !0; - return 0; -} - -static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) -{ - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *info; - qctrl.id = cptr->info->v4l_id; - cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); - /* Strip out the const so we can adjust a function pointer. It's - OK to do this here because we know this is a dynamically created - control, so the underlying storage for the info pointer is (a) - private to us, and (b) not in read-only storage. Either we do - this or we significantly complicate the underlying control - implementation. */ - info = (struct pvr2_ctl_info *)(cptr->info); - if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { - if (info->set_value) { - info->set_value = 0; - } - } else { - if (!(info->set_value)) { - info->set_value = ctrl_cx2341x_set; - } - } - return qctrl.flags; -} - -static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->flag_streaming_enabled; - return 0; -} - -static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp) -{ - int result = pvr2_hdw_is_hsm(cptr->hdw); - *vp = PVR2_CVAL_HSM_FULL; - if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; - if (result) *vp = PVR2_CVAL_HSM_HIGH; - return 0; -} - -static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_avail; - return 0; -} - -static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_avail; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_avail) return 0; - hdw->std_mask_avail = ns; - pvr2_hdw_internal_set_std_avail(hdw); - pvr2_hdw_internal_find_stdenum(hdw); - return 0; -} - -static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, - char *bufPtr,unsigned int bufSize, - unsigned int *len) -{ - *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); - return 0; -} - -static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, - const char *bufPtr,unsigned int bufSize, - int *mskp,int *valp) -{ - int ret; - v4l2_std_id id; - ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); - if (ret < 0) return ret; - if (mskp) *mskp = id; - if (valp) *valp = id; - return 0; -} - -static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_cur; - return 0; -} - -static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_cur; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_cur) return 0; - hdw->std_mask_cur = ns; - hdw->std_dirty = !0; - pvr2_hdw_internal_find_stdenum(hdw); - return 0; -} - -static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_dirty != 0; -} - -static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->std_dirty = 0; -} - -static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & - PVR2_SIGNAL_OK) ? 1 : 0); - return 0; -} - -static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->subsys_enabled_mask; - return 0; -} - -static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v) -{ - pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); - return 0; -} - -static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->subsys_stream_mask; - return 0; -} - -static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v) -{ - pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); - return 0; -} - -static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if (v < 0) return -EINVAL; - if (v > hdw->std_enum_cnt) return -EINVAL; - hdw->std_enum_cur = v; - if (!v) return 0; - v--; - if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0; - hdw->std_mask_cur = hdw->std_defs[v].id; - hdw->std_dirty = !0; - return 0; -} - - -static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_enum_cur; - return 0; -} - - -static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_dirty != 0; -} - - -static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->std_dirty = 0; -} - - -#define DEFINT(vmin,vmax) \ - .type = pvr2_ctl_int, \ - .def.type_int.min_value = vmin, \ - .def.type_int.max_value = vmax - -#define DEFENUM(tab) \ - .type = pvr2_ctl_enum, \ - .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ - .def.type_enum.value_names = tab - -#define DEFBOOL \ - .type = pvr2_ctl_bool - -#define DEFMASK(msk,tab) \ - .type = pvr2_ctl_bitmask, \ - .def.type_bitmask.valid_bits = msk, \ - .def.type_bitmask.bit_names = tab - -#define DEFREF(vname) \ - .set_value = ctrl_set_##vname, \ - .get_value = ctrl_get_##vname, \ - .is_dirty = ctrl_isdirty_##vname, \ - .clear_dirty = ctrl_cleardirty_##vname - - -#define VCREATE_FUNCS(vname) \ -static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \ -{*vp = cptr->hdw->vname##_val; return 0;} \ -static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \ -{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \ -static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \ -{return cptr->hdw->vname##_dirty != 0;} \ -static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \ -{cptr->hdw->vname##_dirty = 0;} - -VCREATE_FUNCS(brightness) -VCREATE_FUNCS(contrast) -VCREATE_FUNCS(saturation) -VCREATE_FUNCS(hue) -VCREATE_FUNCS(volume) -VCREATE_FUNCS(balance) -VCREATE_FUNCS(bass) -VCREATE_FUNCS(treble) -VCREATE_FUNCS(mute) -VCREATE_FUNCS(input) -VCREATE_FUNCS(audiomode) -VCREATE_FUNCS(res_hor) -VCREATE_FUNCS(res_ver) -VCREATE_FUNCS(srate) - -#define MIN_FREQ 55250000L -#define MAX_FREQ 850000000L - -/* Table definition of all controls which can be manipulated */ -static const struct pvr2_ctl_info control_defs[] = { - { - .v4l_id = V4L2_CID_BRIGHTNESS, - .desc = "Brightness", - .name = "brightness", - .default_value = 128, - DEFREF(brightness), - DEFINT(0,255), - },{ - .v4l_id = V4L2_CID_CONTRAST, - .desc = "Contrast", - .name = "contrast", - .default_value = 68, - DEFREF(contrast), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_SATURATION, - .desc = "Saturation", - .name = "saturation", - .default_value = 64, - DEFREF(saturation), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_HUE, - .desc = "Hue", - .name = "hue", - .default_value = 0, - DEFREF(hue), - DEFINT(-128,127), - },{ - .v4l_id = V4L2_CID_AUDIO_VOLUME, - .desc = "Volume", - .name = "volume", - .default_value = 65535, - DEFREF(volume), - DEFINT(0,65535), - },{ - .v4l_id = V4L2_CID_AUDIO_BALANCE, - .desc = "Balance", - .name = "balance", - .default_value = 0, - DEFREF(balance), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_BASS, - .desc = "Bass", - .name = "bass", - .default_value = 0, - DEFREF(bass), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_TREBLE, - .desc = "Treble", - .name = "treble", - .default_value = 0, - DEFREF(treble), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_MUTE, - .desc = "Mute", - .name = "mute", - .default_value = 0, - DEFREF(mute), - DEFBOOL, - },{ - .desc = "Video Source", - .name = "input", - .internal_id = PVR2_CID_INPUT, - .default_value = PVR2_CVAL_INPUT_TV, - DEFREF(input), - DEFENUM(control_values_input), - },{ - .desc = "Audio Mode", - .name = "audio_mode", - .internal_id = PVR2_CID_AUDIOMODE, - .default_value = V4L2_TUNER_MODE_STEREO, - DEFREF(audiomode), - DEFENUM(control_values_audiomode), - },{ - .desc = "Horizontal capture resolution", - .name = "resolution_hor", - .internal_id = PVR2_CID_HRES, - .default_value = 720, - DEFREF(res_hor), - DEFINT(320,720), - },{ - .desc = "Vertical capture resolution", - .name = "resolution_ver", - .internal_id = PVR2_CID_VRES, - .default_value = 480, - DEFREF(res_ver), - DEFINT(200,625), - },{ - .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, - .desc = "Sample rate", - .name = "srate", - .default_value = PVR2_CVAL_SRATE_48, - DEFREF(srate), - DEFENUM(control_values_srate), - },{ - .desc = "Tuner Frequency (Hz)", - .name = "frequency", - .internal_id = PVR2_CID_FREQUENCY, - .default_value = 175250000L, - .set_value = ctrl_freq_set, - .get_value = ctrl_freq_get, - .is_dirty = ctrl_freq_is_dirty, - .clear_dirty = ctrl_freq_clear_dirty, - DEFINT(MIN_FREQ,MAX_FREQ), - },{ - .desc = "Channel", - .name = "channel", - .set_value = ctrl_channel_set, - .get_value = ctrl_channel_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Channel Program Frequency", - .name = "freq_table_value", - .set_value = ctrl_channelfreq_set, - .get_value = ctrl_channelfreq_get, - DEFINT(MIN_FREQ,MAX_FREQ), - },{ - .desc = "Channel Program ID", - .name = "freq_table_channel", - .set_value = ctrl_channelprog_set, - .get_value = ctrl_channelprog_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Streaming Enabled", - .name = "streaming_enabled", - .get_value = ctrl_streamingenabled_get, - DEFBOOL, - },{ - .desc = "USB Speed", - .name = "usb_speed", - .get_value = ctrl_hsm_get, - DEFENUM(control_values_hsm), - },{ - .desc = "Signal Present", - .name = "signal_present", - .get_value = ctrl_signal_get, - DEFBOOL, - },{ - .desc = "Video Standards Available Mask", - .name = "video_standard_mask_available", - .internal_id = PVR2_CID_STDAVAIL, - .skip_init = !0, - .get_value = ctrl_stdavail_get, - .set_value = ctrl_stdavail_set, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Video Standards In Use Mask", - .name = "video_standard_mask_active", - .internal_id = PVR2_CID_STDCUR, - .skip_init = !0, - .get_value = ctrl_stdcur_get, - .set_value = ctrl_stdcur_set, - .is_dirty = ctrl_stdcur_is_dirty, - .clear_dirty = ctrl_stdcur_clear_dirty, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Subsystem enabled mask", - .name = "debug_subsys_mask", - .skip_init = !0, - .get_value = ctrl_subsys_get, - .set_value = ctrl_subsys_set, - DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), - },{ - .desc = "Subsystem stream mask", - .name = "debug_subsys_stream_mask", - .skip_init = !0, - .get_value = ctrl_subsys_stream_get, - .set_value = ctrl_subsys_stream_set, - DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), - },{ - .desc = "Video Standard Name", - .name = "video_standard", - .internal_id = PVR2_CID_STDENUM, - .skip_init = !0, - .get_value = ctrl_stdenumcur_get, - .set_value = ctrl_stdenumcur_set, - .is_dirty = ctrl_stdenumcur_is_dirty, - .clear_dirty = ctrl_stdenumcur_clear_dirty, - .type = pvr2_ctl_enum, - } -}; - -#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) - - -const char *pvr2_config_get_name(enum pvr2_config cfg) -{ - switch (cfg) { - case pvr2_config_empty: return "empty"; - case pvr2_config_mpeg: return "mpeg"; - case pvr2_config_vbi: return "vbi"; - case pvr2_config_radio: return "radio"; - } - return ""; -} - - -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw) -{ - return hdw->usb_dev; -} - - -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) -{ - return hdw->serial_number; -} - - -struct pvr2_hdw *pvr2_hdw_find(int unit_number) -{ - if (unit_number < 0) return 0; - if (unit_number >= PVR_NUM) return 0; - return unit_pointers[unit_number]; -} - - -int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) -{ - return hdw->unit_number; -} - - -/* Attempt to locate one of the given set of files. Messages are logged - appropriate to what has been found. The return value will be 0 or - greater on success (it will be the index of the file name found) and - fw_entry will be filled in. Otherwise a negative error is returned on - failure. If the return value is -ENOENT then no viable firmware file - could be located. */ -static int pvr2_locate_firmware(struct pvr2_hdw *hdw, - const struct firmware **fw_entry, - const char *fwtypename, - unsigned int fwcount, - const char *fwnames[]) -{ - unsigned int idx; - int ret = -EINVAL; - for (idx = 0; idx < fwcount; idx++) { - ret = request_firmware(fw_entry, - fwnames[idx], - &hdw->usb_dev->dev); - if (!ret) { - trace_firmware("Located %s firmware: %s;" - " uploading...", - fwtypename, - fwnames[idx]); - return idx; - } - if (ret == -ENOENT) continue; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware fatal error with code=%d",ret); - return ret; - } - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device %s firmware" - " seems to be missing.", - fwtypename); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware files" - " in their proper location?"); - if (fwcount == 1) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate %s file %s", - fwtypename,fwnames[0]); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate" - " one of the following %s files:", - fwtypename); - for (idx = 0; idx < fwcount; idx++) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware: Failed to find %s", - fwnames[idx]); - } - } - return ret; -} - - -/* - * pvr2_upload_firmware1(). - * - * Send the 8051 firmware to the device. After the upload, arrange for - * device to re-enumerate. - * - * NOTE : the pointer to the firmware data given by request_firmware() - * is not suitable for an usb transaction. - * - */ -int pvr2_upload_firmware1(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = 0; - void *fw_ptr; - unsigned int pipe; - int ret; - u16 address; - static const char *fw_files_29xxx[] = { - "v4l-pvrusb2-29xxx-01.fw", - }; -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - static const char *fw_files_24xxx[] = { - "v4l-pvrusb2-24xxx-01.fw", - }; -#endif - static const struct pvr2_string_table fw_file_defs[] = { - [PVR2_HDW_TYPE_29XXX] = { - fw_files_29xxx, - sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), - }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { - fw_files_24xxx, - sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), - }, -#endif - }; - hdw->fw1_state = FW1_STATE_FAILED; // default result - - trace_firmware("pvr2_upload_firmware1"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", - fw_file_defs[hdw->hdw_type].cnt, - fw_file_defs[hdw->hdw_type].lst); - if (ret < 0) { - if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; - return ret; - } - - usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); - usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); - - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - - if (fw_entry->size != 0x2000){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); - release_firmware(fw_entry); - return -ENOMEM; - } - - fw_ptr = kmalloc(0x800, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - return -ENOMEM; - } - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes - chunk. */ - - ret = 0; - for(address = 0; address < fw_entry->size; address += 0x800) { - memcpy(fw_ptr, fw_entry->data + address, 0x800); - ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, - 0, fw_ptr, 0x800, HZ); - } - - trace_firmware("Upload done, releasing device's CPU"); - - /* Now release the CPU. It will disconnect and reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - - kfree(fw_ptr); - release_firmware(fw_entry); - - trace_firmware("Upload done (%d bytes sent)",ret); - - /* We should have written 8192 bytes */ - if (ret == 8192) { - hdw->fw1_state = FW1_STATE_RELOAD; - return 0; - } - - return -EIO; -} - - -/* - * pvr2_upload_firmware2() - * - * This uploads encoder firmware on endpoint 2. - * - */ - -int pvr2_upload_firmware2(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = 0; - void *fw_ptr; - unsigned int pipe, fw_len, fw_done; - int actual_length; - int ret = 0; - int fwidx; - static const char *fw_files[] = { - CX2341X_FIRM_ENC_FILENAME, - }; - - trace_firmware("pvr2_upload_firmware2"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", - sizeof(fw_files)/sizeof(fw_files[0]), - fw_files); - if (ret < 0) return ret; - fwidx = ret; - ret = 0; - /* Since we're about to completely reinitialize the encoder, - invalidate our cached copy of its configuration state. Next - time we configure the encoder, then we'll fully configure it. */ - hdw->enc_cur_valid = 0; - - /* First prepare firmware loading */ - ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_hdw_cmd_deep_reset(hdw); - ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/ - ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/ - ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/ - ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/ - ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ - ret |= pvr2_write_u8(hdw, 0x52, 0); - ret |= pvr2_write_u16(hdw, 0x0600, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload prep failed, ret=%d",ret); - release_firmware(fw_entry); - return ret; - } - - /* Now send firmware */ - - fw_len = fw_entry->size; - - if (fw_len % FIRMWARE_CHUNK_SIZE) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "size of %s firmware" - " must be a multiple of 8192B", - fw_files[fwidx]); - release_firmware(fw_entry); - return -1; - } - - fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "failed to allocate memory for firmware2 upload"); - return -ENOMEM; - } - - pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); - - for (fw_done = 0 ; (fw_done < fw_len) && !ret ; - fw_done += FIRMWARE_CHUNK_SIZE ) { - int i; - memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE); - /* Usbsnoop log shows that we must swap bytes... */ - for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++) - ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]); - - ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr, - FIRMWARE_CHUNK_SIZE, - &actual_length, HZ); - ret |= (actual_length != FIRMWARE_CHUNK_SIZE); - } - - trace_firmware("upload of %s : %i / %i ", - fw_files[fwidx],fw_done,fw_len); - - kfree(fw_ptr); - release_firmware(fw_entry); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload transfer failure"); - return ret; - } - - /* Finish upload */ - - ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ - ret |= pvr2_write_u16(hdw, 0x0600, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload post-proc failure"); - } else { - hdw->subsys_enabled_mask |= (1<flag_ok) return; - - msk &= PVR2_SUBSYS_ALL; - nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk); - nmsk &= PVR2_SUBSYS_ALL; - - for (;;) { - tryCount++; - if (!((nmsk ^ hdw->subsys_enabled_mask) & - PVR2_SUBSYS_ALL)) break; - if (tryCount > 4) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Too many retries when configuring device;" - " giving up"); - pvr2_hdw_render_useless(hdw); - break; - } - if (tryCount > 1) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Retrying device reconfiguration"); - } - pvr2_trace(PVR2_TRACE_INIT, - "subsys mask changing 0x%lx:0x%lx" - " from 0x%lx to 0x%lx", - msk,val,hdw->subsys_enabled_mask,nmsk); - - vmsk = (nmsk ^ hdw->subsys_enabled_mask) & - hdw->subsys_enabled_mask; - if (vmsk) { - if (vmsk & (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - if (vmsk & (1<decoder_ctrl) { - hdw->decoder_ctrl->enable( - hdw->decoder_ctrl->ctxt,0); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " No decoder present"); - } - hdw->subsys_enabled_mask &= - ~(1<subsys_enabled_mask &= - ~(vmsk & PVR2_SUBSYS_CFG_ALL); - } - } - vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk; - if (vmsk) { - if (vmsk & (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - if (vmsk & (1<decoder_ctrl) { - hdw->decoder_ctrl->enable( - hdw->decoder_ctrl->ctxt,!0); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " No decoder present"); - } - hdw->subsys_enabled_mask |= - (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - } - } -} - - -void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk) -{ - pvr2_hdw_subsys_bit_chg(hdw,msk,msk); -} - - -void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk) -{ - pvr2_hdw_subsys_bit_chg(hdw,msk,0); -} - - -unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw) -{ - return hdw->subsys_enabled_mask; -} - - -unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw) -{ - return hdw->subsys_stream_mask; -} - - -void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) -{ - unsigned long val2; - msk &= PVR2_SUBSYS_ALL; - val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk)); - pvr2_trace(PVR2_TRACE_INIT, - "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx", - msk,val,hdw->subsys_stream_mask,val2); - hdw->subsys_stream_mask = val2; -} - - -void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl) -{ - if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0; - if (enableFl) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*--TRACE_STREAM--*/ enable"); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0); - } else { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*--TRACE_STREAM--*/ disable"); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); - } - if (!hdw->flag_ok) return -EIO; - hdw->flag_streaming_enabled = enableFl != 0; - return 0; -} - - -int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) -{ - return hdw->flag_streaming_enabled != 0; -} - - -int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) -{ - int ret; - LOCK_TAKE(hdw->big_lock); do { - ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag); - } while (0); LOCK_GIVE(hdw->big_lock); - return ret; -} - - -int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw, - enum pvr2_config config) -{ - unsigned long sm = hdw->subsys_enabled_mask; - if (!hdw->flag_ok) return -EIO; - pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); - hdw->config = config; - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm); - return 0; -} - - -int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) -{ - int ret; - if (!hdw->flag_ok) return -EIO; - LOCK_TAKE(hdw->big_lock); - ret = pvr2_hdw_set_stream_type_no_lock(hdw,config); - LOCK_GIVE(hdw->big_lock); - return ret; -} - - -static int get_default_tuner_type(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = -1; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tuner[unit_number]; - } - if (tp < 0) return -EINVAL; - hdw->tuner_type = tp; - return 0; -} - - -static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = video_std[unit_number]; - } - return tp; -} - - -static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tolerance[unit_number]; - } - return tp; -} - - -static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) -{ - /* Try a harmless request to fetch the eeprom's address over - endpoint 1. See what happens. Only the full FX2 image can - respond to this. If this probe fails then likely the FX2 - firmware needs be loaded. */ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; - result = pvr2_send_request_ex(hdw,HZ*1,!0, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - } while(0); LOCK_GIVE(hdw->ctl_lock); - if (result) { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 result status %d", - result); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 succeeded"); - } - return result == 0; -} - -static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) -{ - char buf[40]; - unsigned int bcnt; - v4l2_std_id std1,std2; - - std1 = get_default_standard(hdw); - - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); - pvr2_trace(PVR2_TRACE_INIT, - "Supported video standard(s) reported by eeprom: %.*s", - bcnt,buf); - - hdw->std_mask_avail = hdw->std_mask_eeprom; - - std2 = std1 & ~hdw->std_mask_avail; - if (std2) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); - pvr2_trace(PVR2_TRACE_INIT, - "Expanding supported video standards" - " to include: %.*s", - bcnt,buf); - hdw->std_mask_avail |= std2; - } - - pvr2_hdw_internal_set_std_avail(hdw); - - if (std1) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); - pvr2_trace(PVR2_TRACE_INIT, - "Initial video standard forced to %.*s", - bcnt,buf); - hdw->std_mask_cur = std1; - hdw->std_dirty = !0; - pvr2_hdw_internal_find_stdenum(hdw); - return; - } - - if (hdw->std_enum_cnt > 1) { - // Autoselect the first listed standard - hdw->std_enum_cur = 1; - hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id; - hdw->std_dirty = !0; - pvr2_trace(PVR2_TRACE_INIT, - "Initial video standard auto-selected to %s", - hdw->std_defs[hdw->std_enum_cur-1].name); - return; - } - - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to select a viable initial video standard"); -} - - -static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) -{ - int ret; - unsigned int idx; - struct pvr2_ctrl *cptr; - int reloadFl = 0; - if (!reloadFl) { - reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints - == 0); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "USB endpoint config looks strange" - "; possibly firmware needs to be loaded"); - } - } - if (!reloadFl) { - reloadFl = !pvr2_hdw_check_firmware(hdw); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "Check for FX2 firmware failed" - "; possibly firmware needs to be loaded"); - } - } - if (reloadFl) { - if (pvr2_upload_firmware1(hdw) != 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failure uploading firmware1"); - } - return; - } - hdw->fw1_state = FW1_STATE_OK; - - if (initusbreset) { - pvr2_hdw_device_reset(hdw); - } - if (!pvr2_hdw_dev_ok(hdw)) return; - - for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) { - request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]); - } - - pvr2_hdw_cmd_powerup(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - if (pvr2_upload_firmware2(hdw)){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); - pvr2_hdw_render_useless(hdw); - return; - } - - // This step MUST happen after the earlier powerup step. - pvr2_i2c_core_init(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - if (cptr->info->skip_init) continue; - if (!cptr->info->set_value) continue; - cptr->info->set_value(cptr,~0,cptr->info->default_value); - } - - // Do not use pvr2_reset_ctl_endpoints() here. It is not - // thread-safe against the normal pvr2_send_request() mechanism. - // (We should make it thread safe). - - ret = pvr2_hdw_get_eeprom_addr(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to determine location of eeprom, skipping"); - } else { - hdw->eeprom_addr = ret; - pvr2_eeprom_analyze(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - } - - pvr2_hdw_setup_std(hdw); - - if (!get_default_tuner_type(hdw)) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: Tuner type overridden to %d", - hdw->tuner_type); - } - - hdw->tuner_updated = !0; - pvr2_i2c_core_check_stale(hdw); - hdw->tuner_updated = 0; - - if (!pvr2_hdw_dev_ok(hdw)) return; - - pvr2_hdw_commit_ctl_internal(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->vid_stream = pvr2_stream_create(); - if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); - if (hdw->vid_stream) { - idx = get_default_error_tolerance(hdw); - if (idx) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream %p" - " setting tolerance %u", - hdw->vid_stream,idx); - } - pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, - PVR2_VID_ENDPOINT,idx); - } - - if (!pvr2_hdw_dev_ok(hdw)) return; - - /* Make sure everything is up to date */ - pvr2_i2c_core_sync(hdw); - - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->flag_init_ok = !0; -} - - -int pvr2_hdw_setup(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_setup_low(hdw); - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", - hdw,hdw->flag_ok,hdw->flag_init_ok); - if (pvr2_hdw_dev_ok(hdw)) { - if (pvr2_hdw_init_ok(hdw)) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device initialization" - " completed successfully."); - break; - } - if (hdw->fw1_state == FW1_STATE_RELOAD) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device microcontroller firmware" - " (re)loaded; it should now reset" - " and reconnect."); - break; - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Device initialization was not successful."); - if (hdw->fw1_state == FW1_STATE_MISSING) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up since device" - " microcontroller firmware" - " appears to be missing."); - break; - } - } - if (procreload) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempting pvrusb2 recovery by reloading" - " primary firmware."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "If this works, device should disconnect" - " and reconnect in a sane state."); - hdw->fw1_state = FW1_STATE_UNKNOWN; - pvr2_upload_firmware1(hdw); - } else { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 device hardware" - " appears to be jammed" - " and I can't clear it."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "You might need to power cycle" - " the pvrusb2 device" - " in order to recover."); - } - } while (0); LOCK_GIVE(hdw->big_lock); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); - return hdw->flag_init_ok; -} - - -/* Create and return a structure for interacting with the underlying - hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - unsigned int idx,cnt1,cnt2; - struct pvr2_hdw *hdw; - unsigned int hdw_type; - int valid_std_mask; - struct pvr2_ctrl *cptr; - __u8 ifnum; - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *ciptr; - - hdw_type = devid - pvr2_device_table; - if (hdw_type >= - sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Bogus device type of %u reported",hdw_type); - return 0; - } - - hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", - hdw,pvr2_device_names[hdw_type]); - if (!hdw) goto fail; - memset(hdw,0,sizeof(*hdw)); - cx2341x_fill_defaults(&hdw->enc_ctl_state); - - hdw->control_cnt = CTRLDEF_COUNT; - hdw->control_cnt += MPEGDEF_COUNT; - hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, - GFP_KERNEL); - if (!hdw->controls) goto fail; - memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt); - hdw->hdw_type = hdw_type; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - cptr->hdw = hdw; - } - for (idx = 0; idx < 32; idx++) { - hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx]; - } - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - cptr->info = control_defs+idx; - } - /* Define and configure additional controls from cx2341x module. */ - hdw->mpeg_ctrl_info = kmalloc( - sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); - if (!hdw->mpeg_ctrl_info) goto fail; - memset(hdw->mpeg_ctrl_info,0, - sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT); - for (idx = 0; idx < MPEGDEF_COUNT; idx++) { - cptr = hdw->controls + idx + CTRLDEF_COUNT; - ciptr = &(hdw->mpeg_ctrl_info[idx].info); - ciptr->desc = hdw->mpeg_ctrl_info[idx].desc; - ciptr->name = mpeg_ids[idx].strid; - ciptr->v4l_id = mpeg_ids[idx].id; - ciptr->skip_init = !0; - ciptr->get_value = ctrl_cx2341x_get; - ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags; - ciptr->is_dirty = ctrl_cx2341x_is_dirty; - if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty; - qctrl.id = ciptr->v4l_id; - cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl); - if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { - ciptr->set_value = ctrl_cx2341x_set; - } - strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, - PVR2_CTLD_INFO_DESC_SIZE); - hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; - ciptr->default_value = qctrl.default_value; - switch (qctrl.type) { - default: - case V4L2_CTRL_TYPE_INTEGER: - ciptr->type = pvr2_ctl_int; - ciptr->def.type_int.min_value = qctrl.minimum; - ciptr->def.type_int.max_value = qctrl.maximum; - break; - case V4L2_CTRL_TYPE_BOOLEAN: - ciptr->type = pvr2_ctl_bool; - break; - case V4L2_CTRL_TYPE_MENU: - ciptr->type = pvr2_ctl_enum; - ciptr->def.type_enum.value_names = - cx2341x_ctrl_get_menu(ciptr->v4l_id); - for (cnt1 = 0; - ciptr->def.type_enum.value_names[cnt1] != NULL; - cnt1++) { } - ciptr->def.type_enum.count = cnt1; - break; - } - cptr->info = ciptr; - } - - // Initialize video standard enum dynamic control - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); - if (cptr) { - memcpy(&hdw->std_info_enum,cptr->info, - sizeof(hdw->std_info_enum)); - cptr->info = &hdw->std_info_enum; - - } - // Initialize control data regarding video standard masks - valid_std_mask = pvr2_std_get_usable(); - for (idx = 0; idx < 32; idx++) { - if (!(valid_std_mask & (1 << idx))) continue; - cnt1 = pvr2_std_id_to_str( - hdw->std_mask_names[idx], - sizeof(hdw->std_mask_names[idx])-1, - 1 << idx); - hdw->std_mask_names[idx][cnt1] = 0; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); - if (cptr) { - memcpy(&hdw->std_info_avail,cptr->info, - sizeof(hdw->std_info_avail)); - cptr->info = &hdw->std_info_avail; - hdw->std_info_avail.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_avail.def.type_bitmask.valid_bits = - valid_std_mask; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR); - if (cptr) { - memcpy(&hdw->std_info_cur,cptr->info, - sizeof(hdw->std_info_cur)); - cptr->info = &hdw->std_info_cur; - hdw->std_info_cur.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_avail.def.type_bitmask.valid_bits = - valid_std_mask; - } - - hdw->eeprom_addr = -1; - hdw->unit_number = -1; - hdw->v4l_minor_number = -1; - hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_write_buffer) goto fail; - hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_read_buffer) goto fail; - hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_write_urb) goto fail; - hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_read_urb) goto fail; - - down(&pvr2_unit_sem); do { - for (idx = 0; idx < PVR_NUM; idx++) { - if (unit_pointers[idx]) continue; - hdw->unit_number = idx; - unit_pointers[idx] = hdw; - break; - } - } while (0); up(&pvr2_unit_sem); - - cnt1 = 0; - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); - cnt1 += cnt2; - if (hdw->unit_number >= 0) { - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c", - ('a' + hdw->unit_number)); - cnt1 += cnt2; - } - if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; - hdw->name[cnt1] = 0; - - pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", - hdw->unit_number,hdw->name); - - hdw->tuner_type = -1; - hdw->flag_ok = !0; - /* Initialize the mask of subsystems that we will shut down when we - stop streaming. */ - hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL; - hdw->subsys_stream_mask |= (1<subsys_stream_mask); - - hdw->usb_intf = intf; - hdw->usb_dev = interface_to_usbdev(intf); - - ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; - usb_set_interface(hdw->usb_dev,ifnum,0); - - mutex_init(&hdw->ctl_lock_mutex); - mutex_init(&hdw->big_lock_mutex); - - return hdw; - fail: - if (hdw) { - if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb); - if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb); - if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); - if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); - if (hdw->controls) kfree(hdw->controls); - if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); - kfree(hdw); - } - return 0; -} - - -/* Remove _all_ associations between this driver and the underlying USB - layer. */ -void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) -{ - if (hdw->flag_disconnected) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw); - if (hdw->ctl_read_urb) { - usb_kill_urb(hdw->ctl_read_urb); - usb_free_urb(hdw->ctl_read_urb); - hdw->ctl_read_urb = 0; - } - if (hdw->ctl_write_urb) { - usb_kill_urb(hdw->ctl_write_urb); - usb_free_urb(hdw->ctl_write_urb); - hdw->ctl_write_urb = 0; - } - if (hdw->ctl_read_buffer) { - kfree(hdw->ctl_read_buffer); - hdw->ctl_read_buffer = 0; - } - if (hdw->ctl_write_buffer) { - kfree(hdw->ctl_write_buffer); - hdw->ctl_write_buffer = 0; - } - pvr2_hdw_render_useless_unlocked(hdw); - hdw->flag_disconnected = !0; - hdw->usb_dev = 0; - hdw->usb_intf = 0; -} - - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); - if (hdw->fw_buffer) { - kfree(hdw->fw_buffer); - hdw->fw_buffer = 0; - } - if (hdw->vid_stream) { - pvr2_stream_destroy(hdw->vid_stream); - hdw->vid_stream = 0; - } - if (hdw->audio_stat) { - hdw->audio_stat->detach(hdw->audio_stat->ctxt); - } - if (hdw->decoder_ctrl) { - hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); - } - pvr2_i2c_core_done(hdw); - pvr2_hdw_remove_usb_stuff(hdw); - down(&pvr2_unit_sem); do { - if ((hdw->unit_number >= 0) && - (hdw->unit_number < PVR_NUM) && - (unit_pointers[hdw->unit_number] == hdw)) { - unit_pointers[hdw->unit_number] = 0; - } - } while (0); up(&pvr2_unit_sem); - if (hdw->controls) kfree(hdw->controls); - if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); - if (hdw->std_defs) kfree(hdw->std_defs); - if (hdw->std_enum_names) kfree(hdw->std_enum_names); - kfree(hdw); -} - - -int pvr2_hdw_init_ok(struct pvr2_hdw *hdw) -{ - return hdw->flag_init_ok; -} - - -int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) -{ - return (hdw && hdw->flag_ok); -} - - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); - LOCK_TAKE(hdw->big_lock); - LOCK_TAKE(hdw->ctl_lock); - pvr2_hdw_remove_usb_stuff(hdw); - LOCK_GIVE(hdw->ctl_lock); - LOCK_GIVE(hdw->big_lock); -} - - -// Attempt to autoselect an appropriate value for std_enum_cur given -// whatever is currently in std_mask_cur -void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw) -{ - unsigned int idx; - for (idx = 1; idx < hdw->std_enum_cnt; idx++) { - if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) { - hdw->std_enum_cur = idx; - return; - } - } - hdw->std_enum_cur = 0; -} - - -// Calculate correct set of enumerated standards based on currently known -// set of available standards bits. -void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw) -{ - struct v4l2_standard *newstd; - unsigned int std_cnt; - unsigned int idx; - - newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail); - - if (hdw->std_defs) { - kfree(hdw->std_defs); - hdw->std_defs = 0; - } - hdw->std_enum_cnt = 0; - if (hdw->std_enum_names) { - kfree(hdw->std_enum_names); - hdw->std_enum_names = 0; - } - - if (!std_cnt) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "WARNING: Failed to identify any viable standards"); - } - hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); - hdw->std_enum_names[0] = "none"; - for (idx = 0; idx < std_cnt; idx++) { - hdw->std_enum_names[idx+1] = - newstd[idx].name; - } - // Set up the dynamic control for this standard - hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; - hdw->std_info_enum.def.type_enum.count = std_cnt+1; - hdw->std_defs = newstd; - hdw->std_enum_cnt = std_cnt+1; - hdw->std_enum_cur = 0; - hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; -} - - -int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw, - struct v4l2_standard *std, - unsigned int idx) -{ - int ret = -EINVAL; - if (!idx) return ret; - LOCK_TAKE(hdw->big_lock); do { - if (idx >= hdw->std_enum_cnt) break; - idx--; - memcpy(std,hdw->std_defs+idx,sizeof(*std)); - ret = 0; - } while (0); LOCK_GIVE(hdw->big_lock); - return ret; -} - - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) -{ - return hdw->control_cnt; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, - unsigned int idx) -{ - if (idx >= hdw->control_cnt) return 0; - return hdw->controls + idx; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->internal_id; - if (i && (i == ctl_id)) return cptr; - } - return 0; -} - - -/* Given a V4L ID, retrieve the control structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (i && (i == ctl_id)) return cptr; - } - return 0; -} - - -/* Given a V4L ID for its immediate predecessor, retrieve the control - structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr,*cp2; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - cp2 = 0; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (!i) continue; - if (i <= ctl_id) continue; - if (cp2 && (cp2->info->v4l_id < i)) continue; - cp2 = cptr; - } - return cp2; - return 0; -} - - -static const char *get_ctrl_typename(enum pvr2_ctl_type tp) -{ - switch (tp) { - case pvr2_ctl_int: return "integer"; - case pvr2_ctl_enum: return "enum"; - case pvr2_ctl_bool: return "boolean"; - case pvr2_ctl_bitmask: return "bitmask"; - } - return ""; -} - - -/* Commit all control changes made up to this point. Subsystems can be - indirectly affected by these changes. For a given set of things being - committed, we'll clear the affected subsystem bits and then once we're - done committing everything we'll make a request to restore the subsystem - state(s) back to their previous value before this function was called. - Thus we can automatically reconfigure affected pieces of the driver as - controls are changed. */ -int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) -{ - unsigned long saved_subsys_mask = hdw->subsys_enabled_mask; - unsigned long stale_subsys_mask = 0; - unsigned int idx; - struct pvr2_ctrl *cptr; - int value; - int commit_flag = 0; - char buf[100]; - unsigned int bcnt,ccnt; - - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (cptr->info->is_dirty == 0) continue; - if (!cptr->info->is_dirty(cptr)) continue; - if (!commit_flag) { - commit_flag = !0; - } - - bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", - cptr->info->name); - value = 0; - cptr->info->get_value(cptr,&value); - pvr2_ctrl_value_to_sym_internal(cptr,~0,value, - buf+bcnt, - sizeof(buf)-bcnt,&ccnt); - bcnt += ccnt; - bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>", - get_ctrl_typename(cptr->info->type)); - pvr2_trace(PVR2_TRACE_CTL, - "/*--TRACE_COMMIT--*/ %.*s", - bcnt,buf); - } - - if (!commit_flag) { - /* Nothing has changed */ - return 0; - } - - /* When video standard changes, reset the hres and vres values - - but if the user has pending changes there, then let the changes - take priority. */ - if (hdw->std_dirty) { - /* Rewrite the vertical resolution to be appropriate to the - video standard that has been selected. */ - int nvres; - if (hdw->std_mask_cur & V4L2_STD_525_60) { - nvres = 480; - } else { - nvres = 576; - } - if (nvres != hdw->res_ver_val) { - hdw->res_ver_val = nvres; - hdw->res_ver_dirty = !0; - } - } - - if (hdw->std_dirty || - 0) { - /* If any of this changes, then the encoder needs to be - reconfigured, and we need to reset the stream. */ - stale_subsys_mask |= (1<subsys_stream_mask; - } - - if (hdw->srate_dirty) { - /* Write new sample rate into control structure since - * the master copy is stale. We must track srate - * separate from the mpeg control structure because - * other logic also uses this value. */ - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; - c1.value = hdw->srate_val; - cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS); - } - - /* Scan i2c core at this point - before we clear all the dirty - bits. Various parts of the i2c core will notice dirty bits as - appropriate and arrange to broadcast or directly send updates to - the client drivers in order to keep everything in sync */ - pvr2_i2c_core_check_stale(hdw); - - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (!cptr->info->clear_dirty) continue; - cptr->info->clear_dirty(cptr); - } - - /* Now execute i2c core update */ - pvr2_i2c_core_sync(hdw); - - pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask); - - return 0; -} - - -int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_commit_ctl_internal(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - return 0; -} - - -void pvr2_hdw_poll(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_i2c_core_sync(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw, - void (*func)(void *), - void *data) -{ - LOCK_TAKE(hdw->big_lock); do { - hdw->poll_trigger_func = func; - hdw->poll_trigger_data = data; - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw) -{ - if (hdw->poll_trigger_func) { - hdw->poll_trigger_func(hdw->poll_trigger_data); - } -} - - -void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_poll_trigger_unlocked(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) -{ - return hdw->name; -} - - -/* Return bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) -{ - unsigned int msk = 0; - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - case PVR2_CVAL_INPUT_RADIO: - if (hdw->decoder_ctrl && - hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) { - msk |= PVR2_SIGNAL_OK; - if (hdw->audio_stat && - hdw->audio_stat->status(hdw->audio_stat->ctxt)) { - if (hdw->flag_stereo) { - msk |= PVR2_SIGNAL_STEREO; - } - if (hdw->flag_bilingual) { - msk |= PVR2_SIGNAL_SAP; - } - } - } - break; - default: - msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO; - } - return msk; -} - - -int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0x0b; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = (hdw->cmd_buffer[0] != 0); - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -/* Return bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) -{ - unsigned int msk = 0; - LOCK_TAKE(hdw->big_lock); do { - msk = pvr2_hdw_get_signal_status_internal(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - return msk; -} - - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) -{ - return hp->vid_stream; -} - - -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) -{ - int nr = pvr2_hdw_get_unit_number(hdw); - LOCK_TAKE(hdw->big_lock); do { - hdw->log_requested = !0; - printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); - pvr2_i2c_core_check_stale(hdw); - hdw->log_requested = 0; - pvr2_i2c_core_sync(hdw); - pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); - cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); - printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); - } while (0); LOCK_GIVE(hdw->big_lock); -} - -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) -{ - int ret; - u16 address; - unsigned int pipe; - LOCK_TAKE(hdw->big_lock); do { - if ((hdw->fw_buffer == 0) == !enable_flag) break; - - if (!enable_flag) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Cleaning up after CPU firmware fetch"); - kfree(hdw->fw_buffer); - hdw->fw_buffer = 0; - hdw->fw_size = 0; - /* Now release the CPU. It will disconnect and - reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - break; - } - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware"); - hdw->fw_size = 0x2000; - hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL); - if (!hdw->fw_buffer) { - hdw->fw_size = 0; - break; - } - - memset(hdw->fw_buffer,0,hdw->fw_size); - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* download the firmware from address 0000-1fff in 2048 - (=0x800) bytes chunk. */ - - pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware"); - pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); - for(address = 0; address < hdw->fw_size; address += 0x800) { - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0, - address,0, - hdw->fw_buffer+address,0x800,HZ); - if (ret < 0) break; - } - - pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware"); - - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) -{ - return hdw->fw_buffer != 0; -} - - -int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, - char *buf,unsigned int cnt) -{ - int ret = -EINVAL; - LOCK_TAKE(hdw->big_lock); do { - if (!buf) break; - if (!cnt) break; - - if (!hdw->fw_buffer) { - ret = -EIO; - break; - } - - if (offs >= hdw->fw_size) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d EOF", - offs); - ret = 0; - break; - } - - if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs; - - memcpy(buf,hdw->fw_buffer+offs,cnt); - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d cnt=%d", - offs,cnt); - ret = cnt; - } while (0); LOCK_GIVE(hdw->big_lock); - - return ret; -} - - -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw) -{ - return hdw->v4l_minor_number; -} - - -/* Store the v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v) -{ - hdw->v4l_minor_number = v; -} - - -void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw) -{ - if (!hdw->usb_dev) return; - usb_settoggle(hdw->usb_dev, PVR2_CTL_WRITE_ENDPOINT & 0xf, - !(PVR2_CTL_WRITE_ENDPOINT & USB_DIR_IN), 0); - usb_settoggle(hdw->usb_dev, PVR2_CTL_READ_ENDPOINT & 0xf, - !(PVR2_CTL_READ_ENDPOINT & USB_DIR_IN), 0); - usb_clear_halt(hdw->usb_dev, - usb_rcvbulkpipe(hdw->usb_dev, - PVR2_CTL_READ_ENDPOINT & 0x7f)); - usb_clear_halt(hdw->usb_dev, - usb_sndbulkpipe(hdw->usb_dev, - PVR2_CTL_WRITE_ENDPOINT & 0x7f)); -} - - -static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_write_pend_flag = 0; - if (hdw->ctl_read_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_read_pend_flag = 0; - if (hdw->ctl_write_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - hdw->ctl_timeout_flag = !0; - if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) { - usb_unlink_urb(hdw->ctl_write_urb); - } - if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) { - usb_unlink_urb(hdw->ctl_read_urb); - } - } -} - - -int pvr2_send_request_ex(struct pvr2_hdw *hdw, - unsigned int timeout,int probe_fl, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - unsigned int idx; - int status = 0; - struct timer_list timer; - if (!hdw->ctl_lock_held) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " without lock!!"); - return -EDEADLK; - } - if ((!hdw->flag_ok) && !probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when device not ok"); - return -EIO; - } - if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when USB is disconnected"); - } - return -ENOTTY; - } - - /* Ensure that we have sane parameters */ - if (!write_data) write_len = 0; - if (!read_data) read_len = 0; - if (write_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-write transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if (read_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-read transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if ((!write_len) && (!read_len)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute null control transfer?"); - return -EINVAL; - } - - - hdw->cmd_debug_state = 1; - if (write_len) { - hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; - } else { - hdw->cmd_debug_code = 0; - } - hdw->cmd_debug_write_len = write_len; - hdw->cmd_debug_read_len = read_len; - - /* Initialize common stuff */ - init_completion(&hdw->ctl_done); - hdw->ctl_timeout_flag = 0; - hdw->ctl_write_pend_flag = 0; - hdw->ctl_read_pend_flag = 0; - init_timer(&timer); - timer.expires = jiffies + timeout; - timer.data = (unsigned long)hdw; - timer.function = pvr2_ctl_timeout; - - if (write_len) { - hdw->cmd_debug_state = 2; - /* Transfer write data to internal buffer */ - for (idx = 0; idx < write_len; idx++) { - hdw->ctl_write_buffer[idx] = - ((unsigned char *)write_data)[idx]; - } - /* Initiate a write request */ - usb_fill_bulk_urb(hdw->ctl_write_urb, - hdw->usb_dev, - usb_sndbulkpipe(hdw->usb_dev, - PVR2_CTL_WRITE_ENDPOINT), - hdw->ctl_write_buffer, - write_len, - pvr2_ctl_write_complete, - hdw); - hdw->ctl_write_urb->actual_length = 0; - hdw->ctl_write_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit write-control" - " URB status=%d",status); - hdw->ctl_write_pend_flag = 0; - goto done; - } - } - - if (read_len) { - hdw->cmd_debug_state = 3; - memset(hdw->ctl_read_buffer,0x43,read_len); - /* Initiate a read request */ - usb_fill_bulk_urb(hdw->ctl_read_urb, - hdw->usb_dev, - usb_rcvbulkpipe(hdw->usb_dev, - PVR2_CTL_READ_ENDPOINT), - hdw->ctl_read_buffer, - read_len, - pvr2_ctl_read_complete, - hdw); - hdw->ctl_read_urb->actual_length = 0; - hdw->ctl_read_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit read-control" - " URB status=%d",status); - hdw->ctl_read_pend_flag = 0; - goto done; - } - } - - /* Start timer */ - add_timer(&timer); - - /* Now wait for all I/O to complete */ - hdw->cmd_debug_state = 4; - while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - wait_for_completion(&hdw->ctl_done); - } - hdw->cmd_debug_state = 5; - - /* Stop timer */ - del_timer_sync(&timer); - - hdw->cmd_debug_state = 6; - status = 0; - - if (hdw->ctl_timeout_flag) { - status = -ETIMEDOUT; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Timed out control-write"); - } - goto done; - } - - if (write_len) { - /* Validate results of write request */ - if ((hdw->ctl_write_urb->status != 0) && - (hdw->ctl_write_urb->status != -ENOENT) && - (hdw->ctl_write_urb->status != -ESHUTDOWN) && - (hdw->ctl_write_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the write */ - status = hdw->ctl_write_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_write_urb->actual_length < write_len) { - /* Failed to write enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB short," - " expected=%d got=%d", - write_len, - hdw->ctl_write_urb->actual_length); - } - goto done; - } - } - if (read_len) { - /* Validate results of read request */ - if ((hdw->ctl_read_urb->status != 0) && - (hdw->ctl_read_urb->status != -ENOENT) && - (hdw->ctl_read_urb->status != -ESHUTDOWN) && - (hdw->ctl_read_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the read */ - status = hdw->ctl_read_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_read_urb->actual_length < read_len) { - /* Failed to read enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB short," - " expected=%d got=%d", - read_len, - hdw->ctl_read_urb->actual_length); - } - goto done; - } - /* Transfer retrieved data out from internal buffer */ - for (idx = 0; idx < read_len; idx++) { - ((unsigned char *)read_data)[idx] = - hdw->ctl_read_buffer[idx]; - } - } - - done: - - hdw->cmd_debug_state = 0; - if ((status < 0) && (!probe_fl)) { - pvr2_hdw_render_useless_unlocked(hdw); - } - return status; -} - - -int pvr2_send_request(struct pvr2_hdw *hdw, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - return pvr2_send_request_ex(hdw,HZ*4,0, - write_data,write_len, - read_data,read_len); -} - -int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = 0x04; /* write register prefix */ - PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) -{ - int ret = 0; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = 0x05; /* read register prefix */ - hdw->cmd_buffer[1] = 0; - hdw->cmd_buffer[2] = 0; - hdw->cmd_buffer[3] = 0; - hdw->cmd_buffer[4] = 0; - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4); - *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = (data >> 8) & 0xff; - hdw->cmd_buffer[1] = data & 0xff; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = data; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) -{ - if (!hdw->flag_ok) return; - pvr2_trace(PVR2_TRACE_INIT,"render_useless"); - hdw->flag_ok = 0; - if (hdw->vid_stream) { - pvr2_stream_setup(hdw->vid_stream,0,0,0); - } - hdw->flag_streaming_enabled = 0; - hdw->subsys_enabled_mask = 0; -} - - -void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->ctl_lock); - pvr2_hdw_render_useless_unlocked(hdw); - LOCK_GIVE(hdw->ctl_lock); -} - - -void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) -{ - int ret; - pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); - ret = usb_lock_device_for_reset(hdw->usb_dev,0); - if (ret == 1) { - ret = usb_reset_device(hdw->usb_dev); - usb_unlock_device(hdw->usb_dev); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to lock USB device ret=%d",ret); - } - if (init_pause_msec) { - pvr2_trace(PVR2_TRACE_INFO, - "Waiting %u msec for hardware to settle", - init_pause_msec); - msleep(init_pause_msec); - } - -} - - -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) -{ - char da[1]; - unsigned int pipe; - int ret; - - if (!hdw->usb_dev) return; - - pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); - - da[0] = val ? 0x01 : 0x00; - - /* Write the CPUCS register on the 8051. The lsb of the register - is the reset bit; a 1 asserts reset while a 0 clears it. */ - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "cpureset_assert(%d) error=%d",val,ret); - pvr2_hdw_render_useless(hdw); - } -} - - -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); - hdw->flag_ok = !0; - hdw->cmd_buffer[0] = 0xdd; - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - return status; -} - - -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); - hdw->cmd_buffer[0] = 0xde; - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - return status; -} - - -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) -{ - if (!hdw->decoder_ctrl) { - pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: nothing attached"); - return -ENOTTY; - } - - if (!hdw->decoder_ctrl->force_reset) { - pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: not implemented"); - return -ENOTTY; - } - - pvr2_trace(PVR2_TRACE_INIT, - "Requesting decoder reset"); - hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); - return 0; -} - - -int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37); - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - if (!status) { - hdw->subsys_enabled_mask = - ((hdw->subsys_enabled_mask & - ~(1<big_lock_held = hdw->big_lock_held; - ptr->ctl_lock_held = hdw->ctl_lock_held; - ptr->flag_ok = hdw->flag_ok; - ptr->flag_disconnected = hdw->flag_disconnected; - ptr->flag_init_ok = hdw->flag_init_ok; - ptr->flag_streaming_enabled = hdw->flag_streaming_enabled; - ptr->subsys_flags = hdw->subsys_enabled_mask; - ptr->cmd_debug_state = hdw->cmd_debug_state; - ptr->cmd_code = hdw->cmd_debug_code; - ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; - ptr->cmd_debug_read_len = hdw->cmd_debug_read_len; - ptr->cmd_debug_timeout = hdw->ctl_timeout_flag; - ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag; - ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag; - ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status; - ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status; -} - - -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); -} - - -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp); -} - - -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_IN,dp); -} - - -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing 0x%x:0x%x" - " from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval); -} - - -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval); -} - - -int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = hdw->cmd_buffer[0]; - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h deleted file mode 100644 index 63f529154431..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_HDW_H -#define __PVRUSB2_HDW_H - -#include -#include -#include "pvrusb2-io.h" -#include "pvrusb2-ctrl.h" - - -/* Private internal control ids, look these up with - pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ -#define PVR2_CID_STDENUM 1 -#define PVR2_CID_STDCUR 2 -#define PVR2_CID_STDAVAIL 3 -#define PVR2_CID_INPUT 4 -#define PVR2_CID_AUDIOMODE 5 -#define PVR2_CID_FREQUENCY 6 -#define PVR2_CID_HRES 7 -#define PVR2_CID_VRES 8 - -/* Legal values for the INPUT state variable */ -#define PVR2_CVAL_INPUT_TV 0 -#define PVR2_CVAL_INPUT_SVIDEO 1 -#define PVR2_CVAL_INPUT_COMPOSITE 2 -#define PVR2_CVAL_INPUT_RADIO 3 - -/* Values that pvr2_hdw_get_signal_status() returns */ -#define PVR2_SIGNAL_OK 0x0001 -#define PVR2_SIGNAL_STEREO 0x0002 -#define PVR2_SIGNAL_SAP 0x0004 - - -/* Subsystem definitions - these are various pieces that can be - independently stopped / started. Usually you don't want to mess with - this directly (let the driver handle things itself), but it is useful - for debugging. */ -#define PVR2_SUBSYS_B_ENC_FIRMWARE 0 -#define PVR2_SUBSYS_B_ENC_CFG 1 -#define PVR2_SUBSYS_B_DIGITIZER_RUN 2 -#define PVR2_SUBSYS_B_USBSTREAM_RUN 3 -#define PVR2_SUBSYS_B_ENC_RUN 4 - -#define PVR2_SUBSYS_CFG_ALL ( \ - (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \ - (1 << PVR2_SUBSYS_B_ENC_CFG) ) -#define PVR2_SUBSYS_RUN_ALL ( \ - (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \ - (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \ - (1 << PVR2_SUBSYS_B_ENC_RUN) ) -#define PVR2_SUBSYS_ALL ( \ - PVR2_SUBSYS_CFG_ALL | \ - PVR2_SUBSYS_RUN_ALL ) - -enum pvr2_config { - pvr2_config_empty, - pvr2_config_mpeg, - pvr2_config_vbi, - pvr2_config_radio, -}; - -const char *pvr2_config_get_name(enum pvr2_config); - -struct pvr2_hdw; - -/* Create and return a structure for interacting with the underlying - hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid); - -/* Poll for background activity (if any) */ -void pvr2_hdw_poll(struct pvr2_hdw *); - -/* Trigger a poll to take place later at a convenient time */ -void pvr2_hdw_poll_trigger(struct pvr2_hdw *); -void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *); - -/* Register a callback used to trigger a future poll */ -void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *, - void (*func)(void *), - void *data); - -/* Get pointer to structure given unit number */ -struct pvr2_hdw *pvr2_hdw_find(int unit_number); - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *); - -/* Set up the structure and attempt to put the device into a usable state. - This can be a time-consuming operation, which is why it is not done - internally as part of the create() step. Return value is exactly the - same as pvr2_hdw_init_ok(). */ -int pvr2_hdw_setup(struct pvr2_hdw *); - -/* Initialization succeeded */ -int pvr2_hdw_init_ok(struct pvr2_hdw *); - -/* Return true if in the ready (normal) state */ -int pvr2_hdw_dev_ok(struct pvr2_hdw *); - -/* Return small integer number [1..N] for logical instance number of this - device. This is useful for indexing array-valued module parameters. */ -int pvr2_hdw_get_unit_number(struct pvr2_hdw *); - -/* Get pointer to underlying USB device */ -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *); - -/* Retrieve serial number of device */ -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *); - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *); - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its internal ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id); - -/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *, - unsigned int ctl_id); - -/* Commit all control changes made up to this point */ -int pvr2_hdw_commit_ctl(struct pvr2_hdw *); - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); - -/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *); - -/* Query device and see if it thinks it is on a high-speed USB link */ -int pvr2_hdw_is_hsm(struct pvr2_hdw *); - -/* Turn streaming on/off */ -int pvr2_hdw_set_streaming(struct pvr2_hdw *,int); - -/* Find out if streaming is on */ -int pvr2_hdw_get_streaming(struct pvr2_hdw *); - -/* Configure the type of stream to generate */ -int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); - -/* Emit a video standard struct */ -int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, - unsigned int idx); - -/* Enable / disable various pieces of hardware. Items to change are - identified by bit positions within msk, and new state for each item is - identified by corresponding bit positions within val. */ -void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); - -/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */ -void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk); - -/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,0) */ -void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk); - -/* Retrieve mask indicating which pieces of hardware are currently enabled - / configured. */ -unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *); - -/* Adjust mask of what get shut down when streaming is stopped. This is a - debugging aid. */ -void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); - -/* Retrieve mask indicating which pieces of hardware are disabled when - streaming is turned off. */ -unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *); - - -/* Enable / disable retrieval of CPU firmware. This must be enabled before - pvr2_hdw_cpufw_get() will function. Note that doing this may prevent - the device from running (and leaving this mode may imply a device - reset). */ -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag); - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); - -/* Retrieve a piece of the CPU's firmware at the given offset. Return - value is the number of bytes retrieved or zero if we're past the end or - an error otherwise (e.g. if firmware retrieval is not enabled). */ -int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs, - char *buf,unsigned int cnt); - -/* Retrieve previously stored v4l minor device number */ -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *); - -/* Store the v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int); - - -/* The following entry points are all lower level things you normally don't - want to worry about. */ - -/* Attempt to recover from a USB foul-up (in practice I find that if you - have to do this, then it's already too late). */ -void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw); - -/* Issue a command and get a response from the device. LOTS of higher - level stuff is built on this. */ -int pvr2_send_request(struct pvr2_hdw *, - void *write_ptr,unsigned int write_len, - void *read_ptr,unsigned int read_len); - -/* Issue a command and get a response from the device. This extended - version includes a probe flag (which if set means that device errors - should not be logged or treated as fatal) and a timeout in jiffies. - This can be used to non-lethally probe the health of endpoint 1. */ -int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl, - void *write_ptr,unsigned int write_len, - void *read_ptr,unsigned int read_len); - -/* Slightly higher level device communication functions. */ -int pvr2_write_register(struct pvr2_hdw *, u16, u32); -int pvr2_read_register(struct pvr2_hdw *, u16, u32 *); -int pvr2_write_u16(struct pvr2_hdw *, u16, int); -int pvr2_write_u8(struct pvr2_hdw *, u8, int); - -/* Call if for any reason we can't talk to the hardware anymore - this will - cause the driver to stop flailing on the device. */ -void pvr2_hdw_render_useless(struct pvr2_hdw *); -void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *); - -/* Set / clear 8051's reset bit */ -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int); - -/* Execute a USB-commanded device reset */ -void pvr2_hdw_device_reset(struct pvr2_hdw *); - -/* Execute hard reset command (after this point it's likely that the - encoder will have to be reconfigured). This also clears the "useless" - state. */ -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); - -/* Execute simple reset command */ -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); - -/* Order decoder to reset */ -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); - -/* Stop / start video stream transport */ -int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); - -/* Find I2C address of eeprom */ -int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *); - -/* Direct manipulation of GPIO bits */ -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val); -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val); - -/* This data structure is specifically for the next function... */ -struct pvr2_hdw_debug_info { - int big_lock_held; - int ctl_lock_held; - int flag_ok; - int flag_disconnected; - int flag_init_ok; - int flag_streaming_enabled; - unsigned long subsys_flags; - int cmd_debug_state; - int cmd_debug_write_len; - int cmd_debug_read_len; - int cmd_debug_write_pend; - int cmd_debug_read_pend; - int cmd_debug_timeout; - int cmd_debug_rstatus; - int cmd_debug_wstatus; - unsigned char cmd_code; -}; - -/* Non-intrusively retrieve internal state info - this is useful for - diagnosing lockups. Note that this operation is completed without any - kind of locking and so it is not atomic and may yield inconsistent - results. This is *purely* a debugging aid. */ -void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *); - -/* Cause modules to log their state once */ -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); - -/* Cause encoder firmware to be uploaded into the device. This is normally - done autonomously, but the interface is exported here because it is also - a debugging aid. */ -int pvr2_upload_firmware2(struct pvr2_hdw *hdw); - -/* List of device types that we can match */ -extern struct usb_device_id pvr2_device_table[]; - -#endif /* __PVRUSB2_HDW_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c deleted file mode 100644 index 1dd4f6249b99..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-i2c-cmd-v4l2.h" -#include "pvrusb2-audio.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-demod.h" -#include "pvrusb2-video-v4l.h" -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-wm8775.h" -#endif - -#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) - -#define OP_STANDARD 0 -#define OP_BCSH 1 -#define OP_VOLUME 2 -#define OP_FREQ 3 -#define OP_AUDIORATE 4 -#define OP_SIZE 5 -#define OP_LOG 6 - -static const struct pvr2_i2c_op * const ops[] = { - [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, - [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, - [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, - [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, - [OP_SIZE] = &pvr2_i2c_op_v4l2_size, - [OP_LOG] = &pvr2_i2c_op_v4l2_log, -}; - -void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - int id; - id = cp->client->driver->id; - cp->ctl_mask = ((1 << OP_STANDARD) | - (1 << OP_BCSH) | - (1 << OP_VOLUME) | - (1 << OP_FREQ) | - (1 << OP_SIZE) | - (1 << OP_LOG)); - - if (id == I2C_DRIVERID_MSP3400) { - if (pvr2_i2c_msp3400_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_TUNER) { - if (pvr2_i2c_tuner_setup(hdw,cp)) { - return; - } - } -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - if (id == I2C_DRIVERID_CX25840) { - if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_WM8775) { - if (pvr2_i2c_wm8775_setup(hdw,cp)) { - return; - } - } -#endif - if (id == I2C_DRIVERID_SAA711X) { - if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_TDA9887) { - if (pvr2_i2c_demod_setup(hdw,cp)) { - return; - } - } -} - - -const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx) -{ - if (idx >= sizeof(ops)/sizeof(ops[0])) return 0; - return ops[idx]; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c deleted file mode 100644 index 9f81aff2b38a..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-i2c-cmd-v4l2.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include - - -static void set_standard(struct pvr2_hdw *hdw) -{ - v4l2_std_id vs; - vs = hdw->std_mask_cur; - pvr2_trace(PVR2_TRACE_CHIPS, - "i2c v4l2 set_standard(0x%llx)",(__u64)vs); - - pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); -} - - -static int check_standard(struct pvr2_hdw *hdw) -{ - return hdw->std_dirty != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = { - .check = check_standard, - .update = set_standard, - .name = "v4l2_standard", -}; - - -static void set_bcsh(struct pvr2_hdw *hdw) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh" - " b=%d c=%d s=%d h=%d", - hdw->brightness_val,hdw->contrast_val, - hdw->saturation_val,hdw->hue_val); - memset(&ctrl,0,sizeof(ctrl)); - ctrl.id = V4L2_CID_BRIGHTNESS; - ctrl.value = hdw->brightness_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_CONTRAST; - ctrl.value = hdw->contrast_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_SATURATION; - ctrl.value = hdw->saturation_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_HUE; - ctrl.value = hdw->hue_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); -} - - -static int check_bcsh(struct pvr2_hdw *hdw) -{ - return (hdw->brightness_dirty || - hdw->contrast_dirty || - hdw->saturation_dirty || - hdw->hue_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = { - .check = check_bcsh, - .update = set_bcsh, - .name = "v4l2_bcsh", -}; - - -static void set_volume(struct pvr2_hdw *hdw) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS, - "i2c v4l2 set_volume" - "(vol=%d bal=%d bas=%d treb=%d mute=%d)", - hdw->volume_val, - hdw->balance_val, - hdw->bass_val, - hdw->treble_val, - hdw->mute_val); - memset(&ctrl,0,sizeof(ctrl)); - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = hdw->mute_val ? 1 : 0; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_VOLUME; - ctrl.value = hdw->volume_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_BALANCE; - ctrl.value = hdw->balance_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_BASS; - ctrl.value = hdw->bass_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_TREBLE; - ctrl.value = hdw->treble_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); -} - - -static int check_volume(struct pvr2_hdw *hdw) -{ - return (hdw->volume_dirty || - hdw->balance_dirty || - hdw->bass_dirty || - hdw->treble_dirty || - hdw->mute_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = { - .check = check_volume, - .update = set_volume, - .name = "v4l2_volume", -}; - - -static void set_frequency(struct pvr2_hdw *hdw) -{ - unsigned long fv; - struct v4l2_frequency freq; - fv = hdw->freqVal; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv); - memset(&freq,0,sizeof(freq)); - freq.frequency = fv / 62500; - freq.tuner = 0; - freq.type = V4L2_TUNER_ANALOG_TV; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq); -} - - -static int check_frequency(struct pvr2_hdw *hdw) -{ - return hdw->freqDirty != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = { - .check = check_frequency, - .update = set_frequency, - .name = "v4l2_freq", -}; - - -static void set_size(struct pvr2_hdw *hdw) -{ - struct v4l2_format fmt; - - memset(&fmt,0,sizeof(fmt)); - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = hdw->res_hor_val; - fmt.fmt.pix.height = hdw->res_ver_val; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)", - fmt.fmt.pix.width,fmt.fmt.pix.height); - - pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt); -} - - -static int check_size(struct pvr2_hdw *hdw) -{ - return (hdw->res_hor_dirty || hdw->res_ver_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { - .check = check_size, - .update = set_size, - .name = "v4l2_size", -}; - - -static void do_log(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); - pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,0); - -} - - -static int check_log(struct pvr2_hdw *hdw) -{ - return hdw->log_requested != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { - .check = check_log, - .update = do_log, - .name = "v4l2_log", -}; - - -void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) -{ - pvr2_i2c_client_cmd(cp, - (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0); -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h deleted file mode 100644 index ecabddba1ec5..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_CMD_V4L2_H -#define __PVRUSB2_CMD_V4L2_H - -#include "pvrusb2-i2c-core.h" - -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; - -void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); - -#endif /* __PVRUSB2_CMD_V4L2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c deleted file mode 100644 index c8d0bdee3ff1..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ /dev/null @@ -1,937 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - -#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) - -/* - - This module attempts to implement a compliant I2C adapter for the pvrusb2 - device. By doing this we can then make use of existing functionality in - V4L (e.g. tuner.c) rather than rolling our own. - -*/ - -static unsigned int i2c_scan = 0; -module_param(i2c_scan, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); - -static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 length) /* Size of data to write */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) length = 0; - if (length > (sizeof(hdw->cmd_buffer) - 3)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C write to %u that is too large" - " (desired=%u limit=%u)", - i2c_addr, - length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write */ - hdw->cmd_buffer[0] = 0x08; /* write prefix */ - hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ - hdw->cmd_buffer[2] = length; /* length of what follows */ - if (length) memcpy(hdw->cmd_buffer + 3, data, length); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - length + 3, - hdw->cmd_buffer, - 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_write[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 dlen, /* Size of data to write */ - u8 *res, /* Where to put data we read */ - u16 rlen) /* Amount of data to read */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) dlen = 0; - if (dlen > (sizeof(hdw->cmd_buffer) - 4)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has wlen too large" - " (desired=%u limit=%u)", - i2c_addr, - dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4)); - return -ENOTSUPP; - } - if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has rlen too large" - " (desired=%u limit=%u)", - i2c_addr, - rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write followed by a read */ - hdw->cmd_buffer[0] = 0x09; /* read prefix */ - hdw->cmd_buffer[1] = dlen; /* arg length */ - hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one - more byte (status). */ - hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */ - if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - 4 + dlen, - hdw->cmd_buffer, - rlen + 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_read[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - /* Copy back the result */ - if (res && rlen) { - if (ret) { - /* Error, just blank out the return buffer */ - memset(res, 0, rlen); - } else { - memcpy(res, hdw->cmd_buffer + 1, rlen); - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -/* This is the common low level entry point for doing I2C operations to the - hardware. */ -int pvr2_i2c_basic_op(struct pvr2_hdw *hdw, - u8 i2c_addr, - u8 *wdata, - u16 wlen, - u8 *rdata, - u16 rlen) -{ - if (!rdata) rlen = 0; - if (!wdata) wlen = 0; - if (rlen || !wlen) { - return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } else { - return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen); - } -} - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - -/* This is a special entry point that is entered if an I2C operation is - attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this - part doesn't work, but we know it is really there. So let's look for - the autodetect attempt and just return success if we see that. */ -static int i2c_hack_wm8775(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - if (!(rlen || wlen)) { - // This is a probe attempt. Just let it succeed. - return 0; - } - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); -} - -/* This is a special entry point that is entered if an I2C operation is - attempted to a cx25840 chip on model 24xxx hardware. This chip can - sometimes wedge itself. Worse still, when this happens msp3400 can - falsely detect this part and then the system gets hosed up after msp3400 - gets confused and dies. What we want to do here is try to keep msp3400 - away and also try to notice if the chip is wedged and send a warning to - the system log. */ -static int i2c_hack_cx25840(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - int ret; - unsigned int subaddr; - u8 wbuf[2]; - int state = hdw->i2c_cx25840_hack_state; - - if (!(rlen || wlen)) { - // Probe attempt - always just succeed and don't bother the - // hardware (this helps to make the state machine further - // down somewhat easier). - return 0; - } - - if (state == 3) { - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } - - /* We're looking for the exact pattern where the revision register - is being read. The cx25840 module will always look at the - revision register first. Any other pattern of access therefore - has to be a probe attempt from somebody else so we'll reject it. - Normally we could just let each client just probe the part - anyway, but when the cx25840 is wedged, msp3400 will get a false - positive and that just screws things up... */ - - if (wlen == 0) { - switch (state) { - case 1: subaddr = 0x0100; break; - case 2: subaddr = 0x0101; break; - default: goto fail; - } - } else if (wlen == 2) { - subaddr = (wdata[0] << 8) | wdata[1]; - switch (subaddr) { - case 0x0100: state = 1; break; - case 0x0101: state = 2; break; - default: goto fail; - } - } else { - goto fail; - } - if (!rlen) goto success; - state = 0; - if (rlen != 1) goto fail; - - /* If we get to here then we have a legitimate read for one of the - two revision bytes, so pass it through. */ - wbuf[0] = subaddr >> 8; - wbuf[1] = subaddr; - ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen); - - if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Detected a wedged cx25840 chip;" - " the device will not work."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Try power cycling the pvrusb2 device."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Disabling further access to the device" - " to prevent other foul-ups."); - // This blocks all further communication with the part. - hdw->i2c_func[0x44] = 0; - pvr2_hdw_render_useless(hdw); - goto fail; - } - - /* Success! */ - pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK."); - state = 3; - - success: - hdw->i2c_cx25840_hack_state = state; - return 0; - - fail: - hdw->i2c_cx25840_hack_state = state; - return -EIO; -} - -#endif /* CONFIG_VIDEO_PVRUSB2_24XXX */ - -/* This is a very, very limited I2C adapter implementation. We can only - support what we actually know will work on the device... */ -static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], - int num) -{ - int ret = -ENOTSUPP; - pvr2_i2c_func funcp = 0; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data); - - if (!num) { - ret = -EINVAL; - goto done; - } - if ((msgs[0].flags & I2C_M_NOSTART)) { - trace_i2c("i2c refusing I2C_M_NOSTART"); - goto done; - } - if (msgs[0].addr < PVR2_I2C_FUNC_CNT) { - funcp = hdw->i2c_func[msgs[0].addr]; - } - if (!funcp) { - ret = -EIO; - goto done; - } - - if (num == 1) { - if (msgs[0].flags & I2C_M_RD) { - /* Simple read */ - u16 tcnt,bcnt,offs; - if (!msgs[0].len) { - /* Length == 0 read. This is a probe. */ - if (funcp(hdw,msgs[0].addr,0,0,0,0)) { - ret = -EIO; - goto done; - } - ret = 1; - goto done; - } - /* If the read is short enough we'll do the whole - thing atomically. Otherwise we have no choice - but to break apart the reads. */ - tcnt = msgs[0].len; - offs = 0; - while (tcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr,0,0, - msgs[0].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - } - ret = 1; - goto done; - } else { - /* Simple write */ - ret = 1; - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,msgs[0].len,0,0)) { - ret = -EIO; - } - goto done; - } - } else if (num == 2) { - if (msgs[0].addr != msgs[1].addr) { - trace_i2c("i2c refusing 2 phase transfer with" - " conflicting target addresses"); - ret = -ENOTSUPP; - goto done; - } - if ((!((msgs[0].flags & I2C_M_RD))) && - (msgs[1].flags & I2C_M_RD)) { - u16 tcnt,bcnt,wcnt,offs; - /* Write followed by atomic read. If the read - portion is short enough we'll do the whole thing - atomically. Otherwise we have no choice but to - break apart the reads. */ - tcnt = msgs[1].len; - wcnt = msgs[0].len; - offs = 0; - while (tcnt || wcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,wcnt, - msgs[1].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - wcnt = 0; - } - ret = 2; - goto done; - } else { - trace_i2c("i2c refusing complex transfer" - " read0=%d read1=%d", - (msgs[0].flags & I2C_M_RD), - (msgs[1].flags & I2C_M_RD)); - } - } else { - trace_i2c("i2c refusing %d phase transfer",num); - } - - done: - if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) { - unsigned int idx,offs,cnt; - for (idx = 0; idx < num; idx++) { - cnt = msgs[idx].len; - printk(KERN_INFO - "pvrusb2 i2c xfer %u/%u:" - " addr=0x%x len=%d %s%s", - idx+1,num, - msgs[idx].addr, - cnt, - (msgs[idx].flags & I2C_M_RD ? - "read" : "write"), - (msgs[idx].flags & I2C_M_NOSTART ? - " nostart" : "")); - if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { - if (cnt > 8) cnt = 8; - printk(" ["); - for (offs = 0; offs < (cnt>8?8:cnt); offs++) { - if (offs) printk(" "); - printk("%02x",msgs[idx].buf[offs]); - } - if (offs < cnt) printk(" ..."); - printk("]"); - } - if (idx+1 == num) { - printk(" result=%d",ret); - } - printk("\n"); - } - if (!num) { - printk(KERN_INFO - "pvrusb2 i2c xfer null transfer result=%d\n", - ret); - } - } - return ret; -} - -static int pvr2_i2c_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) -{ - return 0; -} - -static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA; -} - -static int pvr2_i2c_core_singleton(struct i2c_client *cp, - unsigned int cmd,void *arg) -{ - int stat; - if (!cp) return -EINVAL; - if (!(cp->driver)) return -EINVAL; - if (!(cp->driver->command)) return -EINVAL; - if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN; - stat = cp->driver->command(cp,cmd,arg); - module_put(cp->driver->driver.owner); - return stat; -} - -int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg) -{ - int stat; - if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { - char buf[100]; - unsigned int cnt; - cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, - buf,sizeof(buf)); - pvr2_trace(PVR2_TRACE_I2C_CMD, - "i2c COMMAND (code=%u 0x%x) to %.*s", - cmd,cmd,cnt,buf); - } - stat = pvr2_i2c_core_singleton(cp->client,cmd,arg); - if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { - char buf[100]; - unsigned int cnt; - cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, - buf,sizeof(buf)); - pvr2_trace(PVR2_TRACE_I2C_CMD, - "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat); - } - return stat; -} - -int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg) -{ - struct list_head *item,*nc; - struct pvr2_i2c_client *cp; - int stat = -EINVAL; - - if (!hdw) return stat; - - mutex_lock(&hdw->i2c_list_lock); - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (!cp->recv_enable) continue; - mutex_unlock(&hdw->i2c_list_lock); - stat = pvr2_i2c_client_cmd(cp,cmd,arg); - mutex_lock(&hdw->i2c_list_lock); - } - mutex_unlock(&hdw->i2c_list_lock); - return stat; -} - - -static int handler_check(struct pvr2_i2c_client *cp) -{ - struct pvr2_i2c_handler *hp = cp->handler; - if (!hp) return 0; - if (!hp->func_table->check) return 0; - return hp->func_table->check(hp->func_data) != 0; -} - -#define BUFSIZE 500 - -void pvr2_i2c_core_sync(struct pvr2_hdw *hdw) -{ - unsigned long msk; - unsigned int idx; - struct list_head *item,*nc; - struct pvr2_i2c_client *cp; - - if (!hdw->i2c_linked) return; - if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) { - return; - } - mutex_lock(&hdw->i2c_list_lock); do { - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN"); - if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) { - /* One or more I2C clients have attached since we - last synced. So scan the list and identify the - new clients. */ - char *buf; - unsigned int cnt; - unsigned long amask = 0; - buf = kmalloc(BUFSIZE,GFP_KERNEL); - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT"); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - if (!cp->detected_flag) { - cp->ctl_mask = 0; - pvr2_i2c_probe(hdw,cp); - cp->detected_flag = !0; - msk = cp->ctl_mask; - cnt = 0; - if (buf) { - cnt = pvr2_i2c_client_describe( - cp, - PVR2_I2C_DETAIL_ALL, - buf,BUFSIZE); - } - trace_i2c("Probed: %.*s",cnt,buf); - if (handler_check(cp)) { - hdw->i2c_pend_types |= - PVR2_I2C_PEND_CLIENT; - } - cp->pend_mask = msk; - hdw->i2c_pend_mask |= msk; - hdw->i2c_pend_types |= - PVR2_I2C_PEND_REFRESH; - } - amask |= cp->ctl_mask; - } - hdw->i2c_active_mask = amask; - if (buf) kfree(buf); - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) { - /* Need to do one or more global updates. Arrange - for this to happen. */ - unsigned long m2; - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: PEND_STALE (0x%lx)", - hdw->i2c_stale_mask); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - m2 = hdw->i2c_stale_mask; - m2 &= cp->ctl_mask; - m2 &= ~cp->pend_mask; - if (m2) { - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: cp=%p setting 0x%lx", - cp,m2); - cp->pend_mask |= m2; - } - } - hdw->i2c_pend_mask |= hdw->i2c_stale_mask; - hdw->i2c_stale_mask = 0; - hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH; - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) { - /* One or more client handlers are asking for an - update. Run through the list of known clients - and update each one. */ - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT"); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT; - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - if (!cp->handler) continue; - if (!cp->handler->func_table->update) continue; - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: cp=%p update",cp); - mutex_unlock(&hdw->i2c_list_lock); - cp->handler->func_table->update( - cp->handler->func_data); - mutex_lock(&hdw->i2c_list_lock); - /* If client's update function set some - additional pending bits, account for that - here. */ - if (cp->pend_mask & ~hdw->i2c_pend_mask) { - hdw->i2c_pend_mask |= cp->pend_mask; - hdw->i2c_pend_types |= - PVR2_I2C_PEND_REFRESH; - } - } - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) { - const struct pvr2_i2c_op *opf; - unsigned long pm; - /* Some actual updates are pending. Walk through - each update type and perform it. */ - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH" - " (0x%lx)",hdw->i2c_pend_mask); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH; - pm = hdw->i2c_pend_mask; - hdw->i2c_pend_mask = 0; - for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { - if (!(pm & msk)) continue; - pm &= ~msk; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item, - struct pvr2_i2c_client, - list); - if (cp->pend_mask & msk) { - cp->pend_mask &= ~msk; - cp->recv_enable = !0; - } else { - cp->recv_enable = 0; - } - } - opf = pvr2_i2c_get_op(idx); - if (!opf) continue; - mutex_unlock(&hdw->i2c_list_lock); - opf->update(hdw); - mutex_lock(&hdw->i2c_list_lock); - } - } - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END"); - } while (0); mutex_unlock(&hdw->i2c_list_lock); -} - -int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw) -{ - unsigned long msk,sm,pm; - unsigned int idx; - const struct pvr2_i2c_op *opf; - struct list_head *item; - struct pvr2_i2c_client *cp; - unsigned int pt = 0; - - pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN"); - - pm = hdw->i2c_active_mask; - sm = 0; - for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { - if (!(msk & pm)) continue; - pm &= ~msk; - opf = pvr2_i2c_get_op(idx); - if (!opf) continue; - if (opf->check(hdw)) { - sm |= msk; - } - } - if (sm) pt |= PVR2_I2C_PEND_STALE; - - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (!handler_check(cp)) continue; - pt |= PVR2_I2C_PEND_CLIENT; - } - - if (pt) { - mutex_lock(&hdw->i2c_list_lock); do { - hdw->i2c_pend_types |= pt; - hdw->i2c_stale_mask |= sm; - hdw->i2c_pend_mask |= hdw->i2c_stale_mask; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - } - - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: types=0x%x stale=0x%lx pend=0x%lx", - hdw->i2c_pend_types, - hdw->i2c_stale_mask, - hdw->i2c_pend_mask); - pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END"); - - return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0; -} - -unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, - unsigned int detail, - char *buf,unsigned int maxlen) -{ - unsigned int ccnt,bcnt; - int spcfl = 0; - const struct pvr2_i2c_op *opf; - - ccnt = 0; - if (detail & PVR2_I2C_DETAIL_DEBUG) { - bcnt = scnprintf(buf,maxlen, - "ctxt=%p ctl_mask=0x%lx", - cp,cp->ctl_mask); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - spcfl = !0; - } - bcnt = scnprintf(buf,maxlen, - "%s%s @ 0x%x", - (spcfl ? " " : ""), - cp->client->name, - cp->client->addr); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - if ((detail & PVR2_I2C_DETAIL_HANDLER) && - cp->handler && cp->handler->func_table->describe) { - bcnt = scnprintf(buf,maxlen," ("); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = cp->handler->func_table->describe( - cp->handler->func_data,buf,maxlen); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = scnprintf(buf,maxlen,")"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { - unsigned int idx; - unsigned long msk,sm; - int spcfl; - bcnt = scnprintf(buf,maxlen," ["); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - sm = 0; - spcfl = 0; - for (idx = 0, msk = 1; msk; idx++, msk <<= 1) { - if (!(cp->ctl_mask & msk)) continue; - opf = pvr2_i2c_get_op(idx); - if (opf) { - bcnt = scnprintf(buf,maxlen,"%s%s", - spcfl ? " " : "", - opf->name); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - spcfl = !0; - } else { - sm |= msk; - } - } - if (sm) { - bcnt = scnprintf(buf,maxlen,"%s%lx", - idx != 0 ? " " : "",sm); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - bcnt = scnprintf(buf,maxlen,"]"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - return ccnt; -} - -unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw, - char *buf,unsigned int maxlen) -{ - unsigned int ccnt,bcnt; - struct list_head *item; - struct pvr2_i2c_client *cp; - ccnt = 0; - mutex_lock(&hdw->i2c_list_lock); do { - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - bcnt = pvr2_i2c_client_describe( - cp, - (PVR2_I2C_DETAIL_HANDLER| - PVR2_I2C_DETAIL_CTLMASK), - buf,maxlen); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = scnprintf(buf,maxlen,"\n"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - } while (0); mutex_unlock(&hdw->i2c_list_lock); - return ccnt; -} - -static int pvr2_i2c_attach_inform(struct i2c_client *client) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); - struct pvr2_i2c_client *cp; - int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL); - cp = kmalloc(sizeof(*cp),GFP_KERNEL); - trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]", - client->name, - client->addr,cp); - if (!cp) return -ENOMEM; - memset(cp,0,sizeof(*cp)); - INIT_LIST_HEAD(&cp->list); - cp->client = client; - mutex_lock(&hdw->i2c_list_lock); do { - list_add_tail(&cp->list,&hdw->i2c_clients); - hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - if (fl) pvr2_hdw_poll_trigger_unlocked(hdw); - return 0; -} - -static int pvr2_i2c_detach_inform(struct i2c_client *client) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); - struct pvr2_i2c_client *cp; - struct list_head *item,*nc; - unsigned long amask = 0; - int foundfl = 0; - mutex_lock(&hdw->i2c_list_lock); do { - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (cp->client == client) { - trace_i2c("pvr2_i2c_detach" - " [client=%s @ 0x%x ctxt=%p]", - client->name, - client->addr,cp); - if (cp->handler && - cp->handler->func_table->detach) { - cp->handler->func_table->detach( - cp->handler->func_data); - } - list_del(&cp->list); - kfree(cp); - foundfl = !0; - continue; - } - amask |= cp->ctl_mask; - } - hdw->i2c_active_mask = amask; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - if (!foundfl) { - trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=]", - client->name, - client->addr); - } - return 0; -} - -static struct i2c_algorithm pvr2_i2c_algo_template = { - .master_xfer = pvr2_i2c_xfer, - .algo_control = pvr2_i2c_control, - .functionality = pvr2_i2c_functionality, -}; - -static struct i2c_adapter pvr2_i2c_adap_template = { - .owner = THIS_MODULE, - .class = I2C_CLASS_TV_ANALOG, - .id = I2C_HW_B_BT848, - .client_register = pvr2_i2c_attach_inform, - .client_unregister = pvr2_i2c_detach_inform, -}; - -static void do_i2c_scan(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[1]; - int i,rc; - msg[0].addr = 0; - msg[0].flags = I2C_M_RD; - msg[0].len = 0; - msg[0].buf = 0; - printk("%s: i2c scan beginning\n",hdw->name); - for (i = 0; i < 128; i++) { - msg[0].addr = i; - rc = i2c_transfer(&hdw->i2c_adap,msg, - sizeof(msg)/sizeof(msg[0])); - if (rc != 1) continue; - printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i); - } - printk("%s: i2c scan done.\n",hdw->name); -} - -void pvr2_i2c_core_init(struct pvr2_hdw *hdw) -{ - unsigned int idx; - - // The default action for all possible I2C addresses is just to do - // the transfer normally. - for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { - hdw->i2c_func[idx] = pvr2_i2c_basic_op; - } - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - // If however we're dealing with new hardware, insert some hacks in - // the I2C transfer stack to let things work better. - if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { - hdw->i2c_func[0x1b] = i2c_hack_wm8775; - hdw->i2c_func[0x44] = i2c_hack_cx25840; - } -#endif - - // Configure the adapter and set up everything else related to it. - memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap)); - memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); - strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); - hdw->i2c_adap.algo = &hdw->i2c_algo; - hdw->i2c_adap.algo_data = hdw; - hdw->i2c_pend_mask = 0; - hdw->i2c_stale_mask = 0; - hdw->i2c_active_mask = 0; - INIT_LIST_HEAD(&hdw->i2c_clients); - mutex_init(&hdw->i2c_list_lock); - hdw->i2c_linked = !0; - i2c_add_adapter(&hdw->i2c_adap); - if (i2c_scan) do_i2c_scan(hdw); -} - -void pvr2_i2c_core_done(struct pvr2_hdw *hdw) -{ - if (hdw->i2c_linked) { - i2c_del_adapter(&hdw->i2c_adap); - hdw->i2c_linked = 0; - } -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h deleted file mode 100644 index e8af5b0ed3ce..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_I2C_CORE_H -#define __PVRUSB2_I2C_CORE_H - -#include -#include - -struct pvr2_hdw; -struct pvr2_i2c_client; -struct pvr2_i2c_handler; -struct pvr2_i2c_handler_functions; -struct pvr2_i2c_op; -struct pvr2_i2c_op_functions; - -struct pvr2_i2c_client { - struct i2c_client *client; - struct pvr2_i2c_handler *handler; - struct list_head list; - int detected_flag; - int recv_enable; - unsigned long pend_mask; - unsigned long ctl_mask; -}; - -struct pvr2_i2c_handler { - void *func_data; - const struct pvr2_i2c_handler_functions *func_table; -}; - -struct pvr2_i2c_handler_functions { - void (*detach)(void *); - int (*check)(void *); - void (*update)(void *); - unsigned int (*describe)(void *,char *,unsigned int); -}; - -struct pvr2_i2c_op { - int (*check)(struct pvr2_hdw *); - void (*update)(struct pvr2_hdw *); - const char *name; -}; - -void pvr2_i2c_core_init(struct pvr2_hdw *); -void pvr2_i2c_core_done(struct pvr2_hdw *); - -int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg); -int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg); - -int pvr2_i2c_core_check_stale(struct pvr2_hdw *); -void pvr2_i2c_core_sync(struct pvr2_hdw *); -unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen); -#define PVR2_I2C_DETAIL_DEBUG 0x0001 -#define PVR2_I2C_DETAIL_HANDLER 0x0002 -#define PVR2_I2C_DETAIL_CTLMASK 0x0004 -#define PVR2_I2C_DETAIL_ALL (\ - PVR2_I2C_DETAIL_DEBUG |\ - PVR2_I2C_DETAIL_HANDLER |\ - PVR2_I2C_DETAIL_CTLMASK) -unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *, - unsigned int detail_mask, - char *buf,unsigned int maxlen); - -void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *); -const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx); - -#endif /* __PVRUSB2_I2C_CORE_H */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c deleted file mode 100644 index a984c91f571c..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-io.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - -#define BUFFER_SIG 0x47653271 - -// #define SANITY_CHECK_BUFFERS - - -#ifdef SANITY_CHECK_BUFFERS -#define BUFFER_CHECK(bp) do { \ - if ((bp)->signature != BUFFER_SIG) { \ - pvr2_trace(PVR2_TRACE_ERROR_LEGS, \ - "Buffer %p is bad at %s:%d", \ - (bp),__FILE__,__LINE__); \ - pvr2_buffer_describe(bp,"BadSig"); \ - BUG(); \ - } \ -} while (0) -#else -#define BUFFER_CHECK(bp) do {} while(0) -#endif - -struct pvr2_stream { - /* Buffers queued for reading */ - struct list_head queued_list; - unsigned int q_count; - unsigned int q_bcount; - /* Buffers with retrieved data */ - struct list_head ready_list; - unsigned int r_count; - unsigned int r_bcount; - /* Buffers available for use */ - struct list_head idle_list; - unsigned int i_count; - unsigned int i_bcount; - /* Pointers to all buffers */ - struct pvr2_buffer **buffers; - /* Array size of buffers */ - unsigned int buffer_slot_count; - /* Total buffers actually in circulation */ - unsigned int buffer_total_count; - /* Designed number of buffers to be in circulation */ - unsigned int buffer_target_count; - /* Executed when ready list become non-empty */ - pvr2_stream_callback callback_func; - void *callback_data; - /* Context for transfer endpoint */ - struct usb_device *dev; - int endpoint; - /* Overhead for mutex enforcement */ - spinlock_t list_lock; - struct mutex mutex; - /* Tracking state for tolerating errors */ - unsigned int fail_count; - unsigned int fail_tolerance; -}; - -struct pvr2_buffer { - int id; - int signature; - enum pvr2_buffer_state state; - void *ptr; /* Pointer to storage area */ - unsigned int max_count; /* Size of storage area */ - unsigned int used_count; /* Amount of valid data in storage area */ - int status; /* Transfer result status */ - struct pvr2_stream *stream; - struct list_head list_overhead; - struct urb *purb; -}; - -const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st) -{ - switch (st) { - case pvr2_buffer_state_none: return "none"; - case pvr2_buffer_state_idle: return "idle"; - case pvr2_buffer_state_queued: return "queued"; - case pvr2_buffer_state_ready: return "ready"; - } - return "unknown"; -} - -void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg) -{ - pvr2_trace(PVR2_TRACE_INFO, - "buffer%s%s %p state=%s id=%d status=%d" - " stream=%p purb=%p sig=0x%x", - (msg ? " " : ""), - (msg ? msg : ""), - bp, - (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"), - (bp ? bp->id : 0), - (bp ? bp->status : 0), - (bp ? bp->stream : 0), - (bp ? bp->purb : 0), - (bp ? bp->signature : 0)); -} - -static void pvr2_buffer_remove(struct pvr2_buffer *bp) -{ - unsigned int *cnt; - unsigned int *bcnt; - unsigned int ccnt; - struct pvr2_stream *sp = bp->stream; - switch (bp->state) { - case pvr2_buffer_state_idle: - cnt = &sp->i_count; - bcnt = &sp->i_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_queued: - cnt = &sp->q_count; - bcnt = &sp->q_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_ready: - cnt = &sp->r_count; - bcnt = &sp->r_bcount; - ccnt = bp->used_count; - break; - default: - return; - } - list_del_init(&bp->list_overhead); - (*cnt)--; - (*bcnt) -= ccnt; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s dec cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state),*bcnt,*cnt); - bp->state = pvr2_buffer_state_none; -} - -static void pvr2_buffer_set_none(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_none)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static int pvr2_buffer_set_ready(struct pvr2_buffer *bp) -{ - int fl; - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_ready)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - fl = (sp->r_count == 0); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->ready_list); - bp->state = pvr2_buffer_state_ready; - (sp->r_count)++; - sp->r_bcount += bp->used_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->r_bcount,sp->r_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - return fl; -} - -static void pvr2_buffer_set_idle(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_idle)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->idle_list); - bp->state = pvr2_buffer_state_idle; - (sp->i_count)++; - sp->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->i_bcount,sp->i_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_set_queued(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_queued)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->queued_list); - bp->state = pvr2_buffer_state_queued; - (sp->q_count)++; - sp->q_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->q_bcount,sp->q_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_wipe(struct pvr2_buffer *bp) -{ - if (bp->state == pvr2_buffer_state_queued) { - usb_kill_urb(bp->purb); - } -} - -static int pvr2_buffer_init(struct pvr2_buffer *bp, - struct pvr2_stream *sp, - unsigned int id) -{ - memset(bp,0,sizeof(*bp)); - bp->signature = BUFFER_SIG; - bp->id = id; - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp); - bp->stream = sp; - bp->state = pvr2_buffer_state_none; - INIT_LIST_HEAD(&bp->list_overhead); - bp->purb = usb_alloc_urb(0,GFP_KERNEL); - if (! bp->purb) return -ENOMEM; -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"create"); -#endif - return 0; -} - -static void pvr2_buffer_done(struct pvr2_buffer *bp) -{ -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"delete"); -#endif - pvr2_buffer_wipe(bp); - pvr2_buffer_set_none(bp); - bp->signature = 0; - bp->stream = 0; - if (bp->purb) usb_free_urb(bp->purb); - pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" - " bufferDone %p",bp); -} - -static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - unsigned int scnt; - - /* Allocate buffers pointer array in multiples of 32 entries */ - if (cnt == sp->buffer_total_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ poolResize " - " stream=%p cur=%d adj=%+d", - sp, - sp->buffer_total_count, - cnt-sp->buffer_total_count); - - scnt = cnt & ~0x1f; - if (cnt > scnt) scnt += 0x20; - - if (cnt > sp->buffer_total_count) { - if (scnt > sp->buffer_slot_count) { - struct pvr2_buffer **nb; - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - if (sp->buffer_slot_count) { - memcpy(nb,sp->buffers, - sp->buffer_slot_count * sizeof(*nb)); - kfree(sp->buffers); - } - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - while (sp->buffer_total_count < cnt) { - struct pvr2_buffer *bp; - bp = kmalloc(sizeof(*bp),GFP_KERNEL); - if (!bp) return -ENOMEM; - ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count); - if (ret) { - kfree(bp); - return -ENOMEM; - } - sp->buffers[sp->buffer_total_count] = bp; - (sp->buffer_total_count)++; - pvr2_buffer_set_idle(bp); - } - } else { - while (sp->buffer_total_count > cnt) { - struct pvr2_buffer *bp; - bp = sp->buffers[sp->buffer_total_count - 1]; - /* Paranoia */ - sp->buffers[sp->buffer_total_count - 1] = 0; - (sp->buffer_total_count)--; - pvr2_buffer_done(bp); - kfree(bp); - } - if (scnt < sp->buffer_slot_count) { - struct pvr2_buffer **nb = 0; - if (scnt) { - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - memcpy(nb,sp->buffers,scnt * sizeof(*nb)); - } - kfree(sp->buffers); - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - } - return 0; -} - -static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - unsigned int cnt; - - if (sp->buffer_total_count == sp->buffer_target_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/" - " poolCheck stream=%p cur=%d tgt=%d", - sp,sp->buffer_total_count,sp->buffer_target_count); - - if (sp->buffer_total_count < sp->buffer_target_count) { - return pvr2_stream_buffer_count(sp,sp->buffer_target_count); - } - - cnt = 0; - while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) { - bp = sp->buffers[sp->buffer_total_count - (cnt + 1)]; - if (bp->state != pvr2_buffer_state_idle) break; - cnt++; - } - if (cnt) { - pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt); - } - - return 0; -} - -static void pvr2_stream_internal_flush(struct pvr2_stream *sp) -{ - struct list_head *lp; - struct pvr2_buffer *bp1; - while ((lp = sp->queued_list.next) != &sp->queued_list) { - bp1 = list_entry(lp,struct pvr2_buffer,list_overhead); - pvr2_buffer_wipe(bp1); - /* At this point, we should be guaranteed that no - completion callback may happen on this buffer. But it's - possible that it might have completed after we noticed - it but before we wiped it. So double check its status - here first. */ - if (bp1->state != pvr2_buffer_state_queued) continue; - pvr2_buffer_set_idle(bp1); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } -} - -static void pvr2_stream_init(struct pvr2_stream *sp) -{ - spin_lock_init(&sp->list_lock); - mutex_init(&sp->mutex); - INIT_LIST_HEAD(&sp->queued_list); - INIT_LIST_HEAD(&sp->ready_list); - INIT_LIST_HEAD(&sp->idle_list); -} - -static void pvr2_stream_done(struct pvr2_stream *sp) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - pvr2_stream_buffer_count(sp,0); - } while (0); mutex_unlock(&sp->mutex); -} - -static void buffer_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_buffer *bp = urb->context; - struct pvr2_stream *sp; - unsigned long irq_flags; - BUFFER_CHECK(bp); - sp = bp->stream; - bp->used_count = 0; - bp->status = 0; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d", - bp,urb->status,urb->actual_length); - spin_lock_irqsave(&sp->list_lock,irq_flags); - if ((!(urb->status)) || - (urb->status == -ENOENT) || - (urb->status == -ECONNRESET) || - (urb->status == -ESHUTDOWN)) { - bp->used_count = urb->actual_length; - if (sp->fail_count) { - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p transfer ok" - " - fail count reset",sp); - sp->fail_count = 0; - } - } else if (sp->fail_count < sp->fail_tolerance) { - // We can tolerate this error, because we're below the - // threshold... - (sp->fail_count)++; - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p ignoring error %d" - " - fail count increased to %u", - sp,urb->status,sp->fail_count); - } else { - bp->status = urb->status; - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - pvr2_buffer_set_ready(bp); - if (sp && sp->callback_func) { - sp->callback_func(sp->callback_data); - } -} - -struct pvr2_stream *pvr2_stream_create(void) -{ - struct pvr2_stream *sp; - sp = kmalloc(sizeof(*sp),GFP_KERNEL); - if (!sp) return sp; - memset(sp,0,sizeof(*sp)); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp); - pvr2_stream_init(sp); - return sp; -} - -void pvr2_stream_destroy(struct pvr2_stream *sp) -{ - if (!sp) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp); - pvr2_stream_done(sp); - kfree(sp); -} - -void pvr2_stream_setup(struct pvr2_stream *sp, - struct usb_device *dev, - int endpoint, - unsigned int tolerance) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - sp->dev = dev; - sp->endpoint = endpoint; - sp->fail_tolerance = tolerance; - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_set_callback(struct pvr2_stream *sp, - pvr2_stream_callback func, - void *data) -{ - unsigned long irq_flags; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - sp->callback_data = data; - sp->callback_func = func; - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); -} - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) -{ - return sp->buffer_target_count; -} - -int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - if (sp->buffer_target_count == cnt) return 0; - mutex_lock(&sp->mutex); do { - sp->buffer_target_count = cnt; - ret = pvr2_stream_achieve_buffer_count(sp); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->idle_list.next; - if (lp == &sp->idle_list) return 0; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->ready_list.next; - if (lp == &sp->ready_list) return 0; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id) -{ - if (id < 0) return 0; - if (id >= sp->buffer_total_count) return 0; - return sp->buffers[id]; -} - -int pvr2_stream_get_ready_count(struct pvr2_stream *sp) -{ - return sp->r_count; -} - -int pvr2_stream_get_idle_count(struct pvr2_stream *sp) -{ - return sp->i_count; -} - -void pvr2_stream_flush(struct pvr2_stream *sp) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_kill(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) { - pvr2_buffer_set_idle(bp); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } - } while(0); mutex_unlock(&sp->mutex); -} - -int pvr2_buffer_queue(struct pvr2_buffer *bp) -{ -#undef SEED_BUFFER -#ifdef SEED_BUFFER - unsigned int idx; - unsigned int val; -#endif - int ret = 0; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - pvr2_buffer_wipe(bp); - if (!sp->dev) { - ret = -EIO; - break; - } - pvr2_buffer_set_queued(bp); -#ifdef SEED_BUFFER - for (idx = 0; idx < (bp->max_count) / 4; idx++) { - val = bp->id << 24; - val |= idx; - ((unsigned int *)(bp->ptr))[idx] = val; - } -#endif - bp->status = -EINPROGRESS; - usb_fill_bulk_urb(bp->purb, // struct urb *urb - sp->dev, // struct usb_device *dev - // endpoint (below) - usb_rcvbulkpipe(sp->dev,sp->endpoint), - bp->ptr, // void *transfer_buffer - bp->max_count, // int buffer_length - buffer_complete, - bp); - usb_submit_urb(bp->purb,GFP_KERNEL); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -int pvr2_buffer_idle(struct pvr2_buffer *bp) -{ - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - pvr2_buffer_wipe(bp); - pvr2_buffer_set_idle(bp); - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } - } while(0); mutex_unlock(&sp->mutex); - return 0; -} - -int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) -{ - int ret = 0; - unsigned long irq_flags; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - if (bp->state != pvr2_buffer_state_idle) { - ret = -EPERM; - } else { - bp->ptr = ptr; - bp->stream->i_bcount -= bp->max_count; - bp->max_count = cnt; - bp->stream->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferPool " - " %8s cap cap=%07d cnt=%02d", - pvr2_buffer_state_decode( - pvr2_buffer_state_idle), - bp->stream->i_bcount,bp->stream->i_count); - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp) -{ - return bp->used_count; -} - -int pvr2_buffer_get_status(struct pvr2_buffer *bp) -{ - return bp->status; -} - -enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *bp) -{ - return bp->state; -} - -int pvr2_buffer_get_id(struct pvr2_buffer *bp) -{ - return bp->id; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h deleted file mode 100644 index 65e11385b2b3..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_IO_H -#define __PVRUSB2_IO_H - -#include -#include - -typedef void (*pvr2_stream_callback)(void *); - -enum pvr2_buffer_state { - pvr2_buffer_state_none = 0, // Not on any list - pvr2_buffer_state_idle = 1, // Buffer is ready to be used again - pvr2_buffer_state_queued = 2, // Buffer has been queued for filling - pvr2_buffer_state_ready = 3, // Buffer has data available -}; - -struct pvr2_stream; -struct pvr2_buffer; - -const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); - -/* Initialize / tear down stream structure */ -struct pvr2_stream *pvr2_stream_create(void); -void pvr2_stream_destroy(struct pvr2_stream *); -void pvr2_stream_setup(struct pvr2_stream *, - struct usb_device *dev,int endpoint, - unsigned int tolerance); -void pvr2_stream_set_callback(struct pvr2_stream *, - pvr2_stream_callback func, - void *data); - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *); -int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); - -/* Get a pointer to a buffer that is either idle, ready, or is specified - named. */ -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id); - -/* Find out how many buffers are idle or ready */ -int pvr2_stream_get_idle_count(struct pvr2_stream *); -int pvr2_stream_get_ready_count(struct pvr2_stream *); - -/* Kill all pending operations */ -void pvr2_stream_flush(struct pvr2_stream *); - -/* Kill all pending buffers and throw away any ready buffers as well */ -void pvr2_stream_kill(struct pvr2_stream *); - -/* Set up the actual storage for a buffer */ -int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt); - -/* Find out size of data in the given ready buffer */ -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *); - -/* Retrieve completion code for given ready buffer */ -int pvr2_buffer_get_status(struct pvr2_buffer *); - -/* Retrieve state of given buffer */ -enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *); - -/* Retrieve ID of given buffer */ -int pvr2_buffer_get_id(struct pvr2_buffer *); - -/* Start reading into given buffer (kill it if needed) */ -int pvr2_buffer_queue(struct pvr2_buffer *); - -/* Move buffer back to idle pool (kill it if needed) */ -int pvr2_buffer_idle(struct pvr2_buffer *); - -#endif /* __PVRUSB2_IO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c deleted file mode 100644 index 49da062e3271..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-ioread.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -#define BUFFER_COUNT 32 -#define BUFFER_SIZE PAGE_ALIGN(0x4000) - -struct pvr2_ioread { - struct pvr2_stream *stream; - char *buffer_storage[BUFFER_COUNT]; - char *sync_key_ptr; - unsigned int sync_key_len; - unsigned int sync_buf_offs; - unsigned int sync_state; - unsigned int sync_trashed_count; - int enabled; // Streaming is on - int spigot_open; // OK to pass data to client - int stream_running; // Passing data to client now - - /* State relevant to current buffer being read */ - struct pvr2_buffer *c_buf; - char *c_data_ptr; - unsigned int c_data_len; - unsigned int c_data_offs; - struct mutex mutex; -}; - -static int pvr2_ioread_init(struct pvr2_ioread *cp) -{ - unsigned int idx; - - cp->stream = 0; - mutex_init(&cp->mutex); - - for (idx = 0; idx < BUFFER_COUNT; idx++) { - cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL); - if (!(cp->buffer_storage[idx])) break; - } - - if (idx < BUFFER_COUNT) { - // An allocation appears to have failed - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } - return -ENOMEM; - } - return 0; -} - -static void pvr2_ioread_done(struct pvr2_ioread *cp) -{ - unsigned int idx; - - pvr2_ioread_setup(cp,0); - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } -} - -struct pvr2_ioread *pvr2_ioread_create(void) -{ - struct pvr2_ioread *cp; - cp = kmalloc(sizeof(*cp),GFP_KERNEL); - if (!cp) return 0; - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp); - memset(cp,0,sizeof(*cp)); - if (pvr2_ioread_init(cp) < 0) { - kfree(cp); - return 0; - } - return cp; -} - -void pvr2_ioread_destroy(struct pvr2_ioread *cp) -{ - if (!cp) return; - pvr2_ioread_done(cp); - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp); - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = 0; - } - kfree(cp); -} - -void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp, - const char *sync_key_ptr, - unsigned int sync_key_len) -{ - if (!cp) return; - - if (!sync_key_ptr) sync_key_len = 0; - if ((sync_key_len == cp->sync_key_len) && - ((!sync_key_len) || - (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return; - - if (sync_key_len != cp->sync_key_len) { - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = 0; - } - cp->sync_key_len = 0; - if (sync_key_len) { - cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL); - if (cp->sync_key_ptr) { - cp->sync_key_len = sync_key_len; - } - } - } - if (!cp->sync_key_len) return; - memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len); -} - -static void pvr2_ioread_stop(struct pvr2_ioread *cp) -{ - if (!(cp->enabled)) return; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp); - pvr2_stream_kill(cp->stream); - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->enabled = 0; - cp->stream_running = 0; - cp->spigot_open = 0; - if (cp->sync_state) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 0"); - cp->sync_state = 0; - } -} - -static int pvr2_ioread_start(struct pvr2_ioread *cp) -{ - int stat; - struct pvr2_buffer *bp; - if (cp->enabled) return 0; - if (!(cp->stream)) return 0; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp); - while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) { - stat = pvr2_buffer_queue(bp); - if (stat < 0) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_start id=%p" - " error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return stat; - } - } - cp->enabled = !0; - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->stream_running = 0; - if (cp->sync_key_len) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 1"); - cp->sync_state = 1; - cp->sync_trashed_count = 0; - cp->sync_buf_offs = 0; - } - cp->spigot_open = 0; - return 0; -} - -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp) -{ - return cp->stream; -} - -int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) -{ - int ret; - unsigned int idx; - struct pvr2_buffer *bp; - - mutex_lock(&cp->mutex); do { - if (cp->stream) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (tear-down) id=%p",cp); - pvr2_ioread_stop(cp); - pvr2_stream_kill(cp->stream); - pvr2_stream_set_buffer_count(cp->stream,0); - cp->stream = 0; - } - if (sp) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (setup) id=%p",cp); - pvr2_stream_kill(sp); - ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT); - if (ret < 0) return ret; - for (idx = 0; idx < BUFFER_COUNT; idx++) { - bp = pvr2_stream_get_buffer(sp,idx); - pvr2_buffer_set_buffer(bp, - cp->buffer_storage[idx], - BUFFER_SIZE); - } - cp->stream = sp; - } - } while (0); mutex_unlock(&cp->mutex); - - return 0; -} - -int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) -{ - int ret = 0; - if ((!fl) == (!(cp->enabled))) return ret; - - mutex_lock(&cp->mutex); do { - if (fl) { - ret = pvr2_ioread_start(cp); - } else { - pvr2_ioread_stop(cp); - } - } while (0); mutex_unlock(&cp->mutex); - return ret; -} - -int pvr2_ioread_get_enabled(struct pvr2_ioread *cp) -{ - return cp->enabled != 0; -} - -int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) -{ - int stat; - - while (cp->c_data_len <= cp->c_data_offs) { - if (cp->c_buf) { - // Flush out current buffer first. - stat = pvr2_buffer_queue(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " queue_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return 0; - } - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - } - // Now get a freshly filled buffer. - cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream); - if (!cp->c_buf) break; // Nothing ready; done. - cp->c_data_len = pvr2_buffer_get_count(cp->c_buf); - if (!cp->c_data_len) { - // Nothing transferred. Was there an error? - stat = pvr2_buffer_get_status(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " buffer_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - // Give up. - return 0; - } - // Start over... - continue; - } - cp->c_data_offs = 0; - cp->c_data_ptr = cp->buffer_storage[ - pvr2_buffer_get_id(cp->c_buf)]; - } - return !0; -} - -void pvr2_ioread_filter(struct pvr2_ioread *cp) -{ - unsigned int idx; - if (!cp->enabled) return; - if (cp->sync_state != 1) return; - - // Search the stream for our synchronization key. This is made - // complicated by the fact that in order to be honest with - // ourselves here we must search across buffer boundaries... - mutex_lock(&cp->mutex); while (1) { - // Ensure we have a buffer - if (!pvr2_ioread_get_buffer(cp)) break; - if (!cp->c_data_len) break; - - // Now walk the buffer contents until we match the key or - // run out of buffer data. - for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) { - if (cp->sync_buf_offs >= cp->sync_key_len) break; - if (cp->c_data_ptr[idx] == - cp->sync_key_ptr[cp->sync_buf_offs]) { - // Found the next key byte - (cp->sync_buf_offs)++; - } else { - // Whoops, mismatched. Start key over... - cp->sync_buf_offs = 0; - } - } - - // Consume what we've walked through - cp->c_data_offs += idx; - cp->sync_trashed_count += idx; - - // If we've found the key, then update state and get out. - if (cp->sync_buf_offs >= cp->sync_key_len) { - cp->sync_trashed_count -= cp->sync_key_len; - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 2 (skipped %u bytes)", - cp->sync_trashed_count); - cp->sync_state = 2; - cp->sync_buf_offs = 0; - break; - } - - if (cp->c_data_offs < cp->c_data_len) { - // Sanity check - should NEVER get here - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ERROR: pvr2_ioread filter sync problem" - " len=%u offs=%u", - cp->c_data_len,cp->c_data_offs); - // Get out so we don't get stuck in an infinite - // loop. - break; - } - - continue; // (for clarity) - } mutex_unlock(&cp->mutex); -} - -int pvr2_ioread_avail(struct pvr2_ioread *cp) -{ - int ret; - if (!(cp->enabled)) { - // Stream is not enabled; so this is an I/O error - return -EIO; - } - - if (cp->sync_state == 1) { - pvr2_ioread_filter(cp); - if (cp->sync_state == 1) return -EAGAIN; - } - - ret = 0; - if (cp->stream_running) { - if (!pvr2_stream_get_ready_count(cp->stream)) { - // No data available at all right now. - ret = -EAGAIN; - } - } else { - if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) { - // Haven't buffered up enough yet; try again later - ret = -EAGAIN; - } - } - - if ((!(cp->spigot_open)) != (!(ret == 0))) { - cp->spigot_open = (ret == 0); - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ data is %s", - cp->spigot_open ? "available" : "pending"); - } - - return ret; -} - -int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) -{ - unsigned int copied_cnt; - unsigned int bcnt; - const char *src; - int stat; - int ret = 0; - unsigned int req_cnt = cnt; - - if (!cnt) { - pvr2_trace(PVR2_TRACE_TRAP, - "/*---TRACE_READ---*/ pvr2_ioread_read id=%p" - " ZERO Request? Returning zero.",cp); - return 0; - } - - stat = pvr2_ioread_avail(cp); - if (stat < 0) return stat; - - cp->stream_running = !0; - - mutex_lock(&cp->mutex); do { - - // Suck data out of the buffers and copy to the user - copied_cnt = 0; - if (!buf) cnt = 0; - while (1) { - if (!pvr2_ioread_get_buffer(cp)) { - ret = -EIO; - break; - } - - if (!cnt) break; - - if (cp->sync_state == 2) { - // We're repeating the sync key data into - // the stream. - src = cp->sync_key_ptr + cp->sync_buf_offs; - bcnt = cp->sync_key_len - cp->sync_buf_offs; - } else { - // Normal buffer copy - src = cp->c_data_ptr + cp->c_data_offs; - bcnt = cp->c_data_len - cp->c_data_offs; - } - - if (!bcnt) break; - - // Don't run past user's buffer - if (bcnt > cnt) bcnt = cnt; - - if (copy_to_user(buf,src,bcnt)) { - // User supplied a bad pointer? - // Give up - this *will* cause data - // to be lost. - ret = -EFAULT; - break; - } - cnt -= bcnt; - buf += bcnt; - copied_cnt += bcnt; - - if (cp->sync_state == 2) { - // Update offset inside sync key that we're - // repeating back out. - cp->sync_buf_offs += bcnt; - if (cp->sync_buf_offs >= cp->sync_key_len) { - // Consumed entire key; switch mode - // to normal. - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 0"); - cp->sync_state = 0; - } - } else { - // Update buffer offset. - cp->c_data_offs += bcnt; - } - } - - } while (0); mutex_unlock(&cp->mutex); - - if (!ret) { - if (copied_cnt) { - // If anything was copied, return that count - ret = copied_cnt; - } else { - // Nothing copied; suggest to caller that another - // attempt should be tried again later - ret = -EAGAIN; - } - } - - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ pvr2_ioread_read" - " id=%p request=%d result=%d", - cp,req_cnt,ret); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h deleted file mode 100644 index 6b002597f5de..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_IOREAD_H -#define __PVRUSB2_IOREAD_H - -#include "pvrusb2-io.h" - -struct pvr2_ioread; - -struct pvr2_ioread *pvr2_ioread_create(void); -void pvr2_ioread_destroy(struct pvr2_ioread *); -int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *); -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *); -void pvr2_ioread_set_sync_key(struct pvr2_ioread *, - const char *sync_key_ptr, - unsigned int sync_key_len); -int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl); -int pvr2_ioread_get_enabled(struct pvr2_ioread *); -int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt); -int pvr2_ioread_avail(struct pvr2_ioread *); - -#endif /* __PVRUSB2_IOREAD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c deleted file mode 100644 index b95248274ed0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pvrusb2-hdw.h" -#include "pvrusb2-context.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -#include "pvrusb2-sysfs.h" -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -#define DRIVER_AUTHOR "Mike Isely " -#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner" -#define DRIVER_VERSION "V4L in-tree version" - -#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ - PVR2_TRACE_INFO| \ - PVR2_TRACE_TOLERANCE| \ - PVR2_TRACE_TRAP| \ - 0) - -int pvrusb2_debug = DEFAULT_DEBUG_MASK; - -module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug, "Debug trace mask"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -static struct pvr2_sysfs_class *class_ptr = 0; -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -static void pvr_setup_attach(struct pvr2_context *pvr) -{ - /* Create association with v4l layer */ - pvr2_v4l2_create(pvr); -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_create(pvr,class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ -} - -static int pvr_probe(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - struct pvr2_context *pvr; - - /* Create underlying hardware interface */ - pvr = pvr2_context_create(intf,devid,pvr_setup_attach); - if (!pvr) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to create hdw handler"); - return -ENOMEM; - } - - pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr); - - usb_set_intfdata(intf, pvr); - - return 0; -} - -/* - * pvr_disconnect() - * - */ -static void pvr_disconnect(struct usb_interface *intf) -{ - struct pvr2_context *pvr = usb_get_intfdata(intf); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr); - - usb_set_intfdata (intf, NULL); - pvr2_context_disconnect(pvr); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr); - -} - -static struct usb_driver pvr_driver = { - name: "pvrusb2", - id_table: pvr2_device_table, - probe: pvr_probe, - disconnect: pvr_disconnect -}; - -/* - * pvr_init() / pvr_exit() - * - * This code is run to initialize/exit the driver. - * - */ -static int __init pvr_init(void) -{ - int ret; - - pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - class_ptr = pvr2_sysfs_class_create(); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - ret = usb_register(&pvr_driver); - - if (ret == 0) - info(DRIVER_DESC " : " DRIVER_VERSION); - if (pvrusb2_debug) info("Debug mask is %d (0x%x)", - pvrusb2_debug,pvrusb2_debug); - - return ret; -} - -static void __exit pvr_exit(void) -{ - - pvr2_trace(PVR2_TRACE_INIT,"pvr_exit"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_class_destroy(class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - usb_deregister(&pvr_driver); -} - -module_init(pvr_init); -module_exit(pvr_exit); - -/* Mike Isely 11-Mar-2006: See pvrusb2-hdw.c for - MODULE_DEVICE_TABLE(). We have to declare that attribute there - because that's where the device table actually is now and it seems - that certain gcc configurations get angry if MODULE_DEVICE_TABLE() - is used on what ends up being an external symbol. */ -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c deleted file mode 100644 index 134063693643..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2-std.h" -#include "pvrusb2-debug.h" -#include -#include - -struct std_name { - const char *name; - v4l2_std_id id; -}; - - -#define CSTD_PAL \ - (V4L2_STD_PAL_B| \ - V4L2_STD_PAL_B1| \ - V4L2_STD_PAL_G| \ - V4L2_STD_PAL_H| \ - V4L2_STD_PAL_I| \ - V4L2_STD_PAL_D| \ - V4L2_STD_PAL_D1| \ - V4L2_STD_PAL_K| \ - V4L2_STD_PAL_M| \ - V4L2_STD_PAL_N| \ - V4L2_STD_PAL_Nc| \ - V4L2_STD_PAL_60) - -#define CSTD_NTSC \ - (V4L2_STD_NTSC_M| \ - V4L2_STD_NTSC_M_JP| \ - V4L2_STD_NTSC_M_KR| \ - V4L2_STD_NTSC_443) - -#define CSTD_SECAM \ - (V4L2_STD_SECAM_B| \ - V4L2_STD_SECAM_D| \ - V4L2_STD_SECAM_G| \ - V4L2_STD_SECAM_H| \ - V4L2_STD_SECAM_K| \ - V4L2_STD_SECAM_K1| \ - V4L2_STD_SECAM_L| \ - V4L2_STD_SECAM_LC) - -#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B) -#define TSTD_B1 (V4L2_STD_PAL_B1) -#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D) -#define TSTD_D1 (V4L2_STD_PAL_D1) -#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G) -#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H) -#define TSTD_I (V4L2_STD_PAL_I) -#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K) -#define TSTD_K1 (V4L2_STD_SECAM_K1) -#define TSTD_L (V4L2_STD_SECAM_L) -#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M) -#define TSTD_N (V4L2_STD_PAL_N) -#define TSTD_Nc (V4L2_STD_PAL_Nc) -#define TSTD_60 (V4L2_STD_PAL_60) - -#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM) - -/* Mapping of standard bits to color system */ -const static struct std_name std_groups[] = { - {"PAL",CSTD_PAL}, - {"NTSC",CSTD_NTSC}, - {"SECAM",CSTD_SECAM}, -}; - -/* Mapping of standard bits to modulation system */ -const static struct std_name std_items[] = { - {"B",TSTD_B}, - {"B1",TSTD_B1}, - {"D",TSTD_D}, - {"D1",TSTD_D1}, - {"G",TSTD_G}, - {"H",TSTD_H}, - {"I",TSTD_I}, - {"K",TSTD_K}, - {"K1",TSTD_K1}, - {"L",TSTD_L}, - {"LC",V4L2_STD_SECAM_LC}, - {"M",TSTD_M}, - {"Mj",V4L2_STD_NTSC_M_JP}, - {"443",V4L2_STD_NTSC_443}, - {"Mk",V4L2_STD_NTSC_M_KR}, - {"N",TSTD_N}, - {"Nc",TSTD_Nc}, - {"60",TSTD_60}, -}; - - -// Search an array of std_name structures and return a pointer to the -// element with the matching name. -static const struct std_name *find_std_name(const struct std_name *arrPtr, - unsigned int arrSize, - const char *bufPtr, - unsigned int bufSize) -{ - unsigned int idx; - const struct std_name *p; - for (idx = 0; idx < arrSize; idx++) { - p = arrPtr + idx; - if (strlen(p->name) != bufSize) continue; - if (!memcmp(bufPtr,p->name,bufSize)) return p; - } - return 0; -} - - -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize) -{ - v4l2_std_id id = 0; - v4l2_std_id cmsk = 0; - v4l2_std_id t; - int mMode = 0; - unsigned int cnt; - char ch; - const struct std_name *sp; - - while (bufSize) { - if (!mMode) { - cnt = 0; - while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++; - if (cnt >= bufSize) return 0; // No more characters - sp = find_std_name( - std_groups, - sizeof(std_groups)/sizeof(std_groups[0]), - bufPtr,cnt); - if (!sp) return 0; // Illegal color system name - cnt++; - bufPtr += cnt; - bufSize -= cnt; - mMode = !0; - cmsk = sp->id; - continue; - } - cnt = 0; - while (cnt < bufSize) { - ch = bufPtr[cnt]; - if (ch == ';') { - mMode = 0; - break; - } - if (ch == '/') break; - cnt++; - } - sp = find_std_name(std_items, - sizeof(std_items)/sizeof(std_items[0]), - bufPtr,cnt); - if (!sp) return 0; // Illegal modulation system ID - t = sp->id & cmsk; - if (!t) return 0; // Specific color + modulation system illegal - id |= t; - if (cnt < bufSize) cnt++; - bufPtr += cnt; - bufSize -= cnt; - } - - if (idPtr) *idPtr = id; - return !0; -} - - -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id) -{ - unsigned int idx1,idx2; - const struct std_name *ip,*gp; - int gfl,cfl; - unsigned int c1,c2; - cfl = 0; - c1 = 0; - for (idx1 = 0; - idx1 < sizeof(std_groups)/sizeof(std_groups[0]); - idx1++) { - gp = std_groups + idx1; - gfl = 0; - for (idx2 = 0; - idx2 < sizeof(std_items)/sizeof(std_items[0]); - idx2++) { - ip = std_items + idx2; - if (!(gp->id & ip->id & id)) continue; - if (!gfl) { - if (cfl) { - c2 = scnprintf(bufPtr,bufSize,";"); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - cfl = !0; - c2 = scnprintf(bufPtr,bufSize, - "%s-",gp->name); - gfl = !0; - } else { - c2 = scnprintf(bufPtr,bufSize,"/"); - } - c1 += c2; - bufSize -= c2; - bufPtr += c2; - c2 = scnprintf(bufPtr,bufSize, - ip->name); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - } - return c1; -} - - -// Template data for possible enumerated video standards. Here we group -// standards which share common frame rates and resolution. -static struct v4l2_standard generic_standards[] = { - { - .id = (TSTD_B|TSTD_B1| - TSTD_D|TSTD_D1| - TSTD_G| - TSTD_H| - TSTD_I| - TSTD_K|TSTD_K1| - TSTD_L| - V4L2_STD_SECAM_LC | - TSTD_N|TSTD_Nc), - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = (TSTD_M| - V4L2_STD_NTSC_M_JP| - V4L2_STD_NTSC_M_KR), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is a total wild guess - .id = (TSTD_60), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is total wild guess - .id = V4L2_STD_NTSC_443, - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - } -}; - -#define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0])) - -static struct v4l2_standard *match_std(v4l2_std_id id) -{ - unsigned int idx; - for (idx = 0; idx < generic_standards_cnt; idx++) { - if (generic_standards[idx].id & id) { - return generic_standards + idx; - } - } - return 0; -} - -static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id) -{ - struct v4l2_standard *template; - int idx; - unsigned int bcnt; - template = match_std(id); - if (!template) return 0; - idx = std->index; - memcpy(std,template,sizeof(*template)); - std->index = idx; - std->id = id; - bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id); - std->name[bcnt] = 0; - pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s", - std->index,std->name); - return !0; -} - -/* These are special cases of combined standards that we should enumerate - separately if the component pieces are present. */ -static v4l2_std_id std_mixes[] = { - V4L2_STD_PAL_B | V4L2_STD_PAL_G, - V4L2_STD_PAL_D | V4L2_STD_PAL_K, - V4L2_STD_SECAM_B | V4L2_STD_SECAM_G, - V4L2_STD_SECAM_D | V4L2_STD_SECAM_K, -}; - -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id) -{ - unsigned int std_cnt = 0; - unsigned int idx,bcnt,idx2; - v4l2_std_id idmsk,cmsk,fmsk; - struct v4l2_standard *stddefs; - - if (pvrusb2_debug & PVR2_TRACE_INIT) { - char buf[50]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); - pvr2_trace( - PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)", - (int)id,bcnt,buf); - } - - *countptr = 0; - std_cnt = 0; - fmsk = 0; - for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (match_std(idmsk)) { - std_cnt++; - continue; - } - fmsk |= idmsk; - } - - for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) { - if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; - } - - if (fmsk) { - char buf[50]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " Failed to classify the following standard(s): %.*s", - bcnt,buf); - } - - pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)", - std_cnt); - if (!std_cnt) return 0; // paranoia - - stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt, - GFP_KERNEL); - memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt); - for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx; - - idx = 0; - - /* Enumerate potential special cases */ - for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) && - (idx < std_cnt)); idx2++) { - if (!(id & std_mixes[idx2])) continue; - if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++; - } - /* Now enumerate individual pieces */ - for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (!pvr2_std_fill(stddefs+idx,idmsk)) continue; - idx++; - } - - *countptr = std_cnt; - return stddefs; -} - -v4l2_std_id pvr2_std_get_usable(void) -{ - return CSTD_ALL; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h deleted file mode 100644 index 07c399375341..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_STD_H -#define __PVRUSB2_STD_H - -#include - -// Convert string describing one or more video standards into a mask of V4L -// standard bits. Return true if conversion succeeds otherwise return -// false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and -// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are -// modulation schemes (e.g. "M", "B", "G", etc). -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize); - -// Convert any arbitrary set of video standard bits into an unambiguous -// readable string. Return value is the number of bytes consumed in the -// buffer. The formatted string is of a form that can be parsed by our -// sibling std_std_to_id() function. -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id); - -// Create an array of suitable v4l2_standard structures given a bit mask of -// video standards to support. The array is allocated from the heap, and -// the number of elements is returned in the first argument. -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id); - -// Return mask of which video standard bits are valid -v4l2_std_id pvr2_std_get_usable(void); - -#endif /* __PVRUSB2_STD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c deleted file mode 100644 index c6e6523d74b4..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include "pvrusb2-sysfs.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -#include "pvrusb2-debugifc.h" -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) - -struct pvr2_sysfs { - struct pvr2_channel channel; - struct class_device *class_dev; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - struct pvr2_sysfs_debugifc *debugifc; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - struct pvr2_sysfs_ctl_item *item_first; - struct pvr2_sysfs_ctl_item *item_last; - struct sysfs_ops kops; - struct kobj_type ktype; - struct class_device_attribute attr_v4l_minor_number; - struct class_device_attribute attr_unit_number; -}; - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -struct pvr2_sysfs_debugifc { - struct class_device_attribute attr_debugcmd; - struct class_device_attribute attr_debuginfo; -}; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -struct pvr2_sysfs_ctl_item { - struct class_device_attribute attr_name; - struct class_device_attribute attr_type; - struct class_device_attribute attr_min; - struct class_device_attribute attr_max; - struct class_device_attribute attr_enum; - struct class_device_attribute attr_bits; - struct class_device_attribute attr_val; - struct class_device_attribute attr_custom; - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *chptr; - struct pvr2_sysfs_ctl_item *item_next; - struct attribute *attr_gen[7]; - struct attribute_group grp; - char name[80]; -}; - -struct pvr2_sysfs_class { - struct class class; -}; - -static ssize_t show_name(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - const char *name; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - name = pvr2_ctrl_get_desc(cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name); - - if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); -} - -static ssize_t show_type(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - const char *name; - enum pvr2_ctl_type tp; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - tp = pvr2_ctrl_get_type(cptr); - switch (tp) { - case pvr2_ctl_int: name = "integer"; break; - case pvr2_ctl_enum: name = "enum"; break; - case pvr2_ctl_bitmask: name = "bitmask"; break; - case pvr2_ctl_bool: name = "boolean"; break; - default: name = "?"; break; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); - - if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); -} - -static ssize_t show_min(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_min(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); -} - -static ssize_t show_max(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_max(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); -} - -static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; - unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); - if (ret < 0) return ret; - - ret = pvr2_ctrl_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; - unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); - if (ret < 0) return ret; - - ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_enum(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - unsigned int bcnt,ccnt,ecnt; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - ecnt = pvr2_ctrl_get_cnt(cptr); - bcnt = 0; - for (val = 0; val < ecnt; val++) { - pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); - if (!ccnt) continue; - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id); - return bcnt; -} - -static ssize_t show_bits(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int valid_bits,msk; - unsigned int bcnt,ccnt; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - valid_bits = pvr2_ctrl_get_mask(cptr); - bcnt = 0; - for (msk = 1; valid_bits; msk <<= 1) { - if (!(msk & valid_bits)) continue; - valid_bits &= ~msk; - pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id); - return bcnt; -} - -static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, - const char *buf,unsigned int count) -{ - struct pvr2_ctrl *cptr; - int ret; - int mask,val; - - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (customfl) { - ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val); - } else { - ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val); - } - if (ret < 0) return ret; - ret = pvr2_ctrl_set_mask_value(cptr,mask,val); - pvr2_hdw_commit_ctl(sfp->channel.hdw); - return ret; -} - -static ssize_t store_val_norm(int id,struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - ret = store_val_any(id,0,sfp,buf,count); - if (!ret) ret = count; - return ret; -} - -static ssize_t store_val_custom(int id,struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - ret = store_val_any(id,1,sfp,buf,count); - if (!ret) ret = count; - return ret; -} - -/* - Mike Isely 30-April-2005 - - This next batch of horrible preprocessor hackery is needed because the - kernel's class_device_attribute mechanism fails to pass the actual - attribute through to the show / store functions, which means we have no - way to package up any attribute-specific parameters, like for example the - control id. So we work around this brain-damage by encoding the control - id into the show / store functions themselves and pick the function based - on the control id we're setting up. These macros try to ease the pain. - Yuck. -*/ - -#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \ -{ return sf_name(ctl_id,class_dev,buf); } - -#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \ -{ return sf_name(ctl_id,class_dev,buf,count); } - -#define CREATE_BATCH(ctl_id) \ -CREATE_SHOW_INSTANCE(show_name,ctl_id) \ -CREATE_SHOW_INSTANCE(show_type,ctl_id) \ -CREATE_SHOW_INSTANCE(show_min,ctl_id) \ -CREATE_SHOW_INSTANCE(show_max,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ -CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ -CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ - -CREATE_BATCH(0) -CREATE_BATCH(1) -CREATE_BATCH(2) -CREATE_BATCH(3) -CREATE_BATCH(4) -CREATE_BATCH(5) -CREATE_BATCH(6) -CREATE_BATCH(7) -CREATE_BATCH(8) -CREATE_BATCH(9) -CREATE_BATCH(10) -CREATE_BATCH(11) -CREATE_BATCH(12) -CREATE_BATCH(13) -CREATE_BATCH(14) -CREATE_BATCH(15) -CREATE_BATCH(16) -CREATE_BATCH(17) -CREATE_BATCH(18) -CREATE_BATCH(19) -CREATE_BATCH(20) -CREATE_BATCH(21) -CREATE_BATCH(22) -CREATE_BATCH(23) -CREATE_BATCH(24) -CREATE_BATCH(25) -CREATE_BATCH(26) -CREATE_BATCH(27) -CREATE_BATCH(28) -CREATE_BATCH(29) -CREATE_BATCH(30) -CREATE_BATCH(31) -CREATE_BATCH(32) -CREATE_BATCH(33) -CREATE_BATCH(34) -CREATE_BATCH(35) -CREATE_BATCH(36) -CREATE_BATCH(37) -CREATE_BATCH(38) -CREATE_BATCH(39) -CREATE_BATCH(40) -CREATE_BATCH(41) -CREATE_BATCH(42) -CREATE_BATCH(43) -CREATE_BATCH(44) -CREATE_BATCH(45) -CREATE_BATCH(46) -CREATE_BATCH(47) -CREATE_BATCH(48) -CREATE_BATCH(49) -CREATE_BATCH(50) -CREATE_BATCH(51) -CREATE_BATCH(52) -CREATE_BATCH(53) -CREATE_BATCH(54) -CREATE_BATCH(55) -CREATE_BATCH(56) -CREATE_BATCH(57) -CREATE_BATCH(58) -CREATE_BATCH(59) - -struct pvr2_sysfs_func_set { - ssize_t (*show_name)(struct class_device *,char *); - ssize_t (*show_type)(struct class_device *,char *); - ssize_t (*show_min)(struct class_device *,char *); - ssize_t (*show_max)(struct class_device *,char *); - ssize_t (*show_enum)(struct class_device *,char *); - ssize_t (*show_bits)(struct class_device *,char *); - ssize_t (*show_val_norm)(struct class_device *,char *); - ssize_t (*store_val_norm)(struct class_device *, - const char *,size_t); - ssize_t (*show_val_custom)(struct class_device *,char *); - ssize_t (*store_val_custom)(struct class_device *, - const char *,size_t); -}; - -#define INIT_BATCH(ctl_id) \ -[ctl_id] = { \ - .show_name = show_name_##ctl_id, \ - .show_type = show_type_##ctl_id, \ - .show_min = show_min_##ctl_id, \ - .show_max = show_max_##ctl_id, \ - .show_enum = show_enum_##ctl_id, \ - .show_bits = show_bits_##ctl_id, \ - .show_val_norm = show_val_norm_##ctl_id, \ - .store_val_norm = store_val_norm_##ctl_id, \ - .show_val_custom = show_val_custom_##ctl_id, \ - .store_val_custom = store_val_custom_##ctl_id, \ -} \ - -static struct pvr2_sysfs_func_set funcs[] = { - INIT_BATCH(0), - INIT_BATCH(1), - INIT_BATCH(2), - INIT_BATCH(3), - INIT_BATCH(4), - INIT_BATCH(5), - INIT_BATCH(6), - INIT_BATCH(7), - INIT_BATCH(8), - INIT_BATCH(9), - INIT_BATCH(10), - INIT_BATCH(11), - INIT_BATCH(12), - INIT_BATCH(13), - INIT_BATCH(14), - INIT_BATCH(15), - INIT_BATCH(16), - INIT_BATCH(17), - INIT_BATCH(18), - INIT_BATCH(19), - INIT_BATCH(20), - INIT_BATCH(21), - INIT_BATCH(22), - INIT_BATCH(23), - INIT_BATCH(24), - INIT_BATCH(25), - INIT_BATCH(26), - INIT_BATCH(27), - INIT_BATCH(28), - INIT_BATCH(29), - INIT_BATCH(30), - INIT_BATCH(31), - INIT_BATCH(32), - INIT_BATCH(33), - INIT_BATCH(34), - INIT_BATCH(35), - INIT_BATCH(36), - INIT_BATCH(37), - INIT_BATCH(38), - INIT_BATCH(39), - INIT_BATCH(40), - INIT_BATCH(41), - INIT_BATCH(42), - INIT_BATCH(43), - INIT_BATCH(44), - INIT_BATCH(45), - INIT_BATCH(46), - INIT_BATCH(47), - INIT_BATCH(48), - INIT_BATCH(49), - INIT_BATCH(50), - INIT_BATCH(51), - INIT_BATCH(52), - INIT_BATCH(53), - INIT_BATCH(54), - INIT_BATCH(55), - INIT_BATCH(56), - INIT_BATCH(57), - INIT_BATCH(58), - INIT_BATCH(59), -}; - - -static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) -{ - struct pvr2_sysfs_ctl_item *cip; - struct pvr2_sysfs_func_set *fp; - struct pvr2_ctrl *cptr; - unsigned int cnt,acnt; - - if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { - return; - } - - fp = funcs + ctl_id; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); - if (!cptr) return; - - cip = kmalloc(sizeof(*cip),GFP_KERNEL); - if (!cip) return; - memset(cip,0,sizeof(*cip)); - pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); - - cip->cptr = cptr; - - cip->chptr = sfp; - cip->item_next = 0; - if (sfp->item_last) { - sfp->item_last->item_next = cip; - } else { - sfp->item_first = cip; - } - sfp->item_last = cip; - - cip->attr_name.attr.owner = THIS_MODULE; - cip->attr_name.attr.name = "name"; - cip->attr_name.attr.mode = S_IRUGO; - cip->attr_name.show = fp->show_name; - - cip->attr_type.attr.owner = THIS_MODULE; - cip->attr_type.attr.name = "type"; - cip->attr_type.attr.mode = S_IRUGO; - cip->attr_type.show = fp->show_type; - - cip->attr_min.attr.owner = THIS_MODULE; - cip->attr_min.attr.name = "min_val"; - cip->attr_min.attr.mode = S_IRUGO; - cip->attr_min.show = fp->show_min; - - cip->attr_max.attr.owner = THIS_MODULE; - cip->attr_max.attr.name = "max_val"; - cip->attr_max.attr.mode = S_IRUGO; - cip->attr_max.show = fp->show_max; - - cip->attr_val.attr.owner = THIS_MODULE; - cip->attr_val.attr.name = "cur_val"; - cip->attr_val.attr.mode = S_IRUGO; - - cip->attr_custom.attr.owner = THIS_MODULE; - cip->attr_custom.attr.name = "custom_val"; - cip->attr_custom.attr.mode = S_IRUGO; - - cip->attr_enum.attr.owner = THIS_MODULE; - cip->attr_enum.attr.name = "enum_val"; - cip->attr_enum.attr.mode = S_IRUGO; - cip->attr_enum.show = fp->show_enum; - - cip->attr_bits.attr.owner = THIS_MODULE; - cip->attr_bits.attr.name = "bit_val"; - cip->attr_bits.attr.mode = S_IRUGO; - cip->attr_bits.show = fp->show_bits; - - if (pvr2_ctrl_is_writable(cptr)) { - cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; - cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP; - } - - acnt = 0; - cip->attr_gen[acnt++] = &cip->attr_name.attr; - cip->attr_gen[acnt++] = &cip->attr_type.attr; - cip->attr_gen[acnt++] = &cip->attr_val.attr; - cip->attr_val.show = fp->show_val_norm; - cip->attr_val.store = fp->store_val_norm; - if (pvr2_ctrl_has_custom_symbols(cptr)) { - cip->attr_gen[acnt++] = &cip->attr_custom.attr; - cip->attr_custom.show = fp->show_val_custom; - cip->attr_custom.store = fp->store_val_custom; - } - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - // Control is an enumeration - cip->attr_gen[acnt++] = &cip->attr_enum.attr; - break; - case pvr2_ctl_int: - // Control is an integer - cip->attr_gen[acnt++] = &cip->attr_min.attr; - cip->attr_gen[acnt++] = &cip->attr_max.attr; - break; - case pvr2_ctl_bitmask: - // Control is an bitmask - cip->attr_gen[acnt++] = &cip->attr_bits.attr; - break; - default: break; - } - - cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s", - pvr2_ctrl_get_name(cptr)); - cip->name[cnt] = 0; - cip->grp.name = cip->name; - cip->grp.attrs = cip->attr_gen; - - sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); -} - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct class_device *,char *); -static ssize_t debugcmd_show(struct class_device *,char *); -static ssize_t debugcmd_store(struct class_device *,const char *,size_t count); - -static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_debugifc *dip; - dip = kmalloc(sizeof(*dip),GFP_KERNEL); - if (!dip) return; - memset(dip,0,sizeof(*dip)); - dip->attr_debugcmd.attr.owner = THIS_MODULE; - dip->attr_debugcmd.attr.name = "debugcmd"; - dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; - dip->attr_debugcmd.show = debugcmd_show; - dip->attr_debugcmd.store = debugcmd_store; - dip->attr_debuginfo.attr.owner = THIS_MODULE; - dip->attr_debuginfo.attr.name = "debuginfo"; - dip->attr_debuginfo.attr.mode = S_IRUGO; - dip->attr_debuginfo.show = debuginfo_show; - sfp->debugifc = dip; - class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); - class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); -} - - -static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) -{ - if (!sfp->debugifc) return; - class_device_remove_file(sfp->class_dev, - &sfp->debugifc->attr_debuginfo); - class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd); - kfree(sfp->debugifc); - sfp->debugifc = 0; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp) -{ - unsigned int idx,cnt; - cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw); - for (idx = 0; idx < cnt; idx++) { - pvr2_sysfs_add_control(sfp,idx); - } -} - - -static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_ctl_item *cip1,*cip2; - for (cip1 = sfp->item_first; cip1; cip1 = cip2) { - cip2 = cip1->item_next; - sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); - pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); - kfree(cip1); - } -} - - -static void pvr2_sysfs_class_release(struct class *class) -{ - struct pvr2_sysfs_class *clp; - clp = container_of(class,struct pvr2_sysfs_class,class); - pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); - kfree(clp); -} - - -static void pvr2_sysfs_release(struct class_device *class_dev) -{ - pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); - kfree(class_dev); -} - - -static void class_dev_destroy(struct pvr2_sysfs *sfp) -{ - if (!sfp->class_dev) return; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_tear_down_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - pvr2_sysfs_tear_down_controls(sfp); - class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number); - class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number); - pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); - sfp->class_dev->class_data = 0; - class_device_unregister(sfp->class_dev); - sfp->class_dev = 0; -} - - -static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw)); -} - - -static ssize_t unit_number_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_get_unit_number(sfp->channel.hdw)); -} - - -static void class_dev_create(struct pvr2_sysfs *sfp, - struct pvr2_sysfs_class *class_ptr) -{ - struct usb_device *usb_dev; - struct class_device *class_dev; - usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); - if (!usb_dev) return; - class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); - if (!class_dev) return; - memset(class_dev,0,sizeof(*class_dev)); - - pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); - - class_dev->class = &class_ptr->class; - if (pvr2_hdw_get_sn(sfp->channel.hdw)) { - snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu", - pvr2_hdw_get_sn(sfp->channel.hdw)); - } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) { - snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c", - pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a'); - } else { - kfree(class_dev); - return; - } - - class_dev->dev = &usb_dev->dev; - - sfp->class_dev = class_dev; - class_dev->class_data = sfp; - class_device_register(class_dev); - - sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; - sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; - sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; - sfp->attr_v4l_minor_number.show = v4l_minor_number_show; - sfp->attr_v4l_minor_number.store = 0; - class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); - sfp->attr_unit_number.attr.owner = THIS_MODULE; - sfp->attr_unit_number.attr.name = "unit_number"; - sfp->attr_unit_number.attr.mode = S_IRUGO; - sfp->attr_unit_number.show = unit_number_show; - sfp->attr_unit_number.store = 0; - class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); - - pvr2_sysfs_add_controls(sfp); -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_add_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ -} - - -static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_sysfs *sfp; - sfp = container_of(chp,struct pvr2_sysfs,channel); - if (!sfp->channel.mc_head->disconnect_flag) return; - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp); - class_dev_destroy(sfp); - pvr2_channel_done(&sfp->channel); - kfree(sfp); -} - - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, - struct pvr2_sysfs_class *class_ptr) -{ - struct pvr2_sysfs *sfp; - sfp = kmalloc(sizeof(*sfp),GFP_KERNEL); - if (!sfp) return sfp; - memset(sfp,0,sizeof(*sfp)); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); - pvr2_channel_init(&sfp->channel,mp); - sfp->channel.check_func = pvr2_sysfs_internal_check; - - class_dev_create(sfp,class_ptr); - return sfp; -} - - -static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp, - int numenvp,char *buf,int size) -{ - /* Even though we don't do anything here, we still need this function - because sysfs will still try to call it. */ - return 0; -} - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) -{ - struct pvr2_sysfs_class *clp; - clp = kmalloc(sizeof(*clp),GFP_KERNEL); - if (!clp) return clp; - memset(clp,0,sizeof(*clp)); - pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); - clp->class.name = "pvrusb2"; - clp->class.class_release = pvr2_sysfs_class_release; - clp->class.release = pvr2_sysfs_release; - clp->class.uevent = pvr2_sysfs_hotplug; - if (class_register(&clp->class)) { - pvr2_sysfs_trace( - "Registration failed for pvr2_sysfs_class id=%p",clp); - kfree(clp); - clp = 0; - } - return clp; -} - - -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) -{ - class_unregister(&clp->class); -} - - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - pvr2_hdw_trigger_module_log(sfp->channel.hdw); - return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_store(struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - - ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count); - if (ret < 0) return ret; - return count; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h deleted file mode 100644 index ff9373b47f8f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_SYSFS_H -#define __PVRUSB2_SYSFS_H - -#include -#include -#include "pvrusb2-context.h" - -struct pvr2_sysfs; -struct pvr2_sysfs_class; - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, - struct pvr2_sysfs_class *); - -#endif /* __PVRUSB2_SYSFS_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c deleted file mode 100644 index f4aba8144ce0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "pvrusb2.h" -#include "pvrusb2-util.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - -struct pvr2_tuner_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - int type_update_fl; -}; - - -static void set_type(struct pvr2_tuner_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct tuner_setup setup; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type); - if (((int)(hdw->tuner_type)) < 0) return; - - setup.addr = ADDR_UNSET; - setup.type = hdw->tuner_type; - setup.mode_mask = T_RADIO | T_ANALOG_TV; - /* We may really want mode_mask to be T_ANALOG_TV for now */ - pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup); - ctxt->type_update_fl = 0; -} - - -static int tuner_check(struct pvr2_tuner_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - if (hdw->tuner_updated) ctxt->type_update_fl = !0; - return ctxt->type_update_fl != 0; -} - - -static void tuner_update(struct pvr2_tuner_handler *ctxt) -{ - if (ctxt->type_update_fl) set_type(ctxt); -} - - -static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-tuner"); -} - - -const static struct pvr2_i2c_handler_functions tuner_funcs = { - .detach = (void (*)(void *))pvr2_tuner_detach, - .check = (int (*)(void *))tuner_check, - .update = (void (*)(void *))tuner_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe, -}; - - -int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_tuner_handler *ctxt; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &tuner_funcs; - ctxt->type_update_fl = !0; - ctxt->client = cp; - ctxt->hdw = hdw; - cp->handler = &ctxt->i2c_handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h deleted file mode 100644 index 556f12aa9160..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_TUNER_H -#define __PVRUSB2_TUNER_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_TUNER_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h deleted file mode 100644 index e53aee416f56..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_UTIL_H -#define __PVRUSB2_UTIL_H - -#define PVR2_DECOMPOSE_LE(t,i,d) \ - do { \ - (t)[i] = (d) & 0xff;\ - (t)[i+1] = ((d) >> 8) & 0xff;\ - (t)[i+2] = ((d) >> 16) & 0xff;\ - (t)[i+3] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_DECOMPOSE_BE(t,i,d) \ - do { \ - (t)[i+3] = (d) & 0xff;\ - (t)[i+2] = ((d) >> 8) & 0xff;\ - (t)[i+1] = ((d) >> 16) & 0xff;\ - (t)[i] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_COMPOSE_LE(t,i) \ - ((((u32)((t)[i+3])) << 24) | \ - (((u32)((t)[i+2])) << 16) | \ - (((u32)((t)[i+1])) << 8) | \ - ((u32)((t)[i]))) - -#define PVR2_COMPOSE_BE(t,i) \ - ((((u32)((t)[i])) << 24) | \ - (((u32)((t)[i+1])) << 16) | \ - (((u32)((t)[i+2])) << 8) | \ - ((u32)((t)[i+3]))) - - -#endif /* __PVRUSB2_UTIL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c deleted file mode 100644 index 961951010c27..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include "pvrusb2-context.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#include "pvrusb2-ioread.h" -#include -#include - -struct pvr2_v4l2_dev; -struct pvr2_v4l2_fh; -struct pvr2_v4l2; - -/* V4L no longer provide the ability to set / get a private context pointer - (i.e. video_get_drvdata / video_set_drvdata), which means we have to - concoct our own context locating mechanism. Supposedly this is intended - to simplify driver implementation. It's not clear to me how that can - possibly be true. Our solution here is to maintain a lookup table of - our context instances, indexed by the minor device number of the V4L - device. See pvr2_v4l2_open() for some implications of this approach. */ -static struct pvr2_v4l2_dev *devices[256]; -static DEFINE_MUTEX(device_lock); - -struct pvr2_v4l2_dev { - struct pvr2_v4l2 *v4lp; - struct video_device *vdev; - struct pvr2_context_stream *stream; - int ctxt_idx; - enum pvr2_config config; -}; - -struct pvr2_v4l2_fh { - struct pvr2_channel channel; - struct pvr2_v4l2_dev *dev_info; - enum v4l2_priority prio; - struct pvr2_ioread *rhp; - struct file *file; - struct pvr2_v4l2 *vhead; - struct pvr2_v4l2_fh *vnext; - struct pvr2_v4l2_fh *vprev; - wait_queue_head_t wait_data; - int fw_mode_flag; -}; - -struct pvr2_v4l2 { - struct pvr2_channel channel; - struct pvr2_v4l2_fh *vfirst; - struct pvr2_v4l2_fh *vlast; - - struct v4l2_prio_state prio; - - /* streams */ - struct pvr2_v4l2_dev video_dev; -}; - -static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; -module_param_array(video_nr, int, NULL, 0444); -MODULE_PARM_DESC(video_nr, "Offset for device's minor"); - -struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = KERNEL_VERSION(0,8,0), - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE), - .reserved = {0,0,0,0} -}; - -static struct v4l2_tuner pvr_v4l2_tuners[]= { - { - .index = 0, - .name = "TV Tuner", - .type = V4L2_TUNER_ANALOG_TV, - .capability = (V4L2_TUNER_CAP_NORM | - V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2), - .rangelow = 0, - .rangehigh = 0, - .rxsubchans = V4L2_TUNER_SUB_STEREO, - .audmode = V4L2_TUNER_MODE_STEREO, - .signal = 0, - .afc = 0, - .reserved = {0,0,0,0} - } -}; - -struct v4l2_fmtdesc pvr_fmtdesc [] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .description = "MPEG1/2", - // This should really be V4L2_PIX_FMT_MPEG, but xawtv - // breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - .reserved = { 0, 0, 0, 0 } - } -}; - -#define PVR_FORMAT_PIX 0 -#define PVR_FORMAT_VBI 1 - -struct v4l2_format pvr_format [] = { - [PVR_FORMAT_PIX] = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .fmt = { - .pix = { - .width = 720, - .height = 576, - // This should really be V4L2_PIX_FMT_MPEG, - // but xawtv breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - .field = V4L2_FIELD_INTERLACED, - .bytesperline = 0, // doesn't make sense - // here - //FIXME : Don't know what to put here... - .sizeimage = (32*1024), - .colorspace = 0, // doesn't make sense here - .priv = 0 - } - } - }, - [PVR_FORMAT_VBI] = { - .type = V4L2_BUF_TYPE_VBI_CAPTURE, - .fmt = { - .vbi = { - .sampling_rate = 27000000, - .offset = 248, - .samples_per_line = 1443, - .sample_format = V4L2_PIX_FMT_GREY, - .start = { 0, 0 }, - .count = { 0, 0 }, - .flags = 0, - .reserved = { 0, 0 } - } - } - } -}; - -/* - * pvr_ioctl() - * - * This is part of Video 4 Linux API. The procedure handles ioctl() calls. - * - */ -static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - struct pvr2_v4l2_dev *dev_info = fh->dev_info; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int ret = -EINVAL; - - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); - } - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ioctl failed - bad or no context"); - return -EFAULT; - } - - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - ret = v4l2_prio_check(&vp->prio, &fh->prio); - if (ret) - return ret; - } - - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); - - ret = 0; - break; - } - - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p = arg; - - *p = v4l2_prio_max(&vp->prio); - ret = 0; - break; - } - - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *prio = arg; - - ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio); - break; - } - - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *vs = (struct v4l2_standard *)arg; - int idx = vs->index; - ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1); - break; - } - - case VIDIOC_G_STD: - { - int val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val); - *(v4l2_std_id *)arg = val; - break; - } - - case VIDIOC_S_STD: - { - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR), - *(v4l2_std_id *)arg); - break; - } - - case VIDIOC_ENUMINPUT: - { - struct pvr2_ctrl *cptr; - struct v4l2_input *vi = (struct v4l2_input *)arg; - struct v4l2_input tmp; - unsigned int cnt; - - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); - - memset(&tmp,0,sizeof(tmp)); - tmp.index = vi->index; - ret = 0; - switch (vi->index) { - case PVR2_CVAL_INPUT_TV: - case PVR2_CVAL_INPUT_RADIO: - tmp.type = V4L2_INPUT_TYPE_TUNER; - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - tmp.type = V4L2_INPUT_TYPE_CAMERA; - break; - default: - ret = -EINVAL; - break; - } - if (ret < 0) break; - - cnt = 0; - pvr2_ctrl_get_valname(cptr,vi->index, - tmp.name,sizeof(tmp.name)-1,&cnt); - tmp.name[cnt] = 0; - - /* Don't bother with audioset, since this driver currently - always switches the audio whenever the video is - switched. */ - - /* Handling std is a tougher problem. It doesn't make - sense in cases where a device might be multi-standard. - We could just copy out the current value for the - standard, but it can change over time. For now just - leave it zero. */ - - memcpy(vi, &tmp, sizeof(tmp)); - - ret = 0; - break; - } - - case VIDIOC_G_INPUT: - { - struct pvr2_ctrl *cptr; - struct v4l2_input *vi = (struct v4l2_input *)arg; - int val; - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); - val = 0; - ret = pvr2_ctrl_get_value(cptr,&val); - vi->index = val; - break; - } - - case VIDIOC_S_INPUT: - { - struct v4l2_input *vi = (struct v4l2_input *)arg; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), - vi->index); - break; - } - - case VIDIOC_ENUMAUDIO: - { - ret = -EINVAL; - break; - } - - case VIDIOC_G_AUDIO: - { - ret = -EINVAL; - break; - } - - case VIDIOC_S_AUDIO: - { - ret = -EINVAL; - break; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; - unsigned int status_mask; - int val; - if (vt->index !=0) break; - - status_mask = pvr2_hdw_get_signal_status(hdw); - - memcpy(vt, &pvr_v4l2_tuners[vt->index], - sizeof(struct v4l2_tuner)); - - vt->signal = 0; - if (status_mask & PVR2_SIGNAL_OK) { - if (status_mask & PVR2_SIGNAL_STEREO) { - vt->rxsubchans = V4L2_TUNER_SUB_STEREO; - } else { - vt->rxsubchans = V4L2_TUNER_SUB_MONO; - } - if (status_mask & PVR2_SIGNAL_SAP) { - vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 | - V4L2_TUNER_SUB_LANG2); - } - vt->signal = 65535; - } - - val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), - &val); - vt->audmode = val; - break; - } - - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; - - if (vt->index != 0) - break; - - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), - vt->audmode); - } - - case VIDIOC_S_FREQUENCY: - { - const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), - vf->frequency * 62500); - break; - } - - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; - int val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), - &val); - val /= 62500; - vf->frequency = val; - break; - } - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg; - - /* Only one format is supported : mpeg.*/ - if (fd->index != 0) - break; - - memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc)); - ret = 0; - break; - } - - case VIDIOC_G_FMT: - { - struct v4l2_format *vf = (struct v4l2_format *)arg; - int val; - switch(vf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], - sizeof(struct v4l2_format)); - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES), - &val); - vf->fmt.pix.width = val; - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES), - &val); - vf->fmt.pix.height = val; - ret = 0; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - // ????? Still need to figure out to do VBI correctly - ret = -EINVAL; - break; - default: - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: - { - struct v4l2_format *vf = (struct v4l2_format *)arg; - - ret = 0; - switch(vf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - int h = vf->fmt.pix.height; - int w = vf->fmt.pix.width; - - if (h < 200) { - h = 200; - } else if (h > 625) { - h = 625; - } - if (w < 320) { - w = 320; - } else if (w > 720) { - w = 720; - } - - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], - sizeof(struct v4l2_format)); - vf->fmt.pix.width = w; - vf->fmt.pix.height = h; - - if (cmd == VIDIOC_S_FMT) { - pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_HRES), - vf->fmt.pix.width); - pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_VRES), - vf->fmt.pix.height); - } - } break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - // ????? Still need to figure out to do VBI correctly - ret = -EINVAL; - break; - default: - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_STREAMON: - { - ret = pvr2_hdw_set_stream_type(hdw,dev_info->config); - if (ret < 0) return ret; - ret = pvr2_hdw_set_streaming(hdw,!0); - break; - } - - case VIDIOC_STREAMOFF: - { - ret = pvr2_hdw_set_streaming(hdw,0); - break; - } - - case VIDIOC_QUERYCTRL: - { - struct pvr2_ctrl *cptr; - struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; - ret = 0; - if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { - cptr = pvr2_hdw_get_ctrl_nextv4l( - hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); - if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr); - } else { - cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id); - } - if (!cptr) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x not implemented here", - vc->id); - ret = -EINVAL; - break; - } - - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x mapping name=%s (%s)", - vc->id,pvr2_ctrl_get_name(cptr), - pvr2_ctrl_get_desc(cptr)); - strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); - vc->flags = pvr2_ctrl_get_v4lflags(cptr); - vc->default_value = pvr2_ctrl_get_def(cptr); - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - vc->type = V4L2_CTRL_TYPE_MENU; - vc->minimum = 0; - vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; - vc->step = 1; - break; - case pvr2_ctl_bool: - vc->type = V4L2_CTRL_TYPE_BOOLEAN; - vc->minimum = 0; - vc->maximum = 1; - vc->step = 1; - break; - case pvr2_ctl_int: - vc->type = V4L2_CTRL_TYPE_INTEGER; - vc->minimum = pvr2_ctrl_get_min(cptr); - vc->maximum = pvr2_ctrl_get_max(cptr); - vc->step = 1; - break; - default: - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x name=%s not mappable", - vc->id,pvr2_ctrl_get_name(cptr)); - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_QUERYMENU: - { - struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg; - unsigned int cnt = 0; - ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id), - vm->index, - vm->name,sizeof(vm->name)-1, - &cnt); - vm->name[cnt] = 0; - break; - } - - case VIDIOC_G_CTRL: - { - struct v4l2_control *vc = (struct v4l2_control *)arg; - int val = 0; - ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), - &val); - vc->value = val; - break; - } - - case VIDIOC_S_CTRL: - { - struct v4l2_control *vc = (struct v4l2_control *)arg; - ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), - vc->value); - break; - } - - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - unsigned int idx; - int val; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val); - if (ret) { - ctls->error_idx = idx; - break; - } - /* Ensure that if read as a 64 bit value, the user - will still get a hopefully sane value */ - ctrl->value64 = 0; - ctrl->value = val; - } - break; - } - - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - unsigned int idx; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id), - ctrl->value); - if (ret) { - ctls->error_idx = idx; - break; - } - } - break; - } - - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - struct pvr2_ctrl *pctl; - unsigned int idx; - /* For the moment just validate that the requested control - actually exists. */ - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id); - if (!pctl) { - ret = -EINVAL; - ctls->error_idx = idx; - break; - } - } - break; - } - - case VIDIOC_LOG_STATUS: - { - pvr2_hdw_trigger_module_log(hdw); - ret = 0; - break; - } - - default : - ret = v4l_compat_translate_ioctl(inode,file,cmd, - arg,pvr2_v4l2_do_ioctl); - } - - pvr2_hdw_commit_ctl(hdw); - - if (ret < 0) { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d",ret); - } else { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d" - " command was:",ret); - v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), - cmd); - } - } - } else { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)", - ret,ret); - } - return ret; -} - - -static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) -{ - pvr2_trace(PVR2_TRACE_INIT, - "unregistering device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); - if (dip->ctxt_idx >= 0) { - mutex_lock(&device_lock); - devices[dip->ctxt_idx] = NULL; - dip->ctxt_idx = -1; - mutex_unlock(&device_lock); - } - video_unregister_device(dip->vdev); -} - - -static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) -{ - pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1); - pvr2_v4l2_dev_destroy(&vp->video_dev); - - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); - pvr2_channel_done(&vp->channel); - kfree(vp); -} - - -void pvr2_v4l2_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_v4l2 *vp; - vp = container_of(chp,struct pvr2_v4l2,channel); - if (!vp->channel.mc_head->disconnect_flag) return; - if (vp->vfirst) return; - pvr2_v4l2_destroy_no_lock(vp); -} - - -int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - -/* Temporary hack : use ivtv api until a v4l2 one is available. */ -#define IVTV_IOC_G_CODEC 0xFFEE7703 -#define IVTV_IOC_S_CODEC 0xFFEE7704 - if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0; - return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl); -} - - -int pvr2_v4l2_release(struct inode *inode, struct file *file) -{ - struct pvr2_v4l2_fh *fhp = file->private_data; - struct pvr2_v4l2 *vp = fhp->vhead; - struct pvr2_context *mp = fhp->vhead->channel.mc_head; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); - - if (fhp->rhp) { - struct pvr2_stream *sp; - struct pvr2_hdw *hdw; - hdw = fhp->channel.mc_head->hdw; - pvr2_hdw_set_streaming(hdw,0); - sp = pvr2_ioread_get_stream(fhp->rhp); - if (sp) pvr2_stream_set_callback(sp,0,0); - pvr2_ioread_destroy(fhp->rhp); - fhp->rhp = 0; - } - v4l2_prio_close(&vp->prio, &fhp->prio); - file->private_data = NULL; - - pvr2_context_enter(mp); do { - if (fhp->vnext) { - fhp->vnext->vprev = fhp->vprev; - } else { - vp->vlast = fhp->vprev; - } - if (fhp->vprev) { - fhp->vprev->vnext = fhp->vnext; - } else { - vp->vfirst = fhp->vnext; - } - fhp->vnext = 0; - fhp->vprev = 0; - fhp->vhead = 0; - pvr2_channel_done(&fhp->channel); - pvr2_trace(PVR2_TRACE_STRUCT, - "Destroying pvr_v4l2_fh id=%p",fhp); - kfree(fhp); - if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { - pvr2_v4l2_destroy_no_lock(vp); - } - } while (0); pvr2_context_exit(mp); - return 0; -} - - -int pvr2_v4l2_open(struct inode *inode, struct file *file) -{ - struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */ - struct pvr2_v4l2_fh *fhp; - struct pvr2_v4l2 *vp; - struct pvr2_hdw *hdw; - - mutex_lock(&device_lock); - /* MCI 7-Jun-2006 Even though we're just doing what amounts to an - atomic read of the device mapping array here, we still need the - mutex. The problem is that there is a tiny race possible when - we register the device. We can't update the device mapping - array until after the device has been registered, owing to the - fact that we can't know the minor device number until after the - registration succeeds. And if another thread tries to open the - device in the window of time after registration but before the - map is updated, then it will get back an erroneous null pointer - and the open will result in a spurious failure. The only way to - prevent that is to (a) be inside the mutex here before we access - the array, and (b) cover the entire registration process later - on with this same mutex. Thus if we get inside the mutex here, - then we can be assured that the registration process actually - completed correctly. This is an unhappy complication from the - use of global data in a driver that lives in a preemptible - environment. It sure would be nice if the video device itself - had a means for storing and retrieving a local context pointer. - Oh wait. It did. But now it's gone. Silly me. */ - { - unsigned int midx = iminor(file->f_dentry->d_inode); - if (midx < sizeof(devices)/sizeof(devices[0])) { - dip = devices[midx]; - } - } - mutex_unlock(&device_lock); - - if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */ - - vp = dip->v4lp; - hdw = vp->channel.hdw; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open"); - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_OPEN_CLOSE, - "pvr2_v4l2_open: hardware not ready"); - return -EIO; - } - - fhp = kmalloc(sizeof(*fhp),GFP_KERNEL); - if (!fhp) { - return -ENOMEM; - } - memset(fhp,0,sizeof(*fhp)); - - init_waitqueue_head(&fhp->wait_data); - fhp->dev_info = dip; - - pvr2_context_enter(vp->channel.mc_head); do { - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); - pvr2_channel_init(&fhp->channel,vp->channel.mc_head); - fhp->vnext = 0; - fhp->vprev = vp->vlast; - if (vp->vlast) { - vp->vlast->vnext = fhp; - } else { - vp->vfirst = fhp; - } - vp->vlast = fhp; - fhp->vhead = vp; - } while (0); pvr2_context_exit(vp->channel.mc_head); - - fhp->file = file; - file->private_data = fhp; - v4l2_prio_open(&vp->prio,&fhp->prio); - - fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); - - return 0; -} - - -static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) -{ - wake_up(&fhp->wait_data); -} - -static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) -{ - int ret; - struct pvr2_stream *sp; - struct pvr2_hdw *hdw; - if (fh->rhp) return 0; - - /* First read() attempt. Try to claim the stream and start - it... */ - if ((ret = pvr2_channel_claim_stream(&fh->channel, - fh->dev_info->stream)) != 0) { - /* Someone else must already have it */ - return ret; - } - - fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream); - if (!fh->rhp) { - pvr2_channel_claim_stream(&fh->channel,0); - return -ENOMEM; - } - - hdw = fh->channel.mc_head->hdw; - sp = fh->dev_info->stream->stream; - pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); - pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); - pvr2_hdw_set_streaming(hdw,!0); - ret = pvr2_ioread_set_enabled(fh->rhp,!0); - - return ret; -} - - -static ssize_t pvr2_v4l2_read(struct file *file, - char __user *buff, size_t count, loff_t *ppos) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - char *tbuf; - int c1,c2; - int tcnt = 0; - unsigned int offs = *ppos; - - tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL); - if (!tbuf) return -ENOMEM; - - while (count) { - c1 = count; - if (c1 > PAGE_SIZE) c1 = PAGE_SIZE; - c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1); - if (c2 < 0) { - tcnt = c2; - break; - } - if (!c2) break; - if (copy_to_user(buff,tbuf,c2)) { - tcnt = -EFAULT; - break; - } - offs += c2; - tcnt += c2; - buff += c2; - count -= c2; - *ppos += c2; - } - kfree(tbuf); - return tcnt; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) { - return ret; - } - } - - for (;;) { - ret = pvr2_ioread_read(fh->rhp,buff,count); - if (ret >= 0) break; - if (ret != -EAGAIN) break; - if (file->f_flags & O_NONBLOCK) break; - /* Doing blocking I/O. Wait here. */ - ret = wait_event_interruptible( - fh->wait_data, - pvr2_ioread_avail(fh->rhp) >= 0); - if (ret < 0) break; - } - - return ret; -} - - -static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) -{ - unsigned int mask = 0; - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - mask |= POLLIN | POLLRDNORM; - return mask; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) return POLLERR; - } - - poll_wait(file,&fh->wait_data,wait); - - if (pvr2_ioread_avail(fh->rhp) >= 0) { - mask |= POLLIN | POLLRDNORM; - } - - return mask; -} - - -static struct file_operations vdev_fops = { - .owner = THIS_MODULE, - .open = pvr2_v4l2_open, - .release = pvr2_v4l2_release, - .read = pvr2_v4l2_read, - .ioctl = pvr2_v4l2_ioctl, - .llseek = no_llseek, - .poll = pvr2_v4l2_poll, -}; - - -#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */ - -static struct video_device vdev_template = { - .owner = THIS_MODULE, - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, - .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE - | V4L2_CAP_TUNER | V4L2_CAP_AUDIO - | V4L2_CAP_READWRITE), - .hardware = VID_HARDWARE_PVRUSB2, - .fops = &vdev_fops, -}; - - -static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, - struct pvr2_v4l2 *vp, - enum pvr2_config cfg) -{ - int mindevnum; - int unit_number; - int v4l_type; - dip->v4lp = vp; - dip->config = cfg; - - - switch (cfg) { - case pvr2_config_mpeg: - v4l_type = VFL_TYPE_GRABBER; - dip->stream = &vp->channel.mc_head->video_stream; - break; - case pvr2_config_vbi: - v4l_type = VFL_TYPE_VBI; - break; - case pvr2_config_radio: - v4l_type = VFL_TYPE_RADIO; - break; - default: - /* Bail out (this should be impossible) */ - err("Failed to set up pvrusb2 v4l dev" - " due to unrecognized config"); - return; - } - - if (!dip->stream) { - err("Failed to set up pvrusb2 v4l dev" - " due to missing stream instance"); - return; - } - - dip->vdev = video_device_alloc(); - if (!dip->vdev) { - err("Alloc of pvrusb2 v4l video device failed"); - return; - } - - memcpy(dip->vdev,&vdev_template,sizeof(vdev_template)); - dip->vdev->release = video_device_release; - mutex_lock(&device_lock); - - mindevnum = -1; - unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - mindevnum = video_nr[unit_number]; - } - if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) && - (video_register_device(dip->vdev, v4l_type, -1) < 0)) { - err("Failed to register pvrusb2 v4l video device"); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "registered device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); - } - - if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) && - (devices[dip->vdev->minor] == NULL)) { - dip->ctxt_idx = dip->vdev->minor; - devices[dip->ctxt_idx] = dip; - } - mutex_unlock(&device_lock); - - pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, - dip->vdev->minor); -} - - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) -{ - struct pvr2_v4l2 *vp; - - vp = kmalloc(sizeof(*vp),GFP_KERNEL); - if (!vp) return vp; - memset(vp,0,sizeof(*vp)); - vp->video_dev.ctxt_idx = -1; - pvr2_channel_init(&vp->channel,mnp); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); - - vp->channel.check_func = pvr2_v4l2_internal_check; - - /* register streams */ - pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg); - - - return vp; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h deleted file mode 100644 index 9a995e2d2256..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_V4L2_H -#define __PVRUSB2_V4L2_H - -#include "pvrusb2-context.h" - -struct pvr2_v4l2; - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *); - -#endif /* __PVRUSB2_V4L2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c deleted file mode 100644 index e4ec7f25194c..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - - This source file is specifically designed to interface with the - saa711x support that is available in the v4l available starting - with linux 2.6.15. - -*/ - -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -struct pvr2_v4l_decoder { - struct pvr2_i2c_handler handler; - struct pvr2_decoder_ctrl ctrl; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); - switch(hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - route.input = SAA7115_COMPOSITE4; - break; - case PVR2_CVAL_INPUT_COMPOSITE: - route.input = SAA7115_COMPOSITE5; - break; - case PVR2_CVAL_INPUT_SVIDEO: - route.input = SAA7115_SVIDEO2; - break; - case PVR2_CVAL_INPUT_RADIO: - // ????? No idea yet what to do here - default: - return; - } - route.output = 0; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); -} - - -static int check_input(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -static void set_audio(struct pvr2_v4l_decoder *ctxt) -{ - u32 val; - struct pvr2_hdw *hdw = ctxt->hdw; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); -} - - -static int check_audio(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->srate_dirty != 0; -} - - -struct pvr2_v4l_decoder_ops { - void (*update)(struct pvr2_v4l_decoder *); - int (*check)(struct pvr2_v4l_decoder *); -}; - - -static const struct pvr2_v4l_decoder_ops decoder_ops[] = { - { .update = set_input, .check = check_input}, - { .update = set_audio, .check = check_audio}, -}; - - -static void decoder_detach(struct pvr2_v4l_decoder *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->decoder_ctrl = 0; - kfree(ctxt); -} - - -static int decoder_check(struct pvr2_v4l_decoder *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (decoder_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void decoder_update(struct pvr2_v4l_decoder *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - decoder_ops[idx].update(ctxt); - } -} - - -static int decoder_detect(struct pvr2_i2c_client *cp) -{ - /* Attempt to query the decoder - let's see if it will answer */ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt); - return ret == 0; /* Return true if it answered */ -} - - -static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); - pvr2_v4l2_cmd_stream(ctxt->client,fl); -} - - -static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt) -{ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (ret < 0) return -EINVAL; - return vt.signal ? 1 : 0; -} - - -static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))decoder_detach, - .check = (int (*)(void *))decoder_check, - .update = (void (*)(void *))decoder_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, -}; - - -int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, - struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_decoder *ctxt; - - if (hdw->decoder_ctrl) return 0; - if (cp->handler) return 0; - if (!decoder_detect(cp)) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->ctrl.ctxt = ctxt; - ctxt->ctrl.detach = (void (*)(void *))decoder_detach; - ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; - ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ - sizeof(decoder_ops[0]))) - 1; - hdw->decoder_ctrl = &ctxt->ctrl; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h deleted file mode 100644 index 2b917fda02e4..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_VIDEO_V4L_H -#define __PVRUSB2_VIDEO_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles device video processing. This interface is - used internally by the driver; higher level code should only - interact through the interface provided by pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_VIDEO_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c deleted file mode 100644 index fcad346e3955..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - - This source file is specifically designed to interface with the - wm8775. - -*/ - -#include "pvrusb2-wm8775.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - -struct pvr2_v4l_wm8775 { - struct pvr2_i2c_handler handler; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_wm8775 *ctxt) -{ - struct v4l2_routing route; - struct pvr2_hdw *hdw = ctxt->hdw; - int msk = 0; - - memset(&route,0,sizeof(route)); - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)", - hdw->input_val,msk); - - // Always point to input #1 no matter what - route.input = 2; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - -static int check_input(struct pvr2_v4l_wm8775 *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -struct pvr2_v4l_wm8775_ops { - void (*update)(struct pvr2_v4l_wm8775 *); - int (*check)(struct pvr2_v4l_wm8775 *); -}; - - -static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = { - { .update = set_input, .check = check_input}, -}; - - -static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-wm8775"); -} - - -static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (wm8775_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - wm8775_ops[idx].update(ctxt); - } -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))wm8775_detach, - .check = (int (*)(void *))wm8775_check, - .update = (void (*)(void *))wm8775_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe, -}; - - -int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_wm8775 *ctxt; - - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/ - sizeof(wm8775_ops[0]))) - 1; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h deleted file mode 100644 index 8aaeff4e1e20..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_WM8775_H -#define __PVRUSB2_WM8775_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which performs analog -> digital audio conversion for - external audio inputs. This interface is used internally by the - driver; higher level code should only interact through the - interface provided by pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_WM8775_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2.h deleted file mode 100644 index 074533e9c21e..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_H -#define __PVRUSB2_H - -/* Maximum number of pvrusb2 instances we can track at once. You - might want to increase this - however the driver operation will not - be impaired if it is too small. Instead additional units just - won't have an ID assigned and it might not be possible to specify - module paramters for those extra units. */ -#define PVR_NUM 20 - -#endif /* __PVRUSB2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pwc/Kconfig b/trunk/drivers/media/video/pwc/Kconfig index 697145e0bf15..53cbc950f95c 100644 --- a/trunk/drivers/media/video/pwc/Kconfig +++ b/trunk/drivers/media/video/pwc/Kconfig @@ -7,7 +7,6 @@ config USB_PWC * Philips PCA645, PCA646 * Philips PCVC675, PCVC680, PCVC690 * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 - * Philips SPC900NC * Askey VC010 * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' and 'Orbit'/'Sphere' @@ -20,18 +19,10 @@ config USB_PWC and never will be, but the 665 and 720/20 are supported by other drivers. - Some newer logitech webcams are not handled by this driver but by the - Usb Video Class driver (linux-uvc). + See for more information and + installation instructions. The built-in microphone is enabled by selecting USB Audio support. To compile this driver as a module, choose M here: the module will be called pwc. - -config USB_PWC_DEBUG - bool "USB Philips Cameras verbose debug" - depends USB_PWC - help - Say Y here in order to have the pwc driver generate verbose debugging - messages. - A special module options 'trace' is used to control the verbosity. diff --git a/trunk/drivers/media/video/pwc/Makefile b/trunk/drivers/media/video/pwc/Makefile index 9db2260d10cc..33d60126c024 100644 --- a/trunk/drivers/media/video/pwc/Makefile +++ b/trunk/drivers/media/video/pwc/Makefile @@ -1,12 +1,3 @@ -pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o -pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o +pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o obj-$(CONFIG_USB_PWC) += pwc.o - -ifeq ($(CONFIG_USB_PWC_DEBUG),y) -EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1 -else -EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0 -endif - - diff --git a/trunk/drivers/media/video/pwc/pwc-ctrl.c b/trunk/drivers/media/video/pwc/pwc-ctrl.c index 0bd115588f31..4ba549bfa0e0 100644 --- a/trunk/drivers/media/video/pwc/pwc-ctrl.c +++ b/trunk/drivers/media/video/pwc/pwc-ctrl.c @@ -2,7 +2,7 @@ Functions that send various control messages to the webcam, including video modes. (C) 1999-2003 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -41,14 +41,12 @@ #include #endif #include -#include #include "pwc.h" +#include "pwc-ioctl.h" #include "pwc-uncompress.h" #include "pwc-kiara.h" #include "pwc-timon.h" -#include "pwc-dec1.h" -#include "pwc-dec23.h" /* Request types: video */ #define SET_LUM_CTL 0x01 @@ -59,10 +57,6 @@ #define GET_STATUS_CTL 0x06 #define SET_EP_STREAM_CTL 0x07 #define GET_EP_STREAM_CTL 0x08 -#define GET_XX_CTL 0x09 -#define SET_XX_CTL 0x0A -#define GET_XY_CTL 0x0B -#define SET_XY_CTL 0x0C #define SET_MPT_CTL 0x0D #define GET_MPT_CTL 0x0E @@ -99,20 +93,12 @@ #define READ_SHUTTER_FORMATTER 0x0600 #define READ_RED_GAIN_FORMATTER 0x0700 #define READ_BLUE_GAIN_FORMATTER 0x0800 -#define GET_STATUS_B00 0x0B00 #define SENSOR_TYPE_FORMATTER1 0x0C00 -#define GET_STATUS_3000 0x3000 #define READ_RAW_Y_MEAN_FORMATTER 0x3100 #define SET_POWER_SAVE_MODE_FORMATTER 0x3200 #define MIRROR_IMAGE_FORMATTER 0x3300 #define LED_FORMATTER 0x3400 -#define LOWLIGHT 0x3500 -#define GET_STATUS_3600 0x3600 #define SENSOR_TYPE_FORMATTER2 0x3700 -#define GET_STATUS_3800 0x3800 -#define GET_STATUS_4000 0x4000 -#define GET_STATUS_4100 0x4100 /* Get */ -#define CTL_STATUS_4200 0x4200 /* [GS] 1 */ /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */ #define VIDEO_OUTPUT_CONTROL_FORMATTER 0x0100 @@ -152,7 +138,6 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][8] = #include "pwc-nala.h" }; -static void pwc_set_image_buffer_size(struct pwc_device *pdev); /****************************************************************************/ @@ -174,7 +159,31 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev); &buf, buflen, 500) -static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) +#if PWC_DEBUG +void pwc_hexdump(void *p, int len) +{ + int i; + unsigned char *s; + char buf[100], *d; + + s = (unsigned char *)p; + d = buf; + *d = '\0'; + Debug("Doing hexdump @ %p, %d bytes.\n", p, len); + for (i = 0; i < len; i++) { + d += sprintf(d, "%02X ", *s++); + if ((i & 0xF) == 0xF) { + Debug("%s\n", buf); + d = buf; + *d = '\0'; + } + } + if ((i & 0xF) != 0) + Debug("%s\n", buf); +} +#endif + +static inline int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) { return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), @@ -187,7 +196,7 @@ static int send_video_command(struct usb_device *udev, int index, void *buf, int -static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) +static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) { unsigned char buf[3]; int ret, fps; @@ -220,14 +229,34 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) if (pEntry->alternate == 0) return -EINVAL; + if (pEntry->compressed) + return -ENOENT; /* Not supported. */ + memcpy(buf, pEntry->mode, 3); ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); if (ret < 0) { - PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); + Debug("Failed to send video command... %d\n", ret); return ret; } if (pEntry->compressed && pdev->vpalette != VIDEO_PALETTE_RAW) - pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); + { + switch(pdev->type) { + case 645: + case 646: +/* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ + break; + + case 675: + case 680: + case 690: + case 720: + case 730: + case 740: + case 750: +/* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ + break; + } + } pdev->cmd_len = 3; memcpy(pdev->cmd_buf, buf, 3); @@ -254,7 +283,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) } -static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) +static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) { unsigned char buf[13]; const struct Timon_table_entry *pChoose; @@ -286,8 +315,8 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i if (ret < 0) return ret; - if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pwc_dec23_init(pdev, pdev->type, buf); +/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) + pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ pdev->cmd_len = 13; memcpy(pdev->cmd_buf, buf, 13); @@ -307,7 +336,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i } -static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) +static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) { const struct Kiara_table_entry *pChoose = NULL; int fps, ret; @@ -321,14 +350,21 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i fps = (frames / 5) - 1; /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ - if (size == PSZ_VGA && frames == 5 && snapshot && pdev->vpalette == VIDEO_PALETTE_RAW) + if (size == PSZ_VGA && frames == 5 && snapshot) { /* Only available in case the raw palette is selected or we have the decompressor available. This mode is only available in compressed form */ - PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n"); - pChoose = &RawEntry; + if (pdev->vpalette == VIDEO_PALETTE_RAW) + { + Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); + pChoose = &RawEntry; + } + else + { + Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n"); + } } else { @@ -336,7 +372,6 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i if the preferred ratio is not available. Skip this step when using RAW modes. */ - snapshot = 0; while (compression <= 3) { pChoose = &Kiara_table[size][fps][compression]; if (pChoose->alternate != 0) @@ -347,7 +382,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i if (pChoose == NULL || pChoose->alternate == 0) return -ENOENT; /* Not supported. */ - PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate); + Debug("Using alternate setting %d.\n", pChoose->alternate); /* usb_control_msg won't take staticly allocated arrays as argument?? */ memcpy(buf, pChoose->mode, 12); @@ -359,8 +394,8 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i if (ret < 0) return ret; - if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pwc_dec23_init(pdev, pdev->type, buf); +/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) + pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ pdev->cmd_len = 12; memcpy(pdev->cmd_buf, buf, 12); @@ -375,13 +410,49 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; else pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; - PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n", - pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength); return 0; } +static void pwc_set_image_buffer_size(struct pwc_device *pdev) +{ + int i, factor = 0, filler = 0; + + /* for PALETTE_YUV420P */ + switch(pdev->vpalette) + { + case VIDEO_PALETTE_YUV420P: + factor = 6; + filler = 128; + break; + case VIDEO_PALETTE_RAW: + factor = 6; /* can be uncompressed YUV420P */ + filler = 0; + break; + } + + /* Set sizes in bytes */ + pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; + pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; + + /* Align offset, or you'll get some very weird results in + YUV420 mode... x must be multiple of 4 (to get the Y's in + place), and y even (or you'll mixup U & V). This is less of a + problem for YUV420P. + */ + pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; + pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; + + /* Fill buffers with gray or black */ + for (i = 0; i < MAX_IMAGES; i++) { + if (pdev->image_ptr[i] != NULL) + memset(pdev->image_ptr[i], filler, pdev->view.size); + } +} + + + /** @pdev: device structure @width: viewport width @@ -394,78 +465,50 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame { int ret, size; - PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); + Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); size = pwc_decode_size(pdev, width, height); if (size < 0) { - PWC_DEBUG_MODULE("Could not find suitable size.\n"); + Debug("Could not find suitable size.\n"); return -ERANGE; } - PWC_TRACE("decode_size = %d.\n", size); + Debug("decode_size = %d.\n", size); - if (DEVICE_USE_CODEC1(pdev->type)) { + ret = -EINVAL; + switch(pdev->type) { + case 645: + case 646: ret = set_video_mode_Nala(pdev, size, frames); + break; - } else if (DEVICE_USE_CODEC3(pdev->type)) { - ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); - - } else { + case 675: + case 680: + case 690: ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); + break; + + case 720: + case 730: + case 740: + case 750: + ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot); + break; } if (ret < 0) { - PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); + if (ret == -ENOENT) + Info("Video mode %s@%d fps is only supported with the decompressor module (pwcx).\n", size2name[size], frames); + else { + Err("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); + } return ret; } pdev->view.x = width; pdev->view.y = height; pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; pwc_set_image_buffer_size(pdev); - PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); + Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); return 0; } -#define BLACK_Y 0 -#define BLACK_U 128 -#define BLACK_V 128 - -static void pwc_set_image_buffer_size(struct pwc_device *pdev) -{ - int i, factor = 0; - - /* for PALETTE_YUV420P */ - switch(pdev->vpalette) - { - case VIDEO_PALETTE_YUV420P: - factor = 6; - break; - case VIDEO_PALETTE_RAW: - factor = 6; /* can be uncompressed YUV420P */ - break; - } - - /* Set sizes in bytes */ - pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; - pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; - - /* Align offset, or you'll get some very weird results in - YUV420 mode... x must be multiple of 4 (to get the Y's in - place), and y even (or you'll mixup U & V). This is less of a - problem for YUV420P. - */ - pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; - pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; - - /* Fill buffers with black colors */ - for (i = 0; i < pwc_mbufs; i++) { - unsigned char *p = pdev->image_data + pdev->images[i].offset; - memset(p, BLACK_Y, pdev->view.x * pdev->view.y); - p += pdev->view.x * pdev->view.y; - memset(p, BLACK_U, pdev->view.x * pdev->view.y/4); - p += pdev->view.x * pdev->view.y/4; - memset(p, BLACK_V, pdev->view.x * pdev->view.y/4); - } -} - - /* BRIGHTNESS */ @@ -477,7 +520,7 @@ int pwc_get_brightness(struct pwc_device *pdev) ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); if (ret < 0) return ret; - return buf; + return buf << 9; } int pwc_set_brightness(struct pwc_device *pdev, int value) @@ -502,7 +545,7 @@ int pwc_get_contrast(struct pwc_device *pdev) ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); if (ret < 0) return ret; - return buf; + return buf << 10; } int pwc_set_contrast(struct pwc_device *pdev, int value) @@ -527,7 +570,7 @@ int pwc_get_gamma(struct pwc_device *pdev) ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); if (ret < 0) return ret; - return buf; + return buf << 11; } int pwc_set_gamma(struct pwc_device *pdev, int value) @@ -545,47 +588,37 @@ int pwc_set_gamma(struct pwc_device *pdev, int value) /* SATURATION */ -/* return a value between [-100 , 100] */ -int pwc_get_saturation(struct pwc_device *pdev, int *value) +int pwc_get_saturation(struct pwc_device *pdev) { char buf; - int ret, saturation_register; + int ret; if (pdev->type < 675) - return -EINVAL; - if (pdev->type < 730) - saturation_register = SATURATION_MODE_FORMATTER2; - else - saturation_register = SATURATION_MODE_FORMATTER1; - ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1); + return -1; + ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); if (ret < 0) return ret; - *value = (signed)buf; - return 0; + return 32768 + buf * 327; } -/* @param value saturation color between [-100 , 100] */ int pwc_set_saturation(struct pwc_device *pdev, int value) { char buf; - int saturation_register; if (pdev->type < 675) return -EINVAL; - if (value < -100) - value = -100; - if (value > 100) - value = 100; - if (pdev->type < 730) - saturation_register = SATURATION_MODE_FORMATTER2; - else - saturation_register = SATURATION_MODE_FORMATTER1; - return SendControlMsg(SET_CHROM_CTL, saturation_register, 1); + if (value < 0) + value = 0; + if (value > 0xffff) + value = 0xffff; + /* saturation ranges from -100 to +100 */ + buf = (value - 32768) / 327; + return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); } /* AGC */ -int pwc_set_agc(struct pwc_device *pdev, int mode, int value) +static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value) { char buf; int ret; @@ -610,7 +643,7 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value) return 0; } -int pwc_get_agc(struct pwc_device *pdev, int *value) +static inline int pwc_get_agc(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -640,7 +673,7 @@ int pwc_get_agc(struct pwc_device *pdev, int *value) return 0; } -int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) +static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) { char buf[2]; int speed, ret; @@ -658,16 +691,23 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) value = 0; if (value > 0xffff) value = 0xffff; - - if (DEVICE_USE_CODEC2(pdev->type)) { + switch(pdev->type) { + case 675: + case 680: + case 690: /* speed ranges from 0x0 to 0x290 (656) */ speed = (value / 100); buf[1] = speed >> 8; buf[0] = speed & 0xff; - } else if (DEVICE_USE_CODEC3(pdev->type)) { + break; + case 720: + case 730: + case 740: + case 750: /* speed seems to range from 0x0 to 0xff */ buf[1] = 0; buf[0] = value >> 8; + break; } ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); @@ -675,25 +715,6 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) return ret; } -/* This function is not exported to v4l1, so output values between 0 -> 256 */ -int pwc_get_shutter_speed(struct pwc_device *pdev, int *value) -{ - unsigned char buf[2]; - int ret; - - ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2); - if (ret < 0) - return ret; - *value = buf[0] + (buf[1] << 8); - if (DEVICE_USE_CODEC2(pdev->type)) { - /* speed ranges from 0x0 to 0x290 (656) */ - *value *= 256/656; - } else if (DEVICE_USE_CODEC3(pdev->type)) { - /* speed seems to range from 0x0 to 0xff */ - } - return 0; -} - /* POWER */ @@ -715,19 +736,19 @@ int pwc_camera_power(struct pwc_device *pdev, int power) /* private calls */ -int pwc_restore_user(struct pwc_device *pdev) +static inline int pwc_restore_user(struct pwc_device *pdev) { char buf; /* dummy */ return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); } -int pwc_save_user(struct pwc_device *pdev) +static inline int pwc_save_user(struct pwc_device *pdev) { char buf; /* dummy */ return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); } -int pwc_restore_factory(struct pwc_device *pdev) +static inline int pwc_restore_factory(struct pwc_device *pdev) { char buf; /* dummy */ return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); @@ -745,7 +766,7 @@ int pwc_restore_factory(struct pwc_device *pdev) * 03: manual * 04: auto */ -int pwc_set_awb(struct pwc_device *pdev, int mode) +static inline int pwc_set_awb(struct pwc_device *pdev, int mode) { char buf; int ret; @@ -765,7 +786,7 @@ int pwc_set_awb(struct pwc_device *pdev, int mode) return 0; } -int pwc_get_awb(struct pwc_device *pdev) +static inline int pwc_get_awb(struct pwc_device *pdev) { unsigned char buf; int ret; @@ -777,7 +798,7 @@ int pwc_get_awb(struct pwc_device *pdev) return buf; } -int pwc_set_red_gain(struct pwc_device *pdev, int value) +static inline int pwc_set_red_gain(struct pwc_device *pdev, int value) { unsigned char buf; @@ -790,7 +811,7 @@ int pwc_set_red_gain(struct pwc_device *pdev, int value) return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); } -int pwc_get_red_gain(struct pwc_device *pdev, int *value) +static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -803,7 +824,7 @@ int pwc_get_red_gain(struct pwc_device *pdev, int *value) } -int pwc_set_blue_gain(struct pwc_device *pdev, int value) +static inline int pwc_set_blue_gain(struct pwc_device *pdev, int value) { unsigned char buf; @@ -816,7 +837,7 @@ int pwc_set_blue_gain(struct pwc_device *pdev, int value) return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); } -int pwc_get_blue_gain(struct pwc_device *pdev, int *value) +static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -833,7 +854,7 @@ int pwc_get_blue_gain(struct pwc_device *pdev, int *value) internal red/blue gains, which may be different from the manual gains set or read above. */ -static int pwc_read_red_gain(struct pwc_device *pdev, int *value) +static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -845,7 +866,7 @@ static int pwc_read_red_gain(struct pwc_device *pdev, int *value) return 0; } -static int pwc_read_blue_gain(struct pwc_device *pdev, int *value) +static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -858,7 +879,7 @@ static int pwc_read_blue_gain(struct pwc_device *pdev, int *value) } -static int pwc_set_wb_speed(struct pwc_device *pdev, int speed) +static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed) { unsigned char buf; @@ -867,7 +888,7 @@ static int pwc_set_wb_speed(struct pwc_device *pdev, int speed) return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); } -static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) +static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -880,7 +901,7 @@ static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) } -static int pwc_set_wb_delay(struct pwc_device *pdev, int delay) +static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay) { unsigned char buf; @@ -889,7 +910,7 @@ static int pwc_set_wb_delay(struct pwc_device *pdev, int delay) return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); } -static int pwc_get_wb_delay(struct pwc_device *pdev, int *value) +static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) { unsigned char buf; int ret; @@ -944,7 +965,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) return 0; } -int pwc_set_contour(struct pwc_device *pdev, int contour) +static inline int pwc_set_contour(struct pwc_device *pdev, int contour) { unsigned char buf; int ret; @@ -969,7 +990,7 @@ int pwc_set_contour(struct pwc_device *pdev, int contour) return 0; } -int pwc_get_contour(struct pwc_device *pdev, int *contour) +static inline int pwc_get_contour(struct pwc_device *pdev, int *contour) { unsigned char buf; int ret; @@ -991,7 +1012,7 @@ int pwc_get_contour(struct pwc_device *pdev, int *contour) } -int pwc_set_backlight(struct pwc_device *pdev, int backlight) +static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight) { unsigned char buf; @@ -1002,7 +1023,7 @@ int pwc_set_backlight(struct pwc_device *pdev, int backlight) return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); } -int pwc_get_backlight(struct pwc_device *pdev, int *backlight) +static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) { int ret; unsigned char buf; @@ -1010,35 +1031,12 @@ int pwc_get_backlight(struct pwc_device *pdev, int *backlight) ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); if (ret < 0) return ret; - *backlight = !!buf; + *backlight = buf; return 0; } -int pwc_set_colour_mode(struct pwc_device *pdev, int colour) -{ - unsigned char buf; - if (colour) - buf = 0xff; - else - buf = 0x0; - return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); -} - -int pwc_get_colour_mode(struct pwc_device *pdev, int *colour) -{ - int ret; - unsigned char buf; - - ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); - if (ret < 0) - return ret; - *colour = !!buf; - return 0; -} - - -int pwc_set_flicker(struct pwc_device *pdev, int flicker) +static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker) { unsigned char buf; @@ -1049,7 +1047,7 @@ int pwc_set_flicker(struct pwc_device *pdev, int flicker) return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); } -int pwc_get_flicker(struct pwc_device *pdev, int *flicker) +static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) { int ret; unsigned char buf; @@ -1057,11 +1055,12 @@ int pwc_get_flicker(struct pwc_device *pdev, int *flicker) ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); if (ret < 0) return ret; - *flicker = !!buf; + *flicker = buf; return 0; } -int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) + +static inline int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) { unsigned char buf; @@ -1073,7 +1072,7 @@ int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); } -int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) +static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) { int ret; unsigned char buf; @@ -1085,7 +1084,7 @@ int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) return 0; } -static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) +static int pwc_mpt_reset(struct pwc_device *pdev, int flags) { unsigned char buf; @@ -1093,18 +1092,7 @@ static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); } -int pwc_mpt_reset(struct pwc_device *pdev, int flags) -{ - int ret; - ret = _pwc_mpt_reset(pdev, flags); - if (ret >= 0) { - pdev->pan_angle = 0; - pdev->tilt_angle = 0; - } - return ret; -} - -static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) +static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) { unsigned char buf[4]; @@ -1122,35 +1110,7 @@ static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); } -int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) -{ - int ret; - - /* check absolute ranges */ - if (pan < pdev->angle_range.pan_min || - pan > pdev->angle_range.pan_max || - tilt < pdev->angle_range.tilt_min || - tilt > pdev->angle_range.tilt_max) - return -ERANGE; - - /* go to relative range, check again */ - pan -= pdev->pan_angle; - tilt -= pdev->tilt_angle; - /* angles are specified in degrees * 100, thus the limit = 36000 */ - if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000) - return -ERANGE; - - ret = _pwc_mpt_set_angle(pdev, pan, tilt); - if (ret >= 0) { - pdev->pan_angle += pan; - pdev->tilt_angle += tilt; - } - if (ret == -EPIPE) /* stall -> out of range */ - ret = -ERANGE; - return ret; -} - -static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) +static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status) { int ret; unsigned char buf[5]; @@ -1191,26 +1151,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) /* End of Add-Ons */ /* ************************************************* */ -/* Linux 2.5.something and 2.6 pass direct pointers to arguments of - ioctl() calls. With 2.4, you have to do tedious copy_from_user() - and copy_to_user() calls. With these macros we circumvent this, - and let me maintain only one source file. The functionality is - exactly the same otherwise. - */ - - -/* define local variable for arg */ -#define ARG_DEF(ARG_type, ARG_name)\ - ARG_type *ARG_name = arg; -/* copy arg to local variable */ -#define ARG_IN(ARG_name) /* nothing */ -/* argument itself (referenced) */ -#define ARGR(ARG_name) (*ARG_name) -/* argument address */ -#define ARGA(ARG_name) ARG_name -/* copy local variable to arg */ -#define ARG_OUT(ARG_name) /* nothing */ - int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { @@ -1240,243 +1180,206 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) case VIDIOCPWCSCQUAL: { - ARG_DEF(int, qual) + int *qual = arg; - ARG_IN(qual) - if (ARGR(qual) < 0 || ARGR(qual) > 3) + if (*qual < 0 || *qual > 3) ret = -EINVAL; else - ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); + ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); if (ret >= 0) - pdev->vcompression = ARGR(qual); + pdev->vcompression = *qual; break; } case VIDIOCPWCGCQUAL: { - ARG_DEF(int, qual) - - ARGR(qual) = pdev->vcompression; - ARG_OUT(qual) + int *qual = arg; + *qual = pdev->vcompression; break; } case VIDIOCPWCPROBE: { - ARG_DEF(struct pwc_probe, probe) - - strcpy(ARGR(probe).name, pdev->vdev->name); - ARGR(probe).type = pdev->type; - ARG_OUT(probe) + struct pwc_probe *probe = arg; + strcpy(probe->name, pdev->vdev->name); + probe->type = pdev->type; break; } case VIDIOCPWCGSERIAL: { - ARG_DEF(struct pwc_serial, serial) - - strcpy(ARGR(serial).serial, pdev->serial); - ARG_OUT(serial) + struct pwc_serial *serial = arg; + strcpy(serial->serial, pdev->serial); break; } case VIDIOCPWCSAGC: { - ARG_DEF(int, agc) - - ARG_IN(agc) - if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) + int *agc = arg; + if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) ret = -EINVAL; break; } case VIDIOCPWCGAGC: { - ARG_DEF(int, agc) + int *agc = arg; - if (pwc_get_agc(pdev, ARGA(agc))) + if (pwc_get_agc(pdev, agc)) ret = -EINVAL; - ARG_OUT(agc) break; } case VIDIOCPWCSSHUTTER: { - ARG_DEF(int, shutter_speed) - - ARG_IN(shutter_speed) - ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); + int *shutter_speed = arg; + ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); break; } case VIDIOCPWCSAWB: { - ARG_DEF(struct pwc_whitebalance, wb) + struct pwc_whitebalance *wb = arg; - ARG_IN(wb) - ret = pwc_set_awb(pdev, ARGR(wb).mode); - if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { - pwc_set_red_gain(pdev, ARGR(wb).manual_red); - pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); + ret = pwc_set_awb(pdev, wb->mode); + if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { + pwc_set_red_gain(pdev, wb->manual_red); + pwc_set_blue_gain(pdev, wb->manual_blue); } break; } case VIDIOCPWCGAWB: { - ARG_DEF(struct pwc_whitebalance, wb) + struct pwc_whitebalance *wb = arg; - memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); - ARGR(wb).mode = pwc_get_awb(pdev); - if (ARGR(wb).mode < 0) + memset(wb, 0, sizeof(struct pwc_whitebalance)); + wb->mode = pwc_get_awb(pdev); + if (wb->mode < 0) ret = -EINVAL; else { - if (ARGR(wb).mode == PWC_WB_MANUAL) { - ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); + if (wb->mode == PWC_WB_MANUAL) { + ret = pwc_get_red_gain(pdev, &wb->manual_red); if (ret < 0) break; - ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); + ret = pwc_get_blue_gain(pdev, &wb->manual_blue); if (ret < 0) break; } - if (ARGR(wb).mode == PWC_WB_AUTO) { - ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); + if (wb->mode == PWC_WB_AUTO) { + ret = pwc_read_red_gain(pdev, &wb->read_red); if (ret < 0) break; - ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); + ret = pwc_read_blue_gain(pdev, &wb->read_blue); if (ret < 0) break; } } - ARG_OUT(wb) break; } case VIDIOCPWCSAWBSPEED: { - ARG_DEF(struct pwc_wb_speed, wbs) + struct pwc_wb_speed *wbs = arg; - if (ARGR(wbs).control_speed > 0) { - ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); + if (wbs->control_speed > 0) { + ret = pwc_set_wb_speed(pdev, wbs->control_speed); } - if (ARGR(wbs).control_delay > 0) { - ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); + if (wbs->control_delay > 0) { + ret = pwc_set_wb_delay(pdev, wbs->control_delay); } break; } case VIDIOCPWCGAWBSPEED: { - ARG_DEF(struct pwc_wb_speed, wbs) + struct pwc_wb_speed *wbs = arg; - ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); + ret = pwc_get_wb_speed(pdev, &wbs->control_speed); if (ret < 0) break; - ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); + ret = pwc_get_wb_delay(pdev, &wbs->control_delay); if (ret < 0) break; - ARG_OUT(wbs) break; } case VIDIOCPWCSLED: { - ARG_DEF(struct pwc_leds, leds) - - ARG_IN(leds) - ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); - break; + struct pwc_leds *leds = arg; + ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); + break; } case VIDIOCPWCGLED: { - ARG_DEF(struct pwc_leds, leds) - - ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); - ARG_OUT(leds) + struct pwc_leds *leds = arg; + ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); break; } case VIDIOCPWCSCONTOUR: { - ARG_DEF(int, contour) - - ARG_IN(contour) - ret = pwc_set_contour(pdev, ARGR(contour)); + int *contour = arg; + ret = pwc_set_contour(pdev, *contour); break; } case VIDIOCPWCGCONTOUR: { - ARG_DEF(int, contour) - - ret = pwc_get_contour(pdev, ARGA(contour)); - ARG_OUT(contour) + int *contour = arg; + ret = pwc_get_contour(pdev, contour); break; } case VIDIOCPWCSBACKLIGHT: { - ARG_DEF(int, backlight) - - ARG_IN(backlight) - ret = pwc_set_backlight(pdev, ARGR(backlight)); + int *backlight = arg; + ret = pwc_set_backlight(pdev, *backlight); break; } case VIDIOCPWCGBACKLIGHT: { - ARG_DEF(int, backlight) - - ret = pwc_get_backlight(pdev, ARGA(backlight)); - ARG_OUT(backlight) + int *backlight = arg; + ret = pwc_get_backlight(pdev, backlight); break; } case VIDIOCPWCSFLICKER: { - ARG_DEF(int, flicker) - - ARG_IN(flicker) - ret = pwc_set_flicker(pdev, ARGR(flicker)); + int *flicker = arg; + ret = pwc_set_flicker(pdev, *flicker); break; } case VIDIOCPWCGFLICKER: { - ARG_DEF(int, flicker) - - ret = pwc_get_flicker(pdev, ARGA(flicker)); - ARG_OUT(flicker) + int *flicker = arg; + ret = pwc_get_flicker(pdev, flicker); break; } case VIDIOCPWCSDYNNOISE: { - ARG_DEF(int, dynnoise) - - ARG_IN(dynnoise) - ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); + int *dynnoise = arg; + ret = pwc_set_dynamic_noise(pdev, *dynnoise); break; } case VIDIOCPWCGDYNNOISE: { - ARG_DEF(int, dynnoise) - - ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise)); - ARG_OUT(dynnoise); + int *dynnoise = arg; + ret = pwc_get_dynamic_noise(pdev, dynnoise); break; } case VIDIOCPWCGREALSIZE: { - ARG_DEF(struct pwc_imagesize, size) - - ARGR(size).width = pdev->image.x; - ARGR(size).height = pdev->image.y; - ARG_OUT(size) + struct pwc_imagesize *size = arg; + size->width = pdev->image.x; + size->height = pdev->image.y; break; } @@ -1484,10 +1387,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(int, flags) + int *flags = arg; - ARG_IN(flags) - ret = pwc_mpt_reset(pdev, ARGR(flags)); + ret = pwc_mpt_reset(pdev, *flags); + if (ret >= 0) + { + pdev->pan_angle = 0; + pdev->tilt_angle = 0; + } } else { @@ -1500,10 +1407,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_range, range) - - ARGR(range) = pdev->angle_range; - ARG_OUT(range) + struct pwc_mpt_range *range = arg; + *range = pdev->angle_range; } else { @@ -1518,23 +1423,48 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_angles, angles) - - ARG_IN(angles) + struct pwc_mpt_angles *angles = arg; /* The camera can only set relative angles, so do some calculations when getting an absolute angle . */ - if (ARGR(angles).absolute) + if (angles->absolute) { - new_pan = ARGR(angles).pan; - new_tilt = ARGR(angles).tilt; + new_pan = angles->pan; + new_tilt = angles->tilt; } else { - new_pan = pdev->pan_angle + ARGR(angles).pan; - new_tilt = pdev->tilt_angle + ARGR(angles).tilt; + new_pan = pdev->pan_angle + angles->pan; + new_tilt = pdev->tilt_angle + angles->tilt; + } + /* check absolute ranges */ + if (new_pan < pdev->angle_range.pan_min || + new_pan > pdev->angle_range.pan_max || + new_tilt < pdev->angle_range.tilt_min || + new_tilt > pdev->angle_range.tilt_max) + { + ret = -ERANGE; + } + else + { + /* go to relative range, check again */ + new_pan -= pdev->pan_angle; + new_tilt -= pdev->tilt_angle; + /* angles are specified in degrees * 100, thus the limit = 36000 */ + if (new_pan < -36000 || new_pan > 36000 || new_tilt < -36000 || new_tilt > 36000) + ret = -ERANGE; + } + if (ret == 0) /* no errors so far */ + { + ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); + if (ret >= 0) + { + pdev->pan_angle += new_pan; + pdev->tilt_angle += new_tilt; + } + if (ret == -EPIPE) /* stall -> out of range */ + ret = -ERANGE; } - ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt); } else { @@ -1548,12 +1478,11 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_angles, angles) + struct pwc_mpt_angles *angles = arg; - ARGR(angles).absolute = 1; - ARGR(angles).pan = pdev->pan_angle; - ARGR(angles).tilt = pdev->tilt_angle; - ARG_OUT(angles) + angles->absolute = 1; + angles->pan = pdev->pan_angle; + angles->tilt = pdev->tilt_angle; } else { @@ -1566,10 +1495,8 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { if (pdev->features & FEATURE_MOTOR_PANTILT) { - ARG_DEF(struct pwc_mpt_status, status) - - ret = pwc_mpt_get_status(pdev, ARGA(status)); - ARG_OUT(status) + struct pwc_mpt_status *status = arg; + ret = pwc_mpt_get_status(pdev, status); } else { @@ -1580,24 +1507,22 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) case VIDIOCPWCGVIDCMD: { - ARG_DEF(struct pwc_video_command, cmd); - - ARGR(cmd).type = pdev->type; - ARGR(cmd).release = pdev->release; - ARGR(cmd).command_len = pdev->cmd_len; - memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); - ARGR(cmd).bandlength = pdev->vbandlength; - ARGR(cmd).frame_size = pdev->frame_size; - ARG_OUT(cmd) + struct pwc_video_command *cmd = arg; + + cmd->type = pdev->type; + cmd->release = pdev->release; + cmd->command_len = pdev->cmd_len; + memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len); + cmd->bandlength = pdev->vbandlength; + cmd->frame_size = pdev->frame_size; break; } /* case VIDIOCPWCGVIDTABLE: { - ARG_DEF(struct pwc_table_init_buffer, table); - ARGR(table).len = pdev->cmd_len; - memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size); - ARG_OUT(table) + struct pwc_table_init_buffer *table = arg; + table->len = pdev->cmd_len; + memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size); break; } */ @@ -1613,4 +1538,4 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) } -/* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ + diff --git a/trunk/drivers/media/video/pwc/pwc-dec1.c b/trunk/drivers/media/video/pwc/pwc-dec1.c deleted file mode 100644 index c29593f589eb..000000000000 --- a/trunk/drivers/media/video/pwc/pwc-dec1.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Linux driver for Philips webcam - Decompression for chipset version 1 - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - - -#include "pwc-dec1.h" - - -void pwc_dec1_init(int type, int release, void *buffer, void *table) -{ - -} - -void pwc_dec1_exit(void) -{ - - - -} - -int pwc_dec1_alloc(struct pwc_device *pwc) -{ - pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL); - if (pwc->decompress_data == NULL) - return -ENOMEM; - return 0; -} - diff --git a/trunk/drivers/media/video/pwc/pwc-dec1.h b/trunk/drivers/media/video/pwc/pwc-dec1.h deleted file mode 100644 index 8b62ddcc5c7e..000000000000 --- a/trunk/drivers/media/video/pwc/pwc-dec1.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - - -#ifndef PWC_DEC1_H -#define PWC_DEC1_H - -#include "pwc.h" - -struct pwc_dec1_private -{ - int version; - -}; - -int pwc_dec1_alloc(struct pwc_device *pwc); -void pwc_dec1_init(int type, int release, void *buffer, void *private_data); -void pwc_dec1_exit(void); - -#endif - diff --git a/trunk/drivers/media/video/pwc/pwc-dec23.c b/trunk/drivers/media/video/pwc/pwc-dec23.c deleted file mode 100644 index 9e2d91f26bfe..000000000000 --- a/trunk/drivers/media/video/pwc/pwc-dec23.c +++ /dev/null @@ -1,941 +0,0 @@ -/* Linux driver for Philips webcam - Decompression for chipset version 2 et 3 - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include "pwc-timon.h" -#include "pwc-kiara.h" -#include "pwc-dec23.h" -#include - -#include - -/* - * USE_LOOKUP_TABLE_TO_CLAMP - * 0: use a C version of this tests: { a<0?0:(a>255?255:a) } - * 1: use a faster lookup table for cpu with a big cache (intel) - */ -#define USE_LOOKUP_TABLE_TO_CLAMP 1 -/* - * UNROLL_LOOP_FOR_COPYING_BLOCK - * 0: use a loop for a smaller code (but little slower) - * 1: when unrolling the loop, gcc produces some faster code (perhaps only - * valid for intel processor class). Activating this option, automaticaly - * activate USE_LOOKUP_TABLE_TO_CLAMP - */ -#define UNROLL_LOOP_FOR_COPY 1 -#if UNROLL_LOOP_FOR_COPY -# undef USE_LOOKUP_TABLE_TO_CLAMP -# define USE_LOOKUP_TABLE_TO_CLAMP 1 -#endif - -/* - * ENABLE_BAYER_DECODER - * 0: bayer decoder is not build (save some space) - * 1: bayer decoder is build and can be used - */ -#define ENABLE_BAYER_DECODER 0 - -static void build_subblock_pattern(struct pwc_dec23_private *pdec) -{ - static const unsigned int initial_values[12] = { - -0x526500, -0x221200, 0x221200, 0x526500, - -0x3de200, 0x3de200, - -0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480, - -0x12c200, 0x12c200 - - }; - static const unsigned int values_derivated[12] = { - 0xa4ca, 0x4424, -0x4424, -0xa4ca, - 0x7bc4, -0x7bc4, - 0xdb69, 0x5aba, -0x5aba, -0xdb69, - 0x2584, -0x2584 - }; - unsigned int temp_values[12]; - int i, j; - - memcpy(temp_values, initial_values, sizeof(initial_values)); - for (i = 0; i < 256; i++) { - for (j = 0; j < 12; j++) { - pdec->table_subblock[i][j] = temp_values[j]; - temp_values[j] += values_derivated[j]; - } - } -} - -static void build_bit_powermask_table(struct pwc_dec23_private *pdec) -{ - unsigned char *p; - unsigned int bit, byte, mask, val; - unsigned int bitpower = 1; - - for (bit = 0; bit < 8; bit++) { - mask = bitpower - 1; - p = pdec->table_bitpowermask[bit]; - for (byte = 0; byte < 256; byte++) { - val = (byte & mask); - if (byte & bitpower) - val = -val; - *p++ = val; - } - bitpower<<=1; - } -} - - -static void build_table_color(const unsigned int romtable[16][8], - unsigned char p0004[16][1024], - unsigned char p8004[16][256]) -{ - int compression_mode, j, k, bit, pw; - unsigned char *p0, *p8; - const unsigned int *r; - - /* We have 16 compressions tables */ - for (compression_mode = 0; compression_mode < 16; compression_mode++) { - p0 = p0004[compression_mode]; - p8 = p8004[compression_mode]; - r = romtable[compression_mode]; - - for (j = 0; j < 8; j++, r++, p0 += 128) { - - for (k = 0; k < 16; k++) { - if (k == 0) - bit = 1; - else if (k >= 1 && k < 3) - bit = (r[0] >> 15) & 7; - else if (k >= 3 && k < 6) - bit = (r[0] >> 12) & 7; - else if (k >= 6 && k < 10) - bit = (r[0] >> 9) & 7; - else if (k >= 10 && k < 13) - bit = (r[0] >> 6) & 7; - else if (k >= 13 && k < 15) - bit = (r[0] >> 3) & 7; - else - bit = (r[0]) & 7; - if (k == 0) - *p8++ = 8; - else - *p8++ = j - bit; - *p8++ = bit; - - pw = 1 << bit; - p0[k + 0x00] = (1 * pw) + 0x80; - p0[k + 0x10] = (2 * pw) + 0x80; - p0[k + 0x20] = (3 * pw) + 0x80; - p0[k + 0x30] = (4 * pw) + 0x80; - p0[k + 0x40] = (-1 * pw) + 0x80; - p0[k + 0x50] = (-2 * pw) + 0x80; - p0[k + 0x60] = (-3 * pw) + 0x80; - p0[k + 0x70] = (-4 * pw) + 0x80; - } /* end of for (k=0; k<16; k++, p8++) */ - } /* end of for (j=0; j<8; j++ , table++) */ - } /* end of foreach compression_mode */ -} - -/* - * - */ -static void fill_table_dc00_d800(struct pwc_dec23_private *pdec) -{ -#define SCALEBITS 15 -#define ONE_HALF (1UL << (SCALEBITS - 1)) - int i; - unsigned int offset1 = ONE_HALF; - unsigned int offset2 = 0x0000; - - for (i=0; i<256; i++) { - pdec->table_dc00[i] = offset1 & ~(ONE_HALF); - pdec->table_d800[i] = offset2; - - offset1 += 0x7bc4; - offset2 += 0x7bc4; - } -} - -/* - * To decode the stream: - * if look_bits(2) == 0: # op == 2 in the lookup table - * skip_bits(2) - * end of the stream - * elif look_bits(3) == 7: # op == 1 in the lookup table - * skip_bits(3) - * yyyy = get_bits(4) - * xxxx = get_bits(8) - * else: # op == 0 in the lookup table - * skip_bits(x) - * - * For speedup processing, we build a lookup table and we takes the first 6 bits. - * - * struct { - * unsigned char op; // operation to execute - * unsigned char bits; // bits use to perform operation - * unsigned char offset1; // offset to add to access in the table_0004 % 16 - * unsigned char offset2; // offset to add to access in the table_0004 - * } - * - * How to build this table ? - * op == 2 when (i%4)==0 - * op == 1 when (i%8)==7 - * op == 0 otherwise - * - */ -static const unsigned char hash_table_ops[64*4] = { - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x10, - 0x00, 0x06, 0x01, 0x30, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x01, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x50, - 0x00, 0x05, 0x02, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x03, 0x00, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x10, - 0x00, 0x06, 0x02, 0x10, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x01, 0x60, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x50, - 0x00, 0x05, 0x02, 0x40, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x03, 0x40, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x10, - 0x00, 0x06, 0x01, 0x70, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x01, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x50, - 0x00, 0x05, 0x02, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x03, 0x00, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x10, - 0x00, 0x06, 0x02, 0x50, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x01, 0x60, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x00, - 0x00, 0x04, 0x01, 0x50, - 0x00, 0x05, 0x02, 0x40, - 0x02, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x40, - 0x00, 0x05, 0x03, 0x40, - 0x01, 0x00, 0x00, 0x00 -}; - -/* - * - */ -static const unsigned int MulIdx[16][16] = { - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,}, - {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,}, - {4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,}, - {6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,}, - {4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,}, - {1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,}, - {0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,}, - {0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,}, - {1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,}, - {7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,}, - {4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,}, - {7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,}, - {1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,}, - {1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,}, - {10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10} -}; - -#if USE_LOOKUP_TABLE_TO_CLAMP -#define MAX_OUTER_CROP_VALUE (512) -static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE]; -#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)]) -#else -#define CLAMP(x) ((x)>255?255:((x)<0?0:x)) -#endif - - -/* If the type or the command change, we rebuild the lookup table */ -int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd) -{ - int flags, version, shift, i; - struct pwc_dec23_private *pdec; - - if (pwc->decompress_data == NULL) { - pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); - if (pdec == NULL) - return -ENOMEM; - pwc->decompress_data = pdec; - } - pdec = pwc->decompress_data; - - if (DEVICE_USE_CODEC3(type)) { - flags = cmd[2] & 0x18; - if (flags == 8) - pdec->nbits = 7; /* More bits, mean more bits to encode the stream, but better quality */ - else if (flags == 0x10) - pdec->nbits = 8; - else - pdec->nbits = 6; - - version = cmd[2] >> 5; - build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); - build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); - - } else { - - flags = cmd[2] & 6; - if (flags == 2) - pdec->nbits = 7; - else if (flags == 4) - pdec->nbits = 8; - else - pdec->nbits = 6; - - version = cmd[2] >> 3; - build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1); - build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2); - } - - /* Informations can be coded on a variable number of bits but never less than 8 */ - shift = 8 - pdec->nbits; - pdec->scalebits = SCALEBITS - shift; - pdec->nbitsmask = 0xFF >> shift; - - fill_table_dc00_d800(pdec); - build_subblock_pattern(pdec); - build_bit_powermask_table(pdec); - -#if USE_LOOKUP_TABLE_TO_CLAMP - /* Build the static table to clamp value [0-255] */ - for (i=0;i> scalebits]; - *d++ = cm[c[1] >> scalebits]; - *d++ = cm[c[2] >> scalebits]; - *d++ = cm[c[3] >> scalebits]; - - d = dst + bytes_per_line; - *d++ = cm[c[4] >> scalebits]; - *d++ = cm[c[5] >> scalebits]; - *d++ = cm[c[6] >> scalebits]; - *d++ = cm[c[7] >> scalebits]; - - d = dst + bytes_per_line*2; - *d++ = cm[c[8] >> scalebits]; - *d++ = cm[c[9] >> scalebits]; - *d++ = cm[c[10] >> scalebits]; - *d++ = cm[c[11] >> scalebits]; - - d = dst + bytes_per_line*3; - *d++ = cm[c[12] >> scalebits]; - *d++ = cm[c[13] >> scalebits]; - *d++ = cm[c[14] >> scalebits]; - *d++ = cm[c[15] >> scalebits]; -#else - int i; - const int *c = src; - unsigned char *d = dst; - for (i = 0; i < 4; i++, c++) - *d++ = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line; - for (i = 0; i < 4; i++, c++) - *d++ = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line*2; - for (i = 0; i < 4; i++, c++) - *d++ = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line*3; - for (i = 0; i < 4; i++, c++) - *d++ = CLAMP((*c) >> scalebits); -#endif -} - -/* - * Copy the 4x4 image block to a CrCb plane buffer - * - */ -static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) -{ -#if UNROLL_LOOP_FOR_COPY - /* Unroll all loops */ - const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; - const int *c = src; - unsigned char *d = dst; - - *d++ = cm[c[0] >> scalebits]; - *d++ = cm[c[4] >> scalebits]; - *d++ = cm[c[1] >> scalebits]; - *d++ = cm[c[5] >> scalebits]; - *d++ = cm[c[2] >> scalebits]; - *d++ = cm[c[6] >> scalebits]; - *d++ = cm[c[3] >> scalebits]; - *d++ = cm[c[7] >> scalebits]; - - d = dst + bytes_per_line; - *d++ = cm[c[12] >> scalebits]; - *d++ = cm[c[8] >> scalebits]; - *d++ = cm[c[13] >> scalebits]; - *d++ = cm[c[9] >> scalebits]; - *d++ = cm[c[14] >> scalebits]; - *d++ = cm[c[10] >> scalebits]; - *d++ = cm[c[15] >> scalebits]; - *d++ = cm[c[11] >> scalebits]; -#else - int i; - const int *c1 = src; - const int *c2 = src + 4; - unsigned char *d = dst; - - for (i = 0; i < 4; i++, c1++, c2++) { - *d++ = CLAMP((*c1) >> scalebits); - *d++ = CLAMP((*c2) >> scalebits); - } - c1 = src + 12; - d = dst + bytes_per_line; - for (i = 0; i < 4; i++, c1++, c2++) { - *d++ = CLAMP((*c1) >> scalebits); - *d++ = CLAMP((*c2) >> scalebits); - } -#endif -} - -#if ENABLE_BAYER_DECODER -/* - * Format: 8x2 pixels - * . G . G . G . G . G . G . G - * . . . . . . . . . . . . . . - * . G . G . G . G . G . G . G - * . . . . . . . . . . . . . . - * or - * . . . . . . . . . . . . . . - * G . G . G . G . G . G . G . - * . . . . . . . . . . . . . . - * G . G . G . G . G . G . G . -*/ -static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) -{ -#if UNROLL_LOOP_FOR_COPY - /* Unroll all loops */ - const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; - unsigned char *d = dst; - const int *c = src; - - d[0] = cm[c[0] >> scalebits]; - d[2] = cm[c[1] >> scalebits]; - d[4] = cm[c[2] >> scalebits]; - d[6] = cm[c[3] >> scalebits]; - d[8] = cm[c[4] >> scalebits]; - d[10] = cm[c[5] >> scalebits]; - d[12] = cm[c[6] >> scalebits]; - d[14] = cm[c[7] >> scalebits]; - - d = dst + bytes_per_line; - d[0] = cm[c[8] >> scalebits]; - d[2] = cm[c[9] >> scalebits]; - d[4] = cm[c[10] >> scalebits]; - d[6] = cm[c[11] >> scalebits]; - d[8] = cm[c[12] >> scalebits]; - d[10] = cm[c[13] >> scalebits]; - d[12] = cm[c[14] >> scalebits]; - d[14] = cm[c[15] >> scalebits]; -#else - int i; - unsigned char *d; - const int *c = src; - - d = dst; - for (i = 0; i < 8; i++, c++) - d[i*2] = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line; - for (i = 0; i < 8; i++, c++) - d[i*2] = CLAMP((*c) >> scalebits); -#endif -} -#endif - -#if ENABLE_BAYER_DECODER -/* - * Format: 4x4 pixels - * R . R . R . R - * . B . B . B . - * R . R . R . R - * . B . B . B . - */ -static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits) -{ -#if UNROLL_LOOP_FOR_COPY - /* Unroll all loops */ - const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE; - unsigned char *d = dst; - const int *c = src; - - d[0] = cm[c[0] >> scalebits]; - d[2] = cm[c[1] >> scalebits]; - d[4] = cm[c[2] >> scalebits]; - d[6] = cm[c[3] >> scalebits]; - - d = dst + bytes_per_line; - d[1] = cm[c[4] >> scalebits]; - d[3] = cm[c[5] >> scalebits]; - d[5] = cm[c[6] >> scalebits]; - d[7] = cm[c[7] >> scalebits]; - - d = dst + bytes_per_line*2; - d[0] = cm[c[8] >> scalebits]; - d[2] = cm[c[9] >> scalebits]; - d[4] = cm[c[10] >> scalebits]; - d[6] = cm[c[11] >> scalebits]; - - d = dst + bytes_per_line*3; - d[1] = cm[c[12] >> scalebits]; - d[3] = cm[c[13] >> scalebits]; - d[5] = cm[c[14] >> scalebits]; - d[7] = cm[c[15] >> scalebits]; -#else - int i; - unsigned char *d; - const int *c = src; - - d = dst; - for (i = 0; i < 4; i++, c++) - d[i*2] = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line; - for (i = 0; i < 4; i++, c++) - d[i*2+1] = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line*2; - for (i = 0; i < 4; i++, c++) - d[i*2] = CLAMP((*c) >> scalebits); - - d = dst + bytes_per_line*3; - for (i = 0; i < 4; i++, c++) - d[i*2+1] = CLAMP((*c) >> scalebits); -#endif -} -#endif - -/* - * To manage the stream, we keep bits in a 32 bits register. - * fill_nbits(n): fill the reservoir with at least n bits - * skip_bits(n): discard n bits from the reservoir - * get_bits(n): fill the reservoir, returns the first n bits and discard the - * bits from the reservoir. - * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir - * contains at least n bits. bits returned is discarded. - */ -#define fill_nbits(pdec, nbits_wanted) do { \ - while (pdec->nbits_in_reservoir<(nbits_wanted)) \ - { \ - pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \ - pdec->nbits_in_reservoir += 8; \ - } \ -} while(0); - -#define skip_nbits(pdec, nbits_to_skip) do { \ - pdec->reservoir >>= (nbits_to_skip); \ - pdec->nbits_in_reservoir -= (nbits_to_skip); \ -} while(0); - -#define get_nbits(pdec, nbits_wanted, result) do { \ - fill_nbits(pdec, nbits_wanted); \ - result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ - skip_nbits(pdec, nbits_wanted); \ -} while(0); - -#define __get_nbits(pdec, nbits_wanted, result) do { \ - result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \ - skip_nbits(pdec, nbits_wanted); \ -} while(0); - -#define look_nbits(pdec, nbits_wanted) \ - ((pdec->reservoir) & ((1U<<(nbits_wanted))-1)) - -/* - * Decode a 4x4 pixel block - */ -static void decode_block(struct pwc_dec23_private *pdec, - const unsigned char *ptable0004, - const unsigned char *ptable8004) -{ - unsigned int primary_color; - unsigned int channel_v, offset1, op; - int i; - - fill_nbits(pdec, 16); - __get_nbits(pdec, pdec->nbits, primary_color); - - if (look_nbits(pdec,2) == 0) { - skip_nbits(pdec, 2); - /* Very simple, the color is the same for all pixels of the square */ - for (i = 0; i < 16; i++) - pdec->temp_colors[i] = pdec->table_dc00[primary_color]; - - return; - } - - /* This block is encoded with small pattern */ - for (i = 0; i < 16; i++) - pdec->temp_colors[i] = pdec->table_d800[primary_color]; - - __get_nbits(pdec, 3, channel_v); - channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2); - - ptable0004 += (channel_v * 128); - ptable8004 += (channel_v * 32); - - offset1 = 0; - do - { - unsigned int htable_idx, rows = 0; - const unsigned int *block; - - /* [ zzzz y x x ] - * xx == 00 :=> end of the block def, remove the two bits from the stream - * yxx == 111 - * yxx == any other value - * - */ - fill_nbits(pdec, 16); - htable_idx = look_nbits(pdec, 6); - op = hash_table_ops[htable_idx * 4]; - - if (op == 2) { - skip_nbits(pdec, 2); - - } else if (op == 1) { - /* 15bits [ xxxx xxxx yyyy 111 ] - * yyy => offset in the table8004 - * xxx => offset in the tabled004 (tree) - */ - unsigned int mask, shift; - unsigned int nbits, col1; - unsigned int yyyy; - - skip_nbits(pdec, 3); - /* offset1 += yyyy */ - __get_nbits(pdec, 4, yyyy); - offset1 += 1 + yyyy; - offset1 &= 0x0F; - nbits = ptable8004[offset1 * 2]; - - /* col1 = xxxx xxxx */ - __get_nbits(pdec, nbits+1, col1); - - /* Bit mask table */ - mask = pdec->table_bitpowermask[nbits][col1]; - shift = ptable8004[offset1 * 2 + 1]; - rows = ((mask << shift) + 0x80) & 0xFF; - - block = pdec->table_subblock[rows]; - for (i = 0; i < 16; i++) - pdec->temp_colors[i] += block[MulIdx[offset1][i]]; - - } else { - /* op == 0 - * offset1 is coded on 3 bits - */ - unsigned int shift; - - offset1 += hash_table_ops [htable_idx * 4 + 2]; - offset1 &= 0x0F; - - rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]]; - block = pdec->table_subblock[rows]; - for (i = 0; i < 16; i++) - pdec->temp_colors[i] += block[MulIdx[offset1][i]]; - - shift = hash_table_ops[htable_idx * 4 + 1]; - skip_nbits(pdec, shift); - } - - } while (op != 2); - -} - -static void DecompressBand23(struct pwc_dec23_private *pdec, - const unsigned char *rawyuv, - unsigned char *planar_y, - unsigned char *planar_u, - unsigned char *planar_v, - unsigned int compressed_image_width, - unsigned int real_image_width) -{ - int compression_index, nblocks; - const unsigned char *ptable0004; - const unsigned char *ptable8004; - - pdec->reservoir = 0; - pdec->nbits_in_reservoir = 0; - pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */ - - get_nbits(pdec, 4, compression_index); - - /* pass 1: uncompress Y component */ - nblocks = compressed_image_width / 4; - - ptable0004 = pdec->table_0004_pass1[compression_index]; - ptable8004 = pdec->table_8004_pass1[compression_index]; - - /* Each block decode a square of 4x4 */ - while (nblocks) { - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits); - planar_y += 4; - nblocks--; - } - - /* pass 2: uncompress UV component */ - nblocks = compressed_image_width / 8; - - ptable0004 = pdec->table_0004_pass2[compression_index]; - ptable8004 = pdec->table_8004_pass2[compression_index]; - - /* Each block decode a square of 4x4 */ - while (nblocks) { - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits); - - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits); - - planar_v += 8; - planar_u += 8; - nblocks -= 2; - } - -} - -#if ENABLE_BAYER_DECODER -/* - * Size need to be a multiple of 8 in width - * - * Return a block of four line encoded like this: - * - * G R G R G R G R G R G R G R G R - * B G B G B G B G B G B G B G B G - * G R G R G R G R G R G R G R G R - * B G B G B G B G B G B G B G B G - * - */ -static void DecompressBandBayer(struct pwc_dec23_private *pdec, - const unsigned char *rawyuv, - unsigned char *rgbbayer, - unsigned int compressed_image_width, - unsigned int real_image_width) -{ - int compression_index, nblocks; - const unsigned char *ptable0004; - const unsigned char *ptable8004; - unsigned char *dest; - - pdec->reservoir = 0; - pdec->nbits_in_reservoir = 0; - pdec->stream = rawyuv + 1; /* The first byte of the stream is skipped */ - - get_nbits(pdec, 4, compression_index); - - /* pass 1: uncompress RB component */ - nblocks = compressed_image_width / 4; - - ptable0004 = pdec->table_0004_pass1[compression_index]; - ptable8004 = pdec->table_8004_pass1[compression_index]; - dest = rgbbayer; - - /* Each block decode a square of 4x4 */ - while (nblocks) { - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits); - dest += 8; - nblocks--; - } - - /* pass 2: uncompress G component */ - nblocks = compressed_image_width / 8; - - ptable0004 = pdec->table_0004_pass2[compression_index]; - ptable8004 = pdec->table_8004_pass2[compression_index]; - - /* Each block decode a square of 4x4 */ - while (nblocks) { - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits); - - decode_block(pdec, ptable0004, ptable8004); - copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits); - - rgbbayer += 16; - nblocks -= 2; - } -} -#endif - - -/** - * - * Uncompress a pwc23 buffer. - * - * pwc.view: size of the image wanted - * pwc.image: size of the image returned by the camera - * pwc.offset: (x,y) to displayer image in the view - * - * src: raw data - * dst: image output - * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER - */ -void pwc_dec23_decompress(const struct pwc_device *pwc, - const void *src, - void *dst, - int flags) -{ - int bandlines_left, stride, bytes_per_block; - - bandlines_left = pwc->image.y / 4; - bytes_per_block = pwc->view.x * 4; - - if (flags & PWCX_FLAG_BAYER) { -#if ENABLE_BAYER_DECODER - /* RGB Bayer format */ - unsigned char *rgbout; - - stride = pwc->view.x * pwc->offset.y; - rgbout = dst + stride + pwc->offset.x; - - - while (bandlines_left--) { - - DecompressBandBayer(pwc->decompress_data, - src, - rgbout, - pwc->image.x, pwc->view.x); - - src += pwc->vbandlength; - rgbout += bytes_per_block; - - } -#else - memset(dst, 0, pwc->view.x * pwc->view.y); -#endif - - } else { - /* YUV420P image format */ - unsigned char *pout_planar_y; - unsigned char *pout_planar_u; - unsigned char *pout_planar_v; - unsigned int plane_size; - - plane_size = pwc->view.x * pwc->view.y; - - /* offset in Y plane */ - stride = pwc->view.x * pwc->offset.y; - pout_planar_y = dst + stride + pwc->offset.x; - - /* offsets in U/V planes */ - stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2; - pout_planar_u = dst + plane_size + stride; - pout_planar_v = dst + plane_size + plane_size / 4 + stride; - - while (bandlines_left--) { - - DecompressBand23(pwc->decompress_data, - src, - pout_planar_y, pout_planar_u, pout_planar_v, - pwc->image.x, pwc->view.x); - src += pwc->vbandlength; - pout_planar_y += bytes_per_block; - pout_planar_u += pwc->view.x; - pout_planar_v += pwc->view.x; - - } - - } - -} - -void pwc_dec23_exit(void) -{ - /* Do nothing */ - -} - -/** - * Allocate a private structure used by lookup table. - * You must call kfree() to free the memory allocated. - */ -int pwc_dec23_alloc(struct pwc_device *pwc) -{ - pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); - if (pwc->decompress_data == NULL) - return -ENOMEM; - return 0; -} - -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/trunk/drivers/media/video/pwc/pwc-dec23.h b/trunk/drivers/media/video/pwc/pwc-dec23.h deleted file mode 100644 index 1c55298ad153..000000000000 --- a/trunk/drivers/media/video/pwc/pwc-dec23.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef PWC_DEC23_H -#define PWC_DEC23_H - -#include "pwc.h" - -struct pwc_dec23_private -{ - unsigned int scalebits; - unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */ - - unsigned int reservoir; - unsigned int nbits_in_reservoir; - const unsigned char *stream; - int temp_colors[16]; - - unsigned char table_0004_pass1[16][1024]; - unsigned char table_0004_pass2[16][1024]; - unsigned char table_8004_pass1[16][256]; - unsigned char table_8004_pass2[16][256]; - unsigned int table_subblock[256][12]; - - unsigned char table_bitpowermask[8][256]; - unsigned int table_d800[256]; - unsigned int table_dc00[256]; - -}; - - -int pwc_dec23_alloc(struct pwc_device *pwc); -int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd); -void pwc_dec23_exit(void); -void pwc_dec23_decompress(const struct pwc_device *pwc, - const void *src, - void *dst, - int flags); - - - -#endif - - -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ - diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index 47d0d83a0264..41418294a32b 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -1,7 +1,7 @@ /* Linux driver for Philips webcam USB and Video4Linux interface part. (C) 1999-2004 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -62,21 +62,18 @@ #include #include #include -#include #include -#include #include "pwc.h" +#include "pwc-ioctl.h" #include "pwc-kiara.h" #include "pwc-timon.h" -#include "pwc-dec23.h" -#include "pwc-dec1.h" #include "pwc-uncompress.h" /* Function prototypes and driver templates */ /* hotplug device table support */ -static const struct usb_device_id pwc_device_table [] = { +static struct usb_device_id pwc_device_table [] = { { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */ { USB_DEVICE(0x0471, 0x0303) }, { USB_DEVICE(0x0471, 0x0304) }, @@ -84,10 +81,9 @@ static const struct usb_device_id pwc_device_table [] = { { USB_DEVICE(0x0471, 0x0308) }, { USB_DEVICE(0x0471, 0x030C) }, { USB_DEVICE(0x0471, 0x0310) }, - { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */ + { USB_DEVICE(0x0471, 0x0311) }, { USB_DEVICE(0x0471, 0x0312) }, { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ - { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */ { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ @@ -98,9 +94,8 @@ static const struct usb_device_id pwc_device_table [] = { { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */ { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */ { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */ - { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */ - { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */ - { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */ + { USB_DEVICE(0x055D, 0x9000) }, /* Samsung */ + { USB_DEVICE(0x055D, 0x9001) }, { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ @@ -127,13 +122,11 @@ static struct usb_driver pwc_driver = { static int default_size = PSZ_QCIF; static int default_fps = 10; static int default_fbufs = 3; /* Default number of frame buffers */ - int pwc_mbufs = 2; /* Default number of mmap() buffers */ -#if CONFIG_PWC_DEBUG - int pwc_trace = PWC_DEBUG_LEVEL; -#endif +static int default_mbufs = 2; /* Default number of mmap() buffers */ + int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX; static int power_save = 0; static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ -static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ +static int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */ static struct { int type; char serial_number[30]; @@ -145,7 +138,7 @@ static struct { static int pwc_video_open(struct inode *inode, struct file *file); static int pwc_video_close(struct inode *inode, struct file *file); -static ssize_t pwc_video_read(struct file *file, char __user *buf, +static ssize_t pwc_video_read(struct file *file, char __user * buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static int pwc_video_ioctl(struct inode *inode, struct file *file, @@ -160,6 +153,7 @@ static struct file_operations pwc_fops = { .poll = pwc_video_poll, .mmap = pwc_video_mmap, .ioctl = pwc_video_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device pwc_template = { @@ -209,44 +203,52 @@ static struct video_device pwc_template = { /* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long kva, ret; + kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); + kva |= adr & (PAGE_SIZE-1); /* restore the offset */ + ret = __pa(kva); + return ret; +} - -static void *pwc_rvmalloc(unsigned long size) +static void * rvmalloc(unsigned long size) { void * mem; unsigned long adr; + size=PAGE_ALIGN(size); mem=vmalloc_32(size); - if (!mem) - return NULL; - - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr=(unsigned long) mem; - while (size > 0) - { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } + if (mem) + { + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr=(unsigned long) mem; + while (size > 0) + { + SetPageReserved(vmalloc_to_page((void *)adr)); + adr+=PAGE_SIZE; + size-=PAGE_SIZE; + } + } return mem; } -static void pwc_rvfree(void * mem, unsigned long size) +static void rvfree(void * mem, unsigned long size) { unsigned long adr; - if (!mem) - return; - - adr=(unsigned long) mem; - while ((long) size > 0) - { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - vfree(mem); + if (mem) + { + adr=(unsigned long) mem; + while ((long) size > 0) + { + ClearPageReserved(vmalloc_to_page((void *)adr)); + adr+=PAGE_SIZE; + size-=PAGE_SIZE; + } + vfree(mem); + } } @@ -254,83 +256,100 @@ static void pwc_rvfree(void * mem, unsigned long size) static int pwc_allocate_buffers(struct pwc_device *pdev) { - int i, err; + int i; void *kbuf; - PWC_DEBUG_MEMORY(">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); + Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev); if (pdev == NULL) return -ENXIO; - /* Allocate Isochronuous pipe buffers */ +#ifdef PWC_MAGIC + if (pdev->magic != PWC_MAGIC) { + Err("allocate_buffers(): magic failed.\n"); + return -ENXIO; + } +#endif + /* Allocate Isochronous pipe buffers */ for (i = 0; i < MAX_ISO_BUFS; i++) { if (pdev->sbuf[i].data == NULL) { - kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL); + kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); if (kbuf == NULL) { - PWC_ERROR("Failed to allocate iso buffer %d.\n", i); + Err("Failed to allocate iso buffer %d.\n", i); return -ENOMEM; } - PWC_DEBUG_MEMORY("Allocated iso buffer at %p.\n", kbuf); + Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf); pdev->sbuf[i].data = kbuf; + memset(kbuf, 0, ISO_BUFFER_SIZE); } } /* Allocate frame buffer structure */ if (pdev->fbuf == NULL) { - kbuf = kzalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); + kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL); if (kbuf == NULL) { - PWC_ERROR("Failed to allocate frame buffer structure.\n"); + Err("Failed to allocate frame buffer structure.\n"); return -ENOMEM; } - PWC_DEBUG_MEMORY("Allocated frame buffer structure at %p.\n", kbuf); + Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf); pdev->fbuf = kbuf; + memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf)); } - /* create frame buffers, and make circular ring */ for (i = 0; i < default_fbufs; i++) { if (pdev->fbuf[i].data == NULL) { kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ if (kbuf == NULL) { - PWC_ERROR("Failed to allocate frame buffer %d.\n", i); + Err("Failed to allocate frame buffer %d.\n", i); return -ENOMEM; } - PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); + Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf); pdev->fbuf[i].data = kbuf; - memset(kbuf, 0, PWC_FRAME_SIZE); + memset(kbuf, 128, PWC_FRAME_SIZE); } } /* Allocate decompressor table space */ - if (DEVICE_USE_CODEC1(pdev->type)) - err = pwc_dec1_alloc(pdev); - else - err = pwc_dec23_alloc(pdev); - - if (err) { - PWC_ERROR("Failed to allocate decompress table.\n"); - return err; - } + kbuf = NULL; + switch (pdev->type) + { + case 675: + case 680: + case 690: + case 720: + case 730: + case 740: + case 750: +#if 0 + Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private)); + kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */ + break; + case 645: + case 646: + /* TODO & FIXME */ + kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); + break; +#endif + ; + } + pdev->decompress_data = kbuf; /* Allocate image buffer; double buffer for mmap() */ - kbuf = pwc_rvmalloc(pwc_mbufs * pdev->len_per_image); + kbuf = rvmalloc(default_mbufs * pdev->len_per_image); if (kbuf == NULL) { - PWC_ERROR("Failed to allocate image buffer(s). needed (%d)\n", - pwc_mbufs * pdev->len_per_image); + Err("Failed to allocate image buffer(s). needed (%d)\n",default_mbufs * pdev->len_per_image); return -ENOMEM; } - PWC_DEBUG_MEMORY("Allocated image buffer at %p.\n", kbuf); + Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf); pdev->image_data = kbuf; - for (i = 0; i < pwc_mbufs; i++) { - pdev->images[i].offset = i * pdev->len_per_image; - pdev->images[i].vma_use_count = 0; - } - for (; i < MAX_IMAGES; i++) { - pdev->images[i].offset = 0; - } + for (i = 0; i < default_mbufs; i++) + pdev->image_ptr[i] = kbuf + i * pdev->len_per_image; + for (; i < MAX_IMAGES; i++) + pdev->image_ptr[i] = NULL; kbuf = NULL; - PWC_DEBUG_MEMORY("<< pwc_allocate_buffers()\n"); + Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n"); return 0; } @@ -338,14 +357,21 @@ static void pwc_free_buffers(struct pwc_device *pdev) { int i; - PWC_DEBUG_MEMORY("Entering free_buffers(%p).\n", pdev); + Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev); if (pdev == NULL) return; +#ifdef PWC_MAGIC + if (pdev->magic != PWC_MAGIC) { + Err("free_buffers(): magic failed.\n"); + return; + } +#endif + /* Release Iso-pipe buffers */ for (i = 0; i < MAX_ISO_BUFS; i++) if (pdev->sbuf[i].data != NULL) { - PWC_DEBUG_MEMORY("Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); + Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data); kfree(pdev->sbuf[i].data); pdev->sbuf[i].data = NULL; } @@ -354,7 +380,7 @@ static void pwc_free_buffers(struct pwc_device *pdev) if (pdev->fbuf != NULL) { for (i = 0; i < default_fbufs; i++) { if (pdev->fbuf[i].data != NULL) { - PWC_DEBUG_MEMORY("Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); + Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data); vfree(pdev->fbuf[i].data); pdev->fbuf[i].data = NULL; } @@ -365,19 +391,20 @@ static void pwc_free_buffers(struct pwc_device *pdev) /* Intermediate decompression buffer & tables */ if (pdev->decompress_data != NULL) { - PWC_DEBUG_MEMORY("Freeing decompression buffer at %p.\n", pdev->decompress_data); + Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data); kfree(pdev->decompress_data); pdev->decompress_data = NULL; } + pdev->decompressor = NULL; /* Release image buffers */ if (pdev->image_data != NULL) { - PWC_DEBUG_MEMORY("Freeing image buffer at %p.\n", pdev->image_data); - pwc_rvfree(pdev->image_data, pwc_mbufs * pdev->len_per_image); + Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data); + rvfree(pdev->image_data, default_mbufs * pdev->len_per_image); } pdev->image_data = NULL; - PWC_DEBUG_MEMORY("Leaving free_buffers().\n"); + Trace(TRACE_MEMORY, "Leaving free_buffers().\n"); } /* The frame & image buffer mess. @@ -437,7 +464,7 @@ static void pwc_free_buffers(struct pwc_device *pdev) /** \brief Find next frame buffer to fill. Take from empty or full list, whichever comes first. */ -static int pwc_next_fill_frame(struct pwc_device *pdev) +static inline int pwc_next_fill_frame(struct pwc_device *pdev) { int ret; unsigned long flags; @@ -462,17 +489,23 @@ static int pwc_next_fill_frame(struct pwc_device *pdev) } else { /* Hmm. Take it from the full list */ +#if PWC_DEBUG /* sanity check */ if (pdev->full_frames == NULL) { - PWC_ERROR("Neither empty or full frames available!\n"); + Err("Neither empty or full frames available!\n"); spin_unlock_irqrestore(&pdev->ptrlock, flags); return -EINVAL; } +#endif pdev->fill_frame = pdev->full_frames; pdev->full_frames = pdev->full_frames->next; ret = 1; } pdev->fill_frame->next = NULL; +#if PWC_DEBUG + Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence); + pdev->fill_frame->sequence = pdev->sequence++; +#endif spin_unlock_irqrestore(&pdev->ptrlock, flags); return ret; } @@ -488,8 +521,6 @@ static void pwc_reset_buffers(struct pwc_device *pdev) int i; unsigned long flags; - PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__); - spin_lock_irqsave(&pdev->ptrlock, flags); pdev->full_frames = NULL; pdev->full_frames_tail = NULL; @@ -509,15 +540,13 @@ static void pwc_reset_buffers(struct pwc_device *pdev) pdev->image_read_pos = 0; pdev->fill_image = 0; spin_unlock_irqrestore(&pdev->ptrlock, flags); - - PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__); } /** \brief Do all the handling for getting one frame: get pointer, decompress, advance pointers. */ -int pwc_handle_frame(struct pwc_device *pdev) +static int pwc_handle_frame(struct pwc_device *pdev) { int ret = 0; unsigned long flags; @@ -527,40 +556,41 @@ int pwc_handle_frame(struct pwc_device *pdev) we can release the lock after this without problems */ if (pdev->read_frame != NULL) { /* This can't theoretically happen */ - PWC_ERROR("Huh? Read frame still in use?\n"); - spin_unlock_irqrestore(&pdev->ptrlock, flags); - return ret; - } - - - if (pdev->full_frames == NULL) { - PWC_ERROR("Woops. No frames ready.\n"); + Err("Huh? Read frame still in use?\n"); } else { - pdev->read_frame = pdev->full_frames; - pdev->full_frames = pdev->full_frames->next; - pdev->read_frame->next = NULL; - } - - if (pdev->read_frame != NULL) { - /* Decompression is a lenghty process, so it's outside of the lock. - This gives the isoc_handler the opportunity to fill more frames - in the mean time. - */ - spin_unlock_irqrestore(&pdev->ptrlock, flags); - ret = pwc_decompress(pdev); - spin_lock_irqsave(&pdev->ptrlock, flags); - - /* We're done with read_buffer, tack it to the end of the empty buffer list */ - if (pdev->empty_frames == NULL) { - pdev->empty_frames = pdev->read_frame; - pdev->empty_frames_tail = pdev->empty_frames; + if (pdev->full_frames == NULL) { + Err("Woops. No frames ready.\n"); } else { - pdev->empty_frames_tail->next = pdev->read_frame; - pdev->empty_frames_tail = pdev->read_frame; + pdev->read_frame = pdev->full_frames; + pdev->full_frames = pdev->full_frames->next; + pdev->read_frame->next = NULL; + } + + if (pdev->read_frame != NULL) { +#if PWC_DEBUG + Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence); +#endif + /* Decompression is a lenghty process, so it's outside of the lock. + This gives the isoc_handler the opportunity to fill more frames + in the mean time. + */ + spin_unlock_irqrestore(&pdev->ptrlock, flags); + ret = pwc_decompress(pdev); + spin_lock_irqsave(&pdev->ptrlock, flags); + + /* We're done with read_buffer, tack it to the end of the empty buffer list */ + if (pdev->empty_frames == NULL) { + pdev->empty_frames = pdev->read_frame; + pdev->empty_frames_tail = pdev->empty_frames; + } + else { + pdev->empty_frames_tail->next = pdev->read_frame; + pdev->empty_frames_tail = pdev->read_frame; + } + pdev->read_frame = NULL; } - pdev->read_frame = NULL; } spin_unlock_irqrestore(&pdev->ptrlock, flags); return ret; @@ -569,114 +599,12 @@ int pwc_handle_frame(struct pwc_device *pdev) /** \brief Advance pointers of image buffer (after each user request) */ -void pwc_next_image(struct pwc_device *pdev) +static inline void pwc_next_image(struct pwc_device *pdev) { pdev->image_used[pdev->fill_image] = 0; - pdev->fill_image = (pdev->fill_image + 1) % pwc_mbufs; + pdev->fill_image = (pdev->fill_image + 1) % default_mbufs; } -/** - * Print debug information when a frame is discarded because all of our buffer - * is full - */ -static void pwc_frame_dumped(struct pwc_device *pdev) -{ - pdev->vframes_dumped++; - if (pdev->vframe_count < FRAME_LOWMARK) - return; - - if (pdev->vframes_dumped < 20) - PWC_DEBUG_FLOW("Dumping frame %d\n", pdev->vframe_count); - else if (pdev->vframes_dumped == 20) - PWC_DEBUG_FLOW("Dumping frame %d (last message)\n", - pdev->vframe_count); -} - -static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) -{ - int awake = 0; - - /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus - frames on the USB wire after an exposure change. This conditition is - however detected in the cam and a bit is set in the header. - */ - if (pdev->type == 730) { - unsigned char *ptr = (unsigned char *)fbuf->data; - - if (ptr[1] == 1 && ptr[0] & 0x10) { - PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n"); - pdev->drop_frames += 2; - pdev->vframes_error++; - } - if ((ptr[0] ^ pdev->vmirror) & 0x01) { - if (ptr[0] & 0x01) { - pdev->snapshot_button_status = 1; - PWC_TRACE("Snapshot button pressed.\n"); - } - else { - PWC_TRACE("Snapshot button released.\n"); - } - } - if ((ptr[0] ^ pdev->vmirror) & 0x02) { - if (ptr[0] & 0x02) - PWC_TRACE("Image is mirrored.\n"); - else - PWC_TRACE("Image is normal.\n"); - } - pdev->vmirror = ptr[0] & 0x03; - /* Sometimes the trailer of the 730 is still sent as a 4 byte packet - after a short frame; this condition is filtered out specifically. A 4 byte - frame doesn't make sense anyway. - So we get either this sequence: - drop_bit set -> 4 byte frame -> short frame -> good frame - Or this one: - drop_bit set -> short frame -> good frame - So we drop either 3 or 2 frames in all! - */ - if (fbuf->filled == 4) - pdev->drop_frames++; - } - else if (pdev->type == 740 || pdev->type == 720) { - unsigned char *ptr = (unsigned char *)fbuf->data; - if ((ptr[0] ^ pdev->vmirror) & 0x01) { - if (ptr[0] & 0x01) { - pdev->snapshot_button_status = 1; - PWC_TRACE("Snapshot button pressed.\n"); - } - else - PWC_TRACE("Snapshot button released.\n"); - } - pdev->vmirror = ptr[0] & 0x03; - } - - /* In case we were instructed to drop the frame, do so silently. - The buffer pointers are not updated either (but the counters are reset below). - */ - if (pdev->drop_frames > 0) - pdev->drop_frames--; - else { - /* Check for underflow first */ - if (fbuf->filled < pdev->frame_total_size) { - PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);" - " discarded.\n", fbuf->filled); - pdev->vframes_error++; - } - else { - /* Send only once per EOF */ - awake = 1; /* delay wake_ups */ - - /* Find our next frame to fill. This will always succeed, since we - * nick a frame from either empty or full list, but if we had to - * take it from the full list, it means a frame got dropped. - */ - if (pwc_next_fill_frame(pdev)) - pwc_frame_dumped(pdev); - - } - } /* !drop_frames */ - pdev->vframe_count++; - return awake; -} /* This gets called for the Isochronous pipe (video). This is done in * interrupt time, so it has to be fast, not crash, and not stall. Neat. @@ -692,12 +620,17 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) awake = 0; pdev = (struct pwc_device *)urb->context; if (pdev == NULL) { - PWC_ERROR("isoc_handler() called with NULL device?!\n"); + Err("isoc_handler() called with NULL device?!\n"); return; } - +#ifdef PWC_MAGIC + if (pdev->magic != PWC_MAGIC) { + Err("isoc_handler() called with bad magic!\n"); + return; + } +#endif if (urb->status == -ENOENT || urb->status == -ECONNRESET) { - PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); + Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); return; } if (urb->status != -EINPROGRESS && urb->status != 0) { @@ -712,13 +645,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break; case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break; } - PWC_DEBUG_FLOW("pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); + Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg); /* Give up after a number of contiguous errors on the USB bus. Appearantly something is wrong so we simulate an unplug event. */ if (++pdev->visoc_errors > MAX_ISOC_ERRORS) { - PWC_INFO("Too many ISOC errors, bailing out.\n"); + Info("Too many ISOC errors, bailing out.\n"); pdev->error_status = EIO; awake = 1; wake_up_interruptible(&pdev->frameq); @@ -728,7 +661,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) fbuf = pdev->fill_frame; if (fbuf == NULL) { - PWC_ERROR("pwc_isoc_handler without valid fill frame.\n"); + Err("pwc_isoc_handler without valid fill frame.\n"); awake = 1; goto handler_end; } @@ -755,7 +688,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) /* ...copy data to frame buffer, if possible */ if (flen + fbuf->filled > pdev->frame_total_size) { - PWC_DEBUG_FLOW("Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); + Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ pdev->vframes_error++; } @@ -771,28 +704,96 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) /* Shorter packet... We probably have the end of an image-frame; wake up read() process and let select()/poll() do something. Decompression is done in user time over there. - */ + */ if (pdev->vsync == 2) { - if (pwc_rcv_short_packet(pdev, fbuf)) { - awake = 1; - fbuf = pdev->fill_frame; + /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus + frames on the USB wire after an exposure change. This conditition is + however detected in the cam and a bit is set in the header. + */ + if (pdev->type == 730) { + unsigned char *ptr = (unsigned char *)fbuf->data; + + if (ptr[1] == 1 && ptr[0] & 0x10) { +#if PWC_DEBUG + Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence); +#endif + pdev->drop_frames += 2; + pdev->vframes_error++; + } + if ((ptr[0] ^ pdev->vmirror) & 0x01) { + if (ptr[0] & 0x01) + Info("Snapshot button pressed.\n"); + else + Info("Snapshot button released.\n"); + } + if ((ptr[0] ^ pdev->vmirror) & 0x02) { + if (ptr[0] & 0x02) + Info("Image is mirrored.\n"); + else + Info("Image is normal.\n"); + } + pdev->vmirror = ptr[0] & 0x03; + /* Sometimes the trailer of the 730 is still sent as a 4 byte packet + after a short frame; this condition is filtered out specifically. A 4 byte + frame doesn't make sense anyway. + So we get either this sequence: + drop_bit set -> 4 byte frame -> short frame -> good frame + Or this one: + drop_bit set -> short frame -> good frame + So we drop either 3 or 2 frames in all! + */ + if (fbuf->filled == 4) + pdev->drop_frames++; } + + /* In case we were instructed to drop the frame, do so silently. + The buffer pointers are not updated either (but the counters are reset below). + */ + if (pdev->drop_frames > 0) + pdev->drop_frames--; + else { + /* Check for underflow first */ + if (fbuf->filled < pdev->frame_total_size) { + Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled); + pdev->vframes_error++; + } + else { + /* Send only once per EOF */ + awake = 1; /* delay wake_ups */ + + /* Find our next frame to fill. This will always succeed, since we + * nick a frame from either empty or full list, but if we had to + * take it from the full list, it means a frame got dropped. + */ + if (pwc_next_fill_frame(pdev)) { + pdev->vframes_dumped++; + if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) { + if (pdev->vframes_dumped < 20) + Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count); + if (pdev->vframes_dumped == 20) + Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count); + } + } + fbuf = pdev->fill_frame; + } + } /* !drop_frames */ + pdev->vframe_count++; } fbuf->filled = 0; fillptr = fbuf->data; pdev->vsync = 1; - } - + } /* .. flen < last_packet_size */ pdev->vlast_packet_size = flen; } /* ..status == 0 */ +#if PWC_DEBUG + /* This is normally not interesting to the user, unless you are really debugging something */ else { - /* This is normally not interesting to the user, unless - * you are really debugging something */ static int iso_error = 0; iso_error++; if (iso_error < 20) - PWC_DEBUG_FLOW("Iso frame %d of USB has error %d\n", i, fst); + Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst); } +#endif } handler_end: @@ -802,11 +803,11 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs) urb->dev = pdev->udev; i = usb_submit_urb(urb, GFP_ATOMIC); if (i != 0) - PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); + Err("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); } -int pwc_isoc_init(struct pwc_device *pdev) +static int pwc_isoc_init(struct pwc_device *pdev) { struct usb_device *udev; struct urb *urb; @@ -825,6 +826,7 @@ int pwc_isoc_init(struct pwc_device *pdev) /* Get the current alternate interface, adjust packet size */ if (!udev->actconfig) return -EFAULT; + intf = usb_ifnum_to_if(udev, 0); if (intf) idesc = usb_altnum_to_altsetting(intf, pdev->valternate); @@ -834,21 +836,20 @@ int pwc_isoc_init(struct pwc_device *pdev) /* Search video endpoint */ pdev->vmax_packet_size = -1; - for (i = 0; i < idesc->desc.bNumEndpoints; i++) { + for (i = 0; i < idesc->desc.bNumEndpoints; i++) if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize); break; } - } if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { - PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n"); + Err("Failed to find packet size for video endpoint in current alternate setting.\n"); return -ENFILE; /* Odd error, that should be noticeable */ } /* Set alternate interface */ ret = 0; - PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); + Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate); ret = usb_set_interface(pdev->udev, 0, pdev->valternate); if (ret < 0) return ret; @@ -856,12 +857,12 @@ int pwc_isoc_init(struct pwc_device *pdev) for (i = 0; i < MAX_ISO_BUFS; i++) { urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); if (urb == NULL) { - PWC_ERROR("Failed to allocate urb %d\n", i); + Err("Failed to allocate urb %d\n", i); ret = -ENOMEM; break; } pdev->sbuf[i].urb = urb; - PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb); + Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb); } if (ret) { /* De-allocate in reverse order */ @@ -898,26 +899,24 @@ int pwc_isoc_init(struct pwc_device *pdev) for (i = 0; i < MAX_ISO_BUFS; i++) { ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); if (ret) - PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); + Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); else - PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); + Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); } /* All is done... */ pdev->iso_init = 1; - PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); + Trace(TRACE_OPEN, "<< pwc_isoc_init()\n"); return 0; } -void pwc_isoc_cleanup(struct pwc_device *pdev) +static void pwc_isoc_cleanup(struct pwc_device *pdev) { int i; - PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); + Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); if (pdev == NULL) return; - if (pdev->iso_init == 0) - return; /* Unlinking ISOC buffers one by one */ for (i = 0; i < MAX_ISO_BUFS; i++) { @@ -926,10 +925,10 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) urb = pdev->sbuf[i].urb; if (urb != 0) { if (pdev->iso_init) { - PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb); + Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb); usb_kill_urb(urb); } - PWC_DEBUG_MEMORY("Freeing URB\n"); + Trace(TRACE_MEMORY, "Freeing URB\n"); usb_free_urb(urb); pdev->sbuf[i].urb = NULL; } @@ -939,12 +938,12 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) is signalled by EPIPE) */ if (pdev->error_status && pdev->error_status != EPIPE) { - PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); + Trace(TRACE_OPEN, "Setting alternate interface 0.\n"); usb_set_interface(pdev->udev, 0, 0); } pdev->iso_init = 0; - PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); + Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n"); } int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) @@ -958,18 +957,18 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f /* Try to set video mode... */ start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); if (ret) { - PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n"); + Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n"); /* That failed... restore old mode (we know that worked) */ start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); if (start) { - PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n"); + Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); } } if (start == 0) { if (pwc_isoc_init(pdev) < 0) { - PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); + Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); ret = -EAGAIN; /* let's try again, who knows if it works a second time */ } } @@ -977,129 +976,54 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f return ret; /* Return original error code */ } -/********* - * sysfs - *********/ -static struct pwc_device *cd_to_pwc(struct class_device *cd) -{ - struct video_device *vdev = to_video_device(cd); - return video_get_drvdata(vdev); -} - -static ssize_t show_pan_tilt(struct class_device *class_dev, char *buf) -{ - struct pwc_device *pdev = cd_to_pwc(class_dev); - return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle); -} - -static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf, - size_t count) -{ - struct pwc_device *pdev = cd_to_pwc(class_dev); - int pan, tilt; - int ret = -EINVAL; - - if (strncmp(buf, "reset", 5) == 0) - ret = pwc_mpt_reset(pdev, 0x3); - - else if (sscanf(buf, "%d %d", &pan, &tilt) > 0) - ret = pwc_mpt_set_angle(pdev, pan, tilt); - - if (ret < 0) - return ret; - return strlen(buf); -} -static CLASS_DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt, - store_pan_tilt); - -static ssize_t show_snapshot_button_status(struct class_device *class_dev, char *buf) -{ - struct pwc_device *pdev = cd_to_pwc(class_dev); - int status = pdev->snapshot_button_status; - pdev->snapshot_button_status = 0; - return sprintf(buf, "%d\n", status); -} - -static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, - NULL); - -static void pwc_create_sysfs_files(struct video_device *vdev) -{ - struct pwc_device *pdev = video_get_drvdata(vdev); - if (pdev->features & FEATURE_MOTOR_PANTILT) - video_device_create_file(vdev, &class_device_attr_pan_tilt); - video_device_create_file(vdev, &class_device_attr_button); -} - -static void pwc_remove_sysfs_files(struct video_device *vdev) -{ - struct pwc_device *pdev = video_get_drvdata(vdev); - if (pdev->features & FEATURE_MOTOR_PANTILT) - video_device_remove_file(vdev, &class_device_attr_pan_tilt); - video_device_remove_file(vdev, &class_device_attr_button); -} - -#if CONFIG_PWC_DEBUG -static const char *pwc_sensor_type_to_string(unsigned int sensor_type) -{ - switch(sensor_type) { - case 0x00: - return "Hyundai CMOS sensor"; - case 0x20: - return "Sony CCD sensor + TDA8787"; - case 0x2E: - return "Sony CCD sensor + Exas 98L59"; - case 0x2F: - return "Sony CCD sensor + ADI 9804"; - case 0x30: - return "Sharp CCD sensor + TDA8787"; - case 0x3E: - return "Sharp CCD sensor + Exas 98L59"; - case 0x3F: - return "Sharp CCD sensor + ADI 9804"; - case 0x40: - return "UPA 1021 sensor"; - case 0x100: - return "VGA sensor"; - case 0x101: - return "PAL MR sensor"; - default: - return "unknown type of sensor"; - } -} -#endif /***************************************************************************/ /* Video4Linux functions */ static int pwc_video_open(struct inode *inode, struct file *file) { - int i, ret; + int i; struct video_device *vdev = video_devdata(file); struct pwc_device *pdev; - PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); + Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev); pdev = (struct pwc_device *)vdev->priv; if (pdev == NULL) BUG(); - if (pdev->vopen) { - PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); + if (pdev->vopen) return -EBUSY; - } down(&pdev->modlock); if (!pdev->usb_init) { - PWC_DEBUG_OPEN("Doing first time initialization.\n"); + Trace(TRACE_OPEN, "Doing first time initialization.\n"); pdev->usb_init = 1; - /* Query sensor type */ - ret = pwc_get_cmos_sensor(pdev, &i); - if (ret >= 0) + if (pwc_trace & TRACE_OPEN) { - PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", - pdev->vdev->name, - pwc_sensor_type_to_string(i), i); + /* Query sensor type */ + const char *sensor_type = NULL; + int ret; + + ret = pwc_get_cmos_sensor(pdev, &i); + if (ret >= 0) + { + switch(i) { + case 0x00: sensor_type = "Hyundai CMOS sensor"; break; + case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break; + case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break; + case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break; + case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break; + case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break; + case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break; + case 0x40: sensor_type = "UPA 1021 sensor"; break; + case 0x100: sensor_type = "VGA sensor"; break; + case 0x101: sensor_type = "PAL MR sensor"; break; + default: sensor_type = "unknown type of sensor"; break; + } + } + if (sensor_type != NULL) + Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev->name, sensor_type, i); } } @@ -1107,32 +1031,34 @@ static int pwc_video_open(struct inode *inode, struct file *file) if (power_save) { i = pwc_camera_power(pdev, 1); if (i < 0) - PWC_DEBUG_OPEN("Failed to restore power to the camera! (%d)\n", i); + Info("Failed to restore power to the camera! (%d)\n", i); } /* Set LED on/off time */ if (pwc_set_leds(pdev, led_on, led_off) < 0) - PWC_DEBUG_OPEN("Failed to set LED on/off time.\n"); + Info("Failed to set LED on/off time.\n"); pwc_construct(pdev); /* set min/max sizes correct */ /* So far, so good. Allocate memory. */ i = pwc_allocate_buffers(pdev); if (i < 0) { - PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); - pwc_free_buffers(pdev); + Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n"); up(&pdev->modlock); return i; } /* Reset buffers & parameters */ pwc_reset_buffers(pdev); - for (i = 0; i < pwc_mbufs; i++) + for (i = 0; i < default_mbufs; i++) pdev->image_used[i] = 0; pdev->vframe_count = 0; pdev->vframes_dumped = 0; pdev->vframes_error = 0; pdev->visoc_errors = 0; pdev->error_status = 0; +#if PWC_DEBUG + pdev->sequence = 0; +#endif pwc_construct(pdev); /* set min/max sizes correct */ /* Set some defaults */ @@ -1144,44 +1070,29 @@ static int pwc_video_open(struct inode *inode, struct file *file) */ i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0); if (i) { - unsigned int default_resolution; - PWC_DEBUG_OPEN("First attempt at set_video_mode failed.\n"); - if (pdev->type>= 730) - default_resolution = PSZ_QSIF; + Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n"); + if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750) + i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0); else - default_resolution = PSZ_QCIF; - - i = pwc_set_video_mode(pdev, - pwc_image_sizes[default_resolution].x, - pwc_image_sizes[default_resolution].y, - 10, - pdev->vcompression, - 0); + i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0); } if (i) { - PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); - pwc_free_buffers(pdev); + Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n"); up(&pdev->modlock); return i; } i = pwc_isoc_init(pdev); if (i) { - PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); - pwc_isoc_cleanup(pdev); - pwc_free_buffers(pdev); + Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i); up(&pdev->modlock); return i; } - /* Initialize the webcam to sane value */ - pwc_set_brightness(pdev, 0x7fff); - pwc_set_agc(pdev, 1, 0); - pdev->vopen++; file->private_data = vdev; up(&pdev->modlock); - PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); + Trace(TRACE_OPEN, "<< video_open() returns 0.\n"); return 0; } @@ -1192,23 +1103,35 @@ static int pwc_video_close(struct inode *inode, struct file *file) struct pwc_device *pdev; int i; - PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); + Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev); pdev = (struct pwc_device *)vdev->priv; if (pdev->vopen == 0) - PWC_DEBUG_MODULE("video_close() called on closed device?\n"); + Info("video_close() called on closed device?\n"); /* Dump statistics, but only if a reasonable amount of frames were processed (to prevent endless log-entries in case of snap-shot programs) */ if (pdev->vframe_count > 20) - PWC_DEBUG_MODULE("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); + Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); - if (DEVICE_USE_CODEC1(pdev->type)) - pwc_dec1_exit(); - else - pwc_dec23_exit(); + switch (pdev->type) + { + case 675: + case 680: + case 690: + case 720: + case 730: + case 740: + case 750: +/* pwc_dec23_exit(); *//* Timon & Kiara */ + break; + case 645: + case 646: +/* pwc_dec1_exit(); */ + break; + } pwc_isoc_cleanup(pdev); pwc_free_buffers(pdev); @@ -1217,15 +1140,15 @@ static int pwc_video_close(struct inode *inode, struct file *file) if (pdev->error_status != EPIPE) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) - PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); + Info("Failed to set LED on/off time.\n"); if (power_save) { i = pwc_camera_power(pdev, 0); if (i < 0) - PWC_ERROR("Failed to power down camera (%d)\n", i); + Err("Failed to power down camera (%d)\n", i); } } - pdev->vopen--; - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + pdev->vopen = 0; + Trace(TRACE_OPEN, "<< video_close()\n"); return 0; } @@ -1241,7 +1164,7 @@ static int pwc_video_close(struct inode *inode, struct file *file) device is tricky anyhow. */ -static ssize_t pwc_video_read(struct file *file, char __user *buf, +static ssize_t pwc_video_read(struct file *file, char __user * buf, size_t count, loff_t *ppos) { struct video_device *vdev = file->private_data; @@ -1249,10 +1172,8 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, int noblock = file->f_flags & O_NONBLOCK; DECLARE_WAITQUEUE(wait, current); int bytes_to_read; - void *image_buffer_addr; - PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n", - vdev, buf, count); + Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count); if (vdev == NULL) return -EFAULT; pdev = vdev->priv; @@ -1293,19 +1214,16 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, return -EFAULT; } - PWC_DEBUG_READ("Copying data to user space.\n"); + Trace(TRACE_READ, "Copying data to user space.\n"); if (pdev->vpalette == VIDEO_PALETTE_RAW) - bytes_to_read = pdev->frame_size + sizeof(struct pwc_raw_frame); + bytes_to_read = pdev->frame_size; else bytes_to_read = pdev->view.size; /* copy bytes to user space; we allow for partial reads */ if (count + pdev->image_read_pos > bytes_to_read) count = bytes_to_read - pdev->image_read_pos; - image_buffer_addr = pdev->image_data; - image_buffer_addr += pdev->images[pdev->fill_image].offset; - image_buffer_addr += pdev->image_read_pos; - if (copy_to_user(buf, image_buffer_addr, count)) + if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) return -EFAULT; pdev->image_read_pos += count; if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ @@ -1335,56 +1253,370 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) return 0; } +static int pwc_video_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *vdev = file->private_data; + struct pwc_device *pdev; + DECLARE_WAITQUEUE(wait, current); + + if (vdev == NULL) + return -EFAULT; + pdev = vdev->priv; + if (pdev == NULL) + return -EFAULT; + + switch (cmd) { + /* Query cabapilities */ + case VIDIOCGCAP: + { + struct video_capability *caps = arg; + + strcpy(caps->name, vdev->name); + caps->type = VID_TYPE_CAPTURE; + caps->channels = 1; + caps->audios = 1; + caps->minwidth = pdev->view_min.x; + caps->minheight = pdev->view_min.y; + caps->maxwidth = pdev->view_max.x; + caps->maxheight = pdev->view_max.y; + break; + } + + /* Channel functions (simulate 1 channel) */ + case VIDIOCGCHAN: + { + struct video_channel *v = arg; + + if (v->channel != 0) + return -EINVAL; + v->flags = 0; + v->tuners = 0; + v->type = VIDEO_TYPE_CAMERA; + strcpy(v->name, "Webcam"); + return 0; + } + + case VIDIOCSCHAN: + { + /* The spec says the argument is an integer, but + the bttv driver uses a video_channel arg, which + makes sense becasue it also has the norm flag. + */ + struct video_channel *v = arg; + if (v->channel != 0) + return -EINVAL; + return 0; + } + + + /* Picture functions; contrast etc. */ + case VIDIOCGPICT: + { + struct video_picture *p = arg; + int val; + + val = pwc_get_brightness(pdev); + if (val >= 0) + p->brightness = val; + else + p->brightness = 0xffff; + val = pwc_get_contrast(pdev); + if (val >= 0) + p->contrast = val; + else + p->contrast = 0xffff; + /* Gamma, Whiteness, what's the difference? :) */ + val = pwc_get_gamma(pdev); + if (val >= 0) + p->whiteness = val; + else + p->whiteness = 0xffff; + val = pwc_get_saturation(pdev); + if (val >= 0) + p->colour = val; + else + p->colour = 0xffff; + p->depth = 24; + p->palette = pdev->vpalette; + p->hue = 0xFFFF; /* N/A */ + break; + } + + case VIDIOCSPICT: + { + struct video_picture *p = arg; + /* + * FIXME: Suppose we are mid read + ANSWER: No problem: the firmware of the camera + can handle brightness/contrast/etc + changes at _any_ time, and the palette + is used exactly once in the uncompress + routine. + */ + pwc_set_brightness(pdev, p->brightness); + pwc_set_contrast(pdev, p->contrast); + pwc_set_gamma(pdev, p->whiteness); + pwc_set_saturation(pdev, p->colour); + if (p->palette && p->palette != pdev->vpalette) { + switch (p->palette) { + case VIDEO_PALETTE_YUV420P: + case VIDEO_PALETTE_RAW: + pdev->vpalette = p->palette; + return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); + break; + default: + return -EINVAL; + break; + } + } + break; + } + + /* Window/size parameters */ + case VIDIOCGWIN: + { + struct video_window *vw = arg; + + vw->x = 0; + vw->y = 0; + vw->width = pdev->view.x; + vw->height = pdev->view.y; + vw->chromakey = 0; + vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | + (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); + break; + } + + case VIDIOCSWIN: + { + struct video_window *vw = arg; + int fps, snapshot, ret; + + fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; + snapshot = vw->flags & PWC_FPS_SNAPSHOT; + if (fps == 0) + fps = pdev->vframes; + if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) + return 0; + ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); + if (ret) + return ret; + break; + } + + /* We don't have overlay support (yet) */ + case VIDIOCGFBUF: + { + struct video_buffer *vb = arg; + + memset(vb,0,sizeof(*vb)); + break; + } + + /* mmap() functions */ + case VIDIOCGMBUF: + { + /* Tell the user program how much memory is needed for a mmap() */ + struct video_mbuf *vm = arg; + int i; + + memset(vm, 0, sizeof(*vm)); + vm->size = default_mbufs * pdev->len_per_image; + vm->frames = default_mbufs; /* double buffering should be enough for most applications */ + for (i = 0; i < default_mbufs; i++) + vm->offsets[i] = i * pdev->len_per_image; + break; + } + + case VIDIOCMCAPTURE: + { + /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ + struct video_mmap *vm = arg; + + Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); + if (vm->frame < 0 || vm->frame >= default_mbufs) + return -EINVAL; + + /* xawtv is nasty. It probes the available palettes + by setting a very small image size and trying + various palettes... The driver doesn't support + such small images, so I'm working around it. + */ + if (vm->format) + { + switch (vm->format) + { + case VIDEO_PALETTE_YUV420P: + case VIDEO_PALETTE_RAW: + break; + default: + return -EINVAL; + break; + } + } + + if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && + (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { + int ret; + + Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); + ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); + if (ret) + return ret; + } /* ... size mismatch */ + + /* FIXME: should we lock here? */ + if (pdev->image_used[vm->frame]) + return -EBUSY; /* buffer wasn't available. Bummer */ + pdev->image_used[vm->frame] = 1; + + /* Okay, we're done here. In the SYNC call we wait until a + frame comes available, then expand image into the given + buffer. + In contrast to the CPiA cam the Philips cams deliver a + constant stream, almost like a grabber card. Also, + we have separate buffers for the rawdata and the image, + meaning we can nearly always expand into the requested buffer. + */ + Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n"); + break; + } + + case VIDIOCSYNC: + { + /* The doc says: "Whenever a buffer is used it should + call VIDIOCSYNC to free this frame up and continue." + + The only odd thing about this whole procedure is + that MCAPTURE flags the buffer as "in use", and + SYNC immediately unmarks it, while it isn't + after SYNC that you know that the buffer actually + got filled! So you better not start a CAPTURE in + the same frame immediately (use double buffering). + This is not a problem for this cam, since it has + extra intermediate buffers, but a hardware + grabber card will then overwrite the buffer + you're working on. + */ + int *mbuf = arg; + int ret; + + Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", *mbuf); + + /* bounds check */ + if (*mbuf < 0 || *mbuf >= default_mbufs) + return -EINVAL; + /* check if this buffer was requested anyway */ + if (pdev->image_used[*mbuf] == 0) + return -EINVAL; + + /* Add ourselves to the frame wait-queue. + + FIXME: needs auditing for safety. + QUESTION: In what respect? I think that using the + frameq is safe now. + */ + add_wait_queue(&pdev->frameq, &wait); + while (pdev->full_frames == NULL) { + if (pdev->error_status) { + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + return -pdev->error_status; + } + + if (signal_pending(current)) { + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + return -ERESTARTSYS; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + remove_wait_queue(&pdev->frameq, &wait); + set_current_state(TASK_RUNNING); + + /* The frame is ready. Expand in the image buffer + requested by the user. I don't care if you + mmap() 5 buffers and request data in this order: + buffer 4 2 3 0 1 2 3 0 4 3 1 . . . + Grabber hardware may not be so forgiving. + */ + Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n"); + pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ + /* Decompress, etc */ + ret = pwc_handle_frame(pdev); + pdev->image_used[*mbuf] = 0; + if (ret) + return -EFAULT; + break; + } + + case VIDIOCGAUDIO: + { + struct video_audio *v = arg; + + strcpy(v->name, "Microphone"); + v->audio = -1; /* unknown audio minor */ + v->flags = 0; + v->mode = VIDEO_SOUND_MONO; + v->volume = 0; + v->bass = 0; + v->treble = 0; + v->balance = 0x8000; + v->step = 1; + break; + } + + case VIDIOCSAUDIO: + { + /* Dummy: nothing can be set */ + break; + } + + case VIDIOCGUNIT: + { + struct video_unit *vu = arg; + + vu->video = pdev->vdev->minor & 0x3F; + vu->audio = -1; /* not known yet */ + vu->vbi = -1; + vu->radio = -1; + vu->teletext = -1; + break; + } + default: + return pwc_ioctl(pdev, cmd, arg); + } /* ..switch */ + return 0; +} + static int pwc_video_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl); } + static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - unsigned long start; - unsigned long size; - unsigned long page, pos = 0; - int index; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end-vma->vm_start; + unsigned long page, pos; - PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__); + Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size); pdev = vdev->priv; - size = vma->vm_end - vma->vm_start; - start = vma->vm_start; - /* Find the idx buffer for this mapping */ - for (index = 0; index < pwc_mbufs; index++) { - pos = pdev->images[index].offset; - if ((pos>>PAGE_SHIFT) == vma->vm_pgoff) - break; - } - if (index == MAX_IMAGES) - return -EINVAL; - if (index == 0) { - /* - * Special case for v4l1. In v4l1, we map only one big buffer, - * but in v4l2 each buffer is mapped - */ - unsigned long total_size; - total_size = pwc_mbufs * pdev->len_per_image; - if (size != pdev->len_per_image && size != total_size) { - PWC_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n", - size, pdev->len_per_image, total_size); - return -EINVAL; - } - } else if (size > pdev->len_per_image) - return -EINVAL; + vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_IO; /* from 2.6.9-acX */ - - pos += (unsigned long)pdev->image_data; + pos = (unsigned long)pdev->image_data; while (size > 0) { page = vmalloc_to_pfn((void *)pos); if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; + start += PAGE_SIZE; pos += PAGE_SIZE; if (size > PAGE_SIZE) @@ -1392,6 +1624,7 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) else size = 0; } + return 0; } @@ -1412,12 +1645,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id int video_nr = -1; /* default: use next available device */ char serial_number[30], *name; - vendor_id = le16_to_cpu(udev->descriptor.idVendor); - product_id = le16_to_cpu(udev->descriptor.idProduct); - /* Check if we can handle this device */ - PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n", - vendor_id, product_id, + Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), intf->altsetting->desc.bInterfaceNumber); /* the interfaces are probed one by one. We are only interested in the @@ -1427,63 +1658,61 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id if (intf->altsetting->desc.bInterfaceNumber > 0) return -ENODEV; + vendor_id = le16_to_cpu(udev->descriptor.idVendor); + product_id = le16_to_cpu(udev->descriptor.idProduct); + if (vendor_id == 0x0471) { switch (product_id) { case 0x0302: - PWC_INFO("Philips PCA645VC USB webcam detected.\n"); + Info("Philips PCA645VC USB webcam detected.\n"); name = "Philips 645 webcam"; type_id = 645; break; case 0x0303: - PWC_INFO("Philips PCA646VC USB webcam detected.\n"); + Info("Philips PCA646VC USB webcam detected.\n"); name = "Philips 646 webcam"; type_id = 646; break; case 0x0304: - PWC_INFO("Askey VC010 type 2 USB webcam detected.\n"); + Info("Askey VC010 type 2 USB webcam detected.\n"); name = "Askey VC010 webcam"; type_id = 646; break; case 0x0307: - PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n"); + Info("Philips PCVC675K (Vesta) USB webcam detected.\n"); name = "Philips 675 webcam"; type_id = 675; break; case 0x0308: - PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); + Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); name = "Philips 680 webcam"; type_id = 680; break; case 0x030C: - PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); + Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); name = "Philips 690 webcam"; type_id = 690; break; case 0x0310: - PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); + Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); name = "Philips 730 webcam"; type_id = 730; break; case 0x0311: - PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); + Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); name = "Philips 740 webcam"; type_id = 740; break; case 0x0312: - PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); + Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); name = "Philips 750 webcam"; type_id = 750; break; case 0x0313: - PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); + Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); name = "Philips 720K/40 webcam"; type_id = 720; break; - case 0x0329: - PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); - name = "Philips SPC 900NC webcam"; - type_id = 720; - break; default: return -ENODEV; break; @@ -1492,7 +1721,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id else if (vendor_id == 0x069A) { switch(product_id) { case 0x0001: - PWC_INFO("Askey VC010 type 1 USB webcam detected.\n"); + Info("Askey VC010 type 1 USB webcam detected.\n"); name = "Askey VC010 webcam"; type_id = 645; break; @@ -1504,33 +1733,32 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id else if (vendor_id == 0x046d) { switch(product_id) { case 0x08b0: - PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n"); + Info("Logitech QuickCam Pro 3000 USB webcam detected.\n"); name = "Logitech QuickCam Pro 3000"; type_id = 740; /* CCD sensor */ break; case 0x08b1: - PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n"); + Info("Logitech QuickCam Notebook Pro USB webcam detected.\n"); name = "Logitech QuickCam Notebook Pro"; type_id = 740; /* CCD sensor */ break; case 0x08b2: - PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n"); + Info("Logitech QuickCam 4000 Pro USB webcam detected.\n"); name = "Logitech QuickCam Pro 4000"; type_id = 740; /* CCD sensor */ break; case 0x08b3: - PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n"); + Info("Logitech QuickCam Zoom USB webcam detected.\n"); name = "Logitech QuickCam Zoom"; type_id = 740; /* CCD sensor */ break; case 0x08B4: - PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); + Info("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); name = "Logitech QuickCam Zoom"; type_id = 740; /* CCD sensor */ - power_save = 1; break; case 0x08b5: - PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); + Info("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); name = "Logitech QuickCam Orbit"; type_id = 740; /* CCD sensor */ features |= FEATURE_MOTOR_PANTILT; @@ -1538,7 +1766,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id case 0x08b6: case 0x08b7: case 0x08b8: - PWC_INFO("Logitech QuickCam detected (reserved ID).\n"); + Info("Logitech QuickCam detected (reserved ID).\n"); name = "Logitech QuickCam (res.)"; type_id = 730; /* Assuming CMOS */ break; @@ -1554,20 +1782,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id */ switch(product_id) { case 0x9000: - PWC_INFO("Samsung MPC-C10 USB webcam detected.\n"); + Info("Samsung MPC-C10 USB webcam detected.\n"); name = "Samsung MPC-C10"; type_id = 675; break; case 0x9001: - PWC_INFO("Samsung MPC-C30 USB webcam detected.\n"); + Info("Samsung MPC-C30 USB webcam detected.\n"); name = "Samsung MPC-C30"; type_id = 675; break; - case 0x9002: - PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n"); - name = "Samsung MPC-C30"; - type_id = 740; - break; default: return -ENODEV; break; @@ -1576,12 +1799,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id else if (vendor_id == 0x041e) { switch(product_id) { case 0x400c: - PWC_INFO("Creative Labs Webcam 5 detected.\n"); + Info("Creative Labs Webcam 5 detected.\n"); name = "Creative Labs Webcam 5"; type_id = 730; break; case 0x4011: - PWC_INFO("Creative Labs Webcam Pro Ex detected.\n"); + Info("Creative Labs Webcam Pro Ex detected.\n"); name = "Creative Labs Webcam Pro Ex"; type_id = 740; break; @@ -1593,7 +1816,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id else if (vendor_id == 0x04cc) { switch(product_id) { case 0x8116: - PWC_INFO("Sotec Afina Eye USB webcam detected.\n"); + Info("Sotec Afina Eye USB webcam detected.\n"); name = "Sotec Afina Eye"; type_id = 730; break; @@ -1606,7 +1829,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id switch(product_id) { case 0x8116: /* This is essentially the same cam as the Sotec Afina Eye */ - PWC_INFO("AME Co. Afina Eye USB webcam detected.\n"); + Info("AME Co. Afina Eye USB webcam detected.\n"); name = "AME Co. Afina Eye"; type_id = 750; break; @@ -1619,12 +1842,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id else if (vendor_id == 0x0d81) { switch(product_id) { case 0x1900: - PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n"); + Info("Visionite VCS-UC300 USB webcam detected.\n"); name = "Visionite VCS-UC300"; type_id = 740; /* CCD sensor */ break; case 0x1910: - PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n"); + Info("Visionite VCS-UM100 USB webcam detected.\n"); name = "Visionite VCS-UM100"; type_id = 730; /* CMOS sensor */ break; @@ -1638,15 +1861,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id memset(serial_number, 0, 30); usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); - PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number); + Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number); if (udev->descriptor.bNumConfigurations > 1) - PWC_WARNING("Warning: more than 1 configuration available.\n"); + Info("Warning: more than 1 configuration available.\n"); /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); if (pdev == NULL) { - PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); + Err("Oops, could not allocate memory for pwc_device.\n"); return -ENOMEM; } pdev->type = type_id; @@ -1677,18 +1900,17 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vdev = video_device_alloc(); if (pdev->vdev == 0) { - PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); + Err("Err, cannot allocate video_device struture. Failing probe."); kfree(pdev); return -ENOMEM; } memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); - pdev->vdev->dev = &(udev->dev); strcpy(pdev->vdev->name, name); pdev->vdev->owner = THIS_MODULE; video_set_drvdata(pdev->vdev, pdev); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); - PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); + Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); /* Now search device_hint[] table for a match, so we can hint a node number. */ for (hint = 0; hint < MAX_DEV_HINTS; hint++) { @@ -1696,10 +1918,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id (device_hint[hint].pdev == NULL)) { /* so far, so good... try serial number */ if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) { - /* match! */ - video_nr = device_hint[hint].device_node; - PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr); - break; + /* match! */ + video_nr = device_hint[hint].device_node; + Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr); + break; } } } @@ -1707,27 +1929,21 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pdev->vdev->release = video_device_release; i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); if (i < 0) { - PWC_ERROR("Failed to register as video device (%d).\n", i); + Err("Failed to register as video device (%d).\n", i); video_device_release(pdev->vdev); /* Drip... drip... drip... */ kfree(pdev); /* Oops, no memory leaks please */ return -EIO; } else { - PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); + Info("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); } /* occupy slot */ if (hint < MAX_DEV_HINTS) device_hint[hint].pdev = pdev; - PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); + Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev); usb_set_intfdata (intf, pdev); - pwc_create_sysfs_files(pdev->vdev); - - /* Set the leds off */ - pwc_set_leds(pdev, 0, 0); - pwc_camera_power(pdev, 0); - return 0; } @@ -1741,21 +1957,27 @@ static void usb_pwc_disconnect(struct usb_interface *intf) pdev = usb_get_intfdata (intf); usb_set_intfdata (intf, NULL); if (pdev == NULL) { - PWC_ERROR("pwc_disconnect() Called without private pointer.\n"); + Err("pwc_disconnect() Called without private pointer.\n"); goto disconnect_out; } if (pdev->udev == NULL) { - PWC_ERROR("pwc_disconnect() already called for %p\n", pdev); + Err("pwc_disconnect() already called for %p\n", pdev); goto disconnect_out; } if (pdev->udev != interface_to_usbdev(intf)) { - PWC_ERROR("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); + Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); + goto disconnect_out; + } +#ifdef PWC_MAGIC + if (pdev->magic != PWC_MAGIC) { + Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); goto disconnect_out; } +#endif /* We got unplugged; this is signalled by an EPIPE error code */ if (pdev->vopen) { - PWC_INFO("Disconnected while webcam is in use!\n"); + Info("Disconnected while webcam is in use!\n"); pdev->error_status = EPIPE; } @@ -1765,8 +1987,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf) while (pdev->vopen) schedule(); /* Device is now closed, so we can safely unregister it */ - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); - pwc_remove_sysfs_files(pdev->vdev); + Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); video_unregister_device(pdev->vdev); /* Free memory (don't set pdev to 0 just yet) */ @@ -1800,64 +2021,58 @@ static int pwc_atoi(const char *s) * Initialization code & module stuff */ -static char *size; -static int fps; -static int fbufs; -static int mbufs; +static char size[10]; +static int fps = 0; +static int fbufs = 0; +static int mbufs = 0; +static int trace = -1; static int compression = -1; static int leds[2] = { -1, -1 }; -static int leds_nargs; -static char *dev_hint[MAX_DEV_HINTS]; -static int dev_hint_nargs; - -module_param(size, charp, 0444); -module_param(fps, int, 0444); -module_param(fbufs, int, 0444); -module_param(mbufs, int, 0444); -#if CONFIG_PWC_DEBUG -module_param_named(trace, pwc_trace, int, 0644); -#endif -module_param(power_save, int, 0444); -module_param(compression, int, 0444); -module_param_array(leds, int, &leds_nargs, 0444); -module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); +static char *dev_hint[MAX_DEV_HINTS] = { }; +module_param_string(size, size, sizeof(size), 0); MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga"); +module_param(fps, int, 0000); MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); +module_param(fbufs, int, 0000); MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); +module_param(mbufs, int, 0000); MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); +module_param(trace, int, 0000); MODULE_PARM_DESC(trace, "For debugging purposes"); +module_param(power_save, bool, 0000); MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); +module_param(compression, int, 0000); MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); +module_param_array(leds, int, NULL, 0000); MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); +module_param_array(dev_hint, charp, NULL, 0000); MODULE_PARM_DESC(dev_hint, "Device node hints"); MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); MODULE_AUTHOR("Luc Saillard "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("pwcx"); -MODULE_VERSION( PWC_VERSION ); static int __init usb_pwc_init(void) { int i, sz; char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; - PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n"); - PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); - PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); - PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); + Info("Philips webcam module version " PWC_VERSION " loaded.\n"); + Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); + Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); + Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); if (fps) { if (fps < 4 || fps > 30) { - PWC_ERROR("Framerate out of bounds (4-30).\n"); + Err("Framerate out of bounds (4-30).\n"); return -EINVAL; } default_fps = fps; - PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); + Info("Default framerate set to %d.\n", default_fps); } - if (size) { + if (size[0]) { /* string; try matching with array */ for (sz = 0; sz < PSZ_MAX; sz++) { if (!strcmp(sizenames[sz], size)) { /* Found! */ @@ -1866,42 +2081,41 @@ static int __init usb_pwc_init(void) } } if (sz == PSZ_MAX) { - PWC_ERROR("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); + Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n"); return -EINVAL; } - PWC_DEBUG_MODULE("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); + Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y); } if (mbufs) { if (mbufs < 1 || mbufs > MAX_IMAGES) { - PWC_ERROR("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); + Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES); return -EINVAL; } - pwc_mbufs = mbufs; - PWC_DEBUG_MODULE("Number of image buffers set to %d.\n", pwc_mbufs); + default_mbufs = mbufs; + Info("Number of image buffers set to %d.\n", default_mbufs); } if (fbufs) { if (fbufs < 2 || fbufs > MAX_FRAMES) { - PWC_ERROR("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); + Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES); return -EINVAL; } default_fbufs = fbufs; - PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs); + Info("Number of frame buffers set to %d.\n", default_fbufs); } -#if CONFIG_PWC_DEBUG - if (pwc_trace >= 0) { - PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); + if (trace >= 0) { + Info("Trace options: 0x%04x\n", trace); + pwc_trace = trace; } -#endif if (compression >= 0) { if (compression > 3) { - PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); + Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); return -EINVAL; } pwc_preferred_compression = compression; - PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression); + Info("Preferred compression set to %d.\n", pwc_preferred_compression); } if (power_save) - PWC_DEBUG_MODULE("Enabling power save on open/close.\n"); + Info("Enabling power save on open/close.\n"); if (leds[0] >= 0) led_on = leds[0]; if (leds[1] >= 0) @@ -1932,14 +2146,14 @@ static int __init usb_pwc_init(void) dot++; /* Few sanity checks */ if (*dot != '\0' && dot > colon) { - PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n"); + Err("Malformed camera hint: the colon must be after the dot.\n"); return -EINVAL; } if (*colon == '\0') { /* No colon */ if (*dot != '\0') { - PWC_ERROR("Malformed camera hint: no colon + device node given.\n"); + Err("Malformed camera hint: no colon + device node given.\n"); return -EINVAL; } else { @@ -1964,27 +2178,28 @@ static int __init usb_pwc_init(void) device_hint[i].serial_number[k] = '\0'; } } - PWC_TRACE("device_hint[%d]:\n", i); - PWC_TRACE(" type : %d\n", device_hint[i].type); - PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number); - PWC_TRACE(" node : %d\n", device_hint[i].device_node); +#if PWC_DEBUG + Debug("device_hint[%d]:\n", i); + Debug(" type : %d\n", device_hint[i].type); + Debug(" serial# : %s\n", device_hint[i].serial_number); + Debug(" node : %d\n", device_hint[i].device_node); +#endif } else device_hint[i].type = 0; /* not filled */ } /* ..for MAX_DEV_HINTS */ - PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver); + Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver); return usb_register(&pwc_driver); } static void __exit usb_pwc_exit(void) { - PWC_DEBUG_MODULE("Deregistering driver.\n"); + Trace(TRACE_MODULE, "Deregistering driver.\n"); usb_deregister(&pwc_driver); - PWC_INFO("Philips webcam module removed.\n"); + Info("Philips webcam module removed.\n"); } module_init(usb_pwc_init); module_exit(usb_pwc_exit); -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/trunk/drivers/media/video/pwc/pwc-kiara.c b/trunk/drivers/media/video/pwc/pwc-kiara.c index fec39cc5a9f1..4c96037f7be5 100644 --- a/trunk/drivers/media/video/pwc/pwc-kiara.c +++ b/trunk/drivers/media/video/pwc/pwc-kiara.c @@ -1,5 +1,5 @@ /* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -316,576 +316,3 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = }, }; - -/* - * Rom table for kiara chips - * - * 32 roms tables (one for each resolution ?) - * 2 tables per roms (one for each passes) (Y, and U&V) - * 128 bytes per passes - */ - -const unsigned int KiaraRomTable [8][2][16][8] = -{ - { /* version 0 */ - { /* version 0, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009292,0x00009292,0x00009493,0x000124db}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x0000a493,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x000124db,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 0, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000001,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009292, - 0x00009492,0x00009493,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000126dc,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 1 */ - { /* version 1, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 1, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000049,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 2 */ - { /* version 2, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x0000a49b}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 2, passes 1 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x0000a49b,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 3 */ - { /* version 3, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 3, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 4 */ - { /* version 4, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 4, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 5 */ - { /* version 5, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 5, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x00009252,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 6 */ - { /* version 6, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 6, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 7 */ - { /* version 7, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 7, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - } -}; - diff --git a/trunk/drivers/media/video/pwc/pwc-kiara.h b/trunk/drivers/media/video/pwc/pwc-kiara.h index 0bdb22547d86..12929abbb1f0 100644 --- a/trunk/drivers/media/video/pwc/pwc-kiara.h +++ b/trunk/drivers/media/video/pwc/pwc-kiara.h @@ -1,5 +1,5 @@ /* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -27,7 +27,7 @@ #ifndef PWC_KIARA_H #define PWC_KIARA_H -#include +#include "pwc-ioctl.h" struct Kiara_table_entry { @@ -37,8 +37,8 @@ struct Kiara_table_entry unsigned char mode[12]; /* precomputed mode settings for cam */ }; -extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; -extern const unsigned int KiaraRomTable[8][2][16][8]; +const extern struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4]; +const extern unsigned int KiaraRomTable[8][2][16][8]; #endif diff --git a/trunk/drivers/media/video/pwc/pwc-misc.c b/trunk/drivers/media/video/pwc/pwc-misc.c index 589c687439da..58fe79747992 100644 --- a/trunk/drivers/media/video/pwc/pwc-misc.c +++ b/trunk/drivers/media/video/pwc/pwc-misc.c @@ -1,7 +1,7 @@ /* Linux driver for Philips webcam Various miscellaneous functions and tables. (C) 1999-2003 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -24,17 +24,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include "pwc.h" -const struct pwc_coord pwc_image_sizes[PSZ_MAX] = +struct pwc_coord pwc_image_sizes[PSZ_MAX] = { - { 128, 96, 0 }, /* sqcif */ - { 160, 120, 0 }, /* qsif */ - { 176, 144, 0 }, /* qcif */ - { 320, 240, 0 }, /* sif */ - { 352, 288, 0 }, /* cif */ - { 640, 480, 0 }, /* vga */ + { 128, 96, 0 }, + { 160, 120, 0 }, + { 176, 144, 0 }, + { 320, 240, 0 }, + { 352, 288, 0 }, + { 640, 480, 0 }, }; /* x,y -> PSZ_ */ @@ -51,7 +52,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) { if (width > pdev->abs_max.x || height > pdev->abs_max.y) { - PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); + Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); return -1; } } @@ -59,7 +60,7 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) { if (width > pdev->view_max.x || height > pdev->view_max.y) { - PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n"); + Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); return -1; } } @@ -80,8 +81,9 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height) /* initialize variables depending on type and decompressor*/ void pwc_construct(struct pwc_device *pdev) { - if (DEVICE_USE_CODEC1(pdev->type)) { - + switch(pdev->type) { + case 645: + case 646: pdev->view_min.x = 128; pdev->view_min.y = 96; pdev->view_max.x = 352; @@ -93,23 +95,10 @@ void pwc_construct(struct pwc_device *pdev) pdev->vendpoint = 4; pdev->frame_header_size = 0; pdev->frame_trailer_size = 0; - - } else if (DEVICE_USE_CODEC3(pdev->type)) { - - pdev->view_min.x = 160; - pdev->view_min.y = 120; - pdev->view_max.x = 640; - pdev->view_max.y = 480; - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; - pdev->abs_max.x = 640; - pdev->abs_max.y = 480; - pdev->vcinterface = 3; - pdev->vendpoint = 5; - pdev->frame_header_size = TOUCAM_HEADER_SIZE; - pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; - - } else /* if (DEVICE_USE_CODEC2(pdev->type)) */ { - + break; + case 675: + case 680: + case 690: pdev->view_min.x = 128; pdev->view_min.y = 96; /* Anthill bug #38: PWC always reports max size, even without PWCX */ @@ -122,12 +111,30 @@ void pwc_construct(struct pwc_device *pdev) pdev->vendpoint = 4; pdev->frame_header_size = 0; pdev->frame_trailer_size = 0; + break; + case 720: + case 730: + case 740: + case 750: + pdev->view_min.x = 160; + pdev->view_min.y = 120; + pdev->view_max.x = 640; + pdev->view_max.y = 480; + pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; + pdev->abs_max.x = 640; + pdev->abs_max.y = 480; + pdev->vcinterface = 3; + pdev->vendpoint = 5; + pdev->frame_header_size = TOUCAM_HEADER_SIZE; + pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; + break; } + Debug("type = %d\n",pdev->type); pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; /* length of image, in YUV format; always allocate enough memory. */ - pdev->len_per_image = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2); + pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; } diff --git a/trunk/drivers/media/video/pwc/pwc-timon.c b/trunk/drivers/media/video/pwc/pwc-timon.c index be65bdcd195b..175250d089cf 100644 --- a/trunk/drivers/media/video/pwc/pwc-timon.c +++ b/trunk/drivers/media/video/pwc/pwc-timon.c @@ -1,5 +1,5 @@ /* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -314,1133 +314,3 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = }, }; -/* - * 16 versions: - * 2 tables (one for Y, and one for U&V) - * 16 levels of details per tables - * 8 blocs - */ - -const unsigned int TimonRomTable [16][2][16][8] = -{ - { /* version 0 */ - { /* version 0, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000001,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000001, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 0, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000001,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000001, - 0x00000001,0x00000009,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000009,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000009,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 1 */ - { /* version 1, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 1, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000001,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000049,0x00000249,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 2 */ - { /* version 2, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 2, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000049,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 3 */ - { /* version 3, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 3, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00000049,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009292, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 4 */ - { /* version 4, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x0000a49b}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 4, passes 1 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x0000a49b,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 5 */ - { /* version 5, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 5, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x000124db,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009493,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 6 */ - { /* version 6, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 6, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 7 */ - { /* version 7, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x0002496e}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001c96e,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 7, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001b724,0x0001b925,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 8 */ - { /* version 8, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x00024b76,0x00024b77}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x00024b76,0x00025bbf}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 8, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0002496d,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 9 */ - { /* version 9, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 9, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 10 */ - { /* version 10, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 10, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x00009493,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009493,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 11 */ - { /* version 11, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 11, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x00009252,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 12 */ - { /* version 12, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 12, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 13 */ - { /* version 13, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 13, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 14 */ - { /* version 14, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0002496d,0x00024b76,0x00024b77}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 14, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000136e4,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 15 */ - { /* version 15, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0002496d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 15, passes 1 */ - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009292,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000124db,0x0001b724,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x0001b724,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001c924,0x0001b724,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001c924,0x0001b724,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002496d,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - } -}; diff --git a/trunk/drivers/media/video/pwc/pwc-timon.h b/trunk/drivers/media/video/pwc/pwc-timon.h index eef9e2cd4320..a86b3782a081 100644 --- a/trunk/drivers/media/video/pwc/pwc-timon.h +++ b/trunk/drivers/media/video/pwc/pwc-timon.h @@ -1,5 +1,5 @@ /* Linux driver for Philips webcam - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -42,7 +42,7 @@ #ifndef PWC_TIMON_H #define PWC_TIMON_H -#include +#include "pwc-ioctl.h" struct Timon_table_entry { @@ -52,8 +52,8 @@ struct Timon_table_entry unsigned char mode[13]; /* precomputed mode settings for cam */ }; -extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; -extern const unsigned int TimonRomTable [16][2][16][8]; +const extern struct Timon_table_entry Timon_table[PSZ_MAX][6][4]; +const extern unsigned int TimonRomTable [16][2][16][8]; #endif diff --git a/trunk/drivers/media/video/pwc/pwc-uncompress.c b/trunk/drivers/media/video/pwc/pwc-uncompress.c index 5d82028ef942..b37a89a163f9 100644 --- a/trunk/drivers/media/video/pwc/pwc-uncompress.c +++ b/trunk/drivers/media/video/pwc/pwc-uncompress.c @@ -1,7 +1,7 @@ /* Linux driver for Philips webcam Decompression frontend. (C) 1999-2003 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -22,8 +22,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - vim: set ts=8: */ #include @@ -31,8 +29,6 @@ #include "pwc.h" #include "pwc-uncompress.h" -#include "pwc-dec1.h" -#include "pwc-dec23.h" int pwc_decompress(struct pwc_device *pdev) { @@ -44,95 +40,107 @@ int pwc_decompress(struct pwc_device *pdev) if (pdev == NULL) return -EFAULT; +#if defined(__KERNEL__) && defined(PWC_MAGIC) + if (pdev->magic != PWC_MAGIC) { + Err("pwc_decompress(): magic failed.\n"); + return -EFAULT; + } +#endif fbuf = pdev->read_frame; if (fbuf == NULL) return -EFAULT; - image = pdev->image_data; - image += pdev->images[pdev->fill_image].offset; + image = pdev->image_ptr[pdev->fill_image]; + if (!image) + return -EFAULT; yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ /* Raw format; that's easy... */ if (pdev->vpalette == VIDEO_PALETTE_RAW) { - struct pwc_raw_frame *raw_frame = image; - raw_frame->type = cpu_to_le16(pdev->type); - raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength); - /* cmd_buf is always 4 bytes, but sometimes, only the - * first 3 bytes is filled (Nala case). We can - * determine this using the type of the webcam */ - memcpy(raw_frame->cmd, pdev->cmd_buf, 4); - memcpy(raw_frame+1, yuv, pdev->frame_size); + memcpy(image, yuv, pdev->frame_size); return 0; } if (pdev->vbandlength == 0) { - /* Uncompressed mode. - * We copy the data into the output buffer, using the viewport - * size (which may be larger than the image size). - * Unfortunately we have to do a bit of byte stuffing to get - * the desired output format/size. - * - * We do some byte shuffling here to go from the - * native format to YUV420P. + /* Uncompressed mode. We copy the data into the output buffer, + using the viewport size (which may be larger than the image + size). Unfortunately we have to do a bit of byte stuffing + to get the desired output format/size. */ - src = (u16 *)yuv; - n = pdev->view.x * pdev->view.y; - - /* offset in Y plane */ - stride = pdev->view.x * pdev->offset.y + pdev->offset.x; - dsty = (u16 *)(image + stride); - - /* offsets in U/V planes */ - stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; - dstu = (u16 *)(image + n + stride); - dstv = (u16 *)(image + n + n / 4 + stride); - - /* increment after each line */ - stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ - - for (line = 0; line < pdev->image.y; line++) { - for (col = 0; col < pdev->image.x; col += 4) { - *dsty++ = *src++; - *dsty++ = *src++; + /* + * We do some byte shuffling here to go from the + * native format to YUV420P. + */ + src = (u16 *)yuv; + n = pdev->view.x * pdev->view.y; + + /* offset in Y plane */ + stride = pdev->view.x * pdev->offset.y + pdev->offset.x; + dsty = (u16 *)(image + stride); + + /* offsets in U/V planes */ + stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; + dstu = (u16 *)(image + n + stride); + dstv = (u16 *)(image + n + n / 4 + stride); + + /* increment after each line */ + stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ + + for (line = 0; line < pdev->image.y; line++) { + for (col = 0; col < pdev->image.x; col += 4) { + *dsty++ = *src++; + *dsty++ = *src++; + if (line & 1) + *dstv++ = *src++; + else + *dstu++ = *src++; + } + dsty += stride; if (line & 1) - *dstv++ = *src++; + dstv += (stride >> 1); else - *dstu++ = *src++; + dstu += (stride >> 1); } - dsty += stride; - if (line & 1) - dstv += (stride >> 1); - else - dstu += (stride >> 1); - } - - return 0; - } - - /* - * Compressed; - * the decompressor routines will write the data in planar format - * immediately. - */ - if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) { - PWC_ERROR("Mode Bayer is not supported for now\n"); - /* flags |= PWCX_FLAG_BAYER; */ - return -ENXIO; /* No such device or address: missing decompressor */ } - - if (DEVICE_USE_CODEC1(pdev->type)) { - - /* TODO & FIXME */ - PWC_ERROR("This chipset is not supported for now\n"); - return -ENXIO; /* No such device or address: missing decompressor */ - - } else { - pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR); + else { + /* Compressed; the decompressor routines will write the data + in planar format immediately. + */ + int flags; + + flags = PWCX_FLAG_PLANAR; + if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) + { + printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); + flags |= PWCX_FLAG_BAYER; + return -ENXIO; /* No such device or address: missing decompressor */ + } + +#if 0 + switch (pdev->type) + { + case 675: + case 680: + case 690: + case 720: + case 730: + case 740: + case 750: + pwc_dec23_decompress(&pdev->image, &pdev->view, + &pdev->offset, yuv, image, flags, + pdev->decompress_data, pdev->vbandlength); + break; + case 645: + case 646: + /* TODO & FIXME */ + return -ENXIO; /* Missing decompressor */ + break; + } +#endif } return 0; } -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/trunk/drivers/media/video/pwc/pwc-uncompress.h b/trunk/drivers/media/video/pwc/pwc-uncompress.h index 041227f65246..f75e1b6cbe19 100644 --- a/trunk/drivers/media/video/pwc/pwc-uncompress.h +++ b/trunk/drivers/media/video/pwc/pwc-uncompress.h @@ -1,5 +1,5 @@ /* (C) 1999-2003 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -32,7 +32,7 @@ #include -#include +#include "pwc-ioctl.h" /* from pwc-dec.h */ #define PWCX_FLAG_PLANAR 0x0001 diff --git a/trunk/drivers/media/video/pwc/pwc-v4l.c b/trunk/drivers/media/video/pwc/pwc-v4l.c deleted file mode 100644 index b7eb3ce3b968..000000000000 --- a/trunk/drivers/media/video/pwc/pwc-v4l.c +++ /dev/null @@ -1,1202 +0,0 @@ -/* Linux driver for Philips webcam - USB and Video4Linux interface part. - (C) 1999-2004 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pwc.h" - -static struct v4l2_queryctrl pwc_controls[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 128, - .step = 1, - .default_value = 64, - }, - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 64, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = -100, - .maximum = 100, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0, - .maximum = 32, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Gain", - .minimum = 0, - .maximum = 256, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Gain", - .minimum = 0, - .maximum = 256, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto White Balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Shutter Speed (Exposure)", - .minimum = 0, - .maximum = 256, - .step = 1, - .default_value = 200, - }, - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Gain Enabled", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain Level", - .minimum = 0, - .maximum = 256, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_SAVE_USER, - .type = V4L2_CTRL_TYPE_BUTTON, - .name = "Save User Settings", - .minimum = 0, - .maximum = 0, - .step = 0, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_RESTORE_USER, - .type = V4L2_CTRL_TYPE_BUTTON, - .name = "Restore User Settings", - .minimum = 0, - .maximum = 0, - .step = 0, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_RESTORE_FACTORY, - .type = V4L2_CTRL_TYPE_BUTTON, - .name = "Restore Factory Settings", - .minimum = 0, - .maximum = 0, - .step = 0, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_COLOUR_MODE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Colour mode", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_AUTOCONTOUR, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto contour", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_CONTOUR, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contour", - .minimum = 0, - .maximum = 63, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_BACKLIGHT, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Backlight compensation", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_FLICKERLESS, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flickerless", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_PRIVATE_NOISE_REDUCTION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Noise reduction", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, -}; - - -static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) -{ - memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); - f->fmt.pix.width = pdev->view.x; - f->fmt.pix.height = pdev->view.y; - f->fmt.pix.field = V4L2_FIELD_NONE; - if (pdev->vpalette == VIDEO_PALETTE_YUV420P) { - f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; - f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; - f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - } else { - /* vbandlength contains 4 lines ... */ - f->fmt.pix.bytesperline = pdev->vbandlength/4; - f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame); - if (DEVICE_USE_CODEC1(pdev->type)) - f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1; - else - f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2; - } - PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " - "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", - f->fmt.pix.width, - f->fmt.pix.height, - f->fmt.pix.bytesperline, - f->fmt.pix.sizeimage, - (f->fmt.pix.pixelformat)&255, - (f->fmt.pix.pixelformat>>8)&255, - (f->fmt.pix.pixelformat>>16)&255, - (f->fmt.pix.pixelformat>>24)&255); -} - -/* ioctl(VIDIOC_TRY_FMT) */ -static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) -{ - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - return -EINVAL; - } - - switch (f->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_YUV420: - break; - case V4L2_PIX_FMT_PWC1: - if (DEVICE_USE_CODEC23(pdev->type)) { - PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n"); - return -EINVAL; - } - break; - case V4L2_PIX_FMT_PWC2: - if (DEVICE_USE_CODEC1(pdev->type)) { - PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n"); - return -EINVAL; - } - break; - default: - PWC_DEBUG_IOCTL("Unsupported pixel format\n"); - return -EINVAL; - - } - - if (f->fmt.pix.width > pdev->view_max.x) - f->fmt.pix.width = pdev->view_max.x; - else if (f->fmt.pix.width < pdev->view_min.x) - f->fmt.pix.width = pdev->view_min.x; - - if (f->fmt.pix.height > pdev->view_max.y) - f->fmt.pix.height = pdev->view_max.y; - else if (f->fmt.pix.height < pdev->view_min.y) - f->fmt.pix.height = pdev->view_min.y; - - return 0; -} - -/* ioctl(VIDIOC_SET_FMT) */ -static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) -{ - int ret, fps, snapshot, compression, pixelformat; - - ret = pwc_vidioc_try_fmt(pdev, f); - if (ret<0) - return ret; - - pixelformat = f->fmt.pix.pixelformat; - compression = pdev->vcompression; - snapshot = 0; - fps = pdev->vframes; - if (f->fmt.pix.priv) { - compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT; - snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT); - fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; - if (fps == 0) - fps = pdev->vframes; - } - - if (pixelformat == V4L2_PIX_FMT_YUV420) - pdev->vpalette = VIDEO_PALETTE_YUV420P; - else - pdev->vpalette = VIDEO_PALETTE_RAW; - - PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " - "compression=%d snapshot=%d format=%c%c%c%c\n", - f->fmt.pix.width, f->fmt.pix.height, fps, - compression, snapshot, - (pixelformat)&255, - (pixelformat>>8)&255, - (pixelformat>>16)&255, - (pixelformat>>24)&255); - - ret = pwc_try_video_mode(pdev, - f->fmt.pix.width, - f->fmt.pix.height, - fps, - compression, - snapshot); - - PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret); - - if (ret) - return ret; - - pwc_vidioc_fill_fmt(pdev, f); - - return 0; - -} - -int pwc_video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vdev = video_devdata(file); - struct pwc_device *pdev; - DECLARE_WAITQUEUE(wait, current); - - if (vdev == NULL) - return -EFAULT; - pdev = vdev->priv; - if (pdev == NULL) - return -EFAULT; - -#if CONFIG_PWC_DEBUG - if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) - v4l_printk_ioctl(cmd); -#endif - - - switch (cmd) { - /* Query cabapilities */ - case VIDIOCGCAP: - { - struct video_capability *caps = arg; - - strcpy(caps->name, vdev->name); - caps->type = VID_TYPE_CAPTURE; - caps->channels = 1; - caps->audios = 1; - caps->minwidth = pdev->view_min.x; - caps->minheight = pdev->view_min.y; - caps->maxwidth = pdev->view_max.x; - caps->maxheight = pdev->view_max.y; - break; - } - - /* Channel functions (simulate 1 channel) */ - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - - if (v->channel != 0) - return -EINVAL; - v->flags = 0; - v->tuners = 0; - v->type = VIDEO_TYPE_CAMERA; - strcpy(v->name, "Webcam"); - return 0; - } - - case VIDIOCSCHAN: - { - /* The spec says the argument is an integer, but - the bttv driver uses a video_channel arg, which - makes sense becasue it also has the norm flag. - */ - struct video_channel *v = arg; - if (v->channel != 0) - return -EINVAL; - return 0; - } - - - /* Picture functions; contrast etc. */ - case VIDIOCGPICT: - { - struct video_picture *p = arg; - int val; - - val = pwc_get_brightness(pdev); - if (val >= 0) - p->brightness = (val<<9); - else - p->brightness = 0xffff; - val = pwc_get_contrast(pdev); - if (val >= 0) - p->contrast = (val<<10); - else - p->contrast = 0xffff; - /* Gamma, Whiteness, what's the difference? :) */ - val = pwc_get_gamma(pdev); - if (val >= 0) - p->whiteness = (val<<11); - else - p->whiteness = 0xffff; - if (pwc_get_saturation(pdev, &val)<0) - p->colour = 0xffff; - else - p->colour = 32768 + val * 327; - p->depth = 24; - p->palette = pdev->vpalette; - p->hue = 0xFFFF; /* N/A */ - break; - } - - case VIDIOCSPICT: - { - struct video_picture *p = arg; - /* - * FIXME: Suppose we are mid read - ANSWER: No problem: the firmware of the camera - can handle brightness/contrast/etc - changes at _any_ time, and the palette - is used exactly once in the uncompress - routine. - */ - pwc_set_brightness(pdev, p->brightness); - pwc_set_contrast(pdev, p->contrast); - pwc_set_gamma(pdev, p->whiteness); - pwc_set_saturation(pdev, (p->colour-32768)/327); - if (p->palette && p->palette != pdev->vpalette) { - switch (p->palette) { - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_RAW: - pdev->vpalette = p->palette; - return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - break; - default: - return -EINVAL; - break; - } - } - break; - } - - /* Window/size parameters */ - case VIDIOCGWIN: - { - struct video_window *vw = arg; - - vw->x = 0; - vw->y = 0; - vw->width = pdev->view.x; - vw->height = pdev->view.y; - vw->chromakey = 0; - vw->flags = (pdev->vframes << PWC_FPS_SHIFT) | - (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0); - break; - } - - case VIDIOCSWIN: - { - struct video_window *vw = arg; - int fps, snapshot, ret; - - fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT; - snapshot = vw->flags & PWC_FPS_SNAPSHOT; - if (fps == 0) - fps = pdev->vframes; - if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot) - return 0; - ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot); - if (ret) - return ret; - break; - } - - /* We don't have overlay support (yet) */ - case VIDIOCGFBUF: - { - struct video_buffer *vb = arg; - - memset(vb,0,sizeof(*vb)); - break; - } - - /* mmap() functions */ - case VIDIOCGMBUF: - { - /* Tell the user program how much memory is needed for a mmap() */ - struct video_mbuf *vm = arg; - int i; - - memset(vm, 0, sizeof(*vm)); - vm->size = pwc_mbufs * pdev->len_per_image; - vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */ - for (i = 0; i < pwc_mbufs; i++) - vm->offsets[i] = i * pdev->len_per_image; - break; - } - - case VIDIOCMCAPTURE: - { - /* Start capture into a given image buffer (called 'frame' in video_mmap structure) */ - struct video_mmap *vm = arg; - - PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format); - if (vm->frame < 0 || vm->frame >= pwc_mbufs) - return -EINVAL; - - /* xawtv is nasty. It probes the available palettes - by setting a very small image size and trying - various palettes... The driver doesn't support - such small images, so I'm working around it. - */ - if (vm->format) - { - switch (vm->format) - { - case VIDEO_PALETTE_YUV420P: - case VIDEO_PALETTE_RAW: - break; - default: - return -EINVAL; - break; - } - } - - if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && - (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { - int ret; - - PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); - ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - if (ret) - return ret; - } /* ... size mismatch */ - - /* FIXME: should we lock here? */ - if (pdev->image_used[vm->frame]) - return -EBUSY; /* buffer wasn't available. Bummer */ - pdev->image_used[vm->frame] = 1; - - /* Okay, we're done here. In the SYNC call we wait until a - frame comes available, then expand image into the given - buffer. - In contrast to the CPiA cam the Philips cams deliver a - constant stream, almost like a grabber card. Also, - we have separate buffers for the rawdata and the image, - meaning we can nearly always expand into the requested buffer. - */ - PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n"); - break; - } - - case VIDIOCSYNC: - { - /* The doc says: "Whenever a buffer is used it should - call VIDIOCSYNC to free this frame up and continue." - - The only odd thing about this whole procedure is - that MCAPTURE flags the buffer as "in use", and - SYNC immediately unmarks it, while it isn't - after SYNC that you know that the buffer actually - got filled! So you better not start a CAPTURE in - the same frame immediately (use double buffering). - This is not a problem for this cam, since it has - extra intermediate buffers, but a hardware - grabber card will then overwrite the buffer - you're working on. - */ - int *mbuf = arg; - int ret; - - PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf); - - /* bounds check */ - if (*mbuf < 0 || *mbuf >= pwc_mbufs) - return -EINVAL; - /* check if this buffer was requested anyway */ - if (pdev->image_used[*mbuf] == 0) - return -EINVAL; - - /* Add ourselves to the frame wait-queue. - - FIXME: needs auditing for safety. - QUESTION: In what respect? I think that using the - frameq is safe now. - */ - add_wait_queue(&pdev->frameq, &wait); - while (pdev->full_frames == NULL) { - /* Check for unplugged/etc. here */ - if (pdev->error_status) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -pdev->error_status; - } - - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - - /* The frame is ready. Expand in the image buffer - requested by the user. I don't care if you - mmap() 5 buffers and request data in this order: - buffer 4 2 3 0 1 2 3 0 4 3 1 . . . - Grabber hardware may not be so forgiving. - */ - PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n"); - pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */ - /* Decompress, etc */ - ret = pwc_handle_frame(pdev); - pdev->image_used[*mbuf] = 0; - if (ret) - return -EFAULT; - break; - } - - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - - strcpy(v->name, "Microphone"); - v->audio = -1; /* unknown audio minor */ - v->flags = 0; - v->mode = VIDEO_SOUND_MONO; - v->volume = 0; - v->bass = 0; - v->treble = 0; - v->balance = 0x8000; - v->step = 1; - break; - } - - case VIDIOCSAUDIO: - { - /* Dummy: nothing can be set */ - break; - } - - case VIDIOCGUNIT: - { - struct video_unit *vu = arg; - - vu->video = pdev->vdev->minor & 0x3F; - vu->audio = -1; /* not known yet */ - vu->vbi = -1; - vu->radio = -1; - vu->teletext = -1; - break; - } - - /* V4L2 Layer */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\ - "try to use the v4l2 layer\n"); - strcpy(cap->driver,PWC_NAME); - strlcpy(cap->card, vdev->name, sizeof(cap->card)); - usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info)); - cap->version = PWC_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - return 0; - } - - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - - if ( i->index ) /* Only one INPUT is supported */ - return -EINVAL; - - memset(i, 0, sizeof(struct v4l2_input)); - strcpy(i->name, "usb"); - return 0; - } - - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = 0; /* Only one INPUT is supported */ - return 0; - } - case VIDIOC_S_INPUT: - { - int *i = arg; - - if ( *i ) { /* Only one INPUT is supported */ - PWC_DEBUG_IOCTL("Only one input source is"\ - " supported with this webcam.\n"); - return -EINVAL; - } - return 0; - } - - /* TODO: */ - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *c = arg; - int i; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id); - for (i=0; iid) { - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); - memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl)); - return 0; - } - } - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n"); - - return -EINVAL; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *c = arg; - int ret; - - switch (c->id) - { - case V4L2_CID_BRIGHTNESS: - c->value = pwc_get_brightness(pdev); - if (c->value<0) - return -EINVAL; - return 0; - case V4L2_CID_CONTRAST: - c->value = pwc_get_contrast(pdev); - if (c->value<0) - return -EINVAL; - return 0; - case V4L2_CID_SATURATION: - ret = pwc_get_saturation(pdev, &c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_GAMMA: - c->value = pwc_get_gamma(pdev); - if (c->value<0) - return -EINVAL; - return 0; - case V4L2_CID_RED_BALANCE: - ret = pwc_get_red_gain(pdev, &c->value); - if (ret<0) - return -EINVAL; - c->value >>= 8; - return 0; - case V4L2_CID_BLUE_BALANCE: - ret = pwc_get_blue_gain(pdev, &c->value); - if (ret<0) - return -EINVAL; - c->value >>= 8; - return 0; - case V4L2_CID_AUTO_WHITE_BALANCE: - ret = pwc_get_awb(pdev); - if (ret<0) - return -EINVAL; - c->value = (ret == PWC_WB_MANUAL)?0:1; - return 0; - case V4L2_CID_GAIN: - ret = pwc_get_agc(pdev, &c->value); - if (ret<0) - return -EINVAL; - c->value >>= 8; - return 0; - case V4L2_CID_AUTOGAIN: - ret = pwc_get_agc(pdev, &c->value); - if (ret<0) - return -EINVAL; - c->value = (c->value < 0)?1:0; - return 0; - case V4L2_CID_EXPOSURE: - ret = pwc_get_shutter_speed(pdev, &c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_COLOUR_MODE: - ret = pwc_get_colour_mode(pdev, &c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_AUTOCONTOUR: - ret = pwc_get_contour(pdev, &c->value); - if (ret < 0) - return -EINVAL; - c->value=(c->value == -1?1:0); - return 0; - case V4L2_CID_PRIVATE_CONTOUR: - ret = pwc_get_contour(pdev, &c->value); - if (ret < 0) - return -EINVAL; - c->value >>= 10; - return 0; - case V4L2_CID_PRIVATE_BACKLIGHT: - ret = pwc_get_backlight(pdev, &c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_FLICKERLESS: - ret = pwc_get_flicker(pdev, &c->value); - if (ret < 0) - return -EINVAL; - c->value=(c->value?1:0); - return 0; - case V4L2_CID_PRIVATE_NOISE_REDUCTION: - ret = pwc_get_dynamic_noise(pdev, &c->value); - if (ret < 0) - return -EINVAL; - return 0; - - case V4L2_CID_PRIVATE_SAVE_USER: - case V4L2_CID_PRIVATE_RESTORE_USER: - case V4L2_CID_PRIVATE_RESTORE_FACTORY: - return -EINVAL; - } - return -EINVAL; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *c = arg; - int ret; - - switch (c->id) - { - case V4L2_CID_BRIGHTNESS: - c->value <<= 9; - ret = pwc_set_brightness(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_CONTRAST: - c->value <<= 10; - ret = pwc_set_contrast(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_SATURATION: - ret = pwc_set_saturation(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_GAMMA: - c->value <<= 11; - ret = pwc_set_gamma(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_RED_BALANCE: - c->value <<= 8; - ret = pwc_set_red_gain(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_BLUE_BALANCE: - c->value <<= 8; - ret = pwc_set_blue_gain(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_AUTO_WHITE_BALANCE: - c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO; - ret = pwc_set_awb(pdev, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_EXPOSURE: - c->value <<= 8; - ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_AUTOGAIN: - /* autogain off means nothing without a gain */ - if (c->value == 0) - return 0; - ret = pwc_set_agc(pdev, c->value, 0); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_GAIN: - c->value <<= 8; - ret = pwc_set_agc(pdev, 0, c->value); - if (ret<0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_SAVE_USER: - if (pwc_save_user(pdev)) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_RESTORE_USER: - if (pwc_restore_user(pdev)) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_RESTORE_FACTORY: - if (pwc_restore_factory(pdev)) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_COLOUR_MODE: - ret = pwc_set_colour_mode(pdev, c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_AUTOCONTOUR: - c->value=(c->value == 1)?-1:0; - ret = pwc_set_contour(pdev, c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_CONTOUR: - c->value <<= 10; - ret = pwc_set_contour(pdev, c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_BACKLIGHT: - ret = pwc_set_backlight(pdev, c->value); - if (ret < 0) - return -EINVAL; - return 0; - case V4L2_CID_PRIVATE_FLICKERLESS: - ret = pwc_set_flicker(pdev, c->value); - if (ret < 0) - return -EINVAL; - case V4L2_CID_PRIVATE_NOISE_REDUCTION: - ret = pwc_set_dynamic_noise(pdev, c->value); - if (ret < 0) - return -EINVAL; - return 0; - - } - return -EINVAL; - } - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - int index; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* We only support two format: the raw format, and YUV */ - index = f->index; - memset(f,0,sizeof(struct v4l2_fmtdesc)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->index = index; - switch(index) - { - case 0: - /* RAW format */ - f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description)); - break; - case 1: - f->pixelformat = V4L2_PIX_FMT_YUV420; - strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description)); - break; - default: - return -EINVAL; - } - return 0; - } - - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - pwc_vidioc_fill_fmt(pdev, f); - - return 0; - } - - case VIDIOC_TRY_FMT: - return pwc_vidioc_try_fmt(pdev, arg); - - case VIDIOC_S_FMT: - return pwc_vidioc_set_fmt(pdev, arg); - - case VIDIOC_G_STD: - { - v4l2_std_id *std = arg; - *std = V4L2_STD_UNKNOWN; - return 0; - } - - case VIDIOC_S_STD: - { - v4l2_std_id *std = arg; - if (*std != V4L2_STD_UNKNOWN) - return -EINVAL; - return 0; - } - - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *std = arg; - if (std->index != 0) - return -EINVAL; - std->id = V4L2_STD_UNKNOWN; - strncpy(std->name, "webcam", sizeof(std->name)); - return 0; - } - - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *rb = arg; - int nbuffers; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count); - if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (rb->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - nbuffers = rb->count; - if (nbuffers < 2) - nbuffers = 2; - else if (nbuffers > pwc_mbufs) - nbuffers = pwc_mbufs; - /* Force to use our # of buffers */ - rb->count = pwc_mbufs; - return 0; - } - - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - int index; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index); - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); - return -EINVAL; - } - if (buf->memory != V4L2_MEMORY_MMAP) { - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); - return -EINVAL; - } - index = buf->index; - if (index < 0 || index >= pwc_mbufs) { - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index); - return -EINVAL; - } - - memset(buf, 0, sizeof(struct v4l2_buffer)); - buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf->index = index; - buf->m.offset = index * pdev->len_per_image; - if (pdev->vpalette == VIDEO_PALETTE_RAW) - buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); - else - buf->bytesused = pdev->view.size; - buf->field = V4L2_FIELD_NONE; - buf->memory = V4L2_MEMORY_MMAP; - //buf->flags = V4L2_BUF_FLAG_MAPPED; - buf->length = pdev->len_per_image; - - PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index); - PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset); - PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused); - - return 0; - } - - case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index); - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (buf->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - if (buf->index < 0 || buf->index >= pwc_mbufs) - return -EINVAL; - - buf->flags |= V4L2_BUF_FLAG_QUEUED; - buf->flags &= ~V4L2_BUF_FLAG_DONE; - - return 0; - } - - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - int ret; - - PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); - - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* Add ourselves to the frame wait-queue. - - FIXME: needs auditing for safety. - QUESTION: In what respect? I think that using the - frameq is safe now. - */ - add_wait_queue(&pdev->frameq, &wait); - while (pdev->full_frames == NULL) { - if (pdev->error_status) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -pdev->error_status; - } - - if (signal_pending(current)) { - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - return -ERESTARTSYS; - } - schedule(); - set_current_state(TASK_INTERRUPTIBLE); - } - remove_wait_queue(&pdev->frameq, &wait); - set_current_state(TASK_RUNNING); - - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n"); - /* Decompress data in pdev->images[pdev->fill_image] */ - ret = pwc_handle_frame(pdev); - if (ret) - return -EFAULT; - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); - - buf->index = pdev->fill_image; - if (pdev->vpalette == VIDEO_PALETTE_RAW) - buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); - else - buf->bytesused = pdev->view.size; - buf->flags = V4L2_BUF_FLAG_MAPPED; - buf->field = V4L2_FIELD_NONE; - do_gettimeofday(&buf->timestamp); - buf->sequence = 0; - buf->memory = V4L2_MEMORY_MMAP; - buf->m.offset = pdev->fill_image * pdev->len_per_image; - buf->length = buf->bytesused; - pwc_next_image(pdev); - - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index); - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length); - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset); - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused); - PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n"); - return 0; - - } - - case VIDIOC_STREAMON: - { - /* WARNING: pwc_try_video_mode() called pwc_isoc_init */ - pwc_isoc_init(pdev); - return 0; - } - - case VIDIOC_STREAMOFF: - { - pwc_isoc_cleanup(pdev); - return 0; - } - - default: - return pwc_ioctl(pdev, cmd, arg); - } /* ..switch */ - return 0; -} - -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/trunk/drivers/media/video/pwc/pwc.h b/trunk/drivers/media/video/pwc/pwc.h index 629f79e44fb6..1b0ee0ced0ed 100644 --- a/trunk/drivers/media/video/pwc/pwc.h +++ b/trunk/drivers/media/video/pwc/pwc.h @@ -1,5 +1,5 @@ /* (C) 1999-2003 Nemosoft Unv. - (C) 2004-2006 Luc Saillard (luc@saillard.org) + (C) 2004 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -29,87 +29,51 @@ #include #include #include +#include #include #include -#include #include #include -#include -#include #include "pwc-uncompress.h" -#include +#include "pwc-ioctl.h" -/* Turn some debugging options on/off */ -#ifndef CONFIG_PWC_DEBUG -#define CONFIG_PWC_DEBUG 1 -#endif - -/* Version block */ -#define PWC_MAJOR 10 -#define PWC_MINOR 0 -#define PWC_EXTRAMINOR 12 -#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR) -#define PWC_VERSION "10.0.12" -#define PWC_NAME "pwc" -#define PFX PWC_NAME ": " +/* Defines and structures for the Philips webcam */ +/* Used for checking memory corruption/pointer validation */ +#define PWC_MAGIC 0x89DC10ABUL +#undef PWC_MAGIC +/* Turn some debugging options on/off */ +#define PWC_DEBUG 0 /* Trace certain actions in the driver */ -#define PWC_DEBUG_LEVEL_MODULE (1<<0) -#define PWC_DEBUG_LEVEL_PROBE (1<<1) -#define PWC_DEBUG_LEVEL_OPEN (1<<2) -#define PWC_DEBUG_LEVEL_READ (1<<3) -#define PWC_DEBUG_LEVEL_MEMORY (1<<4) -#define PWC_DEBUG_LEVEL_FLOW (1<<5) -#define PWC_DEBUG_LEVEL_SIZE (1<<6) -#define PWC_DEBUG_LEVEL_IOCTL (1<<7) -#define PWC_DEBUG_LEVEL_TRACE (1<<8) - -#define PWC_DEBUG_MODULE(fmt, args...) PWC_DEBUG(MODULE, fmt, ##args) -#define PWC_DEBUG_PROBE(fmt, args...) PWC_DEBUG(PROBE, fmt, ##args) -#define PWC_DEBUG_OPEN(fmt, args...) PWC_DEBUG(OPEN, fmt, ##args) -#define PWC_DEBUG_READ(fmt, args...) PWC_DEBUG(READ, fmt, ##args) -#define PWC_DEBUG_MEMORY(fmt, args...) PWC_DEBUG(MEMORY, fmt, ##args) -#define PWC_DEBUG_FLOW(fmt, args...) PWC_DEBUG(FLOW, fmt, ##args) -#define PWC_DEBUG_SIZE(fmt, args...) PWC_DEBUG(SIZE, fmt, ##args) -#define PWC_DEBUG_IOCTL(fmt, args...) PWC_DEBUG(IOCTL, fmt, ##args) -#define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) - - -#if CONFIG_PWC_DEBUG - -#define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE) - -#define PWC_DEBUG(level, fmt, args...) do {\ - if ((PWC_DEBUG_LEVEL_ ##level) & pwc_trace) \ - printk(KERN_DEBUG PFX fmt, ##args); \ - } while(0) - -#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) -#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) -#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) -#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) - -#else /* if ! CONFIG_PWC_DEBUG */ - -#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args) -#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args) -#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args) -#define PWC_TRACE(fmt, args...) do { } while(0) -#define PWC_DEBUG(level, fmt, args...) do { } while(0) - -#define pwc_trace 0 +#define TRACE_MODULE 0x0001 +#define TRACE_PROBE 0x0002 +#define TRACE_OPEN 0x0004 +#define TRACE_READ 0x0008 +#define TRACE_MEMORY 0x0010 +#define TRACE_FLOW 0x0020 +#define TRACE_SIZE 0x0040 +#define TRACE_PWCX 0x0080 +#define TRACE_SEQUENCE 0x1000 + +#define Trace(R, A...) if (pwc_trace & R) printk(KERN_DEBUG PWC_NAME " " A) +#define Debug(A...) printk(KERN_DEBUG PWC_NAME " " A) +#define Info(A...) printk(KERN_INFO PWC_NAME " " A) +#define Err(A...) printk(KERN_ERR PWC_NAME " " A) -#endif /* Defines for ToUCam cameras */ #define TOUCAM_HEADER_SIZE 8 #define TOUCAM_TRAILER_SIZE 4 #define FEATURE_MOTOR_PANTILT 0x0001 -#define FEATURE_CODEC1 0x0002 -#define FEATURE_CODEC2 0x0004 + +/* Version block */ +#define PWC_MAJOR 9 +#define PWC_MINOR 0 +#define PWC_VERSION "9.0.2-unofficial" +#define PWC_NAME "pwc" /* Turn certain features on/off */ #define PWC_INT_PIPE 0 @@ -131,18 +95,6 @@ /* Absolute maximum number of buffers available for mmap() */ #define MAX_IMAGES 10 -/* Some macros to quickly find the type of a webcam */ -#define DEVICE_USE_CODEC1(x) ((x)<675) -#define DEVICE_USE_CODEC2(x) ((x)>=675 && (x)<700) -#define DEVICE_USE_CODEC3(x) ((x)>=700) -#define DEVICE_USE_CODEC23(x) ((x)>=675) - - -#ifndef V4L2_PIX_FMT_PWC1 -#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') -#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') -#endif - /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ struct pwc_iso_buf { @@ -158,19 +110,17 @@ struct pwc_frame_buf void *data; volatile int filled; /* number of bytes filled */ struct pwc_frame_buf *next; /* list */ -}; - -/* additionnal informations used when dealing image between kernel and userland */ -struct pwc_imgbuf -{ - unsigned long offset; /* offset of this buffer in the big array of image_data */ - int vma_use_count; /* count the number of time this memory is mapped */ +#if PWC_DEBUG + int sequence; /* Sequence number */ +#endif }; struct pwc_device { struct video_device *vdev; - +#ifdef PWC_MAGIC + int magic; +#endif /* Pointer to our usb_device */ struct usb_device *udev; @@ -227,8 +177,12 @@ struct pwc_device int frame_size; int frame_total_size; /* including header & trailer */ int drop_frames; +#if PWC_DEBUG + int sequence; /* Debugging aid */ +#endif /* 3: decompression */ + struct pwc_decompressor *decompressor; /* function block with decompression routines */ void *decompress_data; /* private data for decompression engine */ /* 4: image */ @@ -244,7 +198,7 @@ struct pwc_device struct pwc_coord offset; /* offset within the viewport */ void *image_data; /* total buffer, which is subdivided into ... */ - struct pwc_imgbuf images[MAX_IMAGES];/* ...several images... */ + void *image_ptr[MAX_IMAGES]; /* ...several images... */ int fill_image; /* ...which are rotated. */ int len_per_image; /* length per image */ int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ @@ -257,7 +211,6 @@ struct pwc_device struct pwc_mpt_range angle_range; int pan_angle; /* in degrees * 100 */ int tilt_angle; /* absolute angle; 0,0 is home position */ - int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */ /*** Misc. data ***/ wait_queue_head_t frameq; /* When waiting for a frame to finish... */ @@ -266,26 +219,20 @@ struct pwc_device #endif }; + #ifdef __cplusplus extern "C" { #endif -/* Global variables */ -#if CONFIG_PWC_DEBUG +/* Global variable */ extern int pwc_trace; -#endif -extern int pwc_mbufs; /** functions in pwc-if.c */ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); -int pwc_handle_frame(struct pwc_device *pdev); -void pwc_next_image(struct pwc_device *pdev); -int pwc_isoc_init(struct pwc_device *pdev); -void pwc_isoc_cleanup(struct pwc_device *pdev); /** Functions in pwc-misc.c */ /* sizes in pixels */ -extern const struct pwc_coord pwc_image_sizes[PSZ_MAX]; +extern struct pwc_coord pwc_image_sizes[PSZ_MAX]; int pwc_decode_size(struct pwc_device *pdev, int width, int height); void pwc_construct(struct pwc_device *pdev); @@ -293,9 +240,6 @@ void pwc_construct(struct pwc_device *pdev); /** Functions in pwc-ctrl.c */ /* Request a certain video mode. Returns < 0 if not possible */ extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot); -/* Calculate the number of bytes per image (not frame) */ -extern int pwc_mpt_reset(struct pwc_device *pdev, int flags); -extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); /* Various controls; should be obvious. Value 0..65535, or < 0 on error */ extern int pwc_get_brightness(struct pwc_device *pdev); @@ -304,36 +248,10 @@ extern int pwc_get_contrast(struct pwc_device *pdev); extern int pwc_set_contrast(struct pwc_device *pdev, int value); extern int pwc_get_gamma(struct pwc_device *pdev); extern int pwc_set_gamma(struct pwc_device *pdev, int value); -extern int pwc_get_saturation(struct pwc_device *pdev, int *value); +extern int pwc_get_saturation(struct pwc_device *pdev); extern int pwc_set_saturation(struct pwc_device *pdev, int value); extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); -extern int pwc_restore_user(struct pwc_device *pdev); -extern int pwc_save_user(struct pwc_device *pdev); -extern int pwc_restore_factory(struct pwc_device *pdev); - -/* exported for use by v4l2 controls */ -extern int pwc_get_red_gain(struct pwc_device *pdev, int *value); -extern int pwc_set_red_gain(struct pwc_device *pdev, int value); -extern int pwc_get_blue_gain(struct pwc_device *pdev, int *value); -extern int pwc_set_blue_gain(struct pwc_device *pdev, int value); -extern int pwc_get_awb(struct pwc_device *pdev); -extern int pwc_set_awb(struct pwc_device *pdev, int mode); -extern int pwc_set_agc(struct pwc_device *pdev, int mode, int value); -extern int pwc_get_agc(struct pwc_device *pdev, int *value); -extern int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value); -extern int pwc_get_shutter_speed(struct pwc_device *pdev, int *value); - -extern int pwc_set_colour_mode(struct pwc_device *pdev, int colour); -extern int pwc_get_colour_mode(struct pwc_device *pdev, int *colour); -extern int pwc_set_contour(struct pwc_device *pdev, int contour); -extern int pwc_get_contour(struct pwc_device *pdev, int *contour); -extern int pwc_set_backlight(struct pwc_device *pdev, int backlight); -extern int pwc_get_backlight(struct pwc_device *pdev, int *backlight); -extern int pwc_set_flicker(struct pwc_device *pdev, int flicker); -extern int pwc_get_flicker(struct pwc_device *pdev, int *flicker); -extern int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise); -extern int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise); /* Power down or up the camera; not supported by all models */ extern int pwc_camera_power(struct pwc_device *pdev, int power); @@ -341,9 +259,6 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power); /* Private ioctl()s; see pwc-ioctl.h */ extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); -/** Functions in pwc-v4l.c */ -extern int pwc_video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); /** pwc-uncompress.c */ /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ @@ -355,4 +270,3 @@ extern int pwc_decompress(struct pwc_device *pdev); #endif -/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ diff --git a/trunk/drivers/media/video/saa5246a.c b/trunk/drivers/media/video/saa5246a.c index 59a187272c83..dd830e0e5e96 100644 --- a/trunk/drivers/media/video/saa5246a.c +++ b/trunk/drivers/media/video/saa5246a.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include "saa5246a.h" diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 19a8d65699f8..531e9461cb66 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -56,7 +56,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/media/video/saa7110.c b/trunk/drivers/media/video/saa7110.c index 676b9970eb2e..41d951db6ec0 100644 --- a/trunk/drivers/media/video/saa7110.c +++ b/trunk/drivers/media/video/saa7110.c @@ -43,7 +43,6 @@ MODULE_LICENSE("GPL"); #define I2C_NAME(s) (s)->name #include -#include #include static int debug = 0; diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c index b59c11717273..dceebc0b1250 100644 --- a/trunk/drivers/media/video/saa7115.c +++ b/trunk/drivers/media/video/saa7115.c @@ -72,10 +72,6 @@ struct saa7115_state { int sat; enum v4l2_chip_ident ident; u32 audclk_freq; - u32 crystal_freq; - u8 ucgc; - u8 cgcdiv; - u8 apll; }; /* ----------------------------------------------------------------------- */ @@ -379,6 +375,10 @@ static const unsigned char saa7113_init_auto_input[] = { }; static const unsigned char saa7115_init_misc[] = { + 0x38, 0x03, /* audio stuff */ + 0x39, 0x10, + 0x3a, 0x08, + 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ 0x82, 0x00, 0x83, 0x01, /* I port settings */ @@ -584,7 +584,6 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) u32 acni; u32 hz; u64 f; - u8 acc = 0; /* reg 0x3a, audio clock control */ v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); @@ -592,34 +591,18 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) if (freq < 32000 || freq > 48000) return -EINVAL; - /* The saa7113 has no audio clock */ - if (state->ident == V4L2_IDENT_SAA7113) - return 0; - /* hz is the refresh rate times 100 */ hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ acpf = (25600 * freq) / hz; /* acni = (256 * freq * 2^23) / crystal_frequency = (freq * 2^(8+23)) / crystal_frequency = - (freq << 31) / crystal_frequency */ + (freq << 31) / 32.11 MHz */ f = freq; f = f << 31; - do_div(f, state->crystal_freq); + do_div(f, 32110000); acni = f; - if (state->ucgc) { - acpf = acpf * state->cgcdiv / 16; - acni = acni * state->cgcdiv / 16; - acc = 0x80; - if (state->cgcdiv == 3) - acc |= 0x40; - } - if (state->apll) - acc |= 0x08; - saa7115_write(client, 0x38, 0x03); - saa7115_write(client, 0x39, 0x10); - saa7115_write(client, 0x3a, acc); saa7115_write(client, 0x30, acpf & 0xff); saa7115_write(client, 0x31, (acpf >> 8) & 0xff); saa7115_write(client, 0x32, (acpf >> 16) & 0x03); @@ -1090,6 +1073,48 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, /* ============ SAA7115 AUDIO settings (end) ============= */ +static struct v4l2_queryctrl saa7115_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + }, +}; + +/* ----------------------------------------------------------------------- */ + static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct saa7115_state *state = i2c_get_clientdata(client); @@ -1133,16 +1158,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; + int i; - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++) + if (qc->id && qc->id == saa7115_qctrl[i].id) { + memcpy(qc, &saa7115_qctrl[i], sizeof(*qc)); + return 0; + } + return -EINVAL; } case VIDIOC_G_STD: @@ -1198,6 +1221,34 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar break; } + case VIDIOC_G_INPUT: + *(int *)arg = state->input; + break; + + case VIDIOC_S_INPUT: + v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg); + /* inputs from 0-9 are available */ + if (*iarg < 0 || *iarg > 9) { + return -EINVAL; + } + + if (state->input == *iarg) + break; + v4l_dbg(1, debug, client, "now setting %s input\n", + *iarg >= 6 ? "S-Video" : "Composite"); + state->input = *iarg; + + /* select mode */ + saa7115_write(client, 0x02, + (saa7115_read(client, 0x02) & 0xf0) | + state->input); + + /* bypass chrominance trap for modes 6..9 */ + saa7115_write(client, 0x09, + (saa7115_read(client, 0x09) & 0x7f) | + (state->input < 6 ? 0x0 : 0x80)); + break; + case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: v4l_dbg(1, debug, client, "%s output\n", @@ -1209,21 +1260,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar } break; - case VIDIOC_INT_S_CRYSTAL_FREQ: - { - struct v4l2_crystal_freq *freq = arg; - - if (freq->freq != SAA7115_FREQ_32_11_MHZ && - freq->freq != SAA7115_FREQ_24_576_MHZ) - return -EINVAL; - state->crystal_freq = freq->freq; - state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; - state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; - state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; - saa7115_set_audio_clock_freq(client, state->audclk_freq); - break; - } - case VIDIOC_INT_DECODE_VBI_LINE: saa7115_decode_vbi_line(client, arg); break; @@ -1365,13 +1401,10 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) v4l_dbg(1, debug, client, "writing init values\n"); /* init to 60hz/48khz */ - if (state->ident == V4L2_IDENT_SAA7113) { - state->crystal_freq = SAA7115_FREQ_24_576_MHZ; + if (state->ident == V4L2_IDENT_SAA7113) saa7115_writeregs(client, saa7113_init_auto_input); - } else { - state->crystal_freq = SAA7115_FREQ_32_11_MHZ; + else saa7115_writeregs(client, saa7115_init_auto_input); - } saa7115_writeregs(client, saa7115_init_misc); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c index ad401bdefeaf..c271e2e14105 100644 --- a/trunk/drivers/media/video/saa7127.c +++ b/trunk/drivers/media/video/saa7127.c @@ -270,7 +270,7 @@ static const char * const wss_strs[] = { "letterbox 16:9 top", "invalid", "invalid", - "16:9 full format anamorphic", + "16:9 full format anamorphic" "4:3 full format", "invalid", "invalid", diff --git a/trunk/drivers/media/video/saa7134/saa6752hs.c b/trunk/drivers/media/video/saa7134/saa6752hs.c index afc8f352b8e7..0e0ba50946e8 100644 --- a/trunk/drivers/media/video/saa7134/saa6752hs.c +++ b/trunk/drivers/media/video/saa7134/saa6752hs.c @@ -39,23 +39,6 @@ enum saa6752hs_videoformat { SAA6752HS_VF_UNKNOWN, }; -struct saa6752hs_mpeg_params { - /* transport streams */ - __u16 ts_pid_pmt; - __u16 ts_pid_audio; - __u16 ts_pid_video; - __u16 ts_pid_pcr; - - /* audio */ - enum v4l2_mpeg_audio_l2_bitrate au_l2_bitrate; - - /* video */ - enum v4l2_mpeg_video_aspect vi_aspect; - enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; - __u32 vi_bitrate; - __u32 vi_bitrate_peak; -}; - static const struct v4l2_format v4l2_format_table[] = { [SAA6752HS_VF_D1] = @@ -72,19 +55,18 @@ static const struct v4l2_format v4l2_format_table[] = struct saa6752hs_state { struct i2c_client client; - struct v4l2_mpeg_compression old_params; - struct saa6752hs_mpeg_params params; + struct v4l2_mpeg_compression params; enum saa6752hs_videoformat video_format; v4l2_std_id standard; }; enum saa6752hs_command { SAA6752HS_COMMAND_RESET = 0, - SAA6752HS_COMMAND_STOP = 1, - SAA6752HS_COMMAND_START = 2, - SAA6752HS_COMMAND_PAUSE = 3, - SAA6752HS_COMMAND_RECONFIGURE = 4, - SAA6752HS_COMMAND_SLEEP = 5, + SAA6752HS_COMMAND_STOP = 1, + SAA6752HS_COMMAND_START = 2, + SAA6752HS_COMMAND_PAUSE = 3, + SAA6752HS_COMMAND_RECONFIGURE = 4, + SAA6752HS_COMMAND_SLEEP = 5, SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6, SAA6752HS_COMMAND_MAX @@ -147,22 +129,7 @@ static u8 PMT[] = { 0x00, 0x00, 0x00, 0x00 /* CRC32 */ }; -static struct saa6752hs_mpeg_params param_defaults = -{ - .ts_pid_pmt = 16, - .ts_pid_video = 260, - .ts_pid_audio = 256, - .ts_pid_pcr = 259, - - .vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, - .vi_bitrate = 4000, - .vi_bitrate_peak = 6000, - .vi_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - - .au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K, -}; - -static struct v4l2_mpeg_compression old_param_defaults = +static struct v4l2_mpeg_compression param_defaults = { .st_type = V4L2_MPEG_TS_2, .st_bitrate = { @@ -261,57 +228,45 @@ static int saa6752hs_chip_command(struct i2c_client* client, static int saa6752hs_set_bitrate(struct i2c_client* client, - struct saa6752hs_mpeg_params* params) + struct v4l2_mpeg_compression* params) { u8 buf[3]; - int tot_bitrate; /* set the bitrate mode */ buf[0] = 0x71; - buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; + buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; i2c_master_send(client, buf, 2); /* set the video bitrate */ - if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { + if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { /* set the target bitrate */ buf[0] = 0x80; - buf[1] = params->vi_bitrate >> 8; - buf[2] = params->vi_bitrate & 0xff; + buf[1] = params->vi_bitrate.target >> 8; + buf[2] = params->vi_bitrate.target & 0xff; i2c_master_send(client, buf, 3); /* set the max bitrate */ buf[0] = 0x81; - buf[1] = params->vi_bitrate_peak >> 8; - buf[2] = params->vi_bitrate_peak & 0xff; + buf[1] = params->vi_bitrate.max >> 8; + buf[2] = params->vi_bitrate.max & 0xff; i2c_master_send(client, buf, 3); - tot_bitrate = params->vi_bitrate_peak; } else { /* set the target bitrate (no max bitrate for CBR) */ buf[0] = 0x81; - buf[1] = params->vi_bitrate >> 8; - buf[2] = params->vi_bitrate & 0xff; + buf[1] = params->vi_bitrate.target >> 8; + buf[2] = params->vi_bitrate.target & 0xff; i2c_master_send(client, buf, 3); - tot_bitrate = params->vi_bitrate; } /* set the audio bitrate */ buf[0] = 0x94; - buf[1] = (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 0 : 1; + buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; i2c_master_send(client, buf, 2); - tot_bitrate += (V4L2_MPEG_AUDIO_L2_BITRATE_256K == params->au_l2_bitrate) ? 256 : 384; - - /* Note: the total max bitrate is determined by adding the video and audio - bitrates together and also adding an extra 768kbit/s to stay on the - safe side. If more control should be required, then an extra MPEG control - should be added. */ - tot_bitrate += 768; - if (tot_bitrate > MPEG_TOTAL_TARGET_BITRATE_MAX) - tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; /* set the total bitrate */ buf[0] = 0xb1; - buf[1] = tot_bitrate >> 8; - buf[2] = tot_bitrate & 0xff; + buf[1] = params->st_bitrate.target >> 8; + buf[2] = params->st_bitrate.target & 0xff; i2c_master_send(client, buf, 3); return 0; @@ -363,188 +318,50 @@ static void saa6752hs_set_subsampling(struct i2c_client* client, } -static void saa6752hs_old_set_params(struct i2c_client* client, +static void saa6752hs_set_params(struct i2c_client* client, struct v4l2_mpeg_compression* params) { struct saa6752hs_state *h = i2c_get_clientdata(client); /* check PIDs */ - if (params->ts_pid_pmt <= MPEG_PID_MAX) { - h->old_params.ts_pid_pmt = params->ts_pid_pmt; + if (params->ts_pid_pmt <= MPEG_PID_MAX) h->params.ts_pid_pmt = params->ts_pid_pmt; - } - if (params->ts_pid_pcr <= MPEG_PID_MAX) { - h->old_params.ts_pid_pcr = params->ts_pid_pcr; + if (params->ts_pid_pcr <= MPEG_PID_MAX) h->params.ts_pid_pcr = params->ts_pid_pcr; - } - if (params->ts_pid_video <= MPEG_PID_MAX) { - h->old_params.ts_pid_video = params->ts_pid_video; + if (params->ts_pid_video <= MPEG_PID_MAX) h->params.ts_pid_video = params->ts_pid_video; - } - if (params->ts_pid_audio <= MPEG_PID_MAX) { - h->old_params.ts_pid_audio = params->ts_pid_audio; + if (params->ts_pid_audio <= MPEG_PID_MAX) h->params.ts_pid_audio = params->ts_pid_audio; - } /* check bitrate parameters */ if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) || - (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) { - h->old_params.vi_bitrate.mode = params->vi_bitrate.mode; - h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; - } + (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) + h->params.vi_bitrate.mode = params->vi_bitrate.mode; if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) - h->old_params.st_bitrate.target = params->st_bitrate.target; + h->params.st_bitrate.target = params->st_bitrate.target; if (params->vi_bitrate.mode != V4L2_BITRATE_NONE) - h->old_params.vi_bitrate.target = params->vi_bitrate.target; + h->params.vi_bitrate.target = params->vi_bitrate.target; if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) - h->old_params.vi_bitrate.max = params->vi_bitrate.max; + h->params.vi_bitrate.max = params->vi_bitrate.max; if (params->au_bitrate.mode != V4L2_BITRATE_NONE) - h->old_params.au_bitrate.target = params->au_bitrate.target; + h->params.au_bitrate.target = params->au_bitrate.target; /* aspect ratio */ if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 || - params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) { - h->old_params.vi_aspect_ratio = params->vi_aspect_ratio; - if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3) - h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; - else - h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9; - } + params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) + h->params.vi_aspect_ratio = params->vi_aspect_ratio; /* range checks */ - if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) - h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; - if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) - h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; - if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) - h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; - h->params.vi_bitrate = params->vi_bitrate.target; - h->params.vi_bitrate_peak = params->vi_bitrate.max; - if (h->old_params.au_bitrate.target <= 256) { - h->old_params.au_bitrate.target = 256; - h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K; - } - else { - h->old_params.au_bitrate.target = 384; - h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K; - } -} - -static int handle_ctrl(struct saa6752hs_mpeg_params *params, - struct v4l2_ext_control *ctrl, unsigned int cmd) -{ - int old = 0, new; - int set = (cmd == VIDIOC_S_EXT_CTRLS); - - new = ctrl->value; - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_STREAM_PID_PMT: - old = params->ts_pid_pmt; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_pmt = new; - break; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: - old = params->ts_pid_audio; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_audio = new; - break; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: - old = params->ts_pid_video; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_video = new; - break; - case V4L2_CID_MPEG_STREAM_PID_PCR: - old = params->ts_pid_pcr; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_pcr = new; - break; - case V4L2_CID_MPEG_AUDIO_ENCODING: - old = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - old = params->au_l2_bitrate; - if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && - new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) - return -ERANGE; - if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) - new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; - else - new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; - params->au_l2_bitrate = new; - break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - old = params->vi_aspect; - if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && - new != V4L2_MPEG_VIDEO_ASPECT_4x3) - return -ERANGE; - if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) - new = V4L2_MPEG_VIDEO_ASPECT_4x3; - params->vi_aspect = new; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - old = params->vi_bitrate * 1000; - new = 1000 * (new / 1000); - if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - return -ERANGE; - if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; - params->vi_bitrate = new / 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - old = params->vi_bitrate_peak * 1000; - new = 1000 * (new / 1000); - if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - return -ERANGE; - if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; - params->vi_bitrate_peak = new / 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - old = params->vi_bitrate_mode; - params->vi_bitrate_mode = new; - break; - default: - return -EINVAL; - } - if (cmd == VIDIOC_G_EXT_CTRLS) - ctrl->value = old; + if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX) + h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX; + if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX) + h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX; + if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX) + h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX; + if (h->params.au_bitrate.target <= 256) + h->params.au_bitrate.target = 256; else - ctrl->value = new; - return 0; + h->params.au_bitrate.target = 384; } static int saa6752hs_init(struct i2c_client* client) @@ -578,22 +395,22 @@ static int saa6752hs_init(struct i2c_client* client) buf[2] = 0x0D; i2c_master_send(client,buf,3); - /* Set minimum Q-scale {4} */ + /* Set minimum Q-scale {4} */ buf[0] = 0x82; buf[1] = 0x04; i2c_master_send(client,buf,2); - /* Set maximum Q-scale {12} */ + /* Set maximum Q-scale {12} */ buf[0] = 0x83; buf[1] = 0x0C; i2c_master_send(client,buf,2); - /* Set Output Protocol */ + /* Set Output Protocol */ buf[0] = 0xD0; buf[1] = 0x81; i2c_master_send(client,buf,2); - /* Set video output stream format {TS} */ + /* Set video output stream format {TS} */ buf[0] = 0xB0; buf[1] = 0x05; i2c_master_send(client,buf,2); @@ -624,7 +441,7 @@ static int saa6752hs_init(struct i2c_client* client) localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; localPMT[sizeof(PMT) - 1] = crc & 0xFF; - /* Set Audio PID */ + /* Set Audio PID */ buf[0] = 0xC1; buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; buf[2] = h->params.ts_pid_audio & 0xFF; @@ -672,11 +489,11 @@ static int saa6752hs_init(struct i2c_client* client) buf[3] = 0x82; buf[4] = 0xB0; buf[5] = buf2[0]; - switch(h->params.vi_aspect) { - case V4L2_MPEG_VIDEO_ASPECT_16x9: + switch(h->params.vi_aspect_ratio) { + case V4L2_MPEG_ASPECT_16_9: buf[6] = buf2[1] | 0x40; break; - case V4L2_MPEG_VIDEO_ASPECT_4x3: + case V4L2_MPEG_ASPECT_4_3: default: buf[6] = buf2[1] & 0xBF; break; @@ -698,7 +515,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) return -ENOMEM; h->client = client_template; h->params = param_defaults; - h->old_params = old_param_defaults; h->client.adapter = adap; h->client.addr = addr; @@ -734,45 +550,20 @@ static int saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct saa6752hs_state *h = i2c_get_clientdata(client); - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_mpeg_compression *old_params = arg; - struct saa6752hs_mpeg_params params; + struct v4l2_mpeg_compression *params = arg; int err = 0; - int i; switch (cmd) { case VIDIOC_S_MPEGCOMP: - if (NULL == old_params) { + if (NULL == params) { /* apply settings and start encoder */ saa6752hs_init(client); break; } - saa6752hs_old_set_params(client, old_params); + saa6752hs_set_params(client, params); /* fall through */ case VIDIOC_G_MPEGCOMP: - *old_params = h->old_params; - break; - case VIDIOC_S_EXT_CTRLS: - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - if (ctrls->count == 0) { - /* apply settings and start encoder */ - saa6752hs_init(client); - break; - } - /* fall through */ - case VIDIOC_TRY_EXT_CTRLS: - case VIDIOC_G_EXT_CTRLS: - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - params = h->params; - for (i = 0; i < ctrls->count; i++) { - if ((err = handle_ctrl(¶ms, ctrls->controls + i, cmd))) { - ctrls->error_idx = i; - return err; - } - } - h->params = params; + *params = h->params; break; case VIDIOC_G_FMT: { diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c index d77e6a8d9432..bb3e0ba946d3 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c +++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c @@ -818,7 +818,7 @@ static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, break; } - /* output xbar always main channel */ + /* output xbar always main channel */ saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); if (left || right) { // We've got data, turn the input on diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 927413aded10..86eae3528330 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -2160,7 +2160,7 @@ struct saa7134_board saa7134_boards[] = { .radio = { .name = name_radio, .amux = LINE2, - }, + }, }, [SAA7134_BOARD_GOTVIEW_7135] = { /* Mike Baikov */ @@ -2842,55 +2842,6 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ }, }, - [SAA7134_BOARD_FLYVIDEO3000_NTSC] = { - /* "Zac Bowling" */ - .name = "LifeView FlyVIDEO3000 (NTSC)", - .audio_clock = 0x00200000, - .tuner_type = TUNER_PHILIPS_NTSC, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - - .gpiomask = 0xe000, - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .gpio = 0x8000, - .tv = 1, - },{ - .name = name_tv_mono, - .vmux = 1, - .amux = LINE2, - .gpio = 0x0000, - .tv = 1, - },{ - .name = name_comp1, - .vmux = 0, - .amux = LINE2, - .gpio = 0x4000, - },{ - .name = name_comp2, - .vmux = 3, - .amux = LINE2, - .gpio = 0x4000, - },{ - .name = name_svideo, - .vmux = 8, - .amux = LINE2, - .gpio = 0x4000, - }}, - .radio = { - .name = name_radio, - .amux = LINE2, - .gpio = 0x2000, - }, - .mute = { - .name = name_mute, - .amux = TV, - .gpio = 0x8000, - }, - }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -2947,12 +2898,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x153b, .subdevice = 0x1162, .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7134, - .subvendor = 0x5169, - .subdevice = 0x0138, - .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -3514,7 +3459,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_FLYVIDEO2000: case SAA7134_BOARD_FLYVIDEO3000: - case SAA7134_BOARD_FLYVIDEO3000_NTSC: dev->has_remote = SAA7134_REMOTE_GPIO; board_flyvideo(dev); break; diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 279828b8f299..222a36c38917 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -132,8 +132,9 @@ static int mt352_aver777_init(struct dvb_frontend* fe) return 0; } -static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) +static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params, + u8* pllbuf) { u8 off[] = { 0x00, 0xf1}; u8 on[] = { 0x00, 0x71}; @@ -146,31 +147,30 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, f.tuner = 0; f.type = V4L2_TUNER_DIGITAL_TV; f.frequency = params->frequency / 1000 * 16 / 1000; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); msg.buf = on; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); pinnacle_antenna_pwr(dev, antenna_pwr); /* mt352 setup */ - return mt352_pinnacle_init(fe); + mt352_pinnacle_init(fe); + pllbuf[0] = 0xc2; + pllbuf[1] = 0x00; + pllbuf[2] = 0x00; + pllbuf[3] = 0x80; + pllbuf[4] = 0x00; + return 0; } -static int mt352_aver777_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) +static int mt352_aver777_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf) { - if (buf_len < 5) - return -EINVAL; - - pllbuf[0] = 0x61; + pllbuf[0] = 0xc2; dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, params->frequency, params->u.ofdm.bandwidth); - return 5; + return 0; } static struct mt352_config pinnacle_300i = { @@ -179,11 +179,13 @@ static struct mt352_config pinnacle_300i = { .if2 = 36150, .no_tuner = 1, .demod_init = mt352_pinnacle_init, + .pll_set = mt352_pinnacle_pll_set, }; static struct mt352_config avermedia_777 = { .demod_address = 0xf, .demod_init = mt352_aver777_init, + .pll_set = mt352_aver777_pll_set, }; #endif @@ -266,8 +268,6 @@ static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_ tuner_buf[2] = 0xca; tuner_buf[3] = (cp << 5) | (filter << 3) | band; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -281,8 +281,6 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; /* setup PLL configuration */ - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -292,12 +290,12 @@ static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) /* ------------------------------------------------------------------ */ -static int philips_tu1216_tuner_60_init(struct dvb_frontend *fe) +static int philips_tu1216_pll_60_init(struct dvb_frontend *fe) { return philips_tda6651_pll_init(0x60, fe); } -static int philips_tu1216_tuner_60_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { return philips_tda6651_pll_set(0x60, fe, params); } @@ -317,17 +315,20 @@ static struct tda1004x_config philips_tu1216_60_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, + .pll_init = philips_tu1216_pll_60_init, + .pll_set = philips_tu1216_pll_60_set, + .pll_sleep = NULL, .request_firmware = philips_tu1216_request_firmware, }; /* ------------------------------------------------------------------ */ -static int philips_tu1216_tuner_61_init(struct dvb_frontend *fe) +static int philips_tu1216_pll_61_init(struct dvb_frontend *fe) { return philips_tda6651_pll_init(0x61, fe); } -static int philips_tu1216_tuner_61_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { return philips_tda6651_pll_set(0x61, fe, params); } @@ -340,20 +341,21 @@ static struct tda1004x_config philips_tu1216_61_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, + .pll_init = philips_tu1216_pll_61_init, + .pll_set = philips_tu1216_pll_61_set, + .pll_sleep = NULL, .request_firmware = philips_tu1216_request_firmware, }; /* ------------------------------------------------------------------ */ -static int philips_europa_tuner_init(struct dvb_frontend *fe) +static int philips_europa_pll_init(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; /* setup PLL configuration */ - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) return -EIO; msleep(1); @@ -363,20 +365,18 @@ static int philips_europa_tuner_init(struct dvb_frontend *fe) init_msg.len = 0x02; msg[0] = 0x00; msg[1] = 0x40; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) return -EIO; return 0; } -static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { return philips_tda6651_pll_set(0x61, fe, params); } -static int philips_europa_tuner_sleep(struct dvb_frontend *fe) +static void philips_europa_analog(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; /* this message actually turns the tuner back to analog mode */ @@ -391,20 +391,7 @@ static int philips_europa_tuner_sleep(struct dvb_frontend *fe) analog_msg.len = 0x02; msg[0] = 0x00; msg[1] = 0x14; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &analog_msg, 1); - return 0; -} - -static int philips_europa_demod_sleep(struct dvb_frontend *fe) -{ - struct saa7134_dev *dev = fe->dvb->priv; - - if (dev->original_demod_sleep) - dev->original_demod_sleep(fe); - fe->ops.i2c_gate_ctrl(fe, 1); - return 0; } static struct tda1004x_config philips_europa_config = { @@ -415,20 +402,21 @@ static struct tda1004x_config philips_europa_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_IFO_AUTO_POS, .if_freq = TDA10046_FREQ_052, + .pll_init = philips_europa_pll_init, + .pll_set = philips_td1316_pll_set, + .pll_sleep = philips_europa_analog, .request_firmware = NULL, }; /* ------------------------------------------------------------------ */ -static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) +static int philips_fmd1216_pll_init(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; /* this message is to set up ATC and ALC */ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) return -EIO; msleep(1); @@ -436,27 +424,22 @@ static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) return 0; } -static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe) +static void philips_fmd1216_analog(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; /* this message actually turns the tuner back to analog mode */ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); msleep(1); fmd1216_init[2] = 0x86; fmd1216_init[3] = 0x54; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); msleep(1); - return 0; } -static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct saa7134_dev *dev = fe->dvb->priv; u8 tuner_buf[4]; @@ -533,8 +516,6 @@ static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_ tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; tuner_buf[3] = 0x40 | band; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) return -EIO; return 0; @@ -547,6 +528,9 @@ static struct tda1004x_config medion_cardbus = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_IFO_AUTO_NEG, .if_freq = TDA10046_FREQ_3613, + .pll_init = philips_fmd1216_pll_init, + .pll_set = philips_fmd1216_pll_set, + .pll_sleep = philips_fmd1216_analog, .request_firmware = NULL, }; @@ -594,12 +578,12 @@ static struct tda827x_data tda827x_dvbt[] = { { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} }; -static int philips_tda827x_tuner_init(struct dvb_frontend *fe) +static int philips_tda827x_pll_init(struct dvb_frontend *fe) { return 0; } -static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct saa7134_dev *dev = fe->dvb->priv; u8 tuner_buf[14]; @@ -646,8 +630,6 @@ static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_ tuner_buf[13] = 0x40; tuner_msg.len = 14; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) return -EIO; @@ -656,23 +638,18 @@ static int philips_tda827x_tuner_set_params(struct dvb_frontend *fe, struct dvb_ tuner_buf[0] = 0x30; tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp; tuner_msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); return 0; } -static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe) +static void philips_tda827x_pll_sleep(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 tda827x_sleep[] = { 0x30, 0xd0}; struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, .len = sizeof(tda827x_sleep) }; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); - return 0; } static struct tda1004x_config tda827x_lifeview_config = { @@ -682,6 +659,9 @@ static struct tda1004x_config tda827x_lifeview_config = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_TDA827X, .if_freq = TDA10046_FREQ_045, + .pll_init = philips_tda827x_pll_init, + .pll_set = philips_tda827x_pll_set, + .pll_sleep = philips_tda827x_pll_sleep, .request_firmware = NULL, }; @@ -773,8 +753,6 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb tuner_buf[12] = 0x00; tuner_buf[13] = 0x39; // lpsel msg.len = 14; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) return -EIO; @@ -782,14 +760,10 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb msg.len = 2; reg2[0] = 0x60; reg2[1] = 0x3c; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); reg2[0] = 0xa0; reg2[1] = 0x40; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); msleep(2); @@ -797,43 +771,36 @@ static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb reg2[0] = 0x30; reg2[1] = 0x10 + tda827xa_dvbt[i].scr; msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); msleep(550); reg2[0] = 0x50; reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); return 0; } -static int philips_tda827xa_tuner_sleep(u8 addr, struct dvb_frontend *fe) +static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 tda827xa_sleep[] = { 0x30, 0x90}; struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, .len = sizeof(tda827xa_sleep) }; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); - return 0; + } /* ------------------------------------------------------------------ */ -static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int ret; struct saa7134_dev *dev = fe->dvb->priv; static u8 tda8290_close[] = { 0x21, 0xc0}; static u8 tda8290_open[] = { 0x21, 0x80}; struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; - /* close tda8290 i2c bridge */ tda8290_msg.buf = tda8290_close; ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); @@ -849,7 +816,7 @@ static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_fr return ret; } -static int philips_tiger_tuner_init(struct dvb_frontend *fe) +static int philips_tiger_dvb_mode(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 data[] = { 0x3c, 0x33, 0x6a}; @@ -860,15 +827,14 @@ static int philips_tiger_tuner_init(struct dvb_frontend *fe) return 0; } -static int philips_tiger_tuner_sleep(struct dvb_frontend *fe) +static void philips_tiger_analog_mode(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 data[] = { 0x3c, 0x33, 0x68}; struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; i2c_transfer(&dev->i2c_adap, &msg, 1); - philips_tda827xa_tuner_sleep( 0x61, fe); - return 0; + philips_tda827xa_pll_sleep( 0x61, fe); } static struct tda1004x_config philips_tiger_config = { @@ -878,12 +844,15 @@ static struct tda1004x_config philips_tiger_config = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_TDA827X, .if_freq = TDA10046_FREQ_045, + .pll_init = philips_tiger_dvb_mode, + .pll_set = philips_tiger_pll_set, + .pll_sleep = philips_tiger_analog_mode, .request_firmware = NULL, }; /* ------------------------------------------------------------------ */ -static int lifeview_trio_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int ret; @@ -891,12 +860,16 @@ static int lifeview_trio_tuner_set_params(struct dvb_frontend *fe, struct dvb_fr return ret; } -static int lifeview_trio_tuner_sleep(struct dvb_frontend *fe) +static int lifeview_trio_dvb_mode(struct dvb_frontend *fe) { - philips_tda827xa_tuner_sleep(0x60, fe); return 0; } +static void lifeview_trio_analog_mode(struct dvb_frontend *fe) +{ + philips_tda827xa_pll_sleep(0x60, fe); +} + static struct tda1004x_config lifeview_trio_config = { .demod_address = 0x09, .invert = 1, @@ -904,12 +877,15 @@ static struct tda1004x_config lifeview_trio_config = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_TDA827X_GPL, .if_freq = TDA10046_FREQ_045, + .pll_init = lifeview_trio_dvb_mode, + .pll_set = lifeview_trio_pll_set, + .pll_sleep = lifeview_trio_analog_mode, .request_firmware = NULL, }; /* ------------------------------------------------------------------ */ -static int ads_duo_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int ret; @@ -917,7 +893,7 @@ static int ads_duo_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend return ret; } -static int ads_duo_tuner_init(struct dvb_frontend *fe) +static int ads_duo_dvb_mode(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; /* route TDA8275a AGC input to the channel decoder */ @@ -925,13 +901,12 @@ static int ads_duo_tuner_init(struct dvb_frontend *fe) return 0; } -static int ads_duo_tuner_sleep(struct dvb_frontend *fe) +static void ads_duo_analog_mode(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; /* route TDA8275a AGC input to the analog IF chip*/ saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20); - philips_tda827xa_tuner_sleep( 0x61, fe); - return 0; + philips_tda827xa_pll_sleep( 0x61, fe); } static struct tda1004x_config ads_tech_duo_config = { @@ -941,24 +916,31 @@ static struct tda1004x_config ads_tech_duo_config = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_TDA827X_GPL, .if_freq = TDA10046_FREQ_045, + .pll_init = ads_duo_dvb_mode, + .pll_set = ads_duo_pll_set, + .pll_sleep = ads_duo_analog_mode, .request_firmware = NULL, }; /* ------------------------------------------------------------------ */ -static int tevion_dvb220rf_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int ret; ret = philips_tda827xa_pll_set(0x60, fe, params); return ret; } -static int tevion_dvb220rf_tuner_sleep(struct dvb_frontend *fe) +static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe) { - philips_tda827xa_tuner_sleep( 0x61, fe); return 0; } +static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe) +{ + philips_tda827xa_pll_sleep( 0x61, fe); +} + static struct tda1004x_config tevion_dvbt220rf_config = { .demod_address = 0x08, .invert = 1, @@ -966,6 +948,9 @@ static struct tda1004x_config tevion_dvbt220rf_config = { .xtal_freq = TDA10046_XTAL_16M, .agc_config = TDA10046_AGC_TDA827X, .if_freq = TDA10046_FREQ_045, + .pll_init = tevion_dvb220rf_pll_init, + .pll_set = tevion_dvb220rf_pll_set, + .pll_sleep = tevion_dvb220rf_pll_sleep, .request_firmware = NULL, }; @@ -976,6 +961,8 @@ static struct tda1004x_config tevion_dvbt220rf_config = { #ifdef HAVE_NXT200X static struct nxt200x_config avertvhda180 = { .demod_address = 0x0a, + .pll_address = 0x61, + .pll_desc = &dvb_pll_tdhu2, }; static int nxt200x_set_pll_input(u8 *buf, int input) @@ -989,6 +976,8 @@ static int nxt200x_set_pll_input(u8 *buf, int input) static struct nxt200x_config kworldatsc110 = { .demod_address = 0x0a, + .pll_address = 0x61, + .pll_desc = &dvb_pll_tuv1236d, .set_pll_input = nxt200x_set_pll_input, }; #endif @@ -1014,158 +1003,78 @@ static int dvb_init(struct saa7134_dev *dev) printk("%s: pinnacle 300i dvb setup\n",dev->name); dev->dvb.frontend = mt352_attach(&pinnacle_300i, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; - } break; case SAA7134_BOARD_AVERMEDIA_777: printk("%s: avertv 777 dvb setup\n",dev->name); dev->dvb.frontend = mt352_attach(&avermedia_777, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.calc_regs = mt352_aver777_tuner_calc_regs; - } break; #endif #ifdef HAVE_TDA1004X case SAA7134_BOARD_MD7134: dev->dvb.frontend = tda10046_attach(&medion_cardbus, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; - } break; case SAA7134_BOARD_PHILIPS_TOUGH: dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_60_init; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_60_set_params; - } break; case SAA7134_BOARD_FLYDVBTDUO: dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; - } break; case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; - } break; case SAA7134_BOARD_PHILIPS_EUROPA: dev->dvb.frontend = tda10046_attach(&philips_europa_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; - dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; - dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; - } break; case SAA7134_BOARD_VIDEOMATE_DVBT_300: dev->dvb.frontend = tda10046_attach(&philips_europa_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; - } break; case SAA7134_BOARD_VIDEOMATE_DVBT_200: dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_tuner_61_init; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tu1216_tuner_61_set_params; - } break; case SAA7134_BOARD_PHILIPS_TIGER: dev->dvb.frontend = tda10046_attach(&philips_tiger_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; - } break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: dev->dvb.frontend = tda10046_attach(&philips_tiger_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; - } break; case SAA7134_BOARD_FLYDVBT_LR301: dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = philips_tda827x_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = philips_tda827x_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda827x_tuner_set_params; - } break; case SAA7134_BOARD_FLYDVB_TRIO: dev->dvb.frontend = tda10046_attach(&lifeview_trio_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = lifeview_trio_tuner_set_params; - } break; case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params; - } break; case SAA7134_BOARD_TEVION_DVBT_220RF: dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.sleep = tevion_dvb220rf_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = tevion_dvb220rf_tuner_set_params; - } break; case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config, &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.init = ads_duo_tuner_init; - dev->dvb.frontend->ops.tuner_ops.sleep = ads_duo_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = ads_duo_tuner_set_params; - } break; #endif #ifdef HAVE_NXT200X case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); - if (dev->dvb.frontend) { - dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tdhu2); - } break; case SAA7134_BOARD_KWORLD_ATSC110: dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap); - if (dev->dvb.frontend) { - dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d); - } break; #endif default: @@ -1179,7 +1088,7 @@ static int dvb_init(struct saa7134_dev *dev) } /* register everything else */ - return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); + return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); } static int dvb_fini(struct saa7134_dev *dev) diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 65d044086ce9..1d972edb3be6 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -64,10 +64,8 @@ static void ts_reset_encoder(struct saa7134_dev* dev) static int ts_init_encoder(struct saa7134_dev* dev) { - struct v4l2_ext_controls ctrls = { V4L2_CTRL_CLASS_MPEG, 0 }; - ts_reset_encoder(dev); - saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, &ctrls); + saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); dev->empress_started = 1; return 0; } @@ -164,7 +162,6 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct saa7134_dev *dev = file->private_data; - struct v4l2_ext_controls *ctrls = arg; if (debug > 1) v4l_print_ioctl(dev->name,cmd); @@ -281,31 +278,12 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, return saa7134_common_ioctl(dev, cmd, arg); case VIDIOC_S_MPEGCOMP: - printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. " - "Replace with VIDIOC_S_EXT_CTRLS!"); saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg); ts_init_encoder(dev); return 0; case VIDIOC_G_MPEGCOMP: - printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. " - "Replace with VIDIOC_G_EXT_CTRLS!"); saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg); return 0; - case VIDIOC_S_EXT_CTRLS: - /* count == 0 is abused in saa6752hs.c, so that special - case is handled here explicitly. */ - if (ctrls->count == 0) - return 0; - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, arg); - ts_init_encoder(dev); - return 0; - case VIDIOC_G_EXT_CTRLS: - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, arg); - return 0; default: return -ENOIOCTLCMD; diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c index 7c595492c56b..1426e4c8602f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-input.c +++ b/trunk/drivers/media/video/saa7134/saa7134-input.c @@ -37,10 +37,6 @@ static unsigned int ir_debug = 0; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); -static int pinnacle_remote = 0; -module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */ -MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)"); - #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) #define i2cdprintk(fmt, arg...) if (ir_debug) \ @@ -320,13 +316,8 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); - if (pinnacle_remote == 0) { - ir->get_key = get_key_pinnacle_color; - ir->ir_codes = ir_codes_pinnacle_color; - } else { - ir->get_key = get_key_pinnacle_grey; - ir->ir_codes = ir_codes_pinnacle_grey; - } + ir->get_key = get_key_pinnacle; + ir->ir_codes = ir_codes_pinnacle; break; case SAA7134_BOARD_UPMOST_PURPLE_TV: snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index d5ee99c574cc..353af3a8b766 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -33,7 +33,6 @@ #include -#include #include #include #include @@ -222,7 +221,6 @@ struct saa7134_format { #define SAA7134_BOARD_AVERMEDIA_A169_B1 92 #define SAA7134_BOARD_MD7134_BRIDGE_2 93 #define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94 -#define SAA7134_BOARD_FLYVIDEO3000_NTSC 95 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -533,7 +531,6 @@ struct saa7134_dev { /* SAA7134_MPEG_DVB only */ struct videobuf_dvb dvb; - int (*original_demod_sleep)(struct dvb_frontend* fe); }; /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/se401.h b/trunk/drivers/media/video/se401.h index c0891b3e0018..a7a216bd4413 100644 --- a/trunk/drivers/media/video/se401.h +++ b/trunk/drivers/media/video/se401.h @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_core.c b/trunk/drivers/media/video/sn9c102/sn9c102_core.c index 48d138a7c723..ea4394dc9415 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_core.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_core.c @@ -2608,9 +2608,11 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_CTRL: return sn9c102_vidioc_g_ctrl(cam, arg); + case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: return sn9c102_vidioc_s_ctrl(cam, arg); + case VIDIOC_CROPCAP_OLD: case VIDIOC_CROPCAP: return sn9c102_vidioc_cropcap(cam, arg); @@ -2657,6 +2659,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_PARM: return sn9c102_vidioc_g_parm(cam, arg); + case VIDIOC_S_PARM_OLD: case VIDIOC_S_PARM: return sn9c102_vidioc_s_parm(cam, arg); diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index c18b31d9928c..07476c71174a 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -42,7 +42,6 @@ #include #include #include -#include #include "saa7146.h" #include "saa7146reg.h" @@ -2190,7 +2189,7 @@ static struct pci_driver stradis_driver = { .remove = __devexit_p(stradis_remove) }; -static int __init stradis_init(void) +int __init stradis_init(void) { int retval; @@ -2203,7 +2202,7 @@ static int __init stradis_init(void) return retval; } -static void __exit stradis_exit(void) +void __exit stradis_exit(void) { pci_unregister_driver(&stradis_driver); printk(KERN_INFO "stradis: module cleanup complete\n"); diff --git a/trunk/drivers/media/video/stv680.c b/trunk/drivers/media/video/stv680.c index 351b182d921f..b38bda83a7c5 100644 --- a/trunk/drivers/media/video/stv680.c +++ b/trunk/drivers/media/video/stv680.c @@ -66,7 +66,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/tda9875.c b/trunk/drivers/media/video/tda9875.c index 827633b3bb43..103ccb919292 100644 --- a/trunk/drivers/media/video/tda9875.c +++ b/trunk/drivers/media/video/tda9875.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -164,7 +163,7 @@ static void do_tda9875_init(struct i2c_client *client) struct tda9875 *t = i2c_get_clientdata(client); dprintk("In tda9875_init\n"); tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ - tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ + tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ diff --git a/trunk/drivers/media/video/tda9887.c b/trunk/drivers/media/video/tda9887.c index 2fadabf99688..0d54f6c1982b 100644 --- a/trunk/drivers/media/video/tda9887.c +++ b/trunk/drivers/media/video/tda9887.c @@ -18,21 +18,49 @@ TDA9886 (PAL, SECAM, NTSC) TDA9887 (PAL, SECAM, NTSC, FM Radio) - Used as part of several tuners + found on: + - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv) + TDA9887 (world), TDA9885 (USA) + Note: OP2 of tda988x must be set to 1, else MT2032 is disabled! + - KNC One TV-Station RDS (saa7134) + - Hauppauge PVR-150/500 (possibly more) */ -#define tda9887_info(fmt, arg...) do {\ - printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ - i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) -#define tda9887_dbg(fmt, arg...) do {\ - if (tuner_debug) \ - printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ - i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) +/* Addresses to scan */ +static unsigned short normal_i2c[] = { + 0x84 >>1, + 0x86 >>1, + 0x96 >>1, + I2C_CLIENT_END, +}; +I2C_CLIENT_INSMOD; + +/* insmod options */ +static unsigned int debug = 0; +module_param(debug, int, 0644); +MODULE_LICENSE("GPL"); /* ---------------------------------------------------------------------- */ #define UNSET (-1U) +#define tda9887_info(fmt, arg...) do {\ + printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ + i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) +#define tda9887_dbg(fmt, arg...) do {\ + if (debug) \ + printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ + i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) + +struct tda9887 { + struct i2c_client client; + v4l2_std_id std; + enum tuner_mode mode; + unsigned int config; + unsigned int using_v4l2; + unsigned int radio_mode; + unsigned char data[4]; +}; struct tvnorm { v4l2_std_id std; @@ -42,6 +70,9 @@ struct tvnorm { unsigned char e; }; +static struct i2c_driver driver; +static struct i2c_client client_template; + /* ---------------------------------------------------------------------- */ // @@ -84,7 +115,8 @@ struct tvnorm { #define cAudioGain6 0x80 // bit c7 #define cTopMask 0x1f // bit c0:4 -#define cTopDefault 0x10 // bit c0:4 +#define cTopPalSecamDefault 0x14 // bit c0:4 +#define cTopNtscRadioDefault 0x10 // bit c0:4 //// third reg (e) #define cAudioIF_4_5 0x00 // bit e0:1 @@ -122,7 +154,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_5_5 | cVideoIF_38_90 ), @@ -133,7 +165,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_0 | cVideoIF_38_90 ), @@ -144,7 +176,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -155,7 +187,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_45_75 ), @@ -164,7 +196,7 @@ static struct tvnorm tvnorms[] = { .name = "SECAM-BGH", .b = ( cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_5_5 | cVideoIF_38_90 ), @@ -173,7 +205,7 @@ static struct tvnorm tvnorms[] = { .name = "SECAM-L", .b = ( cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -183,7 +215,7 @@ static struct tvnorm tvnorms[] = { .b = ( cOutputPort2Inactive | cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_33_90 ), @@ -194,7 +226,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -205,7 +237,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_45_75 ), @@ -216,7 +248,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_58_75 ), @@ -229,7 +261,7 @@ static struct tvnorm radio_stereo = { cQSS ), .c = ( cDeemphasisOFF | cAudioGain6 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cTunerGainLow | cAudioIF_5_5 | cRadioIF_38_90 ), @@ -241,7 +273,7 @@ static struct tvnorm radio_mono = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cTunerGainLow | cAudioIF_5_5 | cRadioIF_38_90 ), @@ -249,7 +281,7 @@ static struct tvnorm radio_mono = { /* ---------------------------------------------------------------------- */ -static void dump_read_message(struct tuner *t, unsigned char *buf) +static void dump_read_message(struct tda9887 *t, unsigned char *buf) { static char *afc[16] = { "- 12.5 kHz", @@ -277,7 +309,7 @@ static void dump_read_message(struct tuner *t, unsigned char *buf) tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); } -static void dump_write_message(struct tuner *t, unsigned char *buf) +static void dump_write_message(struct tda9887 *t, unsigned char *buf) { static char *sound[4] = { "AM/TV", @@ -373,13 +405,13 @@ static void dump_write_message(struct tuner *t, unsigned char *buf) /* ---------------------------------------------------------------------- */ -static int tda9887_set_tvnorm(struct tuner *t, char *buf) +static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) { struct tvnorm *norm = NULL; int i; - if (t->mode == V4L2_TUNER_RADIO) { - if (t->audmode == V4L2_TUNER_MODE_MONO) + if (t->mode == T_RADIO) { + if (t->radio_mode == V4L2_TUNER_MODE_MONO) norm = &radio_mono; else norm = &radio_stereo; @@ -413,7 +445,7 @@ module_param(port2, int, 0644); module_param(qss, int, 0644); module_param(adjust, int, 0644); -static int tda9887_set_insmod(struct tuner *t, char *buf) +static int tda9887_set_insmod(struct tda9887 *t, char *buf) { if (UNSET != port1) { if (port1) @@ -442,27 +474,27 @@ static int tda9887_set_insmod(struct tuner *t, char *buf) return 0; } -static int tda9887_set_config(struct tuner *t, char *buf) +static int tda9887_set_config(struct tda9887 *t, char *buf) { - if (t->tda9887_config & TDA9887_PORT1_ACTIVE) + if (t->config & TDA9887_PORT1_ACTIVE) buf[1] &= ~cOutputPort1Inactive; - if (t->tda9887_config & TDA9887_PORT1_INACTIVE) + if (t->config & TDA9887_PORT1_INACTIVE) buf[1] |= cOutputPort1Inactive; - if (t->tda9887_config & TDA9887_PORT2_ACTIVE) + if (t->config & TDA9887_PORT2_ACTIVE) buf[1] &= ~cOutputPort2Inactive; - if (t->tda9887_config & TDA9887_PORT2_INACTIVE) + if (t->config & TDA9887_PORT2_INACTIVE) buf[1] |= cOutputPort2Inactive; - if (t->tda9887_config & TDA9887_QSS) + if (t->config & TDA9887_QSS) buf[1] |= cQSS; - if (t->tda9887_config & TDA9887_INTERCARRIER) + if (t->config & TDA9887_INTERCARRIER) buf[1] &= ~cQSS; - if (t->tda9887_config & TDA9887_AUTOMUTE) + if (t->config & TDA9887_AUTOMUTE) buf[1] |= cAutoMuteFmActive; - if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) { + if (t->config & TDA9887_DEEMPHASIS_MASK) { buf[2] &= ~0x60; - switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) { + switch (t->config & TDA9887_DEEMPHASIS_MASK) { case TDA9887_DEEMPHASIS_NONE: buf[2] |= cDeemphasisOFF; break; @@ -474,36 +506,153 @@ static int tda9887_set_config(struct tuner *t, char *buf) break; } } - if (t->tda9887_config & TDA9887_TOP_SET) { + if (t->config & TDA9887_TOP_SET) { buf[2] &= ~cTopMask; - buf[2] |= (t->tda9887_config >> 8) & cTopMask; + buf[2] |= (t->config >> 8) & cTopMask; } - if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) + if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) buf[1] &= ~cQSS; return 0; } /* ---------------------------------------------------------------------- */ -static int tda9887_status(struct tuner *t) +static char pal[] = "--"; +static char secam[] = "--"; +static char ntsc[] = "-"; + +module_param_string(pal, pal, sizeof(pal), 0644); +module_param_string(secam, secam, sizeof(secam), 0644); +module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); + +static int tda9887_fixup_std(struct tda9887 *t) +{ + /* get more precise norm info from insmod option */ + if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { + switch (pal[0]) { + case 'b': + case 'B': + case 'g': + case 'G': + case 'h': + case 'H': + case 'n': + case 'N': + if (pal[1] == 'c' || pal[1] == 'C') { + tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); + t->std = V4L2_STD_PAL_Nc; + } else { + tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); + t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; + } + break; + case 'i': + case 'I': + tda9887_dbg("insmod fixup: PAL => PAL-I\n"); + t->std = V4L2_STD_PAL_I; + break; + case 'd': + case 'D': + case 'k': + case 'K': + tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); + t->std = V4L2_STD_PAL_DK; + break; + case 'm': + case 'M': + tda9887_dbg("insmod fixup: PAL => PAL-M\n"); + t->std = V4L2_STD_PAL_M; + break; + case '-': + /* default parameter, do nothing */ + break; + default: + tda9887_info("pal= argument not recognised\n"); + break; + } + } + if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { + switch (secam[0]) { + case 'b': + case 'B': + case 'g': + case 'G': + case 'h': + case 'H': + tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); + t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; + break; + case 'd': + case 'D': + case 'k': + case 'K': + tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n"); + t->std = V4L2_STD_SECAM_DK; + break; + case 'l': + case 'L': + if (secam[1] == 'c' || secam[1] == 'C') { + tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); + t->std = V4L2_STD_SECAM_LC; + } else { + tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); + t->std = V4L2_STD_SECAM_L; + } + break; + case '-': + /* default parameter, do nothing */ + break; + default: + tda9887_info("secam= argument not recognised\n"); + break; + } + } + if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { + switch (ntsc[0]) { + case 'm': + case 'M': + tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); + t->std = V4L2_STD_NTSC_M; + break; + case 'j': + case 'J': + tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); + t->std = V4L2_STD_NTSC_M_JP; + break; + case 'k': + case 'K': + tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); + t->std = V4L2_STD_NTSC_M_KR; + break; + case '-': + /* default parameter, do nothing */ + break; + default: + tda9887_info("ntsc= argument not recognised\n"); + break; + } + } + return 0; +} + +static int tda9887_status(struct tda9887 *t) { unsigned char buf[1]; int rc; memset(buf,0,sizeof(buf)); - if (1 != (rc = i2c_master_recv(&t->i2c,buf,1))) + if (1 != (rc = i2c_master_recv(&t->client,buf,1))) tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); dump_read_message(t, buf); return 0; } -static void tda9887_configure(struct i2c_client *client) +static int tda9887_configure(struct tda9887 *t) { - struct tuner *t = i2c_get_clientdata(client); int rc; - memset(t->tda9887_data,0,sizeof(t->tda9887_data)); - tda9887_set_tvnorm(t,t->tda9887_data); + memset(t->data,0,sizeof(t->data)); + tda9887_set_tvnorm(t,t->data); /* A note on the port settings: These settings tend to depend on the specifics of the board. @@ -518,84 +667,249 @@ static void tda9887_configure(struct i2c_client *client) the ports should be set to active (0), but, again, that may differ depending on the precise hardware configuration. */ - t->tda9887_data[1] |= cOutputPort1Inactive; - t->tda9887_data[1] |= cOutputPort2Inactive; + t->data[1] |= cOutputPort1Inactive; + t->data[1] |= cOutputPort2Inactive; - tda9887_set_config(t,t->tda9887_data); - tda9887_set_insmod(t,t->tda9887_data); + tda9887_set_config(t,t->data); + tda9887_set_insmod(t,t->data); if (t->mode == T_STANDBY) { - t->tda9887_data[1] |= cForcedMuteAudioON; + t->data[1] |= cForcedMuteAudioON; } tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", - t->tda9887_data[1],t->tda9887_data[2],t->tda9887_data[3]); - if (tuner_debug > 1) - dump_write_message(t, t->tda9887_data); + t->data[1],t->data[2],t->data[3]); + if (debug > 1) + dump_write_message(t, t->data); - if (4 != (rc = i2c_master_send(&t->i2c,t->tda9887_data,4))) + if (4 != (rc = i2c_master_send(&t->client,t->data,4))) tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); - if (tuner_debug > 2) { + if (debug > 2) { msleep_interruptible(1000); tda9887_status(t); } + return 0; } /* ---------------------------------------------------------------------- */ -static void tda9887_tuner_status(struct i2c_client *client) +static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) { - struct tuner *t = i2c_get_clientdata(client); - tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->tda9887_data[1], t->tda9887_data[2], t->tda9887_data[3]); + struct tda9887 *t; + + client_template.adapter = adap; + client_template.addr = addr; + + if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL))) + return -ENOMEM; + + t->client = client_template; + t->std = 0; + t->radio_mode = V4L2_TUNER_MODE_STEREO; + + tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); + + i2c_set_clientdata(&t->client, t); + i2c_attach_client(&t->client); + + return 0; } -static int tda9887_get_afc(struct i2c_client *client) +static int tda9887_probe(struct i2c_adapter *adap) { - struct tuner *t = i2c_get_clientdata(client); - static int AFC_BITS_2_kHz[] = { - -12500, -37500, -62500, -97500, - -112500, -137500, -162500, -187500, - 187500, 162500, 137500, 112500, - 97500 , 62500, 37500 , 12500 - }; - int afc=0; - __u8 reg = 0; + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, tda9887_attach); + return 0; +} - if (1 == i2c_master_recv(&t->i2c,®,1)) - afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; +static int tda9887_detach(struct i2c_client *client) +{ + struct tda9887 *t = i2c_get_clientdata(client); - return afc; + i2c_detach_client(client); + kfree(t); + return 0; } -static void tda9887_standby(struct i2c_client *client) +#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ + tda9887_info("switching to v4l2\n"); \ + t->using_v4l2 = 1; +#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ + tda9887_info("ignore v4l1 call\n"); \ + return 0; } + +static int +tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) { - tda9887_configure(client); + struct tda9887 *t = i2c_get_clientdata(client); + + switch (cmd) { + + /* --- configuration --- */ + case AUDC_SET_RADIO: + { + t->mode = T_RADIO; + tda9887_configure(t); + break; + } + case TUNER_SET_STANDBY: + { + t->mode = T_STANDBY; + tda9887_configure(t); + break; + } + case TDA9887_SET_CONFIG: + { + int *i = arg; + + t->config = *i; + tda9887_configure(t); + break; + } + /* --- v4l ioctls --- */ + /* take care: bttv does userspace copying, we'll get a + kernel pointer here... */ + case VIDIOCSCHAN: + { + static const v4l2_std_id map[] = { + [ VIDEO_MODE_PAL ] = V4L2_STD_PAL, + [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M, + [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM, + [ 4 /* bttv */ ] = V4L2_STD_PAL_M, + [ 5 /* bttv */ ] = V4L2_STD_PAL_N, + [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, + }; + struct video_channel *vc = arg; + + CHECK_V4L2; + t->mode = T_ANALOG_TV; + if (vc->norm < ARRAY_SIZE(map)) + t->std = map[vc->norm]; + tda9887_fixup_std(t); + tda9887_configure(t); + break; + } + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg; + + SWITCH_V4L2; + t->mode = T_ANALOG_TV; + t->std = *id; + tda9887_fixup_std(t); + tda9887_configure(t); + break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + SWITCH_V4L2; + if (V4L2_TUNER_ANALOG_TV == f->type) { + if (t->mode == T_ANALOG_TV) + return 0; + t->mode = T_ANALOG_TV; + } + if (V4L2_TUNER_RADIO == f->type) { + if (t->mode == T_RADIO) + return 0; + t->mode = T_RADIO; + } + tda9887_configure(t); + break; + } + case VIDIOC_G_TUNER: + { + static int AFC_BITS_2_kHz[] = { + -12500, -37500, -62500, -97500, + -112500, -137500, -162500, -187500, + 187500, 162500, 137500, 112500, + 97500 , 62500, 37500 , 12500 + }; + struct v4l2_tuner* tuner = arg; + + if (t->mode == T_RADIO) { + __u8 reg = 0; + tuner->afc=0; + if (1 == i2c_master_recv(&t->client,®,1)) + tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f]; + } + break; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner* tuner = arg; + + if (t->mode == T_RADIO) { + t->radio_mode = tuner->audmode; + tda9887_configure (t); + } + break; + } + case VIDIOC_LOG_STATUS: + { + tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]); + break; + } + default: + /* nothing */ + break; + } + return 0; } -static void tda9887_set_freq(struct i2c_client *client, unsigned int freq) +static int tda9887_suspend(struct device * dev, pm_message_t state) { - tda9887_configure(client); + struct i2c_client *c = container_of(dev, struct i2c_client, dev); + struct tda9887 *t = i2c_get_clientdata(c); + + tda9887_dbg("suspend\n"); + return 0; } -int tda9887_tuner_init(struct i2c_client *c) +static int tda9887_resume(struct device * dev) { - struct tuner *t = i2c_get_clientdata(c); + struct i2c_client *c = container_of(dev, struct i2c_client, dev); + struct tda9887 *t = i2c_get_clientdata(c); - strlcpy(c->name, "tda9887", sizeof(c->name)); + tda9887_dbg("resume\n"); + tda9887_configure(t); + return 0; +} - tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr, - t->i2c.driver->driver.name); +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver driver = { + .id = I2C_DRIVERID_TDA9887, + .attach_adapter = tda9887_probe, + .detach_client = tda9887_detach, + .command = tda9887_command, + .driver = { + .name = "tda9887", + .suspend = tda9887_suspend, + .resume = tda9887_resume, + }, +}; +static struct i2c_client client_template = +{ + .name = "tda9887", + .driver = &driver, +}; - t->set_tv_freq = tda9887_set_freq; - t->set_radio_freq = tda9887_set_freq; - t->standby = tda9887_standby; - t->tuner_status=tda9887_tuner_status; - t->get_afc=tda9887_get_afc; +static int __init tda9887_init_module(void) +{ + return i2c_add_driver(&driver); +} - return 0; +static void __exit tda9887_cleanup_module(void) +{ + i2c_del_driver(&driver); } +module_init(tda9887_init_module); +module_exit(tda9887_cleanup_module); + /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/trunk/drivers/media/video/tea5767.c b/trunk/drivers/media/video/tea5767.c index d1c41781ccc4..c2b98f81c192 100644 --- a/trunk/drivers/media/video/tea5767.c +++ b/trunk/drivers/media/video/tea5767.c @@ -3,7 +3,7 @@ * I2C address is allways 0xC0. * * - * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) * This code is placed under the terms of the GNU General Public License * * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa diff --git a/trunk/drivers/media/video/tlv320aic23b.c b/trunk/drivers/media/video/tlv320aic23b.c deleted file mode 100644 index 76b2e96429d9..000000000000 --- a/trunk/drivers/media/video/tlv320aic23b.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * tlv320aic23b - driver version 0.0.1 - * - * Copyright (C) 2006 Scott Alfter - * - * Based on wm8775 driver - * - * Copyright (C) 2004 Ulf Eklund - * Copyright (C) 2005 Hans Verkuil - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("tlv320aic23b driver"); -MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); -MODULE_LICENSE("GPL"); - -static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END }; - - -I2C_CLIENT_INSMOD; - -/* ----------------------------------------------------------------------- */ - -struct tlv320aic23b_state { - u8 muted; -}; - -static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val) -{ - int i; - - if ((reg < 0 || reg > 9) && (reg != 15)) { - v4l_err(client, "Invalid register R%d\n", reg); - return -1; - } - - for (i = 0; i < 3; i++) { - if (i2c_smbus_write_byte_data(client, (reg << 1) | - (val >> 8), val & 0xff) == 0) { - return 0; - } - } - v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); - return -1; -} - -static int tlv320aic23b_command(struct i2c_client *client, unsigned int cmd, - void *arg) -{ - struct tlv320aic23b_state *state = i2c_get_clientdata(client); - struct v4l2_control *ctrl = arg; - u32* freq = arg; - - switch (cmd) { - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - switch (*freq) { - case 32000: /* set sample rate to 32 kHz */ - tlv320aic23b_write(client, 8, 0x018); - break; - case 44100: /* set sample rate to 44.1 kHz */ - tlv320aic23b_write(client, 8, 0x022); - break; - case 48000: /* set sample rate to 48 kHz */ - tlv320aic23b_write(client, 8, 0x000); - break; - default: - return -EINVAL; - } - break; - - case VIDIOC_G_CTRL: - if (ctrl->id != V4L2_CID_AUDIO_MUTE) - return -EINVAL; - ctrl->value = state->muted; - break; - - case VIDIOC_S_CTRL: - if (ctrl->id != V4L2_CID_AUDIO_MUTE) - return -EINVAL; - state->muted = ctrl->value; - tlv320aic23b_write(client, 0, 0x180); /* mute both channels */ - /* set gain on both channels to +3.0 dB */ - if (!state->muted) - tlv320aic23b_write(client, 0, 0x119); - break; - - case VIDIOC_LOG_STATUS: - v4l_info(client, "Input: %s\n", - state->muted ? "muted" : "active"); - break; - - default: - return -EINVAL; - } - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ - -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ - -static struct i2c_driver i2c_driver; - -static int tlv320aic23b_attach(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct tlv320aic23b_state *state; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) - return -ENOMEM; - - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver; - snprintf(client->name, sizeof(client->name) - 1, "tlv320aic23b"); - - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); - - state = kmalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL); - if (state == NULL) { - kfree(client); - return -ENOMEM; - } - state->muted = 0; - i2c_set_clientdata(client, state); - - /* initialize tlv320aic23b */ - tlv320aic23b_write(client, 15, 0x000); /* RESET */ - tlv320aic23b_write(client, 6, 0x00A); /* turn off DAC & mic input */ - tlv320aic23b_write(client, 7, 0x049); /* left-justified, 24-bit, master mode */ - tlv320aic23b_write(client, 0, 0x119); /* set gain on both channels to +3.0 dB */ - tlv320aic23b_write(client, 8, 0x000); /* set sample rate to 48 kHz */ - tlv320aic23b_write(client, 9, 0x001); /* activate digital interface */ - - i2c_attach_client(client); - - return 0; -} - -static int tlv320aic23b_probe(struct i2c_adapter *adapter) -{ - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, tlv320aic23b_attach); - return 0; -} - -static int tlv320aic23b_detach(struct i2c_client *client) -{ - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - kfree(client); - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ -static struct i2c_driver i2c_driver = { - .driver = { - .name = "tlv320aic23b", - }, - .id = I2C_DRIVERID_TLV320AIC23B, - .attach_adapter = tlv320aic23b_probe, - .detach_client = tlv320aic23b_detach, - .command = tlv320aic23b_command, -}; - - -static int __init tlv320aic23b_init_module(void) -{ - return i2c_add_driver(&i2c_driver); -} - -static void __exit tlv320aic23b_cleanup_module(void) -{ - i2c_del_driver(&i2c_driver); -} - -module_init(tlv320aic23b_init_module); -module_exit(tlv320aic23b_cleanup_module); diff --git a/trunk/drivers/media/video/tuner-3036.c b/trunk/drivers/media/video/tuner-3036.c index bdf506e6ae27..74ab48c09c6a 100644 --- a/trunk/drivers/media/video/tuner-3036.c +++ b/trunk/drivers/media/video/tuner-3036.c @@ -25,7 +25,6 @@ #include #include -#include #include diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 011413cf34a8..1013b4de89a2 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -40,6 +40,7 @@ static unsigned int no_autodetect = 0; static unsigned int show_i2c = 0; /* insmod options used at runtime => read/write */ +static unsigned int tuner_debug_old = 0; int tuner_debug = 0; static unsigned int tv_range[2] = { 44, 958 }; @@ -53,6 +54,8 @@ static char ntsc[] = "-"; module_param(addr, int, 0444); module_param(no_autodetect, int, 0444); module_param(show_i2c, int, 0444); +/* Note: tuner_debug is deprecated and will be removed in 2.6.17 */ +module_param_named(tuner_debug,tuner_debug_old, int, 0444); module_param_named(debug,tuner_debug, int, 0644); module_param_string(pal, pal, sizeof(pal), 0644); module_param_string(secam, secam, sizeof(secam), 0644); @@ -196,7 +199,7 @@ static void set_type(struct i2c_client *c, unsigned int type, i2c_master_send(c, buffer, 4); default_tuner_init(c); break; - case TUNER_LG_TDVS_H06XF: + case TUNER_LG_TDVS_H062F: /* Set the Auxiliary Byte. */ buffer[2] &= ~0x20; buffer[2] |= 0x18; @@ -212,9 +215,6 @@ static void set_type(struct i2c_client *c, unsigned int type, i2c_master_send(c,buffer,4); default_tuner_init(c); break; - case TUNER_TDA9887: - tda9887_tuner_init(c); - break; default: default_tuner_init(c); break; @@ -241,8 +241,6 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) { struct tuner *t = i2c_get_clientdata(c); - tuner_dbg("set addr for type %i\n", t->type); - if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && (t->mode_mask & tun_setup->mode_mask)) || tun_setup->addr == c->addr)) { @@ -438,7 +436,11 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ t->audmode = V4L2_TUNER_MODE_STEREO; t->mode_mask = T_UNINITIALIZED; - t->tuner_status = tuner_status; + if (tuner_debug_old) { + tuner_debug = tuner_debug_old; + printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); + printk(KERN_ERR "tuner: use the debug option instead.\n"); + } if (show_i2c) { unsigned char buffer[16]; @@ -460,14 +462,10 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) case 0x4b: /* If chip is not tda8290, don't register. since it can be tda9887*/ - if (tda8290_probe(&t->i2c) == 0) { - tuner_dbg("chip at addr %x is a tda8290\n", addr); - } else { - /* Default is being tda9887 */ - t->type = TUNER_TDA9887; - t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; - t->mode = T_STANDBY; - goto register_client; + if (tda8290_probe(&t->i2c) != 0) { + tuner_dbg("chip at addr %x is not a tda8290\n", addr); + kfree(t); + return 0; } break; case 0x60: @@ -594,7 +592,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) case TUNER_SET_STANDBY: if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) return 0; - t->mode = T_STANDBY; if (t->standby) t->standby (client); break; @@ -607,14 +604,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Should be implemented, since bttv calls it */ tuner_dbg("VIDIOCSAUDIO not implemented.\n"); break; - case TDA9887_SET_CONFIG: - { - int *i = arg; - - t->tda9887_config = *i; - set_freq(client, t->tv_freq); - break; - } /* --- v4l ioctls --- */ /* take care: bttv does userspace copying, we'll get a kernel pointer here... */ @@ -722,10 +711,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_frequency *f = arg; - if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") - == EINVAL) - return 0; switch_v4l2(); + if ((V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode) + || (V4L2_TUNER_DIGITAL_TV == f->type + && V4L2_TUNER_DIGITAL_TV != t->mode)) { + if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") + == EINVAL) + return 0; + } set_freq(client,f->frequency); break; @@ -751,8 +744,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) switch_v4l2(); tuner->type = t->mode; - if (t->get_afc) - tuner->afc=t->get_afc(client); if (t->mode == V4L2_TUNER_ANALOG_TV) tuner->capability |= V4L2_TUNER_CAP_NORM; if (t->mode != V4L2_TUNER_RADIO) { @@ -796,8 +787,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) break; } case VIDIOC_LOG_STATUS: - if (t->tuner_status) - t->tuner_status(client); + tuner_status(client); break; } diff --git a/trunk/drivers/media/video/tuner-simple.c b/trunk/drivers/media/video/tuner-simple.c index 6da6f82b8c88..5d7abed71674 100644 --- a/trunk/drivers/media/video/tuner-simple.c +++ b/trunk/drivers/media/video/tuner-simple.c @@ -105,7 +105,7 @@ static int tuner_stereo(struct i2c_client *c) switch (t->type) { case TUNER_PHILIPS_FM1216ME_MK3: - case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1256_IH3: stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); break; diff --git a/trunk/drivers/media/video/tuner-types.c b/trunk/drivers/media/video/tuner-types.c index 9d9226cb6393..a1ae036b44ec 100644 --- a/trunk/drivers/media/video/tuner-types.c +++ b/trunk/drivers/media/video/tuner-types.c @@ -874,7 +874,7 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { }; -/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */ +/* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { { 16 * 165.00 /*MHz*/, 0x8e, 0x01 }, @@ -883,7 +883,7 @@ static struct tuner_range tuner_tua6034_ntsc_ranges[] = { }; -static struct tuner_params tuner_lg_tdvs_h06xf_params[] = { +static struct tuner_params tuner_tua6034_params[] = { { .type = TUNER_PARAM_TYPE_NTSC, .ranges = tuner_tua6034_ntsc_ranges, @@ -1024,22 +1024,6 @@ static struct tuner_params tuner_thomson_fe6600_params[] = { }, }; -/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */ - -static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = { - { 16 * 146.25 /*MHz*/, 0xce, 0x01, }, - { 16 * 428.50 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, -}; - -static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { - { - .type = TUNER_PARAM_TYPE_PAL, - .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges, - .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges), - }, -}; - /* --------------------------------------------------------------------- */ struct tunertype tuners[] = { @@ -1370,10 +1354,10 @@ struct tunertype tuners[] = { .params = tuner_philips_fmd1216me_mk3_params, .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params), }, - [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */ - .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */ - .params = tuner_lg_tdvs_h06xf_params, - .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params), + [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ + .name = "LG TDVS-H062F/TUA6034", + .params = tuner_tua6034_params, + .count = ARRAY_SIZE(tuner_tua6034_params), }, [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ .name = "Ymec TVF66T5-B/DFF", @@ -1416,16 +1400,6 @@ struct tunertype tuners[] = { .params = tuner_thomson_fe6600_params, .count = ARRAY_SIZE(tuner_thomson_fe6600_params), }, - [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */ - .name = "Samsung TCPG 6121P30A", - .params = tuner_samsung_tcpg_6121p30a_params, - .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params), - }, - [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator. - This chip is part of some modern tuners */ - .name = "Philips TDA988[5,6,7] IF PLL Demodulator", - /* see tda9887.c for details */ - }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index 30f8d80ddcaa..b463e996961a 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -200,7 +200,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "Philips FQ1286A MK4"}, { TUNER_ABSENT, "Philips FQ1216ME MK5"}, { TUNER_ABSENT, "Philips FQ1236 MK5"}, - { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"}, + { TUNER_ABSENT, "Samsung TCPG_6121P30A"}, { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, { TUNER_ABSENT, "TCL 2002MI_3H"}, { TUNER_TCL_2002N, "TCL 2002N 5H"}, diff --git a/trunk/drivers/media/video/tvmixer.c b/trunk/drivers/media/video/tvmixer.c index 1654576de10e..9e86caeb96a7 100644 --- a/trunk/drivers/media/video/tvmixer.c +++ b/trunk/drivers/media/video/tvmixer.c @@ -198,6 +198,10 @@ static int tvmixer_open(struct inode *inode, struct file *file) /* lock bttv in memory while the mixer is in use */ file->private_data = mix; +#ifndef I2C_PEC + if (client->adapter->inc_use) + client->adapter->inc_use(client->adapter); +#endif if (client->adapter->owner) try_module_get(client->adapter->owner); return 0; @@ -213,6 +217,10 @@ static int tvmixer_release(struct inode *inode, struct file *file) return -ENODEV; } +#ifndef I2C_PEC + if (client->adapter->dec_use) + client->adapter->dec_use(client->adapter); +#endif if (client->adapter->owner) module_put(client->adapter->owner); return 0; diff --git a/trunk/drivers/media/video/tvp5150.c b/trunk/drivers/media/video/tvp5150.c index b167ffab2520..dab4973bcf82 100644 --- a/trunk/drivers/media/video/tvp5150.c +++ b/trunk/drivers/media/video/tvp5150.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "tvp5150_reg.h" @@ -90,7 +89,7 @@ struct tvp5150 { struct i2c_client *client; v4l2_std_id norm; /* Current set standard */ - struct v4l2_routing route; + int input; int enable; int bright; int contrast; @@ -284,26 +283,29 @@ static void dump_reg(struct i2c_client *c) /**************************************************************************** Basic functions ****************************************************************************/ +enum tvp5150_input { + TVP5150_ANALOG_CH0 = 0, + TVP5150_SVIDEO = 1, + TVP5150_ANALOG_CH1 = 2, + TVP5150_BLACK_SCREEN = 8 +}; -static inline void tvp5150_selmux(struct i2c_client *c) +static inline void tvp5150_selmux(struct i2c_client *c, + enum tvp5150_input input) { int opmode=0; + struct tvp5150 *decoder = i2c_get_clientdata(c); - int input = 0; - if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable) - input = 8; + if (!decoder->enable) + input |= TVP5150_BLACK_SCREEN; switch (input) { - case TVP5150_COMPOSITE1: - input |= 2; - /* fall through */ - case TVP5150_COMPOSITE0: + case TVP5150_ANALOG_CH0: + case TVP5150_ANALOG_CH1: opmode=0x30; /* TV Mode */ break; - case TVP5150_SVIDEO: default: - input |= 1; opmode=0; /* Auto Mode */ break; } @@ -788,7 +790,7 @@ static inline void tvp5150_reset(struct i2c_client *c) tvp5150_vdp_init(c, vbi_ram_default); /* Selects decoder input */ - tvp5150_selmux(c); + tvp5150_selmux(c, decoder->input); /* Initializes TVP5150 to stream enabled values */ tvp5150_write_inittab(c, tvp5150_init_enable); @@ -858,21 +860,6 @@ static int tvp5150_command(struct i2c_client *c, case VIDIOC_INT_RESET: tvp5150_reset(c); break; - case VIDIOC_INT_G_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - - *route = decoder->route; - break; - } - case VIDIOC_INT_S_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - - decoder->route = *route; - tvp5150_selmux(c); - break; - } case VIDIOC_S_STD: if (decoder->norm == *(v4l2_std_id *)arg) break; @@ -1076,7 +1063,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, rv = i2c_attach_client(c); core->norm = V4L2_STD_ALL; /* Default is autodetect */ - core->route.input = TVP5150_COMPOSITE1; + core->input = 2; core->enable = 1; core->bright = 32768; core->contrast = 32768; diff --git a/trunk/drivers/media/video/usbvideo/Kconfig b/trunk/drivers/media/video/usbvideo/Kconfig index 59fb899f31f3..39269a2c5635 100644 --- a/trunk/drivers/media/video/usbvideo/Kconfig +++ b/trunk/drivers/media/video/usbvideo/Kconfig @@ -36,15 +36,3 @@ config USB_KONICAWC To compile this driver as a module, choose M here: the module will be called konicawc. - -config USB_QUICKCAM_MESSENGER - tristate "USB Logitech Quickcam Messenger" - depends on USB && VIDEO_DEV - select VIDEO_USBVIDEO - ---help--- - Say Y or M here to enable support for the USB Logitech Quickcam - Messenger webcam. - - To compile this driver as a module, choose M here: the - module will be called quickcam_messenger. - diff --git a/trunk/drivers/media/video/usbvideo/Makefile b/trunk/drivers/media/video/usbvideo/Makefile index 4a1b144bee4d..bb52eb8dc2f9 100644 --- a/trunk/drivers/media/video/usbvideo/Makefile +++ b/trunk/drivers/media/video/usbvideo/Makefile @@ -2,4 +2,3 @@ obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o obj-$(CONFIG_USB_KONICAWC) += konicawc.o obj-$(CONFIG_USB_VICAM) += vicam.o -obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += quickcam_messenger.o diff --git a/trunk/drivers/media/video/usbvideo/konicawc.c b/trunk/drivers/media/video/usbvideo/konicawc.c index 6f31ecc88843..c11f5d46b114 100644 --- a/trunk/drivers/media/video/usbvideo/konicawc.c +++ b/trunk/drivers/media/video/usbvideo/konicawc.c @@ -15,7 +15,8 @@ #include #include #include -#include +#include +#include #include "usbvideo.h" diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c deleted file mode 100644 index 56e01b622417..000000000000 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* - * Driver for Logitech Quickcam Messenger usb video camera - * Copyright (C) Jaya Kumar - * - * This work was sponsored by CIS(M) Sdn Bhd. - * History: - * 05/08/2006 - Jaya Kumar - * I wrote this based on the konicawc by Simon Evans. - * - - * Full credit for reverse engineering and creating an initial - * working linux driver for the VV6422 goes to the qce-ga project by - * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell, - * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as - * others. - * --- - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include - -#include "usbvideo.h" -#include "quickcam_messenger.h" - -/* - * Version Information - */ - -#ifdef CONFIG_USB_DEBUG -static int debug; -#define DEBUG(n, format, arg...) \ - if (n <= debug) { \ - printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ - } -#else -#define DEBUG(n, arg...) -static const int debug = 0; -#endif - -#define DRIVER_VERSION "v0.01" -#define DRIVER_DESC "Logitech Quickcam Messenger USB" - -#define USB_LOGITECH_VENDOR_ID 0x046D -#define USB_QCM_PRODUCT_ID 0x08F0 - -#define MAX_CAMERAS 1 - -#define MAX_COLOUR 32768 -#define MAX_HUE 32768 -#define MAX_BRIGHTNESS 32768 -#define MAX_CONTRAST 32768 -#define MAX_WHITENESS 32768 - -static int size = SIZE_320X240; -static int colour = MAX_COLOUR; -static int hue = MAX_HUE; -static int brightness = MAX_BRIGHTNESS; -static int contrast = MAX_CONTRAST; -static int whiteness = MAX_WHITENESS; - -static struct usbvideo *cams; - -static struct usb_device_id qcm_table [] = { - { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) }, - { } -}; -MODULE_DEVICE_TABLE(usb, qcm_table); - -#ifdef CONFIG_INPUT -static void qcm_register_input(struct qcm *cam, struct usb_device *dev) -{ - struct input_dev *input_dev; - - usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); - strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); - - cam->input = input_dev = input_allocate_device(); - if (!input_dev) { - warn("insufficient mem for cam input device"); - return; - } - - input_dev->name = "QCM button"; - input_dev->phys = cam->input_physname; - usb_to_input_id(dev, &input_dev->id); - input_dev->cdev.dev = &dev->dev; - - input_dev->evbit[0] = BIT(EV_KEY); - input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); - - input_dev->private = cam; - - input_register_device(cam->input); -} - -static void qcm_unregister_input(struct qcm *cam) -{ - if (cam->input) { - input_unregister_device(cam->input); - cam->input = NULL; - } -} - -static void qcm_report_buttonstat(struct qcm *cam) -{ - if (cam->input) { - input_report_key(cam->input, BTN_0, cam->button_sts); - input_sync(cam->input); - } -} - -static void qcm_int_irq(struct urb *urb, struct pt_regs *regs) -{ - int ret; - struct uvd *uvd = urb->context; - struct qcm *cam; - - if (!CAMERA_IS_OPERATIONAL(uvd)) - return; - - if (!uvd->streaming) - return; - - uvd->stats.urb_count++; - - if (urb->status < 0) - uvd->stats.iso_err_count++; - else { - if (urb->actual_length > 0 ) { - cam = (struct qcm *) uvd->user_data; - if (cam->button_sts_buf == 0x88) - cam->button_sts = 0x0; - else if (cam->button_sts_buf == 0x80) - cam->button_sts = 0x1; - qcm_report_buttonstat(cam); - } - } - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) - err("usb_submit_urb error (%d)", ret); -} - -static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd) -{ - int errflag; - usb_fill_int_urb(cam->button_urb, uvd->dev, - usb_rcvintpipe(uvd->dev, uvd->video_endp + 1), - &cam->button_sts_buf, - 1, - qcm_int_irq, - uvd, 16); - - errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL); - if (errflag) - err ("usb_submit_int ret %d", errflag); - return errflag; -} - -static void qcm_stop_int_data(struct qcm *cam) -{ - usb_kill_urb(cam->button_urb); -} - -static int qcm_alloc_int_urb(struct qcm *cam) -{ - cam->button_urb = usb_alloc_urb(0, GFP_KERNEL); - - if (!cam->button_urb) - return -ENOMEM; - - return 0; -} - -static void qcm_free_int(struct qcm *cam) -{ - if (cam->button_urb) - usb_free_urb(cam->button_urb); -} -#endif /* CONFIG_INPUT */ - -static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val) -{ - int ret; - - /* we'll wait up to 3 slices but no more */ - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - reg, 0, &val, 1, 3*HZ); - return ret; -} - -static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val) -{ - int ret; - - /* we'll wait up to 3 slices but no more */ - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - reg, 0, &val, 2, 3*HZ); - return ret; -} - -static int qcm_stv_getw(struct usb_device *dev, unsigned short reg, - __le16 *val) -{ - int ret; - - /* we'll wait up to 3 slices but no more */ - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, - reg, 0, val, 2, 3*HZ); - return ret; -} - -static int qcm_camera_on(struct uvd *uvd) -{ - int ret; - CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01)); - return 0; -} - -static int qcm_camera_off(struct uvd *uvd) -{ - int ret; - CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00)); - return 0; -} - -static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b) -{ - unsigned int segment, valsat; - signed int h = (signed int) hue; - unsigned int s = (sat - 32768) * 2; /* rescale */ - unsigned int v = val; - unsigned int p; - - /* - the registers controling gain are 8 bit of which - we affect only the last 4 bits with our gain. - we know that if saturation is 0, (unsaturated) then - we're grayscale (center axis of the colour cone) so - we set rgb=value. we use a formula obtained from - wikipedia to map the cone to the RGB plane. it's - as follows for the human value case of h=0..360, - s=0..1, v=0..1 - h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s) - q = v(1 - f*s) , t = v(1 - (1-f)s) - h_i==0 => r=v , g=t, b=p - h_i==1 => r=q , g=v, b=p - h_i==2 => r=p , g=v, b=t - h_i==3 => r=p , g=q, b=v - h_i==4 => r=t , g=p, b=v - h_i==5 => r=v , g=p, b=q - the bottom side (the point) and the stuff just up - of that is black so we simplify those two cases. - */ - if (sat < 32768) { - /* anything less than this is unsaturated */ - *r = val; - *g = val; - *b = val; - return; - } - if (val <= (0xFFFF/8)) { - /* anything less than this is black */ - *r = 0; - *g = 0; - *b = 0; - return; - } - - /* the rest of this code is copying tukkat's - implementation of the hsv2rgb conversion as taken - from qc-usb-messenger code. the 10923 is 0xFFFF/6 - to divide the cone into 6 sectors. */ - - segment = (h + 10923) & 0xFFFF; - segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */ - hue -= segment * 21845; /* -10923..10923 */ - h = hue; - h *= 3; - valsat = v*s >> 16; /* 0..65534 */ - p = v - valsat; - if (h >= 0) { - unsigned int t = v - (valsat * (32769 - h) >> 15); - switch (segment) { - case 0: /* R-> */ - *r = v; - *g = t; - *b = p; - break; - case 1: /* G-> */ - *r = p; - *g = v; - *b = t; - break; - case 2: /* B-> */ - *r = t; - *g = p; - *b = v; - break; - } - } else { - unsigned int q = v - (valsat * (32769 + h) >> 15); - switch (segment) { - case 0: /* ->R */ - *r = v; - *g = p; - *b = q; - break; - case 1: /* ->G */ - *r = q; - *g = v; - *b = p; - break; - case 2: /* ->B */ - *r = p; - *g = q; - *b = v; - break; - } - } -} - -static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue, - u16 saturation, u16 value) -{ - int ret; - u16 r=0,g=0,b=0; - - /* this code is based on qc-usb-messenger */ - qcm_hsv2rgb(hue, saturation, value, &r, &g, &b); - - r >>= 12; - g >>= 12; - b >>= 12; - - /* min val is 8 */ - r = max((u16) 8, r); - g = max((u16) 8, g); - b = max((u16) 8, b); - - r |= 0x30; - g |= 0x30; - b |= 0x30; - - /* set the r,g,b gain registers */ - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b)); - - /* doing as qc-usb did */ - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); - - return 0; -} - -static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure) -{ - int ret; - int formedval; - - /* calculation was from qc-usb-messenger driver */ - formedval = ( exposure >> 12 ); - - /* max value for formedval is 14 */ - formedval = min(formedval, 14); - - CHECK_RET(ret, qcm_stv_setb(uvd->dev, - 0x143A, 0xF0 | formedval)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); - return 0; -} - -static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast, - int hue, int colour) -{ - int ret; - /* brightness is exposure, contrast is gain, colour is saturation */ - CHECK_RET(ret, - qcm_sensor_set_exposure(uvd, brightness)); - CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast)); - - return 0; -} - -static int qcm_sensor_setsize(struct uvd *uvd, u8 size) -{ - int ret; - - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size)); - return 0; -} - -static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness) -{ - int ret; - /* some rescaling as done by the qc-usb-messenger code */ - if (whiteness > 0xC000) - whiteness = 0xC000 + (whiteness & 0x3FFF)*8; - - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D, - (whiteness >> 8) & 0xFF)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E, - (whiteness >> 16) & 0x03)); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01)); - - return 0; -} - -static int qcm_sensor_init(struct uvd *uvd) -{ - struct qcm *cam = (struct qcm *) uvd->user_data; - int ret; - int i; - - for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) { - CHECK_RET(ret, qcm_stv_setb(uvd->dev, - regval_table[i].reg, - regval_table[i].val)); - } - - CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1, - cpu_to_le16(ISOC_PACKET_SIZE))); - CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08)); - CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01)); - - CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00)); - - CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); - - CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness, - uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour)); - - CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness)); - CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); - - return 0; -} - -static int qcm_set_camera_size(struct uvd *uvd) -{ - int ret; - struct qcm *cam = (struct qcm *) uvd->user_data; - - CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd)); - cam->width = camera_sizes[cam->size].width; - cam->height = camera_sizes[cam->size].height; - uvd->videosize = VIDEOSIZE(cam->width, cam->height); - - return 0; -} - -static int qcm_setup_on_open(struct uvd *uvd) -{ - int ret; - - CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue, - uvd->vpic.colour, uvd->vpic.contrast)); - CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness)); - CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness)); - CHECK_RET(ret, qcm_set_camera_size(uvd)); - CHECK_RET(ret, qcm_camera_on(uvd)); - return 0; -} - -static void qcm_adjust_picture(struct uvd *uvd) -{ - int ret; - struct qcm *cam = (struct qcm *) uvd->user_data; - - ret = qcm_camera_off(uvd); - if (ret) { - err("can't turn camera off. abandoning pic adjustment"); - return; - } - - /* if there's been a change in contrast, hue, or - colour then we need to recalculate hsv in order - to update gains */ - if ((cam->contrast != uvd->vpic.contrast) || - (cam->hue != uvd->vpic.hue) || - (cam->colour != uvd->vpic.colour)) { - cam->contrast = uvd->vpic.contrast; - cam->hue = uvd->vpic.hue; - cam->colour = uvd->vpic.colour; - ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour, - cam->contrast); - if (ret) { - err("can't set gains. abandoning pic adjustment"); - return; - } - } - - if (cam->brightness != uvd->vpic.brightness) { - cam->brightness = uvd->vpic.brightness; - ret = qcm_sensor_set_exposure(uvd, cam->brightness); - if (ret) { - err("can't set exposure. abandoning pic adjustment"); - return; - } - } - - if (cam->whiteness != uvd->vpic.whiteness) { - cam->whiteness = uvd->vpic.whiteness; - qcm_sensor_set_shutter(uvd, cam->whiteness); - if (ret) { - err("can't set shutter. abandoning pic adjustment"); - return; - } - } - - ret = qcm_camera_on(uvd); - if (ret) { - err("can't reenable camera. pic adjustment failed"); - return; - } -} - -static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen) -{ - int datalen; - int totaldata; - struct framehdr { - __be16 id; - __be16 len; - }; - struct framehdr *fhdr; - - totaldata = 0; - while (framelen) { - fhdr = (struct framehdr *) cdata; - datalen = be16_to_cpu(fhdr->len); - framelen -= 4; - cdata += 4; - - if ((fhdr->id) == cpu_to_be16(0x8001)) { - RingQueue_Enqueue(&uvd->dp, marker, 4); - totaldata += 4; - continue; - } - if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) { - RingQueue_Enqueue(&uvd->dp, cdata, datalen); - totaldata += datalen; - } - framelen -= datalen; - cdata += datalen; - } - return totaldata; -} - -static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb) -{ - int totlen; - int i; - unsigned char *cdata; - - totlen=0; - for (i = 0; i < dataurb->number_of_packets; i++) { - int n = dataurb->iso_frame_desc[i].actual_length; - int st = dataurb->iso_frame_desc[i].status; - - cdata = dataurb->transfer_buffer + - dataurb->iso_frame_desc[i].offset; - - if (st < 0) { - warn("Data error: packet=%d. len=%d. status=%d.", - i, n, st); - uvd->stats.iso_err_count++; - continue; - } - if (!n) - continue; - - totlen += qcm_process_frame(uvd, cdata, n); - } - return totlen; -} - -static void resubmit_urb(struct uvd *uvd, struct urb *urb) -{ - int ret; - - urb->dev = uvd->dev; - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) - err("usb_submit_urb error (%d)", ret); -} - -static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs) -{ - int len; - struct uvd *uvd = urb->context; - - if (!CAMERA_IS_OPERATIONAL(uvd)) - return; - - if (!uvd->streaming) - return; - - uvd->stats.urb_count++; - - if (!urb->actual_length) { - resubmit_urb(uvd, urb); - return; - } - - len = qcm_compress_iso(uvd, urb); - resubmit_urb(uvd, urb); - uvd->stats.urb_length = len; - uvd->stats.data_count += len; - if (len) - RingQueue_WakeUpInterruptible(&uvd->dp); -} - -static int qcm_start_data(struct uvd *uvd) -{ - struct qcm *cam = (struct qcm *) uvd->user_data; - int i; - int errflag; - int pktsz; - int err; - - pktsz = uvd->iso_packet_len; - if (!CAMERA_IS_OPERATIONAL(uvd)) { - err("Camera is not operational"); - return -EFAULT; - } - - err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive); - if (err < 0) { - err("usb_set_interface error"); - uvd->last_error = err; - return -EBUSY; - } - - for (i=0; i < USBVIDEO_NUMSBUF; i++) { - int j, k; - struct urb *urb = uvd->sbuf[i].urb; - urb->dev = uvd->dev; - urb->context = uvd; - urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp); - urb->interval = 1; - urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = uvd->sbuf[i].data; - urb->complete = qcm_isoc_irq; - urb->number_of_packets = FRAMES_PER_DESC; - urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC; - for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) { - urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = pktsz; - } - } - - uvd->streaming = 1; - uvd->curframe = -1; - for (i=0; i < USBVIDEO_NUMSBUF; i++) { - errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); - if (errflag) - err ("usb_submit_isoc(%d) ret %d", i, errflag); - } - - CHECK_RET(err, qcm_setup_input_int(cam, uvd)); - CHECK_RET(err, qcm_camera_on(uvd)); - return 0; -} - -static void qcm_stop_data(struct uvd *uvd) -{ - struct qcm *cam = (struct qcm *) uvd->user_data; - int i, j; - int ret; - - if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) - return; - - ret = qcm_camera_off(uvd); - if (ret) - warn("couldn't turn the cam off."); - - uvd->streaming = 0; - - /* Unschedule all of the iso td's */ - for (i=0; i < USBVIDEO_NUMSBUF; i++) - usb_kill_urb(uvd->sbuf[i].urb); - - qcm_stop_int_data(cam); - - if (!uvd->remove_pending) { - /* Set packet size to 0 */ - j = usb_set_interface(uvd->dev, uvd->iface, - uvd->ifaceAltInactive); - if (j < 0) { - err("usb_set_interface() error %d.", j); - uvd->last_error = j; - } - } -} - -static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame) -{ - struct qcm *cam = (struct qcm *) uvd->user_data; - int x; - struct rgb *rgbL0; - struct rgb *rgbL1; - struct bayL0 *bayL0; - struct bayL1 *bayL1; - int hor,ver,hordel,verdel; - assert(frame != NULL); - - switch (cam->size) { - case SIZE_160X120: - hor = 162; ver = 124; hordel = 1; verdel = 2; - break; - case SIZE_320X240: - default: - hor = 324; ver = 248; hordel = 2; verdel = 4; - break; - } - - if (frame->scanstate == ScanState_Scanning) { - while (RingQueue_GetLength(&uvd->dp) >= - 4 + (hor*verdel + hordel)) { - if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) && - (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) && - (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) && - (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) { - frame->curline = 0; - frame->scanstate = ScanState_Lines; - frame->frameState = FrameState_Grabbing; - RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4); - /* - * if we're starting, we need to discard the first - * 4 lines of y bayer data - * and the first 2 gr elements of x bayer data - */ - RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, - (hor*verdel + hordel)); - break; - } - RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1); - } - } - - if (frame->scanstate == ScanState_Scanning) - return; - - /* now we can start processing bayer data so long as we have at least - * 2 lines worth of data. this is the simplest demosaicing method that - * I could think of. I use each 2x2 bayer element without interpolation - * to generate 4 rgb pixels. - */ - while ( frame->curline < cam->height && - (RingQueue_GetLength(&uvd->dp) >= hor*2)) { - /* get 2 lines of bayer for demosaicing - * into 2 lines of RGB */ - RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2); - bayL0 = (struct bayL0 *) cam->scratch; - bayL1 = (struct bayL1 *) (cam->scratch + hor); - /* frame->curline is the rgb y line */ - rgbL0 = (struct rgb *) - ( frame->data + (cam->width*3*frame->curline)); - /* w/2 because we're already doing 2 pixels */ - rgbL1 = rgbL0 + (cam->width/2); - - for (x=0; x < cam->width; x+=2) { - rgbL0->r = bayL0->r; - rgbL0->g = bayL0->g; - rgbL0->b = bayL1->b; - - rgbL0->r2 = bayL0->r; - rgbL0->g2 = bayL1->g; - rgbL0->b2 = bayL1->b; - - rgbL1->r = bayL0->r; - rgbL1->g = bayL1->g; - rgbL1->b = bayL1->b; - - rgbL1->r2 = bayL0->r; - rgbL1->g2 = bayL1->g; - rgbL1->b2 = bayL1->b; - - rgbL0++; - rgbL1++; - - bayL0++; - bayL1++; - } - - frame->seqRead_Length += cam->width*3*2; - frame->curline += 2; - } - /* See if we filled the frame */ - if (frame->curline == cam->height) { - frame->frameState = FrameState_Done_Hold; - frame->curline = 0; - uvd->curframe = -1; - uvd->stats.frame_num++; - } -} - -/* taken from konicawc */ -static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw) -{ - int ret; - int newsize; - int oldsize; - int x = vw->width; - int y = vw->height; - struct qcm *cam = (struct qcm *) uvd->user_data; - - if (x > 0 && y > 0) { - DEBUG(2, "trying to find size %d,%d", x, y); - for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) { - if ((camera_sizes[newsize].width == x) && - (camera_sizes[newsize].height == y)) - break; - } - } else - newsize = cam->size; - - if (newsize > MAX_FRAME_SIZE) { - DEBUG(1, "couldn't find size %d,%d", x, y); - return -EINVAL; - } - - if (newsize == cam->size) { - DEBUG(1, "Nothing to do"); - return 0; - } - - qcm_stop_data(uvd); - - if (cam->size != newsize) { - oldsize = cam->size; - cam->size = newsize; - ret = qcm_set_camera_size(uvd); - if (ret) { - err("Couldn't set camera size, err=%d",ret); - /* restore the original size */ - cam->size = oldsize; - return ret; - } - } - - /* Flush the input queue and clear any current frame in progress */ - - RingQueue_Flush(&uvd->dp); - if (uvd->curframe != -1) { - uvd->frame[uvd->curframe].curline = 0; - uvd->frame[uvd->curframe].seqRead_Length = 0; - uvd->frame[uvd->curframe].seqRead_Index = 0; - } - - CHECK_RET(ret, qcm_start_data(uvd)); - return 0; -} - -static int qcm_configure_video(struct uvd *uvd) -{ - int ret; - memset(&uvd->vpic, 0, sizeof(uvd->vpic)); - memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old)); - - uvd->vpic.colour = colour; - uvd->vpic.hue = hue; - uvd->vpic.brightness = brightness; - uvd->vpic.contrast = contrast; - uvd->vpic.whiteness = whiteness; - uvd->vpic.depth = 24; - uvd->vpic.palette = VIDEO_PALETTE_RGB24; - - memset(&uvd->vcap, 0, sizeof(uvd->vcap)); - strcpy(uvd->vcap.name, "QCM USB Camera"); - uvd->vcap.type = VID_TYPE_CAPTURE; - uvd->vcap.channels = 1; - uvd->vcap.audios = 0; - - uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width; - uvd->vcap.minheight = camera_sizes[SIZE_160X120].height; - uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width; - uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height; - - memset(&uvd->vchan, 0, sizeof(uvd->vchan)); - uvd->vchan.flags = 0 ; - uvd->vchan.tuners = 0; - uvd->vchan.channel = 0; - uvd->vchan.type = VIDEO_TYPE_CAMERA; - strcpy(uvd->vchan.name, "Camera"); - - CHECK_RET(ret, qcm_sensor_init(uvd)); - return 0; -} - -static int qcm_probe(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - int err; - struct uvd *uvd; - struct usb_device *dev = interface_to_usbdev(intf); - struct qcm *cam; - size_t buffer_size; - unsigned char video_ep; - struct usb_host_interface *interface; - struct usb_endpoint_descriptor *endpoint; - int i,j; - unsigned int ifacenum, ifacenum_inact=0; - __le16 sensor_id; - - /* we don't support multiconfig cams */ - if (dev->descriptor.bNumConfigurations != 1) - return -ENODEV; - - /* first check for the video interface and not - * the audio interface */ - interface = &intf->cur_altsetting[0]; - if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) - || (interface->desc.bInterfaceSubClass != - USB_CLASS_VENDOR_SPEC)) - return -ENODEV; - - /* - walk through each endpoint in each setting in the interface - stop when we find the one that's an isochronous IN endpoint. - */ - for (i=0; i < intf->num_altsetting; i++) { - interface = &intf->cur_altsetting[i]; - ifacenum = interface->desc.bAlternateSetting; - /* walk the end points */ - for (j=0; j < interface->desc.bNumEndpoints; j++) { - endpoint = &interface->endpoint[j].desc; - - if ((endpoint->bEndpointAddress & - USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) - continue; /* not input then not good */ - - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - if (!buffer_size) { - ifacenum_inact = ifacenum; - continue; /* 0 pkt size is not what we want */ - } - - if ((endpoint->bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_ISOC) { - video_ep = endpoint->bEndpointAddress; - /* break out of the search */ - goto good_videoep; - } - } - } - /* failed out since nothing useful was found */ - err("No suitable endpoint was found\n"); - return -ENODEV; - -good_videoep: - /* disable isochronous stream before doing anything else */ - err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0); - if (err < 0) { - err("Failed to disable sensor stream"); - return -EIO; - } - - /* - Check that this is the same unknown sensor that is known to work. This - sensor is suspected to be the ST VV6422C001. I'll check the same value - that the qc-usb driver checks. This value is probably not even the - sensor ID since it matches the USB dev ID. Oh well. If it doesn't - match, it's probably a diff sensor so exit and apologize. - */ - err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id); - if (err < 0) { - err("Couldn't read sensor values. Err %d\n",err); - return err; - } - if (sensor_id != cpu_to_le16(0x08F0)) { - err("Sensor ID %x != %x. Unsupported. Sorry\n", - le16_to_cpu(sensor_id), (0x08F0)); - return -ENODEV; - } - - uvd = usbvideo_AllocateDevice(cams); - if (!uvd) - return -ENOMEM; - - cam = (struct qcm *) uvd->user_data; - - /* buf for doing demosaicing */ - cam->scratch = kmalloc(324*2, GFP_KERNEL); - if (!cam->scratch) /* uvd freed in dereg */ - return -ENOMEM; - - /* yes, if we fail after here, cam->scratch gets freed - by qcm_free_uvd */ - - err = qcm_alloc_int_urb(cam); - if (err < 0) - return err; - - /* yes, if we fail after here, int urb gets freed - by qcm_free_uvd */ - - RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240); - cam->width = camera_sizes[size].width; - cam->height = camera_sizes[size].height; - cam->size = size; - - uvd->debug = debug; - uvd->flags = 0; - uvd->dev = dev; - uvd->iface = intf->altsetting->desc.bInterfaceNumber; - uvd->ifaceAltActive = ifacenum; - uvd->ifaceAltInactive = ifacenum_inact; - uvd->video_endp = video_ep; - uvd->iso_packet_len = buffer_size; - uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24; - uvd->defaultPalette = VIDEO_PALETTE_RGB24; - uvd->canvas = VIDEOSIZE(320, 240); - uvd->videosize = VIDEOSIZE(cam->width, cam->height); - err = qcm_configure_video(uvd); - if (err) { - err("failed to configure video settings"); - return err; - } - - err = usbvideo_RegisterVideoDevice(uvd); - if (err) { /* the uvd gets freed in Deregister */ - err("usbvideo_RegisterVideoDevice() failed."); - return err; - } - - uvd->max_frame_size = (320 * 240 * 3); - qcm_register_input(cam, dev); - usb_set_intfdata(intf, uvd); - return 0; -} - -static void qcm_free_uvd(struct uvd *uvd) -{ - struct qcm *cam = (struct qcm *) uvd->user_data; - - kfree(cam->scratch); - qcm_unregister_input(cam); - qcm_free_int(cam); -} - -static struct usbvideo_cb qcm_driver = { - .probe = qcm_probe, - .setupOnOpen = qcm_setup_on_open, - .processData = qcm_process_isoc, - .setVideoMode = qcm_set_video_mode, - .startDataPump = qcm_start_data, - .stopDataPump = qcm_stop_data, - .adjustPicture = qcm_adjust_picture, - .userFree = qcm_free_uvd -}; - -static int __init qcm_init(void) -{ - info(DRIVER_DESC " " DRIVER_VERSION); - - return usbvideo_register( - &cams, - MAX_CAMERAS, - sizeof(struct qcm), - "QCM", - &qcm_driver, - THIS_MODULE, - qcm_table); -} - -static void __exit qcm_exit(void) -{ - usbvideo_Deregister(&cams); -} - -module_param(size, int, 0); -MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240"); -module_param(colour, int, 0); -MODULE_PARM_DESC(colour, "Initial colour"); -module_param(hue, int, 0); -MODULE_PARM_DESC(hue, "Initial hue"); -module_param(brightness, int, 0); -MODULE_PARM_DESC(brightness, "Initial brightness"); -module_param(contrast, int, 0); -MODULE_PARM_DESC(contrast, "Initial contrast"); -module_param(whiteness, int, 0); -MODULE_PARM_DESC(whiteness, "Initial whiteness"); - -#ifdef CONFIG_USB_DEBUG -module_param(debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)"); -#endif - -module_init(qcm_init); -module_exit(qcm_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jaya Kumar"); -MODULE_DESCRIPTION("QCM USB Camera"); -MODULE_SUPPORTED_DEVICE("QCM USB Camera"); diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.h b/trunk/drivers/media/video/usbvideo/quickcam_messenger.h deleted file mode 100644 index baab9c081b52..000000000000 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef quickcam_messenger_h -#define quickcam_messenger_h - -#ifndef CONFIG_INPUT -/* if we're not using input we dummy out these functions */ -#define qcm_register_input(...) -#define qcm_unregister_input(...) -#define qcm_report_buttonstat(...) -#define qcm_setup_input_int(...) 0 -#define qcm_stop_int_data(...) -#define qcm_alloc_int_urb(...) 0 -#define qcm_free_int(...) -#endif - - -#define CHECK_RET(ret, expr) \ - if ((ret = expr) < 0) return ret - -/* Control Registers for the STVV6422 ASIC - * - this define is taken from the qc-usb-messenger code - */ -#define STV_ISO_ENABLE 0x1440 -#define ISOC_PACKET_SIZE 1023 - -/* Chip identification number including revision indicator */ -#define CMOS_SENSOR_IDREV 0xE00A - -struct rgb { - u8 b; - u8 g; - u8 r; - u8 b2; - u8 g2; - u8 r2; -}; - -struct bayL0 { -#ifdef __BIG_ENDIAN - u8 r; - u8 g; -#elif __LITTLE_ENDIAN - u8 g; - u8 r; -#else -#error not byte order defined -#endif -}; - -struct bayL1 { -#ifdef __BIG_ENDIAN - u8 g; - u8 b; -#elif __LITTLE_ENDIAN - u8 b; - u8 g; -#else -#error not byte order defined -#endif -}; - -struct cam_size { - u16 width; - u16 height; - u8 cmd; -}; - -static const struct cam_size camera_sizes[] = { - { 160, 120, 0xf }, - { 320, 240, 0x2 }, -}; - -enum frame_sizes { - SIZE_160X120 = 0, - SIZE_320X240 = 1, -}; - -#define MAX_FRAME_SIZE SIZE_320X240 - -struct qcm { - u16 colour; - u16 hue; - u16 brightness; - u16 contrast; - u16 whiteness; - - u8 size; - int height; - int width; - u8 *scratch; - struct urb *button_urb; - u8 button_sts; - u8 button_sts_buf; - -#ifdef CONFIG_INPUT - struct input_dev *input; - char input_physname[64]; -#endif -}; - -struct regval { - u16 reg; - u8 val; -}; -/* this table is derived from the -qc-usb-messenger code */ -static const struct regval regval_table[] = { - { STV_ISO_ENABLE, 0x00 }, - { 0x1436, 0x00 }, { 0x1432, 0x03 }, - { 0x143a, 0xF9 }, { 0x0509, 0x38 }, - { 0x050a, 0x38 }, { 0x050b, 0x38 }, - { 0x050c, 0x2A }, { 0x050d, 0x01 }, - { 0x1431, 0x00 }, { 0x1433, 0x34 }, - { 0x1438, 0x18 }, { 0x1439, 0x00 }, - { 0x143b, 0x05 }, { 0x143c, 0x00 }, - { 0x143e, 0x01 }, { 0x143d, 0x00 }, - { 0x1442, 0xe2 }, { 0x1500, 0xd0 }, - { 0x1500, 0xd0 }, { 0x1500, 0x50 }, - { 0x1501, 0xaf }, { 0x1502, 0xc2 }, - { 0x1503, 0x45 }, { 0x1505, 0x02 }, - { 0x150e, 0x8e }, { 0x150f, 0x37 }, - { 0x15c0, 0x00 }, -}; - -static const unsigned char marker[] = { 0x00, 0xff, 0x00, 0xFF }; - -#endif /* quickcam_messenger_h */ diff --git a/trunk/drivers/media/video/usbvideo/usbvideo.h b/trunk/drivers/media/video/usbvideo/usbvideo.h index 49dbee5f5628..3cbf4fc499a3 100644 --- a/trunk/drivers/media/video/usbvideo/usbvideo.h +++ b/trunk/drivers/media/video/usbvideo/usbvideo.h @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index 19d3c20dc7ef..474a29bc1760 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 97f946db8597..d330fa985bcc 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -59,7 +59,6 @@ #include #include #include -#define __OLD_VIDIOC_ /* To allow fixing old calls*/ #include #ifdef CONFIG_KMOD @@ -294,10 +293,7 @@ static const char *v4l2_ioctls[] = { #if 1 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", #endif - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", - [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", - [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", - [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS" + [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS" }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) @@ -335,8 +331,7 @@ static const char *v4l2_int_ioctls[] = { [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ" + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING" }; #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) @@ -428,9 +423,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) case TUNER_SET_TYPE_ADDR: case TUNER_SET_STANDBY: case TDA9887_SET_CONFIG: -#ifdef __OLD_VIDIOC_ case VIDIOC_OVERLAY_OLD: -#endif case VIDIOC_STREAMOFF: case VIDIOC_G_OUTPUT: case VIDIOC_S_OUTPUT: @@ -446,9 +439,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) case VIDIOC_G_AUDIO: case VIDIOC_S_AUDIO: case VIDIOC_ENUMAUDIO: -#ifdef __OLD_VIDIOC_ case VIDIOC_G_AUDIO_OLD: -#endif { struct v4l2_audio *p=arg; @@ -459,9 +450,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) case VIDIOC_G_AUDOUT: case VIDIOC_S_AUDOUT: case VIDIOC_ENUMAUDOUT: -#ifdef __OLD_VIDIOC_ case VIDIOC_G_AUDOUT_OLD: -#endif { struct v4l2_audioout *p=arg; printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s, @@ -489,9 +478,9 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) prt_names(p->memory,v4l2_memory_names), p->m.userptr); printk ("%s: timecode= %02d:%02d:%02d type=%d, " - "flags=0x%08x, frames=%d, userbits=0x%08x\n", + "flags=0x%08x, frames=%d, userbits=0x%p\n", s,tc->hours,tc->minutes,tc->seconds, - tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); + tc->type, tc->flags, tc->frames, tc->userbits); break; } case VIDIOC_QUERYCAP: @@ -506,31 +495,12 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) } case VIDIOC_G_CTRL: case VIDIOC_S_CTRL: -#ifdef __OLD_VIDIOC_ case VIDIOC_S_CTRL_OLD: -#endif { struct v4l2_control *p=arg; printk ("%s: id=%d, value=%d\n", s, p->id, p->value); break; } - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - int i; - - printk("%s: ctrl_class=%d, count=%d\n", s, p->ctrl_class, p->count); - for (i = 0; i < p->count; i++) { - struct v4l2_ext_control *c = &p->controls[i]; - if (cmd == VIDIOC_G_EXT_CTRLS) - printk("%s: id=%d\n", s, c->id); - else - printk("%s: id=%d, value=%d\n", s, c->id, c->value); - } - break; - } case VIDIOC_G_CROP: case VIDIOC_S_CROP: { @@ -540,9 +510,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) break; } case VIDIOC_CROPCAP: -#ifdef __OLD_VIDIOC_ case VIDIOC_CROPCAP_OLD: -#endif { struct v4l2_cropcap *p=arg; /*FIXME: Should also show rect structs */ @@ -699,12 +667,6 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); break; } - case VIDIOC_INT_S_CRYSTAL_FREQ: - { - struct v4l2_crystal_freq *p=arg; - printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags); - break; - } case VIDIOC_G_SLICED_VBI_CAP: { struct v4l2_sliced_vbi_cap *p=arg; @@ -734,9 +696,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) } case VIDIOC_G_PARM: case VIDIOC_S_PARM: -#ifdef __OLD_VIDIOC_ case VIDIOC_S_PARM_OLD: -#endif { struct v4l2_streamparm *p=arg; printk ("%s: type=%d\n", s, p->type); @@ -955,498 +915,6 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) /* ----------------------------------------------------------------- */ -/* Helper functions for control handling */ - -/* Check for correctness of the ctrl's value based on the data from - struct v4l2_queryctrl and the available menu items. Note that - menu_items may be NULL, in that case it is ignored. */ -int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, - const char **menu_items) -{ - if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) - return -EINVAL; - if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED) - return -EBUSY; - if (qctrl->type == V4L2_CTRL_TYPE_BUTTON || - qctrl->type == V4L2_CTRL_TYPE_INTEGER64 || - qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) - return 0; - if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum) - return -ERANGE; - if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) { - if (menu_items[ctrl->value] == NULL || - menu_items[ctrl->value][0] == '\0') - return -EINVAL; - } - return 0; -} - -/* Returns NULL or a character pointer array containing the menu for - the given control ID. The pointer array ends with a NULL pointer. - An empty string signifies a menu entry that is invalid. This allows - drivers to disable certain options if it is not supported. */ -const char **v4l2_ctrl_get_menu(u32 id) -{ - static const char *mpeg_audio_sampling_freq[] = { - "44.1 kHz", - "48 kHz", - "32 kHz", - NULL - }; - static const char *mpeg_audio_encoding[] = { - "Layer I", - "Layer II", - "Layer III", - NULL - }; - static const char *mpeg_audio_l1_bitrate[] = { - "32 kbps", - "64 kbps", - "96 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "288 kbps", - "320 kbps", - "352 kbps", - "384 kbps", - "416 kbps", - "448 kbps", - NULL - }; - static const char *mpeg_audio_l2_bitrate[] = { - "32 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - "384 kbps", - NULL - }; - static const char *mpeg_audio_l3_bitrate[] = { - "32 kbps", - "40 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - NULL - }; - static const char *mpeg_audio_mode[] = { - "Stereo", - "Joint Stereo", - "Dual", - "Mono", - NULL - }; - static const char *mpeg_audio_mode_extension[] = { - "Bound 4", - "Bound 8", - "Bound 12", - "Bound 16", - NULL - }; - static const char *mpeg_audio_emphasis[] = { - "No Emphasis", - "50/15 us", - "CCITT J17", - NULL - }; - static const char *mpeg_audio_crc[] = { - "No CRC", - "16-bit CRC", - NULL - }; - static const char *mpeg_video_encoding[] = { - "MPEG-1", - "MPEG-2", - NULL - }; - static const char *mpeg_video_aspect[] = { - "1x1", - "4x3", - "16x9", - "2.21x1", - NULL - }; - static const char *mpeg_video_bitrate_mode[] = { - "Variable Bitrate", - "Constant Bitrate", - NULL - }; - static const char *mpeg_stream_type[] = { - "MPEG-2 Program Stream", - "MPEG-2 Transport Stream", - "MPEG-1 System Stream", - "MPEG-2 DVD-compatible Stream", - "MPEG-1 VCD-compatible Stream", - "MPEG-2 SVCD-compatible Stream", - NULL - }; - static const char *mpeg_stream_vbi_fmt[] = { - "No VBI", - "Private packet, IVTV format", - NULL - }; - - switch (id) { - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - return mpeg_audio_sampling_freq; - case V4L2_CID_MPEG_AUDIO_ENCODING: - return mpeg_audio_encoding; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - return mpeg_audio_l1_bitrate; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - return mpeg_audio_l2_bitrate; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - return mpeg_audio_l3_bitrate; - case V4L2_CID_MPEG_AUDIO_MODE: - return mpeg_audio_mode; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - return mpeg_audio_mode_extension; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - return mpeg_audio_emphasis; - case V4L2_CID_MPEG_AUDIO_CRC: - return mpeg_audio_crc; - case V4L2_CID_MPEG_VIDEO_ENCODING: - return mpeg_video_encoding; - case V4L2_CID_MPEG_VIDEO_ASPECT: - return mpeg_video_aspect; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return mpeg_video_bitrate_mode; - case V4L2_CID_MPEG_STREAM_TYPE: - return mpeg_stream_type; - case V4L2_CID_MPEG_STREAM_VBI_FMT: - return mpeg_stream_vbi_fmt; - default: - return NULL; - } -} - -/* Fill in a struct v4l2_queryctrl */ -int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) -{ - const char *name; - - qctrl->flags = 0; - switch (qctrl->id) { - /* USER controls */ - case V4L2_CID_USER_CLASS: name = "User Controls"; break; - case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break; - case V4L2_CID_AUDIO_MUTE: name = "Mute"; break; - case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break; - case V4L2_CID_AUDIO_BASS: name = "Bass"; break; - case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break; - case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break; - case V4L2_CID_BRIGHTNESS: name = "Brightness"; break; - case V4L2_CID_CONTRAST: name = "Contrast"; break; - case V4L2_CID_SATURATION: name = "Saturation"; break; - case V4L2_CID_HUE: name = "Hue"; break; - - /* MPEG controls */ - case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break; - case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break; - case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break; - case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break; - case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break; - case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break; - case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break; - case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break; - case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break; - case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break; - case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break; - case V4L2_CID_MPEG_STREAM_VBI_FMT: name = "Stream VBI Format"; break; - - default: - return -EINVAL; - } - switch (qctrl->id) { - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_LOUDNESS: - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - case V4L2_CID_MPEG_VIDEO_PULLDOWN: - qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; - min = 0; - max = step = 1; - break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - case V4L2_CID_MPEG_AUDIO_ENCODING: - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - case V4L2_CID_MPEG_AUDIO_MODE: - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - case V4L2_CID_MPEG_AUDIO_CRC: - case V4L2_CID_MPEG_VIDEO_ENCODING: - case V4L2_CID_MPEG_VIDEO_ASPECT: - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - case V4L2_CID_MPEG_STREAM_TYPE: - case V4L2_CID_MPEG_STREAM_VBI_FMT: - qctrl->type = V4L2_CTRL_TYPE_MENU; - step = 1; - break; - case V4L2_CID_USER_CLASS: - case V4L2_CID_MPEG_CLASS: - qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS; - qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - min = max = step = def = 0; - break; - default: - qctrl->type = V4L2_CTRL_TYPE_INTEGER; - break; - } - switch (qctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - case V4L2_CID_MPEG_AUDIO_MODE: - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - case V4L2_CID_MPEG_STREAM_TYPE: - qctrl->flags |= V4L2_CTRL_FLAG_UPDATE; - break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; - break; - } - qctrl->minimum = min; - qctrl->maximum = max; - qctrl->step = step; - qctrl->default_value = def; - qctrl->reserved[0] = qctrl->reserved[1] = 0; - snprintf(qctrl->name, sizeof(qctrl->name), name); - return 0; -} - -/* Fill in a struct v4l2_queryctrl with standard values based on - the control ID. */ -int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) -{ - switch (qctrl->id) { - /* USER controls */ - case V4L2_CID_USER_CLASS: - case V4L2_CID_MPEG_CLASS: - return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880); - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_LOUDNESS: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768); - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0); - - /* MPEG controls */ - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); - case V4L2_CID_MPEG_AUDIO_ENCODING: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_ENCODING_LAYER_1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2); - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_L1_BITRATE_32K, - V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1, - V4L2_MPEG_AUDIO_L1_BITRATE_256K); - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_L2_BITRATE_32K, - V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, - V4L2_MPEG_AUDIO_L2_BITRATE_224K); - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_L3_BITRATE_32K, - V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, - V4L2_MPEG_AUDIO_L3_BITRATE_192K); - case V4L2_CID_MPEG_AUDIO_MODE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_MODE_STEREO, - V4L2_MPEG_AUDIO_MODE_MONO, 1, - V4L2_MPEG_AUDIO_MODE_STEREO); - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4); - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_EMPHASIS_NONE, - V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1, - V4L2_MPEG_AUDIO_EMPHASIS_NONE); - case V4L2_CID_MPEG_AUDIO_CRC: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_CRC_NONE, - V4L2_MPEG_AUDIO_CRC_CRC16, 1, - V4L2_MPEG_AUDIO_CRC_NONE); - case V4L2_CID_MPEG_VIDEO_ENCODING: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, 1, - V4L2_MPEG_VIDEO_ASPECT_4x3); - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12); - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1); - case V4L2_CID_MPEG_VIDEO_PULLDOWN: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: - return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - case V4L2_CID_MPEG_STREAM_PID_PMT: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16); - case V4L2_CID_MPEG_STREAM_PID_AUDIO: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260); - case V4L2_CID_MPEG_STREAM_PID_VIDEO: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256); - case V4L2_CID_MPEG_STREAM_PID_PCR: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259); - case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: - return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); - case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: - return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); - case V4L2_CID_MPEG_STREAM_VBI_FMT: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_VBI_FMT_NONE, - V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1, - V4L2_MPEG_STREAM_VBI_FMT_NONE); - default: - return -EINVAL; - } -} - -/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and - the menu. The qctrl pointer may be NULL, in which case it is ignored. */ -int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, - const char **menu_items) -{ - int i; - - if (menu_items == NULL || - (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) - return -EINVAL; - for (i = 0; i < qmenu->index && menu_items[i]; i++) ; - if (menu_items[i] == NULL || menu_items[i][0] == '\0') - return -EINVAL; - snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]); - qmenu->reserved = 0; - return 0; -} - -/* ctrl_classes points to an array of u32 pointers, the last element is - a NULL pointer. Each u32 array is a 0-terminated array of control IDs. - Each array must be sorted low to high and belong to the same control - class. The array of u32 pointer must also be sorted, from low class IDs - to high class IDs. - - This function returns the first ID that follows after the given ID. - When no more controls are available 0 is returned. */ -u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) -{ - u32 ctrl_class; - const u32 *pctrl; - - /* if no query is desired, then just return the control ID */ - if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) - return id; - if (ctrl_classes == NULL) - return 0; - id &= V4L2_CTRL_ID_MASK; - ctrl_class = V4L2_CTRL_ID2CLASS(id); - id++; /* select next control */ - /* find first class that matches (or is greater than) the class of - the ID */ - while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class) - ctrl_classes++; - /* no more classes */ - if (*ctrl_classes == NULL) - return 0; - pctrl = *ctrl_classes; - /* find first ctrl within the class that is >= ID */ - while (*pctrl && *pctrl < id) pctrl++; - if (*pctrl) - return *pctrl; - /* we are at the end of the controls of the current class. */ - /* continue with next class if available */ - ctrl_classes++; - if (*ctrl_classes == NULL) - return 0; - return **ctrl_classes; -} - -/* ----------------------------------------------------------------- */ - EXPORT_SYMBOL(v4l2_video_std_construct); EXPORT_SYMBOL(v4l2_prio_init); @@ -1461,13 +929,6 @@ EXPORT_SYMBOL(v4l2_type_names); EXPORT_SYMBOL(v4l_printk_ioctl); EXPORT_SYMBOL(v4l_printk_ioctl_arg); -EXPORT_SYMBOL(v4l2_ctrl_next); -EXPORT_SYMBOL(v4l2_ctrl_check); -EXPORT_SYMBOL(v4l2_ctrl_get_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_fill); -EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); - /* * Local variables: * c-basic-offset: 8 diff --git a/trunk/drivers/media/video/video-buf-dvb.c b/trunk/drivers/media/video/video-buf-dvb.c index 7ee8a53cd336..caf3e7e2f219 100644 --- a/trunk/drivers/media/video/video-buf-dvb.c +++ b/trunk/drivers/media/video/video-buf-dvb.c @@ -135,15 +135,14 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) int videobuf_dvb_register(struct videobuf_dvb *dvb, struct module *module, - void *adapter_priv, - struct device *device) + void *adapter_priv) { int result; mutex_init(&dvb->lock); /* register adapter */ - result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device); + result = dvb_register_adapter(&dvb->adapter, dvb->name, module); if (result < 0) { printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", dvb->name, result); diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 2dfa7f23d0ca..5f87dd5f1d0b 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -1,31 +1,20 @@ /* - * Video capture interface for Linux version 2 + * Video capture interface for Linux * - * A generic video device interface for the LINUX operating system - * using a set of device structures/vectors for low level operations. + * A generic video device interface for the LINUX operating system + * using a set of device structures/vectors for low level operations. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. * - * Authors: Alan Cox, (version 1) - * Mauro Carvalho Chehab (version 2) + * Author: Alan Cox, * * Fixes: 20000516 Claudio Matsuoka * - Added procfs support */ -#define dbgarg(cmd, fmt, arg...) \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk (KERN_DEBUG "%s: ", vfd->name); \ - v4l_printk_ioctl(cmd); \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); - -#define dbgarg2(fmt, arg...) \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); - #include #include #include @@ -41,13 +30,7 @@ #include #include -#define __OLD_VIDIOC_ /* To allow fixing old calls*/ -#include - -#ifdef CONFIG_VIDEO_V4L1 #include -#endif -#include #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" @@ -58,8 +41,7 @@ static ssize_t show_name(struct class_device *cd, char *buf) { - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); + struct video_device *vfd = container_of(cd, struct video_device, class_dev); return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); } @@ -80,8 +62,7 @@ void video_device_release(struct video_device *vfd) static void video_release(struct class_device *cd) { - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); + struct video_device *vfd = container_of(cd, struct video_device, class_dev); #if 1 /* needed until all drivers are fixed */ @@ -109,7 +90,7 @@ struct video_device* video_devdata(struct file *file) } /* - * Open a video device - FIXME: Obsoleted + * Open a video device. */ static int video_open(struct inode *inode, struct file *file) { @@ -149,7 +130,6 @@ static int video_open(struct inode *inode, struct file *file) * helper function -- handles userspace copying for ioctl arguments */ -#ifdef __OLD_VIDIOC_ static unsigned int video_fix_command(unsigned int cmd) { @@ -175,11 +155,7 @@ video_fix_command(unsigned int cmd) } return cmd; } -#endif -/* - * Obsolete usercopy function - Should be removed soon - */ int video_usercopy(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, @@ -190,15 +166,8 @@ video_usercopy(struct inode *inode, struct file *file, void *mbuf = NULL; void *parg = NULL; int err = -EINVAL; - int is_ext_ctrl; - size_t ctrls_size = 0; - void __user *user_ptr = NULL; -#ifdef __OLD_VIDIOC_ cmd = video_fix_command(cmd); -#endif - is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || - cmd == VIDIOC_TRY_EXT_CTRLS); /* Copy arguments into temp kernel buffer */ switch (_IOC_DIR(cmd)) { @@ -224,43 +193,14 @@ video_usercopy(struct inode *inode, struct file *file, goto out; break; } - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - /* In case of an error, tell the caller that it wasn't - a specific control that caused it. */ - p->error_idx = p->count; - user_ptr = (void __user *)p->controls; - if (p->count) { - ctrls_size = sizeof(struct v4l2_ext_control) * p->count; - /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ - mbuf = kmalloc(ctrls_size, GFP_KERNEL); - err = -ENOMEM; - if (NULL == mbuf) - goto out_ext_ctrl; - err = -EFAULT; - if (copy_from_user(mbuf, user_ptr, ctrls_size)) - goto out_ext_ctrl; - p->controls = mbuf; - } - } /* call driver */ err = func(inode, file, cmd, parg); if (err == -ENOIOCTLCMD) err = -EINVAL; - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - p->controls = (void *)user_ptr; - if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) - err = -EFAULT; - goto out_ext_ctrl; - } if (err < 0) goto out; -out_ext_ctrl: /* Copy results into user buffer */ switch (_IOC_DIR(cmd)) { @@ -278,7 +218,6 @@ video_usercopy(struct inode *inode, struct file *file, /* * open/release helper functions -- handle exclusive opens - * Should be removed soon */ int video_exclusive_open(struct inode *inode, struct file *file) { @@ -303,1184 +242,6 @@ int video_exclusive_release(struct inode *inode, struct file *file) return 0; } -static char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; - - -/* FIXME: Those stuff are replicated also on v4l2-common.c */ -static char *v4l2_type_names_FIXME[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture", - [V4L2_BUF_TYPE_PRIVATE] = "private", -}; - -static char *v4l2_field_names_FIXME[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", -}; - -#define prt_names(a,arr) (((a)>=0)&&((a)timecode; - - dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " - "bytesused=%d, flags=0x%08d, " - "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", - (p->timestamp.tv_sec/3600), - (int)(p->timestamp.tv_sec/60)%60, - (int)(p->timestamp.tv_sec%60), - p->timestamp.tv_usec, - p->index, - prt_names(p->type,v4l2_type_names_FIXME), - p->bytesused,p->flags, - p->field,p->sequence, - prt_names(p->memory,v4l2_memory_names), - p->m.userptr); - dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " - "flags=0x%08d, frames=%d, userbits=0x%08x\n", - tc->hours,tc->minutes,tc->seconds, - tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); -} - -static inline void dbgrect(struct video_device *vfd, char *s, - struct v4l2_rect *r) -{ - dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top, - r->width, r->height); -}; - -static inline void v4l_print_pix_fmt (struct video_device *vfd, - struct v4l2_pix_format *fmt) -{ - dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, " - "bytesperline=%d sizeimage=%d, colorspace=%d\n", - fmt->width,fmt->height,fmt->pixelformat, - prt_names(fmt->field,v4l2_field_names_FIXME), - fmt->bytesperline,fmt->sizeimage,fmt->colorspace); -}; - - -static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_cap) - return (0); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_overlay) - return (0); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi) - return (0); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - return (0); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_capture) - return (0); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_video_output) - return (0); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - return (0); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - return (0); - break; - } - return (-EINVAL); -} - -static int __video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vfd = video_devdata(file); - void *fh = file->private_data; - int ret = -EINVAL; - - if ( (vfd->debug & V4L2_DEBUG_IOCTL) && - !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) { - v4l_print_ioctl(vfd->name, cmd); - } - - switch(cmd) { - /* --- capabilities ------------------------------------------ */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = (struct v4l2_capability*)arg; - memset(cap, 0, sizeof(*cap)); - - if (!vfd->vidioc_querycap) - break; - - ret=vfd->vidioc_querycap(file, fh, cap); - if (!ret) - dbgarg (cmd, "driver=%s, card=%s, bus=%s, " - "version=0x%08x, " - "capabilities=0x%08x\n", - cap->driver,cap->card,cap->bus_info, - cap->version, - cap->capabilities); - break; - } - - /* --- priority ------------------------------------------ */ - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p=arg; - - if (!vfd->vidioc_g_priority) - break; - ret=vfd->vidioc_g_priority(file, fh, p); - if (!ret) - dbgarg(cmd, "priority is %d\n", *p); - break; - } - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *p=arg; - - if (!vfd->vidioc_s_priority) - break; - dbgarg(cmd, "setting priority to %d\n", *p); - ret=vfd->vidioc_s_priority(file, fh, *p); - break; - } - - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - enum v4l2_buf_type type; - unsigned int index; - - index = f->index; - type = f->type; - memset(f,0,sizeof(*f)); - f->index = index; - f->type = type; - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_enum_fmt_cap) - ret=vfd->vidioc_enum_fmt_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_enum_fmt_overlay) - ret=vfd->vidioc_enum_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi) - ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_enum_fmt_vbi_output) - ret=vfd->vidioc_enum_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi_capture) - ret=vfd->vidioc_enum_fmt_vbi_capture(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_enum_fmt_video_output) - ret=vfd->vidioc_enum_fmt_video_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_enum_fmt_vbi_output) - ret=vfd->vidioc_enum_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_enum_fmt_type_private) - ret=vfd->vidioc_enum_fmt_type_private(file, - fh, f); - break; - } - if (!ret) - dbgarg (cmd, "index=%d, type=%d, flags=%d, " - "description=%s," - " pixelformat=0x%8x\n", - f->index, f->type, f->flags, - f->description, - f->pixelformat); - - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - enum v4l2_buf_type type=f->type; - - memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); - f->type=type; - - /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(type, - v4l2_type_names_FIXME)); - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_g_fmt_cap) - ret=vfd->vidioc_g_fmt_cap(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd,&f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_g_fmt_overlay) - ret=vfd->vidioc_g_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi) - ret=vfd->vidioc_g_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_output) - ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi_capture) - ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_g_fmt_video_output) - ret=vfd->vidioc_g_fmt_video_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_output) - ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_g_fmt_type_private) - ret=vfd->vidioc_g_fmt_type_private(file, - fh, f); - break; - } - - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - v4l_print_pix_fmt(vfd,&f->fmt.pix); - if (vfd->vidioc_s_fmt_cap) - ret=vfd->vidioc_s_fmt_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_s_fmt_overlay) - ret=vfd->vidioc_s_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi) - ret=vfd->vidioc_s_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_output) - ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi_capture) - ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_s_fmt_video_output) - ret=vfd->vidioc_s_fmt_video_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_output) - ret=vfd->vidioc_s_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_s_fmt_type_private) - ret=vfd->vidioc_s_fmt_type_private(file, - fh, f); - break; - } - break; - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_cap) - ret=vfd->vidioc_try_fmt_cap(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd,&f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_overlay) - ret=vfd->vidioc_try_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi) - ret=vfd->vidioc_try_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - ret=vfd->vidioc_try_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_capture) - ret=vfd->vidioc_try_fmt_vbi_capture(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_video_output) - ret=vfd->vidioc_try_fmt_video_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - ret=vfd->vidioc_try_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - ret=vfd->vidioc_try_fmt_type_private(file, - fh, f); - break; - } - - break; - } - /* FIXME: Those buf reqs could be handled here, - with some changes on videobuf to allow its header to be included at - videodev2.h or being merged at videodev2. - */ - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *p=arg; - - if (!vfd->vidioc_reqbufs) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_reqbufs(file, fh, p); - dbgarg (cmd, "count=%d, type=%s, memory=%s\n", - p->count, - prt_names(p->type,v4l2_type_names_FIXME), - prt_names(p->memory,v4l2_memory_names)); - break; - } - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *p=arg; - - if (!vfd->vidioc_querybuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_querybuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_QBUF: - { - struct v4l2_buffer *p=arg; - - if (!vfd->vidioc_qbuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_qbuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_DQBUF: - { - struct v4l2_buffer *p=arg; - if (!vfd->vidioc_qbuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_qbuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_OVERLAY: - { - int *i = arg; - - if (!vfd->vidioc_overlay) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_overlay(file, fh, *i); - break; - } -#ifdef HAVE_V4L1 - /* --- streaming capture ------------------------------------- */ - case VIDIOCGMBUF: - { - struct video_mbuf *p=arg; - - memset(p,0,sizeof(p)); - - if (!vfd->vidiocgmbuf) - break; - ret=vfd->vidiocgmbuf(file, fh, p); - if (!ret) - dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", - p->size, p->frames, - (unsigned long)p->offsets); - break; - } -#endif - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *p=arg; - if (!vfd->vidioc_g_fbuf) - break; - ret=vfd->vidioc_g_fbuf(file, fh, arg); - if (!ret) { - dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", - p->capability,p->flags, - (unsigned long)p->base); - v4l_print_pix_fmt (vfd, &p->fmt); - } - break; - } - case VIDIOC_S_FBUF: - { - struct v4l2_framebuffer *p=arg; - if (!vfd->vidioc_s_fbuf) - break; - - dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", - p->capability,p->flags,(unsigned long)p->base); - v4l_print_pix_fmt (vfd, &p->fmt); - ret=vfd->vidioc_s_fbuf(file, fh, arg); - - break; - } - case VIDIOC_STREAMON: - { - enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamon) - break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); - ret=vfd->vidioc_streamon(file, fh,i); - break; - } - case VIDIOC_STREAMOFF: - { - enum v4l2_buf_type i = *(int *)arg; - - if (!vfd->vidioc_streamoff) - break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); - ret=vfd->vidioc_streamoff(file, fh, i); - break; - } - /* ---------- tv norms ---------- */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *p = arg; - unsigned int index = p->index; - - if (!vfd->tvnormsize) { - printk (KERN_WARNING "%s: no TV norms defined!\n", - vfd->name); - break; - } - - if (index<=0 || index >= vfd->tvnormsize) { - ret=-EINVAL; - break; - } - v4l2_video_std_construct(p, vfd->tvnorms[p->index].id, - vfd->tvnorms[p->index].name); - p->index = index; - - dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " - "framelines=%d\n", p->index, - (unsigned long long)p->id, p->name, - p->frameperiod.numerator, - p->frameperiod.denominator, - p->framelines); - - ret=0; - break; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; - - *id = vfd->current_norm; - - dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); - - ret=0; - break; - } - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - unsigned int i; - - if (!vfd->tvnormsize) { - printk (KERN_WARNING "%s: no TV norms defined!\n", - vfd->name); - break; - } - - dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); - - /* First search for exact match */ - for (i = 0; i < vfd->tvnormsize; i++) - if (*id == vfd->tvnorms[i].id) - break; - /* Then for a generic video std that contains desired std */ - if (i == vfd->tvnormsize) - for (i = 0; i < vfd->tvnormsize; i++) - if (*id & vfd->tvnorms[i].id) - break; - if (i == vfd->tvnormsize) { - break; - } - - /* Calls the specific handler */ - if (vfd->vidioc_s_std) - ret=vfd->vidioc_s_std(file, fh, i); - else - ret=-EINVAL; - - /* Updates standard information */ - if (!ret) - vfd->current_norm=*id; - - break; - } - case VIDIOC_QUERYSTD: - { - v4l2_std_id *p=arg; - - if (!vfd->vidioc_querystd) - break; - ret=vfd->vidioc_querystd(file, fh, arg); - if (!ret) - dbgarg (cmd, "detected std=%Lu\n", - (unsigned long long)*p); - break; - } - /* ------ input switching ---------- */ - /* FIXME: Inputs can be handled inside videodev2 */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *p=arg; - int i=p->index; - - if (!vfd->vidioc_enum_input) - break; - memset(p, 0, sizeof(*p)); - p->index=i; - - ret=vfd->vidioc_enum_input(file, fh, p); - if (!ret) - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "audioset=%d, " - "tuner=%d, std=%Ld, status=%d\n", - p->index,p->name,p->type,p->audioset, - p->tuner, - (unsigned long long)p->std, - p->status); - break; - } - case VIDIOC_G_INPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_g_input) - break; - ret=vfd->vidioc_g_input(file, fh, i); - if (!ret) - dbgarg (cmd, "value=%d\n",*i); - break; - } - case VIDIOC_S_INPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_s_input) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_s_input(file, fh, *i); - break; - } - - /* ------ output switching ---------- */ - case VIDIOC_G_OUTPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_g_output) - break; - ret=vfd->vidioc_g_output(file, fh, i); - if (!ret) - dbgarg (cmd, "value=%d\n",*i); - break; - } - case VIDIOC_S_OUTPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_s_output) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_s_output(file, fh, *i); - break; - } - - /* --- controls ---------------------------------------------- */ - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *p=arg; - - if (!vfd->vidioc_queryctrl) - break; - ret=vfd->vidioc_queryctrl(file, fh, p); - - if (!ret) - dbgarg (cmd, "id=%d, type=%d, name=%s, " - "min/max=%d/%d," - " step=%d, default=%d, flags=0x%08x\n", - p->id,p->type,p->name,p->minimum, - p->maximum,p->step,p->default_value, - p->flags); - break; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *p = arg; - - if (!vfd->vidioc_g_ctrl) - break; - dbgarg(cmd, "Enum for index=%d\n", p->id); - - ret=vfd->vidioc_g_ctrl(file, fh, p); - if (!ret) - dbgarg2 ( "id=%d, value=%d\n", p->id, p->value); - break; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *p = arg; - - if (!vfd->vidioc_s_ctrl) - break; - dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value); - - ret=vfd->vidioc_s_ctrl(file, fh, p); - break; - } - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - if (vfd->vidioc_g_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); - - ret=vfd->vidioc_g_ext_ctrls(file, fh, p); - } - break; - } - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - if (vfd->vidioc_s_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); - - ret=vfd->vidioc_s_ext_ctrls(file, fh, p); - } - break; - } - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - if (vfd->vidioc_try_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); - - ret=vfd->vidioc_try_ext_ctrls(file, fh, p); - } - break; - } - case VIDIOC_QUERYMENU: - { - struct v4l2_querymenu *p=arg; - if (!vfd->vidioc_querymenu) - break; - ret=vfd->vidioc_querymenu(file, fh, p); - if (!ret) - dbgarg (cmd, "id=%d, index=%d, name=%s\n", - p->id,p->index,p->name); - break; - } - /* --- audio ---------------------------------------------- */ - case VIDIOC_ENUMAUDIO: - { - struct v4l2_audio *p=arg; - - if (!vfd->vidioc_enumaudio) - break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_enumaudio(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n",p->index,p->name, - p->capability, p->mode); - break; - } - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *p=arg; - - if (!vfd->vidioc_g_audio) - break; - dbgarg(cmd, "Get for index=%d\n", p->index); - ret=vfd->vidioc_g_audio(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n",p->index, - p->name,p->capability, p->mode); - break; - } - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *p=arg; - - if (!vfd->vidioc_s_audio) - break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability, p->mode); - ret=vfd->vidioc_s_audio(file, fh, p); - break; - } - case VIDIOC_ENUMAUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_enumaudout) - break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_enumaudout(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - break; - } - case VIDIOC_G_AUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_g_audout) - break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_g_audout(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - break; - } - case VIDIOC_S_AUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_s_audout) - break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - - ret=vfd->vidioc_s_audout(file, fh, p); - break; - } - case VIDIOC_G_MODULATOR: - { - struct v4l2_modulator *p=arg; - if (!vfd->vidioc_g_modulator) - break; - ret=vfd->vidioc_g_modulator(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, " - "capability=%d, rangelow=%d," - " rangehigh=%d, txsubchans=%d\n", - p->index, p->name,p->capability, - p->rangelow, p->rangehigh, - p->txsubchans); - break; - } - case VIDIOC_S_MODULATOR: - { - struct v4l2_modulator *p=arg; - if (!vfd->vidioc_s_modulator) - break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "rangelow=%d, rangehigh=%d, txsubchans=%d\n", - p->index, p->name,p->capability,p->rangelow, - p->rangehigh,p->txsubchans); - ret=vfd->vidioc_s_modulator(file, fh, p); - break; - } - case VIDIOC_G_CROP: - { - struct v4l2_crop *p=arg; - if (!vfd->vidioc_g_crop) - break; - ret=vfd->vidioc_g_crop(file, fh, p); - if (!ret) { - dbgarg(cmd, "type=%d\n", p->type); - dbgrect(vfd, "", &p->c); - } - break; - } - case VIDIOC_S_CROP: - { - struct v4l2_crop *p=arg; - if (!vfd->vidioc_s_crop) - break; - dbgarg(cmd, "type=%d\n", p->type); - dbgrect(vfd, "", &p->c); - ret=vfd->vidioc_s_crop(file, fh, p); - break; - } - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *p=arg; - /*FIXME: Should also show v4l2_fract pixelaspect */ - if (!vfd->vidioc_cropcap) - break; - dbgarg(cmd, "type=%d\n", p->type); - dbgrect(vfd, "bounds ", &p->bounds); - dbgrect(vfd, "defrect ", &p->defrect); - ret=vfd->vidioc_cropcap(file, fh, p); - break; - } - case VIDIOC_G_MPEGCOMP: - { - struct v4l2_mpeg_compression *p=arg; - - /*FIXME: Several fields not shown */ - if (!vfd->vidioc_g_mpegcomp) - break; - ret=vfd->vidioc_g_mpegcomp(file, fh, p); - if (!ret) - dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d," - " ts_pid_video=%d, ts_pid_pcr=%d, " - "ps_size=%d, au_sample_rate=%d, " - "au_pesid=%c, vi_frame_rate=%d, " - "vi_frames_per_gop=%d, " - "vi_bframes_count=%d, vi_pesid=%c\n", - p->ts_pid_pmt,p->ts_pid_audio, - p->ts_pid_video,p->ts_pid_pcr, - p->ps_size, p->au_sample_rate, - p->au_pesid, p->vi_frame_rate, - p->vi_frames_per_gop, - p->vi_bframes_count, p->vi_pesid); - break; - } - case VIDIOC_S_MPEGCOMP: - { - struct v4l2_mpeg_compression *p=arg; - /*FIXME: Several fields not shown */ - if (!vfd->vidioc_s_mpegcomp) - break; - dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, " - "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, " - "au_sample_rate=%d, au_pesid=%c, " - "vi_frame_rate=%d, vi_frames_per_gop=%d, " - "vi_bframes_count=%d, vi_pesid=%c\n", - p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video, - p->ts_pid_pcr, p->ps_size, p->au_sample_rate, - p->au_pesid, p->vi_frame_rate, - p->vi_frames_per_gop, p->vi_bframes_count, - p->vi_pesid); - ret=vfd->vidioc_s_mpegcomp(file, fh, p); - break; - } - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *p=arg; - if (!vfd->vidioc_g_jpegcomp) - break; - ret=vfd->vidioc_g_jpegcomp(file, fh, p); - if (!ret) - dbgarg (cmd, "quality=%d, APPn=%d, " - "APP_len=%d, COM_len=%d, " - "jpeg_markers=%d\n", - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - break; - } - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *p=arg; - if (!vfd->vidioc_g_jpegcomp) - break; - dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, " - "COM_len=%d, jpeg_markers=%d\n", - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - ret=vfd->vidioc_s_jpegcomp(file, fh, p); - break; - } - case VIDIOC_G_PARM: - { - struct v4l2_streamparm *p=arg; - if (!vfd->vidioc_g_parm) - break; - ret=vfd->vidioc_g_parm(file, fh, p); - dbgarg (cmd, "type=%d\n", p->type); - break; - } - case VIDIOC_S_PARM: - { - struct v4l2_streamparm *p=arg; - if (!vfd->vidioc_s_parm) - break; - dbgarg (cmd, "type=%d\n", p->type); - ret=vfd->vidioc_s_parm(file, fh, p); - break; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *p=arg; - if (!vfd->vidioc_g_tuner) - break; - ret=vfd->vidioc_g_tuner(file, fh, p); - if (!ret) - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "capability=%d, rangelow=%d, " - "rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=%d, audmode=%d\n", - p->index, p->name, p->type, - p->capability, p->rangelow, - p->rangehigh, p->rxsubchans, - p->audmode, p->signal, p->afc); - break; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *p=arg; - if (!vfd->vidioc_s_tuner) - break; - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "capability=%d, rangelow=%d, rangehigh=%d, " - "signal=%d, afc=%d, rxsubchans=%d, " - "audmode=%d\n",p->index, p->name, p->type, - p->capability, p->rangelow,p->rangehigh, - p->rxsubchans, p->audmode, p->signal, - p->afc); - ret=vfd->vidioc_s_tuner(file, fh, p); - break; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *p=arg; - if (!vfd->vidioc_g_frequency) - break; - ret=vfd->vidioc_g_frequency(file, fh, p); - if (!ret) - dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", - p->tuner,p->type,p->frequency); - break; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *p=arg; - if (!vfd->vidioc_s_frequency) - break; - dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", - p->tuner,p->type,p->frequency); - ret=vfd->vidioc_s_frequency(file, fh, p); - break; - } - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *p=arg; - if (!vfd->vidioc_g_sliced_vbi_cap) - break; - ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p); - if (!ret) - dbgarg (cmd, "service_set=%d\n", p->service_set); - break; - } - case VIDIOC_LOG_STATUS: - { - if (!vfd->vidioc_log_status) - break; - ret=vfd->vidioc_log_status(file, fh); - break; - } - - /* --- Others --------------------------------------------- */ - - default: - ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,__video_do_ioctl); - } - - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { - if (ret<0) { - printk ("%s: err:\n", vfd->name); - v4l_print_ioctl(vfd->name, cmd); - } - } - - return ret; -} - -int video_ioctl2 (struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - int is_ext_ctrl; - size_t ctrls_size = 0; - void __user *user_ptr = NULL; - -#ifdef __OLD_VIDIOC_ - cmd = video_fix_command(cmd); -#endif - is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || - cmd == VIDIOC_TRY_EXT_CTRLS); - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - parg = NULL; - break; - case _IOC_READ: - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (_IOC_DIR(cmd) & _IOC_WRITE) - if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) - goto out; - break; - } - - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - /* In case of an error, tell the caller that it wasn't - a specific control that caused it. */ - p->error_idx = p->count; - user_ptr = (void __user *)p->controls; - if (p->count) { - ctrls_size = sizeof(struct v4l2_ext_control) * p->count; - /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ - mbuf = kmalloc(ctrls_size, GFP_KERNEL); - err = -ENOMEM; - if (NULL == mbuf) - goto out_ext_ctrl; - err = -EFAULT; - if (copy_from_user(mbuf, user_ptr, ctrls_size)) - goto out_ext_ctrl; - p->controls = mbuf; - } - } - - /* Handles IOCTL */ - err = __video_do_ioctl(inode, file, cmd, parg); - if (err == -ENOIOCTLCMD) - err = -EINVAL; - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - p->controls = (void *)user_ptr; - if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) - err = -EFAULT; - goto out_ext_ctrl; - } - if (err < 0) - goto out; - -out_ext_ctrl: - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - kfree(mbuf); - return err; -} - - static struct file_operations video_fops; /** @@ -1610,9 +371,7 @@ void video_unregister_device(struct video_device *vfd) mutex_unlock(&videodev_lock); } -/* - * Video fs operations - */ + static struct file_operations video_fops= { .owner = THIS_MODULE, @@ -1628,7 +387,7 @@ static int __init videodev_init(void) { int ret; - printk(KERN_INFO "Linux video capture interface: v2.00\n"); + printk(KERN_INFO "Linux video capture interface: v1.00\n"); if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); return -EIO; @@ -1659,12 +418,11 @@ EXPORT_SYMBOL(video_devdata); EXPORT_SYMBOL(video_usercopy); EXPORT_SYMBOL(video_exclusive_open); EXPORT_SYMBOL(video_exclusive_release); -EXPORT_SYMBOL(video_ioctl2); EXPORT_SYMBOL(video_device_alloc); EXPORT_SYMBOL(video_device_release); -MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); -MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); +MODULE_AUTHOR("Alan Cox"); +MODULE_DESCRIPTION("Device registrar for Video4Linux drivers"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index 268e69fdefc6..a8c101494cf5 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 41d23c8acbd8..779db26771c0 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -48,15 +48,34 @@ #include "font.h" +#ifndef kzalloc +#define kzalloc(size, flags) \ +({ \ + void *__ret = kmalloc(size, flags); \ + if (__ret) \ + memset(__ret, 0, size); \ + __ret; \ +}) +#endif + +MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); +MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); +MODULE_LICENSE("Dual BSD/GPL"); + #define VIVI_MAJOR_VERSION 0 #define VIVI_MINOR_VERSION 4 #define VIVI_RELEASE 0 #define VIVI_VERSION KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) -/* Declare static vars that will be used as parameters */ -static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ -static struct video_device vivi; /* Video device */ -static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ +static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ +module_param(video_nr, int, 0); + +static int debug = 0; +module_param(debug, int, 0); + +static unsigned int vid_limit = 16; +module_param(vid_limit,int,0644); +MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); /* supported controls */ static struct v4l2_queryctrl vivi_qctrl[] = { @@ -110,10 +129,10 @@ static struct v4l2_queryctrl vivi_qctrl[] = { static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; -#define dprintk(level,fmt, arg...) \ - do { \ - if (vivi.debug >= (level)) \ - printk(KERN_DEBUG "vivi: " fmt , ## arg); \ +#define dprintk(level,fmt, arg...) \ + do { \ + if (debug >= (level)) \ + printk(KERN_DEBUG "vivi: " fmt , ## arg); \ } while (0) /* ------------------------------------------------------------------ @@ -171,7 +190,7 @@ struct vivi_dev { /* various device info */ unsigned int resources; - struct video_device vfd; + struct video_device video_dev; struct vivi_dmaqueue vidq; @@ -229,8 +248,7 @@ static u8 bars[8][3] = { #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 #define TSTAMP_MIN_X 64 -static void prep_to_addr(struct sg_to_addr to_addr[], - struct videobuf_buffer *vb) +void prep_to_addr(struct sg_to_addr to_addr[],struct videobuf_buffer *vb) { int i, pos=0; @@ -241,7 +259,7 @@ static void prep_to_addr(struct sg_to_addr to_addr[], } } -static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) +inline int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) { int p1=0,p2=pages-1,p3=pages/2; @@ -262,8 +280,8 @@ static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) return (p1); } -static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, - int hmax, int line, char *timestr) +void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, + int hmax, int line, char *timestr) { int w,i,j,pos=inipos,pgpos,oldpg,y; char *p,*s,*basep; @@ -473,7 +491,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) dprintk(1,"%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); } -static void vivi_sleep(struct vivi_dmaqueue *dma_q) +void vivi_sleep(struct vivi_dmaqueue *dma_q) { int timeout; DECLARE_WAITQUEUE(wait, current); @@ -508,7 +526,7 @@ static void vivi_sleep(struct vivi_dmaqueue *dma_q) try_to_freeze(); } -static int vivi_thread(void *data) +int vivi_thread(void *data) { struct vivi_dmaqueue *dma_q=data; @@ -524,7 +542,7 @@ static int vivi_thread(void *data) return 0; } -static int vivi_start_thread(struct vivi_dmaqueue *dma_q) +int vivi_start_thread(struct vivi_dmaqueue *dma_q) { dma_q->frame=0; dma_q->ini_jiffies=jiffies; @@ -542,7 +560,7 @@ static int vivi_start_thread(struct vivi_dmaqueue *dma_q) return 0; } -static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) +void vivi_stop_thread(struct vivi_dmaqueue *dma_q) { dprintk(1,"%s\n",__FUNCTION__); /* shutdown control thread */ @@ -648,7 +666,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) return 0; } -static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) +void +free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) { dprintk(1,"%s\n",__FUNCTION__); @@ -772,8 +791,8 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb free_buffer(vq,buf); } -static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, - int direction) +int vivi_map_sg (void *dev, struct scatterlist *sg, int nents, + int direction) { int i; @@ -789,15 +808,15 @@ static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, return nents; } -static int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, - int direction) +int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, + int direction) { dprintk(1,"%s\n",__FUNCTION__); return 0; } -static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages, - int direction) +int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist,int nr_pages, + int direction) { // dprintk(1,"%s\n",__FUNCTION__); @@ -821,80 +840,7 @@ static struct videobuf_queue_ops vivi_video_qops = { IOCTL handling ------------------------------------------------------------------*/ - -static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) -{ - /* is it free? */ - down(&dev->lock); - if (dev->resources) { - /* no, someone else uses it */ - up(&dev->lock); - return 0; - } - /* it's free, grab it */ - dev->resources =1; - dprintk(1,"res: get\n"); - up(&dev->lock); - return 1; -} - -static int res_locked(struct vivi_dev *dev) -{ - return (dev->resources); -} - -static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) -{ - down(&dev->lock); - dev->resources = 0; - dprintk(1,"res: put\n"); - up(&dev->lock); -} - -/* ------------------------------------------------------------------ - IOCTL vidioc handling - ------------------------------------------------------------------*/ -static int vidioc_querycap (struct file *file, void *priv, - struct v4l2_capability *cap) -{ - strcpy(cap->driver, "vivi"); - strcpy(cap->card, "vivi"); - cap->version = VIVI_VERSION; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - return 0; -} - -static int vidioc_enum_fmt_cap (struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index > 0) - return -EINVAL; - - strlcpy(f->description,format.name,sizeof(f->description)); - f->pixelformat = format.fourcc; - return 0; -} - -static int vidioc_g_fmt_cap (struct file *file, void *priv, - struct v4l2_format *f) -{ - struct vivi_fh *fh=priv; - - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vb_vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return (0); -} - -static int vidioc_try_fmt_cap (struct file *file, void *priv, +static int vivi_try_fmt(struct vivi_dev *dev, struct vivi_fh *fh, struct v4l2_format *f) { struct vivi_fmt *fmt; @@ -902,8 +848,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv, unsigned int maxw, maxh; if (format.fourcc != f->fmt.pix.pixelformat) { - dprintk(1,"Fourcc format (0x%08x) invalid. Driver accepts " - "only 0x%08x\n",f->fmt.pix.pixelformat,format.fourcc); + dprintk(1,"Fourcc format invalid.\n"); return -EINVAL; } fmt=&format; @@ -939,196 +884,356 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv, return 0; } -/*FIXME: This seems to be generic enough to be at videodev2 */ -static int vidioc_s_fmt_cap (struct file *file, void *priv, - struct v4l2_format *f) +static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) { - struct vivi_fh *fh=priv; - int ret = vidioc_try_fmt_cap(file,fh,f); - if (ret < 0) - return (ret); - - fh->fmt = &format; - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vb_vidq.field = f->fmt.pix.field; - fh->type = f->type; - - return (0); + /* is it free? */ + down(&dev->lock); + if (dev->resources) { + /* no, someone else uses it */ + up(&dev->lock); + return 0; + } + /* it's free, grab it */ + dev->resources =1; + dprintk(1,"res: get\n"); + up(&dev->lock); + return 1; } -static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) +static inline int res_locked(struct vivi_dev *dev) { - struct vivi_fh *fh=priv; - - return (videobuf_reqbufs(&fh->vb_vidq, p)); + return (dev->resources); } -static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p) +static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) { - struct vivi_fh *fh=priv; - - return (videobuf_querybuf(&fh->vb_vidq, p)); + down(&dev->lock); + dev->resources = 0; + dprintk(1,"res: put\n"); + up(&dev->lock); } -static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) +static int vivi_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct vivi_fh *fh=priv; + struct vivi_fh *fh = file->private_data; + struct vivi_dev *dev = fh->dev; + int ret=0; - return (videobuf_qbuf(&fh->vb_vidq, p)); -} + if (debug) { + if (_IOC_DIR(cmd) & _IOC_WRITE) + v4l_printk_ioctl_arg("vivi(w)",cmd, arg); + else if (!_IOC_DIR(cmd) & _IOC_READ) { + v4l_print_ioctl("vivi", cmd); + } + } -static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct vivi_fh *fh=priv; + switch(cmd) { + /* --- capabilities ------------------------------------------ */ + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = (struct v4l2_capability*)arg; + + memset(cap, 0, sizeof(*cap)); + + strcpy(cap->driver, "vivi"); + strcpy(cap->card, "vivi"); + cap->version = VIVI_VERSION; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; + break; + } + /* --- capture ioctls ---------------------------------------- */ + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *f = arg; + enum v4l2_buf_type type; + unsigned int index; - return (videobuf_dqbuf(&fh->vb_vidq, p, - file->f_flags & O_NONBLOCK)); -} + index = f->index; + type = f->type; -#ifdef HAVE_V4L1 -static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) -{ - struct vivi_fh *fh=priv; - struct videobuf_queue *q=&fh->vb_vidq; - struct v4l2_requestbuffers req; - unsigned int i, ret; - - req.type = q->type; - req.count = 8; - req.memory = V4L2_MEMORY_MMAP; - ret = videobuf_reqbufs(q,&req); - if (ret < 0) - return (ret); - - mbuf->frames = req.count; - mbuf->size = 0; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; - } - return (0); -} -#endif + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct vivi_fh *fh=priv; - struct vivi_dev *dev = fh->dev; + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (index > 0){ + ret=-EINVAL; + break; + } + memset(f,0,sizeof(*f)); - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) - return -EINVAL; + f->index = index; + f->type = type; + strlcpy(f->description,format.name,sizeof(f->description)); + f->pixelformat = format.fourcc; + break; + default: + ret=-EINVAL; + } + break; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; - if (!res_get(dev,fh)) - return -EBUSY; - return (videobuf_streamon(&fh->vb_vidq)); -} + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct vivi_fh *fh=priv; - struct vivi_dev *dev = fh->dev; + memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->vb_vidq.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) - return -EINVAL; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1,"Only capture supported.\n"); + ret=-EINVAL; + break; + } - videobuf_streamoff(&fh->vb_vidq); - res_free(dev,fh); + ret = vivi_try_fmt(dev,fh,f); + if (ret < 0) + break; - return (0); -} + fh->fmt = &format; + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; -static struct v4l2_tvnorm tvnorms[] = { + break; + } + case VIDIOC_TRY_FMT: { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, + struct v4l2_format *f = arg; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + + ret=vivi_try_fmt(dev,fh,f); + break; } -}; + case VIDIOC_REQBUFS: + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + ret=videobuf_reqbufs(&fh->vb_vidq, arg); + break; + case VIDIOC_QUERYBUF: + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + ret=videobuf_querybuf(&fh->vb_vidq, arg); + break; + case VIDIOC_QBUF: + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + ret=videobuf_qbuf(&fh->vb_vidq, arg); + break; + case VIDIOC_DQBUF: + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + ret=videobuf_dqbuf(&fh->vb_vidq, arg, + file->f_flags & O_NONBLOCK); + break; +#ifdef HAVE_V4L1 + /* --- streaming capture ------------------------------------- */ + case VIDIOCGMBUF: + { + struct video_mbuf *mbuf = arg; + struct videobuf_queue *q=&fh->vb_vidq; + struct v4l2_requestbuffers req; + unsigned int i; + + memset(&req,0,sizeof(req)); + req.type = q->type; + req.count = 8; + req.memory = V4L2_MEMORY_MMAP; + ret = videobuf_reqbufs(q,&req); + if (ret < 0) + break; + memset(mbuf,0,sizeof(*mbuf)); + mbuf->frames = req.count; + mbuf->size = 0; + for (i = 0; i < mbuf->frames; i++) { + mbuf->offsets[i] = q->bufs[i]->boff; + mbuf->size += q->bufs[i]->bsize; + } + break; + } +#endif + case VIDIOC_STREAMON: + { + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (!res_get(dev,fh)) + return -EBUSY; + ret=videobuf_streamon(&fh->vb_vidq); + break; + } + case VIDIOC_STREAMOFF: + { + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret=-EINVAL; + break; + } + ret = videobuf_streamoff(&fh->vb_vidq); + if (ret < 0) + break; + res_free(dev,fh); + break; + } + /* ---------- tv norms ---------- */ + case VIDIOC_ENUMSTD: + { + struct v4l2_standard *e = arg; -static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a) -{ + if (e->index>0) { + ret=-EINVAL; + break; + } + ret = v4l2_video_std_construct(e, V4L2_STD_NTSC_M, "NTSC-M"); - return 0; -} + /* Allows vivi to use different fps from video std */ + e->frameperiod.numerator = WAKE_NUMERATOR; + e->frameperiod.denominator = WAKE_DENOMINATOR; -/* only one input in this sample driver */ -static int vidioc_enum_input (struct file *file, void *priv, - struct v4l2_input *inp) -{ - if (inp->index != 0) - return -EINVAL; + break; + } + case VIDIOC_G_STD: + { + v4l2_std_id *id = arg; - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_NTSC_M; - strcpy(inp->name,"Camera"); + *id = V4L2_STD_NTSC_M; + break; + } + case VIDIOC_S_STD: + { + break; + } + /* ------ input switching ---------- */ + case VIDIOC_ENUMINPUT: + { /* only one input in this sample driver */ + struct v4l2_input *inp = arg; - return (0); -} + if (inp->index != 0) { + ret=-EINVAL; + break; + } + memset(inp, 0, sizeof(*inp)); -static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) -{ - *i = 0; + inp->index = 0; + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_NTSC_M; + strcpy(inp->name,"Camera"); + break; + } + case VIDIOC_G_INPUT: + { + unsigned int *i = arg; - return (0); -} -static int vidioc_s_input (struct file *file, void *priv, unsigned int i) -{ - if (i > 0) - return -EINVAL; + *i = 0; + break; + } + case VIDIOC_S_INPUT: + { + unsigned int *i = arg; - return (0); -} + if (*i > 0) + ret=-EINVAL; + break; + } /* --- controls ---------------------------------------------- */ -static int vidioc_queryctrl (struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - int i; + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + if (qc->id && qc->id == vivi_qctrl[i].id) { + memcpy(qc, &(vivi_qctrl[i]), + sizeof(*qc)); + break; + } - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (qc->id && qc->id == vivi_qctrl[i].id) { - memcpy(qc, &(vivi_qctrl[i]), - sizeof(*qc)); - return (0); - } + ret=-EINVAL; + break; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + int i; - return -EINVAL; -} + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + if (ctrl->id == vivi_qctrl[i].id) { + ctrl->value=qctl_regs[i]; + break; + } -static int vidioc_g_ctrl (struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - int i; + ret=-EINVAL; + break; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + int i; + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + if (ctrl->id == vivi_qctrl[i].id) { + if (ctrl->value < + vivi_qctrl[i].minimum + || ctrl->value > + vivi_qctrl[i].maximum) { + ret=-ERANGE; + break; + } + qctl_regs[i]=ctrl->value; + break; + } + ret=-EINVAL; + break; + } + default: + ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,vivi_do_ioctl); + } - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (ctrl->id == vivi_qctrl[i].id) { - ctrl->value=qctl_regs[i]; - return (0); - } + if (debug) { + if (ret<0) { + v4l_print_ioctl("vivi(err)", cmd); + dprintk(1,"errcode=%d\n",ret); + } else if (_IOC_DIR(cmd) & _IOC_READ) + v4l_printk_ioctl_arg("vivi(r)",cmd, arg); + } - return -EINVAL; + return ret; } -static int vidioc_s_ctrl (struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - int i; - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - if (ctrl->id == vivi_qctrl[i].id) { - if (ctrl->value < - vivi_qctrl[i].minimum - || ctrl->value > - vivi_qctrl[i].maximum) { - return (-ERANGE); - } - qctl_regs[i]=ctrl->value; - return (0); - } - return -EINVAL; +static int vivi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + return video_usercopy(inode, file, cmd, arg, vivi_do_ioctl); } /* ------------------------------------------------------------------ @@ -1150,7 +1255,7 @@ static int vivi_open(struct inode *inode, struct file *file) list_for_each(list,&vivi_devlist) { h = list_entry(list, struct vivi_dev, vivi_devlist); - if (h->vfd.minor == minor) { + if (h->video_dev.minor == minor) { dev = h; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } @@ -1159,7 +1264,6 @@ static int vivi_open(struct inode *inode, struct file *file) return -ENODEV; - /* If more than one user, mutex should be added */ dev->users++; @@ -1175,7 +1279,6 @@ static int vivi_open(struct inode *inode, struct file *file) file->private_data = fh; fh->dev = dev; - fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fh->fmt = &format; fh->width = 640; @@ -1211,7 +1314,7 @@ static int vivi_open(struct inode *inode, struct file *file) static ssize_t vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { - struct vivi_fh *fh = file->private_data; + struct vivi_fh *fh = file->private_data; if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (res_locked(fh->dev)) @@ -1225,8 +1328,8 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) static unsigned int vivi_poll(struct file *file, struct poll_table_struct *wait) { - struct vivi_fh *fh = file->private_data; - struct vivi_buffer *buf; + struct vivi_fh *fh = file->private_data; + struct vivi_buffer *buf; dprintk(1,"%s\n",__FUNCTION__); @@ -1255,8 +1358,8 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) static int vivi_release(struct inode *inode, struct file *file) { - struct vivi_fh *fh = file->private_data; - struct vivi_dev *dev = fh->dev; + struct vivi_fh *fh = file->private_data; + struct vivi_dev *dev = fh->dev; struct vivi_dmaqueue *vidq = &dev->vidq; int minor = iminor(inode); @@ -1276,7 +1379,7 @@ static int vivi_release(struct inode *inode, struct file *file) static int vivi_mmap(struct file *file, struct vm_area_struct * vma) { - struct vivi_fh *fh = file->private_data; + struct vivi_fh *fh = file->private_data; int ret; dprintk (1,"mmap called, vma=0x%08lx\n",(unsigned long)vma); @@ -1297,44 +1400,20 @@ static struct file_operations vivi_fops = { .release = vivi_release, .read = vivi_read, .poll = vivi_poll, - .ioctl = video_ioctl2, /* V4L2 ioctl handler */ + .ioctl = vivi_ioctl, .mmap = vivi_mmap, .llseek = no_llseek, }; static struct video_device vivi = { - .name = "vivi", + .name = "VTM Virtual Video Capture Board", .type = VID_TYPE_CAPTURE, .hardware = 0, .fops = &vivi_fops, .minor = -1, // .release = video_device_release, - - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, -#ifdef HAVE_V4L1 - .vidiocgmbuf = vidiocgmbuf, -#endif - .tvnorms = tvnorms, - .tvnormsize = ARRAY_SIZE(tvnorms), }; -/* ----------------------------------------------------------------- +/* ------------------------------------------------------------------ Initialization and module stuff ------------------------------------------------------------------*/ @@ -1378,16 +1457,3 @@ static void __exit vivi_exit(void) module_init(vivi_init); module_exit(vivi_exit); - -MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); -MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); -MODULE_LICENSE("Dual BSD/GPL"); - -module_param(video_nr, int, 0); - -module_param_named(debug,vivi.debug, int, 0644); -MODULE_PARM_DESC(debug,"activates debug info"); - -module_param(vid_limit,int,0644); -MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); - diff --git a/trunk/drivers/media/video/vpx3220.c b/trunk/drivers/media/video/vpx3220.c index 1eca7e65d235..40b205b91481 100644 --- a/trunk/drivers/media/video/vpx3220.c +++ b/trunk/drivers/media/video/vpx3220.c @@ -34,7 +34,6 @@ #define I2C_NAME(x) (x)->name #include -#include #include #define I2C_VPX3220 0x86 diff --git a/trunk/drivers/media/video/w9966.c b/trunk/drivers/media/video/w9966.c index 4bdc886abc4c..80ef8a1b8f63 100644 --- a/trunk/drivers/media/video/w9966.c +++ b/trunk/drivers/media/video/w9966.c @@ -58,7 +58,6 @@ #include #include #include -#include #include //#define DEBUG // Undef me for production diff --git a/trunk/drivers/media/video/zc0301/Kconfig b/trunk/drivers/media/video/zc0301/Kconfig index a859a6920189..115833e4f4dd 100644 --- a/trunk/drivers/media/video/zc0301/Kconfig +++ b/trunk/drivers/media/video/zc0301/Kconfig @@ -1,9 +1,9 @@ config USB_ZC0301 - tristate "USB ZC0301[P] Image Processor and Control Chip support" + tristate "USB ZC0301 Image Processor and Control Chip support" depends on USB && VIDEO_V4L1 ---help--- - Say Y here if you want support for cameras based on the ZC0301 or - ZC0301P Image Processors and Control Chips. + Say Y here if you want support for cameras based on the ZC0301 + Image Processor and Control Chip. See for more info. diff --git a/trunk/drivers/media/video/zc0301/Makefile b/trunk/drivers/media/video/zc0301/Makefile index d9e6d97fade6..d749199d8f06 100644 --- a/trunk/drivers/media/video/zc0301/Makefile +++ b/trunk/drivers/media/video/zc0301/Makefile @@ -1,3 +1,3 @@ -zc0301-objs := zc0301_core.o zc0301_pb0330.o zc0301_pas202bcb.o +zc0301-objs := zc0301_core.o zc0301_pas202bcb.o obj-$(CONFIG_USB_ZC0301) += zc0301.o diff --git a/trunk/drivers/media/video/zc0301/zc0301_core.c b/trunk/drivers/media/video/zc0301/zc0301_core.c index 1b2be2d2a3ec..0fad39754f7a 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_core.c +++ b/trunk/drivers/media/video/zc0301/zc0301_core.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Video4Linux2 driver for ZC0301[P] Image Processor and Control Chip * + * Video4Linux2 driver for ZC0301 Image Processor and Control Chip * * * * Copyright (C) 2006 by Luca Risolia * * * @@ -47,13 +47,13 @@ /*****************************************************************************/ -#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ +#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \ "Image Processor and Control Chip" #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" #define ZC0301_AUTHOR_EMAIL "" #define ZC0301_MODULE_LICENSE "GPL" -#define ZC0301_MODULE_VERSION "1:1.05" -#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 5) +#define ZC0301_MODULE_VERSION "1:1.03" +#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3) /*****************************************************************************/ @@ -427,11 +427,10 @@ static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs) static int zc0301_start_transfer(struct zc0301_device* cam) { struct usb_device *udev = cam->usbdev; - struct usb_host_interface* altsetting = usb_altnum_to_altsetting( - usb_ifnum_to_if(udev, 0), - ZC0301_ALTERNATE_SETTING); - const unsigned int psz = altsetting->endpoint[0].desc.wMaxPacketSize; struct urb* urb; + const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384, + 512, 768, 1023}; + const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING]; s8 i, j; int err = 0; @@ -1773,9 +1772,11 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_CTRL: return zc0301_vidioc_g_ctrl(cam, arg); + case VIDIOC_S_CTRL_OLD: case VIDIOC_S_CTRL: return zc0301_vidioc_s_ctrl(cam, arg); + case VIDIOC_CROPCAP_OLD: case VIDIOC_CROPCAP: return zc0301_vidioc_cropcap(cam, arg); @@ -1822,6 +1823,7 @@ static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp, case VIDIOC_G_PARM: return zc0301_vidioc_g_parm(cam, arg); + case VIDIOC_S_PARM_OLD: case VIDIOC_S_PARM: return zc0301_vidioc_s_parm(cam, arg); @@ -1912,7 +1914,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) mutex_init(&cam->dev_mutex); - DBG(2, "ZC0301[P] Image Processor and Control Chip detected " + DBG(2, "ZC0301 Image Processor and Control Chip detected " "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); for (i = 0; zc0301_sensor_table[i]; i++) { @@ -1934,7 +1936,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->state |= DEV_MISCONFIGURED; } - strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); + strcpy(cam->v4ldev->name, "ZC0301 PC Camera"); cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->hardware = 0; diff --git a/trunk/drivers/media/video/zc0301/zc0301_pas202bcb.c b/trunk/drivers/media/video/zc0301/zc0301_pas202bcb.c index ecfd39a56df1..eaadf0252049 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_pas202bcb.c +++ b/trunk/drivers/media/video/zc0301/zc0301_pas202bcb.c @@ -1,10 +1,10 @@ /*************************************************************************** - * Plug-in for PAS202BCB image sensor connected to the ZC0301[P] Image * + * Plug-in for PAS202BCB image sensor connected to the ZC030! Image * * Processor and Control Chip * * * * Copyright (C) 2006 by Luca Risolia * * * - * Initialization values of the ZC0301[P] have been taken from the SPCA5XX * + * Initialization values of the ZC0301 have been taken from the SPCA5XX * * driver maintained by Michel Xhaard * * * * This program is free software; you can redistribute it and/or modify * diff --git a/trunk/drivers/media/video/zc0301/zc0301_pb0330.c b/trunk/drivers/media/video/zc0301/zc0301_pb0330.c deleted file mode 100644 index ed8542e6c50f..000000000000 --- a/trunk/drivers/media/video/zc0301/zc0301_pb0330.c +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** - * Plug-in for PB-0330 image sensor connected to the ZC0301[P] Image * - * Processor and Control Chip * - * * - * Copyright (C) 2006 by Luca Risolia * - * * - * Initialization values of the ZC0301[P] have been taken from the SPCA5XX * - * driver maintained by Michel Xhaard * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software * - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - ***************************************************************************/ - -#include -#include "zc0301_sensor.h" - - -static struct zc0301_sensor pb0330; - - -static int pb0330_init(struct zc0301_device* cam) -{ - int err = 0; - - err += zc0301_write_reg(cam, 0x0000, 0x01); - err += zc0301_write_reg(cam, 0x0008, 0x03); - err += zc0301_write_reg(cam, 0x0010, 0x0A); - err += zc0301_write_reg(cam, 0x0002, 0x00); - err += zc0301_write_reg(cam, 0x0003, 0x02); - err += zc0301_write_reg(cam, 0x0004, 0x80); - err += zc0301_write_reg(cam, 0x0005, 0x01); - err += zc0301_write_reg(cam, 0x0006, 0xE0); - err += zc0301_write_reg(cam, 0x0001, 0x01); - err += zc0301_write_reg(cam, 0x0012, 0x05); - err += zc0301_write_reg(cam, 0x0012, 0x07); - err += zc0301_write_reg(cam, 0x0098, 0x00); - err += zc0301_write_reg(cam, 0x009A, 0x00); - err += zc0301_write_reg(cam, 0x011A, 0x00); - err += zc0301_write_reg(cam, 0x011C, 0x00); - err += zc0301_write_reg(cam, 0x0012, 0x05); - - err += zc0301_i2c_write(cam, 0x01, 0x0006); - err += zc0301_i2c_write(cam, 0x02, 0x0011); - err += zc0301_i2c_write(cam, 0x03, 0x01E7); - err += zc0301_i2c_write(cam, 0x04, 0x0287); - err += zc0301_i2c_write(cam, 0x06, 0x0003); - err += zc0301_i2c_write(cam, 0x07, 0x3002); - err += zc0301_i2c_write(cam, 0x20, 0x1100); - err += zc0301_i2c_write(cam, 0x2F, 0xF7B0); - err += zc0301_i2c_write(cam, 0x30, 0x0005); - err += zc0301_i2c_write(cam, 0x31, 0x0000); - err += zc0301_i2c_write(cam, 0x34, 0x0100); - err += zc0301_i2c_write(cam, 0x35, 0x0060); - err += zc0301_i2c_write(cam, 0x3D, 0x068F); - err += zc0301_i2c_write(cam, 0x40, 0x01E0); - err += zc0301_i2c_write(cam, 0x58, 0x0078); - err += zc0301_i2c_write(cam, 0x62, 0x0411); - - err += zc0301_write_reg(cam, 0x0087, 0x10); - err += zc0301_write_reg(cam, 0x0101, 0x37); - err += zc0301_write_reg(cam, 0x0012, 0x05); - err += zc0301_write_reg(cam, 0x0100, 0x0D); - err += zc0301_write_reg(cam, 0x0189, 0x06); - err += zc0301_write_reg(cam, 0x01AD, 0x00); - err += zc0301_write_reg(cam, 0x01C5, 0x03); - err += zc0301_write_reg(cam, 0x01CB, 0x13); - err += zc0301_write_reg(cam, 0x0250, 0x08); - err += zc0301_write_reg(cam, 0x0301, 0x08); - err += zc0301_write_reg(cam, 0x01A8, 0x60); - err += zc0301_write_reg(cam, 0x018D, 0x6C); - err += zc0301_write_reg(cam, 0x01AD, 0x09); - err += zc0301_write_reg(cam, 0x01AE, 0x15); - err += zc0301_write_reg(cam, 0x010A, 0x50); - err += zc0301_write_reg(cam, 0x010B, 0xF8); - err += zc0301_write_reg(cam, 0x010C, 0xF8); - err += zc0301_write_reg(cam, 0x010D, 0xF8); - err += zc0301_write_reg(cam, 0x010E, 0x50); - err += zc0301_write_reg(cam, 0x010F, 0xF8); - err += zc0301_write_reg(cam, 0x0110, 0xF8); - err += zc0301_write_reg(cam, 0x0111, 0xF8); - err += zc0301_write_reg(cam, 0x0112, 0x50); - err += zc0301_write_reg(cam, 0x0008, 0x03); - err += zc0301_write_reg(cam, 0x01C6, 0x08); - err += zc0301_write_reg(cam, 0x01CB, 0x0F); - err += zc0301_write_reg(cam, 0x010A, 0x50); - err += zc0301_write_reg(cam, 0x010B, 0xF8); - err += zc0301_write_reg(cam, 0x010C, 0xF8); - err += zc0301_write_reg(cam, 0x010D, 0xF8); - err += zc0301_write_reg(cam, 0x010E, 0x50); - err += zc0301_write_reg(cam, 0x010F, 0xF8); - err += zc0301_write_reg(cam, 0x0110, 0xF8); - err += zc0301_write_reg(cam, 0x0111, 0xF8); - err += zc0301_write_reg(cam, 0x0112, 0x50); - err += zc0301_write_reg(cam, 0x0180, 0x00); - err += zc0301_write_reg(cam, 0x0019, 0x00); - - err += zc0301_i2c_write(cam, 0x05, 0x0066); - err += zc0301_i2c_write(cam, 0x09, 0x02B2); - err += zc0301_i2c_write(cam, 0x10, 0x0002); - - err += zc0301_write_reg(cam, 0x011D, 0x60); - err += zc0301_write_reg(cam, 0x0190, 0x00); - err += zc0301_write_reg(cam, 0x0191, 0x07); - err += zc0301_write_reg(cam, 0x0192, 0x8C); - err += zc0301_write_reg(cam, 0x0195, 0x00); - err += zc0301_write_reg(cam, 0x0196, 0x00); - err += zc0301_write_reg(cam, 0x0197, 0x8A); - err += zc0301_write_reg(cam, 0x018C, 0x10); - err += zc0301_write_reg(cam, 0x018F, 0x20); - err += zc0301_write_reg(cam, 0x01A9, 0x14); - err += zc0301_write_reg(cam, 0x01AA, 0x24); - err += zc0301_write_reg(cam, 0x001D, 0xD7); - err += zc0301_write_reg(cam, 0x001E, 0xF0); - err += zc0301_write_reg(cam, 0x001F, 0xF8); - err += zc0301_write_reg(cam, 0x0020, 0xFF); - err += zc0301_write_reg(cam, 0x01AD, 0x09); - err += zc0301_write_reg(cam, 0x01AE, 0x15); - err += zc0301_write_reg(cam, 0x0180, 0x40); - err += zc0301_write_reg(cam, 0x0180, 0x42); - - msleep(100); - - return err; -} - - -static struct zc0301_sensor pb0330 = { - .name = "PB-0330", - .init = &pb0330_init, - .cropcap = { - .bounds = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - .defrect = { - .left = 0, - .top = 0, - .width = 640, - .height = 480, - }, - }, - .pix_format = { - .width = 640, - .height = 480, - .pixelformat = V4L2_PIX_FMT_JPEG, - .priv = 8, - }, -}; - - -int zc0301_probe_pb0330(struct zc0301_device* cam) -{ - int r0, err = 0; - - err += zc0301_write_reg(cam, 0x0000, 0x01); - err += zc0301_write_reg(cam, 0x0010, 0x0a); - err += zc0301_write_reg(cam, 0x0001, 0x01); - err += zc0301_write_reg(cam, 0x0012, 0x03); - err += zc0301_write_reg(cam, 0x0012, 0x01); - - msleep(10); - - r0 = zc0301_i2c_read(cam, 0x00, 2); - - if (r0 < 0 || err) - return -EIO; - - if (r0 != 0x8243) - return -ENODEV; - - zc0301_attach_sensor(cam, &pb0330); - - return 0; -} diff --git a/trunk/drivers/media/video/zc0301/zc0301_sensor.h b/trunk/drivers/media/video/zc0301/zc0301_sensor.h index 4363a915b1f4..1f95c28b1015 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_sensor.h +++ b/trunk/drivers/media/video/zc0301/zc0301_sensor.h @@ -1,5 +1,5 @@ /*************************************************************************** - * API for image sensors connected to the ZC0301 Image Processor and * + * API for image sensors connected to the ZC030! Image Processor and * * Control Chip * * * * Copyright (C) 2006 by Luca Risolia * @@ -35,13 +35,11 @@ struct zc0301_sensor; /*****************************************************************************/ extern int zc0301_probe_pas202bcb(struct zc0301_device* cam); -extern int zc0301_probe_pb0330(struct zc0301_device* cam); #define ZC0301_SENSOR_TABLE \ /* Weak detections must go at the end of the list */ \ static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \ &zc0301_probe_pas202bcb, \ - &zc0301_probe_pb0330, \ NULL, \ }; @@ -60,28 +58,14 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); #define ZC0301_ID_TABLE \ static const struct usb_device_id zc0301_id_table[] = { \ - { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, /* ICM105 */ \ + { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, \ { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x401f, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x4022, 0xff), }, \ + { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \ { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \ { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x4036, 0xff), }, /* HV7131 */ \ - { ZC0301_USB_DEVICE(0x041e, 0x403a, 0xff), }, /* HV7131 */ \ - { ZC0301_USB_DEVICE(0x0458, 0x7007, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x0458, 0x700C, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x0458, 0x700f, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ - { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ + { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ - { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \ - { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ - { ZC0301_USB_DEVICE(0x10fd, 0x0128, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130 */ \ - { ZC0301_USB_DEVICE(0x10fd, 0x804e, 0xff), }, /* TAS5130 */ \ + { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ { } \ }; diff --git a/trunk/drivers/media/video/zoran.h b/trunk/drivers/media/video/zoran.h index ffcda95ed9d4..0166f555a5ca 100644 --- a/trunk/drivers/media/video/zoran.h +++ b/trunk/drivers/media/video/zoran.h @@ -159,7 +159,7 @@ Private IOCTL to set up for displaying MJPEG #define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ #define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ -#define BUZ_MAX_INPUT 16 +#define BUZ_MAX_INPUT 8 #if VIDEO_MAX_FRAME <= 32 # define V4L_MAX_FRAME 32 @@ -191,9 +191,6 @@ enum card_type { /* Iomega */ BUZ, - /* AverMedia */ - AVS6EYES, - /* total number of cards */ NUM_CARDS }; @@ -382,9 +379,6 @@ struct card_info { /* is the /GWS line conected? */ u8 gws_not_connected; - /* avs6eyes mux setting */ - u8 input_mux; - void (*init) (struct zoran * zr); }; diff --git a/trunk/drivers/media/video/zoran_card.c b/trunk/drivers/media/video/zoran_card.c index 958c1e6fc852..0a85c9e7fb48 100644 --- a/trunk/drivers/media/video/zoran_card.c +++ b/trunk/drivers/media/video/zoran_card.c @@ -27,8 +27,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - #include #include #include @@ -40,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -96,11 +93,6 @@ module_param(default_input, int, 0); MODULE_PARM_DESC(default_input, "Default input (0=Composite, 1=S-Video, 2=Internal)"); -static int default_mux = 1; /* 6 Eyes input selection */ -module_param(default_mux, int, 0); -MODULE_PARM_DESC(default_mux, - "Default 6 Eyes mux setting (Input selection)"); - static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ module_param(default_norm, int, 0); MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); @@ -309,30 +301,6 @@ lml33_init (struct zoran *zr) GPIO(zr, 2, 1); // Set Composite input/output } -static void -avs6eyes_init (struct zoran *zr) -{ - // AverMedia 6-Eyes original driver by Christer Weinigel - - // Lifted straight from Christer's old driver and - // modified slightly by Martin Samuelsson. - - int mux = default_mux; /* 1 = BT866, 7 = VID1 */ - - GPIO(zr, 4, 1); /* Bt866 SLEEP on */ - udelay(2); - - GPIO(zr, 0, 1); /* ZR36060 /RESET on */ - GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */ - GPIO(zr, 2, mux & 1); /* MUX S0 */ - GPIO(zr, 3, 0); /* /FRAME on */ - GPIO(zr, 4, 0); /* Bt866 SLEEP off */ - GPIO(zr, 5, mux & 2); /* MUX S1 */ - GPIO(zr, 6, 0); /* ? */ - GPIO(zr, 7, mux & 4); /* MUX S2 */ - -} - static char * i2cid_to_modulename (u16 i2c_id) { @@ -423,14 +391,6 @@ static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 }; static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; -/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I - * copy Maxim's left shift hack for the 6 Eyes. - * - * Christer's driver used the unshifted norms, though... - * /Sam */ -static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; -static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; - static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { .type = DC10_old, @@ -459,7 +419,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { -1, 0 }, .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, .gws_not_connected = 0, - .input_mux = 0, .init = &dc10_init, }, { .type = DC10_new, @@ -486,7 +445,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { -1, 1}, .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, .gws_not_connected = 0, - .input_mux = 0, .init = &dc10plus_init, }, { .type = DC10plus, @@ -516,7 +474,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { -1, 1 }, .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, .gws_not_connected = 0, - .input_mux = 0, .init = &dc10plus_init, }, { .type = DC30, @@ -545,7 +502,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { -1, 0 }, .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, .gws_not_connected = 0, - .input_mux = 0, .init = &dc10_init, }, { .type = DC30plus, @@ -576,7 +532,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { -1, 0 }, .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, .gws_not_connected = 0, - .input_mux = 0, .init = &dc10_init, }, { .type = LML33, @@ -603,7 +558,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { 3, 1 }, .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, .gws_not_connected = 1, - .input_mux = 0, .init = &lml33_init, }, { .type = LML33R10, @@ -632,7 +586,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { 3, 1 }, .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, .gws_not_connected = 1, - .input_mux = 0, .init = &lml33_init, }, { .type = BUZ, @@ -661,49 +614,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .gpcs = { 3, 1 }, .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, .gws_not_connected = 1, - .input_mux = 0, .init = &buz_init, - }, { - .type = AVS6EYES, - .name = "6-Eyes", - /* AverMedia chose not to brand the 6-Eyes. Thus it - can't be autodetected, and requires card=x. */ - .vendor_id = -1, - .device_id = -1, - .i2c_decoder = I2C_DRIVERID_KS0127, - .i2c_encoder = I2C_DRIVERID_BT866, - .video_codec = CODEC_TYPE_ZR36060, - - .inputs = 10, - .input = { - { 0, "Composite 1" }, - { 1, "Composite 2" }, - { 2, "Composite 3" }, - { 4, "Composite 4" }, - { 5, "Composite 5" }, - { 6, "Composite 6" }, - { 8, "S-Video 1" }, - { 9, "S-Video 2" }, - {10, "S-Video 3" }, - {15, "YCbCr" } - }, - .norms = 2, - .tvn = { - &f50ccir601_avs6eyes, - &f60ccir601_avs6eyes, - NULL - }, - .jpeg_int = ZR36057_ISR_GIRQ1, - .vsync_int = ZR36057_ISR_GIRQ0, - .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam - .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam - .gpcs = { 3, 1 }, // Validity unknown /Sam - .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam - .gws_not_connected = 1, - .input_mux = 1, - .init = &avs6eyes_init, } - }; /* diff --git a/trunk/drivers/media/video/zoran_device.c b/trunk/drivers/media/video/zoran_device.c index 02168d9c2187..c690b2ee880a 100644 --- a/trunk/drivers/media/video/zoran_device.c +++ b/trunk/drivers/media/video/zoran_device.c @@ -536,7 +536,7 @@ zr36057_overlay (struct zoran *zr, * All error messages are internal driver checking only! */ /* video display top and bottom registers */ - reg = (long) zr->buffer.base + + reg = (u32) zr->buffer.base + zr->overlay_settings.x * ((zr->overlay_settings.format->depth + 7) / 8) + zr->overlay_settings.y * diff --git a/trunk/drivers/media/video/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c index 9711f6248ef7..b5a576a37fd2 100644 --- a/trunk/drivers/media/video/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -73,7 +73,6 @@ ) #include -#include #include "videocodec.h" #include @@ -2048,7 +2047,7 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); memset(vcap, 0, sizeof(struct video_capability)); - strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); + strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)); vcap->type = ZORAN_VID_TYPE; vcap->channels = zr->card.inputs; @@ -2690,8 +2689,8 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); memset(cap, 0, sizeof(*cap)); - strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); - strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); + strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)); + strncpy(cap->driver, "zoran", sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev)); cap->version = @@ -2743,7 +2742,7 @@ zoran_do_ioctl (struct inode *inode, memset(fmt, 0, sizeof(*fmt)); fmt->index = index; fmt->type = type; - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); + strncpy(fmt->description, zoran_formats[i].name, 31); fmt->pixelformat = zoran_formats[i].fourcc; if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; @@ -3567,16 +3566,16 @@ zoran_do_ioctl (struct inode *inode, switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); + strncpy(ctrl->name, "Brightness", 31); break; case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); + strncpy(ctrl->name, "Contrast", 31); break; case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); + strncpy(ctrl->name, "Saturation", 31); break; case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); + strncpy(ctrl->name, "Hue", 31); break; } @@ -3694,7 +3693,7 @@ zoran_do_ioctl (struct inode *inode, &caps); if (caps.flags & VIDEO_DECODER_AUTO) { std->id = V4L2_STD_ALL; - strncpy(std->name, "Autodetect", sizeof(std->name)-1); + strncpy(std->name, "Autodetect", 31); return 0; } else return -EINVAL; @@ -3702,21 +3701,21 @@ zoran_do_ioctl (struct inode *inode, switch (std->index) { case 0: std->id = V4L2_STD_PAL; - strncpy(std->name, "PAL", sizeof(std->name)-1); + strncpy(std->name, "PAL", 31); std->frameperiod.numerator = 1; std->frameperiod.denominator = 25; std->framelines = zr->card.tvn[0]->Ht; break; case 1: std->id = V4L2_STD_NTSC; - strncpy(std->name, "NTSC", sizeof(std->name)-1); + strncpy(std->name, "NTSC", 31); std->frameperiod.numerator = 1001; std->frameperiod.denominator = 30000; std->framelines = zr->card.tvn[1]->Ht; break; case 2: std->id = V4L2_STD_SECAM; - strncpy(std->name, "SECAM", sizeof(std->name)-1); + strncpy(std->name, "SECAM", 31); std->frameperiod.numerator = 1; std->frameperiod.denominator = 25; std->framelines = zr->card.tvn[2]->Ht; @@ -3872,7 +3871,7 @@ zoran_do_ioctl (struct inode *inode, memset(outp, 0, sizeof(*outp)); outp->index = 0; outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; - strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); + strncpy(outp->name, "Autodetect", 31); return 0; } diff --git a/trunk/drivers/media/video/zoran_procfs.c b/trunk/drivers/media/video/zoran_procfs.c index f4ffe79bdc5b..a00fae90229a 100644 --- a/trunk/drivers/media/video/zoran_procfs.c +++ b/trunk/drivers/media/video/zoran_procfs.c @@ -43,7 +43,6 @@ #include #include -#include #include #include "videocodec.h" diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 12dd8d493ee2..59690cbabfca 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -1185,6 +1185,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->pcidev = pdev; ioc->diagPending = 0; spin_lock_init(&ioc->diagLock); + spin_lock_init(&ioc->fc_rescan_work_lock); spin_lock_init(&ioc->initializing_hba_lock); /* Initialize the event logging. @@ -1382,6 +1383,30 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) /* Set lookup ptr. */ list_add_tail(&ioc->list, &ioc_list); + ioc->pci_irq = -1; + if (pdev->irq) { + if (mpt_msi_enable && !pci_enable_msi(pdev)) + printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name); + + r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); + + if (r < 0) { + printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n", + ioc->name, pdev->irq); + list_del(&ioc->list); + iounmap(mem); + kfree(ioc); + return -EBUSY; + } + + ioc->pci_irq = pdev->irq; + + pci_set_master(pdev); /* ?? */ + pci_set_drvdata(pdev, ioc); + + dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq)); + } + /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. */ mpt_detect_bound_ports(ioc, pdev); @@ -1391,7 +1416,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n", ioc->name, r); + list_del(&ioc->list); + free_irq(ioc->pci_irq, ioc); + if (mpt_msi_enable) + pci_disable_msi(pdev); if (ioc->alt_ioc) ioc->alt_ioc->alt_ioc = NULL; iounmap(mem); @@ -1610,7 +1639,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) int handlers; int ret = 0; int reset_alt_ioc_active = 0; - int irq_allocated = 0; printk(KERN_INFO MYNAM ": Initiating %s %s\n", ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); @@ -1694,36 +1722,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) } } - /* - * Device is reset now. It must have de-asserted the interrupt line - * (if it was asserted) and it should be safe to register for the - * interrupt now. - */ - if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { - ioc->pci_irq = -1; - if (ioc->pcidev->irq) { - if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev)) - printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", - ioc->name); - rc = request_irq(ioc->pcidev->irq, mpt_interrupt, - SA_SHIRQ, ioc->name, ioc); - if (rc < 0) { - printk(MYIOC_s_ERR_FMT "Unable to allocate " - "interrupt %d!\n", ioc->name, - ioc->pcidev->irq); - if (mpt_msi_enable) - pci_disable_msi(ioc->pcidev); - return -EBUSY; - } - irq_allocated = 1; - ioc->pci_irq = ioc->pcidev->irq; - pci_set_master(ioc->pcidev); /* ?? */ - pci_set_drvdata(ioc->pcidev, ioc); - dprintk((KERN_INFO MYNAM ": %s installed at interrupt " - "%d\n", ioc->name, ioc->pcidev->irq)); - } - } - /* Prime reply & request queues! * (mucho alloc's) Must be done prior to * init as upper addresses are needed for init. @@ -1823,7 +1821,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ret = mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); if(ret != 0) - goto out; + return -1; } /* Find IM volumes @@ -1831,6 +1829,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) mpt_findImVolumes(ioc); } else if (ioc->bus_type == FC) { + /* + * Pre-fetch FC port WWN and stuff... + * (FCPortPage0_t stuff) + */ + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + (void) mptbase_GetFcPortPage0(ioc, ii); + } + if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && (ioc->lan_cnfg_page0.Header.PageLength == 0)) { /* @@ -1896,12 +1902,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) /* FIXME? Examine results here? */ } -out: - if ((ret != 0) && irq_allocated) { - free_irq(ioc->pci_irq, ioc); - if (mpt_msi_enable) - pci_disable_msi(ioc->pcidev); - } return ret; } @@ -2276,7 +2276,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) } if (sleepFlag == CAN_SLEEP) { - msleep(1); + msleep_interruptible(1); } else { mdelay (1); /* 1 msec delay */ } @@ -2664,7 +2664,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) state = mpt_GetIocState(ioc, 1); while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { if (sleepFlag == CAN_SLEEP) { - msleep(1); + msleep_interruptible(1); } else { mdelay(1); } @@ -2916,7 +2916,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) /* wait 1 msec */ if (sleepFlag == CAN_SLEEP) { - msleep(1); + msleep_interruptible(1); } else { mdelay (1); } @@ -2933,7 +2933,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) } /* wait .1 sec */ if (sleepFlag == CAN_SLEEP) { - msleep (100); + msleep_interruptible (100); } else { mdelay (100); } @@ -3023,7 +3023,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) /* wait 1 msec */ if (sleepFlag == CAN_SLEEP) { - msleep (1); + msleep_interruptible (1); } else { mdelay (1); } @@ -3071,7 +3071,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) return 0; } if (sleepFlag == CAN_SLEEP) { - msleep (10); + msleep_interruptible (10); } else { mdelay (10); } @@ -3122,7 +3122,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); if (sleepFlag == CAN_SLEEP) { - msleep (1000); + msleep_interruptible (1000); } else { mdelay (1000); } @@ -3144,7 +3144,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) return hard_reset_done; } if (sleepFlag == CAN_SLEEP) { - msleep (10); + msleep_interruptible (10); } else { mdelay (10); } @@ -3215,7 +3215,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) /* wait 100 msec */ if (sleepFlag == CAN_SLEEP) { - msleep (100); + msleep_interruptible (100); } else { mdelay (100); } @@ -3294,7 +3294,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) /* wait 1 sec */ if (sleepFlag == CAN_SLEEP) { - msleep (1000); + msleep_interruptible (1000); } else { mdelay (1000); } @@ -3322,7 +3322,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) /* wait 1 sec */ if (sleepFlag == CAN_SLEEP) { - msleep (1000); + msleep_interruptible (1000); } else { mdelay (1000); } @@ -3356,7 +3356,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) /* wait 100 msec */ if (sleepFlag == CAN_SLEEP) { - msleep (100); + msleep_interruptible (100); } else { mdelay (100); } @@ -3450,7 +3450,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) } if (sleepFlag == CAN_SLEEP) { - msleep(1); + msleep_interruptible(1); } else { mdelay (1); /* 1 msec delay */ } @@ -3890,7 +3890,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) break; - msleep (1); + msleep_interruptible (1); count++; } } else { @@ -3939,7 +3939,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) intstat = CHIPREG_READ32(&ioc->chip->IntStatus); if (intstat & MPI_HIS_DOORBELL_INTERRUPT) break; - msleep(1); + msleep_interruptible(1); count++; } } else { @@ -4160,6 +4160,108 @@ GetLanConfigPages(MPT_ADAPTER *ioc) return rc; } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* + * mptbase_GetFcPortPage0 - Fetch FCPort config Page0. + * @ioc: Pointer to MPT_ADAPTER structure + * @portnum: IOC Port number + * + * Return: 0 for success + * -ENOMEM if no memory available + * -EPERM if not allowed due to ISR context + * -EAGAIN if no msg frames currently available + * -EFAULT for non-successful reply or no reply (timeout) + */ +int +mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) +{ + ConfigPageHeader_t hdr; + CONFIGPARMS cfg; + FCPortPage0_t *ppage0_alloc; + FCPortPage0_t *pp0dest; + dma_addr_t page0_dma; + int data_sz; + int copy_sz; + int rc; + int count = 400; + + + /* Get FCPort Page 0 header */ + hdr.PageVersion = 0; + hdr.PageLength = 0; + hdr.PageNumber = 0; + hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; + cfg.cfghdr.hdr = &hdr; + cfg.physAddr = -1; + cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; + cfg.dir = 0; + cfg.pageAddr = portnum; + cfg.timeout = 0; + + if ((rc = mpt_config(ioc, &cfg)) != 0) + return rc; + + if (hdr.PageLength == 0) + return 0; + + data_sz = hdr.PageLength * 4; + rc = -ENOMEM; + ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); + if (ppage0_alloc) { + + try_again: + memset((u8 *)ppage0_alloc, 0, data_sz); + cfg.physAddr = page0_dma; + cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + + if ((rc = mpt_config(ioc, &cfg)) == 0) { + /* save the data */ + pp0dest = &ioc->fc_port_page0[portnum]; + copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz); + memcpy(pp0dest, ppage0_alloc, copy_sz); + + /* + * Normalize endianness of structure data, + * by byte-swapping all > 1 byte fields! + */ + pp0dest->Flags = le32_to_cpu(pp0dest->Flags); + pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier); + pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low); + pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High); + pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low); + pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High); + pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass); + pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds); + pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed); + pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize); + pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low); + pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High); + pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low); + pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High); + pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount); + pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators); + + /* + * if still doing discovery, + * hang loose a while until finished + */ + if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) { + if (count-- > 0) { + msleep_interruptible(100); + goto try_again; + } + printk(MYIOC_s_INFO_FMT "Firmware discovery not" + " complete.\n", + ioc->name); + } + } + + pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); + } + + return rc; +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table @@ -6365,6 +6467,7 @@ EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mptbase_sas_persist_operation); +EXPORT_SYMBOL(mptbase_GetFcPortPage0); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index 4720f9ae86aa..f673cca507e1 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.03.10" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10" +#define MPT_LINUX_VERSION_COMMON "3.03.09" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -487,15 +487,6 @@ typedef struct _RaidCfgData { int isRaid; /* bit field, 1 if RAID */ }RaidCfgData; -typedef struct _FcCfgData { - /* will ultimately hold fc_port_page0 also */ - struct { - FCPortPage1_t *data; - dma_addr_t dma; - int pg_sz; - } fc_port_page1[2]; -} FcCfgData; - #define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ #define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ @@ -574,7 +565,6 @@ typedef struct _MPT_ADAPTER SpiCfgData spi_data; /* Scsi config. data */ RaidCfgData raid_data; /* Raid config. data */ SasCfgData sas_data; /* Sas config. data */ - FcCfgData fc_data; /* Fc config. data */ MPT_IOCTL *ioctl; /* ioctl data pointer */ struct proc_dir_entry *ioc_dentry; struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ @@ -635,7 +625,6 @@ typedef struct _MPT_ADAPTER int num_ports; struct work_struct mptscsih_persistTask; - struct work_struct fc_setup_reset_work; struct list_head fc_rports; spinlock_t fc_rescan_work_lock; int fc_rescan_work_count; @@ -1038,6 +1027,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); +extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); /* * Public data decl's... diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 3ff8378ea660..856487741ef4 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -169,6 +169,13 @@ static struct fc_function_template mptfc_transport_functions = { }; +/* FIXME! values controlling firmware RESCAN event + * need to be set low to allow dev_loss_tmo to + * work as expected. Currently, firmware doesn't + * notify driver of RESCAN event until some number + * of seconds elapse. This value can be set via + * lsiutil. + */ static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { @@ -305,8 +312,10 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, } out: - kfree(pp0_array); - kfree(p0_array); + if (pp0_array) + kfree(pp0_array); + if (p0_array) + kfree(p0_array); return rc; } @@ -578,266 +587,15 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) #ifdef DMPT_DEBUG_FC if (unlikely(err)) { dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero, (%x).\n", + "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n", ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name, ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no, - SCpnt->device->id,SCpnt->device->lun,err)); + SCpnt->device->id,SCpnt->device->lun)); } #endif return err; } -/* - * mptfc_GetFcPortPage0 - Fetch FCPort config Page0. - * @ioc: Pointer to MPT_ADAPTER structure - * @portnum: IOC Port number - * - * Return: 0 for success - * -ENOMEM if no memory available - * -EPERM if not allowed due to ISR context - * -EAGAIN if no msg frames currently available - * -EFAULT for non-successful reply or no reply (timeout) - * -EINVAL portnum arg out of range (hardwired to two elements) - */ -static int -mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) -{ - ConfigPageHeader_t hdr; - CONFIGPARMS cfg; - FCPortPage0_t *ppage0_alloc; - FCPortPage0_t *pp0dest; - dma_addr_t page0_dma; - int data_sz; - int copy_sz; - int rc; - int count = 400; - - if (portnum > 1) - return -EINVAL; - - /* Get FCPort Page 0 header */ - hdr.PageVersion = 0; - hdr.PageLength = 0; - hdr.PageNumber = 0; - hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; - cfg.cfghdr.hdr = &hdr; - cfg.physAddr = -1; - cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; - cfg.dir = 0; - cfg.pageAddr = portnum; - cfg.timeout = 0; - - if ((rc = mpt_config(ioc, &cfg)) != 0) - return rc; - - if (hdr.PageLength == 0) - return 0; - - data_sz = hdr.PageLength * 4; - rc = -ENOMEM; - ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); - if (ppage0_alloc) { - - try_again: - memset((u8 *)ppage0_alloc, 0, data_sz); - cfg.physAddr = page0_dma; - cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - - if ((rc = mpt_config(ioc, &cfg)) == 0) { - /* save the data */ - pp0dest = &ioc->fc_port_page0[portnum]; - copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz); - memcpy(pp0dest, ppage0_alloc, copy_sz); - - /* - * Normalize endianness of structure data, - * by byte-swapping all > 1 byte fields! - */ - pp0dest->Flags = le32_to_cpu(pp0dest->Flags); - pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier); - pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low); - pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High); - pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low); - pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High); - pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass); - pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds); - pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed); - pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize); - pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low); - pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High); - pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low); - pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High); - pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount); - pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators); - - /* - * if still doing discovery, - * hang loose a while until finished - */ - if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) { - if (count-- > 0) { - msleep(100); - goto try_again; - } - printk(MYIOC_s_INFO_FMT "Firmware discovery not" - " complete.\n", - ioc->name); - } - } - - pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); - } - - return rc; -} - -static int -mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum) -{ - ConfigPageHeader_t hdr; - CONFIGPARMS cfg; - int rc; - - if (portnum > 1) - return -EINVAL; - - if (!(ioc->fc_data.fc_port_page1[portnum].data)) - return -EINVAL; - - /* get fcport page 1 header */ - hdr.PageVersion = 0; - hdr.PageLength = 0; - hdr.PageNumber = 1; - hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; - cfg.cfghdr.hdr = &hdr; - cfg.physAddr = -1; - cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; - cfg.dir = 0; - cfg.pageAddr = portnum; - cfg.timeout = 0; - - if ((rc = mpt_config(ioc, &cfg)) != 0) - return rc; - - if (hdr.PageLength == 0) - return -ENODEV; - - if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz) - return -EINVAL; - - cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma; - cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; - cfg.dir = 1; - - rc = mpt_config(ioc, &cfg); - - return rc; -} - -static int -mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum) -{ - ConfigPageHeader_t hdr; - CONFIGPARMS cfg; - FCPortPage1_t *page1_alloc; - dma_addr_t page1_dma; - int data_sz; - int rc; - - if (portnum > 1) - return -EINVAL; - - /* get fcport page 1 header */ - hdr.PageVersion = 0; - hdr.PageLength = 0; - hdr.PageNumber = 1; - hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; - cfg.cfghdr.hdr = &hdr; - cfg.physAddr = -1; - cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; - cfg.dir = 0; - cfg.pageAddr = portnum; - cfg.timeout = 0; - - if ((rc = mpt_config(ioc, &cfg)) != 0) - return rc; - - if (hdr.PageLength == 0) - return -ENODEV; - -start_over: - - if (ioc->fc_data.fc_port_page1[portnum].data == NULL) { - data_sz = hdr.PageLength * 4; - if (data_sz < sizeof(FCPortPage1_t)) - data_sz = sizeof(FCPortPage1_t); - - page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev, - data_sz, - &page1_dma); - if (!page1_alloc) - return -ENOMEM; - } - else { - page1_alloc = ioc->fc_data.fc_port_page1[portnum].data; - page1_dma = ioc->fc_data.fc_port_page1[portnum].dma; - data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz; - if (hdr.PageLength * 4 > data_sz) { - ioc->fc_data.fc_port_page1[portnum].data = NULL; - pci_free_consistent(ioc->pcidev, data_sz, (u8 *) - page1_alloc, page1_dma); - goto start_over; - } - } - - memset(page1_alloc,0,data_sz); - - cfg.physAddr = page1_dma; - cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; - - if ((rc = mpt_config(ioc, &cfg)) == 0) { - ioc->fc_data.fc_port_page1[portnum].data = page1_alloc; - ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz; - ioc->fc_data.fc_port_page1[portnum].dma = page1_dma; - } - else { - ioc->fc_data.fc_port_page1[portnum].data = NULL; - pci_free_consistent(ioc->pcidev, data_sz, (u8 *) - page1_alloc, page1_dma); - } - - return rc; -} - -static void -mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc) -{ - int ii; - FCPortPage1_t *pp1; - - #define MPTFC_FW_DEVICE_TIMEOUT (1) - #define MPTFC_FW_IO_PEND_TIMEOUT (1) - #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY) - #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS) - - for (ii=0; iifacts.NumberOfPorts; ii++) { - if (mptfc_GetFcPortPage1(ioc, ii) != 0) - continue; - pp1 = ioc->fc_data.fc_port_page1[ii].data; - if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT) - && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT) - && ((pp1->Flags & ON_FLAGS) == ON_FLAGS) - && ((pp1->Flags & OFF_FLAGS) == 0)) - continue; - pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT; - pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT; - pp1->Flags &= ~OFF_FLAGS; - pp1->Flags |= ON_FLAGS; - mptfc_WriteFcPortPage1(ioc, ii); - } -} - - static void mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) { @@ -870,31 +628,6 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN; } -static void -mptfc_setup_reset(void *arg) -{ - MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; - u64 pn; - struct mptfc_rport_info *ri; - - /* reset about to happen, delete (block) all rports */ - list_for_each_entry(ri, &ioc->fc_rports, list) { - if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { - ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED; - fc_remote_port_delete(ri->rport); /* won't sleep */ - ri->rport = NULL; - - pn = (u64)ri->pg0.WWPN.High << 32 | - (u64)ri->pg0.WWPN.Low; - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_setup_reset.%d: %llx deleted\n", - ioc->name, - ioc->sh->host_no, - (unsigned long long)pn)); - } - } -} - static void mptfc_rescan_devices(void *arg) { @@ -918,7 +651,7 @@ mptfc_rescan_devices(void *arg) * will reregister existing rports */ for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { - (void) mptfc_GetFcPortPage0(ioc, ii); + (void) mptbase_GetFcPortPage0(ioc, ii); mptfc_init_host_attr(ioc,ii); /* refresh */ mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); } @@ -1020,9 +753,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_mptfc_probe; } - spin_lock_init(&ioc->fc_rescan_work_lock); INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc); - INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc); spin_lock_irqsave(&ioc->FreeQlock, flags); @@ -1157,15 +888,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!ioc->fc_rescan_work_q) goto out_mptfc_probe; - /* - * Pre-fetch FC port WWN and stuff... - * (FCPortPage0_t stuff) - */ - for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { - (void) mptfc_GetFcPortPage0(ioc, ii); - } - mptfc_SetFcPortPage1_defaults(ioc); - /* * scan for rports - * by doing it via the workqueue, some locking is eliminated @@ -1195,81 +917,6 @@ static struct pci_driver mptfc_driver = { #endif }; -static int -mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) -{ - MPT_SCSI_HOST *hd; - u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; - unsigned long flags; - int rc=1; - - devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", - ioc->name, event)); - - if (ioc->sh == NULL || - ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) - return 1; - - switch (event) { - case MPI_EVENT_RESCAN: - spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } - spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); - break; - default: - rc = mptscsih_event_process(ioc,pEvReply); - break; - } - return rc; -} - -static int -mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) -{ - int rc; - unsigned long flags; - - rc = mptscsih_ioc_reset(ioc,reset_phase); - if (rc == 0) - return rc; - - - dtmprintk((KERN_WARNING MYNAM - ": IOC %s_reset routed to FC host driver!\n", - reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( - reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - - if (reset_phase == MPT_IOC_SETUP_RESET) { - spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_setup_reset_work); - } - spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); - } - - else if (reset_phase == MPT_IOC_PRE_RESET) { - } - - else { /* MPT_IOC_POST_RESET */ - mptfc_SetFcPortPage1_defaults(ioc); - spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); - if (ioc->fc_rescan_work_q) { - if (ioc->fc_rescan_work_count++ == 0) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); - } - } - spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); - } - return 1; -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptfc_init - Register MPT adapter(s) as SCSI host(s) with @@ -1284,8 +931,8 @@ mptfc_init(void) show_mptmod_ver(my_NAME, my_VERSION); - /* sanity check module parameters */ - if (mptfc_dev_loss_tmo <= 0) + /* sanity check module parameter */ + if (mptfc_dev_loss_tmo == 0) mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; mptfc_transport_template = @@ -1298,12 +945,12 @@ mptfc_init(void) mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); - if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) { + if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { devtverboseprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n")); } - if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) { + if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n")); } @@ -1328,7 +975,6 @@ mptfc_remove(struct pci_dev *pdev) struct mptfc_rport_info *p, *n; struct workqueue_struct *work_q; unsigned long flags; - int ii; /* destroy workqueue */ if ((work_q=ioc->fc_rescan_work_q)) { @@ -1345,16 +991,6 @@ mptfc_remove(struct pci_dev *pdev) kfree(p); } - for (ii=0; iifacts.NumberOfPorts; ii++) { - if (ioc->fc_data.fc_port_page1[ii].data) { - pci_free_consistent(ioc->pcidev, - ioc->fc_data.fc_port_page1[ii].pg_sz, - (u8 *) ioc->fc_data.fc_port_page1[ii].data, - ioc->fc_data.fc_port_page1[ii].dma); - ioc->fc_data.fc_port_page1[ii].data = NULL; - } - } - mptscsih_remove(pdev); } diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 85689ab46cbc..af6ec553ff7c 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -1378,7 +1378,8 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) return 0; out_free_port_info: - kfree(hba); + if (hba) + kfree(hba); out: return error; } diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index 8242b16e3168..84fa271eb8f4 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -1922,7 +1922,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) break; } spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); - msleep(250); + msleep_interruptible(250); } while (--loop_count); return status; @@ -2521,6 +2521,18 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) hd->cmdPtr = NULL; } + /* 7. FC: Rescan for blocked rports which might have returned. + */ + if (ioc->bus_type == FC) { + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); + if (ioc->fc_rescan_work_q) { + if (ioc->fc_rescan_work_count++ == 0) { + queue_work(ioc->fc_rescan_work_q, + &ioc->fc_rescan_work); + } + } + spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + } dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); } @@ -2534,6 +2546,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) { MPT_SCSI_HOST *hd; u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; + unsigned long flags; devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", ioc->name, event)); @@ -2556,6 +2569,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) break; case MPI_EVENT_RESCAN: /* 06 */ + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); + if (ioc->fc_rescan_work_q) { + if (ioc->fc_rescan_work_count++ == 0) { + queue_work(ioc->fc_rescan_work_q, + &ioc->fc_rescan_work); + } + } + spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); break; /* diff --git a/trunk/drivers/message/i2o/i2o_scsi.c b/trunk/drivers/message/i2o/i2o_scsi.c index 6ebf38213f9f..c08ddac3717d 100644 --- a/trunk/drivers/message/i2o/i2o_scsi.c +++ b/trunk/drivers/message/i2o/i2o_scsi.c @@ -65,7 +65,9 @@ #include #include #include +#include #include +#include #define OSM_NAME "scsi-osm" #define OSM_VERSION "1.316" @@ -586,7 +588,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, mptr = &msg->body[0]; -#if 0 /* this code can't work */ #ifdef CONFIG_I2O_EXT_ADAPTEC if (c->adaptec) { u32 adpt_flags = 0; @@ -623,7 +624,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC); *mptr++ = cpu_to_le32(adpt_flags | tid); } -#endif #endif msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid); diff --git a/trunk/drivers/message/i2o/iop.c b/trunk/drivers/message/i2o/iop.c index c74e5460f834..febbdd4e0605 100644 --- a/trunk/drivers/message/i2o/iop.c +++ b/trunk/drivers/message/i2o/iop.c @@ -1239,6 +1239,7 @@ EXPORT_SYMBOL(i2o_cntxt_list_remove); EXPORT_SYMBOL(i2o_cntxt_list_get_ptr); #endif EXPORT_SYMBOL(i2o_msg_get_wait); +EXPORT_SYMBOL(i2o_msg_nop); EXPORT_SYMBOL(i2o_find_iop); EXPORT_SYMBOL(i2o_iop_find_device); EXPORT_SYMBOL(i2o_event_register); diff --git a/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index c8426a9bf273..aff83f966803 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -420,10 +420,8 @@ static int ucb1x00_detect_irq(struct ucb1x00 *ucb) unsigned long mask; mask = probe_irq_on(); - if (!mask) { - probe_irq_off(mask); + if (!mask) return NO_IRQ; - } /* * Enable the ADC interrupt. diff --git a/trunk/drivers/misc/ibmasm/ibmasmfs.c b/trunk/drivers/misc/ibmasm/ibmasmfs.c index 4a35caff5d02..26a230b6ff80 100644 --- a/trunk/drivers/misc/ibmasm/ibmasmfs.c +++ b/trunk/drivers/misc/ibmasm/ibmasmfs.c @@ -90,11 +90,10 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root); static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent); -static int ibmasmfs_get_super(struct file_system_type *fst, - int flags, const char *name, void *data, - struct vfsmount *mnt) +static struct super_block *ibmasmfs_get_super(struct file_system_type *fst, + int flags, const char *name, void *data) { - return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt); + return get_sb_single(fst, flags, data, ibmasmfs_fill_super); } static struct super_operations ibmasmfs_s_ops = { diff --git a/trunk/drivers/misc/ibmasm/module.c b/trunk/drivers/misc/ibmasm/module.c index 9706cc19134a..1fdf03fd2da7 100644 --- a/trunk/drivers/misc/ibmasm/module.c +++ b/trunk/drivers/misc/ibmasm/module.c @@ -85,7 +85,7 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi } memset(sp, 0, sizeof(struct service_processor)); - spin_lock_init(&sp->lock); + sp->lock = SPIN_LOCK_UNLOCKED; INIT_LIST_HEAD(&sp->command_queue); pci_set_drvdata(pdev, (void *)sp); diff --git a/trunk/drivers/mmc/at91_mci.c b/trunk/drivers/mmc/at91_mci.c index 3228516b7d19..88f0eef9cf33 100644 --- a/trunk/drivers/mmc/at91_mci.c +++ b/trunk/drivers/mmc/at91_mci.c @@ -81,6 +81,13 @@ #undef SUPPORT_4WIRE +#ifdef CONFIG_MMC_DEBUG +#define DBG(fmt...) \ + printk(fmt) +#else +#define DBG(fmt...) do { } while (0) +#endif + static struct clk *mci_clk; #define FL_SENT_COMMAND (1 << 0) @@ -195,50 +202,50 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) struct mmc_command *cmd; struct mmc_data *data; - pr_debug("pre dma read\n"); + DBG("pre dma read\n"); cmd = host->cmd; if (!cmd) { - pr_debug("no command\n"); + DBG("no command\n"); return; } data = cmd->data; if (!data) { - pr_debug("no data\n"); + DBG("no data\n"); return; } for (i = 0; i < 2; i++) { /* nothing left to transfer */ if (host->transfer_index >= data->sg_len) { - pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index); + DBG("Nothing left to transfer (index = %d)\n", host->transfer_index); break; } /* Check to see if this needs filling */ if (i == 0) { if (at91_mci_read(AT91_PDC_RCR) != 0) { - pr_debug("Transfer active in current\n"); + DBG("Transfer active in current\n"); continue; } } else { if (at91_mci_read(AT91_PDC_RNCR) != 0) { - pr_debug("Transfer active in next\n"); + DBG("Transfer active in next\n"); continue; } } /* Setup the next transfer */ - pr_debug("Using transfer index %d\n", host->transfer_index); + DBG("Using transfer index %d\n", host->transfer_index); sg = &data->sg[host->transfer_index++]; - pr_debug("sg = %p\n", sg); + DBG("sg = %p\n", sg); sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE); - pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); + DBG("dma address = %08X, length = %d\n", sg->dma_address, sg->length); if (i == 0) { at91_mci_write(AT91_PDC_RPR, sg->dma_address); @@ -250,7 +257,7 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) } } - pr_debug("pre dma read done\n"); + DBG("pre dma read done\n"); } /* @@ -261,17 +268,17 @@ static void at91mci_post_dma_read(struct at91mci_host *host) struct mmc_command *cmd; struct mmc_data *data; - pr_debug("post dma read\n"); + DBG("post dma read\n"); cmd = host->cmd; if (!cmd) { - pr_debug("no command\n"); + DBG("no command\n"); return; } data = cmd->data; if (!data) { - pr_debug("no data\n"); + DBG("no data\n"); return; } @@ -282,17 +289,17 @@ static void at91mci_post_dma_read(struct at91mci_host *host) struct scatterlist *sg; - pr_debug("finishing index %d\n", host->in_use_index); + DBG("finishing index %d\n", host->in_use_index); sg = &data->sg[host->in_use_index++]; - pr_debug("Unmapping page %08X\n", sg->dma_address); + DBG("Unmapping page %08X\n", sg->dma_address); dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); /* Swap the contents of the buffer */ buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; - pr_debug("buffer = %p, length = %d\n", buffer, sg->length); + DBG("buffer = %p, length = %d\n", buffer, sg->length); data->bytes_xfered += sg->length; @@ -313,7 +320,7 @@ static void at91mci_post_dma_read(struct at91mci_host *host) at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); } - pr_debug("post dma read done\n"); + DBG("post dma read done\n"); } /* @@ -324,7 +331,7 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) struct mmc_command *cmd; struct mmc_data *data; - pr_debug("Handling the transmit\n"); + DBG("Handling the transmit\n"); /* Disable the transfer */ at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); @@ -380,12 +387,12 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ /* Not sure if this is needed */ #if 0 if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { - pr_debug("Clearing timeout\n"); + DBG("Clearing timeout\n"); at91_mci_write(AT91_MCI_ARGR, 0); at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD); while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) { /* spin */ - pr_debug("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR)); + DBG("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR)); } } #endif @@ -404,7 +411,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ } if (data) { - block_length = data->blksz; + block_length = 1 << data->blksz_bits; blocks = data->blocks; /* always set data start - also set direction flag for read */ @@ -432,7 +439,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ /* * Set the arguments and send the command */ - pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n", + DBG("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n", cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR)); if (!data) { @@ -484,7 +491,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ at91mci_sg_to_dma(host, data); - pr_debug("Transmitting %d bytes\n", host->total_length); + DBG("Transmitting %d bytes\n", host->total_length); at91_mci_write(AT91_PDC_TPR, host->physical_address); at91_mci_write(AT91_PDC_TCR, host->total_length / 4); @@ -518,7 +525,7 @@ static void at91mci_process_command(struct at91mci_host *host, struct mmc_comman ier = at91_mci_send_command(host, cmd); - pr_debug("setting ier to %08X\n", ier); + DBG("setting ier to %08X\n", ier); /* Stop on errors or the required value */ at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier); @@ -563,7 +570,7 @@ static void at91mci_completed_command(struct at91mci_host *host) status = at91_mci_read(AT91_MCI_SR); - pr_debug("Status = %08X [%08X %08X %08X %08X]\n", + DBG("Status = %08X [%08X %08X %08X %08X]\n", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE | @@ -583,7 +590,7 @@ static void at91mci_completed_command(struct at91mci_host *host) else cmd->error = MMC_ERR_FAILED; - pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n", + DBG("Error detected and set to %d (cmd = %d, retries = %d)\n", cmd->error, cmd->opcode, cmd->retries); } } @@ -614,7 +621,10 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct at91mci_host *host = mmc_priv(mmc); unsigned long at91_master_clock = clk_get_rate(mci_clk); - host->bus_mode = ios->bus_mode; + if (host) + host->bus_mode = ios->bus_mode; + else + printk("MMC: No host for bus_mode\n"); if (ios->clock == 0) { /* Disable the MCI controller */ @@ -630,15 +640,15 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) else clkdiv = (at91_master_clock / ios->clock) / 2; - pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv, + DBG("clkdiv = %d. mcck = %ld\n", clkdiv, at91_master_clock / (2 * (clkdiv + 1))); } if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { - pr_debug("MMC: Setting controller bus width to 4\n"); + DBG("MMC: Setting controller bus width to 4\n"); at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS); } else { - pr_debug("MMC: Setting controller bus width to 1\n"); + DBG("MMC: Setting controller bus width to 1\n"); at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); } @@ -646,7 +656,7 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); /* maybe switch power to the card */ - if (host->board->vcc_pin) { + if (host && host->board->vcc_pin) { switch (ios->power_mode) { case MMC_POWER_OFF: at91_set_gpio_output(host->board->vcc_pin, 0); @@ -669,8 +679,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs) unsigned int int_status; + if (host == NULL) + return IRQ_HANDLED; + int_status = at91_mci_read(AT91_MCI_SR); - pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR), + DBG("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR), int_status & at91_mci_read(AT91_MCI_IMR)); if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000) @@ -679,75 +692,75 @@ static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs) int_status &= at91_mci_read(AT91_MCI_IMR); if (int_status & AT91_MCI_UNRE) - pr_debug("MMC: Underrun error\n"); + DBG("MMC: Underrun error\n"); if (int_status & AT91_MCI_OVRE) - pr_debug("MMC: Overrun error\n"); + DBG("MMC: Overrun error\n"); if (int_status & AT91_MCI_DTOE) - pr_debug("MMC: Data timeout\n"); + DBG("MMC: Data timeout\n"); if (int_status & AT91_MCI_DCRCE) - pr_debug("MMC: CRC error in data\n"); + DBG("MMC: CRC error in data\n"); if (int_status & AT91_MCI_RTOE) - pr_debug("MMC: Response timeout\n"); + DBG("MMC: Response timeout\n"); if (int_status & AT91_MCI_RENDE) - pr_debug("MMC: Response end bit error\n"); + DBG("MMC: Response end bit error\n"); if (int_status & AT91_MCI_RCRCE) - pr_debug("MMC: Response CRC error\n"); + DBG("MMC: Response CRC error\n"); if (int_status & AT91_MCI_RDIRE) - pr_debug("MMC: Response direction error\n"); + DBG("MMC: Response direction error\n"); if (int_status & AT91_MCI_RINDE) - pr_debug("MMC: Response index error\n"); + DBG("MMC: Response index error\n"); /* Only continue processing if no errors */ if (!completed) { if (int_status & AT91_MCI_TXBUFE) { - pr_debug("TX buffer empty\n"); + DBG("TX buffer empty\n"); at91_mci_handle_transmitted(host); } if (int_status & AT91_MCI_RXBUFF) { - pr_debug("RX buffer full\n"); + DBG("RX buffer full\n"); at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); } if (int_status & AT91_MCI_ENDTX) { - pr_debug("Transmit has ended\n"); + DBG("Transmit has ended\n"); } if (int_status & AT91_MCI_ENDRX) { - pr_debug("Receive has ended\n"); + DBG("Receive has ended\n"); at91mci_post_dma_read(host); } if (int_status & AT91_MCI_NOTBUSY) { - pr_debug("Card is ready\n"); + DBG("Card is ready\n"); at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); } if (int_status & AT91_MCI_DTIP) { - pr_debug("Data transfer in progress\n"); + DBG("Data transfer in progress\n"); } if (int_status & AT91_MCI_BLKE) { - pr_debug("Block transfer has ended\n"); + DBG("Block transfer has ended\n"); } if (int_status & AT91_MCI_TXRDY) { - pr_debug("Ready to transmit\n"); + DBG("Ready to transmit\n"); } if (int_status & AT91_MCI_RXRDY) { - pr_debug("Ready to receive\n"); + DBG("Ready to receive\n"); } if (int_status & AT91_MCI_CMDRDY) { - pr_debug("Command ready\n"); + DBG("Command ready\n"); completed = 1; } } at91_mci_write(AT91_MCI_IDR, int_status); if (completed) { - pr_debug("Completed command\n"); + DBG("Completed command\n"); at91_mci_write(AT91_MCI_IDR, 0xffffffff); at91mci_completed_command(host); } @@ -766,10 +779,10 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs) */ if (present != host->present) { host->present = present; - pr_debug("%s: card %s\n", mmc_hostname(host->mmc), + DBG("%s: card %s\n", mmc_hostname(host->mmc), present ? "insert" : "remove"); if (!present) { - pr_debug("****** Resetting SD-card bus width ******\n"); + DBG("****** Resetting SD-card bus width ******\n"); at91_mci_write(AT91_MCI_SDCR, 0); } mmc_detect_change(host->mmc, msecs_to_jiffies(100)); @@ -809,13 +822,13 @@ static int at91_mci_probe(struct platform_device *pdev) struct at91mci_host *host; int ret; - pr_debug("Probe MCI devices\n"); + DBG("Probe MCI devices\n"); at91_mci_disable(); at91_mci_enable(); mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); if (!mmc) { - pr_debug("Failed to allocate mmc host\n"); + DBG("Failed to allocate mmc host\n"); return -ENOMEM; } @@ -841,9 +854,8 @@ static int at91_mci_probe(struct platform_device *pdev) * Get Clock */ mci_clk = clk_get(&pdev->dev, "mci_clk"); - if (IS_ERR(mci_clk)) { + if (!mci_clk) { printk(KERN_ERR "AT91 MMC: no clock defined.\n"); - mmc_free_host(mmc); return -ENODEV; } clk_enable(mci_clk); /* Enable the peripheral clock */ @@ -853,10 +865,7 @@ static int at91_mci_probe(struct platform_device *pdev) */ ret = request_irq(AT91_ID_MCI, at91_mci_irq, SA_SHIRQ, DRIVER_NAME, host); if (ret) { - printk(KERN_ERR "Failed to request MCI interrupt\n"); - clk_disable(mci_clk); - clk_put(mci_clk); - mmc_free_host(mmc); + DBG("Failed to request MCI interrupt\n"); return ret; } @@ -877,12 +886,12 @@ static int at91_mci_probe(struct platform_device *pdev) */ if (host->board->det_pin) { ret = request_irq(host->board->det_pin, at91_mmc_det_irq, - 0, DRIVER_NAME, host); + SA_SAMPLE_RANDOM, DRIVER_NAME, host); if (ret) - printk(KERN_ERR "couldn't allocate MMC detect irq\n"); + DBG("couldn't allocate MMC detect irq\n"); } - pr_debug(KERN_INFO "Added MCI driver\n"); + DBG(KERN_INFO "Added MCI driver\n"); return 0; } @@ -915,7 +924,7 @@ static int at91_mci_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - pr_debug("MCI Removed\n"); + DBG("Removed\n"); return 0; } diff --git a/trunk/drivers/mmc/imxmmc.c b/trunk/drivers/mmc/imxmmc.c index 5c62f4e6ad06..a4eb1d0e7a71 100644 --- a/trunk/drivers/mmc/imxmmc.c +++ b/trunk/drivers/mmc/imxmmc.c @@ -228,7 +228,7 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host, static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data) { unsigned int nob = data->blocks; - unsigned int blksz = data->blksz; + unsigned int blksz = 1 << data->blksz_bits; unsigned int datasz = nob * blksz; int i; diff --git a/trunk/drivers/mmc/omap.c b/trunk/drivers/mmc/omap.c index c25244b3657b..becb3c68c34d 100644 --- a/trunk/drivers/mmc/omap.c +++ b/trunk/drivers/mmc/omap.c @@ -584,10 +584,10 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) int sync_dev = 0; data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA; - frame = data->blksz; + frame = 1 << data->blksz_bits; count = sg_dma_len(sg); - if ((data->blocks == 1) && (count > data->blksz)) + if ((data->blocks == 1) && (count > (1 << data->blksz_bits))) count = frame; host->dma_len = count; @@ -776,7 +776,7 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) } - block_size = data->blksz; + block_size = 1 << data->blksz_bits; OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1); OMAP_MMC_WRITE(host->base, BLEN, block_size - 1); diff --git a/trunk/drivers/mmc/sdhci.c b/trunk/drivers/mmc/sdhci.c index 8e9100bd57ef..6bfcdbc7491e 100644 --- a/trunk/drivers/mmc/sdhci.c +++ b/trunk/drivers/mmc/sdhci.c @@ -268,7 +268,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) } DBG("blksz %04x blks %04x flags %08x\n", - data->blksz, data->blocks, data->flags); + 1 << data->blksz_bits, data->blocks, data->flags); DBG("tsac %d ms nsac %d clk\n", data->timeout_ns / 1000000, data->timeout_clks); @@ -282,7 +282,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); - writew(data->blksz, host->ioaddr + SDHCI_BLOCK_SIZE); + writew(1 << data->blksz_bits, host->ioaddr + SDHCI_BLOCK_SIZE); writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); if (host->flags & SDHCI_USE_DMA) { @@ -294,7 +294,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); } else { - host->size = data->blksz * data->blocks; + host->size = (1 << data->blksz_bits) * data->blocks; host->cur_sg = data->sg; host->num_sg = data->sg_len; @@ -335,7 +335,7 @@ static void sdhci_finish_data(struct sdhci_host *host) blocks = 0; else blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); - data->bytes_xfered = data->blksz * (data->blocks - blocks); + data->bytes_xfered = (1 << data->blksz_bits) * (data->blocks - blocks); if ((data->error == MMC_ERR_NONE) && blocks) { printk(KERN_ERR "%s: Controller signalled completion even " diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index 1344ad7a4b14..5ac265dde423 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -86,14 +86,14 @@ config MTD_REDBOOT_DIRECTORY_BLOCK block and "-2" means the penultimate block. config MTD_REDBOOT_PARTS_UNALLOCATED - bool "Include unallocated flash regions" + bool " Include unallocated flash regions" depends on MTD_REDBOOT_PARTS help If you need to register each unallocated flash region as a MTD 'partition', enable this option. config MTD_REDBOOT_PARTS_READONLY - bool "Force read-only for RedBoot system images" + bool " Force read-only for RedBoot system images" depends on MTD_REDBOOT_PARTS help If you need to force read-only for 'RedBoot', 'RedBoot Config' and diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index 83d0b2a52527..6bdaacc6d6f9 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -212,7 +212,7 @@ config MTD_NETtel Support for flash chips on NETtel/SecureEdge/SnapGear boards. config MTD_ALCHEMY - tristate "AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support" + tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' depends on SOC_AU1X00 help Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards diff --git a/trunk/drivers/mtd/maps/sun_uflash.c b/trunk/drivers/mtd/maps/sun_uflash.c index 24a03152d196..0758cb1d0105 100644 --- a/trunk/drivers/mtd/maps/sun_uflash.c +++ b/trunk/drivers/mtd/maps/sun_uflash.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -31,140 +30,146 @@ #define UFLASH_WINDOW_SIZE 0x200000 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */ -MODULE_AUTHOR("Eric Brower "); -MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets"); -MODULE_SUPPORTED_DEVICE("userflash"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("2.0"); +MODULE_AUTHOR + ("Eric Brower "); +MODULE_DESCRIPTION + ("User-programmable flash device on Sun Microsystems boardsets"); +MODULE_SUPPORTED_DEVICE + ("userflash"); +MODULE_LICENSE + ("GPL"); static LIST_HEAD(device_list); struct uflash_dev { - char *name; /* device name */ + char * name; /* device name */ struct map_info map; /* mtd map info */ - struct mtd_info *mtd; /* mtd info */ + struct mtd_info * mtd; /* mtd info */ + struct list_head list; }; struct map_info uflash_map_templ = { - .name = "SUNW,???-????", - .size = UFLASH_WINDOW_SIZE, - .bankwidth = UFLASH_BUSWIDTH, + .name = "SUNW,???-????", + .size = UFLASH_WINDOW_SIZE, + .bankwidth = UFLASH_BUSWIDTH, }; -int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp) +int uflash_devinit(struct linux_ebus_device* edev) { - struct uflash_dev *up; - struct resource *res; + int iTmp, nregs; + struct linux_prom_registers regs[2]; + struct uflash_dev *pdev; + + iTmp = prom_getproperty( + edev->prom_node, "reg", (void *)regs, sizeof(regs)); + if ((iTmp % sizeof(regs[0])) != 0) { + printk("%s: Strange reg property size %d\n", + UFLASH_DEVNAME, iTmp); + return -ENODEV; + } - res = &edev->resource[0]; + nregs = iTmp / sizeof(regs[0]); - if (edev->num_addrs != 1) { + if (nregs != 1) { /* Non-CFI userflash device-- once I find one we * can work on supporting it. */ printk("%s: unsupported device at 0x%lx (%d regs): " \ "email ebrower@usa.net\n", - dp->full_name, res->start, edev->num_addrs); - + UFLASH_DEVNAME, edev->resource[0].start, nregs); return -ENODEV; } - up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL); - if (!up) - return -ENOMEM; + if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) { + printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); + return(-ENOMEM); + } /* copy defaults and tweak parameters */ - memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ)); - up->map.size = (res->end - res->start) + 1UL; - - up->name = of_get_property(dp, "model", NULL); - if (up->name && 0 < strlen(up->name)) - up->map.name = up->name; - - up->map.phys = res->start; - - up->map.virt = ioremap_nocache(res->start, up->map.size); - if (!up->map.virt) { - printk("%s: Failed to map device.\n", dp->full_name); - kfree(up); - - return -EINVAL; + memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); + pdev->map.size = regs[0].reg_size; + + iTmp = prom_getproplen(edev->prom_node, "model"); + pdev->name = kmalloc(iTmp, GFP_KERNEL); + prom_getstring(edev->prom_node, "model", pdev->name, iTmp); + if(0 != pdev->name && 0 < strlen(pdev->name)) { + pdev->map.name = pdev->name; + } + pdev->map.phys = edev->resource[0].start; + pdev->map.virt = ioremap_nocache(edev->resource[0].start, pdev->map.size); + if(0 == pdev->map.virt) { + printk("%s: failed to map device\n", __FUNCTION__); + kfree(pdev->name); + kfree(pdev); + return(-1); } - simple_map_init(&up->map); + simple_map_init(&pdev->map); /* MTD registration */ - up->mtd = do_map_probe("cfi_probe", &up->map); - if (!up->mtd) { - iounmap(up->map.virt); - kfree(up); - - return -ENXIO; + pdev->mtd = do_map_probe("cfi_probe", &pdev->map); + if(0 == pdev->mtd) { + iounmap(pdev->map.virt); + kfree(pdev->name); + kfree(pdev); + return(-ENXIO); } - up->mtd->owner = THIS_MODULE; + list_add(&pdev->list, &device_list); - add_mtd_device(up->mtd); + pdev->mtd->owner = THIS_MODULE; - dev_set_drvdata(&edev->ofdev.dev, up); - - return 0; + add_mtd_device(pdev->mtd); + return(0); } -static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match) +static int __init uflash_init(void) { - struct linux_ebus_device *edev = to_ebus_device(&dev->dev); - struct device_node *dp = dev->node; + struct linux_ebus *ebus = NULL; + struct linux_ebus_device *edev = NULL; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) { + if(0 > prom_getproplen(edev->prom_node, "user")) { + DEBUG(2, "%s: ignoring device at 0x%lx\n", + UFLASH_DEVNAME, edev->resource[0].start); + } else { + uflash_devinit(edev); + } + } + } + } - if (of_find_property(dp, "user", NULL)) + if(list_empty(&device_list)) { + printk("%s: unable to locate device\n", UFLASH_DEVNAME); return -ENODEV; - - return uflash_devinit(edev, dp); -} - -static int __devexit uflash_remove(struct of_device *dev) -{ - struct uflash_dev *up = dev_get_drvdata(&dev->dev); - - if (up->mtd) { - del_mtd_device(up->mtd); - map_destroy(up->mtd); } - if (up->map.virt) { - iounmap(up->map.virt); - up->map.virt = NULL; - } - - kfree(up); - - return 0; + return(0); } -static struct of_device_id uflash_match[] = { - { - .name = UFLASH_OBPNAME, - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, uflash_match); - -static struct of_platform_driver uflash_driver = { - .name = UFLASH_DEVNAME, - .match_table = uflash_match, - .probe = uflash_probe, - .remove = __devexit_p(uflash_remove), -}; - -static int __init uflash_init(void) +static void __exit uflash_cleanup(void) { - return of_register_driver(&uflash_driver, &ebus_bus_type); -} - -static void __exit uflash_exit(void) -{ - of_unregister_driver(&uflash_driver); + struct list_head *udevlist; + struct uflash_dev *udev; + + list_for_each(udevlist, &device_list) { + udev = list_entry(udevlist, struct uflash_dev, list); + DEBUG(2, "%s: removing device %s\n", + UFLASH_DEVNAME, udev->name); + + if(0 != udev->mtd) { + del_mtd_device(udev->mtd); + map_destroy(udev->mtd); + } + if(0 != udev->map.virt) { + iounmap(udev->map.virt); + udev->map.virt = NULL; + } + kfree(udev->name); + kfree(udev); + } } module_init(uflash_init); -module_exit(uflash_exit); +module_exit(uflash_cleanup); diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 27083ed0a017..8df184f6d8d1 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -1176,7 +1176,7 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, status = chip->waitfunc(mtd, chip); - return status; + return status & NAND_STATUS_FAIL ? -EIO : 0; } /** @@ -1271,10 +1271,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); buf = nand_transfer_oob(chip, buf, ops); - readlen -= ops->ooblen; - if (!readlen) - break; - if (!(chip->options & NAND_NO_READRDY)) { /* * Apply delay or wait for ready/busy pin. Do this @@ -1288,6 +1284,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, nand_wait_ready(mtd); } + readlen -= ops->ooblen; + if (!readlen) + break; + /* Increment page address */ realpage++; diff --git a/trunk/drivers/net/3c501.c b/trunk/drivers/net/3c501.c index 07136ec423bd..bb44509fd404 100644 --- a/trunk/drivers/net/3c501.c +++ b/trunk/drivers/net/3c501.c @@ -508,11 +508,11 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) * speak of. We simply pull the packet out of its PIO buffer (which is slow) * and queue it for the kernel. Then we reset the card for the next packet. * - * We sometimes get surprise interrupts late both because the SMP IRQ delivery + * We sometimes get suprise interrupts late both because the SMP IRQ delivery * is message passing and because the card sometimes seems to deliver late. I * think if it is part way through a receive and the mode is changed it carries * on receiving and sends us an interrupt. We have to band aid all these cases - * to get a sensible 150kBytes/second performance. Even then you want a small + * to get a sensible 150kbytes/second performance. Even then you want a small * TCP window. */ diff --git a/trunk/drivers/net/3c527.c b/trunk/drivers/net/3c527.c index 157eda573925..1b1cb0026072 100644 --- a/trunk/drivers/net/3c527.c +++ b/trunk/drivers/net/3c527.c @@ -1031,7 +1031,8 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev) return 1; } - if (skb_padto(skb, ETH_ZLEN)) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) { netif_wake_queue(dev); return 0; } diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index 0cdc830449d8..46d8c01437e9 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -401,11 +401,6 @@ static void cp_clean_rings (struct cp_private *cp); #ifdef CONFIG_NET_POLL_CONTROLLER static void cp_poll_controller(struct net_device *dev); #endif -static int cp_get_eeprom_len(struct net_device *dev); -static int cp_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data); -static int cp_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data); static struct pci_device_id cp_pci_tbl[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, @@ -797,7 +792,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; @@ -1582,9 +1577,6 @@ static struct ethtool_ops cp_ethtool_ops = { .get_strings = cp_get_strings, .get_ethtool_stats = cp_get_ethtool_stats, .get_perm_addr = ethtool_op_get_perm_addr, - .get_eeprom_len = cp_get_eeprom_len, - .get_eeprom = cp_get_eeprom, - .set_eeprom = cp_set_eeprom, }; static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) @@ -1620,32 +1612,24 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) #define eeprom_delay() readl(ee_addr) /* The EEPROM commands include the alway-set leading bit. */ -#define EE_EXTEND_CMD (4) #define EE_WRITE_CMD (5) #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -#define EE_EWDS_ADDR (0) -#define EE_WRAL_ADDR (1) -#define EE_ERAL_ADDR (2) -#define EE_EWEN_ADDR (3) - -#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139 - -static void eeprom_cmd_start(void __iomem *ee_addr) +static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) { + int i; + unsigned retval = 0; + void __iomem *ee_addr = ioaddr + Cfg9346; + int read_cmd = location | (EE_READ_CMD << addr_len); + writeb (EE_ENB & ~EE_CS, ee_addr); writeb (EE_ENB, ee_addr); eeprom_delay (); -} -static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len) -{ - int i; - - /* Shift the command bits out. */ - for (i = cmd_len - 1; i >= 0; i--) { - int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0; + /* Shift the read command bits out. */ + for (i = 4 + addr_len; i >= 0; i--) { + int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; writeb (EE_ENB | dataval, ee_addr); eeprom_delay (); writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); @@ -1653,33 +1637,6 @@ static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len) } writeb (EE_ENB, ee_addr); eeprom_delay (); -} - -static void eeprom_cmd_end(void __iomem *ee_addr) -{ - writeb (~EE_CS, ee_addr); - eeprom_delay (); -} - -static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd, - int addr_len) -{ - int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2)); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, cmd, 3 + addr_len); - eeprom_cmd_end(ee_addr); -} - -static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len) -{ - int i; - u16 retval = 0; - void __iomem *ee_addr = ioaddr + Cfg9346; - int read_cmd = location | (EE_READ_CMD << addr_len); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, read_cmd, 3 + addr_len); for (i = 16; i > 0; i--) { writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); @@ -1691,125 +1648,13 @@ static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len) eeprom_delay (); } - eeprom_cmd_end(ee_addr); + /* Terminate the EEPROM access. */ + writeb (~EE_CS, ee_addr); + eeprom_delay (); return retval; } -static void write_eeprom(void __iomem *ioaddr, int location, u16 val, - int addr_len) -{ - int i; - void __iomem *ee_addr = ioaddr + Cfg9346; - int write_cmd = location | (EE_WRITE_CMD << addr_len); - - eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len); - - eeprom_cmd_start(ee_addr); - eeprom_cmd(ee_addr, write_cmd, 3 + addr_len); - eeprom_cmd(ee_addr, val, 16); - eeprom_cmd_end(ee_addr); - - eeprom_cmd_start(ee_addr); - for (i = 0; i < 20000; i++) - if (readb(ee_addr) & EE_DATA_READ) - break; - eeprom_cmd_end(ee_addr); - - eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len); -} - -static int cp_get_eeprom_len(struct net_device *dev) -{ - struct cp_private *cp = netdev_priv(dev); - int size; - - spin_lock_irq(&cp->lock); - size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128; - spin_unlock_irq(&cp->lock); - - return size; -} - -static int cp_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned int addr_len; - u16 val; - u32 offset = eeprom->offset >> 1; - u32 len = eeprom->len; - u32 i = 0; - - eeprom->magic = CP_EEPROM_MAGIC; - - spin_lock_irq(&cp->lock); - - addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; - - if (eeprom->offset & 1) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i++] = (u8)(val >> 8); - offset++; - } - - while (i < len - 1) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i++] = (u8)val; - data[i++] = (u8)(val >> 8); - offset++; - } - - if (i < len) { - val = read_eeprom(cp->regs, offset, addr_len); - data[i] = (u8)val; - } - - spin_unlock_irq(&cp->lock); - return 0; -} - -static int cp_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *data) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned int addr_len; - u16 val; - u32 offset = eeprom->offset >> 1; - u32 len = eeprom->len; - u32 i = 0; - - if (eeprom->magic != CP_EEPROM_MAGIC) - return -EINVAL; - - spin_lock_irq(&cp->lock); - - addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; - - if (eeprom->offset & 1) { - val = read_eeprom(cp->regs, offset, addr_len) & 0xff; - val |= (u16)data[i++] << 8; - write_eeprom(cp->regs, offset, val, addr_len); - offset++; - } - - while (i < len - 1) { - val = (u16)data[i++]; - val |= (u16)data[i++] << 8; - write_eeprom(cp->regs, offset, val, addr_len); - offset++; - } - - if (i < len) { - val = read_eeprom(cp->regs, offset, addr_len) & 0xff00; - val |= (u16)data[i]; - write_eeprom(cp->regs, offset, val, addr_len); - } - - spin_unlock_irq(&cp->lock); - return 0; -} - /* Put the board into D3cold state and wait for WakeUp signal */ static void cp_set_d3_state (struct cp_private *cp) { diff --git a/trunk/drivers/net/82596.c b/trunk/drivers/net/82596.c index 8a9f7d61b9b1..da0c878dcba8 100644 --- a/trunk/drivers/net/82596.c +++ b/trunk/drivers/net/82596.c @@ -1070,7 +1070,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len, (unsigned int)skb->data)); if (skb->len < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/8390.c b/trunk/drivers/net/8390.c index 86be96af9c8f..f87027420081 100644 --- a/trunk/drivers/net/8390.c +++ b/trunk/drivers/net/8390.c @@ -275,14 +275,12 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int send_length = skb->len, output_page; unsigned long flags; - char buf[ETH_ZLEN]; - char *data = skb->data; if (skb->len < ETH_ZLEN) { - memset(buf, 0, ETH_ZLEN); /* more efficient than doing just the needed bits */ - memcpy(buf, data, skb->len); + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; send_length = ETH_ZLEN; - data = buf; } /* Mask interrupts from the ethercard. @@ -349,7 +347,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * trigger the send later, upon receiving a Tx done interrupt. */ - ei_block_output(dev, send_length, data, output_page); + ei_block_output(dev, send_length, skb->data, output_page); if (! ei_local->txing) { diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 39189903e355..0c6b45a11d15 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -854,17 +854,6 @@ config SMC9194 . The module will be called smc9194. -config NET_NETX - tristate "NetX Ethernet support" - select MII - depends on NET_ETHERNET && ARCH_NETX - help - This is support for the Hilscher netX builtin Ethernet ports - - To compile this driver as a module, choose M here and read - . The module - will be called netx-eth. - config DM9000 tristate "DM9000 support" depends on (ARM || MIPS) && NET_ETHERNET @@ -1387,8 +1376,8 @@ config APRICOT called apricot. config B44 - tristate "Broadcom 4400 ethernet support" - depends on NET_PCI && PCI + tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)" + depends on NET_PCI && PCI && EXPERIMENTAL select MII help If you have a network (Ethernet) controller of this type, say Y and @@ -2201,7 +2190,7 @@ config BNX2 config SPIDER_NET tristate "Spider Gigabit Ethernet driver" - depends on PCI && PPC_IBM_CELL_BLADE + depends on PCI && PPC_CELL select FW_LOADER help This driver supports the Gigabit Ethernet chips present on the @@ -2209,11 +2198,11 @@ config SPIDER_NET config GIANFAR tristate "Gianfar Ethernet" - depends on 85xx || 83xx || PPC_86xx + depends on 85xx || 83xx select PHYLIB help - This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, - and MPC86xx family of chips, and the FEC on the 8540. + This driver supports the Gigabit TSEC on the MPC85xx + family of chips, and the FEC on the 8540 config GFAR_NAPI bool "NAPI Support" diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index c91e95126f78..1eced3287507 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -187,7 +187,6 @@ obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MACMACE) += macmace.o obj-$(CONFIG_MAC89x0) += mac89x0.o obj-$(CONFIG_TUN) += tun.o -obj-$(CONFIG_NET_NETX) += netx-eth.o obj-$(CONFIG_DL2K) += dl2k.o obj-$(CONFIG_R8169) += r8169.o obj-$(CONFIG_AMD8111_ETH) += amd8111e.o diff --git a/trunk/drivers/net/a2065.c b/trunk/drivers/net/a2065.c index 71165ac0257a..79bb56b8dcef 100644 --- a/trunk/drivers/net/a2065.c +++ b/trunk/drivers/net/a2065.c @@ -573,7 +573,8 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) if (len < ETH_ZLEN) { len = ETH_ZLEN; - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; } diff --git a/trunk/drivers/net/ariadne.c b/trunk/drivers/net/ariadne.c index a9bb7a4aff98..d1b6b1f794e2 100644 --- a/trunk/drivers/net/ariadne.c +++ b/trunk/drivers/net/ariadne.c @@ -607,7 +607,8 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) /* FIXME: is the 79C960 new enough to do its own padding right ? */ if (skb->len < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; len = ETH_ZLEN; } diff --git a/trunk/drivers/net/arm/at91_ether.c b/trunk/drivers/net/arm/at91_ether.c index 613005a0285d..5503dc8a66e4 100644 --- a/trunk/drivers/net/arm/at91_ether.c +++ b/trunk/drivers/net/arm/at91_ether.c @@ -43,9 +43,7 @@ #define DRV_VERSION "1.0" static struct net_device *at91_dev; - -static struct timer_list check_timer; -#define LINK_POLL_INTERVAL (HZ) +static struct clk *ether_clk; /* ..................................................................... */ @@ -145,7 +143,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int * MAC accordingly. * If no link or auto-negotiation is busy, then no changes are made. */ -static void update_linkspeed(struct net_device *dev, int silent) +static void update_linkspeed(struct net_device *dev) { struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int bmsr, bmcr, lpa, mac_cfg; @@ -153,8 +151,7 @@ static void update_linkspeed(struct net_device *dev, int silent) if (!mii_link_ok(&lp->mii)) { /* no link */ netif_carrier_off(dev); - if (!silent) - printk(KERN_INFO "%s: Link down.\n", dev->name); + printk(KERN_INFO "%s: Link down.\n", dev->name); return; } @@ -189,8 +186,7 @@ static void update_linkspeed(struct net_device *dev, int silent) } at91_emac_write(AT91_EMAC_CFG, mac_cfg); - if (!silent) - printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); + printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); netif_carrier_on(dev); } @@ -230,7 +226,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs goto done; } - update_linkspeed(dev, 0); + update_linkspeed(dev); done: disable_mdi(); @@ -247,17 +243,14 @@ static void enable_phyirq(struct net_device *dev) unsigned int dsintr, irq_number; int status; - irq_number = lp->board_data.phy_irq_pin; - if (!irq_number) { - /* - * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), - * or board does not have it connected. - */ - check_timer.expires = jiffies + LINK_POLL_INTERVAL; - add_timer(&check_timer); + if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ + return; + if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ + return; + if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ return; - } + irq_number = lp->board_data.phy_irq_pin; status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); if (status) { printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); @@ -299,11 +292,12 @@ static void disable_phyirq(struct net_device *dev) unsigned int dsintr; unsigned int irq_number; - irq_number = lp->board_data.phy_irq_pin; - if (!irq_number) { - del_timer_sync(&check_timer); + if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ + return; + if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ + return; + if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ return; - } spin_lock_irq(&lp->lock); enable_mdi(); @@ -332,6 +326,7 @@ static void disable_phyirq(struct net_device *dev) disable_mdi(); spin_unlock_irq(&lp->lock); + irq_number = lp->board_data.phy_irq_pin; free_irq(irq_number, dev); /* Free interrupt handler */ } @@ -360,18 +355,6 @@ static void reset_phy(struct net_device *dev) } #endif -static void at91ether_check_link(unsigned long dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - - enable_mdi(); - update_linkspeed(dev, 1); - disable_mdi(); - - check_timer.expires = jiffies + LINK_POLL_INTERVAL; - add_timer(&check_timer); -} - /* ......................... ADDRESS MANAGEMENT ........................ */ /* @@ -518,7 +501,7 @@ static int hash_get_index(__u8 *addr) hash_index |= (bitval << j); } - return hash_index; + return hash_index; } /* @@ -574,8 +557,10 @@ static void at91ether_set_rx_mode(struct net_device *dev) at91_emac_write(AT91_EMAC_CFG, cfg); } + /* ......................... ETHTOOL SUPPORT ........................... */ + static int mdio_read(struct net_device *dev, int phy_id, int location) { unsigned int value; @@ -657,22 +642,6 @@ static struct ethtool_ops at91ether_ethtool_ops = { .get_link = ethtool_op_get_link, }; -static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct at91_private *lp = (struct at91_private *) dev->priv; - int res; - - if (!netif_running(dev)) - return -EINVAL; - - spin_lock_irq(&lp->lock); - enable_mdi(); - res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL); - disable_mdi(); - spin_unlock_irq(&lp->lock); - - return res; -} /* ................................ MAC ................................ */ @@ -716,10 +685,10 @@ static int at91ether_open(struct net_device *dev) struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; - if (!is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; + if (!is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; - clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */ + clk_enable(ether_clk); /* Re-enable Peripheral clock */ /* Clear internal statistics */ ctl = at91_emac_read(AT91_EMAC_CTL); @@ -739,7 +708,7 @@ static int at91ether_open(struct net_device *dev) /* Determine current link speed */ spin_lock_irq(&lp->lock); enable_mdi(); - update_linkspeed(dev, 0); + update_linkspeed(dev); disable_mdi(); spin_unlock_irq(&lp->lock); @@ -753,7 +722,6 @@ static int at91ether_open(struct net_device *dev) */ static int at91ether_close(struct net_device *dev) { - struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; /* Disable Receiver and Transmitter */ @@ -770,7 +738,7 @@ static int at91ether_close(struct net_device *dev) netif_stop_queue(dev); - clk_disable(lp->ether_clk); /* Disable Peripheral clock */ + clk_disable(ether_clk); /* Disable Peripheral clock */ return 0; } @@ -902,7 +870,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ at91ether_rx(dev); - if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ + if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ /* The TCOM bit is set even if the transmission failed. */ if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) lp->stats.tx_errors += 1; @@ -931,8 +899,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re /* * Initialize the ethernet interface */ -static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, - struct platform_device *pdev, struct clk *ether_clk) +static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev) { struct at91_eth_data *board_data = pdev->dev.platform_data; struct net_device *dev; @@ -966,7 +933,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add return -ENOMEM; } lp->board_data = *board_data; - lp->ether_clk = ether_clk; platform_set_drvdata(pdev, dev); spin_lock_init(&lp->lock); @@ -979,7 +945,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->set_multicast_list = at91ether_set_rx_mode; dev->set_mac_address = set_mac_address; dev->ethtool_ops = &at91ether_ethtool_ops; - dev->do_ioctl = at91ether_ioctl; SET_NETDEV_DEV(dev, &pdev->dev); @@ -1010,9 +975,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add lp->mii.dev = dev; /* Support for ethtool */ lp->mii.mdio_read = mdio_read; lp->mii.mdio_write = mdio_write; - lp->mii.phy_id = phy_address; - lp->mii.phy_id_mask = 0x1f; - lp->mii.reg_num_mask = 0x1f; lp->phy_type = phy_type; /* Type of PHY connected */ lp->phy_address = phy_address; /* MDI address of PHY */ @@ -1030,18 +992,11 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add /* Determine current link speed */ spin_lock_irq(&lp->lock); enable_mdi(); - update_linkspeed(dev, 0); + update_linkspeed(dev); disable_mdi(); spin_unlock_irq(&lp->lock); netif_carrier_off(dev); /* will be enabled in open() */ - /* If board has no PHY IRQ, use a timer to poll the PHY */ - if (!lp->board_data.phy_irq_pin) { - init_timer(&check_timer); - check_timer.data = (unsigned long)dev; - check_timer.function = at91ether_check_link; - } - /* Display ethernet banner */ printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", dev->name, (uint) dev->base_addr, dev->irq, @@ -1050,7 +1005,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) - printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); + printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); else if (phy_type == MII_LXT971A_ID) printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); else if (phy_type == MII_RTL8201_ID) @@ -1076,10 +1031,9 @@ static int __init at91ether_probe(struct platform_device *pdev) int detected = -1; unsigned long phy_id; unsigned short phy_address = 0; - struct clk *ether_clk; ether_clk = clk_get(&pdev->dev, "ether_clk"); - if (IS_ERR(ether_clk)) { + if (!ether_clk) { printk(KERN_ERR "at91_ether: no clock defined\n"); return -ENODEV; } @@ -1102,7 +1056,7 @@ static int __init at91ether_probe(struct platform_device *pdev) case MII_DP83847_ID: /* National Semiconductor DP83847: */ case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ - detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk); + detected = at91ether_setup(phy_id, phy_address, pdev); break; } @@ -1121,61 +1075,17 @@ static int __devexit at91ether_remove(struct platform_device *pdev) unregister_netdev(at91_dev); free_irq(at91_dev->irq, at91_dev); dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); - clk_put(lp->ether_clk); + clk_put(ether_clk); free_netdev(at91_dev); at91_dev = NULL; return 0; } -#ifdef CONFIG_PM - -static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - struct at91_private *lp = (struct at91_private *) at91_dev->priv; - struct net_device *net_dev = platform_get_drvdata(pdev); - int phy_irq = lp->board_data.phy_irq_pin; - - if (netif_running(net_dev)) { - if (phy_irq) - disable_irq(phy_irq); - - netif_stop_queue(net_dev); - netif_device_detach(net_dev); - - clk_disable(lp->ether_clk); - } - return 0; -} - -static int at91ether_resume(struct platform_device *pdev) -{ - struct at91_private *lp = (struct at91_private *) at91_dev->priv; - struct net_device *net_dev = platform_get_drvdata(pdev); - int phy_irq = lp->board_data.phy_irq_pin; - - if (netif_running(net_dev)) { - clk_enable(lp->ether_clk); - - netif_device_attach(net_dev); - netif_start_queue(net_dev); - - if (phy_irq) - enable_irq(phy_irq); - } - return 0; -} - -#else -#define at91ether_suspend NULL -#define at91ether_resume NULL -#endif - static struct platform_driver at91ether_driver = { .probe = at91ether_probe, .remove = __devexit_p(at91ether_remove), - .suspend = at91ether_suspend, - .resume = at91ether_resume, + /* FIXME: support suspend and resume */ .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/trunk/drivers/net/arm/at91_ether.h b/trunk/drivers/net/arm/at91_ether.h index d1e72e02be3a..9885735c9c8a 100644 --- a/trunk/drivers/net/arm/at91_ether.h +++ b/trunk/drivers/net/arm/at91_ether.h @@ -80,7 +80,6 @@ struct at91_private struct net_device_stats stats; struct mii_if_info mii; /* ethtool support */ struct at91_eth_data board_data; /* board-specific configuration */ - struct clk *ether_clk; /* clock */ /* PHY */ unsigned long phy_type; /* type of PHY (PHY_ID) */ diff --git a/trunk/drivers/net/arm/ether1.c b/trunk/drivers/net/arm/ether1.c index 312955d07b28..36475eb2727f 100644 --- a/trunk/drivers/net/arm/ether1.c +++ b/trunk/drivers/net/arm/ether1.c @@ -700,7 +700,8 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) } if (skb->len < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) goto out; } diff --git a/trunk/drivers/net/arm/ether3.c b/trunk/drivers/net/arm/ether3.c index 081074180e62..f1d5b1027ff7 100644 --- a/trunk/drivers/net/arm/ether3.c +++ b/trunk/drivers/net/arm/ether3.c @@ -518,7 +518,8 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) length = (length + 1) & ~1; if (length != skb->len) { - if (skb_padto(skb, length)) + skb = skb_padto(skb, length); + if (skb == NULL) goto out; } diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index 91783a8008be..442b2cbeb58a 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -804,7 +804,8 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) ++len; if (len > skb->len) { - if (skb_padto(skb, len)) + skb = skb_padto(skb, len); + if (skb == NULL) return 0; } diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index a7e4ba5a580f..d8233e0b7899 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -29,8 +29,8 @@ #define DRV_MODULE_NAME "b44" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.01" -#define DRV_MODULE_RELDATE "Jun 16, 2006" +#define DRV_MODULE_VERSION "1.00" +#define DRV_MODULE_RELDATE "Apr 7, 2006" #define B44_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -75,15 +75,6 @@ /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) -/* b44 internal pattern match filter info */ -#define B44_PATTERN_BASE 0x400 -#define B44_PATTERN_SIZE 0x80 -#define B44_PMASK_BASE 0x600 -#define B44_PMASK_SIZE 0x10 -#define B44_MAX_PATTERNS 16 -#define B44_ETHIPV6UDP_HLEN 62 -#define B44_ETHIPV4UDP_HLEN 42 - static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -110,7 +101,7 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); static void b44_halt(struct b44 *); static void b44_init_rings(struct b44 *); -static void b44_init_hw(struct b44 *, int); +static void b44_init_hw(struct b44 *); static int dma_desc_align_mask; static int dma_desc_sync_size; @@ -882,7 +873,7 @@ static int b44_poll(struct net_device *netdev, int *budget) spin_lock_irq(&bp->lock); b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); done = 1; @@ -951,7 +942,7 @@ static void b44_tx_timeout(struct net_device *dev) b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); spin_unlock_irq(&bp->lock); @@ -1068,7 +1059,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) b44_halt(bp); dev->mtu = new_mtu; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); spin_unlock_irq(&bp->lock); b44_enable_ints(bp); @@ -1365,15 +1356,13 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) * packet processing. Invoked with bp->lock held. */ static void __b44_set_rx_mode(struct net_device *); -static void b44_init_hw(struct b44 *bp, int full_reset) +static void b44_init_hw(struct b44 *bp) { u32 val; b44_chip_reset(bp); - if (full_reset) { - b44_phy_reset(bp); - b44_setup_phy(bp); - } + b44_phy_reset(bp); + b44_setup_phy(bp); /* Enable CRC32, set proper LED modes and power on PHY */ bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL); @@ -1387,21 +1376,16 @@ static void b44_init_hw(struct b44 *bp, int full_reset) bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ - if (full_reset) { - bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); - bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); - bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); - bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); + bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); + bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); + bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); - bw32(bp, B44_DMARX_PTR, bp->rx_pending); - bp->rx_prod = bp->rx_pending; + bw32(bp, B44_DMARX_PTR, bp->rx_pending); + bp->rx_prod = bp->rx_pending; - bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); - } else { - bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); - } + bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); val = br32(bp, B44_ENET_CTRL); bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); @@ -1417,7 +1401,7 @@ static int b44_open(struct net_device *dev) goto out; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); b44_check_phy(bp); @@ -1466,140 +1450,6 @@ static void b44_poll_controller(struct net_device *dev) } #endif -static void bwfilter_table(struct b44 *bp, u8 *pp, u32 bytes, u32 table_offset) -{ - u32 i; - u32 *pattern = (u32 *) pp; - - for (i = 0; i < bytes; i += sizeof(u32)) { - bw32(bp, B44_FILT_ADDR, table_offset + i); - bw32(bp, B44_FILT_DATA, pattern[i / sizeof(u32)]); - } -} - -static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) -{ - int magicsync = 6; - int k, j, len = offset; - int ethaddr_bytes = ETH_ALEN; - - memset(ppattern + offset, 0xff, magicsync); - for (j = 0; j < magicsync; j++) - set_bit(len++, (unsigned long *) pmask); - - for (j = 0; j < B44_MAX_PATTERNS; j++) { - if ((B44_PATTERN_SIZE - len) >= ETH_ALEN) - ethaddr_bytes = ETH_ALEN; - else - ethaddr_bytes = B44_PATTERN_SIZE - len; - if (ethaddr_bytes <=0) - break; - for (k = 0; k< ethaddr_bytes; k++) { - ppattern[offset + magicsync + - (j * ETH_ALEN) + k] = macaddr[k]; - len++; - set_bit(len, (unsigned long *) pmask); - } - } - return len - 1; -} - -/* Setup magic packet patterns in the b44 WOL - * pattern matching filter. - */ -static void b44_setup_pseudo_magicp(struct b44 *bp) -{ - - u32 val; - int plen0, plen1, plen2; - u8 *pwol_pattern; - u8 pwol_mask[B44_PMASK_SIZE]; - - pwol_pattern = kmalloc(B44_PATTERN_SIZE, GFP_KERNEL); - if (!pwol_pattern) { - printk(KERN_ERR PFX "Memory not available for WOL\n"); - return; - } - - /* Ipv4 magic packet pattern - pattern 0.*/ - memset(pwol_pattern, 0, B44_PATTERN_SIZE); - memset(pwol_mask, 0, B44_PMASK_SIZE); - plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, - B44_ETHIPV4UDP_HLEN); - - bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, B44_PATTERN_BASE); - bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, B44_PMASK_BASE); - - /* Raw ethernet II magic packet pattern - pattern 1 */ - memset(pwol_pattern, 0, B44_PATTERN_SIZE); - memset(pwol_mask, 0, B44_PMASK_SIZE); - plen1 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, - ETH_HLEN); - - bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, - B44_PATTERN_BASE + B44_PATTERN_SIZE); - bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, - B44_PMASK_BASE + B44_PMASK_SIZE); - - /* Ipv6 magic packet pattern - pattern 2 */ - memset(pwol_pattern, 0, B44_PATTERN_SIZE); - memset(pwol_mask, 0, B44_PMASK_SIZE); - plen2 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, - B44_ETHIPV6UDP_HLEN); - - bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, - B44_PATTERN_BASE + B44_PATTERN_SIZE + B44_PATTERN_SIZE); - bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, - B44_PMASK_BASE + B44_PMASK_SIZE + B44_PMASK_SIZE); - - kfree(pwol_pattern); - - /* set these pattern's lengths: one less than each real length */ - val = plen0 | (plen1 << 8) | (plen2 << 16) | WKUP_LEN_ENABLE_THREE; - bw32(bp, B44_WKUP_LEN, val); - - /* enable wakeup pattern matching */ - val = br32(bp, B44_DEVCTRL); - bw32(bp, B44_DEVCTRL, val | DEVCTRL_PFE); - -} - -static void b44_setup_wol(struct b44 *bp) -{ - u32 val; - u16 pmval; - - bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI); - - if (bp->flags & B44_FLAG_B0_ANDLATER) { - - bw32(bp, B44_WKUP_LEN, WKUP_LEN_DISABLE); - - val = bp->dev->dev_addr[2] << 24 | - bp->dev->dev_addr[3] << 16 | - bp->dev->dev_addr[4] << 8 | - bp->dev->dev_addr[5]; - bw32(bp, B44_ADDR_LO, val); - - val = bp->dev->dev_addr[0] << 8 | - bp->dev->dev_addr[1]; - bw32(bp, B44_ADDR_HI, val); - - val = br32(bp, B44_DEVCTRL); - bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE); - - } else { - b44_setup_pseudo_magicp(bp); - } - - val = br32(bp, B44_SBTMSLOW); - bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE); - - pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval); - pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE); - -} - static int b44_close(struct net_device *dev) { struct b44 *bp = netdev_priv(dev); @@ -1625,11 +1475,6 @@ static int b44_close(struct net_device *dev) netif_poll_enable(dev); - if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); - b44_setup_wol(bp); - } - b44_free_consistent(bp); return 0; @@ -1775,6 +1620,8 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct b44 *bp = netdev_priv(dev); + if (!netif_running(dev)) + return -EAGAIN; cmd->supported = (SUPPORTED_Autoneg); cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -1802,12 +1649,6 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) XCVR_INTERNAL : XCVR_EXTERNAL; cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ? AUTONEG_DISABLE : AUTONEG_ENABLE; - if (cmd->autoneg == AUTONEG_ENABLE) - cmd->advertising |= ADVERTISED_Autoneg; - if (!netif_running(dev)){ - cmd->speed = 0; - cmd->duplex = 0xff; - } cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; @@ -1817,6 +1658,9 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct b44 *bp = netdev_priv(dev); + if (!netif_running(dev)) + return -EAGAIN; + /* We do not support gigabit. */ if (cmd->autoneg == AUTONEG_ENABLE) { if (cmd->advertising & @@ -1833,39 +1677,28 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irq(&bp->lock); if (cmd->autoneg == AUTONEG_ENABLE) { - bp->flags &= ~(B44_FLAG_FORCE_LINK | - B44_FLAG_100_BASE_T | - B44_FLAG_FULL_DUPLEX | - B44_FLAG_ADV_10HALF | + bp->flags &= ~B44_FLAG_FORCE_LINK; + bp->flags &= ~(B44_FLAG_ADV_10HALF | B44_FLAG_ADV_10FULL | B44_FLAG_ADV_100HALF | B44_FLAG_ADV_100FULL); - if (cmd->advertising == 0) { - bp->flags |= (B44_FLAG_ADV_10HALF | - B44_FLAG_ADV_10FULL | - B44_FLAG_ADV_100HALF | - B44_FLAG_ADV_100FULL); - } else { - if (cmd->advertising & ADVERTISED_10baseT_Half) - bp->flags |= B44_FLAG_ADV_10HALF; - if (cmd->advertising & ADVERTISED_10baseT_Full) - bp->flags |= B44_FLAG_ADV_10FULL; - if (cmd->advertising & ADVERTISED_100baseT_Half) - bp->flags |= B44_FLAG_ADV_100HALF; - if (cmd->advertising & ADVERTISED_100baseT_Full) - bp->flags |= B44_FLAG_ADV_100FULL; - } + if (cmd->advertising & ADVERTISE_10HALF) + bp->flags |= B44_FLAG_ADV_10HALF; + if (cmd->advertising & ADVERTISE_10FULL) + bp->flags |= B44_FLAG_ADV_10FULL; + if (cmd->advertising & ADVERTISE_100HALF) + bp->flags |= B44_FLAG_ADV_100HALF; + if (cmd->advertising & ADVERTISE_100FULL) + bp->flags |= B44_FLAG_ADV_100FULL; } else { bp->flags |= B44_FLAG_FORCE_LINK; - bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX); if (cmd->speed == SPEED_100) bp->flags |= B44_FLAG_100_BASE_T; if (cmd->duplex == DUPLEX_FULL) bp->flags |= B44_FLAG_FULL_DUPLEX; } - if (netif_running(dev)) - b44_setup_phy(bp); + b44_setup_phy(bp); spin_unlock_irq(&bp->lock); @@ -1901,7 +1734,7 @@ static int b44_set_ringparam(struct net_device *dev, b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); @@ -1944,7 +1777,7 @@ static int b44_set_pauseparam(struct net_device *dev, if (bp->flags & B44_FLAG_PAUSE_AUTO) { b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); } else { __b44_set_flow_ctrl(bp, bp->flags); } @@ -1986,40 +1819,12 @@ static void b44_get_ethtool_stats(struct net_device *dev, spin_unlock_irq(&bp->lock); } -static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct b44 *bp = netdev_priv(dev); - - wol->supported = WAKE_MAGIC; - if (bp->flags & B44_FLAG_WOL_ENABLE) - wol->wolopts = WAKE_MAGIC; - else - wol->wolopts = 0; - memset(&wol->sopass, 0, sizeof(wol->sopass)); -} - -static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct b44 *bp = netdev_priv(dev); - - spin_lock_irq(&bp->lock); - if (wol->wolopts & WAKE_MAGIC) - bp->flags |= B44_FLAG_WOL_ENABLE; - else - bp->flags &= ~B44_FLAG_WOL_ENABLE; - spin_unlock_irq(&bp->lock); - - return 0; -} - static struct ethtool_ops b44_ethtool_ops = { .get_drvinfo = b44_get_drvinfo, .get_settings = b44_get_settings, .set_settings = b44_set_settings, .nway_reset = b44_nway_reset, .get_link = ethtool_op_get_link, - .get_wol = b44_get_wol, - .set_wol = b44_set_wol, .get_ringparam = b44_get_ringparam, .set_ringparam = b44_set_ringparam, .get_pauseparam = b44_get_pauseparam, @@ -2098,10 +1903,6 @@ static int __devinit b44_get_invariants(struct b44 *bp) /* XXX - really required? bp->flags |= B44_FLAG_BUGGY_TXPTR; */ - - if (ssb_get_core_rev(bp) >= 7) - bp->flags |= B44_FLAG_B0_ANDLATER; - out: return err; } @@ -2302,10 +2103,6 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) spin_unlock_irq(&bp->lock); free_irq(dev->irq, dev); - if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); - b44_setup_wol(bp); - } pci_disable_device(pdev); return 0; } @@ -2328,7 +2125,7 @@ static int b44_resume(struct pci_dev *pdev) spin_lock_irq(&bp->lock); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp); netif_device_attach(bp->dev); spin_unlock_irq(&bp->lock); diff --git a/trunk/drivers/net/b44.h b/trunk/drivers/net/b44.h index 4944507fad23..b178662978f3 100644 --- a/trunk/drivers/net/b44.h +++ b/trunk/drivers/net/b44.h @@ -24,9 +24,6 @@ #define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */ #define WKUP_LEN_P3_SHIFT 24 #define WKUP_LEN_D3 0x80000000 -#define WKUP_LEN_DISABLE 0x80808080 -#define WKUP_LEN_ENABLE_TWO 0x80800000 -#define WKUP_LEN_ENABLE_THREE 0x80000000 #define B44_ISTAT 0x0020UL /* Interrupt Status */ #define ISTAT_LS 0x00000020 /* Link Change (B0 only) */ #define ISTAT_PME 0x00000040 /* Power Management Event */ @@ -267,8 +264,6 @@ #define SBIDHIGH_VC_SHIFT 16 /* SSB PCI config space registers. */ -#define SSB_PMCSR 0x44 -#define SSB_PE 0x100 #define SSB_BAR0_WIN 0x80 #define SSB_BAR1_WIN 0x84 #define SSB_SPROM_CONTROL 0x88 @@ -425,7 +420,6 @@ struct b44 { u32 dma_offset; u32 flags; -#define B44_FLAG_B0_ANDLATER 0x00000001 #define B44_FLAG_BUGGY_TXPTR 0x00000002 #define B44_FLAG_REORDER_BUG 0x00000004 #define B44_FLAG_PAUSE_AUTO 0x00008000 @@ -441,7 +435,6 @@ struct b44 { #define B44_FLAG_INTERNAL_PHY 0x10000000 #define B44_FLAG_RX_RING_HACK 0x20000000 #define B44_FLAG_TX_RING_HACK 0x40000000 -#define B44_FLAG_WOL_ENABLE 0x80000000 u32 rx_offset; diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 7635736cc791..702d546567ad 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -1640,7 +1640,7 @@ bnx2_tx_int(struct bnx2 *bp) skb = tx_buf->skb; #ifdef BCM_TSO /* partial BD completions possible with TSO packets */ - if (skb_shinfo(skb)->gso_size) { + if (skb_shinfo(skb)->tso_size) { u16 last_idx, last_ring_idx; last_idx = sw_cons + @@ -4428,7 +4428,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } #ifdef BCM_TSO - if ((mss = skb_shinfo(skb)->gso_size) && + if ((mss = skb_shinfo(skb)->tso_size) && (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index 565a54f1d06a..39f36aa05aa8 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -2915,7 +2915,8 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static int ring; - if (skb_padto(skb, cp->min_frame_size)) + skb = skb_padto(skb, cp->min_frame_size); + if (!skb) return 0; /* XXX: we need some higher-level QoS hooks to steer packets to diff --git a/trunk/drivers/net/chelsio/sge.c b/trunk/drivers/net/chelsio/sge.c index 53efff6da784..4391bf4bf573 100644 --- a/trunk/drivers/net/chelsio/sge.c +++ b/trunk/drivers/net/chelsio/sge.c @@ -1418,7 +1418,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) struct cpl_tx_pkt *cpl; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->gso_size) { + if (skb_shinfo(skb)->tso_size) { int eth_type; struct cpl_tx_pkt_lso *hdr; @@ -1433,7 +1433,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) hdr->ip_hdr_words = skb->nh.iph->ihl; hdr->tcp_hdr_words = skb->h.th->doff; hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, - skb_shinfo(skb)->gso_size)); + skb_shinfo(skb)->tso_size)); hdr->len = htonl(skb->len - sizeof(*hdr)); cpl = (struct cpl_tx_pkt *)hdr; sge->stats.tx_lso_pkts++; diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index d3d958e7ac56..f130bdab3fd3 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -885,7 +885,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skblen; if (len < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; len = ETH_ZLEN; } diff --git a/trunk/drivers/net/depca.c b/trunk/drivers/net/depca.c index e946c43d3b10..0941d40f046f 100644 --- a/trunk/drivers/net/depca.c +++ b/trunk/drivers/net/depca.c @@ -938,8 +938,11 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->len < 1) goto out; - if (skb_padto(skb, ETH_ZLEN)) - goto out; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + goto out; + } netif_stop_queue(dev); diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 32b7d444b374..a373ccb308d8 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2394,7 +2394,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; - if (skb_shinfo(skb)->gso_size) { + if (skb_shinfo(skb)->tso_size) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -2402,7 +2402,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (skb->protocol == htons(ETH_P_IP)) { skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; @@ -2519,7 +2519,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, * tso gets written back prematurely before the data is fully * DMA'd to the controller */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->gso_size) { + !skb_shinfo(skb)->tso_size) { tx_ring->last_tx_tso = 0; size -= 4; } @@ -2757,7 +2757,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: @@ -2807,7 +2807,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO /* Controller Erratum workaround */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->gso_size) + !skb_shinfo(skb)->tso_size) count++; #endif diff --git a/trunk/drivers/net/eepro.c b/trunk/drivers/net/eepro.c index e70f172699db..a806dfe54d23 100644 --- a/trunk/drivers/net/eepro.c +++ b/trunk/drivers/net/eepro.c @@ -1154,7 +1154,8 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name); if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/eexpress.c b/trunk/drivers/net/eexpress.c index a74b20715755..82bd356e4f3a 100644 --- a/trunk/drivers/net/eexpress.c +++ b/trunk/drivers/net/eexpress.c @@ -677,7 +677,8 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) #endif if (buf->len < ETH_ZLEN) { - if (skb_padto(buf, ETH_ZLEN)) + buf = skb_padto(buf, ETH_ZLEN); + if (buf == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/epic100.c b/trunk/drivers/net/epic100.c index 724d7dc35fa3..8d680ce600d7 100644 --- a/trunk/drivers/net/epic100.c +++ b/trunk/drivers/net/epic100.c @@ -1027,8 +1027,11 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 ctrl_word; unsigned long flags; - if (skb_padto(skb, ETH_ZLEN)) - return 0; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; + } /* Caution: the write order is important here, set the field with the "ownership" bit last. */ diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index 4bf76f86d8e9..b67545be2caa 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -1064,7 +1064,8 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) unsigned long flags; if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index db694c832989..bd6983d1afba 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -22,7 +22,7 @@ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) * * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) - * Copyright (c) 2004-2006 Macq Electronique SA. + * Copyright (c) 2004-2005 Macq Electronique SA. */ #include @@ -51,7 +51,7 @@ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) #include #include #include "fec.h" @@ -80,8 +80,6 @@ static unsigned int fec_hw[] = { (MCF_MBAR + 0x1000), #elif defined(CONFIG_M520x) (MCF_MBAR+0x30000), -#elif defined(CONFIG_M532x) - (MCF_MBAR+0xfc030000), #else &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), #endif @@ -145,7 +143,7 @@ typedef struct { #define TX_RING_MOD_MASK 15 /* for this to work */ #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) -#error "FEC: descriptor ring size constants too large" +#error "FEC: descriptor ring size contants too large" #endif /* Interrupt events/masks. @@ -169,12 +167,12 @@ typedef struct { /* - * The 5270/5271/5280/5282/532x RX control register also contains maximum frame + * The 5270/5271/5280/5282 RX control register also contains maximum frame * size bits. Other FEC hardware does not, so we need to take that into * account when setting it. */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) #else #define OPT_FRAME_SIZE 0 @@ -310,7 +308,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; - unsigned short status; fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -323,9 +320,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fill in a Tx ring entry */ bdp = fep->cur_tx; - status = bdp->cbd_sc; #ifndef final_version - if (status & BD_ENET_TX_READY) { + if (bdp->cbd_sc & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since dev->tbusy should be set. */ @@ -336,7 +332,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Clear all of the status flags. */ - status &= ~BD_ENET_TX_STATS; + bdp->cbd_sc &= ~BD_ENET_TX_STATS; /* Set buffer length and buffer pointer. */ @@ -370,22 +366,21 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&fep->lock); - /* Send it on its way. Tell FEC it's ready, interrupt when done, - * it's the last BD of the frame, and to put the CRC on the end. + /* Send it on its way. Tell FEC its ready, interrupt when done, + * its the last BD of the frame, and to put the CRC on the end. */ - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR + bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); - bdp->cbd_sc = status; dev->trans_start = jiffies; /* Trigger transmission start */ - fecp->fec_x_des_active = 0; + fecp->fec_x_des_active = 0x01000000; /* If this was the last BD in the ring, start at the beginning again. */ - if (status & BD_ENET_TX_WRAP) { + if (bdp->cbd_sc & BD_ENET_TX_WRAP) { bdp = fep->tx_bd_base; } else { bdp++; @@ -496,44 +491,43 @@ fec_enet_tx(struct net_device *dev) { struct fec_enet_private *fep; volatile cbd_t *bdp; - unsigned short status; struct sk_buff *skb; fep = netdev_priv(dev); spin_lock(&fep->lock); bdp = fep->dirty_tx; - while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { + while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { if (bdp == fep->cur_tx && fep->tx_full == 0) break; skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ - if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | + if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { fep->stats.tx_errors++; - if (status & BD_ENET_TX_HB) /* No heartbeat */ + if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ fep->stats.tx_heartbeat_errors++; - if (status & BD_ENET_TX_LC) /* Late collision */ + if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ fep->stats.tx_window_errors++; - if (status & BD_ENET_TX_RL) /* Retrans limit */ + if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ fep->stats.tx_aborted_errors++; - if (status & BD_ENET_TX_UN) /* Underrun */ + if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ fep->stats.tx_fifo_errors++; - if (status & BD_ENET_TX_CSL) /* Carrier lost */ + if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ fep->stats.tx_carrier_errors++; } else { fep->stats.tx_packets++; } #ifndef final_version - if (status & BD_ENET_TX_READY) + if (bdp->cbd_sc & BD_ENET_TX_READY) printk("HEY! Enet xmit interrupt and TX_READY.\n"); #endif /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. */ - if (status & BD_ENET_TX_DEF) + if (bdp->cbd_sc & BD_ENET_TX_DEF) fep->stats.collisions++; /* Free the sk buffer associated with this last transmit. @@ -544,7 +538,7 @@ fec_enet_tx(struct net_device *dev) /* Update pointer to next buffer descriptor to be transmitted. */ - if (status & BD_ENET_TX_WRAP) + if (bdp->cbd_sc & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp++; @@ -574,14 +568,9 @@ fec_enet_rx(struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; - unsigned short status; struct sk_buff *skb; ushort pkt_len; __u8 *data; - -#ifdef CONFIG_M532x - flush_cache_all(); -#endif fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -591,13 +580,13 @@ fec_enet_rx(struct net_device *dev) */ bdp = fep->cur_rx; -while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { +while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { #ifndef final_version /* Since we have allocated space to hold a complete frame, * the last indicator should be set. */ - if ((status & BD_ENET_RX_LAST) == 0) + if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0) printk("FEC ENET: rcv is not +last\n"); #endif @@ -605,26 +594,26 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { goto rx_processing_done; /* Check for errors. */ - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { fep->stats.rx_errors++; - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ fep->stats.rx_length_errors++; } - if (status & BD_ENET_RX_NO) /* Frame alignment */ + if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ fep->stats.rx_frame_errors++; - if (status & BD_ENET_RX_CR) /* CRC Error */ + if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ + fep->stats.rx_crc_errors++; + if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ fep->stats.rx_crc_errors++; - if (status & BD_ENET_RX_OV) /* FIFO overrun */ - fep->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. * On this error, the BD is closed, but we don't know what we * have in the buffer. So, just drop this frame on the floor. */ - if (status & BD_ENET_RX_CL) { + if (bdp->cbd_sc & BD_ENET_RX_CL) { fep->stats.rx_errors++; fep->stats.rx_frame_errors++; goto rx_processing_done; @@ -650,7 +639,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { } else { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, data, pkt_len-4, 0); + eth_copy_and_sum(skb, + (unsigned char *)__va(bdp->cbd_bufaddr), + pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -658,16 +649,15 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { /* Clear the status flags for this buffer. */ - status &= ~BD_ENET_RX_STATS; + bdp->cbd_sc &= ~BD_ENET_RX_STATS; /* Mark the buffer empty. */ - status |= BD_ENET_RX_EMPTY; - bdp->cbd_sc = status; + bdp->cbd_sc |= BD_ENET_RX_EMPTY; /* Update BD pointer to next entry. */ - if (status & BD_ENET_RX_WRAP) + if (bdp->cbd_sc & BD_ENET_RX_WRAP) bdp = fep->rx_bd_base; else bdp++; @@ -677,9 +667,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #endif - } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ + } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; #if 0 @@ -690,12 +680,11 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * our way back to the interrupt return only to come right back * here. */ - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #endif } -/* called from interrupt context */ static void fec_enet_mii(struct net_device *dev) { @@ -707,12 +696,10 @@ fec_enet_mii(struct net_device *dev) fep = netdev_priv(dev); ep = fep->hwp; mii_reg = ep->fec_mii_data; - - spin_lock(&fep->lock); if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); - goto unlock; + return; } if (mip->mii_func != NULL) @@ -724,9 +711,6 @@ fec_enet_mii(struct net_device *dev) if ((mip = mii_head) != NULL) ep->fec_mii_data = mip->mii_regval; - -unlock: - spin_unlock(&fep->lock); } static int @@ -744,7 +728,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 0; - spin_lock_irqsave(&fep->lock,flags); + save_flags(flags); + cli(); if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; @@ -764,7 +749,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 1; } - spin_unlock_irqrestore(&fep->lock,flags); + restore_flags(flags); return(retval); } @@ -1231,7 +1216,7 @@ static phy_info_t const * const phy_info[] = { }; /* ------------------------------------------------------------------------- */ -#if !defined(CONFIG_M532x) + #ifdef CONFIG_RPXCLASSIC static void mii_link_interrupt(void *dev_id); @@ -1239,7 +1224,6 @@ mii_link_interrupt(void *dev_id); static irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); #endif -#endif #if defined(CONFIG_M5272) @@ -1400,13 +1384,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev) { volatile unsigned char *icrp; volatile unsigned long *imrp; - int i, ilip; + int i; b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; icrp = (volatile unsigned char *) (MCF_IPSBAR + b + MCFINTC_ICR0); - for (i = 23, ilip = 0x28; (i < 36); i++) - icrp[i] = ilip--; + for (i = 23; (i < 36); i++) + icrp[i] = 0x23; imrp = (volatile unsigned long *) (MCF_IPSBAR + b + MCFINTC_IMRH); @@ -1634,159 +1618,6 @@ static void __inline__ fec_uncache(unsigned long addr) /* ------------------------------------------------------------------------- */ -#elif defined(CONFIG_M532x) -/* - * Code specific for M532x - */ -static void __inline__ fec_request_intrs(struct net_device *dev) -{ - struct fec_enet_private *fep; - int b; - static const struct idesc { - char *name; - unsigned short irq; - } *idp, id[] = { - { "fec(TXF)", 36 }, - { "fec(TXB)", 37 }, - { "fec(TXFIFO)", 38 }, - { "fec(TXCR)", 39 }, - { "fec(RXF)", 40 }, - { "fec(RXB)", 41 }, - { "fec(MII)", 42 }, - { "fec(LC)", 43 }, - { "fec(HBERR)", 44 }, - { "fec(GRA)", 45 }, - { "fec(EBERR)", 46 }, - { "fec(BABT)", 47 }, - { "fec(BABR)", 48 }, - { NULL }, - }; - - fep = netdev_priv(dev); - b = (fep->index) ? 128 : 64; - - /* Setup interrupt handlers. */ - for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) - printk("FEC: Could not allocate %s IRQ(%d)!\n", - idp->name, b+idp->irq); - } - - /* Unmask interrupts */ - MCF_INTC0_ICR36 = 0x2; - MCF_INTC0_ICR37 = 0x2; - MCF_INTC0_ICR38 = 0x2; - MCF_INTC0_ICR39 = 0x2; - MCF_INTC0_ICR40 = 0x2; - MCF_INTC0_ICR41 = 0x2; - MCF_INTC0_ICR42 = 0x2; - MCF_INTC0_ICR43 = 0x2; - MCF_INTC0_ICR44 = 0x2; - MCF_INTC0_ICR45 = 0x2; - MCF_INTC0_ICR46 = 0x2; - MCF_INTC0_ICR47 = 0x2; - MCF_INTC0_ICR48 = 0x2; - - MCF_INTC0_IMRH &= ~( - MCF_INTC_IMRH_INT_MASK36 | - MCF_INTC_IMRH_INT_MASK37 | - MCF_INTC_IMRH_INT_MASK38 | - MCF_INTC_IMRH_INT_MASK39 | - MCF_INTC_IMRH_INT_MASK40 | - MCF_INTC_IMRH_INT_MASK41 | - MCF_INTC_IMRH_INT_MASK42 | - MCF_INTC_IMRH_INT_MASK43 | - MCF_INTC_IMRH_INT_MASK44 | - MCF_INTC_IMRH_INT_MASK45 | - MCF_INTC_IMRH_INT_MASK46 | - MCF_INTC_IMRH_INT_MASK47 | - MCF_INTC_IMRH_INT_MASK48 ); - - /* Set up gpio outputs for MII lines */ - MCF_GPIO_PAR_FECI2C |= (0 | - MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | - MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); - MCF_GPIO_PAR_FEC = (0 | - MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | - MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); -} - -static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) -{ - volatile fec_t *fecp; - - fecp = fep->hwp; - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; - fecp->fec_x_cntrl = 0x00; - - /* - * Set MII speed to 2.5 MHz - */ - fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; - fecp->fec_mii_speed = fep->phy_speed; - - fec_restart(dev, 0); -} - -static void __inline__ fec_get_mac(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - volatile fec_t *fecp; - unsigned char *iap, tmpaddr[ETH_ALEN]; - - fecp = fep->hwp; - - if (FEC_FLASHMAC) { - /* - * Get MAC address from FLASH. - * If it is all 1's or 0's, use the default. - */ - iap = FEC_FLASHMAC; - if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && - (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) - iap = fec_mac_default; - if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && - (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) - iap = fec_mac_default; - } else { - *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; - *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); - iap = &tmpaddr[0]; - } - - memcpy(dev->dev_addr, iap, ETH_ALEN); - - /* Adjust MAC if using default MAC address */ - if (iap == fec_mac_default) - dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; -} - -static void __inline__ fec_enable_phy_intr(void) -{ -} - -static void __inline__ fec_disable_phy_intr(void) -{ -} - -static void __inline__ fec_phy_ack_intr(void) -{ -} - -static void __inline__ fec_localhw_setup(void) -{ -} - -/* - * Do not need to make region uncached on 532x. - */ -static void __inline__ fec_uncache(unsigned long addr) -{ -} - -/* ------------------------------------------------------------------------- */ - - #else /* @@ -2154,12 +1985,9 @@ fec_enet_open(struct net_device *dev) mii_do_cmd(dev, fep->phy->config); mii_do_cmd(dev, phy_cmd_config); /* display configuration */ - /* Poll until the PHY tells us its configuration - * (not link state). - * Request is initiated by mii_do_cmd above, but answer - * comes by interrupt. - * This should take about 25 usec per register at 2.5 MHz, - * and we read approximately 5 registers. + /* FIXME: use netif_carrier_{on,off} ; this polls + * until link is up which is wrong... could be + * 30 seconds or more we are trapped in here. -jgarzik */ while(!fep->sequence_done) schedule(); @@ -2425,11 +2253,15 @@ int __init fec_enet_init(struct net_device *dev) */ fec_request_intrs(dev); + /* Clear and enable interrupts */ + fecp->fec_ievent = 0xffc00000; + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); fecp->fec_hash_table_high = 0; fecp->fec_hash_table_low = 0; fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; dev->base_addr = (unsigned long)fecp; @@ -2449,11 +2281,6 @@ int __init fec_enet_init(struct net_device *dev) /* setup MII interface */ fec_set_mii(dev, fep); - /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); - /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -2485,6 +2312,11 @@ fec_restart(struct net_device *dev, int duplex) fecp->fec_ecntrl = 1; udelay(10); + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + /* Clear any outstanding interrupt. */ fecp->fec_ievent = 0xffc00000; @@ -2576,12 +2408,7 @@ fec_restart(struct net_device *dev, int duplex) /* And last, enable the transmit and receive processing. */ fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; - - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + fecp->fec_r_des_active = 0x01000000; } static void @@ -2593,16 +2420,9 @@ fec_stop(struct net_device *dev) fep = netdev_priv(dev); fecp = fep->hwp; - /* - ** We cannot expect a graceful transmit stop without link !!! - */ - if (fep->link) - { - fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ - udelay(10); - if (!(fecp->fec_ievent & FEC_ENET_GRA)) - printk("fec_stop : Graceful transmit stop did not complete !\n"); - } + fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + + while(!(fecp->fec_ievent & FEC_ENET_GRA)); /* Whack a reset. We should wait for this. */ diff --git a/trunk/drivers/net/fec.h b/trunk/drivers/net/fec.h index 1d421606984f..965c5c49fcdc 100644 --- a/trunk/drivers/net/fec.h +++ b/trunk/drivers/net/fec.h @@ -14,7 +14,7 @@ /****************************************************************************/ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) /* * Just figures, Motorola would have to change the offsets for * registers in the same peripheral device on different models diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 21be4fa071b5..62b38a4494b8 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -1495,8 +1495,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_skbuff[nr] = skb; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->gso_size) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); + if (skb_shinfo(skb)->tso_size) + tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); else #endif tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); @@ -2076,7 +2076,7 @@ static void nv_set_multicast(struct net_device *dev) spin_unlock_irq(&np->lock); } -static void nv_update_pause(struct net_device *dev, u32 pause_flags) +void nv_update_pause(struct net_device *dev, u32 pause_flags) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); diff --git a/trunk/drivers/net/fs_enet/fs_enet-mii.c b/trunk/drivers/net/fs_enet/fs_enet-mii.c index 0cd07150bf4a..c6770377ef87 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-mii.c +++ b/trunk/drivers/net/fs_enet/fs_enet-mii.c @@ -431,7 +431,8 @@ static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) return bus; err: - kfree(bus); + if (bus) + kfree(bus); return ERR_PTR(ret); } diff --git a/trunk/drivers/net/hp100.c b/trunk/drivers/net/hp100.c index dd1dc32dc98d..247c8ca86033 100644 --- a/trunk/drivers/net/hp100.c +++ b/trunk/drivers/net/hp100.c @@ -1487,8 +1487,11 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) if (skb->len <= 0) return 0; - if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN)) - return 0; + if (skb->len < ETH_ZLEN && lp->chip == HP100_CHIPID_SHASTA) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; + } /* Get Tx ring tail pointer */ if (lp->txrtail->next == lp->txrhead) { diff --git a/trunk/drivers/net/ibmveth.c b/trunk/drivers/net/ibmveth.c index 4c2e7279ba34..666346f6469e 100644 --- a/trunk/drivers/net/ibmveth.c +++ b/trunk/drivers/net/ibmveth.c @@ -61,7 +61,7 @@ #undef DEBUG #define ibmveth_printk(fmt, args...) \ - printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args) + printk(KERN_INFO "%s: " fmt, __FILE__, ## args) #define ibmveth_error_printk(fmt, args...) \ printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) diff --git a/trunk/drivers/net/ioc3-eth.c b/trunk/drivers/net/ioc3-eth.c index e76e6e7be0b1..ae71ed57c12d 100644 --- a/trunk/drivers/net/ioc3-eth.c +++ b/trunk/drivers/net/ioc3-eth.c @@ -145,7 +145,7 @@ static inline struct sk_buff * ioc3_alloc_skb(unsigned long length, static inline unsigned long ioc3_map(void *ptr, unsigned long vdev) { #ifdef CONFIG_SGI_IP27 - vdev <<= 57; /* Shift to PCI64_ATTR_VIRTUAL */ + vdev <<= 58; /* Shift to PCI64_ATTR_VIRTUAL */ return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF | ((unsigned long)ptr & TO_PHYS_MASK); diff --git a/trunk/drivers/net/irda/irda-usb.c b/trunk/drivers/net/irda/irda-usb.c index 2a0d538b387f..844fa74ac9ec 100644 --- a/trunk/drivers/net/irda/irda-usb.c +++ b/trunk/drivers/net/irda/irda-usb.c @@ -1105,7 +1105,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) return ret; /* We get a patch from userspace */ - IRDA_MESSAGE("%s(): Received firmware %s (%zu bytes)\n", + IRDA_MESSAGE("%s(): Received firmware %s (%u bytes)\n", __FUNCTION__, stir421x_fw_name, fw->size); ret = -EINVAL; diff --git a/trunk/drivers/net/irda/irport.c b/trunk/drivers/net/irda/irport.c index 44efd49bf4a9..98fa5319e5cc 100644 --- a/trunk/drivers/net/irda/irport.c +++ b/trunk/drivers/net/irda/irport.c @@ -386,7 +386,7 @@ static int __irport_change_speed(struct irda_task *task) /* Locking notes : this function may be called from irq context with * spinlock, via irport_write_wakeup(), or from non-interrupt without * spinlock (from the task timer). Yuck ! - * This is ugly, and unsafe is the spinlock is not already acquired. + * This is ugly, and unsafe is the spinlock is not already aquired. * This will be fixed when irda-task get rewritten. * Jean II */ if (!spin_is_locked(&self->lock)) { diff --git a/trunk/drivers/net/irda/nsc-ircc.c b/trunk/drivers/net/irda/nsc-ircc.c index cb62f2a9676a..cc7ff8f00e42 100644 --- a/trunk/drivers/net/irda/nsc-ircc.c +++ b/trunk/drivers/net/irda/nsc-ircc.c @@ -115,12 +115,8 @@ static nsc_chip_t chips[] = { /* Contributed by Jan Frey - IBM A30/A31 */ { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, nsc_ircc_probe_39x, nsc_ircc_init_39x }, - /* IBM ThinkPads using PC8738x (T60/X60/Z60) */ - { "IBM-PC8738x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, - nsc_ircc_probe_39x, nsc_ircc_init_39x }, - /* IBM ThinkPads using PC8394T (T43/R52/?) */ - { "IBM-PC8394T", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf9, 0xff, - nsc_ircc_probe_39x, nsc_ircc_init_39x }, + { "IBM", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, + nsc_ircc_probe_39x, nsc_ircc_init_39x }, { NULL } }; diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index 93394d76587a..f0f04be989d6 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include @@ -1036,22 +1035,11 @@ static struct ethtool_ops ops = { .get_link = veth_get_link, }; -static struct net_device * __init veth_probe_one(int vlan, - struct vio_dev *vio_dev) +static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) { struct net_device *dev; struct veth_port *port; - struct device *vdev = &vio_dev->dev; int i, rc; - const unsigned char *mac_addr; - - mac_addr = vio_get_attribute(vio_dev, "local-mac-address", NULL); - if (mac_addr == NULL) - mac_addr = vio_get_attribute(vio_dev, "mac-address", NULL); - if (mac_addr == NULL) { - veth_error("Unable to fetch MAC address from device tree.\n"); - return NULL; - } dev = alloc_etherdev(sizeof (struct veth_port)); if (! dev) { @@ -1076,11 +1064,16 @@ static struct net_device * __init veth_probe_one(int vlan, } port->dev = vdev; - memcpy(dev->dev_addr, mac_addr, ETH_ALEN); + dev->dev_addr[0] = 0x02; + dev->dev_addr[1] = 0x01; + dev->dev_addr[2] = 0xff; + dev->dev_addr[3] = vlan; + dev->dev_addr[4] = 0xff; + dev->dev_addr[5] = this_lp; dev->mtu = VETH_MAX_MTU; - memcpy(&port->mac_addr, mac_addr, ETH_ALEN); + memcpy(&port->mac_addr, dev->dev_addr, 6); dev->open = veth_open; dev->hard_start_xmit = veth_start_xmit; @@ -1615,7 +1608,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct net_device *dev; struct veth_port *port; - dev = veth_probe_one(i, vdev); + dev = veth_probe_one(i, &vdev->dev); if (dev == NULL) { veth_remove(vdev); return 1; @@ -1648,7 +1641,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) * support. */ static struct vio_device_id veth_device_table[] __devinitdata = { - { "network", "IBM,iSeries-l-lan" }, + { "vlan", "" }, { "", "" } }; MODULE_DEVICE_TABLE(vio, veth_device_table); diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 8bb32f946993..57006fb8840e 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -1173,7 +1173,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) uint16_t ipcse, tucse, mss; int err; - if(likely(skb_shinfo(skb)->gso_size)) { + if(likely(skb_shinfo(skb)->tso_size)) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -1181,7 +1181,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c index c1c3452c90ca..bb5ad479210b 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -968,7 +968,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The old LANCE chips doesn't automatically pad buffers to min. size. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) { if (skb->len < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) goto out; lp->tx_ring[entry].length = -ETH_ZLEN; } diff --git a/trunk/drivers/net/lasi_82596.c b/trunk/drivers/net/lasi_82596.c index 1ab09447baa5..957888de3d7e 100644 --- a/trunk/drivers/net/lasi_82596.c +++ b/trunk/drivers/net/lasi_82596.c @@ -1083,7 +1083,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len, skb->data)); if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/loopback.c b/trunk/drivers/net/loopback.c index 43fef7de8cb9..b79d6e8d3045 100644 --- a/trunk/drivers/net/loopback.c +++ b/trunk/drivers/net/loopback.c @@ -74,7 +74,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); unsigned int doffset = (iph->ihl + th->doff) * 4; - unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; + unsigned int mtu = skb_shinfo(skb)->tso_size + doffset; unsigned int offset = 0; u32 seq = ntohl(th->seq); u16 id = ntohs(iph->id); @@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) #endif #ifdef LOOPBACK_TSO - if (skb_shinfo(skb)->gso_size) { + if (skb_shinfo(skb)->tso_size) { BUG_ON(skb->protocol != htons(ETH_P_IP)); BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); diff --git a/trunk/drivers/net/lp486e.c b/trunk/drivers/net/lp486e.c index bf3f343ae715..94d5ea1ce8bd 100644 --- a/trunk/drivers/net/lp486e.c +++ b/trunk/drivers/net/lp486e.c @@ -877,7 +877,8 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { length = skb->len; if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index dbdf189436fa..e1feb58bd661 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -1879,7 +1879,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef NETIF_F_TSO if (skb->len > (dev->mtu + ETH_HLEN)) { - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (mss != 0) max_segments = MYRI10GE_MAX_SEND_DESC_TSO; } @@ -1939,7 +1939,8 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) /* pad frames to at least ETH_ZLEN bytes */ if (unlikely(skb->len < ETH_ZLEN)) { - if (skb_padto(skb, ETH_ZLEN)) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) { /* The packet is gone, so we must * return 0 */ mgp->stats.tx_dropped += 1; @@ -2112,14 +2113,14 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) } idx = (idx + 1) & tx->mask; } while (idx != last_idx); - if (skb_shinfo(skb)->gso_size) { + if (skb_shinfo(skb)->tso_size) { printk(KERN_ERR "myri10ge: %s: TSO but wanted to linearize?!?!?\n", mgp->dev->name); goto drop; } - if (skb_linearize(skb)) + if (skb_linearize(skb, GFP_ATOMIC)) goto drop; mgp->tx_linearized++; @@ -2250,6 +2251,12 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) } cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR); + /* nvidia ext cap is not always linked in ext cap chain */ + if (!cap + && bridge->vendor == PCI_VENDOR_ID_NVIDIA + && bridge->device == PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_PCIE) + cap = 0x160; + if (!cap) return; @@ -2725,6 +2732,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Save configuration space to be restored if the * nic resets due to a parity error */ myri10ge_save_state(mgp); + /* Restore state immediately since pci_save_msi_state disables MSI */ + myri10ge_restore_state(mgp); /* Setup the watchdog timer */ setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, diff --git a/trunk/drivers/net/myri_sbus.c b/trunk/drivers/net/myri_sbus.c index d9f616fea3d9..6c86dca62e2a 100644 --- a/trunk/drivers/net/myri_sbus.c +++ b/trunk/drivers/net/myri_sbus.c @@ -1,10 +1,10 @@ -/* myri_sbus.c: MyriCOM MyriNET SBUS card driver. +/* myri_sbus.h: MyriCOM MyriNET SBUS card driver. * - * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) */ static char version[] = - "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; + "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; #include #include @@ -81,6 +81,10 @@ static char version[] = #define DHDR(x) #endif +#ifdef MODULE +static struct myri_eth *root_myri_dev; +#endif + static void myri_reset_off(void __iomem *lp, void __iomem *cregs) { /* Clear IRQ mask. */ @@ -892,9 +896,8 @@ static void dump_eeprom(struct myri_eth *mp) } #endif -static int __init myri_ether_init(struct sbus_dev *sdev) +static int __init myri_ether_init(struct sbus_dev *sdev, int num) { - static int num; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; @@ -910,9 +913,6 @@ static int __init myri_ether_init(struct sbus_dev *sdev) if (version_printed++ == 0) printk(version); - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); - mp = (struct myri_eth *) dev->priv; spin_lock_init(&mp->irq_lock); mp->myri_sdev = sdev; @@ -1092,9 +1092,10 @@ static int __init myri_ether_init(struct sbus_dev *sdev) goto err_free_irq; } - dev_set_drvdata(&sdev->ofdev.dev, mp); - - num++; +#ifdef MODULE + mp->next_module = root_myri_dev; + root_myri_dev = mp; +#endif printk("%s: MyriCOM MyriNET Ethernet ", dev->name); @@ -1113,68 +1114,61 @@ static int __init myri_ether_init(struct sbus_dev *sdev) return -ENODEV; } - -static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __init myri_sbus_match(struct sbus_dev *sdev) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); + char *name = sdev->prom_name; + + if (!strcmp(name, "MYRICOM,mlanai") || + !strcmp(name, "myri")) + return 1; - return myri_ether_init(sdev); + return 0; } -static int __devexit myri_sbus_remove(struct of_device *dev) +static int __init myri_sbus_probe(void) { - struct myri_eth *mp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = mp->dev; + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; + static int called; + int cards = 0, v; - unregister_netdevice(net_dev); - - free_irq(net_dev->irq, net_dev); +#ifdef MODULE + root_myri_dev = NULL; +#endif - if (mp->eeprom.cpuvers < CPUVERS_4_0) { - sbus_iounmap(mp->regs, mp->reg_size); - } else { - sbus_iounmap(mp->cregs, PAGE_SIZE); - sbus_iounmap(mp->lregs, (256 * 1024)); - sbus_iounmap(mp->lanai, (512 * 1024)); + if (called) + return -ENODEV; + called++; + + for_each_sbus(bus) { + for_each_sbusdev(sdev, bus) { + if (myri_sbus_match(sdev)) { + cards++; + DET(("Found myricom myrinet as %s\n", sdev->prom_name)); + if ((v = myri_ether_init(sdev, (cards - 1)))) + return v; + } + } } - - free_netdev(net_dev); - - dev_set_drvdata(&dev->dev, NULL); - + if (!cards) + return -ENODEV; return 0; } -static struct of_device_id myri_sbus_match[] = { - { - .name = "MYRICOM,mlanai", - }, - { - .name = "myri", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, myri_sbus_match); - -static struct of_platform_driver myri_sbus_driver = { - .name = "myri", - .match_table = myri_sbus_match, - .probe = myri_sbus_probe, - .remove = __devexit_p(myri_sbus_remove), -}; - -static int __init myri_sbus_init(void) -{ - return of_register_driver(&myri_sbus_driver, &sbus_bus_type); -} - -static void __exit myri_sbus_exit(void) +static void __exit myri_sbus_cleanup(void) { - of_unregister_driver(&myri_sbus_driver); +#ifdef MODULE + while (root_myri_dev) { + struct myri_eth *next = root_myri_dev->next_module; + + unregister_netdev(root_myri_dev->dev); + /* this will also free the co-allocated 'root_myri_dev' */ + free_netdev(root_myri_dev->dev); + root_myri_dev = next; + } +#endif /* MODULE */ } -module_init(myri_sbus_init); -module_exit(myri_sbus_exit); - +module_init(myri_sbus_probe); +module_exit(myri_sbus_cleanup); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/myri_sbus.h b/trunk/drivers/net/myri_sbus.h index 2f69ef7cdccb..47722f708a41 100644 --- a/trunk/drivers/net/myri_sbus.h +++ b/trunk/drivers/net/myri_sbus.h @@ -290,6 +290,7 @@ struct myri_eth { unsigned int reg_size; /* Size of register space. */ unsigned int shmem_base; /* Offset to shared ram. */ struct sbus_dev *myri_sdev; /* Our SBUS device struct. */ + struct myri_eth *next_module; /* Next in adapter chain. */ }; /* We use this to acquire receive skb's that we can DMA directly into. */ diff --git a/trunk/drivers/net/netx-eth.c b/trunk/drivers/net/netx-eth.c deleted file mode 100644 index b92430c4e3ac..000000000000 --- a/trunk/drivers/net/netx-eth.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * drivers/net/netx-eth.c - * - * Copyright (c) 2005 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* XC Fifo Offsets */ -#define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */ -#define IND_FIFO_PORT_HI(xcno) (1 + ((xcno) << 3)) /* Index of the FIFO where received */ - /* Data packages are indicated by XC */ -#define IND_FIFO_PORT_LO(xcno) (2 + ((xcno) << 3)) /* Index of the FIFO where received */ - /* Data packages are indicated by XC */ -#define REQ_FIFO_PORT_HI(xcno) (3 + ((xcno) << 3)) /* Index of the FIFO where Data packages */ - /* have to be indicated by ARM which */ - /* shall be sent */ -#define REQ_FIFO_PORT_LO(xcno) (4 + ((xcno) << 3)) /* Index of the FIFO where Data packages */ - /* have to be indicated by ARM which shall */ - /* be sent */ -#define CON_FIFO_PORT_HI(xcno) (5 + ((xcno) << 3)) /* Index of the FIFO where sent Data packages */ - /* are confirmed */ -#define CON_FIFO_PORT_LO(xcno) (6 + ((xcno) << 3)) /* Index of the FIFO where sent Data */ - /* packages are confirmed */ -#define PFIFO_MASK(xcno) (0x7f << (xcno*8)) - -#define FIFO_PTR_FRAMELEN_SHIFT 0 -#define FIFO_PTR_FRAMELEN_MASK (0x7ff << 0) -#define FIFO_PTR_FRAMELEN(len) (((len) << 0) & FIFO_PTR_FRAMELEN_MASK) -#define FIFO_PTR_TIMETRIG (1<<11) -#define FIFO_PTR_MULTI_REQ -#define FIFO_PTR_ORIGIN (1<<14) -#define FIFO_PTR_VLAN (1<<15) -#define FIFO_PTR_FRAMENO_SHIFT 16 -#define FIFO_PTR_FRAMENO_MASK (0x3f << 16) -#define FIFO_PTR_FRAMENO(no) (((no) << 16) & FIFO_PTR_FRAMENO_MASK) -#define FIFO_PTR_SEGMENT_SHIFT 22 -#define FIFO_PTR_SEGMENT_MASK (0xf << 22) -#define FIFO_PTR_SEGMENT(seg) (((seg) & 0xf) << 22) -#define FIFO_PTR_ERROR_SHIFT 28 -#define FIFO_PTR_ERROR_MASK (0xf << 28) - -#define ISR_LINK_STATUS_CHANGE (1<<4) -#define ISR_IND_LO (1<<3) -#define ISR_CON_LO (1<<2) -#define ISR_IND_HI (1<<1) -#define ISR_CON_HI (1<<0) - -#define ETH_MAC_LOCAL_CONFIG 0x1560 -#define ETH_MAC_4321 0x1564 -#define ETH_MAC_65 0x1568 - -#define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16 -#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<data; - unsigned int len = skb->len; - - spin_lock_irq(&priv->lock); - memcpy_toio(priv->sram_base + 1560, (void *)buf, len); - if (len < 60) { - memset_io(priv->sram_base + 1560 + len, 0, 60 - len); - len = 60; - } - - pfifo_push(REQ_FIFO_PORT_LO(priv->id), - FIFO_PTR_SEGMENT(priv->id) | - FIFO_PTR_FRAMENO(1) | - FIFO_PTR_FRAMELEN(len)); - - ndev->trans_start = jiffies; - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; - - netif_stop_queue(ndev); - spin_unlock_irq(&priv->lock); - dev_kfree_skb(skb); - - return 0; -} - -static void netx_eth_receive(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - unsigned int val, frameno, seg, len; - unsigned char *data; - struct sk_buff *skb; - - val = pfifo_pop(IND_FIFO_PORT_LO(priv->id)); - - frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT; - seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT; - len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT; - - skb = dev_alloc_skb(len); - if (unlikely(skb == NULL)) { - printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", - ndev->name); - priv->stats.rx_dropped++; - return; - } - - data = skb_put(skb, len); - - memcpy_fromio(data, priv->sram_base + frameno * 1560, len); - - pfifo_push(EMPTY_PTR_FIFO(priv->id), - FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno)); - - ndev->last_rx = jiffies; - skb->dev = ndev; - skb->protocol = eth_type_trans(skb, ndev); - netif_rx(skb); - priv->stats.rx_packets++; - priv->stats.rx_bytes += len; -} - -static irqreturn_t -netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *ndev = dev_id; - struct netx_eth_priv *priv = netdev_priv(ndev); - int status; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - status = readl(NETX_PFIFO_XPEC_ISR(priv->id)); - while (status) { - int fill_level; - writel(status, NETX_PFIFO_XPEC_ISR(priv->id)); - - if ((status & ISR_CON_HI) || (status & ISR_IND_HI)) - printk("%s: unexpected status: 0x%08x\n", - __FUNCTION__, status); - - fill_level = - readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id))); - while (fill_level--) - netx_eth_receive(ndev); - - if (status & ISR_CON_LO) - netif_wake_queue(ndev); - - if (status & ISR_LINK_STATUS_CHANGE) - mii_check_media(&priv->mii, netif_msg_link(priv), 1); - - status = readl(NETX_PFIFO_XPEC_ISR(priv->id)); - } - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_HANDLED; -} - -static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - return &priv->stats; -} - -static int netx_eth_open(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - - if (request_irq - (ndev->irq, &netx_eth_interrupt, SA_SHIRQ, ndev->name, ndev)) - return -EAGAIN; - - writel(ndev->dev_addr[0] | - ndev->dev_addr[1]<<8 | - ndev->dev_addr[2]<<16 | - ndev->dev_addr[3]<<24, - priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321); - writel(ndev->dev_addr[4] | - ndev->dev_addr[5]<<8, - priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65); - - writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN | - LOCAL_CONFIG_CON_LO_IRQ_EN | - LOCAL_CONFIG_CON_HI_IRQ_EN | - LOCAL_CONFIG_IND_LO_IRQ_EN | - LOCAL_CONFIG_IND_HI_IRQ_EN, - priv->xpec_base + NETX_XPEC_RAM_START_OFS + - ETH_MAC_LOCAL_CONFIG); - - mii_check_media(&priv->mii, netif_msg_link(priv), 1); - netif_start_queue(ndev); - - return 0; -} - -static int netx_eth_close(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - - netif_stop_queue(ndev); - - writel(0, - priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG); - - free_irq(ndev->irq, ndev); - - return 0; -} - -static void netx_eth_timeout(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - int i; - - printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name); - - spin_lock_irq(&priv->lock); - - xc_reset(priv->xc); - xc_start(priv->xc); - - for (i=2; i<=18; i++) - pfifo_push(EMPTY_PTR_FIFO(priv->id), - FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id)); - - spin_unlock_irq(&priv->lock); - - netif_wake_queue(ndev); -} - -static int -netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg) -{ - unsigned int val; - - val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) | - MIIMU_REGADDR(reg) | MIIMU_PHY_NRES; - - writel(val, NETX_MIIMU); - while (readl(NETX_MIIMU) & MIIMU_SNRDY); - - return readl(NETX_MIIMU) >> 16; - -} - -static void -netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value) -{ - unsigned int val; - - val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) | - MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE | - MIIMU_DATA(value); - - writel(val, NETX_MIIMU); - while (readl(NETX_MIIMU) & MIIMU_SNRDY); -} - -static int netx_eth_enable(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - unsigned int mac4321, mac65; - int running, i; - - ether_setup(ndev); - - ndev->open = netx_eth_open; - ndev->stop = netx_eth_close; - ndev->hard_start_xmit = netx_eth_hard_start_xmit; - ndev->tx_timeout = netx_eth_timeout; - ndev->watchdog_timeo = msecs_to_jiffies(5000); - ndev->get_stats = netx_eth_query_statistics; - ndev->set_multicast_list = netx_eth_set_multicast_list; - - priv->msg_enable = NETIF_MSG_LINK; - priv->mii.phy_id_mask = 0x1f; - priv->mii.reg_num_mask = 0x1f; - priv->mii.force_media = 0; - priv->mii.full_duplex = 0; - priv->mii.dev = ndev; - priv->mii.mdio_read = netx_eth_phy_read; - priv->mii.mdio_write = netx_eth_phy_write; - priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id; - - running = xc_running(priv->xc); - xc_stop(priv->xc); - - /* if the xc engine is already running, assume the bootloader has - * loaded the firmware for us - */ - if (running) { - /* get Node Address from hardware */ - mac4321 = readl(priv->xpec_base + - NETX_XPEC_RAM_START_OFS + ETH_MAC_4321); - mac65 = readl(priv->xpec_base + - NETX_XPEC_RAM_START_OFS + ETH_MAC_65); - - ndev->dev_addr[0] = mac4321 & 0xff; - ndev->dev_addr[1] = (mac4321 >> 8) & 0xff; - ndev->dev_addr[2] = (mac4321 >> 16) & 0xff; - ndev->dev_addr[3] = (mac4321 >> 24) & 0xff; - ndev->dev_addr[4] = mac65 & 0xff; - ndev->dev_addr[5] = (mac65 >> 8) & 0xff; - } else { - if (xc_request_firmware(priv->xc)) { - printk(CARDNAME ": requesting firmware failed\n"); - return -ENODEV; - } - } - - xc_reset(priv->xc); - xc_start(priv->xc); - - if (!is_valid_ether_addr(ndev->dev_addr)) - printk("%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", ndev->name); - - for (i=2; i<=18; i++) - pfifo_push(EMPTY_PTR_FIFO(priv->id), - FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id)); - - return register_netdev(ndev); - -} - -static int netx_eth_drv_probe(struct platform_device *pdev) -{ - struct netx_eth_priv *priv; - struct net_device *ndev; - struct netxeth_platform_data *pdata; - int ret; - - ndev = alloc_etherdev(sizeof (struct netx_eth_priv)); - if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); - ret = -ENOMEM; - goto exit; - } - SET_MODULE_OWNER(ndev); - SET_NETDEV_DEV(ndev, &pdev->dev); - - platform_set_drvdata(pdev, ndev); - - priv = netdev_priv(ndev); - - pdata = (struct netxeth_platform_data *)pdev->dev.platform_data; - priv->xc = request_xc(pdata->xcno, &pdev->dev); - if (!priv->xc) { - dev_err(&pdev->dev, "unable to request xc engine\n"); - ret = -ENODEV; - goto exit_free_netdev; - } - - ndev->irq = priv->xc->irq; - priv->id = pdev->id; - priv->xpec_base = priv->xc->xpec_base; - priv->xmac_base = priv->xc->xmac_base; - priv->sram_base = priv->xc->sram_base; - - ret = pfifo_request(PFIFO_MASK(priv->id)); - if (ret) { - printk("unable to request PFIFO\n"); - goto exit_free_xc; - } - - ret = netx_eth_enable(ndev); - if (ret) - goto exit_free_pfifo; - - return 0; -exit_free_pfifo: - pfifo_free(PFIFO_MASK(priv->id)); -exit_free_xc: - free_xc(priv->xc); -exit_free_netdev: - platform_set_drvdata(pdev, NULL); - free_netdev(ndev); -exit: - return ret; -} - -static int netx_eth_drv_remove(struct platform_device *pdev) -{ - struct net_device *ndev = dev_get_drvdata(&pdev->dev); - struct netx_eth_priv *priv = netdev_priv(ndev); - - platform_set_drvdata(pdev, NULL); - - unregister_netdev(ndev); - xc_stop(priv->xc); - free_xc(priv->xc); - free_netdev(ndev); - pfifo_free(PFIFO_MASK(priv->id)); - - return 0; -} - -static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state) -{ - dev_err(&pdev->dev, "suspend not implemented\n"); - return 0; -} - -static int netx_eth_drv_resume(struct platform_device *pdev) -{ - dev_err(&pdev->dev, "resume not implemented\n"); - return 0; -} - -static struct platform_driver netx_eth_driver = { - .probe = netx_eth_drv_probe, - .remove = netx_eth_drv_remove, - .suspend = netx_eth_drv_suspend, - .resume = netx_eth_drv_resume, - .driver = { - .name = CARDNAME, - .owner = THIS_MODULE, - }, -}; - -static int __init netx_eth_init(void) -{ - unsigned int phy_control, val; - - printk("NetX Ethernet driver\n"); - - phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) | - PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) | - PHY_CONTROL_PHY1_AUTOMDIX | - PHY_CONTROL_PHY1_EN | - PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) | - PHY_CONTROL_PHY0_AUTOMDIX | - PHY_CONTROL_PHY0_EN | - PHY_CONTROL_CLK_XLATIN; - - val = readl(NETX_SYSTEM_IOC_ACCESS_KEY); - writel(val, NETX_SYSTEM_IOC_ACCESS_KEY); - - writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL); - udelay(100); - - val = readl(NETX_SYSTEM_IOC_ACCESS_KEY); - writel(val, NETX_SYSTEM_IOC_ACCESS_KEY); - - writel(phy_control, NETX_SYSTEM_PHY_CONTROL); - - return platform_driver_register(&netx_eth_driver); -} - -static void __exit netx_eth_cleanup(void) -{ - platform_driver_unregister(&netx_eth_driver); -} - -module_init(netx_eth_init); -module_exit(netx_eth_cleanup); - -MODULE_AUTHOR("Sascha Hauer, Pengutronix"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/net/pcmcia/fmvj18x_cs.c b/trunk/drivers/net/pcmcia/fmvj18x_cs.c index ea93b8f18605..09b11761cdfa 100644 --- a/trunk/drivers/net/pcmcia/fmvj18x_cs.c +++ b/trunk/drivers/net/pcmcia/fmvj18x_cs.c @@ -831,7 +831,8 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev) if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index a73d54553030..e74bf5014ef6 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -1883,7 +1883,7 @@ static void smc_reset(struct net_device *dev) /* Set the Window 1 control, configuration and station addr registers. No point in writing the I/O base register ;-> */ SMC_SELECT_BANK(1); - /* Automatically release successfully transmitted packets, + /* Automatically release succesfully transmitted packets, Accept link errors, counter and Tx error interrupts. */ outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ioaddr + CONTROL); diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index 9bae77ce1314..71f45056a70c 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -1359,7 +1359,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; int okay; unsigned freespace; - unsigned pktlen = skb->len; + unsigned pktlen = skb? skb->len : 0; DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", skb, dev, pktlen); @@ -1374,7 +1374,8 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; pktlen = ETH_ZLEN; } diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index 2ba6d3a40e2e..cda3e53d6917 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -44,11 +44,6 @@ config CICADA_PHY depends on PHYLIB ---help--- Currently supports the cis8204 -config VITESSE_PHY - tristate "Drivers for the Vitesse PHYs" - depends on PHYLIB - ---help--- - Currently supports the vsc8244 config SMSC_PHY tristate "Drivers for SMSC PHYs" diff --git a/trunk/drivers/net/phy/Makefile b/trunk/drivers/net/phy/Makefile index a00e61942525..d9614134cc06 100644 --- a/trunk/drivers/net/phy/Makefile +++ b/trunk/drivers/net/phy/Makefile @@ -9,4 +9,3 @@ obj-$(CONFIG_CICADA_PHY) += cicada.o obj-$(CONFIG_LXT_PHY) += lxt.o obj-$(CONFIG_QSEMI_PHY) += qsemi.o obj-$(CONFIG_SMSC_PHY) += smsc.o -obj-$(CONFIG_VITESSE_PHY) += vitesse.o diff --git a/trunk/drivers/net/phy/vitesse.c b/trunk/drivers/net/phy/vitesse.c deleted file mode 100644 index ffd215d9a9be..000000000000 --- a/trunk/drivers/net/phy/vitesse.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Driver for Vitesse PHYs - * - * Author: Kriston Carson - * - * Copyright (c) 2005 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include - -/* Vitesse Extended Control Register 1 */ -#define MII_VSC8244_EXT_CON1 0x17 -#define MII_VSC8244_EXTCON1_INIT 0x0000 - -/* Vitesse Interrupt Mask Register */ -#define MII_VSC8244_IMASK 0x19 -#define MII_VSC8244_IMASK_IEN 0x8000 -#define MII_VSC8244_IMASK_SPEED 0x4000 -#define MII_VSC8244_IMASK_LINK 0x2000 -#define MII_VSC8244_IMASK_DUPLEX 0x1000 -#define MII_VSC8244_IMASK_MASK 0xf000 - -/* Vitesse Interrupt Status Register */ -#define MII_VSC8244_ISTAT 0x1a -#define MII_VSC8244_ISTAT_STATUS 0x8000 -#define MII_VSC8244_ISTAT_SPEED 0x4000 -#define MII_VSC8244_ISTAT_LINK 0x2000 -#define MII_VSC8244_ISTAT_DUPLEX 0x1000 - -/* Vitesse Auxiliary Control/Status Register */ -#define MII_VSC8244_AUX_CONSTAT 0x1c -#define MII_VSC8244_AUXCONSTAT_INIT 0x0004 -#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 -#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 -#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 -#define MII_VSC8244_AUXCONSTAT_100 0x0008 - -MODULE_DESCRIPTION("Vitesse PHY driver"); -MODULE_AUTHOR("Kriston Carson"); -MODULE_LICENSE("GPL"); - -static int vsc824x_config_init(struct phy_device *phydev) -{ - int err; - - err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, - MII_VSC8244_AUXCONSTAT_INIT); - if (err < 0) - return err; - - err = phy_write(phydev, MII_VSC8244_EXT_CON1, - MII_VSC8244_EXTCON1_INIT); - return err; -} - -static int vsc824x_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, MII_VSC8244_ISTAT); - - return (err < 0) ? err : 0; -} - -static int vsc824x_config_intr(struct phy_device *phydev) -{ - int err; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) - err = phy_write(phydev, MII_VSC8244_IMASK, - MII_VSC8244_IMASK_MASK); - else - err = phy_write(phydev, MII_VSC8244_IMASK, 0); - return err; -} - -/* Vitesse 824x */ -static struct phy_driver vsc8244_driver = { - .phy_id = 0x000fc6c2, - .name = "Vitesse VSC8244", - .phy_id_mask = 0x000fffc0, - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, - .config_init = &vsc824x_config_init, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, - .ack_interrupt = &vsc824x_ack_interrupt, - .config_intr = &vsc824x_config_intr, - .driver = { .owner = THIS_MODULE,}, -}; - -static int __init vsc8244_init(void) -{ - return phy_driver_register(&vsc8244_driver); -} - -static void __exit vsc8244_exit(void) -{ - phy_driver_unregister(&vsc8244_driver); -} - -module_init(vsc8244_init); -module_exit(vsc8244_exit); diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index d643a097faa5..01cd8ec751ea 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -2578,7 +2578,8 @@ ppp_find_channel(int unit) list_for_each_entry(pch, &new_channels, list) { if (pch->file.index == unit) { - list_move(&pch->list, &all_channels); + list_del(&pch->list); + list_add(&pch->list, &all_channels); return pch; } } diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 12d1cb289bb0..9945cc6b8d90 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -2172,7 +2172,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) { if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->gso_size; + u32 mss = skb_shinfo(skb)->tso_size; if (mss) return LargeSend | ((mss & MSSMask) << MSSShift); @@ -2222,7 +2222,8 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skb->len; if (unlikely(len < ETH_ZLEN)) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (!skb) goto err_update_stats; len = ETH_ZLEN; } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 3defe5d4f7d3..cac9fdd2e1d5 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -2626,50 +2626,6 @@ static int s2io_poll(struct net_device *dev, int *budget) } #endif -/** - * s2io_netpoll - Rx interrupt service handler for netpoll support - * @dev : pointer to the device structure. - * Description: - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void s2io_netpoll(struct net_device *dev) -{ - nic_t *nic = dev->priv; - mac_info_t *mac_control; - struct config_param *config; - XENA_dev_config_t __iomem *bar0 = nic->bar0; - u64 val64; - int i; - - disable_irq(dev->irq); - - atomic_inc(&nic->isr_cnt); - mac_control = &nic->mac_control; - config = &nic->config; - - val64 = readq(&bar0->rx_traffic_int); - writeq(val64, &bar0->rx_traffic_int); - - for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); - - for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n"); - break; - } - } - atomic_dec(&nic->isr_cnt); - enable_irq(dev->irq); - return; -} -#endif - /** * rx_intr_handler - Rx interrupt handler * @nic: device private variable. @@ -3959,8 +3915,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Control_1 = 0; txdp->Control_2 = 0; #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->gso_size; - if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) { + mss = skb_shinfo(skb)->tso_size; + if (mss) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); } @@ -3980,10 +3936,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } frg_len = skb->len - skb->data_len; - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) { + if (skb_shinfo(skb)->ufo_size) { int ufo_size; - ufo_size = skb_shinfo(skb)->gso_size; + ufo_size = skb_shinfo(skb)->ufo_size; ufo_size &= ~7; txdp->Control_1 |= TXD_UFO_EN; txdp->Control_1 |= TXD_UFO_MSS(ufo_size); @@ -4009,7 +3965,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) txdp->Control_1 |= TXD_UFO_EN; frg_cnt = skb_shinfo(skb)->nr_frags; @@ -4024,12 +3980,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) txdp->Control_1 |= TXD_UFO_EN; } txdp->Control_1 |= TXD_GATHER_CODE_LAST; - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) frg_cnt++; /* as Txd0 was used for inband header */ tx_fifo = mac_control->tx_FIFO_start[queue]; @@ -4043,7 +3999,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) if (mss) val64 |= TX_FIFO_SPECIAL_FUNC; #endif - if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) + if (skb_shinfo(skb)->ufo_size) val64 |= TX_FIFO_SPECIAL_FUNC; writeq(val64, &tx_fifo->List_Control); @@ -7011,10 +6967,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->weight = 32; #endif -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = s2io_netpoll; -#endif - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; diff --git a/trunk/drivers/net/seeq8005.c b/trunk/drivers/net/seeq8005.c index efd0f235020f..bcef03feb2fc 100644 --- a/trunk/drivers/net/seeq8005.c +++ b/trunk/drivers/net/seeq8005.c @@ -396,7 +396,8 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) unsigned char *buf; if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index df39f3447655..31dd3f036fa8 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -1156,7 +1156,8 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) dma_addr_t mapping; if (unlikely(skb->len < ETH_ZLEN)) { - if (skb_padto(skb, ETH_ZLEN)) { + skb = skb_padto(skb, ETH_ZLEN); + if (!skb) { tp->stats.tx_dropped++; goto out; } diff --git a/trunk/drivers/net/sk98lin/skge.c b/trunk/drivers/net/sk98lin/skge.c index f3efbd177ae7..38a26df4095f 100644 --- a/trunk/drivers/net/sk98lin/skge.c +++ b/trunk/drivers/net/sk98lin/skge.c @@ -1525,7 +1525,7 @@ struct sk_buff *pMessage) /* pointer to send-message */ ** This is to resolve faulty padding by the HW with 0xaa bytes. */ if (BytesSend < C_LEN_ETHERNET_MINSIZE) { - if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) { + if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); return 0; } diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 19a4a16055dc..536dd1cf7f79 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -2310,7 +2310,8 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) u64 map; unsigned long flags; - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (!skb) return NETDEV_TX_OK; if (!spin_trylock_irqsave(&skge->tx_lock, flags)) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index d3577871be28..fba1e4d4d83d 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -1160,7 +1160,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_shinfo(skb)->gso_size) + if (skb_shinfo(skb)->tso_size) ++count; if (skb->ip_summed == CHECKSUM_HW) @@ -1232,7 +1232,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) } /* Check for TCP Segmentation Offload */ - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->tso_size; if (mss != 0) { /* just drop the packet if non-linear expansion fails */ if (skb_header_cloned(skb) && diff --git a/trunk/drivers/net/smc9194.c b/trunk/drivers/net/smc9194.c index 8b0321f1976c..6cf16f322ad5 100644 --- a/trunk/drivers/net/smc9194.c +++ b/trunk/drivers/net/smc9194.c @@ -523,7 +523,8 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de length = skb->len; if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) { netif_wake_queue(dev); return 0; } diff --git a/trunk/drivers/net/sonic.c b/trunk/drivers/net/sonic.c index cab0dd958492..90b818a8de6e 100644 --- a/trunk/drivers/net/sonic.c +++ b/trunk/drivers/net/sonic.c @@ -231,7 +231,8 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) length = skb->len; if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c index c158eedc7813..9b7805be21da 100644 --- a/trunk/drivers/net/starfire.c +++ b/trunk/drivers/net/starfire.c @@ -1349,7 +1349,8 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) if (skb->ip_summed == CHECKSUM_HW) { - if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK)) + skb = skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK); + if (skb == NULL) return NETDEV_TX_OK; } #endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ diff --git a/trunk/drivers/net/sun3lance.c b/trunk/drivers/net/sun3lance.c index a2fad50437e6..d4c0002b43db 100644 --- a/trunk/drivers/net/sun3lance.c +++ b/trunk/drivers/net/sun3lance.c @@ -55,7 +55,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne /* sun3/60 addr/irq for the lance chip. If your sun is different, change this. */ #define LANCE_OBIO 0x120000 -#define LANCE_IRQ IRQ_AUTO_3 +#define LANCE_IRQ IRQ3 /* Debug level: * 0 = silent, print only serious errors diff --git a/trunk/drivers/net/sunbmac.c b/trunk/drivers/net/sunbmac.c index 7127f0f36f0e..cfaf47c63c58 100644 --- a/trunk/drivers/net/sunbmac.c +++ b/trunk/drivers/net/sunbmac.c @@ -72,6 +72,8 @@ MODULE_LICENSE("GPL"); #define DIRQ(x) #endif +static struct bigmac *root_bigmac_dev; + #define DEFAULT_JAMSIZE 4 /* Toe jam */ #define QEC_RESET_TRIES 200 @@ -489,7 +491,7 @@ static void bigmac_tcvr_init(struct bigmac *bp) } } -static int bigmac_init_hw(struct bigmac *, int); +static int bigmac_init(struct bigmac *, int); static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) { @@ -549,7 +551,7 @@ static void bigmac_timer(unsigned long data) if (ret == -1) { printk(KERN_ERR "%s: Link down, cable problem?\n", bp->dev->name); - ret = bigmac_init_hw(bp, 0); + ret = bigmac_init(bp, 0); if (ret) { printk(KERN_ERR "%s: Error, cannot re-init the " "BigMAC.\n", bp->dev->name); @@ -619,7 +621,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) add_timer(&bp->bigmac_timer); } -static int bigmac_init_hw(struct bigmac *bp, int from_irq) +static int bigmac_init(struct bigmac *bp, int from_irq) { void __iomem *gregs = bp->gregs; void __iomem *cregs = bp->creg; @@ -750,7 +752,7 @@ static void bigmac_is_medium_rare(struct bigmac *bp, u32 qec_status, u32 bmac_st } printk(" RESET\n"); - bigmac_init_hw(bp, 1); + bigmac_init(bp, 1); } /* BigMAC transmit complete service routines. */ @@ -924,7 +926,7 @@ static int bigmac_open(struct net_device *dev) return ret; } init_timer(&bp->bigmac_timer); - ret = bigmac_init_hw(bp, 0); + ret = bigmac_init(bp, 0); if (ret) free_irq(dev->irq, bp); return ret; @@ -948,7 +950,7 @@ static void bigmac_tx_timeout(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; - bigmac_init_hw(bp, 0); + bigmac_init(bp, 0); netif_wake_queue(dev); } @@ -1102,8 +1104,6 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) bp->qec_sdev = qec_sdev; bp->bigmac_sdev = qec_sdev->child; - SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev); - spin_lock_init(&bp->lock); /* Verify the registers we expect, are actually there. */ @@ -1226,7 +1226,11 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) goto fail_and_cleanup; } - dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp); + /* Put us into the list of instances attached for later driver + * exit. + */ + bp->next_module = root_bigmac_dev; + root_bigmac_dev = bp; printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); for (i = 0; i < 6; i++) @@ -1262,68 +1266,69 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) /* QEC can be the parent of either QuadEthernet or * a BigMAC. We want the latter. */ -static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __init bigmac_match(struct sbus_dev *sdev) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - - if (!strcmp(dp->name, "be")) - sdev = sdev->parent; - - return bigmac_ether_init(sdev); -} - -static int __devexit bigmac_sbus_remove(struct of_device *dev) -{ - struct bigmac *bp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = bp->dev; - - unregister_netdevice(net_dev); + struct sbus_dev *child = sdev->child; - sbus_iounmap(bp->gregs, GLOB_REG_SIZE); - sbus_iounmap(bp->creg, CREG_REG_SIZE); - sbus_iounmap(bp->bregs, BMAC_REG_SIZE); - sbus_iounmap(bp->tregs, TCVR_REG_SIZE); - sbus_free_consistent(bp->bigmac_sdev, - PAGE_SIZE, - bp->bmac_block, - bp->bblock_dvma); + if (strcmp(sdev->prom_name, "qec") != 0) + return 0; - free_netdev(net_dev); + if (child == NULL) + return 0; - dev_set_drvdata(&dev->dev, NULL); + if (strcmp(child->prom_name, "be") != 0) + return 0; - return 0; + return 1; } -static struct of_device_id bigmac_sbus_match[] = { - { - .name = "qec", - }, - { - .name = "be", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, bigmac_sbus_match); - -static struct of_platform_driver bigmac_sbus_driver = { - .name = "sunbmac", - .match_table = bigmac_sbus_match, - .probe = bigmac_sbus_probe, - .remove = __devexit_p(bigmac_sbus_remove), -}; - -static int __init bigmac_init(void) +static int __init bigmac_probe(void) { - return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type); + struct sbus_bus *sbus; + struct sbus_dev *sdev = NULL; + static int called; + int cards = 0, v; + + root_bigmac_dev = NULL; + + if (called) + return -ENODEV; + called++; + + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if (bigmac_match(sdev)) { + cards++; + if ((v = bigmac_ether_init(sdev))) + return v; + } + } + } + if (!cards) + return -ENODEV; + return 0; } -static void __exit bigmac_exit(void) +static void __exit bigmac_cleanup(void) { - of_unregister_driver(&bigmac_sbus_driver); + while (root_bigmac_dev) { + struct bigmac *bp = root_bigmac_dev; + struct bigmac *bp_nxt = root_bigmac_dev->next_module; + + sbus_iounmap(bp->gregs, GLOB_REG_SIZE); + sbus_iounmap(bp->creg, CREG_REG_SIZE); + sbus_iounmap(bp->bregs, BMAC_REG_SIZE); + sbus_iounmap(bp->tregs, TCVR_REG_SIZE); + sbus_free_consistent(bp->bigmac_sdev, + PAGE_SIZE, + bp->bmac_block, + bp->bblock_dvma); + + unregister_netdev(bp->dev); + free_netdev(bp->dev); + root_bigmac_dev = bp_nxt; + } } -module_init(bigmac_init); -module_exit(bigmac_exit); +module_init(bigmac_probe); +module_exit(bigmac_cleanup); diff --git a/trunk/drivers/net/sunbmac.h b/trunk/drivers/net/sunbmac.h index b563d3c2993e..b0dbc5187143 100644 --- a/trunk/drivers/net/sunbmac.h +++ b/trunk/drivers/net/sunbmac.h @@ -332,6 +332,7 @@ struct bigmac { struct sbus_dev *qec_sdev; struct sbus_dev *bigmac_sdev; struct net_device *dev; + struct bigmac *next_module; }; /* We use this to acquire receive skb's that we can DMA directly into. */ diff --git a/trunk/drivers/net/sundance.c b/trunk/drivers/net/sundance.c index f13b2a195c70..61eec46cb111 100644 --- a/trunk/drivers/net/sundance.c +++ b/trunk/drivers/net/sundance.c @@ -94,13 +94,11 @@ Version LK1.10 (Philippe De Muyter phdm@macqel.be): - Make 'unblock interface after Tx underrun' work - Version LK1.11 (Pedro Alejandro Lopez-Valencia palopezv at gmail.com): - - Add support for IC Plus Corporation IP100A chipset */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.11" -#define DRV_RELDATE "14-Jun-2006" +#define DRV_VERSION "1.01+LK1.10" +#define DRV_RELDATE "28-Oct-2005" /* The user-configurable values. @@ -289,7 +287,6 @@ static struct pci_device_id sundance_pci_tbl[] = { {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -308,7 +305,6 @@ static const struct pci_id_info pci_id_tbl[] = { {"D-Link DFE-530TXS FAST Ethernet Adapter"}, {"D-Link DL10050-based FAST Ethernet Adapter"}, {"Sundance Technology Alta"}, - {"IC Plus Corporation IP100A FAST Ethernet Adapter"}, {NULL,}, /* 0 terminated list. */ }; diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index 5248670d29f7..38cd30cb7c75 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -2880,20 +2880,17 @@ static int __devinit gem_get_device_address(struct gem *gp) #if defined(__sparc__) struct pci_dev *pdev = gp->pdev; struct pcidev_cookie *pcp = pdev->sysdata; - int use_idprom = 1; + int node = -1; if (pcp != NULL) { - unsigned char *addr; - int len; - - addr = of_get_property(pcp->prom_node, "local-mac-address", - &len); - if (addr && len == 6) { - use_idprom = 0; - memcpy(dev->dev_addr, addr, 6); - } + node = pcp->prom_node; + if (prom_getproplen(node, "local-mac-address") == 6) + prom_getproperty(node, "local-mac-address", + dev->dev_addr, 6); + else + node = -1; } - if (use_idprom) + if (node == -1) memcpy(dev->dev_addr, idprom->id_ethaddr, 6); #elif defined(CONFIG_PPC_PMAC) unsigned char *addr; diff --git a/trunk/drivers/net/sunhme.c b/trunk/drivers/net/sunhme.c index c33ead3470db..bd5d2668a362 100644 --- a/trunk/drivers/net/sunhme.c +++ b/trunk/drivers/net/sunhme.c @@ -1,9 +1,9 @@ -/* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, +/* $Id: sunhme.c,v 1.124 2002/01/15 06:25:51 davem Exp $ + * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. * - * Copyright (C) 1996, 1998, 1999, 2002, 2003, - 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) * * Changes : * 2000/11/11 Willy Tarreau @@ -40,13 +40,15 @@ #include #include -#ifdef CONFIG_SPARC +#ifdef __sparc__ #include #include #include #include -#include #include +#ifndef __sparc_v9__ +#include +#endif #endif #include @@ -55,7 +57,7 @@ #ifdef CONFIG_PCI #include -#ifdef CONFIG_SPARC +#ifdef __sparc__ #include #endif #endif @@ -63,9 +65,9 @@ #include "sunhme.h" #define DRV_NAME "sunhme" -#define DRV_VERSION "3.00" -#define DRV_RELDATE "June 23, 2006" -#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" +#define DRV_VERSION "2.02" +#define DRV_RELDATE "8/24/03" +#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" static char version[] = DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; @@ -81,6 +83,8 @@ static int macaddr[6]; module_param_array(macaddr, int, NULL, 0); MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); +static struct happy_meal *root_happy_dev; + #ifdef CONFIG_SBUS static struct quattro *qfe_sbus_list; #endif @@ -177,6 +181,26 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp) #define DEFAULT_IPG2 4 /* For all modes */ #define DEFAULT_JAMSIZE 4 /* Toe jam */ +#if defined(CONFIG_PCI) && defined(MODULE) +/* This happy_pci_ids is declared __initdata because it is only used + as an advisory to depmod. If this is ported to the new PCI interface + where it could be referenced at any time due to hot plugging, + the __initdata reference should be removed. */ + +static struct pci_device_id happymeal_pci_ids[] = { + { + .vendor = PCI_VENDOR_ID_SUN, + .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); + +#endif + /* NOTE: In the descriptor writes one _must_ write the address * member _first_. The card must not be allowed to see * the updated descriptor flags until the address is @@ -1586,7 +1610,7 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("happy_meal_init: old[%08x] bursts<", hme_read32(hp, gregs + GREG_CFG))); -#ifndef CONFIG_SPARC +#ifndef __sparc__ /* It is always PCI and can handle 64byte bursts. */ hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); #else @@ -1623,7 +1647,7 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("XXX>")); hme_write32(hp, gregs + GREG_CFG, 0); } -#endif /* CONFIG_SPARC */ +#endif /* __sparc__ */ /* Turn off interrupts we do not want to hear. */ HMD((", enable global interrupts, ")); @@ -2568,10 +2592,14 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h */ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) { + struct sbus_bus *sbus; struct sbus_dev *sdev; struct quattro *qp; int i; + if (qfe_sbus_list == NULL) + goto found; + for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { for (i = 0, sdev = qp->quattro_dev; (sdev != NULL) && (i < 4); @@ -2580,7 +2608,17 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) return qp; } } + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if (sdev == goal_sdev) + goto found; + } + } + + /* Cannot find quattro parent, fail. */ + return NULL; +found: qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); if (qp != NULL) { int i; @@ -2617,17 +2655,6 @@ static void __init quattro_sbus_register_irqs(void) } } } - -static void __devexit quattro_sbus_free_irqs(void) -{ - struct quattro *qp; - - for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { - struct sbus_dev *sdev = qp->quattro_dev; - - free_irq(sdev->irqs[0], qp); - } -} #endif /* CONFIG_SBUS */ #ifdef CONFIG_PCI @@ -2662,9 +2689,8 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) #endif /* CONFIG_PCI */ #ifdef CONFIG_SBUS -static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) +static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) { - struct device_node *dp = sdev->ofdev.node; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; @@ -2687,7 +2713,6 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) if (!dev) goto err_out; SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); if (hme_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -2703,16 +2728,13 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) for (i = 0; i < 6; i++) dev->dev_addr[i] = macaddr[i]; macaddr[5]++; + } else if (qfe_slot != -1 && + prom_getproplen(sdev->prom_node, + "local-mac-address") == 6) { + prom_getproperty(sdev->prom_node, "local-mac-address", + dev->dev_addr, 6); } else { - unsigned char *addr; - int len; - - addr = of_get_property(dp, "local-mac-address", &len); - - if (qfe_slot != -1 && addr && len == 6) - memcpy(dev->dev_addr, addr, 6); - else - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + memcpy(dev->dev_addr, idprom->id_ethaddr, 6); } hp = dev->priv; @@ -2723,8 +2745,9 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) err = -ENODEV; if (sdev->num_registers != 5) { - printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n", + printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", sdev->num_registers); + printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); goto err_out_free_netdev; } @@ -2738,39 +2761,39 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) hp->gregs = sbus_ioremap(&sdev->resource[0], 0, GREG_REG_SIZE, "HME Global Regs"); if (!hp->gregs) { - printk(KERN_ERR "happymeal: Cannot map global registers.\n"); + printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); goto err_out_free_netdev; } hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, ETX_REG_SIZE, "HME TX Regs"); if (!hp->etxregs) { - printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n"); + printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); goto err_out_iounmap; } hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, ERX_REG_SIZE, "HME RX Regs"); if (!hp->erxregs) { - printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n"); + printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); goto err_out_iounmap; } hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, BMAC_REG_SIZE, "HME BIGMAC Regs"); if (!hp->bigmacregs) { - printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n"); + printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); goto err_out_iounmap; } hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, TCVR_REG_SIZE, "HME Tranceiver Regs"); if (!hp->tcvregs) { - printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n"); + printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); goto err_out_iounmap; } - hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff); + hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); if (hp->hm_revision == 0xff) hp->hm_revision = 0xa0; @@ -2784,8 +2807,8 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) hp->happy_flags |= HFLAG_QUATTRO; /* Get the supported DVMA burst sizes from our Happy SBUS. */ - hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node, - "burst-sizes", 0x00); + hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, + "burst-sizes", 0x00); hp->happy_block = sbus_alloc_consistent(hp->happy_dev, PAGE_SIZE, @@ -2848,8 +2871,6 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) goto err_out_free_consistent; } - dev_set_drvdata(&sdev->ofdev.dev, hp); - if (qfe_slot != -1) printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", dev->name, qfe_slot); @@ -2862,6 +2883,12 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) dev->dev_addr[i], i == 5 ? ' ' : ':'); printk("\n"); + /* We are home free at this point, link us in to the happy + * device list. + */ + hp->next_module = root_happy_dev; + root_happy_dev = hp; + return 0; err_out_free_consistent: @@ -2891,7 +2918,7 @@ static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) #endif #ifdef CONFIG_PCI -#ifndef CONFIG_SPARC +#ifndef __sparc__ static int is_quattro_p(struct pci_dev *pdev) { struct pci_dev *busdev = pdev->bus->self; @@ -2979,14 +3006,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr) get_random_bytes(&dev_addr[3], 3); return; } -#endif /* !(CONFIG_SPARC) */ +#endif /* !(__sparc__) */ -static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __init happy_meal_pci_init(struct pci_dev *pdev) { struct quattro *qp = NULL; -#ifdef CONFIG_SPARC +#ifdef __sparc__ struct pcidev_cookie *pcp; + int node; #endif struct happy_meal *hp; struct net_device *dev; @@ -2997,14 +3024,15 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, int err; /* Now make sure pci_dev cookie is there. */ -#ifdef CONFIG_SPARC +#ifdef __sparc__ pcp = pdev->sysdata; - if (pcp == NULL) { + if (pcp == NULL || pcp->prom_node == -1) { printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); return -ENODEV; } + node = pcp->prom_node; - strcpy(prom_name, pcp->prom_node->name); + prom_getstring(node, "name", prom_name, sizeof(prom_name)); #else if (is_quattro_p(pdev)) strcpy(prom_name, "SUNW,qfe"); @@ -3075,15 +3103,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, dev->dev_addr[i] = macaddr[i]; macaddr[5]++; } else { -#ifdef CONFIG_SPARC - unsigned char *addr; - int len; - +#ifdef __sparc__ if (qfe_slot != -1 && - (addr = of_get_property(pcp->prom_node, - "local-mac-address", &len)) != NULL - && len == 6) { - memcpy(dev->dev_addr, addr, 6); + prom_getproplen(node, "local-mac-address") == 6) { + prom_getproperty(node, "local-mac-address", + dev->dev_addr, 6); } else { memcpy(dev->dev_addr, idprom->id_ethaddr, 6); } @@ -3099,8 +3123,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, hp->bigmacregs = (hpreg_base + 0x6000UL); hp->tcvregs = (hpreg_base + 0x7000UL); -#ifdef CONFIG_SPARC - hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff); +#ifdef __sparc__ + hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); if (hp->hm_revision == 0xff) { unsigned char prev; @@ -3124,7 +3148,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, /* And of course, indicate this is PCI. */ hp->happy_flags |= HFLAG_PCI; -#ifdef CONFIG_SPARC +#ifdef __sparc__ /* Assume PCI happy meals can handle all burst sizes. */ hp->happy_bursts = DMA_BURSTBITS; #endif @@ -3187,8 +3211,6 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, goto err_out_iounmap; } - dev_set_drvdata(&pdev->dev, hp); - if (!qfe_slot) { struct pci_dev *qpdev = qp->quattro_dev; @@ -3218,6 +3240,12 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, printk("\n"); + /* We are home free at this point, link us in to the happy + * device list. + */ + hp->next_module = root_happy_dev; + root_happy_dev = hp; + return 0; err_out_iounmap: @@ -3235,146 +3263,136 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, err_out: return err; } +#endif -static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) -{ - struct happy_meal *hp = dev_get_drvdata(&pdev->dev); - struct net_device *net_dev = hp->dev; - - unregister_netdev(net_dev); - - pci_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); - iounmap(hp->gregs); - pci_release_regions(hp->happy_dev); - - free_netdev(net_dev); - - dev_set_drvdata(&pdev->dev, NULL); -} - -static struct pci_device_id happymeal_pci_ids[] = { - { - .vendor = PCI_VENDOR_ID_SUN, - .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); - -static struct pci_driver hme_pci_driver = { - .name = "hme", - .id_table = happymeal_pci_ids, - .probe = happy_meal_pci_probe, - .remove = __devexit_p(happy_meal_pci_remove), -}; - -static int __init happy_meal_pci_init(void) -{ - return pci_module_init(&hme_pci_driver); -} - -static void happy_meal_pci_exit(void) +#ifdef CONFIG_SBUS +static int __init happy_meal_sbus_probe(void) { - pci_unregister_driver(&hme_pci_driver); - - while (qfe_pci_list) { - struct quattro *qfe = qfe_pci_list; - struct quattro *next = qfe->next; - - kfree(qfe); - - qfe_pci_list = next; + struct sbus_bus *sbus; + struct sbus_dev *sdev; + int cards = 0; + char model[128]; + + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + char *name = sdev->prom_name; + + if (!strcmp(name, "SUNW,hme")) { + cards++; + prom_getstring(sdev->prom_node, "model", + model, sizeof(model)); + if (!strcmp(model, "SUNW,sbus-qfe")) + happy_meal_sbus_init(sdev, 1); + else + happy_meal_sbus_init(sdev, 0); + } else if (!strcmp(name, "qfe") || + !strcmp(name, "SUNW,qfe")) { + cards++; + happy_meal_sbus_init(sdev, 1); + } + } } + if (cards != 0) + quattro_sbus_register_irqs(); + return cards; } - #endif -#ifdef CONFIG_SBUS -static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match) +#ifdef CONFIG_PCI +static int __init happy_meal_pci_probe(void) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - char *model = of_get_property(dp, "model", NULL); - int is_qfe = (match->data != NULL); - - if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) - is_qfe = 1; + struct pci_dev *pdev = NULL; + int cards = 0; - return happy_meal_sbus_probe_one(sdev, is_qfe); + while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, + PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { + if (pci_enable_device(pdev)) + continue; + pci_set_master(pdev); + cards++; + happy_meal_pci_init(pdev); + } + return cards; } +#endif -static int __devexit hme_sbus_remove(struct of_device *dev) +static int __init happy_meal_probe(void) { - struct happy_meal *hp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = hp->dev; - - unregister_netdevice(net_dev); - - /* XXX qfe parent interrupt... */ - - sbus_iounmap(hp->gregs, GREG_REG_SIZE); - sbus_iounmap(hp->etxregs, ETX_REG_SIZE); - sbus_iounmap(hp->erxregs, ERX_REG_SIZE); - sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); - sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); - sbus_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); + static int called = 0; + int cards; - free_netdev(net_dev); + root_happy_dev = NULL; - dev_set_drvdata(&dev->dev, NULL); + if (called) + return -ENODEV; + called++; + cards = 0; +#ifdef CONFIG_SBUS + cards += happy_meal_sbus_probe(); +#endif +#ifdef CONFIG_PCI + cards += happy_meal_pci_probe(); +#endif + if (!cards) + return -ENODEV; return 0; } -static struct of_device_id hme_sbus_match[] = { - { - .name = "SUNW,hme", - }, - { - .name = "SUNW,qfe", - .data = (void *) 1, - }, - { - .name = "qfe", - .data = (void *) 1, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, hme_sbus_match); +static void __exit happy_meal_cleanup_module(void) +{ +#ifdef CONFIG_SBUS + struct quattro *last_seen_qfe = NULL; +#endif -static struct of_platform_driver hme_sbus_driver = { - .name = "hme", - .match_table = hme_sbus_match, - .probe = hme_sbus_probe, - .remove = __devexit_p(hme_sbus_remove), -}; + while (root_happy_dev) { + struct happy_meal *hp = root_happy_dev; + struct happy_meal *next = root_happy_dev->next_module; + struct net_device *dev = hp->dev; -static int __init happy_meal_sbus_init(void) -{ - int err; + /* Unregister netdev before unmapping registers as this + * call can end up trying to access those registers. + */ + unregister_netdev(dev); - err = of_register_driver(&hme_sbus_driver, &sbus_bus_type); - if (!err) - quattro_sbus_register_irqs(); +#ifdef CONFIG_SBUS + if (!(hp->happy_flags & HFLAG_PCI)) { + if (hp->happy_flags & HFLAG_QUATTRO) { + if (hp->qfe_parent != last_seen_qfe) { + free_irq(dev->irq, hp->qfe_parent); + last_seen_qfe = hp->qfe_parent; + } + } - return err; -} + sbus_iounmap(hp->gregs, GREG_REG_SIZE); + sbus_iounmap(hp->etxregs, ETX_REG_SIZE); + sbus_iounmap(hp->erxregs, ERX_REG_SIZE); + sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); + sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); + sbus_free_consistent(hp->happy_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); + } +#endif +#ifdef CONFIG_PCI + if ((hp->happy_flags & HFLAG_PCI)) { + pci_free_consistent(hp->happy_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); + iounmap(hp->gregs); + pci_release_regions(hp->happy_dev); + } +#endif + free_netdev(dev); -static void happy_meal_sbus_exit(void) -{ - of_unregister_driver(&hme_sbus_driver); - quattro_sbus_free_irqs(); + root_happy_dev = next; + } + /* Now cleanup the quattro lists. */ +#ifdef CONFIG_SBUS while (qfe_sbus_list) { struct quattro *qfe = qfe_sbus_list; struct quattro *next = qfe->next; @@ -3383,39 +3401,18 @@ static void happy_meal_sbus_exit(void) qfe_sbus_list = next; } -} -#endif - -static int __init happy_meal_probe(void) -{ - int err = 0; - -#ifdef CONFIG_SBUS - err = happy_meal_sbus_init(); #endif #ifdef CONFIG_PCI - if (!err) { - err = happy_meal_pci_init(); -#ifdef CONFIG_SBUS - if (err) - happy_meal_sbus_exit(); -#endif - } -#endif - - return err; -} + while (qfe_pci_list) { + struct quattro *qfe = qfe_pci_list; + struct quattro *next = qfe->next; + kfree(qfe); -static void __exit happy_meal_exit(void) -{ -#ifdef CONFIG_SBUS - happy_meal_sbus_exit(); -#endif -#ifdef CONFIG_PCI - happy_meal_pci_exit(); + qfe_pci_list = next; + } #endif } module_init(happy_meal_probe); -module_exit(happy_meal_exit); +module_exit(happy_meal_cleanup_module); diff --git a/trunk/drivers/net/sunhme.h b/trunk/drivers/net/sunhme.h index 9b7ccaeeee89..34e9f953cea4 100644 --- a/trunk/drivers/net/sunhme.h +++ b/trunk/drivers/net/sunhme.h @@ -461,6 +461,7 @@ struct happy_meal { struct net_device *dev; /* Backpointer */ struct quattro *qfe_parent; /* For Quattro cards */ int qfe_ent; /* Which instance on quattro */ + struct happy_meal *next_module; }; /* Here are the happy flags. */ diff --git a/trunk/drivers/net/sunlance.c b/trunk/drivers/net/sunlance.c index 2c239ab63a80..6381243d8d00 100644 --- a/trunk/drivers/net/sunlance.c +++ b/trunk/drivers/net/sunlance.c @@ -266,6 +266,7 @@ struct lance_private { char *name; dma_addr_t init_block_dvma; struct net_device *dev; /* Backpointer */ + struct lance_private *next_module; struct sbus_dev *sdev; struct timer_list multicast_timer; }; @@ -297,6 +298,8 @@ int sparc_lance_debug = 2; #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) +static struct lance_private *root_lance_dev; + /* Load the CSR registers */ static void load_csrs(struct lance_private *lp) { @@ -1324,9 +1327,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = { .get_link = sparc_lance_get_link, }; -static int __init sparc_lance_probe_one(struct sbus_dev *sdev, - struct sbus_dma *ledma, - struct sbus_dev *lebuffer) +static int __init sparc_lance_init(struct sbus_dev *sdev, + struct sbus_dma *ledma, + struct sbus_dev *lebuffer) { static unsigned version_printed; struct net_device *dev; @@ -1470,7 +1473,6 @@ static int __init sparc_lance_probe_one(struct sbus_dev *sdev, lp->dev = dev; SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); dev->open = &lance_open; dev->stop = &lance_close; dev->hard_start_xmit = &lance_start_xmit; @@ -1498,7 +1500,8 @@ static int __init sparc_lance_probe_one(struct sbus_dev *sdev, goto fail; } - dev_set_drvdata(&sdev->ofdev.dev, lp); + lp->next_module = root_lance_dev; + root_lance_dev = lp; printk(KERN_INFO "%s: LANCE ", dev->name); @@ -1533,112 +1536,88 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) #include /* Find all the lance cards on the system and initialize them */ -static struct sbus_dev sun4_sdev; -static int __init sparc_lance_init(void) +static int __init sparc_lance_probe(void) { + static struct sbus_dev sdev; + static int called; + + root_lance_dev = NULL; + + if (called) + return -ENODEV; + called++; + if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || (idprom->id_machtype == (SM_SUN4|SM_4_470))) { - memset(&sun4_sdev, 0, sizeof(sdev)); - sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; - sun4_sdev.irqs[0] = 6; - return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); + memset(&sdev, 0, sizeof(sdev)); + sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; + sdev.irqs[0] = 6; + return sparc_lance_init(&sdev, NULL, NULL); } return -ENODEV; } -static int __exit sunlance_sun4_remove(void) -{ - struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); - struct net_device *net_dev = lp->dev; - - unregister_netdevice(net_dev); - - lance_free_hwresources(root_lance_dev); - - free_netdev(net_dev); - - dev_set_drvdata(&sun4_sdev->dev, NULL); - - return 0; -} - #else /* !CONFIG_SUN4 */ -static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - int err; - - if (!strcmp(dp->name, "le")) { - err = sparc_lance_probe_one(sdev, NULL, NULL); - } else if (!strcmp(dp->name, "ledma")) { - struct sbus_dma *ledma = find_ledma(sdev); - - err = sparc_lance_probe_one(sdev->child, ledma, NULL); - } else { - BUG_ON(strcmp(dp->name, "lebuffer")); - - err = sparc_lance_probe_one(sdev->child, NULL, sdev); - } - - return err; -} - -static int __devexit sunlance_sbus_remove(struct of_device *dev) -{ - struct lance_private *lp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = lp->dev; - - unregister_netdevice(net_dev); - - lance_free_hwresources(lp); - - free_netdev(net_dev); - - dev_set_drvdata(&dev->dev, NULL); - - return 0; -} - -static struct of_device_id sunlance_sbus_match[] = { - { - .name = "le", - }, - { - .name = "ledma", - }, - { - .name = "lebuffer", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, sunlance_sbus_match); - -static struct of_platform_driver sunlance_sbus_driver = { - .name = "sunlance", - .match_table = sunlance_sbus_match, - .probe = sunlance_sbus_probe, - .remove = __devexit_p(sunlance_sbus_remove), -}; - - /* Find all the lance cards on the system and initialize them */ -static int __init sparc_lance_init(void) +static int __init sparc_lance_probe(void) { - return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; + struct sbus_dma *ledma = NULL; + static int called; + int cards = 0, v; + + root_lance_dev = NULL; + + if (called) + return -ENODEV; + called++; + + for_each_sbus (bus) { + for_each_sbusdev (sdev, bus) { + if (strcmp(sdev->prom_name, "le") == 0) { + cards++; + if ((v = sparc_lance_init(sdev, NULL, NULL))) + return v; + continue; + } + if (strcmp(sdev->prom_name, "ledma") == 0) { + cards++; + ledma = find_ledma(sdev); + if ((v = sparc_lance_init(sdev->child, + ledma, NULL))) + return v; + continue; + } + if (strcmp(sdev->prom_name, "lebuffer") == 0){ + cards++; + if ((v = sparc_lance_init(sdev->child, + NULL, sdev))) + return v; + continue; + } + } /* for each sbusdev */ + } /* for each sbus */ + if (!cards) + return -ENODEV; + return 0; } #endif /* !CONFIG_SUN4 */ -static void __exit sparc_lance_exit(void) +static void __exit sparc_lance_cleanup(void) { -#ifdef CONFIG_SUN4 - sunlance_sun4_remove(); -#else - of_unregister_driver(&sunlance_sbus_driver); -#endif + struct lance_private *lp; + + while (root_lance_dev) { + lp = root_lance_dev->next_module; + + unregister_netdev(root_lance_dev->dev); + lance_free_hwresources(root_lance_dev); + free_netdev(root_lance_dev->dev); + root_lance_dev = lp; + } } -module_init(sparc_lance_init); -module_exit(sparc_lance_exit); +module_init(sparc_lance_probe); +module_exit(sparc_lance_cleanup); diff --git a/trunk/drivers/net/sunqe.c b/trunk/drivers/net/sunqe.c index 9da6d5b87173..1f2323be60d4 100644 --- a/trunk/drivers/net/sunqe.c +++ b/trunk/drivers/net/sunqe.c @@ -1,9 +1,10 @@ -/* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. +/* $Id: sunqe.c,v 1.55 2002/01/15 06:48:55 davem Exp $ + * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. * Once again I am out to prove that every ethernet * controller out there can be most efficiently programmed * if you make it look like a LANCE. * - * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com) */ #include @@ -40,9 +41,9 @@ #include "sunqe.h" #define DRV_NAME "sunqe" -#define DRV_VERSION "4.0" -#define DRV_RELDATE "June 23, 2006" -#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" +#define DRV_VERSION "3.0" +#define DRV_RELDATE "8/24/03" +#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" static char version[] = DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; @@ -754,269 +755,298 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) qecp->gregs + GLOB_RSIZE); } -static u8 __init qec_get_burst(struct device_node *dp) +/* Four QE's per QEC card. */ +static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) { + static unsigned version_printed; + struct net_device *qe_devs[4]; + struct sunqe *qeps[4]; + struct sbus_dev *qesdevs[4]; + struct sbus_dev *child; + struct sunqec *qecp = NULL; u8 bsizes, bsizes_more; + int i, j, res = -ENOMEM; - /* Find and set the burst sizes for the QEC, since it - * does the actual dma for all 4 channels. - */ - bsizes = of_getintprop_default(dp, "burst-sizes", 0xff); - bsizes &= 0xff; - bsizes_more = of_getintprop_default(dp->parent, "burst-sizes", 0xff); + for (i = 0; i < 4; i++) { + qe_devs[i] = alloc_etherdev(sizeof(struct sunqe)); + if (!qe_devs[i]) + goto out; + } - if (bsizes_more != 0xff) - bsizes &= bsizes_more; - if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || - (bsizes & DMA_BURST32)==0) - bsizes = (DMA_BURST32 - 1); + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); - return bsizes; -} + for (i = 0; i < 4; i++) { + qeps[i] = (struct sunqe *) qe_devs[i]->priv; + for (j = 0; j < 6; j++) + qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j]; + qeps[i]->channel = i; + spin_lock_init(&qeps[i]->lock); + } -static struct sunqec * __init get_qec(struct sbus_dev *child_sdev) -{ - struct sbus_dev *qec_sdev = child_sdev->parent; - struct sunqec *qecp; + qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL); + if (qecp == NULL) + goto out1; + qecp->qec_sdev = sdev; - for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) { - if (qecp->qec_sdev == qec_sdev) - break; + for (i = 0; i < 4; i++) { + qecp->qes[i] = qeps[i]; + qeps[i]->dev = qe_devs[i]; + qeps[i]->parent = qecp; } - if (!qecp) { - qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); - if (qecp) { - u32 ctrl; - - qecp->qec_sdev = qec_sdev; - qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0, - GLOB_REG_SIZE, - "QEC Global Registers"); - if (!qecp->gregs) - goto fail; - - /* Make sure the QEC is in MACE mode. */ - ctrl = sbus_readl(qecp->gregs + GLOB_CTRL); - ctrl &= 0xf0000000; - if (ctrl != GLOB_CTRL_MMODE) { - printk(KERN_ERR "qec: Not in MACE mode!\n"); - goto fail; - } - if (qec_global_reset(qecp->gregs)) - goto fail; + res = -ENODEV; - qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node); + for (i = 0, child = sdev->child; i < 4; i++, child = child->next) { + /* Link in channel */ + j = prom_getintdefault(child->prom_node, "channel#", -1); + if (j == -1) + goto out2; + qesdevs[j] = child; + } - qec_init_once(qecp, qec_sdev); + for (i = 0; i < 4; i++) + qeps[i]->qe_sdev = qesdevs[i]; - if (request_irq(qec_sdev->irqs[0], &qec_interrupt, - SA_SHIRQ, "qec", (void *) qecp)) { - printk(KERN_ERR "qec: Can't register irq.\n"); - goto fail; - } + /* Now map in the registers, QEC globals first. */ + qecp->gregs = sbus_ioremap(&sdev->resource[0], 0, + GLOB_REG_SIZE, "QEC Global Registers"); + if (!qecp->gregs) { + printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n"); + goto out2; + } - qecp->next_module = root_qec_dev; - root_qec_dev = qecp; - } + /* Make sure the QEC is in MACE mode. */ + if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) { + printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n"); + goto out3; } - return qecp; + /* Reset the QEC. */ + if (qec_global_reset(qecp->gregs)) + goto out3; -fail: - if (qecp->gregs) - sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); - kfree(qecp); - return NULL; -} + /* Find and set the burst sizes for the QEC, since it does + * the actual dma for all 4 channels. + */ + bsizes = prom_getintdefault(sdev->prom_node, "burst-sizes", 0xff); + bsizes &= 0xff; + bsizes_more = prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff); -static int __init qec_ether_init(struct sbus_dev *sdev) -{ - static unsigned version_printed; - struct net_device *dev; - struct sunqe *qe; - struct sunqec *qecp; - int i, res; + if (bsizes_more != 0xff) + bsizes &= bsizes_more; + if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || + (bsizes & DMA_BURST32)==0) + bsizes = (DMA_BURST32 - 1); - if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + qecp->qec_bursts = bsizes; - dev = alloc_etherdev(sizeof(struct sunqe)); - if (!dev) - return -ENOMEM; + /* Perform one time QEC initialization, we never touch the QEC + * globals again after this. + */ + qec_init_once(qecp, sdev); + + for (i = 0; i < 4; i++) { + struct sunqe *qe = qeps[i]; + /* Map in QEC per-channel control registers. */ + qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, + CREG_REG_SIZE, "QEC Channel Registers"); + if (!qe->qcregs) { + printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i); + goto out4; + } - qe = netdev_priv(dev); + /* Map in per-channel AMD MACE registers. */ + qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, + MREGS_REG_SIZE, "QE MACE Registers"); + if (!qe->mregs) { + printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i); + goto out4; + } - i = of_getintprop_default(sdev->ofdev.node, "channel#", -1); - if (i == -1) { - struct sbus_dev *td = sdev->parent->child; - i = 0; - while (td != sdev) { - td = td->next; - i++; + qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, + PAGE_SIZE, + &qe->qblock_dvma); + qe->buffers = sbus_alloc_consistent(qe->qe_sdev, + sizeof(struct sunqe_buffers), + &qe->buffers_dvma); + if (qe->qe_block == NULL || qe->qblock_dvma == 0 || + qe->buffers == NULL || qe->buffers_dvma == 0) { + goto out4; } + + /* Stop this QE. */ + qe_stop(qe); } - qe->channel = i; - spin_lock_init(&qe->lock); - - res = -ENODEV; - qecp = get_qec(sdev); - if (!qecp) - goto fail; - qecp->qes[qe->channel] = qe; - qe->dev = dev; - qe->parent = qecp; - qe->qe_sdev = sdev; + for (i = 0; i < 4; i++) { + SET_MODULE_OWNER(qe_devs[i]); + qe_devs[i]->open = qe_open; + qe_devs[i]->stop = qe_close; + qe_devs[i]->hard_start_xmit = qe_start_xmit; + qe_devs[i]->get_stats = qe_get_stats; + qe_devs[i]->set_multicast_list = qe_set_multicast; + qe_devs[i]->tx_timeout = qe_tx_timeout; + qe_devs[i]->watchdog_timeo = 5*HZ; + qe_devs[i]->irq = sdev->irqs[0]; + qe_devs[i]->dma = 0; + qe_devs[i]->ethtool_ops = &qe_ethtool_ops; + } - res = -ENOMEM; - qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, - CREG_REG_SIZE, "QEC Channel Registers"); - if (!qe->qcregs) { - printk(KERN_ERR "qe: Cannot map channel registers.\n"); - goto fail; + /* QEC receives interrupts from each QE, then it sends the actual + * IRQ to the cpu itself. Since QEC is the single point of + * interrupt for all QE channels we register the IRQ handler + * for it now. + */ + if (request_irq(sdev->irqs[0], &qec_interrupt, + SA_SHIRQ, "QuadEther", (void *) qecp)) { + printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n"); + res = -EAGAIN; + goto out4; } - qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, - MREGS_REG_SIZE, "QE MACE Registers"); - if (!qe->mregs) { - printk(KERN_ERR "qe: Cannot map MACE registers.\n"); - goto fail; + for (i = 0; i < 4; i++) { + if (register_netdev(qe_devs[i]) != 0) + goto out5; } - qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, - PAGE_SIZE, - &qe->qblock_dvma); - qe->buffers = sbus_alloc_consistent(qe->qe_sdev, - sizeof(struct sunqe_buffers), - &qe->buffers_dvma); - if (qe->qe_block == NULL || qe->qblock_dvma == 0 || - qe->buffers == NULL || qe->buffers_dvma == 0) - goto fail; - - /* Stop this QE. */ - qe_stop(qe); - - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); - - dev->open = qe_open; - dev->stop = qe_close; - dev->hard_start_xmit = qe_start_xmit; - dev->get_stats = qe_get_stats; - dev->set_multicast_list = qe_set_multicast; - dev->tx_timeout = qe_tx_timeout; - dev->watchdog_timeo = 5*HZ; - dev->irq = sdev->irqs[0]; - dev->dma = 0; - dev->ethtool_ops = &qe_ethtool_ops; - - res = register_netdev(dev); - if (res) - goto fail; - - dev_set_drvdata(&sdev->ofdev.dev, qe); - - printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); - for (i = 0; i < 6; i++) - printk ("%2.2x%c", - dev->dev_addr[i], - i == 5 ? ' ': ':'); - printk("\n"); + /* Report the QE channels. */ + for (i = 0; i < 4; i++) { + printk(KERN_INFO "%s: QuadEthernet channel[%d] ", qe_devs[i]->name, i); + for (j = 0; j < 6; j++) + printk ("%2.2x%c", + qe_devs[i]->dev_addr[j], + j == 5 ? ' ': ':'); + printk("\n"); + } + /* We are home free at this point, link the qe's into + * the master list for later driver exit. + */ + qecp->next_module = root_qec_dev; + root_qec_dev = qecp; return 0; -fail: - if (qe->qcregs) - sbus_iounmap(qe->qcregs, CREG_REG_SIZE); - if (qe->mregs) - sbus_iounmap(qe->mregs, MREGS_REG_SIZE); - if (qe->qe_block) - sbus_free_consistent(qe->qe_sdev, - PAGE_SIZE, - qe->qe_block, - qe->qblock_dvma); - if (qe->buffers) - sbus_free_consistent(qe->qe_sdev, - sizeof(struct sunqe_buffers), - qe->buffers, - qe->buffers_dvma); - - free_netdev(dev); - +out5: + while (i--) + unregister_netdev(qe_devs[i]); + free_irq(sdev->irqs[0], (void *)qecp); +out4: + for (i = 0; i < 4; i++) { + struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv; + + if (qe->qcregs) + sbus_iounmap(qe->qcregs, CREG_REG_SIZE); + if (qe->mregs) + sbus_iounmap(qe->mregs, MREGS_REG_SIZE); + if (qe->qe_block) + sbus_free_consistent(qe->qe_sdev, + PAGE_SIZE, + qe->qe_block, + qe->qblock_dvma); + if (qe->buffers) + sbus_free_consistent(qe->qe_sdev, + sizeof(struct sunqe_buffers), + qe->buffers, + qe->buffers_dvma); + } +out3: + sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); +out2: + kfree(qecp); +out1: + i = 4; +out: + while (i--) + free_netdev(qe_devs[i]); return res; } -static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __init qec_match(struct sbus_dev *sdev) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - return qec_ether_init(sdev); -} - -static int __devexit qec_sbus_remove(struct of_device *dev) -{ - struct sunqe *qp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = qp->dev; - - unregister_netdevice(net_dev); - - sbus_iounmap(qp->qcregs, CREG_REG_SIZE); - sbus_iounmap(qp->mregs, MREGS_REG_SIZE); - sbus_free_consistent(qp->qe_sdev, - PAGE_SIZE, - qp->qe_block, - qp->qblock_dvma); - sbus_free_consistent(qp->qe_sdev, - sizeof(struct sunqe_buffers), - qp->buffers, - qp->buffers_dvma); - - free_netdev(net_dev); + struct sbus_dev *sibling; + int i; - dev_set_drvdata(&dev->dev, NULL); + if (strcmp(sdev->prom_name, "qec") != 0) + return 0; - return 0; + /* QEC can be parent of either QuadEthernet or BigMAC + * children. Do not confuse this with qfe/SUNW,qfe + * which is a quad-happymeal card and handled by + * a different driver. + */ + sibling = sdev->child; + for (i = 0; i < 4; i++) { + if (sibling == NULL) + return 0; + if (strcmp(sibling->prom_name, "qe") != 0) + return 0; + sibling = sibling->next; + } + return 1; } -static struct of_device_id qec_sbus_match[] = { - { - .name = "qe", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, qec_sbus_match); - -static struct of_platform_driver qec_sbus_driver = { - .name = "qec", - .match_table = qec_sbus_match, - .probe = qec_sbus_probe, - .remove = __devexit_p(qec_sbus_remove), -}; - -static int __init qec_init(void) +static int __init qec_probe(void) { - return of_register_driver(&qec_sbus_driver, &sbus_bus_type); + struct net_device *dev = NULL; + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; + static int called; + int cards = 0, v; + + root_qec_dev = NULL; + + if (called) + return -ENODEV; + called++; + + for_each_sbus(bus) { + for_each_sbusdev(sdev, bus) { + if (cards) + dev = NULL; + + if (qec_match(sdev)) { + cards++; + if ((v = qec_ether_init(dev, sdev))) + return v; + } + } + } + if (!cards) + return -ENODEV; + return 0; } -static void __exit qec_exit(void) +static void __exit qec_cleanup(void) { - of_unregister_driver(&qec_sbus_driver); + struct sunqec *next_qec; + int i; while (root_qec_dev) { - struct sunqec *next = root_qec_dev->next_module; - - free_irq(root_qec_dev->qec_sdev->irqs[0], - (void *) root_qec_dev); + next_qec = root_qec_dev->next_module; + + /* Release all four QE channels, then the QEC itself. */ + for (i = 0; i < 4; i++) { + unregister_netdev(root_qec_dev->qes[i]->dev); + sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE); + sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE); + sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, + PAGE_SIZE, + root_qec_dev->qes[i]->qe_block, + root_qec_dev->qes[i]->qblock_dvma); + sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, + sizeof(struct sunqe_buffers), + root_qec_dev->qes[i]->buffers, + root_qec_dev->qes[i]->buffers_dvma); + free_netdev(root_qec_dev->qes[i]->dev); + } + free_irq(root_qec_dev->qec_sdev->irqs[0], (void *)root_qec_dev); sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); - kfree(root_qec_dev); - - root_qec_dev = next; + root_qec_dev = next_qec; } } -module_init(qec_init); -module_exit(qec_exit); +module_init(qec_probe); +module_exit(qec_cleanup); diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 35f931638750..b2ddd4522a87 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -3780,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { + (mss = skb_shinfo(skb)->tso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -3905,7 +3905,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { + (mss = skb_shinfo(skb)->tso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -10549,13 +10549,11 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) struct pcidev_cookie *pcp = pdev->sysdata; if (pcp != NULL) { - unsigned char *addr; - int len; + int node = pcp->prom_node; - addr = of_get_property(pcp->prom_node, "local-mac-address", - &len); - if (addr && len == 6) { - memcpy(dev->dev_addr, addr, 6); + if (prom_getproplen(node, "local-mac-address") == 6) { + prom_getproperty(node, "local-mac-address", + dev->dev_addr, 6); memcpy(dev->perm_addr, dev->dev_addr, 6); return 0; } diff --git a/trunk/drivers/net/tokenring/olympic.c b/trunk/drivers/net/tokenring/olympic.c index c3cb8d26cfe3..23032a7bc0a9 100644 --- a/trunk/drivers/net/tokenring/olympic.c +++ b/trunk/drivers/net/tokenring/olympic.c @@ -217,7 +217,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device dev = alloc_trdev(sizeof(struct olympic_private)) ; if (!dev) { i = -ENOMEM; - goto op_release_dev; + goto op_free_dev; } olympic_priv = dev->priv ; @@ -282,8 +282,8 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device if (olympic_priv->olympic_lap) iounmap(olympic_priv->olympic_lap); +op_free_dev: free_netdev(dev); -op_release_dev: pci_release_regions(pdev); op_disable_dev: diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index e0de66739a42..cabdf894e21e 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1550,14 +1550,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, dev->dev_addr[i] = last_phys_addr[i]; dev->dev_addr[i] = last_phys_addr[i] + 1; #if defined(__sparc__) - if (pcp) { - unsigned char *addr; - int len; - - addr = of_get_property(pcp->prom_node, - "local-mac-address", &len); - if (addr && len == 6) - memcpy(dev->dev_addr, addr, 6); + if ((pcp != NULL) && prom_getproplen(pcp->prom_node, + "local-mac-address") == 6) { + prom_getproperty(pcp->prom_node, "local-mac-address", + dev->dev_addr, 6); } #endif #if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 6c62d5c88268..a1ed2d983740 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -490,9 +490,6 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) err = -EINVAL; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { /* TUN device */ diff --git a/trunk/drivers/net/typhoon.c b/trunk/drivers/net/typhoon.c index e49e8b520c28..d9258d42090c 100644 --- a/trunk/drivers/net/typhoon.c +++ b/trunk/drivers/net/typhoon.c @@ -340,7 +340,7 @@ enum state_values { #endif #if defined(NETIF_F_TSO) -#define skb_tso_size(x) (skb_shinfo(x)->gso_size) +#define skb_tso_size(x) (skb_shinfo(x)->tso_size) #define TSO_NUM_DESCRIPTORS 2 #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT #else diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index c80a4f1d5f7a..fdc21037f6dc 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -1284,8 +1284,11 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) /* Calculate the next Tx descriptor entry. */ entry = rp->cur_tx % TX_RING_SIZE; - if (skb_padto(skb, ETH_ZLEN)) - return 0; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; + } rp->tx_skbuff[entry] = skb; diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index 09e05fe40c38..2eb6b5f9ba0d 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -248,7 +248,6 @@ static void velocity_free_rd_ring(struct velocity_info *vptr); static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); static int velocity_soft_reset(struct velocity_info *vptr); static void mii_init(struct velocity_info *vptr, u32 mii_status); -static u32 velocity_get_link(struct net_device *dev); static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); static void velocity_print_link_status(struct velocity_info *vptr); static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs); @@ -799,9 +798,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi if (ret < 0) goto err_iounmap; - if (velocity_get_link(dev)) - netif_carrier_off(dev); - velocity_print_info(vptr); pci_set_drvdata(pdev, dev); @@ -1657,10 +1653,8 @@ static void velocity_error(struct velocity_info *vptr, int status) if (linked) { vptr->mii_status &= ~VELOCITY_LINK_FAIL; - netif_carrier_on(vptr->dev); } else { vptr->mii_status |= VELOCITY_LINK_FAIL; - netif_carrier_off(vptr->dev); } velocity_print_link_status(vptr); diff --git a/trunk/drivers/net/wan/c101.c b/trunk/drivers/net/wan/c101.c index b60ef02db7b0..43d854ace233 100644 --- a/trunk/drivers/net/wan/c101.c +++ b/trunk/drivers/net/wan/c101.c @@ -326,21 +326,21 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) if (request_irq(irq, sca_intr, 0, devname, card)) { printk(KERN_ERR "c101: could not allocate IRQ\n"); c101_destroy_card(card); - return -EBUSY; + return(-EBUSY); } card->irq = irq; if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) { printk(KERN_ERR "c101: could not request RAM window\n"); c101_destroy_card(card); - return -EBUSY; + return(-EBUSY); } card->phy_winbase = winbase; card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE); if (!card->win0base) { printk(KERN_ERR "c101: could not map I/O address\n"); c101_destroy_card(card); - return -EFAULT; + return -EBUSY; } card->tx_ring_buffers = TX_RING_BUFFERS; diff --git a/trunk/drivers/net/wan/hdlc_generic.c b/trunk/drivers/net/wan/hdlc_generic.c index 57f9538b8fb5..46cef8f92133 100644 --- a/trunk/drivers/net/wan/hdlc_generic.c +++ b/trunk/drivers/net/wan/hdlc_generic.c @@ -259,7 +259,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } } -void hdlc_setup(struct net_device *dev) +static void hdlc_setup(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); @@ -288,6 +288,26 @@ struct net_device *alloc_hdlcdev(void *priv) return dev; } +int register_hdlc_device(struct net_device *dev) +{ + int result = dev_alloc_name(dev, "hdlc%d"); + if (result < 0) + return result; + + result = register_netdev(dev); + if (result != 0) + return -EIO; + +#if 0 + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); /* no carrier until DCD goes up */ +#endif + + return 0; +} + + + void unregister_hdlc_device(struct net_device *dev) { rtnl_lock(); @@ -306,8 +326,8 @@ EXPORT_SYMBOL(hdlc_open); EXPORT_SYMBOL(hdlc_close); EXPORT_SYMBOL(hdlc_set_carrier); EXPORT_SYMBOL(hdlc_ioctl); -EXPORT_SYMBOL(hdlc_setup); EXPORT_SYMBOL(alloc_hdlcdev); +EXPORT_SYMBOL(register_hdlc_device); EXPORT_SYMBOL(unregister_hdlc_device); static struct packet_type hdlc_packet_type = { diff --git a/trunk/drivers/net/wan/n2.c b/trunk/drivers/net/wan/n2.c index b7d88db89a5c..cd32751b64eb 100644 --- a/trunk/drivers/net/wan/n2.c +++ b/trunk/drivers/net/wan/n2.c @@ -387,11 +387,6 @@ static int __init n2_run(unsigned long io, unsigned long irq, } card->phy_winbase = winbase; card->winbase = ioremap(winbase, USE_WINDOWSIZE); - if (!card->winbase) { - printk(KERN_ERR "n2: ioremap() failed\n"); - n2_destroy_card(card); - return -EFAULT; - } outb(0, io + N2_PCR); outb(winbase >> 12, io + N2_BAR); diff --git a/trunk/drivers/net/wan/pci200syn.c b/trunk/drivers/net/wan/pci200syn.c index 670e8bd2245c..f485a97844cc 100644 --- a/trunk/drivers/net/wan/pci200syn.c +++ b/trunk/drivers/net/wan/pci200syn.c @@ -354,7 +354,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card->rambase == NULL) { printk(KERN_ERR "pci200syn: ioremap() failed\n"); pci200_pci_remove_one(pdev); - return -EFAULT; } /* Reset PLX */ diff --git a/trunk/drivers/net/wan/sdla.c b/trunk/drivers/net/wan/sdla.c index 7628c2d81f45..22e794071cf4 100644 --- a/trunk/drivers/net/wan/sdla.c +++ b/trunk/drivers/net/wan/sdla.c @@ -60,9 +60,9 @@ static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org"; -static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; +static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; -static unsigned int valid_mem[] = { +static unsigned int valid_mem[] __initdata = { 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, diff --git a/trunk/drivers/net/wan/wanxl.c b/trunk/drivers/net/wan/wanxl.c index 437e0e938e38..29a756dd979b 100644 --- a/trunk/drivers/net/wan/wanxl.c +++ b/trunk/drivers/net/wan/wanxl.c @@ -634,13 +634,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, /* set up PLX mapping */ plx_phy = pci_resource_start(pdev, 0); - card->plx = ioremap_nocache(plx_phy, 0x70); - if (!card->plx) { - printk(KERN_ERR "wanxl: ioremap() failed\n"); - wanxl_pci_remove_one(pdev); - return -EFAULT; - } #if RESET_WHILE_LOADING wanxl_reset(card); @@ -706,12 +700,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, } mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware)); - if (!mem) { - printk(KERN_ERR "wanxl: ioremap() failed\n"); - wanxl_pci_remove_one(pdev); - return -EFAULT; - } - for (i = 0; i < sizeof(firmware); i += 4) writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i); diff --git a/trunk/drivers/net/wireless/bcm43xx/Kconfig b/trunk/drivers/net/wireless/bcm43xx/Kconfig index 533993f538fc..25ea4748f0b9 100644 --- a/trunk/drivers/net/wireless/bcm43xx/Kconfig +++ b/trunk/drivers/net/wireless/bcm43xx/Kconfig @@ -2,7 +2,6 @@ config BCM43XX tristate "Broadcom BCM43xx wireless support" depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL select FW_LOADER - select HW_RANDOM ---help--- This is an experimental driver for the Broadcom 43xx wireless chip, found in the Apple Airport Extreme and various other devices. diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h index 17a56828e232..e66fdb1f3cfd 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -1,7 +1,6 @@ #ifndef BCM43xx_H_ #define BCM43xx_H_ -#include #include #include #include @@ -83,7 +82,6 @@ #define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ -#define BCM43xx_MMIO_RNG 0x65A #define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 /* SPROM offsets. */ @@ -638,17 +636,6 @@ struct bcm43xx_key { u8 algorithm; }; -/* Driver initialization status. */ -enum { - BCM43xx_STAT_UNINIT, /* Uninitialized. */ - BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */ - BCM43xx_STAT_INITIALIZED, /* Fully operational. */ - BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */ - BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ -}; -#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) -#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) - struct bcm43xx_private { struct ieee80211_device *ieee; struct ieee80211softmac_device *softmac; @@ -659,17 +646,18 @@ struct bcm43xx_private { void __iomem *mmio_addr; - /* Locking, see "theory of locking" text below. */ - spinlock_t irq_lock; - struct mutex mutex; - - /* Driver initialization status BCM43xx_STAT_*** */ - atomic_t init_status; + /* Do not use the lock directly. Use the bcm43xx_lock* helper + * functions, to be MMIO-safe. */ + spinlock_t _lock; - u16 was_initialized:1, /* for PCI suspend/resume. */ + /* Driver status flags. */ + u32 initialized:1, /* init_board() succeed */ + was_initialized:1, /* for PCI suspend/resume. */ + shutting_down:1, /* free_board() in progress */ __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ + powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ short_preamble:1, /* TRUE, if short preamble is enabled. */ firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ @@ -733,7 +721,7 @@ struct bcm43xx_private { struct tasklet_struct isr_tasklet; /* Periodic tasks */ - struct work_struct periodic_work; + struct timer_list periodic_tasks; unsigned int periodic_state; struct work_struct restart_work; @@ -752,65 +740,27 @@ struct bcm43xx_private { const struct firmware *initvals0; const struct firmware *initvals1; - /* Random Number Generator. */ - struct hwrng rng; - char rng_name[20 + 1]; - /* Debugging stuff follows. */ #ifdef CONFIG_BCM43XX_DEBUG struct bcm43xx_dfsentry *dfsentry; #endif }; - -/* *** THEORY OF LOCKING *** - * - * We have two different locks in the bcm43xx driver. - * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private - * and the device registers. - * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. - * - * We have three types of helper function pairs to utilize these locks. - * (Always use the helper functions.) - * 1) bcm43xx_{un}lock_noirq(): - * Takes bcm->mutex. Does _not_ protect against IRQ concurrency, - * so it is almost always unsafe, if device IRQs are enabled. - * So only use this, if device IRQs are masked. - * Locking may sleep. - * You can sleep within the critical section. - * 2) bcm43xx_{un}lock_irqonly(): - * Takes bcm->irq_lock. Does _not_ protect against - * bcm43xx_lock_noirq() critical sections. - * Does only protect against the IRQ handler path and other - * irqonly() critical sections. - * Locking does not sleep. - * You must not sleep within the critical section. - * 3) bcm43xx_{un}lock_irqsafe(): - * This is the cummulative lock and takes both, mutex and irq_lock. - * Protects against noirq() and irqonly() critical sections (and - * the IRQ handler path). - * Locking may sleep. - * You must not sleep within the critical section. +/* bcm43xx_(un)lock() protect struct bcm43xx_private. + * Note that _NO_ MMIO writes are allowed. If you want to + * write to the device through MMIO in the critical section, use + * the *_mmio lock functions. + * MMIO read-access is allowed, though. */ - -/* Lock type 1 */ -#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex) -#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex) -/* Lock type 2 */ -#define bcm43xx_lock_irqonly(bcm, flags) \ - spin_lock_irqsave(&(bcm)->irq_lock, flags) -#define bcm43xx_unlock_irqonly(bcm, flags) \ - spin_unlock_irqrestore(&(bcm)->irq_lock, flags) -/* Lock type 3 */ -#define bcm43xx_lock_irqsafe(bcm, flags) do { \ - bcm43xx_lock_noirq(bcm); \ - bcm43xx_lock_irqonly(bcm, flags); \ - } while (0) -#define bcm43xx_unlock_irqsafe(bcm, flags) do { \ - bcm43xx_unlock_irqonly(bcm, flags); \ - bcm43xx_unlock_noirq(bcm); \ - } while (0) - +#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) +#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) +/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. + * MMIO write-access to the device is allowed. + * All MMIO writes are flushed on unlock, so it is guaranteed to not + * interfere with other threads writing MMIO registers. + */ +#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) +#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) static inline struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) @@ -893,6 +843,16 @@ struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); } +/* Are we running in init_board() context? */ +static inline +int bcm43xx_is_initializing(struct bcm43xx_private *bcm) +{ + if (bcm->initialized) + return 0; + if (bcm->shutting_down) + return 0; + return 1; +} static inline struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index ce2e40b29b4f..7497fb16076e 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c @@ -77,8 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, down(&big_buffer_sem); - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (!bcm->initialized) { fappend("Board not initialized.\n"); goto out; } @@ -121,7 +121,7 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, fappend("\n"); out: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -159,8 +159,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, unsigned long flags; down(&big_buffer_sem); - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (!bcm->initialized) { fappend("Board not initialized.\n"); goto out; } @@ -169,7 +169,7 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); out: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -188,8 +188,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, u64 tsf; down(&big_buffer_sem); - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (!bcm->initialized) { fappend("Board not initialized.\n"); goto out; } @@ -199,7 +199,7 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, (unsigned int)(tsf & 0xFFFFFFFFULL)); out: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -221,8 +221,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, res = -EFAULT; goto out_up; } - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (!bcm->initialized) { printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); res = -EFAULT; goto out_unlock; @@ -233,11 +233,10 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, goto out_unlock; } bcm43xx_tsf_write(bcm, tsf); - mmiowb(); res = buf_size; out_unlock: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); out_up: up(&big_buffer_sem); return res; @@ -258,7 +257,7 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, int i, cnt, j = 0; down(&big_buffer_sem); - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", BCM43xx_NR_LOGGED_XMITSTATUS); @@ -294,14 +293,14 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); if (*ppos == pos) { /* Done. Drop the copied data. */ e->xmitstatus_printing = 0; } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); up(&big_buffer_sem); return res; } diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index ec80692d638a..4b2c02c0b31e 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d) struct bcm43xx_private *bcm = led->bcm; unsigned long flags; - bcm43xx_lock_irqonly(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); if (led->blink_interval) { bcm43xx_led_changestate(led); mod_timer(&led->blink_timer, jiffies + led->blink_interval); } - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } static void bcm43xx_led_blink_start(struct bcm43xx_led *led, diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 27bcf47228e2..736dde96c4a3 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -498,31 +498,20 @@ static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mas return old_mask; } -/* Synchronize IRQ top- and bottom-half. - * IRQs must be masked before calling this. - * This must not be called with the irq_lock held. - */ -static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm) -{ - synchronize_irq(bcm->irq); - tasklet_disable(&bcm->isr_tasklet); -} - /* Make sure we don't receive more data from the device. */ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) { - unsigned long flags; u32 old; + unsigned long flags; - bcm43xx_lock_irqonly(bcm, flags); - if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); + if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { + bcm43xx_unlock_mmio(bcm, flags); return -EBUSY; } old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_unlock_irqonly(bcm, flags); - bcm43xx_synchronize_irq(bcm); - + tasklet_disable(&bcm->isr_tasklet); + bcm43xx_unlock_mmio(bcm, flags); if (oldstate) *oldstate = old; @@ -1400,7 +1389,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); #endif } - if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { + if (bcm->shutting_down) { bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); @@ -1720,7 +1709,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) # define bcmirq_handled(irq) do { /* nothing */ } while (0) #endif /* CONFIG_BCM43XX_DEBUG*/ - bcm43xx_lock_irqonly(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); reason = bcm->irq_reason; dma_reason[0] = bcm->dma_reason[0]; dma_reason[1] = bcm->dma_reason[1]; @@ -1745,8 +1734,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3]); bcm43xx_controller_restart(bcm, "DMA error"); - mmiowb(); - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return; } if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | @@ -1833,8 +1821,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) if (!modparam_noleds) bcm43xx_leds_update(bcm, activity); bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - mmiowb(); - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } static void pio_irq_workaround(struct bcm43xx_private *bcm, @@ -1883,7 +1870,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re if (!bcm) return IRQ_NONE; - spin_lock(&bcm->irq_lock); + spin_lock(&bcm->_lock); reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); if (reason == 0xffffffff) { @@ -1912,7 +1899,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re * completely, but some careful work is needed to fix this. I think it * is best to stay with this cheap workaround for now... . */ - if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { + if (likely(bcm->initialized)) { /* disable all IRQs. They are enabled again in the bottom half. */ bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); /* save the reason code and call our bottom half. */ @@ -1922,7 +1909,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re out: mmiowb(); - spin_unlock(&bcm->irq_lock); + spin_unlock(&bcm->_lock); return ret; } @@ -2146,13 +2133,6 @@ static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) return err; } -#ifdef CONFIG_BCM947XX -static struct pci_device_id bcm43xx_47xx_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, - { 0 } -}; -#endif - static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) { int res; @@ -2162,15 +2142,11 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) bcm->irq = bcm->pci_dev->irq; #ifdef CONFIG_BCM947XX if (bcm->pci_dev->bus->number == 0) { - struct pci_dev *d; - struct pci_device_id *id; - for (id = bcm43xx_47xx_ids; id->vendor; id++) { - d = pci_get_device(id->vendor, id->device, NULL); - if (d != NULL) { - bcm->irq = d->irq; - pci_dev_put(d); - break; - } + struct pci_dev *d = NULL; + /* FIXME: we will probably need more device IDs here... */ + d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); + if (d != NULL) { + bcm->irq = d->irq; } } #endif @@ -3130,10 +3106,15 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) //TODO for APHY (temperature?) } -static void do_periodic_work(struct bcm43xx_private *bcm) +static void bcm43xx_periodic_task_handler(unsigned long d) { + struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; + unsigned long flags; unsigned int state; + bcm43xx_lock_mmio(bcm, flags); + + assert(bcm->initialized); state = bcm->periodic_state; if (state % 8 == 0) bcm43xx_periodic_every120sec(bcm); @@ -3141,93 +3122,29 @@ static void do_periodic_work(struct bcm43xx_private *bcm) bcm43xx_periodic_every60sec(bcm); if (state % 2 == 0) bcm43xx_periodic_every30sec(bcm); - if (state % 1 == 0) - bcm43xx_periodic_every15sec(bcm); + bcm43xx_periodic_every15sec(bcm); bcm->periodic_state = state + 1; - schedule_delayed_work(&bcm->periodic_work, HZ * 15); -} - -/* Estimate a "Badness" value based on the periodic work - * state-machine state. "Badness" is worse (bigger), if the - * periodic work will take longer. - */ -static int estimate_periodic_work_badness(unsigned int state) -{ - int badness = 0; + mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); - if (state % 8 == 0) /* every 120 sec */ - badness += 10; - if (state % 4 == 0) /* every 60 sec */ - badness += 5; - if (state % 2 == 0) /* every 30 sec */ - badness += 1; - if (state % 1 == 0) /* every 15 sec */ - badness += 1; - -#define BADNESS_LIMIT 4 - return badness; -} - -static void bcm43xx_periodic_work_handler(void *d) -{ - struct bcm43xx_private *bcm = d; - unsigned long flags; - u32 savedirqs = 0; - int badness; - - badness = estimate_periodic_work_badness(bcm->periodic_state); - if (badness > BADNESS_LIMIT) { - /* Periodic work will take a long time, so we want it to - * be preemtible. - */ - bcm43xx_lock_irqonly(bcm, flags); - netif_stop_queue(bcm->net_dev); - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_freeze_txqueues(bcm); - savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_unlock_irqonly(bcm, flags); - bcm43xx_lock_noirq(bcm); - bcm43xx_synchronize_irq(bcm); - } else { - /* Periodic work should take short time, so we want low - * locking overhead. - */ - bcm43xx_lock_irqsafe(bcm, flags); - } - - do_periodic_work(bcm); - - if (badness > BADNESS_LIMIT) { - bcm43xx_lock_irqonly(bcm, flags); - if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { - tasklet_enable(&bcm->isr_tasklet); - bcm43xx_interrupt_enable(bcm, savedirqs); - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_thaw_txqueues(bcm); - } - netif_wake_queue(bcm->net_dev); - mmiowb(); - bcm43xx_unlock_irqonly(bcm, flags); - bcm43xx_unlock_noirq(bcm); - } else { - mmiowb(); - bcm43xx_unlock_irqsafe(bcm, flags); - } + bcm43xx_unlock_mmio(bcm, flags); } static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) { - cancel_rearming_delayed_work(&bcm->periodic_work); + del_timer_sync(&bcm->periodic_tasks); } static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) { - struct work_struct *work = &(bcm->periodic_work); + struct timer_list *timer = &(bcm->periodic_tasks); - assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); - INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); - schedule_work(work); + assert(bcm->initialized); + setup_timer(timer, + bcm43xx_periodic_task_handler, + (unsigned long)bcm); + timer->expires = jiffies; + add_timer(timer); } static void bcm43xx_security_init(struct bcm43xx_private *bcm) @@ -3237,51 +3154,21 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm) bcm43xx_clear_keys(bcm); } -static int bcm43xx_rng_read(struct hwrng *rng, u32 *data) -{ - struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv; - unsigned long flags; - - bcm43xx_lock_irqonly(bcm, flags); - *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG); - bcm43xx_unlock_irqonly(bcm, flags); - - return (sizeof(u16)); -} - -static void bcm43xx_rng_exit(struct bcm43xx_private *bcm) -{ - hwrng_unregister(&bcm->rng); -} - -static int bcm43xx_rng_init(struct bcm43xx_private *bcm) -{ - int err; - - snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name), - "%s_%s", KBUILD_MODNAME, bcm->net_dev->name); - bcm->rng.name = bcm->rng_name; - bcm->rng.data_read = bcm43xx_rng_read; - bcm->rng.priv = (unsigned long)bcm; - err = hwrng_register(&bcm->rng); - if (err) - printk(KERN_ERR PFX "RNG init failed (%d)\n", err); - - return err; -} - /* This is the opposite of bcm43xx_init_board() */ static void bcm43xx_free_board(struct bcm43xx_private *bcm) { int i, err; + unsigned long flags; - bcm43xx_lock_noirq(bcm); bcm43xx_sysfs_unregister(bcm); + bcm43xx_periodic_tasks_delete(bcm); - bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); + bcm43xx_lock(bcm, flags); + bcm->initialized = 0; + bcm->shutting_down = 1; + bcm43xx_unlock(bcm, flags); - bcm43xx_rng_exit(bcm); for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { if (!bcm->core_80211[i].available) continue; @@ -3295,19 +3182,23 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) bcm43xx_pctl_set_crystal(bcm, 0); - bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); - bcm43xx_unlock_noirq(bcm); + bcm43xx_lock(bcm, flags); + bcm->shutting_down = 0; + bcm43xx_unlock(bcm, flags); } static int bcm43xx_init_board(struct bcm43xx_private *bcm) { int i, err; int connect_phy; + unsigned long flags; might_sleep(); - bcm43xx_lock_noirq(bcm); - bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); + bcm43xx_lock(bcm, flags); + bcm->initialized = 0; + bcm->shutting_down = 0; + bcm43xx_unlock(bcm, flags); err = bcm43xx_pctl_set_crystal(bcm, 1); if (err) @@ -3359,9 +3250,6 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) bcm43xx_switch_core(bcm, &bcm->core_80211[0]); bcm43xx_mac_enable(bcm); } - err = bcm43xx_rng_init(bcm); - if (err) - goto err_80211_unwind; bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); dprintk(KERN_INFO PFX "80211 cores initialized\n"); @@ -3377,7 +3265,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) } /* Initialization of the board is done. Flag it as such. */ - bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); + bcm43xx_lock(bcm, flags); + bcm->initialized = 1; + bcm43xx_unlock(bcm, flags); bcm43xx_periodic_tasks_setup(bcm); bcm43xx_sysfs_register(bcm); @@ -3388,8 +3278,6 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) assert(err == 0); out: - bcm43xx_unlock_noirq(bcm); - return err; err_80211_unwind: @@ -3646,8 +3534,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, struct bcm43xx_radioinfo *radio; unsigned long flags; - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (bcm->initialized) { bcm43xx_mac_suspend(bcm); bcm43xx_radio_selectchannel(bcm, channel, 0); bcm43xx_mac_enable(bcm); @@ -3655,7 +3543,7 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, radio = bcm43xx_current_radio(bcm); radio->initial_channel = channel; } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } /* set_security() callback in struct ieee80211_device */ @@ -3669,7 +3557,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, dprintk(KERN_INFO PFX "set security called"); - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); for (keyidx = 0; keyidxflags & (1<encrypt); } dprintk("\n"); - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && - !bcm->ieee->host_encrypt) { + if (bcm->initialized && !bcm->ieee->host_encrypt) { if (secinfo->enabled) { /* upload WEP keys to hardware */ char null_address[6] = { 0 }; @@ -3734,7 +3621,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, } else bcm43xx_clear_keys(bcm); } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } /* hard_start_xmit() callback in struct ieee80211_device */ @@ -3746,10 +3633,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, int err = -ENODEV; unsigned long flags; - bcm43xx_lock_irqonly(bcm, flags); - if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) + bcm43xx_lock_mmio(bcm, flags); + if (likely(bcm->initialized)) err = bcm43xx_tx(bcm, txb); - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return err; } @@ -3764,9 +3651,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev) struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_irqonly(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); bcm43xx_controller_restart(bcm, "TX timeout"); - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -3791,11 +3678,9 @@ static int bcm43xx_net_open(struct net_device *net_dev) static int bcm43xx_net_stop(struct net_device *net_dev) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; ieee80211softmac_stop(net_dev); - err = bcm43xx_disable_interrupts_sync(bcm, NULL); - assert(!err); + bcm43xx_disable_interrupts_sync(bcm, NULL); bcm43xx_free_board(bcm); return 0; @@ -3807,7 +3692,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, { int err; - bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm->ieee = netdev_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev); bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; @@ -3816,8 +3700,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, bcm->pci_dev = pci_dev; bcm->net_dev = net_dev; bcm->bad_frames_preempt = modparam_bad_frames_preempt; - spin_lock_init(&bcm->irq_lock); - mutex_init(&bcm->mutex); + spin_lock_init(&bcm->_lock); tasklet_init(&bcm->isr_tasklet, (void (*)(unsigned long))bcm43xx_interrupt_tasklet, (unsigned long)bcm); @@ -3948,7 +3831,7 @@ static void bcm43xx_chip_reset(void *_bcm) struct net_device *net_dev = bcm->net_dev; struct pci_dev *pci_dev = bcm->pci_dev; int err; - int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + int was_initialized = bcm->initialized; netif_stop_queue(bcm->net_dev); tasklet_disable(&bcm->isr_tasklet); @@ -3983,7 +3866,6 @@ static void bcm43xx_chip_reset(void *_bcm) */ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) { - bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); @@ -4002,11 +3884,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) dprintk(KERN_INFO PFX "Suspending...\n"); - bcm43xx_lock_irqsafe(bcm, flags); - bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); - if (bcm->was_initialized) + bcm43xx_lock(bcm, flags); + bcm->was_initialized = bcm->initialized; + if (bcm->initialized) try_to_shutdown = 1; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); netif_device_detach(net_dev); if (try_to_shutdown) { diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index f8200deecc8a..b0abac515530 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1410,10 +1410,7 @@ static inline u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) { struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 ret; - unsigned long flags; - local_irq_save(flags); if (phy->connected) { bcm43xx_phy_write(bcm, 0x15, 0xE300); control <<= 8; @@ -1433,10 +1430,8 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); udelay(8); } - ret = bcm43xx_phy_read(bcm, 0x002D); - local_irq_restore(flags); - return ret; + return bcm43xx_phy_read(bcm, 0x002D); } static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) @@ -1653,7 +1648,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) { static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; - const int is_initializing = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZING); + const int is_initializing = bcm43xx_is_initializing(bcm); struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); u16 h, i, oldi = 0, j; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index 574085c46152..0aa1bd269a25 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c @@ -262,10 +262,8 @@ static void tx_tasklet(unsigned long d) int err; u16 txctl; - bcm43xx_lock_irqonly(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); - if (queue->tx_frozen) - goto out_unlock; txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) goto out_unlock; @@ -300,7 +298,7 @@ static void tx_tasklet(unsigned long d) continue; } out_unlock: - bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); } static void setup_txqueues(struct bcm43xx_pioqueue *queue) @@ -376,6 +374,7 @@ static void cancel_transfers(struct bcm43xx_pioqueue *queue) struct bcm43xx_pio_txpacket *packet, *tmp_packet; netif_tx_disable(queue->bcm->net_dev); + assert(queue->bcm->shutting_down); tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) @@ -635,40 +634,5 @@ void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) & ~BCM43xx_PIO_TXCTL_SUSPEND); bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); - if (!list_empty(&queue->txqueue)) - tasklet_schedule(&queue->txtask); -} - -void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio; - - assert(bcm43xx_using_pio(bcm)); - pio = bcm43xx_current_pio(bcm); - pio->queue0->tx_frozen = 1; - pio->queue1->tx_frozen = 1; - pio->queue2->tx_frozen = 1; - pio->queue3->tx_frozen = 1; -} - -void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio; - - assert(bcm43xx_using_pio(bcm)); - pio = bcm43xx_current_pio(bcm); - pio->queue0->tx_frozen = 0; - pio->queue1->tx_frozen = 0; - pio->queue2->tx_frozen = 0; - pio->queue3->tx_frozen = 0; - if (!list_empty(&pio->queue0->txqueue)) - tasklet_schedule(&pio->queue0->txtask); - if (!list_empty(&pio->queue1->txqueue)) - tasklet_schedule(&pio->queue1->txtask); - if (!list_empty(&pio->queue2->txqueue)) - tasklet_schedule(&pio->queue2->txtask); - if (!list_empty(&pio->queue3->txqueue)) - tasklet_schedule(&pio->queue3->txtask); + tasklet_schedule(&queue->txtask); } - - diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h index bc78a3c2cafb..dfc78209e3a3 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h @@ -54,7 +54,6 @@ struct bcm43xx_pioqueue { u16 mmio_base; u8 tx_suspended:1, - tx_frozen:1, need_workarounds:1; /* Workarounds needed for core.rev < 3 */ /* Adjusted size of the device internal TX buffer. */ @@ -109,12 +108,8 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, struct bcm43xx_xmitstatus *status); void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); -/* Suspend a TX queue on hardware level. */ void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); -/* Suspend (freeze) the TX tasklet (software level). */ -void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm); -void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm); #else /* CONFIG_BCM43XX_PIO */ @@ -150,14 +145,6 @@ static inline void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) { } -static inline -void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) -{ -} -static inline -void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) -{ -} #endif /* CONFIG_BCM43XX_PIO */ #endif /* BCM43xx_PIO_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index 6a23bdc75412..b438f48e891d 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -120,12 +120,12 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, GFP_KERNEL); if (!sprom) return -ENOMEM; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); + assert(bcm->initialized); err = bcm43xx_sprom_read(bcm, sprom); if (!err) err = sprom2hex(sprom, buf, PAGE_SIZE); - mmiowb(); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); kfree(sprom); return err; @@ -150,10 +150,10 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev, err = hex2sprom(sprom, buf, count); if (err) goto out_kfree; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); + assert(bcm->initialized); err = bcm43xx_sprom_write(bcm, sprom); - mmiowb(); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); out_kfree: kfree(sprom); @@ -170,13 +170,15 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); + unsigned long flags; int err; ssize_t count = 0; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock_noirq(bcm); + bcm43xx_lock(bcm, flags); + assert(bcm->initialized); switch (bcm43xx_current_radio(bcm)->interfmode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -193,7 +195,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, } err = 0; - bcm43xx_unlock_noirq(bcm); + bcm43xx_unlock(bcm, flags); return err ? err : count; @@ -229,15 +231,16 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, return -EINVAL; } - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); + assert(bcm->initialized); err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " "supported by device\n"); } - mmiowb(); - bcm43xx_unlock_irqsafe(bcm, flags); + + bcm43xx_unlock_mmio(bcm, flags); return err ? err : count; } @@ -251,13 +254,15 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); + unsigned long flags; int err; ssize_t count; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock_noirq(bcm); + bcm43xx_lock(bcm, flags); + assert(bcm->initialized); if (bcm->short_preamble) count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); @@ -265,7 +270,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); err = 0; - bcm43xx_unlock_noirq(bcm); + bcm43xx_unlock(bcm, flags); return err ? err : count; } @@ -285,12 +290,13 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, value = get_boolean(buf, count); if (value < 0) return value; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); + assert(bcm->initialized); bcm->short_preamble = !!value; err = 0; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return err ? err : count; } @@ -304,7 +310,7 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) struct device *dev = &bcm->pci_dev->dev; int err; - assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + assert(bcm->initialized); err = device_create_file(dev, &dev_attr_sprom); if (err) diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index c35cb3a0777e..b45063974ae9 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -55,13 +55,13 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int i; unsigned long flags; + int i; struct bcm43xx_phyinfo *phy; char suffix[7] = { 0 }; int have_a = 0, have_b = 0, have_g = 0; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); for (i = 0; i < bcm->nr_80211_available; i++) { phy = &(bcm->core_80211_ext[i].phy); switch (phy->type) { @@ -77,7 +77,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, assert(0); } } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); i = 0; if (have_a) { @@ -111,7 +111,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, int freq; int err = -EINVAL; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { channel = data->freq.m; freq = bcm43xx_channel_to_freq(bcm, channel); @@ -121,7 +121,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, } if (!bcm43xx_is_valid_channel(bcm, channel)) goto out_unlock; - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { + if (bcm->initialized) { //ieee80211softmac_disassoc(softmac, $REASON); bcm43xx_mac_suspend(bcm); err = bcm43xx_radio_selectchannel(bcm, channel, 0); @@ -131,7 +131,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, err = 0; } out_unlock: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return err; } @@ -147,10 +147,11 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, int err = -ENODEV; u16 channel; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); radio = bcm43xx_current_radio(bcm); channel = radio->channel; if (channel == 0xFF) { + assert(!bcm->initialized); channel = radio->initial_channel; if (channel == 0xFF) goto out_unlock; @@ -162,7 +163,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return err; } @@ -180,13 +181,13 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev, if (mode == IW_MODE_AUTO) mode = BCM43xx_INITIAL_IWMODE; - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (bcm->initialized) { if (bcm->ieee->iw_mode != mode) bcm43xx_set_iwmode(bcm, mode); } else bcm->ieee->iw_mode = mode; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return 0; } @@ -199,9 +200,9 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); data->mode = bcm->ieee->iw_mode; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -254,7 +255,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); phy = bcm43xx_current_phy(bcm); range->num_bitrates = 0; @@ -301,7 +302,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, } range->num_frequency = j; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -312,13 +313,14 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); + unsigned long flags; size_t len; - bcm43xx_lock_noirq(bcm); + bcm43xx_lock(bcm, flags); len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); memcpy(bcm->nick, extra, len); bcm->nick[len] = '\0'; - bcm43xx_unlock_noirq(bcm); + bcm43xx_unlock(bcm, flags); return 0; } @@ -329,14 +331,15 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); + unsigned long flags; size_t len; - bcm43xx_lock_noirq(bcm); + bcm43xx_lock(bcm, flags); len = strlen(bcm->nick) + 1; memcpy(extra, bcm->nick, len); data->data.length = (__u16)len; data->data.flags = 1; - bcm43xx_unlock_noirq(bcm); + bcm43xx_unlock(bcm, flags); return 0; } @@ -350,7 +353,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); if (data->rts.disabled) { bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; err = 0; @@ -361,7 +364,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return err; } @@ -374,11 +377,11 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); data->rts.value = bcm->rts_threshold; data->rts.fixed = 0; data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -392,7 +395,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); if (data->frag.disabled) { bcm->ieee->fts = MAX_FRAG_THRESHOLD; err = 0; @@ -403,7 +406,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return err; } @@ -416,11 +419,11 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); data->frag.value = bcm->ieee->fts; data->frag.fixed = 0; data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -442,8 +445,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, return -EOPNOTSUPP; } - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) + bcm43xx_lock_mmio(bcm, flags); + if (!bcm->initialized) goto out_unlock; radio = bcm43xx_current_radio(bcm); phy = bcm43xx_current_phy(bcm); @@ -466,7 +469,7 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return err; } @@ -481,8 +484,8 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, unsigned long flags; int err = -ENODEV; - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) + bcm43xx_lock(bcm, flags); + if (!bcm->initialized) goto out_unlock; radio = bcm43xx_current_radio(bcm); /* desired dBm value is in Q5.2 */ @@ -493,7 +496,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return err; } @@ -580,8 +583,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, return -EINVAL; } - bcm43xx_lock_irqsafe(bcm, flags); - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { + bcm43xx_lock_mmio(bcm, flags); + if (bcm->initialized) { err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " @@ -595,7 +598,7 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, } else bcm43xx_current_radio(bcm)->interfmode = mode; } - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); return err; } @@ -609,9 +612,9 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, unsigned long flags; int mode; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); mode = bcm43xx_current_radio(bcm)->interfmode; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); switch (mode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -641,9 +644,9 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, int on; on = *((int *)extra); - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); bcm->short_preamble = !!on; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -657,9 +660,9 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); on = bcm->short_preamble; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); if (on) strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); @@ -681,11 +684,11 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, on = *((int *)extra); - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); bcm->ieee->host_encrypt = !!on; bcm->ieee->host_decrypt = !!on; bcm->ieee->host_build_iv = !on; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); return 0; } @@ -699,9 +702,9 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock(bcm, flags); on = bcm->ieee->host_encrypt; - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock(bcm, flags); if (on) strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); @@ -764,11 +767,11 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, if (!sprom) goto out; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); err = -ENODEV; - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) + if (bcm->initialized) err = bcm43xx_sprom_read(bcm, sprom); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); if (!err) data->data.length = sprom2hex(sprom, extra); kfree(sprom); @@ -809,11 +812,11 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, if (err) goto out_kfree; - bcm43xx_lock_irqsafe(bcm, flags); + bcm43xx_lock_mmio(bcm, flags); err = -ENODEV; - if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) + if (bcm->initialized) err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_irqsafe(bcm, flags); + bcm43xx_unlock_mmio(bcm, flags); out_kfree: kfree(sprom); out: diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index 94aeb23a7729..72335c8eb97f 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -1485,7 +1485,7 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv) * * Sending the PREPARE_FOR_POWER_DOWN will restrict the * hardware from going into standby mode and will transition - * out of D0-standby if it is already in that state. + * out of D0-standy if it is already in that state. * * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the * driver upon completion. Once received, the driver can diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index a8a8f975432f..39f82f219749 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -533,7 +533,7 @@ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); } -static inline void __ipw_enable_interrupts(struct ipw_priv *priv) +static inline void ipw_enable_interrupts(struct ipw_priv *priv) { if (priv->status & STATUS_INT_ENABLED) return; @@ -541,7 +541,7 @@ static inline void __ipw_enable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); } -static inline void __ipw_disable_interrupts(struct ipw_priv *priv) +static inline void ipw_disable_interrupts(struct ipw_priv *priv) { if (!(priv->status & STATUS_INT_ENABLED)) return; @@ -549,24 +549,6 @@ static inline void __ipw_disable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); } -static inline void ipw_enable_interrupts(struct ipw_priv *priv) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->irq_lock, flags); - __ipw_enable_interrupts(priv); - spin_unlock_irqrestore(&priv->irq_lock, flags); -} - -static inline void ipw_disable_interrupts(struct ipw_priv *priv) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->irq_lock, flags); - __ipw_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->irq_lock, flags); -} - #ifdef CONFIG_IPW2200_DEBUG static char *ipw_error_desc(u32 val) { @@ -1229,6 +1211,12 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) return error; } +static void ipw_free_error_log(struct ipw_fw_error *error) +{ + if (error) + kfree(error); +} + static ssize_t show_event_log(struct device *d, struct device_attribute *attr, char *buf) { @@ -1290,9 +1278,10 @@ static ssize_t clear_error(struct device *d, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); - - kfree(priv->error); - priv->error = NULL; + if (priv->error) { + ipw_free_error_log(priv->error); + priv->error = NULL; + } return count; } @@ -1867,7 +1856,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) unsigned long flags; int rc = 0; - spin_lock_irqsave(&priv->irq_lock, flags); + spin_lock_irqsave(&priv->lock, flags); inta = ipw_read32(priv, IPW_INTA_RW); inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); @@ -1876,10 +1865,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) /* Add any cached INTA values that need to be handled */ inta |= priv->isr_inta; - spin_unlock_irqrestore(&priv->irq_lock, flags); - - spin_lock_irqsave(&priv->lock, flags); - /* handle all the justifications for the interrupt */ if (inta & IPW_INTA_BIT_RX_TRANSFER) { ipw_rx(priv); @@ -1963,7 +1948,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) struct ipw_fw_error *error = ipw_alloc_error_log(priv); ipw_dump_error_log(priv, error); - kfree(error); + if (error) + ipw_free_error_log(error); } #endif } else { @@ -2007,10 +1993,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); } - spin_unlock_irqrestore(&priv->lock, flags); - /* enable all interrupts */ ipw_enable_interrupts(priv); + + spin_unlock_irqrestore(&priv->lock, flags); } #define IPW_CMD(x) case IPW_CMD_ ## x : return #x @@ -10474,7 +10460,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) if (!priv) return IRQ_NONE; - spin_lock(&priv->irq_lock); + spin_lock(&priv->lock); if (!(priv->status & STATUS_INT_ENABLED)) { /* Shared IRQ */ @@ -10496,7 +10482,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) } /* tell the device to stop sending interrupts */ - __ipw_disable_interrupts(priv); + ipw_disable_interrupts(priv); /* ack current interrupts */ inta &= (IPW_INTA_MASK_ALL & inta_mask); @@ -10507,11 +10493,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) tasklet_schedule(&priv->irq_tasklet); - spin_unlock(&priv->irq_lock); + spin_unlock(&priv->lock); return IRQ_HANDLED; none: - spin_unlock(&priv->irq_lock); + spin_unlock(&priv->lock); return IRQ_NONE; } @@ -11491,7 +11477,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_IPW2200_DEBUG ipw_debug_level = debug; #endif - spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->lock); for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); @@ -11685,8 +11670,10 @@ static void ipw_pci_remove(struct pci_dev *pdev) } } - kfree(priv->error); - priv->error = NULL; + if (priv->error) { + ipw_free_error_log(priv->error); + priv->error = NULL; + } #ifdef CONFIG_IPW2200_PROMISCUOUS ipw_prom_free(priv); diff --git a/trunk/drivers/net/wireless/ipw2200.h b/trunk/drivers/net/wireless/ipw2200.h index ea12ad66b8e8..6044c0be2c80 100644 --- a/trunk/drivers/net/wireless/ipw2200.h +++ b/trunk/drivers/net/wireless/ipw2200.h @@ -1173,7 +1173,6 @@ struct ipw_priv { struct ieee80211_device *ieee; spinlock_t lock; - spinlock_t irq_lock; struct mutex mutex; /* basic pci-network driver stuff */ diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index a915fe6c6aa5..879eb427607c 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -924,7 +924,8 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/net/wireless/wavelan.c b/trunk/drivers/net/wireless/wavelan.c index 5b69befdab74..dade4b903579 100644 --- a/trunk/drivers/net/wireless/wavelan.c +++ b/trunk/drivers/net/wireless/wavelan.c @@ -1695,8 +1695,8 @@ static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */ /* Look in the table if the frequency is allowed */ if (table[9 - (freq / 16)] & (1 << (freq % 16))) { /* Compute approximate channel number */ - while ((c < NELS(channel_bands)) && - (((channel_bands[c] >> 1) - 24) < freq)) + while ((((channel_bands[c] >> 1) - 24) < freq) && + (c < NELS(channel_bands))) c++; list[i].i = c; /* Set the list index */ @@ -2903,7 +2903,6 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) { net_local *lp = (net_local *) dev->priv; unsigned long flags; - char data[ETH_ZLEN]; #ifdef DEBUG_TX_TRACE printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, @@ -2938,15 +2937,14 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) * able to detect collisions, therefore in theory we don't really * need to pad. Jean II */ if (skb->len < ETH_ZLEN) { - memset(data, 0, ETH_ZLEN); - memcpy(data, skb->data, skb->len); - /* Write packet on the card */ - if(wv_packet_write(dev, data, ETH_ZLEN)) - return 1; /* We failed */ + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; } - else if(wv_packet_write(dev, skb->data, skb->len)) - return 1; /* We failed */ + /* Write packet on the card */ + if(wv_packet_write(dev, skb->data, skb->len)) + return 1; /* We failed */ dev_kfree_skb(skb); diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index 561250f73fd3..f7724eb2fa7e 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -3194,8 +3194,11 @@ wavelan_packet_xmit(struct sk_buff * skb, * and we don't have the Ethernet specific requirement of beeing * able to detect collisions, therefore in theory we don't really * need to pad. Jean II */ - if (skb_padto(skb, ETH_ZLEN)) - return 0; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) + return 0; + } wv_packet_write(dev, skb->data, skb->len); diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c index ecec8e5db786..fd0f43b7db5b 100644 --- a/trunk/drivers/net/yellowfin.c +++ b/trunk/drivers/net/yellowfin.c @@ -862,11 +862,13 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fix GX chipset errata. */ if (cacheline_end > 24 || cacheline_end == 0) { len = skb->len + 32 - cacheline_end + 1; - if (skb_padto(skb, len)) { - yp->tx_skbuff[entry] = NULL; - netif_wake_queue(dev); - return 0; - } + if (len != skb->len) + skb = skb_padto(skb, len); + } + if (skb == NULL) { + yp->tx_skbuff[entry] = NULL; + netif_wake_queue(dev); + return 0; } } yp->tx_skbuff[entry] = skb; diff --git a/trunk/drivers/net/znet.c b/trunk/drivers/net/znet.c index a7c089df66e6..3ac047bc727d 100644 --- a/trunk/drivers/net/znet.c +++ b/trunk/drivers/net/znet.c @@ -544,7 +544,8 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: ZNet_send_packet.\n", dev->name); if (length < ETH_ZLEN) { - if (skb_padto(skb, ETH_ZLEN)) + skb = skb_padto(skb, ETH_ZLEN); + if (skb == NULL) return 0; length = ETH_ZLEN; } diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index 43e521e99126..b2e8e49c8659 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -108,10 +108,10 @@ static int module_load_notify(struct notifier_block * self, unsigned long val, v return 0; /* FIXME: should we process all CPU buffers ? */ - mutex_lock(&buffer_mutex); + down(&buffer_sem); add_event_entry(ESCAPE_CODE); add_event_entry(MODULE_LOADED_CODE); - mutex_unlock(&buffer_mutex); + up(&buffer_sem); #endif return 0; } @@ -501,7 +501,7 @@ void sync_buffer(int cpu) sync_buffer_state state = sb_buffer_start; unsigned long available; - mutex_lock(&buffer_mutex); + down(&buffer_sem); add_cpu_switch(cpu); @@ -550,5 +550,5 @@ void sync_buffer(int cpu) mark_done(cpu); - mutex_unlock(&buffer_mutex); + up(&buffer_sem); } diff --git a/trunk/drivers/oprofile/event_buffer.c b/trunk/drivers/oprofile/event_buffer.c index 04d641714d34..b80318f03420 100644 --- a/trunk/drivers/oprofile/event_buffer.c +++ b/trunk/drivers/oprofile/event_buffer.c @@ -24,7 +24,7 @@ #include "event_buffer.h" #include "oprofile_stats.h" -DEFINE_MUTEX(buffer_mutex); +DECLARE_MUTEX(buffer_sem); static unsigned long buffer_opened; static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); @@ -32,7 +32,7 @@ static unsigned long * event_buffer; static unsigned long buffer_size; static unsigned long buffer_watershed; static size_t buffer_pos; -/* atomic_t because wait_event checks it outside of buffer_mutex */ +/* atomic_t because wait_event checks it outside of buffer_sem */ static atomic_t buffer_ready = ATOMIC_INIT(0); /* Add an entry to the event buffer. When we @@ -60,10 +60,10 @@ void add_event_entry(unsigned long value) */ void wake_up_buffer_waiter(void) { - mutex_lock(&buffer_mutex); + down(&buffer_sem); atomic_set(&buffer_ready, 1); wake_up(&buffer_wait); - mutex_unlock(&buffer_mutex); + up(&buffer_sem); } @@ -162,7 +162,7 @@ static ssize_t event_buffer_read(struct file * file, char __user * buf, if (!atomic_read(&buffer_ready)) return -EAGAIN; - mutex_lock(&buffer_mutex); + down(&buffer_sem); atomic_set(&buffer_ready, 0); @@ -177,7 +177,7 @@ static ssize_t event_buffer_read(struct file * file, char __user * buf, buffer_pos = 0; out: - mutex_unlock(&buffer_mutex); + up(&buffer_sem); return retval; } diff --git a/trunk/drivers/oprofile/event_buffer.h b/trunk/drivers/oprofile/event_buffer.h index 92416276e577..018023630599 100644 --- a/trunk/drivers/oprofile/event_buffer.h +++ b/trunk/drivers/oprofile/event_buffer.h @@ -11,7 +11,7 @@ #define EVENT_BUFFER_H #include -#include +#include int alloc_event_buffer(void); @@ -46,6 +46,6 @@ extern struct file_operations event_buffer_fops; /* mutex between sync_cpu_buffers() and the * file reading code. */ -extern struct mutex buffer_mutex; +extern struct semaphore buffer_sem; #endif /* EVENT_BUFFER_H */ diff --git a/trunk/drivers/oprofile/oprof.c b/trunk/drivers/oprofile/oprof.c index e5162a64018b..b3f1cd6a24c1 100644 --- a/trunk/drivers/oprofile/oprof.c +++ b/trunk/drivers/oprofile/oprof.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "oprof.h" #include "event_buffer.h" @@ -25,7 +25,7 @@ struct oprofile_operations oprofile_ops; unsigned long oprofile_started; unsigned long backtrace_depth; static unsigned long is_setup; -static DEFINE_MUTEX(start_mutex); +static DECLARE_MUTEX(start_sem); /* timer 0 - use performance monitoring hardware if available @@ -37,7 +37,7 @@ int oprofile_setup(void) { int err; - mutex_lock(&start_mutex); + down(&start_sem); if ((err = alloc_cpu_buffers())) goto out; @@ -57,7 +57,7 @@ int oprofile_setup(void) goto out3; is_setup = 1; - mutex_unlock(&start_mutex); + up(&start_sem); return 0; out3: @@ -68,7 +68,7 @@ int oprofile_setup(void) out1: free_cpu_buffers(); out: - mutex_unlock(&start_mutex); + up(&start_sem); return err; } @@ -78,7 +78,7 @@ int oprofile_start(void) { int err = -EINVAL; - mutex_lock(&start_mutex); + down(&start_sem); if (!is_setup) goto out; @@ -95,7 +95,7 @@ int oprofile_start(void) oprofile_started = 1; out: - mutex_unlock(&start_mutex); + up(&start_sem); return err; } @@ -103,7 +103,7 @@ int oprofile_start(void) /* echo 0>/dev/oprofile/enable */ void oprofile_stop(void) { - mutex_lock(&start_mutex); + down(&start_sem); if (!oprofile_started) goto out; oprofile_ops.stop(); @@ -111,20 +111,20 @@ void oprofile_stop(void) /* wake up the daemon to read what remains */ wake_up_buffer_waiter(); out: - mutex_unlock(&start_mutex); + up(&start_sem); } void oprofile_shutdown(void) { - mutex_lock(&start_mutex); + down(&start_sem); sync_stop(); if (oprofile_ops.shutdown) oprofile_ops.shutdown(); is_setup = 0; free_event_buffer(); free_cpu_buffers(); - mutex_unlock(&start_mutex); + up(&start_sem); } @@ -132,7 +132,7 @@ int oprofile_set_backtrace(unsigned long val) { int err = 0; - mutex_lock(&start_mutex); + down(&start_sem); if (oprofile_started) { err = -EBUSY; @@ -147,7 +147,7 @@ int oprofile_set_backtrace(unsigned long val) backtrace_depth = val; out: - mutex_unlock(&start_mutex); + up(&start_sem); return err; } diff --git a/trunk/drivers/oprofile/oprofilefs.c b/trunk/drivers/oprofile/oprofilefs.c index 71c2da277d6e..b62da9b0cbf0 100644 --- a/trunk/drivers/oprofile/oprofilefs.c +++ b/trunk/drivers/oprofile/oprofilefs.c @@ -272,10 +272,10 @@ static int oprofilefs_fill_super(struct super_block * sb, void * data, int silen } -static int oprofilefs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +static struct super_block *oprofilefs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) { - return get_sb_single(fs_type, flags, data, oprofilefs_fill_super, mnt); + return get_sb_single(fs_type, flags, data, oprofilefs_fill_super); } diff --git a/trunk/drivers/parport/Kconfig b/trunk/drivers/parport/Kconfig index c7fa28a28b9f..6c8452ede0e1 100644 --- a/trunk/drivers/parport/Kconfig +++ b/trunk/drivers/parport/Kconfig @@ -85,6 +85,11 @@ config PARPORT_PC_PCMCIA config PARPORT_NOT_PC bool +config PARPORT_ARC + tristate "Archimedes hardware" + depends on ARM && PARPORT + select PARPORT_NOT_PC + config PARPORT_IP32 tristate "SGI IP32 builtin port (EXPERIMENTAL)" depends on SGI_IP32 && PARPORT && EXPERIMENTAL @@ -136,18 +141,6 @@ config PARPORT_SUNBPP found on many Sun machines. Note that many of the newer Ultras actually have pc style hardware instead. -config PARPORT_AX88796 - tristate "AX88796 Parallel Port" - depends on PARPORT - select PARPORT_NOT_PC - help - Say Y here if you need support for the parallel port hardware on - the AX88796 network controller chip. This code is also available - as a module (say M), called parport_ax88796. - - The driver is not dependant on the AX88796 network driver, and - should not interfere with the networking functions of the chip. - config PARPORT_1284 bool "IEEE 1284 transfer modes" depends on PARPORT diff --git a/trunk/drivers/parport/Makefile b/trunk/drivers/parport/Makefile index 696b8d4ca887..a19de35f8de2 100644 --- a/trunk/drivers/parport/Makefile +++ b/trunk/drivers/parport/Makefile @@ -17,5 +17,4 @@ obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o -obj-$(CONFIG_PARPORT_AX88796) += parport_ax88796.o -obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o \ No newline at end of file +obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o diff --git a/trunk/drivers/parport/daisy.c b/trunk/drivers/parport/daisy.c index fd41e28101ea..9ee67321b630 100644 --- a/trunk/drivers/parport/daisy.c +++ b/trunk/drivers/parport/daisy.c @@ -283,7 +283,7 @@ void parport_close (struct pardevice *dev) * * This tries to locate a device on the given parallel port, * multiplexor port and daisy chain address, and returns its - * device number or %-ENXIO if no device with those coordinates + * device number or -NXIO if no device with those coordinates * exists. **/ diff --git a/trunk/drivers/parport/parport_arc.c b/trunk/drivers/parport/parport_arc.c new file mode 100644 index 000000000000..b35bb4f48d62 --- /dev/null +++ b/trunk/drivers/parport/parport_arc.c @@ -0,0 +1,139 @@ +/* Low-level parallel port routines for Archimedes onboard hardware + * + * Author: Phil Blundell + */ + +/* This driver is for the parallel port hardware found on Acorn's old + * range of Archimedes machines. The A5000 and newer systems have PC-style + * I/O hardware and should use the parport_pc driver instead. + * + * The Acorn printer port hardware is very simple. There is a single 8-bit + * write-only latch for the data port and control/status bits are handled + * with various auxilliary input and output lines. The port is not + * bidirectional, does not support any modes other than SPP, and has only + * a subset of the standard printer control lines connected. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DATA_ADDRESS 0x3350010 + +/* This is equivalent to the above and only used for request_region. */ +#define PORT_BASE 0x80000000 | ((DATA_ADDRESS - IO_BASE) >> 2) + +/* The hardware can't read from the data latch, so we must use a soft + copy. */ +static unsigned char data_copy; + +/* These are pretty simple. We know the irq is never shared and the + kernel does all the magic that's required. */ +static void arc_enable_irq(struct parport *p) +{ + enable_irq(p->irq); +} + +static void arc_disable_irq(struct parport *p) +{ + disable_irq(p->irq); +} + +static void arc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + parport_generic_irq(irq, (struct parport *) dev_id, regs); +} + +static void arc_write_data(struct parport *p, unsigned char data) +{ + data_copy = data; + outb_t(data, DATA_LATCH); +} + +static unsigned char arc_read_data(struct parport *p) +{ + return data_copy; +} + +static struct parport_operations parport_arc_ops = +{ + .write_data = arc_write_data, + .read_data = arc_read_data, + + .write_control = arc_write_control, + .read_control = arc_read_control, + .frob_control = arc_frob_control, + + .read_status = arc_read_status, + + .enable_irq = arc_enable_irq, + .disable_irq = arc_disable_irq, + + .data_forward = arc_data_forward, + .data_reverse = arc_data_reverse, + + .init_state = arc_init_state, + .save_state = arc_save_state, + .restore_state = arc_restore_state, + + .epp_write_data = parport_ieee1284_epp_write_data, + .epp_read_data = parport_ieee1284_epp_read_data, + .epp_write_addr = parport_ieee1284_epp_write_addr, + .epp_read_addr = parport_ieee1284_epp_read_addr, + + .ecp_write_data = parport_ieee1284_ecp_write_data, + .ecp_read_data = parport_ieee1284_ecp_read_data, + .ecp_write_addr = parport_ieee1284_ecp_write_addr, + + .compat_write_data = parport_ieee1284_write_compat, + .nibble_read_data = parport_ieee1284_read_nibble, + .byte_read_data = parport_ieee1284_read_byte, + + .owner = THIS_MODULE, +}; + +/* --- Initialisation code -------------------------------- */ + +static int parport_arc_init(void) +{ + /* Archimedes hardware provides only one port, at a fixed address */ + struct parport *p; + struct resource res; + char *fake_name = "parport probe"); + + res = request_region(PORT_BASE, 1, fake_name); + if (res == NULL) + return 0; + + p = parport_register_port (PORT_BASE, IRQ_PRINTERACK, + PARPORT_DMA_NONE, &parport_arc_ops); + + if (!p) { + release_region(PORT_BASE, 1); + return 0; + } + + p->modes = PARPORT_MODE_ARCSPP; + p->size = 1; + rename_region(res, p->name); + + printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n", + p->irq); + + /* Tell the high-level drivers about the port. */ + parport_announce_port (p); + + return 1; +} + +module_init(parport_arc_init) diff --git a/trunk/drivers/parport/parport_ax88796.c b/trunk/drivers/parport/parport_ax88796.c deleted file mode 100644 index 4baa719439a2..000000000000 --- a/trunk/drivers/parport/parport_ax88796.c +++ /dev/null @@ -1,443 +0,0 @@ -/* linux/drivers/parport/parport_ax88796.c - * - * (c) 2005,2006 Simtec Electronics - * Ben Dooks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define AX_SPR_BUSY (1<<7) -#define AX_SPR_ACK (1<<6) -#define AX_SPR_PE (1<<5) -#define AX_SPR_SLCT (1<<4) -#define AX_SPR_ERR (1<<3) - -#define AX_CPR_nDOE (1<<5) -#define AX_CPR_SLCTIN (1<<3) -#define AX_CPR_nINIT (1<<2) -#define AX_CPR_ATFD (1<<1) -#define AX_CPR_STRB (1<<0) - -struct ax_drvdata { - struct parport *parport; - struct parport_state suspend; - - struct device *dev; - struct resource *io; - - unsigned char irq_enabled; - - void __iomem *base; - void __iomem *spp_data; - void __iomem *spp_spr; - void __iomem *spp_cpr; -}; - -static inline struct ax_drvdata *pp_to_drv(struct parport *p) -{ - return p->private_data; -} - -static unsigned char -parport_ax88796_read_data(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - return readb(dd->spp_data); -} - -static void -parport_ax88796_write_data(struct parport *p, unsigned char data) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - writeb(data, dd->spp_data); -} - -static unsigned char -parport_ax88796_read_control(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int cpr = readb(dd->spp_cpr); - unsigned int ret = 0; - - if (!(cpr & AX_CPR_STRB)) - ret |= PARPORT_CONTROL_STROBE; - - if (!(cpr & AX_CPR_ATFD)) - ret |= PARPORT_CONTROL_AUTOFD; - - if (cpr & AX_CPR_nINIT) - ret |= PARPORT_CONTROL_INIT; - - if (!(cpr & AX_CPR_SLCTIN)) - ret |= PARPORT_CONTROL_SELECT; - - return ret; -} - -static void -parport_ax88796_write_control(struct parport *p, unsigned char control) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int cpr = readb(dd->spp_cpr); - - cpr &= AX_CPR_nDOE; - - if (!(control & PARPORT_CONTROL_STROBE)) - cpr |= AX_CPR_STRB; - - if (!(control & PARPORT_CONTROL_AUTOFD)) - cpr |= AX_CPR_ATFD; - - if (control & PARPORT_CONTROL_INIT) - cpr |= AX_CPR_nINIT; - - if (!(control & PARPORT_CONTROL_SELECT)) - cpr |= AX_CPR_SLCTIN; - - dev_dbg(dd->dev, "write_control: ctrl=%02x, cpr=%02x\n", control, cpr); - writeb(cpr, dd->spp_cpr); - - if (parport_ax88796_read_control(p) != control) { - dev_err(dd->dev, "write_control: read != set (%02x, %02x)\n", - parport_ax88796_read_control(p), control); - } -} - -static unsigned char -parport_ax88796_read_status(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned int status = readb(dd->spp_spr); - unsigned int ret = 0; - - if (status & AX_SPR_BUSY) - ret |= PARPORT_STATUS_BUSY; - - if (status & AX_SPR_ACK) - ret |= PARPORT_STATUS_ACK; - - if (status & AX_SPR_ERR) - ret |= PARPORT_STATUS_ERROR; - - if (status & AX_SPR_SLCT) - ret |= PARPORT_STATUS_SELECT; - - if (status & AX_SPR_PE) - ret |= PARPORT_STATUS_PAPEROUT; - - return ret; -} - -static unsigned char -parport_ax88796_frob_control(struct parport *p, unsigned char mask, - unsigned char val) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned char old = parport_ax88796_read_control(p); - - dev_dbg(dd->dev, "frob: mask=%02x, val=%02x, old=%02x\n", - mask, val, old); - - parport_ax88796_write_control(p, (old & ~mask) | val); - return old; -} - -static void -parport_ax88796_enable_irq(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned long flags; - - local_irq_save(flags); - if (!dd->irq_enabled) { - enable_irq(p->irq); - dd->irq_enabled = 1; - } - local_irq_restore(flags); -} - -static void -parport_ax88796_disable_irq(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - unsigned long flags; - - local_irq_save(flags); - if (dd->irq_enabled) { - disable_irq(p->irq); - dd->irq_enabled = 0; - } - local_irq_restore(flags); -} - -static void -parport_ax88796_data_forward(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - void __iomem *cpr = dd->spp_cpr; - - writeb((readb(cpr) & ~AX_CPR_nDOE), cpr); -} - -static void -parport_ax88796_data_reverse(struct parport *p) -{ - struct ax_drvdata *dd = pp_to_drv(p); - void __iomem *cpr = dd->spp_cpr; - - writeb(readb(cpr) | AX_CPR_nDOE, cpr); -} - -static void -parport_ax88796_init_state(struct pardevice *d, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(d->port); - - memset(s, 0, sizeof(struct parport_state)); - - dev_dbg(dd->dev, "init_state: %p: state=%p\n", d, s); - s->u.ax88796.cpr = readb(dd->spp_cpr); -} - -static void -parport_ax88796_save_state(struct parport *p, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - dev_dbg(dd->dev, "save_state: %p: state=%p\n", p, s); - s->u.ax88796.cpr = readb(dd->spp_cpr); -} - -static void -parport_ax88796_restore_state(struct parport *p, struct parport_state *s) -{ - struct ax_drvdata *dd = pp_to_drv(p); - - dev_dbg(dd->dev, "restore_state: %p: state=%p\n", p, s); - writeb(s->u.ax88796.cpr, dd->spp_cpr); -} - -static irqreturn_t -parport_ax88796_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - parport_generic_irq(irq, dev_id, regs); - return IRQ_HANDLED; -} - - -static struct parport_operations parport_ax88796_ops = { - .write_data = parport_ax88796_write_data, - .read_data = parport_ax88796_read_data, - - .write_control = parport_ax88796_write_control, - .read_control = parport_ax88796_read_control, - .frob_control = parport_ax88796_frob_control, - - .read_status = parport_ax88796_read_status, - - .enable_irq = parport_ax88796_enable_irq, - .disable_irq = parport_ax88796_disable_irq, - - .data_forward = parport_ax88796_data_forward, - .data_reverse = parport_ax88796_data_reverse, - - .init_state = parport_ax88796_init_state, - .save_state = parport_ax88796_save_state, - .restore_state = parport_ax88796_restore_state, - - .epp_write_data = parport_ieee1284_epp_write_data, - .epp_read_data = parport_ieee1284_epp_read_data, - .epp_write_addr = parport_ieee1284_epp_write_addr, - .epp_read_addr = parport_ieee1284_epp_read_addr, - - .ecp_write_data = parport_ieee1284_ecp_write_data, - .ecp_read_data = parport_ieee1284_ecp_read_data, - .ecp_write_addr = parport_ieee1284_ecp_write_addr, - - .compat_write_data = parport_ieee1284_write_compat, - .nibble_read_data = parport_ieee1284_read_nibble, - .byte_read_data = parport_ieee1284_read_byte, - - .owner = THIS_MODULE, -}; - -static int parport_ax88796_probe(struct platform_device *pdev) -{ - struct device *_dev = &pdev->dev; - struct ax_drvdata *dd; - struct parport *pp = NULL; - struct resource *res; - unsigned long size; - int spacing; - int irq; - int ret; - - dd = kzalloc(sizeof(struct ax_drvdata), GFP_KERNEL); - if (dd == NULL) { - dev_err(_dev, "no memory for private data\n"); - return -ENOMEM; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(_dev, "no MEM specified\n"); - ret = -ENXIO; - goto exit_mem; - } - - size = (res->end - res->start) + 1; - spacing = size / 3; - - dd->io = request_mem_region(res->start, size, pdev->name); - if (dd->io == NULL) { - dev_err(_dev, "cannot reserve memory\n"); - ret = -ENXIO; - goto exit_mem; - } - - dd->base = ioremap(res->start, size); - if (dd->base == NULL) { - dev_err(_dev, "cannot ioremap region\n"); - ret = -ENXIO; - goto exit_res; - } - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - irq = PARPORT_IRQ_NONE; - - pp = parport_register_port((unsigned long)dd->base, irq, - PARPORT_DMA_NONE, - &parport_ax88796_ops); - - if (pp == NULL) { - dev_err(_dev, "failed to register parallel port\n"); - ret = -ENOMEM; - goto exit_unmap; - } - - pp->private_data = dd; - dd->parport = pp; - dd->dev = _dev; - - dd->spp_data = dd->base; - dd->spp_spr = dd->base + (spacing * 1); - dd->spp_cpr = dd->base + (spacing * 2); - - /* initialise the port controls */ - writeb(AX_CPR_STRB, dd->spp_cpr); - - if (irq >= 0) { - /* request irq */ - ret = request_irq(irq, parport_ax88796_interrupt, - SA_TRIGGER_FALLING, pdev->name, pp); - - if (ret < 0) - goto exit_port; - - dd->irq_enabled = 1; - } - - platform_set_drvdata(pdev, pp); - - dev_info(_dev, "attached parallel port driver\n"); - parport_announce_port(pp); - - return 0; - - exit_port: - parport_remove_port(pp); - exit_unmap: - iounmap(dd->base); - exit_res: - release_resource(dd->io); - kfree(dd->io); - exit_mem: - kfree(dd); - return ret; -} - -static int parport_ax88796_remove(struct platform_device *pdev) -{ - struct parport *p = platform_get_drvdata(pdev); - struct ax_drvdata *dd = pp_to_drv(p); - - free_irq(p->irq, p); - parport_remove_port(p); - iounmap(dd->base); - release_resource(dd->io); - kfree(dd->io); - kfree(dd); - - return 0; -} - -#ifdef CONFIG_PM - -static int parport_ax88796_suspend(struct platform_device *dev, - pm_message_t state) -{ - struct parport *p = platform_get_drvdata(dev); - struct ax_drvdata *dd = pp_to_drv(p); - - parport_ax88796_save_state(p, &dd->suspend); - writeb(AX_CPR_nDOE | AX_CPR_STRB, dd->spp_cpr); - return 0; -} - -static int parport_ax88796_resume(struct platform_device *dev) -{ - struct parport *p = platform_get_drvdata(dev); - struct ax_drvdata *dd = pp_to_drv(p); - - parport_ax88796_restore_state(p, &dd->suspend); - return 0; -} - -#else -#define parport_ax88796_suspend NULL -#define parport_ax88796_resume NULL -#endif - -static struct platform_driver axdrv = { - .driver = { - .name = "ax88796-pp", - .owner = THIS_MODULE, - }, - .probe = parport_ax88796_probe, - .remove = parport_ax88796_remove, - .suspend = parport_ax88796_suspend, - .resume = parport_ax88796_resume, -}; - -static int __init parport_ax88796_init(void) -{ - return platform_driver_register(&axdrv); -} - -static void __exit parport_ax88796_exit(void) -{ - platform_driver_unregister(&axdrv); -} - -module_init(parport_ax88796_init) -module_exit(parport_ax88796_exit) - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("AX88796 Parport parallel port driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/parport/parport_gsc.c b/trunk/drivers/parport/parport_gsc.c index 7352104f7b30..1de52d9febf9 100644 --- a/trunk/drivers/parport/parport_gsc.c +++ b/trunk/drivers/parport/parport_gsc.c @@ -15,7 +15,7 @@ * Phil Blundell * Tim Waugh * Jose Renau - * David Campbell + * David Campbell * Andrea Arcangeli */ diff --git a/trunk/drivers/parport/parport_gsc.h b/trunk/drivers/parport/parport_gsc.h index fc9c37c54022..662f6c1fee5d 100644 --- a/trunk/drivers/parport/parport_gsc.h +++ b/trunk/drivers/parport/parport_gsc.h @@ -24,7 +24,7 @@ * Phil Blundell * Tim Waugh * Jose Renau - * David Campbell + * David Campbell * Andrea Arcangeli */ diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 7318e4a9e436..48bbf32fd980 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -3,7 +3,7 @@ * Authors: Phil Blundell * Tim Waugh * Jose Renau - * David Campbell + * David Campbell * Andrea Arcangeli * * based on work by Grant Guenther and Phil Blundell. diff --git a/trunk/drivers/parport/parport_sunbpp.c b/trunk/drivers/parport/parport_sunbpp.c index 7c43c5392bed..36a1556e64c7 100644 --- a/trunk/drivers/parport/parport_sunbpp.c +++ b/trunk/drivers/parport/parport_sunbpp.c @@ -1,4 +1,5 @@ -/* parport_sunbpp.c: Parallel-port routines for SBUS +/* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $ + * Parallel-port routines for Sun architecture * * Author: Derrick J. Brashear * @@ -13,9 +14,6 @@ * Gus Baldauf (gbaldauf@ix.netcom.com) * Peter Zaitcev * Tom Dyas - * - * Updated to new SBUS device framework: David S. Miller - * */ #include @@ -289,7 +287,14 @@ static struct parport_operations parport_sunbpp_ops = .owner = THIS_MODULE, }; -static int __devinit init_one_port(struct sbus_dev *sdev) +typedef struct { + struct list_head list; + struct parport *port; +} Node; +/* no locks, everything's serialized */ +static LIST_HEAD(port_list); + +static int __init init_one_port(struct sbus_dev *sdev) { struct parport *p; /* at least in theory there may be a "we don't dma" case */ @@ -298,120 +303,109 @@ static int __devinit init_one_port(struct sbus_dev *sdev) int irq, dma, err = 0, size; struct bpp_regs __iomem *regs; unsigned char value_tcr; + Node *node; + + dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev)); + node = kmalloc(sizeof(Node), GFP_KERNEL); + if (!node) + goto out0; irq = sdev->irqs[0]; base = sbus_ioremap(&sdev->resource[0], 0, sdev->reg_addrs[0].reg_size, "sunbpp"); if (!base) - return -ENODEV; + goto out1; size = sdev->reg_addrs[0].reg_size; dma = PARPORT_DMA_NONE; - ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); + dprintk(("alloc(ppops), ")); + ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); if (!ops) - goto out_unmap; + goto out2; memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); dprintk(("register_port\n")); if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) - goto out_free_ops; + goto out3; p->size = size; + dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ", + p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p)); if ((err = request_irq(p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p)) != 0) { - goto out_put_port; + dprintk(("ERROR %d\n", err)); + goto out4; } - + dprintk(("OK\n")); parport_sunbpp_enable_irq(p); regs = (struct bpp_regs __iomem *)p->base; - + dprintk((KERN_DEBUG "forward\n")); value_tcr = sbus_readb(®s->p_tcr); value_tcr &= ~P_TCR_DIR; sbus_writeb(value_tcr, ®s->p_tcr); printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); + node->port = p; + list_add(&node->list, &port_list); + parport_announce_port (p); - dev_set_drvdata(&sdev->ofdev.dev, p); - - parport_announce_port(p); - - return 0; + return 1; -out_put_port: +out4: parport_put_port(p); - -out_free_ops: +out3: kfree(ops); - -out_unmap: +out2: sbus_iounmap(base, size); - +out1: + kfree(node); +out0: return err; } -static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - return init_one_port(sdev); -} - -static int __devexit bpp_remove(struct of_device *dev) -{ - struct parport *p = dev_get_drvdata(&dev->dev); - struct parport_operations *ops = p->ops; - - parport_remove_port(p); - - if (p->irq != PARPORT_IRQ_NONE) { - parport_sunbpp_disable_irq(p); - free_irq(p->irq, p); - } - - sbus_iounmap((void __iomem *) p->base, p->size); - parport_put_port(p); - kfree(ops); - - dev_set_drvdata(&dev->dev, NULL); - - return 0; -} - -static struct of_device_id bpp_match[] = { - { - .name = "SUNW,bpp", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, bpp_match); - -static struct of_platform_driver bpp_sbus_driver = { - .name = "bpp", - .match_table = bpp_match, - .probe = bpp_probe, - .remove = __devexit_p(bpp_remove), -}; - static int __init parport_sunbpp_init(void) { - return of_register_driver(&bpp_sbus_driver, &sbus_bus_type); + struct sbus_bus *sbus; + struct sbus_dev *sdev; + int count = 0; + + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if (!strcmp(sdev->prom_name, "SUNW,bpp")) + count += init_one_port(sdev); + } + } + return count ? 0 : -ENODEV; } static void __exit parport_sunbpp_exit(void) { - of_unregister_driver(&bpp_sbus_driver); + while (!list_empty(&port_list)) { + Node *node = list_entry(port_list.next, Node, list); + struct parport *p = node->port; + struct parport_operations *ops = p->ops; + parport_remove_port(p); + + if (p->irq != PARPORT_IRQ_NONE) { + parport_sunbpp_disable_irq(p); + free_irq(p->irq, p); + } + sbus_iounmap((void __iomem *)p->base, p->size); + parport_put_port(p); + kfree (ops); + list_del(&node->list); + kfree (node); + } } MODULE_AUTHOR("Derrick J Brashear"); MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); -MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); module_init(parport_sunbpp_init) diff --git a/trunk/drivers/parport/procfs.c b/trunk/drivers/parport/procfs.c index 8610ae88b92d..cbe17184b9c7 100644 --- a/trunk/drivers/parport/procfs.c +++ b/trunk/drivers/parport/procfs.c @@ -1,6 +1,6 @@ /* Sysctl interface for parport devices. * - * Authors: David Campbell + * Authors: David Campbell * Tim Waugh * Philip Blundell * Andrea Arcangeli diff --git a/trunk/drivers/parport/share.c b/trunk/drivers/parport/share.c index 2cb22c8d3357..bbbfd79adbaf 100644 --- a/trunk/drivers/parport/share.c +++ b/trunk/drivers/parport/share.c @@ -218,7 +218,7 @@ static void free_port (struct parport *port) * parport_get_port - increment a port's reference count * @port: the port * - * This ensures that a struct parport pointer remains valid + * This ensure's that a struct parport pointer remains valid * until the matching parport_put_port() call. **/ diff --git a/trunk/drivers/pci/Makefile b/trunk/drivers/pci/Makefile index f2d152b818f0..6707df968934 100644 --- a/trunk/drivers/pci/Makefile +++ b/trunk/drivers/pci/Makefile @@ -26,11 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_PPC64) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o - -msiobj-y := msi.o msi-apic.o -msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o -msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o -obj-$(CONFIG_PCI_MSI) += $(msiobj-y) +obj-$(CONFIG_PCI_MSI) += msi.o # # ACPI Related PCI FW Functions diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 723092682023..eed67d9e73bc 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -81,9 +81,9 @@ void __devinit pci_bus_add_device(struct pci_dev *dev) { device_add(&dev->dev); - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_add_tail(&dev->global_list, &pci_devices); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); pci_proc_attach_device(dev); pci_create_sysfs_dev_files(dev); @@ -125,10 +125,10 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) */ if (dev->subordinate) { if (list_empty(&dev->subordinate->node)) { - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_add_tail(&dev->subordinate->node, &dev->bus->children); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); } pci_bus_add_devices(dev->subordinate); @@ -168,7 +168,7 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), struct list_head *next; bus = top; - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); next = top->devices.next; for (;;) { if (next == &bus->devices) { @@ -180,19 +180,22 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), continue; } dev = list_entry(next, struct pci_dev, bus_list); + pci_dev_get(dev); if (dev->subordinate) { /* this is a pci-pci bridge, do its devices next */ next = dev->subordinate->devices.next; bus = dev->subordinate; } else next = dev->bus_list.next; + spin_unlock(&pci_bus_lock); - /* Run device routines with the device locked */ - down(&dev->dev.sem); + /* Run device routines with the bus unlocked */ cb(dev, userdata); - up(&dev->dev.sem); + + spin_lock(&pci_bus_lock); + pci_dev_put(dev); } - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); } EXPORT_SYMBOL_GPL(pci_walk_bus); diff --git a/trunk/drivers/pci/hotplug/acpi_pcihp.c b/trunk/drivers/pci/hotplug/acpi_pcihp.c index 51cb9f817c22..39af9c325f35 100644 --- a/trunk/drivers/pci/hotplug/acpi_pcihp.c +++ b/trunk/drivers/pci/hotplug/acpi_pcihp.c @@ -25,7 +25,6 @@ */ #include -#include #include #include #include @@ -34,184 +33,10 @@ #include #include "pci_hotplug.h" -#define MY_NAME "acpi_pcihp" - -#define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0) -#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) - #define METHOD_NAME__SUN "_SUN" #define METHOD_NAME__HPP "_HPP" #define METHOD_NAME_OSHP "OSHP" -static int debug_acpi; - -static acpi_status -decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx) -{ - int i; - union acpi_object *fields = record->package.elements; - u32 revision = fields[1].integer.value; - - switch (revision) { - case 1: - if (record->package.count != 6) - return AE_ERROR; - for (i = 2; i < 6; i++) - if (fields[i].type != ACPI_TYPE_INTEGER) - return AE_ERROR; - hpx->t0 = &hpx->type0_data; - hpx->t0->revision = revision; - hpx->t0->cache_line_size = fields[2].integer.value; - hpx->t0->latency_timer = fields[3].integer.value; - hpx->t0->enable_serr = fields[4].integer.value; - hpx->t0->enable_perr = fields[5].integer.value; - break; - default: - printk(KERN_WARNING - "%s: Type 0 Revision %d record not supported\n", - __FUNCTION__, revision); - return AE_ERROR; - } - return AE_OK; -} - -static acpi_status -decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx) -{ - int i; - union acpi_object *fields = record->package.elements; - u32 revision = fields[1].integer.value; - - switch (revision) { - case 1: - if (record->package.count != 5) - return AE_ERROR; - for (i = 2; i < 5; i++) - if (fields[i].type != ACPI_TYPE_INTEGER) - return AE_ERROR; - hpx->t1 = &hpx->type1_data; - hpx->t1->revision = revision; - hpx->t1->max_mem_read = fields[2].integer.value; - hpx->t1->avg_max_split = fields[3].integer.value; - hpx->t1->tot_max_split = fields[4].integer.value; - break; - default: - printk(KERN_WARNING - "%s: Type 1 Revision %d record not supported\n", - __FUNCTION__, revision); - return AE_ERROR; - } - return AE_OK; -} - -static acpi_status -decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx) -{ - int i; - union acpi_object *fields = record->package.elements; - u32 revision = fields[1].integer.value; - - switch (revision) { - case 1: - if (record->package.count != 18) - return AE_ERROR; - for (i = 2; i < 18; i++) - if (fields[i].type != ACPI_TYPE_INTEGER) - return AE_ERROR; - hpx->t2 = &hpx->type2_data; - hpx->t2->revision = revision; - hpx->t2->unc_err_mask_and = fields[2].integer.value; - hpx->t2->unc_err_mask_or = fields[3].integer.value; - hpx->t2->unc_err_sever_and = fields[4].integer.value; - hpx->t2->unc_err_sever_or = fields[5].integer.value; - hpx->t2->cor_err_mask_and = fields[6].integer.value; - hpx->t2->cor_err_mask_or = fields[7].integer.value; - hpx->t2->adv_err_cap_and = fields[8].integer.value; - hpx->t2->adv_err_cap_or = fields[9].integer.value; - hpx->t2->pci_exp_devctl_and = fields[10].integer.value; - hpx->t2->pci_exp_devctl_or = fields[11].integer.value; - hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value; - hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value; - hpx->t2->sec_unc_err_sever_and = fields[14].integer.value; - hpx->t2->sec_unc_err_sever_or = fields[15].integer.value; - hpx->t2->sec_unc_err_mask_and = fields[16].integer.value; - hpx->t2->sec_unc_err_mask_or = fields[17].integer.value; - break; - default: - printk(KERN_WARNING - "%s: Type 2 Revision %d record not supported\n", - __FUNCTION__, revision); - return AE_ERROR; - } - return AE_OK; -} - -static acpi_status -acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) -{ - acpi_status status; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *package, *record, *fields; - u32 type; - int i; - - /* Clear the return buffer with zeros */ - memset(hpx, 0, sizeof(struct hotplug_params)); - - status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); - if (ACPI_FAILURE(status)) - return status; - - package = (union acpi_object *)buffer.pointer; - if (package->type != ACPI_TYPE_PACKAGE) { - status = AE_ERROR; - goto exit; - } - - for (i = 0; i < package->package.count; i++) { - record = &package->package.elements[i]; - if (record->type != ACPI_TYPE_PACKAGE) { - status = AE_ERROR; - goto exit; - } - - fields = record->package.elements; - if (fields[0].type != ACPI_TYPE_INTEGER || - fields[1].type != ACPI_TYPE_INTEGER) { - status = AE_ERROR; - goto exit; - } - - type = fields[0].integer.value; - switch (type) { - case 0: - status = decode_type0_hpx_record(record, hpx); - if (ACPI_FAILURE(status)) - goto exit; - break; - case 1: - status = decode_type1_hpx_record(record, hpx); - if (ACPI_FAILURE(status)) - goto exit; - break; - case 2: - status = decode_type2_hpx_record(record, hpx); - if (ACPI_FAILURE(status)) - goto exit; - break; - default: - printk(KERN_ERR "%s: Type %d record not supported\n", - __FUNCTION__, type); - status = AE_ERROR; - goto exit; - } - } - exit: - kfree(buffer.pointer); - return status; -} static acpi_status acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) @@ -225,9 +50,6 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); - /* Clear the return buffer with zeros */ - memset(hpp, 0, sizeof(struct hotplug_params)); - /* get _hpp */ status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); switch (status) { @@ -236,7 +58,7 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) if (!ret_buf.pointer) { printk(KERN_ERR "%s:%s alloc for _HPP fail\n", __FUNCTION__, (char *)string.pointer); - kfree(string.pointer); + acpi_os_free(string.pointer); return AE_NO_MEMORY; } status = acpi_evaluate_object(handle, METHOD_NAME__HPP, @@ -247,7 +69,7 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) if (ACPI_FAILURE(status)) { pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__, (char *)string.pointer, status); - kfree(string.pointer); + acpi_os_free(string.pointer); return status; } } @@ -276,20 +98,19 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) } } - hpp->t0 = &hpp->type0_data; - hpp->t0->cache_line_size = nui[0]; - hpp->t0->latency_timer = nui[1]; - hpp->t0->enable_serr = nui[2]; - hpp->t0->enable_perr = nui[3]; + hpp->cache_line_size = nui[0]; + hpp->latency_timer = nui[1]; + hpp->enable_serr = nui[2]; + hpp->enable_perr = nui[3]; - pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size); - pr_debug(" _HPP: latency timer =0x%x\n", hpp->t0->latency_timer); - pr_debug(" _HPP: enable SERR =0x%x\n", hpp->t0->enable_serr); - pr_debug(" _HPP: enable PERR =0x%x\n", hpp->t0->enable_perr); + pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); + pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer); + pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); + pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); free_and_return: - kfree(string.pointer); - kfree(ret_buf.pointer); + acpi_os_free(string.pointer); + acpi_os_free(ret_buf.pointer); return status; } @@ -309,17 +130,13 @@ acpi_status acpi_run_oshp(acpi_handle handle) /* run OSHP */ status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); if (ACPI_FAILURE(status)) - if (status != AE_NOT_FOUND) - printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", - __FUNCTION__, (char *)string.pointer, status); - else - dbg("%s:%s OSHP not found\n", - __FUNCTION__, (char *)string.pointer); + printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__, + (char *)string.pointer, status); else pr_debug("%s:%s OSHP passes\n", __FUNCTION__, (char *)string.pointer); - kfree(string.pointer); + acpi_os_free(string.pointer); return status; } EXPORT_SYMBOL_GPL(acpi_run_oshp); @@ -328,27 +145,14 @@ EXPORT_SYMBOL_GPL(acpi_run_oshp); /* acpi_get_hp_params_from_firmware * - * @bus - the pci_bus of the bus on which the device is newly added + * @dev - the pci_dev of the newly added device * @hpp - allocated by the caller */ -acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, +acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) { acpi_status status = AE_NOT_FOUND; - acpi_handle handle, phandle; - struct pci_bus *pbus = bus; - struct pci_dev *pdev; - - do { - pdev = pbus->self; - if (!pdev) { - handle = acpi_get_pci_rootbridge_handle( - pci_domain_nr(pbus), pbus->number); - break; - } - handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); - pbus = pbus->parent; - } while (!handle); + struct pci_dev *pdev = dev; /* * _HPP settings apply to all child buses, until another _HPP is @@ -356,19 +160,15 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, * look for it in the parent device scope since that would apply to * this pci dev. If we don't find any _HPP, use hardcoded defaults */ - while (handle) { - status = acpi_run_hpx(handle, hpp); - if (ACPI_SUCCESS(status)) + while (pdev && (ACPI_FAILURE(status))) { + acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); + if (!handle) break; status = acpi_run_hpp(handle, hpp); - if (ACPI_SUCCESS(status)) + if (!(pdev->bus->parent)) break; - if (acpi_root_bridge(handle)) - break; - status = acpi_get_parent(handle, &phandle); - if (ACPI_FAILURE(status)) - break; - handle = phandle; + /* Check if a parent object supports _HPP */ + pdev = pdev->bus->parent->self; } return status; } @@ -392,23 +192,20 @@ int acpi_root_bridge(acpi_handle handle) if ((info->valid & ACPI_VALID_HID) && !strcmp(PCI_ROOT_HID_STRING, info->hardware_id.value)) { - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); return 1; } if (info->valid & ACPI_VALID_CID) { for (i=0; i < info->compatibility_id.count; i++) { if (!strcmp(PCI_ROOT_HID_STRING, info->compatibility_id.id[i].value)) { - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); return 1; } } } - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); } return 0; } EXPORT_SYMBOL_GPL(acpi_root_bridge); - -module_param(debug_acpi, bool, 0644); -MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index 17a93f890dba..467ac70a46ff 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -75,10 +75,6 @@ struct acpiphp_bridge { struct list_head list; acpi_handle handle; struct acpiphp_slot *slots; - - /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ - struct acpiphp_func *func; - int type; int nr_slots; @@ -126,7 +122,6 @@ struct acpiphp_slot { */ struct acpiphp_func { struct acpiphp_slot *slot; /* parent */ - struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ struct list_head sibling; struct pci_dev *pci_dev; diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index d370f999782e..053ee843863c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -286,19 +286,13 @@ static void decode_hpp(struct acpiphp_bridge *bridge) { acpi_status status; - status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp); - if (ACPI_FAILURE(status) || - !bridge->hpp.t0 || (bridge->hpp.t0->revision > 1)) { + status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp); + if (ACPI_FAILURE(status)) { /* use default numbers */ - printk(KERN_WARNING - "%s: Could not get hotplug parameters. Use defaults\n", - __FUNCTION__); - bridge->hpp.t0 = &bridge->hpp.type0_data; - bridge->hpp.t0->revision = 0; - bridge->hpp.t0->cache_line_size = 0x10; - bridge->hpp.t0->latency_timer = 0x40; - bridge->hpp.t0->enable_serr = 0; - bridge->hpp.t0->enable_perr = 0; + bridge->hpp.cache_line_size = 0x10; + bridge->hpp.latency_timer = 0x40; + bridge->hpp.enable_serr = 0; + bridge->hpp.enable_perr = 0; } } @@ -325,13 +319,6 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) /* install notify handler */ if (bridge->type != BRIDGE_TYPE_HOST) { - if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { - status = acpi_remove_notify_handler(bridge->func->handle, - ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_func); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - } status = acpi_install_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, @@ -344,66 +331,6 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) } -/* find acpiphp_func from acpiphp_bridge */ -static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) -{ - struct list_head *node, *l; - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot; - struct acpiphp_func *func; - - list_for_each(node, &bridge_list) { - bridge = list_entry(node, struct acpiphp_bridge, list); - for (slot = bridge->slots; slot; slot = slot->next) { - list_for_each(l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, - sibling); - if (func->handle == handle) - return func; - } - } - } - - return NULL; -} - - -static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) -{ - acpi_handle dummy_handle; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_STA", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_STA; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_EJ0", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_EJ0; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_PS0", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_PS0; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_PS3", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_PS3; - - /* is this ejectable p2p bridge? */ - if (bridge->flags & BRIDGE_HAS_EJ0) { - struct acpiphp_func *func; - - dbg("found ejectable p2p bridge\n"); - - /* make link between PCI bridge and PCI function */ - func = acpiphp_bridge_handle_to_function(bridge->handle); - if (!func) - return; - bridge->func = func; - func->bridge = bridge; - } -} - - /* allocate and initialize host bridge data structure */ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) { @@ -437,7 +364,6 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) bridge->type = BRIDGE_TYPE_P2P; bridge->handle = handle; - config_p2p_bridge_flags(bridge); bridge->pci_dev = pci_dev_get(pci_dev); bridge->pci_bus = pci_dev->subordinate; @@ -497,7 +423,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, find_p2p_bridge, dev->subordinate, NULL); if (ACPI_FAILURE(status)) - warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + warn("find_p2p_bridge faied (error code = 0x%x)\n", status); out: pci_dev_put(dev); @@ -552,6 +478,7 @@ static int add_bridge(acpi_handle handle) if (detect_ejectable_slots(handle) > 0) { dbg("found PCI host-bus bridge with hot-pluggable slots\n"); add_host_bridge(handle, pci_bus); + return 0; } /* search P2P bridges under this host bridge */ @@ -559,7 +486,7 @@ static int add_bridge(acpi_handle handle) find_p2p_bridge, pci_bus, NULL); if (ACPI_FAILURE(status)) - warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + warn("find_p2p_bridge faied (error code = 0x%x)\n",status); return 0; } @@ -589,16 +516,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) if (ACPI_FAILURE(status)) err("failed to remove notify handler\n"); - if ((bridge->type != BRIDGE_TYPE_HOST) && - ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { - status = acpi_install_notify_handler(bridge->func->handle, - ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_func, - bridge->func); - if (ACPI_FAILURE(status)) - err("failed to install interrupt notify handler\n"); - } - slot = bridge->slots; while (slot) { struct acpiphp_slot *next = slot->next; @@ -632,11 +549,6 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { struct acpiphp_bridge *bridge; - /* cleanup p2p bridges under this P2P bridge - in a depth-first manner */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, - cleanup_p2p_bridge, NULL, NULL); - if (!(bridge = acpiphp_handle_to_bridge(handle))) return AE_OK; cleanup_bridge(bridge); @@ -647,14 +559,15 @@ static void remove_bridge(acpi_handle handle) { struct acpiphp_bridge *bridge; - /* cleanup p2p bridges under this host bridge - in a depth-first manner */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, - (u32)1, cleanup_p2p_bridge, NULL, NULL); - bridge = acpiphp_handle_to_bridge(handle); - if (bridge) + if (bridge) { cleanup_bridge(bridge); + } else { + /* clean-up p2p bridges under this host bridge */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, cleanup_p2p_bridge, + NULL, NULL); + } } static struct pci_dev * get_apic_pci_info(acpi_handle handle) @@ -721,7 +634,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base) break; } out: - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); return result; } @@ -884,6 +797,36 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) } + +/** + * get_func - get a pointer to acpiphp_func given a slot, device + * @slot: slot to search + * @dev: pci_dev struct to match. + * + * This function will increase the reference count of pci_dev, + * so callers should call pci_dev_put when complete. + * + */ +static struct acpiphp_func * +get_func(struct acpiphp_slot *slot, struct pci_dev *dev) +{ + struct acpiphp_func *func = NULL; + struct pci_bus *bus = slot->bridge->pci_bus; + struct pci_dev *pdev; + + list_for_each_entry(func, &slot->funcs, sibling) { + pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, + func->function)); + if (pdev) { + if (pdev == dev) + break; + pci_dev_put(pdev); + } + } + return func; +} + + /** * acpiphp_bus_add - add a new bus to acpi subsystem * @func: acpiphp_func of the bridge @@ -929,28 +872,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) } -/** - * acpiphp_bus_trim - trim a bus from acpi subsystem - * @handle: handle to acpi namespace - * - */ -int acpiphp_bus_trim(acpi_handle handle) -{ - struct acpi_device *device; - int retval; - - retval = acpi_bus_get_device(handle, &device); - if (retval) { - dbg("acpi_device not found\n"); - return retval; - } - - retval = acpi_bus_trim(device, 1); - if (retval) - err("cannot remove from acpi list\n"); - - return retval; -} /** * enable_device - enable, configure a slot @@ -968,7 +889,6 @@ static int enable_device(struct acpiphp_slot *slot) struct acpiphp_func *func; int retval = 0; int num, max, pass; - acpi_status status; if (slot->flags & SLOT_ENABLED) goto err_exit; @@ -998,17 +918,19 @@ static int enable_device(struct acpiphp_slot *slot) if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { max = pci_scan_bridge(bus, dev, max, pass); - if (pass && dev->subordinate) + if (pass && dev->subordinate) { pci_bus_size_bridges(dev->subordinate); + func = get_func(slot, dev); + if (func) { + acpiphp_bus_add(func); + /* side effect of get_func */ + pci_dev_put(dev); + } + } } } } - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - acpiphp_bus_add(func); - } - pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); pci_enable_bridges(bus); @@ -1021,17 +943,6 @@ static int enable_device(struct acpiphp_slot *slot) func = list_entry(l, struct acpiphp_func, sibling); func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, func->function)); - if (!func->pci_dev) - continue; - - if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && - func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) - continue; - - status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); - if (ACPI_FAILURE(status)) - warn("find_p2p_bridge failed (error code = 0x%x)\n", - status); } slot->flags |= SLOT_ENABLED; @@ -1056,18 +967,6 @@ static int disable_device(struct acpiphp_slot *slot) list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - - if (func->bridge) { - /* cleanup p2p bridges under this P2P bridge */ - cleanup_p2p_bridge(func->bridge->handle, - (u32)1, NULL, NULL); - func->bridge = NULL; - } - - acpiphp_bus_trim(func->handle); - /* try to remove anyway. - * acpiphp_bus_add might have been failed */ - if (!func->pci_dev) continue; @@ -1212,17 +1111,16 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) return; - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - bridge->hpp.t0->cache_line_size); + bridge->hpp.cache_line_size); pci_write_config_byte(dev, PCI_LATENCY_TIMER, - bridge->hpp.t0->latency_timer); + bridge->hpp.latency_timer); pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); - if (bridge->hpp.t0->enable_serr) + if (bridge->hpp.enable_serr) pci_cmd |= PCI_COMMAND_SERR; else pci_cmd &= ~PCI_COMMAND_SERR; - if (bridge->hpp.t0->enable_perr) + if (bridge->hpp.enable_perr) pci_cmd |= PCI_COMMAND_PARITY; else pci_cmd &= ~PCI_COMMAND_PARITY; @@ -1231,13 +1129,13 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) /* Program bridge control value and child devices */ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, - bridge->hpp.t0->latency_timer); + bridge->hpp.latency_timer); pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); - if (bridge->hpp.t0->enable_serr) + if (bridge->hpp.enable_serr) pci_bctl |= PCI_BRIDGE_CTL_SERR; else pci_bctl &= ~PCI_BRIDGE_CTL_SERR; - if (bridge->hpp.t0->enable_perr) + if (bridge->hpp.enable_perr) pci_bctl |= PCI_BRIDGE_CTL_PARITY; else pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; @@ -1257,7 +1155,6 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus) memset(&bridge, 0, sizeof(bridge)); bridge.handle = handle; - bridge.pci_bus = bus; bridge.pci_dev = bus->self; decode_hpp(&bridge); list_for_each_entry(dev, &bus->devices, bus_list) @@ -1400,13 +1297,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); - if ((bridge->type != BRIDGE_TYPE_HOST) && - (bridge->flags & BRIDGE_HAS_EJ0)) { - struct acpiphp_slot *slot; - slot = bridge->func->slot; - if (!acpiphp_disable_slot(slot)) - acpiphp_eject_slot(slot); - } break; case ACPI_NOTIFY_FREQUENCY_MISMATCH: @@ -1600,15 +1490,9 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) if (retval) goto err_exit; - if (get_slot_status(slot) == ACPI_STA_ALL) { + if (get_slot_status(slot) == ACPI_STA_ALL) /* configure all functions */ retval = enable_device(slot); - if (retval) - power_off_slot(slot); - } else { - dbg("%s: Slot status is not ACPI_STA_ALL\n", __FUNCTION__); - power_off_slot(slot); - } err_exit: mutex_unlock(&slot->crit_sect); diff --git a/trunk/drivers/pci/hotplug/ibmphp_core.c b/trunk/drivers/pci/hotplug/ibmphp_core.c index 59392946c2bd..e13d5b87241a 100644 --- a/trunk/drivers/pci/hotplug/ibmphp_core.c +++ b/trunk/drivers/pci/hotplug/ibmphp_core.c @@ -285,7 +285,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { memcpy(&myslot, pslot, sizeof(struct slot)); @@ -315,7 +315,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { memcpy(&myslot, pslot, sizeof(struct slot)); @@ -342,7 +342,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { memcpy(&myslot, pslot, sizeof(struct slot)); @@ -369,7 +369,7 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { memcpy(&myslot, pslot, sizeof(struct slot)); @@ -401,7 +401,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { rc = 0; @@ -441,7 +441,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe ibmphp_lock_operations(); - if (hotplug_slot) { + if (hotplug_slot && value) { pslot = hotplug_slot->private; if (pslot) { rc = get_cur_bus_info(&pslot); diff --git a/trunk/drivers/pci/hotplug/pci_hotplug.h b/trunk/drivers/pci/hotplug/pci_hotplug.h index e929b7c11429..eb0d01d47236 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug.h +++ b/trunk/drivers/pci/hotplug/pci_hotplug.h @@ -176,51 +176,11 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info); extern struct subsystem pci_hotplug_slots_subsys; -/* PCI Setting Record (Type 0) */ -struct hpp_type0 { - u32 revision; - u8 cache_line_size; - u8 latency_timer; - u8 enable_serr; - u8 enable_perr; -}; - -/* PCI-X Setting Record (Type 1) */ -struct hpp_type1 { - u32 revision; - u8 max_mem_read; - u8 avg_max_split; - u16 tot_max_split; -}; - -/* PCI Express Setting Record (Type 2) */ -struct hpp_type2 { - u32 revision; - u32 unc_err_mask_and; - u32 unc_err_mask_or; - u32 unc_err_sever_and; - u32 unc_err_sever_or; - u32 cor_err_mask_and; - u32 cor_err_mask_or; - u32 adv_err_cap_and; - u32 adv_err_cap_or; - u16 pci_exp_devctl_and; - u16 pci_exp_devctl_or; - u16 pci_exp_lnkctl_and; - u16 pci_exp_lnkctl_or; - u32 sec_unc_err_sever_and; - u32 sec_unc_err_sever_or; - u32 sec_unc_err_mask_and; - u32 sec_unc_err_mask_or; -}; - struct hotplug_params { - struct hpp_type0 *t0; /* Type0: NULL if not available */ - struct hpp_type1 *t1; /* Type1: NULL if not available */ - struct hpp_type2 *t2; /* Type2: NULL if not available */ - struct hpp_type0 type0_data; - struct hpp_type1 type1_data; - struct hpp_type2 type2_data; + u8 cache_line_size; + u8 latency_timer; + u8 enable_serr; + u8 enable_perr; }; #ifdef CONFIG_ACPI @@ -228,7 +188,7 @@ struct hotplug_params { #include #include extern acpi_status acpi_run_oshp(acpi_handle handle); -extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, +extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp); int acpi_root_bridge(acpi_handle handle); #endif diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index ce89f5815861..92c1f0f1e1ad 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -284,7 +284,7 @@ struct hpc_ops { static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) { - if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) + if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) return -ENODEV; return 0; } diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index c67b7c3f1ddf..601cf9045b20 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -69,7 +69,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); -static int get_address (struct hotplug_slot *slot, u32 *value); static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); @@ -82,7 +81,6 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, - .get_address = get_address, .get_max_bus_speed = get_max_bus_speed, .get_cur_bus_speed = get_cur_bus_speed, }; @@ -333,18 +331,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) -{ - struct slot *slot = hotplug_slot->private; - struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; - - dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - - *value = (pci_domain_nr(bus) << 16) | (slot->bus << 8) | slot->device; - - return 0; -} - static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { struct slot *slot = hotplug_slot->private; diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index d77138ecb098..6c14d9e46b2e 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -1288,7 +1288,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) if (ACPI_SUCCESS(status)) { dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev), (char *)string.pointer); - kfree(string.pointer); + acpi_os_free(string.pointer); return 0; } if (acpi_root_bridge(handle)) @@ -1302,7 +1302,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) err("Cannot get control of hotplug hardware for pci %s\n", pci_name(dev)); - kfree(string.pointer); + acpi_os_free(string.pointer); return -1; } #endif @@ -1404,6 +1404,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); + if (pci_enable_device(pdev)) + goto abort_free_ctlr; + mutex_init(&ctrl->crit_sect); /* setup wait queue */ init_waitqueue_head(&ctrl->queue); @@ -1471,7 +1474,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); - goto abort_free_irq; + goto abort_free_ctlr; } intr_enable = intr_enable | PRSN_DETECT_ENABLE; @@ -1497,19 +1500,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); - goto abort_free_irq; + goto abort_free_ctlr; } rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); - goto abort_disable_intr; + goto abort_free_ctlr; } temp_word = 0x1F; /* Clear all events */ rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); - goto abort_disable_intr; + goto abort_free_ctlr; } if (pciehp_force) { @@ -1518,7 +1521,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) } else { rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); if (rc) - goto abort_disable_intr; + goto abort_free_ctlr; } /* Add this HPC instance into the HPC list */ @@ -1545,21 +1548,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) return 0; /* We end up here for the many possible ways to fail this API. */ -abort_disable_intr: - rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); - if (!rc) { - temp_word &= ~(intr_enable | HP_INTR_ENABLE); - rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); - } - if (rc) - err("%s : disabling interrupts failed\n", __FUNCTION__); - -abort_free_irq: - if (pciehp_poll_mode) - del_timer_sync(&php_ctlr->int_poll_timer); - else - free_irq(php_ctlr->irq, ctrl); - abort_free_ctlr: pcie_cap_base = saved_cap_base; kfree(php_ctlr); diff --git a/trunk/drivers/pci/hotplug/pciehp_pci.c b/trunk/drivers/pci/hotplug/pciehp_pci.c index 854aaea09e4d..4017fb03a0b8 100644 --- a/trunk/drivers/pci/hotplug/pciehp_pci.c +++ b/trunk/drivers/pci/hotplug/pciehp_pci.c @@ -34,144 +34,6 @@ #include "../pci.h" #include "pciehp.h" -static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) -{ - u16 pci_cmd, pci_bctl; - - if (hpp->revision > 1) { - printk(KERN_WARNING "%s: Rev.%d type0 record not supported\n", - __FUNCTION__, hpp->revision); - return; - } - - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer); - pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); - if (hpp->enable_serr) - pci_cmd |= PCI_COMMAND_SERR; - else - pci_cmd &= ~PCI_COMMAND_SERR; - if (hpp->enable_perr) - pci_cmd |= PCI_COMMAND_PARITY; - else - pci_cmd &= ~PCI_COMMAND_PARITY; - pci_write_config_word(dev, PCI_COMMAND, pci_cmd); - - /* Program bridge control value */ - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, - hpp->latency_timer); - pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); - if (hpp->enable_serr) - pci_bctl |= PCI_BRIDGE_CTL_SERR; - else - pci_bctl &= ~PCI_BRIDGE_CTL_SERR; - if (hpp->enable_perr) - pci_bctl |= PCI_BRIDGE_CTL_PARITY; - else - pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); - } -} - -static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) -{ - int pos; - u16 reg16; - u32 reg32; - - if (hpp->revision > 1) { - printk(KERN_WARNING "%s: Rev.%d type2 record not supported\n", - __FUNCTION__, hpp->revision); - return; - } - - /* Find PCI Express capability */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return; - - /* Initialize Device Control Register */ - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); - reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or; - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); - - /* Initialize Link Control Register */ - if (dev->subordinate) { - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, ®16); - reg16 = (reg16 & hpp->pci_exp_lnkctl_and) - | hpp->pci_exp_lnkctl_or; - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16); - } - - /* Find Advanced Error Reporting Enhanced Capability */ - pos = 256; - do { - pci_read_config_dword(dev, pos, ®32); - if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) - break; - } while ((pos = PCI_EXT_CAP_NEXT(reg32))); - if (!pos) - return; - - /* Initialize Uncorrectable Error Mask Register */ - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32); - reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or; - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32); - - /* Initialize Uncorrectable Error Severity Register */ - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32); - reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or; - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32); - - /* Initialize Correctable Error Mask Register */ - pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32); - reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or; - pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32); - - /* Initialize Advanced Error Capabilities and Control Register */ - pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); - reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; - pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); - - /* - * FIXME: The following two registers are not supported yet. - * - * o Secondary Uncorrectable Error Severity Register - * o Secondary Uncorrectable Error Mask Register - */ -} - -static void program_fw_provided_values(struct pci_dev *dev) -{ - struct pci_dev *cdev; - struct hotplug_params hpp; - - /* Program hpp values for this device */ - if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || - (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) - return; - - if (pciehp_get_hp_params_from_firmware(dev, &hpp)) { - printk(KERN_WARNING "%s: Could not get hotplug parameters\n", - __FUNCTION__); - return; - } - - if (hpp.t2) - program_hpp_type2(dev, hpp.t2); - if (hpp.t0) - program_hpp_type0(dev, hpp.t0); - - /* Program child devices */ - if (dev->subordinate) { - list_for_each_entry(cdev, &dev->subordinate->devices, - bus_list) - program_fw_provided_values(cdev); - } -} - static int pciehp_add_bridge(struct pci_dev *dev) { struct pci_bus *parent = dev->bus; @@ -204,11 +66,10 @@ int pciehp_configure_device(struct slot *p_slot) struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; int num, fn; - dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); + dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0)); if (dev) { err("Device %s already exists at %x:%x, cannot hot-add\n", pci_name(dev), p_slot->bus, p_slot->device); - pci_dev_put(dev); return -EINVAL; } @@ -225,15 +86,14 @@ int pciehp_configure_device(struct slot *p_slot) if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { err("Cannot hot-add display device %s\n", pci_name(dev)); - pci_dev_put(dev); continue; } if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { pciehp_add_bridge(dev); } - program_fw_provided_values(dev); - pci_dev_put(dev); + /* TBD: program firmware provided _HPP values */ + /* program_fw_provided_values(dev); */ } pci_bus_assign_resources(parent); @@ -246,20 +106,18 @@ int pciehp_unconfigure_device(struct slot *p_slot) int rc = 0; int j; u8 bctl = 0; - struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device); for (j=0; j<8 ; j++) { - struct pci_dev* temp = pci_get_slot(parent, + struct pci_dev* temp = pci_find_slot(p_slot->bus, (p_slot->device << 3) | j); if (!temp) continue; if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { err("Cannot remove display device %s\n", pci_name(temp)); - pci_dev_put(temp); continue; } if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { @@ -267,12 +125,10 @@ int pciehp_unconfigure_device(struct slot *p_slot) if (bctl & PCI_BRIDGE_CTL_VGA) { err("Cannot remove display device %s\n", pci_name(temp)); - pci_dev_put(temp); continue; } } pci_remove_bus_device(temp); - pci_dev_put(temp); } /* * Some PCI Express root ports require fixup after hot-plug operation. diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index f31d83c2c633..8cb9abde736b 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -18,13 +18,11 @@ #include #include -#include #include #include #include #include #include -#include #include #include @@ -104,7 +102,8 @@ static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path); static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) { struct pcibus_info *pcibus_info; - u16 busnum, segment, ioboard_type; + int bricktype; + int bus_num; pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus); @@ -112,14 +111,12 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) if (!(pcibus_info->pbi_valid_devices & (1 << device))) return -EPERM; - ioboard_type = sn_ioboard_to_pci_bus(pci_bus); - busnum = pcibus_info->pbi_buscommon.bs_persist_busnum; - segment = pci_domain_nr(pci_bus) & 0xf; + bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); + bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf; /* Do not allow hotplug operations on base I/O cards */ - if ((ioboard_type == L1_BRICKTYPE_IX || - ioboard_type == L1_BRICKTYPE_IA) && - (segment == 1 && busnum == 0 && device != 1)) + if ((bricktype == L1_BRICKTYPE_IX || bricktype == L1_BRICKTYPE_IA) && + (bus_num == 1 && device != 1)) return -EPERM; return 1; @@ -128,23 +125,23 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) static int sn_pci_bus_valid(struct pci_bus *pci_bus) { struct pcibus_info *pcibus_info; - u32 asic_type; - u16 ioboard_type; + int asic_type; + int bricktype; - /* Don't register slots hanging off the TIOCA bus */ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus); + + /* Don't register slots hanging off the TIOCA bus */ asic_type = pcibus_info->pbi_buscommon.bs_asic_type; if (asic_type == PCIIO_ASIC_TYPE_TIOCA) return -EPERM; /* Only register slots in I/O Bricks that support hotplug */ - ioboard_type = sn_ioboard_to_pci_bus(pci_bus); - switch (ioboard_type) { + bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); + switch (bricktype) { case L1_BRICKTYPE_IX: case L1_BRICKTYPE_PX: case L1_BRICKTYPE_IA: case L1_BRICKTYPE_PA: - case L1_BOARDTYPE_PCIX3SLOT: return 1; break; default: @@ -178,11 +175,14 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, slot->pci_bus = pci_bus; sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x", pci_domain_nr(pci_bus), - ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum), + ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf, device + 1); - - sn_generate_path(pci_bus, slot->physical_path); - + sprintf(slot->physical_path, "module_%c%c%c%c%.2d", + '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), + '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), + '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), + MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid), + MODULE_GET_BPOS(pcibus_info->pbi_moduleid)); slot->hotplug_slot = bss_hotplug_slot; list_add(&slot->hp_list, &sn_hp_list); @@ -461,12 +461,10 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, { struct slot *slot = bss_hotplug_slot->private; struct pcibus_info *pcibus_info; - u32 power; pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus); mutex_lock(&sn_hotplug_mutex); - power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num); - *value = power ? 1 : 0; + *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num); mutex_unlock(&sn_hotplug_mutex); return 0; } @@ -555,8 +553,8 @@ static int sn_pci_hotplug_init(void) int rc; int registered = 0; - if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) { - printk(KERN_ERR "%s: PROM version does not support hotplug.\n", + if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) { + printk(KERN_ERR "%s: PROM version must be greater than 4.30\n", __FUNCTION__); return -EPERM; } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index 7208b95c6ee7..5c70f43908c4 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -168,9 +168,9 @@ struct controller { * error Messages */ #define msg_initialization_err "Initialization failure, error=%d\n" -#define msg_button_on "PCI slot #%s - powering on due to button press.\n" -#define msg_button_off "PCI slot #%s - powering off due to button press.\n" -#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" +#define msg_button_on "PCI slot #%d - powering on due to button press.\n" +#define msg_button_off "PCI slot #%d - powering off due to button press.\n" +#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" /* sysfs functions for the hotplug controller info */ extern void shpchp_create_ctrl_files (struct controller *ctrl); @@ -196,7 +196,7 @@ extern void queue_pushbutton_work(void *data); static inline int get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) { - if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) + if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) return -ENODEV; return 0; } diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index a14e7de19846..3be4d492ccc2 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -491,9 +491,16 @@ static int __init shpcd_init(void) shpchp_poll_mode = 1; #endif + shpchp_wq = create_singlethread_workqueue("shpchpd"); + if (!shpchp_wq) + return -ENOMEM; + retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + if (retval) { + destroy_workqueue(shpchp_wq); + } return retval; } @@ -501,6 +508,7 @@ static void __exit shpcd_cleanup(void) { dbg("unload_shpchpd()\n"); pci_unregister_driver(&shpc_driver); + destroy_workqueue(shpchp_wq); info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } diff --git a/trunk/drivers/pci/hotplug/shpchp_ctrl.c b/trunk/drivers/pci/hotplug/shpchp_ctrl.c index c39901dbff20..4e6381481c55 100644 --- a/trunk/drivers/pci/hotplug/shpchp_ctrl.c +++ b/trunk/drivers/pci/hotplug/shpchp_ctrl.c @@ -72,7 +72,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) /* * Button pressed - See if need to TAKE ACTION!!! */ - info("Button pressed on Slot(%s)\n", p_slot->name); + info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_BUTTON_PRESS; queue_interrupt_event(p_slot, event_type); @@ -101,7 +101,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) /* * Switch opened */ - info("Latch open on Slot(%s)\n", p_slot->name); + info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_SWITCH_OPEN; if (p_slot->pwr_save && p_slot->presence_save) { event_type = INT_POWER_FAULT; @@ -111,7 +111,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) /* * Switch closed */ - info("Latch close on Slot(%s)\n", p_slot->name); + info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_SWITCH_CLOSE; } @@ -139,13 +139,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) /* * Card Present */ - info("Card present on Slot(%s)\n", p_slot->name); + info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_PRESENCE_ON; } else { /* * Not Present */ - info("Card not present on Slot(%s)\n", p_slot->name); + info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_PRESENCE_OFF; } @@ -169,14 +169,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) /* * Power fault Cleared */ - info("Power fault cleared on Slot(%s)\n", p_slot->name); + info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); p_slot->status = 0x00; event_type = INT_POWER_FAULT_CLEAR; } else { /* * Power fault */ - info("Power fault on Slot(%s)\n", p_slot->name); + info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); event_type = INT_POWER_FAULT; /* set power fault status for this board */ p_slot->status = 0xFF; @@ -496,10 +496,10 @@ static void handle_button_press_event(struct slot *p_slot) p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (getstatus) { p_slot->state = BLINKINGOFF_STATE; - info(msg_button_off, p_slot->name); + info(msg_button_off, p_slot->number); } else { p_slot->state = BLINKINGON_STATE; - info(msg_button_on, p_slot->name); + info(msg_button_on, p_slot->number); } /* blink green LED and turn off amber */ p_slot->hpc_ops->green_led_blink(p_slot); @@ -522,7 +522,7 @@ static void handle_button_press_event(struct slot *p_slot) else p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->set_attention_status(p_slot, 0); - info(msg_button_cancel, p_slot->name); + info(msg_button_cancel, p_slot->number); p_slot->state = STATIC_STATE; break; case POWEROFF_STATE: @@ -575,17 +575,17 @@ static int shpchp_enable_slot (struct slot *p_slot) mutex_lock(&p_slot->ctrl->crit_sect); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { - info("No adapter on slot(%s)\n", p_slot->name); + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { - info("Latch open on slot(%s)\n", p_slot->name); + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { - info("Already enabled on slot(%s)\n", p_slot->name); + info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } @@ -634,17 +634,17 @@ static int shpchp_disable_slot (struct slot *p_slot) rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { - info("No adapter on slot(%s)\n", p_slot->name); + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { - info("Latch open on slot(%s)\n", p_slot->name); + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || !getstatus) { - info("Already disabled slot(%s)\n", p_slot->name); + info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); goto out; } diff --git a/trunk/drivers/pci/hotplug/shpchp_hpc.c b/trunk/drivers/pci/hotplug/shpchp_hpc.c index 45facaad39bd..66123cf4deaa 100644 --- a/trunk/drivers/pci/hotplug/shpchp_hpc.c +++ b/trunk/drivers/pci/hotplug/shpchp_hpc.c @@ -90,94 +90,77 @@ #define MRLSENSOR 0x40000000 #define ATTN_BUTTON 0x80000000 -/* - * Interrupt Locator Register definitions - */ -#define CMD_INTR_PENDING (1 << 0) -#define SLOT_INTR_PENDING(i) (1 << (i + 1)) +/* Slot Status Field Definitions */ +/* Slot State */ +#define PWR_ONLY 0x0001 +#define ENABLED 0x0002 +#define DISABLED 0x0003 -/* - * Controller SERR-INT Register - */ -#define GLOBAL_INTR_MASK (1 << 0) -#define GLOBAL_SERR_MASK (1 << 1) -#define COMMAND_INTR_MASK (1 << 2) -#define ARBITER_SERR_MASK (1 << 3) -#define COMMAND_DETECTED (1 << 16) -#define ARBITER_DETECTED (1 << 17) -#define SERR_INTR_RSVDZ_MASK 0xfffc0000 +/* Power Indicator State */ +#define PWR_LED_ON 0x0004 +#define PWR_LED_BLINK 0x0008 +#define PWR_LED_OFF 0x000c -/* - * Logical Slot Register definitions - */ -#define SLOT_REG(i) (SLOT1 + (4 * i)) - -#define SLOT_STATE_SHIFT (0) -#define SLOT_STATE_MASK (3 << 0) -#define SLOT_STATE_PWRONLY (1) -#define SLOT_STATE_ENABLED (2) -#define SLOT_STATE_DISABLED (3) -#define PWR_LED_STATE_SHIFT (2) -#define PWR_LED_STATE_MASK (3 << 2) -#define ATN_LED_STATE_SHIFT (4) -#define ATN_LED_STATE_MASK (3 << 4) -#define ATN_LED_STATE_ON (1) -#define ATN_LED_STATE_BLINK (2) -#define ATN_LED_STATE_OFF (3) -#define POWER_FAULT (1 << 6) -#define ATN_BUTTON (1 << 7) -#define MRL_SENSOR (1 << 8) -#define MHZ66_CAP (1 << 9) -#define PRSNT_SHIFT (10) -#define PRSNT_MASK (3 << 10) -#define PCIX_CAP_SHIFT (12) -#define PCIX_CAP_MASK_PI1 (3 << 12) -#define PCIX_CAP_MASK_PI2 (7 << 12) -#define PRSNT_CHANGE_DETECTED (1 << 16) -#define ISO_PFAULT_DETECTED (1 << 17) -#define BUTTON_PRESS_DETECTED (1 << 18) -#define MRL_CHANGE_DETECTED (1 << 19) -#define CON_PFAULT_DETECTED (1 << 20) -#define PRSNT_CHANGE_INTR_MASK (1 << 24) -#define ISO_PFAULT_INTR_MASK (1 << 25) -#define BUTTON_PRESS_INTR_MASK (1 << 26) -#define MRL_CHANGE_INTR_MASK (1 << 27) -#define CON_PFAULT_INTR_MASK (1 << 28) -#define MRL_CHANGE_SERR_MASK (1 << 29) -#define CON_PFAULT_SERR_MASK (1 << 30) -#define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21) +/* Attention Indicator State */ +#define ATTEN_LED_ON 0x0010 +#define ATTEN_LED_BLINK 0x0020 +#define ATTEN_LED_OFF 0x0030 -/* - * SHPC Command Code definitnions - * - * Slot Operation 00h - 3Fh - * Set Bus Segment Speed/Mode A 40h - 47h - * Power-Only All Slots 48h - * Enable All Slots 49h - * Set Bus Segment Speed/Mode B (PI=2) 50h - 5Fh - * Reserved Command Codes 60h - BFh - * Vendor Specific Commands C0h - FFh - */ -#define SET_SLOT_PWR 0x01 /* Slot Operation */ -#define SET_SLOT_ENABLE 0x02 -#define SET_SLOT_DISABLE 0x03 -#define SET_PWR_ON 0x04 -#define SET_PWR_BLINK 0x08 -#define SET_PWR_OFF 0x0c -#define SET_ATTN_ON 0x10 -#define SET_ATTN_BLINK 0x20 -#define SET_ATTN_OFF 0x30 -#define SETA_PCI_33MHZ 0x40 /* Set Bus Segment Speed/Mode A */ +/* Power Fault */ +#define pwr_fault 0x0040 + +/* Attention Button */ +#define ATTEN_BUTTON 0x0080 + +/* MRL Sensor */ +#define MRL_SENSOR 0x0100 + +/* 66 MHz Capable */ +#define IS_66MHZ_CAP 0x0200 + +/* PRSNT1#/PRSNT2# */ +#define SLOT_EMP 0x0c00 + +/* PCI-X Capability */ +#define NON_PCIX 0x0000 +#define PCIX_66 0x1000 +#define PCIX_133 0x3000 +#define PCIX_266 0x4000 /* For PI = 2 only */ +#define PCIX_533 0x5000 /* For PI = 2 only */ + +/* SHPC 'write' operations/commands */ + +/* Slot operation - 0x00h to 0x3Fh */ + +#define NO_CHANGE 0x00 + +/* Slot state - Bits 0 & 1 of controller command register */ +#define SET_SLOT_PWR 0x01 +#define SET_SLOT_ENABLE 0x02 +#define SET_SLOT_DISABLE 0x03 + +/* Power indicator state - Bits 2 & 3 of controller command register*/ +#define SET_PWR_ON 0x04 +#define SET_PWR_BLINK 0x08 +#define SET_PWR_OFF 0x0C + +/* Attention indicator state - Bits 4 & 5 of controller command register*/ +#define SET_ATTN_ON 0x010 +#define SET_ATTN_BLINK 0x020 +#define SET_ATTN_OFF 0x030 + +/* Set bus speed/mode A - 0x40h to 0x47h */ +#define SETA_PCI_33MHZ 0x40 #define SETA_PCI_66MHZ 0x41 #define SETA_PCIX_66MHZ 0x42 #define SETA_PCIX_100MHZ 0x43 #define SETA_PCIX_133MHZ 0x44 -#define SETA_RESERVED1 0x45 -#define SETA_RESERVED2 0x46 -#define SETA_RESERVED3 0x47 -#define SET_PWR_ONLY_ALL 0x48 /* Power-Only All Slots */ -#define SET_ENABLE_ALL 0x49 /* Enable All Slots */ -#define SETB_PCI_33MHZ 0x50 /* Set Bus Segment Speed/Mode B */ +#define RESERV_1 0x45 +#define RESERV_2 0x46 +#define RESERV_3 0x47 + +/* Set bus speed/mode B - 0x50h to 0x5fh */ +#define SETB_PCI_33MHZ 0x50 #define SETB_PCI_66MHZ 0x51 #define SETB_PCIX_66MHZ_PM 0x52 #define SETB_PCIX_100MHZ_PM 0x53 @@ -191,115 +174,81 @@ #define SETB_PCIX_66MHZ_533 0x5b #define SETB_PCIX_100MHZ_533 0x5c #define SETB_PCIX_133MHZ_533 0x5d -#define SETB_RESERVED1 0x5e -#define SETB_RESERVED2 0x5f -/* - * SHPC controller command error code - */ + +/* Power-on all slots - 0x48h */ +#define SET_PWR_ON_ALL 0x48 + +/* Enable all slots - 0x49h */ +#define SET_ENABLE_ALL 0x49 + +/* SHPC controller command error code */ #define SWITCH_OPEN 0x1 #define INVALID_CMD 0x2 #define INVALID_SPEED_MODE 0x4 -/* - * For accessing SHPC Working Register Set via PCI Configuration Space - */ +/* For accessing SHPC Working Register Set */ #define DWORD_SELECT 0x2 #define DWORD_DATA 0x4 +#define BASE_OFFSET 0x0 /* Field Offset in Logical Slot Register - byte boundary */ #define SLOT_EVENT_LATCH 0x2 #define SLOT_SERR_INT_MASK 0x3 +static spinlock_t hpc_event_lock; + DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ static int ctlr_seq_num = 0; /* Controller sequenc # */ static spinlock_t list_lock; -static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); +static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); -static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs); -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec); +static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); static int hpc_check_cmd_status(struct controller *ctrl); -static inline u8 shpc_readb(struct controller *ctrl, int reg) -{ - return readb(ctrl->hpc_ctlr_handle->creg + reg); -} - -static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) -{ - writeb(val, ctrl->hpc_ctlr_handle->creg + reg); -} - -static inline u16 shpc_readw(struct controller *ctrl, int reg) +/* This is the interrupt polling timeout function. */ +static void int_poll_timeout(unsigned long lphp_ctlr) { - return readw(ctrl->hpc_ctlr_handle->creg + reg); -} + struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; -static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) -{ - writew(val, ctrl->hpc_ctlr_handle->creg + reg); -} + DBG_ENTER_ROUTINE -static inline u32 shpc_readl(struct controller *ctrl, int reg) -{ - return readl(ctrl->hpc_ctlr_handle->creg + reg); -} + if ( !php_ctlr ) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return; + } -static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) -{ - writel(val, ctrl->hpc_ctlr_handle->creg + reg); -} + /* Poll for interrupt events. regs == NULL => polling */ + shpc_isr( 0, (void *)php_ctlr, NULL ); -static inline int shpc_indirect_read(struct controller *ctrl, int index, - u32 *value) -{ - int rc; - u32 cap_offset = ctrl->cap_offset; - struct pci_dev *pdev = ctrl->pci_dev; + init_timer(&php_ctlr->int_poll_timer); + if (!shpchp_poll_time) + shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ - rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index); - if (rc) - return rc; - return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value); + start_int_poll_timer(php_ctlr, shpchp_poll_time); + + return; } -/* - * This is the interrupt polling timeout function. - */ -static void int_poll_timeout(unsigned long lphp_ctlr) +/* This function starts the interrupt polling timer. */ +static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) { - struct php_ctlr_state_s *php_ctlr = - (struct php_ctlr_state_s *)lphp_ctlr; - - DBG_ENTER_ROUTINE - - /* Poll for interrupt events. regs == NULL => polling */ - shpc_isr(0, php_ctlr->callback_instance_id, NULL); - - init_timer(&php_ctlr->int_poll_timer); - if (!shpchp_poll_time) - shpchp_poll_time = 2; /* default polling interval is 2 sec */ + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return; + } - start_int_poll_timer(php_ctlr, shpchp_poll_time); + if ( ( seconds <= 0 ) || ( seconds > 60 ) ) + seconds = 2; /* Clamp to sane value */ - DBG_LEAVE_ROUTINE -} + php_ctlr->int_poll_timer.function = &int_poll_timeout; + php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ + php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ; + add_timer(&php_ctlr->int_poll_timer); -/* - * This function starts the interrupt polling timer. - */ -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) -{ - /* Clamp to sane value */ - if ((sec <= 0) || (sec > 60)) - sec = 2; - - php_ctlr->int_poll_timer.function = &int_poll_timeout; - php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; - php_ctlr->int_poll_timer.expires = jiffies + sec * HZ; - add_timer(&php_ctlr->int_poll_timer); + return; } static inline int shpc_wait_cmd(struct controller *ctrl) @@ -323,7 +272,7 @@ static inline int shpc_wait_cmd(struct controller *ctrl) static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 cmd_status; int retval = 0; u16 temp_word; @@ -333,8 +282,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) mutex_lock(&slot->ctrl->cmd_lock); + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + retval = -EINVAL; + goto out; + } + for (i = 0; i < 10; i++) { - cmd_status = shpc_readw(ctrl, CMD_STATUS); + cmd_status = readw(php_ctlr->creg + CMD_STATUS); if (!(cmd_status & 0x1)) break; @@ -342,7 +297,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) msleep(100); } - cmd_status = shpc_readw(ctrl, CMD_STATUS); + cmd_status = readw(php_ctlr->creg + CMD_STATUS); if (cmd_status & 0x1) { /* After 1 sec and and the controller is still busy */ @@ -359,7 +314,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) * command. */ slot->ctrl->cmd_busy = 1; - shpc_writew(ctrl, CMD, temp_word); + writew(temp_word, php_ctlr->creg + CMD); /* * Wait for command completion. @@ -383,12 +338,18 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) static int hpc_check_cmd_status(struct controller *ctrl) { + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; u16 cmd_status; int retval = 0; DBG_ENTER_ROUTINE + + if (!ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } - cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; + cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F; switch (cmd_status >> 1) { case 0: @@ -417,27 +378,37 @@ static int hpc_check_cmd_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; - u8 state; + u16 slot_status; + u8 atten_led_state; DBG_ENTER_ROUTINE - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + slot_status = (u16) slot_reg; + atten_led_state = (slot_status & 0x0030) >> 4; - switch (state) { - case ATN_LED_STATE_ON: + switch (atten_led_state) { + case 0: + *status = 0xFF; /* Reserved */ + break; + case 1: *status = 1; /* On */ break; - case ATN_LED_STATE_BLINK: + case 2: *status = 2; /* Blink */ break; - case ATN_LED_STATE_OFF: + case 3: *status = 0; /* Off */ break; default: - *status = 0xFF; /* Reserved */ + *status = 0xFF; break; } @@ -447,44 +418,64 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) static int hpc_get_power_status(struct slot * slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; - u8 state; + u16 slot_status; + u8 slot_state; + int retval = 0; DBG_ENTER_ROUTINE - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + slot_status = (u16) slot_reg; + slot_state = (slot_status & 0x0003); - switch (state) { - case SLOT_STATE_PWRONLY: + switch (slot_state) { + case 0: + *status = 0xFF; + break; + case 1: *status = 2; /* Powered only */ break; - case SLOT_STATE_ENABLED: + case 2: *status = 1; /* Enabled */ break; - case SLOT_STATE_DISABLED: + case 3: *status = 0; /* Disabled */ break; default: - *status = 0xFF; /* Reserved */ + *status = 0xFF; break; } DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_get_latch_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; + u16 slot_status; DBG_ENTER_ROUTINE - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */ + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + slot_status = (u16)slot_reg; + + *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */ + DBG_LEAVE_ROUTINE return 0; @@ -492,15 +483,22 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) static int hpc_get_adapter_status(struct slot *slot, u8 *status) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; - u8 state; + u16 slot_status; + u8 card_state; DBG_ENTER_ROUTINE - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; - *status = (state != 0x3) ? 1 : 0; + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + slot_status = (u16)slot_reg; + card_state = (u8)((slot_status & 0x0C00) >> 10); + *status = (card_state != 0x3) ? 1 : 0; DBG_LEAVE_ROUTINE return 0; @@ -508,11 +506,16 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; DBG_ENTER_ROUTINE + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } - *prog_int = shpc_readb(ctrl, PROG_INTERFACE); + *prog_int = readb(php_ctlr->creg + PROG_INTERFACE); DBG_LEAVE_ROUTINE return 0; @@ -521,27 +524,13 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) { int retval = 0; - struct controller *ctrl = slot->ctrl; - u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - u8 m66_cap = !!(slot_reg & MHZ66_CAP); - u8 pi, pcix_cap; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot); + u8 pcix_cap = (slot_reg >> 12) & 7; + u8 m66_cap = (slot_reg >> 9) & 1; DBG_ENTER_ROUTINE - if ((retval = hpc_get_prog_int(slot, &pi))) - return retval; - - switch (pi) { - case 1: - pcix_cap = (slot_reg & PCIX_CAP_MASK_PI1) >> PCIX_CAP_SHIFT; - break; - case 2: - pcix_cap = (slot_reg & PCIX_CAP_MASK_PI2) >> PCIX_CAP_SHIFT; - break; - default: - return -ENODEV; - } - dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n", __FUNCTION__, slot_reg, pcix_cap, m66_cap); @@ -575,15 +564,20 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u16 sec_bus_status; u8 pi; int retval = 0; DBG_ENTER_ROUTINE - pi = shpc_readb(ctrl, PROG_INTERFACE); - sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + pi = readb(php_ctlr->creg + PROG_INTERFACE); + sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); if (pi == 2) { *mode = (sec_bus_status & 0x0100) >> 8; @@ -599,53 +593,128 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) static int hpc_query_power_fault(struct slot * slot) { - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u32 slot_reg; + u16 slot_status; + u8 pwr_fault_state, status; DBG_ENTER_ROUTINE - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); + slot_status = (u16) slot_reg; + pwr_fault_state = (slot_status & 0x0040) >> 7; + status = (pwr_fault_state == 1) ? 0 : 1; DBG_LEAVE_ROUTINE /* Note: Logic 0 => fault */ - return !(slot_reg & POWER_FAULT); + return status; } static int hpc_set_attention_status(struct slot *slot, u8 value) { + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 slot_cmd = 0; + int rc = 0; + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } switch (value) { case 0 : - slot_cmd = SET_ATTN_OFF; /* OFF */ + slot_cmd = 0x30; /* OFF */ break; case 1: - slot_cmd = SET_ATTN_ON; /* ON */ + slot_cmd = 0x10; /* ON */ break; case 2: - slot_cmd = SET_ATTN_BLINK; /* BLINK */ + slot_cmd = 0x20; /* BLINK */ break; default: return -1; } - return shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + + return rc; } static void hpc_set_green_led_on(struct slot *slot) { - shpc_write_cmd(slot, slot->hp_slot, SET_PWR_ON); + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + slot_cmd = 0x04; + + shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + + return; } static void hpc_set_green_led_off(struct slot *slot) { - shpc_write_cmd(slot, slot->hp_slot, SET_PWR_OFF); + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + slot_cmd = 0x0C; + + shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + + return; } static void hpc_set_green_led_blink(struct slot *slot) { - shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return ; + } + + slot_cmd = 0x08; + + shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + + return; } int shpc_get_ctlr_slot_config(struct controller *ctrl, @@ -655,17 +724,21 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl, int *updown, /* physical_slot_num increament: 1 or -1 */ int *flags) { - u32 slot_config; + struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; DBG_ENTER_ROUTINE - slot_config = shpc_readl(ctrl, SLOT_CONFIG); - *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8; - *num_ctlr_slots = slot_config & SLOT_NUM; - *physical_slot_num = (slot_config & PSN) >> 16; - *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1; + if (!ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */ + *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */ + *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16; dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); + *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1; DBG_LEAVE_ROUTINE return 0; @@ -676,33 +749,21 @@ static void hpc_release_ctlr(struct controller *ctrl) struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; struct php_ctlr_state_s *p, *p_prev; int i; - u32 slot_reg, serr_int; DBG_ENTER_ROUTINE - /* - * Mask event interrupts and SERRs of all slots - */ - for (i = 0; i < ctrl->num_slots; i++) { - slot_reg = shpc_readl(ctrl, SLOT_REG(i)); - slot_reg |= (PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK | - BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK | - CON_PFAULT_INTR_MASK | MRL_CHANGE_SERR_MASK | - CON_PFAULT_SERR_MASK); - slot_reg &= ~SLOT_REG_RSVDZ_MASK; - shpc_writel(ctrl, SLOT_REG(i), slot_reg); + if (!ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return ; } - cleanup_slots(ctrl); - /* - * Mask SERR and System Interrut generation + * Mask all slot event interrupts */ - serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); - serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK | - COMMAND_INTR_MASK | ARBITER_SERR_MASK); - serr_int &= ~SERR_INTR_RSVDZ_MASK; - shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); + for (i = 0; i < ctrl->num_slots; i++) + writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i)); + + cleanup_slots(ctrl); if (shpchp_poll_mode) { del_timer(&php_ctlr->int_poll_timer); @@ -739,79 +800,113 @@ static void hpc_release_ctlr(struct controller *ctrl) kfree(php_ctlr); - /* - * If this is the last controller to be released, destroy the - * shpchpd work queue - */ - if (atomic_dec_and_test(&shpchp_num_controllers)) - destroy_workqueue(shpchp_wq); - DBG_LEAVE_ROUTINE } static int hpc_power_on_slot(struct slot * slot) { - int retval; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + int retval = 0; DBG_ENTER_ROUTINE - retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + slot_cmd = 0x01; + + retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); - return retval; + return -1; } DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_slot_enable(struct slot * slot) { - int retval; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + int retval = 0; DBG_ENTER_ROUTINE - /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ - retval = shpc_write_cmd(slot, slot->hp_slot, - SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + /* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ + slot_cmd = 0x3A; + + retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); - return retval; + return -1; } DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_slot_disable(struct slot * slot) { - int retval; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + u8 slot_cmd; + int retval = 0; DBG_ENTER_ROUTINE - /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */ - retval = shpc_write_cmd(slot, slot->hp_slot, - SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON); + if (!slot->ctrl->hpc_ctlr_handle) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); + return -1; + } + + if (slot->hp_slot >= php_ctlr->num_slots) { + err("%s: Invalid HPC slot number!\n", __FUNCTION__); + return -1; + } + + /* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */ + slot_cmd = 0x1F; + + retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); + if (retval) { err("%s: Write command failed!\n", __FUNCTION__); - return retval; + return -1; } DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) { int retval; - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; u8 pi, cmd; DBG_ENTER_ROUTINE - pi = shpc_readb(ctrl, PROG_INTERFACE); + pi = readb(php_ctlr->creg + PROG_INTERFACE); if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) return -EINVAL; @@ -870,86 +965,100 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) return retval; } -static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) { - struct controller *ctrl = (struct controller *)dev_id; - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; - u32 serr_int, slot_reg, intr_loc, intr_loc2; + struct controller *ctrl = NULL; + struct php_ctlr_state_s *php_ctlr; + u8 schedule_flag = 0; + u8 temp_byte; + u32 temp_dword, intr_loc, intr_loc2; int hp_slot; + if (!dev_id) + return IRQ_NONE; + + if (!shpchp_poll_mode) { + ctrl = (struct controller *)dev_id; + php_ctlr = ctrl->hpc_ctlr_handle; + } else { + php_ctlr = (struct php_ctlr_state_s *) dev_id; + ctrl = (struct controller *)php_ctlr->callback_instance_id; + } + + if (!ctrl) + return IRQ_NONE; + + if (!php_ctlr || !php_ctlr->creg) + return IRQ_NONE; + /* Check to see if it was our interrupt */ - intr_loc = shpc_readl(ctrl, INTR_LOC); + intr_loc = readl(php_ctlr->creg + INTR_LOC); + if (!intr_loc) return IRQ_NONE; - dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); if(!shpchp_poll_mode) { - /* - * Mask Global Interrupt Mask - see implementation - * note on p. 139 of SHPC spec rev 1.0 - */ - serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); - serr_int |= GLOBAL_INTR_MASK; - serr_int &= ~SERR_INTR_RSVDZ_MASK; - shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); + /* Mask Global Interrupt Mask - see implementation note on p. 139 */ + /* of SHPC spec rev 1.0*/ + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + temp_dword |= 0x00000001; + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); - intr_loc2 = shpc_readl(ctrl, INTR_LOC); + intr_loc2 = readl(php_ctlr->creg + INTR_LOC); dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); } - if (intr_loc & CMD_INTR_PENDING) { + if (intr_loc & 0x0001) { /* * Command Complete Interrupt Pending * RO only - clear by writing 1 to the Command Completion * Detect bit in Controller SERR-INT register */ - serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); - serr_int &= ~SERR_INTR_RSVDZ_MASK; - shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); - + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + temp_dword &= 0xfffdffff; + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); ctrl->cmd_busy = 0; wake_up_interruptible(&ctrl->queue); } - if (!(intr_loc & ~CMD_INTR_PENDING)) + if ((intr_loc = (intr_loc >> 1)) == 0) goto out; for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { - /* To find out which slot has interrupt pending */ - if (!(intr_loc & SLOT_INTR_PENDING(hp_slot))) - continue; - - slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); - dbg("%s: Slot %x with intr, slot register = %x\n", - __FUNCTION__, hp_slot, slot_reg); - - if (slot_reg & MRL_CHANGE_DETECTED) - php_ctlr->switch_change_callback( - hp_slot, php_ctlr->callback_instance_id); - - if (slot_reg & BUTTON_PRESS_DETECTED) - php_ctlr->attention_button_callback( - hp_slot, php_ctlr->callback_instance_id); - - if (slot_reg & PRSNT_CHANGE_DETECTED) - php_ctlr->presence_change_callback( - hp_slot , php_ctlr->callback_instance_id); - - if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) - php_ctlr->power_fault_callback( - hp_slot, php_ctlr->callback_instance_id); - - /* Clear all slot events */ - slot_reg &= ~SLOT_REG_RSVDZ_MASK; - shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); + /* To find out which slot has interrupt pending */ + if ((intr_loc >> hp_slot) & 0x01) { + temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot)); + dbg("%s: Slot %x with intr, slot register = %x\n", + __FUNCTION__, hp_slot, temp_dword); + temp_byte = (temp_dword >> 16) & 0xFF; + if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08)) + schedule_flag += php_ctlr->switch_change_callback( + hp_slot, php_ctlr->callback_instance_id); + if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04)) + schedule_flag += php_ctlr->attention_button_callback( + hp_slot, php_ctlr->callback_instance_id); + if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01)) + schedule_flag += php_ctlr->presence_change_callback( + hp_slot , php_ctlr->callback_instance_id); + if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12)) + schedule_flag += php_ctlr->power_fault_callback( + hp_slot, php_ctlr->callback_instance_id); + + /* Clear all slot events */ + temp_dword = 0xe01f3fff; + writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); + + intr_loc2 = readl(php_ctlr->creg + INTR_LOC); + dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + } } out: if (!shpchp_poll_mode) { /* Unmask Global Interrupt Mask */ - serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); - serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK); - shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + temp_dword &= 0xfffffffe; + writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); } return IRQ_HANDLED; @@ -958,11 +1067,11 @@ static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs) static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) { int retval = 0; - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u8 pi = shpc_readb(ctrl, PROG_INTERFACE); - u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); - u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); + u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); + u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); + u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); DBG_ENTER_ROUTINE @@ -1005,10 +1114,10 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) { int retval = 0; - struct controller *ctrl = slot->ctrl; + struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); - u8 pi = shpc_readb(ctrl, PROG_INTERFACE); + u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG); + u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); DBG_ENTER_ROUTINE @@ -1097,14 +1206,28 @@ static struct hpc_ops shpchp_hpc_ops = { .release_ctlr = hpc_release_ctlr, }; +inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, + u32 *value) +{ + int rc; + u32 cap_offset = ctrl->cap_offset; + struct pci_dev *pdev = ctrl->pci_dev; + + rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index); + if (rc) + return rc; + return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value); +} + int shpc_init(struct controller * ctrl, struct pci_dev * pdev) { struct php_ctlr_state_s *php_ctlr, *p; void *instance_id = ctrl; int rc, num_slots = 0; u8 hp_slot; + static int first = 1; u32 shpc_base_offset; - u32 tempdword, slot_reg, slot_config; + u32 tempdword, slot_reg; u8 i; DBG_ENTER_ROUTINE @@ -1134,13 +1257,13 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) } dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); - rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); + rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset); if (rc) { err("%s: cannot read base_offset\n", __FUNCTION__); goto abort_free_ctlr; } - rc = shpc_indirect_read(ctrl, 3, &tempdword); + rc = shpc_indirect_creg_read(ctrl, 3, &tempdword); if (rc) { err("%s: cannot read slot config\n", __FUNCTION__); goto abort_free_ctlr; @@ -1149,7 +1272,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); for (i = 0; i < 9 + num_slots; i++) { - rc = shpc_indirect_read(ctrl, i, &tempdword); + rc = shpc_indirect_creg_read(ctrl, i, &tempdword); if (rc) { err("%s: cannot read creg (index = %d)\n", __FUNCTION__, i); @@ -1164,6 +1287,11 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) ctrl->mmio_size = 0x24 + 0x4 * num_slots; } + if (first) { + spin_lock_init(&hpc_event_lock); + first = 0; + } + info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); @@ -1198,39 +1326,29 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) php_ctlr->power_fault_callback = shpchp_handle_power_fault; php_ctlr->callback_instance_id = instance_id; - ctrl->hpc_ctlr_handle = php_ctlr; - ctrl->hpc_ops = &shpchp_hpc_ops; - /* Return PCI Controller Info */ - slot_config = shpc_readl(ctrl, SLOT_CONFIG); - php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; - php_ctlr->num_slots = slot_config & SLOT_NUM; + php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8; + php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM; dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ - tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); + tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); - tempdword |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK | - COMMAND_INTR_MASK | ARBITER_SERR_MASK); - tempdword &= ~SERR_INTR_RSVDZ_MASK; - shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); - tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); + tempdword = 0x0003000f; + writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); + tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); /* Mask the MRL sensor SERR Mask of individual slot in * Slot SERR-INT Mask & clear all the existing event if any */ for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { - slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); - slot_reg |= (PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK | - BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK | - CON_PFAULT_INTR_MASK | MRL_CHANGE_SERR_MASK | - CON_PFAULT_SERR_MASK); - slot_reg &= ~SLOT_REG_RSVDZ_MASK; - shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); + tempdword = 0xffff3fff; + writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); } if (shpchp_poll_mode) {/* Install interrupt polling code */ @@ -1274,37 +1392,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) } spin_unlock(&list_lock); - ctlr_seq_num++; - /* - * If this is the first controller to be initialized, - * initialize the shpchpd work queue - */ - if (atomic_add_return(1, &shpchp_num_controllers) == 1) { - shpchp_wq = create_singlethread_workqueue("shpchpd"); - if (!shpchp_wq) - return -ENOMEM; - } + ctlr_seq_num++; + ctrl->hpc_ctlr_handle = php_ctlr; + ctrl->hpc_ops = &shpchp_hpc_ops; - /* - * Unmask all event interrupts of all slots - */ for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { - slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); + slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); - slot_reg &= ~(PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK | - BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK | - CON_PFAULT_INTR_MASK | SLOT_REG_RSVDZ_MASK); - shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); + tempdword = 0xe01f3fff; + writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); } if (!shpchp_poll_mode) { /* Unmask all general input interrupts and SERR */ - tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); - tempdword &= ~(GLOBAL_INTR_MASK | COMMAND_INTR_MASK | - SERR_INTR_RSVDZ_MASK); - shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); - tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); + tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); + tempdword = 0x0000000a; + writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); + tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); } diff --git a/trunk/drivers/pci/hotplug/shpchp_pci.c b/trunk/drivers/pci/hotplug/shpchp_pci.c index 0a6b25ef194c..257adc233996 100644 --- a/trunk/drivers/pci/hotplug/shpchp_pci.c +++ b/trunk/drivers/pci/hotplug/shpchp_pci.c @@ -47,28 +47,21 @@ static void program_fw_provided_values(struct pci_dev *dev) return; /* use default values if we can't get them from firmware */ - if (get_hp_params_from_firmware(dev, &hpp) || - !hpp.t0 || (hpp.t0->revision > 1)) { - printk(KERN_WARNING - "%s: Could not get hotplug parameters. Use defaults\n", - __FUNCTION__); - hpp.t0 = &hpp.type0_data; - hpp.t0->revision = 0; - hpp.t0->cache_line_size = 8; - hpp.t0->latency_timer = 0x40; - hpp.t0->enable_serr = 0; - hpp.t0->enable_perr = 0; + if (get_hp_params_from_firmware(dev, &hpp)) { + hpp.cache_line_size = 8; + hpp.latency_timer = 0x40; + hpp.enable_serr = 0; + hpp.enable_perr = 0; } - pci_write_config_byte(dev, - PCI_CACHE_LINE_SIZE, hpp.t0->cache_line_size); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.t0->latency_timer); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); - if (hpp.t0->enable_serr) + if (hpp.enable_serr) pci_cmd |= PCI_COMMAND_SERR; else pci_cmd &= ~PCI_COMMAND_SERR; - if (hpp.t0->enable_perr) + if (hpp.enable_perr) pci_cmd |= PCI_COMMAND_PARITY; else pci_cmd &= ~PCI_COMMAND_PARITY; @@ -77,13 +70,13 @@ static void program_fw_provided_values(struct pci_dev *dev) /* Program bridge control value and child devices */ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, - hpp.t0->latency_timer); + hpp.latency_timer); pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); - if (hpp.t0->enable_serr) + if (hpp.enable_serr) pci_bctl |= PCI_BRIDGE_CTL_SERR; else pci_bctl &= ~PCI_BRIDGE_CTL_SERR; - if (hpp.t0->enable_perr) + if (hpp.enable_perr) pci_bctl |= PCI_BRIDGE_CTL_PARITY; else pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; diff --git a/trunk/drivers/pci/msi-altix.c b/trunk/drivers/pci/msi-altix.c deleted file mode 100644 index bed4183a5e39..000000000000 --- a/trunk/drivers/pci/msi-altix.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "msi.h" - -struct sn_msi_info { - u64 pci_addr; - struct sn_irq_info *sn_irq_info; -}; - -static struct sn_msi_info *sn_msi_info; - -static void -sn_msi_teardown(unsigned int vector) -{ - nasid_t nasid; - int widget; - struct pci_dev *pdev; - struct pcidev_info *sn_pdev; - struct sn_irq_info *sn_irq_info; - struct pcibus_bussoft *bussoft; - struct sn_pcibus_provider *provider; - - sn_irq_info = sn_msi_info[vector].sn_irq_info; - if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) - return; - - sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; - pdev = sn_pdev->pdi_linux_pcidev; - provider = SN_PCIDEV_BUSPROVIDER(pdev); - - (*provider->dma_unmap)(pdev, - sn_msi_info[vector].pci_addr, - PCI_DMA_FROMDEVICE); - sn_msi_info[vector].pci_addr = 0; - - bussoft = SN_PCIDEV_BUSSOFT(pdev); - nasid = NASID_GET(bussoft->bs_base); - widget = (nasid & 1) ? - TIO_SWIN_WIDGETNUM(bussoft->bs_base) : - SWIN_WIDGETNUM(bussoft->bs_base); - - sn_intr_free(nasid, widget, sn_irq_info); - sn_msi_info[vector].sn_irq_info = NULL; - - return; -} - -int -sn_msi_setup(struct pci_dev *pdev, unsigned int vector, - u32 *addr_hi, u32 *addr_lo, u32 *data) -{ - int widget; - int status; - nasid_t nasid; - u64 bus_addr; - struct sn_irq_info *sn_irq_info; - struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); - struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - - if (bussoft == NULL) - return -EINVAL; - - if (provider == NULL || provider->dma_map_consistent == NULL) - return -EINVAL; - - /* - * Set up the vector plumbing. Let the prom (via sn_intr_alloc) - * decide which cpu to direct this msi at by default. - */ - - nasid = NASID_GET(bussoft->bs_base); - widget = (nasid & 1) ? - TIO_SWIN_WIDGETNUM(bussoft->bs_base) : - SWIN_WIDGETNUM(bussoft->bs_base); - - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (! sn_irq_info) - return -ENOMEM; - - status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1); - if (status) { - kfree(sn_irq_info); - return -ENOMEM; - } - - sn_irq_info->irq_int_bit = -1; /* mark this as an MSI irq */ - sn_irq_fixup(pdev, sn_irq_info); - - /* Prom probably should fill these in, but doesn't ... */ - sn_irq_info->irq_bridge_type = bussoft->bs_asic_type; - sn_irq_info->irq_bridge = (void *)bussoft->bs_base; - - /* - * Map the xio address into bus space - */ - bus_addr = (*provider->dma_map_consistent)(pdev, - sn_irq_info->irq_xtalkaddr, - sizeof(sn_irq_info->irq_xtalkaddr), - SN_DMA_MSI|SN_DMA_ADDR_XIO); - if (! bus_addr) { - sn_intr_free(nasid, widget, sn_irq_info); - kfree(sn_irq_info); - return -ENOMEM; - } - - sn_msi_info[vector].sn_irq_info = sn_irq_info; - sn_msi_info[vector].pci_addr = bus_addr; - - *addr_hi = (u32)(bus_addr >> 32); - *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); - - /* - * In the SN platform, bit 16 is a "send vector" bit which - * must be present in order to move the vector through the system. - */ - *data = 0x100 + (unsigned int)vector; - -#ifdef CONFIG_SMP - set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0); -#endif - - return 0; -} - -static void -sn_msi_target(unsigned int vector, unsigned int cpu, - u32 *addr_hi, u32 *addr_lo) -{ - int slice; - nasid_t nasid; - u64 bus_addr; - struct pci_dev *pdev; - struct pcidev_info *sn_pdev; - struct sn_irq_info *sn_irq_info; - struct sn_irq_info *new_irq_info; - struct sn_pcibus_provider *provider; - - sn_irq_info = sn_msi_info[vector].sn_irq_info; - if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) - return; - - /* - * Release XIO resources for the old MSI PCI address - */ - - sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; - pdev = sn_pdev->pdi_linux_pcidev; - provider = SN_PCIDEV_BUSPROVIDER(pdev); - - bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo); - (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE); - sn_msi_info[vector].pci_addr = 0; - - nasid = cpuid_to_nasid(cpu); - slice = cpuid_to_slice(cpu); - - new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice); - sn_msi_info[vector].sn_irq_info = new_irq_info; - if (new_irq_info == NULL) - return; - - /* - * Map the xio address into bus space - */ - - bus_addr = (*provider->dma_map_consistent)(pdev, - new_irq_info->irq_xtalkaddr, - sizeof(new_irq_info->irq_xtalkaddr), - SN_DMA_MSI|SN_DMA_ADDR_XIO); - - sn_msi_info[vector].pci_addr = bus_addr; - *addr_hi = (u32)(bus_addr >> 32); - *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); -} - -struct msi_ops sn_msi_ops = { - .setup = sn_msi_setup, - .teardown = sn_msi_teardown, -#ifdef CONFIG_SMP - .target = sn_msi_target, -#endif -}; - -int -sn_msi_init(void) -{ - sn_msi_info = - kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL); - if (! sn_msi_info) - return -ENOMEM; - - msi_register(&sn_msi_ops); - return 0; -} diff --git a/trunk/drivers/pci/msi-apic.c b/trunk/drivers/pci/msi-apic.c deleted file mode 100644 index 5ed798b319c7..000000000000 --- a/trunk/drivers/pci/msi-apic.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * MSI hooks for standard x86 apic - */ - -#include -#include -#include - -#include "msi.h" - -/* - * Shifts for APIC-based data - */ - -#define MSI_DATA_VECTOR_SHIFT 0 -#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) - -#define MSI_DATA_DELIVERY_SHIFT 8 -#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) -#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT) - -#define MSI_DATA_LEVEL_SHIFT 14 -#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) -#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) - -#define MSI_DATA_TRIGGER_SHIFT 15 -#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) -#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) - -/* - * Shift/mask fields for APIC-based bus address - */ - -#define MSI_ADDR_HEADER 0xfee00000 - -#define MSI_ADDR_DESTID_MASK 0xfff0000f -#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT) - -#define MSI_ADDR_DESTMODE_SHIFT 2 -#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT) -#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT) - -#define MSI_ADDR_REDIRECTION_SHIFT 3 -#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) -#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) - - -static void -msi_target_apic(unsigned int vector, - unsigned int dest_cpu, - u32 *address_hi, /* in/out */ - u32 *address_lo) /* in/out */ -{ - u32 addr = *address_lo; - - addr &= MSI_ADDR_DESTID_MASK; - addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu)); - - *address_lo = addr; -} - -static int -msi_setup_apic(struct pci_dev *pdev, /* unused in generic */ - unsigned int vector, - u32 *address_hi, - u32 *address_lo, - u32 *data) -{ - unsigned long dest_phys_id; - - dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); - - *address_hi = 0; - *address_lo = MSI_ADDR_HEADER | - MSI_ADDR_DESTMODE_PHYS | - MSI_ADDR_REDIRECTION_CPU | - MSI_ADDR_DESTID_CPU(dest_phys_id); - - *data = MSI_DATA_TRIGGER_EDGE | - MSI_DATA_LEVEL_ASSERT | - MSI_DATA_DELIVERY_FIXED | - MSI_DATA_VECTOR(vector); - - return 0; -} - -static void -msi_teardown_apic(unsigned int vector) -{ - return; /* no-op */ -} - -/* - * Generic ops used on most IA archs/platforms. Set with msi_register() - */ - -struct msi_ops msi_apic_ops = { - .setup = msi_setup_apic, - .teardown = msi_teardown_apic, - .target = msi_target_apic, -}; diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 7f8429284fab..9855c4c920b8 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -23,6 +23,8 @@ #include "pci.h" #include "msi.h" +#define MSI_TARGET_CPU first_cpu(cpu_online_map) + static DEFINE_SPINLOCK(msi_lock); static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static kmem_cache_t* msi_cachep; @@ -35,17 +37,9 @@ static int nr_msix_devices; #ifndef CONFIG_X86_IO_APIC int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; +u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; #endif -static struct msi_ops *msi_ops; - -int -msi_register(struct msi_ops *ops) -{ - msi_ops = ops; - return 0; -} - static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) { memset(p, 0, NR_IRQS * sizeof(struct msi_desc)); @@ -98,7 +92,7 @@ static void msi_set_mask_bit(unsigned int vector, int flag) static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) { struct msi_desc *entry; - u32 address_hi, address_lo; + struct msg_address address; unsigned int irq = vector; unsigned int dest_cpu = first_cpu(cpu_mask); @@ -114,36 +108,28 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) if (!pos) return; - pci_read_config_dword(entry->dev, msi_upper_address_reg(pos), - &address_hi); pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), - &address_lo); - - msi_ops->target(vector, dest_cpu, &address_hi, &address_lo); - - pci_write_config_dword(entry->dev, msi_upper_address_reg(pos), - address_hi); + &address.lo_address.value); + address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; + address.lo_address.value |= (cpu_physical_id(dest_cpu) << + MSI_TARGET_CPU_SHIFT); + entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), - address_lo); + address.lo_address.value); set_native_irq_info(irq, cpu_mask); break; } case PCI_CAP_ID_MSIX: { - int offset_hi = - entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET; - int offset_lo = - entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; - - address_hi = readl(entry->mask_base + offset_hi); - address_lo = readl(entry->mask_base + offset_lo); - - msi_ops->target(vector, dest_cpu, &address_hi, &address_lo); - - writel(address_hi, entry->mask_base + offset_hi); - writel(address_lo, entry->mask_base + offset_lo); + int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; + + address.lo_address.value = readl(entry->mask_base + offset); + address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; + address.lo_address.value |= (cpu_physical_id(dest_cpu) << + MSI_TARGET_CPU_SHIFT); + entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); + writel(address.lo_address.value, entry->mask_base + offset); set_native_irq_info(irq, cpu_mask); break; } @@ -265,6 +251,30 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = { .set_affinity = set_msi_affinity }; +static void msi_data_init(struct msg_data *msi_data, + unsigned int vector) +{ + memset(msi_data, 0, sizeof(struct msg_data)); + msi_data->vector = (u8)vector; + msi_data->delivery_mode = MSI_DELIVERY_MODE; + msi_data->level = MSI_LEVEL_MODE; + msi_data->trigger = MSI_TRIGGER_MODE; +} + +static void msi_address_init(struct msg_address *msi_address) +{ + unsigned int dest_id; + unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU); + + memset(msi_address, 0, sizeof(struct msg_address)); + msi_address->hi_address = (u32)0; + dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT); + msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE; + msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE; + msi_address->lo_address.u.dest_id = dest_id; + msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT); +} + static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); static int assign_msi_vector(void) { @@ -359,29 +369,13 @@ static int msi_init(void) return status; } - status = msi_arch_init(); - if (status < 0) { - pci_msi_enable = 0; - printk(KERN_WARNING - "PCI: MSI arch init failed. MSI disabled.\n"); - return status; - } - - if (! msi_ops) { - printk(KERN_WARNING - "PCI: MSI ops not registered. MSI disabled.\n"); - status = -EINVAL; - return status; - } - - last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); status = msi_cache_init(); if (status < 0) { pci_msi_enable = 0; printk(KERN_WARNING "PCI: MSI cache init failed\n"); return status; } - + last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); if (last_alloc_vector < 0) { pci_msi_enable = 0; printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); @@ -448,11 +442,9 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type) /* Set enabled bits to single MSI & enable MSI_enable bit */ msi_enable(control, 1); pci_write_config_word(dev, msi_control_reg(pos), control); - dev->msi_enabled = 1; } else { msix_enable(control); pci_write_config_word(dev, msi_control_reg(pos), control); - dev->msix_enabled = 1; } if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { /* PCI Express Endpoint device detected */ @@ -469,11 +461,9 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) /* Set enabled bits to single MSI & enable MSI_enable bit */ msi_disable(control); pci_write_config_word(dev, msi_control_reg(pos), control); - dev->msi_enabled = 0; } else { msix_disable(control); pci_write_config_word(dev, msi_control_reg(pos), control); - dev->msix_enabled = 0; } if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { /* PCI Express Endpoint device detected */ @@ -548,6 +538,7 @@ int pci_save_msi_state(struct pci_dev *dev) pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); if (control & PCI_MSI_FLAGS_MASKBIT) pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); + disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); save_state->cap_nr = PCI_CAP_ID_MSI; pci_add_saved_cap(dev, save_state); return 0; @@ -584,8 +575,6 @@ void pci_restore_msi_state(struct pci_dev *dev) int pci_save_msix_state(struct pci_dev *dev) { int pos; - int temp; - int vector, head, tail = 0; u16 control; struct pci_cap_saved_state *save_state; @@ -593,7 +582,6 @@ int pci_save_msix_state(struct pci_dev *dev) if (pos <= 0 || dev->no_msi) return 0; - /* save the capability */ pci_read_config_word(dev, msi_control_reg(pos), &control); if (!(control & PCI_MSIX_FLAGS_ENABLE)) return 0; @@ -605,38 +593,7 @@ int pci_save_msix_state(struct pci_dev *dev) } *((u16 *)&save_state->data[0]) = control; - /* save the table */ - temp = dev->irq; - if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { - kfree(save_state); - return -EINVAL; - } - - vector = head = dev->irq; - while (head != tail) { - int j; - void __iomem *base; - struct msi_desc *entry; - - entry = msi_desc[vector]; - base = entry->mask_base; - j = entry->msi_attrib.entry_nr; - - entry->address_lo_save = - readl(base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - entry->address_hi_save = - readl(base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - entry->data_save = - readl(base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_DATA_OFFSET); - - tail = msi_desc[vector]->link.tail; - vector = tail; - } - dev->irq = temp; - + disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); save_state->cap_nr = PCI_CAP_ID_MSIX; pci_add_saved_cap(dev, save_state); return 0; @@ -649,6 +606,8 @@ void pci_restore_msix_state(struct pci_dev *dev) int vector, head, tail = 0; void __iomem *base; int j; + struct msg_address address; + struct msg_data data; struct msi_desc *entry; int temp; struct pci_cap_saved_state *save_state; @@ -674,13 +633,20 @@ void pci_restore_msix_state(struct pci_dev *dev) base = entry->mask_base; j = entry->msi_attrib.entry_nr; - writel(entry->address_lo_save, + msi_address_init(&address); + msi_data_init(&data, vector); + + address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; + address.lo_address.value |= entry->msi_attrib.current_cpu << + MSI_TARGET_CPU_SHIFT; + + writel(address.lo_address.value, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(entry->address_hi_save, + writel(address.hi_address, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(entry->data_save, + writel(*(u32*)&data, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_DATA_OFFSET); @@ -694,32 +660,30 @@ void pci_restore_msix_state(struct pci_dev *dev) } #endif -static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) +static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) { - int status; - u32 address_hi; - u32 address_lo; - u32 data; + struct msg_address address; + struct msg_data data; int pos, vector = dev->irq; u16 control; pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); - /* Configure MSI capability structure */ - status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data); - if (status < 0) - return status; - - pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo); + msi_address_init(&address); + msi_data_init(&data, vector); + entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> + MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); + pci_write_config_dword(dev, msi_lower_address_reg(pos), + address.lo_address.value); if (is_64bit_address(control)) { pci_write_config_dword(dev, - msi_upper_address_reg(pos), address_hi); + msi_upper_address_reg(pos), address.hi_address); pci_write_config_word(dev, - msi_data_reg(pos, 1), data); + msi_data_reg(pos, 1), *((u32*)&data)); } else pci_write_config_word(dev, - msi_data_reg(pos, 0), data); + msi_data_reg(pos, 0), *((u32*)&data)); if (entry->msi_attrib.maskbit) { unsigned int maskbits, temp; /* All MSIs are unmasked by default, Mask them all */ @@ -733,8 +697,6 @@ static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) msi_mask_bits_reg(pos, is_64bit_address(control)), maskbits); } - - return 0; } /** @@ -748,7 +710,6 @@ static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry) **/ static int msi_capability_init(struct pci_dev *dev) { - int status; struct msi_desc *entry; int pos, vector; u16 control; @@ -781,12 +742,7 @@ static int msi_capability_init(struct pci_dev *dev) /* Replace with MSI handler */ irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); /* Configure MSI capability structure */ - status = msi_register_init(dev, entry); - if (status != 0) { - dev->irq = entry->msi_attrib.default_vector; - kmem_cache_free(msi_cachep, entry); - return status; - } + msi_register_init(dev, entry); attach_msi_entry(entry, vector); /* Set MSI enabled bits */ @@ -809,10 +765,8 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; - u32 address_hi; - u32 address_lo; - u32 data; - int status; + struct msg_address address; + struct msg_data data; int vector, pos, i, j, nr_entries, temp = 0; unsigned long phys_addr; u32 table_offset; @@ -868,20 +822,18 @@ static int msix_capability_init(struct pci_dev *dev, /* Replace with MSI-X handler */ irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); /* Configure MSI-X capability structure */ - status = msi_ops->setup(dev, vector, - &address_hi, - &address_lo, - &data); - if (status < 0) - break; - - writel(address_lo, + msi_address_init(&address); + msi_data_init(&data, vector); + entry->msi_attrib.current_cpu = + ((address.lo_address.u.dest_id >> + MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); + writel(address.lo_address.value, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(address_hi, + writel(address.hi_address, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(data, + writel(*(u32*)&data, base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_DATA_OFFSET); attach_msi_entry(entry, vector); @@ -913,7 +865,6 @@ static int msix_capability_init(struct pci_dev *dev, **/ int pci_enable_msi(struct pci_dev* dev) { - struct pci_bus *bus; int pos, temp, status = -EINVAL; u16 control; @@ -923,9 +874,8 @@ int pci_enable_msi(struct pci_dev* dev) if (dev->no_msi) return status; - for (bus = dev->bus; bus; bus = bus->parent) - if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) - return -EINVAL; + if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) + return -EINVAL; temp = dev->irq; @@ -937,23 +887,23 @@ int pci_enable_msi(struct pci_dev* dev) if (!pos) return -EINVAL; + pci_read_config_word(dev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) + return 0; /* Already in MSI mode */ + if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { /* Lookup Sucess */ unsigned long flags; - pci_read_config_word(dev, msi_control_reg(pos), &control); - if (control & PCI_MSI_FLAGS_ENABLE) - return 0; /* Already in MSI mode */ spin_lock_irqsave(&msi_lock, flags); if (!vector_irq[dev->irq]) { msi_desc[dev->irq]->msi_attrib.state = 0; vector_irq[dev->irq] = -1; nr_released_vectors--; spin_unlock_irqrestore(&msi_lock, flags); - status = msi_register_init(dev, msi_desc[dev->irq]); - if (status == 0) - enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - return status; + msi_register_init(dev, msi_desc[dev->irq]); + enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); + return 0; } spin_unlock_irqrestore(&msi_lock, flags); dev->irq = temp; @@ -1030,8 +980,6 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) void __iomem *base; unsigned long flags; - msi_ops->teardown(vector); - spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[vector]; if (!entry || entry->dev != dev) { @@ -1060,8 +1008,33 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) entry_nr * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - if (head == vector) + if (head == vector) { + /* + * Detect last MSI-X vector to be released. + * Release the MSI-X memory-mapped table. + */ +#if 0 + int pos, nr_entries; + unsigned long phys_addr; + u32 table_offset; + u16 control; + u8 bir; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, msi_control_reg(pos), + &control); + nr_entries = multi_msix_capable(control); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; + phys_addr = pci_resource_start(dev, bir) + table_offset; +/* + * FIXME! and what did you want to do with phys_addr? + */ +#endif iounmap(base); + } } return 0; @@ -1135,7 +1108,6 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) **/ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { - struct pci_bus *bus; int status, pos, nr_entries, free_vectors; int i, j, temp; u16 control; @@ -1144,13 +1116,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) if (!pci_msi_enable || !dev || !entries) return -EINVAL; - if (dev->no_msi) - return -EINVAL; - - for (bus = dev->bus; bus; bus = bus->parent) - if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) - return -EINVAL; - status = msi_init(); if (status < 0) return status; @@ -1335,6 +1300,24 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) } msi_free_vector(dev, vector, 0); if (warning) { + /* Force to release the MSI-X memory-mapped table */ +#if 0 + unsigned long phys_addr; + u32 table_offset; + u16 control; + u8 bir; + + pci_read_config_word(dev, msi_control_reg(pos), + &control); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; + phys_addr = pci_resource_start(dev, bir) + table_offset; +/* + * FIXME! and what did you want to do with phys_addr? + */ +#endif iounmap(base); printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on all MSI-X vectors\n", diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h index 56951c39d3a3..4ac52d441e47 100644 --- a/trunk/drivers/pci/msi.h +++ b/trunk/drivers/pci/msi.h @@ -6,68 +6,6 @@ #ifndef MSI_H #define MSI_H -/* - * MSI operation vector. Used by the msi core code (drivers/pci/msi.c) - * to abstract platform-specific tasks relating to MSI address generation - * and resource management. - */ -struct msi_ops { - /** - * setup - generate an MSI bus address and data for a given vector - * @pdev: PCI device context (in) - * @vector: vector allocated by the msi core (in) - * @addr_hi: upper 32 bits of PCI bus MSI address (out) - * @addr_lo: lower 32 bits of PCI bus MSI address (out) - * @data: MSI data payload (out) - * - * Description: The setup op is used to generate a PCI bus addres and - * data which the msi core will program into the card MSI capability - * registers. The setup routine is responsible for picking an initial - * cpu to target the MSI at. The setup routine is responsible for - * examining pdev to determine the MSI capabilities of the card and - * generating a suitable address/data. The setup routine is - * responsible for allocating and tracking any system resources it - * needs to route the MSI to the cpu it picks, and for associating - * those resources with the passed in vector. - * - * Returns 0 if the MSI address/data was successfully setup. - **/ - - int (*setup) (struct pci_dev *pdev, unsigned int vector, - u32 *addr_hi, u32 *addr_lo, u32 *data); - - /** - * teardown - release resources allocated by setup - * @vector: vector context for resources (in) - * - * Description: The teardown op is used to release any resources - * that were allocated in the setup routine associated with the passed - * in vector. - **/ - - void (*teardown) (unsigned int vector); - - /** - * target - retarget an MSI at a different cpu - * @vector: vector context for resources (in) - * @cpu: new cpu to direct vector at (in) - * @addr_hi: new value of PCI bus upper 32 bits (in/out) - * @addr_lo: new value of PCI bus lower 32 bits (in/out) - * - * Description: The target op is used to redirect an MSI vector - * at a different cpu. addr_hi/addr_lo coming in are the existing - * values that the MSI core has programmed into the card. The - * target code is responsible for freeing any resources (if any) - * associated with the old address, and generating a new PCI bus - * addr_hi/addr_lo that will redirect the vector at the indicated cpu. - **/ - - void (*target) (unsigned int vector, unsigned int cpu, - u32 *addr_hi, u32 *addr_lo); -}; - -extern int msi_register(struct msi_ops *ops); - #include /* @@ -125,6 +63,67 @@ extern int pci_vector_resources(int last, int nr_released); #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) +/* + * MSI Defined Data Structures + */ +#define MSI_ADDRESS_HEADER 0xfee +#define MSI_ADDRESS_HEADER_SHIFT 12 +#define MSI_ADDRESS_HEADER_MASK 0xfff000 +#define MSI_ADDRESS_DEST_ID_MASK 0xfff0000f +#define MSI_TARGET_CPU_MASK 0xff +#define MSI_DELIVERY_MODE 0 +#define MSI_LEVEL_MODE 1 /* Edge always assert */ +#define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */ +#define MSI_PHYSICAL_MODE 0 +#define MSI_LOGICAL_MODE 1 +#define MSI_REDIRECTION_HINT_MODE 0 + +struct msg_data { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u32 vector : 8; + __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */ + __u32 reserved_1 : 3; + __u32 level : 1; /* 0: deassert | 1: assert */ + __u32 trigger : 1; /* 0: edge | 1: level */ + __u32 reserved_2 : 16; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u32 reserved_2 : 16; + __u32 trigger : 1; /* 0: edge | 1: level */ + __u32 level : 1; /* 0: deassert | 1: assert */ + __u32 reserved_1 : 3; + __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */ + __u32 vector : 8; +#else +#error "Bitfield endianness not defined! Check your byteorder.h" +#endif +} __attribute__ ((packed)); + +struct msg_address { + union { + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u32 reserved_1 : 2; + __u32 dest_mode : 1; /*0:physic | 1:logic */ + __u32 redirection_hint: 1; /*0: dedicated CPU + 1: lowest priority */ + __u32 reserved_2 : 4; + __u32 dest_id : 24; /* Destination ID */ +#elif defined(__BIG_ENDIAN_BITFIELD) + __u32 dest_id : 24; /* Destination ID */ + __u32 reserved_2 : 4; + __u32 redirection_hint: 1; /*0: dedicated CPU + 1: lowest priority */ + __u32 dest_mode : 1; /*0:physic | 1:logic */ + __u32 reserved_1 : 2; +#else +#error "Bitfield endianness not defined! Check your byteorder.h" +#endif + }u; + __u32 value; + }lo_address; + __u32 hi_address; +} __attribute__ ((packed)); + struct msi_desc { struct { __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ @@ -133,7 +132,7 @@ struct msi_desc { __u8 reserved: 1; /* reserved */ __u8 entry_nr; /* specific enabled entry */ __u8 default_vector; /* default pre-assigned vector */ - __u8 unused; /* formerly unused destination cpu*/ + __u8 current_cpu; /* current destination cpu */ }msi_attrib; struct { @@ -143,14 +142,6 @@ struct msi_desc { void __iomem *mask_base; struct pci_dev *dev; - -#ifdef CONFIG_PM - /* PM save area for MSIX address/data */ - - u32 address_hi_save; - u32 address_lo_save; - u32 data_save; -#endif }; #endif /* MSI_H */ diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index bb7456c1dbac..c2ecae5ff0c1 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -267,7 +267,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) /* ACPI bus type */ -static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) +static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) { struct pci_dev * pci_dev; acpi_integer addr; @@ -281,7 +281,7 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) return 0; } -static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) +static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle) { int num; unsigned int seg, bus; @@ -299,21 +299,21 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) return 0; } -static struct acpi_bus_type acpi_pci_bus = { +static struct acpi_bus_type pci_acpi_bus = { .bus = &pci_bus_type, - .find_device = acpi_pci_find_device, - .find_bridge = acpi_pci_find_root_bridge, + .find_device = pci_acpi_find_device, + .find_bridge = pci_acpi_find_root_bridge, }; -static int __init acpi_pci_init(void) +static int __init pci_acpi_init(void) { int ret; - ret = register_acpi_bus_type(&acpi_pci_bus); + ret = register_acpi_bus_type(&pci_acpi_bus); if (ret) return 0; platform_pci_choose_state = acpi_pci_choose_state; platform_pci_set_power_state = acpi_pci_set_power_state; return 0; } -arch_initcall(acpi_pci_init); +arch_initcall(pci_acpi_init); diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index bc405c035ce3..56ac2bc003c7 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -43,29 +43,6 @@ pci_config_attr(subsystem_vendor, "0x%04x\n"); pci_config_attr(subsystem_device, "0x%04x\n"); pci_config_attr(class, "0x%06x\n"); pci_config_attr(irq, "%u\n"); -pci_config_attr(is_enabled, "%u\n"); - -static ssize_t broken_parity_status_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - return sprintf (buf, "%u\n", pdev->broken_parity_status); -} - -static ssize_t broken_parity_status_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - ssize_t consumed = -EINVAL; - - if ((count > 0) && (*buf == '0' || *buf == '1')) { - pdev->broken_parity_status = *buf == '1' ? 1 : 0; - consumed = count; - } - return consumed; -} static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -113,25 +90,6 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), (u8)(pci_dev->class)); } -static ssize_t -is_enabled_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - /* this can crash the machine when done on the "wrong" device */ - if (!capable(CAP_SYS_ADMIN)) - return count; - - if (*buf == '0') - pci_disable_device(pdev); - - if (*buf == '1') - pci_enable_device(pdev); - - return count; -} - struct device_attribute pci_dev_attrs[] = { __ATTR_RO(resource), @@ -143,9 +101,6 @@ struct device_attribute pci_dev_attrs[] = { __ATTR_RO(irq), __ATTR_RO(local_cpus), __ATTR_RO(modalias), - __ATTR(enable, 0600, is_enabled_show, is_enabled_store), - __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), - broken_parity_status_show,broken_parity_status_store), __ATTR_NULL, }; diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 23d3b17c8cad..fde41cc14734 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -369,7 +369,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) /* * Give firmware a chance to be called, such as ACPI _PRx, _PSx - * Firmware method after native method ? + * Firmware method after natice method ? */ if (platform_pci_set_power_state) platform_pci_set_power_state(dev, state); @@ -517,12 +517,7 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) int pci_enable_device(struct pci_dev *dev) { - int err; - - if (dev->is_enabled) - return 0; - - err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); + int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); if (err) return err; pci_fixup_device(pci_fixup_enable, dev); @@ -551,14 +546,7 @@ void pci_disable_device(struct pci_dev *dev) { u16 pci_command; - - if (dev->msi_enabled) - disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), - PCI_CAP_ID_MSI); - if (dev->msix_enabled) - disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), - PCI_CAP_ID_MSIX); - + pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { pci_command &= ~PCI_COMMAND_MASTER; diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 29bdeca031a8..30630cbe2fe3 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -40,7 +40,7 @@ extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int extern void pci_remove_legacy_files(struct pci_bus *bus); /* Lock for read/write access to pci device and bus lists */ -extern struct rw_semaphore pci_bus_sem; +extern spinlock_t pci_bus_lock; #ifdef CONFIG_X86_IO_APIC extern int pci_msi_quirk; diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index f89dbc3738b7..a10ed9dab2c2 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -180,31 +180,25 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) res->flags |= pci_calc_resource_flags(l); if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { - u32 szhi, lhi; - pci_read_config_dword(dev, reg+4, &lhi); - pci_write_config_dword(dev, reg+4, ~0); - pci_read_config_dword(dev, reg+4, &szhi); - pci_write_config_dword(dev, reg+4, lhi); - szhi = pci_size(lhi, szhi, 0xffffffff); + pci_read_config_dword(dev, reg+4, &l); next++; #if BITS_PER_LONG == 64 - res->start |= ((unsigned long) lhi) << 32; + res->start |= ((unsigned long) l) << 32; res->end = res->start + sz; - if (szhi) { + pci_write_config_dword(dev, reg+4, ~0); + pci_read_config_dword(dev, reg+4, &sz); + pci_write_config_dword(dev, reg+4, l); + sz = pci_size(l, sz, 0xffffffff); + if (sz) { /* This BAR needs > 4GB? Wow. */ - res->end |= (unsigned long)szhi<<32; + res->end |= (unsigned long)sz<<32; } #else - if (szhi) { - printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev)); + if (l) { + printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); res->start = 0; res->flags = 0; - } else if (lhi) { - /* 64-bit wide address, treat as disabled */ - pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); - pci_write_config_dword(dev, reg+4, 0); - res->start = 0; - res->end = sz; + continue; } #endif } @@ -383,9 +377,9 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de child = pci_alloc_child_bus(parent, dev, busnr); if (child) { - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_add_tail(&child->node, &parent->children); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); } return child; } @@ -844,9 +838,9 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) * and the bus list for fixup functions, etc. */ INIT_LIST_HEAD(&dev->global_list); - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_add_tail(&dev->bus_list, &bus->devices); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); } struct pci_dev * __devinit @@ -981,10 +975,9 @@ struct pci_bus * __devinit pci_create_bus(struct device *parent, pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); goto err_out; } - - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_add_tail(&b->node, &pci_root_buses); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); memset(dev, 0, sizeof(*dev)); dev->parent = parent; @@ -1024,9 +1017,9 @@ struct pci_bus * __devinit pci_create_bus(struct device *parent, class_dev_reg_err: device_unregister(dev); dev_reg_err: - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_del(&b->node); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); err_out: kfree(dev); kfree(b); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 4364d793f73b..d378478612fb 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -24,17 +24,6 @@ #include #include "pci.h" -/* The Mellanox Tavor device gives false positive parity errors - * Mark this device with a broken_parity_status, to allow - * PCI scanning code to "skip" this now blacklisted device. - */ -static void __devinit quirk_mellanox_tavor(struct pci_dev *dev) -{ - dev->broken_parity_status = 1; /* This device gives false positives */ -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor); - /* Deal with broken BIOS'es that neglect to enable passive release, which can cause problems in combination with the 82441FX/PPro MTRRs */ static void __devinit quirk_passive_release(struct pci_dev *dev) @@ -889,30 +878,27 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e * when a PCI-Soundcard is added. The BIOS only gives Options * "Disabled" and "AUTO". This Quirk Sets the corresponding * Register-Value to enable the Soundcard. - * - * FIXME: Presently this quirk will run on anything that has an 8237 - * which isn't correct, we need to check DMI tables or something in - * order to make sure it only runs on the MSI-K8T-Neo2Fir. Because it - * runs everywhere at present we suppress the printk output in most - * irrelevant cases. */ static void __init k8t_sound_hostbridge(struct pci_dev *dev) { unsigned char val; + printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n"); pci_read_config_byte(dev, 0x50, &val); if (val == 0x88 || val == 0xc8) { - /* Assume it's probably a MSI-K8T-Neo2Fir */ - printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); pci_write_config_byte(dev, 0x50, val & (~0x40)); /* Verify the Change for Status output */ pci_read_config_byte(dev, 0x50, &val); if (val & 0x40) - printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard still off\n"); + printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n"); else - printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard on\n"); + printk(KERN_INFO "PCI: MSI-K8T soundcard on\n"); + } else { + printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: " + "no Change!\n"); } + } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); @@ -1499,25 +1485,6 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); -/* Under some circumstances, AER is not linked with extended capabilities. - * Force it to be linked by setting the corresponding control bit in the - * config space. - */ -static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) -{ - uint8_t b; - if (pci_read_config_byte(dev, 0xf41, &b) == 0) { - if (!(b & 0x20)) { - pci_write_config_byte(dev, 0xf41, b | 0x20); - printk(KERN_INFO - "PCI: Linking AER extended capability on %s\n", - pci_name(dev)); - } - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, - quirk_nvidia_ck804_pcie_aer_ext_cap); - EXPORT_SYMBOL(pcie_mch_quirk); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_fixup_device); diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c index 99ffbd478b29..1a6bf9de166f 100644 --- a/trunk/drivers/pci/remove.c +++ b/trunk/drivers/pci/remove.c @@ -22,18 +22,18 @@ static void pci_destroy_dev(struct pci_dev *dev) pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); device_unregister(&dev->dev); - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_del(&dev->global_list); dev->global_list.next = dev->global_list.prev = NULL; - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); } /* Remove the device from the device lists, and prevent any further * list accesses from this device */ - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_del(&dev->bus_list); dev->bus_list.next = dev->bus_list.prev = NULL; - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); pci_free_resources(dev); pci_dev_put(dev); @@ -62,9 +62,9 @@ void pci_remove_bus(struct pci_bus *pci_bus) { pci_proc_detach_bus(pci_bus); - down_write(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_del(&pci_bus->node); - up_write(&pci_bus_sem); + spin_unlock(&pci_bus_lock); pci_remove_legacy_files(pci_bus); class_device_remove_file(&pci_bus->class_dev, &class_device_attr_cpuaffinity); diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index 622b3f8ba820..ce7dd6e7be60 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -13,7 +13,7 @@ #include #include "pci.h" -DECLARE_RWSEM(pci_bus_sem); +DEFINE_SPINLOCK(pci_bus_lock); static struct pci_bus * __devinit pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) @@ -72,11 +72,11 @@ pci_find_next_bus(const struct pci_bus *from) struct pci_bus *b = NULL; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); n = from ? from->node.next : pci_root_buses.next; if (n != &pci_root_buses) b = pci_bus_b(n); - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); return b; } @@ -124,7 +124,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) struct pci_dev *dev; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); list_for_each(tmp, &bus->devices) { dev = pci_dev_b(tmp); @@ -135,7 +135,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) dev = NULL; out: pci_dev_get(dev); - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); return dev; } @@ -167,7 +167,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor, struct pci_dev *dev; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); n = from ? from->global_list.next : pci_devices.next; while (n && (n != &pci_devices)) { @@ -181,7 +181,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor, } dev = NULL; exit: - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); return dev; } @@ -232,7 +232,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device, struct pci_dev *dev; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); n = from ? from->global_list.next : pci_devices.next; while (n && (n != &pci_devices)) { @@ -247,7 +247,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device, dev = NULL; exit: dev = pci_dev_get(dev); - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); pci_dev_put(from); return dev; } @@ -292,7 +292,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p struct pci_dev *dev; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); n = from ? from->global_list.prev : pci_devices.prev; while (n && (n != &pci_devices)) { @@ -304,7 +304,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p } dev = NULL; exit: - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); return dev; } @@ -328,7 +328,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) struct pci_dev *dev; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); n = from ? from->global_list.next : pci_devices.next; while (n && (n != &pci_devices)) { @@ -340,7 +340,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) dev = NULL; exit: dev = pci_dev_get(dev); - up_read(&pci_bus_sem); + spin_unlock(&pci_bus_lock); pci_dev_put(from); return dev; } @@ -362,7 +362,7 @@ int pci_dev_present(const struct pci_device_id *ids) int found = 0; WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); + spin_lock(&pci_bus_lock); while (ids->vendor || ids->subvendor || ids->class_mask) { list_for_each_entry(dev, &pci_devices, global_list) { if (pci_match_one_device(ids, dev)) { @@ -372,8 +372,8 @@ int pci_dev_present(const struct pci_device_id *ids) } ids++; } -exit: - up_read(&pci_bus_sem); +exit: + spin_unlock(&pci_bus_lock); return found; } EXPORT_SYMBOL(pci_dev_present); diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 35086e80faa9..28ce3a7ee434 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -55,10 +55,9 @@ pbus_assign_resources_sorted(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { u16 class = dev->class >> 8; - /* Don't touch classless devices or host bridges or ioapics. */ + /* Don't touch classless devices and host bridges. */ if (class == PCI_CLASS_NOT_DEFINED || - class == PCI_CLASS_BRIDGE_HOST || - class == PCI_CLASS_SYSTEM_PIC) + class == PCI_CLASS_BRIDGE_HOST) continue; pdev_sort_resources(dev, &head); diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 577f4b55c46d..ea9277b7f899 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -155,46 +155,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) return ret; } -#ifdef CONFIG_EMBEDDED -int pci_assign_resource_fixed(struct pci_dev *dev, int resno) -{ - struct pci_bus *bus = dev->bus; - struct resource *res = dev->resource + resno; - unsigned int type_mask; - int i, ret = -EBUSY; - - type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; - if (!r) - continue; - - /* type_mask must match */ - if ((res->flags ^ r->flags) & type_mask) - continue; - - ret = request_resource(r, res); - - if (ret == 0) - break; - } - - if (ret) { - printk(KERN_ERR "PCI: Failed to allocate %s resource " - "#%d:%llx@%llx for %s\n", - res->flags & IORESOURCE_IO ? "I/O" : "mem", - resno, (unsigned long long)(res->end - res->start + 1), - (unsigned long long)res->start, pci_name(dev)); - } else if (resno < PCI_BRIDGE_RESOURCES) { - pci_update_resource(dev, res, resno); - } - - return ret; -} -EXPORT_SYMBOL_GPL(pci_assign_resource_fixed); -#endif - /* Sort resources by alignment */ void __devinit pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index d0f68ab8f041..0e07d9535116 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -157,7 +157,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int pcmcia_schlvl = PCMCIA_SCHLVL; -static DEFINE_SPINLOCK(events_lock); +static spinlock_t events_lock = SPIN_LOCK_UNLOCKED; #define PCMCIA_SOCKET_KEY_5V 1 @@ -644,7 +644,7 @@ static struct platform_device m8xx_device = { }; static u32 pending_events[PCMCIA_SOCKETS_NO]; -static DEFINE_SPINLOCK(pending_event_lock); +static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED; static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) { diff --git a/trunk/drivers/pnp/card.c b/trunk/drivers/pnp/card.c index 0b4adcb60df4..bb19c64073c6 100644 --- a/trunk/drivers/pnp/card.c +++ b/trunk/drivers/pnp/card.c @@ -60,34 +60,30 @@ static void card_remove_first(struct pnp_dev * dev) card_remove(dev); } -static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv) +static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv) { - const struct pnp_card_device_id *id; - struct pnp_card_link *clink; - struct pnp_dev *dev; - - if (!drv->probe) - return 0; - id = match_card(drv,card); - if (!id) - return 0; - - clink = pnp_alloc(sizeof(*clink)); - if (!clink) - return 0; - clink->card = card; - clink->driver = drv; - clink->pm_state = PMSG_ON; - - if (drv->probe(clink, id) >= 0) - return 1; - - /* Recovery */ - card_for_each_dev(card, dev) { - if (dev->card_link == clink) - pnp_release_card_device(dev); + const struct pnp_card_device_id *id = match_card(drv,card); + if (id) { + struct pnp_card_link * clink = pnp_alloc(sizeof(struct pnp_card_link)); + if (!clink) + return 0; + clink->card = card; + clink->driver = drv; + clink->pm_state = PMSG_ON; + if (drv->probe) { + if (drv->probe(clink, id)>=0) + return 1; + else { + struct pnp_dev * dev; + card_for_each_dev(card, dev) { + if (dev->card_link == clink) + pnp_release_card_device(dev); + } + kfree(clink); + } + } else + return 1; } - kfree(clink); return 0; } diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index 3a4a644c2686..407b4eaddcbf 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -36,13 +36,13 @@ static int irq_flags(int triggering, int polarity) { int flag; if (triggering == ACPI_LEVEL_SENSITIVE) { - if (polarity == ACPI_ACTIVE_LOW) + if(polarity == ACPI_ACTIVE_LOW) flag = IORESOURCE_IRQ_LOWLEVEL; else flag = IORESOURCE_IRQ_HIGHLEVEL; } else { - if (polarity == ACPI_ACTIVE_LOW) + if(polarity == ACPI_ACTIVE_LOW) flag = IORESOURCE_IRQ_LOWEDGE; else flag = IORESOURCE_IRQ_HIGHEDGE; @@ -57,7 +57,7 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) *triggering = ACPI_LEVEL_SENSITIVE; *polarity = ACPI_ACTIVE_LOW; break; - case IORESOURCE_IRQ_HIGHLEVEL: + case IORESOURCE_IRQ_HIGHLEVEL: *triggering = ACPI_LEVEL_SENSITIVE; *polarity = ACPI_ACTIVE_HIGH; break; @@ -73,7 +73,7 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) } static void -pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, +pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi, int triggering, int polarity) { int i = 0; @@ -101,7 +101,7 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, } static void -pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma) +pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, u32 dma) { int i = 0; while (i < PNP_MAX_DMA && @@ -119,8 +119,8 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma) } static void -pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, - u64 io, u64 len) +pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res, + u32 io, u32 len) { int i = 0; while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && @@ -138,7 +138,7 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, } static void -pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, +pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res, u64 mem, u64 len) { int i = 0; @@ -156,32 +156,11 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, } } -static void -pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, - struct acpi_resource *res) -{ - struct acpi_resource_address64 addr, *p = &addr; - acpi_status status; - - status = acpi_resource_to_address64(res, p); - if (!ACPI_SUCCESS(status)) { - pnp_warn("PnPACPI: failed to convert resource type %d", - res->type); - return; - } - - if (p->resource_type == ACPI_MEMORY_RANGE) - pnpacpi_parse_allocated_memresource(res_table, - p->minimum, p->address_length); - else if (p->resource_type == ACPI_IO_RANGE) - pnpacpi_parse_allocated_ioresource(res_table, - p->minimum, p->address_length); -} static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { - struct pnp_resource_table *res_table = (struct pnp_resource_table *)data; + struct pnp_resource_table * res_table = (struct pnp_resource_table *)data; int i; switch (res->type) { @@ -242,9 +221,19 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, res->data.fixed_memory32.address_length); break; case ACPI_RESOURCE_TYPE_ADDRESS16: + pnpacpi_parse_allocated_memresource(res_table, + res->data.address16.minimum, + res->data.address16.address_length); + break; case ACPI_RESOURCE_TYPE_ADDRESS32: + pnpacpi_parse_allocated_memresource(res_table, + res->data.address32.minimum, + res->data.address32.address_length); + break; case ACPI_RESOURCE_TYPE_ADDRESS64: - pnpacpi_parse_allocated_address_space(res_table, res); + pnpacpi_parse_allocated_memresource(res_table, + res->data.address64.minimum, + res->data.address64.address_length); break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: @@ -266,11 +255,11 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; } - + return AE_OK; } -acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, struct pnp_resource_table *res) +acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, struct pnp_resource_table * res) { /* Blank the resource table values */ pnp_init_resource_table(res); @@ -328,17 +317,17 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso pnp_err("Invalid DMA transfer type"); } - pnp_register_dma_resource(option, dma); + pnp_register_dma_resource(option,dma); return; } - + static void pnpacpi_parse_irq_option(struct pnp_option *option, struct acpi_resource_irq *p) { int i; - struct pnp_irq *irq; - + struct pnp_irq * irq; + if (p->interrupt_count == 0) return; irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL); @@ -358,7 +347,7 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, struct acpi_resource_extended_irq *p) { int i; - struct pnp_irq *irq; + struct pnp_irq * irq; if (p->interrupt_count == 0) return; @@ -379,7 +368,7 @@ static void pnpacpi_parse_port_option(struct pnp_option *option, struct acpi_resource_io *io) { - struct pnp_port *port; + struct pnp_port * port; if (io->address_length == 0) return; @@ -392,7 +381,7 @@ pnpacpi_parse_port_option(struct pnp_option *option, port->size = io->address_length; port->flags = ACPI_DECODE_16 == io->io_decode ? PNP_PORT_FLAG_16BITADDR : 0; - pnp_register_port_resource(option, port); + pnp_register_port_resource(option,port); return; } @@ -400,7 +389,7 @@ static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, struct acpi_resource_fixed_io *io) { - struct pnp_port *port; + struct pnp_port * port; if (io->address_length == 0) return; @@ -411,7 +400,7 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option, port->size = io->address_length; port->align = 0; port->flags = PNP_PORT_FLAG_FIXED; - pnp_register_port_resource(option, port); + pnp_register_port_resource(option,port); return; } @@ -419,7 +408,7 @@ static void pnpacpi_parse_mem24_option(struct pnp_option *option, struct acpi_resource_memory24 *p) { - struct pnp_mem *mem; + struct pnp_mem * mem; if (p->address_length == 0) return; @@ -434,7 +423,7 @@ pnpacpi_parse_mem24_option(struct pnp_option *option, mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; - pnp_register_mem_resource(option, mem); + pnp_register_mem_resource(option,mem); return; } @@ -442,7 +431,7 @@ static void pnpacpi_parse_mem32_option(struct pnp_option *option, struct acpi_resource_memory32 *p) { - struct pnp_mem *mem; + struct pnp_mem * mem; if (p->address_length == 0) return; @@ -457,7 +446,7 @@ pnpacpi_parse_mem32_option(struct pnp_option *option, mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; - pnp_register_mem_resource(option, mem); + pnp_register_mem_resource(option,mem); return; } @@ -465,7 +454,7 @@ static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, struct acpi_resource_fixed_memory32 *p) { - struct pnp_mem *mem; + struct pnp_mem * mem; if (p->address_length == 0) return; @@ -479,7 +468,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? IORESOURCE_MEM_WRITEABLE : 0; - pnp_register_mem_resource(option, mem); + pnp_register_mem_resource(option,mem); return; } @@ -488,8 +477,8 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) { struct acpi_resource_address64 addr, *p = &addr; acpi_status status; - struct pnp_mem *mem; - struct pnp_port *port; + struct pnp_mem * mem; + struct pnp_port * port; status = acpi_resource_to_address64(r, p); if (!ACPI_SUCCESS(status)) { @@ -509,7 +498,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) mem->align = 0; mem->flags = (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0; - pnp_register_mem_resource(option, mem); + pnp_register_mem_resource(option,mem); } else if (p->resource_type == ACPI_IO_RANGE) { port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); if (!port) @@ -518,7 +507,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) port->size = p->address_length; port->align = 0; port->flags = PNP_PORT_FLAG_FIXED; - pnp_register_port_resource(option, port); + pnp_register_port_resource(option,port); } } @@ -542,7 +531,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_DMA: - pnpacpi_parse_dma_option(option, &res->data.dma); + pnpacpi_parse_dma_option(option, &res->data.dma); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: @@ -550,7 +539,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, case ACPI_GOOD_CONFIGURATION: priority = PNP_RES_PRIORITY_PREFERRED; break; - + case ACPI_ACCEPTABLE_CONFIGURATION: priority = PNP_RES_PRIORITY_ACCEPTABLE; break; @@ -566,7 +555,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, option = pnp_register_dependent_option(dev, priority); if (!option) return AE_ERROR; - parse_data->option = option; + parse_data->option = option; break; case ACPI_RESOURCE_TYPE_END_DEPENDENT: @@ -626,7 +615,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, pnp_warn("PnPACPI: unknown resource type %d", res->type); return AE_ERROR; } - + return AE_OK; } @@ -647,8 +636,13 @@ acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, return status; } -static int pnpacpi_supported_resource(struct acpi_resource *res) +/* + * Set resource + */ +static acpi_status pnpacpi_count_resources(struct acpi_resource *res, + void *data) { + int *res_cnt = (int *)data; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: case ACPI_RESOURCE_TYPE_DMA: @@ -661,32 +655,43 @@ static int pnpacpi_supported_resource(struct acpi_resource *res) case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - return 1; + (*res_cnt) ++; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: + default: + return AE_OK; } - return 0; -} - -/* - * Set resource - */ -static acpi_status pnpacpi_count_resources(struct acpi_resource *res, - void *data) -{ - int *res_cnt = (int *)data; - - if (pnpacpi_supported_resource(res)) - (*res_cnt)++; return AE_OK; } -static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) +static acpi_status pnpacpi_type_resources(struct acpi_resource *res, + void *data) { - struct acpi_resource **resource = (struct acpi_resource **)data; - - if (pnpacpi_supported_resource(res)) { + struct acpi_resource **resource = (struct acpi_resource **)data; + switch (res->type) { + case ACPI_RESOURCE_TYPE_IRQ: + case ACPI_RESOURCE_TYPE_DMA: + case ACPI_RESOURCE_TYPE_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: + case ACPI_RESOURCE_TYPE_MEMORY24: + case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: (*resource)->type = res->type; - (*resource)->length = sizeof(struct acpi_resource); (*resource)++; + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + case ACPI_RESOURCE_TYPE_VENDOR: + case ACPI_RESOURCE_TYPE_END_TAG: + case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: + default: + return AE_OK; } return AE_OK; @@ -730,8 +735,11 @@ static void pnpacpi_encode_irq(struct acpi_resource *resource, struct resource *p) { int triggering, polarity; - - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, + &polarity); + resource->type = ACPI_RESOURCE_TYPE_IRQ; + resource->length = sizeof(struct acpi_resource); resource->data.irq.triggering = triggering; resource->data.irq.polarity = polarity; if (triggering == ACPI_EDGE_SENSITIVE) @@ -746,8 +754,11 @@ static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, struct resource *p) { int triggering, polarity; - - decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); + + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, + &polarity); + resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ; + resource->length = sizeof(struct acpi_resource); resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; resource->data.extended_irq.triggering = triggering; resource->data.extended_irq.polarity = polarity; @@ -762,6 +773,8 @@ static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, static void pnpacpi_encode_dma(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_DMA; + resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ if (p->flags & IORESOURCE_DMA_COMPATIBLE) resource->data.dma.type = ACPI_COMPATIBILITY; @@ -785,6 +798,8 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, static void pnpacpi_encode_io(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_IO; + resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR)? ACPI_DECODE_16 : ACPI_DECODE_10; @@ -797,6 +812,8 @@ static void pnpacpi_encode_io(struct acpi_resource *resource, static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_FIXED_IO; + resource->length = sizeof(struct acpi_resource); resource->data.fixed_io.address = p->start; resource->data.fixed_io.address_length = p->end - p->start + 1; } @@ -804,6 +821,8 @@ static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, static void pnpacpi_encode_mem24(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_MEMORY24; + resource->length = sizeof(struct acpi_resource); /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ resource->data.memory24.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? @@ -817,6 +836,8 @@ static void pnpacpi_encode_mem24(struct acpi_resource *resource, static void pnpacpi_encode_mem32(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_MEMORY32; + resource->length = sizeof(struct acpi_resource); resource->data.memory32.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; @@ -829,6 +850,8 @@ static void pnpacpi_encode_mem32(struct acpi_resource *resource, static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, struct resource *p) { + resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32; + resource->length = sizeof(struct acpi_resource); resource->data.fixed_memory32.write_protect = (p->flags & IORESOURCE_MEM_WRITEABLE) ? ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; @@ -859,37 +882,37 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, pnp_dbg("Encode dma"); pnpacpi_encode_dma(resource, &res_table->dma_resource[dma]); - dma++; + dma ++; break; case ACPI_RESOURCE_TYPE_IO: pnp_dbg("Encode io"); pnpacpi_encode_io(resource, &res_table->port_resource[port]); - port++; + port ++; break; case ACPI_RESOURCE_TYPE_FIXED_IO: pnp_dbg("Encode fixed io"); pnpacpi_encode_fixed_io(resource, &res_table->port_resource[port]); - port++; + port ++; break; case ACPI_RESOURCE_TYPE_MEMORY24: pnp_dbg("Encode mem24"); pnpacpi_encode_mem24(resource, &res_table->mem_resource[mem]); - mem++; + mem ++; break; case ACPI_RESOURCE_TYPE_MEMORY32: pnp_dbg("Encode mem32"); pnpacpi_encode_mem32(resource, &res_table->mem_resource[mem]); - mem++; + mem ++; break; case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: pnp_dbg("Encode fixed mem32"); pnpacpi_encode_fixed_mem32(resource, &res_table->mem_resource[mem]); - mem++; + mem ++; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: pnp_dbg("Encode ext irq"); @@ -910,8 +933,8 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, pnp_warn("unknown resource type %d", resource->type); return -EINVAL; } - resource++; - i++; + resource ++; + i ++; } return 0; } diff --git a/trunk/drivers/rapidio/rio-access.c b/trunk/drivers/rapidio/rio-access.c index 8b56bbdd011e..b9fab2ae3a36 100644 --- a/trunk/drivers/rapidio/rio-access.c +++ b/trunk/drivers/rapidio/rio-access.c @@ -17,8 +17,8 @@ * These interrupt-safe spinlocks protect all accesses to RIO * configuration space and doorbell access. */ -static DEFINE_SPINLOCK(rio_config_lock); -static DEFINE_SPINLOCK(rio_doorbell_lock); +static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED; /* * Wrappers for all RIO configuration access functions. They just check diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index bccff400b198..65d090dbef46 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -73,13 +73,6 @@ config RTC_INTF_DEV This driver can also be built as a module. If so, the module will be called rtc-dev. -config RTC_INTF_DEV_UIE_EMUL - bool "RTC UIE emulation on dev interface" - depends on RTC_INTF_DEV - help - Provides an emulation for RTC_UIE if the underlaying rtc chip - driver did not provide RTC_UIE ioctls. - comment "RTC drivers" depends on RTC_CLASS @@ -93,34 +86,6 @@ config RTC_DRV_X1205 This driver can also be built as a module. If so, the module will be called rtc-x1205. -config RTC_DRV_DS1307 - tristate "Dallas/Maxim DS1307 and similar I2C RTC chips" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for various compatible RTC - chips (often with battery backup) connected with I2C. This driver - should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, - and probably other chips. In some cases the RTC must already - have been initialized (by manufacturing or a bootloader). - - The first seven registers on these chips hold an RTC, and other - registers may add features such as NVRAM, a trickle charger for - the RTC/NVRAM backup power, and alarms. This driver may not - expose all those available chip features. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1307. - -config RTC_DRV_DS1553 - tristate "Dallas DS1553" - depends on RTC_CLASS - help - If you say yes here you get support for the - Dallas DS1553 timekeeping chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1553. - config RTC_DRV_DS1672 tristate "Dallas/Maxim DS1672" depends on RTC_CLASS && I2C @@ -131,16 +96,6 @@ config RTC_DRV_DS1672 This driver can also be built as a module. If so, the module will be called rtc-ds1672. -config RTC_DRV_DS1742 - tristate "Dallas DS1742" - depends on RTC_CLASS - help - If you say yes here you get support for the - Dallas DS1742 timekeeping chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1742. - config RTC_DRV_PCF8563 tristate "Philips PCF8563/Epson RTC8564" depends on RTC_CLASS && I2C @@ -152,16 +107,6 @@ config RTC_DRV_PCF8563 This driver can also be built as a module. If so, the module will be called rtc-pcf8563. -config RTC_DRV_PCF8583 - tristate "Philips PCF8583" - depends on RTC_CLASS && I2C - help - If you say yes here you get support for the - Philips PCF8583 RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-pcf8583. - config RTC_DRV_RS5C372 tristate "Ricoh RS5C372A/B" depends on RTC_CLASS && I2C @@ -212,22 +157,6 @@ config RTC_DRV_VR41XX To compile this driver as a module, choose M here: the module will be called rtc-vr41xx. -config RTC_DRV_PL031 - tristate "ARM AMBA PL031 RTC" - depends on RTC_CLASS && ARM_AMBA - help - If you say Y here you will get access to ARM AMBA - PrimeCell PL031 UART found on certain ARM SOCs. - - To compile this driver as a module, choose M here: the - module will be called rtc-pl031. - -config RTC_DRV_AT91 - tristate "AT91RM9200" - depends on RTC_CLASS && ARCH_AT91RM9200 - help - Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). - config RTC_DRV_TEST tristate "Test driver/device" depends on RTC_CLASS @@ -243,24 +172,4 @@ config RTC_DRV_TEST This driver can also be built as a module. If so, the module will be called rtc-test. -config RTC_DRV_MAX6902 - tristate "Maxim 6902" - depends on RTC_CLASS && SPI - help - If you say yes here you will get support for the - Maxim MAX6902 spi RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-max6902. - -config RTC_DRV_V3020 - tristate "EM Microelectronic V3020" - depends on RTC_CLASS - help - If you say yes here you will get support for the - EM Microelectronic v3020 RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-v3020. - endmenu diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index 900d210dd1a2..a9ca0f171686 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -13,18 +13,10 @@ obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o -obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o -obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o -obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o -obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o -obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o -obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o -obj-$(CONFIG_RTC_DRV_AT91) += rtc-at91.o diff --git a/trunk/drivers/rtc/class.c b/trunk/drivers/rtc/class.c index 1cb61a761cb2..413c7d54ea10 100644 --- a/trunk/drivers/rtc/class.c +++ b/trunk/drivers/rtc/class.c @@ -69,7 +69,6 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->id = id; rtc->ops = ops; rtc->owner = owner; - rtc->max_user_freq = 64; rtc->class_dev.dev = dev; rtc->class_dev.class = rtc_class; rtc->class_dev.release = rtc_device_release; @@ -94,9 +93,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, kfree(rtc); exit_idr: - mutex_lock(&idr_lock); idr_remove(&rtc_idr, id); - mutex_unlock(&idr_lock); exit: dev_err(dev, "rtc core: unable to register %s, err = %d\n", diff --git a/trunk/drivers/rtc/interface.c b/trunk/drivers/rtc/interface.c index 579cd667b16f..56e490709b87 100644 --- a/trunk/drivers/rtc/interface.c +++ b/trunk/drivers/rtc/interface.c @@ -229,9 +229,6 @@ int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int unsigned long flags; struct rtc_device *rtc = to_rtc_device(class_dev); - if (rtc->ops->irq_set_state == NULL) - return -ENXIO; - spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != task) err = -ENXIO; @@ -246,12 +243,25 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_state); int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) { - int err = 0; + int err = 0, tmp = 0; unsigned long flags; struct rtc_device *rtc = to_rtc_device(class_dev); - if (rtc->ops->irq_set_freq == NULL) - return -ENXIO; + /* allowed range is 2-8192 */ + if (freq < 2 || freq > 8192) + return -EINVAL; +/* + FIXME: this does not belong here, will move where appropriate + at a later stage. It cannot hurt right now, trust me :) + if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) + return -EACCES; +*/ + /* check if freq is a power of 2 */ + while (freq > (1 << tmp)) + tmp++; + + if (freq != (1 << tmp)) + return -EINVAL; spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != task) diff --git a/trunk/drivers/rtc/rtc-at91.c b/trunk/drivers/rtc/rtc-at91.c deleted file mode 100644 index b676f443c17e..000000000000 --- a/trunk/drivers/rtc/rtc-at91.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Real Time Clock interface for Linux on Atmel AT91RM9200 - * - * Copyright (C) 2002 Rick Bronson - * - * Converted to RTC class model by Andrew Victor - * - * Ported to Linux 2.6 by Steven Scholz - * Based on s3c2410-rtc.c Simtec Electronics - * - * Based on sa1100-rtc.c by Nils Faerber - * Based on rtc.c by Paul Gortmaker - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#define AT91_RTC_FREQ 1 -#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ - -static DECLARE_COMPLETION(at91_rtc_updated); -static unsigned int at91_alarm_year = AT91_RTC_EPOCH; - -/* - * Decode time/date into rtc_time structure - */ -static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, - struct rtc_time *tm) -{ - unsigned int time, date; - - /* must read twice in case it changes */ - do { - time = at91_sys_read(timereg); - date = at91_sys_read(calreg); - } while ((time != at91_sys_read(timereg)) || - (date != at91_sys_read(calreg))); - - tm->tm_sec = BCD2BIN((time & AT91_RTC_SEC) >> 0); - tm->tm_min = BCD2BIN((time & AT91_RTC_MIN) >> 8); - tm->tm_hour = BCD2BIN((time & AT91_RTC_HOUR) >> 16); - - /* - * The Calendar Alarm register does not have a field for - * the year - so these will return an invalid value. When an - * alarm is set, at91_alarm_year wille store the current year. - */ - tm->tm_year = BCD2BIN(date & AT91_RTC_CENT) * 100; /* century */ - tm->tm_year += BCD2BIN((date & AT91_RTC_YEAR) >> 8); /* year */ - - tm->tm_wday = BCD2BIN((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */ - tm->tm_mon = BCD2BIN((date & AT91_RTC_MONTH) >> 16) - 1; - tm->tm_mday = BCD2BIN((date & AT91_RTC_DATE) >> 24); -} - -/* - * Read current time and date in RTC - */ -static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) -{ - at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, tm); - tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); - tm->tm_year = tm->tm_year - 1900; - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return 0; -} - -/* - * Set current time and date in RTC - */ -static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) -{ - unsigned long cr; - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - /* Stop Time/Calendar from counting */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); - - at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD); - wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); - - at91_sys_write(AT91_RTC_TIMR, - BIN2BCD(tm->tm_sec) << 0 - | BIN2BCD(tm->tm_min) << 8 - | BIN2BCD(tm->tm_hour) << 16); - - at91_sys_write(AT91_RTC_CALR, - BIN2BCD((tm->tm_year + 1900) / 100) /* century */ - | BIN2BCD(tm->tm_year % 100) << 8 /* year */ - | BIN2BCD(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ - | BIN2BCD(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */ - | BIN2BCD(tm->tm_mday) << 24); - - /* Restart Time/Calendar */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); - - return 0; -} - -/* - * Read alarm time and date in RTC - */ -static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct rtc_time *tm = &alrm->time; - - at91_rtc_decodetime(AT91_RTC_TIMALR, AT91_RTC_CALALR, tm); - tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); - tm->tm_year = at91_alarm_year - 1900; - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return 0; -} - -/* - * Set alarm time and date in RTC - */ -static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct rtc_time tm; - - at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm); - - at91_alarm_year = tm.tm_year; - - tm.tm_hour = alrm->time.tm_hour; - tm.tm_min = alrm->time.tm_min; - tm.tm_sec = alrm->time.tm_sec; - - at91_sys_write(AT91_RTC_TIMALR, - BIN2BCD(tm.tm_sec) << 0 - | BIN2BCD(tm.tm_min) << 8 - | BIN2BCD(tm.tm_hour) << 16 - | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); - at91_sys_write(AT91_RTC_CALALR, - BIN2BCD(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ - | BIN2BCD(tm.tm_mday) << 24 - | AT91_RTC_DATEEN | AT91_RTC_MTHEN); - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, - tm.tm_min, tm.tm_sec); - - return 0; -} - -/* - * Handle commands from user-space - */ -static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - int ret = 0; - - pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __FUNCTION__, cmd, arg); - - switch (cmd) { - case RTC_AIE_OFF: /* alarm off */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); - break; - case RTC_AIE_ON: /* alarm on */ - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); - break; - case RTC_UIE_OFF: /* update off */ - case RTC_PIE_OFF: /* periodic off */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); - break; - case RTC_UIE_ON: /* update on */ - case RTC_PIE_ON: /* periodic on */ - at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); - break; - case RTC_IRQP_READ: /* read periodic alarm frequency */ - ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg); - break; - case RTC_IRQP_SET: /* set periodic alarm frequency */ - if (arg != AT91_RTC_FREQ) - ret = -EINVAL; - break; - default: - ret = -ENOIOCTLCMD; - break; - } - - return ret; -} - -/* - * Provide additional RTC information in /proc/driver/rtc - */ -static int at91_rtc_proc(struct device *dev, struct seq_file *seq) -{ - unsigned long imr = at91_sys_read(AT91_RTC_IMR); - - seq_printf(seq, "alarm_IRQ\t: %s\n", - (imr & AT91_RTC_ALARM) ? "yes" : "no"); - seq_printf(seq, "update_IRQ\t: %s\n", - (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); - seq_printf(seq, "periodic_IRQ\t: %s\n", - (imr & AT91_RTC_SECEV) ? "yes" : "no"); - seq_printf(seq, "periodic_freq\t: %ld\n", - (unsigned long) AT91_RTC_FREQ); - - return 0; -} - -/* - * IRQ handler for the RTC - */ -static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - struct platform_device *pdev = dev_id; - struct rtc_device *rtc = platform_get_drvdata(pdev); - unsigned int rtsr; - unsigned long events = 0; - - rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR); - if (rtsr) { /* this interrupt is shared! Is it ours? */ - if (rtsr & AT91_RTC_ALARM) - events |= (RTC_AF | RTC_IRQF); - if (rtsr & AT91_RTC_SECEV) - events |= (RTC_UF | RTC_IRQF); - if (rtsr & AT91_RTC_ACKUPD) - complete(&at91_rtc_updated); - - at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ - - rtc_update_irq(&rtc->class_dev, 1, events); - - pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, - events >> 8, events & 0x000000FF); - - return IRQ_HANDLED; - } - return IRQ_NONE; /* not handled */ -} - -static struct rtc_class_ops at91_rtc_ops = { - .ioctl = at91_rtc_ioctl, - .read_time = at91_rtc_readtime, - .set_time = at91_rtc_settime, - .read_alarm = at91_rtc_readalarm, - .set_alarm = at91_rtc_setalarm, - .proc = at91_rtc_proc, -}; - -/* - * Initialize and install RTC driver - */ -static int __init at91_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - int ret; - - at91_sys_write(AT91_RTC_CR, 0); - at91_sys_write(AT91_RTC_MR, 0); /* 24 hour mode */ - - /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | - AT91_RTC_SECEV | AT91_RTC_TIMEV | - AT91_RTC_CALEV); - - ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, - SA_SHIRQ, "at91_rtc", pdev); - if (ret) { - printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", - AT91_ID_SYS); - return ret; - } - - rtc = rtc_device_register(pdev->name, &pdev->dev, - &at91_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - free_irq(AT91_ID_SYS, pdev); - return PTR_ERR(rtc); - } - platform_set_drvdata(pdev, rtc); - - printk(KERN_INFO "AT91 Real Time Clock driver.\n"); - return 0; -} - -/* - * Disable and remove the RTC driver - */ -static int __devexit at91_rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc = platform_get_drvdata(pdev); - - /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | - AT91_RTC_SECEV | AT91_RTC_TIMEV | - AT91_RTC_CALEV); - free_irq(AT91_ID_SYS, pdev); - - rtc_device_unregister(rtc); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -#ifdef CONFIG_PM - -/* AT91RM9200 RTC Power management control */ - -static struct timespec at91_rtc_delta; - -static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct rtc_time tm; - struct timespec time; - - time.tv_nsec = 0; - - /* calculate time delta for suspend */ - at91_rtc_readtime(&pdev->dev, &tm); - rtc_tm_to_time(&tm, &time.tv_sec); - save_time_delta(&at91_rtc_delta, &time); - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - - return 0; -} - -static int at91_rtc_resume(struct platform_device *pdev) -{ - struct rtc_time tm; - struct timespec time; - - time.tv_nsec = 0; - - at91_rtc_readtime(&pdev->dev, &tm); - rtc_tm_to_time(&tm, &time.tv_sec); - restore_time_delta(&at91_rtc_delta, &time); - - pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, - 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - - return 0; -} -#else -#define at91_rtc_suspend NULL -#define at91_rtc_resume NULL -#endif - -static struct platform_driver at91_rtc_driver = { - .probe = at91_rtc_probe, - .remove = at91_rtc_remove, - .suspend = at91_rtc_suspend, - .resume = at91_rtc_resume, - .driver = { - .name = "at91_rtc", - .owner = THIS_MODULE, - }, -}; - -static int __init at91_rtc_init(void) -{ - return platform_driver_register(&at91_rtc_driver); -} - -static void __exit at91_rtc_exit(void) -{ - platform_driver_unregister(&at91_rtc_driver); -} - -module_init(at91_rtc_init); -module_exit(at91_rtc_exit); - -MODULE_AUTHOR("Rick Bronson"); -MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 61a58259c93f..2011567005f9 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -48,93 +48,6 @@ static int rtc_dev_open(struct inode *inode, struct file *file) return err; } -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL -/* - * Routine to poll RTC seconds field for change as often as possible, - * after first RTC_UIE use timer to reduce polling - */ -static void rtc_uie_task(void *data) -{ - struct rtc_device *rtc = data; - struct rtc_time tm; - int num = 0; - int err; - - err = rtc_read_time(&rtc->class_dev, &tm); - spin_lock_irq(&rtc->irq_lock); - if (rtc->stop_uie_polling || err) { - rtc->uie_task_active = 0; - } else if (rtc->oldsecs != tm.tm_sec) { - num = (tm.tm_sec + 60 - rtc->oldsecs) % 60; - rtc->oldsecs = tm.tm_sec; - rtc->uie_timer.expires = jiffies + HZ - (HZ/10); - rtc->uie_timer_active = 1; - rtc->uie_task_active = 0; - add_timer(&rtc->uie_timer); - } else if (schedule_work(&rtc->uie_task) == 0) { - rtc->uie_task_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); - if (num) - rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); -} - -static void rtc_uie_timer(unsigned long data) -{ - struct rtc_device *rtc = (struct rtc_device *)data; - unsigned long flags; - - spin_lock_irqsave(&rtc->irq_lock, flags); - rtc->uie_timer_active = 0; - rtc->uie_task_active = 1; - if ((schedule_work(&rtc->uie_task) == 0)) - rtc->uie_task_active = 0; - spin_unlock_irqrestore(&rtc->irq_lock, flags); -} - -static void clear_uie(struct rtc_device *rtc) -{ - spin_lock_irq(&rtc->irq_lock); - if (rtc->irq_active) { - rtc->stop_uie_polling = 1; - if (rtc->uie_timer_active) { - spin_unlock_irq(&rtc->irq_lock); - del_timer_sync(&rtc->uie_timer); - spin_lock_irq(&rtc->irq_lock); - rtc->uie_timer_active = 0; - } - if (rtc->uie_task_active) { - spin_unlock_irq(&rtc->irq_lock); - flush_scheduled_work(); - spin_lock_irq(&rtc->irq_lock); - } - rtc->irq_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); -} - -static int set_uie(struct rtc_device *rtc) -{ - struct rtc_time tm; - int err; - - err = rtc_read_time(&rtc->class_dev, &tm); - if (err) - return err; - spin_lock_irq(&rtc->irq_lock); - if (!rtc->irq_active) { - rtc->irq_active = 1; - rtc->stop_uie_polling = 0; - rtc->oldsecs = tm.tm_sec; - rtc->uie_task_active = 1; - if (schedule_work(&rtc->uie_task) == 0) - rtc->uie_task_active = 0; - } - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - return 0; -} -#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ static ssize_t rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -214,28 +127,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, struct rtc_wkalrm alarm; void __user *uarg = (void __user *) arg; - /* check that the calles has appropriate permissions - * for certain ioctls. doing this check here is useful - * to avoid duplicate code in each driver. - */ - switch (cmd) { - case RTC_EPOCH_SET: - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) - return -EACCES; - break; - - case RTC_IRQP_SET: - if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) - return -EACCES; - break; - - case RTC_PIE_ON: - if (!capable(CAP_SYS_RESOURCE)) - return -EACCES; - break; - } - /* avoid conflicting IRQ users */ if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { spin_lock(&rtc->irq_task_lock); @@ -294,6 +185,9 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, break; case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + if (copy_from_user(&tm, uarg, sizeof(tm))) return -EFAULT; @@ -309,6 +203,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, err = -EINVAL; break; } + if (!capable(CAP_SYS_TIME)) { + err = -EACCES; + break; + } rtc_epoch = arg; err = 0; #endif @@ -334,14 +232,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, return -EFAULT; break; -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - case RTC_UIE_OFF: - clear_uie(rtc); - return 0; - - case RTC_UIE_ON: - return set_uie(rtc); -#endif default: err = -ENOTTY; break; @@ -354,9 +244,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file) { struct rtc_device *rtc = to_rtc_device(file->private_data); -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - clear_uie(rtc); -#endif if (rtc->ops->release) rtc->ops->release(rtc->class_dev.dev); @@ -397,10 +284,6 @@ static int rtc_dev_add_device(struct class_device *class_dev, mutex_init(&rtc->char_lock); spin_lock_init(&rtc->irq_lock); init_waitqueue_head(&rtc->irq_queue); -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - INIT_WORK(&rtc->uie_task, rtc_uie_task, rtc); - setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); -#endif cdev_init(&rtc->char_dev, &rtc_dev_fops); rtc->char_dev.owner = rtc->owner; diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c deleted file mode 100644 index e8afb9384786..000000000000 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * rtc-ds1307.c - RTC driver for some mostly-compatible I2C chips. - * - * Copyright (C) 2005 James Chapman (ds1337 core) - * Copyright (C) 2006 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - - - -/* We can't determine type by probing, but if we expect pre-Linux code - * to have set the chip up as a clock (turning on the oscillator and - * setting the date and time), Linux can ignore the non-clock features. - * That's a natural job for a factory or repair bench. - * - * If the I2C "force" mechanism is used, we assume the chip is a ds1337. - * (Much better would be board-specific tables of I2C devices, along with - * the platform_data drivers would use to sort such issues out.) - */ -enum ds_type { - unknown = 0, - ds_1307, /* or ds1338, ... */ - ds_1337, /* or ds1339, ... */ - ds_1340, /* or st m41t00, ... */ - // rs5c372 too? different address... -}; - -static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - - - -/* RTC registers don't differ much, except for the century flag */ -#define DS1307_REG_SECS 0x00 /* 00-59 */ -# define DS1307_BIT_CH 0x80 -#define DS1307_REG_MIN 0x01 /* 00-59 */ -#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ -# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ -# define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ -#define DS1307_REG_WDAY 0x03 /* 01-07 */ -#define DS1307_REG_MDAY 0x04 /* 01-31 */ -#define DS1307_REG_MONTH 0x05 /* 01-12 */ -# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ -#define DS1307_REG_YEAR 0x06 /* 00-99 */ - -/* Other registers (control, status, alarms, trickle charge, NVRAM, etc) - * start at 7, and they differ a lot. Only control and status matter for RTC; - * be careful using them. - */ -#define DS1307_REG_CONTROL 0x07 -# define DS1307_BIT_OUT 0x80 -# define DS1307_BIT_SQWE 0x10 -# define DS1307_BIT_RS1 0x02 -# define DS1307_BIT_RS0 0x01 -#define DS1337_REG_CONTROL 0x0e -# define DS1337_BIT_nEOSC 0x80 -# define DS1337_BIT_RS2 0x10 -# define DS1337_BIT_RS1 0x08 -# define DS1337_BIT_INTCN 0x04 -# define DS1337_BIT_A2IE 0x02 -# define DS1337_BIT_A1IE 0x01 -#define DS1337_REG_STATUS 0x0f -# define DS1337_BIT_OSF 0x80 -# define DS1337_BIT_A2I 0x02 -# define DS1337_BIT_A1I 0x01 -#define DS1339_REG_TRICKLE 0x10 - - - -struct ds1307 { - u8 reg_addr; - u8 regs[8]; - enum ds_type type; - struct i2c_msg msg[2]; - struct i2c_client client; - struct rtc_device *rtc; -}; - - -static int ds1307_get_time(struct device *dev, struct rtc_time *t) -{ - struct ds1307 *ds1307 = dev_get_drvdata(dev); - int tmp; - - /* read the RTC registers all at once */ - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = 7; - - tmp = i2c_transfer(ds1307->client.adapter, ds1307->msg, 2); - if (tmp != 2) { - dev_err(dev, "%s error %d\n", "read", tmp); - return -EIO; - } - - dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", - "read", - ds1307->regs[0], ds1307->regs[1], - ds1307->regs[2], ds1307->regs[3], - ds1307->regs[4], ds1307->regs[5], - ds1307->regs[6]); - - t->tm_sec = BCD2BIN(ds1307->regs[DS1307_REG_SECS] & 0x7f); - t->tm_min = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f); - tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f; - t->tm_hour = BCD2BIN(tmp); - t->tm_wday = BCD2BIN(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1; - t->tm_mday = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f); - tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f; - t->tm_mon = BCD2BIN(tmp) - 1; - - /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */ - t->tm_year = BCD2BIN(ds1307->regs[DS1307_REG_YEAR]) + 100; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "read", t->tm_sec, t->tm_min, - t->tm_hour, t->tm_mday, - t->tm_mon, t->tm_year, t->tm_wday); - - return 0; -} - -static int ds1307_set_time(struct device *dev, struct rtc_time *t) -{ - struct ds1307 *ds1307 = dev_get_drvdata(dev); - int result; - int tmp; - u8 *buf = ds1307->regs; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "write", dt->tm_sec, dt->tm_min, - dt->tm_hour, dt->tm_mday, - dt->tm_mon, dt->tm_year, dt->tm_wday); - - *buf++ = 0; /* first register addr */ - buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec); - buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min); - buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour); - buf[DS1307_REG_WDAY] = BIN2BCD(t->tm_wday + 1); - buf[DS1307_REG_MDAY] = BIN2BCD(t->tm_mday); - buf[DS1307_REG_MONTH] = BIN2BCD(t->tm_mon + 1); - - /* assume 20YY not 19YY */ - tmp = t->tm_year - 100; - buf[DS1307_REG_YEAR] = BIN2BCD(tmp); - - if (ds1307->type == ds_1337) - buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY; - else if (ds1307->type == ds_1340) - buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN - | DS1340_BIT_CENTURY; - - ds1307->msg[1].flags = 0; - ds1307->msg[1].len = 8; - - dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", - "write", buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6]); - - result = i2c_transfer(ds1307->client.adapter, &ds1307->msg[1], 1); - if (result != 1) { - dev_err(dev, "%s error %d\n", "write", tmp); - return -EIO; - } - return 0; -} - -static struct rtc_class_ops ds13xx_rtc_ops = { - .read_time = ds1307_get_time, - .set_time = ds1307_set_time, -}; - -static struct i2c_driver ds1307_driver; - -static int __devinit -ds1307_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct ds1307 *ds1307; - int err = -ENODEV; - struct i2c_client *client; - int tmp; - - if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &ds1307->client; - client->addr = address; - client->adapter = adapter; - client->driver = &ds1307_driver; - client->flags = 0; - - i2c_set_clientdata(client, ds1307); - - ds1307->msg[0].addr = client->addr; - ds1307->msg[0].flags = 0; - ds1307->msg[0].len = 1; - ds1307->msg[0].buf = &ds1307->reg_addr; - - ds1307->msg[1].addr = client->addr; - ds1307->msg[1].flags = I2C_M_RD; - ds1307->msg[1].len = sizeof(ds1307->regs); - ds1307->msg[1].buf = ds1307->regs; - - /* HACK: "force" implies "needs ds1337-style-oscillator setup" */ - if (kind >= 0) { - ds1307->type = ds_1337; - - ds1307->reg_addr = DS1337_REG_CONTROL; - ds1307->msg[1].len = 2; - - tmp = i2c_transfer(client->adapter, ds1307->msg, 2); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - ds1307->reg_addr = 0; - ds1307->msg[1].len = sizeof(ds1307->regs); - - /* oscillator is off; need to turn it on */ - if ((ds1307->regs[0] & DS1337_BIT_nEOSC) - || (ds1307->regs[1] & DS1337_BIT_OSF)) { - printk(KERN_ERR "no ds1337 oscillator code\n"); - goto exit_free; - } - } else - ds1307->type = ds_1307; - -read_rtc: - /* read RTC registers */ - - tmp = i2c_transfer(client->adapter, ds1307->msg, 2); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - /* minimal sanity checking; some chips (like DS1340) don't - * specify the extra bits as must-be-zero, but there are - * still a few values that are clearly out-of-range. - */ - tmp = ds1307->regs[DS1307_REG_SECS]; - if (tmp & DS1307_BIT_CH) { - if (ds1307->type && ds1307->type != ds_1307) { - pr_debug("not a ds1307?\n"); - goto exit_free; - } - ds1307->type = ds_1307; - - /* this partial initialization should work for ds1307, - * ds1338, ds1340, st m41t00, and more. - */ - dev_warn(&client->dev, "oscillator started; SET TIME!\n"); - i2c_smbus_write_byte_data(client, 0, 0); - goto read_rtc; - } - tmp = BCD2BIN(tmp & 0x7f); - if (tmp > 60) - goto exit_free; - tmp = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f); - if (tmp > 60) - goto exit_free; - - tmp = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f); - if (tmp == 0 || tmp > 31) - goto exit_free; - - tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f); - if (tmp == 0 || tmp > 12) - goto exit_free; - - /* force into in 24 hour mode (most chips) or - * disable century bit (ds1340) - */ - tmp = ds1307->regs[DS1307_REG_HOUR]; - if (tmp & (1 << 6)) { - if (tmp & (1 << 5)) - tmp = BCD2BIN(tmp & 0x1f) + 12; - else - tmp = BCD2BIN(tmp); - i2c_smbus_write_byte_data(client, - DS1307_REG_HOUR, - BIN2BCD(tmp)); - } - - /* FIXME chips like 1337 can generate alarm irqs too; those are - * worth exposing through the API (especially when the irq is - * wakeup-capable). - */ - - switch (ds1307->type) { - case unknown: - strlcpy(client->name, "unknown", I2C_NAME_SIZE); - break; - case ds_1307: - strlcpy(client->name, "ds1307", I2C_NAME_SIZE); - break; - case ds_1337: - strlcpy(client->name, "ds1337", I2C_NAME_SIZE); - break; - case ds_1340: - strlcpy(client->name, "ds1340", I2C_NAME_SIZE); - break; - } - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; - - ds1307->rtc = rtc_device_register(client->name, &client->dev, - &ds13xx_rtc_ops, THIS_MODULE); - if (IS_ERR(ds1307->rtc)) { - err = PTR_ERR(ds1307->rtc); - dev_err(&client->dev, - "unable to register the class device\n"); - goto exit_detach; - } - - return 0; - -exit_detach: - i2c_detach_client(client); -exit_free: - kfree(ds1307); -exit: - return err; -} - -static int __devinit -ds1307_attach_adapter(struct i2c_adapter *adapter) -{ - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) - return 0; - return i2c_probe(adapter, &addr_data, ds1307_detect); -} - -static int __devexit ds1307_detach_client(struct i2c_client *client) -{ - int err; - struct ds1307 *ds1307 = i2c_get_clientdata(client); - - rtc_device_unregister(ds1307->rtc); - if ((err = i2c_detach_client(client))) - return err; - kfree(ds1307); - return 0; -} - -static struct i2c_driver ds1307_driver = { - .driver = { - .name = "ds1307", - .owner = THIS_MODULE, - }, - .attach_adapter = ds1307_attach_adapter, - .detach_client = __devexit_p(ds1307_detach_client), -}; - -static int __init ds1307_init(void) -{ - return i2c_add_driver(&ds1307_driver); -} -module_init(ds1307_init); - -static void __exit ds1307_exit(void) -{ - i2c_del_driver(&ds1307_driver); -} -module_exit(ds1307_exit); - -MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c deleted file mode 100644 index 762521a1419c..000000000000 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * An rtc driver for the Dallas DS1553 - * - * Copyright (C) 2006 Atsushi Nemoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "0.1" - -#define RTC_REG_SIZE 0x2000 -#define RTC_OFFSET 0x1ff0 - -#define RTC_FLAGS (RTC_OFFSET + 0) -#define RTC_SECONDS_ALARM (RTC_OFFSET + 2) -#define RTC_MINUTES_ALARM (RTC_OFFSET + 3) -#define RTC_HOURS_ALARM (RTC_OFFSET + 4) -#define RTC_DATE_ALARM (RTC_OFFSET + 5) -#define RTC_INTERRUPTS (RTC_OFFSET + 6) -#define RTC_WATCHDOG (RTC_OFFSET + 7) -#define RTC_CONTROL (RTC_OFFSET + 8) -#define RTC_CENTURY (RTC_OFFSET + 8) -#define RTC_SECONDS (RTC_OFFSET + 9) -#define RTC_MINUTES (RTC_OFFSET + 10) -#define RTC_HOURS (RTC_OFFSET + 11) -#define RTC_DAY (RTC_OFFSET + 12) -#define RTC_DATE (RTC_OFFSET + 13) -#define RTC_MONTH (RTC_OFFSET + 14) -#define RTC_YEAR (RTC_OFFSET + 15) - -#define RTC_CENTURY_MASK 0x3f -#define RTC_SECONDS_MASK 0x7f -#define RTC_DAY_MASK 0x07 - -/* Bits in the Control/Century register */ -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 - -/* Bits in the Seconds register */ -#define RTC_STOP 0x80 - -/* Bits in the Flags register */ -#define RTC_FLAGS_AF 0x40 -#define RTC_FLAGS_BLF 0x10 - -/* Bits in the Interrupts register */ -#define RTC_INTS_AE 0x80 - -struct rtc_plat_data { - struct rtc_device *rtc; - void __iomem *ioaddr; - unsigned long baseaddr; - unsigned long last_jiffies; - int irq; - unsigned int irqen; - int alrm_sec; - int alrm_min; - int alrm_hour; - int alrm_mday; -}; - -static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - u8 century; - - century = BIN2BCD((tm->tm_year + 1900) / 100); - - writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL); - - writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); - writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); - writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); - writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); - writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); - writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); - writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); - - /* RTC_CENTURY and RTC_CONTROL share same register */ - writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); - writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); - return 0; -} - -static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - unsigned int year, month, day, hour, minute, second, week; - unsigned int century; - - /* give enough time to update RTC in case of continuous read */ - if (pdata->last_jiffies == jiffies) - msleep(1); - pdata->last_jiffies = jiffies; - writeb(RTC_READ, ioaddr + RTC_CONTROL); - second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK; - minute = readb(ioaddr + RTC_MINUTES); - hour = readb(ioaddr + RTC_HOURS); - day = readb(ioaddr + RTC_DATE); - week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK; - month = readb(ioaddr + RTC_MONTH); - year = readb(ioaddr + RTC_YEAR); - century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; - writeb(0, ioaddr + RTC_CONTROL); - tm->tm_sec = BCD2BIN(second); - tm->tm_min = BCD2BIN(minute); - tm->tm_hour = BCD2BIN(hour); - tm->tm_mday = BCD2BIN(day); - tm->tm_wday = BCD2BIN(week); - tm->tm_mon = BCD2BIN(month) - 1; - /* year is 1900 + tm->tm_year */ - tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900; - - if (rtc_valid_tm(tm) < 0) { - dev_err(dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } - return 0; -} - -static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata) -{ - void __iomem *ioaddr = pdata->ioaddr; - unsigned long flags; - - spin_lock_irqsave(&pdata->rtc->irq_lock, flags); - writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? - 0x80 : BIN2BCD(pdata->alrm_mday), - ioaddr + RTC_DATE_ALARM); - writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? - 0x80 : BIN2BCD(pdata->alrm_hour), - ioaddr + RTC_HOURS_ALARM); - writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? - 0x80 : BIN2BCD(pdata->alrm_min), - ioaddr + RTC_MINUTES_ALARM); - writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? - 0x80 : BIN2BCD(pdata->alrm_sec), - ioaddr + RTC_SECONDS_ALARM); - writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS); - readb(ioaddr + RTC_FLAGS); /* clear interrupts */ - spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); -} - -static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq < 0) - return -EINVAL; - pdata->alrm_mday = alrm->time.tm_mday; - pdata->alrm_hour = alrm->time.tm_hour; - pdata->alrm_min = alrm->time.tm_min; - pdata->alrm_sec = alrm->time.tm_sec; - if (alrm->enabled) - pdata->irqen |= RTC_AF; - ds1553_rtc_update_alarm(pdata); - return 0; -} - -static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq < 0) - return -EINVAL; - alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; - alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; - alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; - alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec; - alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0; - return 0; -} - -static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - struct platform_device *pdev = dev_id; - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - unsigned long events = RTC_IRQF; - - /* read and clear interrupt */ - if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF)) - return IRQ_NONE; - if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80) - events |= RTC_UF; - else - events |= RTC_AF; - rtc_update_irq(&pdata->rtc->class_dev, 1, events); - return IRQ_HANDLED; -} - -static void ds1553_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq >= 0) { - pdata->irqen = 0; - ds1553_rtc_update_alarm(pdata); - } -} - -static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq < 0) - return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ - switch (cmd) { - case RTC_AIE_OFF: - pdata->irqen &= ~RTC_AF; - ds1553_rtc_update_alarm(pdata); - break; - case RTC_AIE_ON: - pdata->irqen |= RTC_AF; - ds1553_rtc_update_alarm(pdata); - break; - case RTC_UIE_OFF: - pdata->irqen &= ~RTC_UF; - ds1553_rtc_update_alarm(pdata); - break; - case RTC_UIE_ON: - pdata->irqen |= RTC_UF; - ds1553_rtc_update_alarm(pdata); - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static struct rtc_class_ops ds1553_rtc_ops = { - .read_time = ds1553_rtc_read_time, - .set_time = ds1553_rtc_set_time, - .read_alarm = ds1553_rtc_read_alarm, - .set_alarm = ds1553_rtc_set_alarm, - .release = ds1553_rtc_release, - .ioctl = ds1553_rtc_ioctl, -}; - -static ssize_t ds1553_nvram_read(struct kobject *kobj, char *buf, - loff_t pos, size_t size) -{ - struct platform_device *pdev = - to_platform_device(container_of(kobj, struct device, kobj)); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; - - for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) - *buf++ = readb(ioaddr + pos++); - return count; -} - -static ssize_t ds1553_nvram_write(struct kobject *kobj, char *buf, - loff_t pos, size_t size) -{ - struct platform_device *pdev = - to_platform_device(container_of(kobj, struct device, kobj)); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; - - for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) - writeb(*buf++, ioaddr + pos++); - return count; -} - -static struct bin_attribute ds1553_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUGO, - .owner = THIS_MODULE, - }, - .size = RTC_OFFSET, - .read = ds1553_nvram_read, - .write = ds1553_nvram_write, -}; - -static int __init ds1553_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - struct resource *res; - unsigned int cen, sec; - struct rtc_plat_data *pdata = NULL; - void __iomem *ioaddr = NULL; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - pdata->irq = -1; - if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { - ret = -EBUSY; - goto out; - } - pdata->baseaddr = res->start; - ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE); - if (!ioaddr) { - ret = -ENOMEM; - goto out; - } - pdata->ioaddr = ioaddr; - pdata->irq = platform_get_irq(pdev, 0); - - /* turn RTC on if it was not on */ - sec = readb(ioaddr + RTC_SECONDS); - if (sec & RTC_STOP) { - sec &= RTC_SECONDS_MASK; - cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; - writeb(RTC_WRITE, ioaddr + RTC_CONTROL); - writeb(sec, ioaddr + RTC_SECONDS); - writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); - } - if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF) - dev_warn(&pdev->dev, "voltage-low detected.\n"); - - if (pdata->irq >= 0) { - writeb(0, ioaddr + RTC_INTERRUPTS); - if (request_irq(pdata->irq, ds1553_rtc_interrupt, SA_SHIRQ, - pdev->name, pdev) < 0) { - dev_warn(&pdev->dev, "interrupt not available.\n"); - pdata->irq = -1; - } - } - - rtc = rtc_device_register(pdev->name, &pdev->dev, - &ds1553_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } - pdata->rtc = rtc; - pdata->last_jiffies = jiffies; - platform_set_drvdata(pdev, pdata); - sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); - return 0; - out: - if (pdata->irq >= 0) - free_irq(pdata->irq, pdev); - if (ioaddr) - iounmap(ioaddr); - if (pdata->baseaddr) - release_mem_region(pdata->baseaddr, RTC_REG_SIZE); - kfree(pdata); - return ret; -} - -static int __devexit ds1553_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); - rtc_device_unregister(pdata->rtc); - if (pdata->irq >= 0) { - writeb(0, pdata->ioaddr + RTC_INTERRUPTS); - free_irq(pdata->irq, pdev); - } - iounmap(pdata->ioaddr); - release_mem_region(pdata->baseaddr, RTC_REG_SIZE); - kfree(pdata); - return 0; -} - -static struct platform_driver ds1553_rtc_driver = { - .probe = ds1553_rtc_probe, - .remove = __devexit_p(ds1553_rtc_remove), - .driver = { - .name = "ds1553", - .owner = THIS_MODULE, - }, -}; - -static __init int ds1553_init(void) -{ - return platform_driver_register(&ds1553_rtc_driver); -} - -static __exit void ds1553_exit(void) -{ - return platform_driver_unregister(&ds1553_rtc_driver); -} - -module_init(ds1553_init); -module_exit(ds1553_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Dallas DS1553 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/rtc/rtc-ds1742.c b/trunk/drivers/rtc/rtc-ds1742.c deleted file mode 100644 index 8e47e5a06d2a..000000000000 --- a/trunk/drivers/rtc/rtc-ds1742.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * An rtc driver for the Dallas DS1742 - * - * Copyright (C) 2006 Atsushi Nemoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "0.1" - -#define RTC_REG_SIZE 0x800 -#define RTC_OFFSET 0x7f8 - -#define RTC_CONTROL (RTC_OFFSET + 0) -#define RTC_CENTURY (RTC_OFFSET + 0) -#define RTC_SECONDS (RTC_OFFSET + 1) -#define RTC_MINUTES (RTC_OFFSET + 2) -#define RTC_HOURS (RTC_OFFSET + 3) -#define RTC_DAY (RTC_OFFSET + 4) -#define RTC_DATE (RTC_OFFSET + 5) -#define RTC_MONTH (RTC_OFFSET + 6) -#define RTC_YEAR (RTC_OFFSET + 7) - -#define RTC_CENTURY_MASK 0x3f -#define RTC_SECONDS_MASK 0x7f -#define RTC_DAY_MASK 0x07 - -/* Bits in the Control/Century register */ -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 - -/* Bits in the Seconds register */ -#define RTC_STOP 0x80 - -/* Bits in the Day register */ -#define RTC_BATT_FLAG 0x80 - -struct rtc_plat_data { - struct rtc_device *rtc; - void __iomem *ioaddr; - unsigned long baseaddr; - unsigned long last_jiffies; -}; - -static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - u8 century; - - century = BIN2BCD((tm->tm_year + 1900) / 100); - - writeb(RTC_WRITE, ioaddr + RTC_CONTROL); - - writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); - writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); - writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); - writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); - writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); - writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); - writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); - - /* RTC_CENTURY and RTC_CONTROL share same register */ - writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); - writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); - return 0; -} - -static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - unsigned int year, month, day, hour, minute, second, week; - unsigned int century; - - /* give enough time to update RTC in case of continuous read */ - if (pdata->last_jiffies == jiffies) - msleep(1); - pdata->last_jiffies = jiffies; - writeb(RTC_READ, ioaddr + RTC_CONTROL); - second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK; - minute = readb(ioaddr + RTC_MINUTES); - hour = readb(ioaddr + RTC_HOURS); - day = readb(ioaddr + RTC_DATE); - week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK; - month = readb(ioaddr + RTC_MONTH); - year = readb(ioaddr + RTC_YEAR); - century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; - writeb(0, ioaddr + RTC_CONTROL); - tm->tm_sec = BCD2BIN(second); - tm->tm_min = BCD2BIN(minute); - tm->tm_hour = BCD2BIN(hour); - tm->tm_mday = BCD2BIN(day); - tm->tm_wday = BCD2BIN(week); - tm->tm_mon = BCD2BIN(month) - 1; - /* year is 1900 + tm->tm_year */ - tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900; - - if (rtc_valid_tm(tm) < 0) { - dev_err(dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } - return 0; -} - -static struct rtc_class_ops ds1742_rtc_ops = { - .read_time = ds1742_rtc_read_time, - .set_time = ds1742_rtc_set_time, -}; - -static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf, - loff_t pos, size_t size) -{ - struct platform_device *pdev = - to_platform_device(container_of(kobj, struct device, kobj)); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; - - for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) - *buf++ = readb(ioaddr + pos++); - return count; -} - -static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf, - loff_t pos, size_t size) -{ - struct platform_device *pdev = - to_platform_device(container_of(kobj, struct device, kobj)); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; - - for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) - writeb(*buf++, ioaddr + pos++); - return count; -} - -static struct bin_attribute ds1742_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUGO, - .owner = THIS_MODULE, - }, - .size = RTC_OFFSET, - .read = ds1742_nvram_read, - .write = ds1742_nvram_write, -}; - -static int __init ds1742_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - struct resource *res; - unsigned int cen, sec; - struct rtc_plat_data *pdata = NULL; - void __iomem *ioaddr = NULL; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { - ret = -EBUSY; - goto out; - } - pdata->baseaddr = res->start; - ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE); - if (!ioaddr) { - ret = -ENOMEM; - goto out; - } - pdata->ioaddr = ioaddr; - - /* turn RTC on if it was not on */ - sec = readb(ioaddr + RTC_SECONDS); - if (sec & RTC_STOP) { - sec &= RTC_SECONDS_MASK; - cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; - writeb(RTC_WRITE, ioaddr + RTC_CONTROL); - writeb(sec, ioaddr + RTC_SECONDS); - writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL); - } - if (readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG) - dev_warn(&pdev->dev, "voltage-low detected.\n"); - - rtc = rtc_device_register(pdev->name, &pdev->dev, - &ds1742_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } - pdata->rtc = rtc; - pdata->last_jiffies = jiffies; - platform_set_drvdata(pdev, pdata); - sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); - return 0; - out: - if (ioaddr) - iounmap(ioaddr); - if (pdata->baseaddr) - release_mem_region(pdata->baseaddr, RTC_REG_SIZE); - kfree(pdata); - return ret; -} - -static int __devexit ds1742_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); - rtc_device_unregister(pdata->rtc); - iounmap(pdata->ioaddr); - release_mem_region(pdata->baseaddr, RTC_REG_SIZE); - kfree(pdata); - return 0; -} - -static struct platform_driver ds1742_rtc_driver = { - .probe = ds1742_rtc_probe, - .remove = __devexit_p(ds1742_rtc_remove), - .driver = { - .name = "ds1742", - .owner = THIS_MODULE, - }, -}; - -static __init int ds1742_init(void) -{ - return platform_driver_register(&ds1742_rtc_driver); -} - -static __exit void ds1742_exit(void) -{ - return platform_driver_unregister(&ds1742_rtc_driver); -} - -module_init(ds1742_init); -module_exit(ds1742_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/rtc/rtc-lib.c b/trunk/drivers/rtc/rtc-lib.c index 9812120f3a7c..cfedc1d28ee1 100644 --- a/trunk/drivers/rtc/rtc-lib.c +++ b/trunk/drivers/rtc/rtc-lib.c @@ -18,34 +18,15 @@ static const unsigned char rtc_days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static const unsigned short rtc_ydays[2][13] = { - /* Normal years */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } -}; - #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) #define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) -/* - * The number of days in the month. - */ int rtc_month_days(unsigned int month, unsigned int year) { return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); } EXPORT_SYMBOL(rtc_month_days); -/* - * The number of days since January 1. (0 to 365) - */ -int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) -{ - return rtc_ydays[LEAP_YEAR(year)][month] + day-1; -} -EXPORT_SYMBOL(rtc_year_days); - /* * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. */ diff --git a/trunk/drivers/rtc/rtc-max6902.c b/trunk/drivers/rtc/rtc-max6902.c deleted file mode 100644 index 2c9739562b5c..000000000000 --- a/trunk/drivers/rtc/rtc-max6902.c +++ /dev/null @@ -1,286 +0,0 @@ -/* drivers/char/max6902.c - * - * Copyright (C) 2006 8D Technologies inc. - * Copyright (C) 2004 Compulab Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Driver for MAX6902 spi RTC - * - * Changelog: - * - * 24-May-2006: Raphael Assenat - * - Major rework - * Converted to rtc_device and uses the SPI layer. - * - * ??-???-2005: Someone at Compulab - * - Initial driver creation. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MAX6902_REG_SECONDS 0x01 -#define MAX6902_REG_MINUTES 0x03 -#define MAX6902_REG_HOURS 0x05 -#define MAX6902_REG_DATE 0x07 -#define MAX6902_REG_MONTH 0x09 -#define MAX6902_REG_DAY 0x0B -#define MAX6902_REG_YEAR 0x0D -#define MAX6902_REG_CONTROL 0x0F -#define MAX6902_REG_CENTURY 0x13 - -#undef MAX6902_DEBUG - -struct max6902 { - struct rtc_device *rtc; - u8 buf[9]; /* Burst read cmd + 8 registers */ - u8 tx_buf[2]; - u8 rx_buf[2]; -}; - -static void max6902_set_reg(struct device *dev, unsigned char address, - unsigned char data) -{ - struct spi_device *spi = to_spi_device(dev); - unsigned char buf[2]; - - /* MSB must be '0' to write */ - buf[0] = address & 0x7f; - buf[1] = data; - - spi_write(spi, buf, 2); -} - -static int max6902_get_reg(struct device *dev, unsigned char address, - unsigned char *data) -{ - struct spi_device *spi = to_spi_device(dev); - struct max6902 *chip = dev_get_drvdata(dev); - struct spi_message message; - struct spi_transfer xfer; - int status; - - if (!data) - return -EINVAL; - - /* Build our spi message */ - spi_message_init(&message); - memset(&xfer, 0, sizeof(xfer)); - xfer.len = 2; - /* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */ - xfer.tx_buf = chip->tx_buf; - xfer.rx_buf = chip->rx_buf; - - /* Set MSB to indicate read */ - chip->tx_buf[0] = address | 0x80; - - spi_message_add_tail(&xfer, &message); - - /* do the i/o */ - status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else - return status; - - *data = chip->rx_buf[1]; - - return status; -} - -static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) -{ - unsigned char tmp; - int century; - int err; - struct spi_device *spi = to_spi_device(dev); - struct max6902 *chip = dev_get_drvdata(dev); - struct spi_message message; - struct spi_transfer xfer; - int status; - - err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp); - if (err) - return err; - - /* build the message */ - spi_message_init(&message); - memset(&xfer, 0, sizeof(xfer)); - xfer.len = 1 + 7; /* Burst read command + 7 registers */ - xfer.tx_buf = chip->buf; - xfer.rx_buf = chip->buf; - chip->buf[0] = 0xbf; /* Burst read */ - spi_message_add_tail(&xfer, &message); - - /* do the i/o */ - status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else - return status; - - /* The chip sends data in this order: - * Seconds, Minutes, Hours, Date, Month, Day, Year */ - dt->tm_sec = BCD2BIN(chip->buf[1]); - dt->tm_min = BCD2BIN(chip->buf[2]); - dt->tm_hour = BCD2BIN(chip->buf[3]); - dt->tm_mday = BCD2BIN(chip->buf[4]); - dt->tm_mon = BCD2BIN(chip->buf[5] - 1); - dt->tm_wday = BCD2BIN(chip->buf[6]); - dt->tm_year = BCD2BIN(chip->buf[7]); - - century = BCD2BIN(tmp) * 100; - - dt->tm_year += century; - dt->tm_year -= 1900; - -#ifdef MAX6902_DEBUG - printk("\n%s : Read RTC values\n",__FUNCTION__); - printk("tm_hour: %i\n",dt->tm_hour); - printk("tm_min : %i\n",dt->tm_min); - printk("tm_sec : %i\n",dt->tm_sec); - printk("tm_year: %i\n",dt->tm_year); - printk("tm_mon : %i\n",dt->tm_mon); - printk("tm_mday: %i\n",dt->tm_mday); - printk("tm_wday: %i\n",dt->tm_wday); -#endif - - return 0; -} - -static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) -{ - dt->tm_year = dt->tm_year+1900; - -#ifdef MAX6902_DEBUG - printk("\n%s : Setting RTC values\n",__FUNCTION__); - printk("tm_sec : %i\n",dt->tm_sec); - printk("tm_min : %i\n",dt->tm_min); - printk("tm_hour: %i\n",dt->tm_hour); - printk("tm_mday: %i\n",dt->tm_mday); - printk("tm_wday: %i\n",dt->tm_wday); - printk("tm_year: %i\n",dt->tm_year); -#endif - - /* Remove write protection */ - max6902_set_reg(dev, 0xF, 0); - - max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec)); - max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min)); - max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour)); - - max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday)); - max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1)); - max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday)); - max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100)); - max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100)); - - /* Compulab used a delay here. However, the datasheet - * does not mention a delay being required anywhere... */ - /* delay(2000); */ - - /* Write protect */ - max6902_set_reg(dev, 0xF, 0x80); - - return 0; -} - -static int max6902_read_time(struct device *dev, struct rtc_time *tm) -{ - return max6902_get_datetime(dev, tm); -} - -static int max6902_set_time(struct device *dev, struct rtc_time *tm) -{ - return max6902_set_datetime(dev, tm); -} - -static struct rtc_class_ops max6902_rtc_ops = { - .read_time = max6902_read_time, - .set_time = max6902_set_time, -}; - -static int __devinit max6902_probe(struct spi_device *spi) -{ - struct rtc_device *rtc; - unsigned char tmp; - struct max6902 *chip; - int res; - - rtc = rtc_device_register("max6902", - &spi->dev, &max6902_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - - chip = kzalloc(sizeof *chip, GFP_KERNEL); - if (!chip) { - rtc_device_unregister(rtc); - return -ENOMEM; - } - chip->rtc = rtc; - dev_set_drvdata(&spi->dev, chip); - - res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); - if (res) { - rtc_device_unregister(rtc); - return res; - } - - return 0; -} - -static int __devexit max6902_remove(struct spi_device *spi) -{ - struct max6902 *chip = platform_get_drvdata(spi); - struct rtc_device *rtc = chip->rtc; - - if (rtc) - rtc_device_unregister(rtc); - - kfree(chip); - - return 0; -} - -static struct spi_driver max6902_driver = { - .driver = { - .name = "max6902", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = max6902_probe, - .remove = __devexit_p(max6902_remove), -}; - -static __init int max6902_init(void) -{ - printk("max6902 spi driver\n"); - return spi_register_driver(&max6902_driver); -} -module_init(max6902_init); - -static __exit void max6902_exit(void) -{ - spi_unregister_driver(&max6902_driver); -} -module_exit(max6902_exit); - -MODULE_DESCRIPTION ("max6902 spi RTC driver"); -MODULE_AUTHOR ("Raphael Assenat"); -MODULE_LICENSE ("GPL"); diff --git a/trunk/drivers/rtc/rtc-pcf8583.c b/trunk/drivers/rtc/rtc-pcf8583.c deleted file mode 100644 index b235a30cb661..000000000000 --- a/trunk/drivers/rtc/rtc-pcf8583.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * drivers/rtc/rtc-pcf8583.c - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Driver for PCF8583 RTC & RAM chip - * - * Converted to the generic RTC susbsystem by G. Liakhovetski (2006) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -struct rtc_mem { - unsigned int loc; - unsigned int nr; - unsigned char *data; -}; - -struct pcf8583 { - struct i2c_client client; - struct rtc_device *rtc; - unsigned char ctrl; -}; - -#define CTRL_STOP 0x80 -#define CTRL_HOLD 0x40 -#define CTRL_32KHZ 0x00 -#define CTRL_MASK 0x08 -#define CTRL_ALARMEN 0x04 -#define CTRL_ALARM 0x02 -#define CTRL_TIMER 0x01 - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Module parameters */ -I2C_CLIENT_INSMOD; - -static struct i2c_driver pcf8583_driver; - -#define get_ctrl(x) ((struct pcf8583 *)i2c_get_clientdata(x))->ctrl -#define set_ctrl(x, v) get_ctrl(x) = v - -#define CMOS_YEAR (64 + 128) -#define CMOS_CHECKSUM (63) - -static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt) -{ - unsigned char buf[8], addr[1] = { 1 }; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = 6, - .buf = buf, - } - }; - int ret; - - memset(buf, 0, sizeof(buf)); - - ret = i2c_transfer(client->adapter, msgs, 2); - if (ret == 2) { - dt->tm_year = buf[4] >> 6; - dt->tm_wday = buf[5] >> 5; - - buf[4] &= 0x3f; - buf[5] &= 0x1f; - - dt->tm_sec = BCD_TO_BIN(buf[1]); - dt->tm_min = BCD_TO_BIN(buf[2]); - dt->tm_hour = BCD_TO_BIN(buf[3]); - dt->tm_mday = BCD_TO_BIN(buf[4]); - dt->tm_mon = BCD_TO_BIN(buf[5]); - } - - return ret == 2 ? 0 : -EIO; -} - -static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo) -{ - unsigned char buf[8]; - int ret, len = 6; - - buf[0] = 0; - buf[1] = get_ctrl(client) | 0x80; - buf[2] = 0; - buf[3] = BIN_TO_BCD(dt->tm_sec); - buf[4] = BIN_TO_BCD(dt->tm_min); - buf[5] = BIN_TO_BCD(dt->tm_hour); - - if (datetoo) { - len = 8; - buf[6] = BIN_TO_BCD(dt->tm_mday) | (dt->tm_year << 6); - buf[7] = BIN_TO_BCD(dt->tm_mon) | (dt->tm_wday << 5); - } - - ret = i2c_master_send(client, (char *)buf, len); - if (ret != len) - return -EIO; - - buf[1] = get_ctrl(client); - ret = i2c_master_send(client, (char *)buf, 2); - - return ret == 2 ? 0 : -EIO; -} - -static int pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl) -{ - *ctrl = get_ctrl(client); - return 0; -} - -static int pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl) -{ - unsigned char buf[2]; - - buf[0] = 0; - buf[1] = *ctrl; - set_ctrl(client, *ctrl); - - return i2c_master_send(client, (char *)buf, 2); -} - -static int pcf8583_read_mem(struct i2c_client *client, struct rtc_mem *mem) -{ - unsigned char addr[1]; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = mem->nr, - .buf = mem->data, - } - }; - - if (mem->loc < 8) - return -EINVAL; - - addr[0] = mem->loc; - - return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; -} - -static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem) -{ - unsigned char addr[1]; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_NOSTART, - .len = mem->nr, - .buf = mem->data, - } - }; - - if (mem->loc < 8) - return -EINVAL; - - addr[0] = mem->loc; - - return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; -} - -static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned char ctrl, year[2]; - struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year }; - int real_year, year_offset, err; - - /* - * Ensure that the RTC is running. - */ - pcf8583_get_ctrl(client, &ctrl); - if (ctrl & (CTRL_STOP | CTRL_HOLD)) { - unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD); - - printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n", - ctrl, new_ctrl); - - if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0) - return err; - } - - if (pcf8583_get_datetime(client, tm) || - pcf8583_read_mem(client, &mem)) - return -EIO; - - real_year = year[0]; - - /* - * The RTC year holds the LSB two bits of the current - * year, which should reflect the LSB two bits of the - * CMOS copy of the year. Any difference indicates - * that we have to correct the CMOS version. - */ - year_offset = tm->tm_year - (real_year & 3); - if (year_offset < 0) - /* - * RTC year wrapped. Adjust it appropriately. - */ - year_offset += 4; - - tm->tm_year = real_year + year_offset + year[1] * 100; - - return 0; -} - -static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned char year[2], chk; - struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; - struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; - int ret; - - /* - * The RTC's own 2-bit year must reflect the least - * significant two bits of the CMOS year. - */ - - ret = pcf8583_set_datetime(client, tm, 1); - if (ret) - return ret; - - ret = pcf8583_read_mem(client, &cmos_check); - if (ret) - return ret; - - ret = pcf8583_read_mem(client, &cmos_year); - if (ret) - return ret; - - chk -= year[1] + year[0]; - - year[1] = tm->tm_year / 100; - year[0] = tm->tm_year % 100; - - chk += year[1] + year[0]; - - ret = pcf8583_write_mem(client, &cmos_year); - - if (ret) - return ret; - - ret = pcf8583_write_mem(client, &cmos_check); - - return ret; -} - -static struct rtc_class_ops pcf8583_rtc_ops = { - .read_time = pcf8583_rtc_read_time, - .set_time = pcf8583_rtc_set_time, -}; - -static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind); - -static int pcf8583_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, pcf8583_probe); -} - -static int pcf8583_detach(struct i2c_client *client) -{ - int err; - struct pcf8583 *pcf = i2c_get_clientdata(client); - struct rtc_device *rtc = pcf->rtc; - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(pcf); - return 0; -} - -static struct i2c_driver pcf8583_driver = { - .driver = { - .name = "pcf8583", - }, - .id = I2C_DRIVERID_PCF8583, - .attach_adapter = pcf8583_attach, - .detach_client = pcf8583_detach, -}; - -static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind) -{ - struct pcf8583 *pcf; - struct i2c_client *client; - struct rtc_device *rtc; - unsigned char buf[1], ad[1] = { 0 }; - int err; - struct i2c_msg msgs[2] = { - { - .addr = addr, - .flags = 0, - .len = 1, - .buf = ad, - }, { - .addr = addr, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); - if (!pcf) - return -ENOMEM; - - client = &pcf->client; - - client->addr = addr; - client->adapter = adap; - client->driver = &pcf8583_driver; - - strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE); - - if (i2c_transfer(client->adapter, msgs, 2) != 2) { - err = -EIO; - goto exit_kfree; - } - - err = i2c_attach_client(client); - - if (err) - goto exit_kfree; - - rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev, - &pcf8583_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } - - pcf->rtc = rtc; - i2c_set_clientdata(client, pcf); - set_ctrl(client, buf[0]); - - return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(pcf); - - return err; -} - -static __init int pcf8583_init(void) -{ - return i2c_add_driver(&pcf8583_driver); -} - -static __exit void pcf8583_exit(void) -{ - i2c_del_driver(&pcf8583_driver); -} - -module_init(pcf8583_init); -module_exit(pcf8583_exit); - -MODULE_AUTHOR("Russell King"); -MODULE_DESCRIPTION("PCF8583 I2C RTC driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c deleted file mode 100644 index ee538632660b..000000000000 --- a/trunk/drivers/rtc/rtc-pl031.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * drivers/rtc/rtc-pl031.c - * - * Real Time Clock interface for ARM AMBA PrimeCell 031 RTC - * - * Author: Deepak Saxena - * - * Copyright 2006 (c) MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -/* - * Register definitions - */ -#define RTC_DR 0x00 /* Data read register */ -#define RTC_MR 0x04 /* Match register */ -#define RTC_LR 0x08 /* Data load register */ -#define RTC_CR 0x0c /* Control register */ -#define RTC_IMSC 0x10 /* Interrupt mask and set register */ -#define RTC_RIS 0x14 /* Raw interrupt status register */ -#define RTC_MIS 0x18 /* Masked interrupt status register */ -#define RTC_ICR 0x1c /* Interrupt clear register */ - -struct pl031_local { - struct rtc_device *rtc; - void __iomem *base; -}; - -static irqreturn_t pl031_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct rtc_device *rtc = dev_id; - - rtc_update_irq(&rtc->class_dev, 1, RTC_AF); - - return IRQ_HANDLED; -} - -static int pl031_open(struct device *dev) -{ - /* - * We request IRQ in pl031_probe, so nothing to do here... - */ - return 0; -} - -static void pl031_release(struct device *dev) -{ -} - -static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - - switch (cmd) { - case RTC_AIE_OFF: - __raw_writel(1, ldata->base + RTC_MIS); - return 0; - case RTC_AIE_ON: - __raw_writel(0, ldata->base + RTC_MIS); - return 0; - } - - return -ENOIOCTLCMD; -} - -static int pl031_read_time(struct device *dev, struct rtc_time *tm) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - - rtc_time_to_tm(__raw_readl(ldata->base + RTC_DR), tm); - - return 0; -} - -static int pl031_set_time(struct device *dev, struct rtc_time *tm) -{ - unsigned long time; - struct pl031_local *ldata = dev_get_drvdata(dev); - - rtc_tm_to_time(tm, &time); - __raw_writel(time, ldata->base + RTC_LR); - - return 0; -} - -static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - - rtc_time_to_tm(__raw_readl(ldata->base + RTC_MR), &alarm->time); - alarm->pending = __raw_readl(ldata->base + RTC_RIS); - alarm->enabled = __raw_readl(ldata->base + RTC_IMSC); - - return 0; -} - -static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - unsigned long time; - - rtc_tm_to_time(&alarm->time, &time); - - __raw_writel(time, ldata->base + RTC_MR); - __raw_writel(!alarm->enabled, ldata->base + RTC_MIS); - - return 0; -} - -static struct rtc_class_ops pl031_ops = { - .open = pl031_open, - .release = pl031_release, - .ioctl = pl031_ioctl, - .read_time = pl031_read_time, - .set_time = pl031_set_time, - .read_alarm = pl031_read_alarm, - .set_alarm = pl031_set_alarm, -}; - -static int pl031_remove(struct amba_device *adev) -{ - struct pl031_local *ldata = dev_get_drvdata(&adev->dev); - - if (ldata) { - dev_set_drvdata(&adev->dev, NULL); - free_irq(adev->irq[0], ldata->rtc); - rtc_device_unregister(ldata->rtc); - iounmap(ldata->base); - kfree(ldata); - } - - return 0; -} - -static int pl031_probe(struct amba_device *adev, void *id) -{ - int ret; - struct pl031_local *ldata; - - - ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); - if (!ldata) { - ret = -ENOMEM; - goto out; - } - dev_set_drvdata(&adev->dev, ldata); - - ldata->base = ioremap(adev->res.start, - adev->res.end - adev->res.start + 1); - if (!ldata->base) { - ret = -ENOMEM; - goto out_no_remap; - } - - if (request_irq(adev->irq[0], pl031_interrupt, SA_INTERRUPT, - "rtc-pl031", ldata->rtc)) { - ret = -EIO; - goto out_no_irq; - } - - ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops, - THIS_MODULE); - if (IS_ERR(ldata->rtc)) { - ret = PTR_ERR(ldata->rtc); - goto out_no_rtc; - } - - return 0; - -out_no_rtc: - free_irq(adev->irq[0], ldata->rtc); -out_no_irq: - iounmap(ldata->base); -out_no_remap: - dev_set_drvdata(&adev->dev, NULL); - kfree(ldata); -out: - return ret; -} - -static struct amba_id pl031_ids[] __initdata = { - { - .id = 0x00041031, - .mask = 0x000fffff, }, - {0, 0}, -}; - -static struct amba_driver pl031_driver = { - .drv = { - .name = "rtc-pl031", - }, - .id_table = pl031_ids, - .probe = pl031_probe, - .remove = pl031_remove, -}; - -static int __init pl031_init(void) -{ - return amba_driver_register(&pl031_driver); -} - -static void __exit pl031_exit(void) -{ - amba_driver_unregister(&pl031_driver); -} - -module_init(pl031_init); -module_exit(pl031_exit); - -MODULE_AUTHOR("Deepak Saxena 64) && !capable(CAP_SYS_RESOURCE)) + return -EACCES; spin_lock_irq(&sa1100_rtc_lock); OSMR1 = TIMER_FREQ/rtc_freq + OSCR; OIER |= OIER_E1; @@ -240,6 +242,8 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, case RTC_IRQP_SET: if (arg < 1 || arg > TIMER_FREQ) return -EINVAL; + if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) + return -EACCES; rtc_freq = arg; return 0; } diff --git a/trunk/drivers/rtc/rtc-v3020.c b/trunk/drivers/rtc/rtc-v3020.c deleted file mode 100644 index a40f400acff6..000000000000 --- a/trunk/drivers/rtc/rtc-v3020.c +++ /dev/null @@ -1,264 +0,0 @@ -/* drivers/rtc/rtc-v3020.c - * - * Copyright (C) 2006 8D Technologies inc. - * Copyright (C) 2004 Compulab Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Driver for the V3020 RTC - * - * Changelog: - * - * 10-May-2006: Raphael Assenat - * - Converted to platform driver - * - Use the generic rtc class - * - * ??-???-2004: Someone at Compulab - * - Initial driver creation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#undef DEBUG - -struct v3020 { - void __iomem *ioaddress; - int leftshift; - struct rtc_device *rtc; -}; - -static void v3020_set_reg(struct v3020 *chip, unsigned char address, - unsigned char data) -{ - int i; - unsigned char tmp; - - tmp = address; - for (i = 0; i < 4; i++) { - writel((tmp & 1) << chip->leftshift, chip->ioaddress); - tmp >>= 1; - } - - /* Commands dont have data */ - if (!V3020_IS_COMMAND(address)) { - for (i = 0; i < 8; i++) { - writel((data & 1) << chip->leftshift, chip->ioaddress); - data >>= 1; - } - } -} - -static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) -{ - unsigned int data=0; - int i; - - for (i = 0; i < 4; i++) { - writel((address & 1) << chip->leftshift, chip->ioaddress); - address >>= 1; - } - - for (i = 0; i < 8; i++) { - data >>= 1; - if (readl(chip->ioaddress) & (1 << chip->leftshift)) - data |= 0x80; - } - - return data; -} - -static int v3020_read_time(struct device *dev, struct rtc_time *dt) -{ - struct v3020 *chip = dev_get_drvdata(dev); - int tmp; - - /* Copy the current time to ram... */ - v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0); - - /* ...and then read constant values. */ - tmp = v3020_get_reg(chip, V3020_SECONDS); - dt->tm_sec = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_MINUTES); - dt->tm_min = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_HOURS); - dt->tm_hour = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_MONTH_DAY); - dt->tm_mday = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_MONTH); - dt->tm_mon = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_WEEK_DAY); - dt->tm_wday = BCD2BIN(tmp); - tmp = v3020_get_reg(chip, V3020_YEAR); - dt->tm_year = BCD2BIN(tmp)+100; - -#ifdef DEBUG - printk("\n%s : Read RTC values\n",__FUNCTION__); - printk("tm_hour: %i\n",dt->tm_hour); - printk("tm_min : %i\n",dt->tm_min); - printk("tm_sec : %i\n",dt->tm_sec); - printk("tm_year: %i\n",dt->tm_year); - printk("tm_mon : %i\n",dt->tm_mon); - printk("tm_mday: %i\n",dt->tm_mday); - printk("tm_wday: %i\n",dt->tm_wday); -#endif - - return 0; -} - - -static int v3020_set_time(struct device *dev, struct rtc_time *dt) -{ - struct v3020 *chip = dev_get_drvdata(dev); - -#ifdef DEBUG - printk("\n%s : Setting RTC values\n",__FUNCTION__); - printk("tm_sec : %i\n",dt->tm_sec); - printk("tm_min : %i\n",dt->tm_min); - printk("tm_hour: %i\n",dt->tm_hour); - printk("tm_mday: %i\n",dt->tm_mday); - printk("tm_wday: %i\n",dt->tm_wday); - printk("tm_year: %i\n",dt->tm_year); -#endif - - /* Write all the values to ram... */ - v3020_set_reg(chip, V3020_SECONDS, BIN2BCD(dt->tm_sec)); - v3020_set_reg(chip, V3020_MINUTES, BIN2BCD(dt->tm_min)); - v3020_set_reg(chip, V3020_HOURS, BIN2BCD(dt->tm_hour)); - v3020_set_reg(chip, V3020_MONTH_DAY, BIN2BCD(dt->tm_mday)); - v3020_set_reg(chip, V3020_MONTH, BIN2BCD(dt->tm_mon)); - v3020_set_reg(chip, V3020_WEEK_DAY, BIN2BCD(dt->tm_wday)); - v3020_set_reg(chip, V3020_YEAR, BIN2BCD(dt->tm_year % 100)); - - /* ...and set the clock. */ - v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0); - - /* Compulab used this delay here. I dont know why, - * the datasheet does not specify a delay. */ - /*mdelay(5);*/ - - return 0; -} - -static struct rtc_class_ops v3020_rtc_ops = { - .read_time = v3020_read_time, - .set_time = v3020_set_time, -}; - -static int rtc_probe(struct platform_device *pdev) -{ - struct v3020_platform_data *pdata = pdev->dev.platform_data; - struct v3020 *chip; - struct rtc_device *rtc; - int retval = -EBUSY; - int i; - int temp; - - if (pdev->num_resources != 1) - return -EBUSY; - - if (pdev->resource[0].flags != IORESOURCE_MEM) - return -EBUSY; - - if (pdev == NULL) - return -EBUSY; - - chip = kzalloc(sizeof *chip, GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->leftshift = pdata->leftshift; - chip->ioaddress = ioremap(pdev->resource[0].start, 1); - if (chip->ioaddress == NULL) - goto err_chip; - - /* Make sure the v3020 expects a communication cycle - * by reading 8 times */ - for (i = 0; i < 8; i++) - temp = readl(chip->ioaddress); - - /* Test chip by doing a write/read sequence - * to the chip ram */ - v3020_set_reg(chip, V3020_SECONDS, 0x33); - if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) { - retval = -ENODEV; - goto err_io; - } - - /* Make sure frequency measurment mode, test modes, and lock - * are all disabled */ - v3020_set_reg(chip, V3020_STATUS_0, 0x0); - - dev_info(&pdev->dev, "Chip available at physical address 0x%p," - "data connected to D%d\n", - (void*)pdev->resource[0].start, - chip->leftshift); - - platform_set_drvdata(pdev, chip); - - rtc = rtc_device_register("v3020", - &pdev->dev, &v3020_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - retval = PTR_ERR(rtc); - goto err_io; - } - chip->rtc = rtc; - - return 0; - -err_io: - iounmap(chip->ioaddress); -err_chip: - kfree(chip); - - return retval; -} - -static int rtc_remove(struct platform_device *dev) -{ - struct v3020 *chip = platform_get_drvdata(dev); - struct rtc_device *rtc = chip->rtc; - - if (rtc) - rtc_device_unregister(rtc); - - iounmap(chip->ioaddress); - kfree(chip); - - return 0; -} - -static struct platform_driver rtc_device_driver = { - .probe = rtc_probe, - .remove = rtc_remove, - .driver = { - .name = "v3020", - .owner = THIS_MODULE, - }, -}; - -static __init int v3020_init(void) -{ - return platform_driver_register(&rtc_device_driver); -} - -static __exit void v3020_exit(void) -{ - platform_driver_unregister(&rtc_device_driver); -} - -module_init(v3020_init); -module_exit(v3020_exit); - -MODULE_DESCRIPTION("V3020 RTC"); -MODULE_AUTHOR("Raphael Assenat"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index 4b9291dd4443..277596c302e3 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -81,6 +81,7 @@ MODULE_LICENSE("GPL"); #define RTC_FREQUENCY 32768 #define MAX_PERIODIC_RATE 6553 +#define MAX_USER_PERIODIC_RATE 64 static void __iomem *rtc1_base; static void __iomem *rtc2_base; @@ -93,7 +94,7 @@ static void __iomem *rtc2_base; static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ -static DEFINE_SPINLOCK(rtc_lock); +static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; static char rtc_name[] = "RTC"; static unsigned long periodic_frequency; static unsigned long periodic_count; @@ -239,6 +240,9 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long if (arg > MAX_PERIODIC_RATE) return -EINVAL; + if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) + return -EACCES; + periodic_frequency = arg; count = RTC_FREQUENCY; @@ -259,6 +263,10 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long /* Doesn't support before 1900 */ if (arg < 1900) return -EINVAL; + + if (capable(CAP_SYS_TIME) == 0) + return -EACCES; + epoch = arg; break; default: diff --git a/trunk/drivers/s390/block/dasd_eer.c b/trunk/drivers/s390/block/dasd_eer.c index 2d8af709947f..2d946b6ca074 100644 --- a/trunk/drivers/s390/block/dasd_eer.c +++ b/trunk/drivers/s390/block/dasd_eer.c @@ -89,7 +89,7 @@ struct eerbuffer { }; static LIST_HEAD(bufferlist); -static DEFINE_SPINLOCK(bufferlock); +static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); /* diff --git a/trunk/drivers/s390/char/sclp_quiesce.c b/trunk/drivers/s390/char/sclp_quiesce.c index a4c53c172db6..56fa69168898 100644 --- a/trunk/drivers/s390/char/sclp_quiesce.c +++ b/trunk/drivers/s390/char/sclp_quiesce.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -67,6 +66,8 @@ do_machine_quiesce(void) } #endif +extern void ctrl_alt_del(void); + /* Handler for quiesce event. Start shutdown procedure. */ static void sclp_quiesce_handler(struct evbuf_header *evbuf) diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index 2eded55ae88d..f94419b334f7 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -1140,9 +1140,10 @@ lcs_fix_multicast_list(struct lcs_card *card) } } /* re-insert all entries from the failed_list into ipm_list */ - list_for_each_entry_safe(ipm, tmp, &failed_list, list) - list_move_tail(&ipm->list, &card->ipm_list); - + list_for_each_entry_safe(ipm, tmp, &failed_list, list) { + list_del_init(&ipm->list); + list_add_tail(&ipm->list, &card->ipm_list); + } spin_unlock_irqrestore(&card->ipm_lock, flags); } diff --git a/trunk/drivers/s390/net/qeth_eddp.c b/trunk/drivers/s390/net/qeth_eddp.c index 38aad8321456..0bab60a20309 100644 --- a/trunk/drivers/s390/net/qeth_eddp.c +++ b/trunk/drivers/s390/net/qeth_eddp.c @@ -420,7 +420,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, } tcph = eddp->skb->h.th; while (eddp->skb_offset < eddp->skb->len) { - data_len = min((int)skb_shinfo(eddp->skb)->gso_size, + data_len = min((int)skb_shinfo(eddp->skb)->tso_size, (int)(eddp->skb->len - eddp->skb_offset)); /* prepare qdio hdr */ if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ @@ -515,20 +515,20 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, QETH_DBF_TEXT(trace, 5, "eddpcanp"); /* can we put multiple skbs in one page? */ - skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len); + skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); if (skbs_per_page > 1){ - ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) / + ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) / skbs_per_page + 1; ctx->elements_per_skb = 1; } else { /* no -> how many elements per skb? */ - ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len + + ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len + PAGE_SIZE) >> PAGE_SHIFT; ctx->num_pages = ctx->elements_per_skb * - (skb_shinfo(skb)->gso_segs + 1); + (skb_shinfo(skb)->tso_segs + 1); } ctx->num_elements = ctx->elements_per_skb * - (skb_shinfo(skb)->gso_segs + 1); + (skb_shinfo(skb)->tso_segs + 1); } static inline struct qeth_eddp_context * diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index 56009d768326..9e671a48cd2f 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -4417,7 +4417,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) struct qeth_eddp_context *ctx = NULL; int tx_bytes = skb->len; unsigned short nr_frags = skb_shinfo(skb)->nr_frags; - unsigned short tso_size = skb_shinfo(skb)->gso_size; + unsigned short tso_size = skb_shinfo(skb)->tso_size; int rc; QETH_DBF_TEXT(trace, 6, "sendpkt"); @@ -4453,7 +4453,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) queue = card->qdio.out_qs [qeth_get_priority_queue(card, skb, ipv, cast_type)]; - if (skb_shinfo(skb)->gso_size) + if (skb_shinfo(skb)->tso_size) large_send = card->options.large_send; /*are we able to do TSO ? If so ,prepare and send it from here */ diff --git a/trunk/drivers/s390/net/qeth_tso.h b/trunk/drivers/s390/net/qeth_tso.h index 593f298142c1..24ef40ca9562 100644 --- a/trunk/drivers/s390/net/qeth_tso.h +++ b/trunk/drivers/s390/net/qeth_tso.h @@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) hdr->ext.hdr_version = 1; hdr->ext.hdr_len = 28; /*insert non-fix values */ - hdr->ext.mss = skb_shinfo(skb)->gso_size; + hdr->ext.mss = skb_shinfo(skb)->tso_size; hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - sizeof(struct qeth_hdr_tso)); diff --git a/trunk/drivers/s390/scsi/zfcp_aux.c b/trunk/drivers/s390/scsi/zfcp_aux.c index 9cd789b8acd4..395cfc6a344f 100644 --- a/trunk/drivers/s390/scsi/zfcp_aux.c +++ b/trunk/drivers/s390/scsi/zfcp_aux.c @@ -1,8 +1,18 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. * - * (C) Copyright IBM Corp. 2002, 2006 + * linux/drivers/s390/scsi/zfcp_aux.c + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 + * + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,20 +29,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - * Driver authors: - * Martin Peschke (originator of the driver) - * Raimund Schroeder - * Aron Zeh - * Wolfgang Taphorn - * Stefan Bader - * Heiko Carstens (kernel 2.6 port of the driver) - * Andreas Herrmann - * Maxim Shchetynin - * Volker Sameske - * Ralph Wuerthner - */ - #include "zfcp_ext.h" /* accumulated log level (module parameter) */ @@ -79,9 +75,15 @@ static struct miscdevice zfcp_cfdc_misc = { /* declare driver module init/cleanup functions */ module_init(zfcp_module_init); -MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); +MODULE_AUTHOR("Heiko Carstens , " + "Andreas Herrman , " + "Martin Peschke , " + "Raimund Schroeder , " + "Wolfgang Taphorn , " + "Aron Zeh , " + "IBM Deutschland Entwicklung GmbH"); MODULE_DESCRIPTION - ("FCP (SCSI over Fibre Channel) HBA driver for IBM System z9 and zSeries"); + ("FCP (SCSI over Fibre Channel) HBA driver for IBM eServer zSeries"); MODULE_LICENSE("GPL"); module_param(device, charp, 0400); @@ -289,11 +291,12 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, goto out; } - sg_list = kzalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL); + sg_list = kmalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL); if (sg_list == NULL) { retval = -ENOMEM; goto out; } + memset(sg_list, 0, sizeof(*sg_list)); if (command != ZFCP_CFDC_IOC) { ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command); @@ -475,13 +478,14 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) sg_list->count = size >> PAGE_SHIFT; if (size & ~PAGE_MASK) sg_list->count++; - sg_list->sg = kcalloc(sg_list->count, sizeof(struct scatterlist), + sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist), GFP_KERNEL); if (sg_list->sg == NULL) { sg_list->count = 0; retval = -ENOMEM; goto out; } + memset(sg_list->sg, 0, sg_list->count * sizeof(struct scatterlist)); for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) { sg->length = min(size, PAGE_SIZE); @@ -740,7 +744,7 @@ struct zfcp_unit * zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) { struct zfcp_unit *unit, *tmp_unit; - unsigned int scsi_lun; + scsi_lun_t scsi_lun; int found; /* @@ -754,9 +758,10 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) if (unit) return NULL; - unit = kzalloc(sizeof (struct zfcp_unit), GFP_KERNEL); + unit = kmalloc(sizeof (struct zfcp_unit), GFP_KERNEL); if (!unit) return NULL; + memset(unit, 0, sizeof (struct zfcp_unit)); /* initialise reference count stuff */ atomic_set(&unit->refcount, 0); @@ -924,12 +929,13 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) */ /* try to allocate new adapter data structure (zeroed) */ - adapter = kzalloc(sizeof (struct zfcp_adapter), GFP_KERNEL); + adapter = kmalloc(sizeof (struct zfcp_adapter), GFP_KERNEL); if (!adapter) { ZFCP_LOG_INFO("error: allocation of base adapter " "structure failed\n"); goto out; } + memset(adapter, 0, sizeof (struct zfcp_adapter)); ccw_device->handler = NULL; @@ -991,6 +997,12 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* intitialise SCSI ER timer */ init_timer(&adapter->scsi_er_timer); + /* set FC service class used per default */ + adapter->fc_service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT; + + sprintf(adapter->name, "%s", zfcp_get_busid_by_adapter(adapter)); + ASCEBC(adapter->name, strlen(adapter->name)); + /* mark adapter unusable as long as sysfs registration is not complete */ atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); @@ -1127,9 +1139,10 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, return NULL; } - port = kzalloc(sizeof (struct zfcp_port), GFP_KERNEL); + port = kmalloc(sizeof (struct zfcp_port), GFP_KERNEL); if (!port) return NULL; + memset(port, 0, sizeof (struct zfcp_port)); /* initialise reference count stuff */ atomic_set(&port->refcount, 0); @@ -1341,19 +1354,18 @@ static void zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, struct fsf_status_read_buffer *status_buffer) { - struct fsf_plogi *els_plogi; + logi *els_logi = (logi *) status_buffer->payload; struct zfcp_port *port; unsigned long flags; - els_plogi = (struct fsf_plogi *) status_buffer->payload; read_lock_irqsave(&zfcp_data.config_lock, flags); list_for_each_entry(port, &adapter->port_list_head, list) { - if (port->wwpn == (*(wwn_t *) &els_plogi->serv_param.wwpn)) + if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn)) break; } read_unlock_irqrestore(&zfcp_data.config_lock, flags); - if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) { + if (!port || (port->wwpn != (*(wwn_t *) & els_logi->nport_wwn))) { ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port " "with d_id 0x%08x on adapter %s\n", status_buffer->d_id, @@ -1748,25 +1760,4 @@ zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par) return ret; } -/** - * zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields - * into zfcp_port structure - * @port: zfcp_port structure - * @plogi: plogi payload - */ -void -zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi) -{ - port->maxframe_size = plogi->serv_param.common_serv_param[7] | - ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8); - if (plogi->serv_param.class1_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS1; - if (plogi->serv_param.class2_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS2; - if (plogi->serv_param.class3_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS3; - if (plogi->serv_param.class4_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS4; -} - #undef ZFCP_LOG_AREA diff --git a/trunk/drivers/s390/scsi/zfcp_ccw.c b/trunk/drivers/s390/scsi/zfcp_ccw.c index 57d8e4bfb8d9..241136d0c6eb 100644 --- a/trunk/drivers/s390/scsi/zfcp_ccw.c +++ b/trunk/drivers/s390/scsi/zfcp_ccw.c @@ -1,8 +1,16 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_ccw.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * CCW driver related routines + * + * (C) Copyright IBM Corp. 2003, 2004 + * + * Authors: + * Martin Peschke + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/s390/scsi/zfcp_dbf.c b/trunk/drivers/s390/scsi/zfcp_dbf.c index c033145d0f19..a5f2ba9a8fdb 100644 --- a/trunk/drivers/s390/scsi/zfcp_dbf.c +++ b/trunk/drivers/s390/scsi/zfcp_dbf.c @@ -1,8 +1,12 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. * - * (C) Copyright IBM Corp. 2002, 2006 + * linux/drivers/s390/scsi/zfcp_dbf.c + * + * FCP adapter driver for IBM eServer zSeries + * + * Debugging facilities + * + * (C) Copyright IBM Corp. 2005 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 2df512a18e2c..6eba56cd89ba 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -1,8 +1,19 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * + * linux/drivers/s390/scsi/zfcp_def.h + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 * - * (C) Copyright IBM Corp. 2002, 2006 + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann + * Volker Sameske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,6 +50,7 @@ #include #include #include +#include "../../fc4/fc.h" #include "zfcp_fsf.h" #include #include @@ -52,7 +64,7 @@ /********************* GENERAL DEFINES *********************************/ /* zfcp version number, it consists of major, minor, and patch-level number */ -#define ZFCP_VERSION "4.7.0" +#define ZFCP_VERSION "4.5.0" /** * zfcp_sg_to_address - determine kernel address from struct scatterlist @@ -77,9 +89,13 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) list->offset = ((unsigned long) address) & (PAGE_SIZE - 1); } -#define REQUEST_LIST_SIZE 128 - /********************* SCSI SPECIFIC DEFINES *********************************/ + +/* 32 bit for SCSI ID and LUN as long as the SCSI stack uses this type */ +typedef u32 scsi_id_t; +typedef u32 scsi_lun_t; + +#define ZFCP_ERP_SCSI_LOW_MEM_TIMEOUT (100*HZ) #define ZFCP_SCSI_ER_TIMEOUT (100*HZ) /********************* CIO/QDIO SPECIFIC DEFINES *****************************/ @@ -217,9 +233,8 @@ struct fcp_rsp_iu { #define RSP_CODE_TASKMAN_FAILED 5 /* see fc-fs */ -#define LS_RSCN 0x61040000 -#define LS_LOGO 0x05000000 -#define LS_PLOGI 0x03000000 +#define LS_FAN 0x60000000 +#define LS_RSCN 0x61040000 struct fcp_rscn_head { u8 command; @@ -248,6 +263,13 @@ struct fcp_rscn_element { #define ZFCP_NO_PORTS_PER_DOMAIN 0x10000 #define ZFCP_NO_PORTS_PER_FABRIC 0x1000000 +struct fcp_fan { + u32 command; + u32 fport_did; + wwn_t fport_wwpn; + wwn_t fport_wwname; +} __attribute__((packed)); + /* see fc-ph */ struct fcp_logo { u32 command; @@ -485,6 +507,9 @@ struct zfcp_rc_entry { #define ZFCP_NAME "zfcp" +/* read-only LUN sharing switch initial value */ +#define ZFCP_RO_LUN_SHARING_DEFAULTS 0 + /* independent log areas */ #define ZFCP_LOG_AREA_OTHER 0 #define ZFCP_LOG_AREA_SCSI 1 @@ -583,6 +608,7 @@ do { \ * and unit */ #define ZFCP_COMMON_FLAGS 0xfff00000 +#define ZFCP_SPECIFIC_FLAGS 0x000fffff /* common status bits */ #define ZFCP_STATUS_COMMON_REMOVE 0x80000000 @@ -607,6 +633,11 @@ do { \ #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 #define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800 +#define ZFCP_STATUS_ADAPTER_SCSI_UP \ + (ZFCP_STATUS_COMMON_UNBLOCKED | \ + ZFCP_STATUS_ADAPTER_REGISTERED) + + /* FC-PH/FC-GS well-known address identifiers for generic services */ #define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA #define ZFCP_DID_TIME_SERVICE 0xFFFFFB @@ -621,6 +652,7 @@ do { \ #define ZFCP_STATUS_PORT_NO_WWPN 0x00000008 #define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010 #define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020 +#define ZFCP_STATUS_PORT_ACCESS_DENIED 0x00000040 /* for ports with well known addresses */ #define ZFCP_STATUS_PORT_WKA \ @@ -876,12 +908,15 @@ struct zfcp_adapter { wwn_t peer_wwpn; /* P2P peer WWPN */ u32 peer_d_id; /* P2P peer D_ID */ struct ccw_device *ccw_device; /* S/390 ccw device */ + u8 fc_service_class; u32 hydra_version; /* Hydra version */ u32 fsf_lic_version; u32 adapter_features; /* FCP channel features */ u32 connection_features; /* host connection features */ u32 hardware_version; /* of FCP channel */ struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ + unsigned short scsi_host_no; /* Assigned host number */ + unsigned char name[9]; struct list_head port_list_head; /* remote port list */ struct list_head port_remove_lh; /* head of ports to be removed */ @@ -959,8 +994,6 @@ struct zfcp_port { u32 handle; /* handle assigned by FSF */ struct zfcp_erp_action erp_action; /* pending error recovery */ atomic_t erp_counter; - u32 maxframe_size; - u32 supported_classes; }; /* the struct device sysfs_device must be at the beginning of this structure. @@ -975,7 +1008,7 @@ struct zfcp_unit { refcount drop to zero */ struct zfcp_port *port; /* remote port of unit */ atomic_t status; /* status of this logical unit */ - unsigned int scsi_lun; /* own SCSI LUN */ + scsi_lun_t scsi_lun; /* own SCSI LUN */ fcp_lun_t fcp_lun; /* own FCP_LUN */ u32 handle; /* handle assigned by FSF */ struct scsi_device *device; /* scsi device struct pointer */ @@ -1019,6 +1052,11 @@ struct zfcp_data { struct list_head adapter_list_head; /* head of adapter list */ struct list_head adapter_remove_lh; /* head of adapters to be removed */ + rwlock_t status_read_lock; /* for status read thread */ + struct list_head status_read_receive_head; + struct list_head status_read_send_head; + struct semaphore status_read_sema; + wait_queue_head_t status_read_thread_wqh; u32 adapters; /* # of adapters in list */ rwlock_t config_lock; /* serialises changes to adapter/port/unit @@ -1057,6 +1095,9 @@ struct zfcp_fsf_req_pool_element { /********************** ZFCP SPECIFIC DEFINES ********************************/ +#define ZFCP_FSFREQ_CLEANUP_TIMEOUT HZ/10 + +#define ZFCP_KNOWN 0x00000001 #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 #define ZFCP_WAIT_FOR_SBAL 0x00000004 #define ZFCP_REQ_NO_QTCB 0x00000008 @@ -1064,6 +1105,9 @@ struct zfcp_fsf_req_pool_element { #define ZFCP_SET 0x00000100 #define ZFCP_CLEAR 0x00000200 +#define ZFCP_INTERRUPTIBLE 1 +#define ZFCP_UNINTERRUPTIBLE 0 + #ifndef atomic_test_mask #define atomic_test_mask(mask, target) \ ((atomic_read(target) & mask) == mask) diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c index 909731b99d26..57cb628a05aa 100644 --- a/trunk/drivers/s390/scsi/zfcp_erp.c +++ b/trunk/drivers/s390/scsi/zfcp_erp.c @@ -1,8 +1,18 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. - * - * (C) Copyright IBM Corp. 2002, 2006 + * + * linux/drivers/s390/scsi/zfcp_erp.c + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 + * + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -167,7 +177,7 @@ zfcp_fsf_scsi_er_timeout_handler(unsigned long data) * initiates adapter recovery which is done * asynchronously * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ int @@ -203,7 +213,7 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) * purpose: Wrappper for zfcp_erp_adapter_reopen_internal * used to ensure the correct locking * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ int @@ -221,6 +231,13 @@ zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ int zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask) { @@ -234,6 +251,13 @@ zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ int zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask) { @@ -247,6 +271,13 @@ zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ int zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask) { @@ -275,17 +306,20 @@ zfcp_erp_adisc(struct zfcp_port *port) int retval = 0; struct timer_list *timer; - send_els = kzalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC); + send_els = kmalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC); if (send_els == NULL) goto nomem; + memset(send_els, 0, sizeof(*send_els)); - send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC); + send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC); if (send_els->req == NULL) goto nomem; + memset(send_els->req, 0, sizeof(*send_els->req)); - send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC); + send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC); if (send_els->resp == NULL) goto nomem; + memset(send_els->resp, 0, sizeof(*send_els->resp)); address = (void *) get_zeroed_page(GFP_ATOMIC); if (address == NULL) @@ -469,7 +503,7 @@ zfcp_test_link(struct zfcp_port *port) * initiates Forced Reopen recovery which is done * asynchronously * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ static int @@ -509,7 +543,7 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask) * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal * used to ensure the correct locking * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ int @@ -536,7 +570,7 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask) * initiates Reopen recovery which is done * asynchronously * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ static int @@ -605,7 +639,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask) * initiates Reopen recovery which is done * asynchronously * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ static int @@ -778,6 +812,13 @@ zfcp_erp_unit_unblock(struct zfcp_unit *unit) atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status); } +/* + * function: + * + * purpose: + * + * returns: + */ static void zfcp_erp_action_ready(struct zfcp_erp_action *erp_action) { @@ -1315,6 +1356,13 @@ zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) { @@ -1490,6 +1538,13 @@ zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result) return result; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_statechange(int action, u32 status, @@ -1531,6 +1586,13 @@ zfcp_erp_strategy_statechange(int action, return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static inline int zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) { @@ -1543,6 +1605,13 @@ zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) !(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)); } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) { @@ -1573,6 +1642,13 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) return result; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) { @@ -1602,6 +1678,13 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) return result; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) { @@ -1681,6 +1764,13 @@ zfcp_erp_strategy_followup_actions(int action, return 0; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter) { @@ -1719,6 +1809,12 @@ zfcp_erp_wait(struct zfcp_adapter *adapter) return retval; } +/* + * function: zfcp_erp_modify_adapter_status + * + * purpose: + * + */ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u32 mask, int set_or_clear) @@ -1805,7 +1901,7 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear) * purpose: Wrappper for zfcp_erp_port_reopen_all_internal * used to ensure the correct locking * - * returns: 0 - initiated action successfully + * returns: 0 - initiated action succesfully * <0 - failed to initiate action */ int @@ -1823,6 +1919,13 @@ zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask) return retval; } +/* + * function: + * + * purpose: + * + * returns: FIXME + */ static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask) { @@ -2267,6 +2370,13 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) return ret; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action *erp_action) @@ -2435,6 +2545,13 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action) { @@ -2449,6 +2566,15 @@ zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + * + * FIXME(design): currently only prepared for fabric (nameserver!) + */ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) { @@ -2564,6 +2690,13 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) { @@ -2680,6 +2813,13 @@ zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) { @@ -2882,6 +3022,13 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) { @@ -2982,6 +3129,13 @@ zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static inline void zfcp_erp_timeout_init(struct zfcp_erp_action *erp_action) { @@ -3177,6 +3331,13 @@ zfcp_erp_action_enqueue(int action, return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ static int zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) { @@ -3241,13 +3402,9 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, break; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: case ZFCP_ERP_ACTION_REOPEN_PORT: - if (atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, - &port->status)) { - zfcp_port_put(port); - break; - } - if ((result == ZFCP_ERP_SUCCEEDED) + && !atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, + &port->status) && !port->rport) { struct fc_rport_identifiers ids; ids.node_name = port->wwnn; @@ -3261,30 +3418,12 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, "(adapter %s, wwpn=0x%016Lx)\n", zfcp_get_busid_by_port(port), port->wwpn); - else { + else scsi_flush_work(adapter->scsi_host); - port->rport->maxframe_size = port->maxframe_size; - port->rport->supported_classes = - port->supported_classes; - } - } - if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) { - fc_remote_port_delete(port->rport); - port->rport = NULL; } zfcp_port_put(port); break; case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - if (result != ZFCP_ERP_SUCCEEDED) { - struct zfcp_port *port; - list_for_each_entry(port, &adapter->port_list_head, list) - if (port->rport && - !atomic_test_mask(ZFCP_STATUS_PORT_WKA, - &port->status)) { - fc_remote_port_delete(port->rport); - port->rport = NULL; - } - } zfcp_adapter_put(adapter); break; default: @@ -3293,6 +3432,13 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, } +/* + * function: + * + * purpose: + * + * returns: FIXME + */ static int zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) { @@ -3309,6 +3455,13 @@ zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) return retval; } +/* + * function: + * + * purpose: + * + * returns: FIXME + */ static int zfcp_erp_action_dismiss_port(struct zfcp_port *port) { @@ -3327,6 +3480,13 @@ zfcp_erp_action_dismiss_port(struct zfcp_port *port) return retval; } +/* + * function: + * + * purpose: + * + * returns: FIXME + */ static int zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) { @@ -3341,6 +3501,13 @@ zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) return retval; } +/* + * function: + * + * purpose: moves erp_action to 'erp running list' + * + * returns: + */ static inline void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) { @@ -3351,6 +3518,13 @@ zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) list_move(&erp_action->list, &erp_action->adapter->erp_running_head); } +/* + * function: + * + * purpose: moves erp_action to 'erp ready list' + * + * returns: + */ static inline void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) { @@ -3361,6 +3535,11 @@ zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) list_move(&erp_action->list, &erp_action->adapter->erp_ready_head); } +/* + * function: zfcp_erp_port_boxed + * + * purpose: + */ void zfcp_erp_port_boxed(struct zfcp_port *port) { @@ -3377,6 +3556,11 @@ zfcp_erp_port_boxed(struct zfcp_port *port) zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED); } +/* + * function: zfcp_erp_unit_boxed + * + * purpose: + */ void zfcp_erp_unit_boxed(struct zfcp_unit *unit) { @@ -3390,6 +3574,11 @@ zfcp_erp_unit_boxed(struct zfcp_unit *unit) zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED); } +/* + * function: zfcp_erp_port_access_denied + * + * purpose: + */ void zfcp_erp_port_access_denied(struct zfcp_port *port) { @@ -3406,6 +3595,11 @@ zfcp_erp_port_access_denied(struct zfcp_port *port) read_unlock_irqrestore(&zfcp_data.config_lock, flags); } +/* + * function: zfcp_erp_unit_access_denied + * + * purpose: + */ void zfcp_erp_unit_access_denied(struct zfcp_unit *unit) { @@ -3419,6 +3613,11 @@ zfcp_erp_unit_access_denied(struct zfcp_unit *unit) ZFCP_SET); } +/* + * function: zfcp_erp_adapter_access_changed + * + * purpose: + */ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter) { @@ -3429,7 +3628,7 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter) return; debug_text_event(adapter->erp_dbf, 3, "a_access_recover"); - debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8); + debug_event(adapter->erp_dbf, 3, &adapter->name, 8); read_lock_irqsave(&zfcp_data.config_lock, flags); if (adapter->nameserver_port) @@ -3440,6 +3639,11 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter) read_unlock_irqrestore(&zfcp_data.config_lock, flags); } +/* + * function: zfcp_erp_port_access_changed + * + * purpose: + */ void zfcp_erp_port_access_changed(struct zfcp_port *port) { @@ -3468,6 +3672,11 @@ zfcp_erp_port_access_changed(struct zfcp_port *port) zfcp_get_busid_by_adapter(adapter), port->wwpn); } +/* + * function: zfcp_erp_unit_access_changed + * + * purpose: + */ void zfcp_erp_unit_access_changed(struct zfcp_unit *unit) { diff --git a/trunk/drivers/s390/scsi/zfcp_ext.h b/trunk/drivers/s390/scsi/zfcp_ext.h index d02366004cdd..700f5402a978 100644 --- a/trunk/drivers/s390/scsi/zfcp_ext.h +++ b/trunk/drivers/s390/scsi/zfcp_ext.h @@ -1,8 +1,18 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * + * linux/drivers/s390/scsi/zfcp_ext.h + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 * - * (C) Copyright IBM Corp. 2002, 2006 + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -115,7 +125,6 @@ extern int zfcp_nameserver_enqueue(struct zfcp_adapter *); extern int zfcp_ns_gid_pn_request(struct zfcp_erp_action *); extern int zfcp_check_ct_response(struct ct_hdr *); extern int zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *); -extern void zfcp_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); /******************************* SCSI ****************************************/ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); @@ -132,6 +141,8 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *, struct scsi_cmnd *, struct timer_list *); extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, struct timer_list *); +extern void zfcp_set_fc_host_attrs(struct zfcp_adapter *); +extern void zfcp_set_fc_rport_attrs(struct zfcp_port *); extern struct scsi_transport_template *zfcp_transport_template; extern struct fc_function_template zfcp_transport_functions; diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index 6335f9229184..662ec571d73b 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -1,8 +1,19 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. * - * (C) Copyright IBM Corp. 2002, 2006 + * linux/drivers/s390/scsi/zfcp_fsf.c + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 + * + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann + * Volker Sameske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -866,7 +877,6 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) struct zfcp_adapter *adapter = fsf_req->adapter; struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; - struct fsf_bit_error_payload *fsf_bit_error; if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer); @@ -893,37 +903,10 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: - fsf_bit_error = (struct fsf_bit_error_payload *) - status_buffer->payload; - ZFCP_LOG_NORMAL("Warning: bit error threshold data " - "received (adapter %s, " - "link failures = %i, loss of sync errors = %i, " - "loss of signal errors = %i, " - "primitive sequence errors = %i, " - "invalid transmission word errors = %i, " - "CRC errors = %i)\n", - zfcp_get_busid_by_adapter(adapter), - fsf_bit_error->link_failure_error_count, - fsf_bit_error->loss_of_sync_error_count, - fsf_bit_error->loss_of_signal_error_count, - fsf_bit_error->primitive_sequence_error_count, - fsf_bit_error->invalid_transmission_word_error_count, - fsf_bit_error->crc_error_count); - ZFCP_LOG_INFO("Additional bit error threshold data " - "(adapter %s, " - "primitive sequence event time-outs = %i, " - "elastic buffer overrun errors = %i, " - "advertised receive buffer-to-buffer credit = %i, " - "current receice buffer-to-buffer credit = %i, " - "advertised transmit buffer-to-buffer credit = %i, " - "current transmit buffer-to-buffer credit = %i)\n", - zfcp_get_busid_by_adapter(adapter), - fsf_bit_error->primitive_sequence_event_timeout_count, - fsf_bit_error->elastic_buffer_overrun_error_count, - fsf_bit_error->advertised_receive_b2b_credit, - fsf_bit_error->current_receive_b2b_credit, - fsf_bit_error->advertised_transmit_b2b_credit, - fsf_bit_error->current_transmit_b2b_credit); + ZFCP_LOG_NORMAL("Bit error threshold data received:\n"); + ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, + (char *) status_buffer, + sizeof (struct fsf_status_read_buffer)); break; case FSF_STATUS_READ_LINK_DOWN: @@ -1444,8 +1427,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, /* settings in QTCB */ fsf_req->qtcb->header.port_handle = port->handle; - fsf_req->qtcb->bottom.support.service_class = - ZFCP_FC_SERVICE_CLASS_DEFAULT; + fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; fsf_req->qtcb->bottom.support.timeout = ct->timeout; fsf_req->data = (unsigned long) ct; @@ -1514,10 +1496,18 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_port(port), - ZFCP_FC_SERVICE_CLASS_DEFAULT); + if (adapter->fc_service_class <= 3) { + ZFCP_LOG_INFO("error: adapter %s does not support fc " + "class %d.\n", + zfcp_get_busid_by_port(port), + adapter->fc_service_class); + } else { + ZFCP_LOG_INFO("bug: The fibre channel class at the " + "adapter %s is invalid. " + "(debug info %d)\n", + zfcp_get_busid_by_port(port), + adapter->fc_service_class); + } /* stop operation for this adapter */ debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup"); zfcp_erp_adapter_shutdown(adapter, 0); @@ -1740,8 +1730,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) /* settings in QTCB */ fsf_req->qtcb->bottom.support.d_id = d_id; - fsf_req->qtcb->bottom.support.service_class = - ZFCP_FC_SERVICE_CLASS_DEFAULT; + fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT; fsf_req->data = (unsigned long) els; @@ -1811,10 +1800,18 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_adapter(adapter), - ZFCP_FC_SERVICE_CLASS_DEFAULT); + if (adapter->fc_service_class <= 3) { + ZFCP_LOG_INFO("error: adapter %s does " + "not support fibrechannel class %d.\n", + zfcp_get_busid_by_adapter(adapter), + adapter->fc_service_class); + } else { + ZFCP_LOG_INFO("bug: The fibrechannel class at " + "adapter %s is invalid. " + "(debug info %d)\n", + zfcp_get_busid_by_adapter(adapter), + adapter->fc_service_class); + } /* stop operation for this adapter */ debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup"); zfcp_erp_adapter_shutdown(adapter, 0); @@ -1943,6 +1940,14 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) return retval; } +/* + * function: + * + * purpose: + * + * returns: address of initiated FSF request + * NULL - request could not be initiated + */ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) { @@ -2560,7 +2565,8 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status)) { if (fsf_req->qtcb->bottom.support.els1_length < - sizeof (struct fsf_plogi)) { + ((((unsigned long) &plogi->serv_param.wwpn) - + ((unsigned long) plogi)) + sizeof (u64))) { ZFCP_LOG_INFO( "warning: insufficient length of " "PLOGI payload (%i)\n", @@ -2579,10 +2585,8 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) atomic_clear_mask( ZFCP_STATUS_PORT_DID_DID, &port->status); - } else { + } else port->wwnn = plogi->serv_param.wwnn; - zfcp_plogi_evaluate(port, plogi); - } } } break; @@ -2989,8 +2993,8 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) erp_action->fsf_req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun; if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE)) - erp_action->fsf_req->qtcb->bottom.support.option = - FSF_OPEN_LUN_SUPPRESS_BOXING; + erp_action->fsf_req->qtcb->bottom.support.option = + FSF_OPEN_LUN_SUPPRESS_BOXING; atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); erp_action->fsf_req->data = (unsigned long) erp_action->unit; erp_action->fsf_req->erp_action = erp_action; @@ -3565,7 +3569,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, } /* set FC service class in QTCB (3 per default) */ - fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT; + fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class; /* set FCP_LUN in FCP_CMND IU in QTCB */ fcp_cmnd_iu->fcp_lun = unit->fcp_lun; @@ -3663,6 +3667,18 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, return retval; } +/* + * function: zfcp_fsf_send_fcp_command_task_management + * + * purpose: + * + * returns: + * + * FIXME(design): should be watched by a timeout!!! + * FIXME(design) shouldn't this be modified to return an int + * also...don't know how though + * + */ struct zfcp_fsf_req * zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, struct zfcp_unit *unit, @@ -3704,7 +3720,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, fsf_req->qtcb->header.lun_handle = unit->handle; fsf_req->qtcb->header.port_handle = unit->port->handle; fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; - fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT; + fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class; fsf_req->qtcb->bottom.io.fcp_cmnd_length = sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t); @@ -3827,10 +3843,18 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_unit(unit), - ZFCP_FC_SERVICE_CLASS_DEFAULT); + if (fsf_req->adapter->fc_service_class <= 3) { + ZFCP_LOG_NORMAL("error: The adapter %s does " + "not support fibrechannel class %d.\n", + zfcp_get_busid_by_unit(unit), + fsf_req->adapter->fc_service_class); + } else { + ZFCP_LOG_NORMAL("bug: The fibrechannel class at " + "adapter %s is invalid. " + "(debug info %d)\n", + zfcp_get_busid_by_unit(unit), + fsf_req->adapter->fc_service_class); + } /* stop operation for this adapter */ debug_text_exception(fsf_req->adapter->erp_dbf, 0, "fsf_s_class_nsup"); diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.h b/trunk/drivers/s390/scsi/zfcp_fsf.h index 71186618947c..e734415cae6d 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.h +++ b/trunk/drivers/s390/scsi/zfcp_fsf.h @@ -1,8 +1,19 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * + * linux/drivers/s390/scsi/zfcp_fsf.h + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 * - * (C) Copyright IBM Corp. 2002, 2006 + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann + * Volker Sameske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +33,8 @@ #ifndef FSF_H #define FSF_H -#define FSF_QTCB_CURRENT_VERSION 0x00000001 +#define FSF_QTCB_VERSION1 0x00000001 +#define FSF_QTCB_CURRENT_VERSION FSF_QTCB_VERSION1 /* FSF commands */ #define FSF_QTCB_FCP_CMND 0x00000001 @@ -52,7 +64,7 @@ #define FSF_CFDC_OPTION_FULL_ACCESS 0x00000002 #define FSF_CFDC_OPTION_RESTRICTED_ACCESS 0x00000004 -/* FSF protocol states */ +/* FSF protocol stati */ #define FSF_PROT_GOOD 0x00000001 #define FSF_PROT_QTCB_VERSION_ERROR 0x00000010 #define FSF_PROT_SEQ_NUMB_ERROR 0x00000020 @@ -64,7 +76,7 @@ #define FSF_PROT_REEST_QUEUE 0x00000800 #define FSF_PROT_ERROR_STATE 0x01000000 -/* FSF states */ +/* FSF stati */ #define FSF_GOOD 0x00000000 #define FSF_PORT_ALREADY_OPEN 0x00000001 #define FSF_LUN_ALREADY_OPEN 0x00000002 @@ -257,6 +269,20 @@ #define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000 #define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000 +struct fsf_queue_designator; +struct fsf_status_read_buffer; +struct fsf_port_closed_payload; +struct fsf_bit_error_payload; +union fsf_prot_status_qual; +struct fsf_qual_version_error; +struct fsf_qual_sequence_error; +struct fsf_qtcb_prefix; +struct fsf_qtcb_header; +struct fsf_qtcb_bottom_config; +struct fsf_qtcb_bottom_support; +struct fsf_qtcb_bottom_io; +union fsf_qtcb_bottom; + struct fsf_queue_designator { u8 cssid; u8 chpid; diff --git a/trunk/drivers/s390/scsi/zfcp_qdio.c b/trunk/drivers/s390/scsi/zfcp_qdio.c index 345a191926a4..1c3275163c91 100644 --- a/trunk/drivers/s390/scsi/zfcp_qdio.c +++ b/trunk/drivers/s390/scsi/zfcp_qdio.c @@ -1,8 +1,18 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_qdio.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * QDIO related routines + * + * (C) Copyright IBM Corp. 2002, 2004 + * + * Authors: + * Martin Peschke + * Raimund Schroeder + * Wolfgang Taphorn + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -168,8 +178,7 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter) init_data->cdev = adapter->ccw_device; init_data->q_format = QDIO_SCSI_QFMT; - memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8); - ASCEBC(init_data->adapter_name, 8); + memcpy(init_data->adapter_name, &adapter->name, 8); init_data->qib_param_field_format = 0; init_data->qib_param_field = NULL; init_data->input_slib_elements = NULL; diff --git a/trunk/drivers/s390/scsi/zfcp_scsi.c b/trunk/drivers/s390/scsi/zfcp_scsi.c index 46e14f22ec18..9e6d07d7b3c8 100644 --- a/trunk/drivers/s390/scsi/zfcp_scsi.c +++ b/trunk/drivers/s390/scsi/zfcp_scsi.c @@ -1,8 +1,18 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * + * linux/drivers/s390/scsi/zfcp_scsi.c + * + * FCP adapter driver for IBM eServer zSeries + * + * (C) Copyright IBM Corp. 2002, 2004 * - * (C) Copyright IBM Corp. 2002, 2006 + * Author(s): Martin Peschke + * Raimund Schroeder + * Aron Zeh + * Wolfgang Taphorn + * Stefan Bader + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,8 +45,8 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); static int zfcp_task_management_function(struct zfcp_unit *, u8, struct scsi_cmnd *); -static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, - unsigned int, unsigned int); +static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t, + scsi_lun_t); static struct device_attribute *zfcp_sysfs_sdev_attrs[]; @@ -151,6 +161,14 @@ set_driver_byte(u32 * result, char status) set_byte(result, status, 3); } +/* + * function: zfcp_scsi_slave_alloc + * + * purpose: + * + * returns: + */ + static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) { @@ -177,6 +195,14 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) return retval; } +/* + * function: zfcp_scsi_slave_destroy + * + * purpose: + * + * returns: + */ + static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) { @@ -348,9 +374,18 @@ zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, return zfcp_scsi_command_async(adapter, unit, scpnt, NULL); } +/* + * function: zfcp_unit_lookup + * + * purpose: + * + * returns: + * + * context: + */ static struct zfcp_unit * -zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id, - unsigned int lun) +zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id, + scsi_lun_t lun) { struct zfcp_port *port; struct zfcp_unit *unit, *retval = NULL; @@ -456,6 +491,13 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) return retval; } +/* + * function: zfcp_scsi_eh_device_reset_handler + * + * purpose: + * + * returns: + */ int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) { @@ -583,6 +625,13 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) return SUCCESS; } +/* + * function: + * + * purpose: + * + * returns: + */ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) { @@ -608,6 +657,10 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) adapter->scsi_host->unique_id = unique_id++; /* FIXME */ adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH; adapter->scsi_host->transportt = zfcp_transport_template; + /* + * Reverse mapping of the host number to avoid race condition + */ + adapter->scsi_host_no = adapter->scsi_host->host_no; /* * save a pointer to our own adapter data structure within @@ -625,6 +678,13 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) return retval; } +/* + * function: + * + * purpose: + * + * returns: + */ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) { @@ -643,6 +703,7 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) scsi_remove_host(shost); scsi_host_put(shost); adapter->scsi_host = NULL; + adapter->scsi_host_no = 0; atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status); return; @@ -756,9 +817,10 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost) if (!fc_stats) return NULL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) return NULL; + memset(data, 0, sizeof(*data)); ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); if (ret) { @@ -786,9 +848,10 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) int ret; adapter = (struct zfcp_adapter *)shost->hostdata[0]; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) return; + memset(data, 0, sizeof(*data)); ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); if (ret == 0) { @@ -800,18 +863,11 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) } } -static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) -{ - rport->dev_loss_tmo = timeout; -} - struct fc_function_template zfcp_transport_functions = { .show_starget_port_id = 1, .show_starget_port_name = 1, .show_starget_node_name = 1, .show_rport_supported_classes = 1, - .show_rport_maxframe_size = 1, - .show_rport_dev_loss_tmo = 1, .show_host_node_name = 1, .show_host_port_name = 1, .show_host_permanent_port_name = 1, @@ -821,7 +877,6 @@ struct fc_function_template zfcp_transport_functions = { .show_host_serial_number = 1, .get_fc_host_stats = zfcp_get_fc_host_stats, .reset_fc_host_stats = zfcp_reset_fc_host_stats, - .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo, /* no functions registered for following dynamic attributes but directly set by LLDD */ .show_host_port_type = 1, diff --git a/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c b/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c index 705c6d4428f3..b29ac25e07f3 100644 --- a/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -1,8 +1,16 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_sysfs_adapter.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * sysfs adapter related routines + * + * (C) Copyright IBM Corp. 2003, 2004 + * + * Authors: + * Martin Peschke + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/s390/scsi/zfcp_sysfs_driver.c b/trunk/drivers/s390/scsi/zfcp_sysfs_driver.c index 005e62f8593b..6622d55e0a45 100644 --- a/trunk/drivers/s390/scsi/zfcp_sysfs_driver.c +++ b/trunk/drivers/s390/scsi/zfcp_sysfs_driver.c @@ -1,8 +1,16 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_sysfs_driver.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * sysfs driver related routines + * + * (C) Copyright IBM Corp. 2003, 2004 + * + * Authors: + * Martin Peschke + * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/s390/scsi/zfcp_sysfs_port.c b/trunk/drivers/s390/scsi/zfcp_sysfs_port.c index 1320c0591431..f401d42db21c 100644 --- a/trunk/drivers/s390/scsi/zfcp_sysfs_port.c +++ b/trunk/drivers/s390/scsi/zfcp_sysfs_port.c @@ -1,8 +1,17 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_sysfs_port.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * sysfs port related routines + * + * (C) Copyright IBM Corp. 2003, 2004 + * + * Authors: + * Martin Peschke + * Heiko Carstens + * Andreas Herrmann + * Volker Sameske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/s390/scsi/zfcp_sysfs_unit.c b/trunk/drivers/s390/scsi/zfcp_sysfs_unit.c index 81a484175863..ad5dfb889bee 100644 --- a/trunk/drivers/s390/scsi/zfcp_sysfs_unit.c +++ b/trunk/drivers/s390/scsi/zfcp_sysfs_unit.c @@ -1,8 +1,17 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * linux/drivers/s390/scsi/zfcp_sysfs_unit.c * - * (C) Copyright IBM Corp. 2002, 2006 + * FCP adapter driver for IBM eServer zSeries + * + * sysfs unit related routines + * + * (C) Copyright IBM Corp. 2003, 2004 + * + * Authors: + * Martin Peschke + * Heiko Carstens + * Andreas Herrmann + * Volker Sameske * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/trunk/drivers/sbus/char/bbc_envctrl.c b/trunk/drivers/sbus/char/bbc_envctrl.c index 1cc706e11119..d89f83f769f5 100644 --- a/trunk/drivers/sbus/char/bbc_envctrl.c +++ b/trunk/drivers/sbus/char/bbc_envctrl.c @@ -575,9 +575,9 @@ int bbc_envctrl_init(void) int devidx = 0; while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { - if (!strcmp(echild->prom_node->name, "temperature")) + if (!strcmp(echild->prom_name, "temperature")) attach_one_temp(echild, temp_index++); - if (!strcmp(echild->prom_node->name, "fan-control")) + if (!strcmp(echild->prom_name, "fan-control")) attach_one_fan(echild, fan_index++); } if (temp_index != 0 && fan_index != 0) { diff --git a/trunk/drivers/sbus/char/bbc_i2c.c b/trunk/drivers/sbus/char/bbc_i2c.c index 73634371393b..3e156e005f2e 100644 --- a/trunk/drivers/sbus/char/bbc_i2c.c +++ b/trunk/drivers/sbus/char/bbc_i2c.c @@ -423,7 +423,7 @@ static int __init bbc_present(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "bbc")) + if (!strcmp(edev->prom_name, "bbc")) return 1; } } @@ -446,7 +446,7 @@ static int __init bbc_i2c_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "i2c")) { + if (!strcmp(edev->prom_name, "i2c")) { if (!attach_one_i2c(edev, index)) index++; } diff --git a/trunk/drivers/sbus/char/cpwatchdog.c b/trunk/drivers/sbus/char/cpwatchdog.c index 21737b7e86a1..5bf3dd901b65 100644 --- a/trunk/drivers/sbus/char/cpwatchdog.c +++ b/trunk/drivers/sbus/char/cpwatchdog.c @@ -755,7 +755,7 @@ static int __init wd_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->ofdev.node->name, WD_OBPNAME)) + if (!strcmp(edev->prom_name, WD_OBPNAME)) goto ebus_done; } } diff --git a/trunk/drivers/sbus/char/display7seg.c b/trunk/drivers/sbus/char/display7seg.c index d92bc8827a9e..c3a51d1fae5d 100644 --- a/trunk/drivers/sbus/char/display7seg.c +++ b/trunk/drivers/sbus/char/display7seg.c @@ -184,7 +184,7 @@ static int __init d7s_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, D7S_OBPNAME)) + if (!strcmp(edev->prom_name, D7S_OBPNAME)) goto ebus_done; } } diff --git a/trunk/drivers/sbus/char/envctrl.c b/trunk/drivers/sbus/char/envctrl.c index cf97e9efe9b6..19e8eddf887a 100644 --- a/trunk/drivers/sbus/char/envctrl.c +++ b/trunk/drivers/sbus/char/envctrl.c @@ -768,14 +768,16 @@ static void envctrl_set_mon(struct i2c_child_t *pchild, * decoding tables, monitor type, optional properties. * Return: None. */ -static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp) +static void envctrl_init_adc(struct i2c_child_t *pchild, int node) { + char chnls_desc[CHANNEL_DESC_SZ]; int i = 0, len; - char *pos; - unsigned int *pval; + char *pos = chnls_desc; /* Firmware describe channels into a stream separated by a '\0'. */ - pos = of_get_property(dp, "channels-description", &len); + len = prom_getproperty(node, "channels-description", chnls_desc, + CHANNEL_DESC_SZ); + chnls_desc[CHANNEL_DESC_SZ - 1] = '\0'; while (len > 0) { int l = strlen(pos) + 1; @@ -785,13 +787,10 @@ static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp) } /* Get optional properties. */ - pval = of_get_property(dp, "warning-temp", NULL); - if (pval) - warning_temperature = *pval; - - pval = of_get_property(dp, "shutdown-temp", NULL); - if (pval) - shutdown_temperature = *pval; + len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature, + sizeof(warning_temperature)); + len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature, + sizeof(shutdown_temperature)); } /* Function Description: Initialize child device monitoring fan status. @@ -865,18 +864,21 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild) static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, struct i2c_child_t *pchild) { - int len, i, tbls_size = 0; - struct device_node *dp = edev_child->prom_node; - void *pval; + int node, len, i, tbls_size = 0; + + node = edev_child->prom_node; /* Get device address. */ - pval = of_get_property(dp, "reg", &len); - memcpy(&pchild->addr, pval, len); + len = prom_getproperty(node, "reg", + (char *) &(pchild->addr), + sizeof(pchild->addr)); /* Get tables property. Read firmware temperature tables. */ - pval = of_get_property(dp, "translation", &len); - if (pval && len > 0) { - memcpy(pchild->tblprop_array, pval, len); + len = prom_getproperty(node, "translation", + (char *) pchild->tblprop_array, + (PCF8584_MAX_CHANNELS * + sizeof(struct pcf8584_tblprop))); + if (len > 0) { pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); for (i = 0; i < pchild->total_tbls; i++) { if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { @@ -889,12 +891,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, printk("envctrl: Failed to allocate table.\n"); return; } - pval = of_get_property(dp, "tables", &len); - if (!pval || len <= 0) { + len = prom_getproperty(node, "tables", + (char *) pchild->tables, tbls_size); + if (len <= 0) { printk("envctrl: Failed to get table.\n"); return; } - memcpy(pchild->tables, pval, len); } /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) @@ -905,11 +907,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, * 'NULL' monitor type. */ if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { - struct device_node *root_node; int len; + char prop[56]; - root_node = of_find_node_by_path("/"); - if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) { + len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop)); + if (0 < len && (0 == strncmp(prop, "SUNW,UltraSPARC-IIi-cEngine", len))) + { for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { pchild->mon_type[len] = ENVCTRL_NOMON; } @@ -918,14 +921,16 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, } /* Get the monitor channels. */ - pval = of_get_property(dp, "channels-in-use", &len); - memcpy(pchild->chnl_array, pval, len); + len = prom_getproperty(node, "channels-in-use", + (char *) pchild->chnl_array, + (PCF8584_MAX_CHANNELS * + sizeof(struct pcf8584_channel))); pchild->total_chnls = len / sizeof(struct pcf8584_channel); for (i = 0; i < pchild->total_chnls; i++) { switch (pchild->chnl_array[i].type) { case PCF8584_TEMP_TYPE: - envctrl_init_adc(pchild, dp); + envctrl_init_adc(pchild, node); break; case PCF8584_GLOBALADDR_TYPE: @@ -940,7 +945,7 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, case PCF8584_VOLTAGE_TYPE: if (pchild->i2ctype == I2C_ADC) { - envctrl_init_adc(pchild,dp); + envctrl_init_adc(pchild,node); } else { envctrl_init_voltage_status(pchild); } @@ -1041,7 +1046,7 @@ static int __init envctrl_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "bbc")) { + if (!strcmp(edev->prom_name, "bbc")) { /* If we find a boot-bus controller node, * then this envctrl driver is not for us. */ @@ -1055,14 +1060,14 @@ static int __init envctrl_init(void) */ for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "i2c")) { + if (!strcmp(edev->prom_name, "i2c")) { i2c = ioremap(edev->resource[0].start, 0x2); for_each_edevchild(edev, edev_child) { - if (!strcmp("gpio", edev_child->prom_node->name)) { + if (!strcmp("gpio", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_GPIO; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } - if (!strcmp("adc", edev_child->prom_node->name)) { + if (!strcmp("adc", edev_child->prom_name)) { i2c_childlist[i].i2ctype = I2C_ADC; envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); } diff --git a/trunk/drivers/sbus/char/flash.c b/trunk/drivers/sbus/char/flash.c index 31b8a5f6116f..2beb3dded087 100644 --- a/trunk/drivers/sbus/char/flash.c +++ b/trunk/drivers/sbus/char/flash.c @@ -71,6 +71,7 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); + vma->vm_flags |= (VM_SHM | VM_LOCKED); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) @@ -191,11 +192,9 @@ static int __init flash_init(void) } if (!sdev) { #ifdef CONFIG_PCI - struct linux_prom_registers *ebus_regs; - for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "flashprom")) + if (!strcmp(edev->prom_name, "flashprom")) goto ebus_done; } } @@ -203,23 +202,23 @@ static int __init flash_init(void) if (!edev) return -ENODEV; - ebus_regs = of_get_property(edev->prom_node, "reg", &len); - if (!ebus_regs || (len % sizeof(regs[0])) != 0) { + len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs)); + if ((len % sizeof(regs[0])) != 0) { printk("flash: Strange reg property size %d\n", len); return -ENODEV; } - nregs = len / sizeof(ebus_regs[0]); + nregs = len / sizeof(regs[0]); flash.read_base = edev->resource[0].start; - flash.read_size = ebus_regs[0].reg_size; + flash.read_size = regs[0].reg_size; if (nregs == 1) { flash.write_base = edev->resource[0].start; - flash.write_size = ebus_regs[0].reg_size; + flash.write_size = regs[0].reg_size; } else if (nregs == 2) { flash.write_base = edev->resource[1].start; - flash.write_size = ebus_regs[1].reg_size; + flash.write_size = regs[1].reg_size; } else { printk("flash: Strange number of regs %d\n", nregs); return -ENODEV; diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index d7e4bb41bd79..239e108b8ed1 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/drivers/sbus/char/openprom.c @@ -29,6 +29,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define PROMLIB_INTERNAL + #include #include #include @@ -37,10 +39,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -49,20 +51,15 @@ #include #endif -MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@skynet.be)"); -MODULE_DESCRIPTION("OPENPROM Configuration Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - /* Private data kept by the driver for each descriptor. */ typedef struct openprom_private_data { - struct device_node *current_node; /* Current node for SunOS ioctls. */ - struct device_node *lastnode; /* Last valid node used by BSD ioctls. */ + int current_node; /* Current node for SunOS ioctls. */ + int lastnode; /* Last valid node used by BSD ioctls. */ } DATA; /* ID of the PROM node containing all of the EEPROM options. */ -static struct device_node *options_node; +static int options_node = 0; /* * Copy an openpromio structure into kernel space from user space. @@ -90,8 +87,9 @@ static int copyin(struct openpromio __user *info, struct openpromio **opp_p) if (bufsize > OPROMMAXPARAM) bufsize = OPROMMAXPARAM; - if (!(*opp_p = kzalloc(sizeof(int) + bufsize + 1, GFP_KERNEL))) + if (!(*opp_p = kmalloc(sizeof(int) + bufsize + 1, GFP_KERNEL))) return -ENOMEM; + memset(*opp_p, 0, sizeof(int) + bufsize + 1); if (copy_from_user(&(*opp_p)->oprom_array, &info->oprom_array, bufsize)) { @@ -109,9 +107,10 @@ static int getstrings(struct openpromio __user *info, struct openpromio **opp_p) if (!info || !opp_p) return -EFAULT; - if (!(*opp_p = kzalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL))) + if (!(*opp_p = kmalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL))) return -ENOMEM; + memset(*opp_p, 0, sizeof(int) + OPROMMAXPARAM + 1); (*opp_p)->oprom_size = 0; n = bufsize = 0; @@ -141,164 +140,16 @@ static int copyout(void __user *info, struct openpromio *opp, int len) return 0; } -static int opromgetprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) -{ - void *pval; - int len; - - pval = of_get_property(dp, op->oprom_array, &len); - if (!pval || len <= 0 || len > bufsize) - return copyout(argp, op, sizeof(int)); - - memcpy(op->oprom_array, pval, len); - op->oprom_array[len] = '\0'; - op->oprom_size = len; - - return copyout(argp, op, sizeof(int) + bufsize); -} - -static int opromnxtprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) -{ - struct property *prop; - int len; - - if (op->oprom_array[0] == '\0') { - prop = dp->properties; - if (!prop) - return copyout(argp, op, sizeof(int)); - len = strlen(prop->name); - } else { - prop = of_find_property(dp, op->oprom_array, NULL); - - if (!prop || - !prop->next || - (len = strlen(prop->next->name)) + 1 > bufsize) - return copyout(argp, op, sizeof(int)); - - prop = prop->next; - } - - memcpy(op->oprom_array, prop->name, len); - op->oprom_array[len] = '\0'; - op->oprom_size = ++len; - - return copyout(argp, op, sizeof(int) + bufsize); -} - -static int opromsetopt(struct device_node *dp, struct openpromio *op, int bufsize) -{ - char *buf = op->oprom_array + strlen(op->oprom_array) + 1; - int len = op->oprom_array + bufsize - buf; - - return of_set_property(options_node, op->oprom_array, buf, len); -} - -static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - phandle ph; - - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - - if (bufsize < sizeof(phandle)) - return -EINVAL; - - ph = *((int *) op->oprom_array); - if (ph) { - dp = of_find_node_by_phandle(ph); - if (!dp) - return -EINVAL; - - switch (cmd) { - case OPROMNEXT: - dp = dp->sibling; - break; - - case OPROMCHILD: - dp = dp->child; - break; - - case OPROMSETCUR: - default: - break; - }; - } else { - /* Sibling of node zero is the root node. */ - if (cmd != OPROMNEXT) - return -EINVAL; - - dp = of_find_node_by_path("/"); - } - - ph = 0; - if (dp) - ph = dp->node; - - data->current_node = dp; - *((int *) op->oprom_array) = ph; - op->oprom_size = sizeof(phandle); - - return copyout(argp, op, bufsize + sizeof(int)); -} - -static int oprompci2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - int err = -EINVAL; - - if (bufsize >= 2*sizeof(int)) { -#ifdef CONFIG_PCI - struct pci_dev *pdev; - struct pcidev_cookie *pcp; - pdev = pci_find_slot (((int *) op->oprom_array)[0], - ((int *) op->oprom_array)[1]); - - pcp = pdev->sysdata; - if (pcp != NULL) { - dp = pcp->prom_node; - data->current_node = dp; - *((int *)op->oprom_array) = dp->node; - op->oprom_size = sizeof(int); - err = copyout(argp, op, bufsize + sizeof(int)); - } -#endif - } - - return err; -} - -static int oprompath2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - dp = of_find_node_by_path(op->oprom_array); - data->current_node = dp; - *((int *)op->oprom_array) = dp->node; - op->oprom_size = sizeof(int); - - return copyout(argp, op, bufsize + sizeof(int)); -} - -static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsize) -{ - char *buf = saved_command_line; - int len = strlen(buf); - - if (len > bufsize) - return -EINVAL; - - strcpy(op->oprom_array, buf); - op->oprom_size = len; - - return copyout(argp, op, bufsize + sizeof(int)); -} - /* * SunOS and Solaris /dev/openprom ioctl calls. */ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg, - struct device_node *dp) + unsigned int cmd, unsigned long arg, int node) { - DATA *data = file->private_data; + DATA *data = (DATA *) file->private_data; + char buffer[OPROMMAXPARAM+1], *buf; struct openpromio *opp; - int bufsize, error = 0; + int bufsize, len, error = 0; static int cnt; void __user *argp = (void __user *)arg; @@ -313,35 +164,119 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, switch (cmd) { case OPROMGETOPT: case OPROMGETPROP: - error = opromgetprop(argp, dp, opp, bufsize); + len = prom_getproplen(node, opp->oprom_array); + + if (len <= 0 || len > bufsize) { + error = copyout(argp, opp, sizeof(int)); + break; + } + + len = prom_getproperty(node, opp->oprom_array, buffer, bufsize); + + memcpy(opp->oprom_array, buffer, len); + opp->oprom_array[len] = '\0'; + opp->oprom_size = len; + + error = copyout(argp, opp, sizeof(int) + bufsize); break; case OPROMNXTOPT: case OPROMNXTPROP: - error = opromnxtprop(argp, dp, opp, bufsize); + buf = prom_nextprop(node, opp->oprom_array, buffer); + + len = strlen(buf); + if (len == 0 || len + 1 > bufsize) { + error = copyout(argp, opp, sizeof(int)); + break; + } + + memcpy(opp->oprom_array, buf, len); + opp->oprom_array[len] = '\0'; + opp->oprom_size = ++len; + + error = copyout(argp, opp, sizeof(int) + bufsize); break; case OPROMSETOPT: case OPROMSETOPT2: - error = opromsetopt(dp, opp, bufsize); + buf = opp->oprom_array + strlen(opp->oprom_array) + 1; + len = opp->oprom_array + bufsize - buf; + + error = prom_setprop(options_node, opp->oprom_array, + buf, len); + + if (error < 0) + error = -EINVAL; break; case OPROMNEXT: case OPROMCHILD: case OPROMSETCUR: - error = opromnext(argp, cmd, dp, opp, bufsize, data); + if (bufsize < sizeof(int)) { + error = -EINVAL; + break; + } + + node = *((int *) opp->oprom_array); + + switch (cmd) { + case OPROMNEXT: node = __prom_getsibling(node); break; + case OPROMCHILD: node = __prom_getchild(node); break; + case OPROMSETCUR: break; + } + + data->current_node = node; + *((int *)opp->oprom_array) = node; + opp->oprom_size = sizeof(int); + + error = copyout(argp, opp, bufsize + sizeof(int)); break; case OPROMPCI2NODE: - error = oprompci2node(argp, dp, opp, bufsize, data); + error = -EINVAL; + + if (bufsize >= 2*sizeof(int)) { +#ifdef CONFIG_PCI + struct pci_dev *pdev; + struct pcidev_cookie *pcp; + pdev = pci_find_slot (((int *) opp->oprom_array)[0], + ((int *) opp->oprom_array)[1]); + + pcp = pdev->sysdata; + if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) { + node = pcp->prom_node; + data->current_node = node; + *((int *)opp->oprom_array) = node; + opp->oprom_size = sizeof(int); + error = copyout(argp, opp, bufsize + sizeof(int)); + } +#endif + } break; case OPROMPATH2NODE: - error = oprompath2node(argp, dp, opp, bufsize, data); + node = prom_finddevice(opp->oprom_array); + data->current_node = node; + *((int *)opp->oprom_array) = node; + opp->oprom_size = sizeof(int); + + error = copyout(argp, opp, bufsize + sizeof(int)); break; case OPROMGETBOOTARGS: - error = opromgetbootargs(argp, opp, bufsize); + buf = saved_command_line; + + len = strlen(buf); + + if (len > bufsize) { + error = -EINVAL; + break; + } + + strcpy(opp->oprom_array, buf); + opp->oprom_size = len; + + error = copyout(argp, opp, bufsize + sizeof(int)); break; case OPROMU2P: @@ -362,14 +297,25 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, return error; } -static struct device_node *get_node(phandle n, DATA *data) -{ - struct device_node *dp = of_find_node_by_phandle(n); - if (dp) - data->lastnode = dp; +/* Return nonzero if a specific node is in the PROM device tree. */ +static int intree(int root, int node) +{ + for (; root != 0; root = prom_getsibling(root)) + if (root == node || intree(prom_getchild(root),node)) + return 1; + return 0; +} - return dp; +/* Return nonzero if a specific node is "valid". */ +static int goodnode(int n, DATA *data) +{ + if (n == data->lastnode || n == prom_root_node || n == options_node) + return 1; + if (n == 0 || n == -1 || !intree(prom_root_node,n)) + return 0; + data->lastnode = n; + return 1; } /* Copy in a whole string from userspace into kernelspace. */ @@ -384,7 +330,7 @@ static int copyin_string(char __user *user, size_t len, char **ptr) if (!tmp) return -ENOMEM; - if (copy_from_user(tmp, user, len)) { + if(copy_from_user(tmp, user, len)) { kfree(tmp); return -EFAULT; } @@ -399,187 +345,162 @@ static int copyin_string(char __user *user, size_t len, char **ptr) /* * NetBSD /dev/openprom ioctl calls. */ -static int opiocget(void __user *argp, DATA *data) +static int openprom_bsd_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) { + DATA *data = (DATA *) file->private_data; + void __user *argp = (void __user *)arg; struct opiocdesc op; - struct device_node *dp; - char *str; - void *pval; - int err, len; + int error, node, len; + char *str, *tmp; + char buffer[64]; + static int cnt; - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; + switch (cmd) { + case OPIOCGET: + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; - dp = get_node(op.op_nodeid, data); + if (!goodnode(op.op_nodeid,data)) + return -EINVAL; - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; + error = copyin_string(op.op_name, op.op_namelen, &str); + if (error) + return error; - pval = of_get_property(dp, str, &len); - err = 0; - if (!pval || len > op.op_buflen) { - err = -EINVAL; - } else { - op.op_buflen = len; - if (copy_to_user(argp, &op, sizeof(op)) || - copy_to_user(op.op_buf, pval, len)) - err = -EFAULT; - } - kfree(str); - - return err; -} + len = prom_getproplen(op.op_nodeid,str); -static int opiocnextprop(void __user *argp, DATA *data) -{ - struct opiocdesc op; - struct device_node *dp; - struct property *prop; - char *str; - int err, len; + if (len > op.op_buflen) { + kfree(str); + return -ENOMEM; + } - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; + op.op_buflen = len; - dp = get_node(op.op_nodeid, data); - if (!dp) - return -EINVAL; + if (len <= 0) { + kfree(str); + /* Verified by the above copy_from_user */ + if (__copy_to_user(argp, &op, + sizeof(op))) + return -EFAULT; + return 0; + } - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; + tmp = kmalloc(len + 1, GFP_KERNEL); + if (!tmp) { + kfree(str); + return -ENOMEM; + } - if (str[0] == '\0') { - prop = dp->properties; - } else { - prop = of_find_property(dp, str, NULL); - if (prop) - prop = prop->next; - } - kfree(str); + cnt = prom_getproperty(op.op_nodeid, str, tmp, len); + if (cnt <= 0) { + error = -EINVAL; + } else { + tmp[len] = '\0'; - if (!prop) - len = 0; - else - len = prop->length; + if (__copy_to_user(argp, &op, sizeof(op)) != 0 || + copy_to_user(op.op_buf, tmp, len) != 0) + error = -EFAULT; + } - if (len > op.op_buflen) - len = op.op_buflen; + kfree(tmp); + kfree(str); - if (copy_to_user(argp, &op, sizeof(op))) - return -EFAULT; + return error; - if (len && - copy_to_user(op.op_buf, prop->value, len)) - return -EFAULT; + case OPIOCNEXTPROP: + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; - return 0; -} + if (!goodnode(op.op_nodeid,data)) + return -EINVAL; -static int opiocset(void __user *argp, DATA *data) -{ - struct opiocdesc op; - struct device_node *dp; - char *str, *tmp; - int err; + error = copyin_string(op.op_name, op.op_namelen, &str); + if (error) + return error; - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; + tmp = prom_nextprop(op.op_nodeid,str,buffer); - dp = get_node(op.op_nodeid, data); - if (!dp) - return -EINVAL; + if (tmp) { + len = strlen(tmp); + if (len > op.op_buflen) + len = op.op_buflen; + else + op.op_buflen = len; + } else { + len = op.op_buflen = 0; + } - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; + if (!access_ok(VERIFY_WRITE, argp, sizeof(op))) { + kfree(str); + return -EFAULT; + } - err = copyin_string(op.op_buf, op.op_buflen, &tmp); - if (err) { - kfree(str); - return err; - } + if (!access_ok(VERIFY_WRITE, op.op_buf, len)) { + kfree(str); + return -EFAULT; + } - err = of_set_property(dp, str, tmp, op.op_buflen); + error = __copy_to_user(argp, &op, sizeof(op)); + if (!error) error = __copy_to_user(op.op_buf, tmp, len); - kfree(str); - kfree(tmp); + kfree(str); - return err; -} + return error; -static int opiocgetnext(unsigned int cmd, void __user *argp) -{ - struct device_node *dp; - phandle nd; + case OPIOCSET: + if (copy_from_user(&op, argp, sizeof(op))) + return -EFAULT; - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); + if (!goodnode(op.op_nodeid,data)) + return -EINVAL; - if (copy_from_user(&nd, argp, sizeof(phandle))) - return -EFAULT; + error = copyin_string(op.op_name, op.op_namelen, &str); + if (error) + return error; - if (nd == 0) { - if (cmd != OPIOCGETNEXT) - return -EINVAL; - dp = of_find_node_by_path("/"); - } else { - dp = of_find_node_by_phandle(nd); - nd = 0; - if (dp) { - if (cmd == OPIOCGETNEXT) - dp = dp->sibling; - else - dp = dp->child; + error = copyin_string(op.op_buf, op.op_buflen, &tmp); + if (error) { + kfree(str); + return error; } - } - if (dp) - nd = dp->node; - if (copy_to_user(argp, &nd, sizeof(phandle))) - return -EFAULT; - return 0; -} + len = prom_setprop(op.op_nodeid,str,tmp,op.op_buflen+1); -static int openprom_bsd_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - DATA *data = (DATA *) file->private_data; - void __user *argp = (void __user *)arg; - int err; - - switch (cmd) { - case OPIOCGET: - err = opiocget(argp, data); - break; + if (len != op.op_buflen) + return -EINVAL; - case OPIOCNEXTPROP: - err = opiocnextprop(argp, data); - break; + kfree(str); + kfree(tmp); - case OPIOCSET: - err = opiocset(argp, data); - break; + return 0; case OPIOCGETOPTNODE: - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - - if (copy_to_user(argp, &options_node->node, sizeof(phandle))) + if (copy_to_user(argp, &options_node, sizeof(int))) return -EFAULT; - return 0; case OPIOCGETNEXT: case OPIOCGETCHILD: - err = opiocgetnext(cmd, argp); - break; + if (copy_from_user(&node, argp, sizeof(int))) + return -EFAULT; + + if (cmd == OPIOCGETNEXT) + node = __prom_getsibling(node); + else + node = __prom_getchild(node); + + if (__copy_to_user(argp, &node, sizeof(int))) + return -EFAULT; + + return 0; default: + if (cnt++ < 10) + printk(KERN_INFO "openprom_bsd_ioctl: cmd 0x%X\n", cmd); return -EINVAL; - }; - - return err; + } } @@ -590,6 +511,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; + static int cnt; switch (cmd) { case OPROMGETOPT: @@ -641,8 +563,10 @@ static int openprom_ioctl(struct inode * inode, struct file * file, return openprom_bsd_ioctl(inode,file,cmd,arg); default: + if (cnt++ < 10) + printk("openprom_ioctl: cmd 0x%X, arg 0x%lX\n", cmd, arg); return -EINVAL; - }; + } } static long openprom_compat_ioctl(struct file *file, unsigned int cmd, @@ -670,7 +594,9 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd, case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE: + lock_kernel(); rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg); + lock_kernel(); break; } @@ -681,13 +607,13 @@ static int openprom_open(struct inode * inode, struct file * file) { DATA *data; - data = kmalloc(sizeof(DATA), GFP_KERNEL); + data = (DATA *) kmalloc(sizeof(DATA), GFP_KERNEL); if (!data) return -ENOMEM; - data->current_node = of_find_node_by_path("/"); - data->lastnode = data->current_node; - file->private_data = (void *) data; + data->current_node = prom_root_node; + data->lastnode = prom_root_node; + file->private_data = (void *)data; return 0; } @@ -708,30 +634,24 @@ static struct file_operations openprom_fops = { }; static struct miscdevice openprom_dev = { - .minor = SUN_OPENPROM_MINOR, - .name = "openprom", - .fops = &openprom_fops, + SUN_OPENPROM_MINOR, "openprom", &openprom_fops }; static int __init openprom_init(void) { - struct device_node *dp; - int err; - - err = misc_register(&openprom_dev); - if (err) - return err; + int error; - dp = of_find_node_by_path("/"); - dp = dp->child; - while (dp) { - if (!strcmp(dp->name, "options")) - break; - dp = dp->sibling; + error = misc_register(&openprom_dev); + if (error) { + printk(KERN_ERR "openprom: unable to get misc minor\n"); + return error; } - options_node = dp; - if (!options_node) { + options_node = prom_getchild(prom_root_node); + options_node = prom_searchsiblings(options_node,"options"); + + if (options_node == 0 || options_node == -1) { + printk(KERN_ERR "openprom: unable to find options node\n"); misc_deregister(&openprom_dev); return -EIO; } @@ -746,3 +666,4 @@ static void __exit openprom_cleanup(void) module_init(openprom_init); module_exit(openprom_cleanup); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/sbus/char/riowatchdog.c b/trunk/drivers/sbus/char/riowatchdog.c index 2a9cc8204429..d1babff6a535 100644 --- a/trunk/drivers/sbus/char/riowatchdog.c +++ b/trunk/drivers/sbus/char/riowatchdog.c @@ -211,7 +211,7 @@ static int __init riowd_bbc_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->ofdev.node->name, "bbc")) + if (!strcmp(edev->prom_name, "bbc")) goto found_bbc; } } @@ -238,7 +238,7 @@ static int __init riowd_init(void) for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->ofdev.node->name, RIOWD_NAME)) + if (!strcmp(edev->prom_name, RIOWD_NAME)) goto ebus_done; } } diff --git a/trunk/drivers/sbus/char/vfc_dev.c b/trunk/drivers/sbus/char/vfc_dev.c index ddcd330b9e89..dfdd6be551f3 100644 --- a/trunk/drivers/sbus/char/vfc_dev.c +++ b/trunk/drivers/sbus/char/vfc_dev.c @@ -623,7 +623,7 @@ static int vfc_mmap(struct file *file, struct vm_area_struct *vma) map_size = sizeof(struct vfc_regs); vma->vm_flags |= - (VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE); + (VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE); map_offset = (unsigned int) (long)dev->phys_regs; ret = io_remap_pfn_range(vma, vma->vm_start, MK_IOSPACE_PFN(dev->which_io, diff --git a/trunk/drivers/sbus/sbus.c b/trunk/drivers/sbus/sbus.c index 387a6aa8c020..5d30a3ebfccd 100644 --- a/trunk/drivers/sbus/sbus.c +++ b/trunk/drivers/sbus/sbus.c @@ -1,6 +1,7 @@ -/* sbus.c: SBus support routines. +/* $Id: sbus.c,v 1.100 2002/01/24 15:36:24 davem Exp $ + * sbus.c: SBus support routines. * - * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) */ #include @@ -13,76 +14,237 @@ #include #include #include -#include -#include #include #include -struct sbus_bus *sbus_root; +struct sbus_bus *sbus_root = NULL; -static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) -{ - unsigned long base; - void *pval; - int len; +static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } }; +#ifdef CONFIG_SPARC32 +static int interrupts[PROMINTR_MAX] __initdata = { 0 }; +#endif - sdev->prom_node = dp->node; - strcpy(sdev->prom_name, dp->name); +#ifdef CONFIG_PCI +extern int pcic_present(void); +#endif - pval = of_get_property(dp, "reg", &len); - sdev->num_registers = 0; - if (pval) { - memcpy(sdev->reg_addrs, pval, len); +/* Perhaps when I figure out more about the iommu we'll put a + * device registration routine here that probe_sbus() calls to + * setup the iommu for each Sbus. + */ + +/* We call this for each SBus device, and fill the structure based + * upon the prom device tree. We return the start of memory after + * the things we have allocated. + */ - sdev->num_registers = - len / sizeof(struct linux_prom_registers); +/* #define DEBUG_FILL */ - base = (unsigned long) sdev->reg_addrs[0].phys_addr; +static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev) +{ + unsigned long address, base; + int len; - /* Compute the slot number. */ - if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) - sdev->slot = sbus_dev_slot(base); - else - sdev->slot = sdev->reg_addrs[0].which_io; + sdev->prom_node = prom_node; + prom_getstring(prom_node, "name", + sdev->prom_name, sizeof(sdev->prom_name)); + address = prom_getint(prom_node, "address"); + len = prom_getproperty(prom_node, "reg", + (char *) sdev->reg_addrs, + sizeof(sdev->reg_addrs)); + if (len == -1) { + sdev->num_registers = 0; + goto no_regs; } - pval = of_get_property(dp, "ranges", &len); - sdev->num_device_ranges = 0; - if (pval) { - memcpy(sdev->device_ranges, pval, len); - sdev->num_device_ranges = - len / sizeof(struct linux_prom_ranges); + if (len % sizeof(struct linux_prom_registers)) { + prom_printf("fill_sbus_device: proplen for regs of %s " + " was %d, need multiple of %d\n", + sdev->prom_name, len, + (int) sizeof(struct linux_prom_registers)); + prom_halt(); + } + if (len > (sizeof(struct linux_prom_registers) * PROMREG_MAX)) { + prom_printf("fill_sbus_device: Too many register properties " + "for device %s, len=%d\n", + sdev->prom_name, len); + prom_halt(); } + sdev->num_registers = len / sizeof(struct linux_prom_registers); + sdev->ranges_applied = 0; - sbus_fill_device_irq(sdev); + base = (unsigned long) sdev->reg_addrs[0].phys_addr; - sdev->ofdev.node = dp; - if (sdev->parent) - sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; - else - sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; - sdev->ofdev.dev.bus = &sbus_bus_type; - strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name); + /* Compute the slot number. */ + if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) { + sdev->slot = sbus_dev_slot(base); + } else { + sdev->slot = sdev->reg_addrs[0].which_io; + } - if (of_device_register(&sdev->ofdev) != 0) - printk(KERN_DEBUG "sbus: device registration error for %s!\n", - sdev->ofdev.dev.bus_id); +no_regs: + len = prom_getproperty(prom_node, "ranges", + (char *)sdev->device_ranges, + sizeof(sdev->device_ranges)); + if (len == -1) { + sdev->num_device_ranges = 0; + goto no_ranges; + } + if (len % sizeof(struct linux_prom_ranges)) { + prom_printf("fill_sbus_device: proplen for ranges of %s " + " was %d, need multiple of %d\n", + sdev->prom_name, len, + (int) sizeof(struct linux_prom_ranges)); + prom_halt(); + } + if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) { + prom_printf("fill_sbus_device: Too many range properties " + "for device %s, len=%d\n", + sdev->prom_name, len); + prom_halt(); + } + sdev->num_device_ranges = + len / sizeof(struct linux_prom_ranges); + +no_ranges: + /* XXX Unfortunately, IRQ issues are very arch specific. + * XXX Pull this crud out into an arch specific area + * XXX at some point. -DaveM + */ +#ifdef CONFIG_SPARC64 + len = prom_getproperty(prom_node, "interrupts", + (char *) irqs, sizeof(irqs)); + if (len == -1 || len == 0) { + sdev->irqs[0] = 0; + sdev->num_irqs = 0; + } else { + unsigned int pri = irqs[0].pri; + + sdev->num_irqs = 1; + if (pri < 0x20) + pri += sdev->slot * 8; + + sdev->irqs[0] = sbus_build_irq(sdev->bus, pri); + } +#endif /* CONFIG_SPARC64 */ + +#ifdef CONFIG_SPARC32 + len = prom_getproperty(prom_node, "intr", + (char *)irqs, sizeof(irqs)); + if (len != -1) { + sdev->num_irqs = len / 8; + if (sdev->num_irqs == 0) { + sdev->irqs[0] = 0; + } else if (sparc_cpu_model == sun4d) { + extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); + + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri); + } else { + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = irqs[len].pri; + } + } else { + /* No "intr" node found-- check for "interrupts" node. + * This node contains SBus interrupt levels, not IPLs + * as in "intr", and no vector values. We convert + * SBus interrupt levels to PILs (platform specific). + */ + len = prom_getproperty(prom_node, "interrupts", + (char *)interrupts, sizeof(interrupts)); + if (len == -1) { + sdev->irqs[0] = 0; + sdev->num_irqs = 0; + } else { + sdev->num_irqs = len / sizeof(int); + for (len = 0; len < sdev->num_irqs; len++) { + sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]); + } + } + } +#endif /* CONFIG_SPARC32 */ } -static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) +/* This routine gets called from whoever needs the sbus first, to scan + * the SBus device tree. Currently it just prints out the devices + * found on the bus and builds trees of SBUS structs and attached + * devices. + */ + +extern void iommu_init(int iommu_node, struct sbus_bus *sbus); +extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus); +void sun4_init(void); +#ifdef CONFIG_SUN_AUXIO +extern void auxio_probe(void); +#endif + +static void __init sbus_do_child_siblings(int start_node, + struct sbus_dev *child, + struct sbus_dev *parent, + struct sbus_bus *sbus) { - void *pval; - int len; + struct sbus_dev *this_dev = child; + int this_node = start_node; + + /* Child already filled in, just need to traverse siblings. */ + child->child = NULL; + child->parent = parent; + while((this_node = prom_getsibling(this_node)) != 0) { + this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); + this_dev = this_dev->next; + this_dev->next = NULL; + this_dev->parent = parent; + + this_dev->bus = sbus; + fill_sbus_device(this_node, this_dev); + + if(prom_getchild(this_node)) { + this_dev->child = kmalloc(sizeof(struct sbus_dev), + GFP_ATOMIC); + this_dev->child->bus = sbus; + this_dev->child->next = NULL; + fill_sbus_device(prom_getchild(this_node), this_dev->child); + sbus_do_child_siblings(prom_getchild(this_node), + this_dev->child, this_dev, sbus); + } else { + this_dev->child = NULL; + } + } +} - pval = of_get_property(dp, "ranges", &len); - sbus->num_sbus_ranges = 0; - if (pval) { - memcpy(sbus->sbus_ranges, pval, len); - sbus->num_sbus_ranges = - len / sizeof(struct linux_prom_ranges); +/* + * XXX This functions appears to be a distorted version of + * prom_sbus_ranges_init(), with all sun4d stuff cut away. + * Ask DaveM what is going on here, how is sun4d supposed to work... XXX + */ +/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ + +static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus) +{ + int len; - sbus_arch_bus_ranges_init(dp->parent, sbus); + len = prom_getproperty(sbus->prom_node, "ranges", + (char *) sbus->sbus_ranges, + sizeof(sbus->sbus_ranges)); + if (len == -1 || len == 0) { + sbus->num_sbus_ranges = 0; + return; } + sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges); +#ifdef CONFIG_SPARC32 + if (sparc_cpu_model == sun4d) { + struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; + int num_iounit_ranges; + + len = prom_getproperty(parent_node, "ranges", + (char *) iounit_ranges, + sizeof (iounit_ranges)); + if (len != -1) { + num_iounit_ranges = (len/sizeof(struct linux_prom_ranges)); + prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges); + } + } +#endif } static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, @@ -160,127 +322,241 @@ static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev) } } -/* We preserve the "probe order" of these bus and device lists to give - * the same ordering as the old code. - */ -static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root) -{ - while (*root) - root = &(*root)->next; - *root = sbus; - sbus->next = NULL; -} +extern void register_proc_sparc_ioport(void); +extern void firetruck_init(void); -static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) -{ - while (*root) - root = &(*root)->next; - *root = sdev; - sdev->next = NULL; -} +#ifdef CONFIG_SUN4 +extern void sun4_dvma_init(void); +#endif -static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) +static int __init sbus_init(void) { - dp = dp->child; - while (dp) { - struct sbus_dev *sdev; - - sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); - if (sdev) { - sdev_insert(sdev, &parent->child); - - sdev->bus = sbus; - sdev->parent = parent; + int nd, this_sbus, sbus_devs, topnd, iommund; + unsigned int sbus_clock; + struct sbus_bus *sbus; + struct sbus_dev *this_dev; + int num_sbus = 0; /* How many did we find? */ - fill_sbus_device(dp, sdev); +#ifdef CONFIG_SPARC32 + register_proc_sparc_ioport(); +#endif - walk_children(dp, sdev, sbus); +#ifdef CONFIG_SUN4 + sun4_dvma_init(); + return 0; +#endif + + topnd = prom_getchild(prom_root_node); + + /* Finding the first sbus is a special case... */ + iommund = 0; + if(sparc_cpu_model == sun4u) { + nd = prom_searchsiblings(topnd, "sbus"); + if(nd == 0) { +#ifdef CONFIG_PCI + if (!pcic_present()) { + prom_printf("Neither SBUS nor PCI found.\n"); + prom_halt(); + } else { +#ifdef CONFIG_SPARC64 + firetruck_init(); +#endif + } + return 0; +#else + prom_printf("YEEE, UltraSparc sbus not found\n"); + prom_halt(); +#endif + } + } else if(sparc_cpu_model == sun4d) { + if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 || + (nd = prom_getchild(iommund)) == 0 || + (nd = prom_searchsiblings(nd, "sbi")) == 0) { + panic("sbi not found"); + } + } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) { + if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 || + (nd = prom_getchild(iommund)) == 0 || + (nd = prom_searchsiblings(nd, "sbus")) == 0) { +#ifdef CONFIG_PCI + if (!pcic_present()) { + prom_printf("Neither SBUS nor PCI found.\n"); + prom_halt(); + } + return 0; +#else + /* No reason to run further - the data access trap will occur. */ + panic("sbus not found"); +#endif } - dp = dp->sibling; } -} - -static void __init build_one_sbus(struct device_node *dp, int num_sbus) -{ - struct sbus_bus *sbus; - unsigned int sbus_clock; - struct device_node *dev_dp; - - sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); - if (!sbus) - return; - - sbus_insert(sbus, &sbus_root); - sbus->prom_node = dp->node; - - sbus_setup_iommu(sbus, dp); - - printk("sbus%d: ", num_sbus); - - sbus_clock = of_getintprop_default(dp, "clock-frequency", - (25*1000*1000)); - sbus->clock_freq = sbus_clock; - - printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), - (int) (((sbus_clock/1000)%1000 != 0) ? - (((sbus_clock/1000)%1000) + 1000) : 0)); - - strcpy(sbus->prom_name, dp->name); - - sbus_setup_arch_props(sbus, dp); - - sbus_bus_ranges_init(dp, sbus); - sbus->ofdev.node = dp; - sbus->ofdev.dev.parent = NULL; - sbus->ofdev.dev.bus = &sbus_bus_type; - strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name); - - if (of_device_register(&sbus->ofdev) != 0) - printk(KERN_DEBUG "sbus: device registration error for %s!\n", - sbus->ofdev.dev.bus_id); - - dev_dp = dp->child; - while (dev_dp) { - struct sbus_dev *sdev; + /* Ok, we've found the first one, allocate first SBus struct + * and place in chain. + */ + sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); + sbus->next = NULL; + sbus->prom_node = nd; + this_sbus = nd; - sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); - if (sdev) { - sdev_insert(sdev, &sbus->devices); + if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d) + iommu_init(iommund, sbus); - sdev->bus = sbus; - sdev->parent = NULL; - fill_sbus_device(dev_dp, sdev); + /* Loop until we find no more SBUS's */ + while(this_sbus) { +#ifdef CONFIG_SPARC64 + /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */ + if(sparc_cpu_model == sun4u) { + extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus); - walk_children(dev_dp, sdev, sbus); + sbus_iommu_init(this_sbus, sbus); + } +#endif /* CONFIG_SPARC64 */ + +#ifdef CONFIG_SPARC32 + if (sparc_cpu_model == sun4d) + iounit_init(this_sbus, iommund, sbus); +#endif /* CONFIG_SPARC32 */ + printk("sbus%d: ", num_sbus); + sbus_clock = prom_getint(this_sbus, "clock-frequency"); + if(sbus_clock == -1) + sbus_clock = (25*1000*1000); + printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), + (int) (((sbus_clock/1000)%1000 != 0) ? + (((sbus_clock/1000)%1000) + 1000) : 0)); + + prom_getstring(this_sbus, "name", + sbus->prom_name, sizeof(sbus->prom_name)); + sbus->clock_freq = sbus_clock; +#ifdef CONFIG_SPARC32 + if (sparc_cpu_model == sun4d) { + sbus->devid = prom_getint(iommund, "device-id"); + sbus->board = prom_getint(iommund, "board#"); + } +#endif + + sbus_bus_ranges_init(iommund, sbus); + + sbus_devs = prom_getchild(this_sbus); + if (!sbus_devs) { + sbus->devices = NULL; + goto next_bus; } - dev_dp = dev_dp->sibling; - } - - sbus_fixup_all_regs(sbus->devices); - - dvma_init(sbus); -} -static int __init sbus_init(void) -{ - struct device_node *dp; - const char *sbus_name = "sbus"; - int num_sbus = 0; + sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); + + this_dev = sbus->devices; + this_dev->next = NULL; + + this_dev->bus = sbus; + this_dev->parent = NULL; + fill_sbus_device(sbus_devs, this_dev); + + /* Should we traverse for children? */ + if(prom_getchild(sbus_devs)) { + /* Allocate device node */ + this_dev->child = kmalloc(sizeof(struct sbus_dev), + GFP_ATOMIC); + /* Fill it */ + this_dev->child->bus = sbus; + this_dev->child->next = NULL; + fill_sbus_device(prom_getchild(sbus_devs), + this_dev->child); + sbus_do_child_siblings(prom_getchild(sbus_devs), + this_dev->child, + this_dev, + sbus); + } else { + this_dev->child = NULL; + } - if (sbus_arch_preinit()) - return 0; + while((sbus_devs = prom_getsibling(sbus_devs)) != 0) { + /* Allocate device node */ + this_dev->next = kmalloc(sizeof(struct sbus_dev), + GFP_ATOMIC); + this_dev = this_dev->next; + this_dev->next = NULL; + + /* Fill it */ + this_dev->bus = sbus; + this_dev->parent = NULL; + fill_sbus_device(sbus_devs, this_dev); + + /* Is there a child node hanging off of us? */ + if(prom_getchild(sbus_devs)) { + /* Get new device struct */ + this_dev->child = kmalloc(sizeof(struct sbus_dev), + GFP_ATOMIC); + /* Fill it */ + this_dev->child->bus = sbus; + this_dev->child->next = NULL; + fill_sbus_device(prom_getchild(sbus_devs), + this_dev->child); + sbus_do_child_siblings(prom_getchild(sbus_devs), + this_dev->child, + this_dev, + sbus); + } else { + this_dev->child = NULL; + } + } - if (sparc_cpu_model == sun4d) - sbus_name = "sbi"; + /* Walk all devices and apply parent ranges. */ + sbus_fixup_all_regs(sbus->devices); - for_each_node_by_name(dp, sbus_name) { - build_one_sbus(dp, num_sbus); + dvma_init(sbus); + next_bus: num_sbus++; + if(sparc_cpu_model == sun4u) { + this_sbus = prom_getsibling(this_sbus); + if(!this_sbus) + break; + this_sbus = prom_searchsiblings(this_sbus, "sbus"); + } else if(sparc_cpu_model == sun4d) { + iommund = prom_getsibling(iommund); + if(!iommund) + break; + iommund = prom_searchsiblings(iommund, "io-unit"); + if(!iommund) + break; + this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi"); + } else { + this_sbus = prom_getsibling(this_sbus); + if(!this_sbus) + break; + this_sbus = prom_searchsiblings(this_sbus, "sbus"); + } + if(this_sbus) { + sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); + sbus = sbus->next; + sbus->next = NULL; + sbus->prom_node = this_sbus; + } else { + break; + } + } /* while(this_sbus) */ + if (sparc_cpu_model == sun4d) { + extern void sun4d_init_sbi_irq(void); + sun4d_init_sbi_irq(); } - - sbus_arch_postinit(); + +#ifdef CONFIG_SPARC64 + if (sparc_cpu_model == sun4u) { + firetruck_init(); + } +#endif +#ifdef CONFIG_SUN_AUXIO + if (sparc_cpu_model == sun4u) + auxio_probe (); +#endif +#ifdef CONFIG_SPARC64 + if (sparc_cpu_model == sun4u) { + extern void clock_probe(void); + + clock_probe(); + } +#endif return 0; } diff --git a/trunk/drivers/scsi/3w-9xxx.c b/trunk/drivers/scsi/3w-9xxx.c index b003baf8d404..caeb6d246e57 100644 --- a/trunk/drivers/scsi/3w-9xxx.c +++ b/trunk/drivers/scsi/3w-9xxx.c @@ -1388,7 +1388,7 @@ static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id) if (cmd->use_sg == 0) goto out; - use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL); + use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL); if (use_sg == 0) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list"); diff --git a/trunk/drivers/scsi/3w-xxxx.c b/trunk/drivers/scsi/3w-xxxx.c index 17dbd4ac8692..e8e41e6eb42a 100644 --- a/trunk/drivers/scsi/3w-xxxx.c +++ b/trunk/drivers/scsi/3w-xxxx.c @@ -405,7 +405,7 @@ static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill /* Attempt to return intelligent sense information */ if (fill_sense) { if ((command->status == 0xc7) || (command->status == 0xcb)) { - for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) { + for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) { if (command->flags == tw_sense_table[i][0]) { /* Valid bit and 'current errors' */ @@ -625,7 +625,7 @@ static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) if (aen == 0x0ff) { printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no); } else { - table_max = ARRAY_SIZE(tw_aen_string); + table_max = sizeof(tw_aen_string)/sizeof(char *); if ((aen & 0x0ff) < table_max) { if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') { printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8); @@ -786,7 +786,7 @@ static int tw_aen_drain_queue(TW_Device_Extension *tw_dev) if (aen == 0x0ff) { printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n"); } else { - table_max = ARRAY_SIZE(tw_aen_string); + table_max = sizeof(tw_aen_string)/sizeof(char *); if ((aen & 0x0ff) < table_max) { if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') { printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8); @@ -1286,7 +1286,7 @@ static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) if (cmd->use_sg == 0) return 0; - use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL); + use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL); if (use_sg == 0) { printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n"); diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index 3c683dc23541..6a0f9506ea00 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -183,10 +183,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; -struct NCR_700_sense { - unsigned char cmnd[MAX_COMMAND_SIZE]; -}; - static char *NCR_700_phase[] = { "", "after selection", @@ -320,7 +316,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); hostdata->dev = dev; - + pSlots = pScript + SLOTS_OFFSET; /* Fill in the missing routines from the host template */ @@ -336,18 +332,19 @@ NCR_700_detect(struct scsi_host_template *tpnt, tpnt->slave_destroy = NCR_700_slave_destroy; tpnt->change_queue_depth = NCR_700_change_queue_depth; tpnt->change_queue_type = NCR_700_change_queue_type; - + if(tpnt->name == NULL) tpnt->name = "53c700"; if(tpnt->proc_name == NULL) tpnt->proc_name = "53c700"; + host = scsi_host_alloc(tpnt, 4); if (!host) return NULL; memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST); - for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { + for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0] - (unsigned long)&hostdata->slots[0].SG[0]); hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset)); @@ -358,12 +355,14 @@ NCR_700_detect(struct scsi_host_template *tpnt, hostdata->slots[j].state = NCR_700_SLOT_FREE; } - for (j = 0; j < ARRAY_SIZE(SCRIPT); j++) + for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) { script[j] = bS_to_host(SCRIPT[j]); + } /* adjust all labels to be bus physical */ - for (j = 0; j < PATCHES; j++) + for(j = 0; j < PATCHES; j++) { script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); + } /* now patch up fixed addresses. */ script_patch_32(script, MessageLocation, pScript + MSGOUT_OFFSET); @@ -377,7 +376,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); hostdata->state = NCR_700_HOST_FREE; hostdata->cmd = NULL; - host->max_id = 8; + host->max_id = 7; host->max_lun = NCR_700_MAX_LUNS; BUG_ON(NCR_700_transport_template == NULL); host->transportt = NCR_700_transport_template; @@ -386,17 +385,17 @@ NCR_700_detect(struct scsi_host_template *tpnt, host->hostdata[0] = (unsigned long)hostdata; /* kick the chip */ NCR_700_writeb(0xff, host, CTEST9_REG); - if (hostdata->chip710) + if(hostdata->chip710) hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f; else hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f; hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0); - if (banner == 0) { + if(banner == 0) { printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); banner = 1; } printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, - hostdata->chip710 ? "53c710" : + hostdata->chip710 ? "53c710" : (hostdata->fast ? "53c700-66" : "53c700"), hostdata->rev, hostdata->differential ? "(Differential)" : ""); @@ -541,7 +540,6 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata) * finish routine. If we cannot queue the command when it * is properly build, we then change to NCR_700_SLOT_QUEUED */ slot->state = NCR_700_SLOT_BUSY; - slot->flags = 0; hostdata->command_slot_count++; return slot; @@ -591,7 +589,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp, if(SCp->sc_data_direction != DMA_NONE && SCp->sc_data_direction != DMA_BIDIRECTIONAL) { if(SCp->use_sg) { - dma_unmap_sg(hostdata->dev, SCp->request_buffer, + dma_unmap_sg(hostdata->dev, SCp->buffer, SCp->use_sg, SCp->sc_data_direction); } else { dma_unmap_single(hostdata->dev, slot->dma_handle, @@ -613,23 +611,30 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, (struct NCR_700_command_slot *)SCp->host_scribble; NCR_700_unmap(hostdata, SCp, slot); - if (slot->flags == NCR_700_FLAG_AUTOSENSE) { - struct NCR_700_sense *sense = SCp->device->hostdata; + dma_unmap_single(hostdata->dev, slot->pCmd, + sizeof(SCp->cmnd), DMA_TO_DEVICE); + if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) { #ifdef NCR_700_DEBUG printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", SCp, SCp->cmnd[7], result); scsi_print_sense("53c700", SCp); #endif - dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); /* restore the old result if the request sense was * successful */ if(result == 0) - result = sense->cmnd[7]; - } else - dma_unmap_single(hostdata->dev, slot->pCmd, - sizeof(SCp->cmnd), DMA_TO_DEVICE); - + result = SCp->cmnd[7]; + /* now restore the original command */ + memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd, + sizeof(SCp->data_cmnd)); + SCp->request_buffer = SCp->buffer; + SCp->request_bufflen = SCp->bufflen; + SCp->use_sg = SCp->old_use_sg; + SCp->cmd_len = SCp->old_cmd_len; + SCp->sc_data_direction = SCp->sc_old_data_direction; + SCp->underflow = SCp->old_underflow; + + } free_slot(slot, hostdata); #ifdef NCR_700_DEBUG if(NCR_700_get_depth(SCp->device) == 0 || @@ -977,7 +982,6 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, "broken device is looping in contingent allegiance: ignoring\n"); NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); } else { - struct NCR_700_sense *sense = SCp->device->hostdata; #ifdef NCR_DEBUG scsi_print_command(SCp); printk(" cmd %p has status %d, requesting sense\n", @@ -991,25 +995,27 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * data associated with the command * here */ NCR_700_unmap(hostdata, SCp, slot); - dma_unmap_single(hostdata->dev, slot->pCmd, - sizeof(SCp->cmnd), - DMA_TO_DEVICE); - - sense->cmnd[0] = REQUEST_SENSE; - sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; - sense->cmnd[2] = 0; - sense->cmnd[3] = 0; - sense->cmnd[4] = sizeof(SCp->sense_buffer); - sense->cmnd[5] = 0; + + SCp->cmnd[0] = REQUEST_SENSE; + SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5; + SCp->cmnd[2] = 0; + SCp->cmnd[3] = 0; + SCp->cmnd[4] = sizeof(SCp->sense_buffer); + SCp->cmnd[5] = 0; + SCp->cmd_len = 6; /* Here's a quiet hack: the * REQUEST_SENSE command is six bytes, * so store a flag indicating that * this was an internal sense request * and the original status at the end * of the command */ - sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; - sense->cmnd[7] = hostdata->status[0]; - slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); + SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; + SCp->cmnd[7] = hostdata->status[0]; + SCp->use_sg = 0; + SCp->sc_data_direction = DMA_FROM_DEVICE; + dma_sync_single_for_device(hostdata->dev, slot->pCmd, + SCp->cmd_len, DMA_TO_DEVICE); + SCp->request_bufflen = sizeof(SCp->sense_buffer); slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); slot->SG[0].pAddr = bS_to_host(slot->dma_handle); @@ -1021,7 +1027,6 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, /* queue the command for reissue */ slot->state = NCR_700_SLOT_QUEUED; - slot->flags = NCR_700_FLAG_AUTOSENSE; hostdata->state = NCR_700_HOST_FREE; hostdata->cmd = NULL; } @@ -1242,7 +1247,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, if(SCp->use_sg) { for(i = 0; i < SCp->use_sg + 1; i++) { - printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); + printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); } } } @@ -1401,14 +1406,12 @@ NCR_700_start_command(struct scsi_cmnd *SCp) /* keep interrupts disabled until we have the command correctly * set up so we cannot take a selection interrupt */ - hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE && - slot->flags != NCR_700_FLAG_AUTOSENSE), + hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE, SCp->device->lun); /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure * if the negotiated transfer parameters still hold, so * always renegotiate them */ - if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE || - slot->flags == NCR_700_FLAG_AUTOSENSE) { + if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) { NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); } @@ -1417,8 +1420,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp) * will refuse all tags, so send the request sense as untagged * */ if((hostdata->tag_negotiated & (1<tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE && - slot->flags != NCR_700_FLAG_AUTOSENSE)) { + && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); } @@ -1864,9 +1866,8 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) __u32 count = 0; if(SCp->use_sg) { - sg_count = dma_map_sg(hostdata->dev, - SCp->request_buffer, SCp->use_sg, - direction); + sg_count = dma_map_sg(hostdata->dev, SCp->buffer, + SCp->use_sg, direction); } else { vPtr = dma_map_single(hostdata->dev, SCp->request_buffer, @@ -1881,7 +1882,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) for(i = 0; i < sg_count; i++) { if(SCp->use_sg) { - struct scatterlist *sg = SCp->request_buffer; + struct scatterlist *sg = SCp->buffer; vPtr = sg_dma_address(&sg[i]); count = sg_dma_len(&sg[i]); @@ -2044,11 +2045,6 @@ NCR_700_slave_configure(struct scsi_device *SDp) struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; - SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); - - if (!SDp->hostdata) - return -ENOMEM; - /* to do here: allocate memory; build a queue_full list */ if(SDp->tagged_supported) { scsi_set_tag_type(SDp, MSG_ORDERED_TAG); @@ -2072,8 +2068,7 @@ NCR_700_slave_configure(struct scsi_device *SDp) STATIC void NCR_700_slave_destroy(struct scsi_device *SDp) { - kfree(SDp->hostdata); - SDp->hostdata = NULL; + /* to do here: deallocate memory */ } static int diff --git a/trunk/drivers/scsi/53c700.h b/trunk/drivers/scsi/53c700.h index 7f22a06fe5ec..a8c83bb03630 100644 --- a/trunk/drivers/scsi/53c700.h +++ b/trunk/drivers/scsi/53c700.h @@ -163,8 +163,6 @@ struct NCR_700_command_slot { #define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */ #define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */ __u8 state; - #define NCR_700_FLAG_AUTOSENSE 0x01 - __u8 flags; int tag; __u32 resume_offset; struct scsi_cmnd *cmnd; @@ -474,7 +472,8 @@ NCR_700_readl(struct Scsi_Host *host, __u32 reg) ioread32(hostdata->base + reg); #if 1 /* sanity check the register */ - BUG_ON((reg & 0x3) != 0); + if((reg & 0x3) != 0) + BUG(); #endif return value; @@ -497,7 +496,8 @@ NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg) #if 1 /* sanity check the register */ - BUG_ON((reg & 0x3) != 0); + if((reg & 0x3) != 0) + BUG(); #endif bEBus ? iowrite32be(value, hostdata->base + reg): diff --git a/trunk/drivers/scsi/53c7xx.c b/trunk/drivers/scsi/53c7xx.c index 765769a629e4..7894b8ea84bd 100644 --- a/trunk/drivers/scsi/53c7xx.c +++ b/trunk/drivers/scsi/53c7xx.c @@ -361,7 +361,7 @@ int CmdPageStart = (0 - Ent_dsa_zero - sizeof(struct NCR53c7x0_cmd)) & 0xff; static char *setup_strings[] = {"","","","","","","",""}; -#define MAX_SETUP_STRINGS ARRAY_SIZE(setup_strings) +#define MAX_SETUP_STRINGS (sizeof(setup_strings) / sizeof(char *)) #define SETUP_BUFFER_SIZE 200 static char setup_buffer[SETUP_BUFFER_SIZE]; static char setup_used[MAX_SETUP_STRINGS]; @@ -709,7 +709,7 @@ request_synchronous (int host, int target) { printk (KERN_ALERT "target %d is host ID\n", target); return -1; } - else if (target >= h->max_id) { + else if (target > h->max_id) { printk (KERN_ALERT "target %d exceeds maximum of %d\n", target, h->max_id); return -1; @@ -2190,15 +2190,15 @@ static const struct { */ -static void +static void synchronous (struct Scsi_Host *host, int target, char *msg) { struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0]; int desire, divisor, i, limit; unsigned char scntl3, sxfer; /* The diagnostic message fits on one line, even with max. width integers */ - char buf[80]; - + char buf[80]; + /* Desired transfer clock in Hz */ desire = 1000000000L / (msg[3] * 4); /* Scale the available SCSI clock by 10 so we get tenths */ @@ -2209,14 +2209,14 @@ synchronous (struct Scsi_Host *host, int target, char *msg) { msg[4] = 8; if (hostdata->options & OPTION_DEBUG_SDTR) - printk("scsi%d : optimal synchronous divisor of %d.%01d\n", + printk("scsi%d : optimal synchronous divisor of %d.%01d\n", host->host_no, divisor / 10, divisor % 10); - limit = ARRAY_SIZE(syncs) - 1; + limit = (sizeof(syncs) / sizeof(syncs[0]) -1); for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i); if (hostdata->options & OPTION_DEBUG_SDTR) - printk("scsi%d : selected synchronous divisor of %d.%01d\n", + printk("scsi%d : selected synchronous divisor of %d.%01d\n", host->host_no, syncs[i].div / 10, syncs[i].div % 10); msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4); @@ -3622,7 +3622,7 @@ NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { #ifdef LINUX_1_2 || cmd->device->id > 7 #else - || cmd->device->id >= host->max_id + || cmd->device->id > host->max_id #endif || cmd->device->id == host->this_id || hostdata->state == STATE_DISABLED) { diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 96a81cd17617..a480a3742d47 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -501,7 +501,7 @@ config SCSI_ATA_PIIX tristate "Intel PIIX/ICH SATA support" depends on SCSI_SATA && PCI help - This option enables support for ICH5/6/7/8 Serial ATA. + This option enables support for ICH5 Serial ATA. If PATA support was enabled previously, this enables support for select Intel PIIX/ICH PATA host controllers. @@ -532,16 +532,6 @@ config SCSI_PDC_ADMA If unsure, say N. -config SCSI_HPTIOP - tristate "HighPoint RocketRAID 3xxx Controller support" - depends on SCSI && PCI - help - This option enables support for HighPoint RocketRAID 3xxx - controllers. - - To compile this driver as a module, choose M here; the module - will be called hptiop. If unsure, say N. - config SCSI_SATA_QSTOR tristate "Pacific Digital SATA QStor support" depends on SCSI_SATA && PCI @@ -1169,7 +1159,7 @@ config SCSI_NCR_Q720 you do not have this SCSI card, so say N. config SCSI_NCR53C8XX_DEFAULT_TAGS - int "default tagged command queue depth" + int " default tagged command queue depth" depends on SCSI_ZALON || SCSI_NCR_Q720 default "8" ---help--- @@ -1195,7 +1185,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS There is no safe option other than using good SCSI devices. config SCSI_NCR53C8XX_MAX_TAGS - int "maximum number of queued commands" + int " maximum number of queued commands" depends on SCSI_ZALON || SCSI_NCR_Q720 default "32" ---help--- @@ -1212,7 +1202,7 @@ config SCSI_NCR53C8XX_MAX_TAGS There is no safe option and the default answer is recommended. config SCSI_NCR53C8XX_SYNC - int "synchronous transfers frequency in MHz" + int " synchronous transfers frequency in MHz" depends on SCSI_ZALON || SCSI_NCR_Q720 default "20" ---help--- @@ -1246,7 +1236,7 @@ config SCSI_NCR53C8XX_SYNC terminations and SCSI conformant devices. config SCSI_NCR53C8XX_PROFILE - bool "enable profiling" + bool " enable profiling" depends on SCSI_ZALON || SCSI_NCR_Q720 help This option allows you to enable profiling information gathering. @@ -1257,7 +1247,7 @@ config SCSI_NCR53C8XX_PROFILE The normal answer therefore is N. config SCSI_NCR53C8XX_NO_DISCONNECT - bool "not allow targets to disconnect" + bool " not allow targets to disconnect" depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 help This option is only provided for safety if you suspect some SCSI diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index ebd0cf00bf3e..81803a16f986 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -33,8 +33,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o -obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o -obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o +obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o @@ -137,7 +136,6 @@ obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o -obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_ARM) += arm/ @@ -166,7 +164,7 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) zalon7xx-objs := zalon.o ncr53c8xx.o NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o -libata-objs := libata-core.o libata-scsi.o libata-bmdma.o libata-eh.o +libata-objs := libata-core.o libata-scsi.o libata-bmdma.o oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o # Files generated that shall be removed upon make clean diff --git a/trunk/drivers/scsi/NCR5380.c b/trunk/drivers/scsi/NCR5380.c index 75f2f7ae2a8e..9f0ddbe6dc76 100644 --- a/trunk/drivers/scsi/NCR5380.c +++ b/trunk/drivers/scsi/NCR5380.c @@ -296,7 +296,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+ cmd->SCp.buffer->offset; @@ -500,7 +500,7 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) /* * Function : int should_disconnect (unsigned char cmd) * - * Purpose : decide whether a command would normally disconnect or + * Purpose : decide weather a command would normally disconnect or * not, since if it won't disconnect we should go to sleep. * * Input : cmd - opcode of SCSI command diff --git a/trunk/drivers/scsi/NCR53c406a.c b/trunk/drivers/scsi/NCR53c406a.c index 8472c5359023..ae37d3ab9c4a 100644 --- a/trunk/drivers/scsi/NCR53c406a.c +++ b/trunk/drivers/scsi/NCR53c406a.c @@ -213,16 +213,16 @@ static void *addresses[] = { (void *) 0xd8000, (void *) 0xc8000 }; -#define ADDRESS_COUNT ARRAY_SIZE(addresses) +#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned )) #endif /* USE_BIOS */ /* possible i/o port addresses */ static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; -#define PORT_COUNT ARRAY_SIZE(ports) +#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short )) /* possible interrupt channels */ static unsigned short intrs[] = { 10, 11, 12, 15 }; -#define INTR_COUNT ARRAY_SIZE(intrs) +#define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short )) /* signatures for NCR 53c406a based controllers */ #if USE_BIOS @@ -236,7 +236,7 @@ struct signature { { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82},}; -#define SIGNATURE_COUNT ARRAY_SIZE(signatures) +#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature )) #endif /* USE_BIOS */ /* ============================================================ */ diff --git a/trunk/drivers/scsi/aacraid/aachba.c b/trunk/drivers/scsi/aacraid/aachba.c index 83b5c7d085f2..642a3b4e5937 100644 --- a/trunk/drivers/scsi/aacraid/aachba.c +++ b/trunk/drivers/scsi/aacraid/aachba.c @@ -148,8 +148,6 @@ static int nondasd = -1; static int dacmode = -1; static int commit = -1; -int startup_timeout = 180; -int aif_timeout = 120; module_param(nondasd, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); @@ -157,10 +155,6 @@ module_param(dacmode, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); module_param(commit, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); -module_param(startup_timeout, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS."); -module_param(aif_timeout, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for applications to pick up AIFs before\nderegistering them. This is typically adjusted for heavily burdened systems."); int numacb = -1; module_param(numacb, int, S_IRUGO|S_IWUSR); @@ -396,7 +390,8 @@ static void get_container_name_callback(void *context, struct fib * fibptr) scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); - BUG_ON(fibptr == NULL); + if (fibptr == NULL) + BUG(); get_name_reply = (struct aac_get_name_resp *) fib_data(fibptr); /* Failure is irrelevant, using default value instead */ @@ -640,13 +635,13 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) cp[sizeof(str->pid)] = c; } else { struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); - - inqstrcpy (mp->vname, str->vid); + + inqstrcpy (mp->vname, str->vid); /* last six chars reserved for vol type */ inqstrcpy (mp->model, str->pid); } - if (tindex < ARRAY_SIZE(container_types)){ + if (tindex < (sizeof(container_types)/sizeof(char *))){ char *findit = str->pid; for ( ; *findit != ' '; findit++); /* walk till we find a space */ @@ -955,11 +950,12 @@ static void io_callback(void *context, struct fib * fibptr) smp_processor_id(), (unsigned long long)lba, jiffies); } - BUG_ON(fibptr == NULL); + if (fibptr == NULL) + BUG(); if(scsicmd->use_sg) pci_unmap_sg(dev->pdev, - (struct scatterlist *)scsicmd->request_buffer, + (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) @@ -1090,7 +1086,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) aac_build_sgraw(scsicmd, &readcmd->sg); fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); - BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); + if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) + BUG(); /* * Now send the Fib to the adapter */ @@ -1258,7 +1255,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) aac_build_sgraw(scsicmd, &writecmd->sg); fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); - BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); + if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) + BUG(); /* * Now send the Fib to the adapter */ @@ -1572,7 +1570,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * see: .c i.e. aac.c */ if (scmd_id(scsicmd) == host->this_id) { - setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); + setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; @@ -1900,7 +1898,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr) scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; - BUG_ON(fibptr == NULL); + if (fibptr == NULL) + BUG(); srbreply = (struct aac_srb_reply *) fib_data(fibptr); @@ -1914,7 +1913,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) if(scsicmd->use_sg) pci_unmap_sg(dev->pdev, - (struct scatterlist *)scsicmd->request_buffer, + (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) @@ -2219,15 +2218,15 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg) } } else if(scsicmd->request_bufflen) { - u32 addr; - scsicmd->SCp.dma_handle = pci_map_single(dev->pdev, + dma_addr_t addr; + addr = pci_map_single(dev->pdev, scsicmd->request_buffer, scsicmd->request_bufflen, scsicmd->sc_data_direction); - addr = scsicmd->SCp.dma_handle; psg->count = cpu_to_le32(1); psg->sg[0].addr = cpu_to_le32(addr); psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen); + scsicmd->SCp.dma_handle = addr; byte_count = scsicmd->request_bufflen; } return byte_count; @@ -2376,7 +2375,7 @@ static struct aac_srb_status_info srb_status_info[] = { { SRB_STATUS_SUCCESS, "Success"}, { SRB_STATUS_ABORTED, "Aborted Command"}, { SRB_STATUS_ABORT_FAILED, "Abort Failed"}, - { SRB_STATUS_ERROR, "Error Event"}, + { SRB_STATUS_ERROR, "Error Event"}, { SRB_STATUS_BUSY, "Device Busy"}, { SRB_STATUS_INVALID_REQUEST, "Invalid Request"}, { SRB_STATUS_INVALID_PATH_ID, "Invalid Path ID"}, @@ -2395,7 +2394,7 @@ static struct aac_srb_status_info srb_status_info[] = { { SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"}, { SRB_STATUS_REQUEST_FLUSHED, "Request Flushed"}, { SRB_STATUS_DELAYED_RETRY, "Delayed Retry"}, - { SRB_STATUS_INVALID_LUN, "Invalid LUN"}, + { SRB_STATUS_INVALID_LUN, "Invalid LUN"}, { SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"}, { SRB_STATUS_BAD_FUNCTION, "Bad Function"}, { SRB_STATUS_ERROR_RECOVERY, "Error Recovery"}, @@ -2410,9 +2409,11 @@ char *aac_get_status_string(u32 status) { int i; - for (i = 0; i < ARRAY_SIZE(srb_status_info); i++) - if (srb_status_info[i].status == status) + for(i=0; i < (sizeof(srb_status_info)/sizeof(struct aac_srb_status_info)); i++ ){ + if(srb_status_info[i].status == status){ return srb_status_info[i].str; + } + } return "Bad Status Code"; } diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index d0eecd4bec83..f773b0dcfc95 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -12,7 +12,7 @@ #ifndef AAC_DRIVER_BUILD # define AAC_DRIVER_BUILD 2409 -# define AAC_DRIVER_BRANCH "-mh2" +# define AAC_DRIVER_BRANCH "-mh1" #endif #define MAXIMUM_NUM_CONTAINERS 32 @@ -563,6 +563,7 @@ struct aac_queue { spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */ struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */ /* only valid for command queues which receive entries from the adapter. */ + struct list_head pendingq; /* A queue of outstanding fib's to the adapter. */ u32 numpending; /* Number of entries on outstanding queue. */ struct aac_dev * dev; /* Back pointer to adapter structure */ }; @@ -821,6 +822,11 @@ struct fib { fib_callback callback; void *callback_data; u32 flags; // u32 dmb was ulong + /* + * The following is used to put this fib context onto the + * Outstanding I/O queue. + */ + struct list_head queue; /* * And for the internal issue/reply queues (we may be able * to merge these two) @@ -1809,5 +1815,3 @@ int aac_probe_container(struct aac_dev *dev, int cid); extern int numacb; extern int acbsize; extern char aac_driver_version[]; -extern int startup_timeout; -extern int aif_timeout; diff --git a/trunk/drivers/scsi/aacraid/commctrl.c b/trunk/drivers/scsi/aacraid/commctrl.c index 255421de9d1a..9f75144e5247 100644 --- a/trunk/drivers/scsi/aacraid/commctrl.c +++ b/trunk/drivers/scsi/aacraid/commctrl.c @@ -535,7 +535,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) default: data_dir = DMA_NONE; } - if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) { + if (user_srbcmd->sg.count > (sizeof(sg_list)/sizeof(sg_list[0]))) { dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n", le32_to_cpu(srbcmd->sg.count))); rcode = -EINVAL; diff --git a/trunk/drivers/scsi/aacraid/comminit.c b/trunk/drivers/scsi/aacraid/comminit.c index 7cea514e810a..19397453bae7 100644 --- a/trunk/drivers/scsi/aacraid/comminit.c +++ b/trunk/drivers/scsi/aacraid/comminit.c @@ -103,12 +103,9 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co * This assumes the memory is mapped zero->n, which isnt * always true on real computers. It also has some slight problems * with the GART on x86-64. I've btw never tried DMA from PCI space - * on this platform but don't be surprised if its problematic. - * [AK: something is very very wrong when a driver tests this symbol. - * Someone should figure out what the comment writer really meant here and fix - * the code. Or just remove that bad code. ] + * on this platform but don't be suprised if its problematic. */ -#ifndef CONFIG_IOMMU +#ifndef CONFIG_GART_IOMMU if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) { init->HostPhysMemPages = cpu_to_le32(num_physpages << (PAGE_SHIFT-12)); @@ -162,6 +159,7 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, { q->numpending = 0; q->dev = dev; + INIT_LIST_HEAD(&q->pendingq); init_waitqueue_head(&q->cmdready); INIT_LIST_HEAD(&q->cmdq); init_waitqueue_head(&q->qfull); diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 3f27419c66af..9f9f4aae23c0 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -229,7 +229,8 @@ void aac_fib_init(struct fib *fibptr) static void fib_dealloc(struct fib * fibptr) { struct hw_fib *hw_fib = fibptr->hw_fib; - BUG_ON(hw_fib->header.StructType != FIB_MAGIC); + if(hw_fib->header.StructType != FIB_MAGIC) + BUG(); hw_fib->header.XferState = 0; } @@ -471,6 +472,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, spin_lock_irqsave(q->lock, qflags); if (dev->new_comm_interface) { unsigned long count = 10000000L; /* 50 seconds */ + list_add_tail(&fibptr->queue, &q->pendingq); q->numpending++; spin_unlock_irqrestore(q->lock, qflags); while (aac_adapter_send(fibptr) != 0) { @@ -479,6 +481,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_lock_irqsave(q->lock, qflags); q->numpending--; + list_del(&fibptr->queue); spin_unlock_irqrestore(q->lock, qflags); return -ETIMEDOUT; } @@ -489,6 +492,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, unsigned long nointr = 0; aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); + list_add_tail(&fibptr->queue, &q->pendingq); q->numpending++; *(q->headers.producer) = cpu_to_le32(index + 1); spin_unlock_irqrestore(q->lock, qflags); @@ -516,6 +520,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, if (--count == 0) { spin_lock_irqsave(q->lock, qflags); q->numpending--; + list_del(&fibptr->queue); spin_unlock_irqrestore(q->lock, qflags); if (wait == -1) { printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n" @@ -529,7 +534,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } } else down(&fibptr->event_wait); - BUG_ON(fibptr->done == 0); + if(fibptr->done == 0) + BUG(); if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ return -ETIMEDOUT; @@ -1208,7 +1214,7 @@ int aac_command_thread(void *data) * since the last read off * the queue? */ - if ((time_now - time_last) > aif_timeout) { + if ((time_now - time_last) > 120) { entry = entry->next; aac_close_fib_context(dev, fibctx); continue; diff --git a/trunk/drivers/scsi/aacraid/dpcsup.c b/trunk/drivers/scsi/aacraid/dpcsup.c index b2a5c7262f36..f6bcb9486f85 100644 --- a/trunk/drivers/scsi/aacraid/dpcsup.c +++ b/trunk/drivers/scsi/aacraid/dpcsup.c @@ -85,9 +85,10 @@ unsigned int aac_response_normal(struct aac_queue * q) * continue. The caller has already been notified that * the fib timed out. */ - if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { + list_del(&fib->queue); dev->queues->queue[AdapNormCmdQueue].numpending--; - else { + } else { printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); continue; @@ -283,6 +284,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) return 0; } + list_del(&fib->queue); dev->queues->queue[AdapNormCmdQueue].numpending--; if (fast) { diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c index e42a479ce64a..6ef89c99dd12 100644 --- a/trunk/drivers/scsi/aacraid/linit.c +++ b/trunk/drivers/scsi/aacraid/linit.c @@ -119,7 +119,7 @@ static struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */ { 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */ { 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */ - { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */ + { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */ { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */ { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */ { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */ @@ -143,7 +143,7 @@ static struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */ { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */ { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */ - { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800SAS (Hurricane44) */ + { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */ { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/ { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/ @@ -195,7 +195,7 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rkt_init, "aacraid", "ICP ", "ICP9014R0 ", 1 }, /* ICP9014R0 (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */ - { aac_rkt_init, "aacraid", "ICP ", "ICP5445AU ", 1 }, /* ICP5445AU (Hurricane44) */ + { aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */ { aac_rx_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */ { aac_rx_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9067MA ", 1 }, /* ICP9067MA (Intruder-6) */ @@ -217,7 +217,7 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */ - { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-3800SAS ", 1 }, /* ASR-3800SAS (Hurricane44) */ + { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */ { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/ { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/ @@ -453,10 +453,15 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + + + spin_lock_irq(host->host_lock); + aac = (struct aac_dev *)host->hostdata; if (aac_adapter_check_health(aac)) { printk(KERN_ERR "%s: Host adapter appears dead\n", AAC_DRIVERNAME); + spin_unlock_irq(host->host_lock); return -ENODEV; } /* @@ -482,10 +487,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) /* * We can exit If all the commands are complete */ + spin_unlock_irq(host->host_lock); if (active == 0) return SUCCESS; ssleep(1); + spin_lock_irq(host->host_lock); } + spin_unlock_irq(host->host_lock); printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); return -ETIMEDOUT; } @@ -564,7 +572,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long f = compat_alloc_user_space(sizeof(*f)); ret = 0; - if (clear_user(f, sizeof(*f))) + if (clear_user(f, sizeof(*f)) != sizeof(*f)) ret = -EFAULT; if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32))) ret = -EFAULT; diff --git a/trunk/drivers/scsi/aacraid/rkt.c b/trunk/drivers/scsi/aacraid/rkt.c index 5b52966bbbf3..7a23e027eb78 100644 --- a/trunk/drivers/scsi/aacraid/rkt.c +++ b/trunk/drivers/scsi/aacraid/rkt.c @@ -444,14 +444,14 @@ int aac_rkt_init(struct aac_dev *dev) */ while (!(rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING)) { - if(time_after(jiffies, start+startup_timeout*HZ)) + if(time_after(jiffies, start+180*HZ)) { status = rkt_readl(dev, MUnit.OMRx[0]); printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } - msleep(1); + schedule_timeout_uninterruptible(1); } if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) { diff --git a/trunk/drivers/scsi/aacraid/rx.c b/trunk/drivers/scsi/aacraid/rx.c index 9dadfb28b3f1..729b9eb268c2 100644 --- a/trunk/drivers/scsi/aacraid/rx.c +++ b/trunk/drivers/scsi/aacraid/rx.c @@ -444,14 +444,14 @@ int aac_rx_init(struct aac_dev *dev) while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) || (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))) { - if(time_after(jiffies, start+startup_timeout*HZ)) + if(time_after(jiffies, start+180*HZ)) { status = rx_readl(dev, IndexRegs.Mailbox[7]); printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } - msleep(1); + schedule_timeout_uninterruptible(1); } if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) { diff --git a/trunk/drivers/scsi/aacraid/sa.c b/trunk/drivers/scsi/aacraid/sa.c index 88d400fccc94..a53454908205 100644 --- a/trunk/drivers/scsi/aacraid/sa.c +++ b/trunk/drivers/scsi/aacraid/sa.c @@ -66,11 +66,11 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs) sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */ sa_writew(dev, DoorbellReg_s, PrintfDone); } else if (intstat & DOORBELL_1) { // dev -> Host Normal Command Ready - sa_writew(dev, DoorbellClrReg_p, DOORBELL_1); aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + sa_writew(dev, DoorbellClrReg_p, DOORBELL_1); } else if (intstat & DOORBELL_2) { // dev -> Host Normal Response Ready - sa_writew(dev, DoorbellClrReg_p, DOORBELL_2); aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + sa_writew(dev, DoorbellClrReg_p, DOORBELL_2); } else if (intstat & DOORBELL_3) { // dev -> Host Normal Command Not Full sa_writew(dev, DoorbellClrReg_p, DOORBELL_3); } else if (intstat & DOORBELL_4) { // dev -> Host Normal Response Not Full @@ -318,13 +318,13 @@ int aac_sa_init(struct aac_dev *dev) * Wait for the adapter to be up and running. Wait up to 3 minutes. */ while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) { - if (time_after(jiffies, start+startup_timeout*HZ)) { + if (time_after(jiffies, start+180*HZ)) { status = sa_readl(dev, Mailbox7); printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %lx.\n", name, instance, status); goto error_iounmap; } - msleep(1); + schedule_timeout_uninterruptible(1); } if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) { diff --git a/trunk/drivers/scsi/advansys.c b/trunk/drivers/scsi/advansys.c index dd9fb3d91000..2a419634b256 100644 --- a/trunk/drivers/scsi/advansys.c +++ b/trunk/drivers/scsi/advansys.c @@ -12374,7 +12374,7 @@ AscInitFromEEP(ASC_DVC_VAR *asc_dvc) ASC_PRINT1( "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i); } else { - ASC_PRINT("AscInitFromEEP: Successfully re-wrote EEPROM.\n"); + ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM."); } } return (warn_code); @@ -17316,7 +17316,7 @@ AdvWaitEEPCmd(AdvPortAddr iop_base) /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) { ushort *wbuf; @@ -17383,7 +17383,7 @@ AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) { @@ -17451,7 +17451,7 @@ AdvSet38C0800EEPConfig(AdvPortAddr iop_base, /* * Write the EEPROM from 'cfg_buf'. */ -void __init +void AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) { diff --git a/trunk/drivers/scsi/aha1542.c b/trunk/drivers/scsi/aha1542.c index 86c6bd234591..51bad7a1e773 100644 --- a/trunk/drivers/scsi/aha1542.c +++ b/trunk/drivers/scsi/aha1542.c @@ -1011,7 +1011,7 @@ static int __init do_setup(char *str) int count=setup_idx; - get_options(str, ARRAY_SIZE(ints), ints); + get_options(str, sizeof(ints)/sizeof(int), ints); aha1542_setup(str,ints); return count #define DRV_NAME "ahci" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.2" enum { @@ -56,15 +56,12 @@ enum { AHCI_MAX_SG = 168, /* hardware max is 64K */ AHCI_DMA_BOUNDARY = 0xffffffff, AHCI_USE_CLUSTERING = 0, - AHCI_MAX_CMDS = 32, - AHCI_CMD_SZ = 32, - AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, + AHCI_CMD_SLOT_SZ = 32 * 32, AHCI_RX_FIS_SZ = 256, + AHCI_CMD_TBL_HDR = 0x80, AHCI_CMD_TBL_CDB = 0x40, - AHCI_CMD_TBL_HDR_SZ = 0x80, - AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16), - AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS, - AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + + AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16), + AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ, AHCI_IRQ_ON_SG = (1 << 31), AHCI_CMD_ATAPI = (1 << 5), @@ -74,10 +71,8 @@ enum { AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ - RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ board_ahci = 0, - board_ahci_vt8251 = 1, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -92,9 +87,8 @@ enum { HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ - HOST_CAP_CLO = (1 << 24), /* Command List Override support */ - HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ + HOST_CAP_CLO = (1 << 24), /* Command List Override support */ /* registers for each SATA port */ PORT_LST_ADDR = 0x00, /* command list DMA addr */ @@ -133,17 +127,15 @@ enum { PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */ - PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR | - PORT_IRQ_IF_ERR | - PORT_IRQ_CONNECT | - PORT_IRQ_PHYRDY | - PORT_IRQ_UNK_FIS, - PORT_IRQ_ERROR = PORT_IRQ_FREEZE | - PORT_IRQ_TF_ERR | - PORT_IRQ_HBUS_DATA_ERR, - DEF_PORT_IRQ = PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | - PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | - PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS, + PORT_IRQ_FATAL = PORT_IRQ_TF_ERR | + PORT_IRQ_HBUS_ERR | + PORT_IRQ_HBUS_DATA_ERR | + PORT_IRQ_IF_ERR, + DEF_PORT_IRQ = PORT_IRQ_FATAL | PORT_IRQ_PHYRDY | + PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE | + PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS | + PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS | + PORT_IRQ_D2H_REG_FIS, /* PORT_CMD bits */ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ @@ -161,10 +153,6 @@ enum { /* hpriv->flags bits */ AHCI_FLAG_MSI = (1 << 0), - - /* ap->flags bits */ - AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), - AHCI_FLAG_NO_NCQ = (1 << 25), }; struct ahci_cmd_hdr { @@ -193,6 +181,7 @@ struct ahci_port_priv { dma_addr_t cmd_slot_dma; void *cmd_tbl; dma_addr_t cmd_tbl_dma; + struct ahci_sg *cmd_tbl_sg; void *rx_fis; dma_addr_t rx_fis_dma; }; @@ -202,16 +191,15 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); static void ahci_irq_clear(struct ata_port *ap); +static void ahci_eng_timeout(struct ata_port *ap); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void ahci_qc_prep(struct ata_queued_cmd *qc); static u8 ahci_check_status(struct ata_port *ap); -static void ahci_freeze(struct ata_port *ap); -static void ahci_thaw(struct ata_port *ap); -static void ahci_error_handler(struct ata_port *ap); -static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); +static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); static void ahci_remove_one (struct pci_dev *pdev); static struct scsi_host_template ahci_sht = { @@ -219,8 +207,7 @@ static struct scsi_host_template ahci_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, - .change_queue_depth = ata_scsi_change_queue_depth, - .can_queue = AHCI_MAX_CMDS - 1, + .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = AHCI_MAX_SG, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, @@ -229,7 +216,6 @@ static struct scsi_host_template ahci_sht = { .proc_name = DRV_NAME, .dma_boundary = AHCI_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -242,21 +228,19 @@ static const struct ata_port_operations ahci_ops = { .tf_read = ahci_tf_read, + .probe_reset = ahci_probe_reset, + .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue, + .eng_timeout = ahci_eng_timeout, + .irq_handler = ahci_interrupt, .irq_clear = ahci_irq_clear, .scr_read = ahci_scr_read, .scr_write = ahci_scr_write, - .freeze = ahci_freeze, - .thaw = ahci_thaw, - - .error_handler = ahci_error_handler, - .post_internal_cmd = ahci_post_internal_cmd, - .port_start = ahci_port_start, .port_stop = ahci_port_stop, }; @@ -266,19 +250,7 @@ static const struct ata_port_info ahci_port_info[] = { { .sht = &ahci_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY, - .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ - .port_ops = &ahci_ops, - }, - /* board_ahci_vt8251 */ - { - .sht = &ahci_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_SKIP_D2H_BSY | - AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ, + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, @@ -286,7 +258,6 @@ static const struct ata_port_info ahci_port_info[] = { }; static const struct pci_device_id ahci_pci_tbl[] = { - /* Intel */ { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ICH6 */ { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -317,39 +288,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* ICH8M */ { PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ICH8M */ - - /* JMicron */ { 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB360 */ - { 0x197b, 0x2361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* JMicron JMB361 */ { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB363 */ - { 0x197b, 0x2365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* JMicron JMB365 */ - { 0x197b, 0x2366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* JMicron JMB366 */ - - /* ATI */ { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ATI SB600 non-raid */ { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ATI SB600 raid */ - - /* VIA */ - { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci_vt8251 }, /* VIA VT8251 */ - - /* NVIDIA */ - { PCI_VENDOR_ID_NVIDIA, 0x044c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* MCP65 */ - { PCI_VENDOR_ID_NVIDIA, 0x044d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* MCP65 */ - { PCI_VENDOR_ID_NVIDIA, 0x044e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* MCP65 */ - { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* MCP65 */ - { } /* terminate list */ }; @@ -428,6 +374,8 @@ static int ahci_port_start(struct ata_port *ap) pp->cmd_tbl = mem; pp->cmd_tbl_dma = mem_dma; + pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR; + ap->private_data = pp; if (hpriv->cap & HOST_CAP_64) @@ -560,71 +508,46 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) return ata_dev_classify(&tf); } -static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, - u32 opts) +static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) { - dma_addr_t cmd_tbl_dma; - - cmd_tbl_dma = pp->cmd_tbl_dma + tag * AHCI_CMD_TBL_SZ; - - pp->cmd_slot[tag].opts = cpu_to_le32(opts); - pp->cmd_slot[tag].status = 0; - pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); - pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); + pp->cmd_slot[0].opts = cpu_to_le32(opts); + pp->cmd_slot[0].status = 0; + pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); + pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); } -static int ahci_clo(struct ata_port *ap) +static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, + unsigned long interval_msec, + unsigned long timeout_msec) { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; - struct ahci_host_priv *hpriv = ap->host_set->private_data; + unsigned long timeout; u32 tmp; - if (!(hpriv->cap & HOST_CAP_CLO)) - return -EOPNOTSUPP; - - tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_CLO; - writel(tmp, port_mmio + PORT_CMD); - - tmp = ata_wait_register(port_mmio + PORT_CMD, - PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); - if (tmp & PORT_CMD_CLO) - return -EIO; - - return 0; -} - -static int ahci_prereset(struct ata_port *ap) -{ - if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) && - (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) { - /* ATA_BUSY hasn't cleared, so send a CLO */ - ahci_clo(ap); - } + timeout = jiffies + (timeout_msec * HZ) / 1000; + do { + tmp = readl(reg); + if ((tmp & mask) == val) + return 0; + msleep(interval_msec); + } while (time_before(jiffies, timeout)); - return ata_std_prereset(ap); + return -1; } -static int ahci_softreset(struct ata_port *ap, unsigned int *class) +static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) { + struct ahci_host_priv *hpriv = ap->host_set->private_data; struct ahci_port_priv *pp = ap->private_data; void __iomem *mmio = ap->host_set->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const u32 cmd_fis_len = 5; /* five dwords */ const char *reason = NULL; struct ata_taskfile tf; - u32 tmp; u8 *fis; int rc; DPRINTK("ENTER\n"); - if (ata_port_offline(ap)) { - DPRINTK("PHY reports no device\n"); - *class = ATA_DEV_NONE; - return 0; - } - /* prepare for SRST (AHCI-1.1 10.4.1) */ rc = ahci_stop_engine(ap); if (rc) { @@ -635,13 +558,23 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) /* check BUSY/DRQ, perform Command List Override if necessary */ ahci_tf_read(ap, &tf); if (tf.command & (ATA_BUSY | ATA_DRQ)) { - rc = ahci_clo(ap); + u32 tmp; - if (rc == -EOPNOTSUPP) { - reason = "port busy but CLO unavailable"; + if (!(hpriv->cap & HOST_CAP_CLO)) { + rc = -EIO; + reason = "port busy but no CLO"; goto fail_restart; - } else if (rc) { - reason = "port busy but CLO failed"; + } + + tmp = readl(port_mmio + PORT_CMD); + tmp |= PORT_CMD_CLO; + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ + + if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, + 1, 500)) { + rc = -EIO; + reason = "CLO failed"; goto fail_restart; } } @@ -649,21 +582,20 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) /* restart engine */ ahci_start_engine(ap); - ata_tf_init(ap->device, &tf); + ata_tf_init(ap, &tf, 0); fis = pp->cmd_tbl; /* issue the first D2H Register FIS */ - ahci_fill_cmd_slot(pp, 0, - cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); + ahci_fill_cmd_slot(pp, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); tf.ctl |= ATA_SRST; ata_tf_to_fis(&tf, fis, 0); fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ writel(1, port_mmio + PORT_CMD_ISSUE); + readl(port_mmio + PORT_CMD_ISSUE); /* flush */ - tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500); - if (tmp & 0x1) { + if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) { rc = -EIO; reason = "1st FIS failed"; goto fail; @@ -673,7 +605,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) msleep(1); /* issue the second D2H Register FIS */ - ahci_fill_cmd_slot(pp, 0, cmd_fis_len); + ahci_fill_cmd_slot(pp, cmd_fis_len); tf.ctl &= ~ATA_SRST; ata_tf_to_fis(&tf, fis, 0); @@ -693,7 +625,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) msleep(150); *class = ATA_DEV_NONE; - if (ata_port_online(ap)) { + if (sata_dev_present(ap)) { if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { rc = -EIO; reason = "device not ready"; @@ -708,31 +640,25 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) fail_restart: ahci_start_engine(ap); fail: - ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); + if (verbose) + printk(KERN_ERR "ata%u: softreset failed (%s)\n", + ap->id, reason); + else + DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason); return rc; } -static int ahci_hardreset(struct ata_port *ap, unsigned int *class) +static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) { - struct ahci_port_priv *pp = ap->private_data; - u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; - struct ata_taskfile tf; int rc; DPRINTK("ENTER\n"); ahci_stop_engine(ap); - - /* clear D2H reception area to properly wait for D2H FIS */ - ata_tf_init(ap->device, &tf); - tf.command = 0xff; - ata_tf_to_fis(&tf, d2h_fis, 0); - - rc = sata_std_hardreset(ap, class); - + rc = sata_std_hardreset(ap, verbose, class); ahci_start_engine(ap); - if (rc == 0 && ata_port_online(ap)) + if (rc == 0) *class = ahci_dev_classify(ap); if (*class == ATA_DEV_UNKNOWN) *class = ATA_DEV_NONE; @@ -760,6 +686,13 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class) } } +static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) +{ + return ata_drive_probe_reset(ap, ata_std_probeinit, + ahci_softreset, ahci_hardreset, + ahci_postreset, classes); +} + static u8 ahci_check_status(struct ata_port *ap) { void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; @@ -775,8 +708,9 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) ata_tf_from_fis(d2h_fis, tf); } -static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) +static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) { + struct ahci_port_priv *pp = qc->ap->private_data; struct scatterlist *sg; struct ahci_sg *ahci_sg; unsigned int n_sg = 0; @@ -786,7 +720,7 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) /* * Next, the S/G list. */ - ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; + ahci_sg = pp->cmd_tbl_sg; ata_for_each_sg(sg, qc) { dma_addr_t addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); @@ -807,7 +741,6 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct ahci_port_priv *pp = ap->private_data; int is_atapi = is_atapi_taskfile(&qc->tf); - void *cmd_tbl; u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ unsigned int n_elem; @@ -816,17 +749,16 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) * Fill in command table information. First, the header, * a SATA Register - Host to Device command FIS. */ - cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; - - ata_tf_to_fis(&qc->tf, cmd_tbl, 0); + ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); if (is_atapi) { - memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); - memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); + memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); + memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, + qc->dev->cdb_len); } n_elem = 0; if (qc->flags & ATA_QCFLAG_DMAMAP) - n_elem = ahci_fill_sg(qc, cmd_tbl); + n_elem = ahci_fill_sg(qc); /* * Fill in command slot information. @@ -837,122 +769,112 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) if (is_atapi) opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; - ahci_fill_cmd_slot(pp, qc->tag, opts); + ahci_fill_cmd_slot(pp, opts); } -static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) +static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) { - struct ahci_port_priv *pp = ap->private_data; - struct ata_eh_info *ehi = &ap->eh_info; - unsigned int err_mask = 0, action = 0; - struct ata_queued_cmd *qc; - u32 serror; - - ata_ehi_clear_desc(ehi); - - /* AHCI needs SError cleared; otherwise, it might lock up */ - serror = ahci_scr_read(ap, SCR_ERROR); - ahci_scr_write(ap, SCR_ERROR, serror); - - /* analyze @irq_stat */ - ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); + void __iomem *mmio = ap->host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + u32 tmp; - if (irq_stat & PORT_IRQ_TF_ERR) - err_mask |= AC_ERR_DEV; + if ((ap->device[0].class != ATA_DEV_ATAPI) || + ((irq_stat & PORT_IRQ_TF_ERR) == 0)) + printk(KERN_WARNING "ata%u: port reset, " + "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n", + ap->id, + irq_stat, + readl(mmio + HOST_IRQ_STAT), + readl(port_mmio + PORT_IRQ_STAT), + readl(port_mmio + PORT_CMD), + readl(port_mmio + PORT_TFDATA), + readl(port_mmio + PORT_SCR_STAT), + readl(port_mmio + PORT_SCR_ERR)); + + /* stop DMA */ + ahci_stop_engine(ap); - if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { - err_mask |= AC_ERR_HOST_BUS; - action |= ATA_EH_SOFTRESET; - } + /* clear SATA phy error, if any */ + tmp = readl(port_mmio + PORT_SCR_ERR); + writel(tmp, port_mmio + PORT_SCR_ERR); - if (irq_stat & PORT_IRQ_IF_ERR) { - err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, ", interface fatal error"); + /* if DRQ/BSY is set, device needs to be reset. + * if so, issue COMRESET + */ + tmp = readl(port_mmio + PORT_TFDATA); + if (tmp & (ATA_BUSY | ATA_DRQ)) { + writel(0x301, port_mmio + PORT_SCR_CTL); + readl(port_mmio + PORT_SCR_CTL); /* flush */ + udelay(10); + writel(0x300, port_mmio + PORT_SCR_CTL); + readl(port_mmio + PORT_SCR_CTL); /* flush */ } - if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { - ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? - "connection status changed" : "PHY RDY changed"); - } + /* re-start DMA */ + ahci_start_engine(ap); +} - if (irq_stat & PORT_IRQ_UNK_FIS) { - u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); +static void ahci_eng_timeout(struct ata_port *ap) +{ + struct ata_host_set *host_set = ap->host_set; + void __iomem *mmio = host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + struct ata_queued_cmd *qc; + unsigned long flags; - err_mask |= AC_ERR_HSM; - action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", - unk[0], unk[1], unk[2], unk[3]); - } + printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id); - /* okay, let's hand over to EH */ - ehi->serror |= serror; - ehi->action |= action; + spin_lock_irqsave(&host_set->lock, flags); + ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc) - qc->err_mask |= err_mask; - else - ehi->err_mask |= err_mask; + qc->err_mask |= AC_ERR_TIMEOUT; - if (irq_stat & PORT_IRQ_FREEZE) - ata_port_freeze(ap); - else - ata_port_abort(ap); + spin_unlock_irqrestore(&host_set->lock, flags); + + ata_eh_qc_complete(qc); } -static void ahci_host_intr(struct ata_port *ap) +static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) { void __iomem *mmio = ap->host_set->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - struct ata_eh_info *ehi = &ap->eh_info; - u32 status, qc_active; - int rc; + u32 status, serr, ci; + + serr = readl(port_mmio + PORT_SCR_ERR); + writel(serr, port_mmio + PORT_SCR_ERR); status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); - if (unlikely(status & PORT_IRQ_ERROR)) { - ahci_error_intr(ap, status); - return; - } - - if (ap->sactive) - qc_active = readl(port_mmio + PORT_SCR_ACT); - else - qc_active = readl(port_mmio + PORT_CMD_ISSUE); - - rc = ata_qc_complete_multiple(ap, qc_active, NULL); - if (rc > 0) - return; - if (rc < 0) { - ehi->err_mask |= AC_ERR_HSM; - ehi->action |= ATA_EH_SOFTRESET; - ata_port_freeze(ap); - return; + ci = readl(port_mmio + PORT_CMD_ISSUE); + if (likely((ci & 0x1) == 0)) { + if (qc) { + WARN_ON(qc->err_mask); + ata_qc_complete(qc); + qc = NULL; + } } - /* hmmm... a spurious interupt */ - - /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) - return; - - /* ignore interim PIO setup fis interrupts */ - if (ata_tag_valid(ap->active_tag)) { - struct ata_queued_cmd *qc = - ata_qc_from_tag(ap, ap->active_tag); - - if (qc && qc->tf.protocol == ATA_PROT_PIO && - (status & PORT_IRQ_PIOS_FIS)) - return; + if (status & PORT_IRQ_FATAL) { + unsigned int err_mask; + if (status & PORT_IRQ_TF_ERR) + err_mask = AC_ERR_DEV; + else if (status & PORT_IRQ_IF_ERR) + err_mask = AC_ERR_ATA_BUS; + else + err_mask = AC_ERR_HOST_BUS; + + /* command processing has stopped due to error; restart */ + ahci_restart_port(ap, status); + + if (qc) { + qc->err_mask |= err_mask; + ata_qc_complete(qc); + } } - if (ata_ratelimit()) - ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", - status, ap->active_tag, ap->sactive); + return 1; } static void ahci_irq_clear(struct ata_port *ap) @@ -960,7 +882,7 @@ static void ahci_irq_clear(struct ata_port *ap) /* TODO */ } -static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { struct ata_host_set *host_set = dev_instance; struct ahci_host_priv *hpriv; @@ -989,7 +911,14 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *r ap = host_set->ports[i]; if (ap) { - ahci_host_intr(ap); + struct ata_queued_cmd *qc; + qc = ata_qc_from_tag(ap, ap->active_tag); + if (!ahci_host_intr(ap, qc)) + if (ata_ratelimit()) + dev_printk(KERN_WARNING, host_set->dev, + "unhandled interrupt on port %u\n", + i); + VPRINTK("port %u\n", i); } else { VPRINTK("port %u (no irq)\n", i); @@ -1006,7 +935,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *r handled = 1; } - spin_unlock(&host_set->lock); + spin_unlock(&host_set->lock); VPRINTK("EXIT\n"); @@ -1018,65 +947,12 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; - if (qc->tf.protocol == ATA_PROT_NCQ) - writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); - writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); + writel(1, port_mmio + PORT_CMD_ISSUE); readl(port_mmio + PORT_CMD_ISSUE); /* flush */ return 0; } -static void ahci_freeze(struct ata_port *ap) -{ - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - - /* turn IRQ off */ - writel(0, port_mmio + PORT_IRQ_MASK); -} - -static void ahci_thaw(struct ata_port *ap) -{ - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - u32 tmp; - - /* clear IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - writel(tmp, port_mmio + PORT_IRQ_STAT); - writel(1 << ap->id, mmio + HOST_IRQ_STAT); - - /* turn IRQ back on */ - writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); -} - -static void ahci_error_handler(struct ata_port *ap) -{ - if (!(ap->flags & ATA_FLAG_FROZEN)) { - /* restart engine */ - ahci_stop_engine(ap); - ahci_start_engine(ap); - } - - /* perform recovery */ - ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset, - ahci_postreset); -} - -static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - - if (qc->err_mask) { - /* make DMA engine forget about the failed command */ - ahci_stop_engine(ap); - ahci_start_engine(ap); - } -} - static void ahci_setup_port(struct ata_ioports *port, unsigned long base, unsigned int port_idx) { @@ -1221,6 +1097,9 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) writel(tmp, port_mmio + PORT_IRQ_STAT); writel(1 << i, mmio + HOST_IRQ_STAT); + + /* set irq mask (enables interrupts) */ + writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); } tmp = readl(mmio + HOST_CTL); @@ -1318,8 +1197,6 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) VPRINTK("ENTER\n"); - WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); - if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -1387,10 +1264,6 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto err_out_hpriv; - if (!(probe_ent->host_flags & AHCI_FLAG_NO_NCQ) && - (hpriv->cap & HOST_CAP_NCQ)) - probe_ent->host_flags |= ATA_FLAG_NCQ; - ahci_print_info(probe_ent); /* FIXME: check ata_device_add return value */ @@ -1422,17 +1295,21 @@ static void ahci_remove_one (struct pci_dev *pdev) struct device *dev = pci_dev_to_dev(pdev); struct ata_host_set *host_set = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host_set->private_data; + struct ata_port *ap; unsigned int i; int have_msi; - for (i = 0; i < host_set->n_ports; i++) - ata_port_detach(host_set->ports[i]); + for (i = 0; i < host_set->n_ports; i++) { + ap = host_set->ports[i]; + + scsi_remove_host(ap->host); + } have_msi = hpriv->flags & AHCI_FLAG_MSI; free_irq(host_set->irq, host_set); for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; + ap = host_set->ports[i]; ata_scsi_release(ap->host); scsi_host_put(ap->host); diff --git a/trunk/drivers/scsi/aic7xxx/aic7770.c b/trunk/drivers/scsi/aic7xxx/aic7770.c index c4d17231c828..527efd36f5c1 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7770.c +++ b/trunk/drivers/scsi/aic7xxx/aic7770.c @@ -107,7 +107,7 @@ struct aic7770_identity aic7770_ident_table[] = ahc_aic7770_EISA_setup } }; -const int ahc_num_aic7770_devs = ARRAY_SIZE(aic7770_ident_table); +const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table); struct aic7770_identity * aic7770_find_device(uint32_t id) diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx.h b/trunk/drivers/scsi/aic7xxx/aic79xx.h index eb7745692682..bb5166da4358 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx.h @@ -68,6 +68,8 @@ struct scb_platform_data; #define FALSE 0 #endif +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) + #define ALL_CHANNELS '\0' #define ALL_TARGETS_MASK 0xFFFF #define INITIATOR_WILDCARD (~0) diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c index 801fc81d0b20..08771f6f6859 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c @@ -59,7 +59,7 @@ char *ahd_chip_names[] = "aic7902", "aic7901A" }; -static const u_int num_chip_names = ARRAY_SIZE(ahd_chip_names); +static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names); /* * Hardware error codes. @@ -77,7 +77,7 @@ static struct ahd_hard_error_entry ahd_hard_errors[] = { { MPARERR, "Scratch or SCB Memory Parity Error" }, { CIOPARERR, "CIOBUS Parity Error" }, }; -static const u_int num_errors = ARRAY_SIZE(ahd_hard_errors); +static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors); static struct ahd_phase_table_entry ahd_phase_table[] = { @@ -97,7 +97,7 @@ static struct ahd_phase_table_entry ahd_phase_table[] = * In most cases we only wish to itterate over real phases, so * exclude the last element from the count. */ -static const u_int num_phases = ARRAY_SIZE(ahd_phase_table) - 1; +static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1; /* Our Sequencer Program */ #include "aic79xx_seq.h" @@ -7259,7 +7259,7 @@ ahd_qinfifo_count(struct ahd_softc *ahd) return (wrap_qinfifonext - wrap_qinpos); else return (wrap_qinfifonext - + ARRAY_SIZE(ahd->qinfifo) - wrap_qinpos); + + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos); } void @@ -8619,7 +8619,7 @@ ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch, struct patch *last_patch; u_int num_patches; - num_patches = ARRAY_SIZE(patches); + num_patches = sizeof(patches)/sizeof(struct patch); last_patch = &patches[num_patches]; cur_patch = *start_patch; @@ -9396,8 +9396,8 @@ ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb, } else { u_int max_id; - max_id = (ahd->features & AHD_WIDE) ? 16 : 8; - if (ccb->ccb_h.target_id >= max_id) + max_id = (ahd->features & AHD_WIDE) ? 15 : 7; + if (ccb->ccb_h.target_id > max_id) return (CAM_TID_INVALID); if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS) diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index e0ccdf362200..66e4a47bb9ee 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -916,7 +916,7 @@ ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value) { if ((instance >= 0) - && (instance < ARRAY_SIZE(aic79xx_iocell_info))) { + && (instance < NUM_ELEMENTS(aic79xx_iocell_info))) { uint8_t *iocell_info; iocell_info = (uint8_t*)&aic79xx_iocell_info[instance]; @@ -934,7 +934,7 @@ ahd_linux_setup_tag_info_global(char *p) tags = simple_strtoul(p + 1, NULL, 0) & 0xff; printf("Setting Global Tags= %d\n", tags); - for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) { + for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) { for (j = 0; j < AHD_NUM_TARGETS; j++) { aic79xx_tag_info[i].tag_commands[j] = tags; } @@ -946,7 +946,7 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) { if ((instance >= 0) && (targ >= 0) - && (instance < ARRAY_SIZE(aic79xx_tag_info)) + && (instance < NUM_ELEMENTS(aic79xx_tag_info)) && (targ < AHD_NUM_TARGETS)) { aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF; if (bootverbose) @@ -1072,21 +1072,21 @@ aic79xx_setup(char *s) end = strchr(s, '\0'); /* - * XXX ia64 gcc isn't smart enough to know that ARRAY_SIZE + * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS * will never be 0 in this case. - */ - n = 0; + */ + n = 0; while ((p = strsep(&s, ",.")) != NULL) { if (*p == '\0') continue; - for (i = 0; i < ARRAY_SIZE(options); i++) { + for (i = 0; i < NUM_ELEMENTS(options); i++) { n = strlen(options[i].name); if (strncmp(options[i].name, p, n) == 0) break; } - if (i == ARRAY_SIZE(options)) + if (i == NUM_ELEMENTS(options)) continue; if (strncmp(p, "global_tag_depth", n) == 0) { @@ -1294,7 +1294,7 @@ ahd_platform_init(struct ahd_softc *ahd) /* * Lookup and commit any modified IO Cell options. */ - if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) { + if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) { struct ahd_linux_iocell_opts *iocell_opts; iocell_opts = &aic79xx_iocell_info[ahd->unit]; @@ -1426,7 +1426,7 @@ ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) tags = 0; if ((ahd->user_discenable & devinfo->target_mask) != 0) { - if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) { + if (ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) { if (warned_user == 0) { printf(KERN_WARNING diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c index 14850f31aafa..757242e522c2 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c @@ -201,7 +201,7 @@ struct ahd_pci_identity ahd_pci_ident_table [] = } }; -const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); +const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table); #define DEVCONFIG 0x40 #define PCIXINITPAT 0x0000E000ul diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c b/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c index 24fd59a230bf..39a27840fce6 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -76,9 +76,11 @@ static u_int ahd_calc_syncsrate(u_int period_factor) { int i; + int num_syncrates; + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); /* See if the period is in the "exception" table */ - for (i = 0; i < ARRAY_SIZE(scsi_syncrates); i++) { + for (i = 0; i < num_syncrates; i++) { if (period_factor == scsi_syncrates[i].period_factor) { /* Period in kHz */ diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx.h b/trunk/drivers/scsi/aic7xxx/aic7xxx.h index 62ff8c3dc2bb..91d294c6334e 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx.h @@ -69,6 +69,8 @@ struct seeprom_descriptor; #define FALSE 0 #endif +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) + #define ALL_CHANNELS '\0' #define ALL_TARGETS_MASK 0xFFFF #define INITIATOR_WILDCARD (~0) @@ -231,7 +233,6 @@ typedef enum { AHC_TARGETMODE = 0x20000, /* Has tested target mode support */ AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */ AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */ - AHC_HVD = 0x100000, /* HVD rather than SE */ AHC_AIC7770_FE = AHC_FENONE, /* * The real 7850 does not support Ultra modes, but there are diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c index 93e4e40944b6..d37566978fba 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -68,7 +68,7 @@ char *ahc_chip_names[] = "aic7892", "aic7899" }; -static const u_int num_chip_names = ARRAY_SIZE(ahc_chip_names); +static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names); /* * Hardware error codes. @@ -88,7 +88,7 @@ static struct ahc_hard_error_entry ahc_hard_errors[] = { { PCIERRSTAT, "PCI Error detected" }, { CIOPARERR, "CIOBUS Parity Error" }, }; -static const u_int num_errors = ARRAY_SIZE(ahc_hard_errors); +static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors); static struct ahc_phase_table_entry ahc_phase_table[] = { @@ -108,7 +108,7 @@ static struct ahc_phase_table_entry ahc_phase_table[] = * In most cases we only wish to itterate over real phases, so * exclude the last element from the count. */ -static const u_int num_phases = ARRAY_SIZE(ahc_phase_table) - 1; +static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1; /* * Valid SCSIRATE values. (p. 3-17) @@ -6367,7 +6367,7 @@ ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch, struct patch *last_patch; u_int num_patches; - num_patches = ARRAY_SIZE(patches); + num_patches = sizeof(patches)/sizeof(struct patch); last_patch = &patches[num_patches]; cur_patch = *start_patch; @@ -6774,8 +6774,8 @@ ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb, } else { u_int max_id; - max_id = (ahc->features & AHC_WIDE) ? 16 : 8; - if (ccb->ccb_h.target_id >= max_id) + max_id = (ahc->features & AHC_WIDE) ? 15 : 7; + if (ccb->ccb_h.target_id > max_id) return (CAM_TID_INVALID); if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS) diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c index debf3e2a0798..2c801672d8bb 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -886,7 +886,7 @@ ahc_linux_setup_tag_info_global(char *p) tags = simple_strtoul(p + 1, NULL, 0) & 0xff; printf("Setting Global Tags= %d\n", tags); - for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) { + for (i = 0; i < NUM_ELEMENTS(aic7xxx_tag_info); i++) { for (j = 0; j < AHC_NUM_TARGETS; j++) { aic7xxx_tag_info[i].tag_commands[j] = tags; } @@ -898,7 +898,7 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) { if ((instance >= 0) && (targ >= 0) - && (instance < ARRAY_SIZE(aic7xxx_tag_info)) + && (instance < NUM_ELEMENTS(aic7xxx_tag_info)) && (targ < AHC_NUM_TARGETS)) { aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff; if (bootverbose) @@ -1020,7 +1020,7 @@ aic7xxx_setup(char *s) end = strchr(s, '\0'); /* - * XXX ia64 gcc isn't smart enough to know that ARRAY_SIZE + * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS * will never be 0 in this case. */ n = 0; @@ -1028,13 +1028,13 @@ aic7xxx_setup(char *s) while ((p = strsep(&s, ",.")) != NULL) { if (*p == '\0') continue; - for (i = 0; i < ARRAY_SIZE(options); i++) { + for (i = 0; i < NUM_ELEMENTS(options); i++) { n = strlen(options[i].name); if (strncmp(options[i].name, p, n) == 0) break; } - if (i == ARRAY_SIZE(options)) + if (i == NUM_ELEMENTS(options)) continue; if (strncmp(p, "global_tag_depth", n) == 0) { @@ -1360,7 +1360,7 @@ ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) tags = 0; if ((ahc->user_discenable & devinfo->target_mask) != 0) { - if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) { + if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) { if (warned_user == 0) { printf(KERN_WARNING @@ -2537,22 +2537,6 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) } #endif -static void ahc_linux_get_signalling(struct Scsi_Host *shost) -{ - struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata; - u8 mode = ahc_inb(ahc, SBLKCTL); - - if (mode & ENAB40) - spi_signalling(shost) = SPI_SIGNAL_LVD; - else if (mode & ENAB20) - spi_signalling(shost) = - ahc->features & AHC_HVD ? - SPI_SIGNAL_HVD : - SPI_SIGNAL_SE; - else - spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; -} - static struct spi_function_template ahc_linux_transport_functions = { .set_offset = ahc_linux_set_offset, .show_offset = 1, @@ -2568,7 +2552,6 @@ static struct spi_function_template ahc_linux_transport_functions = { .set_qas = ahc_linux_set_qas, .show_qas = 1, #endif - .get_signalling = ahc_linux_get_signalling, }; diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c index 63cab2d74552..3adecef21783 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -144,22 +144,16 @@ static ahc_device_setup_t ahc_aic785X_setup; static ahc_device_setup_t ahc_aic7860_setup; static ahc_device_setup_t ahc_apa1480_setup; static ahc_device_setup_t ahc_aic7870_setup; -static ahc_device_setup_t ahc_aic7870h_setup; static ahc_device_setup_t ahc_aha394X_setup; -static ahc_device_setup_t ahc_aha394Xh_setup; static ahc_device_setup_t ahc_aha494X_setup; -static ahc_device_setup_t ahc_aha494Xh_setup; static ahc_device_setup_t ahc_aha398X_setup; static ahc_device_setup_t ahc_aic7880_setup; -static ahc_device_setup_t ahc_aic7880h_setup; static ahc_device_setup_t ahc_aha2940Pro_setup; static ahc_device_setup_t ahc_aha394XU_setup; -static ahc_device_setup_t ahc_aha394XUh_setup; static ahc_device_setup_t ahc_aha398XU_setup; static ahc_device_setup_t ahc_aic7890_setup; static ahc_device_setup_t ahc_aic7892_setup; static ahc_device_setup_t ahc_aic7895_setup; -static ahc_device_setup_t ahc_aic7895h_setup; static ahc_device_setup_t ahc_aic7896_setup; static ahc_device_setup_t ahc_aic7899_setup; static ahc_device_setup_t ahc_aha29160C_setup; @@ -231,19 +225,19 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_2944, ID_ALL_MASK, "Adaptec 2944 SCSI adapter", - ahc_aic7870h_setup + ahc_aic7870_setup }, { ID_AHA_3944, ID_ALL_MASK, "Adaptec 3944 SCSI adapter", - ahc_aha394Xh_setup + ahc_aha394X_setup }, { ID_AHA_4944, ID_ALL_MASK, "Adaptec 4944 SCSI adapter", - ahc_aha494Xh_setup + ahc_aha494X_setup }, /* aic7880 based controllers */ { @@ -262,13 +256,13 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_2944U & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 2944 Ultra SCSI adapter", - ahc_aic7880h_setup + ahc_aic7880_setup }, { ID_AHA_3944U & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 3944 Ultra SCSI adapter", - ahc_aha394XUh_setup + ahc_aha394XU_setup }, { ID_AHA_398XU & ID_DEV_VENDOR_MASK, @@ -284,7 +278,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_4944U & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 4944 Ultra SCSI adapter", - ahc_aic7880h_setup + ahc_aic7880_setup }, { ID_AHA_2930U & ID_DEV_VENDOR_MASK, @@ -420,7 +414,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_3944AU, ID_ALL_MASK, "Adaptec 3944A Ultra SCSI adapter", - ahc_aic7895h_setup + ahc_aic7895_setup }, { ID_AIC7895_ARO, @@ -559,7 +553,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = } }; -const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); +const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table); #define AHC_394X_SLOT_CHANNEL_A 4 #define AHC_394X_SLOT_CHANNEL_B 5 @@ -2126,16 +2120,6 @@ ahc_aic7870_setup(struct ahc_softc *ahc) return (0); } -static int -ahc_aic7870h_setup(struct ahc_softc *ahc) -{ - int error = ahc_aic7870_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - static int ahc_aha394X_setup(struct ahc_softc *ahc) { @@ -2147,16 +2131,6 @@ ahc_aha394X_setup(struct ahc_softc *ahc) return (error); } -static int -ahc_aha394Xh_setup(struct ahc_softc *ahc) -{ - int error = ahc_aha394X_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - static int ahc_aha398X_setup(struct ahc_softc *ahc) { @@ -2179,16 +2153,6 @@ ahc_aha494X_setup(struct ahc_softc *ahc) return (error); } -static int -ahc_aha494Xh_setup(struct ahc_softc *ahc) -{ - int error = ahc_aha494X_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - static int ahc_aic7880_setup(struct ahc_softc *ahc) { @@ -2210,17 +2174,6 @@ ahc_aic7880_setup(struct ahc_softc *ahc) return (0); } -static int -ahc_aic7880h_setup(struct ahc_softc *ahc) -{ - int error = ahc_aic7880_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - - static int ahc_aha2940Pro_setup(struct ahc_softc *ahc) { @@ -2240,16 +2193,6 @@ ahc_aha394XU_setup(struct ahc_softc *ahc) return (error); } -static int -ahc_aha394XUh_setup(struct ahc_softc *ahc) -{ - int error = ahc_aha394XU_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - static int ahc_aha398XU_setup(struct ahc_softc *ahc) { @@ -2348,16 +2291,6 @@ ahc_aic7895_setup(struct ahc_softc *ahc) return (0); } -static int -ahc_aic7895h_setup(struct ahc_softc *ahc) -{ - int error = ahc_aic7895_setup(ahc); - - ahc->features |= AHC_HVD; - - return error; -} - static int ahc_aic7896_setup(struct ahc_softc *ahc) { diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c index 5914b4aa4a8f..04a3506cf340 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -77,9 +77,11 @@ static u_int ahc_calc_syncsrate(u_int period_factor) { int i; + int num_syncrates; + num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); /* See if the period is in the "exception" table */ - for (i = 0; i < ARRAY_SIZE(scsi_syncrates); i++) { + for (i = 0; i < num_syncrates; i++) { if (period_factor == scsi_syncrates[i].period_factor) { /* Period in kHz */ diff --git a/trunk/drivers/scsi/aic7xxx_old.c b/trunk/drivers/scsi/aic7xxx_old.c index 5dba1c63122e..770f1647e4d6 100644 --- a/trunk/drivers/scsi/aic7xxx_old.c +++ b/trunk/drivers/scsi/aic7xxx_old.c @@ -1565,7 +1565,7 @@ aic7xxx_check_patch(struct aic7xxx_host *p, struct sequencer_patch *last_patch; int num_patches; - num_patches = ARRAY_SIZE(sequencer_patches); + num_patches = sizeof(sequencer_patches)/sizeof(struct sequencer_patch); last_patch = &sequencer_patches[num_patches]; cur_patch = *start_patch; diff --git a/trunk/drivers/scsi/arm/queue.c b/trunk/drivers/scsi/arm/queue.c index 8caa5903ce38..b10750bb5c09 100644 --- a/trunk/drivers/scsi/arm/queue.c +++ b/trunk/drivers/scsi/arm/queue.c @@ -118,7 +118,8 @@ int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head) list_del(l); q = list_entry(l, QE_t, list); - BUG_ON(BAD_MAGIC(q, QUEUE_MAGIC_FREE)); + if (BAD_MAGIC(q, QUEUE_MAGIC_FREE)) + BUG(); SET_MAGIC(q, QUEUE_MAGIC_USED); q->SCpnt = SCpnt; @@ -143,7 +144,8 @@ static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent) */ list_del(ent); q = list_entry(ent, QE_t, list); - BUG_ON(BAD_MAGIC(q, QUEUE_MAGIC_USED)); + if (BAD_MAGIC(q, QUEUE_MAGIC_USED)) + BUG(); SET_MAGIC(q, QUEUE_MAGIC_FREE); list_add(ent, &queue->free); diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 94b1261a259d..6dc88149f9f1 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -93,7 +93,7 @@ #include #define DRV_NAME "ata_piix" -#define DRV_VERSION "2.00" +#define DRV_VERSION "1.05" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ @@ -146,10 +146,11 @@ struct piix_map_db { static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); + +static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes); +static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes); static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); -static void piix_pata_error_handler(struct ata_port *ap); -static void piix_sata_error_handler(struct ata_port *ap); static unsigned int in_module_init = 1; @@ -158,7 +159,6 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, - { 0x8086, 0x27df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, #endif /* NOTE: The following PCI ids must be kept in sync with the @@ -218,7 +218,6 @@ static struct scsi_host_template piix_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, .resume = ata_scsi_device_resume, .suspend = ata_scsi_device_suspend, @@ -228,7 +227,6 @@ static const struct ata_port_operations piix_pata_ops = { .port_disable = ata_port_disable, .set_piomode = piix_set_piomode, .set_dmamode = piix_set_dmamode, - .mode_filter = ata_pci_default_filter, .tf_load = ata_tf_load, .tf_read = ata_tf_read, @@ -236,18 +234,16 @@ static const struct ata_port_operations piix_pata_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .probe_reset = piix_pata_probe_reset, + .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = piix_pata_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -266,18 +262,16 @@ static const struct ata_port_operations piix_sata_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .probe_reset = piix_sata_probe_reset, + .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = piix_sata_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -461,51 +455,59 @@ static void piix_pata_cbl_detect(struct ata_port *ap) } /** - * piix_pata_prereset - prereset for PATA host controller + * piix_pata_probeinit - probeinit for PATA host controller * @ap: Target port * - * Prereset including cable detection. + * Probeinit including cable detection. + * + * LOCKING: + * None (inherited from caller). + */ +static void piix_pata_probeinit(struct ata_port *ap) +{ + piix_pata_cbl_detect(ap); + ata_std_probeinit(ap); +} + +/** + * piix_pata_probe_reset - Perform reset on PATA port and classify + * @ap: Port to reset + * @classes: Resulting classes of attached devices + * + * Reset PATA phy and classify attached devices. * * LOCKING: * None (inherited from caller). */ -static int piix_pata_prereset(struct ata_port *ap) +static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { - ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); - ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); return 0; } - piix_pata_cbl_detect(ap); - - return ata_std_prereset(ap); -} - -static void piix_pata_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, piix_pata_prereset, ata_std_softreset, NULL, - ata_std_postreset); + return ata_drive_probe_reset(ap, piix_pata_probeinit, + ata_std_softreset, NULL, + ata_std_postreset, classes); } /** - * piix_sata_prereset - prereset for SATA host controller - * @ap: Target port + * piix_sata_probe - Probe PCI device for present SATA devices + * @ap: Port associated with the PCI device we wish to probe * * Reads and configures SATA PCI device's PCI config register * Port Configuration and Status (PCS) to determine port and - * device availability. Return -ENODEV to skip reset if no - * device is present. + * device availability. * * LOCKING: * None (inherited from caller). * * RETURNS: - * 0 if device is present, -ENODEV otherwise. + * Mask of avaliable devices on the port. */ -static int piix_sata_prereset(struct ata_port *ap) +static unsigned int piix_sata_probe (struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); const unsigned int *map = ap->host_set->private_data; @@ -547,19 +549,29 @@ static int piix_sata_prereset(struct ata_port *ap) DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", ap->id, pcs, present_mask); - if (!present_mask) { - ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); - ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; - return 0; - } - - return ata_std_prereset(ap); + return present_mask; } -static void piix_sata_error_handler(struct ata_port *ap) +/** + * piix_sata_probe_reset - Perform reset on SATA port and classify + * @ap: Port to reset + * @classes: Resulting classes of attached devices + * + * Reset SATA phy and classify attached devices. + * + * LOCKING: + * None (inherited from caller). + */ +static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes) { - ata_bmdma_drive_eh(ap, piix_sata_prereset, ata_std_softreset, NULL, - ata_std_postreset); + if (!piix_sata_probe(ap)) { + printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id); + return 0; + } + + return ata_drive_probe_reset(ap, ata_std_probeinit, + ata_std_softreset, NULL, + ata_std_postreset, classes); } /** @@ -748,15 +760,15 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); pci_read_config_word(pdev, 0x41, &cfg); /* Only on the original revision: IDE DMA can hang */ - if (rev == 0x00) + if(rev == 0x00) no_piix_dma = 1; /* On all revisions below 5 PXB bus lock must be disabled for IDE */ - else if (cfg & (1<<14) && rev < 5) + else if(cfg & (1<<14) && rev < 5) no_piix_dma = 2; } - if (no_piix_dma) + if(no_piix_dma) dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n"); - if (no_piix_dma == 2) + if(no_piix_dma == 2) dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n"); return no_piix_dma; } diff --git a/trunk/drivers/scsi/atp870u.c b/trunk/drivers/scsi/atp870u.c index 3ee4d4d3f445..a198d86667e9 100644 --- a/trunk/drivers/scsi/atp870u.c +++ b/trunk/drivers/scsi/atp870u.c @@ -473,7 +473,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *re */ if (workreq->use_sg) { pci_unmap_sg(dev->pdev, - (struct scatterlist *)workreq->request_buffer, + (struct scatterlist *)workreq->buffer, workreq->use_sg, workreq->sc_data_direction); } else if (workreq->request_bufflen && @@ -3047,7 +3047,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (atp_dev.chip_ver == 4) shpnt->max_id = 16; else - shpnt->max_id = 8; + shpnt->max_id = 7; shpnt->this_id = host_id; shpnt->unique_id = base_io; shpnt->io_port = base_io; diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index d92d5040a9fe..30a335349cee 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -13,9 +13,9 @@ #include #include -#include #include #include +#include #include #include @@ -114,7 +114,8 @@ static const struct value_name_pair maint_in_arr[] = { {0xd, "Report supported task management functions"}, {0xe, "Report priority"}, }; -#define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr) +#define MAINT_IN_SZ \ + (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0])) static const struct value_name_pair maint_out_arr[] = { {0x6, "Set device identifier"}, @@ -122,29 +123,34 @@ static const struct value_name_pair maint_out_arr[] = { {0xb, "Change aliases"}, {0xe, "Set priority"}, }; -#define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr) +#define MAINT_OUT_SZ \ + (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0])) static const struct value_name_pair serv_in12_arr[] = { {0x1, "Read media serial number"}, }; -#define SERV_IN12_SZ ARRAY_SIZE(serv_in12_arr) +#define SERV_IN12_SZ \ + (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0])) static const struct value_name_pair serv_out12_arr[] = { {-1, "dummy entry"}, }; -#define SERV_OUT12_SZ ARRAY_SIZE(serv_out12_arr) +#define SERV_OUT12_SZ \ + (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0])) static const struct value_name_pair serv_in16_arr[] = { {0x10, "Read capacity(16)"}, {0x11, "Read long(16)"}, }; -#define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr) +#define SERV_IN16_SZ \ + (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0])) static const struct value_name_pair serv_out16_arr[] = { {0x11, "Write long(16)"}, {0x1f, "Notify data transfer device(16)"}, }; -#define SERV_OUT16_SZ ARRAY_SIZE(serv_out16_arr) +#define SERV_OUT16_SZ \ + (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0])) static const struct value_name_pair variable_length_arr[] = { {0x1, "Rebuild(32)"}, @@ -184,7 +190,8 @@ static const struct value_name_pair variable_length_arr[] = { {0x8f7e, "Perform SCSI command (osd)"}, {0x8f7f, "Perform task management function (osd)"}, }; -#define VARIABLE_LENGTH_SZ ARRAY_SIZE(variable_length_arr) +#define VARIABLE_LENGTH_SZ \ + (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0])) static const char * get_sa_name(const struct value_name_pair * arr, int arr_sz, int service_action) @@ -1261,6 +1268,16 @@ void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) } EXPORT_SYMBOL(scsi_print_sense); +void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq) +{ + const char *name = devclass; + + if (sreq->sr_request->rq_disk) + name = sreq->sr_request->rq_disk->disk_name; + __scsi_print_sense(name, sreq->sr_sense_buffer, SCSI_SENSE_BUFFERSIZE); +} +EXPORT_SYMBOL(scsi_print_req_sense); + void scsi_print_command(struct scsi_cmnd *cmd) { /* Assume appended output (i.e. not at start of line) */ @@ -1273,10 +1290,10 @@ EXPORT_SYMBOL(scsi_print_command); #ifdef CONFIG_SCSI_CONSTANTS static const char * const hostbyte_table[]={ -"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", +"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; -#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) +#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *)) void scsi_print_hostbyte(int scsiresult) { @@ -1286,7 +1303,7 @@ void scsi_print_hostbyte(int scsiresult) if (hb < NUM_HOSTBYTE_STRS) printk("(%s) ", hostbyte_table[hb]); else - printk("is invalid "); + printk("is invalid "); } #else void scsi_print_hostbyte(int scsiresult) @@ -1298,14 +1315,14 @@ void scsi_print_hostbyte(int scsiresult) #ifdef CONFIG_SCSI_CONSTANTS static const char * const driverbyte_table[]={ -"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", +"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; -#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) +#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *)) static const char * const driversuggest_table[]={"SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; -#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) +#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *)) void scsi_print_driverbyte(int scsiresult) { diff --git a/trunk/drivers/scsi/dc395x.c b/trunk/drivers/scsi/dc395x.c index 58b0748045ee..cbf825263f3b 100644 --- a/trunk/drivers/scsi/dc395x.c +++ b/trunk/drivers/scsi/dc395x.c @@ -230,12 +230,13 @@ struct ScsiReqBlk { struct scsi_cmnd *cmd; struct SGentry *segment_x; /* Linear array of hw sg entries (up to 64 entries) */ - dma_addr_t sg_bus_addr; /* Bus address of sg list (ie, of segment_x) */ + u32 sg_bus_addr; /* Bus address of sg list (ie, of segment_x) */ u8 sg_count; /* No of HW sg entries for this request */ u8 sg_index; /* Index of HW sg entry for this request */ - size_t total_xfer_length; /* Total number of bytes remaining to be transfered */ - size_t request_length; /* Total number of bytes in this request */ + u32 total_xfer_length; /* Total number of bytes remaining to be transfered */ + unsigned char *virt_addr; /* Virtual address of current transfer position */ + /* * The sense buffer handling function, request_sense, uses * the first hw sg entry (segment_x[0]) and the transfer @@ -245,7 +246,8 @@ struct ScsiReqBlk { * total_xfer_length in xferred. These values are restored in * pci_unmap_srb_sense. This is the only place xferred is used. */ - size_t xferred; /* Saved copy of total_xfer_length */ + unsigned char *virt_addr_req; /* Saved virtual address of the request buffer */ + u32 xferred; /* Saved copy of total_xfer_length */ u16 state; @@ -975,6 +977,17 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb) } } +static inline void pio_trigger(void) +{ + static int feedback_requested; + + if (!feedback_requested) { + feedback_requested = 1; + printk(KERN_WARNING "%s: Please, contact " + "to help improve support for your system.\n", __FILE__); + } +} + /* Prepare SRB for being sent to Device DCB w/ command *cmd */ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) @@ -988,6 +1001,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, srb->sg_count = 0; srb->total_xfer_length = 0; srb->sg_bus_addr = 0; + srb->virt_addr = NULL; srb->sg_index = 0; srb->adapter_status = 0; srb->target_status = 0; @@ -1018,6 +1032,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, reqlen, cmd->request_buffer, cmd->use_sg, srb->sg_count); + srb->virt_addr = page_address(sl->page); for (i = 0; i < srb->sg_count; i++) { u32 busaddr = (u32)sg_dma_address(&sl[i]); u32 seglen = (u32)sl[i].length; @@ -1062,14 +1077,12 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, srb->total_xfer_length++; srb->segment_x[0].length = srb->total_xfer_length; - + srb->virt_addr = cmd->request_buffer; dprintkdbg(DBG_0, "build_srb: [1] len=%d buf=%p use_sg=%d map=%08x\n", srb->total_xfer_length, cmd->request_buffer, cmd->use_sg, srb->segment_x[0].address); } - - srb->request_length = srb->total_xfer_length; } @@ -1401,10 +1414,10 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd) } srb = find_cmd(cmd, &dcb->srb_going_list); if (srb) { - dprintkl(KERN_DEBUG, "eh_abort: Command in progress\n"); + dprintkl(KERN_DEBUG, "eh_abort: Command in progress"); /* XXX: Should abort the command here */ } else { - dprintkl(KERN_DEBUG, "eh_abort: Command not found\n"); + dprintkl(KERN_DEBUG, "eh_abort: Command not found"); } return FAILED; } @@ -1963,11 +1976,14 @@ static void sg_verify_length(struct ScsiReqBlk *srb) /* * Compute the next Scatter Gather list index and adjust its length - * and address if necessary + * and address if necessary; also compute virt_addr */ static void sg_update_list(struct ScsiReqBlk *srb, u32 left) { u8 idx; + struct scatterlist *sg; + struct scsi_cmnd *cmd = srb->cmd; + int segment = cmd->use_sg; u32 xferred = srb->total_xfer_length - left; /* bytes transfered */ struct SGentry *psge = srb->segment_x + srb->sg_index; @@ -2000,6 +2016,29 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left) psge++; } sg_verify_length(srb); + + /* we need the corresponding virtual address */ + if (!segment || (srb->flag & AUTO_REQSENSE)) { + srb->virt_addr += xferred; + return; + } + + /* We have to walk the scatterlist to find it */ + sg = (struct scatterlist *)cmd->request_buffer; + while (segment--) { + unsigned long mask = + ~((unsigned long)sg->length - 1) & PAGE_MASK; + if ((sg_dma_address(sg) & mask) == (psge->address & mask)) { + srb->virt_addr = (page_address(sg->page) + + psge->address - + (psge->address & PAGE_MASK)); + return; + } + ++sg; + } + + dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n"); + srb->virt_addr = NULL; } @@ -2011,7 +2050,15 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left) */ static void sg_subtract_one(struct ScsiReqBlk *srb) { - sg_update_list(srb, srb->total_xfer_length - 1); + srb->total_xfer_length--; + srb->segment_x[srb->sg_index].length--; + if (srb->total_xfer_length && + !srb->segment_x[srb->sg_index].length) { + if (debug_enabled(DBG_PIO)) + printk(" (next segment)"); + srb->sg_index++; + sg_update_list(srb, srb->total_xfer_length); + } } @@ -2071,7 +2118,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, * If we need more data, the DMA SG list will be freshly set up, anyway */ dprintkdbg(DBG_PIO, "data_out_phase0: " - "DMA{fifocnt=0x%02x fifostat=0x%02x} " + "DMA{fifcnt=0x%02x fifostat=0x%02x} " "SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n", DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), @@ -2192,11 +2239,12 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, data_io_transfer(acb, srb, XFERDATAOUT); } + static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, u16 *pscsi_status) { u16 scsi_status = *pscsi_status; - + u32 d_left_counter = 0; dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); @@ -2214,9 +2262,6 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, * seem to be a bad idea, actually. */ if (!(srb->state & SRB_XFERPAD)) { - u32 d_left_counter; - unsigned int sc, fc; - if (scsi_status & PARITYERROR) { dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " "Parity Error\n", srb->cmd->pid); @@ -2253,19 +2298,18 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT)); } /* Now: Check remainig data: The SCSI counters should tell us ... */ - sc = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER); - fc = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT); - d_left_counter = sc + ((fc & 0x1f) + d_left_counter = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER) + + ((DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f) << ((srb->dcb->sync_period & WIDE_SYNC) ? 1 : 0)); dprintkdbg(DBG_KG, "data_in_phase0: " "SCSI{fifocnt=0x%02x%s ctr=0x%08x} " "DMA{fifocnt=0x%02x fifostat=0x%02x ctr=0x%08x} " "Remain{totxfer=%i scsi_fifo+ctr=%i}\n", - fc, + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT), (srb->dcb->sync_period & WIDE_SYNC) ? "words" : "bytes", - sc, - fc, + DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), + DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT), DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT), DC395x_read32(acb, TRM_S1040_DMA_CXCNT), srb->total_xfer_length, d_left_counter); @@ -2273,79 +2317,40 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, /* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */ if (d_left_counter && srb->total_xfer_length <= DC395x_LASTPIO) { - size_t left_io = srb->total_xfer_length; - /*u32 addr = (srb->segment_x[srb->sg_index].address); */ /*sg_update_list (srb, d_left_counter); */ - dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) " - "for remaining %i bytes:", - fc & 0x1f, + dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) to " + "%p for remaining %i bytes:", + DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f, (srb->dcb->sync_period & WIDE_SYNC) ? "words" : "bytes", + srb->virt_addr, srb->total_xfer_length); if (srb->dcb->sync_period & WIDE_SYNC) DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, CFG2_WIDEFIFO); - while (left_io) { - unsigned char *virt, *base = NULL; - unsigned long flags = 0; - size_t len = left_io; - - if (srb->cmd->use_sg) { - size_t offset = srb->request_length - left_io; - local_irq_save(flags); - /* Assumption: it's inside one page as it's at most 4 bytes and - I just assume it's on a 4-byte boundary */ - base = scsi_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer, - srb->sg_count, &offset, &len); - virt = base + offset; - } else { - virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io; - len = left_io; - } - left_io -= len; - - while (len) { - u8 byte; - byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); - *virt++ = byte; - + while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) { + u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + pio_trigger(); + *(srb->virt_addr)++ = byte; + if (debug_enabled(DBG_PIO)) + printk(" %02x", byte); + d_left_counter--; + sg_subtract_one(srb); + } + if (srb->dcb->sync_period & WIDE_SYNC) { +#if 1 + /* Read the last byte ... */ + if (srb->total_xfer_length > 0) { + u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); + pio_trigger(); + *(srb->virt_addr)++ = byte; + srb->total_xfer_length--; if (debug_enabled(DBG_PIO)) printk(" %02x", byte); - - d_left_counter--; - sg_subtract_one(srb); - - len--; - - fc = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT); - - if (fc == 0x40) { - left_io = 0; - break; - } - } - - WARN_ON((fc != 0x40) == !d_left_counter); - - if (fc == 0x40 && (srb->dcb->sync_period & WIDE_SYNC)) { - /* Read the last byte ... */ - if (srb->total_xfer_length > 0) { - u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); - - *virt++ = byte; - srb->total_xfer_length--; - if (debug_enabled(DBG_PIO)) - printk(" %02x", byte); - } - - DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0); - } - - if (srb->cmd->use_sg) { - scsi_kunmap_atomic_sg(base); - local_irq_restore(flags); } +#endif + DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0); } /*printk(" %08x", *(u32*)(bus_to_virt (addr))); */ /*srb->total_xfer_length = 0; */ @@ -2504,43 +2509,22 @@ static void data_io_transfer(struct AdapterCtlBlk *acb, SCMD_FIFO_IN); } else { /* write */ int ln = srb->total_xfer_length; - size_t left_io = srb->total_xfer_length; - if (srb->dcb->sync_period & WIDE_SYNC) DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, CFG2_WIDEFIFO); + dprintkdbg(DBG_PIO, + "data_io_transfer: PIO %i bytes from %p:", + srb->total_xfer_length, srb->virt_addr); - while (left_io) { - unsigned char *virt, *base = NULL; - unsigned long flags = 0; - size_t len = left_io; - - if (srb->cmd->use_sg) { - size_t offset = srb->request_length - left_io; - local_irq_save(flags); - /* Again, max 4 bytes */ - base = scsi_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer, - srb->sg_count, &offset, &len); - virt = base + offset; - } else { - virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io; - len = left_io; - } - left_io -= len; - - while (len--) { - if (debug_enabled(DBG_PIO)) - printk(" %02x", *virt); - - DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *virt++); + while (srb->total_xfer_length) { + if (debug_enabled(DBG_PIO)) + printk(" %02x", (unsigned char) *(srb->virt_addr)); - sg_subtract_one(srb); - } + pio_trigger(); + DC395x_write8(acb, TRM_S1040_SCSI_FIFO, + *(srb->virt_addr)++); - if (srb->cmd->use_sg) { - scsi_kunmap_atomic_sg(base); - local_irq_restore(flags); - } + sg_subtract_one(srb); } if (srb->dcb->sync_period & WIDE_SYNC) { if (ln % 2) { @@ -3335,6 +3319,7 @@ static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb, srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address; srb->segment_x[0].length = srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].length; + srb->virt_addr = srb->virt_addr_req; } @@ -3347,14 +3332,21 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, { u8 tempcnt, status; struct scsi_cmnd *cmd = srb->cmd; + struct ScsiInqData *ptr; enum dma_data_direction dir = cmd->sc_data_direction; - int ckc_only = 1; + + if (cmd->use_sg) { + struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; + ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset); + } else { + ptr = (struct ScsiInqData *)(cmd->request_buffer); + } dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); - dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", + dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n", srb, cmd->use_sg, srb->sg_index, srb->sg_count, - cmd->request_buffer); + cmd->request_buffer, ptr); status = srb->target_status; if (srb->flag & AUTO_REQSENSE) { dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n"); @@ -3493,47 +3485,29 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, srb->segment_x[0].address, cmd->request_bufflen, dir); } - ckc_only = 0; + + if ((cmd->result & RES_DID) == 0 && cmd->cmnd[0] == INQUIRY + && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8 + && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2) + dcb->inquiry7 = ptr->Flags; /* Check Error Conditions */ ckc_e: - if (cmd->cmnd[0] == INQUIRY) { - unsigned char *base = NULL; - struct ScsiInqData *ptr; - unsigned long flags = 0; - - if (cmd->use_sg) { - struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; - size_t offset = 0, len = sizeof(struct ScsiInqData); - - local_irq_save(flags); - base = scsi_kmap_atomic_sg(sg, cmd->use_sg, &offset, &len); - ptr = (struct ScsiInqData *)(base + offset); - } else - ptr = (struct ScsiInqData *)(cmd->request_buffer); - - if (!ckc_only && (cmd->result & RES_DID) == 0 - && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8 - && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2) - dcb->inquiry7 = ptr->Flags; - /*if( srb->cmd->cmnd[0] == INQUIRY && */ /* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */ - if ((cmd->result == (DID_OK << 16) - || status_byte(cmd->result) & - CHECK_CONDITION)) { - if (!dcb->init_tcq_flag) { - add_dev(acb, dcb, ptr); - dcb->init_tcq_flag = 1; - } + if (cmd->cmnd[0] == INQUIRY && (cmd->result == (DID_OK << 16) + || status_byte(cmd-> + result) & + CHECK_CONDITION)) { + + if (!dcb->init_tcq_flag) { + add_dev(acb, dcb, ptr); + dcb->init_tcq_flag = 1; } - if (cmd->use_sg) { - scsi_kunmap_atomic_sg(base); - local_irq_restore(flags); - } } + /* Here is the info for Doug Gilbert's sg3 ... */ cmd->resid = srb->total_xfer_length; /* This may be interpreted by sb. or not ... */ @@ -3739,6 +3713,8 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, srb->xferred = srb->total_xfer_length; /* srb->segment_x : a one entry of S/G list table */ srb->total_xfer_length = sizeof(cmd->sense_buffer); + srb->virt_addr_req = srb->virt_addr; + srb->virt_addr = cmd->sense_buffer; srb->segment_x[0].length = sizeof(cmd->sense_buffer); /* Map sense buffer */ srb->segment_x[0].address = @@ -3771,7 +3747,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, * @target: The target for the new device. * @lun: The lun for the new device. * - * Return the new device if successful or NULL on failure. + * Return the new device if succesfull or NULL on failure. **/ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 target, u8 lun) diff --git a/trunk/drivers/scsi/dtc.c b/trunk/drivers/scsi/dtc.c index c5108c8c887b..310d2f488668 100644 --- a/trunk/drivers/scsi/dtc.c +++ b/trunk/drivers/scsi/dtc.c @@ -145,35 +145,35 @@ static struct override { 0, IRQ_AUTO}}; #endif -#define NO_OVERRIDES ARRAY_SIZE(overrides) +#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) static struct base { unsigned long address; int noauto; -} bases[] __initdata = { - { 0xcc000, 0 }, - { 0xc8000, 0 }, - { 0xdc000, 0 }, +} bases[] __initdata = { + { 0xcc000, 0 }, + { 0xc8000, 0 }, + { 0xdc000, 0 }, { 0xd8000, 0 } }; -#define NO_BASES ARRAY_SIZE(bases) +#define NO_BASES (sizeof (bases) / sizeof (struct base)) static const struct signature { const char *string; int offset; -} signatures[] = { +} signatures[] = { {"DATA TECHNOLOGY CORPORATION BIOS", 0x25}, }; -#define NO_SIGNATURES ARRAY_SIZE(signatures) +#define NO_SIGNATURES (sizeof (signatures) / sizeof (struct signature)) #ifndef MODULE /* * Function : dtc_setup(char *str, int *ints) * * Purpose : LILO command line initialization of the overrides array, - * + * * Inputs : str - unused, ints - array of integer parameters with ints[0] * equal to the number of ints. * diff --git a/trunk/drivers/scsi/esp.c b/trunk/drivers/scsi/esp.c index ddb512463b45..0a3e45d7a972 100644 --- a/trunk/drivers/scsi/esp.c +++ b/trunk/drivers/scsi/esp.c @@ -1,6 +1,7 @@ -/* esp.c: ESP Sun SCSI driver. +/* $Id: esp.c,v 1.101 2002/01/15 06:48:55 davem Exp $ + * esp.c: EnhancedScsiProcessor Sun SCSI driver code. * - * Copyright (C) 1995, 1998, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) */ /* TODO: @@ -184,6 +185,11 @@ enum { /*5*/ do_intr_end }; +/* The master ring of all esp hosts we are managing in this driver. */ +static struct esp *espchain; +static DEFINE_SPINLOCK(espchain_lock); +static int esps_running = 0; + /* Forward declarations. */ static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); @@ -688,6 +694,36 @@ static void __init esp_bootup_reset(struct esp *esp) sbus_readb(esp->eregs + ESP_INTRPT); } +static void esp_chain_add(struct esp *esp) +{ + spin_lock_irq(&espchain_lock); + if (espchain) { + struct esp *elink = espchain; + while (elink->next) + elink = elink->next; + elink->next = esp; + } else { + espchain = esp; + } + esp->next = NULL; + spin_unlock_irq(&espchain_lock); +} + +static void esp_chain_del(struct esp *esp) +{ + spin_lock_irq(&espchain_lock); + if (espchain == esp) { + espchain = esp->next; + } else { + struct esp *elink = espchain; + while (elink->next != esp) + elink = elink->next; + elink->next = esp->next; + } + esp->next = NULL; + spin_unlock_irq(&espchain_lock); +} + static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev) { struct sbus_dev *sdev = esp->sdev; @@ -794,20 +830,19 @@ static int __init esp_register_irq(struct esp *esp) static void __init esp_get_scsi_id(struct esp *esp) { struct sbus_dev *sdev = esp->sdev; - struct device_node *dp = sdev->ofdev.node; - esp->scsi_id = of_getintprop_default(dp, - "initiator-id", - -1); + esp->scsi_id = prom_getintdefault(esp->prom_node, + "initiator-id", + -1); if (esp->scsi_id == -1) - esp->scsi_id = of_getintprop_default(dp, - "scsi-initiator-id", - -1); + esp->scsi_id = prom_getintdefault(esp->prom_node, + "scsi-initiator-id", + -1); if (esp->scsi_id == -1) esp->scsi_id = (sdev->bus == NULL) ? 7 : - of_getintprop_default(sdev->bus->ofdev.node, - "scsi-initiator-id", - 7); + prom_getintdefault(sdev->bus->prom_node, + "scsi-initiator-id", + 7); esp->ehost->this_id = esp->scsi_id; esp->scsi_id_mask = (1 << esp->scsi_id); @@ -1032,30 +1067,28 @@ static void __init esp_init_swstate(struct esp *esp) esp->prev_hme_dmacsr = 0xffffffff; } -static int __init detect_one_esp(struct scsi_host_template *tpnt, - struct device *dev, - struct sbus_dev *esp_dev, - struct sbus_dev *espdma, - struct sbus_bus *sbus, - int hme) +static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, + struct sbus_dev *espdma, struct sbus_bus *sbus, + int id, int hme) { - static int instance; - struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp)); + struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp)); struct esp *esp; - if (!esp_host) - return -ENOMEM; - + if (!esp_host) { + printk("ESP: Cannot register SCSI host\n"); + return -1; + } if (hme) esp_host->max_id = 16; esp = (struct esp *) esp_host->hostdata; esp->ehost = esp_host; esp->sdev = esp_dev; - esp->esp_id = instance; + esp->esp_id = id; esp->prom_node = esp_dev->prom_node; prom_getstring(esp->prom_node, "name", esp->prom_name, sizeof(esp->prom_name)); + esp_chain_add(esp); if (esp_find_dvma(esp, espdma) < 0) goto fail_unlink; if (esp_map_regs(esp, hme) < 0) { @@ -1082,19 +1115,8 @@ static int __init detect_one_esp(struct scsi_host_template *tpnt, esp_bootup_reset(esp); - if (scsi_add_host(esp_host, dev)) - goto fail_free_irq; - - dev_set_drvdata(&esp_dev->ofdev.dev, esp); - - scsi_scan_host(esp_host); - instance++; - return 0; -fail_free_irq: - free_irq(esp->ehost->irq, esp); - fail_unmap_cmdarea: sbus_free_consistent(esp->sdev, 16, (void *) esp->esp_command, @@ -1107,98 +1129,119 @@ static int __init detect_one_esp(struct scsi_host_template *tpnt, esp->dma->allocated = 0; fail_unlink: - scsi_host_put(esp_host); + esp_chain_del(esp); + scsi_unregister(esp_host); return -1; } /* Detecting ESP chips on the machine. This is the simple and easy * version. */ -static int __devexit esp_remove_common(struct esp *esp) -{ - unsigned int irq = esp->ehost->irq; - - scsi_remove_host(esp->ehost); - - ESP_INTSOFF(esp->dregs); -#if 0 - esp_reset_dma(esp); - esp_reset_esp(esp); -#endif - - free_irq(irq, esp); - sbus_free_consistent(esp->sdev, 16, - (void *) esp->esp_command, esp->esp_command_dvma); - sbus_iounmap(esp->eregs, ESP_REG_SIZE); - esp->dma->allocated = 0; - - scsi_host_put(esp->ehost); - - return 0; -} - #ifdef CONFIG_SUN4 #include -static struct sbus_dev sun4_esp_dev; - -static int __init esp_sun4_probe(struct scsi_host_template *tpnt) +static int __init esp_detect(struct scsi_host_template *tpnt) { + static struct sbus_dev esp_dev; + int esps_in_use = 0; + + espchain = NULL; + if (sun4_esp_physaddr) { - memset(&sun4_esp_dev, 0, sizeof(esp_dev)); - sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; - sun4_esp_dev.irqs[0] = 4; - sun4_esp_dev.resource[0].start = sun4_esp_physaddr; - sun4_esp_dev.resource[0].end = - sun4_esp_physaddr + ESP_REG_SIZE - 1; - sun4_esp_dev.resource[0].flags = IORESOURCE_IO; - - return detect_one_esp(tpnt, NULL, - &sun4_esp_dev, NULL, NULL, 0); + memset (&esp_dev, 0, sizeof(esp_dev)); + esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; + esp_dev.irqs[0] = 4; + esp_dev.resource[0].start = sun4_esp_physaddr; + esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1; + esp_dev.resource[0].flags = IORESOURCE_IO; + + if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0)) + esps_in_use++; + printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use); + esps_running = esps_in_use; } - return 0; + return esps_in_use; } -static int __devexit esp_sun4_remove(void) +#else /* !CONFIG_SUN4 */ + +static int __init esp_detect(struct scsi_host_template *tpnt) { - struct esp *esp = dev_get_drvdata(&dev->dev); + struct sbus_bus *sbus; + struct sbus_dev *esp_dev, *sbdev_iter; + int nesps = 0, esps_in_use = 0; - return esp_remove_common(esp); + espchain = 0; + if (!sbus_root) { +#ifdef CONFIG_PCI + return 0; +#else + panic("No SBUS in esp_detect()"); +#endif + } + for_each_sbus(sbus) { + for_each_sbusdev(sbdev_iter, sbus) { + struct sbus_dev *espdma = NULL; + int hme = 0; + + /* Is it an esp sbus device? */ + esp_dev = sbdev_iter; + if (strcmp(esp_dev->prom_name, "esp") && + strcmp(esp_dev->prom_name, "SUNW,esp")) { + if (!strcmp(esp_dev->prom_name, "SUNW,fas")) { + hme = 1; + espdma = esp_dev; + } else { + if (!esp_dev->child || + (strcmp(esp_dev->prom_name, "espdma") && + strcmp(esp_dev->prom_name, "dma"))) + continue; /* nope... */ + espdma = esp_dev; + esp_dev = esp_dev->child; + if (strcmp(esp_dev->prom_name, "esp") && + strcmp(esp_dev->prom_name, "SUNW,esp")) + continue; /* how can this happen? */ + } + } + + if (detect_one_esp(tpnt, esp_dev, espdma, sbus, nesps++, hme) < 0) + continue; + + esps_in_use++; + } /* for each sbusdev */ + } /* for each sbus */ + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, + esps_in_use); + esps_running = esps_in_use; + return esps_in_use; } -#else /* !CONFIG_SUN4 */ +#endif /* !CONFIG_SUN4 */ -static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match) +/* + */ +static int esp_release(struct Scsi_Host *host) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - struct sbus_dev *dma_sdev = NULL; - int hme = 0; - - if (dp->parent && - (!strcmp(dp->parent->name, "espdma") || - !strcmp(dp->parent->name, "dma"))) - dma_sdev = sdev->parent; - else if (!strcmp(dp->name, "SUNW,fas")) { - dma_sdev = sdev; - hme = 1; - } + struct esp *esp = (struct esp *) host->hostdata; - return detect_one_esp(match->data, &dev->dev, - sdev, dma_sdev, sdev->bus, hme); -} + ESP_INTSOFF(esp->dregs); +#if 0 + esp_reset_dma(esp); + esp_reset_esp(esp); +#endif -static int __devexit esp_sbus_remove(struct of_device *dev) -{ - struct esp *esp = dev_get_drvdata(&dev->dev); + free_irq(esp->ehost->irq, esp); + sbus_free_consistent(esp->sdev, 16, + (void *) esp->esp_command, esp->esp_command_dvma); + sbus_iounmap(esp->eregs, ESP_REG_SIZE); + esp->dma->allocated = 0; + esp_chain_del(esp); - return esp_remove_common(esp); + return 0; } -#endif /* !CONFIG_SUN4 */ - /* The info function will return whatever useful * information the developer sees fit. If not provided, then * the name field will be used instead. @@ -1372,11 +1415,18 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len) static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) { - struct esp *esp = (struct esp *) host->hostdata; + struct esp *esp; if (inout) return -EINVAL; /* not yet */ + for_each_esp(esp) { + if (esp->ehost == host) + break; + } + if (!esp) + return -EINVAL; + if (start) *start = buffer; @@ -4327,12 +4377,15 @@ static void esp_slave_destroy(struct scsi_device *SDptr) SDptr->hostdata = NULL; } -static struct scsi_host_template esp_template = { - .module = THIS_MODULE, - .name = "esp", - .info = esp_info, +static struct scsi_host_template driver_template = { + .proc_name = "esp", + .proc_info = esp_proc_info, + .name = "Sun ESP 100/100a/200", + .detect = esp_detect, .slave_alloc = esp_slave_alloc, .slave_destroy = esp_slave_destroy, + .release = esp_release, + .info = esp_info, .queuecommand = esp_queue, .eh_abort_handler = esp_abort, .eh_bus_reset_handler = esp_reset, @@ -4341,58 +4394,12 @@ static struct scsi_host_template esp_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, - .proc_name = "esp", - .proc_info = esp_proc_info, -}; - -#ifndef CONFIG_SUN4 -static struct of_device_id esp_match[] = { - { - .name = "SUNW,esp", - .data = &esp_template, - }, - { - .name = "SUNW,fas", - .data = &esp_template, - }, - { - .name = "esp", - .data = &esp_template, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, esp_match); - -static struct of_platform_driver esp_sbus_driver = { - .name = "esp", - .match_table = esp_match, - .probe = esp_sbus_probe, - .remove = __devexit_p(esp_sbus_remove), }; -#endif - -static int __init esp_init(void) -{ -#ifdef CONFIG_SUN4 - return esp_sun4_probe(&esp_template); -#else - return of_register_driver(&esp_sbus_driver, &sbus_bus_type); -#endif -} -static void __exit esp_exit(void) -{ -#ifdef CONFIG_SUN4 - esp_sun4_remove(); -#else - of_unregister_driver(&esp_sbus_driver); -#endif -} +#include "scsi_module.c" -MODULE_DESCRIPTION("ESP Sun SCSI driver"); -MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver"); +MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -module_init(esp_init); -module_exit(esp_exit); diff --git a/trunk/drivers/scsi/esp.h b/trunk/drivers/scsi/esp.h index a98cda9121fc..73f7d6968ab6 100644 --- a/trunk/drivers/scsi/esp.h +++ b/trunk/drivers/scsi/esp.h @@ -403,4 +403,8 @@ struct esp { #define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) #define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) +/* For our interrupt engine. */ +#define for_each_esp(esp) \ + for((esp) = espchain; (esp); (esp) = (esp)->next) + #endif /* !(_SPARC_ESP_H) */ diff --git a/trunk/drivers/scsi/fd_mcs.c b/trunk/drivers/scsi/fd_mcs.c index 70a1606bd580..cca485a2b438 100644 --- a/trunk/drivers/scsi/fd_mcs.c +++ b/trunk/drivers/scsi/fd_mcs.c @@ -279,7 +279,7 @@ static struct fd_mcs_adapters_struct fd_mcs_adapters[] = { 2}, }; -#define FD_BRDS ARRAY_SIZE(fd_mcs_adapters) +#define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct) static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs); diff --git a/trunk/drivers/scsi/fdomain.c b/trunk/drivers/scsi/fdomain.c index e16013f0ad6e..7334244397d1 100644 --- a/trunk/drivers/scsi/fdomain.c +++ b/trunk/drivers/scsi/fdomain.c @@ -420,10 +420,10 @@ static unsigned long addresses[] = { 0xd0000, 0xe0000, }; -#define ADDRESS_COUNT ARRAY_SIZE(addresses) - +#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned )) + static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 }; -#define PORT_COUNT ARRAY_SIZE(ports) +#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short )) static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 }; @@ -502,7 +502,7 @@ static struct signature { geometry location are verified). */ }; -#define SIGNATURE_COUNT ARRAY_SIZE(signatures) +#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature )) static void print_banner( struct Scsi_Host *shpnt ) { @@ -519,7 +519,7 @@ static void print_banner( struct Scsi_Host *shpnt ) if (bios_minor >= 0) printk("%d", bios_minor); else printk("?."); - + printk( " at 0x%lx using scsi id %d\n", bios_base, shpnt->this_id ); } diff --git a/trunk/drivers/scsi/g_NCR5380.c b/trunk/drivers/scsi/g_NCR5380.c index 5f313c93b7a9..e6bcfe949340 100644 --- a/trunk/drivers/scsi/g_NCR5380.c +++ b/trunk/drivers/scsi/g_NCR5380.c @@ -138,9 +138,10 @@ static struct override { [1] __initdata = { { 0,},}; #endif -#define NO_OVERRIDES ARRAY_SIZE(overrides) -#ifndef MODULE +#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) + +#ifndef MODULE /** * internal_setup - handle lilo command string override @@ -209,7 +210,7 @@ static int __init do_NCR5380_setup(char *str) { int ints[10]; - get_options(str, ARRAY_SIZE(ints), ints); + get_options(str, sizeof(ints) / sizeof(int), ints); internal_setup(BOARD_NCR5380, str, ints); return 1; } @@ -217,7 +218,7 @@ static int __init do_NCR5380_setup(char *str) /** * do_NCR53C400_setup - set up entry point * @str: unused - * @ints: integer parameters from kernel setup code + * @ints: integer parameters from kernel setup code * * Setup function invoked at boot to parse the ncr53c400= command * line. @@ -227,7 +228,7 @@ static int __init do_NCR53C400_setup(char *str) { int ints[10]; - get_options(str, ARRAY_SIZE(ints), ints); + get_options(str, sizeof(ints) / sizeof(int), ints); internal_setup(BOARD_NCR53C400, str, ints); return 1; } @@ -235,7 +236,7 @@ static int __init do_NCR53C400_setup(char *str) /** * do_NCR53C400A_setup - set up entry point * @str: unused - * @ints: integer parameters from kernel setup code + * @ints: integer parameters from kernel setup code * * Setup function invoked at boot to parse the ncr53c400a= command * line. @@ -245,7 +246,7 @@ static int __init do_NCR53C400A_setup(char *str) { int ints[10]; - get_options(str, ARRAY_SIZE(ints), ints); + get_options(str, sizeof(ints) / sizeof(int), ints); internal_setup(BOARD_NCR53C400A, str, ints); return 1; } @@ -253,7 +254,7 @@ static int __init do_NCR53C400A_setup(char *str) /** * do_DTC3181E_setup - set up entry point * @str: unused - * @ints: integer parameters from kernel setup code + * @ints: integer parameters from kernel setup code * * Setup function invoked at boot to parse the dtc3181e= command * line. @@ -263,7 +264,7 @@ static int __init do_DTC3181E_setup(char *str) { int ints[10]; - get_options(str, ARRAY_SIZE(ints), ints); + get_options(str, sizeof(ints) / sizeof(int), ints); internal_setup(BOARD_DTC3181E, str, ints); return 1; } diff --git a/trunk/drivers/scsi/gdth.c b/trunk/drivers/scsi/gdth.c index 76071a158306..d5740bbdef3e 100644 --- a/trunk/drivers/scsi/gdth.c +++ b/trunk/drivers/scsi/gdth.c @@ -4,9 +4,9 @@ * Intel Corporation: Storage RAID Controllers * * * * gdth.c * - * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner * + * Copyright (C) 1995-04 ICP vortex GmbH, Achim Leubner * * Copyright (C) 2002-04 Intel Corporation * - * Copyright (C) 2003-06 Adaptec Inc. * + * Copyright (C) 2003-04 Adaptec Inc. * * * * * * Additions/Fixes: * @@ -27,14 +27,9 @@ * along with this kernel; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * - * Linux kernel 2.4.x, 2.6.x supported * + * Linux kernel 2.2.x, 2.4.x, 2.6.x supported * * * * $Log: gdth.c,v $ - * Revision 1.74 2006/04/10 13:44:47 achim - * Community changes for 2.6.x - * Kernel 2.2.x no longer supported - * scsi_request interface removed, thanks to Christoph Hellwig - * * Revision 1.73 2004/03/31 13:33:03 achim * Special command 0xfd implemented to detect 64-bit DMA support * @@ -99,7 +94,7 @@ * Bugfix free_irq() * * Revision 1.56 2001/08/09 11:19:39 achim - * Scsi_Host_Template changes + * struct scsi_host_template changes * * Revision 1.55 2001/08/09 10:11:28 achim * Command HOST_UNFREEZE_IO before cache service init. @@ -393,13 +388,7 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) #include -#else -#define DMA_32BIT_MASK 0x00000000ffffffffULL -#define DMA_64BIT_MASK 0xffffffffffffffffULL -#endif - #ifdef GDTH_RTC #include #endif @@ -419,8 +408,8 @@ #include "scsi.h" #include -#include "gdth_kcompat.h" #include "gdth.h" +#include "gdth_kcompat.h" static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); @@ -475,8 +464,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, static void gdth_flush(int hanum); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); -static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); -static void gdth_scsi_done(struct scsi_cmnd *scp); #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -569,8 +556,8 @@ static struct timer_list gdth_timer; #endif #define PTR2USHORT(a) (ushort)(ulong)(a) -#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) -#define INDEX_OK(i,t) ((i)b) +#define INDEX_OK(i,t) ((i)hostdata)) #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) @@ -656,7 +643,6 @@ static int probe_eisa_isa = 0; static int force_dma32 = 0; /* parameters for modprobe/insmod */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) module_param_array(irq, int, NULL, 0); module_param(disable, int, 0); module_param(reserve_mode, int, 0); @@ -669,20 +655,6 @@ module_param(virt_ctr, int, 0); module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); -#else -MODULE_PARM(irq, "i"); -MODULE_PARM(disable, "i"); -MODULE_PARM(reserve_mode, "i"); -MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); -MODULE_PARM(reverse_scan, "i"); -MODULE_PARM(hdr_channel, "i"); -MODULE_PARM(max_ids, "i"); -MODULE_PARM(rescan, "i"); -MODULE_PARM(virt_ctr, "i"); -MODULE_PARM(shared_access, "i"); -MODULE_PARM(probe_eisa_isa, "i"); -MODULE_PARM(force_dma32, "i"); -#endif MODULE_AUTHOR("Achim Leubner"); MODULE_LICENSE("GPL"); @@ -711,91 +683,6 @@ static void gdth_delay(int milliseconds) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -static void gdth_scsi_done(struct scsi_cmnd *scp) -{ - TRACE2(("gdth_scsi_done()\n")); - - if (scp->request) - complete((struct completion *)scp->request); -} - -int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - Scsi_Cmnd *scp; - DECLARE_COMPLETION(wait); - int rval; - - scp = kmalloc(sizeof(*scp), GFP_KERNEL); - if (!scp) - return -ENOMEM; - memset(scp, 0, sizeof(*scp)); - scp->device = sdev; - /* use request field to save the ptr. to completion struct. */ - scp->request = (struct request *)&wait; - scp->timeout_per_command = timeout*HZ; - scp->request_buffer = gdtcmd; - scp->cmd_len = 12; - memcpy(scp->cmnd, cmnd, 12); - scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->done = gdth_scsi_done; /* some fn. test this */ - gdth_queuecommand(scp, gdth_scsi_done); - wait_for_completion(&wait); - - rval = scp->SCp.Status; - if (info) - *info = scp->SCp.Message; - kfree(scp); - return rval; -} -#else -static void gdth_scsi_done(Scsi_Cmnd *scp) -{ - TRACE2(("gdth_scsi_done()\n")); - - scp->request.rq_status = RQ_SCSI_DONE; - if (scp->request.waiting) - complete(scp->request.waiting); -} - -int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); - unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; - DECLARE_COMPLETION(wait); - int rval; - - if (!scp) - return -ENOMEM; - scp->cmd_len = 12; - scp->use_sg = 0; - scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->request.rq_status = RQ_SCSI_BUSY; - scp->request.waiting = &wait; - scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); - wait_for_completion(&wait); - - rval = scp->SCp.Status; - if (info) - *info = scp->SCp.Message; - - scsi_release_command(scp); - return rval; -} -#endif - -int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - struct scsi_device *sdev = scsi_get_host_dev(shost); - int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info); - - scsi_free_host_dev(sdev); - return rval; -} - static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs) { *cyls = size /HEADS/SECS; @@ -886,7 +773,7 @@ static struct pci_device_id gdthtable[] __attribute_used__ = { MODULE_DEVICE_TABLE(pci,gdthtable); static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, - ushort vendor, ushort device) + ushort vendor, ushort device) { ulong base0, base1, base2; struct pci_dev *pdev; @@ -2361,16 +2248,14 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); - if (scp->done != gdth_scsi_done) { - scp->SCp.this_residual = (int)priority; - b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; - t = scp->device->id; - if (priority >= DEFAULT_PRI) { - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || - (b==ha->virt_bus && thdr[t].lock)) { - TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); - } + scp->SCp.this_residual = (int)priority; + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + t = scp->device->id; + if (priority >= DEFAULT_PRI) { + if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || + (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { + TRACE2(("gdth_putq(): locked IO -> update_timeout()\n")); + scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } @@ -2424,18 +2309,14 @@ static void gdth_next(int hanum) for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - if (nscp->done != gdth_scsi_done) { - b = virt_ctr ? - NUMDATA(nscp->device->host)->busnum : nscp->device->channel; - t = nscp->device->id; - l = nscp->device->lun; - if (nscp->SCp.this_residual >= DEFAULT_PRI) { - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || - (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) - continue; - } - } else - b = t = l = 0; + b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; + t = nscp->device->id; + l = nscp->device->lun; + if (nscp->SCp.this_residual >= DEFAULT_PRI) { + if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || + (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) + continue; + } if (firsttime) { if (gdth_test_busy(hanum)) { /* controller busy ? */ @@ -2450,7 +2331,7 @@ static void gdth_next(int hanum) firsttime = FALSE; } - if (nscp->done != gdth_scsi_done) { + if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) { if (nscp->SCp.phase == -1) { nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ if (nscp->cmnd[0] == TEST_UNIT_READY) { @@ -2513,7 +2394,7 @@ static void gdth_next(int hanum) else nscp->scsi_done(nscp); } - } else if (nscp->done == gdth_scsi_done) { + } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) this_cmd = FALSE; next_cmd = FALSE; @@ -2661,13 +2542,13 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, gdth_ha_str *ha; char *address; - cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; + cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen; ha = HADATA(gdth_ctr_tab[hanum]); if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; for (i=0,cpsum=0; iuse_sg; ++i,++sl) { - unsigned long flags; + unsigned long flags; cpnow = (ushort)sl->length; TRACE(("copy_internal() now %d sum %d count %d %d\n", cpnow,cpsum,cpcount,(ushort)scp->bufflen)); @@ -2679,19 +2560,12 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, hanum); return; } - local_irq_save(flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; - memcpy(address,buffer,cpnow); - flush_dcache_page(sl->page); - kunmap_atomic(address, KM_BIO_SRC_IRQ); -#else - address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; + local_irq_save(flags); + address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; memcpy(address,buffer,cpnow); - flush_dcache_page(sl->page); - kunmap_atomic(address, KM_BH_IRQ); -#endif - local_irq_restore(flags); + flush_dcache_page(sl->page); + kunmap_atomic(address, KM_BIO_SRC_IRQ); + local_irq_restore(flags); if (cpsum == cpcount) break; buffer += cpnow; @@ -3072,9 +2946,9 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) offset = (ulong)scp->sense_buffer & ~PAGE_MASK; sense_paddr = pci_map_page(ha->pdev,page,offset, 16,PCI_DMA_FROMDEVICE); - *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; + scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr); /* high part, if 64bit */ - *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); + scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32); cmdp->OpCode = GDT_WRITE; /* always */ cmdp->BoardNode = LOCALBOARD; if (mode64) { @@ -3148,7 +3022,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) } #endif - } else if (scp->request_bufflen) { + } else { scp->SCp.Status = GDTH_MAP_SINGLE; scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; page = virt_to_page(scp->request_buffer); @@ -3435,7 +3309,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) } if (!gdth_polling) - spin_lock_irqsave(&ha2->smp_lock, flags); + spin_lock_irqsave(&ha2->smp_lock, flags); wait_index = 0; /* search controller */ @@ -3768,10 +3642,9 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) scp->request_bufflen,scp->SCp.Message); if (scp->SCp.buffer) { dma_addr_t addr; - addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; + addr = (dma_addr_t)(ulong32)scp->SCp.buffer; if (scp->host_scribble) - addr += (dma_addr_t) - ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); + addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32); pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); } @@ -4281,11 +4154,7 @@ int __init option_setup(char *str) return 1; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int __init gdth_detect(struct scsi_host_template *shtp) -#else -static int __init gdth_detect(Scsi_Host_Template *shtp) -#endif { struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; @@ -4319,7 +4188,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) return 0; } - printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); + printk("GDT-HA: Storage RAID Controller Driver. Version: %s \n",GDTH_VERSION_STR); /* initializations */ gdth_polling = TRUE; b = 0; gdth_clear_events(); @@ -4882,7 +4751,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, BUS_L2P(ha,b), 0, 0); gdth_polling = FALSE; - spin_unlock_irqrestore(&ha->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } return SUCCESS; } @@ -4950,9 +4819,7 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) priority = DEFAULT_PRI; if (scp->done == gdth_scsi_done) priority = scp->SCp.this_residual; - else - gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); - + gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); gdth_putq( hanum, scp, priority ); gdth_next( hanum ); return 0; @@ -5055,7 +4922,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) gdth_cmd_str cmd; int hanum; gdth_ha_str *ha; - int rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) @@ -5072,11 +4943,25 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) cmd.u.cache64.DeviceNo = res.number; else cmd.u.cache.DeviceNo = res.number; - - rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL); - if (rval < 0) - return rval; - res.status = rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + return -ENOMEM; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &cmd, cmnd, 30); + res.status = (ushort)srp->sr_command->SCp.Status; + scsi_release_request(srp); +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + return -ENOMEM; + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &cmd, cmnd, 30); + res.status = (ushort)scp->SCp.Status; + scsi_release_command(scp); +#endif if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) return -EFAULT; @@ -5089,8 +4974,12 @@ static int ioc_general(void __user *arg, char *cmnd) char *buf = NULL; ulong64 paddr; int hanum; - gdth_ha_str *ha; - int rval; + gdth_ha_str *ha; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || gen.ionode >= gdth_ctr_count) @@ -5182,10 +5071,27 @@ static int ioc_general(void __user *arg, char *cmnd) } } - rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info); - if (rval < 0) - return rval; - gen.status = rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + return -ENOMEM; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &gen.command, cmnd, gen.timeout); + gen.status = srp->sr_command->SCp.Status; + gen.info = srp->sr_command->SCp.Message; + scsi_release_request(srp); +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + return -ENOMEM; + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout); + gen.status = scp->SCp.Status; + gen.info = scp->SCp.Message; + scsi_release_command(scp); +#endif if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, gen.data_len + gen.sense_len)) { @@ -5208,22 +5114,40 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) gdth_ha_str *ha; unchar i; int hanum, rc = -ENOMEM; - u32 cluster_type = 0; - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif + rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); if (!rsc || !cmd) - goto free_fail; + goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || rsc->ionode >= gdth_ctr_count) { rc = -EFAULT; - goto free_fail; + goto free_fail; } hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); memset(cmd, 0, sizeof(gdth_cmd_str)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + goto free_fail; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + goto free_fail; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + for (i = 0; i < MAX_HDRIVES; ++i) { if (!ha->hdr[i].present) { rsc->hdr_list[i].bus = 0xff; @@ -5240,15 +5164,27 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK) - rsc->hdr_list[i].cluster_type = cluster_type; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + if (srp->sr_command->SCp.Status == S_OK) + rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + if (scp->SCp.Status == S_OK) + rsc->hdr_list[i].cluster_type = scp->SCp.Message; +#endif } } - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); +#else + scsi_release_command(scp); +#endif + if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) rc = -EFAULT; else - rc = 0; + rc = 0; free_fail: kfree(rsc); @@ -5266,21 +5202,40 @@ static int ioc_rescan(void __user *arg, char *cmnd) int rc = -ENOMEM; ulong flags; gdth_ha_str *ha; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd || !rsc) - goto free_fail; + goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || rsc->ionode >= gdth_ctr_count) { - rc = -EFAULT; - goto free_fail; + rc = -EFAULT; + goto free_fail; } hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); memset(cmd, 0, sizeof(gdth_cmd_str)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + goto free_fail; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + goto free_fail; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + if (rsc->flag == 0) { /* old method: re-init. cache service */ cmd->Service = CACHESERVICE; @@ -5291,8 +5246,19 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->OpCode = GDT_INIT; cmd->u.cache.DeviceNo = LINUX_OS; } - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#else + gdth_do_cmd(&scp, cmd, cmnd, 30); + status = (ushort)scp.SCp.Status; + info = (ulong32)scp.SCp.Message; +#endif i = 0; hdr_cnt = (status == S_OK ? (ushort)info : 0); } else { @@ -5307,9 +5273,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); rsc->hdr_list[i].bus = ha->virt_bus; rsc->hdr_list[i].target = i; @@ -5341,9 +5313,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); spin_unlock_irqrestore(&ha->smp_lock, flags); @@ -5354,9 +5332,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].cluster_type = ((status == S_OK && !shared_access) ? (ushort)info : 0); @@ -5369,18 +5353,29 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); spin_unlock_irqrestore(&ha->smp_lock, flags); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); +#else + scsi_release_command(scp); +#endif if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) rc = -EFAULT; else - rc = 0; + rc = 0; free_fail: kfree(rsc); @@ -5520,18 +5515,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, hanum = res.ionode; ha = HADATA(gdth_ctr_tab[hanum]); + /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.6.x */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - scp = kmalloc(sizeof(*scp), GFP_KERNEL); + scp = scsi_get_command(ha->sdev, GFP_KERNEL); if (!scp) return -ENOMEM; - memset(scp, 0, sizeof(*scp)); - scp->device = ha->sdev; scp->cmd_len = 12; scp->use_sg = 0; scp->device->channel = virt_ctr ? 0 : res.number; rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); - kfree(scp); + scsi_put_command(scp); #else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) @@ -5564,12 +5558,34 @@ static void gdth_flush(int hanum) int i; gdth_ha_str *ha; gdth_cmd_str gdtcmd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif + struct scsi_device *sdev; char cmnd[MAX_COMMAND_SIZE]; memset(cmnd, 0xff, MAX_COMMAND_SIZE); TRACE2(("gdth_flush() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + srp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!srp) + return; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) + return; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + for (i = 0; i < MAX_HDRIVES; ++i) { if (ha->hdr[i].present) { gdtcmd.BoardNode = LOCALBOARD; @@ -5585,10 +5601,20 @@ static void gdth_flush(int hanum) gdtcmd.u.cache.sg_canz = 0; } TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); - - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, &gdtcmd, cmnd, 30); +#else + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); +#endif } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); + scsi_free_host_dev(sdev); +#else + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif } /* shutdown routine */ @@ -5597,11 +5623,18 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) int hanum; #ifndef __alpha__ gdth_cmd_str gdtcmd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; + struct scsi_device *sdev; +#else + Scsi_Cmnd *scp; + struct scsi_device *sdev; +#endif char cmnd[MAX_COMMAND_SIZE]; #endif if (notifier_disabled) - return NOTIFY_OK; + return NOTIFY_OK; TRACE2(("gdth_halt() event %d\n",(int)event)); if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) @@ -5619,7 +5652,31 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdtcmd.Service = CACHESERVICE; gdtcmd.OpCode = GDT_RESET; TRACE2(("gdth_halt(): reset controller %d\n", hanum)); - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + srp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!srp) { + unregister_reboot_notifier(&gdth_notifier); + return NOTIFY_OK; + } + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &gdtcmd, cmnd, 10); + scsi_release_request(srp); + scsi_free_host_dev(sdev); +#else + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) { + unregister_reboot_notifier(&gdth_notifier); + return NOTIFY_OK; + } + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &gdtcmd, cmnd, 10); + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif #endif } printk("Done.\n"); @@ -5630,22 +5687,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) return NOTIFY_OK; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -/* configure lun */ -static int gdth_slave_configure(struct scsi_device *sdev) -{ - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - sdev->skip_ms_page_3f = 1; - sdev->skip_ms_page_8 = 1; - return 0; -} -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct scsi_host_template driver_template = { -#else -static Scsi_Host_Template driver_template = { -#endif .proc_name = "gdth", .proc_info = gdth_proc_info, .name = "GDT SCSI Disk Array Controller", @@ -5656,9 +5698,6 @@ static Scsi_Host_Template driver_template = { .eh_bus_reset_handler = gdth_eh_bus_reset, .bios_param = gdth_bios_param, .can_queue = GDTH_MAXCMDS, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - .slave_configure = gdth_slave_configure, -#endif .this_id = -1, .sg_tablesize = GDTH_MAXSG, .cmd_per_lun = GDTH_MAXC_P_L, diff --git a/trunk/drivers/scsi/gdth.h b/trunk/drivers/scsi/gdth.h index 47eae0299750..cc4882fb97ad 100644 --- a/trunk/drivers/scsi/gdth.h +++ b/trunk/drivers/scsi/gdth.h @@ -4,13 +4,13 @@ /* * Header file for the GDT Disk Array/Storage RAID controllers driver for Linux * - * gdth.h Copyright (C) 1995-06 ICP vortex, Achim Leubner + * gdth.h Copyright (C) 1995-03 ICP vortex, Achim Leubner * See gdth.c for further informations and * below for supported controller types * * * - * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ + * $Id: gdth.h,v 1.57 2004/03/31 11:52:09 achim Exp $ */ #include @@ -26,9 +26,9 @@ /* defines, macros */ /* driver version */ -#define GDTH_VERSION_STR "3.05" +#define GDTH_VERSION_STR "3.04" #define GDTH_VERSION 3 -#define GDTH_SUBVERSION 5 +#define GDTH_SUBVERSION 4 /* protocol version */ #define PROTOCOL_VERSION 1 diff --git a/trunk/drivers/scsi/gdth_kcompat.h b/trunk/drivers/scsi/gdth_kcompat.h index 2a302eee669a..e6cf0edfa0ca 100644 --- a/trunk/drivers/scsi/gdth_kcompat.h +++ b/trunk/drivers/scsi/gdth_kcompat.h @@ -1,3 +1,5 @@ + + #ifndef IRQ_HANDLED typedef void irqreturn_t; #define IRQ_NONE @@ -8,18 +10,6 @@ typedef void irqreturn_t; #define MODULE_LICENSE(x) #endif -#ifndef __iomem -#define __iomem -#endif - -#ifndef __attribute_used__ -#define __attribute_used__ __devinitdata -#endif - -#ifndef __user -#define __user -#endif - #ifndef SERVICE_ACTION_IN #define SERVICE_ACTION_IN 0x9e #endif diff --git a/trunk/drivers/scsi/gdth_proc.c b/trunk/drivers/scsi/gdth_proc.c index 32982eb75c84..5e8657f9cdf6 100644 --- a/trunk/drivers/scsi/gdth_proc.c +++ b/trunk/drivers/scsi/gdth_proc.c @@ -1,5 +1,5 @@ /* gdth_proc.c - * $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $ + * $Id: gdth_proc.c,v 1.42 2004/03/05 15:50:20 achim Exp $ */ #include @@ -51,26 +51,57 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length,int hostno, static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, int hanum,int busnum) { - int ret_val = -EINVAL; - + int ret_val = -EINVAL; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *scp; + struct scsi_device *sdev; +#else + Scsi_Cmnd *scp; + struct scsi_device *sdev; +#endif TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(host); + scp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!scp) + return -ENOMEM; + scp->sr_cmd_len = 12; + scp->sr_use_sg = 0; +#else + sdev = scsi_get_host_dev(host); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) + return -ENOMEM; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + if (length >= 4) { if (strncmp(buffer,"gdth",4) == 0) { buffer += 5; length -= 5; - ret_val = gdth_set_asc_info(host, buffer, length, hanum); + ret_val = gdth_set_asc_info( buffer, length, hanum, scp ); } } - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(scp); + scsi_free_host_dev(sdev); +#else + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif return ret_val; } -static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length,int hanum) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp) +#else +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp) +#endif { - int orig_length, drive, wb_mode; - int i, found; + int orig_length, drive, wb_mode; + int i, found; gdth_ha_str *ha; gdth_cmd_str gdtcmd; gdth_cpar_str *pcpar; @@ -115,8 +146,11 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, gdtcmd.u.cache.DeviceNo = i; gdtcmd.u.cache.BlockNo = 1; } - - gdth_execute(host, &gdtcmd, cmnd, 30, NULL); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, &gdtcmd, cmnd, 30); +#else + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); +#endif } } if (!found) @@ -168,9 +202,11 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; gdtcmd.u.ioctl.channel = INVALID_CHANNEL; pcpar->write_back = wb_mode==1 ? 0:1; - - gdth_execute(host, &gdtcmd, cmnd, 30, NULL); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, &gdtcmd, cmnd, 30); +#else + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); +#endif gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr); printk("Done.\n"); return(orig_length); @@ -194,6 +230,13 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdth_cmd_str *gdtcmd; gdth_evt_str *estr; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *scp; + struct scsi_device *sdev; +#else + Scsi_Cmnd *scp; + struct scsi_device *sdev; +#endif char hrec[161]; struct timeval tv; @@ -209,7 +252,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL); estr = kmalloc(sizeof(*estr), GFP_KERNEL); if (!gdtcmd || !estr) - goto free_fail; + goto free_fail; memset(cmnd, 0xff, 12); memset(gdtcmd, 0, sizeof(gdth_cmd_str)); @@ -217,6 +260,28 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); ha = HADATA(gdth_ctr_tab[hanum]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(host); + scp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!scp) + goto free_fail; + scp->sr_cmd_len = 12; + scp->sr_use_sg = 0; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + sdev = scsi_get_host_dev(host); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) + goto free_fail; + scp->cmd_len = 12; + scp->use_sg = 0; +#else + memset(&sdev,0,sizeof(struct scsi_device)); + memset(&scp, 0,sizeof(Scsi_Cmnd)); + sdev.host = scp.host = host; + sdev.id = scp.target = sdev.host->this_id; + scp.device = &sdev; +#endif + /* request is i.e. "cat /proc/scsi/gdth/0" */ /* format: %-15s\t%-10s\t%-15s\t%s */ @@ -321,9 +386,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, sizeof(pds->list[0]); if (pds->entries > cnt) pds->entries = cnt; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status != S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) +#endif + { pds->count = 0; + } /* other IOCTLs must fit into area GDTH_SCRATCH/4 */ for (j = 0; j < ha->raw[i].pdev_cnt; ++j) { @@ -338,8 +410,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; gdtcmd->u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status == S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) +#endif + { strncpy(hrec,pdi->vendor,8); strncpy(hrec+8,pdi->product,16); strncpy(hrec+24,pdi->revision,4); @@ -388,8 +466,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd->u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; pdef->sddc_type = 0x08; - - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status == S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) +#endif + { size = sprintf(buffer+len, " Grown Defects:\t%d\n", pdef->sddc_cnt); @@ -435,8 +519,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str); gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO; gdtcmd->u.ioctl.channel = drv_no; - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status != S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) +#endif + { break; + } pcdi->ld_dtype >>= 16; j++; if (pcdi->ld_dtype > 2) { @@ -537,7 +629,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str); gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; gdtcmd->u.ioctl.channel = i; - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status == S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) +#endif + { if (pai->ai_state == 0) strcpy(hrec, "idle"); else if (pai->ai_state == 2) @@ -611,7 +710,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdtcmd->u.ioctl.channel = i; phg->entries = MAX_HDRIVES; phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); - if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(scp, gdtcmd, cmnd, 30); + if (scp->sr_command->SCp.Status != S_OK) +#else + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) +#endif + { ha->hdr[i].ldr_no = i; ha->hdr[i].rw_attribs = 0; ha->hdr[i].start_sec = 0; @@ -685,6 +791,13 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, } stop_output: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(scp); + scsi_free_host_dev(sdev); +#else + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif *start = buffer +(offset-begin); len -= (offset-begin); if (len > length) @@ -699,6 +812,64 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, return rc; } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void gdth_do_req(Scsi_Request *scp, gdth_cmd_str *gdtcmd, + char *cmnd, int timeout) +{ + unsigned bufflen; + DECLARE_COMPLETION(wait); + + TRACE2(("gdth_do_req()\n")); + if (gdtcmd != NULL) { + bufflen = sizeof(gdth_cmd_str); + } else { + bufflen = 0; + } + scp->sr_request->rq_status = RQ_SCSI_BUSY; + scp->sr_request->waiting = &wait; + scsi_do_req(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); + wait_for_completion(&wait); +} + +#else +static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, + char *cmnd, int timeout) +{ + unsigned bufflen; + DECLARE_COMPLETION(wait); + + TRACE2(("gdth_do_cmd()\n")); + if (gdtcmd != NULL) { + scp->SCp.this_residual = IOCTL_PRI; + bufflen = sizeof(gdth_cmd_str); + } else { + scp->SCp.this_residual = DEFAULT_PRI; + bufflen = 0; + } + + scp->request.rq_status = RQ_SCSI_BUSY; + scp->request.waiting = &wait; + scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); + wait_for_completion(&wait); +} +#endif + +void gdth_scsi_done(Scsi_Cmnd *scp) +{ + TRACE2(("gdth_scsi_done()\n")); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scp->request->rq_status = RQ_SCSI_DONE; + if (scp->request->waiting != NULL) + complete(scp->request->waiting); +#else + scp->request.rq_status = RQ_SCSI_DONE; + if (scp->request.waiting != NULL) + complete(scp->request.waiting); +#endif +} + static char *gdth_ioctl_alloc(int hanum, int size, int scratch, ulong64 *paddr) { @@ -805,14 +976,11 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (scp->done != gdth_scsi_done) { - b = virt_ctr ? - NUMDATA(scp->device->host)->busnum : scp->device->channel; - t = scp->device->id; - if (t == (unchar)id && b == (unchar)busnum) { - TRACE2(("gdth_stop_timeout(): update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); - } + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + t = scp->device->id; + if (t == (unchar)id && b == (unchar)busnum) { + TRACE2(("gdth_stop_timeout(): update_timeout()\n")); + scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } spin_unlock_irqrestore(&ha->smp_lock, flags); @@ -829,14 +997,11 @@ static void gdth_start_timeout(int hanum, int busnum, int id) spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - if (scp->done != gdth_scsi_done) { - b = virt_ctr ? - NUMDATA(scp->device->host)->busnum : scp->device->channel; - t = scp->device->id; - if (t == (unchar)id && b == (unchar)busnum) { - TRACE2(("gdth_start_timeout(): update_timeout()\n")); - gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); - } + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + t = scp->device->id; + if (t == (unchar)id && b == (unchar)busnum) { + TRACE2(("gdth_start_timeout(): update_timeout()\n")); + gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); } } spin_unlock_irqrestore(&ha->smp_lock, flags); diff --git a/trunk/drivers/scsi/gdth_proc.h b/trunk/drivers/scsi/gdth_proc.h index a679eeb6820b..295e825e2c60 100644 --- a/trunk/drivers/scsi/gdth_proc.h +++ b/trunk/drivers/scsi/gdth_proc.h @@ -5,16 +5,20 @@ * $Id: gdth_proc.h,v 1.16 2004/01/14 13:09:01 achim Exp $ */ -int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info); - static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, int hanum,int busnum); static int gdth_get_info(char *buffer,char **start,off_t offset,int length, struct Scsi_Host *host,int hanum,int busnum); -static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, - int length, int hanum); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, + char *cmnd, int timeout); +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp); +#else +static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, + char *cmnd, int timeout); +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp); +#endif static char *gdth_ioctl_alloc(int hanum, int size, int scratch, ulong64 *paddr); @@ -24,5 +28,7 @@ static void gdth_stop_timeout(int hanum, int busnum, int id); static void gdth_start_timeout(int hanum, int busnum, int id); static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout); +void gdth_scsi_done(Scsi_Cmnd *scp); + #endif diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c deleted file mode 100644 index f77808329e7c..000000000000 --- a/trunk/drivers/scsi/hptiop.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* - * HighPoint RR3xxx controller driver for Linux - * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Please report bugs/comments/suggestions to linux@highpoint-tech.com - * - * For more information, visit http://www.highpoint-tech.com - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hptiop.h" - -MODULE_AUTHOR("HighPoint Technologies, Inc."); -MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver"); - -static char driver_name[] = "hptiop"; -static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; -static const char driver_ver[] = "v1.0 (060426)"; - -static DEFINE_SPINLOCK(hptiop_hba_list_lock); -static LIST_HEAD(hptiop_hba_list); -static int hptiop_cdev_major = -1; - -static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); -static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); -static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg); - -static inline void hptiop_pci_posting_flush(struct hpt_iopmu __iomem *iop) -{ - readl(&iop->outbound_intstatus); -} - -static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec) -{ - u32 req = 0; - int i; - - for (i = 0; i < millisec; i++) { - req = readl(&iop->inbound_queue); - if (req != IOPMU_QUEUE_EMPTY) - break; - msleep(1); - } - - if (req != IOPMU_QUEUE_EMPTY) { - writel(req, &iop->outbound_queue); - hptiop_pci_posting_flush(iop); - return 0; - } - - return -1; -} - -static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) -{ - if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) - return hptiop_host_request_callback(hba, - tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); - else - return hptiop_iop_request_callback(hba, tag); -} - -static inline void hptiop_drain_outbound_queue(struct hptiop_hba *hba) -{ - u32 req; - - while ((req = readl(&hba->iop->outbound_queue)) != IOPMU_QUEUE_EMPTY) { - - if (req & IOPMU_QUEUE_MASK_HOST_BITS) - hptiop_request_callback(hba, req); - else { - struct hpt_iop_request_header __iomem * p; - - p = (struct hpt_iop_request_header __iomem *) - ((char __iomem *)hba->iop + req); - - if (readl(&p->flags) & IOP_REQUEST_FLAG_SYNC_REQUEST) { - if (readl(&p->context)) - hptiop_request_callback(hba, req); - else - writel(1, &p->context); - } - else - hptiop_request_callback(hba, req); - } - } -} - -static int __iop_intr(struct hptiop_hba *hba) -{ - struct hpt_iopmu __iomem *iop = hba->iop; - u32 status; - int ret = 0; - - status = readl(&iop->outbound_intstatus); - - if (status & IOPMU_OUTBOUND_INT_MSG0) { - u32 msg = readl(&iop->outbound_msgaddr0); - dprintk("received outbound msg %x\n", msg); - writel(IOPMU_OUTBOUND_INT_MSG0, &iop->outbound_intstatus); - hptiop_message_callback(hba, msg); - ret = 1; - } - - if (status & IOPMU_OUTBOUND_INT_POSTQUEUE) { - hptiop_drain_outbound_queue(hba); - ret = 1; - } - - return ret; -} - -static int iop_send_sync_request(struct hptiop_hba *hba, - void __iomem *_req, u32 millisec) -{ - struct hpt_iop_request_header __iomem *req = _req; - u32 i; - - writel(readl(&req->flags) | IOP_REQUEST_FLAG_SYNC_REQUEST, - &req->flags); - - writel(0, &req->context); - - writel((unsigned long)req - (unsigned long)hba->iop, - &hba->iop->inbound_queue); - - hptiop_pci_posting_flush(hba->iop); - - for (i = 0; i < millisec; i++) { - __iop_intr(hba); - if (readl(&req->context)) - return 0; - msleep(1); - } - - return -1; -} - -static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec) -{ - u32 i; - - hba->msg_done = 0; - - writel(msg, &hba->iop->inbound_msgaddr0); - - hptiop_pci_posting_flush(hba->iop); - - for (i = 0; i < millisec; i++) { - spin_lock_irq(hba->host->host_lock); - __iop_intr(hba); - spin_unlock_irq(hba->host->host_lock); - if (hba->msg_done) - break; - msleep(1); - } - - return hba->msg_done? 0 : -1; -} - -static int iop_get_config(struct hptiop_hba *hba, - struct hpt_iop_request_get_config *config) -{ - u32 req32; - struct hpt_iop_request_get_config __iomem *req; - - req32 = readl(&hba->iop->inbound_queue); - if (req32 == IOPMU_QUEUE_EMPTY) - return -1; - - req = (struct hpt_iop_request_get_config __iomem *) - ((unsigned long)hba->iop + req32); - - writel(0, &req->header.flags); - writel(IOP_REQUEST_TYPE_GET_CONFIG, &req->header.type); - writel(sizeof(struct hpt_iop_request_get_config), &req->header.size); - writel(IOP_RESULT_PENDING, &req->header.result); - - if (iop_send_sync_request(hba, req, 20000)) { - dprintk("Get config send cmd failed\n"); - return -1; - } - - memcpy_fromio(config, req, sizeof(*config)); - writel(req32, &hba->iop->outbound_queue); - return 0; -} - -static int iop_set_config(struct hptiop_hba *hba, - struct hpt_iop_request_set_config *config) -{ - u32 req32; - struct hpt_iop_request_set_config __iomem *req; - - req32 = readl(&hba->iop->inbound_queue); - if (req32 == IOPMU_QUEUE_EMPTY) - return -1; - - req = (struct hpt_iop_request_set_config __iomem *) - ((unsigned long)hba->iop + req32); - - memcpy_toio((u8 __iomem *)req + sizeof(struct hpt_iop_request_header), - (u8 *)config + sizeof(struct hpt_iop_request_header), - sizeof(struct hpt_iop_request_set_config) - - sizeof(struct hpt_iop_request_header)); - - writel(0, &req->header.flags); - writel(IOP_REQUEST_TYPE_SET_CONFIG, &req->header.type); - writel(sizeof(struct hpt_iop_request_set_config), &req->header.size); - writel(IOP_RESULT_PENDING, &req->header.result); - - if (iop_send_sync_request(hba, req, 20000)) { - dprintk("Set config send cmd failed\n"); - return -1; - } - - writel(req32, &hba->iop->outbound_queue); - return 0; -} - -static int hptiop_initialize_iop(struct hptiop_hba *hba) -{ - struct hpt_iopmu __iomem *iop = hba->iop; - - /* enable interrupts */ - writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0), - &iop->outbound_intmask); - - hba->initialized = 1; - - /* start background tasks */ - if (iop_send_sync_msg(hba, - IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) { - printk(KERN_ERR "scsi%d: fail to start background task\n", - hba->host->host_no); - return -1; - } - return 0; -} - -static int hptiop_map_pci_bar(struct hptiop_hba *hba) -{ - u32 mem_base_phy, length; - void __iomem *mem_base_virt; - struct pci_dev *pcidev = hba->pcidev; - - if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) { - printk(KERN_ERR "scsi%d: pci resource invalid\n", - hba->host->host_no); - return -1; - } - - mem_base_phy = pci_resource_start(pcidev, 0); - length = pci_resource_len(pcidev, 0); - mem_base_virt = ioremap(mem_base_phy, length); - - if (!mem_base_virt) { - printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", - hba->host->host_no); - return -1; - } - - hba->iop = mem_base_virt; - dprintk("hptiop_map_pci_bar: iop=%p\n", hba->iop); - return 0; -} - -static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg) -{ - dprintk("iop message 0x%x\n", msg); - - if (!hba->initialized) - return; - - if (msg == IOPMU_INBOUND_MSG0_RESET) { - atomic_set(&hba->resetting, 0); - wake_up(&hba->reset_wq); - } - else if (msg <= IOPMU_INBOUND_MSG0_MAX) - hba->msg_done = 1; -} - -static inline struct hptiop_request *get_req(struct hptiop_hba *hba) -{ - struct hptiop_request *ret; - - dprintk("get_req : req=%p\n", hba->req_list); - - ret = hba->req_list; - if (ret) - hba->req_list = ret->next; - - return ret; -} - -static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req) -{ - dprintk("free_req(%d, %p)\n", req->index, req); - req->next = hba->req_list; - hba->req_list = req; -} - -static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) -{ - struct hpt_iop_request_scsi_command *req; - struct scsi_cmnd *scp; - - req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt; - dprintk("hptiop_host_request_callback: req=%p, type=%d, " - "result=%d, context=0x%x tag=%d\n", - req, req->header.type, req->header.result, - req->header.context, tag); - - BUG_ON(!req->header.result); - BUG_ON(req->header.type != cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND)); - - scp = hba->reqs[tag].scp; - - if (HPT_SCP(scp)->mapped) { - if (scp->use_sg) - pci_unmap_sg(hba->pcidev, - (struct scatterlist *)scp->request_buffer, - scp->use_sg, - scp->sc_data_direction - ); - else - pci_unmap_single(hba->pcidev, - HPT_SCP(scp)->dma_handle, - scp->request_bufflen, - scp->sc_data_direction - ); - } - - switch (le32_to_cpu(req->header.result)) { - case IOP_RESULT_SUCCESS: - scp->result = (DID_OK<<16); - break; - case IOP_RESULT_BAD_TARGET: - scp->result = (DID_BAD_TARGET<<16); - break; - case IOP_RESULT_BUSY: - scp->result = (DID_BUS_BUSY<<16); - break; - case IOP_RESULT_RESET: - scp->result = (DID_RESET<<16); - break; - case IOP_RESULT_FAIL: - scp->result = (DID_ERROR<<16); - break; - case IOP_RESULT_INVALID_REQUEST: - scp->result = (DID_ABORT<<16); - break; - case IOP_RESULT_MODE_SENSE_CHECK_CONDITION: - scp->result = SAM_STAT_CHECK_CONDITION; - memset(&scp->sense_buffer, - 0, sizeof(scp->sense_buffer)); - memcpy(&scp->sense_buffer, - &req->sg_list, le32_to_cpu(req->dataxfer_length)); - break; - - default: - scp->result = ((DRIVER_INVALID|SUGGEST_ABORT)<<24) | - (DID_ABORT<<16); - break; - } - - dprintk("scsi_done(%p)\n", scp); - scp->scsi_done(scp); - free_req(hba, &hba->reqs[tag]); -} - -void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag) -{ - struct hpt_iop_request_header __iomem *req; - struct hpt_iop_request_ioctl_command __iomem *p; - struct hpt_ioctl_k *arg; - - req = (struct hpt_iop_request_header __iomem *) - ((unsigned long)hba->iop + tag); - dprintk("hptiop_iop_request_callback: req=%p, type=%d, " - "result=%d, context=0x%x tag=%d\n", - req, readl(&req->type), readl(&req->result), - readl(&req->context), tag); - - BUG_ON(!readl(&req->result)); - BUG_ON(readl(&req->type) != IOP_REQUEST_TYPE_IOCTL_COMMAND); - - p = (struct hpt_iop_request_ioctl_command __iomem *)req; - arg = (struct hpt_ioctl_k *)(unsigned long) - (readl(&req->context) | - ((u64)readl(&req->context_hi32)<<32)); - - if (readl(&req->result) == IOP_RESULT_SUCCESS) { - arg->result = HPT_IOCTL_RESULT_OK; - - if (arg->outbuf_size) - memcpy_fromio(arg->outbuf, - &p->buf[(readl(&p->inbuf_size) + 3)& ~3], - arg->outbuf_size); - - if (arg->bytes_returned) - *arg->bytes_returned = arg->outbuf_size; - } - else - arg->result = HPT_IOCTL_RESULT_FAILED; - - arg->done(arg); - writel(tag, &hba->iop->outbound_queue); -} - -static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs) -{ - struct hptiop_hba *hba = dev_id; - int handled; - unsigned long flags; - - spin_lock_irqsave(hba->host->host_lock, flags); - handled = __iop_intr(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); - - return handled; -} - -static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg) -{ - struct Scsi_Host *host = scp->device->host; - struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; - struct scatterlist *sglist = (struct scatterlist *)scp->request_buffer; - - /* - * though we'll not get non-use_sg fields anymore, - * keep use_sg checking anyway - */ - if (scp->use_sg) { - int idx; - - HPT_SCP(scp)->sgcnt = pci_map_sg(hba->pcidev, - sglist, scp->use_sg, - scp->sc_data_direction); - HPT_SCP(scp)->mapped = 1; - BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors); - - for (idx = 0; idx < HPT_SCP(scp)->sgcnt; idx++) { - psg[idx].pci_address = - cpu_to_le64(sg_dma_address(&sglist[idx])); - psg[idx].size = cpu_to_le32(sg_dma_len(&sglist[idx])); - psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ? - cpu_to_le32(1) : 0; - } - - return HPT_SCP(scp)->sgcnt; - } else { - HPT_SCP(scp)->dma_handle = pci_map_single( - hba->pcidev, - scp->request_buffer, - scp->request_bufflen, - scp->sc_data_direction - ); - HPT_SCP(scp)->mapped = 1; - psg->pci_address = cpu_to_le64(HPT_SCP(scp)->dma_handle); - psg->size = cpu_to_le32(scp->request_bufflen); - psg->eot = cpu_to_le32(1); - return 1; - } -} - -static int hptiop_queuecommand(struct scsi_cmnd *scp, - void (*done)(struct scsi_cmnd *)) -{ - struct Scsi_Host *host = scp->device->host; - struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; - struct hpt_iop_request_scsi_command *req; - int sg_count = 0; - struct hptiop_request *_req; - - BUG_ON(!done); - scp->scsi_done = done; - - _req = get_req(hba); - if (_req == NULL) { - dprintk("hptiop_queuecmd : no free req\n"); - return SCSI_MLQUEUE_HOST_BUSY; - } - - _req->scp = scp; - - dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%x-%x-%x) " - "req_index=%d, req=%p\n", - scp, - host->host_no, scp->device->channel, - scp->device->id, scp->device->lun, - *((u32 *)&scp->cmnd), - *((u32 *)&scp->cmnd + 1), - *((u32 *)&scp->cmnd + 2), - _req->index, _req->req_virt); - - scp->result = 0; - - if (scp->device->channel || scp->device->lun || - scp->device->id > hba->max_devices) { - scp->result = DID_BAD_TARGET << 16; - free_req(hba, _req); - goto cmd_done; - } - - req = (struct hpt_iop_request_scsi_command *)_req->req_virt; - - /* build S/G table */ - if (scp->request_bufflen) - sg_count = hptiop_buildsgl(scp, req->sg_list); - else - HPT_SCP(scp)->mapped = 0; - - req->header.flags = cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT); - req->header.type = cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND); - req->header.result = cpu_to_le32(IOP_RESULT_PENDING); - req->header.context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT | - (u32)_req->index); - req->header.context_hi32 = 0; - req->dataxfer_length = cpu_to_le32(scp->request_bufflen); - req->channel = scp->device->channel; - req->target = scp->device->id; - req->lun = scp->device->lun; - req->header.size = cpu_to_le32( - sizeof(struct hpt_iop_request_scsi_command) - - sizeof(struct hpt_iopsg) - + sg_count * sizeof(struct hpt_iopsg)); - - memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); - - writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, - &hba->iop->inbound_queue); - - return 0; - -cmd_done: - dprintk("scsi_done(scp=%p)\n", scp); - scp->scsi_done(scp); - return 0; -} - -static const char *hptiop_info(struct Scsi_Host *host) -{ - return driver_name_long; -} - -static int hptiop_reset_hba(struct hptiop_hba *hba) -{ - if (atomic_xchg(&hba->resetting, 1) == 0) { - atomic_inc(&hba->reset_count); - writel(IOPMU_INBOUND_MSG0_RESET, - &hba->iop->outbound_msgaddr0); - hptiop_pci_posting_flush(hba->iop); - } - - wait_event_timeout(hba->reset_wq, - atomic_read(&hba->resetting) == 0, 60 * HZ); - - if (atomic_read(&hba->resetting)) { - /* IOP is in unkown state, abort reset */ - printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no); - return -1; - } - - if (iop_send_sync_msg(hba, - IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) { - dprintk("scsi%d: fail to start background task\n", - hba->host->host_no); - } - - return 0; -} - -static int hptiop_reset(struct scsi_cmnd *scp) -{ - struct Scsi_Host * host = scp->device->host; - struct hptiop_hba * hba = (struct hptiop_hba *)host->hostdata; - - printk(KERN_WARNING "hptiop_reset(%d/%d/%d) scp=%p\n", - scp->device->host->host_no, scp->device->channel, - scp->device->id, scp); - - return hptiop_reset_hba(hba)? FAILED : SUCCESS; -} - -static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev, - int queue_depth) -{ - if(queue_depth > 256) - queue_depth = 256; - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); - return queue_depth; -} - -struct hptiop_getinfo { - char __user *buffer; - loff_t buflength; - loff_t bufoffset; - loff_t buffillen; - loff_t filpos; -}; - -static void hptiop_copy_mem_info(struct hptiop_getinfo *pinfo, - char *data, int datalen) -{ - if (pinfo->filpos < pinfo->bufoffset) { - if (pinfo->filpos + datalen <= pinfo->bufoffset) { - pinfo->filpos += datalen; - return; - } else { - data += (pinfo->bufoffset - pinfo->filpos); - datalen -= (pinfo->bufoffset - pinfo->filpos); - pinfo->filpos = pinfo->bufoffset; - } - } - - pinfo->filpos += datalen; - if (pinfo->buffillen == pinfo->buflength) - return; - - if (pinfo->buflength - pinfo->buffillen < datalen) - datalen = pinfo->buflength - pinfo->buffillen; - - if (copy_to_user(pinfo->buffer + pinfo->buffillen, data, datalen)) - return; - - pinfo->buffillen += datalen; -} - -static int hptiop_copy_info(struct hptiop_getinfo *pinfo, char *fmt, ...) -{ - va_list args; - char buf[128]; - int len; - - va_start(args, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - hptiop_copy_mem_info(pinfo, buf, len); - return len; -} - -static void hptiop_ioctl_done(struct hpt_ioctl_k *arg) -{ - arg->done = NULL; - wake_up(&arg->hba->ioctl_wq); -} - -static void hptiop_do_ioctl(struct hpt_ioctl_k *arg) -{ - struct hptiop_hba *hba = arg->hba; - u32 val; - struct hpt_iop_request_ioctl_command __iomem *req; - int ioctl_retry = 0; - - dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no); - - /* - * check (in + out) buff size from application. - * outbuf must be dword aligned. - */ - if (((arg->inbuf_size + 3) & ~3) + arg->outbuf_size > - hba->max_request_size - - sizeof(struct hpt_iop_request_header) - - 4 * sizeof(u32)) { - dprintk("scsi%d: ioctl buf size (%d/%d) is too large\n", - hba->host->host_no, - arg->inbuf_size, arg->outbuf_size); - arg->result = HPT_IOCTL_RESULT_FAILED; - return; - } - -retry: - spin_lock_irq(hba->host->host_lock); - - val = readl(&hba->iop->inbound_queue); - if (val == IOPMU_QUEUE_EMPTY) { - spin_unlock_irq(hba->host->host_lock); - dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no); - arg->result = -1; - return; - } - - req = (struct hpt_iop_request_ioctl_command __iomem *) - ((unsigned long)hba->iop + val); - - writel(HPT_CTL_CODE_LINUX_TO_IOP(arg->ioctl_code), - &req->ioctl_code); - writel(arg->inbuf_size, &req->inbuf_size); - writel(arg->outbuf_size, &req->outbuf_size); - - /* - * use the buffer on the IOP local memory first, then copy it - * back to host. - * the caller's request buffer shoudl be little-endian. - */ - if (arg->inbuf_size) - memcpy_toio(req->buf, arg->inbuf, arg->inbuf_size); - - /* correct the controller ID for IOP */ - if ((arg->ioctl_code == HPT_IOCTL_GET_CHANNEL_INFO || - arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO_V2 || - arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO) - && arg->inbuf_size >= sizeof(u32)) - writel(0, req->buf); - - writel(IOP_REQUEST_TYPE_IOCTL_COMMAND, &req->header.type); - writel(0, &req->header.flags); - writel(offsetof(struct hpt_iop_request_ioctl_command, buf) - + arg->inbuf_size, &req->header.size); - writel((u32)(unsigned long)arg, &req->header.context); - writel(BITS_PER_LONG > 32 ? (u32)((unsigned long)arg>>32) : 0, - &req->header.context_hi32); - writel(IOP_RESULT_PENDING, &req->header.result); - - arg->result = HPT_IOCTL_RESULT_FAILED; - arg->done = hptiop_ioctl_done; - - writel(val, &hba->iop->inbound_queue); - hptiop_pci_posting_flush(hba->iop); - - spin_unlock_irq(hba->host->host_lock); - - wait_event_timeout(hba->ioctl_wq, arg->done == NULL, 60 * HZ); - - if (arg->done != NULL) { - hptiop_reset_hba(hba); - if (ioctl_retry++ < 3) - goto retry; - } - - dprintk("hpt_iop_ioctl %x result %d\n", - arg->ioctl_code, arg->result); -} - -static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf, - u32 insize, void *outbuf, u32 outsize) -{ - struct hpt_ioctl_k arg; - arg.hba = hba; - arg.ioctl_code = code; - arg.inbuf = inbuf; - arg.outbuf = outbuf; - arg.inbuf_size = insize; - arg.outbuf_size = outsize; - arg.bytes_returned = NULL; - hptiop_do_ioctl(&arg); - return arg.result; -} - -static inline int hpt_id_valid(__le32 id) -{ - return id != 0 && id != cpu_to_le32(0xffffffff); -} - -static int hptiop_get_controller_info(struct hptiop_hba *hba, - struct hpt_controller_info *pinfo) -{ - int id = 0; - - return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CONTROLLER_INFO, - &id, sizeof(int), pinfo, sizeof(*pinfo)); -} - - -static int hptiop_get_channel_info(struct hptiop_hba *hba, int bus, - struct hpt_channel_info *pinfo) -{ - u32 ids[2]; - - ids[0] = 0; - ids[1] = bus; - return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CHANNEL_INFO, - ids, sizeof(ids), pinfo, sizeof(*pinfo)); - -} - -static int hptiop_get_logical_devices(struct hptiop_hba *hba, - __le32 *pids, int maxcount) -{ - int i; - u32 count = maxcount - 1; - - if (__hpt_do_ioctl(hba, HPT_IOCTL_GET_LOGICAL_DEVICES, - &count, sizeof(u32), - pids, sizeof(u32) * maxcount)) - return -1; - - maxcount = le32_to_cpu(pids[0]); - for (i = 0; i < maxcount; i++) - pids[i] = pids[i+1]; - - return maxcount; -} - -static int hptiop_get_device_info_v3(struct hptiop_hba *hba, __le32 id, - struct hpt_logical_device_info_v3 *pinfo) -{ - return __hpt_do_ioctl(hba, HPT_IOCTL_GET_DEVICE_INFO_V3, - &id, sizeof(u32), - pinfo, sizeof(*pinfo)); -} - -static const char *get_array_status(struct hpt_logical_device_info_v3 *devinfo) -{ - static char s[64]; - u32 flags = le32_to_cpu(devinfo->u.array.flags); - u32 trans_prog = le32_to_cpu(devinfo->u.array.transforming_progress); - u32 reb_prog = le32_to_cpu(devinfo->u.array.rebuilding_progress); - - if (flags & ARRAY_FLAG_DISABLED) - return "Disabled"; - else if (flags & ARRAY_FLAG_TRANSFORMING) - sprintf(s, "Expanding/Migrating %d.%d%%%s%s", - trans_prog / 100, - trans_prog % 100, - (flags & (ARRAY_FLAG_NEEDBUILDING|ARRAY_FLAG_BROKEN))? - ", Critical" : "", - ((flags & ARRAY_FLAG_NEEDINITIALIZING) && - !(flags & ARRAY_FLAG_REBUILDING) && - !(flags & ARRAY_FLAG_INITIALIZING))? - ", Unintialized" : ""); - else if ((flags & ARRAY_FLAG_BROKEN) && - devinfo->u.array.array_type != AT_RAID6) - return "Critical"; - else if (flags & ARRAY_FLAG_REBUILDING) - sprintf(s, - (flags & ARRAY_FLAG_NEEDINITIALIZING)? - "%sBackground initializing %d.%d%%" : - "%sRebuilding %d.%d%%", - (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", - reb_prog / 100, - reb_prog % 100); - else if (flags & ARRAY_FLAG_VERIFYING) - sprintf(s, "%sVerifying %d.%d%%", - (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", - reb_prog / 100, - reb_prog % 100); - else if (flags & ARRAY_FLAG_INITIALIZING) - sprintf(s, "%sForground initializing %d.%d%%", - (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", - reb_prog / 100, - reb_prog % 100); - else if (flags & ARRAY_FLAG_NEEDTRANSFORM) - sprintf(s,"%s%s%s", "Need Expanding/Migrating", - (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", - ((flags & ARRAY_FLAG_NEEDINITIALIZING) && - !(flags & ARRAY_FLAG_REBUILDING) && - !(flags & ARRAY_FLAG_INITIALIZING))? - ", Unintialized" : ""); - else if (flags & ARRAY_FLAG_NEEDINITIALIZING && - !(flags & ARRAY_FLAG_REBUILDING) && - !(flags & ARRAY_FLAG_INITIALIZING)) - sprintf(s,"%sUninitialized", - (flags & ARRAY_FLAG_BROKEN)? "Critical, " : ""); - else if ((flags & ARRAY_FLAG_NEEDBUILDING) || - (flags & ARRAY_FLAG_BROKEN)) - return "Critical"; - else - return "Normal"; - return s; -} - -static void hptiop_dump_devinfo(struct hptiop_hba *hba, - struct hptiop_getinfo *pinfo, __le32 id, int indent) -{ - struct hpt_logical_device_info_v3 devinfo; - int i; - u64 capacity; - - for (i = 0; i < indent; i++) - hptiop_copy_info(pinfo, "\t"); - - if (hptiop_get_device_info_v3(hba, id, &devinfo)) { - hptiop_copy_info(pinfo, "unknown\n"); - return; - } - - switch (devinfo.type) { - - case LDT_DEVICE: { - struct hd_driveid *driveid; - u32 flags = le32_to_cpu(devinfo.u.device.flags); - - driveid = (struct hd_driveid *)devinfo.u.device.ident; - /* model[] is 40 chars long, but we just want 20 chars here */ - driveid->model[20] = 0; - - if (indent) - if (flags & DEVICE_FLAG_DISABLED) - hptiop_copy_info(pinfo,"Missing\n"); - else - hptiop_copy_info(pinfo, "CH%d %s\n", - devinfo.u.device.path_id + 1, - driveid->model); - else { - capacity = le64_to_cpu(devinfo.capacity) * 512; - do_div(capacity, 1000000); - hptiop_copy_info(pinfo, - "CH%d %s, %lluMB, %s %s%s%s%s\n", - devinfo.u.device.path_id + 1, - driveid->model, - capacity, - (flags & DEVICE_FLAG_DISABLED)? - "Disabled" : "Normal", - devinfo.u.device.read_ahead_enabled? - "[RA]" : "", - devinfo.u.device.write_cache_enabled? - "[WC]" : "", - devinfo.u.device.TCQ_enabled? - "[TCQ]" : "", - devinfo.u.device.NCQ_enabled? - "[NCQ]" : "" - ); - } - break; - } - - case LDT_ARRAY: - if (devinfo.target_id != INVALID_TARGET_ID) - hptiop_copy_info(pinfo, "[DISK %d_%d] ", - devinfo.vbus_id, devinfo.target_id); - - capacity = le64_to_cpu(devinfo.capacity) * 512; - do_div(capacity, 1000000); - hptiop_copy_info(pinfo, "%s (%s), %lluMB, %s\n", - devinfo.u.array.name, - devinfo.u.array.array_type==AT_RAID0? "RAID0" : - devinfo.u.array.array_type==AT_RAID1? "RAID1" : - devinfo.u.array.array_type==AT_RAID5? "RAID5" : - devinfo.u.array.array_type==AT_RAID6? "RAID6" : - devinfo.u.array.array_type==AT_JBOD? "JBOD" : - "unknown", - capacity, - get_array_status(&devinfo)); - for (i = 0; i < devinfo.u.array.ndisk; i++) { - if (hpt_id_valid(devinfo.u.array.members[i])) { - if (cpu_to_le16(1<private_data; - struct hptiop_getinfo info; - int i, j, ndev; - struct hpt_controller_info con_info; - struct hpt_channel_info chan_info; - __le32 ids[32]; - - info.buffer = buf; - info.buflength = count; - info.bufoffset = ppos ? *ppos : 0; - info.filpos = 0; - info.buffillen = 0; - - if (hptiop_get_controller_info(hba, &con_info)) - return -EIO; - - for (i = 0; i < con_info.num_buses; i++) { - if (hptiop_get_channel_info(hba, i, &chan_info) == 0) { - if (hpt_id_valid(chan_info.devices[0])) - hptiop_dump_devinfo(hba, &info, - chan_info.devices[0], 0); - if (hpt_id_valid(chan_info.devices[1])) - hptiop_dump_devinfo(hba, &info, - chan_info.devices[1], 0); - } - } - - ndev = hptiop_get_logical_devices(hba, ids, - sizeof(ids) / sizeof(ids[0])); - - /* - * if hptiop_get_logical_devices fails, ndev==-1 and it just - * output nothing here - */ - for (j = 0; j < ndev; j++) - hptiop_dump_devinfo(hba, &info, ids[j], 0); - - if (ppos) - *ppos += info.buffillen; - - return info.buffillen; -} - -static int hptiop_cdev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct hptiop_hba *hba = file->private_data; - struct hpt_ioctl_u ioctl_u; - struct hpt_ioctl_k ioctl_k; - u32 bytes_returned; - int err = -EINVAL; - - if (copy_from_user(&ioctl_u, - (void __user *)arg, sizeof(struct hpt_ioctl_u))) - return -EINVAL; - - if (ioctl_u.magic != HPT_IOCTL_MAGIC) - return -EINVAL; - - ioctl_k.ioctl_code = ioctl_u.ioctl_code; - ioctl_k.inbuf = NULL; - ioctl_k.inbuf_size = ioctl_u.inbuf_size; - ioctl_k.outbuf = NULL; - ioctl_k.outbuf_size = ioctl_u.outbuf_size; - ioctl_k.hba = hba; - ioctl_k.bytes_returned = &bytes_returned; - - /* verify user buffer */ - if ((ioctl_k.inbuf_size && !access_ok(VERIFY_READ, - ioctl_u.inbuf, ioctl_k.inbuf_size)) || - (ioctl_k.outbuf_size && !access_ok(VERIFY_WRITE, - ioctl_u.outbuf, ioctl_k.outbuf_size)) || - (ioctl_u.bytes_returned && !access_ok(VERIFY_WRITE, - ioctl_u.bytes_returned, sizeof(u32))) || - ioctl_k.inbuf_size + ioctl_k.outbuf_size > 0x10000) { - - dprintk("scsi%d: got bad user address\n", hba->host->host_no); - return -EINVAL; - } - - /* map buffer to kernel. */ - if (ioctl_k.inbuf_size) { - ioctl_k.inbuf = kmalloc(ioctl_k.inbuf_size, GFP_KERNEL); - if (!ioctl_k.inbuf) { - dprintk("scsi%d: fail to alloc inbuf\n", - hba->host->host_no); - err = -ENOMEM; - goto err_exit; - } - - if (copy_from_user(ioctl_k.inbuf, - ioctl_u.inbuf, ioctl_k.inbuf_size)) { - goto err_exit; - } - } - - if (ioctl_k.outbuf_size) { - ioctl_k.outbuf = kmalloc(ioctl_k.outbuf_size, GFP_KERNEL); - if (!ioctl_k.outbuf) { - dprintk("scsi%d: fail to alloc outbuf\n", - hba->host->host_no); - err = -ENOMEM; - goto err_exit; - } - } - - hptiop_do_ioctl(&ioctl_k); - - if (ioctl_k.result == HPT_IOCTL_RESULT_OK) { - if (ioctl_k.outbuf_size && - copy_to_user(ioctl_u.outbuf, - ioctl_k.outbuf, ioctl_k.outbuf_size)) - goto err_exit; - - if (ioctl_u.bytes_returned && - copy_to_user(ioctl_u.bytes_returned, - &bytes_returned, sizeof(u32))) - goto err_exit; - - err = 0; - } - -err_exit: - kfree(ioctl_k.inbuf); - kfree(ioctl_k.outbuf); - - return err; -} - -static int hptiop_cdev_open(struct inode *inode, struct file *file) -{ - struct hptiop_hba *hba; - unsigned i = 0, minor = iminor(inode); - int ret = -ENODEV; - - spin_lock(&hptiop_hba_list_lock); - list_for_each_entry(hba, &hptiop_hba_list, link) { - if (i == minor) { - file->private_data = hba; - ret = 0; - goto out; - } - i++; - } - -out: - spin_unlock(&hptiop_hba_list_lock); - return ret; -} - -static struct file_operations hptiop_cdev_fops = { - .owner = THIS_MODULE, - .read = hptiop_cdev_read, - .ioctl = hptiop_cdev_ioctl, - .open = hptiop_cdev_open, -}; - -static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf) -{ - struct Scsi_Host *host = class_to_shost(class_dev); - struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; - - return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", - hba->firmware_version >> 24, - (hba->firmware_version >> 16) & 0xff, - (hba->firmware_version >> 8) & 0xff, - hba->firmware_version & 0xff); -} - -static struct class_device_attribute hptiop_attr_version = { - .attr = { - .name = "driver-version", - .mode = S_IRUGO, - }, - .show = hptiop_show_version, -}; - -static struct class_device_attribute hptiop_attr_fw_version = { - .attr = { - .name = "firmware-version", - .mode = S_IRUGO, - }, - .show = hptiop_show_fw_version, -}; - -static struct class_device_attribute *hptiop_attrs[] = { - &hptiop_attr_version, - &hptiop_attr_fw_version, - NULL -}; - -static struct scsi_host_template driver_template = { - .module = THIS_MODULE, - .name = driver_name, - .queuecommand = hptiop_queuecommand, - .eh_device_reset_handler = hptiop_reset, - .eh_bus_reset_handler = hptiop_reset, - .info = hptiop_info, - .unchecked_isa_dma = 0, - .emulated = 0, - .use_clustering = ENABLE_CLUSTERING, - .proc_name = driver_name, - .shost_attrs = hptiop_attrs, - .this_id = -1, - .change_queue_depth = hptiop_adjust_disk_queue_depth, -}; - -static int __devinit hptiop_probe(struct pci_dev *pcidev, - const struct pci_device_id *id) -{ - struct Scsi_Host *host = NULL; - struct hptiop_hba *hba; - struct hpt_iop_request_get_config iop_config; - struct hpt_iop_request_set_config set_config; - dma_addr_t start_phy; - void *start_virt; - u32 offset, i, req_size; - - dprintk("hptiop_probe(%p)\n", pcidev); - - if (pci_enable_device(pcidev)) { - printk(KERN_ERR "hptiop: fail to enable pci device\n"); - return -ENODEV; - } - - printk(KERN_INFO "adapter at PCI %d:%d:%d, IRQ %d\n", - pcidev->bus->number, pcidev->devfn >> 3, pcidev->devfn & 7, - pcidev->irq); - - pci_set_master(pcidev); - - /* Enable 64bit DMA if possible */ - if (pci_set_dma_mask(pcidev, DMA_64BIT_MASK)) { - if (pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) { - printk(KERN_ERR "hptiop: fail to set dma_mask\n"); - goto disable_pci_device; - } - } - - if (pci_request_regions(pcidev, driver_name)) { - printk(KERN_ERR "hptiop: pci_request_regions failed\n"); - goto disable_pci_device; - } - - host = scsi_host_alloc(&driver_template, sizeof(struct hptiop_hba)); - if (!host) { - printk(KERN_ERR "hptiop: fail to alloc scsi host\n"); - goto free_pci_regions; - } - - hba = (struct hptiop_hba *)host->hostdata; - - hba->pcidev = pcidev; - hba->host = host; - hba->initialized = 0; - - atomic_set(&hba->resetting, 0); - atomic_set(&hba->reset_count, 0); - - init_waitqueue_head(&hba->reset_wq); - init_waitqueue_head(&hba->ioctl_wq); - - host->max_lun = 1; - host->max_channel = 0; - host->io_port = 0; - host->n_io_port = 0; - host->irq = pcidev->irq; - - if (hptiop_map_pci_bar(hba)) - goto free_scsi_host; - - if (iop_wait_ready(hba->iop, 20000)) { - printk(KERN_ERR "scsi%d: firmware not ready\n", - hba->host->host_no); - goto unmap_pci_bar; - } - - if (iop_get_config(hba, &iop_config)) { - printk(KERN_ERR "scsi%d: get config failed\n", - hba->host->host_no); - goto unmap_pci_bar; - } - - hba->max_requests = min(le32_to_cpu(iop_config.max_requests), - HPTIOP_MAX_REQUESTS); - hba->max_devices = le32_to_cpu(iop_config.max_devices); - hba->max_request_size = le32_to_cpu(iop_config.request_size); - hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); - hba->firmware_version = le32_to_cpu(iop_config.firmware_version); - hba->sdram_size = le32_to_cpu(iop_config.sdram_size); - - host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; - host->max_id = le32_to_cpu(iop_config.max_devices); - host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); - host->can_queue = le32_to_cpu(iop_config.max_requests); - host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); - host->max_cmd_len = 16; - - set_config.vbus_id = cpu_to_le32(host->host_no); - set_config.iop_id = cpu_to_le32(host->host_no); - - if (iop_set_config(hba, &set_config)) { - printk(KERN_ERR "scsi%d: set config failed\n", - hba->host->host_no); - goto unmap_pci_bar; - } - - if (scsi_add_host(host, &pcidev->dev)) { - printk(KERN_ERR "scsi%d: scsi_add_host failed\n", - hba->host->host_no); - goto unmap_pci_bar; - } - - pci_set_drvdata(pcidev, host); - - if (request_irq(pcidev->irq, hptiop_intr, SA_SHIRQ, - driver_name, hba)) { - printk(KERN_ERR "scsi%d: request irq %d failed\n", - hba->host->host_no, pcidev->irq); - goto remove_scsi_host; - } - - /* Allocate request mem */ - req_size = sizeof(struct hpt_iop_request_scsi_command) - + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); - if ((req_size& 0x1f) != 0) - req_size = (req_size + 0x1f) & ~0x1f; - - dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); - - hba->req_size = req_size; - start_virt = dma_alloc_coherent(&pcidev->dev, - hba->req_size*hba->max_requests + 0x20, - &start_phy, GFP_KERNEL); - - if (!start_virt) { - printk(KERN_ERR "scsi%d: fail to alloc request mem\n", - hba->host->host_no); - goto free_request_irq; - } - - hba->dma_coherent = start_virt; - hba->dma_coherent_handle = start_phy; - - if ((start_phy & 0x1f) != 0) - { - offset = ((start_phy + 0x1f) & ~0x1f) - start_phy; - start_phy += offset; - start_virt += offset; - } - - hba->req_list = start_virt; - for (i = 0; i < hba->max_requests; i++) { - hba->reqs[i].next = NULL; - hba->reqs[i].req_virt = start_virt; - hba->reqs[i].req_shifted_phy = start_phy >> 5; - hba->reqs[i].index = i; - free_req(hba, &hba->reqs[i]); - start_virt = (char *)start_virt + hba->req_size; - start_phy = start_phy + hba->req_size; - } - - /* Enable Interrupt and start background task */ - if (hptiop_initialize_iop(hba)) - goto free_request_mem; - - spin_lock(&hptiop_hba_list_lock); - list_add_tail(&hba->link, &hptiop_hba_list); - spin_unlock(&hptiop_hba_list_lock); - - scsi_scan_host(host); - - dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no); - return 0; - -free_request_mem: - dma_free_coherent(&hba->pcidev->dev, - hba->req_size*hba->max_requests + 0x20, - hba->dma_coherent, hba->dma_coherent_handle); - -free_request_irq: - free_irq(hba->pcidev->irq, hba); - -remove_scsi_host: - scsi_remove_host(host); - -unmap_pci_bar: - iounmap(hba->iop); - -free_pci_regions: - pci_release_regions(pcidev) ; - -free_scsi_host: - scsi_host_put(host); - -disable_pci_device: - pci_disable_device(pcidev); - - dprintk("scsi%d: hptiop_probe fail\n", host->host_no); - return -ENODEV; -} - -static void hptiop_shutdown(struct pci_dev *pcidev) -{ - struct Scsi_Host *host = pci_get_drvdata(pcidev); - struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; - struct hpt_iopmu __iomem *iop = hba->iop; - u32 int_mask; - - dprintk("hptiop_shutdown(%p)\n", hba); - - /* stop the iop */ - if (iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_SHUTDOWN, 60000)) - printk(KERN_ERR "scsi%d: shutdown the iop timeout\n", - hba->host->host_no); - - /* disable all outbound interrupts */ - int_mask = readl(&iop->outbound_intmask); - writel(int_mask | - IOPMU_OUTBOUND_INT_MSG0 | IOPMU_OUTBOUND_INT_POSTQUEUE, - &iop->outbound_intmask); - hptiop_pci_posting_flush(iop); -} - -static void hptiop_remove(struct pci_dev *pcidev) -{ - struct Scsi_Host *host = pci_get_drvdata(pcidev); - struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; - - dprintk("scsi%d: hptiop_remove\n", hba->host->host_no); - - scsi_remove_host(host); - - spin_lock(&hptiop_hba_list_lock); - list_del_init(&hba->link); - spin_unlock(&hptiop_hba_list_lock); - - hptiop_shutdown(pcidev); - - free_irq(hba->pcidev->irq, hba); - - dma_free_coherent(&hba->pcidev->dev, - hba->req_size * hba->max_requests + 0x20, - hba->dma_coherent, - hba->dma_coherent_handle); - - iounmap(hba->iop); - - pci_release_regions(hba->pcidev); - pci_set_drvdata(hba->pcidev, NULL); - pci_disable_device(hba->pcidev); - - scsi_host_put(host); -} - -static struct pci_device_id hptiop_id_table[] = { - { PCI_DEVICE(0x1103, 0x3220) }, - { PCI_DEVICE(0x1103, 0x3320) }, - {}, -}; - -MODULE_DEVICE_TABLE(pci, hptiop_id_table); - -static struct pci_driver hptiop_pci_driver = { - .name = driver_name, - .id_table = hptiop_id_table, - .probe = hptiop_probe, - .remove = hptiop_remove, - .shutdown = hptiop_shutdown, -}; - -static int __init hptiop_module_init(void) -{ - int error; - - printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver); - - error = pci_register_driver(&hptiop_pci_driver); - if (error < 0) - return error; - - hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops); - if (hptiop_cdev_major < 0) { - printk(KERN_WARNING "unable to register hptiop device.\n"); - return hptiop_cdev_major; - } - - return 0; -} - -static void __exit hptiop_module_exit(void) -{ - dprintk("hptiop_module_exit\n"); - unregister_chrdev(hptiop_cdev_major, "hptiop"); - pci_unregister_driver(&hptiop_pci_driver); -} - - -module_init(hptiop_module_init); -module_exit(hptiop_module_exit); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/hptiop.h b/trunk/drivers/scsi/hptiop.h deleted file mode 100644 index f04f7e81d1ae..000000000000 --- a/trunk/drivers/scsi/hptiop.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * HighPoint RR3xxx controller driver for Linux - * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Please report bugs/comments/suggestions to linux@highpoint-tech.com - * - * For more information, visit http://www.highpoint-tech.com - */ -#ifndef _HPTIOP_H_ -#define _HPTIOP_H_ - -/* - * logical device type. - * Identify array (logical device) and physical device. - */ -#define LDT_ARRAY 1 -#define LDT_DEVICE 2 - -/* - * Array types - */ -#define AT_UNKNOWN 0 -#define AT_RAID0 1 -#define AT_RAID1 2 -#define AT_RAID5 3 -#define AT_RAID6 4 -#define AT_JBOD 7 - -#define MAX_NAME_LENGTH 36 -#define MAX_ARRAYNAME_LEN 16 - -#define MAX_ARRAY_MEMBERS_V1 8 -#define MAX_ARRAY_MEMBERS_V2 16 - -/* keep definition for source code compatiblity */ -#define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1 - -/* - * array flags - */ -#define ARRAY_FLAG_DISABLED 0x00000001 /* The array is disabled */ -#define ARRAY_FLAG_NEEDBUILDING 0x00000002 /* need to be rebuilt */ -#define ARRAY_FLAG_REBUILDING 0x00000004 /* in rebuilding process */ -#define ARRAY_FLAG_BROKEN 0x00000008 /* broken but still working */ -#define ARRAY_FLAG_BOOTDISK 0x00000010 /* has a active partition */ -#define ARRAY_FLAG_BOOTMARK 0x00000040 /* array has boot mark set */ -#define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ -#define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ -#define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ -#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ -#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ -#define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */ -#define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */ - -/* - * device flags - */ -#define DEVICE_FLAG_DISABLED 0x00000001 /* device is disabled */ -#define DEVICE_FLAG_UNINITIALIZED 0x00010000 /* device is not initialized */ -#define DEVICE_FLAG_LEGACY 0x00020000 /* lagacy drive */ -#define DEVICE_FLAG_IS_SPARE 0x80000000 /* is a spare disk */ - -/* - * ioctl codes - */ -#define HPT_CTL_CODE(x) (x+0xFF00) -#define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00) - -#define HPT_IOCTL_GET_CONTROLLER_INFO HPT_CTL_CODE(2) -#define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3) -#define HPT_IOCTL_GET_LOGICAL_DEVICES HPT_CTL_CODE(4) -#define HPT_IOCTL_GET_DRIVER_CAPABILITIES HPT_CTL_CODE(19) -#define HPT_IOCTL_GET_DEVICE_INFO_V3 HPT_CTL_CODE(46) -#define HPT_IOCTL_GET_CONTROLLER_INFO_V2 HPT_CTL_CODE(47) - -/* - * Controller information. - */ -struct hpt_controller_info { - u8 chip_type; /* chip type */ - u8 interrupt_level; /* IRQ level */ - u8 num_buses; /* bus count */ - u8 chip_flags; - - u8 product_id[MAX_NAME_LENGTH];/* product name */ - u8 vendor_id[MAX_NAME_LENGTH]; /* vendor name */ -} -__attribute__((packed)); - -/* - * Channel information. - */ -struct hpt_channel_info { - __le32 io_port; /* IDE Base Port Address */ - __le32 control_port; /* IDE Control Port Address */ - __le32 devices[2]; /* device connected to this channel */ -} -__attribute__((packed)); - -/* - * Array information. - */ -struct hpt_array_info_v3 { - u8 name[MAX_ARRAYNAME_LEN]; /* array name */ - u8 description[64]; /* array description */ - u8 create_manager[16]; /* who created it */ - __le32 create_time; /* when created it */ - - u8 array_type; /* array type */ - u8 block_size_shift; /* stripe size */ - u8 ndisk; /* Number of ID in Members[] */ - u8 reserved; - - __le32 flags; /* working flags, see ARRAY_FLAG_XXX */ - __le32 members[MAX_ARRAY_MEMBERS_V2]; /* member array/disks */ - - __le32 rebuilding_progress; - __le64 rebuilt_sectors; /* rebuilding point (LBA) for single member */ - - __le32 transform_source; - __le32 transform_target; /* destination device ID */ - __le32 transforming_progress; - __le32 signature; /* persistent identification*/ - __le16 critical_members; /* bit mask of critical members */ - __le16 reserve2; - __le32 reserve; -} -__attribute__((packed)); - -/* - * physical device information. - */ -#define MAX_PARENTS_PER_DISK 8 - -struct hpt_device_info_v2 { - u8 ctlr_id; /* controller id */ - u8 path_id; /* bus */ - u8 target_id; /* id */ - u8 device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */ - /* 5-7 MW DMA0-2, 8-13 UDMA0-5 */ - u8 device_type; /* device type */ - u8 usable_mode; /* highest usable mode */ - -#ifdef __BIG_ENDIAN_BITFIELD - u8 NCQ_enabled: 1; - u8 NCQ_supported: 1; - u8 TCQ_enabled: 1; - u8 TCQ_supported: 1; - u8 write_cache_enabled: 1; - u8 write_cache_supported: 1; - u8 read_ahead_enabled: 1; - u8 read_ahead_supported: 1; - u8 reserved6: 6; - u8 spin_up_mode: 2; -#else - u8 read_ahead_supported: 1; - u8 read_ahead_enabled: 1; - u8 write_cache_supported: 1; - u8 write_cache_enabled: 1; - u8 TCQ_supported: 1; - u8 TCQ_enabled: 1; - u8 NCQ_supported: 1; - u8 NCQ_enabled: 1; - u8 spin_up_mode: 2; - u8 reserved6: 6; -#endif - - __le32 flags; /* working flags, see DEVICE_FLAG_XXX */ - u8 ident[150]; /* (partitial) Identify Data of this device */ - - __le64 total_free; - __le64 max_free; - __le64 bad_sectors; - __le32 parent_arrays[MAX_PARENTS_PER_DISK]; -} -__attribute__((packed)); - -/* - * Logical device information. - */ -#define INVALID_TARGET_ID 0xFF -#define INVALID_BUS_ID 0xFF - -struct hpt_logical_device_info_v3 { - u8 type; /* LDT_ARRAY or LDT_DEVICE */ - u8 cache_policy; /* refer to CACHE_POLICY_xxx */ - u8 vbus_id; /* vbus sequence in vbus_list */ - u8 target_id; /* OS target id. 0xFF is invalid */ - /* OS name: DISK $VBusId_$TargetId */ - __le64 capacity; /* array capacity */ - __le32 parent_array; /* don't use this field for physical - device. use ParentArrays field in - hpt_device_info_v2 */ - /* reserved statistic fields */ - __le32 stat1; - __le32 stat2; - __le32 stat3; - __le32 stat4; - - union { - struct hpt_array_info_v3 array; - struct hpt_device_info_v2 device; - } __attribute__((packed)) u; - -} -__attribute__((packed)); - -/* - * ioctl structure - */ -#define HPT_IOCTL_MAGIC 0xA1B2C3D4 - -struct hpt_ioctl_u { - u32 magic; /* used to check if it's a valid ioctl packet */ - u32 ioctl_code; /* operation control code */ - void __user *inbuf; /* input data buffer */ - u32 inbuf_size; /* size of input data buffer */ - void __user *outbuf; /* output data buffer */ - u32 outbuf_size; /* size of output data buffer */ - void __user *bytes_returned; /* count of bytes returned */ -} -__attribute__((packed)); - - -struct hpt_iopmu -{ - __le32 resrved0[4]; - __le32 inbound_msgaddr0; - __le32 inbound_msgaddr1; - __le32 outbound_msgaddr0; - __le32 outbound_msgaddr1; - __le32 inbound_doorbell; - __le32 inbound_intstatus; - __le32 inbound_intmask; - __le32 outbound_doorbell; - __le32 outbound_intstatus; - __le32 outbound_intmask; - __le32 reserved1[2]; - __le32 inbound_queue; - __le32 outbound_queue; -}; - -#define IOPMU_QUEUE_EMPTY 0xffffffff -#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 -#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 - -#define IOPMU_OUTBOUND_INT_MSG0 1 -#define IOPMU_OUTBOUND_INT_MSG1 2 -#define IOPMU_OUTBOUND_INT_DOORBELL 4 -#define IOPMU_OUTBOUND_INT_POSTQUEUE 8 -#define IOPMU_OUTBOUND_INT_PCI 0x10 - -#define IOPMU_INBOUND_INT_MSG0 1 -#define IOPMU_INBOUND_INT_MSG1 2 -#define IOPMU_INBOUND_INT_DOORBELL 4 -#define IOPMU_INBOUND_INT_ERROR 8 -#define IOPMU_INBOUND_INT_POSTQUEUE 0x10 - -enum hpt_iopmu_message { - /* host-to-iop messages */ - IOPMU_INBOUND_MSG0_NOP = 0, - IOPMU_INBOUND_MSG0_RESET, - IOPMU_INBOUND_MSG0_FLUSH, - IOPMU_INBOUND_MSG0_SHUTDOWN, - IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, - IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, - IOPMU_INBOUND_MSG0_MAX = 0xff, - /* iop-to-host messages */ - IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, - IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, - IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, - IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, - IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, - IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, -}; - -struct hpt_iop_request_header -{ - __le32 size; - __le32 type; - __le32 flags; - __le32 result; - __le32 context; /* host context */ - __le32 context_hi32; -}; - -#define IOP_REQUEST_FLAG_SYNC_REQUEST 1 -#define IOP_REQUEST_FLAG_BIST_REQUEST 2 -#define IOP_REQUEST_FLAG_REMAPPED 4 -#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 - -enum hpt_iop_request_type { - IOP_REQUEST_TYPE_GET_CONFIG = 0, - IOP_REQUEST_TYPE_SET_CONFIG, - IOP_REQUEST_TYPE_BLOCK_COMMAND, - IOP_REQUEST_TYPE_SCSI_COMMAND, - IOP_REQUEST_TYPE_IOCTL_COMMAND, - IOP_REQUEST_TYPE_MAX -}; - -enum hpt_iop_result_type { - IOP_RESULT_PENDING = 0, - IOP_RESULT_SUCCESS, - IOP_RESULT_FAIL, - IOP_RESULT_BUSY, - IOP_RESULT_RESET, - IOP_RESULT_INVALID_REQUEST, - IOP_RESULT_BAD_TARGET, - IOP_RESULT_MODE_SENSE_CHECK_CONDITION, -}; - -struct hpt_iop_request_get_config -{ - struct hpt_iop_request_header header; - __le32 interface_version; - __le32 firmware_version; - __le32 max_requests; - __le32 request_size; - __le32 max_sg_count; - __le32 data_transfer_length; - __le32 alignment_mask; - __le32 max_devices; - __le32 sdram_size; -}; - -struct hpt_iop_request_set_config -{ - struct hpt_iop_request_header header; - __le32 iop_id; - __le32 vbus_id; - __le32 reserve[6]; -}; - -struct hpt_iopsg -{ - __le32 size; - __le32 eot; /* non-zero: end of table */ - __le64 pci_address; -}; - -struct hpt_iop_request_block_command -{ - struct hpt_iop_request_header header; - u8 channel; - u8 target; - u8 lun; - u8 pad1; - __le16 command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ - __le16 sectors; - __le64 lba; - struct hpt_iopsg sg_list[1]; -}; - -#define IOP_BLOCK_COMMAND_READ 1 -#define IOP_BLOCK_COMMAND_WRITE 2 -#define IOP_BLOCK_COMMAND_VERIFY 3 -#define IOP_BLOCK_COMMAND_FLUSH 4 -#define IOP_BLOCK_COMMAND_SHUTDOWN 5 - -struct hpt_iop_request_scsi_command -{ - struct hpt_iop_request_header header; - u8 channel; - u8 target; - u8 lun; - u8 pad1; - u8 cdb[16]; - __le32 dataxfer_length; - struct hpt_iopsg sg_list[1]; -}; - -struct hpt_iop_request_ioctl_command -{ - struct hpt_iop_request_header header; - __le32 ioctl_code; - __le32 inbuf_size; - __le32 outbuf_size; - __le32 bytes_returned; - u8 buf[1]; - /* out data should be put at buf[(inbuf_size+3)&~3] */ -}; - -#define HPTIOP_MAX_REQUESTS 256u - -struct hptiop_request { - struct hptiop_request * next; - void * req_virt; - u32 req_shifted_phy; - struct scsi_cmnd * scp; - int index; -}; - -struct hpt_scsi_pointer { - int mapped; - int sgcnt; - dma_addr_t dma_handle; -}; - -#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp) - -struct hptiop_hba { - struct hpt_iopmu __iomem * iop; - struct Scsi_Host * host; - struct pci_dev * pcidev; - - struct list_head link; - - /* IOP config info */ - u32 firmware_version; - u32 sdram_size; - u32 max_devices; - u32 max_requests; - u32 max_request_size; - u32 max_sg_descriptors; - - u32 req_size; /* host-allocated request buffer size */ - int initialized; - int msg_done; - - struct hptiop_request * req_list; - struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; - - /* used to free allocated dma area */ - void * dma_coherent; - dma_addr_t dma_coherent_handle; - - atomic_t reset_count; - atomic_t resetting; - - wait_queue_head_t reset_wq; - wait_queue_head_t ioctl_wq; -}; - -struct hpt_ioctl_k -{ - struct hptiop_hba * hba; - u32 ioctl_code; - u32 inbuf_size; - u32 outbuf_size; - void * inbuf; - void * outbuf; - u32 * bytes_returned; - void (*done)(struct hpt_ioctl_k *); - int result; /* HPT_IOCTL_RESULT_ */ -}; - -#define HPT_IOCTL_RESULT_OK 0 -#define HPT_IOCTL_RESULT_FAILED (-1) - -#if 0 -#define dprintk(fmt, args...) do { printk(fmt, ##args); } while(0) -#else -#define dprintk(fmt, args...) -#endif - -#endif diff --git a/trunk/drivers/scsi/ibmmca.c b/trunk/drivers/scsi/ibmmca.c index 497f6642b2dc..24eb59e143a9 100644 --- a/trunk/drivers/scsi/ibmmca.c +++ b/trunk/drivers/scsi/ibmmca.c @@ -760,7 +760,7 @@ static int device_inquiry(int host_index, int ldn) while (!got_interrupt(host_index)) barrier(); - /*if command successful, break */ + /*if command succesful, break */ if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) return 1; } @@ -885,7 +885,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, while (!got_interrupt(host_index)) barrier(); - /*if command successful, break */ + /*if command succesful, break */ if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) return 1; } @@ -921,7 +921,7 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti return 2; } else global_command_error_excuse = 0; - /*if command successful, break */ + /*if command succesful, break */ if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) return 1; } @@ -959,7 +959,7 @@ static int immediate_reset(int host_index, unsigned int ldn) /* did not work, finish */ return 1; } - /*if command successful, break */ + /*if command succesful, break */ if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) return 1; } @@ -1441,7 +1441,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id) struct Scsi_Host *dev = dev_id; spin_lock_irqsave(dev->host_lock, flags); - + shpnt = dev; /* assign host-structure to local pointer */ len = 0; /* set filled text-buffer index to 0 */ /* get the _special contents of the hostdata structure */ @@ -1456,7 +1456,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id) /* if the integrated subsystem has been found automatically: */ len += sprintf(buf + len, "Adapter category: integrated\n" "Chip revision level: %d\n" "Chip status: %s\n" "8 kByte NVRAM status: %s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 1) ? "enabled" : "disabled", (pos[2] & 2) ? "locked" : "accessible"); - } else if ((speciale >= 0) && (speciale < ARRAY_SIZE(subsys_list))) { + } else if ((speciale >= 0) && (speciale < (sizeof(subsys_list) / sizeof(struct subsys_list_struct)))) { /* if the subsystem is a slot adapter */ len += sprintf(buf + len, "Adapter category: slot-card\n" "ROM Segment Address: "); if ((pos[2] & 0xf0) == 0xf0) @@ -1477,16 +1477,16 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id) while (len % sizeof(int) != (sizeof(int) - 1)) len += sprintf(buf + len, " "); len += sprintf(buf + len, "\n"); - + spin_unlock_irqrestore(shpnt->host_lock, flags); - + return len; } int ibmmca_detect(struct scsi_host_template * scsi_template) { struct Scsi_Host *shpnt; - int port, id, i, j, k, slot; + int port, id, i, j, k, list_size, slot; int devices_on_irq_11 = 0; int devices_on_irq_14 = 0; int IRQ14_registered = 0; @@ -1603,7 +1603,8 @@ int ibmmca_detect(struct scsi_host_template * scsi_template) /* now look for other adapters in MCA slots, */ /* determine the number of known IBM-SCSI-subsystem types */ /* see the pos[2] dependence to get the adapter port-offset. */ - for (i = 0; i < ARRAY_SIZE(subsys_list); i++) { + list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct); + for (i = 0; i < list_size; i++) { /* scan each slot for a fitting adapter id */ slot = 0; /* start at slot 0 */ while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot)) @@ -1668,7 +1669,8 @@ int ibmmca_detect(struct scsi_host_template * scsi_template) /* now check for SCSI-adapters, mapped to the integrated SCSI * area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here, * as this is a known effect on some models 95xx. */ - for (i = 0; i < ARRAY_SIZE(subsys_list); i++) { + list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct); + for (i = 0; i < list_size; i++) { /* scan each slot for a fitting adapter id */ slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI); if (slot != MCA_NOTFOUND) { /* scan through all slots */ @@ -2241,7 +2243,8 @@ static int __ibmmca_host_reset(Scsi_Cmnd * cmd) int host_index; unsigned long imm_command; - BUG_ON(cmd == NULL); + if (cmd == NULL) + BUG(); ticks = IM_RESET_DELAY * HZ; shpnt = cmd->device->host; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 944fc1203ebd..2e9be83a697f 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -121,9 +121,10 @@ static int initialize_event_pool(struct event_pool *pool, pool->size = size; pool->next = 0; - pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL); + pool->events = kmalloc(pool->size * sizeof(*pool->events), GFP_KERNEL); if (!pool->events) return -ENOMEM; + memset(pool->events, 0x00, pool->size * sizeof(*pool->events)); pool->iu_storage = dma_alloc_coherent(hostdata->dev, diff --git a/trunk/drivers/scsi/ide-scsi.c b/trunk/drivers/scsi/ide-scsi.c index 988e6f7af01a..39b760a24241 100644 --- a/trunk/drivers/scsi/ide-scsi.c +++ b/trunk/drivers/scsi/ide-scsi.c @@ -600,7 +600,8 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) "issuing a packet command\n"); return ide_do_reset (drive); } - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); /* Set the interrupt routine */ ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); /* Send the actual packet */ @@ -690,7 +691,8 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) set_bit(PC_DMA_OK, &pc->flags); if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { - BUG_ON(HWGROUP(drive)->handler != NULL); + if (HWGROUP(drive)->handler != NULL) + BUG(); ide_set_handler(drive, &idescsi_transfer_pc, get_timeout(pc), idescsi_expiry); /* Issue the packet command */ diff --git a/trunk/drivers/scsi/imm.c b/trunk/drivers/scsi/imm.c index 681bd18493f3..fc0f30ae0f77 100644 --- a/trunk/drivers/scsi/imm.c +++ b/trunk/drivers/scsi/imm.c @@ -3,6 +3,9 @@ * * (The IMM is the embedded controller in the ZIP Plus drive.) * + * Current Maintainer: David Campbell (Perth, Western Australia) + * campbell@torque.net + * * My unoffical company acronym list is 21 pages long: * FLA: Four letter acronym with built in facility for * future expansion to five letters. @@ -1116,10 +1119,6 @@ static int device_check(imm_struct *dev) return -ENODEV; } -/* - * imm cannot deal with highmem, so this causes all IO pages for this host - * to reside in low memory (hence mapped) - */ static int imm_adjust_queue(struct scsi_device *device) { blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); @@ -1142,6 +1141,10 @@ static struct scsi_host_template imm_template = { .use_clustering = ENABLE_CLUSTERING, .can_queue = 1, .slave_alloc = imm_adjust_queue, + .unchecked_isa_dma = 1, /* imm cannot deal with highmem, so + * this is an easy trick to ensure + * all io pages for this host reside + * in low memory */ }; /*************************************************************************** diff --git a/trunk/drivers/scsi/imm.h b/trunk/drivers/scsi/imm.h index ece936ac29c7..dc3aebf0e365 100644 --- a/trunk/drivers/scsi/imm.h +++ b/trunk/drivers/scsi/imm.h @@ -2,7 +2,7 @@ /* Driver for the Iomega MatchMaker parallel port SCSI HBA embedded in * the Iomega ZIP Plus drive * - * (c) 1998 David Campbell + * (c) 1998 David Campbell campbell@torque.net * * Please note that I live in Perth, Western Australia. GMT+0800 */ diff --git a/trunk/drivers/scsi/in2000.c b/trunk/drivers/scsi/in2000.c index 883bc92b4d9a..9c519876f8a0 100644 --- a/trunk/drivers/scsi/in2000.c +++ b/trunk/drivers/scsi/in2000.c @@ -370,7 +370,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; cmd->SCp.this_residual = cmd->SCp.buffer->length; @@ -1809,7 +1809,7 @@ static int in2000_abort(Scsi_Cmnd * cmd) #define MAX_IN2000_HOSTS 3 -#define MAX_SETUP_ARGS ARRAY_SIZE(setup_args) +#define MAX_SETUP_ARGS (sizeof(setup_args) / sizeof(char *)) #define SETUP_BUFFER_SIZE 200 static char setup_buffer[SETUP_BUFFER_SIZE]; static char setup_used[MAX_SETUP_ARGS]; diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c index 913ba95f85bd..0cc7f65b584f 100644 --- a/trunk/drivers/scsi/initio.c +++ b/trunk/drivers/scsi/initio.c @@ -154,6 +154,7 @@ static unsigned int i91u_debug = DEBUG_DEFAULT; #endif +#define TULSZ(sz) (sizeof(sz) / sizeof(sz[0])) #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) typedef struct PCI_ID_Struc { @@ -2770,7 +2771,7 @@ static int tul_NewReturnNumberOfAdapters(void) init_i91uAdapter_table(); - for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++) + for (i = 0; i < TULSZ(i91u_pci_devices); i++) { while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { if (pci_enable_device(pDev)) diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 96b65b307dd0..8b80e59c8c52 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "ipr.h" /* diff --git a/trunk/drivers/scsi/ips.c b/trunk/drivers/scsi/ips.c index 78f2ff736c3e..a4c0b04cfdbd 100644 --- a/trunk/drivers/scsi/ips.c +++ b/trunk/drivers/scsi/ips.c @@ -556,7 +556,7 @@ ips_setup(char *ips_str) * We now have key/value pairs. * Update the variables */ - for (i = 0; i < ARRAY_SIZE(options); i++) { + for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) { if (strnicmp (key, options[i].option_name, strlen(options[i].option_name)) == 0) { @@ -4364,7 +4364,7 @@ ips_rdcap(ips_ha_t * ha, ips_scb_t * scb) METHOD_TRACE("ips_rdcap", 1); - if (scb->scsi_cmd->request_bufflen < 8) + if (scb->scsi_cmd->bufflen < 8) return (0); cap.lba = @@ -6438,7 +6438,7 @@ ips_erase_bios(ips_ha_t * ha) /* VPP failure */ return (1); - /* check for successful flash */ + /* check for succesful flash */ if (status & 0x30) /* sequence error */ return (1); @@ -6550,7 +6550,7 @@ ips_erase_bios_memio(ips_ha_t * ha) /* VPP failure */ return (1); - /* check for successful flash */ + /* check for succesful flash */ if (status & 0x30) /* sequence error */ return (1); diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index b4743a9ecc80..2068b66822b7 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -3,8 +3,7 @@ * * Copyright (C) 2004 Dmitry Yusupov * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 - 2006 Mike Christie - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2005 Mike Christie * maintained by open-iscsi@googlegroups.com * * This program is free software; you can redistribute it and/or modify @@ -37,28 +36,37 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include "iscsi_tcp.h" -#define ISCSI_TCP_VERSION "1.0-595" - MODULE_AUTHOR("Dmitry Yusupov , " "Alex Aizman "); MODULE_DESCRIPTION("iSCSI/TCP data-path"); MODULE_LICENSE("GPL"); -MODULE_VERSION(ISCSI_TCP_VERSION); +MODULE_VERSION("0:4.445"); /* #define DEBUG_TCP */ +/* #define DEBUG_SCSI */ #define DEBUG_ASSERT #ifdef DEBUG_TCP -#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt) +#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt) #else #define debug_tcp(fmt...) #endif +#ifdef DEBUG_SCSI +#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt) +#else +#define debug_scsi(fmt...) +#endif + #ifndef DEBUG_ASSERT #ifdef BUG_ON #undef BUG_ON @@ -66,9 +74,22 @@ MODULE_VERSION(ISCSI_TCP_VERSION); #define BUG_ON(expr) #endif +#define INVALID_SN_DELTA 0xffff + static unsigned int iscsi_max_lun = 512; module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); +/* global data */ +static kmem_cache_t *taskcache; + +static inline void +iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size) +{ + sg_init_one(&ibuf->sg, (u8 *)vbuf, size); + ibuf->sent = 0; + ibuf->use_sendmsg = 0; +} + static inline void iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) { @@ -109,39 +130,68 @@ static inline void iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf, u8* crc) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - - crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc); + crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc); buf->sg.length += sizeof(uint32_t); } +static void +iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) +{ + struct iscsi_session *session = conn->session; + unsigned long flags; + + spin_lock_irqsave(&session->lock, flags); + if (session->conn_cnt == 1 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + spin_unlock_irqrestore(&session->lock, flags); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + iscsi_conn_error(conn->cls_conn, err); +} + static inline int -iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) +iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) { - struct sk_buff *skb = tcp_conn->in.skb; + uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn); + uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn); + + if (max_cmdsn < exp_cmdsn -1 && + max_cmdsn > exp_cmdsn - INVALID_SN_DELTA) + return ISCSI_ERR_MAX_CMDSN; + if (max_cmdsn > session->max_cmdsn || + max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA) + session->max_cmdsn = max_cmdsn; + if (exp_cmdsn > session->exp_cmdsn || + exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA) + session->exp_cmdsn = exp_cmdsn; + + return 0; +} - tcp_conn->in.zero_copy_hdr = 0; +static inline int +iscsi_hdr_extract(struct iscsi_conn *conn) +{ + struct sk_buff *skb = conn->in.skb; - if (tcp_conn->in.copy >= tcp_conn->hdr_size && - tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) { + if (conn->in.copy >= conn->hdr_size && + conn->in_progress == IN_PROGRESS_WAIT_HEADER) { /* * Zero-copy PDU Header: using connection context * to store header pointer. */ if (skb_shinfo(skb)->frag_list == NULL && - !skb_shinfo(skb)->nr_frags) { - tcp_conn->in.hdr = (struct iscsi_hdr *) - ((char*)skb->data + tcp_conn->in.offset); - tcp_conn->in.zero_copy_hdr = 1; - } else { + !skb_shinfo(skb)->nr_frags) + conn->in.hdr = (struct iscsi_hdr *) + ((char*)skb->data + conn->in.offset); + else { /* ignoring return code since we checked * in.copy before */ - skb_copy_bits(skb, tcp_conn->in.offset, - &tcp_conn->hdr, tcp_conn->hdr_size); - tcp_conn->in.hdr = &tcp_conn->hdr; + skb_copy_bits(skb, conn->in.offset, + &conn->hdr, conn->hdr_size); + conn->in.hdr = &conn->hdr; } - tcp_conn->in.offset += tcp_conn->hdr_size; - tcp_conn->in.copy -= tcp_conn->hdr_size; + conn->in.offset += conn->hdr_size; + conn->in.copy -= conn->hdr_size; } else { int hdr_remains; int copylen; @@ -151,51 +201,118 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) * copying it... This'll happen quite rarely. */ - if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) - tcp_conn->in.hdr_offset = 0; + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER) + conn->in.hdr_offset = 0; - hdr_remains = tcp_conn->hdr_size - tcp_conn->in.hdr_offset; + hdr_remains = conn->hdr_size - conn->in.hdr_offset; BUG_ON(hdr_remains <= 0); - copylen = min(tcp_conn->in.copy, hdr_remains); - skb_copy_bits(skb, tcp_conn->in.offset, - (char*)&tcp_conn->hdr + tcp_conn->in.hdr_offset, - copylen); + copylen = min(conn->in.copy, hdr_remains); + skb_copy_bits(skb, conn->in.offset, + (char*)&conn->hdr + conn->in.hdr_offset, copylen); debug_tcp("PDU gather offset %d bytes %d in.offset %d " - "in.copy %d\n", tcp_conn->in.hdr_offset, copylen, - tcp_conn->in.offset, tcp_conn->in.copy); + "in.copy %d\n", conn->in.hdr_offset, copylen, + conn->in.offset, conn->in.copy); - tcp_conn->in.offset += copylen; - tcp_conn->in.copy -= copylen; + conn->in.offset += copylen; + conn->in.copy -= copylen; if (copylen < hdr_remains) { - tcp_conn->in_progress = IN_PROGRESS_HEADER_GATHER; - tcp_conn->in.hdr_offset += copylen; + conn->in_progress = IN_PROGRESS_HEADER_GATHER; + conn->in.hdr_offset += copylen; return -EAGAIN; } - tcp_conn->in.hdr = &tcp_conn->hdr; - tcp_conn->discontiguous_hdr_cnt++; - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in.hdr = &conn->hdr; + conn->discontiguous_hdr_cnt++; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } return 0; } -/* - * must be called with session lock - */ -static void -__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +static inline void +iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct scsi_cmnd *sc; + struct scsi_cmnd *sc = ctask->sc; + struct iscsi_session *session = conn->session; - sc = ctask->sc; - if (unlikely(!sc)) + spin_lock(&session->lock); + if (unlikely(!sc)) { + spin_unlock(&session->lock); return; + } + if (sc->sc_data_direction == DMA_TO_DEVICE) { + struct iscsi_data_task *dtask, *n; + /* WRITE: cleanup Data-Out's if any */ + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } + } + ctask->xmstate = XMSTATE_IDLE; + ctask->r2t = NULL; + ctask->sc = NULL; + __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + spin_unlock(&session->lock); +} + +/** + * iscsi_cmd_rsp - SCSI Command Response processing + * @conn: iscsi connection + * @ctask: scsi command task + **/ +static int +iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + int rc; + struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr; + struct iscsi_session *session = conn->session; + struct scsi_cmnd *sc = ctask->sc; + + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); + if (rc) { + sc->result = (DID_ERROR << 16); + goto out; + } + + conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; + + sc->result = (DID_OK << 16) | rhdr->cmd_status; + + if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) { + sc->result = (DID_ERROR << 16); + goto out; + } + + if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) { + int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE); - tcp_ctask->xmstate = XMSTATE_IDLE; - tcp_ctask->r2t = NULL; + memcpy(sc->sense_buffer, conn->data + 2, sensecopy); + debug_scsi("copied %d bytes of sense\n", sensecopy); + } + + if (sc->sc_data_direction == DMA_TO_DEVICE) + goto out; + + if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { + int res_count = be32_to_cpu(rhdr->residual_count); + + if (res_count > 0 && res_count <= sc->request_bufflen) + sc->resid = res_count; + else + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) + sc->resid = be32_to_cpu(rhdr->residual_count); + +out: + debug_scsi("done [sc %lx res %d itt 0x%x]\n", + (long)sc, sc->result, ctask->itt); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); + return rc; } /** @@ -207,9 +324,7 @@ static int iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { int rc; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; + struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)conn->in.hdr; struct iscsi_session *session = conn->session; int datasn = be32_to_cpu(rhdr->datasn); @@ -219,9 +334,9 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) /* * setup Data-In byte counter (gets decremented..) */ - ctask->data_count = tcp_conn->in.datalen; + ctask->data_count = conn->in.datalen; - if (tcp_conn->in.datalen == 0) + if (conn->in.datalen == 0) return 0; if (ctask->datasn != datasn) @@ -229,8 +344,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) ctask->datasn++; - tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); - if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length) + ctask->data_offset = be32_to_cpu(rhdr->offset); + if (ctask->data_offset + conn->in.datalen > ctask->total_length) return ISCSI_ERR_DATA_OFFSET; if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) { @@ -275,17 +390,19 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_r2t_info *r2t) { struct iscsi_data *hdr; + struct iscsi_data_task *dtask; struct scsi_cmnd *sc = ctask->sc; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - hdr = &r2t->dtask.hdr; + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; memset(hdr, 0, sizeof(struct iscsi_data)); hdr->ttt = r2t->ttt; hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; hdr->exp_statsn = r2t->exp_statsn; hdr->offset = cpu_to_be32(r2t->data_offset); if (r2t->data_length > conn->max_xmit_dlength) { @@ -301,9 +418,11 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, r2t->sent = 0; - iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + r2t->dtask = dtask; + if (sc->use_sg) { int i, sg_count = 0; struct scatterlist *sg = sc->request_buffer; @@ -332,9 +451,11 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } BUG_ON(r2t->sg == NULL); } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, + iscsi_buf_init_iov(&ctask->sendbuf, (char*)sc->request_buffer + r2t->data_offset, r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); } /** @@ -347,16 +468,17 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_r2t_info *r2t; struct iscsi_session *session = conn->session; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr; + struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr; int r2tsn = be32_to_cpu(rhdr->r2tsn); int rc; - if (tcp_conn->in.datalen) + if (conn->in.ahslen) + return ISCSI_ERR_AHSLEN; + + if (conn->in.datalen) return ISCSI_ERR_DATALEN; - if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn) + if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn) return ISCSI_ERR_R2TSN; rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); @@ -374,7 +496,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) spin_unlock(&session->lock); return 0; } - rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + rc = __kfifo_get(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); BUG_ON(!rc); r2t->exp_statsn = rhdr->statsn; @@ -396,10 +518,10 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) iscsi_solicit_data_init(conn, ctask, r2t); - tcp_ctask->exp_r2tsn = r2tsn + 1; - tcp_ctask->xmstate |= XMSTATE_SOL_HDR; - __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); - __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); + ctask->exp_r2tsn = r2tsn + 1; + ctask->xmstate |= XMSTATE_SOL_HDR; + __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*)); + __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*)); scsi_queue_work(session->host, &conn->xmitwork); conn->r2t_pdus_cnt++; @@ -409,136 +531,258 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) } static int -iscsi_tcp_hdr_recv(struct iscsi_conn *conn) +iscsi_hdr_recv(struct iscsi_conn *conn) { - int rc = 0, opcode, ahslen; + int rc = 0; struct iscsi_hdr *hdr; + struct iscsi_cmd_task *ctask; struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - uint32_t cdgst, rdgst = 0, itt; + uint32_t cdgst, rdgst = 0; - hdr = tcp_conn->in.hdr; + hdr = conn->in.hdr; /* verify PDU length */ - tcp_conn->in.datalen = ntoh24(hdr->dlength); - if (tcp_conn->in.datalen > conn->max_recv_dlength) { + conn->in.datalen = ntoh24(hdr->dlength); + if (conn->in.datalen > conn->max_recv_dlength) { printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n", - tcp_conn->in.datalen, conn->max_recv_dlength); + conn->in.datalen, conn->max_recv_dlength); return ISCSI_ERR_DATALEN; } - tcp_conn->data_copied = 0; + conn->data_copied = 0; /* read AHS */ - ahslen = hdr->hlength << 2; - tcp_conn->in.offset += ahslen; - tcp_conn->in.copy -= ahslen; - if (tcp_conn->in.copy < 0) { + conn->in.ahslen = hdr->hlength * 4; + conn->in.offset += conn->in.ahslen; + conn->in.copy -= conn->in.ahslen; + if (conn->in.copy < 0) { printk(KERN_ERR "iscsi_tcp: can't handle AHS with length " - "%d bytes\n", ahslen); + "%d bytes\n", conn->in.ahslen); return ISCSI_ERR_AHSLEN; } /* calculate read padding */ - tcp_conn->in.padding = tcp_conn->in.datalen & (ISCSI_PAD_LEN-1); - if (tcp_conn->in.padding) { - tcp_conn->in.padding = ISCSI_PAD_LEN - tcp_conn->in.padding; - debug_scsi("read padding %d bytes\n", tcp_conn->in.padding); + conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1); + if (conn->in.padding) { + conn->in.padding = ISCSI_PAD_LEN - conn->in.padding; + debug_scsi("read padding %d bytes\n", conn->in.padding); } if (conn->hdrdgst_en) { struct scatterlist sg; sg_init_one(&sg, (u8 *)hdr, - sizeof(struct iscsi_hdr) + ahslen); - crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst); + sizeof(struct iscsi_hdr) + conn->in.ahslen); + crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst); rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + - ahslen); + conn->in.ahslen); if (cdgst != rdgst) { - printk(KERN_ERR "iscsi_tcp: hdrdgst error " - "recv 0x%x calc 0x%x\n", rdgst, cdgst); + printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error " + "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst, + cdgst); return ISCSI_ERR_HDR_DGST; } } - opcode = hdr->opcode & ISCSI_OPCODE_MASK; + /* save opcode for later */ + conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK; + /* verify itt (itt encoding: age+cid+itt) */ - rc = iscsi_verify_itt(conn, hdr, &itt); - if (rc == ISCSI_ERR_NO_SCSI_CMD) { - tcp_conn->in.datalen = 0; /* force drop */ - return 0; - } else if (rc) - return rc; + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if ((hdr->itt & AGE_MASK) != + (session->age << AGE_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x expected " + "session age (%x)\n", hdr->itt, + session->age & AGE_MASK); + return ISCSI_ERR_BAD_ITT; + } + + if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x, expected " + "CID (%x)\n", hdr->itt, conn->id); + return ISCSI_ERR_BAD_ITT; + } + conn->in.itt = hdr->itt & ITT_MASK; + } else + conn->in.itt = hdr->itt; debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n", - opcode, tcp_conn->in.offset, tcp_conn->in.copy, - ahslen, tcp_conn->in.datalen); + hdr->opcode, conn->in.offset, conn->in.copy, + conn->in.ahslen, conn->in.datalen); - switch(opcode) { - case ISCSI_OP_SCSI_DATA_IN: - tcp_conn->in.ctask = session->cmds[itt]; - rc = iscsi_data_rsp(conn, tcp_conn->in.ctask); - /* fall through */ - case ISCSI_OP_SCSI_CMD_RSP: - tcp_conn->in.ctask = session->cmds[itt]; - if (tcp_conn->in.datalen) - goto copy_hdr; - - spin_lock(&session->lock); - __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); - rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); - spin_unlock(&session->lock); - break; - case ISCSI_OP_R2T: - tcp_conn->in.ctask = session->cmds[itt]; - if (ahslen) - rc = ISCSI_ERR_AHSLEN; - else if (tcp_conn->in.ctask->sc->sc_data_direction == - DMA_TO_DEVICE) - rc = iscsi_r2t_rsp(conn, tcp_conn->in.ctask); - else - rc = ISCSI_ERR_PROTO; - break; - case ISCSI_OP_LOGIN_RSP: - case ISCSI_OP_TEXT_RSP: - case ISCSI_OP_LOGOUT_RSP: - case ISCSI_OP_NOOP_IN: - case ISCSI_OP_REJECT: - case ISCSI_OP_ASYNC_EVENT: - if (tcp_conn->in.datalen) - goto copy_hdr; - /* fall through */ - case ISCSI_OP_SCSI_TMFUNC_RSP: - rc = iscsi_complete_pdu(conn, hdr, NULL, 0); - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } + if (conn->in.itt < session->cmds_max) { + ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt]; - return rc; + if (!ctask->sc) { + printk(KERN_INFO "iscsi_tcp: dropping ctask with " + "itt 0x%x\n", ctask->itt); + conn->in.datalen = 0; /* force drop */ + return 0; + } -copy_hdr: - /* - * if we did zero copy for the header but we will need multiple - * skbs to complete the command then we have to copy the header - * for later use - */ - if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy < - (tcp_conn->in.datalen + tcp_conn->in.padding + - (conn->datadgst_en ? 4 : 0))) { - debug_tcp("Copying header for later use. in.copy %d in.datalen" - " %d\n", tcp_conn->in.copy, tcp_conn->in.datalen); - memcpy(&tcp_conn->hdr, tcp_conn->in.hdr, - sizeof(struct iscsi_hdr)); - tcp_conn->in.hdr = &tcp_conn->hdr; - tcp_conn->in.zero_copy_hdr = 0; - } - return 0; + if (ctask->sc->SCp.phase != session->age) { + printk(KERN_ERR "iscsi_tcp: ctask's session age %d, " + "expected %d\n", ctask->sc->SCp.phase, + session->age); + return ISCSI_ERR_SESSION_FAILED; + } + + conn->in.ctask = ctask; + + debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n", + hdr->opcode, conn->id, (long)ctask->sc, + ctask->itt, conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_SCSI_CMD_RSP: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (!conn->in.datalen) + rc = iscsi_cmd_rsp(conn, ctask); + else + /* + * got sense or response data; copying PDU + * Header to the connection's header + * placeholder + */ + memcpy(&conn->hdr, hdr, + sizeof(struct iscsi_hdr)); + break; + case ISCSI_OP_SCSI_DATA_IN: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + /* save flags for non-exceptional status */ + conn->in.flags = hdr->flags; + /* save cmd_status for sense data */ + conn->in.cmd_status = + ((struct iscsi_data_rsp*)hdr)->cmd_status; + rc = iscsi_data_rsp(conn, ctask); + break; + case ISCSI_OP_R2T: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) + rc = iscsi_r2t_rsp(conn, ctask); + else + rc = ISCSI_ERR_PROTO; + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET && + conn->in.itt < ISCSI_MGMT_ITT_OFFSET + + session->mgmtpool_max) { + struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + + debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", + conn->in.opcode, conn->id, mtask->itt, + conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGOUT_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (!conn->in.datalen) { + rc = iscsi_recv_pdu(conn->cls_conn, hdr, + NULL, 0); + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + case ISCSI_OP_SCSI_TMFUNC_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (conn->in.datalen || conn->in.ahslen) { + rc = ISCSI_ERR_PROTO; + break; + } + conn->tmfrsp_pdus_cnt++; + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + conn->tmabort_state = + ((struct iscsi_tm_rsp *)hdr)-> + response == ISCSI_TMF_RSP_COMPLETE ? + TMABORT_SUCCESS:TMABORT_FAILED; + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); + break; + case ISCSI_OP_NOOP_IN: + if (hdr->ttt != ISCSI_RESERVED_TAG) { + rc = ISCSI_ERR_PROTO; + break; + } + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + + if (!conn->in.datalen) { + struct iscsi_mgmt_task *mtask; + + rc = iscsi_recv_pdu(conn->cls_conn, hdr, + NULL, 0); + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt == ISCSI_RESERVED_TAG) { + switch(conn->in.opcode) { + case ISCSI_OP_NOOP_IN: + if (!conn->in.datalen) { + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) + rc = iscsi_recv_pdu(conn->cls_conn, + hdr, NULL, 0); + } else + rc = ISCSI_ERR_PROTO; + break; + case ISCSI_OP_REJECT: + /* we need sth like iscsi_reject_rsp()*/ + case ISCSI_OP_ASYNC_EVENT: + /* we need sth like iscsi_async_event_rsp() */ + rc = ISCSI_ERR_BAD_OPCODE; + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else + rc = ISCSI_ERR_BAD_ITT; + + return rc; } /** * iscsi_ctask_copy - copy skb bits to the destanation cmd task - * @conn: iscsi tcp connection + * @conn: iscsi connection * @ctask: scsi command task * @buf: buffer to copy to * @buf_size: size of buffer @@ -560,113 +804,110 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) * buf_left left to copy from in progress buffer **/ static inline int -iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask, +iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, void *buf, int buf_size, int offset) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int buf_left = buf_size - (tcp_conn->data_copied + offset); - int size = min(tcp_conn->in.copy, buf_left); + int buf_left = buf_size - (conn->data_copied + offset); + int size = min(conn->in.copy, buf_left); int rc; size = min(size, ctask->data_count); debug_tcp("ctask_copy %d bytes at offset %d copied %d\n", - size, tcp_conn->in.offset, tcp_conn->in.copied); + size, conn->in.offset, conn->in.copied); BUG_ON(size <= 0); - BUG_ON(tcp_ctask->sent + size > ctask->total_length); + BUG_ON(ctask->sent + size > ctask->total_length); - rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, - (char*)buf + (offset + tcp_conn->data_copied), size); + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + (offset + conn->data_copied), size); /* must fit into skb->len */ BUG_ON(rc); - tcp_conn->in.offset += size; - tcp_conn->in.copy -= size; - tcp_conn->in.copied += size; - tcp_conn->data_copied += size; - tcp_ctask->sent += size; + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; + ctask->sent += size; ctask->data_count -= size; - BUG_ON(tcp_conn->in.copy < 0); + BUG_ON(conn->in.copy < 0); BUG_ON(ctask->data_count < 0); - if (buf_size != (tcp_conn->data_copied + offset)) { + if (buf_size != (conn->data_copied + offset)) { if (!ctask->data_count) { - BUG_ON(buf_size - tcp_conn->data_copied < 0); + BUG_ON(buf_size - conn->data_copied < 0); /* done with this PDU */ - return buf_size - tcp_conn->data_copied; + return buf_size - conn->data_copied; } return -EAGAIN; } /* done with this buffer or with both - PDU and buffer */ - tcp_conn->data_copied = 0; + conn->data_copied = 0; return 0; } /** * iscsi_tcp_copy - copy skb bits to the destanation buffer - * @conn: iscsi tcp connection + * @conn: iscsi connection + * @buf: buffer to copy to + * @buf_size: number of bytes to copy * * Notes: * The function calls skb_copy_bits() and updates per-connection * byte counters. **/ static inline int -iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) +iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size) { - void *buf = tcp_conn->data; - int buf_size = tcp_conn->in.datalen; - int buf_left = buf_size - tcp_conn->data_copied; - int size = min(tcp_conn->in.copy, buf_left); + int buf_left = buf_size - conn->data_copied; + int size = min(conn->in.copy, buf_left); int rc; debug_tcp("tcp_copy %d bytes at offset %d copied %d\n", - size, tcp_conn->in.offset, tcp_conn->data_copied); + size, conn->in.offset, conn->data_copied); BUG_ON(size <= 0); - rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, - (char*)buf + tcp_conn->data_copied, size); + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + conn->data_copied, size); BUG_ON(rc); - tcp_conn->in.offset += size; - tcp_conn->in.copy -= size; - tcp_conn->in.copied += size; - tcp_conn->data_copied += size; + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; - if (buf_size != tcp_conn->data_copied) + if (buf_size != conn->data_copied) return -EAGAIN; return 0; } static inline void -partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn, - struct scatterlist *sg, int offset, int length) +partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg, + int offset, int length) { struct scatterlist temp; memcpy(&temp, sg, sizeof(struct scatterlist)); temp.offset = offset; temp.length = length; - crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1); + crypto_digest_update(conn->data_rx_tfm, &temp, 1); } static void -iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len) +iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len) { struct scatterlist tmp; sg_init_one(&tmp, buf, len); - crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1); + crypto_digest_update(conn->data_rx_tfm, &tmp, 1); } static int iscsi_scsi_data_in(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_cmd_task *ctask = tcp_conn->in.ctask; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_cmd_task *ctask = conn->in.ctask; struct scsi_cmnd *sc = ctask->sc; struct scatterlist *sg; int i, offset, rc = 0; @@ -678,33 +919,31 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) */ if (!sc->use_sg) { i = ctask->data_count; - rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer, - sc->request_bufflen, - tcp_ctask->data_offset); + rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer, + sc->request_bufflen, ctask->data_offset); if (rc == -EAGAIN) return rc; if (conn->datadgst_en) - iscsi_recv_digest_update(tcp_conn, sc->request_buffer, - i); + iscsi_recv_digest_update(conn, sc->request_buffer, i); rc = 0; goto done; } - offset = tcp_ctask->data_offset; + offset = ctask->data_offset; sg = sc->request_buffer; - if (tcp_ctask->data_offset) - for (i = 0; i < tcp_ctask->sg_count; i++) + if (ctask->data_offset) + for (i = 0; i < ctask->sg_count; i++) offset -= sg[i].length; /* we've passed through partial sg*/ if (offset < 0) offset = 0; - for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) { + for (i = ctask->sg_count; i < sc->use_sg; i++) { char *dest; dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0); - rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset, + rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset, sg[i].length, offset); kunmap_atomic(dest, KM_SOFTIRQ0); if (rc == -EAGAIN) @@ -713,17 +952,15 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) if (!rc) { if (conn->datadgst_en) { if (!offset) - crypto_digest_update( - tcp_conn->data_rx_tfm, - &sg[i], 1); + crypto_digest_update(conn->data_rx_tfm, + &sg[i], 1); else - partial_sg_digest_update(tcp_conn, - &sg[i], + partial_sg_digest_update(conn, &sg[i], sg[i].offset + offset, sg[i].length - offset); } offset = 0; - tcp_ctask->sg_count++; + ctask->sg_count++; } if (!ctask->data_count) { @@ -731,26 +968,25 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) /* * data-in is complete, but buffer not... */ - partial_sg_digest_update(tcp_conn, &sg[i], + partial_sg_digest_update(conn, &sg[i], sg[i].offset, sg[i].length-rc); rc = 0; break; } - if (!tcp_conn->in.copy) + if (!conn->in.copy) return -EAGAIN; } BUG_ON(ctask->data_count); done: /* check for non-exceptional status */ - if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { + if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) { debug_scsi("done [sc %lx res %d itt 0x%x]\n", (long)sc, sc->result, ctask->itt); - spin_lock(&conn->session->lock); - __iscsi_ctask_cleanup(conn, ctask); - __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); - spin_unlock(&conn->session->lock); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); } return rc; @@ -759,38 +995,71 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) static int iscsi_data_recv(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc = 0, opcode; + struct iscsi_session *session = conn->session; + int rc = 0; - opcode = tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK; - switch (opcode) { + switch(conn->in.opcode) { case ISCSI_OP_SCSI_DATA_IN: rc = iscsi_scsi_data_in(conn); break; - case ISCSI_OP_SCSI_CMD_RSP: - spin_lock(&conn->session->lock); - __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); - spin_unlock(&conn->session->lock); + case ISCSI_OP_SCSI_CMD_RSP: { + /* + * SCSI Sense Data: + * copying the entire Data Segment. + */ + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { + rc = -EAGAIN; + goto exit; + } + + /* + * check for sense + */ + conn->in.hdr = &conn->hdr; + conn->senselen = (conn->data[0] << 8) | conn->data[1]; + rc = iscsi_cmd_rsp(conn, conn->in.ctask); + if (!rc && conn->datadgst_en) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); + } + break; case ISCSI_OP_TEXT_RSP: case ISCSI_OP_LOGIN_RSP: - case ISCSI_OP_NOOP_IN: - case ISCSI_OP_ASYNC_EVENT: - case ISCSI_OP_REJECT: + case ISCSI_OP_NOOP_IN: { + struct iscsi_mgmt_task *mtask = NULL; + + if (conn->in.itt != ISCSI_RESERVED_TAG) + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + /* * Collect data segment to the connection's data * placeholder */ - if (iscsi_tcp_copy(tcp_conn)) { + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { rc = -EAGAIN; goto exit; } - rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data, - tcp_conn->in.datalen); - if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP) - iscsi_recv_digest_update(tcp_conn, tcp_conn->data, - tcp_conn->in.datalen); - break; + rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr, + conn->data, conn->in.datalen); + + if (!rc && conn->datadgst_en && + conn->in.opcode != ISCSI_OP_LOGIN_RSP) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); + + if (mtask && conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&mtask, + sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + case ISCSI_OP_ASYNC_EVENT: + case ISCSI_OP_REJECT: default: BUG_ON(1); } @@ -811,7 +1080,6 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, { int rc; struct iscsi_conn *conn = rd_desc->arg.data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; int processed; char pad[ISCSI_PAD_LEN]; struct scatterlist sg; @@ -820,15 +1088,15 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, * Save current SKB and its offset in the corresponding * connection context. */ - tcp_conn->in.copy = skb->len - offset; - tcp_conn->in.offset = offset; - tcp_conn->in.skb = skb; - tcp_conn->in.len = tcp_conn->in.copy; - BUG_ON(tcp_conn->in.copy <= 0); - debug_tcp("in %d bytes\n", tcp_conn->in.copy); + conn->in.copy = skb->len - offset; + conn->in.offset = offset; + conn->in.skb = skb; + conn->in.len = conn->in.copy; + BUG_ON(conn->in.copy <= 0); + debug_tcp("in %d bytes\n", conn->in.copy); more: - tcp_conn->in.copied = 0; + conn->in.copied = 0; rc = 0; if (unlikely(conn->suspend_rx)) { @@ -836,9 +1104,9 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, return 0; } - if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER || - tcp_conn->in_progress == IN_PROGRESS_HEADER_GATHER) { - rc = iscsi_hdr_extract(tcp_conn); + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER || + conn->in_progress == IN_PROGRESS_HEADER_GATHER) { + rc = iscsi_hdr_extract(conn); if (rc) { if (rc == -EAGAIN) goto nomore; @@ -851,91 +1119,90 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, /* * Verify and process incoming PDU header. */ - rc = iscsi_tcp_hdr_recv(conn); - if (!rc && tcp_conn->in.datalen) { + rc = iscsi_hdr_recv(conn); + if (!rc && conn->in.datalen) { if (conn->datadgst_en) { - BUG_ON(!tcp_conn->data_rx_tfm); - crypto_digest_init(tcp_conn->data_rx_tfm); + BUG_ON(!conn->data_rx_tfm); + crypto_digest_init(conn->data_rx_tfm); } - tcp_conn->in_progress = IN_PROGRESS_DATA_RECV; + conn->in_progress = IN_PROGRESS_DATA_RECV; } else if (rc) { iscsi_conn_failure(conn, rc); return 0; } } - if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { + if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { uint32_t recv_digest; - debug_tcp("extra data_recv offset %d copy %d\n", - tcp_conn->in.offset, tcp_conn->in.copy); - skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, + conn->in.offset, conn->in.copy); + skb_copy_bits(conn->in.skb, conn->in.offset, &recv_digest, 4); - tcp_conn->in.offset += 4; - tcp_conn->in.copy -= 4; - if (recv_digest != tcp_conn->in.datadgst) { + conn->in.offset += 4; + conn->in.copy -= 4; + if (recv_digest != conn->in.datadgst) { debug_tcp("iscsi_tcp: data digest error!" "0x%x != 0x%x\n", recv_digest, - tcp_conn->in.datadgst); + conn->in.datadgst); iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST); return 0; } else { debug_tcp("iscsi_tcp: data digest match!" "0x%x == 0x%x\n", recv_digest, - tcp_conn->in.datadgst); - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in.datadgst); + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } } - if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV && - tcp_conn->in.copy) { + if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) { debug_tcp("data_recv offset %d copy %d\n", - tcp_conn->in.offset, tcp_conn->in.copy); + conn->in.offset, conn->in.copy); rc = iscsi_data_recv(conn); if (rc) { - if (rc == -EAGAIN) + if (rc == -EAGAIN) { + rd_desc->count = conn->in.datalen - + conn->in.ctask->data_count; goto again; + } iscsi_conn_failure(conn, rc); return 0; } - tcp_conn->in.copy -= tcp_conn->in.padding; - tcp_conn->in.offset += tcp_conn->in.padding; + conn->in.copy -= conn->in.padding; + conn->in.offset += conn->in.padding; if (conn->datadgst_en) { - if (tcp_conn->in.padding) { - debug_tcp("padding -> %d\n", - tcp_conn->in.padding); - memset(pad, 0, tcp_conn->in.padding); - sg_init_one(&sg, pad, tcp_conn->in.padding); - crypto_digest_update(tcp_conn->data_rx_tfm, - &sg, 1); + if (conn->in.padding) { + debug_tcp("padding -> %d\n", conn->in.padding); + memset(pad, 0, conn->in.padding); + sg_init_one(&sg, pad, conn->in.padding); + crypto_digest_update(conn->data_rx_tfm, &sg, 1); } - crypto_digest_final(tcp_conn->data_rx_tfm, - (u8 *) & tcp_conn->in.datadgst); - debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst); - tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV; + crypto_digest_final(conn->data_rx_tfm, + (u8 *) & conn->in.datadgst); + debug_tcp("rx digest 0x%x\n", conn->in.datadgst); + conn->in_progress = IN_PROGRESS_DDIGEST_RECV; } else - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } debug_tcp("f, processed %d from out of %d padding %d\n", - tcp_conn->in.offset - offset, (int)len, tcp_conn->in.padding); - BUG_ON(tcp_conn->in.offset - offset > len); + conn->in.offset - offset, (int)len, conn->in.padding); + BUG_ON(conn->in.offset - offset > len); - if (tcp_conn->in.offset - offset != len) { + if (conn->in.offset - offset != len) { debug_tcp("continue to process %d bytes\n", - (int)len - (tcp_conn->in.offset - offset)); + (int)len - (conn->in.offset - offset)); goto more; } nomore: - processed = tcp_conn->in.offset - offset; + processed = conn->in.offset - offset; BUG_ON(processed == 0); return processed; again: - processed = tcp_conn->in.offset - offset; + processed = conn->in.offset - offset; debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n", processed, (int)len, (int)rd_desc->count); BUG_ON(processed == 0); @@ -953,14 +1220,9 @@ iscsi_tcp_data_ready(struct sock *sk, int flag) read_lock(&sk->sk_callback_lock); - /* - * Use rd_desc to pass 'conn' to iscsi_tcp_data_recv. - * We set count to 1 because we want the network layer to - * hand us all the skbs that are available. iscsi_tcp_data_recv - * handled pdus that cross buffers or pdus that still need data. - */ + /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */ rd_desc.arg.data = conn; - rd_desc.count = 1; + rd_desc.count = 0; tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv); read_unlock(&sk->sk_callback_lock); @@ -969,7 +1231,6 @@ iscsi_tcp_data_ready(struct sock *sk, int flag) static void iscsi_tcp_state_change(struct sock *sk) { - struct iscsi_tcp_conn *tcp_conn; struct iscsi_conn *conn; struct iscsi_session *session; void (*old_state_change)(struct sock *); @@ -986,8 +1247,7 @@ iscsi_tcp_state_change(struct sock *sk) iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); } - tcp_conn = conn->dd_data; - old_state_change = tcp_conn->old_state_change; + old_state_change = conn->old_state_change; read_unlock(&sk->sk_callback_lock); @@ -1002,25 +1262,23 @@ static void iscsi_write_space(struct sock *sk) { struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - - tcp_conn->old_write_space(sk); + conn->old_write_space(sk); debug_tcp("iscsi_write_space: cid %d\n", conn->id); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); scsi_queue_work(conn->session->host, &conn->xmitwork); } static void iscsi_conn_set_callbacks(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk = tcp_conn->sock->sk; + struct sock *sk = conn->sock->sk; /* assign new callbacks */ write_lock_bh(&sk->sk_callback_lock); sk->sk_user_data = conn; - tcp_conn->old_data_ready = sk->sk_data_ready; - tcp_conn->old_state_change = sk->sk_state_change; - tcp_conn->old_write_space = sk->sk_write_space; + conn->old_data_ready = sk->sk_data_ready; + conn->old_state_change = sk->sk_state_change; + conn->old_write_space = sk->sk_write_space; sk->sk_data_ready = iscsi_tcp_data_ready; sk->sk_state_change = iscsi_tcp_state_change; sk->sk_write_space = iscsi_write_space; @@ -1030,15 +1288,14 @@ iscsi_conn_set_callbacks(struct iscsi_conn *conn) static void iscsi_conn_restore_callbacks(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk = tcp_conn->sock->sk; + struct sock *sk = conn->sock->sk; /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ write_lock_bh(&sk->sk_callback_lock); sk->sk_user_data = NULL; - sk->sk_data_ready = tcp_conn->old_data_ready; - sk->sk_state_change = tcp_conn->old_state_change; - sk->sk_write_space = tcp_conn->old_write_space; + sk->sk_data_ready = conn->old_data_ready; + sk->sk_state_change = conn->old_state_change; + sk->sk_write_space = conn->old_write_space; sk->sk_no_check = 0; write_unlock_bh(&sk->sk_callback_lock); } @@ -1053,9 +1310,8 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn) static inline int iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct socket *sk = tcp_conn->sock; - int offset = buf->sg.offset + buf->sent, res; + struct socket *sk = conn->sock; + int offset = buf->sg.offset + buf->sent; /* * if we got use_sg=0 or are sending something we kmallocd @@ -1066,22 +1322,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) * slab case. */ if (buf->use_sendmsg) - res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags); - else - res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags); - - if (res >= 0) { - conn->txdata_octets += res; - buf->sent += res; - return res; - } - - tcp_conn->sendpage_failures_cnt++; - if (res == -EAGAIN) - res = -ENOBUFS; + return sock_no_sendpage(sk, buf->sg.page, offset, size, flags); else - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - return res; + return conn->sendpage(sk, buf->sg.page, offset, size, flags); } /** @@ -1107,10 +1350,16 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) res = iscsi_send(conn, buf, size, flags); debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; if (size != res) return -EAGAIN; return 0; - } + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return res; } @@ -1143,46 +1392,47 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", size, buf->sent, *count, *sent, res); if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; *count -= res; *sent += res; if (size != res) return -EAGAIN; return 0; - } + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return res; } static inline void -iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn, - struct iscsi_cmd_task *ctask) +iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - BUG_ON(!tcp_conn->data_tx_tfm); - crypto_digest_init(tcp_conn->data_tx_tfm); - tcp_ctask->digest_count = 4; + BUG_ON(!conn->data_tx_tfm); + crypto_digest_init(conn->data_tx_tfm); + ctask->digest_count = 4; } static int iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_buf *buf, uint32_t *digest, int final) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; int rc = 0; int sent = 0; if (final) - crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest); + crypto_digest_final(conn->data_tx_tfm, (u8*)digest); - iscsi_buf_init_iov(buf, (char*)digest, 4); - rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent); + iscsi_buf_init_virt(buf, (char*)digest, 4); + rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent); if (rc) { - tcp_ctask->datadigest = *digest; - tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; + ctask->datadigest = *digest; + ctask->xmstate |= XMSTATE_DATA_DIGEST; } else - tcp_ctask->digest_count = 4; + ctask->digest_count = 4; return rc; } @@ -1203,19 +1453,21 @@ static void iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_r2t_info *r2t, int left) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_data *hdr; + struct iscsi_data_task *dtask; struct scsi_cmnd *sc = ctask->sc; int new_offset; - hdr = &r2t->dtask.hdr; + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; memset(hdr, 0, sizeof(struct iscsi_data)); hdr->ttt = r2t->ttt; hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; hdr->exp_statsn = r2t->exp_statsn; new_offset = r2t->data_offset + r2t->sent; hdr->offset = cpu_to_be32(new_offset); @@ -1229,98 +1481,181 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } conn->dataout_pdus_cnt++; - iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + r2t->dtask = dtask; + if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { - BUG_ON(tcp_ctask->bad_sg == r2t->sg); + BUG_ON(ctask->bad_sg == r2t->sg); iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); r2t->sg += 1; } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, + iscsi_buf_init_iov(&ctask->sendbuf, (char*)sc->request_buffer + new_offset, r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); } static void iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_data *hdr; struct iscsi_data_task *dtask; - dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; - iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr, - tcp_ctask->r2t_data_count); - iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; + memset(hdr, 0, sizeof(struct iscsi_data)); + hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + hdr->datasn = cpu_to_be32(ctask->unsol_datasn); + ctask->unsol_datasn++; + hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; + hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); + hdr->offset = cpu_to_be32(ctask->total_length - + ctask->r2t_data_count - + ctask->unsol_count); + if (ctask->unsol_count > conn->max_xmit_dlength) { + hton24(hdr->dlength, conn->max_xmit_dlength); + ctask->data_count = conn->max_xmit_dlength; + hdr->flags = 0; + } else { + hton24(hdr->dlength, ctask->unsol_count); + ctask->data_count = ctask->unsol_count; + hdr->flags = ISCSI_FLAG_CMD_FINAL; + } + + iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + + list_add(&dtask->item, &ctask->dataqueue); + + ctask->dtask = dtask; } /** - * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands + * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands * @conn: iscsi connection * @ctask: scsi command task * @sc: scsi command **/ static void -iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) +iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct scsi_cmnd *sc) { - struct scsi_cmnd *sc = ctask->sc; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_session *session = conn->session; - BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); + BUG_ON(__kfifo_len(ctask->r2tqueue)); - tcp_ctask->sent = 0; - tcp_ctask->sg_count = 0; + ctask->sc = sc; + ctask->conn = conn; + ctask->hdr.opcode = ISCSI_OP_SCSI_CMD; + ctask->hdr.flags = ISCSI_ATTR_SIMPLE; + int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun); + ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen); + ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; + ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn); + memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len); + memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); + + ctask->mtask = NULL; + ctask->sent = 0; + ctask->sg_count = 0; + + ctask->total_length = sc->request_bufflen; if (sc->sc_data_direction == DMA_TO_DEVICE) { - tcp_ctask->xmstate = XMSTATE_W_HDR; - tcp_ctask->exp_r2tsn = 0; + ctask->exp_r2tsn = 0; + ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE; BUG_ON(ctask->total_length == 0); - if (sc->use_sg) { struct scatterlist *sg = sc->request_buffer; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &sg[tcp_ctask->sg_count++]); - tcp_ctask->sg = sg; - tcp_ctask->bad_sg = sg + sc->use_sg; - } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, - sc->request_buffer, - sc->request_bufflen); - - if (ctask->imm_count) - tcp_ctask->xmstate |= XMSTATE_IMM_DATA; + iscsi_buf_init_sg(&ctask->sendbuf, + &sg[ctask->sg_count++]); + ctask->sg = sg; + ctask->bad_sg = sg + sc->use_sg; + } else { + iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer, + sc->request_bufflen); + } - tcp_ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1); - if (tcp_ctask->pad_count) { - tcp_ctask->pad_count = ISCSI_PAD_LEN - - tcp_ctask->pad_count; + /* + * Write counters: + * + * imm_count bytes to be sent right after + * SCSI PDU Header + * + * unsol_count bytes(as Data-Out) to be sent + * without R2T ack right after + * immediate data + * + * r2t_data_count bytes to be sent via R2T ack's + * + * pad_count bytes to be sent as zero-padding + */ + ctask->imm_count = 0; + ctask->unsol_count = 0; + ctask->unsol_datasn = 0; + ctask->xmstate = XMSTATE_W_HDR; + /* calculate write padding */ + ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1); + if (ctask->pad_count) { + ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count; debug_scsi("write padding %d bytes\n", - tcp_ctask->pad_count); - tcp_ctask->xmstate |= XMSTATE_W_PAD; + ctask->pad_count); + ctask->xmstate |= XMSTATE_W_PAD; } + if (session->imm_data_en) { + if (ctask->total_length >= session->first_burst) + ctask->imm_count = min(session->first_burst, + conn->max_xmit_dlength); + else + ctask->imm_count = min(ctask->total_length, + conn->max_xmit_dlength); + hton24(ctask->hdr.dlength, ctask->imm_count); + ctask->xmstate |= XMSTATE_IMM_DATA; + } else + zero_data(ctask->hdr.dlength); + + if (!session->initial_r2t_en) + ctask->unsol_count = min(session->first_burst, + ctask->total_length) - ctask->imm_count; + if (!ctask->unsol_count) + /* No unsolicit Data-Out's */ + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + else + ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; - if (ctask->unsol_count) - tcp_ctask->xmstate |= XMSTATE_UNS_HDR | - XMSTATE_UNS_INIT; - tcp_ctask->r2t_data_count = ctask->total_length - + ctask->r2t_data_count = ctask->total_length - ctask->imm_count - ctask->unsol_count; debug_scsi("cmd [itt %x total %d imm %d imm_data %d " "r2t_data %d]\n", ctask->itt, ctask->total_length, ctask->imm_count, - ctask->unsol_count, tcp_ctask->r2t_data_count); - } else - tcp_ctask->xmstate = XMSTATE_R_HDR; + ctask->unsol_count, ctask->r2t_data_count); + } else { + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + if (sc->sc_data_direction == DMA_FROM_DEVICE) + ctask->hdr.flags |= ISCSI_FLAG_CMD_READ; + ctask->datasn = 0; + ctask->xmstate = XMSTATE_R_HDR; + zero_data(ctask->hdr.dlength); + } - iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr, + iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, sizeof(struct iscsi_hdr)); + conn->scsicmd_pdus_cnt++; } /** - * iscsi_tcp_mtask_xmit - xmit management(immediate) task + * iscsi_mtask_xmit - xmit management(immediate) task * @conn: iscsi connection * @mtask: task management task * @@ -1334,167 +1669,132 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress **/ static int -iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) +iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) { - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; - int rc; debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", - conn->id, tcp_mtask->xmstate, mtask->itt); + conn->id, mtask->xmstate, mtask->itt); - if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) { - tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR; + if (mtask->xmstate & XMSTATE_IMM_HDR) { + mtask->xmstate &= ~XMSTATE_IMM_HDR; if (mtask->data_count) - tcp_mtask->xmstate |= XMSTATE_IMM_DATA; + mtask->xmstate |= XMSTATE_IMM_DATA; if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && - conn->stop_stage != STOP_CONN_RECOVER && + conn->stop_stage != STOP_CONN_RECOVER && conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_mtask->headbuf, - (u8*)tcp_mtask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf, - mtask->data_count); - if (rc) { - tcp_mtask->xmstate |= XMSTATE_IMM_HDR; + iscsi_hdr_digest(conn, &mtask->headbuf, + (u8*)mtask->hdrext); + if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) { + mtask->xmstate |= XMSTATE_IMM_HDR; if (mtask->data_count) - tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; - return rc; + mtask->xmstate &= ~XMSTATE_IMM_DATA; + return -EAGAIN; } } - if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) { + if (mtask->xmstate & XMSTATE_IMM_DATA) { BUG_ON(!mtask->data_count); - tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; + mtask->xmstate &= ~XMSTATE_IMM_DATA; /* FIXME: implement. * Virtual buffer could be spreaded across multiple pages... */ do { - int rc; - - rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf, - &mtask->data_count, &tcp_mtask->sent); - if (rc) { - tcp_mtask->xmstate |= XMSTATE_IMM_DATA; - return rc; + if (iscsi_sendpage(conn, &mtask->sendbuf, + &mtask->data_count, &mtask->sent)) { + mtask->xmstate |= XMSTATE_IMM_DATA; + return -EAGAIN; } } while (mtask->data_count); } - BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE); - if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { - struct iscsi_session *session = conn->session; - - spin_lock_bh(&session->lock); - list_del(&conn->mtask->running); - __kfifo_put(session->mgmtpool.queue, (void*)&conn->mtask, - sizeof(void*)); - spin_unlock_bh(&session->lock); - } + BUG_ON(mtask->xmstate != XMSTATE_IDLE); return 0; } static inline int -handle_xmstate_r_hdr(struct iscsi_conn *conn, - struct iscsi_tcp_cmd_task *tcp_ctask) +handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_R_HDR; + ctask->xmstate &= ~XMSTATE_R_HDR; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, - (u8*)tcp_ctask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0); - if (!rc) { - BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE); + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); + if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { + BUG_ON(ctask->xmstate != XMSTATE_IDLE); return 0; /* wait for Data-In */ } - tcp_ctask->xmstate |= XMSTATE_R_HDR; - return rc; + ctask->xmstate |= XMSTATE_R_HDR; + return -EAGAIN; } static inline int -handle_xmstate_w_hdr(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) +handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_W_HDR; + ctask->xmstate &= ~XMSTATE_W_HDR; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, - (u8*)tcp_ctask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); - if (rc) - tcp_ctask->xmstate |= XMSTATE_W_HDR; - return rc; + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { + ctask->xmstate |= XMSTATE_W_HDR; + return -EAGAIN; + } + return 0; } static inline int handle_xmstate_data_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; - debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->datadigest, 0); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; + ctask->xmstate &= ~XMSTATE_DATA_DIGEST; + debug_tcp("resent data digest 0x%x\n", ctask->datadigest); + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->datadigest, 0)) { + ctask->xmstate |= XMSTATE_DATA_DIGEST; debug_tcp("resent data digest 0x%x fail!\n", - tcp_ctask->datadigest); + ctask->datadigest); + return -EAGAIN; } - - return rc; + return 0; } static inline int handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc; - BUG_ON(!ctask->imm_count); - tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; + ctask->xmstate &= ~XMSTATE_IMM_DATA; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); - tcp_ctask->immdigest = 0; + iscsi_data_digest_init(conn, ctask); + ctask->immdigest = 0; } for (;;) { - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, - &ctask->imm_count, &tcp_ctask->sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_IMM_DATA; + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count, + &ctask->sent)) { + ctask->xmstate |= XMSTATE_IMM_DATA; if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, - (u8*)&tcp_ctask->immdigest); + crypto_digest_final(conn->data_tx_tfm, + (u8*)&ctask->immdigest); debug_tcp("tx imm sendpage fail 0x%x\n", - tcp_ctask->datadigest); + ctask->datadigest); } - return rc; + return -EAGAIN; } if (conn->datadgst_en) - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + crypto_digest_update(conn->data_tx_tfm, + &ctask->sendbuf.sg, 1); if (!ctask->imm_count) break; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &tcp_ctask->sg[tcp_ctask->sg_count++]); + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); } - if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->immdigest, 1); - if (rc) { + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { debug_tcp("sending imm digest 0x%x fail!\n", - tcp_ctask->immdigest); - return rc; + ctask->immdigest); + return -EAGAIN; } - debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); + debug_tcp("sending imm digest 0x%x\n", ctask->immdigest); } return 0; @@ -1503,81 +1803,74 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) static inline int handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_data_task *dtask; - int rc; - tcp_ctask->xmstate |= XMSTATE_UNS_DATA; - if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { + ctask->xmstate |= XMSTATE_UNS_DATA; + if (ctask->xmstate & XMSTATE_UNS_INIT) { iscsi_unsolicit_data_init(conn, ctask); - dtask = tcp_ctask->dtask; + BUG_ON(!ctask->dtask); + dtask = ctask->dtask; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)dtask->hdrext); - tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; + ctask->xmstate &= ~XMSTATE_UNS_INIT; } - - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); - if (rc) { - tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; - tcp_ctask->xmstate |= XMSTATE_UNS_HDR; - return rc; + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) { + ctask->xmstate &= ~XMSTATE_UNS_DATA; + ctask->xmstate |= XMSTATE_UNS_HDR; + return -EAGAIN; } debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", - ctask->itt, ctask->unsol_count, tcp_ctask->sent); + ctask->itt, ctask->unsol_count, ctask->sent); return 0; } static inline int handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_data_task *dtask = tcp_ctask->dtask; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc; + struct iscsi_data_task *dtask = ctask->dtask; BUG_ON(!ctask->data_count); - tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; + ctask->xmstate &= ~XMSTATE_UNS_DATA; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); + iscsi_data_digest_init(conn, ctask); dtask->digest = 0; } for (;;) { - int start = tcp_ctask->sent; + int start = ctask->sent; - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, - &ctask->data_count, &tcp_ctask->sent); - if (rc) { - ctask->unsol_count -= tcp_ctask->sent - start; - tcp_ctask->xmstate |= XMSTATE_UNS_DATA; + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count, + &ctask->sent)) { + ctask->unsol_count -= ctask->sent - start; + ctask->xmstate |= XMSTATE_UNS_DATA; /* will continue with this ctask later.. */ if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, + crypto_digest_final(conn->data_tx_tfm, (u8 *)&dtask->digest); debug_tcp("tx uns data fail 0x%x\n", dtask->digest); } - return rc; + return -EAGAIN; } - BUG_ON(tcp_ctask->sent > ctask->total_length); - ctask->unsol_count -= tcp_ctask->sent - start; + BUG_ON(ctask->sent > ctask->total_length); + ctask->unsol_count -= ctask->sent - start; /* * XXX:we may run here with un-initial sendbuf. * so pass it */ - if (conn->datadgst_en && tcp_ctask->sent - start > 0) - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + if (conn->datadgst_en && ctask->sent - start > 0) + crypto_digest_update(conn->data_tx_tfm, + &ctask->sendbuf.sg, 1); if (!ctask->data_count) break; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &tcp_ctask->sg[tcp_ctask->sg_count++]); + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); } BUG_ON(ctask->unsol_count < 0); @@ -1587,29 +1880,27 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) */ if (ctask->unsol_count) { if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send uns digest 0x%x fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("sending uns digest 0x%x, more uns\n", dtask->digest); } - tcp_ctask->xmstate |= XMSTATE_UNS_INIT; + ctask->xmstate |= XMSTATE_UNS_INIT; return 1; } - if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { - rc = iscsi_digest_final_send(conn, ctask, + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send last uns digest 0x%x fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("sending uns digest 0x%x\n",dtask->digest); } @@ -1621,17 +1912,15 @@ static inline int handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_r2t_info *r2t = tcp_ctask->r2t; - struct iscsi_data_task *dtask = &r2t->dtask; - int left, rc; + struct iscsi_r2t_info *r2t = ctask->r2t; + struct iscsi_data_task *dtask = r2t->dtask; + int left; - tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; - tcp_ctask->dtask = dtask; + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->dtask = dtask; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); + iscsi_data_digest_init(conn, ctask); dtask->digest = 0; } solicit_again: @@ -1641,27 +1930,25 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (!r2t->data_count) goto data_out_done; - rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; + if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) { + ctask->xmstate |= XMSTATE_SOL_DATA; /* will continue with this ctask later.. */ if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, + crypto_digest_final(conn->data_tx_tfm, (u8 *)&dtask->digest); debug_tcp("r2t data send fail 0x%x\n", dtask->digest); } - return rc; + return -EAGAIN; } BUG_ON(r2t->data_count < 0); if (conn->datadgst_en) - crypto_digest_update(tcp_conn->data_tx_tfm, &r2t->sendbuf.sg, - 1); + crypto_digest_update(conn->data_tx_tfm, &r2t->sendbuf.sg, 1); if (r2t->data_count) { BUG_ON(ctask->sc->use_sg == 0); if (!iscsi_buf_left(&r2t->sendbuf)) { - BUG_ON(tcp_ctask->bad_sg == r2t->sg); + BUG_ON(ctask->bad_sg == r2t->sg); iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); r2t->sg += 1; } @@ -1677,20 +1964,19 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) left = r2t->data_length - r2t->sent; if (left) { if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send r2t data digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("r2t data send digest 0x%x\n", dtask->digest); } iscsi_solicit_data_cont(conn, ctask, r2t, left); - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; return 1; } @@ -1698,27 +1984,26 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) * Done with this R2T. Check if there are more * outstanding R2Ts ready to be processed. */ - BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0); + BUG_ON(ctask->r2t_data_count - r2t->data_length < 0); if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, + &dtask->digest, 1)) { debug_tcp("send last r2t data digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); } - tcp_ctask->r2t_data_count -= r2t->data_length; - tcp_ctask->r2t = NULL; + ctask->r2t_data_count -= r2t->data_length; + ctask->r2t = NULL; spin_lock_bh(&session->lock); - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); spin_unlock_bh(&session->lock); - if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { - tcp_ctask->r2t = r2t; - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; + if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { + ctask->r2t = r2t; + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; return 1; } @@ -1728,44 +2013,36 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) static inline int handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_data_task *dtask = tcp_ctask->dtask; - int sent, rc; - - tcp_ctask->xmstate &= ~XMSTATE_W_PAD; - iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, - tcp_ctask->pad_count); - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, - &sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_W_PAD; - return rc; + struct iscsi_data_task *dtask = ctask->dtask; + int sent; + + ctask->xmstate &= ~XMSTATE_W_PAD; + iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad, + ctask->pad_count); + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) { + ctask->xmstate |= XMSTATE_W_PAD; + return -EAGAIN; } if (conn->datadgst_en) { - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1); /* imm data? */ if (!dtask) { - rc = iscsi_digest_final_send(conn, ctask, - &tcp_ctask->immbuf, - &tcp_ctask->immdigest, 1); - if (rc) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { debug_tcp("send padding digest 0x%x" - "fail!\n", tcp_ctask->immdigest); - return rc; + "fail!\n", ctask->immdigest); + return -EAGAIN; } debug_tcp("done with padding, digest 0x%x\n", - tcp_ctask->datadigest); + ctask->datadigest); } else { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send padding digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("done with padding, digest 0x%x\n", dtask->digest); @@ -1776,13 +2053,12 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) } static int -iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; int rc = 0; debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n", - conn->id, tcp_ctask->xmstate, ctask->itt); + conn->id, ctask->xmstate, ctask->itt); /* * serialize with TMF AbortTask @@ -1790,38 +2066,40 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (ctask->mtask) return rc; - if (tcp_ctask->xmstate & XMSTATE_R_HDR) - return handle_xmstate_r_hdr(conn, tcp_ctask); + if (ctask->xmstate & XMSTATE_R_HDR) { + rc = handle_xmstate_r_hdr(conn, ctask); + return rc; + } - if (tcp_ctask->xmstate & XMSTATE_W_HDR) { + if (ctask->xmstate & XMSTATE_W_HDR) { rc = handle_xmstate_w_hdr(conn, ctask); if (rc) return rc; } /* XXX: for data digest xmit recover */ - if (tcp_ctask->xmstate & XMSTATE_DATA_DIGEST) { + if (ctask->xmstate & XMSTATE_DATA_DIGEST) { rc = handle_xmstate_data_digest(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { + if (ctask->xmstate & XMSTATE_IMM_DATA) { rc = handle_xmstate_imm_data(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { + if (ctask->xmstate & XMSTATE_UNS_HDR) { BUG_ON(!ctask->unsol_count); - tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR; + ctask->xmstate &= ~XMSTATE_UNS_HDR; unsolicit_head_again: rc = handle_xmstate_uns_hdr(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) { + if (ctask->xmstate & XMSTATE_UNS_DATA) { rc = handle_xmstate_uns_data(conn, ctask); if (rc == 1) goto unsolicit_head_again; @@ -1830,24 +2108,23 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) goto done; } - if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { + if (ctask->xmstate & XMSTATE_SOL_HDR) { struct iscsi_r2t_info *r2t; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - if (!tcp_ctask->r2t) - __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, + ctask->xmstate &= ~XMSTATE_SOL_HDR; + ctask->xmstate |= XMSTATE_SOL_DATA; + if (!ctask->r2t) + __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t, sizeof(void*)); solicit_head_again: - r2t = tcp_ctask->r2t; + r2t = ctask->r2t; if (conn->hdrdgst_en) iscsi_hdr_digest(conn, &r2t->headbuf, - (u8*)r2t->dtask.hdrext); - rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count); - if (rc) { - tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; - tcp_ctask->xmstate |= XMSTATE_SOL_HDR; - return rc; + (u8*)r2t->dtask->hdrext); + if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->xmstate |= XMSTATE_SOL_HDR; + return -EAGAIN; } debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n", @@ -1855,7 +2132,7 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) r2t->sent); } - if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) { + if (ctask->xmstate & XMSTATE_SOL_DATA) { rc = handle_xmstate_sol_data(conn, ctask); if (rc == 1) goto solicit_head_again; @@ -1868,199 +2145,1022 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) * Last thing to check is whether we need to send write * padding. Note that we check for xmstate equality, not just the bit. */ - if (tcp_ctask->xmstate == XMSTATE_W_PAD) + if (ctask->xmstate == XMSTATE_W_PAD) rc = handle_xmstate_w_pad(conn, ctask); return rc; } +/** + * iscsi_data_xmit - xmit any command into the scheduled connection + * @conn: iscsi connection + * + * Notes: + * The function can return -EAGAIN in which case the caller must + * re-schedule it again later or recover. '0' return code means + * successful xmit. + **/ +static int +iscsi_data_xmit(struct iscsi_conn *conn) +{ + if (unlikely(conn->suspend_tx)) { + debug_tcp("conn %d Tx suspended!\n", conn->id); + return 0; + } + + /* + * Transmit in the following order: + * + * 1) un-finished xmit (ctask or mtask) + * 2) immediate control PDUs + * 3) write data + * 4) SCSI commands + * 5) non-immediate control PDUs + * + * No need to lock around __kfifo_get as long as + * there's one producer and one consumer. + */ + + BUG_ON(conn->ctask && conn->mtask); + + if (conn->ctask) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + /* done with this in-progress ctask */ + conn->ctask = NULL; + } + if (conn->mtask) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + /* done with this in-progress mtask */ + conn->mtask = NULL; + } + + /* process immediate first */ + if (unlikely(__kfifo_len(conn->immqueue))) { + struct iscsi_session *session = conn->session; + while (__kfifo_get(conn->immqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + /* process write queue */ + while (__kfifo_get(conn->writequeue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + + /* process command queue */ + while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + /* done with this ctask */ + conn->ctask = NULL; + + /* process the rest control plane PDUs, if any */ + if (unlikely(__kfifo_len(conn->mgmtqueue))) { + struct iscsi_session *session = conn->session; + + while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + return 0; + +again: + if (unlikely(conn->suspend_tx)) + return 0; + + return -EAGAIN; +} + +static void +iscsi_xmitworker(void *data) +{ + struct iscsi_conn *conn = data; + + /* + * serialize Xmit worker on a per-connection basis. + */ + mutex_lock(&conn->xmitmutex); + if (iscsi_data_xmit(conn)) + scsi_queue_work(conn->session->host, &conn->xmitwork); + mutex_unlock(&conn->xmitmutex); +} + +#define FAILURE_BAD_HOST 1 +#define FAILURE_SESSION_FAILED 2 +#define FAILURE_SESSION_FREED 3 +#define FAILURE_WINDOW_CLOSED 4 +#define FAILURE_SESSION_TERMINATE 5 + +static int +iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) +{ + struct Scsi_Host *host; + int reason = 0; + struct iscsi_session *session; + struct iscsi_conn *conn = NULL; + struct iscsi_cmd_task *ctask = NULL; + + sc->scsi_done = done; + sc->result = 0; + + host = sc->device->host; + session = iscsi_hostdata(host->hostdata); + BUG_ON(host != session->host); + + spin_lock(&session->lock); + + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_FAILED) { + reason = FAILURE_SESSION_FAILED; + goto reject; + } else if (session->state == ISCSI_STATE_TERMINATE) { + reason = FAILURE_SESSION_TERMINATE; + goto fault; + } + reason = FAILURE_SESSION_FREED; + goto fault; + } + + /* + * Check for iSCSI window and take care of CmdSN wrap-around + */ + if ((int)(session->max_cmdsn - session->cmdsn) < 0) { + reason = FAILURE_WINDOW_CLOSED; + goto reject; + } + + conn = session->leadconn; + + __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + BUG_ON(ctask->sc); + + sc->SCp.phase = session->age; + sc->SCp.ptr = (char*)ctask; + iscsi_cmd_init(conn, ctask, sc); + + __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); + debug_scsi( + "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", + sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", + conn->id, (long)sc, ctask->itt, sc->request_bufflen, + session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); + spin_unlock(&session->lock); + + scsi_queue_work(host, &conn->xmitwork); + return 0; + +reject: + spin_unlock(&session->lock); + debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); + return SCSI_MLQUEUE_HOST_BUSY; + +fault: + spin_unlock(&session->lock); + printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n", + sc->cmnd[0], reason); + sc->sense_buffer[0] = 0x70; + sc->sense_buffer[2] = NOT_READY; + sc->sense_buffer[7] = 0x6; + sc->sense_buffer[12] = 0x08; + sc->sense_buffer[13] = 0x00; + sc->result = (DID_NO_CONNECT << 16); + sc->resid = sc->request_bufflen; + sc->scsi_done(sc); + return 0; +} + +static int +iscsi_change_queue_depth(struct scsi_device *sdev, int depth) +{ + if (depth > ISCSI_MAX_CMD_PER_LUN) + depth = ISCSI_MAX_CMD_PER_LUN; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + return sdev->queue_depth; +} + +static int +iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) +{ + int i; + + *items = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (*items == NULL) + return -ENOMEM; + + q->max = max; + q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (q->pool == NULL) { + kfree(*items); + return -ENOMEM; + } + + q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), + GFP_KERNEL, NULL); + if (q->queue == ERR_PTR(-ENOMEM)) { + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + + for (i = 0; i < max; i++) { + q->pool[i] = kmalloc(item_size, GFP_KERNEL); + if (q->pool[i] == NULL) { + int j; + + for (j = 0; j < i; j++) + kfree(q->pool[j]); + + kfifo_free(q->queue); + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + memset(q->pool[i], 0, item_size); + (*items)[i] = q->pool[i]; + __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); + } + return 0; +} + +static void +iscsi_pool_free(struct iscsi_queue *q, void **items) +{ + int i; + + for (i = 0; i < q->max; i++) + kfree(items[i]); + kfree(q->pool); + kfree(items); +} + static struct iscsi_cls_conn * -iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) +iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); struct iscsi_conn *conn; struct iscsi_cls_conn *cls_conn; - struct iscsi_tcp_conn *tcp_conn; - cls_conn = iscsi_conn_setup(cls_session, conn_idx); + cls_conn = iscsi_create_conn(cls_session, conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; - /* - * due to strange issues with iser these are not set - * in iscsi_conn_setup - */ - conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + memset(conn, 0, sizeof(*conn)); - tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL); - if (!tcp_conn) - goto tcp_conn_alloc_fail; + conn->cls_conn = cls_conn; + conn->c_stage = ISCSI_CONN_INITIAL_STAGE; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->id = conn_idx; + conn->exp_statsn = 0; + conn->tmabort_state = TMABORT_INITIAL; - conn->dd_data = tcp_conn; - tcp_conn->iscsi_conn = conn; - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; /* initial operational parameters */ - tcp_conn->hdr_size = sizeof(struct iscsi_hdr); - tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + conn->hdr_size = sizeof(struct iscsi_hdr); + conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + + /* initialize general xmit PDU commands queue */ + conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->xmitqueue == ERR_PTR(-ENOMEM)) + goto xmitqueue_alloc_fail; + + /* initialize write response PDU commands queue */ + conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->writequeue == ERR_PTR(-ENOMEM)) + goto writequeue_alloc_fail; + + /* initialize general immediate & non-immediate PDU commands queue */ + conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->immqueue == ERR_PTR(-ENOMEM)) + goto immqueue_alloc_fail; + + conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) + goto mgmtqueue_alloc_fail; + + INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); + + /* allocate login_mtask used for the login/text sequences */ + spin_lock_bh(&session->lock); + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&conn->login_mtask, + sizeof(void*))) { + spin_unlock_bh(&session->lock); + goto login_mtask_alloc_fail; + } + spin_unlock_bh(&session->lock); /* allocate initial PDU receive place holder */ - if (tcp_conn->data_size <= PAGE_SIZE) - tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL); + if (conn->data_size <= PAGE_SIZE) + conn->data = kmalloc(conn->data_size, GFP_KERNEL); else - tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL, - get_order(tcp_conn->data_size)); - if (!tcp_conn->data) + conn->data = (void*)__get_free_pages(GFP_KERNEL, + get_order(conn->data_size)); + if (!conn->data) goto max_recv_dlenght_alloc_fail; + init_timer(&conn->tmabort_timer); + mutex_init(&conn->xmitmutex); + init_waitqueue_head(&conn->ehwait); + return cls_conn; max_recv_dlenght_alloc_fail: - kfree(tcp_conn); -tcp_conn_alloc_fail: - iscsi_conn_teardown(cls_conn); + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); +login_mtask_alloc_fail: + kfifo_free(conn->mgmtqueue); +mgmtqueue_alloc_fail: + kfifo_free(conn->immqueue); +immqueue_alloc_fail: + kfifo_free(conn->writequeue); +writequeue_alloc_fail: + kfifo_free(conn->xmitqueue); +xmitqueue_alloc_fail: + iscsi_destroy_conn(cls_conn); return NULL; } static void -iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) +iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int digest = 0; + struct iscsi_session *session = conn->session; + unsigned long flags; + + mutex_lock(&conn->xmitmutex); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) { + struct sock *sk = conn->sock->sk; + + /* + * conn_start() has never been called! + * need to cleanup the socket. + */ + write_lock_bh(&sk->sk_callback_lock); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&sk->sk_callback_lock); + + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + sock_release(conn->sock); + conn->sock = NULL; + } - if (conn->hdrdgst_en || conn->datadgst_en) - digest = 1; + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; + if (session->leadconn == conn) { + /* + * leading connection? then give up on recovery. + */ + session->state = ISCSI_STATE_TERMINATE; + wake_up(&conn->ehwait); + } + spin_unlock_bh(&session->lock); + + mutex_unlock(&conn->xmitmutex); - iscsi_conn_teardown(cls_conn); + /* + * Block until all in-progress commands for this connection + * time out or fail. + */ + for (;;) { + spin_lock_irqsave(session->host->host_lock, flags); + if (!session->host->host_busy) { /* OK for ERL == 0 */ + spin_unlock_irqrestore(session->host->host_lock, flags); + break; + } + spin_unlock_irqrestore(session->host->host_lock, flags); + msleep_interruptible(500); + printk("conn_destroy(): host_busy %d host_failed %d\n", + session->host->host_busy, session->host->host_failed); + /* + * force eh_abort() to unblock + */ + wake_up(&conn->ehwait); + } - /* now free tcp_conn */ - if (digest) { - if (tcp_conn->tx_tfm) - crypto_free_tfm(tcp_conn->tx_tfm); - if (tcp_conn->rx_tfm) - crypto_free_tfm(tcp_conn->rx_tfm); - if (tcp_conn->data_tx_tfm) - crypto_free_tfm(tcp_conn->data_tx_tfm); - if (tcp_conn->data_rx_tfm) - crypto_free_tfm(tcp_conn->data_rx_tfm); + /* now free crypto */ + if (conn->hdrdgst_en || conn->datadgst_en) { + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); } /* free conn->data, size = MaxRecvDataSegmentLength */ - if (tcp_conn->data_size <= PAGE_SIZE) - kfree(tcp_conn->data); + if (conn->data_size <= PAGE_SIZE) + kfree(conn->data); else - free_pages((unsigned long)tcp_conn->data, - get_order(tcp_conn->data_size)); - kfree(tcp_conn); + free_pages((unsigned long)conn->data, + get_order(conn->data_size)); + + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + list_del(&conn->item); + if (list_empty(&session->connections)) + session->leadconn = NULL; + if (session->leadconn && session->leadconn == conn) + session->leadconn = container_of(session->connections.next, + struct iscsi_conn, item); + + if (session->leadconn == NULL) + /* none connections exits.. reset sequencing */ + session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; + spin_unlock_bh(&session->lock); + + kfifo_free(conn->xmitqueue); + kfifo_free(conn->writequeue); + kfifo_free(conn->immqueue); + kfifo_free(conn->mgmtqueue); + + iscsi_destroy_conn(cls_conn); } static int -iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, - struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, - int is_leading) +iscsi_conn_bind(struct iscsi_cls_session *cls_session, + struct iscsi_cls_conn *cls_conn, uint32_t transport_fd, + int is_leading) { - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; struct sock *sk; struct socket *sock; int err; /* lookup for existing socket */ - sock = sockfd_lookup((int)transport_eph, &err); + sock = sockfd_lookup(transport_fd, &err); if (!sock) { printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err); return -EEXIST; } - err = iscsi_conn_bind(cls_session, cls_conn, is_leading); - if (err) - return err; + /* lookup for existing connection */ + spin_lock_bh(&session->lock); + list_for_each_entry(tmp, &session->connections, item) { + if (tmp == conn) { + if (conn->c_stage != ISCSI_CONN_STOPPED || + conn->stop_stage == STOP_CONN_TERM) { + printk(KERN_ERR "iscsi_tcp: can't bind " + "non-stopped connection (%d:%d)\n", + conn->c_stage, conn->stop_stage); + spin_unlock_bh(&session->lock); + return -EIO; + } + break; + } + } + if (tmp != conn) { + /* bind new iSCSI connection to session */ + conn->session = session; + + list_add(&conn->item, &session->connections); + } + spin_unlock_bh(&session->lock); - /* bind iSCSI connection and socket */ - tcp_conn->sock = sock; + if (conn->stop_stage != STOP_CONN_SUSPEND) { + /* bind iSCSI connection and socket */ + conn->sock = sock; - /* setup Socket parameters */ - sk = sock->sk; - sk->sk_reuse = 1; - sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ - sk->sk_allocation = GFP_ATOMIC; + /* setup Socket parameters */ + sk = sock->sk; + sk->sk_reuse = 1; + sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ + sk->sk_allocation = GFP_ATOMIC; - /* FIXME: disable Nagle's algorithm */ + /* FIXME: disable Nagle's algorithm */ + + /* + * Intercept TCP callbacks for sendfile like receive + * processing. + */ + iscsi_conn_set_callbacks(conn); + + conn->sendpage = conn->sock->ops->sendpage; + + /* + * set receive state machine into initial state + */ + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + + if (is_leading) + session->leadconn = conn; /* - * Intercept TCP callbacks for sendfile like receive - * processing. - */ - conn->recv_lock = &sk->sk_callback_lock; - iscsi_conn_set_callbacks(conn); - tcp_conn->sendpage = tcp_conn->sock->ops->sendpage; - /* - * set receive state machine into initial state + * Unblock xmitworker(), Login Phase will pass through. */ - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); return 0; } -static void -iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +static int +iscsi_conn_start(struct iscsi_cls_conn *cls_conn) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_r2t_info *r2t; + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_session *session = conn->session; + struct sock *sk; - /* flush ctask's r2t queues */ - while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, - sizeof(void*)); + /* FF phase warming up... */ - __iscsi_ctask_cleanup(conn, ctask); + if (session == NULL) { + printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n"); + return -EPERM; + } + + sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_STARTED; + session->state = ISCSI_STATE_LOGGED_IN; + + switch(conn->stop_stage) { + case STOP_CONN_RECOVER: + /* + * unblock eh_abort() if it is blocked. re-try all + * commands after successful recovery + */ + session->conn_cnt++; + conn->stop_stage = 0; + conn->tmabort_state = TMABORT_INITIAL; + session->age++; + wake_up(&conn->ehwait); + break; + case STOP_CONN_TERM: + session->conn_cnt++; + conn->stop_stage = 0; + break; + case STOP_CONN_SUSPEND: + conn->stop_stage = 0; + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); + break; + default: + break; + } + spin_unlock_bh(&session->lock); + write_unlock_bh(&sk->sk_callback_lock); + + return 0; } static void -iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) +iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_session *session = conn->session; struct sock *sk; + unsigned long flags; - if (!tcp_conn->sock) - return; - - sk = tcp_conn->sock->sk; + BUG_ON(!conn->sock); + sk = conn->sock->sk; write_lock_bh(&sk->sk_callback_lock); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); + set_bit(SUSPEND_BIT, &conn->suspend_rx); write_unlock_bh(&sk->sk_callback_lock); + + mutex_lock(&conn->xmitmutex); + + spin_lock_irqsave(session->host->host_lock, flags); + spin_lock(&session->lock); + conn->stop_stage = flag; + conn->c_stage = ISCSI_CONN_STOPPED; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + + if (flag != STOP_CONN_SUSPEND) + session->conn_cnt--; + + if (session->conn_cnt == 0 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + + spin_unlock(&session->lock); + spin_unlock_irqrestore(session->host->host_lock, flags); + + if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) { + struct iscsi_cmd_task *ctask; + struct iscsi_mgmt_task *mtask; + + /* + * Socket must go now. + */ + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + + /* + * flush xmit queues. + */ + spin_lock_bh(&session->lock); + while (__kfifo_get(conn->writequeue, (void*)&ctask, + sizeof(void*)) || + __kfifo_get(conn->xmitqueue, (void*)&ctask, + sizeof(void*))) { + struct iscsi_r2t_info *r2t; + + /* + * flush ctask's r2t queues + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + + spin_unlock_bh(&session->lock); + local_bh_disable(); + iscsi_ctask_cleanup(conn, ctask); + local_bh_enable(); + spin_lock_bh(&session->lock); + } + conn->ctask = NULL; + while (__kfifo_get(conn->immqueue, (void*)&mtask, + sizeof(void*)) || + __kfifo_get(conn->mgmtqueue, (void*)&mtask, + sizeof(void*))) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + } + conn->mtask = NULL; + spin_unlock_bh(&session->lock); + + /* + * release socket only after we stopped data_xmit() + * activity and flushed all outstandings + */ + sock_release(conn->sock); + conn->sock = NULL; + + /* + * for connection level recovery we should not calculate + * header digest. conn->hdr_size used for optimization + * in hdr_extract() and will be re-negotiated at + * set_param() time. + */ + if (flag == STOP_CONN_RECOVER) { + conn->hdr_size = sizeof(struct iscsi_hdr); + conn->hdrdgst_en = 0; + conn->datadgst_en = 0; + } + } + mutex_unlock(&conn->xmitmutex); } -static void -iscsi_tcp_terminate_conn(struct iscsi_conn *conn) +static int +iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_session *session = conn->session; + struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; + struct iscsi_mgmt_task *mtask; - if (!tcp_conn->sock) - return; + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + return -EPERM; + } + if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || + hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + /* + * Login and Text are sent serially, in + * request-followed-by-response sequence. + * Same mtask can be used. Same ITT must be used. + * Note that login_mtask is preallocated at conn_create(). + */ + mtask = conn->login_mtask; + else { + BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); + BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); + + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*))) { + spin_unlock_bh(&session->lock); + return -ENOSPC; + } + } + + /* + * pre-format CmdSN and ExpStatSN for outgoing PDU. + */ + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + hdr->itt = mtask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + nop->cmdsn = cpu_to_be32(session->cmdsn); + if (conn->c_stage == ISCSI_CONN_STARTED && + !(hdr->opcode & ISCSI_OP_IMMEDIATE)) + session->cmdsn++; + } else + /* do not advance CmdSN */ + nop->cmdsn = cpu_to_be32(session->cmdsn); + + nop->exp_statsn = cpu_to_be32(conn->exp_statsn); + + memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr)); + + iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr, + sizeof(struct iscsi_hdr)); + + spin_unlock_bh(&session->lock); + + if (data_size) { + memcpy(mtask->data, data, data_size); + mtask->data_count = data_size; + } else + mtask->data_count = 0; + + mtask->xmstate = XMSTATE_IMM_HDR; + + if (mtask->data_count) { + iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data, + mtask->data_count); + } + + debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", + hdr->opcode, hdr->itt, data_size); - sock_hold(tcp_conn->sock->sk); - iscsi_conn_restore_callbacks(conn); - sock_put(tcp_conn->sock->sk); + /* + * since send_pdu() could be called at least from two contexts, + * we need to serialize __kfifo_put, so we don't have to take + * additional lock on fast data-path + */ + if (hdr->opcode & ISCSI_OP_IMMEDIATE) + __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*)); + else + __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); - sock_release(tcp_conn->sock); - tcp_conn->sock = NULL; - conn->recv_lock = NULL; + scsi_queue_work(session->host, &conn->xmitwork); + return 0; +} + +static int +iscsi_eh_host_reset(struct scsi_cmnd *sc) +{ + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + debug_scsi("failing host reset: session terminated " + "[CID %d age %d]", conn->id, session->age); + spin_unlock_bh(&session->lock); + return FAILED; + } + spin_unlock_bh(&session->lock); + + debug_scsi("failing connection CID %d due to SCSI host reset " + "[itt 0x%x age %d]", conn->id, ctask->itt, + session->age); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + return SUCCESS; } -/* called with host lock */ static void -iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, - char *data, uint32_t data_size) +iscsi_tmabort_timedout(unsigned long data) { - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; - iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, - sizeof(struct iscsi_hdr)); - tcp_mtask->xmstate = XMSTATE_IMM_HDR; + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&ctask->mtask, sizeof(void*)); + conn->tmabort_state = TMABORT_TIMEDOUT; + debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n", + (long)ctask->sc, ctask->itt); + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); +} - if (mtask->data_count) - iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, - mtask->data_count); +static int +iscsi_eh_abort(struct scsi_cmnd *sc) +{ + int rc; + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + conn->eh_abort_cnt++; + debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + + /* + * two cases for ERL=0 here: + * + * 1) connection-level failure; + * 2) recovery due protocol error; + */ + mutex_lock(&conn->xmitmutex); + spin_lock_bh(&session->lock); + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto failed; + } + spin_unlock_bh(&session->lock); + } else { + struct iscsi_tm *hdr = &conn->tmhdr; + + /* + * Still LOGGED_IN... + */ + + if (!ctask->sc || sc->SCp.phase != session->age) { + /* + * 1) ctask completed before time out. But session + * is still ok => Happy Retry. + * 2) session was re-open during time out of ctask. + */ + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + + /* + * ctask timed out but session is OK + * ERL=0 requires task mgmt abort to be issued on each + * failed command. requests must be serialized. + */ + memset(hdr, 0, sizeof(struct iscsi_tm)); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; + hdr->flags = ISCSI_TM_FUNC_ABORT_TASK; + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->rtt = ctask->hdr.itt; + hdr->refcmdsn = ctask->hdr.cmdsn; + + rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr, + NULL, 0); + if (rc) { + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + debug_scsi("abort sent failure [itt 0x%x]", ctask->itt); + } else { + struct iscsi_r2t_info *r2t; + + /* + * TMF abort vs. TMF response race logic + */ + spin_lock_bh(&session->lock); + ctask->mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[(hdr->itt & ITT_MASK) - + ISCSI_MGMT_ITT_OFFSET]; + /* + * have to flush r2tqueue to avoid r2t leaks + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) { + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + } + if (conn->tmabort_state == TMABORT_INITIAL) { + conn->tmfcmd_pdus_cnt++; + conn->tmabort_timer.expires = 3*HZ + jiffies; + conn->tmabort_timer.function = + iscsi_tmabort_timedout; + conn->tmabort_timer.data = (unsigned long)ctask; + add_timer(&conn->tmabort_timer); + debug_scsi("abort sent [itt 0x%x]", ctask->itt); + } else { + if (!ctask->sc || + conn->tmabort_state == TMABORT_SUCCESS) { + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + } + spin_unlock_bh(&session->lock); + } + } + mutex_unlock(&conn->xmitmutex); + + + /* + * block eh thread until: + * + * 1) abort response; + * 2) abort timeout; + * 3) session re-opened; + * 4) session terminated; + */ + for (;;) { + int p_state = session->state; + + rc = wait_event_interruptible(conn->ehwait, + (p_state == ISCSI_STATE_LOGGED_IN ? + (session->state == ISCSI_STATE_TERMINATE || + conn->tmabort_state != TMABORT_INITIAL) : + (session->state == ISCSI_STATE_TERMINATE || + session->state == ISCSI_STATE_LOGGED_IN))); + if (rc) { + /* shutdown.. */ + session->state = ISCSI_STATE_TERMINATE; + goto failed; + } + + if (signal_pending(current)) + flush_signals(current); + + if (session->state == ISCSI_STATE_TERMINATE) + goto failed; + + spin_lock_bh(&session->lock); + if (sc->SCp.phase == session->age && + (conn->tmabort_state == TMABORT_TIMEDOUT || + conn->tmabort_state == TMABORT_FAILED)) { + conn->tmabort_state = TMABORT_INITIAL; + if (!ctask->sc) { + /* + * ctask completed before tmf abort response or + * time out. + * But session is still ok => Happy Retry. + */ + spin_unlock_bh(&session->lock); + break; + } + spin_unlock_bh(&session->lock); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + continue; + } + spin_unlock_bh(&session->lock); + break; + } + +success: + debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = SUCCESS; + goto exit; + +failed: + debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = FAILED; + +exit: + del_timer_sync(&conn->tmabort_timer); + + mutex_lock(&conn->xmitmutex); + if (conn->sock) { + struct sock *sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + iscsi_ctask_cleanup(conn, ctask); + write_unlock_bh(&sk->sk_callback_lock); + } + mutex_unlock(&conn->xmitmutex); + return rc; } static int @@ -2074,7 +3174,6 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; /* * pre-allocated x4 as much r2ts to handle race when @@ -2083,32 +3182,42 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) */ /* R2T pool */ - if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, - (void***)&tcp_ctask->r2ts, - sizeof(struct iscsi_r2t_info))) { + if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4, + (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) { goto r2t_alloc_fail; } /* R2T xmit queue */ - tcp_ctask->r2tqueue = kfifo_alloc( + ctask->r2tqueue = kfifo_alloc( session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); - if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) { + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); goto r2t_alloc_fail; } + + /* + * number of + * Data-Out PDU's within R2T-sequence can be quite big; + * using mempool + */ + ctask->datapool = mempool_create_slab_pool(ISCSI_DTASK_DEFAULT_MAX, + taskcache); + if (ctask->datapool == NULL) { + kfifo_free(ctask->r2tqueue); + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); + goto r2t_alloc_fail; + } + INIT_LIST_HEAD(&ctask->dataqueue); } return 0; r2t_alloc_fail: for (i = 0; i < cmd_i; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); } return -ENOMEM; } @@ -2119,13 +3228,127 @@ iscsi_r2tpool_free(struct iscsi_session *session) int i; for (i = 0; i < session->cmds_max; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); + } +} + +static struct scsi_host_template iscsi_sht = { + .name = "iSCSI Initiator over TCP/IP, v." + ISCSI_VERSION_STR, + .queuecommand = iscsi_queuecommand, + .change_queue_depth = iscsi_change_queue_depth, + .can_queue = ISCSI_XMIT_CMDS_MAX - 1, + .sg_tablesize = ISCSI_SG_TABLESIZE, + .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, + .eh_abort_handler = iscsi_eh_abort, + .eh_host_reset_handler = iscsi_eh_host_reset, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "iscsi_tcp", + .this_id = -1, +}; + +static struct iscsi_transport iscsi_tcp_transport; + +static struct iscsi_cls_session * +iscsi_session_create(struct scsi_transport_template *scsit, + uint32_t initial_cmdsn, uint32_t *sid) +{ + struct Scsi_Host *shost; + struct iscsi_session *session; + int cmd_i; + + shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport); + if (!shost) + return NULL; + + session = iscsi_hostdata(shost->hostdata); + memset(session, 0, sizeof(struct iscsi_session)); + session->host = shost; + session->state = ISCSI_STATE_FREE; + session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; + session->cmds_max = ISCSI_XMIT_CMDS_MAX; + session->cmdsn = initial_cmdsn; + session->exp_cmdsn = initial_cmdsn + 1; + session->max_cmdsn = initial_cmdsn + 1; + session->max_r2t = 1; + *sid = shost->host_no; + + /* initialize SCSI PDU commands pool */ + if (iscsi_pool_init(&session->cmdpool, session->cmds_max, + (void***)&session->cmds, sizeof(struct iscsi_cmd_task))) + goto cmdpool_alloc_fail; + + /* pre-format cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) + session->cmds[cmd_i]->itt = cmd_i; + + spin_lock_init(&session->lock); + INIT_LIST_HEAD(&session->connections); + + /* initialize immediate command pool */ + if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, + (void***)&session->mgmt_cmds, sizeof(struct iscsi_mgmt_task))) + goto mgmtpool_alloc_fail; + + + /* pre-format immediate cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { + session->mgmt_cmds[cmd_i]->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; + session->mgmt_cmds[cmd_i]->data = kmalloc( + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); + if (!session->mgmt_cmds[cmd_i]->data) { + int j; + + for (j = 0; j < cmd_i; j++) + kfree(session->mgmt_cmds[j]->data); + goto immdata_alloc_fail; + } + } + + if (iscsi_r2tpool_alloc(session)) + goto r2tpool_alloc_fail; - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + return hostdata_session(shost->hostdata); + +r2tpool_alloc_fail: + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); +immdata_alloc_fail: + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); +mgmtpool_alloc_fail: + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); +cmdpool_alloc_fail: + iscsi_transport_destroy_session(shost); + return NULL; +} + +static void +iscsi_session_destroy(struct iscsi_cls_session *cls_session) +{ + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + int cmd_i; + struct iscsi_data_task *dtask, *n; + + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { + struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } } + + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); + + iscsi_r2tpool_free(session); + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); + + iscsi_transport_destroy_session(shost); } static int @@ -2134,14 +3357,23 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + + spin_lock_bh(&session->lock); + if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && + conn->stop_stage != STOP_CONN_RECOVER) { + printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n", + param); + spin_unlock_bh(&session->lock); + return 0; + } + spin_unlock_bh(&session->lock); switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: { - char *saveptr = tcp_conn->data; + char *saveptr = conn->data; gfp_t flags = GFP_KERNEL; - if (tcp_conn->data_size >= value) { + if (conn->data_size >= value) { conn->max_recv_dlength = value; break; } @@ -2152,21 +3384,21 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, spin_unlock_bh(&session->lock); if (value <= PAGE_SIZE) - tcp_conn->data = kmalloc(value, flags); + conn->data = kmalloc(value, flags); else - tcp_conn->data = (void*)__get_free_pages(flags, + conn->data = (void*)__get_free_pages(flags, get_order(value)); - if (tcp_conn->data == NULL) { - tcp_conn->data = saveptr; + if (conn->data == NULL) { + conn->data = saveptr; return -ENOMEM; } - if (tcp_conn->data_size <= PAGE_SIZE) + if (conn->data_size <= PAGE_SIZE) kfree(saveptr); else free_pages((unsigned long)saveptr, - get_order(tcp_conn->data_size)); + get_order(conn->data_size)); conn->max_recv_dlength = value; - tcp_conn->data_size = value; + conn->data_size = value; } break; case ISCSI_PARAM_MAX_XMIT_DLENGTH: @@ -2174,51 +3406,49 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, break; case ISCSI_PARAM_HDRDGST_EN: conn->hdrdgst_en = value; - tcp_conn->hdr_size = sizeof(struct iscsi_hdr); + conn->hdr_size = sizeof(struct iscsi_hdr); if (conn->hdrdgst_en) { - tcp_conn->hdr_size += sizeof(__u32); - if (!tcp_conn->tx_tfm) - tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", - 0); - if (!tcp_conn->tx_tfm) + conn->hdr_size += sizeof(__u32); + if (!conn->tx_tfm) + conn->tx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->tx_tfm) return -ENOMEM; - if (!tcp_conn->rx_tfm) - tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", - 0); - if (!tcp_conn->rx_tfm) { - crypto_free_tfm(tcp_conn->tx_tfm); + if (!conn->rx_tfm) + conn->rx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->rx_tfm) { + crypto_free_tfm(conn->tx_tfm); return -ENOMEM; } } else { - if (tcp_conn->tx_tfm) - crypto_free_tfm(tcp_conn->tx_tfm); - if (tcp_conn->rx_tfm) - crypto_free_tfm(tcp_conn->rx_tfm); + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); } break; case ISCSI_PARAM_DATADGST_EN: conn->datadgst_en = value; if (conn->datadgst_en) { - if (!tcp_conn->data_tx_tfm) - tcp_conn->data_tx_tfm = + if (!conn->data_tx_tfm) + conn->data_tx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->data_tx_tfm) + if (!conn->data_tx_tfm) return -ENOMEM; - if (!tcp_conn->data_rx_tfm) - tcp_conn->data_rx_tfm = + if (!conn->data_rx_tfm) + conn->data_rx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->data_rx_tfm) { - crypto_free_tfm(tcp_conn->data_tx_tfm); + if (!conn->data_rx_tfm) { + crypto_free_tfm(conn->data_tx_tfm); return -ENOMEM; } } else { - if (tcp_conn->data_tx_tfm) - crypto_free_tfm(tcp_conn->data_tx_tfm); - if (tcp_conn->data_rx_tfm) - crypto_free_tfm(tcp_conn->data_rx_tfm); + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); } - tcp_conn->sendpage = conn->datadgst_en ? - sock_no_sendpage : tcp_conn->sock->ops->sendpage; + conn->sendpage = conn->datadgst_en ? + sock_no_sendpage : conn->sock->ops->sendpage; break; case ISCSI_PARAM_INITIAL_R2T_EN: session->initial_r2t_en = value; @@ -2259,9 +3489,6 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, BUG_ON(value); session->ofmarker_en = value; break; - case ISCSI_PARAM_EXP_STATSN: - conn->exp_statsn = value; - break; default: break; } @@ -2308,7 +3535,7 @@ iscsi_session_get_param(struct iscsi_cls_session *cls_session, *value = session->ofmarker_en; break; default: - return -EINVAL; + return ISCSI_ERR_PARAM_NOT_FOUND; } return 0; @@ -2319,8 +3546,6 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, uint32_t *value) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct inet_sock *inet; switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: @@ -2335,70 +3560,17 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, case ISCSI_PARAM_DATADGST_EN: *value = conn->datadgst_en; break; - case ISCSI_PARAM_CONN_PORT: - mutex_lock(&conn->xmitmutex); - if (!tcp_conn->sock) { - mutex_unlock(&conn->xmitmutex); - return -EINVAL; - } - - inet = inet_sk(tcp_conn->sock->sk); - *value = be16_to_cpu(inet->dport); - mutex_unlock(&conn->xmitmutex); - case ISCSI_PARAM_EXP_STATSN: - *value = conn->exp_statsn; - break; default: - return -EINVAL; + return ISCSI_ERR_PARAM_NOT_FOUND; } return 0; } -static int -iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, - enum iscsi_param param, char *buf) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk; - struct inet_sock *inet; - struct ipv6_pinfo *np; - int len = 0; - - switch (param) { - case ISCSI_PARAM_CONN_ADDRESS: - mutex_lock(&conn->xmitmutex); - if (!tcp_conn->sock) { - mutex_unlock(&conn->xmitmutex); - return -EINVAL; - } - - sk = tcp_conn->sock->sk; - if (sk->sk_family == PF_INET) { - inet = inet_sk(sk); - len = sprintf(buf, "%u.%u.%u.%u\n", - NIPQUAD(inet->daddr)); - } else { - np = inet6_sk(sk); - len = sprintf(buf, - "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - NIP6(np->daddr)); - } - mutex_unlock(&conn->xmitmutex); - break; - default: - return -EINVAL; - } - - return len; -} - static void iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; stats->txdata_octets = conn->txdata_octets; stats->rxdata_octets = conn->rxdata_octets; @@ -2411,141 +3583,68 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; stats->custom_length = 3; strcpy(stats->custom[0].desc, "tx_sendpage_failures"); - stats->custom[0].value = tcp_conn->sendpage_failures_cnt; + stats->custom[0].value = conn->sendpage_failures_cnt; strcpy(stats->custom[1].desc, "rx_discontiguous_hdr"); - stats->custom[1].value = tcp_conn->discontiguous_hdr_cnt; + stats->custom[1].value = conn->discontiguous_hdr_cnt; strcpy(stats->custom[2].desc, "eh_abort_cnt"); stats->custom[2].value = conn->eh_abort_cnt; } -static struct iscsi_cls_session * -iscsi_tcp_session_create(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - uint32_t initial_cmdsn, uint32_t *hostno) +static int +iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) { - struct iscsi_cls_session *cls_session; - struct iscsi_session *session; - uint32_t hn; - int cmd_i; - - cls_session = iscsi_session_setup(iscsit, scsit, - sizeof(struct iscsi_tcp_cmd_task), - sizeof(struct iscsi_tcp_mgmt_task), - initial_cmdsn, &hn); - if (!cls_session) - return NULL; - *hostno = hn; - - session = class_to_transport_session(cls_session); - for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - ctask->hdr = &tcp_ctask->hdr; - } - - for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { - struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; - - mtask->hdr = &tcp_mtask->hdr; - } - - if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session))) - goto r2tpool_alloc_fail; - - return cls_session; + struct iscsi_conn *conn = cls_conn->dd_data; + int rc; -r2tpool_alloc_fail: - iscsi_session_teardown(cls_session); - return NULL; -} + mutex_lock(&conn->xmitmutex); + rc = iscsi_conn_send_generic(conn, hdr, data, data_size); + mutex_unlock(&conn->xmitmutex); -static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) -{ - iscsi_r2tpool_free(class_to_transport_session(cls_session)); - iscsi_session_teardown(cls_session); + return rc; } -static struct scsi_host_template iscsi_sht = { - .name = "iSCSI Initiator over TCP/IP, v" - ISCSI_TCP_VERSION, - .queuecommand = iscsi_queuecommand, - .change_queue_depth = iscsi_change_queue_depth, - .can_queue = ISCSI_XMIT_CMDS_MAX - 1, - .sg_tablesize = ISCSI_SG_TABLESIZE, - .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, - .eh_abort_handler = iscsi_eh_abort, - .eh_host_reset_handler = iscsi_eh_host_reset, - .use_clustering = DISABLE_CLUSTERING, - .proc_name = "iscsi_tcp", - .this_id = -1, -}; - static struct iscsi_transport iscsi_tcp_transport = { .owner = THIS_MODULE, .name = "tcp", .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST | CAP_DATADGST, - .param_mask = ISCSI_MAX_RECV_DLENGTH | - ISCSI_MAX_XMIT_DLENGTH | - ISCSI_HDRDGST_EN | - ISCSI_DATADGST_EN | - ISCSI_INITIAL_R2T_EN | - ISCSI_MAX_R2T | - ISCSI_IMM_DATA_EN | - ISCSI_FIRST_BURST | - ISCSI_MAX_BURST | - ISCSI_PDU_INORDER_EN | - ISCSI_DATASEQ_INORDER_EN | - ISCSI_ERL | - ISCSI_CONN_PORT | - ISCSI_CONN_ADDRESS | - ISCSI_EXP_STATSN, .host_template = &iscsi_sht, + .hostdata_size = sizeof(struct iscsi_session), .conndata_size = sizeof(struct iscsi_conn), .max_conn = 1, .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, - /* session management */ - .create_session = iscsi_tcp_session_create, - .destroy_session = iscsi_tcp_session_destroy, - /* connection management */ - .create_conn = iscsi_tcp_conn_create, - .bind_conn = iscsi_tcp_conn_bind, - .destroy_conn = iscsi_tcp_conn_destroy, + .create_session = iscsi_session_create, + .destroy_session = iscsi_session_destroy, + .create_conn = iscsi_conn_create, + .bind_conn = iscsi_conn_bind, + .destroy_conn = iscsi_conn_destroy, .set_param = iscsi_conn_set_param, .get_conn_param = iscsi_conn_get_param, - .get_conn_str_param = iscsi_conn_get_str_param, .get_session_param = iscsi_session_get_param, .start_conn = iscsi_conn_start, .stop_conn = iscsi_conn_stop, - /* these are called as part of conn recovery */ - .suspend_conn_recv = iscsi_tcp_suspend_conn_rx, - .terminate_conn = iscsi_tcp_terminate_conn, - /* IO */ .send_pdu = iscsi_conn_send_pdu, .get_stats = iscsi_conn_get_stats, - .init_cmd_task = iscsi_tcp_cmd_init, - .init_mgmt_task = iscsi_tcp_mgmt_init, - .xmit_cmd_task = iscsi_tcp_ctask_xmit, - .xmit_mgmt_task = iscsi_tcp_mtask_xmit, - .cleanup_cmd_task = iscsi_tcp_cleanup_ctask, - /* recovery */ - .session_recovery_timedout = iscsi_session_recovery_timedout, }; static int __init iscsi_tcp_init(void) { if (iscsi_max_lun < 1) { - printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n", - iscsi_max_lun); + printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); return -EINVAL; } iscsi_tcp_transport.max_lun = iscsi_max_lun; + taskcache = kmem_cache_create("iscsi_taskcache", + sizeof(struct iscsi_data_task), 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!taskcache) + return -ENOMEM; + if (!iscsi_register_transport(&iscsi_tcp_transport)) - return -ENODEV; + kmem_cache_destroy(taskcache); return 0; } @@ -2554,6 +3653,7 @@ static void __exit iscsi_tcp_exit(void) { iscsi_unregister_transport(&iscsi_tcp_transport); + kmem_cache_destroy(taskcache); } module_init(iscsi_tcp_init); diff --git a/trunk/drivers/scsi/iscsi_tcp.h b/trunk/drivers/scsi/iscsi_tcp.h index 808302832e68..ba26741ac154 100644 --- a/trunk/drivers/scsi/iscsi_tcp.h +++ b/trunk/drivers/scsi/iscsi_tcp.h @@ -2,8 +2,7 @@ * iSCSI Initiator TCP Transport * Copyright (C) 2004 Dmitry Yusupov * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 - 2006 Mike Christie - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2005 Mike Christie * maintained by open-iscsi@googlegroups.com * * This program is free software; you can redistribute it and/or modify @@ -22,7 +21,20 @@ #ifndef ISCSI_TCP_H #define ISCSI_TCP_H -#include +/* Session's states */ +#define ISCSI_STATE_FREE 1 +#define ISCSI_STATE_LOGGED_IN 2 +#define ISCSI_STATE_FAILED 3 +#define ISCSI_STATE_TERMINATE 4 + +/* Connection's states */ +#define ISCSI_CONN_INITIAL_STAGE 0 +#define ISCSI_CONN_STARTED 1 +#define ISCSI_CONN_STOPPED 2 +#define ISCSI_CONN_CLEANUP_WAIT 3 + +/* Connection suspend "bit" */ +#define SUSPEND_BIT 1 /* Socket's Receive state machine */ #define IN_PROGRESS_WAIT_HEADER 0x0 @@ -30,6 +42,12 @@ #define IN_PROGRESS_DATA_RECV 0x2 #define IN_PROGRESS_DDIGEST_RECV 0x3 +/* Task Mgmt states */ +#define TMABORT_INITIAL 0x0 +#define TMABORT_SUCCESS 0x1 +#define TMABORT_FAILED 0x2 +#define TMABORT_TIMEDOUT 0x3 + /* xmit state machine */ #define XMSTATE_IDLE 0x0 #define XMSTATE_R_HDR 0x1 @@ -44,14 +62,34 @@ #define XMSTATE_W_PAD 0x200 #define XMSTATE_DATA_DIGEST 0x400 +#define ISCSI_CONN_MAX 1 #define ISCSI_CONN_RCVBUF_MIN 262144 #define ISCSI_CONN_SNDBUF_MIN 262144 #define ISCSI_PAD_LEN 4 #define ISCSI_R2T_MAX 16 +#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */ +#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ +#define ISCSI_MGMT_ITT_OFFSET 0xa00 #define ISCSI_SG_TABLESIZE SG_ALL +#define ISCSI_DEF_CMD_PER_LUN 32 +#define ISCSI_MAX_CMD_PER_LUN 128 #define ISCSI_TCP_MAX_CMD_LEN 16 -struct socket; +#define ITT_MASK (0xfff) +#define CID_SHIFT 12 +#define CID_MASK (0xffff<ioaddr; - - ap->ctl |= ATA_NIEN; - ap->last_ctl = ap->ctl; - - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); -} - -/** - * ata_bmdma_thaw - Thaw BMDMA controller port - * @ap: port to thaw - * - * Thaw BMDMA controller port. - * - * LOCKING: - * Inherited from caller. - */ -void ata_bmdma_thaw(struct ata_port *ap) -{ - /* clear & re-enable interrupts */ - ata_chk_status(ap); - ap->ops->irq_clear(ap); - if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ - ata_irq_on(ap); -} - -/** - * ata_bmdma_drive_eh - Perform EH with given methods for BMDMA controller - * @ap: port to handle error for - * @prereset: prereset method (can be NULL) - * @softreset: softreset method (can be NULL) - * @hardreset: hardreset method (can be NULL) - * @postreset: postreset method (can be NULL) - * - * Handle error for ATA BMDMA controller. It can handle both - * PATA and SATA controllers. Many controllers should be able to - * use this EH as-is or with some added handling before and - * after. - * - * This function is intended to be used for constructing - * ->error_handler callback by low level drivers. - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset) -{ - struct ata_eh_context *ehc = &ap->eh_context; - struct ata_queued_cmd *qc; - unsigned long flags; - int thaw = 0; - - qc = __ata_qc_from_tag(ap, ap->active_tag); - if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) - qc = NULL; - - /* reset PIO HSM and stop DMA engine */ - spin_lock_irqsave(ap->lock, flags); - - ap->hsm_task_state = HSM_ST_IDLE; - - if (qc && (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA)) { - u8 host_stat; - - host_stat = ata_bmdma_status(ap); - - ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat); - - /* BMDMA controllers indicate host bus error by - * setting DMA_ERR bit and timing out. As it wasn't - * really a timeout event, adjust error mask and - * cancel frozen state. - */ - if (qc->err_mask == AC_ERR_TIMEOUT && host_stat & ATA_DMA_ERR) { - qc->err_mask = AC_ERR_HOST_BUS; - thaw = 1; - } - - ap->ops->bmdma_stop(qc); - } - - ata_altstatus(ap); - ata_chk_status(ap); - ap->ops->irq_clear(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - if (thaw) - ata_eh_thaw_port(ap); - - /* PIO and DMA engines have been stopped, perform recovery */ - ata_do_eh(ap, prereset, softreset, hardreset, postreset); -} - -/** - * ata_bmdma_error_handler - Stock error handler for BMDMA controller - * @ap: port to handle error for - * - * Stock error handler for BMDMA controller. - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void ata_bmdma_error_handler(struct ata_port *ap) -{ - ata_reset_fn_t hardreset; - - hardreset = NULL; - if (sata_scr_valid(ap)) - hardreset = sata_std_hardreset; - - ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, - ata_std_postreset); -} - -/** - * ata_bmdma_post_internal_cmd - Stock post_internal_cmd for - * BMDMA controller - * @qc: internal command to clean up - * - * LOCKING: - * Kernel thread context (may sleep) - */ -void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) -{ - ata_bmdma_stop(qc); -} - #ifdef CONFIG_PCI static struct ata_probe_ent * ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) @@ -1075,21 +930,10 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, /* FIXME: check ata_device_add return */ if (legacy_mode) { - struct device *dev = &pdev->dev; - struct ata_host_set *host_set = NULL; - - if (legacy_mode & (1 << 0)) { + if (legacy_mode & (1 << 0)) ata_device_add(probe_ent); - host_set = dev_get_drvdata(dev); - } - - if (legacy_mode & (1 << 1)) { + if (legacy_mode & (1 << 1)) ata_device_add(probe_ent2); - if (host_set) { - host_set->next = dev_get_drvdata(dev); - dev_set_drvdata(dev, host_set); - } - } } else ata_device_add(probe_ent); diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index d1c1c30d123f..de9ba7890b5a 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -61,37 +61,26 @@ #include "libata.h" -/* debounce timing parameters in msecs { interval, duration, timeout } */ -const unsigned long sata_deb_timing_boot[] = { 5, 100, 2000 }; -const unsigned long sata_deb_timing_eh[] = { 25, 500, 2000 }; -const unsigned long sata_deb_timing_before_fsrst[] = { 100, 2000, 5000 }; - -static unsigned int ata_dev_init_params(struct ata_device *dev, - u16 heads, u16 sectors); -static unsigned int ata_dev_set_xfermode(struct ata_device *dev); -static void ata_dev_xfermask(struct ata_device *dev); +static unsigned int ata_dev_init_params(struct ata_port *ap, + struct ata_device *dev, + u16 heads, + u16 sectors); +static void ata_set_mode(struct ata_port *ap); +static unsigned int ata_dev_set_xfermode(struct ata_port *ap, + struct ata_device *dev); +static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); static unsigned int ata_unique_id = 1; static struct workqueue_struct *ata_wq; -struct workqueue_struct *ata_aux_wq; - int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); -int atapi_dmadir = 0; -module_param(atapi_dmadir, int, 0444); -MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)"); - int libata_fua = 0; module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); -static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; -module_param(ata_probe_timeout, int, 0444); -MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); - MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -408,22 +397,11 @@ static const char *ata_mode_string(unsigned int xfer_mask) return ""; } -static const char *sata_spd_string(unsigned int spd) -{ - static const char * const spd_str[] = { - "1.5 Gbps", - "3.0 Gbps", - }; - - if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str)) - return ""; - return spd_str[spd - 1]; -} - -void ata_dev_disable(struct ata_device *dev) +static void ata_dev_disable(struct ata_port *ap, struct ata_device *dev) { - if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) { - ata_dev_printk(dev, KERN_WARNING, "disabled\n"); + if (ata_dev_present(dev)) { + printk(KERN_WARNING "ata%u: dev %u disabled\n", + ap->id, dev->devno); dev->class++; } } @@ -781,9 +759,8 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device) void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " - "device %u, wait %u\n", ap->id, device, wait); + VPRINTK("ENTER, ata%u: device %u, wait %u\n", + ap->id, device, wait); if (wait) ata_wait_idle(ap); @@ -938,9 +915,9 @@ void ata_port_flush_task(struct ata_port *ap) DPRINTK("ENTER\n"); - spin_lock_irqsave(ap->lock, flags); + spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags |= ATA_FLAG_FLUSH_PORT_TASK; - spin_unlock_irqrestore(ap->lock, flags); + spin_unlock_irqrestore(&ap->host_set->lock, flags); DPRINTK("flush #1\n"); flush_workqueue(ata_wq); @@ -951,32 +928,30 @@ void ata_port_flush_task(struct ata_port *ap) * Cancel and flush. */ if (!cancel_delayed_work(&ap->port_task)) { - if (ata_msg_ctl(ap)) - ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", - __FUNCTION__); + DPRINTK("flush #2\n"); flush_workqueue(ata_wq); } - spin_lock_irqsave(ap->lock, flags); + spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_FLUSH_PORT_TASK; - spin_unlock_irqrestore(ap->lock, flags); + spin_unlock_irqrestore(&ap->host_set->lock, flags); - if (ata_msg_ctl(ap)) - ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); + DPRINTK("EXIT\n"); } void ata_qc_complete_internal(struct ata_queued_cmd *qc) { struct completion *waiting = qc->private_data; + qc->ap->ops->tf_read(qc->ap, &qc->tf); complete(waiting); } /** * ata_exec_internal - execute libata internal command + * @ap: Port to which the command is sent * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result - * @cdb: CDB for packet command * @dma_dir: Data tranfer direction of the command * @buf: Data buffer of the command * @buflen: Length of data buffer @@ -989,66 +964,25 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc) * * LOCKING: * None. Should be called with kernel context, might sleep. - * - * RETURNS: - * Zero on success, AC_ERR_* mask on failure */ -unsigned ata_exec_internal(struct ata_device *dev, - struct ata_taskfile *tf, const u8 *cdb, - int dma_dir, void *buf, unsigned int buflen) + +static unsigned +ata_exec_internal(struct ata_port *ap, struct ata_device *dev, + struct ata_taskfile *tf, + int dma_dir, void *buf, unsigned int buflen) { - struct ata_port *ap = dev->ap; u8 command = tf->command; struct ata_queued_cmd *qc; - unsigned int tag, preempted_tag; - u32 preempted_sactive, preempted_qc_active; DECLARE_COMPLETION(wait); unsigned long flags; unsigned int err_mask; - int rc; - - spin_lock_irqsave(ap->lock, flags); - /* no internal command while frozen */ - if (ap->flags & ATA_FLAG_FROZEN) { - spin_unlock_irqrestore(ap->lock, flags); - return AC_ERR_SYSTEM; - } - - /* initialize internal qc */ - - /* XXX: Tag 0 is used for drivers with legacy EH as some - * drivers choke if any other tag is given. This breaks - * ata_tag_internal() test for those drivers. Don't use new - * EH stuff without converting to it. - */ - if (ap->ops->error_handler) - tag = ATA_TAG_INTERNAL; - else - tag = 0; - - if (test_and_set_bit(tag, &ap->qc_allocated)) - BUG(); - qc = __ata_qc_from_tag(ap, tag); + spin_lock_irqsave(&ap->host_set->lock, flags); - qc->tag = tag; - qc->scsicmd = NULL; - qc->ap = ap; - qc->dev = dev; - ata_qc_reinit(qc); + qc = ata_qc_new_init(ap, dev); + BUG_ON(qc == NULL); - preempted_tag = ap->active_tag; - preempted_sactive = ap->sactive; - preempted_qc_active = ap->qc_active; - ap->active_tag = ATA_TAG_POISON; - ap->sactive = 0; - ap->qc_active = 0; - - /* prepare & issue qc */ qc->tf = *tf; - if (cdb) - memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); - qc->flags |= ATA_QCFLAG_RESULT_TF; qc->dma_dir = dma_dir; if (dma_dir != DMA_NONE) { ata_sg_init_one(qc, buf, buflen); @@ -1060,58 +994,33 @@ unsigned ata_exec_internal(struct ata_device *dev, ata_qc_issue(qc); - spin_unlock_irqrestore(ap->lock, flags); + spin_unlock_irqrestore(&ap->host_set->lock, flags); - rc = wait_for_completion_timeout(&wait, ata_probe_timeout); + if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) { + ata_port_flush_task(ap); - ata_port_flush_task(ap); - - if (!rc) { - spin_lock_irqsave(ap->lock, flags); + spin_lock_irqsave(&ap->host_set->lock, flags); /* We're racing with irq here. If we lose, the * following test prevents us from completing the qc - * twice. If we win, the port is frozen and will be - * cleaned up by ->post_internal_cmd(). + * again. If completion irq occurs after here but + * before the caller cleans up, it will result in a + * spurious interrupt. We can live with that. */ if (qc->flags & ATA_QCFLAG_ACTIVE) { - qc->err_mask |= AC_ERR_TIMEOUT; - - if (ap->ops->error_handler) - ata_port_freeze(ap); - else - ata_qc_complete(qc); - - if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, - "qc timeout (cmd 0x%x)\n", command); + qc->err_mask = AC_ERR_TIMEOUT; + ata_qc_complete(qc); + printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", + ap->id, command); } - spin_unlock_irqrestore(ap->lock, flags); - } - - /* do post_internal_cmd */ - if (ap->ops->post_internal_cmd) - ap->ops->post_internal_cmd(qc); - - if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) { - if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, - "zero err_mask for failed " - "internal command, assuming AC_ERR_OTHER\n"); - qc->err_mask |= AC_ERR_OTHER; + spin_unlock_irqrestore(&ap->host_set->lock, flags); } - /* finish up */ - spin_lock_irqsave(ap->lock, flags); - - *tf = qc->result_tf; + *tf = qc->tf; err_mask = qc->err_mask; ata_qc_free(qc); - ap->active_tag = preempted_tag; - ap->sactive = preempted_sactive; - ap->qc_active = preempted_qc_active; /* XXX - Some LLDDs (sata_mv) disable port on command failure. * Until those drivers are fixed, we detect the condition @@ -1124,43 +1033,14 @@ unsigned ata_exec_internal(struct ata_device *dev, * * Kill the following code as soon as those drivers are fixed. */ - if (ap->flags & ATA_FLAG_DISABLED) { + if (ap->flags & ATA_FLAG_PORT_DISABLED) { err_mask |= AC_ERR_SYSTEM; ata_port_probe(ap); } - spin_unlock_irqrestore(ap->lock, flags); - return err_mask; } -/** - * ata_do_simple_cmd - execute simple internal command - * @dev: Device to which the command is sent - * @cmd: Opcode to execute - * - * Execute a 'simple' command, that only consists of the opcode - * 'cmd' itself, without filling any other registers - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * Zero on success, AC_ERR_* mask on failure - */ -unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) -{ - struct ata_taskfile tf; - - ata_tf_init(dev, &tf); - - tf.command = cmd; - tf.flags |= ATA_TFLAG_DEVICE; - tf.protocol = ATA_PROT_NODATA; - - return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); -} - /** * ata_pio_need_iordy - check if iordy needed * @adev: ATA device @@ -1196,10 +1076,11 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) /** * ata_dev_read_id - Read ID data from the specified device + * @ap: port on which target device resides * @dev: target device * @p_class: pointer to class of the target device (may be changed) * @post_reset: is this read ID post-reset? - * @id: buffer to read IDENTIFY data into + * @p_id: read IDENTIFY page (newly allocated) * * Read ID data from the specified device. ATA_CMD_ID_ATA is * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI @@ -1212,24 +1093,29 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, - int post_reset, u16 *id) +static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, + unsigned int *p_class, int post_reset, u16 **p_id) { - struct ata_port *ap = dev->ap; unsigned int class = *p_class; struct ata_taskfile tf; unsigned int err_mask = 0; + u16 *id; const char *reason; int rc; - if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ + id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); + if (id == NULL) { + rc = -ENOMEM; + reason = "out of memory"; + goto err_out; + } + retry: - ata_tf_init(dev, &tf); + ata_tf_init(ap, &tf, dev->devno); switch (class) { case ATA_DEV_ATA: @@ -1246,7 +1132,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, tf.protocol = ATA_PROT_PIO; - err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, + err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, id, sizeof(id[0]) * ATA_ID_WORDS); if (err_mask) { rc = -EIO; @@ -1273,7 +1159,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, * Some drives were very specific about that exact sequence. */ if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { - err_mask = ata_dev_init_params(dev, id[3], id[6]); + err_mask = ata_dev_init_params(ap, dev, id[3], id[6]); if (err_mask) { rc = -EIO; reason = "INIT_DEV_PARAMS failed"; @@ -1289,45 +1175,25 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, } *p_class = class; - + *p_id = id; return 0; err_out: - if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY " - "(%s, err_mask=0x%x)\n", reason, err_mask); + printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n", + ap->id, dev->devno, reason); + kfree(id); return rc; } -static inline u8 ata_dev_knobble(struct ata_device *dev) -{ - return ((dev->ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); -} - -static void ata_dev_config_ncq(struct ata_device *dev, - char *desc, size_t desc_sz) +static inline u8 ata_dev_knobble(const struct ata_port *ap, + struct ata_device *dev) { - struct ata_port *ap = dev->ap; - int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); - - if (!ata_id_has_ncq(dev->id)) { - desc[0] = '\0'; - return; - } - - if (ap->flags & ATA_FLAG_NCQ) { - hdepth = min(ap->host->can_queue, ATA_MAX_QUEUE - 1); - dev->flags |= ATA_DFLAG_NCQ; - } - - if (hdepth >= ddepth) - snprintf(desc, desc_sz, "NCQ (depth %d)", ddepth); - else - snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth); + return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); } /** * ata_dev_configure - Configure the specified ATA/ATAPI device + * @ap: Port on which target device resides * @dev: Target device to configure * @print_info: Enable device info printout * @@ -1340,35 +1206,30 @@ static void ata_dev_config_ncq(struct ata_device *dev, * RETURNS: * 0 on success, -errno otherwise */ -int ata_dev_configure(struct ata_device *dev, int print_info) +static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, + int print_info) { - struct ata_port *ap = dev->ap; const u16 *id = dev->id; unsigned int xfer_mask; int i, rc; - if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { - ata_dev_printk(dev, KERN_INFO, - "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", - __FUNCTION__, ap->id, dev->devno); + if (!ata_dev_present(dev)) { + DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", + ap->id, dev->devno); return 0; } - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); /* print device capabilities */ - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " - "85:%04x 86:%04x 87:%04x 88:%04x\n", - __FUNCTION__, - id[49], id[82], id[83], id[84], - id[85], id[86], id[87], id[88]); + if (print_info) + printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x " + "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", + ap->id, dev->devno, id[49], id[82], id[83], + id[84], id[85], id[86], id[87], id[88]); /* initialize to-be-configured parameters */ - dev->flags &= ~ATA_DFLAG_CFG_MASK; + dev->flags = 0; dev->max_sectors = 0; dev->cdb_len = 0; dev->n_sectors = 0; @@ -1383,8 +1244,7 @@ int ata_dev_configure(struct ata_device *dev, int print_info) /* find max transfer mode; for printk only */ xfer_mask = ata_id_xfermask(id); - if (ata_msg_probe(ap)) - ata_dump_id(id); + ata_dump_id(id); /* ATA-specific feature tests */ if (dev->class == ATA_DEV_ATA) { @@ -1392,7 +1252,6 @@ int ata_dev_configure(struct ata_device *dev, int print_info) if (ata_id_has_lba(id)) { const char *lba_desc; - char ncq_desc[20]; lba_desc = "LBA"; dev->flags |= ATA_DFLAG_LBA; @@ -1401,17 +1260,15 @@ int ata_dev_configure(struct ata_device *dev, int print_info) lba_desc = "LBA48"; } - /* config NCQ */ - ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); - /* print device info to dmesg */ - if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, "ATA-%d, " - "max %s, %Lu sectors: %s %s\n", - ata_id_major_version(id), - ata_mode_string(xfer_mask), - (unsigned long long)dev->n_sectors, - lba_desc, ncq_desc); + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATA-%d, " + "max %s, %Lu sectors: %s\n", + ap->id, dev->devno, + ata_id_major_version(id), + ata_mode_string(xfer_mask), + (unsigned long long)dev->n_sectors, + lba_desc); } else { /* CHS */ @@ -1428,22 +1285,14 @@ int ata_dev_configure(struct ata_device *dev, int print_info) } /* print device info to dmesg */ - if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, "ATA-%d, " - "max %s, %Lu sectors: CHS %u/%u/%u\n", - ata_id_major_version(id), - ata_mode_string(xfer_mask), - (unsigned long long)dev->n_sectors, - dev->cylinders, dev->heads, - dev->sectors); - } - - if (dev->id[59] & 0x100) { - dev->multi_count = dev->id[59] & 0xff; - if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, - "ata%u: dev %u multi count %u\n", - ap->id, dev->devno, dev->multi_count); + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATA-%d, " + "max %s, %Lu sectors: CHS %u/%u/%u\n", + ap->id, dev->devno, + ata_id_major_version(id), + ata_mode_string(xfer_mask), + (unsigned long long)dev->n_sectors, + dev->cylinders, dev->heads, dev->sectors); } dev->cdb_len = 16; @@ -1451,28 +1300,18 @@ int ata_dev_configure(struct ata_device *dev, int print_info) /* ATAPI-specific feature tests */ else if (dev->class == ATA_DEV_ATAPI) { - char *cdb_intr_string = ""; - rc = atapi_cdb_len(id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { - if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, - "unsupported CDB len\n"); + printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); rc = -EINVAL; goto err_out_nosup; } dev->cdb_len = (unsigned int) rc; - if (ata_id_cdb_intr(dev->id)) { - dev->flags |= ATA_DFLAG_CDB_INTR; - cdb_intr_string = ", CDB intr"; - } - /* print device info to dmesg */ - if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n", - ata_mode_string(xfer_mask), - cdb_intr_string); + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", + ap->id, dev->devno, ata_mode_string(xfer_mask)); } ap->host->max_cmd_len = 0; @@ -1482,10 +1321,10 @@ int ata_dev_configure(struct ata_device *dev, int print_info) ap->device[i].cdb_len); /* limit bridge transfers to udma5, 200 sectors */ - if (ata_dev_knobble(dev)) { - if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, - "applying bridge limits\n"); + if (ata_dev_knobble(ap, dev)) { + if (print_info) + printk(KERN_INFO "ata%u(%u): applying bridge limits\n", + ap->id, dev->devno); dev->udma_mask &= ATA_UDMA5; dev->max_sectors = ATA_MAX_SECTORS; } @@ -1493,15 +1332,11 @@ int ata_dev_configure(struct ata_device *dev, int print_info) if (ap->ops->dev_config) ap->ops->dev_config(ap, dev); - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", - __FUNCTION__, ata_chk_status(ap)); + DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap)); return 0; err_out_nosup: - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: EXIT, err\n", __FUNCTION__); + DPRINTK("EXIT, err\n"); return rc; } @@ -1517,104 +1352,79 @@ int ata_dev_configure(struct ata_device *dev, int print_info) * PCI/etc. bus probe sem. * * RETURNS: - * Zero on success, negative errno otherwise. + * Zero on success, non-zero on error. */ static int ata_bus_probe(struct ata_port *ap) { unsigned int classes[ATA_MAX_DEVICES]; - int tries[ATA_MAX_DEVICES]; - int i, rc, down_xfermask; - struct ata_device *dev; + unsigned int i, rc, found = 0; ata_port_probe(ap); - for (i = 0; i < ATA_MAX_DEVICES; i++) - tries[i] = ATA_PROBE_MAX_TRIES; - - retry: - down_xfermask = 0; - /* reset and determine device classes */ - ap->ops->phy_reset(ap); + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_UNKNOWN; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; + if (ap->ops->probe_reset) { + rc = ap->ops->probe_reset(ap, classes); + if (rc) { + printk("ata%u: reset failed (errno=%d)\n", ap->id, rc); + return rc; + } + } else { + ap->ops->phy_reset(ap); - if (!(ap->flags & ATA_FLAG_DISABLED) && - dev->class != ATA_DEV_UNKNOWN) - classes[dev->devno] = dev->class; - else - classes[dev->devno] = ATA_DEV_NONE; + if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ap->device[i].class; - dev->class = ATA_DEV_UNKNOWN; + ata_port_probe(ap); } - ata_port_probe(ap); - - /* after the reset the device state is PIO 0 and the controller - state is undefined. Record the mode */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->device[i].pio_mode = XFER_PIO_0; + if (classes[i] == ATA_DEV_UNKNOWN) + classes[i] = ATA_DEV_NONE; /* read IDENTIFY page and configure devices */ for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; + struct ata_device *dev = &ap->device[i]; - if (tries[i]) - dev->class = classes[i]; + dev->class = classes[i]; - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) continue; - rc = ata_dev_read_id(dev, &dev->class, 1, dev->id); - if (rc) - goto fail; + WARN_ON(dev->id != NULL); + if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) { + dev->class = ATA_DEV_NONE; + continue; + } - rc = ata_dev_configure(dev, 1); - if (rc) - goto fail; - } + if (ata_dev_configure(ap, dev, 1)) { + ata_dev_disable(ap, dev); + continue; + } - /* configure transfer mode */ - rc = ata_set_mode(ap, &dev); - if (rc) { - down_xfermask = 1; - goto fail; + found = 1; } - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ata_dev_enabled(&ap->device[i])) - return 0; + if (!found) + goto err_out_disable; - /* no device present, disable port */ - ata_port_disable(ap); - ap->ops->port_disable(ap); - return -ENODEV; + if (ap->ops->set_mode) + ap->ops->set_mode(ap); + else + ata_set_mode(ap); - fail: - switch (rc) { - case -EINVAL: - case -ENODEV: - tries[dev->devno] = 0; - break; - case -EIO: - sata_down_spd_limit(ap); - /* fall through */ - default: - tries[dev->devno]--; - if (down_xfermask && - ata_down_xfermask_limit(dev, tries[dev->devno] == 1)) - tries[dev->devno] = 0; - } + if (ap->flags & ATA_FLAG_PORT_DISABLED) + goto err_out_disable; - if (!tries[dev->devno]) { - ata_down_xfermask_limit(dev, 1); - ata_dev_disable(dev); - } + return 0; - goto retry; +err_out_disable: + ap->ops->port_disable(ap); + return -1; } /** @@ -1630,7 +1440,7 @@ static int ata_bus_probe(struct ata_port *ap) void ata_port_probe(struct ata_port *ap) { - ap->flags &= ~ATA_FLAG_DISABLED; + ap->flags &= ~ATA_FLAG_PORT_DISABLED; } /** @@ -1644,21 +1454,27 @@ void ata_port_probe(struct ata_port *ap) */ static void sata_print_link_status(struct ata_port *ap) { - u32 sstatus, scontrol, tmp; + u32 sstatus, tmp; + const char *speed; - if (sata_scr_read(ap, SCR_STATUS, &sstatus)) + if (!ap->ops->scr_read) return; - sata_scr_read(ap, SCR_CONTROL, &scontrol); - if (ata_port_online(ap)) { + sstatus = scr_read(ap, SCR_STATUS); + + if (sata_dev_present(ap)) { tmp = (sstatus >> 4) & 0xf; - ata_port_printk(ap, KERN_INFO, - "SATA link up %s (SStatus %X SControl %X)\n", - sata_spd_string(tmp), sstatus, scontrol); + if (tmp & (1 << 0)) + speed = "1.5"; + else if (tmp & (1 << 1)) + speed = "3.0"; + else + speed = ""; + printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n", + ap->id, speed, sstatus); } else { - ata_port_printk(ap, KERN_INFO, - "SATA link down (SStatus %X SControl %X)\n", - sstatus, scontrol); + printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n", + ap->id, sstatus); } } @@ -1681,18 +1497,17 @@ void __sata_phy_reset(struct ata_port *ap) if (ap->flags & ATA_FLAG_SATA_RESET) { /* issue phy wake/reset */ - sata_scr_write_flush(ap, SCR_CONTROL, 0x301); + scr_write_flush(ap, SCR_CONTROL, 0x301); /* Couldn't find anything in SATA I/II specs, but * AHCI-1.1 10.4.2 says at least 1 ms. */ mdelay(1); } - /* phy wake/clear reset */ - sata_scr_write_flush(ap, SCR_CONTROL, 0x300); + scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ /* wait for phy to become ready, if necessary */ do { msleep(200); - sata_scr_read(ap, SCR_STATUS, &sstatus); + sstatus = scr_read(ap, SCR_STATUS); if ((sstatus & 0xf) != 1) break; } while (time_before(jiffies, timeout)); @@ -1701,12 +1516,12 @@ void __sata_phy_reset(struct ata_port *ap) sata_print_link_status(ap); /* TODO: phy layer with polling, timeouts, etc. */ - if (!ata_port_offline(ap)) + if (sata_dev_present(ap)) ata_port_probe(ap); else ata_port_disable(ap); - if (ap->flags & ATA_FLAG_DISABLED) + if (ap->flags & ATA_FLAG_PORT_DISABLED) return; if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { @@ -1731,24 +1546,24 @@ void __sata_phy_reset(struct ata_port *ap) void sata_phy_reset(struct ata_port *ap) { __sata_phy_reset(ap); - if (ap->flags & ATA_FLAG_DISABLED) + if (ap->flags & ATA_FLAG_PORT_DISABLED) return; ata_bus_reset(ap); } /** * ata_dev_pair - return other device on cable + * @ap: port * @adev: device * * Obtain the other device on the same cable, or if none is * present NULL is returned */ -struct ata_device *ata_dev_pair(struct ata_device *adev) +struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev) { - struct ata_port *ap = adev->ap; struct ata_device *pair = &ap->device[1 - adev->devno]; - if (!ata_dev_enabled(pair)) + if (!ata_dev_present(pair)) return NULL; return pair; } @@ -1770,122 +1585,7 @@ void ata_port_disable(struct ata_port *ap) { ap->device[0].class = ATA_DEV_NONE; ap->device[1].class = ATA_DEV_NONE; - ap->flags |= ATA_FLAG_DISABLED; -} - -/** - * sata_down_spd_limit - adjust SATA spd limit downward - * @ap: Port to adjust SATA spd limit for - * - * Adjust SATA spd limit of @ap downward. Note that this - * function only adjusts the limit. The change must be applied - * using sata_set_spd(). - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 on success, negative errno on failure - */ -int sata_down_spd_limit(struct ata_port *ap) -{ - u32 sstatus, spd, mask; - int rc, highbit; - - rc = sata_scr_read(ap, SCR_STATUS, &sstatus); - if (rc) - return rc; - - mask = ap->sata_spd_limit; - if (mask <= 1) - return -EINVAL; - highbit = fls(mask) - 1; - mask &= ~(1 << highbit); - - spd = (sstatus >> 4) & 0xf; - if (spd <= 1) - return -EINVAL; - spd--; - mask &= (1 << spd) - 1; - if (!mask) - return -EINVAL; - - ap->sata_spd_limit = mask; - - ata_port_printk(ap, KERN_WARNING, "limiting SATA link speed to %s\n", - sata_spd_string(fls(mask))); - - return 0; -} - -static int __sata_set_spd_needed(struct ata_port *ap, u32 *scontrol) -{ - u32 spd, limit; - - if (ap->sata_spd_limit == UINT_MAX) - limit = 0; - else - limit = fls(ap->sata_spd_limit); - - spd = (*scontrol >> 4) & 0xf; - *scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4); - - return spd != limit; -} - -/** - * sata_set_spd_needed - is SATA spd configuration needed - * @ap: Port in question - * - * Test whether the spd limit in SControl matches - * @ap->sata_spd_limit. This function is used to determine - * whether hardreset is necessary to apply SATA spd - * configuration. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 1 if SATA spd configuration is needed, 0 otherwise. - */ -int sata_set_spd_needed(struct ata_port *ap) -{ - u32 scontrol; - - if (sata_scr_read(ap, SCR_CONTROL, &scontrol)) - return 0; - - return __sata_set_spd_needed(ap, &scontrol); -} - -/** - * sata_set_spd - set SATA spd according to spd limit - * @ap: Port to set SATA spd for - * - * Set SATA spd of @ap according to sata_spd_limit. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 if spd doesn't need to be changed, 1 if spd has been - * changed. Negative errno if SCR registers are inaccessible. - */ -int sata_set_spd(struct ata_port *ap) -{ - u32 scontrol; - int rc; - - if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) - return rc; - - if (!__sata_set_spd_needed(ap, &scontrol)) - return 0; - - if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) - return rc; - - return 1; + ap->flags |= ATA_FLAG_PORT_DISABLED; } /* @@ -2036,149 +1736,52 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, return 0; } -/** - * ata_down_xfermask_limit - adjust dev xfer masks downward - * @dev: Device to adjust xfer masks - * @force_pio0: Force PIO0 - * - * Adjust xfer masks of @dev downward. Note that this function - * does not apply the change. Invoking ata_set_mode() afterwards - * will apply the limit. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 on success, negative errno on failure - */ -int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0) -{ - unsigned long xfer_mask; - int highbit; - - xfer_mask = ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask, - dev->udma_mask); - - if (!xfer_mask) - goto fail; - /* don't gear down to MWDMA from UDMA, go directly to PIO */ - if (xfer_mask & ATA_MASK_UDMA) - xfer_mask &= ~ATA_MASK_MWDMA; - - highbit = fls(xfer_mask) - 1; - xfer_mask &= ~(1 << highbit); - if (force_pio0) - xfer_mask &= 1 << ATA_SHIFT_PIO; - if (!xfer_mask) - goto fail; - - ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, - &dev->udma_mask); - - ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n", - ata_mode_string(xfer_mask)); - - return 0; - - fail: - return -EINVAL; -} - -static int ata_dev_set_mode(struct ata_device *dev) +static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) { unsigned int err_mask; int rc; - dev->flags &= ~ATA_DFLAG_PIO; if (dev->xfer_shift == ATA_SHIFT_PIO) dev->flags |= ATA_DFLAG_PIO; - err_mask = ata_dev_set_xfermode(dev); + err_mask = ata_dev_set_xfermode(ap, dev); if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to set xfermode " - "(err_mask=0x%x)\n", err_mask); + printk(KERN_ERR + "ata%u: failed to set xfermode (err_mask=0x%x)\n", + ap->id, err_mask); return -EIO; } - rc = ata_dev_revalidate(dev, 0); - if (rc) + rc = ata_dev_revalidate(ap, dev, 0); + if (rc) { + printk(KERN_ERR + "ata%u: failed to revalidate after set xfermode\n", + ap->id); return rc; + } DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", dev->xfer_shift, (int)dev->xfer_mode); - ata_dev_printk(dev, KERN_INFO, "configured for %s\n", - ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); + printk(KERN_INFO "ata%u: dev %u configured for %s\n", + ap->id, dev->devno, + ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); return 0; } -/** - * ata_set_mode - Program timings and issue SET FEATURES - XFER - * @ap: port on which timings will be programmed - * @r_failed_dev: out paramter for failed device - * - * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If - * ata_set_mode() fails, pointer to the failing device is - * returned in @r_failed_dev. - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * 0 on success, negative errno otherwise - */ -int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) +static int ata_host_set_pio(struct ata_port *ap) { - struct ata_device *dev; - int i, rc = 0, used_dma = 0, found = 0; - - /* has private set_mode? */ - if (ap->ops->set_mode) { - /* FIXME: make ->set_mode handle no device case and - * return error code and failing device on failure. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (ata_dev_enabled(&ap->device[i])) { - ap->ops->set_mode(ap); - break; - } - } - return 0; - } + int i; - /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { - unsigned int pio_mask, dma_mask; - - dev = &ap->device[i]; - - if (!ata_dev_enabled(dev)) - continue; - - ata_dev_xfermask(dev); - - pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0); - dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); - dev->pio_mode = ata_xfer_mask2mode(pio_mask); - dev->dma_mode = ata_xfer_mask2mode(dma_mask); - - found = 1; - if (dev->dma_mode) - used_dma = 1; - } - if (!found) - goto out; + struct ata_device *dev = &ap->device[i]; - /* step 2: always set host PIO timings */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) continue; if (!dev->pio_mode) { - ata_dev_printk(dev, KERN_WARNING, "no PIO support\n"); - rc = -EINVAL; - goto out; + printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i); + return -1; } dev->xfer_mode = dev->pio_mode; @@ -2187,11 +1790,17 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) ap->ops->set_piomode(ap, dev); } - /* step 3: set host DMA timings */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; - - if (!ata_dev_enabled(dev) || !dev->dma_mode) + return 0; +} + +static void ata_host_set_dma(struct ata_port *ap) +{ + int i; + + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + + if (!ata_dev_present(dev) || !dev->dma_mode) continue; dev->xfer_mode = dev->dma_mode; @@ -2199,33 +1808,79 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) if (ap->ops->set_dmamode) ap->ops->set_dmamode(ap, dev); } +} + +/** + * ata_set_mode - Program timings and issue SET FEATURES - XFER + * @ap: port on which timings will be programmed + * + * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). + * + * LOCKING: + * PCI/etc. bus probe sem. + */ +static void ata_set_mode(struct ata_port *ap) +{ + int i, rc, used_dma = 0; + + /* step 1: calculate xfer_mask */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + unsigned int pio_mask, dma_mask; + + if (!ata_dev_present(dev)) + continue; + + ata_dev_xfermask(ap, dev); + + /* TODO: let LLDD filter dev->*_mask here */ + + pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0); + dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); + dev->pio_mode = ata_xfer_mask2mode(pio_mask); + dev->dma_mode = ata_xfer_mask2mode(dma_mask); + + if (dev->dma_mode) + used_dma = 1; + } + + /* step 2: always set host PIO timings */ + rc = ata_host_set_pio(ap); + if (rc) + goto err_out; + + /* step 3: set host DMA timings */ + ata_host_set_dma(ap); /* step 4: update devices' xfer mode */ for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; + struct ata_device *dev = &ap->device[i]; - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) continue; - rc = ata_dev_set_mode(dev); - if (rc) - goto out; + if (ata_dev_set_mode(ap, dev)) + goto err_out; } - /* Record simplex status. If we selected DMA then the other - * host channels are not permitted to do so. + /* + * Record simplex status. If we selected DMA then the other + * host channels are not permitted to do so. */ + if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX)) ap->host_set->simplex_claimed = 1; - /* step5: chip specific finalisation */ + /* + * Chip specific finalisation + */ if (ap->ops->post_set_mode) ap->ops->post_set_mode(ap); - out: - if (rc) - *r_failed_dev = dev; - return rc; + return; + +err_out: + ata_port_disable(ap); } /** @@ -2275,8 +1930,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap, } if (status & ATA_BUSY) - ata_port_printk(ap, KERN_WARNING, - "port is slow to respond, please be patient\n"); + printk(KERN_WARNING "ata%u is slow to respond, " + "please be patient\n", ap->id); timeout = timer_start + tmout; while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { @@ -2285,8 +1940,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap, } if (status & ATA_BUSY) { - ata_port_printk(ap, KERN_ERR, "port failed to respond " - "(%lu secs)\n", tmout / HZ); + printk(KERN_ERR "ata%u failed to respond (%lu secs)\n", + ap->id, tmout / HZ); return 1; } @@ -2378,10 +2033,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * the bus shows 0xFF because the odd clown forgets the D7 * pulldown resistor. */ - if (ata_check_status(ap) == 0xFF) { - ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n"); + if (ata_check_status(ap) == 0xFF) return AC_ERR_OTHER; - } ata_bus_post_reset(ap, devmask); @@ -2405,7 +2058,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * Obtains host_set lock. * * SIDE EFFECTS: - * Sets ATA_FLAG_DISABLED if bus reset fails. + * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. */ void ata_bus_reset(struct ata_port *ap) @@ -2473,195 +2126,60 @@ void ata_bus_reset(struct ata_port *ap) return; err_out: - ata_port_printk(ap, KERN_ERR, "disabling port\n"); + printk(KERN_ERR "ata%u: disabling port\n", ap->id); ap->ops->port_disable(ap); DPRINTK("EXIT\n"); } -/** - * sata_phy_debounce - debounce SATA phy status - * @ap: ATA port to debounce SATA phy status for - * @params: timing parameters { interval, duratinon, timeout } in msec - * - * Make sure SStatus of @ap reaches stable state, determined by - * holding the same value where DET is not 1 for @duration polled - * every @interval, before @timeout. Timeout constraints the - * beginning of the stable state. Because, after hot unplugging, - * DET gets stuck at 1 on some controllers, this functions waits - * until timeout then returns 0 if DET is stable at 1. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_phy_debounce(struct ata_port *ap, const unsigned long *params) -{ - unsigned long interval_msec = params[0]; - unsigned long duration = params[1] * HZ / 1000; - unsigned long timeout = jiffies + params[2] * HZ / 1000; - unsigned long last_jiffies; - u32 last, cur; - int rc; - - if ((rc = sata_scr_read(ap, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - last = cur; - last_jiffies = jiffies; - - while (1) { - msleep(interval_msec); - if ((rc = sata_scr_read(ap, SCR_STATUS, &cur))) - return rc; - cur &= 0xf; - - /* DET stable? */ - if (cur == last) { - if (cur == 1 && time_before(jiffies, timeout)) - continue; - if (time_after(jiffies, last_jiffies + duration)) - return 0; - continue; - } - - /* unstable, start over */ - last = cur; - last_jiffies = jiffies; - - /* check timeout */ - if (time_after(jiffies, timeout)) - return -EBUSY; - } -} - -/** - * sata_phy_resume - resume SATA phy - * @ap: ATA port to resume SATA phy for - * @params: timing parameters { interval, duratinon, timeout } in msec - * - * Resume SATA phy of @ap and debounce it. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int sata_phy_resume(struct ata_port *ap, const unsigned long *params) -{ - u32 scontrol; - int rc; - - if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) - return rc; - - scontrol = (scontrol & 0x0f0) | 0x300; - - if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) - return rc; - - /* Some PHYs react badly if SStatus is pounded immediately - * after resuming. Delay 200ms before debouncing. - */ - msleep(200); - - return sata_phy_debounce(ap, params); -} - -static void ata_wait_spinup(struct ata_port *ap) +static int sata_phy_resume(struct ata_port *ap) { - struct ata_eh_context *ehc = &ap->eh_context; - unsigned long end, secs; - int rc; - - /* first, debounce phy if SATA */ - if (ap->cbl == ATA_CBL_SATA) { - rc = sata_phy_debounce(ap, sata_deb_timing_eh); - - /* if debounced successfully and offline, no need to wait */ - if ((rc == 0 || rc == -EOPNOTSUPP) && ata_port_offline(ap)) - return; - } - - /* okay, let's give the drive time to spin up */ - end = ehc->i.hotplug_timestamp + ATA_SPINUP_WAIT * HZ / 1000; - secs = ((end - jiffies) + HZ - 1) / HZ; + unsigned long timeout = jiffies + (HZ * 5); + u32 sstatus; - if (time_after(jiffies, end)) - return; + scr_write_flush(ap, SCR_CONTROL, 0x300); - if (secs > 5) - ata_port_printk(ap, KERN_INFO, "waiting for device to spin up " - "(%lu secs)\n", secs); + /* Wait for phy to become ready, if necessary. */ + do { + msleep(200); + sstatus = scr_read(ap, SCR_STATUS); + if ((sstatus & 0xf) != 1) + return 0; + } while (time_before(jiffies, timeout)); - schedule_timeout_uninterruptible(end - jiffies); + return -1; } /** - * ata_std_prereset - prepare for reset - * @ap: ATA port to be reset - * - * @ap is about to be reset. Initialize it. + * ata_std_probeinit - initialize probing + * @ap: port to be probed * - * LOCKING: - * Kernel thread context (may sleep) + * @ap is about to be probed. Initialize it. This function is + * to be used as standard callback for ata_drive_probe_reset(). * - * RETURNS: - * 0 on success, -errno otherwise. + * NOTE!!! Do not use this function as probeinit if a low level + * driver implements only hardreset. Just pass NULL as probeinit + * in that case. Using this function is probably okay but doing + * so makes reset sequence different from the original + * ->phy_reset implementation and Jeff nervous. :-P */ -int ata_std_prereset(struct ata_port *ap) +void ata_std_probeinit(struct ata_port *ap) { - struct ata_eh_context *ehc = &ap->eh_context; - const unsigned long *timing; - int rc; - - /* hotplug? */ - if (ehc->i.flags & ATA_EHI_HOTPLUGGED) { - if (ap->flags & ATA_FLAG_HRST_TO_RESUME) - ehc->i.action |= ATA_EH_HARDRESET; - if (ap->flags & ATA_FLAG_SKIP_D2H_BSY) - ata_wait_spinup(ap); - } - - /* if we're about to do hardreset, nothing more to do */ - if (ehc->i.action & ATA_EH_HARDRESET) - return 0; - - /* if SATA, resume phy */ - if (ap->cbl == ATA_CBL_SATA) { - if (ap->flags & ATA_FLAG_LOADING) - timing = sata_deb_timing_boot; - else - timing = sata_deb_timing_eh; - - rc = sata_phy_resume(ap, timing); - if (rc && rc != -EOPNOTSUPP) { - /* phy resume failed */ - ata_port_printk(ap, KERN_WARNING, "failed to resume " - "link for reset (errno=%d)\n", rc); - return rc; - } + if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { + sata_phy_resume(ap); + if (sata_dev_present(ap)) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); } - - /* Wait for !BSY if the controller can wait for the first D2H - * Reg FIS and we don't know that no device is attached. - */ - if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); - - return 0; } /** * ata_std_softreset - reset host port via ATA SRST * @ap: port to reset + * @verbose: fail verbosely * @classes: resulting classes of attached devices * - * Reset host port using ATA SRST. + * Reset host port using ATA SRST. This function is to be used + * as standard callback for ata_drive_*_reset() functions. * * LOCKING: * Kernel thread context (may sleep) @@ -2669,7 +2187,7 @@ int ata_std_prereset(struct ata_port *ap) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_std_softreset(struct ata_port *ap, unsigned int *classes) +int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes) { unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; unsigned int devmask = 0, err_mask; @@ -2677,7 +2195,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) DPRINTK("ENTER\n"); - if (ata_port_offline(ap)) { + if (ap->ops->scr_read && !sata_dev_present(ap)) { classes[0] = ATA_DEV_NONE; goto out; } @@ -2695,7 +2213,11 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) DPRINTK("about to softreset, devmask=%x\n", devmask); err_mask = ata_bus_softreset(ap, devmask); if (err_mask) { - ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", + if (verbose) + printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n", + ap->id, err_mask); + else + DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n", err_mask); return -EIO; } @@ -2713,9 +2235,12 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) /** * sata_std_hardreset - reset host port via SATA phy reset * @ap: port to reset + * @verbose: fail verbosely * @class: resulting class of attached device * * SATA phy-reset host port using DET bits of SControl register. + * This function is to be used as standard callback for + * ata_drive_*_reset(). * * LOCKING: * Kernel thread context (may sleep) @@ -2723,57 +2248,35 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) * RETURNS: * 0 on success, -errno otherwise. */ -int sata_std_hardreset(struct ata_port *ap, unsigned int *class) +int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class) { - u32 scontrol; - int rc; - DPRINTK("ENTER\n"); - if (sata_set_spd_needed(ap)) { - /* SATA spec says nothing about how to reconfigure - * spd. To be on the safe side, turn off phy during - * reconfiguration. This works for at least ICH7 AHCI - * and Sil3124. - */ - if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) - return rc; - - scontrol = (scontrol & 0x0f0) | 0x302; - - if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) - return rc; - - sata_set_spd(ap); - } - - /* issue phy wake/reset */ - if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) - return rc; - - scontrol = (scontrol & 0x0f0) | 0x301; + /* Issue phy wake/reset */ + scr_write_flush(ap, SCR_CONTROL, 0x301); - if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol))) - return rc; - - /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 + /* + * Couldn't find anything in SATA I/II specs, but AHCI-1.1 * 10.4.2 says at least 1 ms. */ msleep(1); - /* bring phy back */ - sata_phy_resume(ap, sata_deb_timing_eh); + /* Bring phy back */ + sata_phy_resume(ap); /* TODO: phy layer with polling, timeouts, etc. */ - if (ata_port_offline(ap)) { + if (!sata_dev_present(ap)) { *class = ATA_DEV_NONE; DPRINTK("EXIT, link offline\n"); return 0; } if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { - ata_port_printk(ap, KERN_ERR, - "COMRESET failed (device not ready)\n"); + if (verbose) + printk(KERN_ERR "ata%u: COMRESET failed " + "(device not ready)\n", ap->id); + else + DPRINTK("EXIT, device not ready\n"); return -EIO; } @@ -2794,28 +2297,27 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) * the device might have been reset more than once using * different reset methods before postreset is invoked. * + * This function is to be used as standard callback for + * ata_drive_*_reset(). + * * LOCKING: * Kernel thread context (may sleep) */ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) { - u32 serror; - DPRINTK("ENTER\n"); - /* print link status */ - sata_print_link_status(ap); + /* set cable type if it isn't already set */ + if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA) + ap->cbl = ATA_CBL_SATA; - /* clear SError */ - if (sata_scr_read(ap, SCR_ERROR, &serror) == 0) - sata_scr_write(ap, SCR_ERROR, serror); + /* print link status */ + if (ap->cbl == ATA_CBL_SATA) + sata_print_link_status(ap); /* re-enable interrupts */ - if (!ap->ops->error_handler) { - /* FIXME: hack. create a hook instead */ - if (ap->ioaddr.ctl_addr) - ata_irq_on(ap); - } + if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ + ata_irq_on(ap); /* is double-select really necessary? */ if (classes[0] != ATA_DEV_NONE) @@ -2840,8 +2342,127 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) DPRINTK("EXIT\n"); } +/** + * ata_std_probe_reset - standard probe reset method + * @ap: prot to perform probe-reset + * @classes: resulting classes of attached devices + * + * The stock off-the-shelf ->probe_reset method. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes) +{ + ata_reset_fn_t hardreset; + + hardreset = NULL; + if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) + hardreset = sata_std_hardreset; + + return ata_drive_probe_reset(ap, ata_std_probeinit, + ata_std_softreset, hardreset, + ata_std_postreset, classes); +} + +static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset, + ata_postreset_fn_t postreset, + unsigned int *classes) +{ + int i, rc; + + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_UNKNOWN; + + rc = reset(ap, 0, classes); + if (rc) + return rc; + + /* If any class isn't ATA_DEV_UNKNOWN, consider classification + * is complete and convert all ATA_DEV_UNKNOWN to + * ATA_DEV_NONE. + */ + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] != ATA_DEV_UNKNOWN) + break; + + if (i < ATA_MAX_DEVICES) + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] == ATA_DEV_UNKNOWN) + classes[i] = ATA_DEV_NONE; + + if (postreset) + postreset(ap, classes); + + return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV; +} + +/** + * ata_drive_probe_reset - Perform probe reset with given methods + * @ap: port to reset + * @probeinit: probeinit method (can be NULL) + * @softreset: softreset method (can be NULL) + * @hardreset: hardreset method (can be NULL) + * @postreset: postreset method (can be NULL) + * @classes: resulting classes of attached devices + * + * Reset the specified port and classify attached devices using + * given methods. This function prefers softreset but tries all + * possible reset sequences to reset and classify devices. This + * function is intended to be used for constructing ->probe_reset + * callback by low level drivers. + * + * Reset methods should follow the following rules. + * + * - Return 0 on sucess, -errno on failure. + * - If classification is supported, fill classes[] with + * recognized class codes. + * - If classification is not supported, leave classes[] alone. + * - If verbose is non-zero, print error message on failure; + * otherwise, shut up. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -EINVAL if no reset method is avaliable, -ENODEV + * if classification fails, and any error code from reset + * methods. + */ +int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, + ata_reset_fn_t softreset, ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset, unsigned int *classes) +{ + int rc = -EINVAL; + + if (probeinit) + probeinit(ap); + + if (softreset) { + rc = do_probe_reset(ap, softreset, postreset, classes); + if (rc == 0) + return 0; + } + + if (!hardreset) + return rc; + + rc = do_probe_reset(ap, hardreset, postreset, classes); + if (rc == 0 || rc != -ENODEV) + return rc; + + if (softreset) + rc = do_probe_reset(ap, softreset, postreset, classes); + + return rc; +} + /** * ata_dev_same_device - Determine whether new ID matches configured device + * @ap: port on which the device to compare against resides * @dev: device to compare against * @new_class: class of the new device * @new_id: IDENTIFY page of the new device @@ -2856,16 +2477,17 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) * RETURNS: * 1 if @dev matches @new_class and @new_id, 0 otherwise. */ -static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, - const u16 *new_id) +static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev, + unsigned int new_class, const u16 *new_id) { const u16 *old_id = dev->id; unsigned char model[2][41], serial[2][21]; u64 new_n_sectors; if (dev->class != new_class) { - ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n", - dev->class, new_class); + printk(KERN_INFO + "ata%u: dev %u class mismatch %d != %d\n", + ap->id, dev->devno, dev->class, new_class); return 0; } @@ -2876,22 +2498,24 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, new_n_sectors = ata_id_n_sectors(new_id); if (strcmp(model[0], model[1])) { - ata_dev_printk(dev, KERN_INFO, "model number mismatch " - "'%s' != '%s'\n", model[0], model[1]); + printk(KERN_INFO + "ata%u: dev %u model number mismatch '%s' != '%s'\n", + ap->id, dev->devno, model[0], model[1]); return 0; } if (strcmp(serial[0], serial[1])) { - ata_dev_printk(dev, KERN_INFO, "serial number mismatch " - "'%s' != '%s'\n", serial[0], serial[1]); + printk(KERN_INFO + "ata%u: dev %u serial number mismatch '%s' != '%s'\n", + ap->id, dev->devno, serial[0], serial[1]); return 0; } if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) { - ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch " - "%llu != %llu\n", - (unsigned long long)dev->n_sectors, - (unsigned long long)new_n_sectors); + printk(KERN_INFO + "ata%u: dev %u n_sectors mismatch %llu != %llu\n", + ap->id, dev->devno, (unsigned long long)dev->n_sectors, + (unsigned long long)new_n_sectors); return 0; } @@ -2900,6 +2524,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, /** * ata_dev_revalidate - Revalidate ATA device + * @ap: port on which the device to revalidate resides * @dev: device to revalidate * @post_reset: is this revalidation after reset? * @@ -2912,37 +2537,40 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, * RETURNS: * 0 on success, negative errno otherwise */ -int ata_dev_revalidate(struct ata_device *dev, int post_reset) +int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, + int post_reset) { - unsigned int class = dev->class; - u16 *id = (void *)dev->ap->sector_buf; + unsigned int class; + u16 *id; int rc; - if (!ata_dev_enabled(dev)) { - rc = -ENODEV; - goto fail; - } + if (!ata_dev_present(dev)) + return -ENODEV; - /* read ID data */ - rc = ata_dev_read_id(dev, &class, post_reset, id); + class = dev->class; + id = NULL; + + /* allocate & read ID data */ + rc = ata_dev_read_id(ap, dev, &class, post_reset, &id); if (rc) goto fail; /* is the device still there? */ - if (!ata_dev_same_device(dev, class, id)) { + if (!ata_dev_same_device(ap, dev, class, id)) { rc = -ENODEV; goto fail; } - memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS); + kfree(dev->id); + dev->id = id; /* configure device according to the new ID */ - rc = ata_dev_configure(dev, 0); - if (rc == 0) - return 0; + return ata_dev_configure(ap, dev, 0); fail: - ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc); + printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n", + ap->id, dev->devno, rc); + kfree(id); return rc; } @@ -2998,14 +2626,6 @@ static int ata_dma_blacklisted(const struct ata_device *dev) unsigned int nlen, rlen; int i; - /* We don't support polling DMA. - * DMA blacklist those ATAPI devices with CDB-intr (and use PIO) - * if the LLDD handles only interrupts in the HSM_ST_LAST state. - */ - if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) && - (dev->flags & ATA_DFLAG_CDB_INTR)) - return 1; - ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num)); ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS, @@ -3026,6 +2646,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev) /** * ata_dev_xfermask - Compute supported xfermask of the given device + * @ap: Port on which the device to compute xfermask for resides * @dev: Device to compute xfermask for * * Compute supported xfermask of @dev and store it in @@ -3040,61 +2661,49 @@ static int ata_dma_blacklisted(const struct ata_device *dev) * LOCKING: * None. */ -static void ata_dev_xfermask(struct ata_device *dev) +static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) { - struct ata_port *ap = dev->ap; struct ata_host_set *hs = ap->host_set; unsigned long xfer_mask; int i; - xfer_mask = ata_pack_xfermask(ap->pio_mask, - ap->mwdma_mask, ap->udma_mask); - - /* Apply cable rule here. Don't apply it early because when - * we handle hot plug the cable type can itself change. - */ - if (ap->cbl == ATA_CBL_PATA40) - xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); + xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, + ap->udma_mask); /* FIXME: Use port-wide xfermask for now */ for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *d = &ap->device[i]; - - if (ata_dev_absent(d)) - continue; - - if (ata_dev_disabled(d)) { - /* to avoid violating device selection timing */ - xfer_mask &= ata_pack_xfermask(d->pio_mask, - UINT_MAX, UINT_MAX); + if (!ata_dev_present(d)) continue; - } - - xfer_mask &= ata_pack_xfermask(d->pio_mask, - d->mwdma_mask, d->udma_mask); + xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask, + d->udma_mask); xfer_mask &= ata_id_xfermask(d->id); if (ata_dma_blacklisted(d)) xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); + /* Apply cable rule here. Don't apply it early because when + we handle hot plug the cable type can itself change */ + if (ap->cbl == ATA_CBL_PATA40) + xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); } if (ata_dma_blacklisted(dev)) - ata_dev_printk(dev, KERN_WARNING, - "device is on DMA blacklist, disabling DMA\n"); + printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " + "disabling DMA\n", ap->id, dev->devno); if (hs->flags & ATA_HOST_SIMPLEX) { if (hs->simplex_claimed) xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); } - if (ap->ops->mode_filter) xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); - ata_unpack_xfermask(xfer_mask, &dev->pio_mask, - &dev->mwdma_mask, &dev->udma_mask); + ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, + &dev->udma_mask); } /** * ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command + * @ap: Port associated with device @dev * @dev: Device to which command will be sent * * Issue SET FEATURES - XFER MODE command to device @dev @@ -3107,7 +2716,8 @@ static void ata_dev_xfermask(struct ata_device *dev) * 0 on success, AC_ERR_* mask otherwise. */ -static unsigned int ata_dev_set_xfermode(struct ata_device *dev) +static unsigned int ata_dev_set_xfermode(struct ata_port *ap, + struct ata_device *dev) { struct ata_taskfile tf; unsigned int err_mask; @@ -3115,14 +2725,14 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) /* set up set-features taskfile */ DPRINTK("set features - xfer mode\n"); - ata_tf_init(dev, &tf); + ata_tf_init(ap, &tf, dev->devno); tf.command = ATA_CMD_SET_FEATURES; tf.feature = SETFEATURES_XFER; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.protocol = ATA_PROT_NODATA; tf.nsect = dev->xfer_mode; - err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; @@ -3130,6 +2740,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) /** * ata_dev_init_params - Issue INIT DEV PARAMS command + * @ap: Port associated with device @dev * @dev: Device to which command will be sent * @heads: Number of heads (taskfile parameter) * @sectors: Number of sectors (taskfile parameter) @@ -3140,8 +2751,11 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) * RETURNS: * 0 on success, AC_ERR_* mask otherwise. */ -static unsigned int ata_dev_init_params(struct ata_device *dev, - u16 heads, u16 sectors) + +static unsigned int ata_dev_init_params(struct ata_port *ap, + struct ata_device *dev, + u16 heads, + u16 sectors) { struct ata_taskfile tf; unsigned int err_mask; @@ -3153,14 +2767,14 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, /* set up init dev params taskfile */ DPRINTK("init dev params \n"); - ata_tf_init(dev, &tf); + ata_tf_init(ap, &tf, dev->devno); tf.command = ATA_CMD_INIT_DEV_PARAMS; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.protocol = ATA_PROT_NODATA; tf.nsect = sectors; tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ - err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; @@ -3343,7 +2957,6 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) qc->n_elem = 1; qc->orig_n_elem = 1; qc->buf_virt = buf; - qc->nbytes = buflen; sg = qc->__sg; sg_init_one(sg, buf, buflen); @@ -3527,30 +3140,158 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) } /** - * swap_buf_le16 - swap halves of 16-bit words in place - * @buf: Buffer to swap - * @buf_words: Number of 16-bit words in buffer. - * - * Swap halves of 16-bit words if needed to convert from - * little-endian byte order to native cpu byte order, or - * vice-versa. + * ata_poll_qc_complete - turn irq back on and finish qc + * @qc: Command to complete + * @err_mask: ATA status register content * * LOCKING: - * Inherited from caller. + * None. (grabs host lock) */ -void swap_buf_le16(u16 *buf, unsigned int buf_words) + +void ata_poll_qc_complete(struct ata_queued_cmd *qc) { -#ifdef __BIG_ENDIAN - unsigned int i; + struct ata_port *ap = qc->ap; + unsigned long flags; - for (i = 0; i < buf_words; i++) + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_NOINTR; + ata_irq_on(ap); + ata_qc_complete(qc); + spin_unlock_irqrestore(&ap->host_set->lock, flags); +} + +/** + * ata_pio_poll - poll using PIO, depending on current state + * @ap: the target ata_port + * + * LOCKING: + * None. (executing in kernel thread context) + * + * RETURNS: + * timeout value to use + */ + +static unsigned long ata_pio_poll(struct ata_port *ap) +{ + struct ata_queued_cmd *qc; + u8 status; + unsigned int poll_state = HSM_ST_UNKNOWN; + unsigned int reg_state = HSM_ST_UNKNOWN; + + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + + switch (ap->hsm_task_state) { + case HSM_ST: + case HSM_ST_POLL: + poll_state = HSM_ST_POLL; + reg_state = HSM_ST; + break; + case HSM_ST_LAST: + case HSM_ST_LAST_POLL: + poll_state = HSM_ST_LAST_POLL; + reg_state = HSM_ST_LAST; + break; + default: + BUG(); + break; + } + + status = ata_chk_status(ap); + if (status & ATA_BUSY) { + if (time_after(jiffies, ap->pio_task_timeout)) { + qc->err_mask |= AC_ERR_TIMEOUT; + ap->hsm_task_state = HSM_ST_TMOUT; + return 0; + } + ap->hsm_task_state = poll_state; + return ATA_SHORT_PAUSE; + } + + ap->hsm_task_state = reg_state; + return 0; +} + +/** + * ata_pio_complete - check if drive is busy or idle + * @ap: the target ata_port + * + * LOCKING: + * None. (executing in kernel thread context) + * + * RETURNS: + * Non-zero if qc completed, zero otherwise. + */ + +static int ata_pio_complete (struct ata_port *ap) +{ + struct ata_queued_cmd *qc; + u8 drv_stat; + + /* + * This is purely heuristic. This is a fast path. Sometimes when + * we enter, BSY will be cleared in a chk-status or two. If not, + * the drive is probably seeking or something. Snooze for a couple + * msecs, then chk-status again. If still busy, fall back to + * HSM_ST_POLL state. + */ + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { + msleep(2); + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { + ap->hsm_task_state = HSM_ST_LAST_POLL; + ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; + return 0; + } + } + + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + + drv_stat = ata_wait_idle(ap); + if (!ata_ok(drv_stat)) { + qc->err_mask |= __ac_err_mask(drv_stat); + ap->hsm_task_state = HSM_ST_ERR; + return 0; + } + + ap->hsm_task_state = HSM_ST_IDLE; + + WARN_ON(qc->err_mask); + ata_poll_qc_complete(qc); + + /* another command may start at this point */ + + return 1; +} + + +/** + * swap_buf_le16 - swap halves of 16-bit words in place + * @buf: Buffer to swap + * @buf_words: Number of 16-bit words in buffer. + * + * Swap halves of 16-bit words if needed to convert from + * little-endian byte order to native cpu byte order, or + * vice-versa. + * + * LOCKING: + * Inherited from caller. + */ +void swap_buf_le16(u16 *buf, unsigned int buf_words) +{ +#ifdef __BIG_ENDIAN + unsigned int i; + + for (i = 0; i < buf_words; i++) buf[i] = le16_to_cpu(buf[i]); #endif /* __BIG_ENDIAN */ } /** * ata_mmio_data_xfer - Transfer data by MMIO - * @adev: device for this I/O + * @ap: port to read/write * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -3561,10 +3302,9 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) * Inherited from caller. */ -void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, + unsigned int buflen, int write_data) { - struct ata_port *ap = adev->ap; unsigned int i; unsigned int words = buflen >> 1; u16 *buf16 = (u16 *) buf; @@ -3596,7 +3336,7 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, /** * ata_pio_data_xfer - Transfer data by PIO - * @adev: device to target + * @ap: port to read/write * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -3607,10 +3347,9 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, * Inherited from caller. */ -void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, + unsigned int buflen, int write_data) { - struct ata_port *ap = adev->ap; unsigned int words = buflen >> 1; /* Transfer multiple of 2 bytes */ @@ -3635,29 +3374,38 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, } /** - * ata_pio_data_xfer_noirq - Transfer data by PIO - * @adev: device to target + * ata_data_xfer - Transfer data from/to the data register. + * @ap: port to read/write * @buf: data buffer * @buflen: buffer length - * @write_data: read/write + * @do_write: read/write * - * Transfer data from/to the device data register by PIO. Do the - * transfer with interrupts disabled. + * Transfer data from/to the device data register. * * LOCKING: * Inherited from caller. */ -void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, + unsigned int buflen, int do_write) { - unsigned long flags; - local_irq_save(flags); - ata_pio_data_xfer(adev, buf, buflen, write_data); - local_irq_restore(flags); + /* Make the crap hardware pay the costs not the good stuff */ + if (unlikely(ap->flags & ATA_FLAG_IRQ_MASK)) { + unsigned long flags; + local_irq_save(flags); + if (ap->flags & ATA_FLAG_MMIO) + ata_mmio_data_xfer(ap, buf, buflen, do_write); + else + ata_pio_data_xfer(ap, buf, buflen, do_write); + local_irq_restore(flags); + } else { + if (ap->flags & ATA_FLAG_MMIO) + ata_mmio_data_xfer(ap, buf, buflen, do_write); + else + ata_pio_data_xfer(ap, buf, buflen, do_write); + } } - /** * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data. * @qc: Command on going @@ -3687,24 +3435,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; - DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - - if (PageHighMem(page)) { - unsigned long flags; - - /* FIXME: use a bounce buffer */ - local_irq_save(flags); - buf = kmap_atomic(page, KM_IRQ0); - - /* do the actual data transfer */ - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); - - kunmap_atomic(buf, KM_IRQ0); - local_irq_restore(flags); - } else { - buf = page_address(page); - ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); - } + buf = kmap(page) + offset; qc->cursect++; qc->cursg_ofs++; @@ -3713,68 +3444,14 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) qc->cursg++; qc->cursg_ofs = 0; } -} -/** - * ata_pio_sectors - Transfer one or many 512-byte sectors. - * @qc: Command on going - * - * Transfer one or many ATA_SECT_SIZE of data from/to the - * ATA device for the DRQ request. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_pio_sectors(struct ata_queued_cmd *qc) -{ - if (is_multi_taskfile(&qc->tf)) { - /* READ/WRITE MULTIPLE */ - unsigned int nsect; - - WARN_ON(qc->dev->multi_count == 0); - - nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count); - while (nsect--) - ata_pio_sector(qc); - } else - ata_pio_sector(qc); -} - -/** - * atapi_send_cdb - Write CDB bytes to hardware - * @ap: Port to which ATAPI device is attached. - * @qc: Taskfile currently active - * - * When device has indicated its readiness to accept - * a CDB, this function is called. Send the CDB. - * - * LOCKING: - * caller. - */ - -static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) -{ - /* send SCSI cdb */ - DPRINTK("send cdb\n"); - WARN_ON(qc->dev->cdb_len < 12); + DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - ap->ops->data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); - ata_altstatus(ap); /* flush */ + /* do the actual data transfer */ + do_write = (qc->tf.flags & ATA_TFLAG_WRITE); + ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write); - switch (qc->tf.protocol) { - case ATA_PROT_ATAPI: - ap->hsm_task_state = HSM_ST; - break; - case ATA_PROT_ATAPI_NODATA: - ap->hsm_task_state = HSM_ST_LAST; - break; - case ATA_PROT_ATAPI_DMA: - ap->hsm_task_state = HSM_ST_LAST; - /* initiate bmdma */ - ap->ops->bmdma_start(qc); - break; - } + kunmap(page); } /** @@ -3815,11 +3492,11 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) unsigned int i; if (words) /* warning if bytes > 1 */ - ata_dev_printk(qc->dev, KERN_WARNING, - "%u bytes trailing data\n", bytes); + printk(KERN_WARNING "ata%u: %u bytes trailing data\n", + ap->id, bytes); for (i = 0; i < words; i++) - ap->ops->data_xfer(qc->dev, (unsigned char*)pad_buf, 2, do_write); + ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); ap->hsm_task_state = HSM_ST_LAST; return; @@ -3840,24 +3517,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) /* don't cross page boundaries */ count = min(count, (unsigned int)PAGE_SIZE - offset); - DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - - if (PageHighMem(page)) { - unsigned long flags; - - /* FIXME: use bounce buffer */ - local_irq_save(flags); - buf = kmap_atomic(page, KM_IRQ0); - - /* do the actual data transfer */ - ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); - - kunmap_atomic(buf, KM_IRQ0); - local_irq_restore(flags); - } else { - buf = page_address(page); - ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); - } + buf = kmap(page) + offset; bytes -= count; qc->curbytes += count; @@ -3868,6 +3528,13 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) qc->cursg_ofs = 0; } + DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); + + /* do the actual data transfer */ + ata_data_xfer(ap, buf, count, do_write); + + kunmap(page); + if (bytes) goto next_sg; } @@ -3889,16 +3556,10 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) unsigned int ireason, bc_lo, bc_hi, bytes; int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; - /* Abuse qc->result_tf for temp storage of intermediate TF - * here to save some kernel stack usage. - * For normal completion, qc->result_tf is not relevant. For - * error, qc->result_tf is later overwritten by ata_qc_complete(). - * So, the correctness of qc->result_tf is not affected. - */ - ap->ops->tf_read(ap, &qc->result_tf); - ireason = qc->result_tf.nsect; - bc_lo = qc->result_tf.lbam; - bc_hi = qc->result_tf.lbah; + ap->ops->tf_read(ap, &qc->tf); + ireason = qc->tf.nsect; + bc_lo = qc->tf.lbam; + bc_hi = qc->tf.lbah; bytes = (bc_hi << 8) | bc_lo; /* shall be cleared to zero, indicating xfer of data */ @@ -3910,365 +3571,307 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) if (do_write != i_write) goto err_out; - VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes); - __atapi_pio_bytes(qc, bytes); return; err_out: - ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n"); + printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n", + ap->id, dev->devno); qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; } /** - * ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue. + * ata_pio_block - start PIO on a block * @ap: the target ata_port - * @qc: qc on going * - * RETURNS: - * 1 if ok in workqueue, 0 otherwise. + * LOCKING: + * None. (executing in kernel thread context) */ -static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc) +static void ata_pio_block(struct ata_port *ap) { - if (qc->tf.flags & ATA_TFLAG_POLLING) - return 1; - - if (ap->hsm_task_state == HSM_ST_FIRST) { - if (qc->tf.protocol == ATA_PROT_PIO && - (qc->tf.flags & ATA_TFLAG_WRITE)) - return 1; + struct ata_queued_cmd *qc; + u8 status; - if (is_atapi_taskfile(&qc->tf) && - !(qc->dev->flags & ATA_DFLAG_CDB_INTR)) - return 1; + /* + * This is purely heuristic. This is a fast path. + * Sometimes when we enter, BSY will be cleared in + * a chk-status or two. If not, the drive is probably seeking + * or something. Snooze for a couple msecs, then + * chk-status again. If still busy, fall back to + * HSM_ST_POLL state. + */ + status = ata_busy_wait(ap, ATA_BUSY, 5); + if (status & ATA_BUSY) { + msleep(2); + status = ata_busy_wait(ap, ATA_BUSY, 10); + if (status & ATA_BUSY) { + ap->hsm_task_state = HSM_ST_POLL; + ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; + return; + } } - return 0; -} - -/** - * ata_hsm_qc_complete - finish a qc running on standard HSM - * @qc: Command to complete - * @in_wq: 1 if called from workqueue, 0 otherwise - * - * Finish @qc which is running on standard HSM. - * - * LOCKING: - * If @in_wq is zero, spin_lock_irqsave(host_set lock). - * Otherwise, none on entry and grabs host lock. - */ -static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) -{ - struct ata_port *ap = qc->ap; - unsigned long flags; - - if (ap->ops->error_handler) { - if (in_wq) { - spin_lock_irqsave(ap->lock, flags); + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); - /* EH might have kicked in while host_set lock - * is released. - */ - qc = ata_qc_from_tag(ap, qc->tag); - if (qc) { - if (likely(!(qc->err_mask & AC_ERR_HSM))) { - ata_irq_on(ap); - ata_qc_complete(qc); - } else - ata_port_freeze(ap); - } + /* check error */ + if (status & (ATA_ERR | ATA_DF)) { + qc->err_mask |= AC_ERR_DEV; + ap->hsm_task_state = HSM_ST_ERR; + return; + } - spin_unlock_irqrestore(ap->lock, flags); - } else { - if (likely(!(qc->err_mask & AC_ERR_HSM))) - ata_qc_complete(qc); - else - ata_port_freeze(ap); + /* transfer data if any */ + if (is_atapi_taskfile(&qc->tf)) { + /* DRQ=0 means no more data to transfer */ + if ((status & ATA_DRQ) == 0) { + ap->hsm_task_state = HSM_ST_LAST; + return; } + + atapi_pio_bytes(qc); } else { - if (in_wq) { - spin_lock_irqsave(ap->lock, flags); - ata_irq_on(ap); - ata_qc_complete(qc); - spin_unlock_irqrestore(ap->lock, flags); - } else - ata_qc_complete(qc); + /* handle BSY=0, DRQ=0 as error */ + if ((status & ATA_DRQ) == 0) { + qc->err_mask |= AC_ERR_HSM; + ap->hsm_task_state = HSM_ST_ERR; + return; + } + + ata_pio_sector(qc); } ata_altstatus(ap); /* flush */ } -/** - * ata_hsm_move - move the HSM to the next state. - * @ap: the target ata_port - * @qc: qc on going - * @status: current device status - * @in_wq: 1 if called from workqueue, 0 otherwise - * - * RETURNS: - * 1 when poll next status needed, 0 otherwise. - */ -int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, - u8 status, int in_wq) +static void ata_pio_error(struct ata_port *ap) { - unsigned long flags = 0; - int poll_next; + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); - WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0); + if (qc->tf.command != ATA_CMD_PACKET) + printk(KERN_WARNING "ata%u: PIO error\n", ap->id); - /* Make sure ata_qc_issue_prot() does not throw things - * like DMA polling into the workqueue. Notice that - * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING). + /* make sure qc->err_mask is available to + * know what's wrong and recover */ - WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, qc)); + WARN_ON(qc->err_mask == 0); -fsm_start: - DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, ap->hsm_task_state, status); + ap->hsm_task_state = HSM_ST_IDLE; - switch (ap->hsm_task_state) { - case HSM_ST_FIRST: - /* Send first data block or PACKET CDB */ + ata_poll_qc_complete(qc); +} - /* If polling, we will stay in the work queue after - * sending the data. Otherwise, interrupt handler - * takes over after sending the data. - */ - poll_next = (qc->tf.flags & ATA_TFLAG_POLLING); - - /* check device status */ - if (unlikely((status & ATA_DRQ) == 0)) { - /* handle BSY=0, DRQ=0 as error */ - if (likely(status & (ATA_ERR | ATA_DF))) - /* device stops HSM for abort/error */ - qc->err_mask |= AC_ERR_DEV; - else - /* HSM violation. Let EH handle this */ - qc->err_mask |= AC_ERR_HSM; +static void ata_pio_task(void *_data) +{ + struct ata_port *ap = _data; + unsigned long timeout; + int qc_completed; - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } +fsm_start: + timeout = 0; + qc_completed = 0; - /* Device should not ask for data transfer (DRQ=1) - * when it finds something wrong. - * We ignore DRQ here and stop the HSM by - * changing hsm_task_state to HSM_ST_ERR and - * let the EH abort the command or reset the device. - */ - if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); - qc->err_mask |= AC_ERR_HSM; - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } + switch (ap->hsm_task_state) { + case HSM_ST_IDLE: + return; - /* Send the CDB (atapi) or the first data block (ata pio out). - * During the state transition, interrupt handler shouldn't - * be invoked before the data transfer is complete and - * hsm_task_state is changed. Hence, the following locking. - */ - if (in_wq) - spin_lock_irqsave(ap->lock, flags); + case HSM_ST: + ata_pio_block(ap); + break; - if (qc->tf.protocol == ATA_PROT_PIO) { - /* PIO data out protocol. - * send first data block. - */ + case HSM_ST_LAST: + qc_completed = ata_pio_complete(ap); + break; - /* ata_pio_sectors() might change the state - * to HSM_ST_LAST. so, the state is changed here - * before ata_pio_sectors(). - */ - ap->hsm_task_state = HSM_ST; - ata_pio_sectors(qc); - ata_altstatus(ap); /* flush */ - } else - /* send CDB */ - atapi_send_cdb(ap, qc); - - if (in_wq) - spin_unlock_irqrestore(ap->lock, flags); - - /* if polling, ata_pio_task() handles the rest. - * otherwise, interrupt handler takes over from here. - */ + case HSM_ST_POLL: + case HSM_ST_LAST_POLL: + timeout = ata_pio_poll(ap); break; - case HSM_ST: - /* complete command or read/write the data register */ - if (qc->tf.protocol == ATA_PROT_ATAPI) { - /* ATAPI PIO protocol */ - if ((status & ATA_DRQ) == 0) { - /* No more data to transfer or device error. - * Device error will be tagged in HSM_ST_LAST. - */ - ap->hsm_task_state = HSM_ST_LAST; - goto fsm_start; - } + case HSM_ST_TMOUT: + case HSM_ST_ERR: + ata_pio_error(ap); + return; + } - /* Device should not ask for data transfer (DRQ=1) - * when it finds something wrong. - * We ignore DRQ here and stop the HSM by - * changing hsm_task_state to HSM_ST_ERR and - * let the EH abort the command or reset the device. - */ - if (unlikely(status & (ATA_ERR | ATA_DF))) { - printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", - ap->id, status); - qc->err_mask |= AC_ERR_HSM; - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } + if (timeout) + ata_port_queue_task(ap, ata_pio_task, ap, timeout); + else if (!qc_completed) + goto fsm_start; +} - atapi_pio_bytes(qc); +/** + * atapi_packet_task - Write CDB bytes to hardware + * @_data: Port to which ATAPI device is attached. + * + * When device has indicated its readiness to accept + * a CDB, this function is called. Send the CDB. + * If DMA is to be performed, exit immediately. + * Otherwise, we are in polling mode, so poll + * status under operation succeeds or fails. + * + * LOCKING: + * Kernel thread context (may sleep) + */ - if (unlikely(ap->hsm_task_state == HSM_ST_ERR)) - /* bad ireason reported by device */ - goto fsm_start; +static void atapi_packet_task(void *_data) +{ + struct ata_port *ap = _data; + struct ata_queued_cmd *qc; + u8 status; - } else { - /* ATA PIO protocol */ - if (unlikely((status & ATA_DRQ) == 0)) { - /* handle BSY=0, DRQ=0 as error */ - if (likely(status & (ATA_ERR | ATA_DF))) - /* device stops HSM for abort/error */ - qc->err_mask |= AC_ERR_DEV; - else - /* HSM violation. Let EH handle this */ - qc->err_mask |= AC_ERR_HSM; - - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); - /* For PIO reads, some devices may ask for - * data transfer (DRQ=1) alone with ERR=1. - * We respect DRQ here and transfer one - * block of junk data before changing the - * hsm_task_state to HSM_ST_ERR. - * - * For PIO writes, ERR=1 DRQ=1 doesn't make - * sense since the data block has been - * transferred to the device. - */ - if (unlikely(status & (ATA_ERR | ATA_DF))) { - /* data might be corrputed */ - qc->err_mask |= AC_ERR_DEV; - - if (!(qc->tf.flags & ATA_TFLAG_WRITE)) { - ata_pio_sectors(qc); - ata_altstatus(ap); - status = ata_wait_idle(ap); - } - - if (status & (ATA_BUSY | ATA_DRQ)) - qc->err_mask |= AC_ERR_HSM; - - /* ata_pio_sectors() might change the - * state to HSM_ST_LAST. so, the state - * is changed after ata_pio_sectors(). - */ - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } + /* sleep-wait for BSY to clear */ + DPRINTK("busy wait\n"); + if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) { + qc->err_mask |= AC_ERR_TIMEOUT; + goto err_out; + } - ata_pio_sectors(qc); + /* make sure DRQ is set */ + status = ata_chk_status(ap); + if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { + qc->err_mask |= AC_ERR_HSM; + goto err_out; + } - if (ap->hsm_task_state == HSM_ST_LAST && - (!(qc->tf.flags & ATA_TFLAG_WRITE))) { - /* all data read */ - ata_altstatus(ap); - status = ata_wait_idle(ap); - goto fsm_start; - } - } + /* send SCSI cdb */ + DPRINTK("send cdb\n"); + WARN_ON(qc->dev->cdb_len < 12); + + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || + qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { + unsigned long flags; + /* Once we're done issuing command and kicking bmdma, + * irq handler takes over. To not lose irq, we need + * to clear NOINTR flag before sending cdb, but + * interrupt handler shouldn't be invoked before we're + * finished. Hence, the following locking. + */ + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_NOINTR; + ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); ata_altstatus(ap); /* flush */ - poll_next = 1; - break; - case HSM_ST_LAST: - if (unlikely(!ata_ok(status))) { - qc->err_mask |= __ac_err_mask(status); - ap->hsm_task_state = HSM_ST_ERR; - goto fsm_start; - } + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) + ap->ops->bmdma_start(qc); /* initiate bmdma */ + spin_unlock_irqrestore(&ap->host_set->lock, flags); + } else { + ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); + ata_altstatus(ap); /* flush */ - /* no more data to transfer */ - DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n", - ap->id, qc->dev->devno, status); + /* PIO commands are handled by polling */ + ap->hsm_task_state = HSM_ST; + ata_port_queue_task(ap, ata_pio_task, ap, 0); + } - WARN_ON(qc->err_mask); + return; - ap->hsm_task_state = HSM_ST_IDLE; +err_out: + ata_poll_qc_complete(qc); +} - /* complete taskfile transaction */ - ata_hsm_qc_complete(qc, in_wq); +/** + * ata_qc_timeout - Handle timeout of queued command + * @qc: Command that timed out + * + * Some part of the kernel (currently, only the SCSI layer) + * has noticed that the active command on port @ap has not + * completed after a specified length of time. Handle this + * condition by disabling DMA (if necessary) and completing + * transactions, with error if necessary. + * + * This also handles the case of the "lost interrupt", where + * for some reason (possibly hardware bug, possibly driver bug) + * an interrupt was not delivered to the driver, even though the + * transaction completed successfully. + * + * LOCKING: + * Inherited from SCSI layer (none, can sleep) + */ - poll_next = 0; - break; +static void ata_qc_timeout(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_host_set *host_set = ap->host_set; + u8 host_stat = 0, drv_stat; + unsigned long flags; - case HSM_ST_ERR: - /* make sure qc->err_mask is available to - * know what's wrong and recover - */ - WARN_ON(qc->err_mask == 0); + DPRINTK("ENTER\n"); - ap->hsm_task_state = HSM_ST_IDLE; + ap->hsm_task_state = HSM_ST_IDLE; - /* complete taskfile transaction */ - ata_hsm_qc_complete(qc, in_wq); + spin_lock_irqsave(&host_set->lock, flags); + + switch (qc->tf.protocol) { + + case ATA_PROT_DMA: + case ATA_PROT_ATAPI_DMA: + host_stat = ap->ops->bmdma_status(ap); + + /* before we do anything else, clear DMA-Start bit */ + ap->ops->bmdma_stop(qc); + + /* fall through */ - poll_next = 0; - break; default: - poll_next = 0; - BUG(); + ata_altstatus(ap); + drv_stat = ata_chk_status(ap); + + /* ack bmdma irq events */ + ap->ops->irq_clear(ap); + + printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n", + ap->id, qc->tf.command, drv_stat, host_stat); + + /* complete taskfile transaction */ + qc->err_mask |= ac_err_mask(drv_stat); + break; } - return poll_next; -} + spin_unlock_irqrestore(&host_set->lock, flags); -static void ata_pio_task(void *_data) -{ - struct ata_queued_cmd *qc = _data; - struct ata_port *ap = qc->ap; - u8 status; - int poll_next; + ata_eh_qc_complete(qc); -fsm_start: - WARN_ON(ap->hsm_task_state == HSM_ST_IDLE); + DPRINTK("EXIT\n"); +} - /* - * This is purely heuristic. This is a fast path. - * Sometimes when we enter, BSY will be cleared in - * a chk-status or two. If not, the drive is probably seeking - * or something. Snooze for a couple msecs, then - * chk-status again. If still busy, queue delayed work. - */ - status = ata_busy_wait(ap, ATA_BUSY, 5); - if (status & ATA_BUSY) { - msleep(2); - status = ata_busy_wait(ap, ATA_BUSY, 10); - if (status & ATA_BUSY) { - ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE); - return; - } - } +/** + * ata_eng_timeout - Handle timeout of queued command + * @ap: Port on which timed-out command is active + * + * Some part of the kernel (currently, only the SCSI layer) + * has noticed that the active command on port @ap has not + * completed after a specified length of time. Handle this + * condition by disabling DMA (if necessary) and completing + * transactions, with error if necessary. + * + * This also handles the case of the "lost interrupt", where + * for some reason (possibly hardware bug, possibly driver bug) + * an interrupt was not delivered to the driver, even though the + * transaction completed successfully. + * + * LOCKING: + * Inherited from SCSI layer (none, can sleep) + */ + +void ata_eng_timeout(struct ata_port *ap) +{ + DPRINTK("ENTER\n"); - /* move the HSM */ - poll_next = ata_hsm_move(ap, qc, status, 1); + ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag)); - /* another command or interrupt handler - * may be running at this point. - */ - if (poll_next) - goto fsm_start; + DPRINTK("EXIT\n"); } /** @@ -4285,14 +3888,9 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) struct ata_queued_cmd *qc = NULL; unsigned int i; - /* no command while frozen */ - if (unlikely(ap->flags & ATA_FLAG_FROZEN)) - return NULL; - - /* the last tag is reserved for internal command. */ - for (i = 0; i < ATA_MAX_QUEUE - 1; i++) - if (!test_and_set_bit(i, &ap->qc_allocated)) { - qc = __ata_qc_from_tag(ap, i); + for (i = 0; i < ATA_MAX_QUEUE; i++) + if (!test_and_set_bit(i, &ap->qactive)) { + qc = ata_qc_from_tag(ap, i); break; } @@ -4304,15 +3902,16 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) /** * ata_qc_new_init - Request an available ATA command, and initialize it + * @ap: Port associated with device @dev * @dev: Device from whom we request an available command structure * * LOCKING: * None. */ -struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) +struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, + struct ata_device *dev) { - struct ata_port *ap = dev->ap; struct ata_queued_cmd *qc; qc = ata_qc_new(ap); @@ -4347,153 +3946,36 @@ void ata_qc_free(struct ata_queued_cmd *qc) qc->flags = 0; tag = qc->tag; if (likely(ata_tag_valid(tag))) { + if (tag == ap->active_tag) + ap->active_tag = ATA_TAG_POISON; qc->tag = ATA_TAG_POISON; - clear_bit(tag, &ap->qc_allocated); + clear_bit(tag, &ap->qactive); } } void __ata_qc_complete(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) ata_sg_clean(qc); - /* command should be marked inactive atomically with qc completion */ - if (qc->tf.protocol == ATA_PROT_NCQ) - ap->sactive &= ~(1 << qc->tag); - else - ap->active_tag = ATA_TAG_POISON; - /* atapi: mark qc as inactive to prevent the interrupt handler * from completing the command twice later, before the error handler * is called. (when rc != 0 and atapi request sense is needed) */ qc->flags &= ~ATA_QCFLAG_ACTIVE; - ap->qc_active &= ~(1 << qc->tag); /* call completion callback */ qc->complete_fn(qc); } -/** - * ata_qc_complete - Complete an active ATA command - * @qc: Command to complete - * @err_mask: ATA Status register contents - * - * Indicate to the mid and upper layers that an ATA - * command has completed, with either an ok or not-ok status. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - /* XXX: New EH and old EH use different mechanisms to - * synchronize EH with regular execution path. - * - * In new EH, a failed qc is marked with ATA_QCFLAG_FAILED. - * Normal execution path is responsible for not accessing a - * failed qc. libata core enforces the rule by returning NULL - * from ata_qc_from_tag() for failed qcs. - * - * Old EH depends on ata_qc_complete() nullifying completion - * requests if ATA_QCFLAG_EH_SCHEDULED is set. Old EH does - * not synchronize with interrupt handler. Only PIO task is - * taken care of. - */ - if (ap->ops->error_handler) { - WARN_ON(ap->flags & ATA_FLAG_FROZEN); - - if (unlikely(qc->err_mask)) - qc->flags |= ATA_QCFLAG_FAILED; - - if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { - if (!ata_tag_internal(qc->tag)) { - /* always fill result TF for failed qc */ - ap->ops->tf_read(ap, &qc->result_tf); - ata_qc_schedule_eh(qc); - return; - } - } - - /* read result TF if requested */ - if (qc->flags & ATA_QCFLAG_RESULT_TF) - ap->ops->tf_read(ap, &qc->result_tf); - - __ata_qc_complete(qc); - } else { - if (qc->flags & ATA_QCFLAG_EH_SCHEDULED) - return; - - /* read result TF if failed or requested */ - if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) - ap->ops->tf_read(ap, &qc->result_tf); - - __ata_qc_complete(qc); - } -} - -/** - * ata_qc_complete_multiple - Complete multiple qcs successfully - * @ap: port in question - * @qc_active: new qc_active mask - * @finish_qc: LLDD callback invoked before completing a qc - * - * Complete in-flight commands. This functions is meant to be - * called from low-level driver's interrupt routine to complete - * requests normally. ap->qc_active and @qc_active is compared - * and commands are completed accordingly. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Number of completed commands on success, -errno otherwise. - */ -int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, - void (*finish_qc)(struct ata_queued_cmd *)) -{ - int nr_done = 0; - u32 done_mask; - int i; - - done_mask = ap->qc_active ^ qc_active; - - if (unlikely(done_mask & qc_active)) { - ata_port_printk(ap, KERN_ERR, "illegal qc_active transition " - "(%08x->%08x)\n", ap->qc_active, qc_active); - return -EINVAL; - } - - for (i = 0; i < ATA_MAX_QUEUE; i++) { - struct ata_queued_cmd *qc; - - if (!(done_mask & (1 << i))) - continue; - - if ((qc = ata_qc_from_tag(ap, i))) { - if (finish_qc) - finish_qc(qc); - ata_qc_complete(qc); - nr_done++; - } - } - - return nr_done; -} - static inline int ata_should_dma_map(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; switch (qc->tf.protocol) { - case ATA_PROT_NCQ: case ATA_PROT_DMA: case ATA_PROT_ATAPI_DMA: return 1; @@ -4528,22 +4010,8 @@ void ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - /* Make sure only one non-NCQ command is outstanding. The - * check is skipped for old EH because it reuses active qc to - * request ATAPI sense. - */ - WARN_ON(ap->ops->error_handler && ata_tag_valid(ap->active_tag)); - - if (qc->tf.protocol == ATA_PROT_NCQ) { - WARN_ON(ap->sactive & (1 << qc->tag)); - ap->sactive |= 1 << qc->tag; - } else { - WARN_ON(ap->sactive); - ap->active_tag = qc->tag; - } - + qc->ap->active_tag = qc->tag; qc->flags |= ATA_QCFLAG_ACTIVE; - ap->qc_active |= 1 << qc->tag; if (ata_should_dma_map(qc)) { if (qc->flags & ATA_QCFLAG_SG) { @@ -4593,105 +4061,43 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - /* Use polling pio if the LLD doesn't handle - * interrupt driven pio and atapi CDB interrupt. - */ - if (ap->flags & ATA_FLAG_PIO_POLLING) { - switch (qc->tf.protocol) { - case ATA_PROT_PIO: - case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: - qc->tf.flags |= ATA_TFLAG_POLLING; - break; - case ATA_PROT_ATAPI_DMA: - if (qc->dev->flags & ATA_DFLAG_CDB_INTR) - /* see ata_dma_blacklisted() */ - BUG(); - break; - default: - break; - } - } - - /* select the device */ ata_dev_select(ap, qc->dev->devno, 1, 0); - /* start the command */ - switch (qc->tf.protocol) { - case ATA_PROT_NODATA: - if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_qc_set_polling(qc); - - ata_tf_to_host(ap, &qc->tf); - ap->hsm_task_state = HSM_ST_LAST; - - if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_port_queue_task(ap, ata_pio_task, qc, 0); - - break; - - case ATA_PROT_DMA: - WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING); - - ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ - ap->ops->bmdma_setup(qc); /* set up bmdma */ - ap->ops->bmdma_start(qc); /* initiate bmdma */ - ap->hsm_task_state = HSM_ST_LAST; - break; - - case ATA_PROT_PIO: - if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_qc_set_polling(qc); - - ata_tf_to_host(ap, &qc->tf); - - if (qc->tf.flags & ATA_TFLAG_WRITE) { - /* PIO data out protocol */ - ap->hsm_task_state = HSM_ST_FIRST; - ata_port_queue_task(ap, ata_pio_task, qc, 0); - - /* always send first data block using - * the ata_pio_task() codepath. - */ - } else { - /* PIO data in protocol */ - ap->hsm_task_state = HSM_ST; - - if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + switch (qc->tf.protocol) { + case ATA_PROT_NODATA: + ata_tf_to_host(ap, &qc->tf); + break; - /* if polling, ata_pio_task() handles the rest. - * otherwise, interrupt handler takes over from here. - */ - } + case ATA_PROT_DMA: + ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ + ap->ops->bmdma_setup(qc); /* set up bmdma */ + ap->ops->bmdma_start(qc); /* initiate bmdma */ + break; + case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ + ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); + ap->hsm_task_state = HSM_ST; + ata_port_queue_task(ap, ata_pio_task, ap, 0); break; case ATA_PROT_ATAPI: - case ATA_PROT_ATAPI_NODATA: - if (qc->tf.flags & ATA_TFLAG_POLLING) - ata_qc_set_polling(qc); - + ata_qc_set_polling(qc); ata_tf_to_host(ap, &qc->tf); + ata_port_queue_task(ap, atapi_packet_task, ap, 0); + break; - ap->hsm_task_state = HSM_ST_FIRST; - - /* send cdb by polling if no cdb interrupt */ - if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || - (qc->tf.flags & ATA_TFLAG_POLLING)) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + case ATA_PROT_ATAPI_NODATA: + ap->flags |= ATA_FLAG_NOINTR; + ata_tf_to_host(ap, &qc->tf); + ata_port_queue_task(ap, atapi_packet_task, ap, 0); break; case ATA_PROT_ATAPI_DMA: - WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING); - + ap->flags |= ATA_FLAG_NOINTR; ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ ap->ops->bmdma_setup(qc); /* set up bmdma */ - ap->hsm_task_state = HSM_ST_FIRST; - - /* send cdb by polling if no cdb interrupt */ - if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) - ata_port_queue_task(ap, ata_pio_task, qc, 0); + ata_port_queue_task(ap, atapi_packet_task, ap, 0); break; default: @@ -4721,66 +4127,52 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) inline unsigned int ata_host_intr (struct ata_port *ap, struct ata_queued_cmd *qc) { - u8 status, host_stat = 0; + u8 status, host_stat; - VPRINTK("ata%u: protocol %d task_state %d\n", - ap->id, qc->tf.protocol, ap->hsm_task_state); + switch (qc->tf.protocol) { - /* Check whether we are expecting interrupt in this state */ - switch (ap->hsm_task_state) { - case HSM_ST_FIRST: - /* Some pre-ATAPI-4 devices assert INTRQ - * at this state when ready to receive CDB. - */ + case ATA_PROT_DMA: + case ATA_PROT_ATAPI_DMA: + case ATA_PROT_ATAPI: + /* check status of DMA engine */ + host_stat = ap->ops->bmdma_status(ap); + VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat); - /* Check the ATA_DFLAG_CDB_INTR flag is enough here. - * The flag was turned on only for atapi devices. - * No need to check is_atapi_taskfile(&qc->tf) again. - */ - if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) + /* if it's not our irq... */ + if (!(host_stat & ATA_DMA_INTR)) goto idle_irq; + + /* before we do anything else, clear DMA-Start bit */ + ap->ops->bmdma_stop(qc); + + /* fall through */ + + case ATA_PROT_ATAPI_NODATA: + case ATA_PROT_NODATA: + /* check altstatus */ + status = ata_altstatus(ap); + if (status & ATA_BUSY) + goto idle_irq; + + /* check main status, clearing INTRQ */ + status = ata_chk_status(ap); + if (unlikely(status & ATA_BUSY)) + goto idle_irq; + DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", + ap->id, qc->tf.protocol, status); + + /* ack bmdma irq events */ + ap->ops->irq_clear(ap); + + /* complete taskfile transaction */ + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); break; - case HSM_ST_LAST: - if (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA) { - /* check status of DMA engine */ - host_stat = ap->ops->bmdma_status(ap); - VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat); - - /* if it's not our irq... */ - if (!(host_stat & ATA_DMA_INTR)) - goto idle_irq; - - /* before we do anything else, clear DMA-Start bit */ - ap->ops->bmdma_stop(qc); - - if (unlikely(host_stat & ATA_DMA_ERR)) { - /* error when transfering data to/from memory */ - qc->err_mask |= AC_ERR_HOST_BUS; - ap->hsm_task_state = HSM_ST_ERR; - } - } - break; - case HSM_ST: - break; + default: goto idle_irq; } - /* check altstatus */ - status = ata_altstatus(ap); - if (status & ATA_BUSY) - goto idle_irq; - - /* check main status, clearing INTRQ */ - status = ata_chk_status(ap); - if (unlikely(status & ATA_BUSY)) - goto idle_irq; - - /* ack bmdma irq events */ - ap->ops->irq_clear(ap); - - ata_hsm_move(ap, qc, status, 0); return 1; /* irq handled */ idle_irq: @@ -4789,7 +4181,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, #ifdef ATA_IRQ_TRAP if ((ap->stats.idle_irq % 1000) == 0) { ata_irq_ack(ap, 0); /* debug trap */ - ata_port_printk(ap, KERN_WARNING, "irq trap\n"); + printk(KERN_WARNING "ata%d: irq trap\n", ap->id); return 1; } #endif @@ -4827,11 +4219,11 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ap = host_set->ports[i]; if (ap && - !(ap->flags & ATA_FLAG_DISABLED)) { + !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && + if (qc && (!(qc->tf.ctl & ATA_NIEN)) && (qc->flags & ATA_QCFLAG_ACTIVE)) handled |= ata_host_intr(ap, qc); } @@ -4842,147 +4234,33 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) return IRQ_RETVAL(handled); } -/** - * sata_scr_valid - test whether SCRs are accessible - * @ap: ATA port to test SCR accessibility for - * - * Test whether SCRs are accessible for @ap. - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if SCRs are accessible, 0 otherwise. - */ -int sata_scr_valid(struct ata_port *ap) -{ - return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read; -} - -/** - * sata_scr_read - read SCR register of the specified port - * @ap: ATA port to read SCR for - * @reg: SCR to read - * @val: Place to store read value - * - * Read SCR register @reg of @ap into *@val. This function is - * guaranteed to succeed if the cable type of the port is SATA - * and the port implements ->scr_read. - * - * LOCKING: - * None. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_read(struct ata_port *ap, int reg, u32 *val) -{ - if (sata_scr_valid(ap)) { - *val = ap->ops->scr_read(ap, reg); - return 0; - } - return -EOPNOTSUPP; -} - -/** - * sata_scr_write - write SCR register of the specified port - * @ap: ATA port to write SCR for - * @reg: SCR to write - * @val: value to write - * - * Write @val to SCR register @reg of @ap. This function is - * guaranteed to succeed if the cable type of the port is SATA - * and the port implements ->scr_read. - * - * LOCKING: - * None. - * - * RETURNS: - * 0 on success, negative errno on failure. - */ -int sata_scr_write(struct ata_port *ap, int reg, u32 val) -{ - if (sata_scr_valid(ap)) { - ap->ops->scr_write(ap, reg, val); - return 0; - } - return -EOPNOTSUPP; -} -/** - * sata_scr_write_flush - write SCR register of the specified port and flush - * @ap: ATA port to write SCR for - * @reg: SCR to write - * @val: value to write - * - * This function is identical to sata_scr_write() except that this - * function performs flush after writing to the register. - * - * LOCKING: - * None. - * - * RETURNS: - * 0 on success, negative errno on failure. +/* + * Execute a 'simple' command, that only consists of the opcode 'cmd' itself, + * without filling any other registers */ -int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) +static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev, + u8 cmd) { - if (sata_scr_valid(ap)) { - ap->ops->scr_write(ap, reg, val); - ap->ops->scr_read(ap, reg); - return 0; - } - return -EOPNOTSUPP; -} + struct ata_taskfile tf; + int err; -/** - * ata_port_online - test whether the given port is online - * @ap: ATA port to test - * - * Test whether @ap is online. Note that this function returns 0 - * if online status of @ap cannot be obtained, so - * ata_port_online(ap) != !ata_port_offline(ap). - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if the port online status is available and online. - */ -int ata_port_online(struct ata_port *ap) -{ - u32 sstatus; + ata_tf_init(ap, &tf, dev->devno); - if (!sata_scr_read(ap, SCR_STATUS, &sstatus) && (sstatus & 0xf) == 0x3) - return 1; - return 0; -} + tf.command = cmd; + tf.flags |= ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_NODATA; -/** - * ata_port_offline - test whether the given port is offline - * @ap: ATA port to test - * - * Test whether @ap is offline. Note that this function returns - * 0 if offline status of @ap cannot be obtained, so - * ata_port_online(ap) != !ata_port_offline(ap). - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if the port offline status is available and offline. - */ -int ata_port_offline(struct ata_port *ap) -{ - u32 sstatus; + err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); + if (err) + printk(KERN_ERR "%s: ata command failed: %d\n", + __FUNCTION__, err); - if (!sata_scr_read(ap, SCR_STATUS, &sstatus) && (sstatus & 0xf) != 0x3) - return 1; - return 0; + return err; } -int ata_flush_cache(struct ata_device *dev) +static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev) { - unsigned int err_mask; u8 cmd; if (!ata_try_flush_cache(dev)) @@ -4993,45 +4271,22 @@ int ata_flush_cache(struct ata_device *dev) else cmd = ATA_CMD_FLUSH; - err_mask = ata_do_simple_cmd(dev, cmd); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to flush cache\n"); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(ap, dev, cmd); } -static int ata_standby_drive(struct ata_device *dev) +static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev) { - unsigned int err_mask; - - err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to standby drive " - "(err_mask=0x%x)\n", err_mask); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1); } -static int ata_start_drive(struct ata_device *dev) +static int ata_start_drive(struct ata_port *ap, struct ata_device *dev) { - unsigned int err_mask; - - err_mask = ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to start drive " - "(err_mask=0x%x)\n", err_mask); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE); } /** * ata_device_resume - wakeup a previously suspended devices + * @ap: port the device is connected to * @dev: the device to resume * * Kick the drive back into action, by sending it an idle immediate @@ -5039,47 +4294,40 @@ static int ata_start_drive(struct ata_device *dev) * and host. * */ -int ata_device_resume(struct ata_device *dev) +int ata_device_resume(struct ata_port *ap, struct ata_device *dev) { - struct ata_port *ap = dev->ap; - if (ap->flags & ATA_FLAG_SUSPENDED) { - struct ata_device *failed_dev; - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000); - ap->flags &= ~ATA_FLAG_SUSPENDED; - while (ata_set_mode(ap, &failed_dev)) - ata_dev_disable(failed_dev); + ata_set_mode(ap); } - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) return 0; if (dev->class == ATA_DEV_ATA) - ata_start_drive(dev); + ata_start_drive(ap, dev); return 0; } /** * ata_device_suspend - prepare a device for suspend + * @ap: port the device is connected to * @dev: the device to suspend * @state: target power management state * * Flush the cache on the drive, if appropriate, then issue a * standbynow command. */ -int ata_device_suspend(struct ata_device *dev, pm_message_t state) +int ata_device_suspend(struct ata_port *ap, struct ata_device *dev, pm_message_t state) { - struct ata_port *ap = dev->ap; - - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) return 0; if (dev->class == ATA_DEV_ATA) - ata_flush_cache(dev); + ata_flush_cache(ap, dev); if (state.event != PM_EVENT_FREEZE) - ata_standby_drive(dev); + ata_standby_drive(ap, dev); ap->flags |= ATA_FLAG_SUSPENDED; return 0; } @@ -5166,38 +4414,6 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) ap->ops->port_stop(ap); } -/** - * ata_dev_init - Initialize an ata_device structure - * @dev: Device structure to initialize - * - * Initialize @dev in preparation for probing. - * - * LOCKING: - * Inherited from caller. - */ -void ata_dev_init(struct ata_device *dev) -{ - struct ata_port *ap = dev->ap; - unsigned long flags; - - /* SATA spd limit is bound to the first device */ - ap->sata_spd_limit = ap->hw_sata_spd_limit; - - /* High bits of dev->flags are used to record warm plug - * requests which occur asynchronously. Synchronize using - * host_set lock. - */ - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_INIT_MASK; - spin_unlock_irqrestore(ap->lock, flags); - - memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0, - sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET); - dev->pio_mask = UINT_MAX; - dev->mwdma_mask = UINT_MAX; - dev->udma_mask = UINT_MAX; -} - /** * ata_host_init - Initialize an ata_port structure * @ap: Structure to initialize @@ -5212,6 +4428,7 @@ void ata_dev_init(struct ata_device *dev) * LOCKING: * Inherited from caller. */ + static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, struct ata_host_set *host_set, const struct ata_probe_ent *ent, unsigned int port_no) @@ -5224,8 +4441,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, host->unique_id = ata_unique_id++; host->max_cmd_len = 12; - ap->lock = &host_set->lock; - ap->flags = ATA_FLAG_DISABLED; + ap->flags = ATA_FLAG_PORT_DISABLED; ap->id = host->unique_id; ap->host = host; ap->ctl = ATA_DEVCTL_OBS; @@ -5239,35 +4455,19 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ap->udma_mask = ent->udma_mask; ap->flags |= ent->host_flags; ap->ops = ent->port_ops; - ap->hw_sata_spd_limit = UINT_MAX; + ap->cbl = ATA_CBL_NONE; ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; -#if defined(ATA_VERBOSE_DEBUG) - /* turn on all debugging levels */ - ap->msg_enable = 0x00FF; -#elif defined(ATA_DEBUG) - ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR; -#else - ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; -#endif - INIT_WORK(&ap->port_task, NULL, NULL); - INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap); - INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap); INIT_LIST_HEAD(&ap->eh_done_q); - init_waitqueue_head(&ap->eh_wait_q); - - /* set cable type */ - ap->cbl = ATA_CBL_NONE; - if (ap->flags & ATA_FLAG_SATA) - ap->cbl = ATA_CBL_SATA; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - dev->ap = ap; dev->devno = i; - ata_dev_init(dev); + dev->pio_mask = UINT_MAX; + dev->mwdma_mask = UINT_MAX; + dev->udma_mask = UINT_MAX; } #ifdef ATA_IRQ_TRAP @@ -5303,7 +4503,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, DPRINTK("ENTER\n"); - if (!ent->port_ops->error_handler && + if (!ent->port_ops->probe_reset && !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { printk(KERN_ERR "ata%u: no reset mechanism available\n", port_no); @@ -5316,7 +4516,7 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, host->transportt = &ata_scsi_transport_template; - ap = ata_shost_to_port(host); + ap = (struct ata_port *) &host->hostdata[0]; ata_host_init(ap, host, host_set, ent, port_no); @@ -5349,12 +4549,12 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, * RETURNS: * Number of ports registered. Zero on error (no ports registered). */ + int ata_device_add(const struct ata_probe_ent *ent) { unsigned int count = 0, i; struct device *dev = ent->dev; struct ata_host_set *host_set; - int rc; DPRINTK("ENTER\n"); /* alloc a container for our list of ATA ports (buses) */ @@ -5387,18 +4587,18 @@ int ata_device_add(const struct ata_probe_ent *ent) (ap->pio_mask << ATA_SHIFT_PIO); /* print per-port info to dmesg */ - ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " - "ctl 0x%lX bmdma 0x%lX irq %lu\n", - ap->flags & ATA_FLAG_SATA ? 'S' : 'P', - ata_mode_string(xfer_mode_mask), - ap->ioaddr.cmd_addr, - ap->ioaddr.ctl_addr, - ap->ioaddr.bmdma_addr, - ent->irq); + printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX " + "bmdma 0x%lX irq %lu\n", + ap->id, + ap->flags & ATA_FLAG_SATA ? 'S' : 'P', + ata_mode_string(xfer_mode_mask), + ap->ioaddr.cmd_addr, + ap->ioaddr.ctl_addr, + ap->ioaddr.bmdma_addr, + ent->irq); ata_chk_status(ap); host_set->ops->irq_clear(ap); - ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ count++; } @@ -5406,72 +4606,41 @@ int ata_device_add(const struct ata_probe_ent *ent) goto err_free_ret; /* obtain irq, that is shared between channels */ - rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, - DRV_NAME, host_set); - if (rc) { - dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", - ent->irq, rc); + if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, + DRV_NAME, host_set)) goto err_out; - } /* perform each probe synchronously */ DPRINTK("probe begin\n"); for (i = 0; i < count; i++) { struct ata_port *ap; - u32 scontrol; int rc; ap = host_set->ports[i]; - /* init sata_spd_limit to the current value */ - if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { - int spd = (scontrol >> 4) & 0xf; - ap->hw_sata_spd_limit &= (1 << spd) - 1; + DPRINTK("ata%u: bus probe begin\n", ap->id); + rc = ata_bus_probe(ap); + DPRINTK("ata%u: bus probe end\n", ap->id); + + if (rc) { + /* FIXME: do something useful here? + * Current libata behavior will + * tear down everything when + * the module is removed + * or the h/w is unplugged. + */ } - ap->sata_spd_limit = ap->hw_sata_spd_limit; rc = scsi_add_host(ap->host, dev); if (rc) { - ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n"); + printk(KERN_ERR "ata%u: scsi_add_host failed\n", + ap->id); /* FIXME: do something useful here */ /* FIXME: handle unconditional calls to * scsi_scan_host and ata_host_remove, below, * at the very least */ } - - if (ap->ops->error_handler) { - unsigned long flags; - - ata_port_probe(ap); - - /* kick EH for boot probing */ - spin_lock_irqsave(ap->lock, flags); - - ap->eh_info.probe_mask = (1 << ATA_MAX_DEVICES) - 1; - ap->eh_info.action |= ATA_EH_SOFTRESET; - - ap->flags |= ATA_FLAG_LOADING; - ata_port_schedule_eh(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - /* wait for EH to finish */ - ata_port_wait_eh(ap); - } else { - DPRINTK("ata%u: bus probe begin\n", ap->id); - rc = ata_bus_probe(ap); - DPRINTK("ata%u: bus probe end\n", ap->id); - - if (rc) { - /* FIXME: do something useful here? - * Current libata behavior will - * tear down everything when - * the module is removed - * or the h/w is unplugged. - */ - } - } } /* probes are done, now scan each port's disk(s) */ @@ -5498,63 +4667,6 @@ int ata_device_add(const struct ata_probe_ent *ent) return 0; } -/** - * ata_port_detach - Detach ATA port in prepration of device removal - * @ap: ATA port to be detached - * - * Detach all ATA devices and the associated SCSI devices of @ap; - * then, remove the associated SCSI host. @ap is guaranteed to - * be quiescent on return from this function. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_port_detach(struct ata_port *ap) -{ - unsigned long flags; - int i; - - if (!ap->ops->error_handler) - return; - - /* tell EH we're leaving & flush EH */ - spin_lock_irqsave(ap->lock, flags); - ap->flags |= ATA_FLAG_UNLOADING; - spin_unlock_irqrestore(ap->lock, flags); - - ata_port_wait_eh(ap); - - /* EH is now guaranteed to see UNLOADING, so no new device - * will be attached. Disable all existing devices. - */ - spin_lock_irqsave(ap->lock, flags); - - for (i = 0; i < ATA_MAX_DEVICES; i++) - ata_dev_disable(&ap->device[i]); - - spin_unlock_irqrestore(ap->lock, flags); - - /* Final freeze & EH. All in-flight commands are aborted. EH - * will be skipped and retrials will be terminated with bad - * target. - */ - spin_lock_irqsave(ap->lock, flags); - ata_port_freeze(ap); /* won't be thawed */ - spin_unlock_irqrestore(ap->lock, flags); - - ata_port_wait_eh(ap); - - /* Flush hotplug task. The sequence is similar to - * ata_port_flush_task(). - */ - flush_workqueue(ata_aux_wq); - cancel_delayed_work(&ap->hotplug_task); - flush_workqueue(ata_aux_wq); - - /* remove the associated SCSI host */ - scsi_remove_host(ap->host); -} - /** * ata_host_set_remove - PCI layer callback for device removal * @host_set: ATA host set that was removed @@ -5568,15 +4680,18 @@ void ata_port_detach(struct ata_port *ap) void ata_host_set_remove(struct ata_host_set *host_set) { + struct ata_port *ap; unsigned int i; - for (i = 0; i < host_set->n_ports; i++) - ata_port_detach(host_set->ports[i]); + for (i = 0; i < host_set->n_ports; i++) { + ap = host_set->ports[i]; + scsi_remove_host(ap->host); + } free_irq(host_set->irq, host_set); for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; + ap = host_set->ports[i]; ata_scsi_release(ap->host); @@ -5614,12 +4729,15 @@ void ata_host_set_remove(struct ata_host_set *host_set) int ata_scsi_release(struct Scsi_Host *host) { - struct ata_port *ap = ata_shost_to_port(host); + struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; + int i; DPRINTK("ENTER\n"); ap->ops->port_disable(ap); ata_host_remove(ap, 0); + for (i = 0; i < ATA_MAX_DEVICES; i++) + kfree(ap->device[i].id); DPRINTK("EXIT\n"); return 1; @@ -5679,12 +4797,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) { struct device *dev = pci_dev_to_dev(pdev); struct ata_host_set *host_set = dev_get_drvdata(dev); - struct ata_host_set *host_set2 = host_set->next; ata_host_set_remove(host_set); - if (host_set2) - ata_host_set_remove(host_set2); - pci_release_regions(pdev); pci_disable_device(pdev); dev_set_drvdata(dev, NULL); @@ -5745,17 +4859,10 @@ int ata_pci_device_resume(struct pci_dev *pdev) static int __init ata_init(void) { - ata_probe_timeout *= HZ; ata_wq = create_workqueue("ata"); if (!ata_wq) return -ENOMEM; - ata_aux_wq = create_singlethread_workqueue("ata_aux"); - if (!ata_aux_wq) { - destroy_workqueue(ata_wq); - return -ENOMEM; - } - printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); return 0; } @@ -5763,14 +4870,13 @@ static int __init ata_init(void) static void __exit ata_exit(void) { destroy_workqueue(ata_wq); - destroy_workqueue(ata_aux_wq); } module_init(ata_init); module_exit(ata_exit); static unsigned long ratelimit_time; -static DEFINE_SPINLOCK(ata_ratelimit_lock); +static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED; int ata_ratelimit(void) { @@ -5790,52 +4896,6 @@ int ata_ratelimit(void) return rc; } -/** - * ata_wait_register - wait until register value changes - * @reg: IO-mapped register - * @mask: Mask to apply to read register value - * @val: Wait condition - * @interval_msec: polling interval in milliseconds - * @timeout_msec: timeout in milliseconds - * - * Waiting for some bits of register to change is a common - * operation for ATA controllers. This function reads 32bit LE - * IO-mapped register @reg and tests for the following condition. - * - * (*@reg & mask) != val - * - * If the condition is met, it returns; otherwise, the process is - * repeated after @interval_msec until timeout. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * The final register value. - */ -u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, - unsigned long interval_msec, - unsigned long timeout_msec) -{ - unsigned long timeout; - u32 tmp; - - tmp = ioread32(reg); - - /* Calculate timeout _after_ the first read to make sure - * preceding writes reach the controller before starting to - * eat away the timeout. - */ - timeout = jiffies + (timeout_msec * HZ) / 1000; - - while ((tmp & mask) == val && time_before(jiffies, timeout)) { - msleep(interval_msec); - tmp = ioread32(reg); - } - - return tmp; -} - /* * libata is essentially a library of internal helper functions for * low-level ATA host controller drivers. As such, the API/ABI is @@ -5843,20 +4903,15 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, * Do not depend on ABI/API stability. */ -EXPORT_SYMBOL_GPL(sata_deb_timing_boot); -EXPORT_SYMBOL_GPL(sata_deb_timing_eh); -EXPORT_SYMBOL_GPL(sata_deb_timing_before_fsrst); EXPORT_SYMBOL_GPL(ata_std_bios_param); EXPORT_SYMBOL_GPL(ata_std_ports); EXPORT_SYMBOL_GPL(ata_device_add); -EXPORT_SYMBOL_GPL(ata_port_detach); EXPORT_SYMBOL_GPL(ata_host_set_remove); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_sg_init_one); -EXPORT_SYMBOL_GPL(ata_hsm_move); -EXPORT_SYMBOL_GPL(ata_qc_complete); -EXPORT_SYMBOL_GPL(ata_qc_complete_multiple); +EXPORT_SYMBOL_GPL(__ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_issue_prot); +EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_tf_load); EXPORT_SYMBOL_GPL(ata_tf_read); EXPORT_SYMBOL_GPL(ata_noop_dev_select); @@ -5870,9 +4925,6 @@ EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); EXPORT_SYMBOL_GPL(ata_host_stop); EXPORT_SYMBOL_GPL(ata_interrupt); -EXPORT_SYMBOL_GPL(ata_mmio_data_xfer); -EXPORT_SYMBOL_GPL(ata_pio_data_xfer); -EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq); EXPORT_SYMBOL_GPL(ata_qc_prep); EXPORT_SYMBOL_GPL(ata_noop_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); @@ -5880,46 +4932,33 @@ EXPORT_SYMBOL_GPL(ata_bmdma_start); EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); EXPORT_SYMBOL_GPL(ata_bmdma_status); EXPORT_SYMBOL_GPL(ata_bmdma_stop); -EXPORT_SYMBOL_GPL(ata_bmdma_freeze); -EXPORT_SYMBOL_GPL(ata_bmdma_thaw); -EXPORT_SYMBOL_GPL(ata_bmdma_drive_eh); -EXPORT_SYMBOL_GPL(ata_bmdma_error_handler); -EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); EXPORT_SYMBOL_GPL(ata_port_probe); -EXPORT_SYMBOL_GPL(sata_set_spd); -EXPORT_SYMBOL_GPL(sata_phy_debounce); -EXPORT_SYMBOL_GPL(sata_phy_resume); EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(__sata_phy_reset); EXPORT_SYMBOL_GPL(ata_bus_reset); -EXPORT_SYMBOL_GPL(ata_std_prereset); +EXPORT_SYMBOL_GPL(ata_std_probeinit); EXPORT_SYMBOL_GPL(ata_std_softreset); EXPORT_SYMBOL_GPL(sata_std_hardreset); EXPORT_SYMBOL_GPL(ata_std_postreset); +EXPORT_SYMBOL_GPL(ata_std_probe_reset); +EXPORT_SYMBOL_GPL(ata_drive_probe_reset); EXPORT_SYMBOL_GPL(ata_dev_revalidate); EXPORT_SYMBOL_GPL(ata_dev_classify); EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); EXPORT_SYMBOL_GPL(ata_ratelimit); -EXPORT_SYMBOL_GPL(ata_wait_register); EXPORT_SYMBOL_GPL(ata_busy_sleep); EXPORT_SYMBOL_GPL(ata_port_queue_task); EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); -EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); -EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); EXPORT_SYMBOL_GPL(ata_scsi_release); EXPORT_SYMBOL_GPL(ata_host_intr); -EXPORT_SYMBOL_GPL(sata_scr_valid); -EXPORT_SYMBOL_GPL(sata_scr_read); -EXPORT_SYMBOL_GPL(sata_scr_write); -EXPORT_SYMBOL_GPL(sata_scr_write_flush); -EXPORT_SYMBOL_GPL(ata_port_online); -EXPORT_SYMBOL_GPL(ata_port_offline); EXPORT_SYMBOL_GPL(ata_id_string); EXPORT_SYMBOL_GPL(ata_id_c_string); EXPORT_SYMBOL_GPL(ata_scsi_simulate); +EXPORT_SYMBOL_GPL(ata_eh_qc_complete); +EXPORT_SYMBOL_GPL(ata_eh_qc_retry); EXPORT_SYMBOL_GPL(ata_pio_need_iordy); EXPORT_SYMBOL_GPL(ata_timing_compute); @@ -5941,13 +4980,3 @@ EXPORT_SYMBOL_GPL(ata_device_suspend); EXPORT_SYMBOL_GPL(ata_device_resume); EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); EXPORT_SYMBOL_GPL(ata_scsi_device_resume); - -EXPORT_SYMBOL_GPL(ata_eng_timeout); -EXPORT_SYMBOL_GPL(ata_port_schedule_eh); -EXPORT_SYMBOL_GPL(ata_port_abort); -EXPORT_SYMBOL_GPL(ata_port_freeze); -EXPORT_SYMBOL_GPL(ata_eh_freeze_port); -EXPORT_SYMBOL_GPL(ata_eh_thaw_port); -EXPORT_SYMBOL_GPL(ata_eh_qc_complete); -EXPORT_SYMBOL_GPL(ata_eh_qc_retry); -EXPORT_SYMBOL_GPL(ata_do_eh); diff --git a/trunk/drivers/scsi/libata-eh.c b/trunk/drivers/scsi/libata-eh.c deleted file mode 100644 index bf5a72aca8a4..000000000000 --- a/trunk/drivers/scsi/libata-eh.c +++ /dev/null @@ -1,1918 +0,0 @@ -/* - * libata-eh.c - libata error handling - * - * Maintained by: Jeff Garzik - * Please ALWAYS copy linux-ide@vger.kernel.org - * on emails. - * - * Copyright 2006 Tejun Heo - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * - * libata documentation is available via 'make {ps|pdf}docs', - * as Documentation/DocBook/libata.* - * - * Hardware documentation available from http://www.t13.org/ and - * http://www.sata-io.org/ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "scsi_transport_api.h" - -#include - -#include "libata.h" - -static void __ata_port_freeze(struct ata_port *ap); -static void ata_eh_finish(struct ata_port *ap); - -static void ata_ering_record(struct ata_ering *ering, int is_io, - unsigned int err_mask) -{ - struct ata_ering_entry *ent; - - WARN_ON(!err_mask); - - ering->cursor++; - ering->cursor %= ATA_ERING_SIZE; - - ent = &ering->ring[ering->cursor]; - ent->is_io = is_io; - ent->err_mask = err_mask; - ent->timestamp = get_jiffies_64(); -} - -static struct ata_ering_entry * ata_ering_top(struct ata_ering *ering) -{ - struct ata_ering_entry *ent = &ering->ring[ering->cursor]; - if (!ent->err_mask) - return NULL; - return ent; -} - -static int ata_ering_map(struct ata_ering *ering, - int (*map_fn)(struct ata_ering_entry *, void *), - void *arg) -{ - int idx, rc = 0; - struct ata_ering_entry *ent; - - idx = ering->cursor; - do { - ent = &ering->ring[idx]; - if (!ent->err_mask) - break; - rc = map_fn(ent, arg); - if (rc) - break; - idx = (idx - 1 + ATA_ERING_SIZE) % ATA_ERING_SIZE; - } while (idx != ering->cursor); - - return rc; -} - -static unsigned int ata_eh_dev_action(struct ata_device *dev) -{ - struct ata_eh_context *ehc = &dev->ap->eh_context; - - return ehc->i.action | ehc->i.dev_action[dev->devno]; -} - -static void ata_eh_clear_action(struct ata_device *dev, - struct ata_eh_info *ehi, unsigned int action) -{ - int i; - - if (!dev) { - ehi->action &= ~action; - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] &= ~action; - } else { - /* doesn't make sense for port-wide EH actions */ - WARN_ON(!(action & ATA_EH_PERDEV_MASK)); - - /* break ehi->action into ehi->dev_action */ - if (ehi->action & action) { - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] |= ehi->action & action; - ehi->action &= ~action; - } - - /* turn off the specified per-dev action */ - ehi->dev_action[dev->devno] &= ~action; - } -} - -/** - * ata_scsi_timed_out - SCSI layer time out callback - * @cmd: timed out SCSI command - * - * Handles SCSI layer timeout. We race with normal completion of - * the qc for @cmd. If the qc is already gone, we lose and let - * the scsi command finish (EH_HANDLED). Otherwise, the qc has - * timed out and EH should be invoked. Prevent ata_qc_complete() - * from finishing it by setting EH_SCHEDULED and return - * EH_NOT_HANDLED. - * - * TODO: kill this function once old EH is gone. - * - * LOCKING: - * Called from timer context - * - * RETURNS: - * EH_HANDLED or EH_NOT_HANDLED - */ -enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host = cmd->device->host; - struct ata_port *ap = ata_shost_to_port(host); - unsigned long flags; - struct ata_queued_cmd *qc; - enum scsi_eh_timer_return ret; - - DPRINTK("ENTER\n"); - - if (ap->ops->error_handler) { - ret = EH_NOT_HANDLED; - goto out; - } - - ret = EH_HANDLED; - spin_lock_irqsave(ap->lock, flags); - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc) { - WARN_ON(qc->scsicmd != cmd); - qc->flags |= ATA_QCFLAG_EH_SCHEDULED; - qc->err_mask |= AC_ERR_TIMEOUT; - ret = EH_NOT_HANDLED; - } - spin_unlock_irqrestore(ap->lock, flags); - - out: - DPRINTK("EXIT, ret=%d\n", ret); - return ret; -} - -/** - * ata_scsi_error - SCSI layer error handler callback - * @host: SCSI host on which error occurred - * - * Handles SCSI-layer-thrown error events. - * - * LOCKING: - * Inherited from SCSI layer (none, can sleep) - * - * RETURNS: - * Zero. - */ -void ata_scsi_error(struct Scsi_Host *host) -{ - struct ata_port *ap = ata_shost_to_port(host); - spinlock_t *ap_lock = ap->lock; - int i, repeat_cnt = ATA_EH_MAX_REPEAT; - unsigned long flags; - - DPRINTK("ENTER\n"); - - /* synchronize with port task */ - ata_port_flush_task(ap); - - /* synchronize with host_set lock and sort out timeouts */ - - /* For new EH, all qcs are finished in one of three ways - - * normal completion, error completion, and SCSI timeout. - * Both cmpletions can race against SCSI timeout. When normal - * completion wins, the qc never reaches EH. When error - * completion wins, the qc has ATA_QCFLAG_FAILED set. - * - * When SCSI timeout wins, things are a bit more complex. - * Normal or error completion can occur after the timeout but - * before this point. In such cases, both types of - * completions are honored. A scmd is determined to have - * timed out iff its associated qc is active and not failed. - */ - if (ap->ops->error_handler) { - struct scsi_cmnd *scmd, *tmp; - int nr_timedout = 0; - - spin_lock_irqsave(ap_lock, flags); - - list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { - struct ata_queued_cmd *qc; - - for (i = 0; i < ATA_MAX_QUEUE; i++) { - qc = __ata_qc_from_tag(ap, i); - if (qc->flags & ATA_QCFLAG_ACTIVE && - qc->scsicmd == scmd) - break; - } - - if (i < ATA_MAX_QUEUE) { - /* the scmd has an associated qc */ - if (!(qc->flags & ATA_QCFLAG_FAILED)) { - /* which hasn't failed yet, timeout */ - qc->err_mask |= AC_ERR_TIMEOUT; - qc->flags |= ATA_QCFLAG_FAILED; - nr_timedout++; - } - } else { - /* Normal completion occurred after - * SCSI timeout but before this point. - * Successfully complete it. - */ - scmd->retries = scmd->allowed; - scsi_eh_finish_cmd(scmd, &ap->eh_done_q); - } - } - - /* If we have timed out qcs. They belong to EH from - * this point but the state of the controller is - * unknown. Freeze the port to make sure the IRQ - * handler doesn't diddle with those qcs. This must - * be done atomically w.r.t. setting QCFLAG_FAILED. - */ - if (nr_timedout) - __ata_port_freeze(ap); - - spin_unlock_irqrestore(ap_lock, flags); - } else - spin_unlock_wait(ap_lock); - - repeat: - /* invoke error handler */ - if (ap->ops->error_handler) { - /* fetch & clear EH info */ - spin_lock_irqsave(ap_lock, flags); - - memset(&ap->eh_context, 0, sizeof(ap->eh_context)); - ap->eh_context.i = ap->eh_info; - memset(&ap->eh_info, 0, sizeof(ap->eh_info)); - - ap->flags |= ATA_FLAG_EH_IN_PROGRESS; - ap->flags &= ~ATA_FLAG_EH_PENDING; - - spin_unlock_irqrestore(ap_lock, flags); - - /* invoke EH. if unloading, just finish failed qcs */ - if (!(ap->flags & ATA_FLAG_UNLOADING)) - ap->ops->error_handler(ap); - else - ata_eh_finish(ap); - - /* Exception might have happend after ->error_handler - * recovered the port but before this point. Repeat - * EH in such case. - */ - spin_lock_irqsave(ap_lock, flags); - - if (ap->flags & ATA_FLAG_EH_PENDING) { - if (--repeat_cnt) { - ata_port_printk(ap, KERN_INFO, - "EH pending after completion, " - "repeating EH (cnt=%d)\n", repeat_cnt); - spin_unlock_irqrestore(ap_lock, flags); - goto repeat; - } - ata_port_printk(ap, KERN_ERR, "EH pending after %d " - "tries, giving up\n", ATA_EH_MAX_REPEAT); - } - - /* this run is complete, make sure EH info is clear */ - memset(&ap->eh_info, 0, sizeof(ap->eh_info)); - - /* Clear host_eh_scheduled while holding ap_lock such - * that if exception occurs after this point but - * before EH completion, SCSI midlayer will - * re-initiate EH. - */ - host->host_eh_scheduled = 0; - - spin_unlock_irqrestore(ap_lock, flags); - } else { - WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); - ap->ops->eng_timeout(ap); - } - - /* finish or retry handled scmd's and clean up */ - WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); - - scsi_eh_flush_done_q(&ap->eh_done_q); - - /* clean up */ - spin_lock_irqsave(ap_lock, flags); - - if (ap->flags & ATA_FLAG_LOADING) { - ap->flags &= ~ATA_FLAG_LOADING; - } else { - if (ap->flags & ATA_FLAG_SCSI_HOTPLUG) - queue_work(ata_aux_wq, &ap->hotplug_task); - if (ap->flags & ATA_FLAG_RECOVERED) - ata_port_printk(ap, KERN_INFO, "EH complete\n"); - } - - ap->flags &= ~(ATA_FLAG_SCSI_HOTPLUG | ATA_FLAG_RECOVERED); - - /* tell wait_eh that we're done */ - ap->flags &= ~ATA_FLAG_EH_IN_PROGRESS; - wake_up_all(&ap->eh_wait_q); - - spin_unlock_irqrestore(ap_lock, flags); - - DPRINTK("EXIT\n"); -} - -/** - * ata_port_wait_eh - Wait for the currently pending EH to complete - * @ap: Port to wait EH for - * - * Wait until the currently pending EH is complete. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_port_wait_eh(struct ata_port *ap) -{ - unsigned long flags; - DEFINE_WAIT(wait); - - retry: - spin_lock_irqsave(ap->lock, flags); - - while (ap->flags & (ATA_FLAG_EH_PENDING | ATA_FLAG_EH_IN_PROGRESS)) { - prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE); - spin_unlock_irqrestore(ap->lock, flags); - schedule(); - spin_lock_irqsave(ap->lock, flags); - } - finish_wait(&ap->eh_wait_q, &wait); - - spin_unlock_irqrestore(ap->lock, flags); - - /* make sure SCSI EH is complete */ - if (scsi_host_in_recovery(ap->host)) { - msleep(10); - goto retry; - } -} - -/** - * ata_qc_timeout - Handle timeout of queued command - * @qc: Command that timed out - * - * Some part of the kernel (currently, only the SCSI layer) - * has noticed that the active command on port @ap has not - * completed after a specified length of time. Handle this - * condition by disabling DMA (if necessary) and completing - * transactions, with error if necessary. - * - * This also handles the case of the "lost interrupt", where - * for some reason (possibly hardware bug, possibly driver bug) - * an interrupt was not delivered to the driver, even though the - * transaction completed successfully. - * - * TODO: kill this function once old EH is gone. - * - * LOCKING: - * Inherited from SCSI layer (none, can sleep) - */ -static void ata_qc_timeout(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - u8 host_stat = 0, drv_stat; - unsigned long flags; - - DPRINTK("ENTER\n"); - - ap->hsm_task_state = HSM_ST_IDLE; - - spin_lock_irqsave(ap->lock, flags); - - switch (qc->tf.protocol) { - - case ATA_PROT_DMA: - case ATA_PROT_ATAPI_DMA: - host_stat = ap->ops->bmdma_status(ap); - - /* before we do anything else, clear DMA-Start bit */ - ap->ops->bmdma_stop(qc); - - /* fall through */ - - default: - ata_altstatus(ap); - drv_stat = ata_chk_status(ap); - - /* ack bmdma irq events */ - ap->ops->irq_clear(ap); - - ata_dev_printk(qc->dev, KERN_ERR, "command 0x%x timeout, " - "stat 0x%x host_stat 0x%x\n", - qc->tf.command, drv_stat, host_stat); - - /* complete taskfile transaction */ - qc->err_mask |= AC_ERR_TIMEOUT; - break; - } - - spin_unlock_irqrestore(ap->lock, flags); - - ata_eh_qc_complete(qc); - - DPRINTK("EXIT\n"); -} - -/** - * ata_eng_timeout - Handle timeout of queued command - * @ap: Port on which timed-out command is active - * - * Some part of the kernel (currently, only the SCSI layer) - * has noticed that the active command on port @ap has not - * completed after a specified length of time. Handle this - * condition by disabling DMA (if necessary) and completing - * transactions, with error if necessary. - * - * This also handles the case of the "lost interrupt", where - * for some reason (possibly hardware bug, possibly driver bug) - * an interrupt was not delivered to the driver, even though the - * transaction completed successfully. - * - * TODO: kill this function once old EH is gone. - * - * LOCKING: - * Inherited from SCSI layer (none, can sleep) - */ -void ata_eng_timeout(struct ata_port *ap) -{ - DPRINTK("ENTER\n"); - - ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag)); - - DPRINTK("EXIT\n"); -} - -/** - * ata_qc_schedule_eh - schedule qc for error handling - * @qc: command to schedule error handling for - * - * Schedule error handling for @qc. EH will kick in as soon as - * other commands are drained. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_qc_schedule_eh(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - WARN_ON(!ap->ops->error_handler); - - qc->flags |= ATA_QCFLAG_FAILED; - qc->ap->flags |= ATA_FLAG_EH_PENDING; - - /* The following will fail if timeout has already expired. - * ata_scsi_error() takes care of such scmds on EH entry. - * Note that ATA_QCFLAG_FAILED is unconditionally set after - * this function completes. - */ - scsi_req_abort_cmd(qc->scsicmd); -} - -/** - * ata_port_schedule_eh - schedule error handling without a qc - * @ap: ATA port to schedule EH for - * - * Schedule error handling for @ap. EH will kick in as soon as - * all commands are drained. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_port_schedule_eh(struct ata_port *ap) -{ - WARN_ON(!ap->ops->error_handler); - - ap->flags |= ATA_FLAG_EH_PENDING; - scsi_schedule_eh(ap->host); - - DPRINTK("port EH scheduled\n"); -} - -/** - * ata_port_abort - abort all qc's on the port - * @ap: ATA port to abort qc's for - * - * Abort all active qc's of @ap and schedule EH. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Number of aborted qc's. - */ -int ata_port_abort(struct ata_port *ap) -{ - int tag, nr_aborted = 0; - - WARN_ON(!ap->ops->error_handler); - - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); - - if (qc) { - qc->flags |= ATA_QCFLAG_FAILED; - ata_qc_complete(qc); - nr_aborted++; - } - } - - if (!nr_aborted) - ata_port_schedule_eh(ap); - - return nr_aborted; -} - -/** - * __ata_port_freeze - freeze port - * @ap: ATA port to freeze - * - * This function is called when HSM violation or some other - * condition disrupts normal operation of the port. Frozen port - * is not allowed to perform any operation until the port is - * thawed, which usually follows a successful reset. - * - * ap->ops->freeze() callback can be used for freezing the port - * hardware-wise (e.g. mask interrupt and stop DMA engine). If a - * port cannot be frozen hardware-wise, the interrupt handler - * must ack and clear interrupts unconditionally while the port - * is frozen. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -static void __ata_port_freeze(struct ata_port *ap) -{ - WARN_ON(!ap->ops->error_handler); - - if (ap->ops->freeze) - ap->ops->freeze(ap); - - ap->flags |= ATA_FLAG_FROZEN; - - DPRINTK("ata%u port frozen\n", ap->id); -} - -/** - * ata_port_freeze - abort & freeze port - * @ap: ATA port to freeze - * - * Abort and freeze @ap. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Number of aborted commands. - */ -int ata_port_freeze(struct ata_port *ap) -{ - int nr_aborted; - - WARN_ON(!ap->ops->error_handler); - - nr_aborted = ata_port_abort(ap); - __ata_port_freeze(ap); - - return nr_aborted; -} - -/** - * ata_eh_freeze_port - EH helper to freeze port - * @ap: ATA port to freeze - * - * Freeze @ap. - * - * LOCKING: - * None. - */ -void ata_eh_freeze_port(struct ata_port *ap) -{ - unsigned long flags; - - if (!ap->ops->error_handler) - return; - - spin_lock_irqsave(ap->lock, flags); - __ata_port_freeze(ap); - spin_unlock_irqrestore(ap->lock, flags); -} - -/** - * ata_port_thaw_port - EH helper to thaw port - * @ap: ATA port to thaw - * - * Thaw frozen port @ap. - * - * LOCKING: - * None. - */ -void ata_eh_thaw_port(struct ata_port *ap) -{ - unsigned long flags; - - if (!ap->ops->error_handler) - return; - - spin_lock_irqsave(ap->lock, flags); - - ap->flags &= ~ATA_FLAG_FROZEN; - - if (ap->ops->thaw) - ap->ops->thaw(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - DPRINTK("ata%u port thawed\n", ap->id); -} - -static void ata_eh_scsidone(struct scsi_cmnd *scmd) -{ - /* nada */ -} - -static void __ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct scsi_cmnd *scmd = qc->scsicmd; - unsigned long flags; - - spin_lock_irqsave(ap->lock, flags); - qc->scsidone = ata_eh_scsidone; - __ata_qc_complete(qc); - WARN_ON(ata_tag_valid(qc->tag)); - spin_unlock_irqrestore(ap->lock, flags); - - scsi_eh_finish_cmd(scmd, &ap->eh_done_q); -} - -/** - * ata_eh_qc_complete - Complete an active ATA command from EH - * @qc: Command to complete - * - * Indicate to the mid and upper layers that an ATA command has - * completed. To be used from EH. - */ -void ata_eh_qc_complete(struct ata_queued_cmd *qc) -{ - struct scsi_cmnd *scmd = qc->scsicmd; - scmd->retries = scmd->allowed; - __ata_eh_qc_complete(qc); -} - -/** - * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH - * @qc: Command to retry - * - * Indicate to the mid and upper layers that an ATA command - * should be retried. To be used from EH. - * - * SCSI midlayer limits the number of retries to scmd->allowed. - * scmd->retries is decremented for commands which get retried - * due to unrelated failures (qc->err_mask is zero). - */ -void ata_eh_qc_retry(struct ata_queued_cmd *qc) -{ - struct scsi_cmnd *scmd = qc->scsicmd; - if (!qc->err_mask && scmd->retries) - scmd->retries--; - __ata_eh_qc_complete(qc); -} - -/** - * ata_eh_detach_dev - detach ATA device - * @dev: ATA device to detach - * - * Detach @dev. - * - * LOCKING: - * None. - */ -static void ata_eh_detach_dev(struct ata_device *dev) -{ - struct ata_port *ap = dev->ap; - unsigned long flags; - - ata_dev_disable(dev); - - spin_lock_irqsave(ap->lock, flags); - - dev->flags &= ~ATA_DFLAG_DETACH; - - if (ata_scsi_offline_dev(dev)) { - dev->flags |= ATA_DFLAG_DETACHED; - ap->flags |= ATA_FLAG_SCSI_HOTPLUG; - } - - /* clear per-dev EH actions */ - ata_eh_clear_action(dev, &ap->eh_info, ATA_EH_PERDEV_MASK); - ata_eh_clear_action(dev, &ap->eh_context.i, ATA_EH_PERDEV_MASK); - - spin_unlock_irqrestore(ap->lock, flags); -} - -/** - * ata_eh_about_to_do - about to perform eh_action - * @ap: target ATA port - * @dev: target ATA dev for per-dev action (can be NULL) - * @action: action about to be performed - * - * Called just before performing EH actions to clear related bits - * in @ap->eh_info such that eh actions are not unnecessarily - * repeated. - * - * LOCKING: - * None. - */ -static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, - unsigned int action) -{ - unsigned long flags; - - spin_lock_irqsave(ap->lock, flags); - ata_eh_clear_action(dev, &ap->eh_info, action); - ap->flags |= ATA_FLAG_RECOVERED; - spin_unlock_irqrestore(ap->lock, flags); -} - -/** - * ata_eh_done - EH action complete - * @ap: target ATA port - * @dev: target ATA dev for per-dev action (can be NULL) - * @action: action just completed - * - * Called right after performing EH actions to clear related bits - * in @ap->eh_context. - * - * LOCKING: - * None. - */ -static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, - unsigned int action) -{ - ata_eh_clear_action(dev, &ap->eh_context.i, action); -} - -/** - * ata_err_string - convert err_mask to descriptive string - * @err_mask: error mask to convert to string - * - * Convert @err_mask to descriptive string. Errors are - * prioritized according to severity and only the most severe - * error is reported. - * - * LOCKING: - * None. - * - * RETURNS: - * Descriptive string for @err_mask - */ -static const char * ata_err_string(unsigned int err_mask) -{ - if (err_mask & AC_ERR_HOST_BUS) - return "host bus error"; - if (err_mask & AC_ERR_ATA_BUS) - return "ATA bus error"; - if (err_mask & AC_ERR_TIMEOUT) - return "timeout"; - if (err_mask & AC_ERR_HSM) - return "HSM violation"; - if (err_mask & AC_ERR_SYSTEM) - return "internal error"; - if (err_mask & AC_ERR_MEDIA) - return "media error"; - if (err_mask & AC_ERR_INVALID) - return "invalid argument"; - if (err_mask & AC_ERR_DEV) - return "device error"; - return "unknown error"; -} - -/** - * ata_read_log_page - read a specific log page - * @dev: target device - * @page: page to read - * @buf: buffer to store read page - * @sectors: number of sectors to read - * - * Read log page using READ_LOG_EXT command. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, AC_ERR_* mask otherwise. - */ -static unsigned int ata_read_log_page(struct ata_device *dev, - u8 page, void *buf, unsigned int sectors) -{ - struct ata_taskfile tf; - unsigned int err_mask; - - DPRINTK("read log page - page %d\n", page); - - ata_tf_init(dev, &tf); - tf.command = ATA_CMD_READ_LOG_EXT; - tf.lbal = page; - tf.nsect = sectors; - tf.hob_nsect = sectors >> 8; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; - tf.protocol = ATA_PROT_PIO; - - err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, - buf, sectors * ATA_SECT_SIZE); - - DPRINTK("EXIT, err_mask=%x\n", err_mask); - return err_mask; -} - -/** - * ata_eh_read_log_10h - Read log page 10h for NCQ error details - * @dev: Device to read log page 10h from - * @tag: Resulting tag of the failed command - * @tf: Resulting taskfile registers of the failed command - * - * Read log page 10h to obtain NCQ error details and clear error - * condition. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int ata_eh_read_log_10h(struct ata_device *dev, - int *tag, struct ata_taskfile *tf) -{ - u8 *buf = dev->ap->sector_buf; - unsigned int err_mask; - u8 csum; - int i; - - err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1); - if (err_mask) - return -EIO; - - csum = 0; - for (i = 0; i < ATA_SECT_SIZE; i++) - csum += buf[i]; - if (csum) - ata_dev_printk(dev, KERN_WARNING, - "invalid checksum 0x%x on log page 10h\n", csum); - - if (buf[0] & 0x80) - return -ENOENT; - - *tag = buf[0] & 0x1f; - - tf->command = buf[2]; - tf->feature = buf[3]; - tf->lbal = buf[4]; - tf->lbam = buf[5]; - tf->lbah = buf[6]; - tf->device = buf[7]; - tf->hob_lbal = buf[8]; - tf->hob_lbam = buf[9]; - tf->hob_lbah = buf[10]; - tf->nsect = buf[12]; - tf->hob_nsect = buf[13]; - - return 0; -} - -/** - * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE - * @dev: device to perform REQUEST_SENSE to - * @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long) - * - * Perform ATAPI REQUEST_SENSE after the device reported CHECK - * SENSE. This function is EH helper. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, AC_ERR_* mask on failure - */ -static unsigned int atapi_eh_request_sense(struct ata_device *dev, - unsigned char *sense_buf) -{ - struct ata_port *ap = dev->ap; - struct ata_taskfile tf; - u8 cdb[ATAPI_CDB_LEN]; - - DPRINTK("ATAPI request sense\n"); - - ata_tf_init(dev, &tf); - - /* FIXME: is this needed? */ - memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); - - /* XXX: why tf_read here? */ - ap->ops->tf_read(ap, &tf); - - /* fill these in, for the case where they are -not- overwritten */ - sense_buf[0] = 0x70; - sense_buf[2] = tf.feature >> 4; - - memset(cdb, 0, ATAPI_CDB_LEN); - cdb[0] = REQUEST_SENSE; - cdb[4] = SCSI_SENSE_BUFFERSIZE; - - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - tf.command = ATA_CMD_PACKET; - - /* is it pointless to prefer PIO for "safety reasons"? */ - if (ap->flags & ATA_FLAG_PIO_DMA) { - tf.protocol = ATA_PROT_ATAPI_DMA; - tf.feature |= ATAPI_PKT_DMA; - } else { - tf.protocol = ATA_PROT_ATAPI; - tf.lbam = (8 * 1024) & 0xff; - tf.lbah = (8 * 1024) >> 8; - } - - return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, - sense_buf, SCSI_SENSE_BUFFERSIZE); -} - -/** - * ata_eh_analyze_serror - analyze SError for a failed port - * @ap: ATA port to analyze SError for - * - * Analyze SError if available and further determine cause of - * failure. - * - * LOCKING: - * None. - */ -static void ata_eh_analyze_serror(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - u32 serror = ehc->i.serror; - unsigned int err_mask = 0, action = 0; - - if (serror & SERR_PERSISTENT) { - err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_HARDRESET; - } - if (serror & - (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) { - err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_SOFTRESET; - } - if (serror & SERR_PROTOCOL) { - err_mask |= AC_ERR_HSM; - action |= ATA_EH_SOFTRESET; - } - if (serror & SERR_INTERNAL) { - err_mask |= AC_ERR_SYSTEM; - action |= ATA_EH_SOFTRESET; - } - if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG)) - ata_ehi_hotplugged(&ehc->i); - - ehc->i.err_mask |= err_mask; - ehc->i.action |= action; -} - -/** - * ata_eh_analyze_ncq_error - analyze NCQ error - * @ap: ATA port to analyze NCQ error for - * - * Read log page 10h, determine the offending qc and acquire - * error status TF. For NCQ device errors, all LLDDs have to do - * is setting AC_ERR_DEV in ehi->err_mask. This function takes - * care of the rest. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -static void ata_eh_analyze_ncq_error(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - struct ata_device *dev = ap->device; - struct ata_queued_cmd *qc; - struct ata_taskfile tf; - int tag, rc; - - /* if frozen, we can't do much */ - if (ap->flags & ATA_FLAG_FROZEN) - return; - - /* is it NCQ device error? */ - if (!ap->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) - return; - - /* has LLDD analyzed already? */ - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - qc = __ata_qc_from_tag(ap, tag); - - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - - if (qc->err_mask) - return; - } - - /* okay, this error is ours */ - rc = ata_eh_read_log_10h(dev, &tag, &tf); - if (rc) { - ata_port_printk(ap, KERN_ERR, "failed to read log page 10h " - "(errno=%d)\n", rc); - return; - } - - if (!(ap->sactive & (1 << tag))) { - ata_port_printk(ap, KERN_ERR, "log page 10h reported " - "inactive tag %d\n", tag); - return; - } - - /* we've got the perpetrator, condemn it */ - qc = __ata_qc_from_tag(ap, tag); - memcpy(&qc->result_tf, &tf, sizeof(tf)); - qc->err_mask |= AC_ERR_DEV; - ehc->i.err_mask &= ~AC_ERR_DEV; -} - -/** - * ata_eh_analyze_tf - analyze taskfile of a failed qc - * @qc: qc to analyze - * @tf: Taskfile registers to analyze - * - * Analyze taskfile of @qc and further determine cause of - * failure. This function also requests ATAPI sense data if - * avaliable. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * Determined recovery action - */ -static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, - const struct ata_taskfile *tf) -{ - unsigned int tmp, action = 0; - u8 stat = tf->command, err = tf->feature; - - if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) { - qc->err_mask |= AC_ERR_HSM; - return ATA_EH_SOFTRESET; - } - - if (!(qc->err_mask & AC_ERR_DEV)) - return 0; - - switch (qc->dev->class) { - case ATA_DEV_ATA: - if (err & ATA_ICRC) - qc->err_mask |= AC_ERR_ATA_BUS; - if (err & ATA_UNC) - qc->err_mask |= AC_ERR_MEDIA; - if (err & ATA_IDNF) - qc->err_mask |= AC_ERR_INVALID; - break; - - case ATA_DEV_ATAPI: - tmp = atapi_eh_request_sense(qc->dev, - qc->scsicmd->sense_buffer); - if (!tmp) { - /* ATA_QCFLAG_SENSE_VALID is used to tell - * atapi_qc_complete() that sense data is - * already valid. - * - * TODO: interpret sense data and set - * appropriate err_mask. - */ - qc->flags |= ATA_QCFLAG_SENSE_VALID; - } else - qc->err_mask |= tmp; - } - - if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) - action |= ATA_EH_SOFTRESET; - - return action; -} - -static int ata_eh_categorize_ering_entry(struct ata_ering_entry *ent) -{ - if (ent->err_mask & (AC_ERR_ATA_BUS | AC_ERR_TIMEOUT)) - return 1; - - if (ent->is_io) { - if (ent->err_mask & AC_ERR_HSM) - return 1; - if ((ent->err_mask & - (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV) - return 2; - } - - return 0; -} - -struct speed_down_needed_arg { - u64 since; - int nr_errors[3]; -}; - -static int speed_down_needed_cb(struct ata_ering_entry *ent, void *void_arg) -{ - struct speed_down_needed_arg *arg = void_arg; - - if (ent->timestamp < arg->since) - return -1; - - arg->nr_errors[ata_eh_categorize_ering_entry(ent)]++; - return 0; -} - -/** - * ata_eh_speed_down_needed - Determine wheter speed down is necessary - * @dev: Device of interest - * - * This function examines error ring of @dev and determines - * whether speed down is necessary. Speed down is necessary if - * there have been more than 3 of Cat-1 errors or 10 of Cat-2 - * errors during last 15 minutes. - * - * Cat-1 errors are ATA_BUS, TIMEOUT for any command and HSM - * violation for known supported commands. - * - * Cat-2 errors are unclassified DEV error for known supported - * command. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 1 if speed down is necessary, 0 otherwise - */ -static int ata_eh_speed_down_needed(struct ata_device *dev) -{ - const u64 interval = 15LLU * 60 * HZ; - static const int err_limits[3] = { -1, 3, 10 }; - struct speed_down_needed_arg arg; - struct ata_ering_entry *ent; - int err_cat; - u64 j64; - - ent = ata_ering_top(&dev->ering); - if (!ent) - return 0; - - err_cat = ata_eh_categorize_ering_entry(ent); - if (err_cat == 0) - return 0; - - memset(&arg, 0, sizeof(arg)); - - j64 = get_jiffies_64(); - if (j64 >= interval) - arg.since = j64 - interval; - else - arg.since = 0; - - ata_ering_map(&dev->ering, speed_down_needed_cb, &arg); - - return arg.nr_errors[err_cat] > err_limits[err_cat]; -} - -/** - * ata_eh_speed_down - record error and speed down if necessary - * @dev: Failed device - * @is_io: Did the device fail during normal IO? - * @err_mask: err_mask of the error - * - * Record error and examine error history to determine whether - * adjusting transmission speed is necessary. It also sets - * transmission limits appropriately if such adjustment is - * necessary. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise - */ -static int ata_eh_speed_down(struct ata_device *dev, int is_io, - unsigned int err_mask) -{ - if (!err_mask) - return 0; - - /* record error and determine whether speed down is necessary */ - ata_ering_record(&dev->ering, is_io, err_mask); - - if (!ata_eh_speed_down_needed(dev)) - return 0; - - /* speed down SATA link speed if possible */ - if (sata_down_spd_limit(dev->ap) == 0) - return ATA_EH_HARDRESET; - - /* lower transfer mode */ - if (ata_down_xfermask_limit(dev, 0) == 0) - return ATA_EH_SOFTRESET; - - ata_dev_printk(dev, KERN_ERR, - "speed down requested but no transfer mode left\n"); - return 0; -} - -/** - * ata_eh_autopsy - analyze error and determine recovery action - * @ap: ATA port to perform autopsy on - * - * Analyze why @ap failed and determine which recovery action is - * needed. This function also sets more detailed AC_ERR_* values - * and fills sense data for ATAPI CHECK SENSE. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -static void ata_eh_autopsy(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - unsigned int action = ehc->i.action; - struct ata_device *failed_dev = NULL; - unsigned int all_err_mask = 0; - int tag, is_io = 0; - u32 serror; - int rc; - - DPRINTK("ENTER\n"); - - /* obtain and analyze SError */ - rc = sata_scr_read(ap, SCR_ERROR, &serror); - if (rc == 0) { - ehc->i.serror |= serror; - ata_eh_analyze_serror(ap); - } else if (rc != -EOPNOTSUPP) - action |= ATA_EH_HARDRESET; - - /* analyze NCQ failure */ - ata_eh_analyze_ncq_error(ap); - - /* any real error trumps AC_ERR_OTHER */ - if (ehc->i.err_mask & ~AC_ERR_OTHER) - ehc->i.err_mask &= ~AC_ERR_OTHER; - - all_err_mask |= ehc->i.err_mask; - - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); - - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - - /* inherit upper level err_mask */ - qc->err_mask |= ehc->i.err_mask; - - /* analyze TF */ - action |= ata_eh_analyze_tf(qc, &qc->result_tf); - - /* DEV errors are probably spurious in case of ATA_BUS error */ - if (qc->err_mask & AC_ERR_ATA_BUS) - qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_MEDIA | - AC_ERR_INVALID); - - /* any real error trumps unknown error */ - if (qc->err_mask & ~AC_ERR_OTHER) - qc->err_mask &= ~AC_ERR_OTHER; - - /* SENSE_VALID trumps dev/unknown error and revalidation */ - if (qc->flags & ATA_QCFLAG_SENSE_VALID) { - qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); - action &= ~ATA_EH_REVALIDATE; - } - - /* accumulate error info */ - failed_dev = qc->dev; - all_err_mask |= qc->err_mask; - if (qc->flags & ATA_QCFLAG_IO) - is_io = 1; - } - - /* enforce default EH actions */ - if (ap->flags & ATA_FLAG_FROZEN || - all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) - action |= ATA_EH_SOFTRESET; - else if (all_err_mask) - action |= ATA_EH_REVALIDATE; - - /* if we have offending qcs and the associated failed device */ - if (failed_dev) { - /* speed down */ - action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); - - /* perform per-dev EH action only on the offending device */ - ehc->i.dev_action[failed_dev->devno] |= - action & ATA_EH_PERDEV_MASK; - action &= ~ATA_EH_PERDEV_MASK; - } - - /* record autopsy result */ - ehc->i.dev = failed_dev; - ehc->i.action = action; - - DPRINTK("EXIT\n"); -} - -/** - * ata_eh_report - report error handling to user - * @ap: ATA port EH is going on - * - * Report EH to user. - * - * LOCKING: - * None. - */ -static void ata_eh_report(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - const char *frozen, *desc; - int tag, nr_failed = 0; - - desc = NULL; - if (ehc->i.desc[0] != '\0') - desc = ehc->i.desc; - - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); - - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - if (qc->flags & ATA_QCFLAG_SENSE_VALID && !qc->err_mask) - continue; - - nr_failed++; - } - - if (!nr_failed && !ehc->i.err_mask) - return; - - frozen = ""; - if (ap->flags & ATA_FLAG_FROZEN) - frozen = " frozen"; - - if (ehc->i.dev) { - ata_dev_printk(ehc->i.dev, KERN_ERR, "exception Emask 0x%x " - "SAct 0x%x SErr 0x%x action 0x%x%s\n", - ehc->i.err_mask, ap->sactive, ehc->i.serror, - ehc->i.action, frozen); - if (desc) - ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc); - } else { - ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " - "SAct 0x%x SErr 0x%x action 0x%x%s\n", - ehc->i.err_mask, ap->sactive, ehc->i.serror, - ehc->i.action, frozen); - if (desc) - ata_port_printk(ap, KERN_ERR, "(%s)\n", desc); - } - - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); - - if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask) - continue; - - ata_dev_printk(qc->dev, KERN_ERR, "tag %d cmd 0x%x " - "Emask 0x%x stat 0x%x err 0x%x (%s)\n", - qc->tag, qc->tf.command, qc->err_mask, - qc->result_tf.command, qc->result_tf.feature, - ata_err_string(qc->err_mask)); - } -} - -static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, - unsigned int *classes) -{ - int i, rc; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_UNKNOWN; - - rc = reset(ap, classes); - if (rc) - return rc; - - /* If any class isn't ATA_DEV_UNKNOWN, consider classification - * is complete and convert all ATA_DEV_UNKNOWN to - * ATA_DEV_NONE. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] != ATA_DEV_UNKNOWN) - break; - - if (i < ATA_MAX_DEVICES) - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] == ATA_DEV_UNKNOWN) - classes[i] = ATA_DEV_NONE; - - return 0; -} - -static int ata_eh_followup_srst_needed(int rc, int classify, - const unsigned int *classes) -{ - if (rc == -EAGAIN) - return 1; - if (rc != 0) - return 0; - if (classify && classes[0] == ATA_DEV_UNKNOWN) - return 1; - return 0; -} - -static int ata_eh_reset(struct ata_port *ap, int classify, - ata_prereset_fn_t prereset, ata_reset_fn_t softreset, - ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) -{ - struct ata_eh_context *ehc = &ap->eh_context; - unsigned int *classes = ehc->classes; - int tries = ATA_EH_RESET_TRIES; - int verbose = !(ap->flags & ATA_FLAG_LOADING); - unsigned int action; - ata_reset_fn_t reset; - int i, did_followup_srst, rc; - - /* Determine which reset to use and record in ehc->i.action. - * prereset() may examine and modify it. - */ - action = ehc->i.action; - ehc->i.action &= ~ATA_EH_RESET_MASK; - if (softreset && (!hardreset || (!sata_set_spd_needed(ap) && - !(action & ATA_EH_HARDRESET)))) - ehc->i.action |= ATA_EH_SOFTRESET; - else - ehc->i.action |= ATA_EH_HARDRESET; - - if (prereset) { - rc = prereset(ap); - if (rc) { - ata_port_printk(ap, KERN_ERR, - "prereset failed (errno=%d)\n", rc); - return rc; - } - } - - /* prereset() might have modified ehc->i.action */ - if (ehc->i.action & ATA_EH_HARDRESET) - reset = hardreset; - else if (ehc->i.action & ATA_EH_SOFTRESET) - reset = softreset; - else { - /* prereset told us not to reset, bang classes and return */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_NONE; - return 0; - } - - /* did prereset() screw up? if so, fix up to avoid oopsing */ - if (!reset) { - ata_port_printk(ap, KERN_ERR, "BUG: prereset() requested " - "invalid reset type\n"); - if (softreset) - reset = softreset; - else - reset = hardreset; - } - - retry: - /* shut up during boot probing */ - if (verbose) - ata_port_printk(ap, KERN_INFO, "%s resetting port\n", - reset == softreset ? "soft" : "hard"); - - /* reset */ - ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); - ehc->i.flags |= ATA_EHI_DID_RESET; - - rc = ata_do_reset(ap, reset, classes); - - did_followup_srst = 0; - if (reset == hardreset && - ata_eh_followup_srst_needed(rc, classify, classes)) { - /* okay, let's do follow-up softreset */ - did_followup_srst = 1; - reset = softreset; - - if (!reset) { - ata_port_printk(ap, KERN_ERR, - "follow-up softreset required " - "but no softreset avaliable\n"); - return -EINVAL; - } - - ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); - rc = ata_do_reset(ap, reset, classes); - - if (rc == 0 && classify && - classes[0] == ATA_DEV_UNKNOWN) { - ata_port_printk(ap, KERN_ERR, - "classification failed\n"); - return -EINVAL; - } - } - - if (rc && --tries) { - const char *type; - - if (reset == softreset) { - if (did_followup_srst) - type = "follow-up soft"; - else - type = "soft"; - } else - type = "hard"; - - ata_port_printk(ap, KERN_WARNING, - "%sreset failed, retrying in 5 secs\n", type); - ssleep(5); - - if (reset == hardreset) - sata_down_spd_limit(ap); - if (hardreset) - reset = hardreset; - goto retry; - } - - if (rc == 0) { - /* After the reset, the device state is PIO 0 and the - * controller state is undefined. Record the mode. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->device[i].pio_mode = XFER_PIO_0; - - if (postreset) - postreset(ap, classes); - - /* reset successful, schedule revalidation */ - ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); - ehc->i.action |= ATA_EH_REVALIDATE; - } - - return rc; -} - -static int ata_eh_revalidate_and_attach(struct ata_port *ap, - struct ata_device **r_failed_dev) -{ - struct ata_eh_context *ehc = &ap->eh_context; - struct ata_device *dev; - unsigned long flags; - int i, rc = 0; - - DPRINTK("ENTER\n"); - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - unsigned int action; - - dev = &ap->device[i]; - action = ata_eh_dev_action(dev); - - if (action & ATA_EH_REVALIDATE && ata_dev_enabled(dev)) { - if (ata_port_offline(ap)) { - rc = -EIO; - break; - } - - ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE); - rc = ata_dev_revalidate(dev, - ehc->i.flags & ATA_EHI_DID_RESET); - if (rc) - break; - - ata_eh_done(ap, dev, ATA_EH_REVALIDATE); - - /* schedule the scsi_rescan_device() here */ - queue_work(ata_aux_wq, &(ap->scsi_rescan_task)); - } else if (dev->class == ATA_DEV_UNKNOWN && - ehc->tries[dev->devno] && - ata_class_enabled(ehc->classes[dev->devno])) { - dev->class = ehc->classes[dev->devno]; - - rc = ata_dev_read_id(dev, &dev->class, 1, dev->id); - if (rc == 0) - rc = ata_dev_configure(dev, 1); - - if (rc) { - dev->class = ATA_DEV_UNKNOWN; - break; - } - - spin_lock_irqsave(ap->lock, flags); - ap->flags |= ATA_FLAG_SCSI_HOTPLUG; - spin_unlock_irqrestore(ap->lock, flags); - } - } - - if (rc) - *r_failed_dev = dev; - - DPRINTK("EXIT\n"); - return rc; -} - -static int ata_port_nr_enabled(struct ata_port *ap) -{ - int i, cnt = 0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ata_dev_enabled(&ap->device[i])) - cnt++; - return cnt; -} - -static int ata_port_nr_vacant(struct ata_port *ap) -{ - int i, cnt = 0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ap->device[i].class == ATA_DEV_UNKNOWN) - cnt++; - return cnt; -} - -static int ata_eh_skip_recovery(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - int i; - - if (ap->flags & ATA_FLAG_FROZEN || ata_port_nr_enabled(ap)) - return 0; - - /* skip if class codes for all vacant slots are ATA_DEV_NONE */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - - if (dev->class == ATA_DEV_UNKNOWN && - ehc->classes[dev->devno] != ATA_DEV_NONE) - return 0; - } - - return 1; -} - -/** - * ata_eh_recover - recover host port after error - * @ap: host port to recover - * @prereset: prereset method (can be NULL) - * @softreset: softreset method (can be NULL) - * @hardreset: hardreset method (can be NULL) - * @postreset: postreset method (can be NULL) - * - * This is the alpha and omega, eum and yang, heart and soul of - * libata exception handling. On entry, actions required to - * recover the port and hotplug requests are recorded in - * eh_context. This function executes all the operations with - * appropriate retrials and fallbacks to resurrect failed - * devices, detach goners and greet newcomers. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno on failure. - */ -static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset) -{ - struct ata_eh_context *ehc = &ap->eh_context; - struct ata_device *dev; - int down_xfermask, i, rc; - - DPRINTK("ENTER\n"); - - /* prep for recovery */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; - - ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; - - /* process hotplug request */ - if (dev->flags & ATA_DFLAG_DETACH) - ata_eh_detach_dev(dev); - - if (!ata_dev_enabled(dev) && - ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno)))) { - ata_eh_detach_dev(dev); - ata_dev_init(dev); - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |= ATA_EH_SOFTRESET; - } - } - - retry: - down_xfermask = 0; - rc = 0; - - /* if UNLOADING, finish immediately */ - if (ap->flags & ATA_FLAG_UNLOADING) - goto out; - - /* skip EH if possible. */ - if (ata_eh_skip_recovery(ap)) - ehc->i.action = 0; - - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehc->classes[i] = ATA_DEV_UNKNOWN; - - /* reset */ - if (ehc->i.action & ATA_EH_RESET_MASK) { - ata_eh_freeze_port(ap); - - rc = ata_eh_reset(ap, ata_port_nr_vacant(ap), prereset, - softreset, hardreset, postreset); - if (rc) { - ata_port_printk(ap, KERN_ERR, - "reset failed, giving up\n"); - goto out; - } - - ata_eh_thaw_port(ap); - } - - /* revalidate existing devices and attach new ones */ - rc = ata_eh_revalidate_and_attach(ap, &dev); - if (rc) - goto dev_fail; - - /* configure transfer mode if the port has been reset */ - if (ehc->i.flags & ATA_EHI_DID_RESET) { - rc = ata_set_mode(ap, &dev); - if (rc) { - down_xfermask = 1; - goto dev_fail; - } - } - - goto out; - - dev_fail: - switch (rc) { - case -ENODEV: - /* device missing, schedule probing */ - ehc->i.probe_mask |= (1 << dev->devno); - case -EINVAL: - ehc->tries[dev->devno] = 0; - break; - case -EIO: - sata_down_spd_limit(ap); - default: - ehc->tries[dev->devno]--; - if (down_xfermask && - ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1)) - ehc->tries[dev->devno] = 0; - } - - if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) { - /* disable device if it has used up all its chances */ - ata_dev_disable(dev); - - /* detach if offline */ - if (ata_port_offline(ap)) - ata_eh_detach_dev(dev); - - /* probe if requested */ - if ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno))) { - ata_eh_detach_dev(dev); - ata_dev_init(dev); - - ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |= ATA_EH_SOFTRESET; - } - } else { - /* soft didn't work? be haaaaard */ - if (ehc->i.flags & ATA_EHI_DID_RESET) - ehc->i.action |= ATA_EH_HARDRESET; - else - ehc->i.action |= ATA_EH_SOFTRESET; - } - - if (ata_port_nr_enabled(ap)) { - ata_port_printk(ap, KERN_WARNING, "failed to recover some " - "devices, retrying in 5 secs\n"); - ssleep(5); - } else { - /* no device left, repeat fast */ - msleep(500); - } - - goto retry; - - out: - if (rc) { - for (i = 0; i < ATA_MAX_DEVICES; i++) - ata_dev_disable(&ap->device[i]); - } - - DPRINTK("EXIT, rc=%d\n", rc); - return rc; -} - -/** - * ata_eh_finish - finish up EH - * @ap: host port to finish EH for - * - * Recovery is complete. Clean up EH states and retry or finish - * failed qcs. - * - * LOCKING: - * None. - */ -static void ata_eh_finish(struct ata_port *ap) -{ - int tag; - - /* retry or finish qcs */ - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { - struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); - - if (!(qc->flags & ATA_QCFLAG_FAILED)) - continue; - - if (qc->err_mask) { - /* FIXME: Once EH migration is complete, - * generate sense data in this function, - * considering both err_mask and tf. - */ - if (qc->err_mask & AC_ERR_INVALID) - ata_eh_qc_complete(qc); - else - ata_eh_qc_retry(qc); - } else { - if (qc->flags & ATA_QCFLAG_SENSE_VALID) { - ata_eh_qc_complete(qc); - } else { - /* feed zero TF to sense generation */ - memset(&qc->result_tf, 0, sizeof(qc->result_tf)); - ata_eh_qc_retry(qc); - } - } - } -} - -/** - * ata_do_eh - do standard error handling - * @ap: host port to handle error for - * @prereset: prereset method (can be NULL) - * @softreset: softreset method (can be NULL) - * @hardreset: hardreset method (can be NULL) - * @postreset: postreset method (can be NULL) - * - * Perform standard error handling sequence. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset) -{ - if (!(ap->flags & ATA_FLAG_LOADING)) { - ata_eh_autopsy(ap); - ata_eh_report(ap); - } - - ata_eh_recover(ap, prereset, softreset, hardreset, postreset); - ata_eh_finish(ap); -} diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index 2915bca691e8..a0289ec3e283 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -38,10 +38,9 @@ #include #include #include -#include #include #include -#include +#include #include #include #include @@ -52,14 +51,10 @@ #define SECTOR_SIZE 512 typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd); - -static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev); -static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev); -static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, - unsigned int id, unsigned int lun); - +static struct ata_device * +ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); +static void ata_scsi_error(struct Scsi_Host *host); +enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); #define RW_RECOVERY_MPAGE 0x1 #define RW_RECOVERY_MPAGE_LEN 12 @@ -107,7 +102,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { struct scsi_transport_template ata_scsi_transport_template = { .eh_strategy_handler = ata_scsi_error, .eh_timed_out = ata_scsi_timed_out, - .user_scan = ata_scsi_user_scan, }; @@ -222,7 +216,9 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) && copy_to_user(arg + sizeof(args), argbuf, argsize)) rc = -EFAULT; error: - kfree(argbuf); + if (argbuf) + kfree(argbuf); + return rc; } @@ -308,6 +304,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) /** * ata_scsi_qc_new - acquire new ata_queued_cmd reference + * @ap: ATA port to which the new command is attached * @dev: ATA device to which the new command is attached * @cmd: SCSI command that originated this ATA command * @done: SCSI command completion function @@ -326,13 +323,14 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) * RETURNS: * Command allocated, or %NULL if none available. */ -struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, +struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap, + struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { struct ata_queued_cmd *qc; - qc = ata_qc_new_init(dev); + qc = ata_qc_new_init(ap, dev); if (qc) { qc->scsicmd = cmd; qc->scsidone = done; @@ -399,18 +397,18 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) int ata_scsi_device_resume(struct scsi_device *sdev) { - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); + struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; + struct ata_device *dev = &ap->device[sdev->id]; - return ata_device_resume(dev); + return ata_device_resume(ap, dev); } int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) { - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); + struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0]; + struct ata_device *dev = &ap->device[sdev->id]; - return ata_device_suspend(dev, state); + return ata_device_suspend(ap, dev, state); } /** @@ -421,7 +419,6 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) * @sk: the sense key we'll fill out * @asc: the additional sense code we'll fill out * @ascq: the additional sense code qualifier we'll fill out - * @verbose: be verbose * * Converts an ATA error into a SCSI error. Fill out pointers to * SK, ASC, and ASCQ bytes for later use in fixed or descriptor @@ -431,7 +428,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) * spin_lock_irqsave(host_set lock) */ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, - u8 *ascq, int verbose) + u8 *ascq) { int i; @@ -496,9 +493,8 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, } } /* No immediate match */ - if (verbose) - printk(KERN_WARNING "ata%u: no sense translation for " - "error 0x%02x\n", id, drv_err); + printk(KERN_WARNING "ata%u: no sense translation for " + "error 0x%02x\n", id, drv_err); } /* Fall back to interpreting status bits */ @@ -511,9 +507,8 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, } } /* No error? Undecoded? */ - if (verbose) - printk(KERN_WARNING "ata%u: no sense translation for " - "status: 0x%02x\n", id, drv_stat); + printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n", + id, drv_stat); /* We need a sensible error return here, which is tricky, and one that won't cause people to do things like return a disk wrongly */ @@ -522,10 +517,9 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, *ascq = 0x00; translate_done: - if (verbose) - printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x " - "to SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", - id, drv_stat, drv_err, *sk, *asc, *ascq); + printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to " + "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err, + *sk, *asc, *ascq); return; } @@ -545,23 +539,27 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; - struct ata_taskfile *tf = &qc->result_tf; + struct ata_taskfile *tf = &qc->tf; unsigned char *sb = cmd->sense_buffer; unsigned char *desc = sb + 8; - int verbose = qc->ap->ops->error_handler == NULL; memset(sb, 0, SCSI_SENSE_BUFFERSIZE); cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + /* + * Read the controller registers. + */ + WARN_ON(qc->ap->ops->tf_read == NULL); + qc->ap->ops->tf_read(qc->ap, tf); + /* * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ - if (qc->err_mask || - tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, - &sb[1], &sb[2], &sb[3], verbose); + &sb[1], &sb[2], &sb[3]); sb[1] &= 0x0f; } @@ -617,22 +615,26 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) void ata_gen_fixed_sense(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; - struct ata_taskfile *tf = &qc->result_tf; + struct ata_taskfile *tf = &qc->tf; unsigned char *sb = cmd->sense_buffer; - int verbose = qc->ap->ops->error_handler == NULL; memset(sb, 0, SCSI_SENSE_BUFFERSIZE); cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; + /* + * Read the controller registers. + */ + WARN_ON(qc->ap->ops->tf_read == NULL); + qc->ap->ops->tf_read(qc->ap, tf); + /* * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ - if (qc->err_mask || - tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, - &sb[2], &sb[12], &sb[13], verbose); + &sb[2], &sb[12], &sb[13]); sb[2] &= 0x0f; } @@ -675,7 +677,7 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, */ max_sectors = ATA_MAX_SECTORS; if (dev->flags & ATA_DFLAG_LBA48) - max_sectors = ATA_MAX_SECTORS_LBA48; + max_sectors = 2048; if (dev->max_sectors) max_sectors = dev->max_sectors; @@ -690,14 +692,6 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, request_queue_t *q = sdev->request_queue; blk_queue_max_hw_segments(q, q->max_hw_segments - 1); } - - if (dev->flags & ATA_DFLAG_NCQ) { - int depth; - - depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); - depth = min(ATA_MAX_QUEUE - 1, depth); - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); - } } /** @@ -714,88 +708,152 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, int ata_scsi_slave_config(struct scsi_device *sdev) { - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); - ata_scsi_sdev_config(sdev); blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); - if (dev) + if (sdev->id < ATA_MAX_DEVICES) { + struct ata_port *ap; + struct ata_device *dev; + + ap = (struct ata_port *) &sdev->host->hostdata[0]; + dev = &ap->device[sdev->id]; + ata_scsi_dev_config(sdev, dev); + } return 0; /* scsi layer doesn't check return value, sigh */ } /** - * ata_scsi_slave_destroy - SCSI device is about to be destroyed - * @sdev: SCSI device to be destroyed + * ata_scsi_timed_out - SCSI layer time out callback + * @cmd: timed out SCSI command * - * @sdev is about to be destroyed for hot/warm unplugging. If - * this unplugging was initiated by libata as indicated by NULL - * dev->sdev, this function doesn't have to do anything. - * Otherwise, SCSI layer initiated warm-unplug is in progress. - * Clear dev->sdev, schedule the device for ATA detach and invoke - * EH. + * Handles SCSI layer timeout. We race with normal completion of + * the qc for @cmd. If the qc is already gone, we lose and let + * the scsi command finish (EH_HANDLED). Otherwise, the qc has + * timed out and EH should be invoked. Prevent ata_qc_complete() + * from finishing it by setting EH_SCHEDULED and return + * EH_NOT_HANDLED. * * LOCKING: - * Defined by SCSI layer. We don't really care. + * Called from timer context + * + * RETURNS: + * EH_HANDLED or EH_NOT_HANDLED */ -void ata_scsi_slave_destroy(struct scsi_device *sdev) +enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) { - struct ata_port *ap = ata_shost_to_port(sdev->host); + struct Scsi_Host *host = cmd->device->host; + struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; unsigned long flags; - struct ata_device *dev; + struct ata_queued_cmd *qc; + enum scsi_eh_timer_return ret = EH_HANDLED; - if (!ap->ops->error_handler) - return; + DPRINTK("ENTER\n"); - spin_lock_irqsave(ap->lock, flags); - dev = __ata_scsi_find_dev(ap, sdev); - if (dev && dev->sdev) { - /* SCSI device already in CANCEL state, no need to offline it */ - dev->sdev = NULL; - dev->flags |= ATA_DFLAG_DETACH; - ata_port_schedule_eh(ap); + spin_lock_irqsave(&ap->host_set->lock, flags); + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc) { + WARN_ON(qc->scsicmd != cmd); + qc->flags |= ATA_QCFLAG_EH_SCHEDULED; + qc->err_mask |= AC_ERR_TIMEOUT; + ret = EH_NOT_HANDLED; } - spin_unlock_irqrestore(ap->lock, flags); + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + DPRINTK("EXIT, ret=%d\n", ret); + return ret; } /** - * ata_scsi_change_queue_depth - SCSI callback for queue depth config - * @sdev: SCSI device to configure queue depth for - * @queue_depth: new queue depth + * ata_scsi_error - SCSI layer error handler callback + * @host: SCSI host on which error occurred * - * This is libata standard hostt->change_queue_depth callback. - * SCSI will call into this callback when user tries to set queue - * depth via sysfs. + * Handles SCSI-layer-thrown error events. * * LOCKING: - * SCSI layer (we don't care) - * - * RETURNS: - * Newly configured queue depth. + * Inherited from SCSI layer (none, can sleep) */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) + +static void ata_scsi_error(struct Scsi_Host *host) { - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev; - int max_depth; + struct ata_port *ap; + unsigned long flags; - if (queue_depth < 1) - return sdev->queue_depth; + DPRINTK("ENTER\n"); - dev = ata_scsi_find_dev(ap, sdev); - if (!dev || !ata_dev_enabled(dev)) - return sdev->queue_depth; + ap = (struct ata_port *) &host->hostdata[0]; - max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); - max_depth = min(ATA_MAX_QUEUE - 1, max_depth); - if (queue_depth > max_depth) - queue_depth = max_depth; + spin_lock_irqsave(&ap->host_set->lock, flags); + WARN_ON(ap->flags & ATA_FLAG_IN_EH); + ap->flags |= ATA_FLAG_IN_EH; + WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL); + spin_unlock_irqrestore(&ap->host_set->lock, flags); - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); - return queue_depth; + ata_port_flush_task(ap); + + ap->ops->eng_timeout(ap); + + WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); + + scsi_eh_flush_done_q(&ap->eh_done_q); + + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_IN_EH; + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + DPRINTK("EXIT\n"); +} + +static void ata_eh_scsidone(struct scsi_cmnd *scmd) +{ + /* nada */ +} + +static void __ata_eh_qc_complete(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct scsi_cmnd *scmd = qc->scsicmd; + unsigned long flags; + + spin_lock_irqsave(&ap->host_set->lock, flags); + qc->scsidone = ata_eh_scsidone; + __ata_qc_complete(qc); + WARN_ON(ata_tag_valid(qc->tag)); + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + scsi_eh_finish_cmd(scmd, &ap->eh_done_q); +} + +/** + * ata_eh_qc_complete - Complete an active ATA command from EH + * @qc: Command to complete + * + * Indicate to the mid and upper layers that an ATA command has + * completed. To be used from EH. + */ +void ata_eh_qc_complete(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *scmd = qc->scsicmd; + scmd->retries = scmd->allowed; + __ata_eh_qc_complete(qc); +} + +/** + * ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH + * @qc: Command to retry + * + * Indicate to the mid and upper layers that an ATA command + * should be retried. To be used from EH. + * + * SCSI midlayer limits the number of retries to scmd->allowed. + * This function might need to adjust scmd->retries for commands + * which get retried due to unrelated NCQ failures. + */ +void ata_eh_qc_retry(struct ata_queued_cmd *qc) +{ + __ata_eh_qc_complete(qc); } /** @@ -833,7 +891,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, tf->nsect = 1; /* 1 sector, lba=0 */ if (qc->dev->flags & ATA_DFLAG_LBA) { - tf->flags |= ATA_TFLAG_LBA; + qc->tf.flags |= ATA_TFLAG_LBA; tf->lbah = 0x0; tf->lbam = 0x0; @@ -1137,7 +1195,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm u64 block; u32 n_block; - qc->flags |= ATA_QCFLAG_IO; tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || @@ -1184,36 +1241,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm */ goto nothing_to_do; - if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) { - /* yay, NCQ */ - if (!lba_48_ok(block, n_block)) - goto out_of_range; - - tf->protocol = ATA_PROT_NCQ; - tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48; - - if (tf->flags & ATA_TFLAG_WRITE) - tf->command = ATA_CMD_FPDMA_WRITE; - else - tf->command = ATA_CMD_FPDMA_READ; - - qc->nsect = n_block; - - tf->nsect = qc->tag << 3; - tf->hob_feature = (n_block >> 8) & 0xff; - tf->feature = n_block & 0xff; - - tf->hob_lbah = (block >> 40) & 0xff; - tf->hob_lbam = (block >> 32) & 0xff; - tf->hob_lbal = (block >> 24) & 0xff; - tf->lbah = (block >> 16) & 0xff; - tf->lbam = (block >> 8) & 0xff; - tf->lbal = block & 0xff; - - tf->device = 1 << 6; - if (tf->flags & ATA_TFLAG_FUA) - tf->device |= 1 << 7; - } else if (dev->flags & ATA_DFLAG_LBA) { + if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; if (lba_28_ok(block, n_block)) { @@ -1304,17 +1332,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) u8 *cdb = cmd->cmnd; int need_sense = (qc->err_mask != 0); - /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and - * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE - * cache - */ - if (!need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && - ((qc->tf.feature == SETFEATURES_WC_ON) || - (qc->tf.feature == SETFEATURES_WC_OFF))) { - qc->ap->eh_info.action |= ATA_EH_REVALIDATE; - ata_port_schedule_eh(qc->ap); - } - /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we * generate because the user forced us to, a check condition @@ -1339,49 +1356,19 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) } } - if (need_sense && !qc->ap->ops->error_handler) - ata_dump_status(qc->ap->id, &qc->result_tf); + if (need_sense) { + /* The ata_gen_..._sense routines fill in tf */ + ata_dump_status(qc->ap->id, &qc->tf); + } qc->scsidone(cmd); ata_qc_free(qc); } -/** - * ata_scmd_need_defer - Check whether we need to defer scmd - * @dev: ATA device to which the command is addressed - * @is_io: Is the command IO (and thus possibly NCQ)? - * - * NCQ and non-NCQ commands cannot run together. As upper layer - * only knows the queue depth, we are responsible for maintaining - * exclusion. This function checks whether a new command can be - * issued to @dev. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * 1 if deferring is needed, 0 otherwise. - */ -static int ata_scmd_need_defer(struct ata_device *dev, int is_io) -{ - struct ata_port *ap = dev->ap; - - if (!(dev->flags & ATA_DFLAG_NCQ)) - return 0; - - if (is_io) { - if (!ata_tag_valid(ap->active_tag)) - return 0; - } else { - if (!ata_tag_valid(ap->active_tag) && !ap->sactive) - return 0; - } - return 1; -} - /** * ata_scsi_translate - Translate then issue SCSI command to ATA device + * @ap: ATA port to which the command is addressed * @dev: ATA device to which the command is addressed * @cmd: SCSI command to execute * @done: SCSI command completion function @@ -1402,25 +1389,19 @@ static int ata_scmd_need_defer(struct ata_device *dev, int is_io) * * LOCKING: * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY if the command - * needs to be deferred. */ -static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, + +static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, + struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), ata_xlat_func_t xlat_func) { struct ata_queued_cmd *qc; u8 *scsicmd = cmd->cmnd; - int is_io = xlat_func == ata_scsi_rw_xlat; VPRINTK("ENTER\n"); - if (unlikely(ata_scmd_need_defer(dev, is_io))) - goto defer; - - qc = ata_scsi_qc_new(dev, cmd, done); + qc = ata_scsi_qc_new(ap, dev, cmd, done); if (!qc) goto err_mem; @@ -1428,8 +1409,8 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, if (cmd->sc_data_direction == DMA_FROM_DEVICE || cmd->sc_data_direction == DMA_TO_DEVICE) { if (unlikely(cmd->request_bufflen < 1)) { - ata_dev_printk(dev, KERN_WARNING, - "WARNING: zero len r/w req\n"); + printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", + ap->id, dev->devno); goto err_did; } @@ -1451,13 +1432,13 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, ata_qc_issue(qc); VPRINTK("EXIT\n"); - return 0; + return; early_finish: ata_qc_free(qc); done(cmd); DPRINTK("EXIT - early finish (good or error)\n"); - return 0; + return; err_did: ata_qc_free(qc); @@ -1465,11 +1446,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, cmd->result = (DID_ERROR << 16); done(cmd); DPRINTK("EXIT - internal\n"); - return 0; - -defer: - DPRINTK("EXIT - defer\n"); - return SCSI_MLQUEUE_DEVICE_BUSY; + return; } /** @@ -1967,7 +1944,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, return 0; dpofua = 0; - if (ata_dev_supports_fua(args->id) && (dev->flags & ATA_DFLAG_LBA48) && + if (ata_dev_supports_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 && (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count)) dpofua = 1 << 4; @@ -2160,14 +2137,13 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 static void atapi_sense_complete(struct ata_queued_cmd *qc) { - if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) { + if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); - } qc->scsidone(qc->scsicmd); ata_qc_free(qc); @@ -2231,38 +2207,21 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) VPRINTK("ENTER, err_mask 0x%X\n", err_mask); - /* handle completion from new EH */ - if (unlikely(qc->ap->ops->error_handler && - (err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID))) { - - if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) { - /* FIXME: not quite right; we don't want the - * translation of taskfile registers into a - * sense descriptors, since that's only - * correct for ATA, not ATAPI - */ - ata_gen_ata_desc_sense(qc); - } - - qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; - qc->scsidone(cmd); - ata_qc_free(qc); - return; - } - - /* successful completion or old EH failure path */ if (unlikely(err_mask & AC_ERR_DEV)) { cmd->result = SAM_STAT_CHECK_CONDITION; atapi_request_sense(qc); return; - } else if (unlikely(err_mask)) { + } + + else if (unlikely(err_mask)) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); - } else { + + else { u8 *scsicmd = cmd->cmnd; if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { @@ -2344,63 +2303,18 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) qc->tf.protocol = ATA_PROT_ATAPI_DMA; qc->tf.feature |= ATAPI_PKT_DMA; - if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE)) - /* some SATA bridges need us to indicate data xfer direction */ +#ifdef ATAPI_ENABLE_DMADIR + /* some SATA bridges need us to indicate data xfer direction */ + if (cmd->sc_data_direction != DMA_TO_DEVICE) qc->tf.feature |= ATAPI_DMADIR; +#endif } - qc->nbytes = cmd->request_bufflen; + qc->nbytes = cmd->bufflen; return 0; } -static struct ata_device * ata_find_dev(struct ata_port *ap, int id) -{ - if (likely(id < ATA_MAX_DEVICES)) - return &ap->device[id]; - return NULL; -} - -static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap, - const struct scsi_device *scsidev) -{ - /* skip commands not addressed to targets we simulate */ - if (unlikely(scsidev->channel || scsidev->lun)) - return NULL; - - return ata_find_dev(ap, scsidev->id); -} - -/** - * ata_scsi_dev_enabled - determine if device is enabled - * @dev: ATA device - * - * Determine if commands should be sent to the specified device. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * 0 if commands are not allowed / 1 if commands are allowed - */ - -static int ata_scsi_dev_enabled(struct ata_device *dev) -{ - if (unlikely(!ata_dev_enabled(dev))) - return 0; - - if (!atapi_enabled || (dev->ap->flags & ATA_FLAG_NO_ATAPI)) { - if (unlikely(dev->class == ATA_DEV_ATAPI)) { - ata_dev_printk(dev, KERN_WARNING, - "WARNING: ATAPI is %s, device ignored.\n", - atapi_enabled ? "not supported with this driver" : "disabled"); - return 0; - } - } - - return 1; -} - /** * ata_scsi_find_dev - lookup ata_device from scsi_cmnd * @ap: ATA port to which the device is attached @@ -2417,14 +2331,33 @@ static int ata_scsi_dev_enabled(struct ata_device *dev) * RETURNS: * Associated ATA device, or %NULL if not found. */ + static struct ata_device * ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) { - struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); + struct ata_device *dev; - if (unlikely(!dev || !ata_scsi_dev_enabled(dev))) + /* skip commands not addressed to targets we simulate */ + if (likely(scsidev->id < ATA_MAX_DEVICES)) + dev = &ap->device[scsidev->id]; + else return NULL; + if (unlikely((scsidev->channel != 0) || + (scsidev->lun != 0))) + return NULL; + + if (unlikely(!ata_dev_present(dev))) + return NULL; + + if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) { + if (unlikely(dev->class == ATA_DEV_ATAPI)) { + printk(KERN_WARNING "ata%u(%u): WARNING: ATAPI is %s, device ignored.\n", + ap->id, dev->devno, atapi_enabled ? "not supported with this driver" : "disabled"); + return NULL; + } + } + return dev; } @@ -2481,15 +2414,10 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) { struct ata_taskfile *tf = &(qc->tf); struct scsi_cmnd *cmd = qc->scsicmd; - struct ata_device *dev = qc->dev; if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) goto invalid_fld; - /* We may not issue DMA commands if no DMA mode is set */ - if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) - goto invalid_fld; - if (scsicmd[1] & 0xe0) /* PIO multi not supported yet */ goto invalid_fld; @@ -2572,10 +2500,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) * TODO: find out if we need to do more here to * cover scatter/gather case. */ - qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE; - - /* request result TF */ - qc->flags |= ATA_QCFLAG_RESULT_TF; + qc->nsect = cmd->bufflen / ATA_SECT_SIZE; return 0; @@ -2653,24 +2578,19 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, #endif } -static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *), - struct ata_device *dev) +static inline void __ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), + struct ata_port *ap, struct ata_device *dev) { - int rc = 0; - if (dev->class == ATA_DEV_ATA) { ata_xlat_func_t xlat_func = ata_get_xlat_func(dev, cmd->cmnd[0]); if (xlat_func) - rc = ata_scsi_translate(dev, cmd, done, xlat_func); + ata_scsi_translate(ap, dev, cmd, done, xlat_func); else - ata_scsi_simulate(dev, cmd, done); + ata_scsi_simulate(ap, dev, cmd, done); } else - rc = ata_scsi_translate(dev, cmd, done, atapi_xlat); - - return rc; + ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); } /** @@ -2689,39 +2609,39 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd, * Releases scsi-layer-held lock, and obtains host_set lock. * * RETURNS: - * Return value from __ata_scsi_queuecmd() if @cmd can be queued, - * 0 otherwise. + * Zero. */ + int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { struct ata_port *ap; struct ata_device *dev; struct scsi_device *scsidev = cmd->device; struct Scsi_Host *shost = scsidev->host; - int rc = 0; - ap = ata_shost_to_port(shost); + ap = (struct ata_port *) &shost->hostdata[0]; spin_unlock(shost->host_lock); - spin_lock(ap->lock); + spin_lock(&ap->host_set->lock); ata_scsi_dump_cdb(ap, cmd); dev = ata_scsi_find_dev(ap, scsidev); if (likely(dev)) - rc = __ata_scsi_queuecmd(cmd, done, dev); + __ata_scsi_queuecmd(cmd, done, ap, dev); else { cmd->result = (DID_BAD_TARGET << 16); done(cmd); } - spin_unlock(ap->lock); + spin_unlock(&ap->host_set->lock); spin_lock(shost->host_lock); - return rc; + return 0; } /** * ata_scsi_simulate - simulate SCSI command on ATA device + * @ap: port the device is connected to * @dev: the target device * @cmd: SCSI command being sent to device. * @done: SCSI command completion function. @@ -2733,12 +2653,14 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) * spin_lock_irqsave(host_set lock) */ -void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, +void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, + struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { struct ata_scsi_args args; const u8 *scsicmd = cmd->cmnd; + args.ap = ap; args.dev = dev; args.id = dev->id; args.cmd = cmd; @@ -2810,241 +2732,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void ata_scsi_scan_host(struct ata_port *ap) { + struct ata_device *dev; unsigned int i; - if (ap->flags & ATA_FLAG_DISABLED) + if (ap->flags & ATA_FLAG_PORT_DISABLED) return; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - struct scsi_device *sdev; - - if (!ata_dev_enabled(dev) || dev->sdev) - continue; - - sdev = __scsi_add_device(ap->host, 0, i, 0, NULL); - if (!IS_ERR(sdev)) { - dev->sdev = sdev; - scsi_device_put(sdev); - } - } -} - -/** - * ata_scsi_offline_dev - offline attached SCSI device - * @dev: ATA device to offline attached SCSI device for - * - * This function is called from ata_eh_hotplug() and responsible - * for taking the SCSI device attached to @dev offline. This - * function is called with host_set lock which protects dev->sdev - * against clearing. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * 1 if attached SCSI device exists, 0 otherwise. - */ -int ata_scsi_offline_dev(struct ata_device *dev) -{ - if (dev->sdev) { - scsi_device_set_state(dev->sdev, SDEV_OFFLINE); - return 1; - } - return 0; -} - -/** - * ata_scsi_remove_dev - remove attached SCSI device - * @dev: ATA device to remove attached SCSI device for - * - * This function is called from ata_eh_scsi_hotplug() and - * responsible for removing the SCSI device attached to @dev. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -static void ata_scsi_remove_dev(struct ata_device *dev) -{ - struct ata_port *ap = dev->ap; - struct scsi_device *sdev; - unsigned long flags; - - /* Alas, we need to grab scan_mutex to ensure SCSI device - * state doesn't change underneath us and thus - * scsi_device_get() always succeeds. The mutex locking can - * be removed if there is __scsi_device_get() interface which - * increments reference counts regardless of device state. - */ - mutex_lock(&ap->host->scan_mutex); - spin_lock_irqsave(ap->lock, flags); - - /* clearing dev->sdev is protected by host_set lock */ - sdev = dev->sdev; - dev->sdev = NULL; - - if (sdev) { - /* If user initiated unplug races with us, sdev can go - * away underneath us after the host_set lock and - * scan_mutex are released. Hold onto it. - */ - if (scsi_device_get(sdev) == 0) { - /* The following ensures the attached sdev is - * offline on return from ata_scsi_offline_dev() - * regardless it wins or loses the race - * against this function. - */ - scsi_device_set_state(sdev, SDEV_OFFLINE); - } else { - WARN_ON(1); - sdev = NULL; - } - } - - spin_unlock_irqrestore(ap->lock, flags); - mutex_unlock(&ap->host->scan_mutex); - - if (sdev) { - ata_dev_printk(dev, KERN_INFO, "detaching (SCSI %s)\n", - sdev->sdev_gendev.bus_id); - - scsi_remove_device(sdev); - scsi_device_put(sdev); - } -} - -/** - * ata_scsi_hotplug - SCSI part of hotplug - * @data: Pointer to ATA port to perform SCSI hotplug on - * - * Perform SCSI part of hotplug. It's executed from a separate - * workqueue after EH completes. This is necessary because SCSI - * hot plugging requires working EH and hot unplugging is - * synchronized with hot plugging with a mutex. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_scsi_hotplug(void *data) -{ - struct ata_port *ap = data; - int i; - - if (ap->flags & ATA_FLAG_UNLOADING) { - DPRINTK("ENTER/EXIT - unloading\n"); - return; - } - - DPRINTK("ENTER\n"); - - /* unplug detached devices */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - unsigned long flags; - - if (!(dev->flags & ATA_DFLAG_DETACHED)) - continue; - - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_DETACHED; - spin_unlock_irqrestore(ap->lock, flags); - - ata_scsi_remove_dev(dev); - } - - /* scan for new ones */ - ata_scsi_scan_host(ap); - - /* If we scanned while EH was in progress, scan would have - * failed silently. Requeue if there are enabled but - * unattached devices. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev) && !dev->sdev) { - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, HZ); - break; - } - } - - DPRINTK("EXIT\n"); -} - -/** - * ata_scsi_user_scan - indication for user-initiated bus scan - * @shost: SCSI host to scan - * @channel: Channel to scan - * @id: ID to scan - * @lun: LUN to scan - * - * This function is called when user explicitly requests bus - * scan. Set probe pending flag and invoke EH. - * - * LOCKING: - * SCSI layer (we don't care) - * - * RETURNS: - * Zero. - */ -static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, - unsigned int id, unsigned int lun) -{ - struct ata_port *ap = ata_shost_to_port(shost); - unsigned long flags; - int rc = 0; - - if (!ap->ops->error_handler) - return -EOPNOTSUPP; - - if ((channel != SCAN_WILD_CARD && channel != 0) || - (lun != SCAN_WILD_CARD && lun != 0)) - return -EINVAL; - - spin_lock_irqsave(ap->lock, flags); - - if (id == SCAN_WILD_CARD) { - ap->eh_info.probe_mask |= (1 << ATA_MAX_DEVICES) - 1; - ap->eh_info.action |= ATA_EH_SOFTRESET; - } else { - struct ata_device *dev = ata_find_dev(ap, id); - - if (dev) { - ap->eh_info.probe_mask |= 1 << dev->devno; - ap->eh_info.action |= ATA_EH_SOFTRESET; - } else - rc = -EINVAL; - } - - if (rc == 0) - ata_port_schedule_eh(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - return rc; -} - -/** - * ata_scsi_dev_rescan - initiate scsi_rescan_device() - * @data: Pointer to ATA port to perform scsi_rescan_device() - * - * After ATA pass thru (SAT) commands are executed successfully, - * libata need to propagate the changes to SCSI layer. This - * function must be executed from ata_aux_wq such that sdev - * attach/detach don't race with rescan. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -void ata_scsi_dev_rescan(void *data) -{ - struct ata_port *ap = data; - struct ata_device *dev; - unsigned int i; - for (i = 0; i < ATA_MAX_DEVICES; i++) { dev = &ap->device[i]; - if (ata_dev_enabled(dev) && dev->sdev) - scsi_rescan_device(&(dev->sdev->sdev_gendev)); + if (ata_dev_present(dev)) + scsi_scan_target(&ap->host->shost_gendev, 0, i, 0, 0); } } + diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index c325679d9b54..bac8cbae06fe 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -29,9 +29,10 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "2.00" /* must be exactly four chars */ +#define DRV_VERSION "1.20" /* must be exactly four chars */ struct ata_scsi_args { + struct ata_port *ap; struct ata_device *dev; u16 *id; struct scsi_cmnd *cmd; @@ -39,34 +40,18 @@ struct ata_scsi_args { }; /* libata-core.c */ -extern struct workqueue_struct *ata_aux_wq; extern int atapi_enabled; -extern int atapi_dmadir; extern int libata_fua; -extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); +extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, + struct ata_device *dev); extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); -extern void ata_dev_disable(struct ata_device *dev); extern void ata_port_flush_task(struct ata_port *ap); -extern unsigned ata_exec_internal(struct ata_device *dev, - struct ata_taskfile *tf, const u8 *cdb, - int dma_dir, void *buf, unsigned int buflen); -extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); -extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, - int post_reset, u16 *id); -extern int ata_dev_configure(struct ata_device *dev, int print_info); -extern int sata_down_spd_limit(struct ata_port *ap); -extern int sata_set_spd_needed(struct ata_port *ap); -extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0); -extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); extern void ata_qc_free(struct ata_queued_cmd *qc); extern void ata_qc_issue(struct ata_queued_cmd *qc); -extern void __ata_qc_complete(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); extern void swap_buf_le16(u16 *buf, unsigned int buf_words); -extern int ata_flush_cache(struct ata_device *dev); -extern void ata_dev_init(struct ata_device *dev); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); @@ -75,8 +60,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct scsi_transport_template ata_scsi_transport_template; extern void ata_scsi_scan_host(struct ata_port *ap); -extern int ata_scsi_offline_dev(struct ata_device *dev); -extern void ata_scsi_hotplug(void *data); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen); @@ -105,13 +88,5 @@ extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor) (struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen)); -extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); -extern void ata_scsi_dev_rescan(void *data); - -/* libata-eh.c */ -extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); -extern void ata_scsi_error(struct Scsi_Host *host); -extern void ata_port_wait_eh(struct ata_port *ap); -extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); #endif /* __LIBATA_H__ */ diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c deleted file mode 100644 index 2673a11a9495..000000000000 --- a/trunk/drivers/scsi/libiscsi.c +++ /dev/null @@ -1,1702 +0,0 @@ -/* - * iSCSI lib functions - * - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. - * Copyright (C) 2004 - 2006 Mike Christie - * Copyright (C) 2004 - 2005 Dmitry Yusupov - * Copyright (C) 2004 - 2005 Alex Aizman - * maintained by open-iscsi@googlegroups.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct iscsi_session * -class_to_transport_session(struct iscsi_cls_session *cls_session) -{ - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - return iscsi_hostdata(shost->hostdata); -} -EXPORT_SYMBOL_GPL(class_to_transport_session); - -#define INVALID_SN_DELTA 0xffff - -int -iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) -{ - uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn); - uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn); - - if (max_cmdsn < exp_cmdsn -1 && - max_cmdsn > exp_cmdsn - INVALID_SN_DELTA) - return ISCSI_ERR_MAX_CMDSN; - if (max_cmdsn > session->max_cmdsn || - max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA) - session->max_cmdsn = max_cmdsn; - if (exp_cmdsn > session->exp_cmdsn || - exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA) - session->exp_cmdsn = exp_cmdsn; - - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn); - -void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, - struct iscsi_data *hdr, - int transport_data_cnt) -{ - struct iscsi_conn *conn = ctask->conn; - - memset(hdr, 0, sizeof(struct iscsi_data)); - hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); - hdr->datasn = cpu_to_be32(ctask->unsol_datasn); - ctask->unsol_datasn++; - hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - - hdr->itt = ctask->hdr->itt; - hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); - - hdr->offset = cpu_to_be32(ctask->total_length - - transport_data_cnt - - ctask->unsol_count); - - if (ctask->unsol_count > conn->max_xmit_dlength) { - hton24(hdr->dlength, conn->max_xmit_dlength); - ctask->data_count = conn->max_xmit_dlength; - hdr->flags = 0; - } else { - hton24(hdr->dlength, ctask->unsol_count); - ctask->data_count = ctask->unsol_count; - hdr->flags = ISCSI_FLAG_CMD_FINAL; - } -} -EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu); - -/** - * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu - * @ctask: iscsi cmd task - * - * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set - * fields like dlength or final based on how much data it sends - */ -static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) -{ - struct iscsi_conn *conn = ctask->conn; - struct iscsi_session *session = conn->session; - struct iscsi_cmd *hdr = ctask->hdr; - struct scsi_cmnd *sc = ctask->sc; - - hdr->opcode = ISCSI_OP_SCSI_CMD; - hdr->flags = ISCSI_ATTR_SIMPLE; - int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); - hdr->itt = ctask->itt | (conn->id << ISCSI_CID_SHIFT) | - (session->age << ISCSI_AGE_SHIFT); - hdr->data_length = cpu_to_be32(sc->request_bufflen); - hdr->cmdsn = cpu_to_be32(session->cmdsn); - session->cmdsn++; - hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); - memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); - memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); - - if (sc->sc_data_direction == DMA_TO_DEVICE) { - hdr->flags |= ISCSI_FLAG_CMD_WRITE; - /* - * Write counters: - * - * imm_count bytes to be sent right after - * SCSI PDU Header - * - * unsol_count bytes(as Data-Out) to be sent - * without R2T ack right after - * immediate data - * - * r2t_data_count bytes to be sent via R2T ack's - * - * pad_count bytes to be sent as zero-padding - */ - ctask->imm_count = 0; - ctask->unsol_count = 0; - ctask->unsol_datasn = 0; - - if (session->imm_data_en) { - if (ctask->total_length >= session->first_burst) - ctask->imm_count = min(session->first_burst, - conn->max_xmit_dlength); - else - ctask->imm_count = min(ctask->total_length, - conn->max_xmit_dlength); - hton24(ctask->hdr->dlength, ctask->imm_count); - } else - zero_data(ctask->hdr->dlength); - - if (!session->initial_r2t_en) - ctask->unsol_count = min(session->first_burst, - ctask->total_length) - ctask->imm_count; - if (!ctask->unsol_count) - /* No unsolicit Data-Out's */ - ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; - } else { - ctask->datasn = 0; - hdr->flags |= ISCSI_FLAG_CMD_FINAL; - zero_data(hdr->dlength); - - if (sc->sc_data_direction == DMA_FROM_DEVICE) - hdr->flags |= ISCSI_FLAG_CMD_READ; - } - - conn->scsicmd_pdus_cnt++; -} -EXPORT_SYMBOL_GPL(iscsi_prep_scsi_cmd_pdu); - -/** - * iscsi_complete_command - return command back to scsi-ml - * @session: iscsi session - * @ctask: iscsi cmd task - * - * Must be called with session lock. - * This function returns the scsi command to scsi-ml and returns - * the cmd task to the pool of available cmd tasks. - */ -static void iscsi_complete_command(struct iscsi_session *session, - struct iscsi_cmd_task *ctask) -{ - struct scsi_cmnd *sc = ctask->sc; - - ctask->sc = NULL; - list_del_init(&ctask->running); - __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); - sc->scsi_done(sc); -} - -/** - * iscsi_cmd_rsp - SCSI Command Response processing - * @conn: iscsi connection - * @hdr: iscsi header - * @ctask: scsi command task - * @data: cmd data buffer - * @datalen: len of buffer - * - * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and - * then completes the command and task. - **/ -static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - struct iscsi_cmd_task *ctask, char *data, - int datalen) -{ - int rc; - struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)hdr; - struct iscsi_session *session = conn->session; - struct scsi_cmnd *sc = ctask->sc; - - rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); - if (rc) { - sc->result = DID_ERROR << 16; - goto out; - } - - conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; - - sc->result = (DID_OK << 16) | rhdr->cmd_status; - - if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) { - sc->result = DID_ERROR << 16; - goto out; - } - - if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION) { - int senselen; - - if (datalen < 2) { -invalid_datalen: - printk(KERN_ERR "iscsi: Got CHECK_CONDITION but " - "invalid data buffer size of %d\n", datalen); - sc->result = DID_BAD_TARGET << 16; - goto out; - } - - senselen = (data[0] << 8) | data[1]; - if (datalen < senselen) - goto invalid_datalen; - - memcpy(sc->sense_buffer, data + 2, - min(senselen, SCSI_SENSE_BUFFERSIZE)); - debug_scsi("copied %d bytes of sense\n", - min(senselen, SCSI_SENSE_BUFFERSIZE)); - } - - if (sc->sc_data_direction == DMA_TO_DEVICE) - goto out; - - if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { - int res_count = be32_to_cpu(rhdr->residual_count); - - if (res_count > 0 && res_count <= sc->request_bufflen) - sc->resid = res_count; - else - sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; - } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) - sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; - else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) - sc->resid = be32_to_cpu(rhdr->residual_count); - -out: - debug_scsi("done [sc %lx res %d itt 0x%x]\n", - (long)sc, sc->result, ctask->itt); - conn->scsirsp_pdus_cnt++; - - iscsi_complete_command(conn->session, ctask); - return rc; -} - -/** - * __iscsi_complete_pdu - complete pdu - * @conn: iscsi conn - * @hdr: iscsi header - * @data: data buffer - * @datalen: len of data buffer - * - * Completes pdu processing by freeing any resources allocated at - * queuecommand or send generic. session lock must be held and verify - * itt must have been called. - */ -int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - char *data, int datalen) -{ - struct iscsi_session *session = conn->session; - int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; - struct iscsi_cmd_task *ctask; - struct iscsi_mgmt_task *mtask; - uint32_t itt; - - if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) - itt = hdr->itt & ISCSI_ITT_MASK; - else - itt = hdr->itt; - - if (itt < session->cmds_max) { - ctask = session->cmds[itt]; - - debug_scsi("cmdrsp [op 0x%x cid %d itt 0x%x len %d]\n", - opcode, conn->id, ctask->itt, datalen); - - switch(opcode) { - case ISCSI_OP_SCSI_CMD_RSP: - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - rc = iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, - datalen); - break; - case ISCSI_OP_SCSI_DATA_IN: - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { - conn->scsirsp_pdus_cnt++; - iscsi_complete_command(session, ctask); - } - break; - case ISCSI_OP_R2T: - /* LLD handles this for now */ - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } - } else if (itt >= ISCSI_MGMT_ITT_OFFSET && - itt < ISCSI_MGMT_ITT_OFFSET + session->mgmtpool_max) { - mtask = session->mgmt_cmds[itt - ISCSI_MGMT_ITT_OFFSET]; - - debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", - opcode, conn->id, mtask->itt, datalen); - - rc = iscsi_check_assign_cmdsn(session, - (struct iscsi_nopin*)hdr); - if (rc) - goto done; - - switch(opcode) { - case ISCSI_OP_LOGOUT_RSP: - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - /* fall through */ - case ISCSI_OP_LOGIN_RSP: - case ISCSI_OP_TEXT_RSP: - /* - * login related PDU's exp_statsn is handled in - * userspace - */ - rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); - list_del(&mtask->running); - if (conn->login_mtask != mtask) - __kfifo_put(session->mgmtpool.queue, - (void*)&mtask, sizeof(void*)); - break; - case ISCSI_OP_SCSI_TMFUNC_RSP: - if (datalen) { - rc = ISCSI_ERR_PROTO; - break; - } - - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - conn->tmfrsp_pdus_cnt++; - if (conn->tmabort_state == TMABORT_INITIAL) { - conn->tmabort_state = - ((struct iscsi_tm_rsp *)hdr)-> - response == ISCSI_TMF_RSP_COMPLETE ? - TMABORT_SUCCESS:TMABORT_FAILED; - /* unblock eh_abort() */ - wake_up(&conn->ehwait); - } - break; - case ISCSI_OP_NOOP_IN: - if (hdr->ttt != ISCSI_RESERVED_TAG) { - rc = ISCSI_ERR_PROTO; - break; - } - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - - rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); - list_del(&mtask->running); - if (conn->login_mtask != mtask) - __kfifo_put(session->mgmtpool.queue, - (void*)&mtask, sizeof(void*)); - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } - } else if (itt == ISCSI_RESERVED_TAG) { - switch(opcode) { - case ISCSI_OP_NOOP_IN: - if (!datalen) { - rc = iscsi_check_assign_cmdsn(session, - (struct iscsi_nopin*)hdr); - if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) - rc = iscsi_recv_pdu(conn->cls_conn, - hdr, NULL, 0); - } else - rc = ISCSI_ERR_PROTO; - break; - case ISCSI_OP_REJECT: - /* we need sth like iscsi_reject_rsp()*/ - case ISCSI_OP_ASYNC_EVENT: - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - /* we need sth like iscsi_async_event_rsp() */ - rc = ISCSI_ERR_BAD_OPCODE; - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } - } else - rc = ISCSI_ERR_BAD_ITT; - -done: - return rc; -} -EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); - -int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - char *data, int datalen) -{ - int rc; - - spin_lock(&conn->session->lock); - rc = __iscsi_complete_pdu(conn, hdr, data, datalen); - spin_unlock(&conn->session->lock); - return rc; -} -EXPORT_SYMBOL_GPL(iscsi_complete_pdu); - -/* verify itt (itt encoding: age+cid+itt) */ -int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - uint32_t *ret_itt) -{ - struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *ctask; - uint32_t itt; - - if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { - if ((hdr->itt & ISCSI_AGE_MASK) != - (session->age << ISCSI_AGE_SHIFT)) { - printk(KERN_ERR "iscsi: received itt %x expected " - "session age (%x)\n", hdr->itt, - session->age & ISCSI_AGE_MASK); - return ISCSI_ERR_BAD_ITT; - } - - if ((hdr->itt & ISCSI_CID_MASK) != - (conn->id << ISCSI_CID_SHIFT)) { - printk(KERN_ERR "iscsi: received itt %x, expected " - "CID (%x)\n", hdr->itt, conn->id); - return ISCSI_ERR_BAD_ITT; - } - itt = hdr->itt & ISCSI_ITT_MASK; - } else - itt = hdr->itt; - - if (itt < session->cmds_max) { - ctask = session->cmds[itt]; - - if (!ctask->sc) { - printk(KERN_INFO "iscsi: dropping ctask with " - "itt 0x%x\n", ctask->itt); - /* force drop */ - return ISCSI_ERR_NO_SCSI_CMD; - } - - if (ctask->sc->SCp.phase != session->age) { - printk(KERN_ERR "iscsi: ctask's session age %d, " - "expected %d\n", ctask->sc->SCp.phase, - session->age); - return ISCSI_ERR_SESSION_FAILED; - } - } - - *ret_itt = itt; - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_verify_itt); - -void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) -{ - struct iscsi_session *session = conn->session; - unsigned long flags; - - spin_lock_irqsave(&session->lock, flags); - if (session->state == ISCSI_STATE_FAILED) { - spin_unlock_irqrestore(&session->lock, flags); - return; - } - - if (conn->stop_stage == 0) - session->state = ISCSI_STATE_FAILED; - spin_unlock_irqrestore(&session->lock, flags); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); - iscsi_conn_error(conn->cls_conn, err); -} -EXPORT_SYMBOL_GPL(iscsi_conn_failure); - -/** - * iscsi_data_xmit - xmit any command into the scheduled connection - * @conn: iscsi connection - * - * Notes: - * The function can return -EAGAIN in which case the caller must - * re-schedule it again later or recover. '0' return code means - * successful xmit. - **/ -static int iscsi_data_xmit(struct iscsi_conn *conn) -{ - struct iscsi_transport *tt; - int rc = 0; - - if (unlikely(conn->suspend_tx)) { - debug_scsi("conn %d Tx suspended!\n", conn->id); - return -ENODATA; - } - tt = conn->session->tt; - - /* - * Transmit in the following order: - * - * 1) un-finished xmit (ctask or mtask) - * 2) immediate control PDUs - * 3) write data - * 4) SCSI commands - * 5) non-immediate control PDUs - * - * No need to lock around __kfifo_get as long as - * there's one producer and one consumer. - */ - - BUG_ON(conn->ctask && conn->mtask); - - if (conn->ctask) { - rc = tt->xmit_cmd_task(conn, conn->ctask); - if (rc) - goto again; - /* done with this in-progress ctask */ - conn->ctask = NULL; - } - if (conn->mtask) { - rc = tt->xmit_mgmt_task(conn, conn->mtask); - if (rc) - goto again; - /* done with this in-progress mtask */ - conn->mtask = NULL; - } - - /* process immediate first */ - if (unlikely(__kfifo_len(conn->immqueue))) { - while (__kfifo_get(conn->immqueue, (void*)&conn->mtask, - sizeof(void*))) { - spin_lock_bh(&conn->session->lock); - list_add_tail(&conn->mtask->running, - &conn->mgmt_run_list); - spin_unlock_bh(&conn->session->lock); - rc = tt->xmit_mgmt_task(conn, conn->mtask); - if (rc) - goto again; - } - /* done with this mtask */ - conn->mtask = NULL; - } - - /* process command queue */ - while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, - sizeof(void*))) { - /* - * iscsi tcp may readd the task to the xmitqueue to send - * write data - */ - spin_lock_bh(&conn->session->lock); - if (list_empty(&conn->ctask->running)) - list_add_tail(&conn->ctask->running, &conn->run_list); - spin_unlock_bh(&conn->session->lock); - rc = tt->xmit_cmd_task(conn, conn->ctask); - if (rc) - goto again; - } - /* done with this ctask */ - conn->ctask = NULL; - - /* process the rest control plane PDUs, if any */ - if (unlikely(__kfifo_len(conn->mgmtqueue))) { - while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, - sizeof(void*))) { - spin_lock_bh(&conn->session->lock); - list_add_tail(&conn->mtask->running, - &conn->mgmt_run_list); - spin_unlock_bh(&conn->session->lock); - rc = tt->xmit_mgmt_task(conn, conn->mtask); - if (rc) - goto again; - } - /* done with this mtask */ - conn->mtask = NULL; - } - - return -ENODATA; - -again: - if (unlikely(conn->suspend_tx)) - return -ENODATA; - - return rc; -} - -static void iscsi_xmitworker(void *data) -{ - struct iscsi_conn *conn = data; - int rc; - /* - * serialize Xmit worker on a per-connection basis. - */ - mutex_lock(&conn->xmitmutex); - do { - rc = iscsi_data_xmit(conn); - } while (rc >= 0 || rc == -EAGAIN); - mutex_unlock(&conn->xmitmutex); -} - -enum { - FAILURE_BAD_HOST = 1, - FAILURE_SESSION_FAILED, - FAILURE_SESSION_FREED, - FAILURE_WINDOW_CLOSED, - FAILURE_SESSION_TERMINATE, - FAILURE_SESSION_IN_RECOVERY, - FAILURE_SESSION_RECOVERY_TIMEOUT, -}; - -int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) -{ - struct Scsi_Host *host; - int reason = 0; - struct iscsi_session *session; - struct iscsi_conn *conn; - struct iscsi_cmd_task *ctask = NULL; - - sc->scsi_done = done; - sc->result = 0; - - host = sc->device->host; - session = iscsi_hostdata(host->hostdata); - - spin_lock(&session->lock); - - /* - * ISCSI_STATE_FAILED is a temp. state. The recovery - * code will decide what is best to do with command queued - * during this time - */ - if (session->state != ISCSI_STATE_LOGGED_IN && - session->state != ISCSI_STATE_FAILED) { - /* - * to handle the race between when we set the recovery state - * and block the session we requeue here (commands could - * be entering our queuecommand while a block is starting - * up because the block code is not locked) - */ - if (session->state == ISCSI_STATE_IN_RECOVERY) { - reason = FAILURE_SESSION_IN_RECOVERY; - goto reject; - } - - if (session->state == ISCSI_STATE_RECOVERY_FAILED) - reason = FAILURE_SESSION_RECOVERY_TIMEOUT; - else if (session->state == ISCSI_STATE_TERMINATE) - reason = FAILURE_SESSION_TERMINATE; - else - reason = FAILURE_SESSION_FREED; - goto fault; - } - - /* - * Check for iSCSI window and take care of CmdSN wrap-around - */ - if ((int)(session->max_cmdsn - session->cmdsn) < 0) { - reason = FAILURE_WINDOW_CLOSED; - goto reject; - } - - conn = session->leadconn; - - __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); - sc->SCp.phase = session->age; - sc->SCp.ptr = (char *)ctask; - - ctask->mtask = NULL; - ctask->conn = conn; - ctask->sc = sc; - INIT_LIST_HEAD(&ctask->running); - ctask->total_length = sc->request_bufflen; - iscsi_prep_scsi_cmd_pdu(ctask); - - session->tt->init_cmd_task(ctask); - - __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); - debug_scsi( - "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", - sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", - conn->id, (long)sc, ctask->itt, sc->request_bufflen, - session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); - spin_unlock(&session->lock); - - scsi_queue_work(host, &conn->xmitwork); - return 0; - -reject: - spin_unlock(&session->lock); - debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); - return SCSI_MLQUEUE_HOST_BUSY; - -fault: - spin_unlock(&session->lock); - printk(KERN_ERR "iscsi: cmd 0x%x is not queued (%d)\n", - sc->cmnd[0], reason); - sc->result = (DID_NO_CONNECT << 16); - sc->resid = sc->request_bufflen; - sc->scsi_done(sc); - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_queuecommand); - -int iscsi_change_queue_depth(struct scsi_device *sdev, int depth) -{ - if (depth > ISCSI_MAX_CMD_PER_LUN) - depth = ISCSI_MAX_CMD_PER_LUN; - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); - return sdev->queue_depth; -} -EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); - -static int -iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - char *data, uint32_t data_size) -{ - struct iscsi_session *session = conn->session; - struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; - struct iscsi_mgmt_task *mtask; - - spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_TERMINATE) { - spin_unlock_bh(&session->lock); - return -EPERM; - } - if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || - hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) - /* - * Login and Text are sent serially, in - * request-followed-by-response sequence. - * Same mtask can be used. Same ITT must be used. - * Note that login_mtask is preallocated at conn_create(). - */ - mtask = conn->login_mtask; - else { - BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); - BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - - nop->exp_statsn = cpu_to_be32(conn->exp_statsn); - if (!__kfifo_get(session->mgmtpool.queue, - (void*)&mtask, sizeof(void*))) { - spin_unlock_bh(&session->lock); - return -ENOSPC; - } - } - - /* - * pre-format CmdSN for outgoing PDU. - */ - if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { - hdr->itt = mtask->itt | (conn->id << ISCSI_CID_SHIFT) | - (session->age << ISCSI_AGE_SHIFT); - nop->cmdsn = cpu_to_be32(session->cmdsn); - if (conn->c_stage == ISCSI_CONN_STARTED && - !(hdr->opcode & ISCSI_OP_IMMEDIATE)) - session->cmdsn++; - } else - /* do not advance CmdSN */ - nop->cmdsn = cpu_to_be32(session->cmdsn); - - if (data_size) { - memcpy(mtask->data, data, data_size); - mtask->data_count = data_size; - } else - mtask->data_count = 0; - - INIT_LIST_HEAD(&mtask->running); - memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); - if (session->tt->init_mgmt_task) - session->tt->init_mgmt_task(conn, mtask, data, data_size); - spin_unlock_bh(&session->lock); - - debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", - hdr->opcode, hdr->itt, data_size); - - /* - * since send_pdu() could be called at least from two contexts, - * we need to serialize __kfifo_put, so we don't have to take - * additional lock on fast data-path - */ - if (hdr->opcode & ISCSI_OP_IMMEDIATE) - __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*)); - else - __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); - - scsi_queue_work(session->host, &conn->xmitwork); - return 0; -} - -int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, - char *data, uint32_t data_size) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - int rc; - - mutex_lock(&conn->xmitmutex); - rc = iscsi_conn_send_generic(conn, hdr, data, data_size); - mutex_unlock(&conn->xmitmutex); - - return rc; -} -EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); - -void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) -{ - struct iscsi_session *session = class_to_transport_session(cls_session); - struct iscsi_conn *conn = session->leadconn; - - spin_lock_bh(&session->lock); - if (session->state != ISCSI_STATE_LOGGED_IN) { - session->state = ISCSI_STATE_RECOVERY_FAILED; - if (conn) - wake_up(&conn->ehwait); - } - spin_unlock_bh(&session->lock); -} -EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); - -int iscsi_eh_host_reset(struct scsi_cmnd *sc) -{ - struct Scsi_Host *host = sc->device->host; - struct iscsi_session *session = iscsi_hostdata(host->hostdata); - struct iscsi_conn *conn = session->leadconn; - int fail_session = 0; - - spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_TERMINATE) { -failed: - debug_scsi("failing host reset: session terminated " - "[CID %d age %d]", conn->id, session->age); - spin_unlock_bh(&session->lock); - return FAILED; - } - - if (sc->SCp.phase == session->age) { - debug_scsi("failing connection CID %d due to SCSI host reset", - conn->id); - fail_session = 1; - } - spin_unlock_bh(&session->lock); - - /* - * we drop the lock here but the leadconn cannot be destoyed while - * we are in the scsi eh - */ - if (fail_session) - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - - debug_scsi("iscsi_eh_host_reset wait for relogin\n"); - wait_event_interruptible(conn->ehwait, - session->state == ISCSI_STATE_TERMINATE || - session->state == ISCSI_STATE_LOGGED_IN || - session->state == ISCSI_STATE_RECOVERY_FAILED); - if (signal_pending(current)) - flush_signals(current); - - spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_LOGGED_IN) - printk(KERN_INFO "iscsi: host reset succeeded\n"); - else - goto failed; - spin_unlock_bh(&session->lock); - - return SUCCESS; -} -EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); - -static void iscsi_tmabort_timedout(unsigned long data) -{ - struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; - struct iscsi_conn *conn = ctask->conn; - struct iscsi_session *session = conn->session; - - spin_lock(&session->lock); - if (conn->tmabort_state == TMABORT_INITIAL) { - conn->tmabort_state = TMABORT_TIMEDOUT; - debug_scsi("tmabort timedout [sc %p itt 0x%x]\n", - ctask->sc, ctask->itt); - /* unblock eh_abort() */ - wake_up(&conn->ehwait); - } - spin_unlock(&session->lock); -} - -/* must be called with the mutex lock */ -static int iscsi_exec_abort_task(struct scsi_cmnd *sc, - struct iscsi_cmd_task *ctask) -{ - struct iscsi_conn *conn = ctask->conn; - struct iscsi_session *session = conn->session; - struct iscsi_tm *hdr = &conn->tmhdr; - int rc; - - /* - * ctask timed out but session is OK requests must be serialized. - */ - memset(hdr, 0, sizeof(struct iscsi_tm)); - hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; - hdr->flags = ISCSI_TM_FUNC_ABORT_TASK; - hdr->flags |= ISCSI_FLAG_CMD_FINAL; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->rtt = ctask->hdr->itt; - hdr->refcmdsn = ctask->hdr->cmdsn; - - rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr, - NULL, 0); - if (rc) { - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc); - return rc; - } - - debug_scsi("abort sent [itt 0x%x]\n", ctask->itt); - - spin_lock_bh(&session->lock); - ctask->mtask = (struct iscsi_mgmt_task *) - session->mgmt_cmds[(hdr->itt & ISCSI_ITT_MASK) - - ISCSI_MGMT_ITT_OFFSET]; - - if (conn->tmabort_state == TMABORT_INITIAL) { - conn->tmfcmd_pdus_cnt++; - conn->tmabort_timer.expires = 10*HZ + jiffies; - conn->tmabort_timer.function = iscsi_tmabort_timedout; - conn->tmabort_timer.data = (unsigned long)ctask; - add_timer(&conn->tmabort_timer); - debug_scsi("abort set timeout [itt 0x%x]", ctask->itt); - } - spin_unlock_bh(&session->lock); - mutex_unlock(&conn->xmitmutex); - - /* - * block eh thread until: - * - * 1) abort response - * 2) abort timeout - * 3) session is terminated or restarted or userspace has - * given up on recovery - */ - wait_event_interruptible(conn->ehwait, - sc->SCp.phase != session->age || - session->state != ISCSI_STATE_LOGGED_IN || - conn->tmabort_state != TMABORT_INITIAL); - if (signal_pending(current)) - flush_signals(current); - del_timer_sync(&conn->tmabort_timer); - - mutex_lock(&conn->xmitmutex); - return 0; -} - -/* - * xmit mutex and session lock must be held - */ -#define iscsi_remove_task(tasktype) \ -static struct iscsi_##tasktype * \ -iscsi_remove_##tasktype(struct kfifo *fifo, uint32_t itt) \ -{ \ - int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); \ - struct iscsi_##tasktype *task; \ - \ - debug_scsi("searching %d tasks\n", nr_tasks); \ - \ - for (i = 0; i < nr_tasks; i++) { \ - __kfifo_get(fifo, (void*)&task, sizeof(void*)); \ - debug_scsi("check task %u\n", task->itt); \ - \ - if (task->itt == itt) { \ - debug_scsi("matched task\n"); \ - return task; \ - } \ - \ - __kfifo_put(fifo, (void*)&task, sizeof(void*)); \ - } \ - return NULL; \ -} - -iscsi_remove_task(mgmt_task); -iscsi_remove_task(cmd_task); - -static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) -{ - struct iscsi_conn *conn = ctask->conn; - struct iscsi_session *session = conn->session; - - if (!ctask->mtask) - return -EINVAL; - - if (!iscsi_remove_mgmt_task(conn->immqueue, ctask->mtask->itt)) - list_del(&ctask->mtask->running); - __kfifo_put(session->mgmtpool.queue, (void*)&ctask->mtask, - sizeof(void*)); - ctask->mtask = NULL; - return 0; -} - -/* - * session lock and xmitmutex must be held - */ -static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, - int err) -{ - struct scsi_cmnd *sc; - - conn->session->tt->cleanup_cmd_task(conn, ctask); - iscsi_ctask_mtask_cleanup(ctask); - - sc = ctask->sc; - if (!sc) - return; - sc->result = err; - sc->resid = sc->request_bufflen; - iscsi_complete_command(conn->session, ctask); -} - -int iscsi_eh_abort(struct scsi_cmnd *sc) -{ - struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; - struct iscsi_conn *conn = ctask->conn; - struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *pending_ctask; - int rc; - - conn->eh_abort_cnt++; - debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); - - mutex_lock(&conn->xmitmutex); - spin_lock_bh(&session->lock); - - /* - * If we are not logged in or we have started a new session - * then let the host reset code handle this - */ - if (session->state != ISCSI_STATE_LOGGED_IN || - sc->SCp.phase != session->age) - goto failed; - - /* ctask completed before time out */ - if (!ctask->sc) - goto success; - - /* what should we do here ? */ - if (conn->ctask == ctask) { - printk(KERN_INFO "iscsi: sc %p itt 0x%x partially sent. " - "Failing abort\n", sc, ctask->itt); - goto failed; - } - - /* check for the easy pending cmd abort */ - pending_ctask = iscsi_remove_cmd_task(conn->xmitqueue, ctask->itt); - if (pending_ctask) { - /* iscsi_tcp queues write transfers on the xmitqueue */ - if (list_empty(&pending_ctask->running)) { - debug_scsi("found pending task\n"); - goto success; - } else - __kfifo_put(conn->xmitqueue, (void*)&pending_ctask, - sizeof(void*)); - } - - conn->tmabort_state = TMABORT_INITIAL; - - spin_unlock_bh(&session->lock); - rc = iscsi_exec_abort_task(sc, ctask); - spin_lock_bh(&session->lock); - - iscsi_ctask_mtask_cleanup(ctask); - if (rc || sc->SCp.phase != session->age || - session->state != ISCSI_STATE_LOGGED_IN) - goto failed; - - /* ctask completed before tmf abort response */ - if (!ctask->sc) { - debug_scsi("sc completed while abort in progress\n"); - goto success; - } - - if (conn->tmabort_state != TMABORT_SUCCESS) { - spin_unlock_bh(&session->lock); - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - spin_lock_bh(&session->lock); - goto failed; - } - -success: - debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); - spin_unlock_bh(&session->lock); - - /* - * clean up task if aborted. we have the xmitmutex so grab - * the recv lock as a writer - */ - write_lock_bh(conn->recv_lock); - spin_lock(&session->lock); - fail_command(conn, ctask, DID_ABORT << 16); - spin_unlock(&session->lock); - write_unlock_bh(conn->recv_lock); - - mutex_unlock(&conn->xmitmutex); - return SUCCESS; - -failed: - spin_unlock_bh(&session->lock); - mutex_unlock(&conn->xmitmutex); - - debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); - return FAILED; -} -EXPORT_SYMBOL_GPL(iscsi_eh_abort); - -int -iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) -{ - int i; - - *items = kmalloc(max * sizeof(void*), GFP_KERNEL); - if (*items == NULL) - return -ENOMEM; - - q->max = max; - q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); - if (q->pool == NULL) { - kfree(*items); - return -ENOMEM; - } - - q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), - GFP_KERNEL, NULL); - if (q->queue == ERR_PTR(-ENOMEM)) { - kfree(q->pool); - kfree(*items); - return -ENOMEM; - } - - for (i = 0; i < max; i++) { - q->pool[i] = kmalloc(item_size, GFP_KERNEL); - if (q->pool[i] == NULL) { - int j; - - for (j = 0; j < i; j++) - kfree(q->pool[j]); - - kfifo_free(q->queue); - kfree(q->pool); - kfree(*items); - return -ENOMEM; - } - memset(q->pool[i], 0, item_size); - (*items)[i] = q->pool[i]; - __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); - } - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_pool_init); - -void iscsi_pool_free(struct iscsi_queue *q, void **items) -{ - int i; - - for (i = 0; i < q->max; i++) - kfree(items[i]); - kfree(q->pool); - kfree(items); -} -EXPORT_SYMBOL_GPL(iscsi_pool_free); - -/* - * iSCSI Session's hostdata organization: - * - * *------------------* <== hostdata_session(host->hostdata) - * | ptr to class sess| - * |------------------| <== iscsi_hostdata(host->hostdata) - * | iscsi_session | - * *------------------* - */ - -#define hostdata_privsize(_sz) (sizeof(unsigned long) + _sz + \ - _sz % sizeof(unsigned long)) - -#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) - -/** - * iscsi_session_setup - create iscsi cls session and host and session - * @scsit: scsi transport template - * @iscsit: iscsi transport template - * @initial_cmdsn: initial CmdSN - * @hostno: host no allocated - * - * This can be used by software iscsi_transports that allocate - * a session per scsi host. - **/ -struct iscsi_cls_session * -iscsi_session_setup(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - int cmd_task_size, int mgmt_task_size, - uint32_t initial_cmdsn, uint32_t *hostno) -{ - struct Scsi_Host *shost; - struct iscsi_session *session; - struct iscsi_cls_session *cls_session; - int cmd_i; - - shost = scsi_host_alloc(iscsit->host_template, - hostdata_privsize(sizeof(*session))); - if (!shost) - return NULL; - - shost->max_id = 1; - shost->max_channel = 0; - shost->max_lun = iscsit->max_lun; - shost->max_cmd_len = iscsit->max_cmd_len; - shost->transportt = scsit; - shost->transportt->create_work_queue = 1; - *hostno = shost->host_no; - - session = iscsi_hostdata(shost->hostdata); - memset(session, 0, sizeof(struct iscsi_session)); - session->host = shost; - session->state = ISCSI_STATE_FREE; - session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; - session->cmds_max = ISCSI_XMIT_CMDS_MAX; - session->cmdsn = initial_cmdsn; - session->exp_cmdsn = initial_cmdsn + 1; - session->max_cmdsn = initial_cmdsn + 1; - session->max_r2t = 1; - session->tt = iscsit; - - /* initialize SCSI PDU commands pool */ - if (iscsi_pool_init(&session->cmdpool, session->cmds_max, - (void***)&session->cmds, - cmd_task_size + sizeof(struct iscsi_cmd_task))) - goto cmdpool_alloc_fail; - - /* pre-format cmds pool with ITT */ - for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - - if (cmd_task_size) - ctask->dd_data = &ctask[1]; - ctask->itt = cmd_i; - } - - spin_lock_init(&session->lock); - INIT_LIST_HEAD(&session->connections); - - /* initialize immediate command pool */ - if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, - (void***)&session->mgmt_cmds, - mgmt_task_size + sizeof(struct iscsi_mgmt_task))) - goto mgmtpool_alloc_fail; - - - /* pre-format immediate cmds pool with ITT */ - for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { - struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; - - if (mgmt_task_size) - mtask->dd_data = &mtask[1]; - mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; - } - - if (scsi_add_host(shost, NULL)) - goto add_host_fail; - - cls_session = iscsi_create_session(shost, iscsit, 0); - if (!cls_session) - goto cls_session_fail; - *(unsigned long*)shost->hostdata = (unsigned long)cls_session; - - return cls_session; - -cls_session_fail: - scsi_remove_host(shost); -add_host_fail: - iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); -mgmtpool_alloc_fail: - iscsi_pool_free(&session->cmdpool, (void**)session->cmds); -cmdpool_alloc_fail: - scsi_host_put(shost); - return NULL; -} -EXPORT_SYMBOL_GPL(iscsi_session_setup); - -/** - * iscsi_session_teardown - destroy session, host, and cls_session - * shost: scsi host - * - * This can be used by software iscsi_transports that allocate - * a session per scsi host. - **/ -void iscsi_session_teardown(struct iscsi_cls_session *cls_session) -{ - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); - - scsi_remove_host(shost); - - iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); - iscsi_pool_free(&session->cmdpool, (void**)session->cmds); - - iscsi_destroy_session(cls_session); - scsi_host_put(shost); -} -EXPORT_SYMBOL_GPL(iscsi_session_teardown); - -/** - * iscsi_conn_setup - create iscsi_cls_conn and iscsi_conn - * @cls_session: iscsi_cls_session - * @conn_idx: cid - **/ -struct iscsi_cls_conn * -iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) -{ - struct iscsi_session *session = class_to_transport_session(cls_session); - struct iscsi_conn *conn; - struct iscsi_cls_conn *cls_conn; - char *data; - - cls_conn = iscsi_create_conn(cls_session, conn_idx); - if (!cls_conn) - return NULL; - conn = cls_conn->dd_data; - memset(conn, 0, sizeof(*conn)); - - conn->session = session; - conn->cls_conn = cls_conn; - conn->c_stage = ISCSI_CONN_INITIAL_STAGE; - conn->id = conn_idx; - conn->exp_statsn = 0; - conn->tmabort_state = TMABORT_INITIAL; - INIT_LIST_HEAD(&conn->run_list); - INIT_LIST_HEAD(&conn->mgmt_run_list); - - /* initialize general xmit PDU commands queue */ - conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), - GFP_KERNEL, NULL); - if (conn->xmitqueue == ERR_PTR(-ENOMEM)) - goto xmitqueue_alloc_fail; - - /* initialize general immediate & non-immediate PDU commands queue */ - conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), - GFP_KERNEL, NULL); - if (conn->immqueue == ERR_PTR(-ENOMEM)) - goto immqueue_alloc_fail; - - conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), - GFP_KERNEL, NULL); - if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) - goto mgmtqueue_alloc_fail; - - INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); - - /* allocate login_mtask used for the login/text sequences */ - spin_lock_bh(&session->lock); - if (!__kfifo_get(session->mgmtpool.queue, - (void*)&conn->login_mtask, - sizeof(void*))) { - spin_unlock_bh(&session->lock); - goto login_mtask_alloc_fail; - } - spin_unlock_bh(&session->lock); - - data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); - if (!data) - goto login_mtask_data_alloc_fail; - conn->login_mtask->data = data; - - init_timer(&conn->tmabort_timer); - mutex_init(&conn->xmitmutex); - init_waitqueue_head(&conn->ehwait); - - return cls_conn; - -login_mtask_data_alloc_fail: - __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, - sizeof(void*)); -login_mtask_alloc_fail: - kfifo_free(conn->mgmtqueue); -mgmtqueue_alloc_fail: - kfifo_free(conn->immqueue); -immqueue_alloc_fail: - kfifo_free(conn->xmitqueue); -xmitqueue_alloc_fail: - iscsi_destroy_conn(cls_conn); - return NULL; -} -EXPORT_SYMBOL_GPL(iscsi_conn_setup); - -/** - * iscsi_conn_teardown - teardown iscsi connection - * cls_conn: iscsi class connection - * - * TODO: we may need to make this into a two step process - * like scsi-mls remove + put host - */ -void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_session *session = conn->session; - unsigned long flags; - - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - mutex_lock(&conn->xmitmutex); - if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) { - if (session->tt->suspend_conn_recv) - session->tt->suspend_conn_recv(conn); - - session->tt->terminate_conn(conn); - } - - spin_lock_bh(&session->lock); - conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; - if (session->leadconn == conn) { - /* - * leading connection? then give up on recovery. - */ - session->state = ISCSI_STATE_TERMINATE; - wake_up(&conn->ehwait); - } - spin_unlock_bh(&session->lock); - - mutex_unlock(&conn->xmitmutex); - - /* - * Block until all in-progress commands for this connection - * time out or fail. - */ - for (;;) { - spin_lock_irqsave(session->host->host_lock, flags); - if (!session->host->host_busy) { /* OK for ERL == 0 */ - spin_unlock_irqrestore(session->host->host_lock, flags); - break; - } - spin_unlock_irqrestore(session->host->host_lock, flags); - msleep_interruptible(500); - printk(KERN_INFO "iscsi: scsi conn_destroy(): host_busy %d " - "host_failed %d\n", session->host->host_busy, - session->host->host_failed); - /* - * force eh_abort() to unblock - */ - wake_up(&conn->ehwait); - } - - spin_lock_bh(&session->lock); - kfree(conn->login_mtask->data); - __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, - sizeof(void*)); - list_del(&conn->item); - if (list_empty(&session->connections)) - session->leadconn = NULL; - if (session->leadconn && session->leadconn == conn) - session->leadconn = container_of(session->connections.next, - struct iscsi_conn, item); - - if (session->leadconn == NULL) - /* no connections exits.. reset sequencing */ - session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; - spin_unlock_bh(&session->lock); - - kfifo_free(conn->xmitqueue); - kfifo_free(conn->immqueue); - kfifo_free(conn->mgmtqueue); - - iscsi_destroy_conn(cls_conn); -} -EXPORT_SYMBOL_GPL(iscsi_conn_teardown); - -int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_session *session = conn->session; - - if (session == NULL) { - printk(KERN_ERR "iscsi: can't start unbound connection\n"); - return -EPERM; - } - - spin_lock_bh(&session->lock); - conn->c_stage = ISCSI_CONN_STARTED; - session->state = ISCSI_STATE_LOGGED_IN; - - switch(conn->stop_stage) { - case STOP_CONN_RECOVER: - /* - * unblock eh_abort() if it is blocked. re-try all - * commands after successful recovery - */ - conn->stop_stage = 0; - conn->tmabort_state = TMABORT_INITIAL; - session->age++; - spin_unlock_bh(&session->lock); - - iscsi_unblock_session(session_to_cls(session)); - wake_up(&conn->ehwait); - return 0; - case STOP_CONN_TERM: - conn->stop_stage = 0; - break; - default: - break; - } - spin_unlock_bh(&session->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_conn_start); - -static void -flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) -{ - struct iscsi_mgmt_task *mtask, *tmp; - - /* handle pending */ - while (__kfifo_get(conn->immqueue, (void*)&mtask, sizeof(void*)) || - __kfifo_get(conn->mgmtqueue, (void*)&mtask, sizeof(void*))) { - if (mtask == conn->login_mtask) - continue; - debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt); - __kfifo_put(session->mgmtpool.queue, (void*)&mtask, - sizeof(void*)); - } - - /* handle running */ - list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { - debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); - list_del(&mtask->running); - - if (mtask == conn->login_mtask) - continue; - __kfifo_put(session->mgmtpool.queue, (void*)&mtask, - sizeof(void*)); - } - - conn->mtask = NULL; -} - -/* Fail commands. Mutex and session lock held and recv side suspended */ -static void fail_all_commands(struct iscsi_conn *conn) -{ - struct iscsi_cmd_task *ctask, *tmp; - - /* flush pending */ - while (__kfifo_get(conn->xmitqueue, (void*)&ctask, sizeof(void*))) { - debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, - ctask->itt); - fail_command(conn, ctask, DID_BUS_BUSY << 16); - } - - /* fail all other running */ - list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) { - debug_scsi("failing in progress sc %p itt 0x%x\n", - ctask->sc, ctask->itt); - fail_command(conn, ctask, DID_BUS_BUSY << 16); - } - - conn->ctask = NULL; -} - -static void iscsi_start_session_recovery(struct iscsi_session *session, - struct iscsi_conn *conn, int flag) -{ - int old_stop_stage; - - spin_lock_bh(&session->lock); - if (conn->stop_stage == STOP_CONN_TERM) { - spin_unlock_bh(&session->lock); - return; - } - - /* - * When this is called for the in_login state, we only want to clean - * up the login task and connection. We do not need to block and set - * the recovery state again - */ - if (flag == STOP_CONN_TERM) - 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; - conn->c_stage = ISCSI_CONN_STOPPED; - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - spin_unlock_bh(&session->lock); - - if (session->tt->suspend_conn_recv) - session->tt->suspend_conn_recv(conn); - - mutex_lock(&conn->xmitmutex); - /* - * for connection level recovery we should not calculate - * header digest. conn->hdr_size used for optimization - * in hdr_extract() and will be re-negotiated at - * set_param() time. - */ - if (flag == STOP_CONN_RECOVER) { - conn->hdrdgst_en = 0; - conn->datadgst_en = 0; - if (session->state == ISCSI_STATE_IN_RECOVERY && - old_stop_stage != STOP_CONN_RECOVER) { - debug_scsi("blocking session\n"); - iscsi_block_session(session_to_cls(session)); - } - } - - session->tt->terminate_conn(conn); - /* - * flush queues. - */ - spin_lock_bh(&session->lock); - fail_all_commands(conn); - flush_control_queues(session, conn); - spin_unlock_bh(&session->lock); - - mutex_unlock(&conn->xmitmutex); -} - -void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_session *session = conn->session; - - switch (flag) { - case STOP_CONN_RECOVER: - case STOP_CONN_TERM: - iscsi_start_session_recovery(session, conn, flag); - break; - default: - printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); - } -} -EXPORT_SYMBOL_GPL(iscsi_conn_stop); - -int iscsi_conn_bind(struct iscsi_cls_session *cls_session, - struct iscsi_cls_conn *cls_conn, int is_leading) -{ - struct iscsi_session *session = class_to_transport_session(cls_session); - struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; - - /* lookup for existing connection */ - spin_lock_bh(&session->lock); - list_for_each_entry(tmp, &session->connections, item) { - if (tmp == conn) { - if (conn->c_stage != ISCSI_CONN_STOPPED || - conn->stop_stage == STOP_CONN_TERM) { - printk(KERN_ERR "iscsi: can't bind " - "non-stopped connection (%d:%d)\n", - conn->c_stage, conn->stop_stage); - spin_unlock_bh(&session->lock); - return -EIO; - } - break; - } - } - if (tmp != conn) { - /* bind new iSCSI connection to session */ - conn->session = session; - list_add(&conn->item, &session->connections); - } - spin_unlock_bh(&session->lock); - - if (is_leading) - session->leadconn = conn; - - /* - * Unblock xmitworker(), Login Phase will pass through. - */ - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - return 0; -} -EXPORT_SYMBOL_GPL(iscsi_conn_bind); - -MODULE_AUTHOR("Mike Christie"); -MODULE_DESCRIPTION("iSCSI library functions"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/mac_esp.c b/trunk/drivers/scsi/mac_esp.c index 118206d68c6c..e31fadd61904 100644 --- a/trunk/drivers/scsi/mac_esp.c +++ b/trunk/drivers/scsi/mac_esp.c @@ -43,6 +43,9 @@ /* #define DEBUG_MAC_ESP */ +#define mac_turnon_irq(x) mac_enable_irq(x) +#define mac_turnoff_irq(x) mac_disable_irq(x) + extern void esp_handle(struct NCR_ESP *esp); extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); @@ -636,13 +639,13 @@ static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length) static void dma_ints_off(struct NCR_ESP * esp) { - disable_irq(esp->irq); + mac_turnoff_irq(esp->irq); } static void dma_ints_on(struct NCR_ESP * esp) { - enable_irq(esp->irq); + mac_turnon_irq(esp->irq); } /* diff --git a/trunk/drivers/scsi/mac_scsi.c b/trunk/drivers/scsi/mac_scsi.c index a942a21dd87e..777f9bcd1179 100644 --- a/trunk/drivers/scsi/mac_scsi.c +++ b/trunk/drivers/scsi/mac_scsi.c @@ -65,6 +65,9 @@ #define RESET_BOOT #define DRIVER_SETUP +#define ENABLE_IRQ() mac_enable_irq( IRQ_MAC_SCSI ); +#define DISABLE_IRQ() mac_disable_irq( IRQ_MAC_SCSI ); + extern void via_scsi_clear(void); #ifdef RESET_BOOT @@ -348,7 +351,7 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance) printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ - disable_irq(IRQ_MAC_SCSI); + mac_disable_irq(IRQ_MAC_SCSI); /* get in phase */ NCR5380_write( TARGET_COMMAND_REG, @@ -366,7 +369,7 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance) barrier(); /* switch on SCSI IRQ again */ - enable_irq(IRQ_MAC_SCSI); + mac_enable_irq(IRQ_MAC_SCSI); printk(KERN_INFO " done\n" ); } diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c index 5d2cefb5e52d..de35ffe2f79d 100644 --- a/trunk/drivers/scsi/megaraid.c +++ b/trunk/drivers/scsi/megaraid.c @@ -524,7 +524,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) * filter the internal and ioctl commands */ if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) { - return cmd->request_buffer; + return cmd->buffer; } @@ -1828,7 +1828,7 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) scb->dma_type = MEGA_SGLIST; - BUG_ON(sgcnt > adapter->sglen); + if( sgcnt > adapter->sglen ) BUG(); *len = 0; @@ -4492,7 +4492,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) scmd->device = sdev; scmd->device->host = adapter->host; - scmd->request_buffer = (void *)scb; + scmd->buffer = (void *)scb; scmd->cmnd[0] = MEGA_INTERNAL_CMD; scb->state |= SCB_ACTIVE; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index b7caf60638e8..bec1424eda85 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -714,7 +714,7 @@ megaraid_io_detach(adapter_t *adapter) * . Allocate memory required for all the commands * . Use internal library of FW routines, build up complete soft state */ -static int __devinit +static int __init megaraid_init_mbox(adapter_t *adapter) { struct pci_dev *pdev; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c index 0c9516ff636f..39729460b00e 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c @@ -741,6 +741,7 @@ static int megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) { u32 frame_count; + unsigned long flags; struct megasas_cmd *cmd; struct megasas_instance *instance; @@ -775,7 +776,9 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) /* * Issue the command to the FW */ - atomic_inc(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding++; + spin_unlock_irqrestore(&instance->instance_lock, flags); instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set); @@ -823,20 +826,19 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) for (i = 0; i < wait_time; i++) { - int outstanding = atomic_read(&instance->fw_outstanding); - - if (!outstanding) + if (!instance->fw_outstanding) break; if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { printk(KERN_NOTICE "megasas: [%2d]waiting for %d " - "commands to complete\n",i,outstanding); + "commands to complete\n", i, + instance->fw_outstanding); } msleep(1000); } - if (atomic_read(&instance->fw_outstanding)) { + if (instance->fw_outstanding) { instance->hw_crit_error = 1; return FAILED; } @@ -1048,6 +1050,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr; + unsigned long flags; if (cmd->scmd) { cmd->scmd->SCp.ptr = (char *)0; @@ -1079,7 +1082,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, if (exception) { - atomic_dec(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding--; + spin_unlock_irqrestore(&instance->instance_lock, flags); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -1127,7 +1132,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, break; } - atomic_dec(&instance->fw_outstanding); + spin_lock_irqsave(&instance->instance_lock, flags); + instance->fw_outstanding--; + spin_unlock_irqrestore(&instance->instance_lock, flags); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); @@ -2164,12 +2171,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) */ INIT_LIST_HEAD(&instance->cmd_pool); - atomic_set(&instance->fw_outstanding,0); - init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); spin_lock_init(&instance->cmd_pool_lock); + spin_lock_init(&instance->instance_lock); sema_init(&instance->aen_mutex, 1); sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 927d6ffef05f..89639f0c38ef 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -1077,8 +1077,9 @@ struct megasas_instance { struct pci_dev *pdev; u32 unique_id; - atomic_t fw_outstanding; + u32 fw_outstanding; u32 hw_crit_error; + spinlock_t instance_lock; struct megasas_instance_template *instancet; }; diff --git a/trunk/drivers/scsi/ncr53c8xx.c b/trunk/drivers/scsi/ncr53c8xx.c index b28712df0b77..22f913127f08 100644 --- a/trunk/drivers/scsi/ncr53c8xx.c +++ b/trunk/drivers/scsi/ncr53c8xx.c @@ -529,7 +529,7 @@ static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) { switch(cmd->__data_mapped) { case 2: - dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg, + dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, cmd->sc_data_direction); break; case 1: @@ -564,7 +564,7 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) if (cmd->use_sg == 0) return 0; - use_sg = dma_map_sg(dev, cmd->request_buffer, cmd->use_sg, + use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, cmd->sc_data_direction); cmd->__data_mapped = 2; cmd->__data_mapping = use_sg; @@ -5118,7 +5118,8 @@ static void ncr_ccb_skipped(struct ncb *np, struct ccb *cp) cp->host_status &= ~HS_SKIPMASK; cp->start.schedule.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, select)); - list_move_tail(&cp->link_ccbq, &lp->skip_ccbq); + list_del(&cp->link_ccbq); + list_add_tail(&cp->link_ccbq, &lp->skip_ccbq); if (cp->queued) { --lp->queuedccbs; } @@ -7696,7 +7697,7 @@ static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd) if (!use_sg) segment = ncr_scatter_no_sglist(np, cp, cmd); else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { - struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer; + struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct scr_tblmove *data; if (use_sg > MAX_SCATTER) { diff --git a/trunk/drivers/scsi/nsp32.c b/trunk/drivers/scsi/nsp32.c index 5c55e152e718..30ee0ef4b459 100644 --- a/trunk/drivers/scsi/nsp32.c +++ b/trunk/drivers/scsi/nsp32.c @@ -1636,7 +1636,7 @@ static void nsp32_scsi_done(struct scsi_cmnd *SCpnt) if (SCpnt->use_sg) { pci_unmap_sg(data->Pci, - (struct scatterlist *)SCpnt->request_buffer, + (struct scatterlist *)SCpnt->buffer, SCpnt->use_sg, SCpnt->sc_data_direction); } else { pci_unmap_single(data->Pci, diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index 4a2fed350d4e..e3bd4bc339f4 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -4724,7 +4724,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) /* Flush the tape buffer before close */ -static int os_scsi_tape_flush(struct file * filp, fl_owner_t id) +static int os_scsi_tape_flush(struct file * filp) { int result = 0, result2; struct osst_tape * STp = filp->private_data; @@ -5492,7 +5492,7 @@ static int __init osst_setup (char *str) char *stp; stp = get_options(str, ARRAY_SIZE(ints), ints); - + if (ints[0] > 0) { for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++) *parms[i].val = ints[i + 1]; @@ -5507,7 +5507,7 @@ static int __init osst_setup (char *str) break; } } - if (i >= ARRAY_SIZE(parms)) + if (i >= sizeof(parms) / sizeof(struct osst_dev_parm)) printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n", stp); stp = strchr(stp, ','); diff --git a/trunk/drivers/scsi/pas16.c b/trunk/drivers/scsi/pas16.c index 1bf96ed8f935..f09e94af9ade 100644 --- a/trunk/drivers/scsi/pas16.c +++ b/trunk/drivers/scsi/pas16.c @@ -156,7 +156,7 @@ static int default_irqs[] __initdata = static struct override { unsigned short io_port; int irq; -} overrides +} overrides #ifdef PAS16_OVERRIDE [] __initdata = PAS16_OVERRIDE; #else @@ -164,19 +164,19 @@ static struct override { {0,IRQ_AUTO}}; #endif -#define NO_OVERRIDES ARRAY_SIZE(overrides) +#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) static struct base { unsigned short io_port; int noauto; -} bases[] __initdata = +} bases[] __initdata = { {PAS16_DEFAULT_BASE_1, 0}, {PAS16_DEFAULT_BASE_2, 0}, {PAS16_DEFAULT_BASE_3, 0}, {PAS16_DEFAULT_BASE_4, 0} }; -#define NO_BASES ARRAY_SIZE(bases) +#define NO_BASES (sizeof (bases) / sizeof (struct base)) static const unsigned short pas16_offset[ 8 ] = { diff --git a/trunk/drivers/scsi/pdc_adma.c b/trunk/drivers/scsi/pdc_adma.c index 7ebe8e03aa96..5cda16cfacb0 100644 --- a/trunk/drivers/scsi/pdc_adma.c +++ b/trunk/drivers/scsi/pdc_adma.c @@ -46,7 +46,7 @@ #include #define DRV_NAME "pdc_adma" -#define DRV_VERSION "0.04" +#define DRV_VERSION "0.03" /* macro to calculate base address for ATA regs */ #define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40)) @@ -152,7 +152,6 @@ static struct scsi_host_template adma_ata_sht = { .proc_name = DRV_NAME, .dma_boundary = ADMA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -168,7 +167,6 @@ static const struct ata_port_operations adma_ata_ops = { .qc_prep = adma_qc_prep, .qc_issue = adma_qc_issue, .eng_timeout = adma_eng_timeout, - .data_xfer = ata_mmio_data_xfer, .irq_handler = adma_intr, .irq_clear = adma_irq_clear, .port_start = adma_port_start, @@ -457,13 +455,13 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) continue; handled = 1; adma_enter_reg_mode(ap); - if (ap->flags & ATA_FLAG_DISABLED) + if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) continue; pp = ap->private_data; if (!pp || pp->state != adma_state_pkt) continue; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { if ((status & (aPERR | aPSD | aUIRQ))) qc->err_mask |= AC_ERR_OTHER; else if (pp->pkt[0] != cDONE) @@ -482,13 +480,13 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) for (port_no = 0; port_no < host_set->n_ports; ++port_no) { struct ata_port *ap; ap = host_set->ports[port_no]; - if (ap && (!(ap->flags & ATA_FLAG_DISABLED))) { + if (ap && (!(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))) { struct ata_queued_cmd *qc; struct adma_port_priv *pp = ap->private_data; if (!pp || pp->state != adma_state_mmio) continue; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { /* check main status, clearing INTRQ */ u8 status = ata_check_status(ap); diff --git a/trunk/drivers/scsi/pluto.c b/trunk/drivers/scsi/pluto.c index 83a671799934..46624ab9c3d2 100644 --- a/trunk/drivers/scsi/pluto.c +++ b/trunk/drivers/scsi/pluto.c @@ -27,9 +27,6 @@ #include -#define RQ_SCSI_BUSY 0xffff -#define RQ_SCSI_DONE 0xfffe - /* #define PLUTO_DEBUG */ #define pluto_printk printk ("PLUTO %s: ", fc->name); printk diff --git a/trunk/drivers/scsi/ppa.c b/trunk/drivers/scsi/ppa.c index d58ac5ad509d..108910f512e4 100644 --- a/trunk/drivers/scsi/ppa.c +++ b/trunk/drivers/scsi/ppa.c @@ -6,6 +6,8 @@ * (c) 1995,1996 Grant R. Guenther, grant@torque.net, * under the terms of the GNU General Public License. * + * Current Maintainer: David Campbell (Perth, Western Australia, GMT+0800) + * campbell@torque.net */ #include diff --git a/trunk/drivers/scsi/ppa.h b/trunk/drivers/scsi/ppa.h index 7511df3588e4..f6e1a1574bb8 100644 --- a/trunk/drivers/scsi/ppa.h +++ b/trunk/drivers/scsi/ppa.h @@ -2,7 +2,7 @@ * the Iomega ZIP drive * * (c) 1996 Grant R. Guenther grant@torque.net - * David Campbell + * David Campbell campbell@torque.net * * All comments to David. */ diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index 680f6063954b..5a48e55f9418 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -397,6 +397,30 @@ #include "ql1280_fw.h" #include "ql1040_fw.h" + +/* + * Missing PCI ID's + */ +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1080 +#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1240 +#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP1280 +#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP10160 +#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016 +#endif +#ifndef PCI_DEVICE_ID_QLOGIC_ISP12160 +#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216 +#endif + +#ifndef PCI_VENDOR_ID_AMI +#define PCI_VENDOR_ID_AMI 0x101e +#endif + #ifndef BITS_PER_LONG #error "BITS_PER_LONG not defined!" #endif @@ -4215,12 +4239,15 @@ qla1280_get_token(char *str) { char *sep; long ret = -1; - int i; + int i, len; + + len = sizeof(setup_token)/sizeof(struct setup_tokens); sep = strchr(str, ':'); if (sep) { - for (i = 0; i < ARRAY_SIZE(setup_token); i++) { + for (i = 0; i < len; i++){ + if (!strncmp(setup_token[i].token, str, (sep - str))) { ret = setup_token[i].val; break; diff --git a/trunk/drivers/scsi/qla2xxx/Kconfig b/trunk/drivers/scsi/qla2xxx/Kconfig index 8c865b9e02b5..ff40906c66f9 100644 --- a/trunk/drivers/scsi/qla2xxx/Kconfig +++ b/trunk/drivers/scsi/qla2xxx/Kconfig @@ -24,3 +24,48 @@ config SCSI_QLA_FC Firmware images can be retrieved from: ftp://ftp.qlogic.com/outgoing/linux/firmware/ + + NOTE: The original method of building firmware-loader + modules has been deprecated as the firmware-images will + be removed from the kernel sources. + +config SCSI_QLA2XXX_EMBEDDED_FIRMWARE + bool " Use firmware-loader modules (DEPRECATED)" + depends on SCSI_QLA_FC + help + This option offers you the deprecated firmware-loader + modules that have been obsoleted by the usage of the + Firmware Loader interface in the qla2xxx driver. + +config SCSI_QLA21XX + tristate " Build QLogic ISP2100 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 21xx (ISP2100) host adapter family. + +config SCSI_QLA22XX + tristate " Build QLogic ISP2200 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 22xx (ISP2200) host adapter family. + +config SCSI_QLA2300 + tristate " Build QLogic ISP2300/ISP6312 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 2300 (ISP2300, ISP2312 and + ISP6312) host adapter family. + +config SCSI_QLA2322 + tristate " Build QLogic ISP2322/ISP6322 firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 2322 (ISP2322 and ISP6322) host + adapter family. + +config SCSI_QLA24XX + tristate " Build QLogic ISP24xx firmware-module" + depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE + ---help--- + This driver supports the QLogic 24xx (ISP2422 and ISP2432) host + adapter family. diff --git a/trunk/drivers/scsi/qla2xxx/Makefile b/trunk/drivers/scsi/qla2xxx/Makefile index 411663af7bb7..c8f670ee60b4 100644 --- a/trunk/drivers/scsi/qla2xxx/Makefile +++ b/trunk/drivers/scsi/qla2xxx/Makefile @@ -1,4 +1,18 @@ +EXTRA_CFLAGS += -DUNIQUE_FW_NAME + qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ - qla_dbg.o qla_sup.o qla_attr.o + qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o + +qla2100-y := ql2100.o ql2100_fw.o +qla2200-y := ql2200.o ql2200_fw.o +qla2300-y := ql2300.o ql2300_fw.o +qla2322-y := ql2322.o ql2322_fw.o +qla2400-y := ql2400.o ql2400_fw.o + +obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o +obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o +obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o +obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o +obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o diff --git a/trunk/drivers/scsi/qla2xxx/ql2100.c b/trunk/drivers/scsi/qla2xxx/ql2100.c new file mode 100644 index 000000000000..f5db2235e432 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2100.c @@ -0,0 +1,91 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2100"; + +extern unsigned char fw2100tp_version[]; +extern unsigned char fw2100tp_version_str[]; +extern unsigned short fw2100tp_addr01; +extern unsigned short fw2100tp_code01[]; +extern unsigned short fw2100tp_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2100tp_code01[0], + .fwlen = &fw2100tp_length01, + .fwstart = &fw2100tp_addr01, + }, + + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl = { + .drv_name = qla_driver_name, + + .isp_name = "ISP2100", + .fw_info = qla_fw_tbl, +}; + +static struct pci_device_id qla2100_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2100, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl, + }, + + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla2100_pci_tbl); + +static int __devinit +qla2100_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla2100_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla2100_pci_driver = { + .name = "qla2100", + .id_table = qla2100_pci_tbl, + .probe = qla2100_probe_one, + .remove = __devexit_p(qla2100_remove_one), +}; + +static int __init +qla2100_init(void) +{ + return pci_module_init(&qla2100_pci_driver); +} + +static void __exit +qla2100_exit(void) +{ + pci_unregister_driver(&qla2100_pci_driver); +} + +module_init(qla2100_init); +module_exit(qla2100_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP21xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/trunk/drivers/scsi/qla2xxx/ql2100_fw.c b/trunk/drivers/scsi/qla2xxx/ql2100_fw.c new file mode 100644 index 000000000000..56006162da40 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2100_fw.c @@ -0,0 +1,4848 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 1.19.25 (13:12 Dec 10, 2003) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_version = 1*1024+19; +#else +unsigned short risc_code_version = 1*1024+19; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2100tp_version_str[] = {1,19,25}; +#else +unsigned char firmware_version[] = {1,19,25}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2100tp_VERSION_STRING "1.19.25" +#else +#define FW_VERSION_STRING "1.19.25" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_addr01 = 0x1000 ; +#else +unsigned short risc_code_addr01 = 0x1000 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0078, 0x102d, 0x0000, 0x9601, 0x0000, 0x0001, 0x0013, 0x0019, + 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1, + 0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff, + 0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04, + 0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c, + 0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020, + 0x2039, 0x8fff, 0x20a1, 0xae00, 0x2708, 0x810d, 0x810d, 0x810d, + 0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8, + 0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102, + 0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1, + 0xa601, 0x2009, 0x0000, 0x20a9, 0x07ff, 0x41a4, 0x3400, 0x20c9, + 0xabff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x25c7, + 0x2051, 0xa700, 0x2a70, 0x7762, 0xa786, 0x8fff, 0x0040, 0x1092, + 0x705f, 0xce00, 0x705b, 0xcdf1, 0x7067, 0x0200, 0x706b, 0x0200, + 0x0078, 0x109a, 0x705b, 0xbe01, 0x7067, 0x0100, 0x706b, 0x0100, + 0x705f, 0xbe00, 0x1078, 0x12df, 0x1078, 0x13ca, 0x1078, 0x1577, + 0x1078, 0x1ce9, 0x1078, 0x42ec, 0x1078, 0x76bf, 0x1078, 0x1355, + 0x1078, 0x2ac0, 0x1078, 0x4e93, 0x1078, 0x49a3, 0x1078, 0x594a, + 0x1078, 0x2263, 0x1078, 0x5c43, 0x1078, 0x5485, 0x1078, 0x2162, + 0x1078, 0x2240, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf, + 0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068, + 0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, + 0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, + 0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x365e, 0x1078, 0x2ae8, + 0x1078, 0x4ee3, 0x1078, 0x4b66, 0x2009, 0x0100, 0x2104, 0xa082, + 0x0002, 0x0048, 0x10f3, 0x1078, 0x5966, 0x0078, 0x10d6, 0x1079, + 0x10f7, 0x0078, 0x10dc, 0x1078, 0x7197, 0x0078, 0x10eb, 0x1101, + 0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078, + 0x1332, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086, + 0x0001, 0x00c0, 0x1198, 0x1078, 0x3aec, 0x2079, 0x0100, 0x7844, + 0xa005, 0x00c0, 0x1198, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x1078, + 0x1adf, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, + 0x8010, 0x73c4, 0x1078, 0x361b, 0x2001, 0xffff, 0x1078, 0x5ae6, + 0x723c, 0xc284, 0x723e, 0x2001, 0xa70c, 0x2014, 0xc2ac, 0x2202, + 0x1078, 0x6f9f, 0x2011, 0x0004, 0x1078, 0x8d2b, 0x1078, 0x489e, + 0x1078, 0x42d4, 0x0040, 0x1144, 0x7087, 0x0001, 0x70bf, 0x0000, + 0x1078, 0x3c9e, 0x0078, 0x1198, 0x1078, 0x4967, 0x0040, 0x114d, + 0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x90b6, 0x70cc, + 0xd09c, 0x00c0, 0x1159, 0x7098, 0xa005, 0x0040, 0x1159, 0x1078, + 0x42b8, 0x70d7, 0x0000, 0x70d3, 0x0000, 0x72cc, 0x2079, 0xa752, + 0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ce, 0xa296, 0x0004, + 0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8d2b, 0x7093, 0x0000, + 0x7097, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x2677, 0x2011, + 0x0005, 0x1078, 0x70e0, 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, + 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x7093, 0x0000, + 0x7097, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x70e0, + 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, + 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e, + 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078, + 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, 0x027f, 0x017f, 0x1078, + 0x298e, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706f, 0x0000, 0x7070, + 0xa084, 0x00ff, 0x7072, 0x709b, 0x0000, 0x007c, 0x127e, 0x2091, + 0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7094, 0xa086, + 0xffff, 0x0040, 0x11d1, 0x1078, 0x2677, 0x1078, 0x62d1, 0x0078, + 0x1244, 0x70cc, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd, + 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, + 0x0040, 0x11fd, 0x70d0, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078, + 0x27f7, 0x1078, 0x62d1, 0x70cc, 0xd094, 0x00c0, 0x1244, 0x2011, + 0x0001, 0x2019, 0x0000, 0x1078, 0x282f, 0x1078, 0x62d1, 0x0078, + 0x1244, 0x70d4, 0xa005, 0x00c0, 0x1244, 0x7090, 0xa005, 0x00c0, + 0x1244, 0x1078, 0x4967, 0x00c0, 0x1244, 0x2001, 0xa753, 0x2004, + 0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0, 0x121a, 0x6000, 0xd0ec, + 0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f, + 0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003, + 0x0003, 0x7097, 0xffff, 0x2001, 0x0000, 0x1078, 0x24e8, 0x1078, + 0x3699, 0x2001, 0xa9b2, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c, + 0x2011, 0x0000, 0x1078, 0x70e0, 0x2011, 0x0000, 0x1078, 0x70ea, + 0x1078, 0x62d1, 0x1078, 0x639b, 0x127f, 0x007c, 0x017e, 0x0f7e, + 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078, + 0x42a1, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040, + 0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008, + 0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5ae6, 0x7900, 0xa18a, + 0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009, + 0x00f8, 0x1078, 0x42a1, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, + 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0, + 0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x24e8, 0x0078, + 0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0, + 0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f, + 0x0000, 0x2009, 0x00f8, 0x1078, 0x42a1, 0x20a9, 0x000e, 0x0005, + 0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010, + 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4, + 0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009, + 0xa732, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4, + 0x200b, 0x0000, 0x1078, 0x2588, 0x2001, 0x0001, 0x1078, 0x24e8, + 0x0078, 0x12d3, 0x2001, 0xa732, 0x2003, 0x0000, 0x7828, 0xc09d, + 0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f, + 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70, + 0x2061, 0xa9ad, 0x2063, 0x0001, 0x6007, 0x0013, 0x600b, 0x0019, + 0x600f, 0x0017, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, + 0x12f5, 0x7053, 0xffff, 0x0078, 0x12f7, 0x7053, 0x0000, 0x7057, + 0xffff, 0x706f, 0x0000, 0x7073, 0x0000, 0x1078, 0x90b6, 0x2061, + 0xa98d, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, + 0x07d0, 0x2061, 0xa995, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, + 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, + 0x0001, 0x601f, 0x0000, 0x2061, 0xa9a5, 0x6003, 0x514c, 0x6007, + 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xa726, 0x2003, + 0x0000, 0x007c, 0x2091, 0x8000, 0x0068, 0x1334, 0x007e, 0x017e, + 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x133a, 0x017f, 0x792e, + 0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, + 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa700, + 0x7803, 0x0005, 0x0078, 0x1352, 0x007c, 0x2071, 0xa700, 0x715c, + 0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, + 0x136b, 0x7060, 0xa302, 0x00c8, 0x136b, 0x220a, 0x2208, 0x2310, + 0x8420, 0x0078, 0x135d, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x007c, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa700, 0x70ac, 0xa0ea, + 0x0010, 0x00c8, 0x137e, 0xa06e, 0x0078, 0x1388, 0x8001, 0x70ae, + 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, + 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa700, 0x127e, 0x2091, + 0x8000, 0x70ac, 0x8001, 0x00c8, 0x1398, 0xa06e, 0x0078, 0x13a1, + 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, + 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa700, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, + 0x70ae, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13c0, 0x6804, + 0x6807, 0x0000, 0x007e, 0x1078, 0x13a4, 0x0d7f, 0x0078, 0x13b4, + 0x007c, 0x0e7e, 0x2071, 0xa700, 0x70ac, 0xa08a, 0x0010, 0xa00d, + 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7007, 0x0000, 0x701b, + 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, + 0x7012, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x0e7e, 0x2270, + 0x700b, 0x0000, 0x2071, 0xa9d6, 0x7018, 0xa088, 0xa9df, 0x220a, + 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, 0x13f6, + 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x127f, + 0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7004, 0xa005, 0x00c0, 0x1406, + 0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x007c, + 0x7000, 0x0079, 0x140b, 0x140f, 0x1479, 0x1496, 0x1496, 0x7018, + 0x711c, 0xa106, 0x00c0, 0x1417, 0x7007, 0x0000, 0x007c, 0x0d7e, + 0xa180, 0xa9df, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, + 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, + 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, + 0x0d7f, 0xd084, 0x0040, 0x1439, 0x7007, 0x0001, 0x1078, 0x143e, + 0x007c, 0x7007, 0x0002, 0x1078, 0x1454, 0x007c, 0x017e, 0x027e, + 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1449, 0x2110, + 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, + 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e, + 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, + 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1468, 0x2110, 0xa006, + 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300, + 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f, + 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa7fa, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, + 0xa7f5, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e, + 0x157e, 0x2001, 0xa829, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, + 0x2001, 0xa82a, 0x20ac, 0x53a6, 0x2099, 0xa82b, 0x20a1, 0x0018, + 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000, + 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, + 0xa826, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e, + 0x2071, 0xa9d6, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, + 0xd1fc, 0x0040, 0x14d0, 0xa18c, 0x0700, 0x7004, 0x1079, 0x14d4, + 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1408, 0x14dc, 0x1509, 0x1531, + 0x1564, 0x14da, 0x0078, 0x14da, 0xa18c, 0x0700, 0x00c0, 0x1502, + 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, + 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, + 0x137f, 0x700c, 0xa005, 0x0040, 0x151e, 0x1078, 0x143e, 0x007c, + 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, + 0x1408, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x0078, + 0x14fd, 0xa18c, 0x0700, 0x00c0, 0x1514, 0x700c, 0xa005, 0x0040, + 0x151e, 0x1078, 0x1454, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, + 0x0200, 0x7007, 0x0000, 0x1078, 0x1408, 0x007c, 0x0d7e, 0x7008, + 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, + 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1408, + 0x007c, 0xa18c, 0x0700, 0x00c0, 0x155e, 0x137e, 0x147e, 0x157e, + 0x2001, 0xa7f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, + 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xa7fa, 0x2004, + 0xd0bc, 0x0040, 0x1554, 0x2001, 0xa803, 0x2004, 0xa080, 0x000d, + 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f, 0x137f, 0x7007, + 0x0000, 0x1078, 0x4f8c, 0x1078, 0x1408, 0x007c, 0x2011, 0x8003, + 0x1078, 0x361b, 0x0078, 0x1562, 0xa18c, 0x0700, 0x00c0, 0x1571, + 0x2001, 0xa828, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1408, + 0x007c, 0x2011, 0x8004, 0x1078, 0x361b, 0x0078, 0x1575, 0x127e, + 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa9e7, 0x7803, 0x0004, + 0x7003, 0x0000, 0x700f, 0xa9ed, 0x7013, 0xa9ed, 0x780f, 0x0076, + 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079, + 0x1591, 0x1599, 0x15df, 0x1599, 0x1599, 0x1599, 0x15c4, 0x15a8, + 0x159d, 0xa085, 0x0001, 0x0078, 0x15f9, 0x684c, 0xd0bc, 0x0040, + 0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x15e7, + 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1599, 0x684c, 0xd0bc, + 0x0040, 0x1599, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, + 0x6832, 0x6858, 0x0078, 0x15ef, 0xa18c, 0x00ff, 0xa186, 0x0015, + 0x00c0, 0x1599, 0x684c, 0xd0ac, 0x0040, 0x1599, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, + 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x15ef, 0x684c, + 0xd0ac, 0x0040, 0x1599, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, + 0x000f, 0xa188, 0x206a, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826, + 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980, + 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, + 0x2004, 0x82ff, 0x0040, 0x161c, 0xa280, 0x0004, 0x0d7e, 0x206c, + 0x684c, 0xd0dc, 0x00c0, 0x1618, 0x1078, 0x158c, 0x0040, 0x1618, + 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0078, 0x161c, + 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e, + 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0, + 0x1630, 0x7206, 0x2001, 0x1651, 0x007e, 0x2260, 0x0078, 0x17e0, + 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, + 0xaa08, 0x0048, 0x163d, 0x2009, 0xa9ed, 0x710e, 0x7010, 0xa102, + 0xa082, 0x0009, 0x0040, 0x1648, 0xa080, 0x001b, 0x00c0, 0x164b, + 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, 0x1651, 0x1078, + 0x17c1, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, 0x0c7e, 0x007e, + 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f, 0x0d7e, 0x0c7e, + 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005, 0x0040, 0x16dd, + 0x6808, 0xa005, 0x0040, 0x174a, 0x7000, 0xa005, 0x00c0, 0x1672, + 0x0078, 0x16d2, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1753, 0x7004, + 0xa406, 0x00c0, 0x16d2, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, + 0x168f, 0x047e, 0x1078, 0x1913, 0x047f, 0x2460, 0x6010, 0xa080, + 0x0002, 0x2004, 0xa005, 0x0040, 0x174a, 0x0078, 0x166c, 0x2001, + 0x0207, 0x2004, 0xd09c, 0x00c0, 0x167b, 0x7804, 0xa084, 0x6000, + 0x0040, 0x16a0, 0xa086, 0x6000, 0x0040, 0x16a0, 0x0078, 0x167b, + 0x7100, 0xa186, 0x0002, 0x00c0, 0x16c0, 0x0e7e, 0x2b68, 0x6818, + 0x2060, 0x1078, 0x203f, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, + 0x16b5, 0x7108, 0x720c, 0x0078, 0x16b7, 0x7110, 0x7214, 0x6810, + 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f, 0x0078, 0x16c4, + 0xa186, 0x0001, 0x00c0, 0x16cc, 0x7820, 0x6910, 0xa100, 0x6812, + 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, + 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009, + 0x0048, 0x1078, 0x775c, 0x0078, 0x1753, 0x6808, 0xa005, 0x0040, + 0x174a, 0x7000, 0xa005, 0x00c0, 0x16e7, 0x0078, 0x174a, 0x700c, + 0x7110, 0xa106, 0x00c0, 0x16f0, 0x7004, 0xa406, 0x00c0, 0x174a, + 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x1704, 0x047e, 0x1078, + 0x1913, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002, 0x2004, 0xa005, + 0x0040, 0x174a, 0x0078, 0x16e1, 0x2001, 0x0207, 0x2004, 0xd09c, + 0x00c0, 0x16f0, 0x2001, 0x0005, 0x2004, 0xd08c, 0x00c0, 0x16f6, + 0x7804, 0xa084, 0x6000, 0x0040, 0x171b, 0xa086, 0x6000, 0x0040, + 0x171b, 0x0078, 0x16f0, 0x7007, 0x0000, 0xa016, 0x2218, 0x7000, + 0xa08e, 0x0001, 0x0040, 0x173c, 0xa08e, 0x0002, 0x00c0, 0x174a, + 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x203f, 0x2804, 0xac70, + 0x6034, 0xd09c, 0x00c0, 0x1738, 0x7308, 0x720c, 0x0078, 0x173a, + 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, 0x7824, 0xa211, + 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009, + 0x0048, 0x1078, 0x775c, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, + 0x0e7e, 0x027e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa9e7, 0x7000, + 0xa086, 0x0000, 0x0040, 0x17ba, 0x7004, 0xac06, 0x00c0, 0x17ab, + 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040, 0x17ab, 0x7804, + 0xd0fc, 0x00c0, 0x17a7, 0x20e1, 0x6000, 0x2011, 0x0032, 0x2001, + 0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, 0x00c0, 0x176f, + 0x8211, 0x00c0, 0x1777, 0x7804, 0xd0fc, 0x00c0, 0x17a7, 0x1078, + 0x1b22, 0x027e, 0x057e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x178d, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, + 0x0000, 0x057f, 0x027f, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, + 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0078, 0x17ab, 0x1078, + 0x1913, 0x0078, 0x175f, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa9ed, + 0x2104, 0xac06, 0x00c0, 0x17b5, 0x200a, 0xa188, 0x0003, 0x00f0, + 0x17b0, 0x157f, 0x057f, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, + 0x007c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x17c9, 0x7003, 0x0000, + 0x007c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, + 0x8108, 0xa182, 0xaa08, 0x0048, 0x17d7, 0x2009, 0xa9ed, 0x7112, + 0x700c, 0xa106, 0x00c0, 0x17e0, 0x2001, 0x0138, 0x2003, 0x0008, + 0x8cff, 0x00c0, 0x17e7, 0x1078, 0x1b4d, 0x0078, 0x1854, 0x6010, + 0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x17f2, 0x682c, 0xa306, + 0x0040, 0x182f, 0x601c, 0xa086, 0x0008, 0x0040, 0x182f, 0x6024, + 0xd0f4, 0x00c0, 0x181c, 0xd0d4, 0x0040, 0x1818, 0x6038, 0xa402, + 0x6034, 0xa303, 0x0040, 0x1806, 0x00c8, 0x1818, 0x643a, 0x6336, + 0x6c2a, 0x6b2e, 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, + 0x2300, 0x6b80, 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x181c, + 0x1078, 0x9063, 0x0040, 0x17e3, 0x2001, 0xa774, 0x2004, 0xd0b4, + 0x00c0, 0x182b, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x182b, 0x6817, + 0x7fff, 0x6813, 0xffff, 0x1078, 0x208a, 0x00c0, 0x17e3, 0x0c7e, + 0x7004, 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, + 0x0040, 0x1840, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17e3, + 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, + 0x000f, 0x2009, 0x0011, 0x1078, 0x1855, 0x0040, 0x1853, 0x2009, + 0x0001, 0x1078, 0x1855, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18ec, + 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1877, 0xd0f4, 0x00c0, + 0x1887, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1867, 0x18ce, + 0x188e, 0x188e, 0x18ce, 0x18ce, 0x18c6, 0x18ce, 0x188e, 0x18ce, + 0x1894, 0x1894, 0x18ce, 0x18ce, 0x18ce, 0x18bd, 0x1894, 0xc0fc, + 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, + 0x18d1, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0xc0f4, + 0x6852, 0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18d8, 0x6b08, 0x6a0c, + 0x6d00, 0x6c04, 0x0078, 0x18d1, 0x7b0c, 0xd3bc, 0x0040, 0x18b5, + 0x7004, 0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, + 0x18b5, 0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, + 0x82ff, 0x00c0, 0x18b0, 0x6810, 0xa302, 0x0048, 0x18b0, 0x6b10, + 0x2011, 0x0000, 0x2468, 0x0078, 0x18b7, 0x6b10, 0x6a14, 0x6d00, + 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x18d1, 0x0d7f, 0x0d7e, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x18ce, 0x0d7f, 0x1078, + 0x2026, 0x00c0, 0x1855, 0xa00e, 0x0078, 0x18ec, 0x0d7f, 0x1078, + 0x1332, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, + 0x7000, 0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, + 0xa201, 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, + 0xa203, 0x6816, 0x1078, 0x2026, 0x007c, 0x1078, 0x1332, 0x1078, + 0x1c97, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, + 0x1078, 0x1af4, 0x1078, 0x8d16, 0x0040, 0x190c, 0x6808, 0x8001, + 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8a11, 0x0078, + 0x1adb, 0x1078, 0x1332, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, + 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, + 0x00c0, 0x18ef, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x1911, + 0x7000, 0x0079, 0x192b, 0x1933, 0x1935, 0x1a34, 0x1ab2, 0x1ac9, + 0x1933, 0x1933, 0x1933, 0x1078, 0x1332, 0x8001, 0x7002, 0xa184, + 0x0880, 0x00c0, 0x194a, 0x8aff, 0x0040, 0x19d4, 0x2009, 0x0001, + 0x1078, 0x1855, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078, 0x1855, + 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, + 0x19b2, 0x027e, 0x037e, 0x017e, 0x7808, 0xd0ec, 0x00c0, 0x1962, + 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, + 0x0078, 0x1964, 0x1078, 0x1bd7, 0x017f, 0xd194, 0x0040, 0x196b, + 0x8aff, 0x0040, 0x19a1, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, + 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, + 0x6024, 0xd0f4, 0x00c0, 0x197e, 0x633a, 0x6236, 0x0c7f, 0x2400, + 0x6910, 0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, + 0x027f, 0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x203f, 0x2a00, + 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, + 0x6808, 0x8001, 0x680a, 0x00c0, 0x19a7, 0x684c, 0xd0e4, 0x0040, + 0x19a7, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x7000, + 0xa086, 0x0004, 0x0040, 0x1adb, 0x7003, 0x0000, 0x1078, 0x17c1, + 0x0078, 0x1adb, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x19b9, 0x1078, + 0xa58e, 0x057f, 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, + 0x4963, 0x0040, 0x19c6, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, + 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, + 0x6980, 0x6916, 0x0078, 0x1adb, 0x7004, 0x0c7e, 0x2060, 0x6024, + 0x0c7f, 0xd0f4, 0x0040, 0x19e1, 0x6808, 0x8001, 0x680a, 0x0078, + 0x19f5, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19f9, + 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19f5, 0x7004, + 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078, + 0x1adb, 0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, + 0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa192, 0x0841, 0x00c8, + 0x18ef, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104, + 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x1078, 0x1b5e, + 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc, + 0x0040, 0x1a1e, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x0076, + 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, + 0x1078, 0x1b92, 0x0040, 0x19f5, 0x8001, 0x7002, 0xd194, 0x0040, + 0x1a46, 0x7804, 0xd0fc, 0x00c0, 0x191b, 0x8aff, 0x0040, 0x1adb, + 0x2009, 0x0001, 0x1078, 0x1855, 0x0078, 0x1adb, 0xa184, 0x0880, + 0x00c0, 0x1a53, 0x8aff, 0x0040, 0x1adb, 0x2009, 0x0001, 0x1078, + 0x1855, 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, + 0x00c0, 0x1a93, 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1a66, + 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a68, 0x1078, 0x1bd7, + 0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, + 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a83, 0x6808, 0x2008, 0xa31a, + 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, + 0x7816, 0x0078, 0x1a8f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, + 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, + 0x0d7f, 0x0078, 0x196d, 0x057e, 0x7d0c, 0x1078, 0xa58e, 0x057f, + 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4963, 0x0040, + 0x1aa4, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, + 0x0078, 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, + 0x0040, 0x1ac5, 0x6808, 0x8001, 0x680a, 0x00c0, 0x1ac5, 0x7004, + 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x1078, 0x17c1, 0x0078, + 0x1adb, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, + 0xa005, 0x0040, 0x1ac5, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, + 0x6b2c, 0x1078, 0x17e0, 0x017f, 0x007f, 0x127f, 0x007c, 0x127e, + 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0, 0x1af2, 0x700c, + 0x7110, 0xa106, 0x0040, 0x1af2, 0x20e1, 0x9028, 0x700f, 0xa9ed, + 0x7013, 0xa9ed, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x1b22, 0x20e1, + 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1b19, 0x2104, 0xa005, + 0x0040, 0x1b08, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, + 0xa188, 0x0003, 0xa182, 0xaa08, 0x0048, 0x1b10, 0x2009, 0xa9ed, + 0x7112, 0x700c, 0xa106, 0x00c0, 0x1af9, 0x2011, 0x0008, 0x0078, + 0x1af9, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0138, 0x2202, + 0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2021, + 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x00c0, 0x1b3f, 0x2001, + 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0, 0x1b3f, 0x2001, 0x0111, + 0x201c, 0x83ff, 0x00c0, 0x1b3f, 0x8421, 0x00c0, 0x1b29, 0x007c, + 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x00c0, 0x1b4c, + 0x8109, 0x00c0, 0x1b44, 0x007c, 0x007c, 0x1078, 0x1b40, 0x0040, + 0x1b55, 0x780c, 0xd0a4, 0x0040, 0x1b5b, 0x1078, 0x1af4, 0xa085, + 0x0001, 0x0078, 0x1b5d, 0x1078, 0x1b92, 0x007c, 0x0e7e, 0x2071, + 0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1b22, 0x2019, + 0x5000, 0x8319, 0x0040, 0x1b7c, 0x2001, 0xaa08, 0x2004, 0xa086, + 0x0000, 0x0040, 0x1b7c, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b69, + 0x1078, 0x1eaa, 0x0078, 0x1b67, 0x20e1, 0x7000, 0x7324, 0x7420, + 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, + 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, + 0x0e7f, 0x007c, 0x027e, 0x2001, 0x015d, 0x2001, 0x0000, 0x7908, + 0xa18c, 0x0fff, 0xa182, 0x0ffd, 0x0048, 0x1ba0, 0x2009, 0x0000, + 0xa190, 0x0007, 0xa294, 0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001, + 0x020a, 0x82ff, 0x0040, 0x1bb5, 0x20e1, 0x6000, 0x200c, 0x200c, + 0x200c, 0x200c, 0x8211, 0x00c0, 0x1bae, 0x20e1, 0x7000, 0x200c, + 0x200c, 0x7003, 0x0000, 0x20e1, 0x6000, 0x2001, 0x0208, 0x200c, + 0x2001, 0x0209, 0x2004, 0xa106, 0x0040, 0x1bd4, 0x1078, 0x1b40, + 0x0040, 0x1bd2, 0x7908, 0xd1ec, 0x00c0, 0x1bd4, 0x790c, 0xd1a4, + 0x0040, 0x1b97, 0x1078, 0x1af4, 0xa006, 0x027f, 0x007c, 0x7c20, + 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c69, + 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c69, 0x0d7e, + 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c67, 0x681c, 0xa086, + 0x0008, 0x0040, 0x1c67, 0x6824, 0xd0d4, 0x00c0, 0x1c67, 0x6810, + 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1c29, 0x8108, 0x2104, 0x6b2c, + 0xa306, 0x00c0, 0x1c67, 0x8108, 0x2104, 0x6a28, 0xa206, 0x00c0, + 0x1c67, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, + 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, + 0xd09c, 0x0040, 0x1c24, 0x6830, 0x2004, 0xac68, 0x6808, 0x783a, + 0x680c, 0x783e, 0x0078, 0x1c65, 0xa006, 0x783a, 0x783e, 0x0078, + 0x1c65, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6b2c, 0xa306, + 0x00c0, 0x1c67, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c67, 0x6a28, + 0xa206, 0x00c0, 0x1c67, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2004, + 0x6918, 0xa160, 0xa180, 0x000d, 0x2004, 0xd09c, 0x00c0, 0x1c57, + 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, + 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0078, 0x1c65, 0x6010, + 0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, + 0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f, + 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0x027e, 0x2071, 0xa9e7, + 0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x0040, + 0x1c92, 0x8211, 0x0040, 0x1c90, 0x2001, 0x0005, 0x2004, 0xd08c, + 0x0040, 0x1c79, 0x7904, 0xa18c, 0x0780, 0x017e, 0x1078, 0x1913, + 0x017f, 0x81ff, 0x00c0, 0x1c90, 0x2011, 0x0050, 0x0078, 0x1c74, + 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f, 0x0f7f, 0x007c, 0x7803, + 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0040, 0x1ce8, 0x8109, + 0x00c0, 0x1c9b, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, 0x1048, + 0x1332, 0x1078, 0x1fca, 0x0e7e, 0x0f7e, 0x2071, 0xa9d6, 0x2079, + 0x0010, 0x7004, 0xa086, 0x0000, 0x0040, 0x1ce0, 0x7800, 0x007e, + 0x7820, 0x007e, 0x7830, 0x007e, 0x7834, 0x007e, 0x7838, 0x007e, + 0x783c, 0x007e, 0x7803, 0x0004, 0x7823, 0x0000, 0x0005, 0x0005, + 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x2079, 0x0010, + 0x007f, 0x783e, 0x007f, 0x783a, 0x007f, 0x7836, 0x007f, 0x7832, + 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f, 0x0e7f, 0x0078, 0x1ce6, + 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x1078, 0x639b, + 0x007c, 0x0e7e, 0x2071, 0xaa08, 0x7003, 0x0000, 0x0e7f, 0x007c, + 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1d6b, + 0x6934, 0xa184, 0x0007, 0x0079, 0x1cfd, 0x1d05, 0x1d56, 0x1d05, + 0x1d05, 0x1d05, 0x1d3b, 0x1d18, 0x1d07, 0x1078, 0x1332, 0x684c, + 0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, + 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1d5e, + 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1d05, 0x684c, + 0xd0b4, 0x0040, 0x1e79, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, + 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, + 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, + 0x6958, 0x0078, 0x1d67, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, + 0x1d6b, 0x684c, 0xd0b4, 0x0040, 0x1e79, 0x6804, 0x681a, 0xa080, + 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, + 0x6958, 0xa006, 0x682e, 0x682a, 0x0078, 0x1d67, 0x684c, 0xd0b4, + 0x0040, 0x18ed, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, + 0x6834, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, 0x6926, + 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020, + 0x7804, 0xd0fc, 0x10c0, 0x1eaa, 0x0e7e, 0x0d7e, 0x2071, 0xaa08, + 0x7000, 0xa005, 0x00c0, 0x1df0, 0x0c7e, 0x7206, 0xa280, 0x0004, + 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068, + 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200, + 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68, + 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, + 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0007, 0x0040, + 0x1db2, 0xa184, 0x0007, 0x0040, 0x1db2, 0x017e, 0x2009, 0x0008, + 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081, + 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, + 0x6814, 0xa106, 0x00c0, 0x1dc9, 0x6928, 0x6810, 0xa106, 0x0040, + 0x1dd6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x208a, 0x047f, + 0x037f, 0x0040, 0x1dd6, 0x0c7f, 0x0078, 0x1df0, 0x8aff, 0x00c0, + 0x1dde, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1df0, 0x127e, 0x2091, + 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0040, + 0x1ded, 0x2009, 0x0001, 0x1078, 0x1df4, 0x127f, 0x0c7f, 0xa006, + 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e, + 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e72, 0x700c, 0x7214, 0xa23a, + 0x7010, 0x7218, 0xa203, 0x0048, 0x1e71, 0xa705, 0x0040, 0x1e71, + 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1e24, 0x0d7e, 0x2804, + 0xac68, 0x2900, 0x0079, 0x1e14, 0x1e53, 0x1e34, 0x1e34, 0x1e53, + 0x1e53, 0x1e4b, 0x1e53, 0x1e34, 0x1e53, 0x1e3a, 0x1e3a, 0x1e53, + 0x1e53, 0x1e53, 0x1e42, 0x1e3a, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, + 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e57, 0x0d7e, 0x2804, 0xac68, + 0x6f08, 0x6e0c, 0x0078, 0x1e56, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, + 0x0078, 0x1e56, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, + 0x0078, 0x1e56, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, + 0x001e, 0x00c0, 0x1e53, 0x0d7f, 0x1078, 0x2026, 0x00c0, 0x1dfa, + 0xa00e, 0x0078, 0x1e72, 0x0d7f, 0x1078, 0x1332, 0x0d7f, 0x7b22, + 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, + 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, + 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x1078, 0x2026, 0x0078, + 0x1e72, 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, + 0x007c, 0x1078, 0x1332, 0x027e, 0x2001, 0x0105, 0x2003, 0x0010, + 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, + 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1e92, 0x6850, + 0xc0bd, 0x6852, 0x0d7f, 0x0c7e, 0x1078, 0x8a11, 0x0c7f, 0x2001, + 0xa9c0, 0x2004, 0xac06, 0x00c0, 0x1ea7, 0x20e1, 0x9040, 0x1078, + 0x738a, 0x2011, 0x0000, 0x1078, 0x70ea, 0x1078, 0x639b, 0x027f, + 0x0078, 0x1f76, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e, + 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0xaa08, 0x2b68, + 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, + 0x1e7b, 0x7000, 0x0079, 0x1ec4, 0x1f76, 0x1ec8, 0x1f43, 0x1f74, + 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1edc, 0x8aff, 0x0040, 0x1efb, + 0x2009, 0x0001, 0x1078, 0x1df4, 0x0040, 0x1f76, 0x2009, 0x0001, + 0x1078, 0x1df4, 0x0078, 0x1f76, 0x7803, 0x0004, 0xd194, 0x0040, + 0x1eec, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1ef1, 0x684c, + 0xc0f5, 0x684e, 0x0078, 0x1ef1, 0x1078, 0x203f, 0x6850, 0xc0fd, + 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, + 0x0000, 0x0078, 0x1f76, 0x711c, 0x81ff, 0x0040, 0x1f11, 0x7918, + 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, + 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, + 0x1f76, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, + 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x037e, + 0x2019, 0x1000, 0x8319, 0x1040, 0x1332, 0x7820, 0xd0bc, 0x00c0, + 0x1f22, 0x037f, 0x79c8, 0x007f, 0xa102, 0x017f, 0x007e, 0x017e, + 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f, 0x78ca, 0xa284, 0x0004, + 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, + 0x0000, 0x0078, 0x1f76, 0x8001, 0x7002, 0xd194, 0x0040, 0x1f58, + 0x7804, 0xd0fc, 0x00c0, 0x1eba, 0xd19c, 0x00c0, 0x1f72, 0x8aff, + 0x0040, 0x1f76, 0x2009, 0x0001, 0x1078, 0x1df4, 0x0078, 0x1f76, + 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078, 0x203f, 0x0d7e, 0x2804, + 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f6b, 0x6808, 0xa31a, 0x680c, + 0xa213, 0x0078, 0x1f6f, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, + 0x0078, 0x1eec, 0x0078, 0x1eec, 0x1078, 0x1332, 0x0c7f, 0x0d7f, + 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, + 0x2071, 0xaa08, 0x7000, 0xa086, 0x0000, 0x0040, 0x1fc7, 0x2079, + 0x0020, 0x017e, 0x2009, 0x0207, 0x210c, 0xd194, 0x0040, 0x1fa4, + 0x2009, 0x020c, 0x210c, 0xa184, 0x0003, 0x0040, 0x1fa4, 0x1078, + 0xa5e2, 0x2001, 0x0133, 0x2004, 0xa005, 0x1040, 0x1332, 0x20e1, + 0x9040, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, + 0x0203, 0x210c, 0xa106, 0x00c0, 0x1faf, 0x20e1, 0x9040, 0x7804, + 0xd0fc, 0x0040, 0x1f8a, 0x1078, 0x1eaa, 0x7000, 0xa086, 0x0000, + 0x00c0, 0x1f8a, 0x017f, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0, + 0x1fbd, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f, + 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, + 0xaa08, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0040, 0x2003, + 0x7004, 0x2060, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1fed, + 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x00c0, 0x1fed, + 0x6808, 0x7a18, 0xa206, 0x0040, 0x2009, 0x2001, 0x0105, 0x2003, + 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, + 0x2060, 0x1078, 0x8a11, 0x20e1, 0x9040, 0x1078, 0x738a, 0x2011, + 0x0000, 0x1078, 0x70ea, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x027f, + 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0, 0x1fed, 0x684c, 0xc0dc, + 0x684e, 0x2c10, 0x1078, 0x1cf0, 0x2001, 0x0105, 0x2003, 0x0010, + 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x2069, 0xa9b1, + 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x2003, 0x8840, 0x2804, + 0xa005, 0x00c0, 0x203a, 0x6004, 0xa005, 0x0040, 0x203c, 0x681a, + 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x206a, 0x2044, 0x88ff, + 0x1040, 0x1332, 0x8a51, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, + 0x8841, 0x2804, 0xa005, 0x00c0, 0x2059, 0x2c00, 0xad06, 0x0040, + 0x204e, 0x6000, 0xa005, 0x00c0, 0x204e, 0x2d00, 0x2060, 0x681a, + 0x6034, 0xa084, 0x000f, 0xa080, 0x207a, 0x2044, 0x88ff, 0x1040, + 0x1332, 0x007c, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, + 0x0025, 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, + 0x0000, 0x0000, 0x0000, 0x205f, 0x205b, 0x0000, 0x0000, 0x2069, + 0x0000, 0x205f, 0x0000, 0x2066, 0x2063, 0x0000, 0x0000, 0x0000, + 0x2069, 0x2066, 0x0000, 0x2061, 0x2061, 0x0000, 0x0000, 0x2069, + 0x0000, 0x2061, 0x0000, 0x2067, 0x2067, 0x0000, 0x0000, 0x0000, + 0x2069, 0x2067, 0x0a7e, 0x097e, 0x087e, 0x6b2e, 0x6c2a, 0x6858, + 0xa055, 0x0040, 0x212d, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, + 0x206a, 0xa986, 0x0007, 0x0040, 0x20a5, 0xa986, 0x000e, 0x0040, + 0x20a5, 0xa986, 0x000f, 0x00c0, 0x20a9, 0x605c, 0xa422, 0x6060, + 0xa31b, 0x2804, 0xa045, 0x00c0, 0x20b7, 0x0050, 0x20b1, 0x0078, + 0x212d, 0x6004, 0xa065, 0x0040, 0x212d, 0x0078, 0x2094, 0x2804, + 0xa005, 0x0040, 0x20d5, 0xac68, 0xd99c, 0x00c0, 0x20c5, 0x6808, + 0xa422, 0x680c, 0xa31b, 0x0078, 0x20c9, 0x6810, 0xa422, 0x6814, + 0xa31b, 0x0048, 0x20f4, 0x2300, 0xa405, 0x0040, 0x20db, 0x8a51, + 0x0040, 0x212d, 0x8840, 0x0078, 0x20b7, 0x6004, 0xa065, 0x0040, + 0x212d, 0x0078, 0x2094, 0x8a51, 0x0040, 0x212d, 0x8840, 0x2804, + 0xa005, 0x00c0, 0x20ee, 0x6004, 0xa065, 0x0040, 0x212d, 0x6034, + 0xa0cc, 0x000f, 0xa9c0, 0x206a, 0x2804, 0x2040, 0x2b68, 0x6850, + 0xc0fc, 0x6852, 0x0078, 0x2121, 0x8422, 0x8420, 0x831a, 0xa399, + 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f, 0xd99c, 0x00c0, + 0x210f, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1048, + 0x1332, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078, 0x211b, 0x6910, + 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048, 0x1332, 0x6800, + 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850, 0xc0fd, + 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, 0x6826, 0x007f, + 0x007f, 0x007f, 0xa006, 0x0078, 0x2132, 0x087f, 0x097f, 0x0a7f, + 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004, 0xa084, 0x0007, + 0x0079, 0x213a, 0x2142, 0x2143, 0x2146, 0x2149, 0x214e, 0x2151, + 0x2156, 0x215b, 0x007c, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x1913, + 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x007c, 0x1078, 0x14be, + 0x007c, 0x1078, 0x1eaa, 0x1078, 0x14be, 0x007c, 0x1078, 0x1913, + 0x1078, 0x14be, 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x1078, + 0x14be, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079, 0x0200, 0x2071, + 0xac80, 0x2069, 0xa700, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004, + 0x1078, 0x251f, 0x781b, 0x0002, 0x20e1, 0x8700, 0x127f, 0x007c, + 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, 0x0079, 0x2180, + 0x21a4, 0x2188, 0x218c, 0x2190, 0x2196, 0x219a, 0x219e, 0x21a2, + 0x1078, 0x548e, 0x0078, 0x21a4, 0x1078, 0x54da, 0x0078, 0x21a4, + 0x1078, 0x548e, 0x1078, 0x54da, 0x0078, 0x21a4, 0x1078, 0x21a6, + 0x0078, 0x21a4, 0x1078, 0x21a6, 0x0078, 0x21a4, 0x1078, 0x21a6, + 0x0078, 0x21a4, 0x1078, 0x21a6, 0x127f, 0x007c, 0x007e, 0x017e, + 0x027e, 0x1078, 0xa5e2, 0x7930, 0xa184, 0x0003, 0x0040, 0x21c9, + 0x2001, 0xa9c0, 0x2004, 0xa005, 0x0040, 0x21c5, 0x2001, 0x0133, + 0x2004, 0xa005, 0x1040, 0x1332, 0x0c7e, 0x2001, 0xa9c0, 0x2064, + 0x1078, 0x8a11, 0x0c7f, 0x0078, 0x21f2, 0x20e1, 0x9040, 0x0078, + 0x21f2, 0xa184, 0x0030, 0x0040, 0x21da, 0x6a00, 0xa286, 0x0003, + 0x00c0, 0x21d4, 0x0078, 0x21d6, 0x1078, 0x4224, 0x20e1, 0x9010, + 0x0078, 0x21f2, 0xa184, 0x00c0, 0x0040, 0x21ec, 0x0e7e, 0x037e, + 0x047e, 0x057e, 0x2071, 0xa9e7, 0x1078, 0x1af4, 0x057f, 0x047f, + 0x037f, 0x0e7f, 0x0078, 0x21f2, 0xa184, 0x0300, 0x0040, 0x21f2, + 0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, + 0x0e7e, 0x0f7e, 0x2071, 0xa700, 0x7128, 0x2001, 0xa990, 0x2102, + 0x2001, 0xa998, 0x2102, 0xa182, 0x0211, 0x00c8, 0x220b, 0x2009, + 0x0008, 0x0078, 0x2235, 0xa182, 0x0259, 0x00c8, 0x2213, 0x2009, + 0x0007, 0x0078, 0x2235, 0xa182, 0x02c1, 0x00c8, 0x221b, 0x2009, + 0x0006, 0x0078, 0x2235, 0xa182, 0x0349, 0x00c8, 0x2223, 0x2009, + 0x0005, 0x0078, 0x2235, 0xa182, 0x0421, 0x00c8, 0x222b, 0x2009, + 0x0004, 0x0078, 0x2235, 0xa182, 0x0581, 0x00c8, 0x2233, 0x2009, + 0x0003, 0x0078, 0x2235, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, + 0x7817, 0x0004, 0x1078, 0x251f, 0x0f7f, 0x0e7f, 0x017f, 0x007c, + 0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0xa700, 0x6024, + 0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb, + 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, + 0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b, + 0x002f, 0x127f, 0x007c, 0x2001, 0xa730, 0x2003, 0x0000, 0x2001, + 0xa72f, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e, + 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x227b, 0xa184, + 0x0007, 0x0079, 0x2281, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079, + 0x2281, 0x22ad, 0x2289, 0x228d, 0x2291, 0x2297, 0x229b, 0x22a1, + 0x22a7, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078, 0x5d45, 0x0078, + 0x22ad, 0x1078, 0x5d45, 0x1078, 0x5c56, 0x0078, 0x22ad, 0x1078, + 0x22b2, 0x0078, 0x22ad, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x0078, + 0x22ad, 0x1078, 0x5d45, 0x1078, 0x22b2, 0x0078, 0x22ad, 0x1078, + 0x5d45, 0x1078, 0x5c56, 0x1078, 0x22b2, 0x027f, 0x017f, 0x007f, + 0x127f, 0x007c, 0x6124, 0xd1ac, 0x0040, 0x23ac, 0x017e, 0x047e, + 0x0c7e, 0x644c, 0xa486, 0xf0f0, 0x00c0, 0x22c5, 0x2061, 0x0100, + 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74c6, 0xa48c, 0xff00, + 0x7034, 0xd084, 0x0040, 0x22dd, 0xa186, 0xf800, 0x00c0, 0x22dd, + 0x703c, 0xd084, 0x00c0, 0x22dd, 0xc085, 0x703e, 0x037e, 0x2418, + 0x2011, 0x8016, 0x1078, 0x361b, 0x037f, 0xa196, 0xff00, 0x0040, + 0x231f, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x231f, + 0x7130, 0xd184, 0x00c0, 0x231f, 0x2011, 0xa753, 0x2214, 0xd2ec, + 0x0040, 0x22fa, 0xc18d, 0x7132, 0x2011, 0xa753, 0x2214, 0xd2ac, + 0x00c0, 0x231f, 0x6240, 0xa294, 0x0010, 0x0040, 0x2306, 0x6248, + 0xa294, 0xff00, 0xa296, 0xff00, 0x0040, 0x231f, 0x7030, 0xd08c, + 0x0040, 0x2371, 0x7034, 0xd08c, 0x00c0, 0x2316, 0x2001, 0xa70c, + 0x200c, 0xd1ac, 0x00c0, 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, + 0x2011, 0x8013, 0x1078, 0x361b, 0x037f, 0x0078, 0x2371, 0x7034, + 0xd08c, 0x00c0, 0x232b, 0x2001, 0xa70c, 0x200c, 0xd1ac, 0x00c0, + 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, 0x2011, 0x8013, 0x1078, + 0x361b, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0xa753, 0x220c, + 0xd1a4, 0x0040, 0x2355, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100, + 0x1078, 0x5bf1, 0x2019, 0x000e, 0x1078, 0xa1a5, 0xa484, 0x00ff, + 0xa080, 0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, + 0x2009, 0x000e, 0x1078, 0xa22d, 0x017f, 0xd1ac, 0x00c0, 0x2362, + 0x017e, 0x2009, 0x0000, 0x2019, 0x0004, 0x1078, 0x284f, 0x017f, + 0x0078, 0x2371, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078, + 0x45c4, 0x00c0, 0x236d, 0x1078, 0x42f8, 0x8108, 0x00f0, 0x2367, + 0x157f, 0x0c7f, 0x047f, 0x0f7e, 0x2079, 0xa9c4, 0x783c, 0xa086, + 0x0000, 0x0040, 0x2383, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, + 0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x70e0, + 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019, + 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, + 0xa700, 0x2014, 0xa296, 0x0004, 0x00c0, 0x23a4, 0xd19c, 0x00c0, + 0x23ac, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa722, + 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x2490, 0x0f7e, + 0x2079, 0xa9c4, 0x783c, 0xa086, 0x0001, 0x00c0, 0x23d0, 0x017e, + 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, + 0x7803, 0x0000, 0x2079, 0xa9b1, 0x7807, 0x0000, 0x7833, 0x0000, + 0x1078, 0x62d1, 0x1078, 0x639b, 0x017f, 0x0f7f, 0x0078, 0x2490, + 0x0f7f, 0x017e, 0x3900, 0xa082, 0xaae3, 0x00c8, 0x23db, 0x017e, + 0x1078, 0x747a, 0x017f, 0x6220, 0xd2b4, 0x0040, 0x2446, 0x1078, + 0x5acb, 0x1078, 0x6e0f, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa9ba, + 0x2304, 0xa07d, 0x0040, 0x241c, 0x7804, 0xa086, 0x0032, 0x00c0, + 0x241c, 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, + 0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, + 0x8001, 0x00c0, 0x2400, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, + 0x0000, 0x618e, 0x628a, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x7810, + 0x2070, 0x7037, 0x0103, 0x2f60, 0x1078, 0x772d, 0x0e7f, 0x0c7f, + 0x0d7f, 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, + 0x6804, 0xa084, 0x4000, 0x0040, 0x2429, 0x6803, 0x1000, 0x6803, + 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6028, 0xa09a, 0x00c8, + 0x00c8, 0x2439, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6e01, 0x0078, + 0x248f, 0x2019, 0xa9ba, 0x2304, 0xa065, 0x0040, 0x2443, 0x2009, + 0x0027, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x248f, 0xd2bc, 0x0040, + 0x248f, 0x1078, 0x5ad8, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, + 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x245b, 0x6803, + 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6044, + 0xa09a, 0x00c8, 0x00c8, 0x247e, 0x8000, 0x6046, 0x603c, 0x0c7f, + 0xa005, 0x0040, 0x248f, 0x2009, 0x07d0, 0x1078, 0x5ad0, 0xa080, + 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x247a, 0x6017, 0x0012, + 0x0078, 0x248f, 0x6017, 0x0016, 0x0078, 0x248f, 0x037e, 0x2019, + 0x0001, 0x1078, 0x7058, 0x037f, 0x2019, 0xa9c0, 0x2304, 0xa065, + 0x0040, 0x248e, 0x2009, 0x004f, 0x1078, 0x775c, 0x0c7f, 0x017f, + 0xd19c, 0x0040, 0x24e4, 0x7034, 0xd0ac, 0x00c0, 0x24c1, 0x017e, + 0x157e, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, + 0x249f, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, + 0x0320, 0x00e0, 0x24a9, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, + 0x24b8, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x24e4, + 0x1078, 0x2577, 0x00f0, 0x24a9, 0x157f, 0x6152, 0x017f, 0x6027, + 0x0008, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, + 0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, + 0x2019, 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x1078, + 0xa5bd, 0x1078, 0xa5db, 0x2001, 0xa700, 0x2003, 0x0004, 0x6027, + 0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, + 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa700, 0x71bc, 0x70be, 0xa116, 0x0040, 0x2518, 0x81ff, + 0x0040, 0x2500, 0x2011, 0x8011, 0x1078, 0x361b, 0x0078, 0x2518, + 0x2011, 0x8012, 0x1078, 0x361b, 0x2001, 0xa772, 0x2004, 0xd0fc, + 0x00c0, 0x2518, 0x037e, 0x0c7e, 0x1078, 0x6f9f, 0x2061, 0x0100, + 0x2019, 0x0028, 0x2009, 0x0000, 0x1078, 0x284f, 0x0c7f, 0x037f, + 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, + 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x253b, 0x2204, + 0x60f2, 0x2011, 0x2548, 0x6000, 0xa082, 0x0003, 0x00c8, 0x2534, + 0x2001, 0x00ff, 0x0078, 0x2535, 0x2204, 0x60ee, 0x027f, 0x007f, + 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, + 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, + 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, + 0x2130, 0xa094, 0xff00, 0x00c0, 0x2558, 0x81ff, 0x0040, 0x255c, + 0x1078, 0x5761, 0x0078, 0x2563, 0xa080, 0x29c0, 0x200c, 0xa18c, + 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x29c0, 0x200c, 0xa18c, + 0x00ff, 0x007c, 0x0c7e, 0x2061, 0xa700, 0x6030, 0x0040, 0x2573, + 0xc09d, 0x0078, 0x2574, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, + 0x157e, 0x0f7e, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, + 0x00c0, 0x2584, 0x00f0, 0x257e, 0x0f7f, 0x157f, 0x007f, 0x007c, + 0x0c7e, 0x007e, 0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, + 0x60e4, 0x007e, 0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, + 0x60ec, 0x007e, 0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, + 0x60e0, 0x007e, 0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, + 0x0005, 0x0005, 0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, + 0x007f, 0x602a, 0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, + 0x007f, 0x60f2, 0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, + 0x007f, 0x604a, 0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x25e7, + 0x25eb, 0x25ef, 0x25f5, 0x25fb, 0x2601, 0x2607, 0x260f, 0x2617, + 0x261d, 0x2623, 0x262b, 0x2633, 0x263b, 0x2643, 0x264d, 0x2657, + 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, + 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x2657, 0x107e, + 0x007e, 0x0078, 0x2670, 0x107e, 0x007e, 0x0078, 0x2670, 0x107e, + 0x007e, 0x1078, 0x226c, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, + 0x226c, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x0078, + 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e, + 0x007e, 0x1078, 0x226c, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e, + 0x007e, 0x1078, 0x226c, 0x1078, 0x2133, 0x0078, 0x2670, 0x107e, + 0x007e, 0x1078, 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, + 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078, + 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078, + 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x1078, + 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x2133, 0x1078, + 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, 0x226c, 0x1078, + 0x2133, 0x1078, 0x2178, 0x0078, 0x2670, 0x107e, 0x007e, 0x1078, + 0x226c, 0x1078, 0x2133, 0x1078, 0x2178, 0x0078, 0x2670, 0x0005, + 0x0078, 0x2657, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x2660, + 0x2670, 0x25ed, 0x25f1, 0x25f7, 0x25fd, 0x2603, 0x2609, 0x2611, + 0x2619, 0x261f, 0x2625, 0x262d, 0x2635, 0x263d, 0x2645, 0x264f, + 0x0008, 0x265a, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, + 0x027e, 0x047e, 0x2021, 0x0000, 0x1078, 0x4967, 0x00c0, 0x2772, + 0x70cc, 0xd09c, 0x0040, 0x268e, 0xd084, 0x00c0, 0x268e, 0xd0bc, + 0x00c0, 0x2772, 0x1078, 0x2776, 0x0078, 0x2772, 0xd0cc, 0x00c0, + 0x2772, 0xd094, 0x0040, 0x2698, 0x7097, 0xffff, 0x0078, 0x2772, + 0x2001, 0x010c, 0x203c, 0x7284, 0xd284, 0x0040, 0x2701, 0xd28c, + 0x00c0, 0x2701, 0x037e, 0x7394, 0xa38e, 0xffff, 0x0040, 0x26ab, + 0x83ff, 0x00c0, 0x26ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xadc0, + 0x2c04, 0xa38c, 0x0001, 0x0040, 0x26ba, 0xa084, 0xff00, 0x8007, + 0x0078, 0x26bc, 0xa084, 0x00ff, 0xa70e, 0x0040, 0x26f6, 0xa08e, + 0x0000, 0x0040, 0x26f6, 0xa08e, 0x00ff, 0x00c0, 0x26d3, 0x7230, + 0xd284, 0x00c0, 0x26fc, 0x7284, 0xc28d, 0x7286, 0x7097, 0xffff, + 0x037f, 0x0078, 0x2701, 0x2009, 0x0000, 0x1078, 0x254d, 0x1078, + 0x455c, 0x00c0, 0x26f9, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x00c0, 0x26f0, 0x7030, 0xd08c, 0x0040, 0x26ea, 0x6000, 0xd0bc, + 0x0040, 0x26f0, 0x1078, 0x278c, 0x0040, 0x26f9, 0x0078, 0x26f6, + 0x1078, 0x28c4, 0x1078, 0x27b9, 0x0040, 0x26f9, 0x8318, 0x0078, + 0x26ad, 0x7396, 0x0078, 0x26fe, 0x7097, 0xffff, 0x037f, 0x0078, + 0x2772, 0xa780, 0x29c0, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x2041, + 0x007e, 0x7094, 0xa096, 0xffff, 0x00c0, 0x2713, 0x2009, 0x0000, + 0x28a8, 0x0078, 0x271f, 0xa812, 0x0048, 0x271b, 0x2008, 0xa802, + 0x20a8, 0x0078, 0x271f, 0x7097, 0xffff, 0x0078, 0x2772, 0x2700, + 0x157e, 0x017e, 0xa106, 0x0040, 0x2766, 0xc484, 0x1078, 0x45c4, + 0x0040, 0x2730, 0x1078, 0x455c, 0x00c0, 0x276f, 0x0078, 0x2731, + 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2740, + 0x7030, 0xd08c, 0x0040, 0x275e, 0x6000, 0xd0bc, 0x00c0, 0x275e, + 0x7284, 0xd28c, 0x0040, 0x2756, 0x6004, 0xa084, 0x00ff, 0xa082, + 0x0006, 0x0048, 0x2766, 0xd484, 0x00c0, 0x2752, 0x1078, 0x457f, + 0x0078, 0x2754, 0x1078, 0x298e, 0x0078, 0x2766, 0x1078, 0x28c4, + 0x1078, 0x27b9, 0x0040, 0x276f, 0x0078, 0x2766, 0x1078, 0x2959, + 0x0040, 0x2766, 0x1078, 0x278c, 0x0040, 0x276f, 0x017f, 0x8108, + 0x157f, 0x00f0, 0x271f, 0x7097, 0xffff, 0x0078, 0x2772, 0x017f, + 0x157f, 0x7196, 0x047f, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x017e, + 0x7097, 0x0001, 0x2009, 0x007e, 0x1078, 0x455c, 0x00c0, 0x2789, + 0x1078, 0x28c4, 0x1078, 0x27b9, 0x0040, 0x2789, 0x70cc, 0xc0bd, + 0x70ce, 0x017f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, + 0x2c68, 0x2001, 0xa757, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, + 0x76c7, 0x0040, 0x27b4, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, + 0x0000, 0x1078, 0x44ee, 0x2001, 0x0000, 0x1078, 0x4502, 0x127e, + 0x2091, 0x8000, 0x7090, 0x8000, 0x7092, 0x127f, 0x2009, 0x0004, + 0x1078, 0x775c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, + 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa757, + 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, 0x9197, 0x0040, 0x27f2, + 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, + 0x0040, 0x27db, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, + 0x27db, 0x1078, 0x2880, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, + 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x127e, 0x2091, 0x8000, + 0x7090, 0x8000, 0x7092, 0x127f, 0x2009, 0x0002, 0x1078, 0x775c, + 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e, + 0x027e, 0x2009, 0x0080, 0x1078, 0x455c, 0x00c0, 0x2805, 0x1078, + 0x2808, 0x0040, 0x2805, 0x70d3, 0xffff, 0x027f, 0x0c7f, 0x007c, + 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x76c7, 0x0040, + 0x282a, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, + 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x127e, 0x2091, 0x8000, + 0x70d4, 0x8000, 0x70d6, 0x127f, 0x2009, 0x0002, 0x1078, 0x775c, + 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e, + 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009, 0x007f, 0x1078, 0x455c, + 0x00c0, 0x284b, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x284b, 0x2d00, + 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022, 0x1078, + 0x775c, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, + 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078, 0x5f0e, 0x1078, 0x5eae, + 0x1078, 0x8068, 0x2130, 0x81ff, 0x0040, 0x2864, 0x20a9, 0x007e, + 0x2009, 0x0000, 0x0078, 0x2868, 0x20a9, 0x007f, 0x2009, 0x0000, + 0x017e, 0x1078, 0x45c4, 0x00c0, 0x2871, 0x1078, 0x47e9, 0x1078, + 0x42f8, 0x017f, 0x8108, 0x00f0, 0x2868, 0x86ff, 0x00c0, 0x287a, + 0x1078, 0x119b, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, + 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, + 0x027e, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, + 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f, 0x017f, 0x2e60, + 0x1078, 0x47e9, 0x6210, 0x6314, 0x1078, 0x42f8, 0x6212, 0x6316, + 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x007e, + 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x28ba, 0x2071, + 0xa700, 0x7090, 0xa005, 0x0040, 0x28b7, 0x8001, 0x7092, 0x007f, + 0x0e7f, 0x007c, 0x2071, 0xa700, 0x70d4, 0xa005, 0x0040, 0x28b7, + 0x8001, 0x70d6, 0x0078, 0x28b7, 0x6000, 0xc08c, 0x6002, 0x007c, + 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x2178, + 0x81ff, 0x00c0, 0x28d7, 0x20a9, 0x0001, 0x0078, 0x28f2, 0x2001, + 0xa753, 0x2004, 0xd0c4, 0x0040, 0x28ee, 0xd0a4, 0x0040, 0x28ee, + 0x047e, 0x6018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, + 0xa006, 0x2009, 0x002d, 0x1078, 0xa22d, 0x047f, 0x20a9, 0x00ff, + 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e, 0x0040, 0x2936, 0xa28e, + 0x007f, 0x0040, 0x2936, 0xa28e, 0x0080, 0x0040, 0x2936, 0xa288, + 0xa835, 0x210c, 0x81ff, 0x0040, 0x2936, 0x8fff, 0x1040, 0x2942, + 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078, 0x4972, 0x0c7f, 0x2019, + 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, + 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, + 0x00c0, 0x2926, 0x6007, 0x0404, 0x0078, 0x292b, 0x2001, 0x0004, + 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f, 0x017e, 0x2c08, 0x1078, + 0x9f9b, 0x017f, 0x077f, 0x2160, 0x1078, 0x47e9, 0x027f, 0x8210, + 0x00f0, 0x28f2, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, + 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e, 0x2001, 0xa753, 0x2004, + 0xd0c4, 0x0040, 0x2955, 0xd0a4, 0x0040, 0x2955, 0xa006, 0x2220, + 0x8427, 0x2009, 0x0029, 0x1078, 0xa22d, 0x017f, 0x027f, 0x047f, + 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e, 0x7284, 0x82ff, 0x0040, + 0x2987, 0xa290, 0xa753, 0x2214, 0xd2ac, 0x00c0, 0x2987, 0x2100, + 0x1078, 0x2564, 0x81ff, 0x0040, 0x2989, 0x2019, 0x0001, 0x8314, + 0xa2e0, 0xadc0, 0x2c04, 0xd384, 0x0040, 0x297b, 0xa084, 0xff00, + 0x8007, 0x0078, 0x297d, 0xa084, 0x00ff, 0xa116, 0x0040, 0x2989, + 0xa096, 0x00ff, 0x0040, 0x2987, 0x8318, 0x0078, 0x296f, 0xa085, + 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f, 0x007c, 0x017e, 0x0c7e, + 0x127e, 0x2091, 0x8000, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, + 0x2019, 0x0029, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, + 0x027f, 0x017f, 0xa180, 0xa835, 0x2004, 0xa065, 0x0040, 0x29b7, + 0x017e, 0x0c7e, 0x1078, 0x9197, 0x017f, 0x1040, 0x1332, 0x611a, + 0x1078, 0x2880, 0x1078, 0x772d, 0x017f, 0x1078, 0x457f, 0x127f, + 0x0c7f, 0x017f, 0x007c, 0x2001, 0xa733, 0x2004, 0xd0cc, 0x007c, + 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, + 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, + 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, + 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, + 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, + 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, + 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, + 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, + 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, + 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, + 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, + 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, + 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, + 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, + 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, + 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, + 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, + 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, + 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, + 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, + 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, + 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, + 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, + 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, + 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, + 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, + 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, + 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, + 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x2071, 0xa782, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, + 0x703e, 0x7033, 0xa792, 0x7037, 0xa792, 0x7007, 0x0001, 0x2061, + 0xa7d2, 0x6003, 0x0002, 0x007c, 0x0090, 0x2ae7, 0x0068, 0x2ae7, + 0x2071, 0xa782, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2ae7, 0x2a60, + 0x7820, 0xa08e, 0x0069, 0x00c0, 0x2bd7, 0x0079, 0x2b6b, 0x007c, + 0x2071, 0xa782, 0x7004, 0x0079, 0x2aed, 0x2af1, 0x2af2, 0x2afc, + 0x2b0e, 0x007c, 0x0090, 0x2afb, 0x0068, 0x2afb, 0x2b78, 0x7818, + 0xd084, 0x0040, 0x2b1a, 0x007c, 0x2b78, 0x2061, 0xa7d2, 0x6008, + 0xa08e, 0x0100, 0x0040, 0x2b09, 0xa086, 0x0200, 0x0040, 0x2bcf, + 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, + 0x6834, 0xa086, 0x0103, 0x0040, 0x2b16, 0x007c, 0x2a60, 0x2b78, + 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2b23, + 0x61bc, 0x0079, 0x2b2b, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2bcb, + 0x61bc, 0x0079, 0x2b6b, 0x2bad, 0x2bdf, 0x2be7, 0x2beb, 0x2bf3, + 0x2bf9, 0x2bfd, 0x2c09, 0x2c0d, 0x2c17, 0x2c1b, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2c1f, 0x2bcb, 0x2c2f, 0x2c46, 0x2c5d, 0x2cdd, 0x2ce2, + 0x2d0f, 0x2d69, 0x2d7a, 0x2d98, 0x2dd9, 0x2de3, 0x2df0, 0x2e03, + 0x2e22, 0x2e2b, 0x2e68, 0x2e6e, 0x2bcb, 0x2e8a, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x2e91, 0x2e9b, 0x2bcb, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2ea3, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x2eb5, 0x2ece, 0x2bcb, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x2ee0, 0x2f37, 0x2f95, 0x2fa9, 0x2bcb, + 0x2bcb, 0x2bcb, 0x398e, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x2c17, 0x2c1b, 0x2fc0, 0x2bcb, 0x2fcd, + 0x3a26, 0x3a83, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, + 0x2bcb, 0x2bcb, 0x2bcb, 0x301a, 0x314f, 0x316b, 0x3177, 0x31da, + 0x3233, 0x323e, 0x327d, 0x328c, 0x329b, 0x329e, 0x2fd1, 0x32c2, + 0x331e, 0x332b, 0x343c, 0x356f, 0x3599, 0x36a6, 0x2bcb, 0x36b6, + 0x36f0, 0x37bf, 0x2bcb, 0x2bcb, 0x2bcb, 0x2bcb, 0x3827, 0x3843, + 0x38bd, 0x3977, 0x713c, 0x0078, 0x2bad, 0x2021, 0x4000, 0x1078, + 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x2bba, 0x7818, 0xd084, + 0x0040, 0x2bbd, 0x127f, 0x0078, 0x2bb1, 0x7c22, 0x7926, 0x7a2a, + 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, + 0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2baf, 0x2021, + 0x4002, 0x0078, 0x2baf, 0x2021, 0x4003, 0x0078, 0x2baf, 0x2021, + 0x4005, 0x0078, 0x2baf, 0x2021, 0x4006, 0x0078, 0x2baf, 0xa02e, + 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3604, 0x7823, + 0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, + 0x7930, 0x0078, 0x3608, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, + 0x2bad, 0x7924, 0x2114, 0x0078, 0x2bad, 0x2099, 0x0009, 0x20a1, + 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, + 0x2bad, 0x7824, 0x2060, 0x0078, 0x2c21, 0x2009, 0x0001, 0x2011, + 0x0013, 0x2019, 0x0019, 0x783b, 0x0017, 0x0078, 0x2bad, 0x7d38, + 0x7c3c, 0x0078, 0x2be1, 0x7d38, 0x7c3c, 0x0078, 0x2bed, 0x2061, + 0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, + 0x2c23, 0x2010, 0xa005, 0x0040, 0x2bad, 0x0078, 0x2bd3, 0x2069, + 0xa752, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040, + 0x2bdb, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, + 0x685a, 0x685e, 0x1078, 0x4eae, 0x0078, 0x2bad, 0x2069, 0xa752, + 0x7824, 0x7934, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040, 0x2bdb, + 0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, + 0x686e, 0x1078, 0x4a3e, 0x0078, 0x2bad, 0xa02e, 0x2520, 0x81ff, + 0x00c0, 0x2bd7, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, + 0xa789, 0x41a1, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020, + 0x1078, 0x3604, 0x701b, 0x2c75, 0x007c, 0x6834, 0x2008, 0xa084, + 0x00ff, 0xa096, 0x0011, 0x0040, 0x2c85, 0xa096, 0x0019, 0x0040, + 0x2c85, 0xa096, 0x0015, 0x00c0, 0x2bd7, 0x810f, 0xa18c, 0x00ff, + 0x0040, 0x2bd7, 0x710e, 0x700c, 0x8001, 0x0040, 0x2cb6, 0x700e, + 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020, 0x2061, 0xa7d2, + 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, + 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, 0x3604, 0x701b, 0x2ca9, + 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x2cb4, + 0xa096, 0x000a, 0x00c0, 0x2bd7, 0x0078, 0x2c8b, 0x7010, 0x2068, + 0x6838, 0xc0fd, 0x683a, 0x1078, 0x4431, 0x00c0, 0x2cc4, 0x7007, + 0x0003, 0x701b, 0x2cc6, 0x007c, 0x1078, 0x4b51, 0x127e, 0x2091, + 0x8000, 0x20a9, 0x0005, 0x2099, 0xa789, 0x530a, 0x2100, 0xa210, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, + 0x2009, 0x0020, 0x127f, 0x0078, 0x3608, 0x61a4, 0x7824, 0x60a6, + 0x0078, 0x2bad, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, + 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, + 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, + 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, + 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, + 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, 0x81ff, + 0x00c0, 0x2bd7, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x45c4, + 0x00c0, 0x2bdb, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, + 0x2d23, 0x0078, 0x2bdb, 0x7c28, 0x7d2c, 0x1078, 0x47a4, 0xd28c, + 0x00c0, 0x2d2e, 0x1078, 0x4736, 0x0078, 0x2d30, 0x1078, 0x4772, + 0x00c0, 0x2d5a, 0x2061, 0xae00, 0x127e, 0x2091, 0x8000, 0x6000, + 0xa086, 0x0000, 0x0040, 0x2d48, 0x6010, 0xa06d, 0x0040, 0x2d48, + 0x683c, 0xa406, 0x00c0, 0x2d48, 0x6840, 0xa506, 0x0040, 0x2d53, + 0x127f, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02, 0x00c8, + 0x2bd7, 0x0078, 0x2d34, 0x1078, 0x8a11, 0x127f, 0x0040, 0x2bd7, + 0x0078, 0x2bad, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51, 0x127e, + 0x2091, 0x8000, 0x1078, 0x8f95, 0x1078, 0x4a73, 0x127f, 0x0078, + 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, 0x0040, 0x2bdb, + 0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078, 0x47b2, 0x0040, 0x2bd7, + 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, + 0x2bdb, 0x1078, 0x482f, 0x0040, 0x2bd7, 0x2019, 0x0005, 0x1078, + 0x47d3, 0x0040, 0x2bd7, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, + 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x5a52, 0x0078, 0x2bad, + 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040, 0x2da2, 0x2009, 0x0001, + 0x0078, 0x2dd3, 0x2029, 0x00ff, 0x6450, 0x2400, 0xa506, 0x0040, + 0x2dcd, 0x2508, 0x1078, 0x45c4, 0x00c0, 0x2dcd, 0x1078, 0x482f, + 0x00c0, 0x2db8, 0x2009, 0x0002, 0x62ac, 0x2518, 0x0078, 0x2dd3, + 0x2019, 0x0004, 0x1078, 0x47d3, 0x00c0, 0x2dc2, 0x2009, 0x0006, + 0x0078, 0x2dd3, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x2dd6, 0x8003, + 0x800b, 0x810b, 0xa108, 0x1078, 0x5a52, 0x8529, 0x00c8, 0x2da5, + 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, 0x2bd7, 0x127f, 0x0078, + 0x2bdb, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x46e7, 0x1078, + 0x47a4, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, + 0x0040, 0x2bdb, 0x1078, 0x46d6, 0x1078, 0x47a4, 0x0078, 0x2bad, + 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, + 0x4775, 0x0040, 0x2bd7, 0x1078, 0x4484, 0x1078, 0x472f, 0x1078, + 0x47a4, 0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, + 0x4673, 0x0040, 0x2bd7, 0x62a0, 0x2019, 0x0005, 0x0c7e, 0x1078, + 0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, + 0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x1078, 0x47a4, + 0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x47a4, + 0x2208, 0x0078, 0x2bad, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0xa814, + 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2e37, 0x2009, 0x0000, 0x6816, + 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0xa835, + 0x2d04, 0xa075, 0x0040, 0x2e4c, 0x704c, 0x1078, 0x2e56, 0xa210, + 0x7080, 0x1078, 0x2e56, 0xa318, 0x8d68, 0x00f0, 0x2e40, 0x2300, + 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, 0x2bad, 0x0f7e, 0x017e, + 0xa07d, 0x0040, 0x2e65, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff, + 0x0040, 0x2e65, 0x2178, 0x0078, 0x2e5d, 0x017f, 0x0f7f, 0x007c, + 0x2069, 0xa814, 0x6910, 0x62a8, 0x0078, 0x2bad, 0x81ff, 0x00c0, + 0x2bd7, 0x6150, 0xa190, 0x29c0, 0x2214, 0xa294, 0x00ff, 0x6070, + 0xa084, 0xff00, 0xa215, 0x636c, 0x67cc, 0xd79c, 0x0040, 0x2e84, + 0x2031, 0x0001, 0x0078, 0x2e86, 0x2031, 0x0000, 0x7e3a, 0x7f3e, + 0x0078, 0x2bad, 0x6140, 0x6244, 0x2019, 0xa9a2, 0x231c, 0x0078, + 0x2bad, 0x127e, 0x2091, 0x8000, 0x6134, 0x6338, 0xa006, 0x2010, + 0x127f, 0x0078, 0x2bad, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6244, + 0x6338, 0x0078, 0x2bad, 0x6140, 0x6244, 0x7824, 0x6042, 0x7b28, + 0x6346, 0x2069, 0xa752, 0x831f, 0xa305, 0x6816, 0x782c, 0x2069, + 0xa9a2, 0x2d1c, 0x206a, 0x0078, 0x2bad, 0x017e, 0x127e, 0x2091, + 0x8000, 0x7824, 0x6036, 0xd094, 0x0040, 0x2ec8, 0x7828, 0xa085, + 0x0001, 0x2009, 0xa9ab, 0x200a, 0x2001, 0xffff, 0x1078, 0x5ae6, + 0x782c, 0x603a, 0x127f, 0x017f, 0x0078, 0x2bad, 0x1078, 0x35e4, + 0x0040, 0x2bdb, 0x7828, 0xa00d, 0x0040, 0x2bdb, 0x782c, 0xa005, + 0x0040, 0x2bdb, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, 0x2bad, + 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e, + 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, + 0x00c0, 0x2ef7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f06, 0xa182, + 0x007f, 0x00c8, 0x2f30, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff, + 0x6030, 0xa116, 0x0040, 0x2f30, 0x810f, 0xa105, 0x127e, 0x2091, + 0x8000, 0x007e, 0x1078, 0x76c7, 0x007f, 0x0040, 0x2f2c, 0x601a, + 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x35ba, 0x0040, 0x2f33, + 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, + 0x775c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7, + 0x0c7f, 0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f2c, 0x2001, + 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e, 0x2061, + 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x00c0, + 0x2f4e, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f5d, 0xa182, 0x007f, + 0x00c8, 0x2f87, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff, 0x6030, + 0xa116, 0x0040, 0x2f87, 0x810f, 0xa105, 0x127e, 0x2091, 0x8000, + 0x007e, 0x1078, 0x76c7, 0x007f, 0x0040, 0x2f83, 0x601a, 0x600b, + 0xbc05, 0x601f, 0x0001, 0x1078, 0x35ba, 0x0040, 0x2f8a, 0x6837, + 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x775c, + 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7, 0x0c7f, + 0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f83, 0x6830, 0xa086, + 0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad, 0x2061, 0xaa33, 0x127e, + 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2fa6, 0x6104, 0x6208, + 0x2019, 0xa712, 0x231c, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, + 0x2bdb, 0x81ff, 0x00c0, 0x2bd7, 0x127e, 0x2091, 0x8000, 0x6248, + 0x6064, 0xa202, 0x0048, 0x2fbd, 0xa085, 0x0001, 0x1078, 0x256a, + 0x1078, 0x3c9e, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, 0x2bdb, + 0x127e, 0x2091, 0x8000, 0x20a9, 0x0012, 0x2001, 0xa740, 0x20a0, + 0xa006, 0x40a4, 0x127f, 0x0078, 0x2bad, 0x7d38, 0x7c3c, 0x0078, + 0x2c5f, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2bd7, + 0x6250, 0xa084, 0xff00, 0x8007, 0xa206, 0x00c0, 0x2fe9, 0x2001, + 0xa740, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, + 0x3608, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2bd7, 0x0c7e, + 0x1078, 0x35ba, 0x0c7f, 0x0040, 0x2bd7, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x1078, 0x8e5a, 0x0040, 0x2bd7, 0x7007, 0x0003, + 0x701b, 0x300b, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, + 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0078, 0x3608, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x1078, 0x42dd, + 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, + 0x701b, 0x302b, 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, + 0x2bdb, 0x6804, 0xd0ac, 0x0040, 0x3038, 0xd0a4, 0x0040, 0x2bdb, + 0xd094, 0x0040, 0x3043, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, + 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x304e, 0x0c7e, 0x2061, + 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, + 0x210c, 0xa18a, 0x0002, 0x0048, 0x3063, 0xd084, 0x0040, 0x3063, + 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x2bdb, 0xa288, 0x29c0, 0x210c, + 0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0040, 0x306c, 0x6828, 0xa08a, + 0x007f, 0x00c8, 0x2bdb, 0x6052, 0x6808, 0xa08a, 0x0100, 0x0048, + 0x2bdb, 0xa08a, 0x0841, 0x00c8, 0x2bdb, 0xa084, 0x0007, 0x00c0, + 0x2bdb, 0x680c, 0xa005, 0x0040, 0x2bdb, 0x6810, 0xa005, 0x0040, + 0x2bdb, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x2bdb, 0x8001, 0x0040, + 0x2bdb, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x2bdb, 0x8001, 0x0040, + 0x2bdb, 0x6804, 0xd0fc, 0x0040, 0x30c2, 0x1078, 0x35ba, 0x0040, + 0x2bd7, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, + 0x0038, 0xa399, 0x0000, 0x1078, 0x3604, 0x701b, 0x30a8, 0x007c, + 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa76e, 0x2da0, + 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xa772, 0x200c, 0xd1e4, + 0x0040, 0x30c2, 0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, + 0x6006, 0x0c7f, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa752, 0x2da0, + 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x6142, 0x8007, 0xa084, 0x00ff, + 0x6046, 0x1078, 0x4eae, 0x1078, 0x49ce, 0x1078, 0x4a3e, 0x6000, + 0xa086, 0x0000, 0x00c0, 0x314d, 0x6808, 0x602a, 0x1078, 0x21f7, + 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, + 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x30fa, + 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, + 0x0078, 0x30fc, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, + 0x1078, 0x5b19, 0x6904, 0xd1fc, 0x0040, 0x312f, 0x0c7e, 0x2009, + 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0040, 0x312c, 0x0078, + 0x3116, 0x839d, 0x00c8, 0x312c, 0x3508, 0x8109, 0x1078, 0x5480, + 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, + 0xa184, 0x00ff, 0x6006, 0x8108, 0x00c0, 0x312a, 0x6003, 0x0003, + 0x0078, 0x312c, 0x6003, 0x0001, 0x00f0, 0x3111, 0x0c7f, 0x0c7e, + 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, + 0x3819, 0x0040, 0x313d, 0x1078, 0x256a, 0x60c0, 0xa005, 0x0040, + 0x3149, 0x6003, 0x0001, 0x2091, 0x301d, 0x1078, 0x4224, 0x0078, + 0x314d, 0x6003, 0x0004, 0x2091, 0x301d, 0x0078, 0x2bad, 0x6000, + 0xa086, 0x0000, 0x0040, 0x2bd7, 0x2069, 0xa752, 0x7830, 0x6842, + 0x7834, 0x6846, 0x6804, 0xd0fc, 0x0040, 0x3162, 0x2009, 0x0030, + 0x0078, 0x3164, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0x0078, 0x3608, 0xa006, 0x1078, 0x256a, 0x81ff, 0x00c0, + 0x2bd7, 0x1078, 0x42dd, 0x1078, 0x4224, 0x0078, 0x2bad, 0x81ff, + 0x00c0, 0x2bd7, 0x6184, 0x81ff, 0x0040, 0x3191, 0x703f, 0x0000, + 0x2001, 0xadc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x127e, 0x2091, 0x8000, 0x1078, 0x3608, 0x701b, 0x2baa, 0x127f, + 0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0xadc0, 0x20a9, 0x0040, + 0x20a1, 0xadc0, 0x2019, 0xffff, 0x43a4, 0x6550, 0xa588, 0x29c0, + 0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, + 0xa506, 0x0040, 0x31c3, 0x1078, 0x45c4, 0x00c0, 0x31c3, 0x6014, + 0x821c, 0x0048, 0x31bb, 0xa398, 0xadc0, 0xa085, 0xff00, 0x8007, + 0x201a, 0x0078, 0x31c2, 0xa398, 0xadc0, 0x2324, 0xa4a4, 0xff00, + 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x31ca, + 0x0078, 0x31a7, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, + 0x20a9, 0x0040, 0x20a1, 0xadc0, 0x2099, 0xadc0, 0x1078, 0x4281, + 0x0078, 0x3180, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0c7e, 0x1078, + 0x35ba, 0x0c7f, 0x00c0, 0x31e8, 0x2009, 0x0002, 0x0078, 0x2bd7, + 0x2001, 0xa753, 0x2004, 0xd0b4, 0x0040, 0x320f, 0x6000, 0xd08c, + 0x00c0, 0x320f, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, + 0x320f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8eae, + 0x00c0, 0x3206, 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003, + 0x701b, 0x320b, 0x007c, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x20a9, + 0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, + 0xac80, 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x4281, + 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, + 0x1078, 0x4281, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, + 0x7d38, 0x0078, 0x3608, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, + 0x0040, 0x2bdb, 0x1078, 0x47bd, 0x0078, 0x2bad, 0x81ff, 0x00c0, + 0x2bd7, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, 0x1078, 0x35e4, + 0x0040, 0x2bdb, 0x1078, 0x482f, 0x0040, 0x2bd7, 0x2019, 0x0004, + 0x1078, 0x47d3, 0x7924, 0x810f, 0x7a28, 0x1078, 0x3259, 0x0078, + 0x2bad, 0xa186, 0x00ff, 0x0040, 0x3261, 0x1078, 0x3271, 0x0078, + 0x3270, 0x2029, 0x007e, 0x2061, 0xa700, 0x6450, 0x2400, 0xa506, + 0x0040, 0x326d, 0x2508, 0x1078, 0x3271, 0x8529, 0x00c8, 0x3266, + 0x007c, 0x1078, 0x45c4, 0x00c0, 0x327c, 0x2200, 0x8003, 0x800b, + 0x810b, 0xa108, 0x1078, 0x5a52, 0x007c, 0x81ff, 0x00c0, 0x2bd7, + 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, + 0x1078, 0x47c8, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, + 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078, + 0x47b2, 0x0078, 0x2bad, 0x6100, 0x0078, 0x2bad, 0x1078, 0x35e4, + 0x0040, 0x2bdb, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, + 0x2bd7, 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x32b2, + 0xace8, 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, + 0x6b04, 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, + 0x0078, 0x2bad, 0xa006, 0x1078, 0x256a, 0x7824, 0xa084, 0x00ff, + 0xa086, 0x00ff, 0x0040, 0x32cf, 0x81ff, 0x00c0, 0x2bd7, 0x1078, + 0x42dd, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, 0x7924, 0xa18c, + 0xff00, 0x810f, 0xa186, 0x00ff, 0x0040, 0x32e5, 0xa182, 0x007f, + 0x00c8, 0x2bdb, 0x2100, 0x1078, 0x2564, 0x027e, 0x0c7e, 0x127e, + 0x2091, 0x8000, 0x2061, 0xa9c4, 0x601b, 0x0000, 0x601f, 0x0000, + 0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea, + 0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078, 0x7058, 0x037f, + 0x2061, 0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4259, + 0x1078, 0x5add, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, + 0x3259, 0x127f, 0x0c7f, 0x027f, 0x0078, 0x2bad, 0x7924, 0xa18c, + 0xff00, 0x810f, 0x0c7e, 0x1078, 0x455c, 0x2c08, 0x0c7f, 0x00c0, + 0x2bdb, 0x0078, 0x2bad, 0x81ff, 0x0040, 0x3332, 0x2009, 0x0001, + 0x0078, 0x2bd7, 0x60cc, 0xd09c, 0x00c0, 0x333a, 0x2009, 0x0005, + 0x0078, 0x2bd7, 0x1078, 0x35ba, 0x00c0, 0x3342, 0x2009, 0x0002, + 0x0078, 0x2bd7, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, + 0x3604, 0x701b, 0x334c, 0x007c, 0x2009, 0x0080, 0x1078, 0x45c4, + 0x00c0, 0x3359, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, + 0x335d, 0x2021, 0x400a, 0x0078, 0x2baf, 0x0d7e, 0xade8, 0x000d, + 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, + 0x0100, 0x0040, 0x33d0, 0xa0be, 0x0112, 0x0040, 0x33d0, 0xa0be, + 0x0113, 0x0040, 0x33d0, 0xa0be, 0x0114, 0x0040, 0x33d0, 0xa0be, + 0x0117, 0x0040, 0x33d0, 0xa0be, 0x011a, 0x0040, 0x33d0, 0xa0be, + 0x0121, 0x0040, 0x33c6, 0xa0be, 0x0131, 0x0040, 0x33c6, 0xa0be, + 0x0171, 0x0040, 0x33d0, 0xa0be, 0x0173, 0x0040, 0x33d0, 0xa0be, + 0x01a1, 0x00c0, 0x3398, 0x6830, 0x8007, 0x6832, 0x0078, 0x33d6, + 0xa0be, 0x0212, 0x0040, 0x33cc, 0xa0be, 0x0213, 0x0040, 0x33cc, + 0xa0be, 0x0214, 0x0040, 0x33be, 0xa0be, 0x0217, 0x0040, 0x33b8, + 0xa0be, 0x021a, 0x00c0, 0x33b1, 0x6838, 0x8007, 0x683a, 0x0078, + 0x33d0, 0xa0be, 0x0300, 0x0040, 0x33d0, 0x0d7f, 0x0078, 0x2bdb, + 0xad80, 0x0010, 0x20a9, 0x0007, 0x1078, 0x3418, 0xad80, 0x000e, + 0x20a9, 0x0001, 0x1078, 0x3418, 0x0078, 0x33d0, 0xad80, 0x000c, + 0x1078, 0x3426, 0x0078, 0x33d6, 0xad80, 0x000e, 0x1078, 0x3426, + 0xad80, 0x000c, 0x20a9, 0x0001, 0x1078, 0x3418, 0x0c7e, 0x1078, + 0x35ba, 0x0040, 0x3409, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, + 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, + 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, + 0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x6823, 0x0000, 0x6804, 0x2068, 0x1078, 0x8e76, 0x00c0, 0x3404, + 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x340f, + 0x007c, 0x0c7f, 0x0d7f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6820, + 0xa086, 0x8001, 0x00c0, 0x2bad, 0x2009, 0x0004, 0x0078, 0x2bd7, + 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, + 0x280a, 0x8108, 0x00f0, 0x341a, 0x017f, 0x007c, 0x017e, 0x0a7e, + 0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, + 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, + 0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x0040, 0x3443, 0x2009, + 0x0001, 0x0078, 0x2bd7, 0x60cc, 0xd09c, 0x00c0, 0x344b, 0x2009, + 0x0005, 0x0078, 0x2bd7, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, + 0xa182, 0x0080, 0x0048, 0x2bdb, 0xa182, 0x00ff, 0x00c8, 0x2bdb, + 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x00c0, 0x3466, 0x6070, 0xa24e, + 0x0040, 0x2bdb, 0xa9cc, 0xff00, 0x0040, 0x2bdb, 0x0c7e, 0x1078, + 0x350f, 0x2c68, 0x0c7f, 0x0040, 0x349e, 0xa0c6, 0x4000, 0x00c0, + 0x3484, 0x0c7e, 0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x489b, + 0x00c0, 0x347b, 0xc185, 0x6000, 0xd0bc, 0x0040, 0x3480, 0xc18d, + 0x007f, 0x0c7f, 0x0078, 0x349b, 0xa0c6, 0x4007, 0x00c0, 0x348b, + 0x2408, 0x0078, 0x349b, 0xa0c6, 0x4008, 0x00c0, 0x3493, 0x2708, + 0x2610, 0x0078, 0x349b, 0xa0c6, 0x4009, 0x00c0, 0x3499, 0x0078, + 0x349b, 0x2001, 0x4006, 0x2020, 0x0078, 0x2baf, 0x2d00, 0x7022, + 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x76c7, 0x0040, + 0x34e4, 0x2d00, 0x601a, 0x2001, 0xa757, 0x2004, 0xa084, 0x00ff, + 0x6842, 0x2e58, 0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, + 0x2b70, 0x00c0, 0x34c5, 0x1078, 0x772d, 0x0e7f, 0x0c7f, 0x0b7f, + 0x017f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6837, 0x0000, 0x2d00, + 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, + 0x8000, 0x1078, 0x2880, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, + 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x2009, 0x0002, + 0x1078, 0x775c, 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, + 0x00c0, 0x34ee, 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003, + 0x701b, 0x34f3, 0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, + 0x00c0, 0x3501, 0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, + 0x2bd7, 0x2009, 0x0000, 0x1078, 0x489b, 0x00c0, 0x3508, 0xc185, + 0x6000, 0xd0bc, 0x0040, 0x350d, 0xc18d, 0x0078, 0x2bad, 0x0e7e, + 0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, + 0xa8b5, 0x2e04, 0xa005, 0x00c0, 0x3524, 0x2100, 0xa406, 0x00c0, + 0x3555, 0x2428, 0x0078, 0x3555, 0x2068, 0x6f10, 0x2700, 0xa306, + 0x00c0, 0x3546, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x3546, 0x2400, + 0xa106, 0x00c0, 0x3542, 0x2d60, 0xd884, 0x0040, 0x356a, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x356a, 0x2001, 0x4000, + 0x0078, 0x356b, 0x2001, 0x4007, 0x0078, 0x356b, 0x2400, 0xa106, + 0x00c0, 0x3555, 0x6e14, 0x87ff, 0x00c0, 0x3551, 0x86ff, 0x0040, + 0x3521, 0x2001, 0x4008, 0x0078, 0x356b, 0x8420, 0x8e70, 0x00f0, + 0x3519, 0x85ff, 0x00c0, 0x3564, 0x2001, 0x4009, 0x0078, 0x356b, + 0x2001, 0x0001, 0x0078, 0x356b, 0x1078, 0x455c, 0x00c0, 0x3560, + 0x6312, 0x6216, 0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, + 0x00c0, 0x2bd7, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0040, 0x2bdb, 0xa096, + 0x00ff, 0x0040, 0x3587, 0xa092, 0x0004, 0x00c8, 0x2bdb, 0x2010, + 0x2d18, 0x1078, 0x282f, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, + 0x3592, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078, + 0x2bad, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, + 0x2bdb, 0xa182, 0x00ff, 0x00c8, 0x2bdb, 0x127e, 0x2091, 0x8000, + 0x1078, 0x8d5b, 0x00c0, 0x35b7, 0xa190, 0xa835, 0x2204, 0xa065, + 0x0040, 0x35b7, 0x1078, 0x42f8, 0x127f, 0x0078, 0x2bad, 0x127f, + 0x0078, 0x2bd7, 0x1078, 0x138b, 0x0040, 0x35d1, 0xa006, 0x6802, + 0x7010, 0xa005, 0x00c0, 0x35c9, 0x2d00, 0x7012, 0x7016, 0x0078, + 0x35cf, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, + 0x000d, 0x007c, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x45c4, + 0x00c0, 0x35e1, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, + 0x35e2, 0xa066, 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, + 0x1078, 0x45c4, 0x00c0, 0x35f2, 0xa6b4, 0x00ff, 0xa682, 0x4000, + 0x0048, 0x35f3, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, + 0x0040, 0x3600, 0x2168, 0x6904, 0x1078, 0x13a4, 0x0078, 0x35f7, + 0x7112, 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x360a, + 0x2031, 0x0000, 0x2061, 0xa7d2, 0x6606, 0x6112, 0x600e, 0x6226, + 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, + 0x701b, 0x2bad, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, + 0x0000, 0x2001, 0xa790, 0x2004, 0xa005, 0x00c0, 0x3636, 0x0068, + 0x3636, 0x7818, 0xd084, 0x00c0, 0x3636, 0x7a22, 0x7b26, 0x7c2a, + 0x781b, 0x0001, 0x2091, 0x4080, 0x0078, 0x365b, 0x017e, 0x0c7e, + 0x0e7e, 0x2071, 0xa782, 0x7138, 0xa182, 0x0008, 0x0048, 0x3644, + 0x7030, 0x2060, 0x0078, 0x3655, 0x7030, 0xa0e0, 0x0008, 0xac82, + 0xa7d2, 0x0048, 0x364d, 0x2061, 0xa792, 0x2c00, 0x7032, 0x81ff, + 0x00c0, 0x3653, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, + 0x0e7f, 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, + 0xa782, 0x7038, 0xa005, 0x0040, 0x3697, 0x127e, 0x2091, 0x8000, + 0x0068, 0x3696, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, + 0x3695, 0x0c7e, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, + 0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, + 0x703a, 0xa005, 0x00c0, 0x368b, 0x7033, 0xa792, 0x7037, 0xa792, + 0x0c7f, 0x0078, 0x3695, 0xac80, 0x0008, 0xa0fa, 0xa7d2, 0x0048, + 0x3693, 0x2001, 0xa792, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, + 0x007c, 0x027e, 0x2001, 0xa753, 0x2004, 0xd0c4, 0x0040, 0x36a4, + 0x2011, 0x8014, 0x1078, 0x361b, 0x027f, 0x007c, 0x81ff, 0x00c0, + 0x2bd7, 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, + 0x6032, 0x1078, 0x4224, 0x127f, 0x0078, 0x2bad, 0x81ff, 0x00c0, + 0x2bd7, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x2001, 0xa753, + 0x2004, 0xd0ac, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x36d3, 0x7828, + 0xa005, 0x0040, 0x2bad, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, 0x0040, + 0x2bd7, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x1078, 0x8f22, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x36e9, + 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad, + 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x7f24, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x35ba, 0x0040, 0x2bd7, + 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, + 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x45c4, 0x00c0, 0x376d, + 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0040, 0x371d, 0xa0c4, + 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x376d, 0x2001, 0xa753, 0x2004, + 0xd0ac, 0x00c0, 0x372a, 0x1078, 0x489b, 0x00c0, 0x372a, 0xd79c, + 0x0040, 0x376d, 0xd794, 0x00c0, 0x3730, 0xd784, 0x0040, 0x373c, + 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, + 0x3426, 0xd794, 0x0040, 0x3745, 0xac80, 0x000a, 0x2098, 0x3400, + 0x20a9, 0x0004, 0x53a3, 0x1078, 0x3426, 0x21a2, 0xd794, 0x0040, + 0x3765, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, 0x53a3, + 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, 0x3400, + 0x20a9, 0x0002, 0x53a3, 0x1078, 0x3418, 0xac80, 0x0026, 0x2098, + 0x20a9, 0x0002, 0x53a3, 0x0078, 0x3766, 0x94a0, 0xd794, 0x0040, + 0x376b, 0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0xd78c, 0x0040, + 0x3777, 0xa186, 0x0100, 0x0040, 0x3788, 0x0078, 0x377b, 0xa186, + 0x007e, 0x0040, 0x3788, 0xd794, 0x0040, 0x3782, 0xa686, 0x0020, + 0x0078, 0x3784, 0xa686, 0x0028, 0x0040, 0x3791, 0x0078, 0x370c, + 0x86ff, 0x00c0, 0x378f, 0x7120, 0x810b, 0x0078, 0x2bad, 0x702f, + 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xa7d2, + 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, + 0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x37a9, + 0x007c, 0x702c, 0xa005, 0x00c0, 0x37bb, 0x711c, 0x7024, 0x20a0, + 0x7728, 0x2031, 0x0000, 0x2061, 0xa7d2, 0x6224, 0x6328, 0x642c, + 0x6530, 0x0078, 0x370c, 0x7120, 0x810b, 0x0078, 0x2bad, 0x2029, + 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, + 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa184, + 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, + 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, + 0x0048, 0x2bdb, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, + 0xa502, 0x0048, 0x2bdb, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, + 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa384, 0x00ff, 0xa0e2, + 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa484, 0xff00, + 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, + 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, + 0x2bdb, 0x2061, 0xa9a5, 0x6102, 0x6206, 0x630a, 0x640e, 0x0078, + 0x2bad, 0x007e, 0x2001, 0xa753, 0x2004, 0xd0cc, 0x007f, 0x007c, + 0x007e, 0x2001, 0xa772, 0x2004, 0xd0bc, 0x007f, 0x007c, 0x6164, + 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x3830, 0x7926, 0x0078, 0x2bad, + 0x83ff, 0x00c0, 0x2bdb, 0x2001, 0xfff0, 0xa200, 0x00c8, 0x2bdb, + 0x2019, 0xffff, 0x6068, 0xa302, 0xa200, 0x0048, 0x2bdb, 0x7926, + 0x6266, 0x0078, 0x2bad, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, + 0x00c0, 0x2bd7, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x1078, 0x35ba, + 0x0040, 0x2bd7, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, + 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xa835, + 0x2c64, 0x8cff, 0x0040, 0x387d, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x0040, 0x3872, 0x6004, 0xa084, 0xff00, 0xa086, 0x0600, + 0x00c0, 0x387d, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105, + 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff, + 0x0040, 0x3888, 0xa386, 0x002a, 0x0040, 0x3891, 0x0078, 0x385e, + 0x83ff, 0x00c0, 0x388f, 0x7120, 0x810c, 0x0078, 0x2bad, 0x702f, + 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0xa7d2, 0x6007, + 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, + 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x38a8, 0x007c, + 0x702c, 0xa005, 0x00c0, 0x38b9, 0x711c, 0x7024, 0x20a0, 0x2019, + 0x0000, 0x2061, 0xa7d2, 0x6424, 0x6528, 0x662c, 0x6730, 0x0078, + 0x385e, 0x7120, 0x810c, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, + 0x60cc, 0xd09c, 0x0040, 0x2bd7, 0x1078, 0x35ba, 0x0040, 0x2bd7, + 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, 0x701b, + 0x38d2, 0x007c, 0x0d7e, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, + 0x0040, 0x38e5, 0xa0be, 0x7100, 0x0040, 0x38e5, 0xa0be, 0x7200, + 0x0040, 0x38e5, 0x0d7f, 0x0078, 0x2bdb, 0x6820, 0x6924, 0x1078, + 0x254d, 0x00c0, 0x3910, 0x1078, 0x455c, 0x00c0, 0x3910, 0x7122, + 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, 0x35ba, 0x0040, 0x3910, + 0x1078, 0x35ba, 0x0040, 0x3910, 0x0c7f, 0x0d7f, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x1078, + 0x8e92, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3913, 0x007c, + 0x0d7f, 0x0078, 0x2bd7, 0x7120, 0x1078, 0x298e, 0x6820, 0xa086, + 0x8001, 0x0040, 0x2bd7, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, + 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x4281, 0x007f, + 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xa7d2, + 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x00c0, 0x393a, + 0x0078, 0x393e, 0xa7c6, 0x7100, 0x00c0, 0x3946, 0xa6c2, 0x0004, + 0x0048, 0x2bdb, 0x2009, 0x0004, 0x0078, 0x3608, 0xa7c6, 0x7200, + 0x00c0, 0x2bdb, 0xa6c2, 0x0054, 0x0048, 0x2bdb, 0x600e, 0x6013, + 0x002a, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13db, + 0x7007, 0x0002, 0x701b, 0x395d, 0x007c, 0x701c, 0x2068, 0x6804, + 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, + 0x2098, 0x20a0, 0x1078, 0x4281, 0x007f, 0x2009, 0x002a, 0x2061, + 0xa7d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3608, 0x81ff, + 0x00c0, 0x2bd7, 0x792c, 0x2001, 0xa99d, 0x2102, 0x1078, 0x35d2, + 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x127e, 0x2091, + 0x8000, 0x1078, 0x47de, 0x127f, 0x0078, 0x2bad, 0x7824, 0xd08c, + 0x00c0, 0x3995, 0xd084, 0x0040, 0x31da, 0x1078, 0x35e4, 0x0040, + 0x2bdb, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, 0x00c0, 0x39a3, 0x2009, + 0x0002, 0x0078, 0x2bd7, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x0040, 0x39b0, 0xa08e, 0x0004, 0x0040, 0x39b0, 0xa08e, 0x0005, + 0x00c0, 0x39dd, 0x7824, 0xd08c, 0x0040, 0x39bb, 0x6000, 0xc08c, + 0x6002, 0x0078, 0x39c5, 0x2001, 0xa753, 0x2004, 0xd0b4, 0x0040, + 0x320f, 0x6000, 0xd08c, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x1078, 0x8eae, 0x00c0, 0x39d2, 0x2009, 0x0003, + 0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x39d7, 0x007c, 0x1078, + 0x35e4, 0x0040, 0x2bdb, 0x0078, 0x320f, 0x2009, 0xa72f, 0x210c, + 0x81ff, 0x0040, 0x39e7, 0x2009, 0x0001, 0x0078, 0x2bd7, 0x2001, + 0xa700, 0x2004, 0xa086, 0x0003, 0x0040, 0x39f2, 0x2009, 0x0007, + 0x0078, 0x2bd7, 0x2001, 0xa753, 0x2004, 0xd0ac, 0x0040, 0x39fc, + 0x2009, 0x0008, 0x0078, 0x2bd7, 0x609c, 0xd0a4, 0x00c0, 0x3a03, + 0xd0ac, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x1078, 0x8f22, 0x00c0, 0x3a12, 0x2009, 0x0003, + 0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3a17, 0x007c, 0x6830, + 0xa086, 0x0100, 0x00c0, 0x3a20, 0x2009, 0x0004, 0x0078, 0x2bd7, + 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0078, 0x39b2, 0x81ff, 0x2009, + 0x0001, 0x00c0, 0x2bd7, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, + 0x00c0, 0x2bd7, 0x2001, 0xa753, 0x2004, 0xd0ac, 0x2009, 0x0008, + 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2bd7, 0x0c7e, + 0x1078, 0x35ba, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2bd7, 0x6837, + 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, + 0xff00, 0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x3a65, 0xc0ed, + 0x6952, 0x792c, 0x6956, 0x0078, 0x3a6e, 0xa28e, 0x0100, 0x00c0, + 0x2bdb, 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, + 0x90cd, 0x2009, 0x0003, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, + 0x3a7a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, + 0x2bd7, 0x0078, 0x2bad, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2bd7, + 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2bd7, 0x1078, + 0x35e4, 0x0040, 0x2bdb, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x2009, 0x0009, 0x00c0, 0x2bd7, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, + 0x2009, 0x0002, 0x0040, 0x2bd7, 0xad80, 0x000f, 0x2009, 0x0008, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, 0x701b, 0x3ab1, + 0x007c, 0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, + 0x3ac4, 0x6804, 0xa005, 0x00c0, 0x3ac4, 0x6808, 0xa084, 0xff00, + 0x00c0, 0x3ac4, 0x0078, 0x3ac7, 0x0d7f, 0x00c0, 0x2bdb, 0x0d7f, + 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, + 0x1078, 0x35e4, 0x00c0, 0x3ad7, 0x0c7f, 0x0078, 0x2bdb, 0x1078, + 0x9129, 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2bd7, 0x7007, 0x0003, + 0x701b, 0x3ae3, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, + 0x0040, 0x2bd7, 0x0078, 0x2bad, 0x127e, 0x0c7e, 0x0e7e, 0x2061, + 0x0100, 0x2071, 0xa700, 0x6044, 0xd0a4, 0x00c0, 0x3b15, 0xd084, + 0x0040, 0x3afe, 0x1078, 0x3c75, 0x0078, 0x3b11, 0xd08c, 0x0040, + 0x3b05, 0x1078, 0x3b8c, 0x0078, 0x3b11, 0xd094, 0x0040, 0x3b0c, + 0x1078, 0x3b60, 0x0078, 0x3b11, 0xd09c, 0x0040, 0x3b11, 0x1078, + 0x3b1f, 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, + 0x00c0, 0x3b1c, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3b11, 0x624c, + 0xa286, 0xf0f0, 0x00c0, 0x3b30, 0x6048, 0xa086, 0xf0f0, 0x0040, + 0x3b30, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3b5f, + 0xa294, 0xff00, 0xa296, 0xf700, 0x0040, 0x3b45, 0x7134, 0xd1a4, + 0x00c0, 0x3b45, 0x6240, 0xa294, 0x0010, 0x0040, 0x3b45, 0x2009, + 0x00f7, 0x1078, 0x42a1, 0x0078, 0x3b5f, 0x6043, 0x0040, 0x6043, + 0x0000, 0x7077, 0x0000, 0x708f, 0x0001, 0x70b3, 0x0000, 0x70cf, + 0x0000, 0x2009, 0xadc0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b, + 0x000f, 0x2009, 0x000f, 0x2011, 0x41d5, 0x1078, 0x5add, 0x007c, + 0x157e, 0x7078, 0xa005, 0x00c0, 0x3b8a, 0x2011, 0x41d5, 0x1078, + 0x5a45, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, + 0x00c8, 0x6044, 0xd08c, 0x00c0, 0x3b83, 0x00f0, 0x3b71, 0x6242, + 0x708b, 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, + 0x6242, 0x0078, 0x3b8a, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, + 0x0078, 0x3b8a, 0x157f, 0x007c, 0x707c, 0xa08a, 0x0003, 0x00c8, + 0x3b95, 0x1079, 0x3b98, 0x0078, 0x3b97, 0x1078, 0x1332, 0x007c, + 0x3b9b, 0x3bea, 0x3c74, 0x0f7e, 0x707f, 0x0001, 0x20e1, 0xa000, + 0x20e1, 0x8700, 0x1078, 0x21f7, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x2079, 0xac00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, + 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, + 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, + 0x782f, 0x0000, 0x2079, 0xac0c, 0x207b, 0x1101, 0x7807, 0x0000, + 0x2099, 0xa705, 0x20a1, 0xac0e, 0x20a9, 0x0004, 0x53a3, 0x2079, + 0xac12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xac00, 0x20a1, + 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, + 0x1078, 0x420b, 0x0f7f, 0x7083, 0x0000, 0x6043, 0x0008, 0x6043, + 0x0000, 0x007c, 0x0d7e, 0x7080, 0x7083, 0x0000, 0xa025, 0x0040, + 0x3c5e, 0x6020, 0xd0b4, 0x00c0, 0x3c5c, 0x718c, 0x81ff, 0x0040, + 0x3c4b, 0xa486, 0x000c, 0x00c0, 0x3c56, 0xa480, 0x0018, 0x8004, + 0x20a8, 0x2011, 0xac80, 0x2019, 0xac00, 0x220c, 0x2304, 0xa106, + 0x00c0, 0x3c22, 0x8210, 0x8318, 0x00f0, 0x3c05, 0x6043, 0x0004, + 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, 0x0002, + 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078, 0x5add, + 0x0078, 0x3c5c, 0x2069, 0xac80, 0x6930, 0xa18e, 0x1101, 0x00c0, + 0x3c56, 0x6834, 0xa005, 0x00c0, 0x3c56, 0x6900, 0xa18c, 0x00ff, + 0x00c0, 0x3c36, 0x6804, 0xa005, 0x0040, 0x3c4b, 0x2011, 0xac8e, + 0x2019, 0xa705, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, + 0x3c49, 0x00c0, 0x3c56, 0x8210, 0x8318, 0x00f0, 0x3c3c, 0x0078, + 0x3c56, 0x708f, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0xac80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, + 0x6043, 0x0000, 0x0078, 0x3c5e, 0x0d7f, 0x007c, 0x6020, 0xd0b4, + 0x00c0, 0x3c5c, 0x60c3, 0x000c, 0x2011, 0xa9bb, 0x2013, 0x0000, + 0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, + 0x1078, 0x6e06, 0x0078, 0x3c5c, 0x007c, 0x7088, 0xa08a, 0x001d, + 0x00c8, 0x3c7e, 0x1079, 0x3c81, 0x0078, 0x3c80, 0x1078, 0x1332, + 0x007c, 0x3cab, 0x3cba, 0x3ce9, 0x3d02, 0x3d2e, 0x3d5a, 0x3d86, + 0x3dbc, 0x3de8, 0x3e10, 0x3e53, 0x3e7d, 0x3e9f, 0x3eb5, 0x3edb, + 0x3eee, 0x3ef7, 0x3f2b, 0x3f57, 0x3f83, 0x3faf, 0x3fe5, 0x4030, + 0x405f, 0x4081, 0x40c3, 0x40e9, 0x4102, 0x4103, 0x0c7e, 0x2061, + 0xa700, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, + 0x6006, 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, + 0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078, + 0x5add, 0x007c, 0x0f7e, 0x7080, 0xa086, 0x0014, 0x00c0, 0x3ce7, + 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3ce7, 0x2079, 0xac80, + 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3ce5, 0x7834, 0xa005, 0x00c0, + 0x3ce5, 0x7a38, 0xd2fc, 0x0040, 0x3cdb, 0x70b0, 0xa005, 0x00c0, + 0x3cdb, 0x70b3, 0x0001, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x708b, + 0x0010, 0x1078, 0x3ef7, 0x0078, 0x3ce7, 0x1078, 0x4224, 0x0f7f, + 0x007c, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x41dc, 0x1078, + 0x5a45, 0x1078, 0x4289, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, + 0x000a, 0x20a3, 0x0000, 0x00f0, 0x3cf9, 0x60c3, 0x0014, 0x1078, + 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d2c, 0x2011, + 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d2a, 0x2079, + 0xac80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3d2a, 0x7834, 0xa005, + 0x00c0, 0x3d2a, 0x7a38, 0xd2fc, 0x0040, 0x3d24, 0x70b0, 0xa005, + 0x00c0, 0x3d24, 0x70b3, 0x0001, 0x708b, 0x0004, 0x1078, 0x3d2e, + 0x0078, 0x3d2c, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0005, + 0x1078, 0x4289, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, + 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3d4c, 0x7074, 0xa005, 0x00c0, + 0x3d4c, 0x7150, 0xa186, 0xffff, 0x0040, 0x3d4c, 0x1078, 0x419d, + 0x0040, 0x3d4c, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298, 0x26a0, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, + 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d84, 0x2011, + 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d82, 0x2079, + 0xac80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3d82, 0x7834, 0xa005, + 0x00c0, 0x3d82, 0x7a38, 0xd2fc, 0x0040, 0x3d7c, 0x70b0, 0xa005, + 0x00c0, 0x3d7c, 0x70b3, 0x0001, 0x708b, 0x0006, 0x1078, 0x3d86, + 0x0078, 0x3d84, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0007, + 0x1078, 0x4289, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, + 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3dae, 0x7074, 0xa005, 0x00c0, + 0x3dae, 0x7154, 0xa186, 0xffff, 0x0040, 0x3dae, 0xa180, 0x29c0, + 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040, 0x3dae, + 0x1078, 0x3820, 0x0040, 0x3dae, 0x1078, 0x256a, 0x20a9, 0x0008, + 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, + 0x3de6, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, + 0x3de4, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3de4, + 0x7834, 0xa005, 0x00c0, 0x3de4, 0x7a38, 0xd2fc, 0x0040, 0x3dde, + 0x70b0, 0xa005, 0x00c0, 0x3dde, 0x70b3, 0x0001, 0x708b, 0x0008, + 0x1078, 0x3de8, 0x0078, 0x3de6, 0x1078, 0x4224, 0x0f7f, 0x007c, + 0x708b, 0x0009, 0x1078, 0x4289, 0x20a3, 0x1105, 0x20a3, 0x0100, + 0x3430, 0x1078, 0x42d4, 0x00c0, 0x3e01, 0x7074, 0xa005, 0x00c0, + 0x3e01, 0x1078, 0x4104, 0x00c0, 0x3e0b, 0xa085, 0x0001, 0x1078, + 0x256a, 0x20a9, 0x0008, 0x2099, 0xac8e, 0x26a0, 0x53a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, + 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3e51, 0x2011, 0x41dc, 0x1078, + 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3e4f, 0x2079, 0xac80, 0x7a30, + 0xa296, 0x1105, 0x00c0, 0x3e4f, 0x7834, 0x2011, 0x0100, 0xa21e, + 0x00c0, 0x3e3a, 0x7a38, 0xd2fc, 0x0040, 0x3e34, 0x70b0, 0xa005, + 0x00c0, 0x3e34, 0x70b3, 0x0001, 0x708b, 0x000a, 0x1078, 0x3e53, + 0x0078, 0x3e51, 0xa005, 0x00c0, 0x3e4f, 0x7a38, 0xd2fc, 0x0040, + 0x3e47, 0x70b0, 0xa005, 0x00c0, 0x3e47, 0x70b3, 0x0001, 0x7087, + 0x0000, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3e51, 0x1078, + 0x4224, 0x0f7f, 0x007c, 0x708b, 0x000b, 0x2011, 0xac0e, 0x22a0, + 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, + 0x0000, 0x41a4, 0x1078, 0x4289, 0x20a3, 0x1106, 0x20a3, 0x0000, + 0x1078, 0x42d4, 0x0040, 0x3e70, 0x2013, 0x0000, 0x0078, 0x3e74, + 0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, + 0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, + 0x0040, 0x3e9d, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084, + 0x00c0, 0x3e9b, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1106, 0x00c0, + 0x3e9b, 0x7834, 0xa005, 0x00c0, 0x3e9b, 0x708b, 0x000c, 0x1078, + 0x3e9f, 0x0078, 0x3e9d, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, + 0x000d, 0x1078, 0x4289, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, + 0xac8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, + 0x0040, 0x3ed9, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084, + 0x00c0, 0x3ed7, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1107, 0x00c0, + 0x3ed7, 0x7834, 0xa005, 0x00c0, 0x3ed7, 0x7087, 0x0001, 0x1078, + 0x427b, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3ed9, 0x1078, + 0x4224, 0x0f7f, 0x007c, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, + 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, + 0x07d0, 0x2011, 0x41dc, 0x1078, 0x5a38, 0x007c, 0x7080, 0xa005, + 0x0040, 0x3ef6, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x007c, 0x708b, + 0x0011, 0x1078, 0x42d4, 0x00c0, 0x3f14, 0x716c, 0x81ff, 0x0040, + 0x3f14, 0x2009, 0x0000, 0x7070, 0xa084, 0x00ff, 0x1078, 0x254d, + 0xa186, 0x007e, 0x0040, 0x3f14, 0xa186, 0x0080, 0x0040, 0x3f14, + 0x2011, 0xac8e, 0x1078, 0x419d, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x2099, 0xac80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, + 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, + 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3f55, + 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3f53, + 0x2079, 0xac80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3f53, 0x7834, + 0xa005, 0x00c0, 0x3f53, 0x7a38, 0xd2fc, 0x0040, 0x3f4d, 0x70b0, + 0xa005, 0x00c0, 0x3f4d, 0x70b3, 0x0001, 0x708b, 0x0012, 0x1078, + 0x3f57, 0x0078, 0x3f55, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, + 0x0013, 0x1078, 0x4295, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, + 0x2011, 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3f75, 0x7074, 0xa005, + 0x00c0, 0x3f75, 0x7150, 0xa186, 0xffff, 0x0040, 0x3f75, 0x1078, + 0x419d, 0x0040, 0x3f75, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3fad, + 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3fab, + 0x2079, 0xac80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3fab, 0x7834, + 0xa005, 0x00c0, 0x3fab, 0x7a38, 0xd2fc, 0x0040, 0x3fa5, 0x70b0, + 0xa005, 0x00c0, 0x3fa5, 0x70b3, 0x0001, 0x708b, 0x0014, 0x1078, + 0x3faf, 0x0078, 0x3fad, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, + 0x0015, 0x1078, 0x4295, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, + 0x2011, 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3fd7, 0x7074, 0xa005, + 0x00c0, 0x3fd7, 0x7154, 0xa186, 0xffff, 0x0040, 0x3fd7, 0xa180, + 0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040, + 0x3fd7, 0x1078, 0x3820, 0x0040, 0x3fd7, 0x1078, 0x256a, 0x20a9, + 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, + 0x0040, 0x402e, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, + 0x00c0, 0x402c, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1105, 0x00c0, + 0x402c, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x400b, 0x7a38, + 0xd2fc, 0x0040, 0x4009, 0x70b0, 0xa005, 0x00c0, 0x4009, 0x70b3, + 0x0001, 0x0078, 0x401a, 0xa005, 0x00c0, 0x402c, 0x7a38, 0xd2fc, + 0x0040, 0x4018, 0x70b0, 0xa005, 0x00c0, 0x4018, 0x70b3, 0x0001, + 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0040, 0x4026, 0x2001, 0xa774, + 0x2004, 0xd0a4, 0x00c0, 0x4026, 0x70cf, 0x0008, 0x708b, 0x0016, + 0x1078, 0x4030, 0x0078, 0x402e, 0x1078, 0x4224, 0x0f7f, 0x007c, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xac80, 0x20a1, 0x020b, + 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xac8e, 0x708b, 0x0017, + 0x1078, 0x42d4, 0x00c0, 0x4050, 0x7074, 0xa005, 0x00c0, 0x4050, + 0x1078, 0x4104, 0x00c0, 0x405a, 0xa085, 0x0001, 0x1078, 0x256a, + 0x20a9, 0x0008, 0x2099, 0xac8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, + 0x7080, 0xa005, 0x0040, 0x407f, 0x2011, 0x41dc, 0x1078, 0x5a45, + 0xa086, 0x0084, 0x00c0, 0x407d, 0x2079, 0xac80, 0x7a30, 0xa296, + 0x1106, 0x00c0, 0x407d, 0x7834, 0xa005, 0x00c0, 0x407d, 0x708b, + 0x0018, 0x1078, 0x4081, 0x0078, 0x407f, 0x1078, 0x4224, 0x0f7f, + 0x007c, 0x708b, 0x0019, 0x1078, 0x4295, 0x20a3, 0x1106, 0x20a3, + 0x0000, 0x3430, 0x2099, 0xac8e, 0x2039, 0xac0e, 0x27a0, 0x20a9, + 0x0040, 0x53a3, 0x1078, 0x42d4, 0x00c0, 0x40b5, 0x2728, 0x2514, + 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, + 0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0xac0e, 0x2414, + 0xa38c, 0x0001, 0x0040, 0x40b0, 0xa294, 0xff00, 0x0078, 0x40b3, + 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, + 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, + 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x40e7, + 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084, 0x00c0, 0x40e5, + 0x2079, 0xac80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x40e5, 0x7834, + 0xa005, 0x00c0, 0x40e5, 0x7087, 0x0001, 0x1078, 0x427b, 0x708b, + 0x001a, 0x1078, 0x40e9, 0x0078, 0x40e7, 0x1078, 0x4224, 0x0f7f, + 0x007c, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0xac80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, + 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, + 0x420b, 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0xa753, + 0x252c, 0x20a9, 0x0008, 0x2041, 0xac0e, 0x28a0, 0x2099, 0xac8e, + 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x411a, + 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, + 0x412c, 0xd5d4, 0x0040, 0x4127, 0x8210, 0x0078, 0x4128, 0x8211, + 0x00f0, 0x411a, 0x0078, 0x4194, 0x82ff, 0x00c0, 0x413e, 0xd5d4, + 0x0040, 0x4138, 0xa1a6, 0x3fff, 0x0040, 0x4124, 0x0078, 0x413c, + 0xa1a6, 0x3fff, 0x0040, 0x4194, 0xa18d, 0xc000, 0x20a9, 0x0010, + 0x2019, 0x0001, 0xd5d4, 0x0040, 0x4147, 0x2019, 0x0010, 0x2120, + 0xd5d4, 0x0040, 0x414e, 0x8423, 0x0078, 0x414f, 0x8424, 0x00c8, + 0x415c, 0xd5d4, 0x0040, 0x4157, 0x8319, 0x0078, 0x4158, 0x8318, + 0x00f0, 0x4148, 0x0078, 0x4194, 0x23a8, 0x2021, 0x0001, 0x8426, + 0x8425, 0x00f0, 0x4160, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, + 0x4174, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, + 0xa5a8, 0x0010, 0x00f0, 0x4170, 0x7552, 0xa5c8, 0x29c0, 0x292c, + 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0000, + 0x7572, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001, 0x26a0, + 0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0xa085, 0x0001, 0x0078, 0x419a, 0xa006, 0x0078, 0x419a, 0xa006, + 0x1078, 0x1332, 0x097f, 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, + 0x2001, 0x0007, 0xa39a, 0x0010, 0x0048, 0x41aa, 0x8420, 0x8001, + 0x0078, 0x41a2, 0x2118, 0x84ff, 0x0040, 0x41b3, 0xa39a, 0x0010, + 0x8421, 0x00c0, 0x41ae, 0x2021, 0x0001, 0x83ff, 0x0040, 0x41bc, + 0x8423, 0x8319, 0x00c0, 0x41b8, 0xa238, 0x2704, 0xa42c, 0x00c0, + 0x41d4, 0xa405, 0x203a, 0x7152, 0xa1a0, 0x29c0, 0x242c, 0xa5ac, + 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0000, 0x7572, + 0x7077, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa700, + 0x707b, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, + 0x1078, 0x5ae6, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x6e0f, + 0x7004, 0xa084, 0x4000, 0x0040, 0x41f1, 0x7003, 0x1000, 0x7003, + 0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0xa722, 0x2073, 0x0000, + 0x7840, 0x027e, 0x017e, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x017f, + 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, + 0x0f7f, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0xa9bb, + 0x2013, 0x0000, 0x7083, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, + 0x0056, 0x60a7, 0x9575, 0x1078, 0x6e06, 0x2009, 0x07d0, 0x2011, + 0x41dc, 0x1078, 0x5add, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, + 0x2091, 0x8000, 0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002, + 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078, + 0x7058, 0x037f, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x2061, 0xa9c4, + 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xa700, 0x6003, 0x0001, + 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x002d, + 0x2011, 0x4259, 0x1078, 0x5a38, 0x127f, 0x0c7f, 0x027f, 0x017f, + 0x007c, 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2001, 0x0001, + 0x1078, 0x5ae6, 0x2071, 0x0100, 0x1078, 0x6e0f, 0x2071, 0x0140, + 0x7004, 0xa084, 0x4000, 0x0040, 0x4271, 0x7003, 0x1000, 0x7003, + 0x0000, 0x2001, 0x0001, 0x1078, 0x24e8, 0x1078, 0x4224, 0x127f, + 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0xadc0, 0x2099, + 0xac8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x4281, + 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xac00, 0x20a1, + 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x2099, 0xac80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, + 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001, 0xa72f, + 0x2004, 0xa005, 0x00c0, 0x42b2, 0x6030, 0xa084, 0x00ff, 0xa105, + 0x0078, 0x42b4, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, + 0x017e, 0x047e, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x42cb, + 0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0xa22d, 0x2001, 0xa70c, + 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x1078, + 0x284f, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0xa70c, 0x2004, + 0xd09c, 0x0040, 0x42db, 0x007f, 0x007c, 0x007e, 0x017e, 0x127e, + 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, + 0x127f, 0x017f, 0x007f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, + 0xa835, 0xa006, 0x200a, 0x8108, 0x00f0, 0x42f2, 0x157f, 0x007c, + 0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0xa752, 0xa006, + 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x29c0, + 0x231c, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, + 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, + 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, + 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, + 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, + 0x61a2, 0x0d7e, 0x60a4, 0xa06d, 0x0040, 0x4338, 0x1078, 0x13a4, + 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0040, 0x4340, 0x1078, 0x13a4, + 0x60ab, 0x0000, 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, + 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, + 0x037f, 0x0d7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x4424, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x00c8, 0x442a, 0x2001, 0xa70c, 0x2004, + 0xa084, 0x0003, 0x0040, 0x4385, 0x2001, 0xa70c, 0x2004, 0xd084, + 0x00c0, 0x4405, 0xa188, 0xa835, 0x2104, 0xa065, 0x0040, 0x4405, + 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x4405, 0x6000, + 0xd0c4, 0x0040, 0x4405, 0x0078, 0x4392, 0xa188, 0xa835, 0x2104, + 0xa065, 0x0040, 0x43e9, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, + 0x00c0, 0x43ef, 0x60a4, 0xa00d, 0x0040, 0x439a, 0x1078, 0x4817, + 0x0040, 0x43e3, 0x60a8, 0xa00d, 0x0040, 0x43b4, 0x1078, 0x486a, + 0x00c0, 0x43b4, 0x694c, 0xd1fc, 0x00c0, 0x43aa, 0x1078, 0x44df, + 0x0078, 0x43de, 0x1078, 0x4484, 0x694c, 0xd1ec, 0x00c0, 0x43de, + 0x1078, 0x46d6, 0x0078, 0x43de, 0x694c, 0xa184, 0xa000, 0x0040, + 0x43ce, 0xd1ec, 0x0040, 0x43c7, 0xd1fc, 0x0040, 0x43c3, 0x1078, + 0x46e7, 0x0078, 0x43ca, 0x1078, 0x46e7, 0x0078, 0x43ce, 0xd1fc, + 0x0040, 0x43ce, 0x1078, 0x4484, 0x0078, 0x43de, 0x6050, 0xa00d, + 0x0040, 0x43d9, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, + 0x43de, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x1078, 0x5da9, + 0xa006, 0x127f, 0x007c, 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, + 0x442e, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x442e, 0xa082, + 0x0006, 0x00c8, 0x4405, 0x60a0, 0xd0bc, 0x00c0, 0x4401, 0x6100, + 0xd1fc, 0x0040, 0x4392, 0x2001, 0x0029, 0x2009, 0x1000, 0x0078, + 0x442e, 0x2001, 0x0028, 0x0078, 0x4420, 0x2009, 0xa70c, 0x210c, + 0xd18c, 0x0040, 0x440f, 0x2001, 0x0004, 0x0078, 0x4420, 0xd184, + 0x0040, 0x4416, 0x2001, 0x0004, 0x0078, 0x4420, 0x2001, 0x0029, + 0x6100, 0xd1fc, 0x0040, 0x4420, 0x2009, 0x1000, 0x0078, 0x442e, + 0x2009, 0x0000, 0x0078, 0x442e, 0x2001, 0x0029, 0x2009, 0x0000, + 0x0078, 0x442e, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x127f, + 0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, + 0x447e, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x00c8, 0x4464, + 0xa188, 0xa835, 0x2104, 0xa065, 0x0040, 0x4464, 0x6004, 0xa084, + 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x446a, 0x684c, 0xd0ec, 0x0040, + 0x4457, 0x1078, 0x46e7, 0x1078, 0x4484, 0x0078, 0x445f, 0x1078, + 0x4484, 0x684c, 0xd0fc, 0x0040, 0x445f, 0x1078, 0x46d6, 0x1078, + 0x472f, 0xa006, 0x0078, 0x4482, 0x2001, 0x0028, 0x2009, 0x0000, + 0x0078, 0x4482, 0xa082, 0x0006, 0x00c8, 0x4478, 0x6100, 0xd1fc, + 0x0040, 0x444d, 0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x4482, + 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x4482, 0x2001, 0x0029, + 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000, 0x6050, + 0xa00d, 0x0040, 0x4492, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, + 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, + 0x4490, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, 0x44af, + 0x0e7e, 0x2071, 0xa9b1, 0x7004, 0xa086, 0x0002, 0x0040, 0x44b6, + 0x0e7f, 0x604c, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, + 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x44ad, 0x701c, 0xac06, + 0x00c0, 0x44a8, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, + 0x0e7f, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, + 0x0040, 0x44d1, 0x6800, 0xa005, 0x00c0, 0x44cf, 0x6052, 0x604e, + 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040, 0x44de, 0x6800, + 0xa005, 0x00c0, 0x44dc, 0x6052, 0x604e, 0xad05, 0x007c, 0x6803, + 0x0000, 0x6084, 0xa00d, 0x0040, 0x44e9, 0x2d00, 0x200a, 0x6086, + 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x44e8, 0x127e, 0x0c7e, + 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0040, + 0x44fc, 0xc285, 0x0078, 0x44fd, 0xc284, 0x6202, 0x027f, 0x0c7f, + 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, + 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4521, 0x609c, 0xd0ac, + 0x0040, 0x4521, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x4521, + 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x00c0, 0x4521, 0x2011, + 0x0600, 0x007f, 0xa294, 0xff00, 0xa215, 0x6206, 0x007e, 0xa086, + 0x0006, 0x00c0, 0x4531, 0x6290, 0x82ff, 0x00c0, 0x4531, 0x1078, + 0x1332, 0x007f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, + 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, + 0x4553, 0x609c, 0xd0a4, 0x0040, 0x4553, 0x2001, 0xa753, 0x2004, + 0xd0ac, 0x00c0, 0x4553, 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, + 0x4553, 0x2011, 0x0006, 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, + 0x6206, 0x0c7f, 0x127f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, + 0x4565, 0xa085, 0x0001, 0x0078, 0x457d, 0xa190, 0xa835, 0x2204, + 0xa065, 0x00c0, 0x457c, 0x017e, 0x0d7e, 0x1078, 0x1370, 0x2d60, + 0x0d7f, 0x017f, 0x0040, 0x4561, 0x2c00, 0x2012, 0x60a7, 0x0000, + 0x60ab, 0x0000, 0x1078, 0x42f8, 0xa006, 0x027f, 0x007c, 0x127e, + 0x2091, 0x8000, 0x027e, 0xa182, 0x00ff, 0x0048, 0x458b, 0xa085, + 0x0001, 0x0078, 0x45c1, 0x0d7e, 0xa190, 0xa835, 0x2204, 0xa06d, + 0x0040, 0x45bf, 0x2013, 0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, + 0xa06d, 0x0040, 0x459d, 0x1078, 0x13a4, 0x60a8, 0xa06d, 0x0040, + 0x45a3, 0x1078, 0x13a4, 0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, + 0x2060, 0x8cff, 0x0040, 0x45bb, 0x600c, 0x007e, 0x6010, 0x2068, + 0x1078, 0x8d16, 0x0040, 0x45b6, 0x1078, 0x13b4, 0x1078, 0x772d, + 0x0c7f, 0x0078, 0x45a9, 0x0c7f, 0x0d7f, 0x1078, 0x13a4, 0x0d7f, + 0xa006, 0x027f, 0x127f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, + 0x45cd, 0xa085, 0x0001, 0x0078, 0x45d4, 0xa188, 0xa835, 0x2104, + 0xa065, 0x0040, 0x45c9, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, + 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, + 0x6002, 0x2069, 0xac8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, + 0xa10a, 0x0048, 0x45ec, 0x603a, 0x6814, 0x6066, 0x2099, 0xac96, + 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xac9a, + 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xacae, + 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, + 0x60a0, 0xa086, 0x007e, 0x00c0, 0x4611, 0x2069, 0xac8e, 0x690c, + 0x616e, 0xa182, 0x0211, 0x00c8, 0x4619, 0x2009, 0x0008, 0x0078, + 0x4643, 0xa182, 0x0259, 0x00c8, 0x4621, 0x2009, 0x0007, 0x0078, + 0x4643, 0xa182, 0x02c1, 0x00c8, 0x4629, 0x2009, 0x0006, 0x0078, + 0x4643, 0xa182, 0x0349, 0x00c8, 0x4631, 0x2009, 0x0005, 0x0078, + 0x4643, 0xa182, 0x0421, 0x00c8, 0x4639, 0x2009, 0x0004, 0x0078, + 0x4643, 0xa182, 0x0581, 0x00c8, 0x4641, 0x2009, 0x0003, 0x0078, + 0x4643, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f, + 0x007c, 0x017e, 0x027e, 0x0e7e, 0x2071, 0xac8d, 0x2e04, 0x6896, + 0x2071, 0xac8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00, 0x2009, + 0xa772, 0x210c, 0xd0bc, 0x0040, 0x4663, 0xd1ec, 0x0040, 0x4663, + 0xc2ad, 0x0078, 0x4664, 0xc2ac, 0xd0c4, 0x0040, 0x466d, 0xd1e4, + 0x0040, 0x466d, 0xc2bd, 0x0078, 0x466e, 0xc2bc, 0x6a02, 0x0e7f, + 0x027f, 0x017f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, + 0xa06d, 0x0040, 0x4697, 0x6900, 0x81ff, 0x00c0, 0x46ab, 0x6a04, + 0xa282, 0x0010, 0x00c8, 0x46b0, 0xad88, 0x0004, 0x20a9, 0x0010, + 0x2104, 0xa086, 0xffff, 0x0040, 0x4692, 0x8108, 0x00f0, 0x4688, + 0x1078, 0x1332, 0x260a, 0x8210, 0x6a06, 0x0078, 0x46ab, 0x1078, + 0x138b, 0x0040, 0x46b0, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, + 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x46a3, + 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, + 0xa006, 0x0078, 0x46ad, 0x127e, 0x2091, 0x8000, 0x0d7e, 0x60a4, + 0xa00d, 0x0040, 0x46d3, 0x2168, 0x6800, 0xa005, 0x00c0, 0x46cf, + 0x1078, 0x4817, 0x00c0, 0x46d3, 0x200b, 0xffff, 0x6804, 0xa08a, + 0x0002, 0x0048, 0x46cf, 0x8001, 0x6806, 0x0078, 0x46d3, 0x1078, + 0x13a4, 0x60a7, 0x0000, 0x0d7f, 0x127f, 0x007c, 0x127e, 0x2091, + 0x8000, 0x1078, 0x487f, 0x0078, 0x46df, 0x1078, 0x4484, 0x1078, + 0x4775, 0x00c0, 0x46dd, 0x1078, 0x472f, 0x127f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a8, 0xa06d, 0x0040, 0x470b, 0x6950, + 0x81ff, 0x00c0, 0x471f, 0x6a54, 0xa282, 0x0010, 0x00c8, 0x472c, + 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, + 0x4706, 0x8108, 0x00f0, 0x46fc, 0x1078, 0x1332, 0x260a, 0x8210, + 0x6a56, 0x0078, 0x471f, 0x1078, 0x138b, 0x0040, 0x472c, 0x2d00, + 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, + 0xffff, 0x8108, 0x00f0, 0x4717, 0x6857, 0x0001, 0x6e62, 0x0078, + 0x4723, 0x1078, 0x44df, 0x1078, 0x4739, 0x00c0, 0x4721, 0xa085, + 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x4729, 0x127e, + 0x2091, 0x8000, 0x1078, 0x5da9, 0x127f, 0x007c, 0xa01e, 0x0078, + 0x473b, 0x2019, 0x0001, 0xa00e, 0x127e, 0x2091, 0x8000, 0x604c, + 0x2068, 0x6000, 0xd0dc, 0x00c0, 0x4759, 0x8dff, 0x0040, 0x4770, + 0x83ff, 0x0040, 0x4751, 0x6848, 0xa606, 0x0040, 0x475e, 0x0078, + 0x4759, 0x683c, 0xa406, 0x00c0, 0x4759, 0x6840, 0xa506, 0x0040, + 0x475e, 0x2d08, 0x6800, 0x2068, 0x0078, 0x4745, 0x1078, 0x7233, + 0x6a00, 0x604c, 0xad06, 0x00c0, 0x4768, 0x624e, 0x0078, 0x476b, + 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x4770, 0x6152, 0x8dff, + 0x127f, 0x007c, 0xa01e, 0x0078, 0x4777, 0x2019, 0x0001, 0xa00e, + 0x6080, 0x2068, 0x8dff, 0x0040, 0x47a3, 0x83ff, 0x0040, 0x4786, + 0x6848, 0xa606, 0x0040, 0x4793, 0x0078, 0x478e, 0x683c, 0xa406, + 0x00c0, 0x478e, 0x6840, 0xa506, 0x0040, 0x4793, 0x2d08, 0x6800, + 0x2068, 0x0078, 0x477a, 0x6a00, 0x6080, 0xad06, 0x00c0, 0x479b, + 0x6282, 0x0078, 0x479e, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, + 0x47a3, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078, 0x4810, 0x00c0, + 0x47ab, 0x2011, 0x0001, 0x1078, 0x4863, 0x00c0, 0x47b1, 0xa295, + 0x0002, 0x007c, 0x1078, 0x489b, 0x0040, 0x47ba, 0x1078, 0x8dda, + 0x0078, 0x47bc, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040, + 0x47c5, 0x1078, 0x8d72, 0x0078, 0x47c7, 0xa085, 0x0001, 0x007c, + 0x1078, 0x489b, 0x0040, 0x47d0, 0x1078, 0x8dbc, 0x0078, 0x47d2, + 0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040, 0x47db, 0x1078, + 0x8d8e, 0x0078, 0x47dd, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b, + 0x0040, 0x47e6, 0x1078, 0x8df8, 0x0078, 0x47e8, 0xa085, 0x0001, + 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, + 0x0040, 0x4808, 0x6800, 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x8f8d, 0x007e, 0x6000, 0xd0fc, 0x0040, 0x4802, + 0x1078, 0xa4fd, 0x007f, 0x1078, 0x4a73, 0x007f, 0x0078, 0x47ef, + 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c, + 0x60a4, 0xa00d, 0x00c0, 0x4817, 0xa085, 0x0001, 0x007c, 0x0e7e, + 0x2170, 0x7000, 0xa005, 0x00c0, 0x482c, 0x20a9, 0x0010, 0xae88, + 0x0004, 0x2104, 0xa606, 0x0040, 0x482c, 0x8108, 0x00f0, 0x4821, + 0xa085, 0x0001, 0x0078, 0x482d, 0xa006, 0x0e7f, 0x007c, 0x0d7e, + 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x483d, 0x1078, + 0x138b, 0x0040, 0x484f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807, + 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, + 0x00f0, 0x4845, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, + 0x0078, 0x484c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, + 0x0040, 0x4860, 0x60a7, 0x0000, 0x1078, 0x13a4, 0xa085, 0x0001, + 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x486a, 0xa085, + 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x487d, + 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x487d, + 0x8108, 0x00f0, 0x4874, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e, + 0x2091, 0x8000, 0x1078, 0x4863, 0x00c0, 0x4899, 0x200b, 0xffff, + 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x4894, + 0x8001, 0x6856, 0x0078, 0x4898, 0x1078, 0x13a4, 0x60ab, 0x0000, + 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71b0, + 0x81ff, 0x00c0, 0x48b9, 0x71cc, 0xd19c, 0x0040, 0x48b9, 0x2001, + 0x007e, 0xa080, 0xa835, 0x2004, 0xa07d, 0x0040, 0x48b9, 0x7804, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x48b9, 0x7800, 0xc0ed, + 0x7802, 0x2079, 0xa752, 0x7804, 0xd0a4, 0x0040, 0x48df, 0x157e, + 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4, + 0x00c0, 0x48d9, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, + 0x0040, 0x48d6, 0xa086, 0x0006, 0x00c0, 0x48d9, 0x6000, 0xc0ed, + 0x6002, 0x017f, 0x8108, 0x00f0, 0x48c5, 0x0c7f, 0x157f, 0x1078, + 0x4967, 0x0040, 0x48e8, 0x2001, 0xa9a1, 0x200c, 0x0078, 0x48f0, + 0x2079, 0xa752, 0x7804, 0xd0a4, 0x0040, 0x48f4, 0x2009, 0x07d0, + 0x2011, 0x48f6, 0x1078, 0x5add, 0x0f7f, 0x007c, 0x2011, 0x48f6, + 0x1078, 0x5a45, 0x1078, 0x4967, 0x0040, 0x491e, 0x2001, 0xa8b3, + 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa753, + 0x2004, 0xd0a4, 0x0040, 0x4912, 0x2009, 0x07d0, 0x2011, 0x48f6, + 0x1078, 0x5add, 0x0e7e, 0x2071, 0xa700, 0x706f, 0x0000, 0x7073, + 0x0000, 0x1078, 0x2677, 0x0e7f, 0x0078, 0x4956, 0x157e, 0x0c7e, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0, + 0x4950, 0x6000, 0xd0ec, 0x0040, 0x4950, 0x047e, 0x62a0, 0xa294, + 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0xa22d, 0x6000, + 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, + 0x6006, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, + 0x1078, 0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x047f, + 0x017f, 0x8108, 0x00f0, 0x4924, 0x0c7f, 0x157f, 0x007c, 0x0c7e, + 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818, + 0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e, + 0x2001, 0xa8b3, 0x2004, 0xa07d, 0x0040, 0x4970, 0x7800, 0xd0ec, + 0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x007e, 0x62a0, + 0xa290, 0xa835, 0x2204, 0xac06, 0x10c0, 0x1332, 0x007f, 0x6200, + 0xa005, 0x0040, 0x4986, 0xc2fd, 0x0078, 0x4987, 0xc2fc, 0x6202, + 0x027f, 0x127f, 0x007c, 0x2011, 0xa733, 0x2204, 0xd0cc, 0x0040, + 0x4998, 0x2001, 0xa99f, 0x200c, 0x2011, 0x4999, 0x1078, 0x5add, + 0x007c, 0x2011, 0x4999, 0x1078, 0x5a45, 0x2011, 0xa733, 0x2204, + 0xc0cc, 0x2012, 0x007c, 0x2071, 0xa814, 0x7003, 0x0001, 0x7007, + 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, + 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, + 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa97d, 0x7003, + 0xa814, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa95d, 0x7013, + 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, + 0x2071, 0xa935, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, + 0xa753, 0x2004, 0xd0fc, 0x00c0, 0x49e8, 0x2001, 0xa753, 0x2004, + 0xa00e, 0xd09c, 0x0040, 0x49e5, 0x8108, 0x7102, 0x0078, 0x4a3b, + 0x2001, 0xa772, 0x200c, 0xa184, 0x000f, 0x2009, 0xa773, 0x210c, + 0x0079, 0x49f2, 0x49dd, 0x4a13, 0x4a1b, 0x4a26, 0x4a2c, 0x49dd, + 0x49dd, 0x49dd, 0x4a02, 0x49dd, 0x49dd, 0x49dd, 0x49dd, 0x49dd, + 0x49dd, 0x49dd, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, + 0xa776, 0x20a1, 0xa986, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, + 0x137f, 0x0078, 0x4a3b, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, + 0x0002, 0x0078, 0x4a21, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, + 0x0003, 0x7002, 0x7097, 0x0001, 0x0078, 0x4a38, 0x7007, 0x0122, + 0x2001, 0x0002, 0x0078, 0x4a30, 0x7007, 0x0121, 0x2001, 0x0003, + 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, + 0xa184, 0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, + 0xa814, 0x684c, 0xa005, 0x00c0, 0x4a4c, 0x7028, 0xc085, 0x702a, + 0xa085, 0x0001, 0x0078, 0x4a71, 0x6a60, 0x7236, 0x6b64, 0x733a, + 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, + 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, + 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, + 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, + 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0, + 0x4ac9, 0x6804, 0xa00d, 0x0040, 0x4a8f, 0x0d7e, 0x2071, 0xa700, + 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, + 0x00c0, 0x4a82, 0x702e, 0x70ac, 0xa200, 0x70ae, 0x0d7f, 0x2071, + 0xa814, 0x701c, 0xa005, 0x00c0, 0x4adb, 0x0068, 0x4ad9, 0x2071, + 0xa935, 0x7200, 0x82ff, 0x0040, 0x4ad9, 0x6934, 0xa186, 0x0103, + 0x00c0, 0x4aec, 0x6948, 0x6844, 0xa105, 0x00c0, 0x4acc, 0x2009, + 0x8020, 0x2200, 0x0079, 0x4aac, 0x4ad9, 0x4ab1, 0x4b09, 0x4b17, + 0x4ad9, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ad9, 0x7122, + 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, + 0x2071, 0xa700, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, + 0x70ae, 0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, + 0x4ad9, 0x6868, 0xa005, 0x00c0, 0x4ad9, 0x2009, 0x8020, 0x0078, + 0x4aa9, 0x2071, 0xa814, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, + 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x4ae9, 0x6902, 0x0078, + 0x4aea, 0x711e, 0x0078, 0x4ac9, 0xa18c, 0x00ff, 0xa186, 0x0017, + 0x0040, 0x4afa, 0xa186, 0x001e, 0x0040, 0x4afa, 0xa18e, 0x001f, + 0x00c0, 0x4ad9, 0x684c, 0xd0cc, 0x0040, 0x4ad9, 0x6850, 0xa084, + 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4ad9, 0x2009, 0x8021, 0x0078, + 0x4aa9, 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4ad9, 0x7186, + 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4b27, 0x7084, + 0x8008, 0xa092, 0x000f, 0x00c8, 0x4ad9, 0x7186, 0xae90, 0x0003, + 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, + 0xa10a, 0x0048, 0x4ac0, 0x718c, 0x7084, 0xa10a, 0x0048, 0x4ac0, + 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ac0, 0x2071, 0xa935, + 0x7000, 0xa086, 0x0002, 0x00c0, 0x4b47, 0x1078, 0x4dc3, 0x2071, + 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4ac0, 0x1078, + 0x4dee, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, + 0x4ac0, 0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, + 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, + 0x00ff, 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa814, + 0x7004, 0x0079, 0x4b6b, 0x4b75, 0x4b86, 0x4d94, 0x4d95, 0x4dbc, + 0x4dc2, 0x4b76, 0x4d82, 0x4d23, 0x4da5, 0x007c, 0x127e, 0x2091, + 0x8000, 0x0068, 0x4b85, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, + 0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa9c4, + 0x6844, 0xa005, 0x0050, 0x4bae, 0x00c0, 0x4bae, 0x127e, 0x2091, + 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xa820, 0x2004, 0xa10a, + 0x0040, 0x4ba9, 0x0068, 0x4bad, 0x2069, 0x0000, 0x6818, 0xd084, + 0x00c0, 0x4bad, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, + 0x4080, 0x2069, 0xa9c4, 0x6847, 0xffff, 0x127f, 0x2069, 0xa700, + 0x6848, 0x6964, 0xa102, 0x2069, 0xa935, 0x688a, 0x6984, 0x701c, + 0xa06d, 0x0040, 0x4bc0, 0x81ff, 0x0040, 0x4c08, 0x0078, 0x4bd6, + 0x81ff, 0x0040, 0x4cda, 0x2071, 0xa935, 0x7184, 0x7088, 0xa10a, + 0x00c8, 0x4bd6, 0x7190, 0x2071, 0xa9c4, 0x7040, 0xa005, 0x0040, + 0x4bd6, 0x00d0, 0x4cda, 0x7142, 0x0078, 0x4cda, 0x2071, 0xa935, + 0x718c, 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4cf7, + 0x0068, 0x4c8c, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4c8c, + 0x2001, 0xffff, 0x2071, 0xa9c4, 0x7042, 0x2071, 0xa935, 0x7000, + 0xa086, 0x0002, 0x00c0, 0x4bfe, 0x1078, 0x4dc3, 0x2071, 0x0000, + 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c, 0x1078, 0x4dee, + 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c, + 0x2071, 0xa935, 0x7000, 0xa005, 0x0040, 0x4cb9, 0x6934, 0xa186, + 0x0103, 0x00c0, 0x4c8f, 0x684c, 0xd0bc, 0x00c0, 0x4cb9, 0x6948, + 0x6844, 0xa105, 0x00c0, 0x4cac, 0x2009, 0x8020, 0x2071, 0xa935, + 0x7000, 0x0079, 0x4c23, 0x4cb9, 0x4c71, 0x4c49, 0x4c5b, 0x4c28, + 0x137e, 0x147e, 0x157e, 0x2099, 0xa776, 0x20a1, 0xa986, 0x20a9, + 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa97d, 0xad80, + 0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, + 0x2e10, 0x1078, 0x13db, 0x2071, 0xa814, 0x7007, 0x0009, 0x0078, + 0x4cda, 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4cda, 0xae90, + 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa814, 0x1078, + 0x4e4c, 0x0078, 0x4cda, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, + 0x4cda, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, + 0x6840, 0x2012, 0x7186, 0x2071, 0xa814, 0x1078, 0x4e4c, 0x0078, + 0x4cda, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8c, 0x2071, 0x0000, + 0x7018, 0xd084, 0x00c0, 0x4c8c, 0x7122, 0x683c, 0x7026, 0x6840, + 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa814, + 0x1078, 0x4e4c, 0x0078, 0x4cda, 0x127f, 0x0078, 0x4cda, 0xa18c, + 0x00ff, 0xa186, 0x0017, 0x0040, 0x4c9d, 0xa186, 0x001e, 0x0040, + 0x4c9d, 0xa18e, 0x001f, 0x00c0, 0x4cb9, 0x684c, 0xd0cc, 0x0040, + 0x4cb9, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4cb9, + 0x2009, 0x8021, 0x0078, 0x4c1e, 0x6844, 0xa086, 0x0100, 0x00c0, + 0x4cb9, 0x6868, 0xa005, 0x00c0, 0x4cb9, 0x2009, 0x8020, 0x0078, + 0x4c1e, 0x2071, 0xa814, 0x1078, 0x4e60, 0x0040, 0x4cda, 0x2071, + 0xa814, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, + 0x00c0, 0x4cd1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4cd1, + 0x710e, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086, 0x0100, + 0x0040, 0x4d95, 0x127e, 0x2091, 0x8000, 0x2071, 0xa814, 0x7008, + 0xa086, 0x0001, 0x00c0, 0x4cf5, 0x0068, 0x4cf5, 0x2009, 0x000d, + 0x7030, 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, + 0x0006, 0x00c0, 0x4cf5, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, + 0xa814, 0x1078, 0x4e60, 0x0040, 0x4d20, 0x2071, 0xa935, 0x7084, + 0x700a, 0x20a9, 0x0020, 0x2099, 0xa936, 0x20a1, 0xa95d, 0x53a3, + 0x7087, 0x0000, 0x2071, 0xa814, 0x2069, 0xa97d, 0x706c, 0x6826, + 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, + 0x13db, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa9c4, 0x7042, + 0x127f, 0x0078, 0x4cda, 0x2069, 0xa97d, 0x6808, 0xa08e, 0x0000, + 0x0040, 0x4d81, 0xa08e, 0x0200, 0x0040, 0x4d7f, 0xa08e, 0x0100, + 0x00c0, 0x4d81, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d7c, 0x2069, + 0x0000, 0x6818, 0xd084, 0x00c0, 0x4d7c, 0x702c, 0x7130, 0x8108, + 0xa102, 0x0048, 0x4d4a, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, + 0x0078, 0x4d54, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d54, + 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, + 0x2001, 0xa95a, 0x2004, 0xa005, 0x00c0, 0x4d73, 0x6934, 0x2069, + 0xa935, 0x689c, 0x699e, 0x2069, 0xa9c4, 0xa102, 0x00c0, 0x4d6c, + 0x6844, 0xa005, 0x00d0, 0x4d7a, 0x2001, 0xa95b, 0x200c, 0x810d, + 0x6946, 0x0078, 0x4d7a, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, + 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4d81, 0x7007, + 0x0005, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d93, 0x1078, 0x4e60, + 0x0040, 0x4d93, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086, + 0x0100, 0x0040, 0x4d95, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, + 0x00c0, 0x4d9e, 0x7007, 0x0004, 0x0078, 0x4dbc, 0xa086, 0x0200, + 0x00c0, 0x4da4, 0x7007, 0x0005, 0x007c, 0x2001, 0xa97f, 0x2004, + 0xa08e, 0x0100, 0x00c0, 0x4db1, 0x7007, 0x0001, 0x1078, 0x4e4c, + 0x007c, 0xa08e, 0x0000, 0x0040, 0x4db0, 0xa08e, 0x0200, 0x00c0, + 0x4db0, 0x7007, 0x0005, 0x007c, 0x1078, 0x4e16, 0x7006, 0x1078, + 0x4e4c, 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa935, 0x7184, + 0x81ff, 0x0040, 0x4deb, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, + 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4de8, 0x2014, + 0x722a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x722e, 0x8000, 0x0070, + 0x4de8, 0x2014, 0x723a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x723e, + 0xa180, 0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, + 0x2071, 0xa935, 0x7184, 0x81ff, 0x0040, 0x4e13, 0xa006, 0x7086, + 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, + 0x2014, 0x722a, 0x8000, 0x0070, 0x4e0c, 0x2014, 0x723a, 0x8000, + 0x2014, 0x723e, 0x0078, 0x4e10, 0x2001, 0x8020, 0x0078, 0x4e12, + 0x2001, 0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, + 0x8108, 0xa102, 0x0048, 0x4e23, 0xa00e, 0x7034, 0x706e, 0x7038, + 0x7072, 0x0078, 0x4e2d, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, + 0x4e2d, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, + 0x700e, 0x00c0, 0x4e43, 0x127e, 0x2091, 0x8000, 0x0068, 0x4e46, + 0x2001, 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, + 0x0000, 0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, + 0x700b, 0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4e5f, + 0x127e, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, + 0xa005, 0x00c0, 0x4e5c, 0x701a, 0x127f, 0x1078, 0x13a4, 0x007c, + 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4e6f, 0x2304, + 0x230c, 0xa10e, 0x0040, 0x4e6f, 0xa006, 0x0078, 0x4e7f, 0x732c, + 0x8319, 0x7130, 0xa102, 0x00c0, 0x4e79, 0x2300, 0xa005, 0x0078, + 0x4e7f, 0x0048, 0x4e7e, 0xa302, 0x0078, 0x4e7f, 0x8002, 0x007c, + 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, + 0x2091, 0x8000, 0x2009, 0xa9d6, 0x2104, 0xc08d, 0x200a, 0x127f, + 0x1078, 0x13f9, 0x007c, 0x2071, 0xa7e2, 0x7003, 0x0000, 0x7007, + 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, + 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, + 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, + 0xa7e2, 0x6848, 0xa005, 0x00c0, 0x4ebc, 0x7028, 0xc085, 0x702a, + 0xa085, 0x0001, 0x0078, 0x4ee1, 0x6a50, 0x7236, 0x6b54, 0x733a, + 0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, + 0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, + 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, + 0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, + 0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa7e2, 0x7004, 0x1079, + 0x4f41, 0x700c, 0x0079, 0x4eec, 0x4ef1, 0x4ee6, 0x4ee6, 0x4ee6, + 0x4ee6, 0x007c, 0x700c, 0x0079, 0x4ef5, 0x4efa, 0x4f3f, 0x4f3f, + 0x4f40, 0x4f40, 0x7830, 0x7930, 0xa106, 0x0040, 0x4f04, 0x7830, + 0x7930, 0xa106, 0x00c0, 0x4f2a, 0x7030, 0xa10a, 0x0040, 0x4f2a, + 0x00c8, 0x4f0c, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4f2b, + 0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00, 0x705a, 0x7063, 0x0040, + 0x2001, 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, + 0x2009, 0xa9d6, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, + 0x1078, 0x13f9, 0x007c, 0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00, + 0x705a, 0x1078, 0x1370, 0x00c0, 0x4f37, 0x0078, 0x4f16, 0x2d00, + 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4f1a, 0x007c, + 0x007c, 0x4f52, 0x4f53, 0x4f8a, 0x4f8b, 0x4f3f, 0x4fc1, 0x4fc6, + 0x4ffd, 0x4ffe, 0x5019, 0x501a, 0x501b, 0x501c, 0x501d, 0x501e, + 0x509e, 0x50c8, 0x007c, 0x700c, 0x0079, 0x4f56, 0x4f5b, 0x4f5e, + 0x4f6e, 0x4f89, 0x4f89, 0x1078, 0x4ef2, 0x007c, 0x127e, 0x8001, + 0x700e, 0x7058, 0x007e, 0x1078, 0x5464, 0x0040, 0x4f6b, 0x2091, + 0x8000, 0x1078, 0x4ef2, 0x0d7f, 0x0078, 0x4f77, 0x127e, 0x8001, + 0x700e, 0x1078, 0x5464, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, + 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, + 0x00c8, 0x4f86, 0x1079, 0x4fa1, 0x127f, 0x007c, 0x127f, 0x1078, + 0x501f, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa7e2, 0x700c, + 0x0079, 0x4f92, 0x4f97, 0x4f97, 0x4f97, 0x4f99, 0x4f9d, 0x0e7f, + 0x007c, 0x700f, 0x0001, 0x0078, 0x4f9f, 0x700f, 0x0002, 0x0e7f, + 0x007c, 0x501f, 0x501f, 0x503b, 0x501f, 0x5171, 0x501f, 0x501f, + 0x501f, 0x501f, 0x501f, 0x503b, 0x51bb, 0x5208, 0x5261, 0x5277, + 0x501f, 0x501f, 0x5057, 0x503b, 0x501f, 0x501f, 0x5078, 0x5338, + 0x5356, 0x501f, 0x5057, 0x501f, 0x501f, 0x501f, 0x501f, 0x506d, + 0x5356, 0x7020, 0x2068, 0x1078, 0x13a4, 0x007c, 0x700c, 0x0079, + 0x4fc9, 0x4fce, 0x4fd1, 0x4fe1, 0x4ffc, 0x4ffc, 0x1078, 0x4ef2, + 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5464, + 0x0040, 0x4fde, 0x2091, 0x8000, 0x1078, 0x4ef2, 0x0d7f, 0x0078, + 0x4fea, 0x127e, 0x8001, 0x700e, 0x1078, 0x5464, 0x7058, 0x2068, + 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, + 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x4ff9, 0x1079, 0x4fff, 0x127f, + 0x007c, 0x127f, 0x1078, 0x501f, 0x007c, 0x007c, 0x007c, 0x501f, + 0x503b, 0x515b, 0x501f, 0x503b, 0x501f, 0x503b, 0x503b, 0x501f, + 0x503b, 0x515b, 0x503b, 0x503b, 0x503b, 0x503b, 0x503b, 0x501f, + 0x503b, 0x515b, 0x501f, 0x501f, 0x503b, 0x501f, 0x501f, 0x501f, + 0x503b, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, + 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, + 0x8000, 0x1078, 0x4a73, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, + 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, + 0x4a73, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, + 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4a73, 0x127f, + 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, + 0x127e, 0x2091, 0x8000, 0x1078, 0x4a73, 0x127f, 0x007c, 0x6834, + 0x8007, 0xa084, 0x00ff, 0x0040, 0x502d, 0x8001, 0x00c0, 0x5064, + 0x7007, 0x0001, 0x0078, 0x513a, 0x7007, 0x0006, 0x7012, 0x2d00, + 0x7016, 0x701a, 0x704b, 0x513a, 0x007c, 0x684c, 0xa084, 0x00c0, + 0xa086, 0x00c0, 0x00c0, 0x5078, 0x7007, 0x0001, 0x0078, 0x5373, + 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, + 0x20a1, 0xa80d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, + 0x5049, 0x6884, 0xa08a, 0x0002, 0x00c8, 0x5049, 0x82ff, 0x00c0, + 0x509a, 0x6888, 0x698c, 0xa105, 0x0040, 0x509a, 0x2001, 0x510a, + 0x0078, 0x509d, 0xa280, 0x5100, 0x2004, 0x70c6, 0x7010, 0xa015, + 0x0040, 0x50e8, 0x1078, 0x1370, 0x00c0, 0x50a9, 0x7007, 0x000f, + 0x007c, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, + 0xad00, 0x7096, 0x6008, 0xa20a, 0x00c8, 0x50b8, 0xa00e, 0x2200, + 0x7112, 0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x50c1, + 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13db, + 0x7090, 0xa08e, 0x0100, 0x0040, 0x50dc, 0xa086, 0x0200, 0x0040, + 0x50d4, 0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x13a4, + 0x7014, 0x2068, 0x0078, 0x5049, 0x7020, 0x2068, 0x7018, 0x6802, + 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x509e, + 0x7014, 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x50f7, + 0x6888, 0x698c, 0xa105, 0x0040, 0x50f7, 0x1078, 0x510e, 0x6834, + 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, 0x5373, 0x0078, 0x513a, + 0x5102, 0x5106, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, + 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, + 0x0c7e, 0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, + 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, + 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, + 0x0040, 0x5130, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x511d, + 0x6004, 0xa065, 0x00c0, 0x5117, 0x067f, 0x077f, 0x0c7f, 0x0e7f, + 0x0f7f, 0x007c, 0x2009, 0xa72f, 0x210c, 0x81ff, 0x00c0, 0x5155, + 0x6838, 0xa084, 0x00ff, 0x683a, 0x1078, 0x4353, 0x00c0, 0x5149, + 0x007c, 0x1078, 0x4b51, 0x127e, 0x2091, 0x8000, 0x1078, 0x8f8d, + 0x1078, 0x4a73, 0x127f, 0x0078, 0x5148, 0x2001, 0x0028, 0x2009, + 0x0000, 0x0078, 0x5149, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, + 0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x516a, 0x7007, 0x0006, + 0x0078, 0x5170, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, + 0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, + 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x519a, + 0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x519a, + 0xa005, 0x00c0, 0x51ad, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, + 0x45c4, 0x00c0, 0x51ad, 0x067e, 0x6e50, 0x1078, 0x46b3, 0x067f, + 0x0078, 0x51ad, 0x047e, 0x2011, 0xa70c, 0x2224, 0xc484, 0xc48c, + 0x2412, 0x047f, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x51a9, 0x1078, + 0x4852, 0x8108, 0x00f0, 0x51a3, 0x0c7f, 0x684c, 0xd084, 0x00c0, + 0x51b4, 0x1078, 0x13a4, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, + 0x4a73, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, + 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x51ff, 0x2061, 0xaa33, + 0x6100, 0xd184, 0x0040, 0x51df, 0x6858, 0xa084, 0x00ff, 0x00c0, + 0x5202, 0x6000, 0xd084, 0x0040, 0x51ff, 0x6004, 0xa005, 0x00c0, + 0x5205, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x51fc, 0x2011, + 0x0001, 0x6860, 0xa005, 0x00c0, 0x51e7, 0x2001, 0x001e, 0x8000, + 0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x51ff, 0x6006, 0x6858, + 0x8007, 0xa084, 0x00ff, 0x0040, 0x51ff, 0x600a, 0x6858, 0x8000, + 0x00c0, 0x51fb, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5453, 0x127f, + 0x0078, 0x544b, 0x127f, 0x0078, 0x5443, 0x127f, 0x0078, 0x5447, + 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa753, 0x2004, + 0xd0a4, 0x0040, 0x525e, 0x2061, 0xaa33, 0x6000, 0xd084, 0x0040, + 0x525e, 0x6204, 0x6308, 0xd08c, 0x00c0, 0x5250, 0x6c48, 0xa484, + 0x0003, 0x0040, 0x5236, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, + 0x522f, 0x2100, 0xa210, 0x0048, 0x525b, 0x0078, 0x5236, 0x8001, + 0x00c0, 0x525b, 0x2100, 0xa212, 0x0048, 0x525b, 0xa484, 0x000c, + 0x0040, 0x5250, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, + 0x00c0, 0x5248, 0x2100, 0xa318, 0x0048, 0x525b, 0x0078, 0x5250, + 0xa082, 0x0004, 0x00c0, 0x525b, 0x2100, 0xa31a, 0x0048, 0x525b, + 0x6860, 0xa005, 0x0040, 0x5256, 0x8000, 0x6016, 0x6206, 0x630a, + 0x127f, 0x0078, 0x5453, 0x127f, 0x0078, 0x544f, 0x127f, 0x0078, + 0x544b, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xaa33, + 0x6300, 0xd38c, 0x00c0, 0x5271, 0x6308, 0x8318, 0x0048, 0x5274, + 0x630a, 0x127f, 0x0078, 0x5461, 0x127f, 0x0078, 0x544f, 0x127e, + 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, + 0x528b, 0x0c7e, 0x2061, 0xaa33, 0x6000, 0xa084, 0xfcff, 0x6002, + 0x0c7f, 0x0078, 0x52ba, 0x6858, 0xa005, 0x0040, 0x52d1, 0x685c, + 0xa065, 0x0040, 0x52cd, 0x2001, 0xa72f, 0x2004, 0xa005, 0x0040, + 0x529d, 0x1078, 0x8ed6, 0x0078, 0x52ab, 0x6013, 0x0400, 0x6037, + 0x0000, 0x694c, 0xd1a4, 0x0040, 0x52a7, 0x6950, 0x6136, 0x2009, + 0x0041, 0x1078, 0x775c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, + 0x00c0, 0x52ba, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, + 0x5bf1, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x52c9, 0x2061, 0xaa33, + 0x6000, 0xd08c, 0x00c0, 0x52c9, 0x6008, 0x8000, 0x0048, 0x52cd, + 0x600a, 0x0c7f, 0x127f, 0x0078, 0x5453, 0x0c7f, 0x127f, 0x0078, + 0x544b, 0x6954, 0xa186, 0x0045, 0x0040, 0x5306, 0xa186, 0x002a, + 0x00c0, 0x52e1, 0x2001, 0xa70c, 0x200c, 0xc194, 0x2102, 0x0078, + 0x52ba, 0xa186, 0x0020, 0x0040, 0x52fa, 0xa186, 0x0029, 0x0040, + 0x52ed, 0xa186, 0x002d, 0x00c0, 0x52cd, 0x6944, 0xa18c, 0xff00, + 0x810f, 0x1078, 0x45c4, 0x00c0, 0x52ba, 0x6000, 0xc0e4, 0x6002, + 0x0078, 0x52ba, 0x685c, 0xa065, 0x0040, 0x52cd, 0x6007, 0x0024, + 0x2001, 0xa9a3, 0x2004, 0x6016, 0x0078, 0x52ba, 0x685c, 0xa065, + 0x0040, 0x52cd, 0x0e7e, 0x6860, 0xa075, 0x2001, 0xa72f, 0x2004, + 0xa005, 0x0040, 0x531e, 0x1078, 0x8ed6, 0x8eff, 0x0040, 0x531b, + 0x2e60, 0x1078, 0x8ed6, 0x0e7f, 0x0078, 0x52ba, 0x6024, 0xc0dc, + 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0040, + 0x532f, 0x6007, 0x003b, 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, + 0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x0078, 0x52ba, + 0x2061, 0xaa33, 0x6000, 0xd084, 0x0040, 0x5352, 0xd08c, 0x00c0, + 0x5461, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048, 0x534c, 0x6206, + 0x2091, 0x8001, 0x0078, 0x5461, 0x2091, 0x8001, 0x6853, 0x0016, + 0x0078, 0x545a, 0x6853, 0x0007, 0x0078, 0x545a, 0x6834, 0x8007, + 0xa084, 0x00ff, 0x00c0, 0x5360, 0x1078, 0x502d, 0x0078, 0x5372, + 0x2030, 0x8001, 0x00c0, 0x536a, 0x7007, 0x0001, 0x1078, 0x5373, + 0x0078, 0x5372, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, + 0x704b, 0x5373, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0xa03e, + 0x2009, 0xa72f, 0x210c, 0x81ff, 0x00c0, 0x53ff, 0x2009, 0xa70c, + 0x210c, 0xd194, 0x00c0, 0x5431, 0x6848, 0x2070, 0xae82, 0xae00, + 0x0048, 0x53ef, 0x2001, 0xa716, 0x2004, 0xae02, 0x00c8, 0x53ef, + 0x2061, 0xaa33, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001, 0x00c0, + 0x53d2, 0x711c, 0xa186, 0x0006, 0x00c0, 0x53da, 0x7018, 0xa005, + 0x0040, 0x53ff, 0x2004, 0xd0e4, 0x00c0, 0x542b, 0x7024, 0xd0dc, + 0x00c0, 0x5435, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7010, + 0xa005, 0x00c0, 0x53be, 0x7112, 0x684c, 0xd0f4, 0x00c0, 0x5439, + 0x2e60, 0x1078, 0x5b27, 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, + 0xa005, 0x00c0, 0x53be, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x00c0, + 0x5439, 0x127f, 0x0e7f, 0x007c, 0x127f, 0x0e7f, 0x6853, 0x0006, + 0x0078, 0x545a, 0xd184, 0x0040, 0x53cc, 0xd1c4, 0x00c0, 0x53f3, + 0x0078, 0x53f7, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x45c4, + 0x00c0, 0x542b, 0x6000, 0xd0e4, 0x00c0, 0x542b, 0x711c, 0xa186, + 0x0007, 0x00c0, 0x53ef, 0x6853, 0x0002, 0x0078, 0x542d, 0x6853, + 0x0008, 0x0078, 0x542d, 0x6853, 0x000e, 0x0078, 0x542d, 0x6853, + 0x0017, 0x0078, 0x542d, 0x6853, 0x0035, 0x0078, 0x542d, 0x2001, + 0xa772, 0x2004, 0xd0fc, 0x0040, 0x5427, 0x6848, 0x2070, 0xae82, + 0xae00, 0x0048, 0x5427, 0x6058, 0xae02, 0x00c8, 0x5427, 0x711c, + 0xa186, 0x0006, 0x00c0, 0x5427, 0x7018, 0xa005, 0x0040, 0x5427, + 0x2004, 0xd0bc, 0x0040, 0x5427, 0x2039, 0x0001, 0x7000, 0xa086, + 0x0007, 0x00c0, 0x537e, 0x7003, 0x0002, 0x0078, 0x537e, 0x6853, + 0x0028, 0x0078, 0x542d, 0x6853, 0x0029, 0x127f, 0x0e7f, 0x0078, + 0x545a, 0x6853, 0x002a, 0x0078, 0x542d, 0x6853, 0x0045, 0x0078, + 0x542d, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x1078, 0x9dd7, + 0x127f, 0x0e7f, 0x007c, 0x2009, 0x003e, 0x0078, 0x5455, 0x2009, + 0x0004, 0x0078, 0x5455, 0x2009, 0x0006, 0x0078, 0x5455, 0x2009, + 0x0016, 0x0078, 0x5455, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, + 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x4a73, 0x2091, 0x8001, + 0x007c, 0x1078, 0x13a4, 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, + 0x0048, 0x5471, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0078, + 0x547d, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8, 0x547d, 0x7074, + 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x007c, + 0x0d7e, 0x1078, 0x5b1e, 0x0d7f, 0x007c, 0x0d7e, 0x2011, 0x0004, + 0x2204, 0xa085, 0x8002, 0x2012, 0x0d7f, 0x007c, 0x20e1, 0x0002, + 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0040, 0x549c, + 0xa086, 0x1000, 0x00c0, 0x54d3, 0x20e1, 0x0000, 0x3d00, 0xa094, + 0xff00, 0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x00c0, 0x54b7, + 0xa184, 0xff00, 0x8007, 0xa086, 0x0008, 0x00c0, 0x54d3, 0x1078, + 0x29bb, 0x00c0, 0x54d3, 0x1078, 0x56b2, 0x0078, 0x54ce, 0x20e1, + 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x54be, 0x3e60, 0xac84, 0x000f, + 0x00c0, 0x54d3, 0xac82, 0xae00, 0x0048, 0x54d3, 0x6858, 0xac02, + 0x00c8, 0x54d3, 0x2009, 0x0047, 0x1078, 0x775c, 0x7a1c, 0xd284, + 0x00c0, 0x548e, 0x007c, 0xa016, 0x1078, 0x15fa, 0x0078, 0x54ce, + 0x0078, 0x54d3, 0x781c, 0xd08c, 0x0040, 0x5502, 0x157e, 0x137e, + 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076, 0x00c0, + 0x5518, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x5507, 0x1078, + 0x554e, 0x0040, 0x5518, 0x20e1, 0x3000, 0x7828, 0x7828, 0x1078, + 0x556c, 0x147f, 0x137f, 0x157f, 0x2009, 0xa9b9, 0x2104, 0xa005, + 0x00c0, 0x5503, 0x007c, 0x1078, 0x62d1, 0x0078, 0x5502, 0xa484, + 0x7000, 0x00c0, 0x5518, 0x1078, 0x554e, 0x0040, 0x552c, 0x7000, + 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x54f3, 0x0078, 0x552c, + 0x1078, 0xa55f, 0xd5a4, 0x0040, 0x5528, 0x047e, 0x1078, 0x1b22, + 0x047f, 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5530, + 0x1078, 0x554e, 0x6883, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, + 0x1078, 0x5537, 0x147f, 0x137f, 0x157f, 0x0078, 0x5502, 0x2001, + 0xa70e, 0x2004, 0xd08c, 0x0040, 0x554d, 0x2001, 0xa700, 0x2004, + 0xa086, 0x0003, 0x00c0, 0x554d, 0x027e, 0x037e, 0x2011, 0x8048, + 0x2518, 0x1078, 0x361b, 0x037f, 0x027f, 0x007c, 0xa484, 0x01ff, + 0x6882, 0xa005, 0x0040, 0x5560, 0xa080, 0x001f, 0xa084, 0x03f8, + 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, + 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, + 0xa085, 0x0001, 0x0078, 0x555f, 0x7000, 0xa084, 0xff00, 0xa08c, + 0xf000, 0x8007, 0xa196, 0x0000, 0x00c0, 0x5579, 0x0078, 0x57ba, + 0x007c, 0xa196, 0x2000, 0x00c0, 0x558a, 0x6900, 0xa18e, 0x0001, + 0x00c0, 0x5586, 0x1078, 0x3aec, 0x0078, 0x5578, 0x1078, 0x5592, + 0x0078, 0x5578, 0xa196, 0x8000, 0x00c0, 0x5578, 0x1078, 0x5871, + 0x0078, 0x5578, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, + 0x0001, 0x0040, 0x559f, 0xa196, 0x0023, 0x00c0, 0x56aa, 0xa08e, + 0x0023, 0x00c0, 0x55d4, 0x1078, 0x591d, 0x0040, 0x56aa, 0x7124, + 0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x55b8, 0x7034, 0xa005, + 0x00c0, 0x56aa, 0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x56aa, + 0xa08e, 0x0214, 0x0040, 0x55c0, 0xa08e, 0x0210, 0x00c0, 0x55c6, + 0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x56aa, 0xa08e, 0x0100, + 0x00c0, 0x56aa, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x0016, + 0x1078, 0x775c, 0x0078, 0x56aa, 0xa08e, 0x0022, 0x00c0, 0x56aa, + 0x7030, 0xa08e, 0x0300, 0x00c0, 0x55e5, 0x7034, 0xa005, 0x00c0, + 0x56aa, 0x2009, 0x0017, 0x0078, 0x5676, 0xa08e, 0x0500, 0x00c0, + 0x55f1, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x0018, 0x0078, + 0x5676, 0xa08e, 0x2010, 0x00c0, 0x55f9, 0x2009, 0x0019, 0x0078, + 0x5676, 0xa08e, 0x2110, 0x00c0, 0x5601, 0x2009, 0x001a, 0x0078, + 0x5676, 0xa08e, 0x5200, 0x00c0, 0x560d, 0x7034, 0xa005, 0x00c0, + 0x56aa, 0x2009, 0x001b, 0x0078, 0x5676, 0xa08e, 0x5000, 0x00c0, + 0x5619, 0x7034, 0xa005, 0x00c0, 0x56aa, 0x2009, 0x001c, 0x0078, + 0x5676, 0xa08e, 0x1300, 0x00c0, 0x5621, 0x2009, 0x0034, 0x0078, + 0x5676, 0xa08e, 0x1200, 0x00c0, 0x562d, 0x7034, 0xa005, 0x00c0, + 0x56aa, 0x2009, 0x0024, 0x0078, 0x5676, 0xa08c, 0xff00, 0xa18e, + 0x2400, 0x00c0, 0x5637, 0x2009, 0x002d, 0x0078, 0x5676, 0xa08c, + 0xff00, 0xa18e, 0x5300, 0x00c0, 0x5641, 0x2009, 0x002a, 0x0078, + 0x5676, 0xa08e, 0x0f00, 0x00c0, 0x5649, 0x2009, 0x0020, 0x0078, + 0x5676, 0xa08e, 0x5300, 0x00c0, 0x564f, 0x0078, 0x566c, 0xa08e, + 0x6104, 0x00c0, 0x566c, 0x2011, 0xac8d, 0x8208, 0x2204, 0xa082, + 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, + 0x047e, 0x2124, 0x1078, 0x361b, 0x047f, 0x8108, 0x00f0, 0x565c, + 0x2009, 0x0023, 0x0078, 0x5676, 0xa08e, 0x6000, 0x00c0, 0x5674, + 0x2009, 0x003f, 0x0078, 0x5676, 0x2009, 0x001d, 0x017e, 0x2011, + 0xac83, 0x2204, 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x56ac, + 0x1078, 0x455c, 0x00c0, 0x56ac, 0x6612, 0x6516, 0x86ff, 0x0040, + 0x569c, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x569c, 0x686c, + 0xa606, 0x00c0, 0x569c, 0x6870, 0xa506, 0xa084, 0xff00, 0x00c0, + 0x569c, 0x6000, 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x76c7, 0x0040, + 0x56af, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, + 0x1078, 0x775c, 0x0c7f, 0x007c, 0x017f, 0x0078, 0x56aa, 0x0c7f, + 0x0078, 0x56ac, 0x0c7e, 0x1078, 0x570f, 0x00c0, 0x570d, 0xa28e, + 0x0033, 0x00c0, 0x56de, 0x1078, 0x591d, 0x0040, 0x570d, 0x7124, + 0x610a, 0x7030, 0xa08e, 0x0200, 0x00c0, 0x56d0, 0x7034, 0xa005, + 0x00c0, 0x570d, 0x2009, 0x0015, 0x1078, 0x775c, 0x0078, 0x570d, + 0xa08e, 0x0100, 0x00c0, 0x570d, 0x7034, 0xa005, 0x00c0, 0x570d, + 0x2009, 0x0016, 0x1078, 0x775c, 0x0078, 0x570d, 0xa28e, 0x0032, + 0x00c0, 0x570d, 0x7030, 0xa08e, 0x1400, 0x00c0, 0x570d, 0x2009, + 0x0038, 0x017e, 0x2011, 0xac83, 0x2204, 0x8211, 0x220c, 0x1078, + 0x254d, 0x00c0, 0x570c, 0x1078, 0x455c, 0x00c0, 0x570c, 0x6612, + 0x6516, 0x0c7e, 0x1078, 0x76c7, 0x0040, 0x570b, 0x017f, 0x611a, + 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x775c, 0x1078, + 0x62d1, 0x0078, 0x570d, 0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, + 0x0d7e, 0x027e, 0x017e, 0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, + 0x2079, 0x0030, 0x2069, 0x0200, 0x1078, 0x1c6a, 0x00c0, 0x5750, + 0x1078, 0x1b40, 0x0040, 0x575d, 0x7908, 0xa18c, 0x1fff, 0xa182, + 0x0011, 0x00c8, 0x575a, 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, + 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, + 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, + 0x10c8, 0x1332, 0x80ac, 0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, + 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, 0x0004, 0xa294, 0x0070, + 0x007f, 0x20e0, 0x157f, 0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, + 0x0f7f, 0x007c, 0xa016, 0x1078, 0x15fa, 0xa085, 0x0001, 0x0078, + 0x5750, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff, + 0x00c0, 0x5782, 0xa596, 0xfffd, 0x00c0, 0x5772, 0x2009, 0x007f, + 0x0078, 0x57b5, 0xa596, 0xfffe, 0x00c0, 0x577a, 0x2009, 0x007e, + 0x0078, 0x57b5, 0xa596, 0xfffc, 0x00c0, 0x5782, 0x2009, 0x0080, + 0x0078, 0x57b5, 0x2011, 0x0000, 0x2021, 0x0081, 0x20a9, 0x007e, + 0x2071, 0xa8b6, 0x2e1c, 0x83ff, 0x00c0, 0x5794, 0x82ff, 0x00c0, + 0x57a9, 0x2410, 0x0078, 0x57a9, 0x2368, 0x6f10, 0x007e, 0x2100, + 0xa706, 0x007f, 0x6b14, 0x00c0, 0x57a3, 0xa346, 0x00c0, 0x57a3, + 0x2408, 0x0078, 0x57b5, 0x87ff, 0x00c0, 0x57a9, 0x83ff, 0x0040, + 0x578e, 0x8420, 0x8e70, 0x00f0, 0x578a, 0x82ff, 0x00c0, 0x57b4, + 0xa085, 0x0001, 0x0078, 0x57b6, 0x2208, 0xa006, 0x0d7f, 0x0e7f, + 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x57bf, 0x007c, 0x57c7, + 0x57c7, 0x57c7, 0x5933, 0x57c7, 0x57c8, 0x57e1, 0x5858, 0x007c, + 0x7110, 0xd1bc, 0x0040, 0x57e0, 0x7120, 0x2160, 0xac8c, 0x000f, + 0x00c0, 0x57e0, 0xac8a, 0xae00, 0x0048, 0x57e0, 0x6858, 0xac02, + 0x00c8, 0x57e0, 0x7124, 0x610a, 0x2009, 0x0046, 0x1078, 0x775c, + 0x007c, 0x0c7e, 0xa484, 0x01ff, 0x0040, 0x5833, 0x7110, 0xd1bc, + 0x00c0, 0x5833, 0x2011, 0xac83, 0x2204, 0x8211, 0x220c, 0x1078, + 0x254d, 0x00c0, 0x5833, 0x1078, 0x455c, 0x00c0, 0x5833, 0x6612, + 0x6516, 0x6000, 0xd0ec, 0x00c0, 0x5833, 0x6204, 0xa294, 0xff00, + 0x8217, 0xa286, 0x0006, 0x00c0, 0x5818, 0x0c7e, 0x1078, 0x76c7, + 0x017f, 0x0040, 0x5835, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, + 0x7130, 0x6122, 0x2009, 0x0044, 0x1078, 0x775c, 0x0078, 0x5833, + 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f, + 0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x582b, 0x6007, + 0x0005, 0x0078, 0x582d, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, + 0x5dd7, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x2001, 0xa70d, 0x2004, + 0xd0ec, 0x0040, 0x583f, 0x2011, 0x8049, 0x1078, 0x361b, 0x0c7e, + 0x1078, 0x9197, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f, 0x0006, + 0x7120, 0x610a, 0x7130, 0x6122, 0x6013, 0x0300, 0x6003, 0x0001, + 0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x5833, + 0x7110, 0xd1bc, 0x0040, 0x5870, 0x7020, 0x2060, 0xac84, 0x000f, + 0x00c0, 0x5870, 0xac82, 0xae00, 0x0048, 0x5870, 0x6858, 0xac02, + 0x00c8, 0x5870, 0x7124, 0x610a, 0x2009, 0x0045, 0x1078, 0x775c, + 0x007c, 0x007e, 0x1078, 0x29bb, 0x007f, 0x00c0, 0x5887, 0x7110, + 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x00c0, 0x5887, 0xa084, + 0x000f, 0xa08a, 0x0006, 0x00c8, 0x5887, 0x1079, 0x5888, 0x007c, + 0x588e, 0x588f, 0x588e, 0x588e, 0x58ff, 0x590e, 0x007c, 0x7110, + 0xd1bc, 0x0040, 0x5897, 0x702c, 0xd084, 0x0040, 0x58fe, 0x700c, + 0x7108, 0x1078, 0x254d, 0x00c0, 0x58fe, 0x1078, 0x455c, 0x00c0, + 0x58fe, 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x0040, 0x58c9, + 0xa28c, 0x00ff, 0xa186, 0x0004, 0x0040, 0x58b2, 0xa186, 0x0006, + 0x00c0, 0x58ef, 0x0c7e, 0x1078, 0x591d, 0x0c7f, 0x0040, 0x58fe, + 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f, + 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x1078, 0x775c, 0x0078, + 0x58fe, 0xa28c, 0x00ff, 0xa186, 0x0006, 0x0040, 0x58de, 0xa186, + 0x0004, 0x0040, 0x58de, 0xa294, 0xff00, 0x8217, 0xa286, 0x0004, + 0x0040, 0x58de, 0xa286, 0x0006, 0x00c0, 0x58ef, 0x0c7e, 0x1078, + 0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f, 0x0005, 0x7120, + 0x610a, 0x2009, 0x0088, 0x1078, 0x775c, 0x0078, 0x58fe, 0x0c7e, + 0x1078, 0x76c7, 0x017f, 0x0040, 0x58fe, 0x611a, 0x601f, 0x0004, + 0x7120, 0x610a, 0x2009, 0x0001, 0x1078, 0x775c, 0x007c, 0x7110, + 0xd1bc, 0x0040, 0x590d, 0x1078, 0x591d, 0x0040, 0x590d, 0x7124, + 0x610a, 0x2009, 0x0089, 0x1078, 0x775c, 0x007c, 0x7110, 0xd1bc, + 0x0040, 0x591c, 0x1078, 0x591d, 0x0040, 0x591c, 0x7124, 0x610a, + 0x2009, 0x008a, 0x1078, 0x775c, 0x007c, 0x7020, 0x2060, 0xac84, + 0x000f, 0x00c0, 0x5930, 0xac82, 0xae00, 0x0048, 0x5930, 0x2001, + 0xa716, 0x2004, 0xac02, 0x00c8, 0x5930, 0xa085, 0x0001, 0x007c, + 0xa006, 0x0078, 0x592f, 0x7110, 0xd1bc, 0x00c0, 0x5949, 0x7024, + 0x2060, 0xac84, 0x000f, 0x00c0, 0x5949, 0xac82, 0xae00, 0x0048, + 0x5949, 0x6858, 0xac02, 0x00c8, 0x5949, 0x2009, 0x0051, 0x1078, + 0x775c, 0x007c, 0x2071, 0xa9c4, 0x7003, 0x0003, 0x700f, 0x0361, + 0xa006, 0x701a, 0x7012, 0x7017, 0xae00, 0x7007, 0x0000, 0x7026, + 0x702b, 0x6e1c, 0x7032, 0x7037, 0x6e70, 0x703b, 0x0002, 0x703f, + 0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c, 0x2071, 0xa9c4, + 0x00e0, 0x5a32, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, + 0x59de, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091, 0x8000, + 0x7138, 0x8109, 0x713a, 0x00c0, 0x59dc, 0x703b, 0x0002, 0x2009, + 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x59dc, 0x703c, 0xa086, + 0x0001, 0x00c0, 0x59b9, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, + 0x4000, 0x0040, 0x5997, 0x6803, 0x1000, 0x0078, 0x599e, 0x6804, + 0xa084, 0x1000, 0x0040, 0x599e, 0x6803, 0x0100, 0x6803, 0x0000, + 0x703f, 0x0000, 0x2069, 0xa9b1, 0x6804, 0xa082, 0x0006, 0x00c0, + 0x59ab, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0, 0x59b2, + 0x6833, 0x0000, 0x1078, 0x62d1, 0x1078, 0x639b, 0x0d7f, 0x0078, + 0x59dc, 0x0d7e, 0x2069, 0xa700, 0x6948, 0x6864, 0xa102, 0x00c8, + 0x59db, 0x2069, 0xa9b1, 0x6804, 0xa086, 0x0000, 0x00c0, 0x59db, + 0x6830, 0xa086, 0x0000, 0x00c0, 0x59db, 0x703f, 0x0001, 0x6807, + 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e, 0x2069, + 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x59e1, 0x127e, 0x2091, + 0x8000, 0x7024, 0xa00d, 0x0040, 0x59f9, 0x7020, 0x8001, 0x7022, + 0x00c0, 0x59f9, 0x7023, 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, + 0x00c0, 0x59f4, 0x7028, 0x107a, 0x81ff, 0x00c0, 0x59f9, 0x7028, + 0x107a, 0x7030, 0xa00d, 0x0040, 0x5a10, 0x702c, 0x8001, 0x702e, + 0x00c0, 0x5a10, 0x702f, 0x0009, 0x8109, 0x7132, 0x0040, 0x5a0e, + 0xa184, 0x007f, 0x1040, 0x6ea2, 0x0078, 0x5a10, 0x7034, 0x107a, + 0x7040, 0xa005, 0x0040, 0x5a18, 0x0050, 0x5a18, 0x8001, 0x7042, + 0x7044, 0xa005, 0x0040, 0x5a20, 0x0050, 0x5a20, 0x8001, 0x7046, + 0x7018, 0xa00d, 0x0040, 0x5a31, 0x7008, 0x8001, 0x700a, 0x00c0, + 0x5a31, 0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x5a31, 0x701c, + 0x107a, 0x127f, 0x7004, 0x0079, 0x5a35, 0x5a5c, 0x5a5d, 0x5a79, + 0x0e7e, 0x2071, 0xa9c4, 0x7018, 0xa005, 0x00c0, 0x5a43, 0x711a, + 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, + 0xa9c4, 0x701c, 0xa206, 0x00c0, 0x5a4f, 0x701a, 0x701e, 0x007f, + 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa9c4, 0x6088, 0xa102, 0x0048, + 0x5a5a, 0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x45c4, + 0x00c0, 0x5a6f, 0x6088, 0x8001, 0x0048, 0x5a6f, 0x608a, 0x00c0, + 0x5a6f, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x8108, + 0xa182, 0x00ff, 0x0048, 0x5a77, 0xa00e, 0x7007, 0x0002, 0x7112, + 0x007c, 0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, + 0x0040, 0x5a88, 0x8001, 0x603e, 0x00c0, 0x5a88, 0x1078, 0x8fac, + 0x6014, 0xa005, 0x0040, 0x5ab2, 0x8001, 0x6016, 0x00c0, 0x5ab2, + 0x611c, 0xa186, 0x0003, 0x0040, 0x5a99, 0xa186, 0x0006, 0x00c0, + 0x5ab0, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x5ab0, + 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5aa9, 0x2001, + 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5ab2, + 0x1078, 0x8ace, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xce00, + 0xa102, 0x0048, 0x5abf, 0x7017, 0xae00, 0x7007, 0x0000, 0x007c, + 0x0e7e, 0x2071, 0xa9c4, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, + 0x0002, 0x0e7f, 0x007c, 0x2001, 0xa9cd, 0x2003, 0x0000, 0x007c, + 0x0e7e, 0x2071, 0xa9c4, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, + 0x2011, 0xa9d0, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa9c4, + 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, + 0x0f7e, 0x2079, 0xa700, 0x7a34, 0xd294, 0x0040, 0x5b15, 0x2071, + 0xa9ac, 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5b02, 0xa0fe, 0x0001, + 0x0040, 0x5b06, 0xa0fe, 0x0002, 0x00c0, 0x5b11, 0xa292, 0x0085, + 0x0078, 0x5b08, 0xa292, 0x0005, 0x0078, 0x5b08, 0xa292, 0x0002, + 0x2272, 0x0040, 0x5b0d, 0x00c8, 0x5b15, 0x2011, 0x8037, 0x1078, + 0x361b, 0x2011, 0xa9ab, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, + 0x007c, 0x0c7e, 0x2061, 0xaa33, 0x0c7f, 0x007c, 0xa184, 0x000f, + 0x8003, 0x8003, 0x8003, 0xa080, 0xaa33, 0x2060, 0x007c, 0x6854, + 0xa08a, 0x199a, 0x0048, 0x5b2e, 0x2001, 0x1999, 0xa005, 0x00c0, + 0x5b3d, 0x0c7e, 0x2061, 0xaa33, 0x6014, 0x0c7f, 0xa005, 0x00c0, + 0x5b42, 0x2001, 0x001e, 0x0078, 0x5b42, 0xa08e, 0xffff, 0x00c0, + 0x5b42, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, + 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5b9e, 0xd0b4, 0x00c0, + 0x5b59, 0xd0bc, 0x00c0, 0x5b8b, 0x2009, 0x0006, 0x1078, 0x5bc3, + 0x007c, 0xd0fc, 0x0040, 0x5b64, 0xa084, 0x0003, 0x0040, 0x5b64, + 0xa086, 0x0003, 0x00c0, 0x5bbc, 0x6024, 0xd0d4, 0x0040, 0x5b6e, + 0xc0d4, 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa774, + 0x2104, 0xd084, 0x0040, 0x5b83, 0x6118, 0xa188, 0x0027, 0x2104, + 0xd08c, 0x00c0, 0x5b83, 0x87ff, 0x00c0, 0x5b82, 0x2009, 0x0042, + 0x1078, 0x775c, 0x007c, 0x87ff, 0x00c0, 0x5b8a, 0x2009, 0x0043, + 0x1078, 0x775c, 0x007c, 0xd0fc, 0x0040, 0x5b96, 0xa084, 0x0003, + 0x0040, 0x5b96, 0xa086, 0x0003, 0x00c0, 0x5bbc, 0x87ff, 0x00c0, + 0x5b9d, 0x2009, 0x0042, 0x1078, 0x775c, 0x007c, 0xd0fc, 0x0040, + 0x5baf, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0040, 0x5bb3, 0x87ff, + 0x00c0, 0x5bae, 0x2009, 0x0041, 0x1078, 0x775c, 0x007c, 0x1078, + 0x5bc1, 0x0078, 0x5bae, 0x87ff, 0x00c0, 0x5bae, 0x2009, 0x0043, + 0x1078, 0x775c, 0x0078, 0x5bae, 0x2009, 0x0004, 0x1078, 0x5bc3, + 0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040, + 0x5bef, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, + 0x5be5, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5be5, + 0x0c7e, 0x2061, 0xaa33, 0x6200, 0xd28c, 0x00c0, 0x5be4, 0x6204, + 0x8210, 0x0048, 0x5be4, 0x6206, 0x0c7f, 0x1078, 0x4a73, 0x6010, + 0xa06d, 0x077e, 0x2039, 0x0000, 0x10c0, 0x5b27, 0x077f, 0x0d7f, + 0x007c, 0x157e, 0x0c7e, 0x2061, 0xaa33, 0x6000, 0x81ff, 0x0040, + 0x5bfc, 0xa205, 0x0078, 0x5bfd, 0xa204, 0x6002, 0x0c7f, 0x157f, + 0x007c, 0x6800, 0xd08c, 0x00c0, 0x5c0d, 0x6808, 0xa005, 0x0040, + 0x5c0d, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x20a9, 0x0010, + 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x5c17, 0xa200, 0x00f0, + 0x5c12, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, + 0x0040, 0x5c3d, 0xa11a, 0x00c8, 0x5c3d, 0x8213, 0x818d, 0x0048, + 0x5c30, 0xa11a, 0x00c8, 0x5c31, 0x00f0, 0x5c25, 0x0078, 0x5c35, + 0xa11a, 0x2308, 0x8210, 0x00f0, 0x5c25, 0x007e, 0x3200, 0xa084, + 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, + 0x0800, 0x0078, 0x5c39, 0x127e, 0x2091, 0x2200, 0x2079, 0xa9b1, + 0x127f, 0x0d7e, 0x2069, 0xa9b1, 0x6803, 0x0005, 0x2069, 0x0004, + 0x2d04, 0xa085, 0x8001, 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027, + 0x0001, 0x7804, 0xa084, 0x0007, 0x0079, 0x5c5e, 0x5c68, 0x5c8d, + 0x5ce8, 0x5c6e, 0x5c8d, 0x5c68, 0x5c66, 0x5c66, 0x1078, 0x1332, + 0x1078, 0x5acb, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x62c0, 0x82ff, + 0x00c0, 0x5c74, 0x0c7f, 0x007c, 0x2011, 0x41dc, 0x1078, 0x5a45, + 0x7828, 0xa092, 0x00c8, 0x00c8, 0x5c83, 0x8000, 0x782a, 0x1078, + 0x421b, 0x0078, 0x5c72, 0x1078, 0x41dc, 0x7807, 0x0003, 0x7827, + 0x0000, 0x782b, 0x0000, 0x0078, 0x5c72, 0x1078, 0x5acb, 0x3c00, + 0x007e, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x007f, 0x20e0, + 0x82ff, 0x0040, 0x5cab, 0x62c0, 0x82ff, 0x00c0, 0x5cab, 0x782b, + 0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013, 0x1078, + 0x775c, 0x0c7f, 0x007c, 0x3900, 0xa082, 0xaae3, 0x00c8, 0x5cb2, + 0x1078, 0x747a, 0x0c7e, 0x7824, 0xa065, 0x1040, 0x1332, 0x7804, + 0xa086, 0x0004, 0x0040, 0x5d2d, 0x7828, 0xa092, 0x2710, 0x00c8, + 0x5cc8, 0x8000, 0x782a, 0x0c7f, 0x1078, 0x6e01, 0x0078, 0x5ca9, + 0x6104, 0xa186, 0x0003, 0x00c0, 0x5cdf, 0x0e7e, 0x2071, 0xa700, + 0x70d8, 0x0e7f, 0xd08c, 0x0040, 0x5cdf, 0x0c7e, 0x0e7e, 0x2061, + 0x0100, 0x2071, 0xa700, 0x1078, 0x4224, 0x0e7f, 0x0c7f, 0x1078, + 0xa5d4, 0x2009, 0x0014, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x5ca9, + 0x2001, 0xa9cd, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5cfc, + 0x782b, 0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013, + 0x1078, 0x77b3, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x3900, 0xa082, + 0xaae3, 0x00c8, 0x5d05, 0x1078, 0x747a, 0x7824, 0xa005, 0x1040, + 0x1332, 0x781c, 0xa06d, 0x1040, 0x1332, 0x6800, 0xc0dc, 0x6802, + 0x7924, 0x2160, 0x1078, 0x772d, 0x693c, 0x81ff, 0x1040, 0x1332, + 0x8109, 0x693e, 0x6854, 0xa015, 0x0040, 0x5d21, 0x7a1e, 0x0078, + 0x5d23, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f, + 0x0c7f, 0x1078, 0x62d1, 0x0078, 0x5cfa, 0x6104, 0xa186, 0x0002, + 0x0040, 0x5d38, 0xa186, 0x0004, 0x0040, 0x5d38, 0x0078, 0x5cbc, + 0x7808, 0xac06, 0x0040, 0x5cbc, 0x1078, 0x61cd, 0x1078, 0x5dd7, + 0x0c7f, 0x1078, 0x62d1, 0x0078, 0x5ca9, 0x0c7e, 0x6027, 0x0002, + 0x62c8, 0x82ff, 0x00c0, 0x5d61, 0x62c4, 0x82ff, 0x00c0, 0x5d61, + 0x793c, 0xa1e5, 0x0000, 0x0040, 0x5d5b, 0x2009, 0x0049, 0x1078, + 0x775c, 0x0c7f, 0x007c, 0x2011, 0xa9d0, 0x2013, 0x0000, 0x0078, + 0x5d59, 0x3908, 0xa192, 0xaae3, 0x00c8, 0x5d68, 0x1078, 0x747a, + 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5d5b, 0x7944, 0xa192, + 0x7530, 0x00c8, 0x5d85, 0x8108, 0x7946, 0x793c, 0xa188, 0x0007, + 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5d81, 0x6017, 0x0012, 0x0078, + 0x5d59, 0x6017, 0x0016, 0x0078, 0x5d59, 0x7848, 0xc085, 0x784a, + 0x0078, 0x5d59, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, + 0x600f, 0x0000, 0x2c08, 0x2061, 0xa9b1, 0x6020, 0x8000, 0x6022, + 0x6010, 0xa005, 0x0040, 0x5da5, 0xa080, 0x0003, 0x2102, 0x6112, + 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, + 0x5da0, 0x0d7e, 0x2069, 0xa9b1, 0x6000, 0xd0d4, 0x0040, 0x5dbe, + 0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x5db9, 0x2c00, + 0x681e, 0x6804, 0xa084, 0x0007, 0x0079, 0x62d9, 0xc0d5, 0x6002, + 0x6818, 0xa005, 0x0040, 0x5dd0, 0x6056, 0x605b, 0x0000, 0x007e, + 0x2c00, 0x681a, 0x0d7f, 0x685a, 0x2069, 0xa9b1, 0x0078, 0x5db0, + 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x5db0, 0x007e, + 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, + 0x2061, 0xa9b1, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, + 0x5df2, 0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, + 0x007f, 0x007c, 0x610e, 0x610a, 0x0078, 0x5ded, 0x0c7e, 0x600f, + 0x0000, 0x2c08, 0x2061, 0xa9b1, 0x6034, 0xa005, 0x0040, 0x5e06, + 0xa080, 0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, + 0x0078, 0x5e04, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, + 0x037e, 0x027e, 0x017e, 0x007e, 0x127e, 0xa02e, 0x2071, 0xa9b1, + 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x5e8c, + 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5e87, 0x87ff, + 0x0040, 0x5e2e, 0x6020, 0xa106, 0x00c0, 0x5e87, 0x703c, 0xac06, + 0x00c0, 0x5e44, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x7033, + 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b, + 0x0000, 0x037f, 0x2029, 0x0001, 0x7038, 0xac36, 0x00c0, 0x5e4a, + 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5e58, 0x2c00, 0xaf36, + 0x0040, 0x5e56, 0x2f00, 0x7036, 0x0078, 0x5e58, 0x7037, 0x0000, + 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5e61, 0x7e0e, 0x0078, + 0x5e62, 0x2678, 0x600f, 0x0000, 0x1078, 0x8d16, 0x0040, 0x5e82, + 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e9d, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x077e, 0x1078, + 0x8f8d, 0x1078, 0xa4f2, 0x1078, 0x4a73, 0x077f, 0x037f, 0x017f, + 0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x5e1d, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x5e1d, 0x85ff, 0x0040, 0x5e91, 0x1078, + 0x639b, 0x127f, 0x007f, 0x017f, 0x027f, 0x037f, 0x057f, 0x067f, + 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, + 0x00c0, 0x5e6f, 0x017e, 0x037e, 0x077e, 0x1078, 0xa4f2, 0x1078, + 0xa1da, 0x077f, 0x037f, 0x017f, 0x0078, 0x5e82, 0x007e, 0x067e, + 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000, + 0x2079, 0xa9b1, 0x7838, 0xa065, 0x0040, 0x5eef, 0x600c, 0x007e, + 0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x5ed6, 0x037e, 0x2019, + 0x0001, 0x1078, 0x7058, 0x7833, 0x0000, 0x783f, 0x0000, 0x7843, + 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x037f, 0x1078, 0x8d16, + 0x0040, 0x5eea, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, + 0x5ef8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, + 0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x007f, 0x0078, 0x5ebb, 0x7e3a, + 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, + 0x601c, 0xa086, 0x0006, 0x00c0, 0x5ee1, 0x1078, 0xa1da, 0x0078, + 0x5eea, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, 0x1078, 0x5f1b, + 0x1078, 0x5fdb, 0x087f, 0x027f, 0x017f, 0x007c, 0x0f7e, 0x127e, + 0x2079, 0xa9b1, 0x2091, 0x8000, 0x1078, 0x6076, 0x1078, 0x60ec, + 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, + 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x7614, + 0x2660, 0x2678, 0x8cff, 0x0040, 0x5fb5, 0x6018, 0xa080, 0x0028, + 0x2004, 0xa206, 0x00c0, 0x5fb0, 0x88ff, 0x0040, 0x5f3b, 0x6020, + 0xa106, 0x00c0, 0x5fb0, 0x7024, 0xac06, 0x00c0, 0x5f6b, 0x2069, + 0x0100, 0x68c0, 0xa005, 0x0040, 0x5f66, 0x1078, 0x5acb, 0x1078, + 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7027, 0x0000, 0x037e, + 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5f5b, 0x6803, + 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, + 0x5f63, 0x6827, 0x0001, 0x037f, 0x0078, 0x5f6b, 0x6003, 0x0009, + 0x630a, 0x0078, 0x5fb0, 0x7014, 0xac36, 0x00c0, 0x5f71, 0x660c, + 0x7616, 0x7010, 0xac36, 0x00c0, 0x5f7f, 0x2c00, 0xaf36, 0x0040, + 0x5f7d, 0x2f00, 0x7012, 0x0078, 0x5f7f, 0x7013, 0x0000, 0x660c, + 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5f88, 0x7e0e, 0x0078, 0x5f89, + 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, + 0x5fa9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5fbe, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x087e, 0x1078, 0x8f8d, + 0x1078, 0xa4f2, 0x1078, 0x4a73, 0x087f, 0x037f, 0x017f, 0x1078, + 0x8ec9, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x5f2a, + 0x2c78, 0x600c, 0x2060, 0x0078, 0x5f2a, 0x127f, 0x007f, 0x017f, + 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, + 0x0006, 0x00c0, 0x5fcf, 0x017e, 0x037e, 0x087e, 0x1078, 0xa4f2, + 0x1078, 0xa1da, 0x087f, 0x037f, 0x017f, 0x0078, 0x5fa9, 0x601c, + 0xa086, 0x0002, 0x00c0, 0x5fa9, 0x6004, 0xa086, 0x0085, 0x0040, + 0x5f96, 0x0078, 0x5fa9, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, + 0xa280, 0xa835, 0x2004, 0xa065, 0x0040, 0x6072, 0x0f7e, 0x0e7e, + 0x0d7e, 0x067e, 0x2071, 0xa9b1, 0x6654, 0x7018, 0xac06, 0x00c0, + 0x5ff2, 0x761a, 0x701c, 0xac06, 0x00c0, 0x5ffe, 0x86ff, 0x00c0, + 0x5ffd, 0x7018, 0x701e, 0x0078, 0x5ffe, 0x761e, 0x6058, 0xa07d, + 0x0040, 0x6003, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x6009, 0x2f00, + 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, + 0x6002, 0x1078, 0x44d3, 0x0040, 0x606e, 0x7624, 0x86ff, 0x0040, + 0x605c, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, 0x605c, 0x0d7e, + 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x6053, 0x1078, 0x5acb, + 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7027, 0x0000, + 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x603c, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0040, 0x6044, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, + 0xa005, 0x0040, 0x604d, 0x8001, 0x603e, 0x2660, 0x1078, 0x8ed6, + 0x0c7f, 0x0078, 0x605c, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, + 0x630a, 0x0c7f, 0x0078, 0x6011, 0x8dff, 0x0040, 0x606a, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f8d, 0x1078, 0xa4f2, + 0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x6011, 0x067f, 0x0d7f, + 0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, + 0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x60d0, + 0x600c, 0x007e, 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x60b5, + 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x60af, 0x1078, 0x5acb, + 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, 0x7827, 0x0000, + 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x60a4, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0040, 0x60ac, 0x6827, 0x0001, 0x037f, 0x0078, 0x60b5, 0x6003, + 0x0009, 0x630a, 0x2c30, 0x0078, 0x60cd, 0x6010, 0x2068, 0x1078, + 0x8d16, 0x0040, 0x60c9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x60d7, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078, + 0x8ec9, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x007f, 0x0078, 0x607d, + 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, + 0xa086, 0x0006, 0x00c0, 0x60e0, 0x1078, 0xa1da, 0x0078, 0x60c9, + 0x601c, 0xa086, 0x0002, 0x00c0, 0x60c9, 0x6004, 0xa086, 0x0085, + 0x0040, 0x60c0, 0x0078, 0x60c9, 0x007e, 0x067e, 0x0c7e, 0x0d7e, + 0x7818, 0xa065, 0x0040, 0x615a, 0x6054, 0x007e, 0x6057, 0x0000, + 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x44d3, + 0x0040, 0x6157, 0x7e24, 0x86ff, 0x0040, 0x6149, 0xa680, 0x0004, + 0x2004, 0xad06, 0x00c0, 0x6149, 0x0d7e, 0x2069, 0x0100, 0x68c0, + 0xa005, 0x0040, 0x6140, 0x1078, 0x5acb, 0x1078, 0x6e0f, 0x68c3, + 0x0000, 0x1078, 0x7378, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, + 0x6b04, 0xa384, 0x1000, 0x0040, 0x6129, 0x6803, 0x0100, 0x6803, + 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x6131, 0x6827, + 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x613a, + 0x8001, 0x603e, 0x2660, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x6149, + 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, + 0x60fe, 0x8dff, 0x0040, 0x6153, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x60fe, 0x007f, + 0x0078, 0x60f1, 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, + 0x007c, 0x0e7e, 0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x6181, + 0x604c, 0xa06d, 0x0040, 0x6181, 0x6848, 0xa606, 0x00c0, 0x6181, + 0x2071, 0xa9b1, 0x7024, 0xa035, 0x0040, 0x6181, 0xa080, 0x0004, + 0x2004, 0xad06, 0x00c0, 0x6181, 0x6000, 0xc0dc, 0x6002, 0x1078, + 0x6185, 0x067f, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x2079, 0x0100, + 0x78c0, 0xa005, 0x00c0, 0x6194, 0x0c7e, 0x2660, 0x6003, 0x0009, + 0x630a, 0x0c7f, 0x0078, 0x61cb, 0x1078, 0x6e0f, 0x78c3, 0x0000, + 0x1078, 0x7378, 0x7027, 0x0000, 0x037e, 0x2079, 0x0140, 0x7b04, + 0xa384, 0x1000, 0x0040, 0x61a8, 0x7803, 0x0100, 0x7803, 0x0000, + 0x2079, 0x0100, 0x7824, 0xd084, 0x0040, 0x61b0, 0x7827, 0x0001, + 0x1078, 0x7378, 0x037f, 0x1078, 0x44d3, 0x0c7e, 0x603c, 0xa005, + 0x0040, 0x61bc, 0x8001, 0x603e, 0x2660, 0x1078, 0x772d, 0x0c7f, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f8d, 0x1078, + 0x4a73, 0x1078, 0x7233, 0x0f7f, 0x007c, 0x0e7e, 0x0c7e, 0x2071, + 0xa9b1, 0x7004, 0xa084, 0x0007, 0x0079, 0x61d6, 0x61e0, 0x61e3, + 0x61fc, 0x6218, 0x6262, 0x61e0, 0x61e0, 0x61de, 0x1078, 0x1332, + 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x61f1, 0x7020, + 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x61f8, 0x7216, 0x600f, + 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, + 0x7216, 0x7212, 0x0078, 0x61f1, 0x6018, 0x2060, 0x1078, 0x44d3, + 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0040, 0x620d, + 0x6054, 0xa015, 0x0040, 0x6214, 0x721e, 0x7007, 0x0000, 0x7027, + 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, 0x0078, 0x620d, + 0x7024, 0xa065, 0x0040, 0x625f, 0x700c, 0xac06, 0x00c0, 0x622f, + 0x1078, 0x7233, 0x600c, 0xa015, 0x0040, 0x622b, 0x720e, 0x600f, + 0x0000, 0x0078, 0x625d, 0x720e, 0x720a, 0x0078, 0x625d, 0x7014, + 0xac06, 0x00c0, 0x6242, 0x1078, 0x7233, 0x600c, 0xa015, 0x0040, + 0x623e, 0x7216, 0x600f, 0x0000, 0x0078, 0x625d, 0x7216, 0x7212, + 0x0078, 0x625d, 0x601c, 0xa086, 0x0003, 0x00c0, 0x625d, 0x6018, + 0x2060, 0x1078, 0x44d3, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7233, + 0x701c, 0xa065, 0x0040, 0x625d, 0x6054, 0xa015, 0x0040, 0x625b, + 0x721e, 0x0078, 0x625d, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, + 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x626f, 0x1078, 0x7233, + 0x600c, 0xa015, 0x0040, 0x6276, 0x720e, 0x600f, 0x0000, 0x1078, + 0x7378, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, + 0x0078, 0x626f, 0x0d7e, 0x2069, 0xa9b1, 0x6830, 0xa084, 0x0003, + 0x0079, 0x6282, 0x6288, 0x628a, 0x62b4, 0x6288, 0x1078, 0x1332, + 0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x62aa, + 0x683c, 0xa065, 0x0040, 0x629b, 0x600c, 0xa015, 0x0040, 0x62a6, + 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, + 0xa9d0, 0x2013, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836, + 0x0078, 0x629b, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x629b, + 0x6003, 0x0003, 0x0078, 0x629b, 0x0c7e, 0x6843, 0x0000, 0x6847, + 0x0000, 0x684b, 0x0000, 0x683c, 0xa065, 0x0040, 0x62ce, 0x600c, + 0xa015, 0x0040, 0x62ca, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, + 0x0078, 0x62ce, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, + 0x007c, 0x0d7e, 0x2069, 0xa9b1, 0x6804, 0xa084, 0x0007, 0x0079, + 0x62d9, 0x62e3, 0x638a, 0x638a, 0x638a, 0x638a, 0x638c, 0x638a, + 0x62e1, 0x1078, 0x1332, 0x6820, 0xa005, 0x00c0, 0x62e9, 0x0d7f, + 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x62f8, 0x6807, 0x0004, + 0x6826, 0x682b, 0x0000, 0x1078, 0x63d4, 0x0c7f, 0x0d7f, 0x007c, + 0x6814, 0xa065, 0x0040, 0x6306, 0x6807, 0x0001, 0x6826, 0x682b, + 0x0000, 0x1078, 0x63d4, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, + 0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x6385, 0x704c, 0xa00d, 0x0040, + 0x6315, 0x7088, 0xa005, 0x0040, 0x632d, 0x7054, 0xa075, 0x0040, + 0x631e, 0xa20e, 0x0040, 0x6385, 0x0078, 0x6323, 0x6818, 0xa20e, + 0x0040, 0x6385, 0x2070, 0x704c, 0xa00d, 0x0040, 0x6315, 0x7088, + 0xa005, 0x00c0, 0x6315, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, + 0x00c8, 0x6315, 0x1078, 0x76fc, 0x0040, 0x6385, 0x8318, 0x733e, + 0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff, + 0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004, + 0xa08a, 0x199a, 0x0048, 0x634e, 0x2001, 0x1999, 0x8003, 0x801b, + 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, + 0x0040, 0x6367, 0x7100, 0xd1f4, 0x0040, 0x6363, 0x7114, 0xa18c, + 0x00ff, 0x0078, 0x636c, 0x2009, 0x0000, 0x0078, 0x636c, 0xa1e0, + 0x29c0, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, + 0x6965, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, + 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, + 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, + 0x0078, 0x6383, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, + 0x6398, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x63d4, + 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa9b1, 0x6830, + 0xa086, 0x0000, 0x00c0, 0x63bb, 0x6838, 0xa07d, 0x0040, 0x63bb, + 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x127e, + 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1d6d, 0x00c0, 0x63be, + 0x127f, 0x1078, 0x6cb3, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, + 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0040, 0x63d0, 0x6a3a, + 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x63bb, + 0x683a, 0x6836, 0x0078, 0x63ca, 0x601c, 0xa084, 0x000f, 0x1079, + 0x63da, 0x007c, 0x63e3, 0x63e8, 0x6809, 0x6922, 0x63e8, 0x6809, + 0x6922, 0x63e3, 0x63e8, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x007c, + 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, + 0x10c8, 0x1332, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x6405, + 0x7900, 0xd1f4, 0x0040, 0x6401, 0x7914, 0xa18c, 0x00ff, 0x0078, + 0x640a, 0x2009, 0x0000, 0x0078, 0x640a, 0xa1f8, 0x29c0, 0x2f0c, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, + 0x00c8, 0x645c, 0x1079, 0x641a, 0x0f7f, 0x0c7f, 0x147f, 0x137f, + 0x157f, 0x007c, 0x64c2, 0x650a, 0x6532, 0x65cd, 0x65fd, 0x6605, + 0x662c, 0x663d, 0x664e, 0x6656, 0x666e, 0x6656, 0x66d9, 0x663d, + 0x66fa, 0x6702, 0x664e, 0x6702, 0x6713, 0x645a, 0x645a, 0x645a, + 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, 0x645a, + 0x6eef, 0x6f14, 0x6f29, 0x6f4c, 0x6f6d, 0x662c, 0x645a, 0x662c, + 0x6656, 0x645a, 0x6532, 0x65cd, 0x645a, 0x749c, 0x6656, 0x645a, + 0x74bc, 0x6656, 0x645a, 0x645a, 0x64bd, 0x646b, 0x645a, 0x74e1, + 0x7558, 0x7640, 0x645a, 0x7651, 0x6626, 0x766d, 0x645a, 0x6f82, + 0x645a, 0x645a, 0x1078, 0x1332, 0x2100, 0x1079, 0x6465, 0x0f7f, + 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x6469, 0x6469, 0x6469, + 0x649f, 0x1078, 0x1332, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6731, + 0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, + 0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6dfb, 0x0d7f, 0x007c, + 0x0d7e, 0x7818, 0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x649c, + 0xa085, 0x0001, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x649a, 0x0d7e, + 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x0500, 0x20a3, 0x0000, + 0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, + 0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, + 0x0010, 0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, + 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x5200, + 0x20a3, 0x0000, 0x0d7e, 0x2069, 0xa752, 0x6804, 0xd084, 0x0040, + 0x64dc, 0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2564, 0x21a2, + 0x017f, 0x0d7f, 0x0078, 0x64e1, 0x0d7f, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x20a9, 0x0004, + 0x2099, 0xa701, 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, + 0x007f, 0x0048, 0x64fb, 0x2001, 0xa71b, 0x20a6, 0x2001, 0xa71c, + 0x20a6, 0x0078, 0x6501, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, + 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, + 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x0500, + 0x20a3, 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, + 0x0048, 0x6522, 0x2001, 0xa71b, 0x20a6, 0x2001, 0xa71c, 0x20a6, + 0x0078, 0x6528, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, + 0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x60c3, 0x0010, 0x1078, + 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x0c7e, 0x7818, + 0x2060, 0x2001, 0x0000, 0x1078, 0x4972, 0x0c7f, 0x7818, 0xa080, + 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x654d, 0x20a3, 0x0400, + 0x620c, 0xc2b4, 0x620e, 0x0078, 0x654f, 0x20a3, 0x0300, 0x20a3, + 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, + 0x659c, 0x2099, 0xa98d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, + 0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, + 0xa705, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa701, 0x53a6, 0x20a9, + 0x0010, 0x20a3, 0x0000, 0x00f0, 0x6579, 0x2099, 0xa995, 0x3304, + 0xc0dd, 0x20a2, 0x2001, 0xa772, 0x2004, 0xd0e4, 0x0040, 0x6594, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, + 0x20a9, 0x0004, 0x0078, 0x6596, 0x20a9, 0x0007, 0x20a3, 0x0000, + 0x00f0, 0x6596, 0x0078, 0x65bc, 0x2099, 0xa98d, 0x20a9, 0x0008, + 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x20a9, 0x0004, + 0x2099, 0xa701, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, + 0x65ad, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x65b3, 0x2099, + 0xa995, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, + 0x00f0, 0x65be, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x65c4, + 0x60c3, 0x0074, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x6731, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, + 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, + 0x2079, 0xa752, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x65e9, 0xa085, + 0x0020, 0xd1a4, 0x0040, 0x65ee, 0xa085, 0x0010, 0xa085, 0x0002, + 0x0d7e, 0x0078, 0x66b7, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x6731, 0x20a3, 0x5000, 0x0078, 0x654f, 0x20a1, 0x020b, 0x1078, + 0x6731, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, + 0x1078, 0x67b9, 0x0078, 0x6630, 0x20a1, 0x020b, 0x1078, 0x67c2, + 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0004, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, + 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, + 0x1078, 0x67c2, 0x20a3, 0x0200, 0x0078, 0x654f, 0x20a1, 0x020b, + 0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, + 0x0040, 0x6665, 0x20a2, 0x0078, 0x6667, 0x20a3, 0x0003, 0x7810, + 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x0d7e, 0x20a1, + 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, + 0x0800, 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x6694, + 0x6998, 0xa184, 0xc000, 0x00c0, 0x6690, 0xd1ec, 0x0040, 0x668c, + 0x20a3, 0x2100, 0x0078, 0x6696, 0x20a3, 0x0100, 0x0078, 0x6696, + 0x20a3, 0x0400, 0x0078, 0x6696, 0x20a3, 0x0700, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa752, 0x7904, + 0x0f7f, 0xd1ac, 0x00c0, 0x66a6, 0xa085, 0x0020, 0xd1a4, 0x0040, + 0x66ab, 0xa085, 0x0010, 0x2009, 0xa774, 0x210c, 0xd184, 0x0040, + 0x66b5, 0x699c, 0xd18c, 0x0040, 0x66b7, 0xa085, 0x0002, 0x027e, + 0x2009, 0xa772, 0x210c, 0xd1e4, 0x0040, 0x66c5, 0xc0c5, 0xa094, + 0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xd1ec, 0x0040, 0x66cf, + 0xa094, 0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xc0bd, 0x027f, + 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x0d7f, + 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0210, 0x20a3, + 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, + 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0200, + 0x0078, 0x64c8, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, + 0x1078, 0x6dfb, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, + 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, + 0x027e, 0x037e, 0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, + 0x6738, 0x027e, 0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, + 0xa286, 0x007e, 0x00c0, 0x674b, 0xa385, 0x00ff, 0x20a2, 0x20a3, + 0xfffe, 0x0078, 0x6780, 0xa286, 0x007f, 0x00c0, 0x6757, 0x0d7e, + 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x0078, 0x676e, 0xd2bc, + 0x0040, 0x6776, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x6766, 0xa385, + 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0078, 0x676e, 0xa2e8, 0xa835, + 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6784, 0x0d7e, 0xa2e8, + 0xa835, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, + 0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, + 0x037f, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, + 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, + 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, + 0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0xa71b, 0x2da6, 0x8d68, + 0x2da6, 0x0d7f, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x678b, + 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, + 0x007c, 0x027e, 0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, + 0x0078, 0x67c9, 0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, + 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa092, 0x007e, 0x0048, 0x67e6, 0x0d7e, 0xa0e8, 0xa835, + 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x67f4, 0x0d7e, 0xa0e8, + 0xa835, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, + 0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, + 0x0000, 0x047f, 0x037f, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, + 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, + 0x007c, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1332, + 0xa08a, 0x008c, 0x10c8, 0x1332, 0x6118, 0x2178, 0x79a0, 0xd1bc, + 0x0040, 0x6827, 0x7900, 0xd1f4, 0x0040, 0x6823, 0x7914, 0xa18c, + 0x00ff, 0x0078, 0x682c, 0x2009, 0x0000, 0x0078, 0x682c, 0xa1f8, + 0x29c0, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, + 0xa082, 0x0085, 0x1079, 0x6837, 0x0f7f, 0x0c7f, 0x007c, 0x6840, + 0x684b, 0x6866, 0x683e, 0x683e, 0x683e, 0x6840, 0x1078, 0x1332, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x6879, 0x60c3, 0x0000, 0x1078, + 0x6dfb, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x68ad, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x147f, 0x007c, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x68ee, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x6dfb, 0x147f, + 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, + 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6898, 0x0d7e, 0xa0e8, + 0xa835, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x68a7, + 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, + 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, + 0x0009, 0x20a3, 0x0000, 0x0078, 0x678b, 0x027e, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, + 0x0048, 0x68cc, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, + 0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68, + 0x2da6, 0x0d7f, 0x0078, 0x68db, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, + 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, + 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, + 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, + 0x007e, 0x0048, 0x690d, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, + 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6, + 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x691c, 0x0d7e, 0xa0e8, 0xa835, + 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, + 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, + 0x0078, 0x68df, 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, + 0x1048, 0x1332, 0xa08a, 0x0053, 0x10c8, 0x1332, 0x7918, 0x2160, + 0x61a0, 0xd1bc, 0x0040, 0x6941, 0x6100, 0xd1f4, 0x0040, 0x693d, + 0x6114, 0xa18c, 0x00ff, 0x0078, 0x6946, 0x2009, 0x0000, 0x0078, + 0x6946, 0xa1e0, 0x29c0, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, + 0x619a, 0xa082, 0x0040, 0x1079, 0x6950, 0x0f7f, 0x0c7f, 0x007c, + 0x6965, 0x6a73, 0x6a14, 0x6c27, 0x6963, 0x6963, 0x6963, 0x6963, + 0x6963, 0x6963, 0x6963, 0x714c, 0x715d, 0x716e, 0x717f, 0x6963, + 0x767e, 0x6963, 0x713b, 0x1078, 0x1332, 0x0d7e, 0x157e, 0x147e, + 0x780b, 0xffff, 0x20a1, 0x020b, 0x1078, 0x69d0, 0x7910, 0x2168, + 0x6948, 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, + 0xa184, 0x000f, 0x00c0, 0x6980, 0x2001, 0x0005, 0x0078, 0x698a, + 0xd184, 0x0040, 0x6987, 0x2001, 0x0004, 0x0078, 0x698a, 0xa084, + 0x0006, 0x8004, 0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, + 0xa105, 0x017f, 0x20a2, 0xd1ac, 0x0040, 0x699a, 0x20a3, 0x0002, + 0x0078, 0x69a6, 0xd1b4, 0x0040, 0x69a1, 0x20a3, 0x0001, 0x0078, + 0x69a6, 0x20a3, 0x0000, 0x2230, 0x0078, 0x69a8, 0x6a80, 0x6e7c, + 0x20a9, 0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, + 0x00f0, 0x69ac, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, + 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa9cd, + 0x2003, 0x07d0, 0x2001, 0xa9cc, 0x2003, 0x0009, 0x2001, 0xa9d2, + 0x2003, 0x0002, 0x1078, 0x158c, 0x147f, 0x157f, 0x0d7f, 0x007c, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, + 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x69f6, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, + 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a05, 0x0d7e, 0xa0e8, + 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, + 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, + 0x20a1, 0x020b, 0x1078, 0x6a34, 0x7810, 0x2068, 0x6860, 0x20a2, + 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x147f, + 0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a52, + 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, + 0x0078, 0x6a61, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, + 0x0500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, + 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, + 0xa0ec, 0xf000, 0x0040, 0x6a8b, 0xa06d, 0x1078, 0x495f, 0x0040, + 0x6a8b, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6a8b, + 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078, 0x6be0, 0xa016, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, + 0x00c0, 0x6aa2, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x6aaa, + 0x0078, 0x6aa5, 0xa006, 0x1079, 0x6aaa, 0x147f, 0x137f, 0x157f, + 0x0d7f, 0x007c, 0x6ab4, 0x6b4c, 0x6b57, 0x6b81, 0x6b95, 0x6bb1, + 0x6bbc, 0x6ab2, 0x1078, 0x1332, 0x017e, 0x037e, 0x694c, 0xa18c, + 0x0003, 0x0040, 0x6abf, 0xa186, 0x0003, 0x00c0, 0x6ace, 0x6b78, + 0x7824, 0xd0cc, 0x0040, 0x6ac5, 0xc3e5, 0x23a2, 0x6868, 0x20a2, + 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x6b8c, 0xa186, 0x0001, + 0x10c0, 0x1332, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x6ad8, 0xc3e5, + 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, + 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, 0x0300, 0x0040, + 0x6b46, 0xd3c4, 0x0040, 0x6aee, 0x687c, 0xa108, 0xd3cc, 0x0040, + 0x6af3, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d, 0xad80, 0x0020, + 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x6af8, 0x157f, 0x22a2, + 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6b46, 0x20a1, 0x020b, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x6b26, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, + 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6b35, 0x0d7e, 0xa0e8, + 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f, 0x7b24, 0xd3cc, + 0x0040, 0x6b3e, 0x20a3, 0x0889, 0x0078, 0x6b40, 0x20a3, 0x0898, + 0x20a2, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x61c2, 0x037f, + 0x017f, 0x1078, 0x6dfb, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, + 0x0040, 0x6b53, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x6b8a, 0x2011, + 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6b5e, 0xc2e5, 0x22a2, 0xa016, + 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, + 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x1078, 0x6dfb, + 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040, 0x6b88, 0xc2e5, + 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x60c3, 0x0018, 0x1078, 0x6dfb, 0x007c, 0x2011, 0x0100, 0x7824, + 0xd0cc, 0x0040, 0x6b9c, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7834, 0xa084, + 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x6dfb, + 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040, 0x6bb8, 0xc2e5, + 0x22a2, 0xa016, 0x0078, 0x6b8a, 0x037e, 0x7b10, 0xa384, 0xff00, + 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6bcf, 0x7824, 0xd0cc, + 0x0040, 0x6bcb, 0xc2e5, 0x22a2, 0x037f, 0x0078, 0x6b8a, 0x047e, + 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f, 0x0040, 0x6bd9, + 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f, 0x0078, 0x6b8c, + 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x6bfe, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, + 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6c0d, 0x0d7e, 0xa0e8, + 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, + 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824, 0xd0cc, 0x0040, + 0x6c15, 0x20a3, 0x0889, 0x0078, 0x6c17, 0x20a3, 0x0898, 0x20a3, + 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, + 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, + 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084, 0x0700, + 0x8007, 0x1079, 0x6c3a, 0x037f, 0x017f, 0x147f, 0x137f, 0x157f, + 0x0d7f, 0x007c, 0x6c42, 0x6c42, 0x6c44, 0x6c42, 0x6c42, 0x6c42, + 0x6c69, 0x6c42, 0x1078, 0x1332, 0x7910, 0xa18c, 0xf8ff, 0xa18d, + 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73, + 0x0d7e, 0x2069, 0xa752, 0x6804, 0xd0bc, 0x0040, 0x6c5e, 0x682c, + 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6c60, 0x20a3, 0x3f00, + 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078, 0x6dfb, + 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73, 0x20a3, + 0x7f00, 0x0078, 0x6c61, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6c91, 0x0d7e, + 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, + 0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, + 0x6ca0, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0100, + 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, + 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, 0x6dea, 0x22a2, + 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e, + 0x037e, 0x2061, 0x0100, 0x2071, 0xa700, 0x6130, 0x7818, 0x2068, + 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6cca, 0x6910, 0x6a14, 0x6430, + 0x0078, 0x6cce, 0x6910, 0x6a14, 0x736c, 0x7470, 0x781c, 0xa086, + 0x0006, 0x0040, 0x6d2d, 0xd5bc, 0x0040, 0x6cde, 0xa185, 0x0100, + 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6ce5, 0xa185, 0x0100, + 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809, 0x6077, + 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, + 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070, + 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, + 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xa582, 0x0080, 0x0048, 0x6d17, 0x6a00, 0xd2f4, 0x0040, 0x6d15, + 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6d17, 0x2011, 0x0000, 0x629e, + 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, + 0x0040, 0x6d24, 0x2009, 0x1b58, 0x1078, 0x5ad0, 0x037f, 0x047f, + 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c, + 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6d85, 0xd5bc, 0x0040, + 0x6d41, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, + 0x6d48, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, + 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, + 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, + 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, + 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, 0xa109, + 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xa582, 0x0080, 0x0048, 0x6d80, 0x6a00, 0xd2f4, 0x0040, + 0x6d7e, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6d80, 0x2011, 0x0000, + 0x629e, 0x6017, 0x0012, 0x0078, 0x6d1a, 0xd5bc, 0x0040, 0x6d90, + 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6d97, + 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x1078, + 0x495f, 0x0040, 0x6dad, 0x0d7e, 0x7810, 0xa06d, 0x684c, 0x0d7f, + 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6dad, 0x7824, 0xc0cd, + 0x7826, 0x6073, 0x0889, 0x0078, 0x6daf, 0x6073, 0x0898, 0x6077, + 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, + 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, + 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, + 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, + 0x0048, 0x6ddd, 0x6a00, 0xd2f4, 0x0040, 0x6ddb, 0x6a14, 0xa294, + 0x00ff, 0x0078, 0x6ddd, 0x2011, 0x0000, 0x629e, 0x7824, 0xd0cc, + 0x0040, 0x6de6, 0x6017, 0x0016, 0x0078, 0x6d1a, 0x6017, 0x0012, + 0x0078, 0x6d1a, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, + 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069, 0xa9b1, 0x6843, + 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x1078, 0x6e06, 0x1078, 0x5ac0, 0x007c, 0x007e, 0x6014, + 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f, 0x007c, 0x007e, + 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, + 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e, + 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, + 0x6e59, 0x1078, 0x6e0f, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, + 0x2061, 0xa9b1, 0x6128, 0xa192, 0x00c8, 0x00c8, 0x6e44, 0x8108, + 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6e54, 0x1078, 0x5ac0, + 0x1078, 0x6e06, 0x0078, 0x6e54, 0x6124, 0xa1e5, 0x0000, 0x0040, + 0x6e51, 0x1078, 0xa5d4, 0x1078, 0x5acb, 0x2009, 0x0014, 0x1078, + 0x775c, 0x0c7f, 0x0078, 0x6e54, 0x027f, 0x017f, 0x0d7f, 0x0c7f, + 0x007c, 0x2001, 0xa9cd, 0x2004, 0xa005, 0x00c0, 0x6e54, 0x0c7e, + 0x2061, 0xa9b1, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6e44, 0x8108, + 0x612a, 0x0c7f, 0x1078, 0x5ac0, 0x1078, 0x4224, 0x0078, 0x6e54, + 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5ad8, 0x2071, + 0xa9b1, 0x713c, 0x81ff, 0x0040, 0x6e9a, 0x2061, 0x0100, 0x2069, + 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6ea0, 0x6803, 0x1000, + 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x037f, + 0x713c, 0x2160, 0x1078, 0xa5d4, 0x2009, 0x004a, 0x1078, 0x775c, + 0x0078, 0x6e9a, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, + 0x0078, 0x6e8a, 0x0e7e, 0x2071, 0xa9b1, 0x7048, 0xd084, 0x0040, + 0x6ebc, 0x713c, 0x81ff, 0x0040, 0x6ebc, 0x2071, 0x0100, 0xa188, + 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x6eba, 0x7017, 0x0012, + 0x0078, 0x6ebc, 0x7017, 0x0016, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e, + 0x0c7e, 0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000, + 0x6018, 0x2068, 0x6ca0, 0x2071, 0xa9b1, 0x7018, 0x2068, 0x8dff, + 0x0040, 0x6ee6, 0x68a0, 0xa406, 0x0040, 0x6eda, 0x6854, 0x2068, + 0x0078, 0x6ecf, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60, + 0x1078, 0x4736, 0x0040, 0x6ee6, 0xa085, 0x0001, 0x127f, 0x007f, + 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, + 0x020b, 0x1078, 0x6731, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x781c, 0xa086, 0x0004, 0x00c0, 0x6f01, 0x6098, 0x0078, + 0x6f02, 0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, + 0x0010, 0xa006, 0x20a2, 0x00f0, 0x6f0a, 0x20a2, 0x20a2, 0x60c3, + 0x002c, 0x1078, 0x6dfb, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x6731, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x147f, 0x157f, + 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, + 0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0xa740, 0x2019, + 0xa741, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, + 0x6f39, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, + 0x6dfb, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, + 0x20a1, 0x020b, 0x1078, 0x6799, 0x1078, 0x67b0, 0x7810, 0xa080, + 0x0000, 0x2004, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, + 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6dfb, + 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x6731, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x147f, + 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, + 0x1078, 0x6731, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, + 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, + 0x1078, 0x6dfb, 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, + 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x700c, + 0x2060, 0x8cff, 0x0040, 0x6fbb, 0x1078, 0x8f10, 0x00c0, 0x6fb2, + 0x1078, 0x7c83, 0x600c, 0x007e, 0x1078, 0x772d, 0x1078, 0x7233, + 0x0c7f, 0x0078, 0x6fa9, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, + 0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, + 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, + 0x0100, 0x2079, 0x0140, 0x2071, 0xa9b1, 0x7024, 0x2060, 0x8cff, + 0x0040, 0x7014, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x5acb, + 0x2009, 0x0013, 0x1078, 0x775c, 0x20a9, 0x01f4, 0x6824, 0xd094, + 0x0040, 0x6ff7, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, + 0x7009, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x7009, 0xd084, + 0x0040, 0x6ffe, 0x6827, 0x0001, 0x0078, 0x7000, 0x00f0, 0x6fe6, + 0x7804, 0xa084, 0x1000, 0x0040, 0x7009, 0x7803, 0x0100, 0x7803, + 0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0xa700, 0x2004, 0xa096, + 0x0001, 0x0040, 0x704e, 0xa096, 0x0004, 0x0040, 0x704e, 0x1078, + 0x5acb, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x41dc, 0x1078, + 0x5a45, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x703c, 0x6827, + 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x704e, 0x7803, 0x1000, + 0x7803, 0x0000, 0x0078, 0x704e, 0xd084, 0x0040, 0x7043, 0x6827, + 0x0001, 0x0078, 0x7045, 0x00f0, 0x702b, 0x7804, 0xa084, 0x1000, + 0x0040, 0x704e, 0x7803, 0x0100, 0x7803, 0x0000, 0x007f, 0x017f, + 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, + 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, + 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0xa9b1, 0x703c, 0x2060, 0x8cff, 0x0040, 0x70d6, 0x68af, 0x95f5, + 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0, 0x7074, 0x68c7, + 0x0000, 0x68cb, 0x0008, 0x1078, 0x5ad8, 0x1078, 0x1f7e, 0x047e, + 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, 0x0169, + 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x70a5, 0x68c7, + 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079, 0x0020, 0x2071, + 0xaa08, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803, + 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a, 0x057f, 0x047f, + 0xa39d, 0x0000, 0x00c0, 0x70b0, 0x2009, 0x0049, 0x1078, 0x775c, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x70c3, 0x6827, 0x0004, + 0x7804, 0xa084, 0x4000, 0x0040, 0x70d5, 0x7803, 0x1000, 0x7803, + 0x0000, 0x0078, 0x70d5, 0xd08c, 0x0040, 0x70ca, 0x6827, 0x0002, + 0x0078, 0x70cc, 0x00f0, 0x70b2, 0x7804, 0xa084, 0x1000, 0x0040, + 0x70d5, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, + 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, + 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa9b1, 0x6a06, 0x127f, + 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa9b1, + 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, + 0x007e, 0x127e, 0x2071, 0xa9b1, 0x7614, 0x2660, 0x2678, 0x2091, + 0x8000, 0x8cff, 0x0040, 0x7134, 0x601c, 0xa206, 0x00c0, 0x712f, + 0x7014, 0xac36, 0x00c0, 0x710e, 0x660c, 0x7616, 0x7010, 0xac36, + 0x00c0, 0x711c, 0x2c00, 0xaf36, 0x0040, 0x711a, 0x2f00, 0x7012, + 0x0078, 0x711c, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, + 0x0040, 0x7125, 0x7e0e, 0x0078, 0x7126, 0x2678, 0x600f, 0x0000, + 0x1078, 0x8ed6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x7101, 0x2c78, + 0x600c, 0x2060, 0x0078, 0x7101, 0x127f, 0x007f, 0x067f, 0x0c7f, + 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, + 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, + 0x20a3, 0x1000, 0x0078, 0x718e, 0x157e, 0x147e, 0x20a1, 0x020b, + 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x20a3, 0x4000, 0x0078, 0x718e, 0x157e, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x718e, 0x157e, 0x147e, + 0x20a1, 0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x718e, 0x157e, + 0x147e, 0x20a1, 0x020b, 0x1078, 0x69d0, 0x7810, 0x20a2, 0xa006, + 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x723e, + 0x60c3, 0x0020, 0x1078, 0x6dfb, 0x147f, 0x157f, 0x007c, 0x127e, + 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, + 0x71a6, 0xd1bc, 0x00c0, 0x71f0, 0x0078, 0x7230, 0x2009, 0x017f, + 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, + 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x71e7, + 0x6020, 0xd0b4, 0x0040, 0x71e7, 0x6024, 0xd094, 0x00c0, 0x71e7, + 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x71e7, 0x00f0, + 0x71b3, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, + 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, + 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, + 0x71e6, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x71dd, 0x027f, 0x0d7f, + 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x7230, + 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, + 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, + 0x0040, 0x7229, 0x6020, 0xd0bc, 0x0040, 0x7229, 0x2104, 0xa084, + 0x000f, 0xa086, 0x0004, 0x00c0, 0x7229, 0x00f0, 0x71fd, 0x027e, + 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, + 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, + 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x7223, + 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, + 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa9b1, 0x7020, 0xa005, + 0x0040, 0x723c, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, + 0x20a2, 0x00f0, 0x7240, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, + 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, + 0x2071, 0xa9b1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, + 0x0040, 0x72e2, 0x8cff, 0x0040, 0x72e2, 0x601c, 0xa086, 0x0006, + 0x00c0, 0x72dd, 0x88ff, 0x0040, 0x726d, 0x2800, 0xac06, 0x00c0, + 0x72dd, 0x2039, 0x0000, 0x0078, 0x7278, 0x6018, 0xa206, 0x00c0, + 0x72dd, 0x85ff, 0x0040, 0x7278, 0x6020, 0xa106, 0x00c0, 0x72dd, + 0x7024, 0xac06, 0x00c0, 0x72a8, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x0040, 0x72a3, 0x1078, 0x5acb, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x1078, 0x7378, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, + 0xa384, 0x1000, 0x0040, 0x7298, 0x6803, 0x0100, 0x6803, 0x0000, + 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x72a0, 0x6827, 0x0001, + 0x037f, 0x0078, 0x72a8, 0x6003, 0x0009, 0x630a, 0x0078, 0x72dd, + 0x7014, 0xac36, 0x00c0, 0x72ae, 0x660c, 0x7616, 0x7010, 0xac36, + 0x00c0, 0x72bc, 0x2c00, 0xaf36, 0x0040, 0x72ba, 0x2f00, 0x7012, + 0x0078, 0x72bc, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, + 0x0040, 0x72c5, 0x7e0e, 0x0078, 0x72c6, 0x2678, 0x89ff, 0x00c0, + 0x72d5, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, + 0x72d3, 0x1078, 0xa1da, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x88ff, + 0x00c0, 0x72ec, 0x0c7f, 0x0078, 0x7257, 0x2c78, 0x600c, 0x2060, + 0x0078, 0x7257, 0xa006, 0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f, + 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, + 0x0001, 0x0078, 0x72e3, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, + 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0040, 0x7367, 0x601c, 0xa086, 0x0006, + 0x00c0, 0x7362, 0x87ff, 0x0040, 0x7313, 0x2700, 0xac06, 0x00c0, + 0x7362, 0x0078, 0x731e, 0x6018, 0xa206, 0x00c0, 0x7362, 0x85ff, + 0x0040, 0x731e, 0x6020, 0xa106, 0x00c0, 0x7362, 0x703c, 0xac06, + 0x00c0, 0x7332, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x7033, + 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b, + 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7338, 0x660c, 0x763a, + 0x7034, 0xac36, 0x00c0, 0x7346, 0x2c00, 0xaf36, 0x0040, 0x7344, + 0x2f00, 0x7036, 0x0078, 0x7346, 0x7037, 0x0000, 0x660c, 0x067e, + 0x2c00, 0xaf06, 0x0040, 0x734f, 0x7e0e, 0x0078, 0x7350, 0x2678, + 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x735a, + 0x1078, 0xa1da, 0x1078, 0x8ed6, 0x87ff, 0x00c0, 0x7371, 0x0c7f, + 0x0078, 0x7302, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7302, 0xa006, + 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7368, + 0x0e7e, 0x2071, 0xa9b1, 0x2001, 0xa700, 0x2004, 0xa086, 0x0002, + 0x00c0, 0x7386, 0x7007, 0x0005, 0x0078, 0x7388, 0x7007, 0x0000, + 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e, + 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x2c10, 0x7638, 0x2660, + 0x2678, 0x8cff, 0x0040, 0x73c8, 0x2200, 0xac06, 0x00c0, 0x73c3, + 0x7038, 0xac36, 0x00c0, 0x73a6, 0x660c, 0x763a, 0x7034, 0xac36, + 0x00c0, 0x73b4, 0x2c00, 0xaf36, 0x0040, 0x73b2, 0x2f00, 0x7036, + 0x0078, 0x73b4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040, + 0x73bc, 0x7e0e, 0x0078, 0x73bd, 0x2678, 0x600f, 0x0000, 0xa085, + 0x0001, 0x0078, 0x73c8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7399, + 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, + 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091, + 0x8000, 0x2071, 0xa9b1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040, + 0x7469, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7464, + 0x7024, 0xac06, 0x00c0, 0x740f, 0x2069, 0x0100, 0x68c0, 0xa005, + 0x0040, 0x743d, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378, + 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0040, 0x7406, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0040, 0x740e, 0x6827, 0x0001, 0x037f, 0x700c, + 0xac36, 0x00c0, 0x7415, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0, + 0x7423, 0x2c00, 0xaf36, 0x0040, 0x7421, 0x2f00, 0x700a, 0x0078, + 0x7423, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, + 0x742c, 0x7e0e, 0x0078, 0x742d, 0x2678, 0x600f, 0x0000, 0x1078, + 0x8efc, 0x00c0, 0x7441, 0x1078, 0x28a6, 0x1078, 0x8f10, 0x00c0, + 0x745d, 0x1078, 0x7c83, 0x0078, 0x745d, 0x1078, 0x7378, 0x0078, + 0x740f, 0x1078, 0x8f10, 0x00c0, 0x7449, 0x1078, 0x7c83, 0x0078, + 0x745d, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x745d, 0x601c, + 0xa086, 0x0003, 0x00c0, 0x7471, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x1078, + 0x7233, 0x0c7f, 0x0078, 0x73de, 0x2c78, 0x600c, 0x2060, 0x0078, + 0x73de, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, + 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x745d, 0x1078, 0xa1da, + 0x0078, 0x745d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006, + 0xa190, 0x0020, 0x221c, 0xa39e, 0x2676, 0x00c0, 0x748b, 0x8210, + 0x8000, 0x0078, 0x7482, 0xa005, 0x0040, 0x7497, 0x20a9, 0x0020, + 0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f, + 0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, + 0x67c2, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x2099, 0xa9a5, 0x20a9, 0x0004, 0x53a6, + 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2, + 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, + 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6dfb, + 0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x91cc, + 0x00c0, 0x7551, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x1300, + 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040, + 0x752d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, + 0x7507, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7542, 0xa286, + 0x007f, 0x00c0, 0x7511, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078, + 0x7542, 0xd2bc, 0x0040, 0x7527, 0xa286, 0x0080, 0x00c0, 0x751e, + 0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7542, 0xa2e8, 0xa835, + 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7542, 0x20a3, + 0x0000, 0x6098, 0x20a2, 0x0078, 0x7542, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa082, 0x007e, 0x0048, 0x753e, 0x0d7e, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7542, 0x20a3, 0x0000, + 0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x017f, 0x0d7f, + 0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c, + 0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040, + 0x757a, 0xa186, 0x0003, 0x0040, 0x75d5, 0xa186, 0x0005, 0x0040, + 0x75b8, 0xa186, 0x0004, 0x0040, 0x75a8, 0xa186, 0x0008, 0x0040, + 0x75c2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7640, 0x027f, + 0x0d7f, 0x007c, 0x1078, 0x75fd, 0x2009, 0x4000, 0x6800, 0x0079, + 0x7581, 0x7594, 0x75a2, 0x7596, 0x75a2, 0x759d, 0x7594, 0x7594, + 0x75a2, 0x75a2, 0x75a2, 0x75a2, 0x7594, 0x7594, 0x7594, 0x7594, + 0x7594, 0x75a2, 0x7594, 0x75a2, 0x1078, 0x1332, 0x6824, 0xd0e4, + 0x0040, 0x759d, 0xd0cc, 0x0040, 0x75a0, 0xa00e, 0x0078, 0x75a2, + 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x75f3, + 0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, + 0x6a00, 0xa286, 0x0002, 0x00c0, 0x75b6, 0xa00e, 0x0078, 0x75f3, + 0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, + 0x0078, 0x75f3, 0x1078, 0x75fd, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x75d2, 0xa286, 0x0002, + 0x00c0, 0x75d3, 0xa00e, 0x0078, 0x75f3, 0x1078, 0x75fd, 0x6810, + 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, + 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040, + 0x75f1, 0xa08e, 0x0004, 0x0040, 0x75f1, 0x2009, 0x4000, 0x0078, + 0x75f3, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018, + 0x1078, 0x6dfb, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e, + 0x067e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0xa006, 0x20a3, 0x0200, + 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028, + 0x2004, 0xa092, 0x007e, 0x0048, 0x7623, 0x0d7e, 0x2069, 0xa71b, + 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa835, 0x2d6c, 0x6b10, 0x6c14, + 0x0d7f, 0x0078, 0x7629, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000, + 0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0, + 0x7637, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x763b, 0x23a2, + 0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c, + 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3, 0x0100, 0x20a3, 0x0000, + 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, + 0x007c, 0x20a1, 0x020b, 0x1078, 0x6728, 0x20a3, 0x1400, 0x20a3, + 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c, + 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000, + 0x60c3, 0x0010, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, + 0x67b9, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810, + 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x147e, 0x20a1, + 0x020b, 0x1078, 0x7689, 0x60c3, 0x0000, 0x1078, 0x6dfb, 0x147f, + 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0xd0bc, 0x0040, 0x76a6, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, + 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, + 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x76ae, 0x20a3, 0x0300, + 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819, + 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x2fa2, + 0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061, + 0xae00, 0x2a70, 0x7064, 0x704a, 0x704f, 0xae00, 0x007c, 0x0e7e, + 0x127e, 0x2071, 0xa700, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010, + 0x0048, 0x76f9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, + 0x76e5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x76e1, 0x0078, + 0x76d4, 0x2061, 0xae00, 0x0078, 0x76d4, 0x6003, 0x0008, 0x8529, + 0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x76f5, 0x754e, + 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xae00, 0x0078, + 0x76f0, 0xa006, 0x0078, 0x76f2, 0x0e7e, 0x2071, 0xa700, 0x7548, + 0xa582, 0x0010, 0x0048, 0x772a, 0x704c, 0x2060, 0x6000, 0xa086, + 0x0000, 0x0040, 0x7717, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, + 0x7713, 0x0078, 0x7706, 0x2061, 0xae00, 0x0078, 0x7706, 0x6003, + 0x0008, 0x8529, 0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, + 0x7726, 0x754e, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704f, 0xae00, + 0x0078, 0x7722, 0xa006, 0x0078, 0x7724, 0xac82, 0xae00, 0x1048, + 0x1332, 0x2001, 0xa716, 0x2004, 0xac02, 0x10c8, 0x1332, 0xa006, + 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, + 0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, + 0x603a, 0x603e, 0x2061, 0xa700, 0x6048, 0x8000, 0x604a, 0xa086, + 0x0001, 0x0040, 0x7754, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, + 0x62d1, 0x127f, 0x0078, 0x7753, 0x601c, 0xa084, 0x000f, 0x0079, + 0x7761, 0x776a, 0x777b, 0x7797, 0x77b3, 0x921e, 0x923a, 0x9256, + 0x776a, 0x777b, 0xa186, 0x0013, 0x00c0, 0x7773, 0x1078, 0x61cd, + 0x1078, 0x62d1, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x777a, 0xa016, + 0x1078, 0x15fa, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, + 0x1332, 0x1079, 0x7785, 0x067f, 0x007c, 0x7795, 0x7b00, 0x7cb2, + 0x7795, 0x7d36, 0x77cf, 0x7795, 0x7795, 0x7a92, 0x80f6, 0x7795, + 0x7795, 0x7795, 0x7795, 0x7795, 0x7795, 0x1078, 0x1332, 0x067e, + 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x77a1, 0x067f, + 0x007c, 0x77b1, 0x87d3, 0x77b1, 0x77b1, 0x77b1, 0x77b1, 0x77b1, + 0x77b1, 0x8776, 0x8961, 0x77b1, 0x8803, 0x8889, 0x8803, 0x8889, + 0x77b1, 0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, + 0x1332, 0x1079, 0x77bd, 0x067f, 0x007c, 0x77cd, 0x813d, 0x820e, + 0x8372, 0x84f1, 0x77cd, 0x77cd, 0x77cd, 0x8116, 0x871e, 0x8722, + 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x8752, 0x1078, 0x1332, 0xa1b6, + 0x0015, 0x00c0, 0x77d7, 0x1078, 0x772d, 0x0078, 0x77dd, 0xa1b6, + 0x0016, 0x10c0, 0x1332, 0x1078, 0x772d, 0x007c, 0x20a9, 0x000e, + 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, + 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, + 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x77ec, + 0x0e7e, 0x1078, 0x8d16, 0x0040, 0x7803, 0x6010, 0x2070, 0x7007, + 0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0d7e, + 0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7814, 0x6018, 0x2068, + 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x781e, + 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x772d, + 0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c, + 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, + 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, + 0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, + 0x772d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68, + 0x017e, 0x2009, 0x0035, 0x1078, 0x91cc, 0x017f, 0x00c0, 0x785f, + 0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xac8c, 0x6b1c, 0xa386, + 0x0003, 0x0040, 0x7863, 0xa386, 0x0006, 0x0040, 0x7867, 0x1078, + 0x772d, 0x0078, 0x7869, 0x1078, 0x786c, 0x0078, 0x7869, 0x1078, + 0x7938, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186, + 0x0015, 0x0040, 0x791d, 0xa18e, 0x0016, 0x00c0, 0x7936, 0x700c, + 0xa08c, 0xff00, 0xa186, 0x1700, 0x0040, 0x7882, 0xa186, 0x0300, + 0x00c0, 0x78f8, 0x8fff, 0x00c0, 0x788c, 0x6800, 0xa086, 0x000f, + 0x0040, 0x78db, 0x0078, 0x7934, 0x6808, 0xa086, 0xffff, 0x00c0, + 0x7921, 0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x00c0, 0x78a2, + 0x797c, 0x7810, 0xa106, 0x00c0, 0x7921, 0x7980, 0x7814, 0xa106, + 0x00c0, 0x7921, 0x1078, 0x8ec9, 0x6830, 0x7852, 0x784c, 0xc0dc, + 0xc0f4, 0xc0d4, 0x784e, 0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, + 0x1078, 0x5c1c, 0x7854, 0xa20a, 0x0048, 0x78b7, 0x8011, 0x7a56, + 0x82ff, 0x027f, 0x00c0, 0x78c3, 0x0c7e, 0x2d60, 0x1078, 0x8af0, + 0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, + 0x00c0, 0x78ce, 0x1078, 0x4353, 0x0078, 0x78d0, 0x1078, 0x4431, + 0x0d7f, 0x0c7f, 0x00c0, 0x7921, 0x0c7e, 0x2d60, 0x1078, 0x772d, + 0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x1078, 0x9197, 0x0040, 0x78f1, + 0x6013, 0x0000, 0x6818, 0x601a, 0x601f, 0x0003, 0x6904, 0x0c7e, + 0x2d60, 0x1078, 0x772d, 0x0c7f, 0x1078, 0x775c, 0x0c7f, 0x0078, + 0x7934, 0x2001, 0xa9a4, 0x2004, 0x683e, 0x0c7f, 0x0078, 0x7934, + 0x7008, 0xa086, 0x000b, 0x00c0, 0x7912, 0x6018, 0x200c, 0xc1bc, + 0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003, + 0x000b, 0x601f, 0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f, + 0x0078, 0x7934, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7921, 0x2001, + 0xa9a4, 0x2004, 0x683e, 0x0078, 0x7934, 0x1078, 0x7953, 0x0078, + 0x7936, 0x8fff, 0x1040, 0x1332, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68, + 0x6837, 0x0103, 0x684b, 0x0003, 0x1078, 0x89df, 0x1078, 0x8ec9, + 0x1078, 0x8ed6, 0x0d7f, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c, + 0xa186, 0x0015, 0x00c0, 0x7942, 0x2001, 0xa9a4, 0x2004, 0x683e, + 0x0078, 0x7950, 0xa18e, 0x0016, 0x00c0, 0x7952, 0x0c7e, 0x2d00, + 0x2060, 0x1078, 0xa4a5, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x0c7f, + 0x1078, 0x772d, 0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, + 0x7b7c, 0xd2f4, 0x0040, 0x7962, 0x2001, 0xa9a4, 0x2004, 0x683e, + 0x0078, 0x79c6, 0x0c7e, 0x2d60, 0x1078, 0x8a03, 0x0c7f, 0x6804, + 0xa086, 0x0050, 0x00c0, 0x797a, 0x0c7e, 0x2d00, 0x2060, 0x6003, + 0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f, + 0x0078, 0x79c6, 0x6800, 0xa086, 0x000f, 0x0040, 0x799c, 0x8fff, + 0x1040, 0x1332, 0x6824, 0xd0dc, 0x00c0, 0x799c, 0x6800, 0xa086, + 0x0004, 0x00c0, 0x79a1, 0x784c, 0xd0ac, 0x0040, 0x79a1, 0x784c, + 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, + 0x0001, 0x682e, 0x0078, 0x79c0, 0x2001, 0x0007, 0x682e, 0x0078, + 0x79c0, 0x784c, 0xd0b4, 0x00c0, 0x79ae, 0xd0ac, 0x0040, 0x799c, + 0x784c, 0xd0f4, 0x00c0, 0x799c, 0x0078, 0x798f, 0xd2ec, 0x00c0, + 0x799c, 0x7024, 0xa306, 0x00c0, 0x79b9, 0x7020, 0xa406, 0x0040, + 0x799c, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, + 0x1078, 0x9000, 0x1078, 0x62d1, 0x0078, 0x79c8, 0x1078, 0x772d, + 0x047f, 0x037f, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, + 0x2068, 0x6a1c, 0xa286, 0x0007, 0x0040, 0x7a35, 0xa286, 0x0002, + 0x0040, 0x7a35, 0xa286, 0x0000, 0x0040, 0x7a35, 0x6808, 0x6338, + 0xa306, 0x00c0, 0x7a35, 0x2071, 0xac8c, 0xa186, 0x0015, 0x0040, + 0x7a2f, 0xa18e, 0x0016, 0x00c0, 0x7a02, 0x6030, 0xa084, 0x00ff, + 0xa086, 0x0001, 0x00c0, 0x7a02, 0x700c, 0xa086, 0x2a00, 0x00c0, + 0x7a02, 0x6034, 0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, + 0x0078, 0x7a2f, 0x0c7e, 0x6034, 0x2060, 0x6104, 0xa186, 0x004b, + 0x0040, 0x7a22, 0xa186, 0x004c, 0x0040, 0x7a22, 0xa186, 0x004d, + 0x0040, 0x7a22, 0xa186, 0x004e, 0x0040, 0x7a22, 0xa186, 0x0052, + 0x0040, 0x7a22, 0x6010, 0x2068, 0x1078, 0x8d16, 0x1040, 0x1332, + 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, + 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f, 0x0078, 0x7a35, 0x6034, + 0x2068, 0x2001, 0xa9a4, 0x2004, 0x683e, 0x1078, 0x772d, 0x027f, + 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, + 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7a73, 0x6018, 0x2068, + 0x157e, 0x037e, 0x027e, 0xae90, 0x000c, 0xa290, 0x0004, 0x20a9, + 0x0004, 0xad98, 0x000a, 0x1078, 0x80de, 0x027f, 0x037f, 0x157f, + 0x00c0, 0x7a76, 0x157e, 0x037e, 0x027e, 0xae90, 0x000c, 0xa290, + 0x0008, 0x20a9, 0x0004, 0xad98, 0x0006, 0x1078, 0x80de, 0x027f, + 0x037f, 0x157f, 0x00c0, 0x7a76, 0x7038, 0x680a, 0x703c, 0x680e, + 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x77f8, 0x1078, 0x2880, + 0x0c7e, 0x1078, 0x76c7, 0x2f00, 0x601a, 0x6013, 0x0000, 0x601f, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x1078, + 0x4502, 0x1078, 0x4535, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0c7f, + 0x0078, 0x7a73, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1332, 0xa1b2, + 0x0040, 0x00c8, 0x7af7, 0x0079, 0x7a9d, 0x7aeb, 0x7adf, 0x7aeb, + 0x7aeb, 0x7aeb, 0x7aeb, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, + 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, + 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, + 0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb, 0x7add, 0x7aeb, 0x7aeb, + 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb, 0x7add, 0x7add, + 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7aeb, + 0x7aeb, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, 0x7add, + 0x7add, 0x7add, 0x7aeb, 0x7add, 0x7add, 0x1078, 0x1332, 0x6003, + 0x0001, 0x6106, 0x1078, 0x5dd7, 0x127e, 0x2091, 0x8000, 0x1078, + 0x62d1, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5dd7, + 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x2600, + 0x0079, 0x7afa, 0x7afe, 0x7afe, 0x7afe, 0x7aeb, 0x1078, 0x1332, + 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0, + 0x7b10, 0xa0b2, 0x0040, 0x00c8, 0x7c79, 0x2008, 0x0079, 0x7bbf, + 0xa1b6, 0x0027, 0x00c0, 0x7b7c, 0x1078, 0x61cd, 0x6004, 0x1078, + 0x8efc, 0x0040, 0x7b2d, 0x1078, 0x8f10, 0x0040, 0x7b74, 0xa08e, + 0x0021, 0x0040, 0x7b78, 0xa08e, 0x0022, 0x0040, 0x7b74, 0xa08e, + 0x003d, 0x0040, 0x7b78, 0x0078, 0x7b6f, 0x1078, 0x28a6, 0x2001, + 0x0007, 0x1078, 0x4502, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, + 0x7c83, 0xa186, 0x007e, 0x00c0, 0x7b42, 0x2001, 0xa733, 0x2014, + 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, + 0x0028, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, 0x027f, + 0x017f, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, + 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x0c7e, 0x6018, + 0xa065, 0x0040, 0x7b65, 0x1078, 0x47e9, 0x0c7f, 0x2c08, 0x1078, + 0x9f9b, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078, 0x457f, 0x1078, + 0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x7b6f, + 0x1078, 0x7ca6, 0x0078, 0x7b6f, 0xa186, 0x0014, 0x00c0, 0x7b73, + 0x1078, 0x61cd, 0x1078, 0x2880, 0x1078, 0x8efc, 0x00c0, 0x7b9b, + 0x1078, 0x28a6, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x7c83, + 0xa186, 0x007e, 0x00c0, 0x7b99, 0x2001, 0xa733, 0x200c, 0xc185, + 0x2102, 0x0078, 0x7b6f, 0x1078, 0x8f10, 0x00c0, 0x7ba3, 0x1078, + 0x7c83, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0032, 0x00c0, 0x7bb4, + 0x0e7e, 0x0f7e, 0x2071, 0xa782, 0x2079, 0x0000, 0x1078, 0x2bd7, + 0x0f7f, 0x0e7f, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0021, 0x0040, + 0x7b9f, 0xa08e, 0x0022, 0x1040, 0x7c83, 0x0078, 0x7b6f, 0x7c01, + 0x7c03, 0x7c07, 0x7c0b, 0x7c0f, 0x7c13, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7c17, 0x7c29, 0x7bff, + 0x7c2b, 0x7c29, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7c29, + 0x7c29, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, + 0x7bff, 0x7c5c, 0x7c29, 0x7bff, 0x7c23, 0x7bff, 0x7bff, 0x7bff, + 0x7c25, 0x7bff, 0x7bff, 0x7bff, 0x7c29, 0x7bff, 0x7bff, 0x1078, + 0x1332, 0x0078, 0x7c29, 0x2001, 0x000b, 0x0078, 0x7c36, 0x2001, + 0x0003, 0x0078, 0x7c36, 0x2001, 0x0005, 0x0078, 0x7c36, 0x2001, + 0x0001, 0x0078, 0x7c36, 0x2001, 0x0009, 0x0078, 0x7c36, 0x1078, + 0x61cd, 0x6003, 0x0005, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x1078, + 0x62d1, 0x0078, 0x7c35, 0x0078, 0x7c29, 0x0078, 0x7c29, 0x1078, + 0x4502, 0x0078, 0x7c6e, 0x1078, 0x61cd, 0x6003, 0x0004, 0x2001, + 0xa9a2, 0x2004, 0x6016, 0x1078, 0x62d1, 0x007c, 0x1078, 0x4502, + 0x1078, 0x61cd, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002, + 0x037e, 0x2019, 0xa75d, 0x2304, 0xa084, 0xff00, 0x00c0, 0x7c4d, + 0x2019, 0xa9a2, 0x231c, 0x0078, 0x7c56, 0x8007, 0xa09a, 0x0004, + 0x0048, 0x7c48, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f, + 0x1078, 0x62d1, 0x0078, 0x7c35, 0x0e7e, 0x0f7e, 0x2071, 0xa782, + 0x2079, 0x0000, 0x1078, 0x2bd7, 0x0f7f, 0x0e7f, 0x1078, 0x61cd, + 0x1078, 0x772d, 0x1078, 0x62d1, 0x0078, 0x7c35, 0x1078, 0x61cd, + 0x6003, 0x0002, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x1078, 0x62d1, + 0x007c, 0x2600, 0x2008, 0x0079, 0x7c7d, 0x7c81, 0x7c81, 0x7c81, + 0x7c6e, 0x1078, 0x1332, 0x0e7e, 0x1078, 0x8d16, 0x0040, 0x7c9f, + 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7c9f, 0x7007, 0x0000, + 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7ca1, 0xa08e, 0x003d, + 0x0040, 0x7ca1, 0x017f, 0x7037, 0x0103, 0x7033, 0x0100, 0x0e7f, + 0x007c, 0x017f, 0x1078, 0x7ca6, 0x0078, 0x7c9f, 0x0e7e, 0xacf0, + 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, + 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, + 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0x6604, 0xa6b6, 0x0043, + 0x00c0, 0x7cc6, 0x1078, 0x9144, 0x0078, 0x7d25, 0x6604, 0xa6b6, + 0x0033, 0x00c0, 0x7ccf, 0x1078, 0x90e8, 0x0078, 0x7d25, 0x6604, + 0xa6b6, 0x0028, 0x00c0, 0x7cd8, 0x1078, 0x8f3f, 0x0078, 0x7d25, + 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7ce1, 0x1078, 0x8f59, 0x0078, + 0x7d25, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7cea, 0x1078, 0x77de, + 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0000, 0x00c0, 0x7cf3, 0x1078, + 0x7a3b, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0022, 0x00c0, 0x7cfc, + 0x1078, 0x7807, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0035, 0x00c0, + 0x7d05, 0x1078, 0x7843, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0039, + 0x00c0, 0x7d0e, 0x1078, 0x79cc, 0x0078, 0x7d25, 0x6604, 0xa6b6, + 0x003d, 0x00c0, 0x7d17, 0x1078, 0x7823, 0x0078, 0x7d25, 0xa1b6, + 0x0015, 0x00c0, 0x7d1f, 0x1079, 0x7d2a, 0x0078, 0x7d25, 0xa1b6, + 0x0016, 0x00c0, 0x7d26, 0x1079, 0x7e7f, 0x007c, 0x1078, 0x7773, + 0x0078, 0x7d25, 0x7d4e, 0x7d51, 0x7d4e, 0x7d9c, 0x7d4e, 0x7e13, + 0x7e8b, 0x7d4e, 0x7d4e, 0x7e57, 0x7d4e, 0x7e6d, 0xa1b6, 0x0048, + 0x0040, 0x7d42, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x15fa, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, + 0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0005, 0x0005, + 0x007c, 0x0e7e, 0x2071, 0xa700, 0x7080, 0xa086, 0x0074, 0x00c0, + 0x7d85, 0x1078, 0x9f6f, 0x00c0, 0x7d77, 0x0d7e, 0x6018, 0x2068, + 0x7030, 0xd08c, 0x0040, 0x7d6a, 0x6800, 0xd0bc, 0x0040, 0x7d6a, + 0xc0c5, 0x6802, 0x1078, 0x7d89, 0x0d7f, 0x2001, 0x0006, 0x1078, + 0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078, 0x7d87, 0x2001, + 0x000a, 0x1078, 0x4502, 0x1078, 0x28a6, 0x6003, 0x0001, 0x6007, + 0x0001, 0x1078, 0x5dd7, 0x0078, 0x7d87, 0x1078, 0x7dff, 0x0e7f, + 0x007c, 0x6800, 0xd084, 0x0040, 0x7d9b, 0x2001, 0x0000, 0x1078, + 0x44ee, 0x2069, 0xa752, 0x6804, 0xd0a4, 0x0040, 0x7d9b, 0x2001, + 0x0006, 0x1078, 0x4535, 0x007c, 0x0d7e, 0x2011, 0xa720, 0x2204, + 0xa086, 0x0074, 0x00c0, 0x7dfb, 0x6018, 0x2068, 0x6aa0, 0xa286, + 0x007e, 0x00c0, 0x7daf, 0x1078, 0x7f9b, 0x0078, 0x7dfd, 0x1078, + 0x7f91, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286, 0x0080, + 0x00c0, 0x7dd3, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, + 0x0040, 0x7dc9, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, + 0x0200, 0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x28a6, 0x1078, + 0x772d, 0x0078, 0x7dfd, 0x0e7e, 0x2071, 0xa733, 0x2e04, 0xd09c, + 0x0040, 0x7dee, 0x2071, 0xac80, 0x7108, 0x720c, 0xa18c, 0x00ff, + 0x00c0, 0x7de6, 0xa284, 0xff00, 0x0040, 0x7dee, 0x6018, 0x2070, + 0x70a0, 0xd0bc, 0x00c0, 0x7dee, 0x7112, 0x7216, 0x0e7f, 0x2001, + 0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, + 0x5dd7, 0x0078, 0x7dfd, 0x1078, 0x7dff, 0x0d7f, 0x007c, 0x2001, + 0x0007, 0x1078, 0x4502, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, + 0x00c0, 0x7e0e, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x28a6, + 0x1078, 0x772d, 0x007c, 0x0e7e, 0x2071, 0xa700, 0x7080, 0xa086, + 0x0014, 0x00c0, 0x7e51, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7e26, + 0x6010, 0xa005, 0x00c0, 0x7e26, 0x1078, 0x3699, 0x0d7e, 0x6018, + 0x2068, 0x1078, 0x4649, 0x1078, 0x7d89, 0x0d7f, 0x1078, 0x8043, + 0x00c0, 0x7e51, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, + 0x0040, 0x7e51, 0x2001, 0x0006, 0x1078, 0x4502, 0x0e7e, 0x6010, + 0xa005, 0x0040, 0x7e4a, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, + 0x7033, 0x0200, 0x0e7f, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078, + 0x7e55, 0x1078, 0x7c83, 0x1078, 0x7dff, 0x0e7f, 0x007c, 0x2011, + 0xa720, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7e6a, 0x2001, 0x0002, + 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5dd7, + 0x0078, 0x7e6c, 0x1078, 0x7dff, 0x007c, 0x2011, 0xa720, 0x2204, + 0xa086, 0x0004, 0x00c0, 0x7e7c, 0x2001, 0x0007, 0x1078, 0x4502, + 0x1078, 0x772d, 0x0078, 0x7e7e, 0x1078, 0x7dff, 0x007c, 0x7d4e, + 0x7e97, 0x7d4e, 0x7ed2, 0x7d4e, 0x7f44, 0x7e8b, 0x7d4e, 0x7d4e, + 0x7f59, 0x7d4e, 0x7f6c, 0x6604, 0xa686, 0x0003, 0x0040, 0x7e13, + 0xa6b6, 0x001e, 0x00c0, 0x7e96, 0x1078, 0x772d, 0x007c, 0x0d7e, + 0x0c7e, 0x1078, 0x7f7f, 0x00c0, 0x7ead, 0x2001, 0x0000, 0x1078, + 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, + 0x0002, 0x1078, 0x5dd7, 0x0078, 0x7ecf, 0x2009, 0xac8e, 0x2104, + 0xa086, 0x0009, 0x00c0, 0x7ec2, 0x6018, 0x2068, 0x6840, 0xa084, + 0x00ff, 0xa005, 0x0040, 0x7ecd, 0x8001, 0x6842, 0x6017, 0x000a, + 0x0078, 0x7ecf, 0x2009, 0xac8f, 0x2104, 0xa084, 0xff00, 0xa086, + 0x1900, 0x00c0, 0x7ecd, 0x0078, 0x7ea1, 0x1078, 0x7dff, 0x0c7f, + 0x0d7f, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7ee6, 0x2001, 0x0000, + 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001, + 0x6007, 0x0002, 0x1078, 0x5dd7, 0x0078, 0x7f12, 0x1078, 0x7c83, + 0x2009, 0xac8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040, + 0x7f13, 0xa686, 0x000b, 0x0040, 0x7f10, 0x2009, 0xac8f, 0x2104, + 0xa084, 0xff00, 0x00c0, 0x7f00, 0xa686, 0x0009, 0x0040, 0x7f13, + 0xa086, 0x1900, 0x00c0, 0x7f10, 0xa686, 0x0009, 0x0040, 0x7f13, + 0x2001, 0x0004, 0x1078, 0x4502, 0x1078, 0x772d, 0x0078, 0x7f12, + 0x1078, 0x7dff, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, + 0x0040, 0x7f21, 0x6838, 0xd0fc, 0x0040, 0x7f21, 0x0d7f, 0x0078, + 0x7f10, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, + 0x7f32, 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, + 0x0078, 0x7f12, 0x68a0, 0xa086, 0x007e, 0x00c0, 0x7f3f, 0x0e7e, + 0x2071, 0xa700, 0x1078, 0x42b8, 0x0e7f, 0x0078, 0x7f41, 0x1078, + 0x2880, 0x0d7f, 0x0078, 0x7f10, 0x1078, 0x7f8e, 0x00c0, 0x7f54, + 0x2001, 0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003, + 0x1078, 0x5dd7, 0x0078, 0x7f58, 0x1078, 0x7c83, 0x1078, 0x7dff, + 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7f69, 0x2001, 0x0008, 0x1078, + 0x4502, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x5dd7, 0x0078, + 0x7f6b, 0x1078, 0x7dff, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7f7c, + 0x2001, 0x000a, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001, + 0x1078, 0x5dd7, 0x0078, 0x7f7e, 0x1078, 0x7dff, 0x007c, 0x2009, + 0xac8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x7f8d, 0x2009, 0xac8f, + 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001, + 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x45d6, + 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x037e, 0x017e, + 0x6018, 0x2068, 0x2071, 0xa733, 0x2e04, 0xa085, 0x0003, 0x2072, + 0x1078, 0x8014, 0x0040, 0x7fd9, 0x2009, 0xa733, 0x2104, 0xc0cd, + 0x200a, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x7fc2, 0xa006, + 0x2020, 0x2009, 0x002a, 0x1078, 0xa22d, 0x2001, 0xa70c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x284f, + 0x2071, 0xa700, 0x1078, 0x2677, 0x0c7e, 0x157e, 0x20a9, 0x0081, + 0x2009, 0x007f, 0x1078, 0x298e, 0x8108, 0x00f0, 0x7fd2, 0x157f, + 0x0c7f, 0x1078, 0x7f91, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, + 0xac80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa71b, + 0x206a, 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa71c, 0x206a, + 0x78ea, 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa726, 0x200a, + 0x2069, 0xac8e, 0x2071, 0xa99e, 0x6810, 0x2072, 0x6814, 0x7006, + 0x6818, 0x700a, 0x681c, 0x700e, 0x1078, 0x907e, 0x2001, 0x0006, + 0x1078, 0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x017f, 0x037f, + 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, + 0x2019, 0xa726, 0x231c, 0x83ff, 0x0040, 0x803e, 0x2071, 0xac80, + 0x2e14, 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, + 0x00c0, 0x803e, 0x2011, 0xac96, 0xad98, 0x000a, 0x20a9, 0x0004, + 0x1078, 0x80de, 0x00c0, 0x803e, 0x2011, 0xac9a, 0xad98, 0x0006, + 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x803e, 0x157f, 0x0e7f, + 0x037f, 0x027f, 0x007c, 0x0e7e, 0x2071, 0xac8c, 0x7004, 0xa086, + 0x0014, 0x00c0, 0x8066, 0x7008, 0xa086, 0x0800, 0x00c0, 0x8066, + 0x700c, 0xd0ec, 0x0040, 0x8064, 0xa084, 0x0f00, 0xa086, 0x0100, + 0x00c0, 0x8064, 0x7024, 0xd0a4, 0x00c0, 0x8061, 0xd0ac, 0x0040, + 0x8064, 0xa006, 0x0078, 0x8066, 0xa085, 0x0001, 0x0e7f, 0x007c, + 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, + 0x127e, 0x2091, 0x8000, 0x2029, 0xa9ba, 0x252c, 0x2021, 0xa9c0, + 0x2424, 0x2061, 0xae00, 0x2071, 0xa700, 0x7248, 0x7064, 0xa202, + 0x00c8, 0x80cc, 0x1078, 0xa252, 0x0040, 0x80c4, 0x671c, 0xa786, + 0x0001, 0x0040, 0x80c4, 0xa786, 0x0007, 0x0040, 0x80c4, 0x2500, + 0xac06, 0x0040, 0x80c4, 0x2400, 0xac06, 0x0040, 0x80c4, 0x0c7e, + 0x6000, 0xa086, 0x0004, 0x00c0, 0x809f, 0x1078, 0x1757, 0xa786, + 0x0008, 0x00c0, 0x80ae, 0x1078, 0x8f10, 0x00c0, 0x80ae, 0x0c7f, + 0x1078, 0x7c83, 0x1078, 0x8ed6, 0x0078, 0x80c4, 0x6010, 0x2068, + 0x1078, 0x8d16, 0x0040, 0x80c1, 0xa786, 0x0003, 0x00c0, 0x80d6, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078, + 0x8ec9, 0x1078, 0x8ed6, 0x0c7f, 0xace0, 0x0010, 0x7058, 0xac02, + 0x00c8, 0x80cc, 0x0078, 0x807d, 0x127f, 0x007f, 0x027f, 0x047f, + 0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, + 0x00c0, 0x80b8, 0x1078, 0xa1da, 0x0078, 0x80c1, 0x220c, 0x2304, + 0xa106, 0x00c0, 0x80e9, 0x8210, 0x8318, 0x00f0, 0x80de, 0xa006, + 0x007c, 0x2304, 0xa102, 0x0048, 0x80f1, 0x2001, 0x0001, 0x0078, + 0x80f3, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, + 0x0044, 0x10c8, 0x1332, 0x1078, 0x8efc, 0x0040, 0x8105, 0x1078, + 0x8f10, 0x0040, 0x8112, 0x0078, 0x810b, 0x1078, 0x28a6, 0x1078, + 0x8f10, 0x0040, 0x8112, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078, + 0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x810b, 0xa182, 0x0040, + 0x0079, 0x811a, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d, + 0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812f, 0x812f, 0x812f, + 0x812f, 0x812d, 0x812d, 0x812d, 0x812f, 0x1078, 0x1332, 0x600b, + 0xffff, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, + 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, + 0x8146, 0x6004, 0xa082, 0x0040, 0x0079, 0x81d1, 0xa186, 0x0027, + 0x00c0, 0x8168, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6110, + 0x2168, 0x1078, 0x8d16, 0x0040, 0x8162, 0x6837, 0x0103, 0x684b, + 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4a73, + 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, + 0xa186, 0x0014, 0x00c0, 0x8171, 0x6004, 0xa082, 0x0040, 0x0079, + 0x8199, 0xa186, 0x0046, 0x0040, 0x817d, 0xa186, 0x0045, 0x0040, + 0x817d, 0xa186, 0x0047, 0x10c0, 0x1332, 0x2001, 0x0109, 0x2004, + 0xd084, 0x0040, 0x8196, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, + 0x027e, 0x1078, 0x5c56, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, + 0xa086, 0x0002, 0x00c0, 0x8196, 0x0078, 0x820e, 0x1078, 0x7773, + 0x007c, 0x81ae, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac, + 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ca, 0x81ca, 0x81ca, 0x81ca, + 0x81ac, 0x81ca, 0x81ac, 0x81ca, 0x1078, 0x1332, 0x1078, 0x61cd, + 0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d16, 0x0040, 0x81c4, 0x6837, + 0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, + 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078, + 0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1, + 0x007c, 0x81e6, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4, + 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81f8, 0x81f8, 0x81f8, 0x81f8, + 0x81e4, 0x8207, 0x81e4, 0x81f8, 0x1078, 0x1332, 0x1078, 0x61cd, + 0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x62d1, + 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, + 0x1078, 0x61cd, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x2001, 0xa9a4, + 0x2004, 0x603e, 0x6003, 0x000f, 0x1078, 0x62d1, 0x007c, 0x1078, + 0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040, + 0x0079, 0x8212, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8227, + 0x8331, 0x8363, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, + 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x1078, 0x1332, 0x0e7e, + 0x0d7e, 0x603f, 0x0000, 0x2071, 0xac80, 0x7124, 0x610a, 0x2071, + 0xac8c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, + 0x82f0, 0xa68c, 0x0c00, 0x0040, 0x8265, 0x0f7e, 0x2c78, 0x1078, + 0x4963, 0x0f7f, 0x0040, 0x8261, 0x684c, 0xd0ac, 0x0040, 0x8261, + 0x6024, 0xd0dc, 0x00c0, 0x8261, 0x6850, 0xd0bc, 0x00c0, 0x8261, + 0x7318, 0x6814, 0xa306, 0x00c0, 0x8308, 0x731c, 0x6810, 0xa31e, + 0x0040, 0x8261, 0xd6d4, 0x0040, 0x8308, 0x6b14, 0xa305, 0x00c0, + 0x8308, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, + 0x0002, 0x0040, 0x8298, 0xa186, 0x0028, 0x00c0, 0x8275, 0x1078, + 0x8eea, 0x684b, 0x001c, 0x0078, 0x829a, 0xd6dc, 0x0040, 0x8291, + 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0040, 0x828f, 0x6914, 0x6a10, + 0x2100, 0xa205, 0x0040, 0x828f, 0x7018, 0xa106, 0x00c0, 0x828c, + 0x701c, 0xa206, 0x0040, 0x828f, 0x6962, 0x6a5e, 0xc6dc, 0x0078, + 0x829a, 0xd6d4, 0x0040, 0x8298, 0x684b, 0x0007, 0x0078, 0x829a, + 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x0040, + 0x82c3, 0xa686, 0x0100, 0x00c0, 0x82ae, 0x2001, 0xac99, 0x2004, + 0xa005, 0x00c0, 0x82ae, 0xc6c4, 0x0078, 0x8236, 0x7328, 0x732c, + 0x6b56, 0x83ff, 0x0040, 0x82c3, 0xa38a, 0x0009, 0x0048, 0x82ba, + 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019, + 0x1078, 0x89f2, 0x037f, 0xd6cc, 0x0040, 0x831e, 0x7124, 0x695a, + 0x81ff, 0x0040, 0x831e, 0xa192, 0x0021, 0x00c8, 0x82dc, 0x2071, + 0xac98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2, + 0x1078, 0x9204, 0x0078, 0x831e, 0x6838, 0xd0fc, 0x0040, 0x82e5, + 0x2009, 0x0020, 0x695a, 0x0078, 0x82cf, 0x0f7e, 0x2d78, 0x1078, + 0x898a, 0x0f7f, 0x1078, 0x9204, 0x1078, 0x89df, 0x0078, 0x8320, + 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x830e, 0x684c, + 0xd0ac, 0x0040, 0x830e, 0x6024, 0xd0dc, 0x00c0, 0x830e, 0x6850, + 0xd0bc, 0x00c0, 0x830e, 0x6810, 0x6914, 0xa105, 0x0040, 0x830e, + 0x1078, 0x8fcf, 0x0d7f, 0x0e7f, 0x0078, 0x8330, 0x684b, 0x0000, + 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x831e, 0x6810, + 0x6914, 0xa115, 0x0040, 0x831e, 0x1078, 0x84e2, 0x1078, 0x4a73, + 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x8328, 0x8211, 0x6a3e, + 0x1078, 0x8f99, 0x0d7f, 0x0e7f, 0x00c0, 0x8330, 0x1078, 0x772d, + 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xac8c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x8348, + 0x6003, 0x0002, 0x0f7f, 0x007c, 0x2130, 0x2228, 0x0078, 0x8354, + 0x2400, 0x797c, 0xa10a, 0x2300, 0x7a80, 0xa213, 0x2600, 0xa102, + 0x2500, 0xa203, 0x0048, 0x8344, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, + 0x0f7f, 0x603f, 0x0000, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, + 0x1078, 0x639b, 0x007c, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003, + 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, + 0x15fa, 0x007c, 0xa182, 0x0040, 0x0079, 0x8376, 0x8389, 0x8389, + 0x8389, 0x8389, 0x8389, 0x838b, 0x8431, 0x8389, 0x8389, 0x8447, + 0x84b8, 0x8389, 0x8389, 0x8389, 0x8389, 0x84c7, 0x8389, 0x8389, + 0x8389, 0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, + 0xac8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, + 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x83a2, + 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x842c, 0xa694, 0xff00, 0xa284, + 0x0c00, 0x0040, 0x83af, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, + 0x0300, 0x0040, 0x842c, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00, + 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, + 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0040, + 0x83cd, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, + 0x0002, 0x0040, 0x83e9, 0xa186, 0x0028, 0x00c0, 0x83db, 0x684b, + 0x001c, 0x0078, 0x83eb, 0xd6dc, 0x0040, 0x83e2, 0x684b, 0x0015, + 0x0078, 0x83eb, 0xd6d4, 0x0040, 0x83e9, 0x684b, 0x0007, 0x0078, + 0x83eb, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, + 0xa01e, 0xd6c4, 0x0040, 0x8409, 0x7328, 0x732c, 0x6b56, 0x83ff, + 0x0040, 0x8409, 0xa38a, 0x0009, 0x0048, 0x8400, 0x2019, 0x0008, + 0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019, 0x1078, 0x89f2, + 0x037f, 0xd6cc, 0x0040, 0x842c, 0x7124, 0x695a, 0x81ff, 0x0040, + 0x842c, 0xa192, 0x0021, 0x00c8, 0x8420, 0x2071, 0xac98, 0x831c, + 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2, 0x0078, 0x842c, + 0x7838, 0xd0fc, 0x0040, 0x8429, 0x2009, 0x0020, 0x695a, 0x0078, + 0x8415, 0x2d78, 0x1078, 0x898a, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, + 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xac8c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, + 0x0f7f, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x6df4, 0x007c, 0x0d7e, + 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x8453, 0x2001, + 0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x627a, 0x1078, + 0x639b, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x84b6, 0xd1cc, + 0x0040, 0x848d, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x8485, 0x017e, + 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, + 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, + 0x00f0, 0x8474, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, + 0x2168, 0x1078, 0x13b4, 0x0078, 0x84b0, 0x017e, 0x1078, 0x13b4, + 0x0d7f, 0x1078, 0x89df, 0x0078, 0x84b0, 0x6837, 0x0103, 0x6944, + 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x84ac, 0xa086, 0x0028, + 0x00c0, 0x849e, 0x684b, 0x001c, 0x0078, 0x84ae, 0xd1dc, 0x0040, + 0x84a5, 0x684b, 0x0015, 0x0078, 0x84ae, 0xd1d4, 0x0040, 0x84ac, + 0x684b, 0x0007, 0x0078, 0x84ae, 0x684b, 0x0000, 0x1078, 0x4a73, + 0x1078, 0x8f99, 0x00c0, 0x84b6, 0x1078, 0x772d, 0x0d7f, 0x007c, + 0x2019, 0x0001, 0x1078, 0x7058, 0x6003, 0x0002, 0x2001, 0xa9a4, + 0x2004, 0x603e, 0x1078, 0x627a, 0x1078, 0x639b, 0x007c, 0x1078, + 0x627a, 0x1078, 0x2880, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d16, + 0x0040, 0x84dc, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, + 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078, + 0x639b, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x84ee, 0x684b, + 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, + 0x007c, 0xa182, 0x0040, 0x0079, 0x84f5, 0x8508, 0x8508, 0x8508, + 0x8508, 0x8508, 0x850a, 0x8508, 0x85e0, 0x85ec, 0x8508, 0x8508, + 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, + 0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xac8c, + 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78, 0x1078, + 0x4963, 0x0f7f, 0x0040, 0x8528, 0xa684, 0x00ff, 0x00c0, 0x8528, + 0x6024, 0xd0f4, 0x0040, 0x8528, 0x1078, 0x8fcf, 0x0078, 0x85db, + 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, + 0x0040, 0x8534, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x85d0, 0xa694, + 0xff00, 0xa284, 0x0c00, 0x0040, 0x8541, 0x7018, 0x7862, 0x701c, + 0x785e, 0xa284, 0x0300, 0x0040, 0x85cd, 0xa686, 0x0100, 0x00c0, + 0x8553, 0x2001, 0xac99, 0x2004, 0xa005, 0x00c0, 0x8553, 0xc6c4, + 0x7e46, 0x0078, 0x8534, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00, + 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, + 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, + 0x0040, 0x856e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0040, 0x858a, 0xa186, 0x0028, 0x00c0, 0x857c, + 0x684b, 0x001c, 0x0078, 0x858c, 0xd6dc, 0x0040, 0x8583, 0x684b, + 0x0015, 0x0078, 0x858c, 0xd6d4, 0x0040, 0x858a, 0x684b, 0x0007, + 0x0078, 0x858c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, + 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x85aa, 0x7328, 0x732c, 0x6b56, + 0x83ff, 0x0040, 0x85aa, 0xa38a, 0x0009, 0x0048, 0x85a1, 0x2019, + 0x0008, 0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019, 0x1078, + 0x89f2, 0x037f, 0xd6cc, 0x0040, 0x85cd, 0x7124, 0x695a, 0x81ff, + 0x0040, 0x85cd, 0xa192, 0x0021, 0x00c8, 0x85c1, 0x2071, 0xac98, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2, 0x0078, + 0x85cd, 0x7838, 0xd0fc, 0x0040, 0x85ca, 0x2009, 0x0020, 0x695a, + 0x0078, 0x85b6, 0x2d78, 0x1078, 0x898a, 0xd6dc, 0x00c0, 0x85d3, + 0xa006, 0x0078, 0x85d9, 0x2001, 0x0001, 0x2071, 0xac8c, 0x7218, + 0x731c, 0x1078, 0x1653, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c, + 0x2001, 0xa9a4, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x15fa, 0x007c, 0x2001, 0xa9a4, 0x2004, 0x603e, + 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, + 0x871c, 0x603f, 0x0000, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, + 0x0040, 0x8632, 0x6814, 0x6910, 0xa115, 0x0040, 0x8632, 0x6a60, + 0xa206, 0x00c0, 0x860f, 0x685c, 0xa106, 0x0040, 0x8632, 0x684c, + 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, + 0x6024, 0xd0f4, 0x00c0, 0x8627, 0x697c, 0x6810, 0xa102, 0x603a, + 0x6980, 0x6814, 0xa103, 0x6036, 0x6024, 0xc0f5, 0x6026, 0x0d7e, + 0x6018, 0x2068, 0x683c, 0x8000, 0x683e, 0x0d7f, 0x1078, 0x8fcf, + 0x0078, 0x871c, 0x694c, 0xd1cc, 0x0040, 0x86e1, 0x6948, 0x6838, + 0xd0fc, 0x0040, 0x8699, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, + 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, + 0x866c, 0xa086, 0x0028, 0x00c0, 0x8653, 0x684b, 0x001c, 0x784b, + 0x001c, 0x0078, 0x8677, 0xd1dc, 0x0040, 0x8663, 0x684b, 0x0015, + 0x784b, 0x0015, 0x1078, 0x917c, 0x0040, 0x8661, 0x7944, 0xc1dc, + 0x7946, 0x0078, 0x8677, 0xd1d4, 0x0040, 0x866c, 0x684b, 0x0007, + 0x784b, 0x0007, 0x0078, 0x8677, 0x684c, 0xd0ac, 0x0040, 0x8677, + 0x6810, 0x6914, 0xa115, 0x0040, 0x8677, 0x1078, 0x84e2, 0x6848, + 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d, 0xaf98, + 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, + 0x8210, 0x00f0, 0x8685, 0x157f, 0x0f7f, 0x007f, 0x6852, 0x007f, + 0x684e, 0x1078, 0x9204, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078, + 0x8716, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, + 0x0002, 0x0040, 0x86c6, 0xa086, 0x0028, 0x00c0, 0x86ad, 0x684b, + 0x001c, 0x784b, 0x001c, 0x0078, 0x86d1, 0xd1dc, 0x0040, 0x86bd, + 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x917c, 0x0040, 0x86bb, + 0x7944, 0xc1dc, 0x7946, 0x0078, 0x86d1, 0xd1d4, 0x0040, 0x86c6, + 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x86d1, 0x684c, 0xd0ac, + 0x0040, 0x86d1, 0x6810, 0x6914, 0xa115, 0x0040, 0x86d1, 0x1078, + 0x84e2, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x0f7f, + 0x1078, 0x13b4, 0x0d7f, 0x1078, 0x9204, 0x1078, 0x89df, 0x0078, + 0x8716, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, + 0x0040, 0x8707, 0xa086, 0x0028, 0x00c0, 0x86f2, 0x684b, 0x001c, + 0x0078, 0x8714, 0xd1dc, 0x0040, 0x8700, 0x684b, 0x0015, 0x1078, + 0x917c, 0x0040, 0x86fe, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8714, + 0xd1d4, 0x0040, 0x8707, 0x684b, 0x0007, 0x0078, 0x8714, 0x684b, + 0x0000, 0x684c, 0xd0ac, 0x0040, 0x8714, 0x6810, 0x6914, 0xa115, + 0x0040, 0x8714, 0x1078, 0x84e2, 0x1078, 0x4a73, 0x1078, 0x8f99, + 0x00c0, 0x871c, 0x1078, 0x772d, 0x0d7f, 0x007c, 0x1078, 0x61cd, + 0x0078, 0x8724, 0x1078, 0x627a, 0x1078, 0x8d16, 0x0040, 0x8743, + 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa70c, 0x210c, + 0xd18c, 0x00c0, 0x874e, 0xd184, 0x00c0, 0x874a, 0x6108, 0x694a, + 0xa18e, 0x0029, 0x00c0, 0x873e, 0x1078, 0xa4f2, 0x6847, 0x0000, + 0x1078, 0x4a73, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x1078, + 0x639b, 0x007c, 0x684b, 0x0004, 0x0078, 0x873e, 0x684b, 0x0004, + 0x0078, 0x873e, 0xa182, 0x0040, 0x0079, 0x8756, 0x8769, 0x8769, + 0x8769, 0x8769, 0x8769, 0x876b, 0x8769, 0x876e, 0x8769, 0x8769, + 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, + 0x8769, 0x1078, 0x1332, 0x1078, 0x772d, 0x007c, 0x007e, 0x027e, + 0xa016, 0x1078, 0x15fa, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, + 0x0079, 0x877a, 0x8783, 0x8781, 0x8781, 0x878f, 0x8781, 0x8781, + 0x8781, 0x1078, 0x1332, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, + 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x027e, + 0x057e, 0x0d7e, 0x0e7e, 0x2071, 0xac80, 0x7224, 0x6212, 0x7220, + 0x1078, 0x8d02, 0x0040, 0x87b4, 0x2268, 0x6800, 0xa086, 0x0000, + 0x0040, 0x87b4, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x87b4, 0x0c7e, + 0x2d60, 0x1078, 0x8a03, 0x0c7f, 0x0040, 0x87b4, 0x6803, 0x0002, + 0x6007, 0x0086, 0x0078, 0x87b6, 0x6007, 0x0087, 0x6003, 0x0001, + 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0f7e, 0x2278, 0x1078, 0x4963, + 0x0f7f, 0x0040, 0x87ce, 0x6824, 0xd0ec, 0x0040, 0x87ce, 0x0c7e, + 0x2260, 0x603f, 0x0000, 0x1078, 0x8fcf, 0x0c7f, 0x0e7f, 0x0d7f, + 0x057f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87e4, 0x6004, + 0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332, + 0xa082, 0x0085, 0x0079, 0x87f3, 0xa186, 0x0027, 0x0040, 0x87ec, + 0xa186, 0x0014, 0x10c0, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6, + 0x1078, 0x62d1, 0x007c, 0x87fa, 0x87fc, 0x87fc, 0x87fa, 0x87fa, + 0x87fa, 0x87fa, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6, + 0x1078, 0x62d1, 0x007c, 0xa186, 0x0013, 0x00c0, 0x880d, 0x6004, + 0xa082, 0x0085, 0x2008, 0x0078, 0x8848, 0xa186, 0x0027, 0x00c0, + 0x8830, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6010, 0x2068, + 0x1078, 0x8d16, 0x0040, 0x8826, 0x6837, 0x0103, 0x6847, 0x0000, + 0x684b, 0x0029, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, + 0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7773, 0x0078, 0x882b, + 0xa186, 0x0014, 0x00c0, 0x882c, 0x1078, 0x61cd, 0x0d7e, 0x6010, + 0x2068, 0x1078, 0x8d16, 0x0040, 0x8826, 0x6837, 0x0103, 0x6847, + 0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8822, + 0x0079, 0x884a, 0x8853, 0x8851, 0x8851, 0x8851, 0x8851, 0x8851, + 0x886e, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6030, 0xa08c, 0xff00, + 0x810f, 0xa186, 0x0039, 0x0040, 0x8861, 0xa186, 0x0035, 0x00c0, + 0x8865, 0x2001, 0xa9a2, 0x0078, 0x8867, 0x2001, 0xa9a3, 0x2004, + 0x6016, 0x6003, 0x000c, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd, + 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x887c, + 0xa186, 0x0035, 0x00c0, 0x8880, 0x2001, 0xa9a2, 0x0078, 0x8882, + 0x2001, 0xa9a3, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x62d1, + 0x007c, 0xa182, 0x008c, 0x00c8, 0x8893, 0xa182, 0x0085, 0x0048, + 0x8893, 0x0079, 0x8896, 0x1078, 0x7773, 0x007c, 0x889d, 0x889d, + 0x889d, 0x889d, 0x889f, 0x88fc, 0x889d, 0x1078, 0x1332, 0x0f7e, + 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x88b2, 0x6030, 0xa08c, + 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8913, 0xa186, 0x0035, + 0x0040, 0x8913, 0x0d7e, 0x1078, 0x8d16, 0x00c0, 0x88bb, 0x1078, + 0x8ec9, 0x0078, 0x88de, 0x6010, 0x2068, 0x684c, 0xd0e4, 0x00c0, + 0x88c3, 0x1078, 0x8ec9, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, + 0x88cf, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x88da, 0xd0bc, + 0x0040, 0x88d6, 0x684b, 0x0002, 0x0078, 0x88da, 0x684b, 0x0005, + 0x1078, 0x8f95, 0x6847, 0x0000, 0x1078, 0x4a73, 0x2c68, 0x1078, + 0x76c7, 0x0040, 0x88f7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, + 0xac8e, 0x210c, 0x6136, 0x2009, 0xac8f, 0x210c, 0x613a, 0x6918, + 0x611a, 0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5d8a, 0x2d60, + 0x1078, 0x772d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963, + 0x0f7f, 0x0040, 0x8939, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, + 0x0035, 0x0040, 0x8913, 0xa186, 0x001e, 0x0040, 0x8913, 0xa186, + 0x0039, 0x00c0, 0x8939, 0x0d7e, 0x2c68, 0x1078, 0x91cc, 0x00c0, + 0x895d, 0x1078, 0x76c7, 0x0040, 0x8936, 0x6106, 0x6003, 0x0001, + 0x601f, 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, + 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, + 0x6920, 0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2d60, 0x0078, + 0x895d, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x895d, + 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x894c, 0xc0ec, 0x6852, + 0x684b, 0x0006, 0x0078, 0x8957, 0xd0bc, 0x0040, 0x8953, 0x684b, + 0x0002, 0x0078, 0x8957, 0x684b, 0x0005, 0x1078, 0x8f95, 0x6847, + 0x0000, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, + 0x007c, 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, + 0x8971, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, + 0x4a73, 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x8983, 0xa186, + 0x0014, 0x0040, 0x8983, 0xa186, 0x0027, 0x0040, 0x8983, 0x1078, + 0x7773, 0x0078, 0x8989, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078, + 0x62d1, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, + 0xa182, 0x0101, 0x00c8, 0x8996, 0x0078, 0x8998, 0x2009, 0x0100, + 0x2130, 0x2069, 0xac98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, + 0xaf90, 0x001d, 0x1078, 0x89f2, 0xa6b2, 0x0020, 0x7804, 0xa06d, + 0x0040, 0x89ac, 0x1078, 0x13b4, 0x1078, 0x138b, 0x0040, 0x89d6, + 0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, + 0x003d, 0x00c8, 0x89c2, 0x2608, 0xad90, 0x000f, 0x1078, 0x89f2, + 0x0078, 0x89d6, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, + 0x000f, 0x1078, 0x89f2, 0x0078, 0x89ac, 0x0f7f, 0x852f, 0xa5ad, + 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x89db, 0x0f7f, 0x852f, + 0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, + 0x8dff, 0x0040, 0x89f0, 0x6804, 0xa07d, 0x0040, 0x89ee, 0x6807, + 0x0000, 0x1078, 0x4a73, 0x2f68, 0x0078, 0x89e3, 0x1078, 0x4a73, + 0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x89f8, 0x8108, + 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, + 0x89fa, 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, + 0x0001, 0x601c, 0xa084, 0x000f, 0x1079, 0x8a1f, 0x127f, 0x067f, + 0x007c, 0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, + 0xa084, 0x000f, 0x1079, 0x8a1f, 0x067f, 0x127f, 0x007c, 0x8a39, + 0x8a27, 0x8a34, 0x8a55, 0x8a27, 0x8a34, 0x8a55, 0x8a34, 0x1078, + 0x1332, 0x037e, 0x2019, 0x0010, 0x1078, 0x9dd7, 0x601f, 0x0006, + 0x6003, 0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, + 0x007c, 0x0d7e, 0x86ff, 0x00c0, 0x8a50, 0x6010, 0x2068, 0x1078, + 0x8d16, 0x0040, 0x8a52, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51, + 0x1078, 0x8f95, 0x1078, 0x4a73, 0x1078, 0x772d, 0xa085, 0x0001, + 0x0d7f, 0x007c, 0xa006, 0x0078, 0x8a50, 0x6000, 0xa08a, 0x0010, + 0x10c8, 0x1332, 0x1079, 0x8a5d, 0x007c, 0x8a6d, 0x8a92, 0x8a6f, + 0x8ab5, 0x8a8e, 0x8a6d, 0x8a34, 0x8a39, 0x8a39, 0x8a34, 0x8a34, + 0x8a34, 0x8a34, 0x8a34, 0x8a34, 0x8a34, 0x1078, 0x1332, 0x86ff, + 0x00c0, 0x8a8b, 0x601c, 0xa086, 0x0006, 0x0040, 0x8a8b, 0x0d7e, + 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x8a80, 0x1078, 0x8f95, + 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, + 0x5d8a, 0x1078, 0x62d1, 0xa085, 0x0001, 0x007c, 0x1078, 0x1757, + 0x0078, 0x8a6f, 0x0e7e, 0x2071, 0xa9b1, 0x7024, 0xac06, 0x00c0, + 0x8a9b, 0x1078, 0x6fc4, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, + 0x00c0, 0x8aad, 0x087e, 0x097e, 0x2049, 0x0001, 0x2c40, 0x1078, + 0x7246, 0x097f, 0x087f, 0x0078, 0x8aaf, 0x1078, 0x6ebe, 0x0e7f, + 0x00c0, 0x8a6f, 0x1078, 0x8a34, 0x007c, 0x037e, 0x0e7e, 0x2071, + 0xa9b1, 0x703c, 0xac06, 0x00c0, 0x8ac5, 0x2019, 0x0000, 0x1078, + 0x7058, 0x0e7f, 0x037f, 0x0078, 0x8a6f, 0x1078, 0x738a, 0x0e7f, + 0x037f, 0x00c0, 0x8a6f, 0x1078, 0x8a34, 0x007c, 0x0c7e, 0x601c, + 0xa084, 0x000f, 0x1079, 0x8ad6, 0x0c7f, 0x007c, 0x8ae5, 0x8b57, + 0x8c8f, 0x8af0, 0x8ed6, 0x8ae5, 0x9dc8, 0x772d, 0x8b57, 0x1078, + 0x8f10, 0x00c0, 0x8ae5, 0x1078, 0x7c83, 0x007c, 0x1078, 0x61cd, + 0x1078, 0x62d1, 0x1078, 0x772d, 0x007c, 0x6017, 0x0001, 0x007c, + 0x1078, 0x8d16, 0x0040, 0x8af8, 0x6010, 0xa080, 0x0019, 0x2c02, + 0x6000, 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b00, 0x007c, + 0x8b10, 0x8b12, 0x8b34, 0x8b46, 0x8b53, 0x8b10, 0x8ae5, 0x8ae5, + 0x8ae5, 0x8b46, 0x8b46, 0x8b10, 0x8b10, 0x8b10, 0x8b10, 0x8b50, + 0x1078, 0x1332, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, + 0x2071, 0xa9b1, 0x7024, 0xac06, 0x0040, 0x8b30, 0x1078, 0x6ebe, + 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa9a3, + 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x007c, + 0x6017, 0x0001, 0x0078, 0x8b2e, 0x0d7e, 0x6010, 0x2068, 0x6850, + 0xc0b5, 0x6852, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, + 0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x0d7e, 0x6017, + 0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, + 0x1078, 0x772d, 0x007c, 0x1078, 0x1757, 0x0078, 0x8b34, 0x6000, + 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b5f, 0x007c, 0x8b6f, + 0x8aed, 0x8b71, 0x8b6f, 0x8b71, 0x8b71, 0x8ae6, 0x8b6f, 0x8adf, + 0x8adf, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x1078, + 0x1332, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, + 0xa08a, 0x000c, 0x10c8, 0x1332, 0x1079, 0x8b7f, 0x007c, 0x8b8b, + 0x8c33, 0x8b8d, 0x8bcd, 0x8b8d, 0x8bcd, 0x8b8d, 0x8b9a, 0x8b8b, + 0x8bcd, 0x8b8b, 0x8bb7, 0x1078, 0x1332, 0x6004, 0xa08e, 0x0016, + 0x0040, 0x8bc8, 0xa08e, 0x0004, 0x0040, 0x8bc8, 0xa08e, 0x0002, + 0x0040, 0x8bc8, 0x6004, 0x1078, 0x8f10, 0x0040, 0x8c4e, 0xa08e, + 0x0021, 0x0040, 0x8c52, 0xa08e, 0x0022, 0x0040, 0x8c4e, 0xa08e, + 0x003d, 0x0040, 0x8c52, 0xa08e, 0x0039, 0x0040, 0x8c56, 0xa08e, + 0x0035, 0x0040, 0x8c56, 0xa08e, 0x001e, 0x0040, 0x8bca, 0xa08e, + 0x0001, 0x00c0, 0x8bc6, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, + 0x00ff, 0x0d7f, 0xa086, 0x0006, 0x0040, 0x8bc8, 0x1078, 0x2880, + 0x1078, 0x7c83, 0x1078, 0x8ed6, 0x007c, 0x0c7e, 0x0d7e, 0x6104, + 0xa186, 0x0016, 0x0040, 0x8c23, 0xa186, 0x0002, 0x00c0, 0x8bf6, + 0x6018, 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x8c7a, 0x6840, 0xa084, + 0x00ff, 0xa005, 0x0040, 0x8bf6, 0x8001, 0x6842, 0x6013, 0x0000, + 0x601f, 0x0007, 0x6017, 0x0398, 0x1078, 0x76c7, 0x0040, 0x8bf6, + 0x2d00, 0x601a, 0x601f, 0x0001, 0x0078, 0x8c23, 0x0d7f, 0x0c7f, + 0x6004, 0xa08e, 0x0002, 0x00c0, 0x8c14, 0x6018, 0xa080, 0x0028, + 0x2004, 0xa086, 0x007e, 0x00c0, 0x8c14, 0x2009, 0xa733, 0x2104, + 0xc085, 0x200a, 0x0e7e, 0x2071, 0xa700, 0x1078, 0x42b8, 0x0e7f, + 0x1078, 0x7c83, 0x0078, 0x8c18, 0x1078, 0x7c83, 0x1078, 0x2880, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x127f, 0x0e7f, + 0x1078, 0x8ed6, 0x007c, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, + 0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0d7f, + 0x0c7f, 0x0078, 0x8c22, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, + 0x0040, 0x8c23, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, + 0x0040, 0x8bf6, 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5dd7, + 0x1078, 0x62d1, 0x0d7f, 0x0c7f, 0x0078, 0x8c22, 0x1078, 0x7c83, + 0x0078, 0x8bca, 0x1078, 0x7ca6, 0x0078, 0x8bca, 0x0d7e, 0x2c68, + 0x6104, 0x1078, 0x91cc, 0x0d7f, 0x0040, 0x8c62, 0x1078, 0x772d, + 0x0078, 0x8c79, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, + 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, + 0x600a, 0x2001, 0xa9a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, + 0x62d1, 0x007c, 0x0d7f, 0x0c7f, 0x1078, 0x7c83, 0x1078, 0x2880, + 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x6013, 0x0000, + 0x601f, 0x0007, 0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, + 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8c97, 0x007c, 0x8ca7, + 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, + 0x8ae5, 0x8ca7, 0x8aed, 0x8ca9, 0x8aed, 0x8cb7, 0x8ca7, 0x1078, + 0x1332, 0x6004, 0xa086, 0x008b, 0x0040, 0x8cb7, 0x6007, 0x008b, + 0x6003, 0x000d, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x1078, + 0x8ec9, 0x1078, 0x8d16, 0x0040, 0x8cef, 0x1078, 0x2880, 0x0d7e, + 0x1078, 0x8d16, 0x0040, 0x8cd1, 0x6010, 0x2068, 0x6837, 0x0103, + 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, + 0x4a73, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x8cdf, 0x6818, 0x601a, + 0x0c7e, 0x2d60, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x8ce0, 0x2d60, + 0x0d7f, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, + 0x0001, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0078, 0x8d01, 0x6030, + 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8cfb, 0xa186, + 0x0035, 0x00c0, 0x8cff, 0x1078, 0x2880, 0x0078, 0x8cd1, 0x1078, + 0x8ed6, 0x007c, 0xa284, 0x000f, 0x00c0, 0x8d13, 0xa282, 0xae00, + 0x0048, 0x8d13, 0x2001, 0xa716, 0x2004, 0xa202, 0x00c8, 0x8d13, + 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x8d12, 0x027e, 0x0e7e, + 0x2071, 0xa700, 0x6210, 0x705c, 0xa202, 0x0048, 0x8d28, 0x7060, + 0xa202, 0x00c8, 0x8d28, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, + 0xa006, 0x0078, 0x8d25, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, + 0x2091, 0x8000, 0x2061, 0xae00, 0x2071, 0xa700, 0x7348, 0x7064, + 0xa302, 0x00c8, 0x8d55, 0x601c, 0xa206, 0x00c0, 0x8d4d, 0x1078, + 0x903b, 0x0040, 0x8d4d, 0x1078, 0x8f10, 0x00c0, 0x8d49, 0x1078, + 0x7c83, 0x0c7e, 0x1078, 0x772d, 0x0c7f, 0xace0, 0x0010, 0x7058, + 0xac02, 0x00c8, 0x8d55, 0x0078, 0x8d36, 0x127f, 0x007f, 0x037f, + 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa835, + 0x210c, 0x81ff, 0x0040, 0x8d69, 0x2061, 0xaab3, 0x611a, 0x1078, + 0x2880, 0xa006, 0x0078, 0x8d6e, 0xa085, 0x0001, 0x017f, 0x0c7f, + 0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, + 0x1078, 0x76c7, 0x057f, 0x0040, 0x8d8b, 0x6612, 0x651a, 0x601f, + 0x0003, 0x2009, 0x004b, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, + 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8d87, 0x0c7e, 0x057e, + 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x76c7, 0x057f, + 0x0040, 0x8db9, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, + 0x2560, 0x1078, 0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039, + 0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f, 0x2009, + 0x004c, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, + 0x007c, 0xa006, 0x0078, 0x8db5, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, + 0x1078, 0x76c7, 0x2c78, 0x0c7f, 0x0040, 0x8dd6, 0x7e12, 0x2c00, + 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8e21, 0x2f60, + 0x2009, 0x004d, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, + 0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7, + 0x2c78, 0x0c7f, 0x0040, 0x8df4, 0x7e12, 0x2c00, 0x781a, 0x781f, + 0x0003, 0x2021, 0x0005, 0x1078, 0x8e21, 0x2f60, 0x2009, 0x004e, + 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, + 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7, 0x2c78, 0x0c7f, + 0x0040, 0x8e1d, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, + 0x0004, 0x1078, 0x8e21, 0x2001, 0xa99d, 0x2004, 0xd0fc, 0x0040, + 0x8e16, 0x2f60, 0x1078, 0x772d, 0x0078, 0x8e1b, 0x2f60, 0x2009, + 0x0052, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, + 0x007c, 0x097e, 0x077e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4775, + 0x0040, 0x8e2e, 0x2001, 0x8e26, 0x0078, 0x8e34, 0x1078, 0x4739, + 0x0040, 0x8e3d, 0x2001, 0x8e2e, 0x007e, 0xa00e, 0x2400, 0x1078, + 0x4b51, 0x1078, 0x4a73, 0x007f, 0x007a, 0x2418, 0x1078, 0x6161, + 0x62a0, 0x087e, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x1078, + 0x5f1b, 0x087f, 0x1078, 0x5e0a, 0x2f08, 0x2648, 0x1078, 0x9f9b, + 0x613c, 0x81ff, 0x1040, 0x5fdb, 0x1078, 0x62d1, 0x127f, 0x077f, + 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, + 0x76c7, 0x017f, 0x0040, 0x8e73, 0x660a, 0x611a, 0x601f, 0x0001, + 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x775c, 0xa085, 0x0001, + 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e70, 0x0c7e, 0x127e, + 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8e8f, + 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, + 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, + 0x0078, 0x8e8c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, + 0x76c7, 0x017f, 0x0040, 0x8eab, 0x660a, 0x611a, 0x601f, 0x0001, + 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, 0x775c, 0xa085, 0x0001, + 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8ea8, 0x0c7e, 0x127e, + 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8ec6, + 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078, + 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, + 0x8ec3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, + 0x8ed3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x007e, 0x6000, + 0xa086, 0x0000, 0x0040, 0x8ee8, 0x6013, 0x0000, 0x601f, 0x0007, + 0x2001, 0xa9a3, 0x2004, 0x6016, 0x1078, 0xa4a5, 0x603f, 0x0000, + 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0xa753, 0x2634, + 0xd6e4, 0x0040, 0x8ef8, 0x6618, 0x2660, 0x6e48, 0x1078, 0x46e7, + 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, + 0x0002, 0x0040, 0x8f0d, 0xa08e, 0x0003, 0x0040, 0x8f0d, 0xa08e, + 0x0004, 0x0040, 0x8f0d, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, + 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8f1d, 0x6838, 0xd0fc, + 0x0040, 0x8f1d, 0xa006, 0x0078, 0x8f1f, 0xa085, 0x0001, 0x0d7f, + 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, + 0x76c7, 0x017f, 0x0040, 0x8f3c, 0x611a, 0x601f, 0x0001, 0x2d00, + 0x6012, 0x1078, 0x2880, 0x2009, 0x0028, 0x1078, 0x775c, 0xa085, + 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8f39, 0xa186, + 0x0015, 0x00c0, 0x8f54, 0x2011, 0xa720, 0x2204, 0xa086, 0x0074, + 0x00c0, 0x8f54, 0x1078, 0x7f91, 0x6003, 0x0001, 0x6007, 0x0029, + 0x1078, 0x5dd7, 0x0078, 0x8f58, 0x1078, 0x7c83, 0x1078, 0x772d, + 0x007c, 0xa186, 0x0016, 0x00c0, 0x8f63, 0x2001, 0x0004, 0x1078, + 0x4502, 0x0078, 0x8f84, 0xa186, 0x0015, 0x00c0, 0x8f88, 0x2011, + 0xa720, 0x2204, 0xa086, 0x0014, 0x00c0, 0x8f88, 0x0d7e, 0x6018, + 0x2068, 0x1078, 0x4649, 0x0d7f, 0x1078, 0x8043, 0x00c0, 0x8f88, + 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x8f88, + 0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x77f8, 0x0078, 0x8f8c, + 0x1078, 0x7c83, 0x1078, 0x772d, 0x007c, 0x6848, 0xa086, 0x0005, + 0x00c0, 0x8f94, 0x1078, 0x8f95, 0x007c, 0x6850, 0xc0ad, 0x6852, + 0x007c, 0x0e7e, 0x2071, 0xac8c, 0x7014, 0xd0e4, 0x0040, 0x8faa, + 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a, + 0x1078, 0x62d1, 0x0e7f, 0x007c, 0x0c7e, 0x0f7e, 0x2c78, 0x1078, + 0x4963, 0x0f7f, 0x0040, 0x8fb9, 0x601c, 0xa084, 0x000f, 0x1079, + 0x8fbb, 0x0c7f, 0x007c, 0x8ae5, 0x8fc6, 0x8fc9, 0x8fcc, 0xa26d, + 0xa289, 0xa28c, 0x8ae5, 0x8ae5, 0x1078, 0x1332, 0x0005, 0x0005, + 0x007c, 0x0005, 0x0005, 0x007c, 0x1078, 0x8fcf, 0x007c, 0x0f7e, + 0x2c78, 0x1078, 0x4963, 0x0040, 0x8ffe, 0x1078, 0x76c7, 0x00c0, + 0x8fdf, 0x2001, 0xa9a4, 0x2004, 0x783e, 0x0078, 0x8ffe, 0x7818, + 0x601a, 0x781c, 0xa086, 0x0003, 0x0040, 0x8fec, 0x7808, 0x6036, + 0x2f00, 0x603a, 0x0078, 0x8ff0, 0x7808, 0x603a, 0x2f00, 0x6036, + 0x602a, 0x601f, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7920, + 0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2f60, 0x0f7f, 0x007c, + 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0040, 0x9011, + 0xa086, 0x0005, 0x0040, 0x9015, 0xa006, 0x602a, 0x602e, 0x0078, + 0x9026, 0x6824, 0xc0f4, 0xc0d5, 0x6826, 0x6810, 0x2078, 0x787c, + 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x00c8, 0x900c, 0x6834, + 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036, + 0x6808, 0x603a, 0x6918, 0x611a, 0x6920, 0x6122, 0x601f, 0x0001, + 0x6007, 0x0039, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x6803, 0x0002, + 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0034, + 0x0040, 0x9060, 0xa08e, 0x0035, 0x0040, 0x9060, 0xa08e, 0x0036, + 0x0040, 0x9060, 0xa08e, 0x0037, 0x0040, 0x9060, 0xa08e, 0x0038, + 0x0040, 0x9060, 0xa08e, 0x0039, 0x0040, 0x9060, 0xa08e, 0x003a, + 0x0040, 0x9060, 0xa08e, 0x003b, 0x0040, 0x9060, 0xa085, 0x0001, + 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x00c0, + 0x906d, 0xa085, 0x0001, 0x0078, 0x907c, 0x6024, 0xd0f4, 0x00c0, + 0x907b, 0xc0f5, 0x6026, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c, + 0x6036, 0x1078, 0x1757, 0xa006, 0x0f7f, 0x007c, 0x007e, 0x017e, + 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa99e, 0x200c, 0x8000, 0x2014, + 0x2001, 0x0032, 0x1078, 0x5c1c, 0x2001, 0xa9a2, 0x82ff, 0x00c0, + 0x9093, 0x2011, 0x0014, 0x2202, 0x2001, 0xa9a0, 0x200c, 0x8000, + 0x2014, 0x2071, 0xa98d, 0x711a, 0x721e, 0x2001, 0x0064, 0x1078, + 0x5c1c, 0x2001, 0xa9a3, 0x82ff, 0x00c0, 0x90a8, 0x2011, 0x0014, + 0x2202, 0x2009, 0xa9a4, 0xa280, 0x000a, 0x200a, 0x1078, 0x498b, + 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e, 0x0e7e, + 0x2001, 0xa9a2, 0x2003, 0x0028, 0x2001, 0xa9a3, 0x2003, 0x0014, + 0x2071, 0xa98d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xa9a4, + 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, + 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x90e5, 0x611a, + 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078, 0x775c, + 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x90e2, + 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa700, 0xa186, 0x0015, 0x00c0, + 0x9117, 0x7080, 0xa086, 0x0018, 0x00c0, 0x9117, 0x6010, 0x2068, + 0x6a3c, 0xd2e4, 0x00c0, 0x910b, 0x2c78, 0x1078, 0x6490, 0x0040, + 0x911f, 0x706c, 0x6a50, 0xa206, 0x00c0, 0x9113, 0x7070, 0x6a54, + 0xa206, 0x00c0, 0x9113, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, + 0x0000, 0x1078, 0x28c8, 0x1078, 0x77f8, 0x0078, 0x911b, 0x1078, + 0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x7050, + 0xa080, 0x29c0, 0x2004, 0x6a54, 0xa206, 0x0040, 0x910b, 0x0078, + 0x9113, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, + 0x017f, 0x0040, 0x9141, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, + 0x2009, 0x0043, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, + 0x007c, 0xa006, 0x0078, 0x913e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, + 0xa700, 0xa186, 0x0015, 0x00c0, 0x916a, 0x7080, 0xa086, 0x0004, + 0x00c0, 0x916a, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078, 0x6490, + 0x0040, 0x9172, 0x706c, 0x6a08, 0xa206, 0x00c0, 0x9166, 0x7070, + 0x6a0c, 0xa206, 0x00c0, 0x9166, 0x1078, 0x2880, 0x1078, 0x77f8, + 0x0078, 0x916e, 0x1078, 0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f, + 0x0d7f, 0x007c, 0x7050, 0xa080, 0x29c0, 0x2004, 0x6a0c, 0xa206, + 0x0040, 0x9164, 0x0078, 0x9166, 0x017e, 0x027e, 0x684c, 0xd0ac, + 0x0040, 0x9194, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x9194, + 0x6860, 0xa106, 0x00c0, 0x9190, 0x685c, 0xa206, 0x0040, 0x9194, + 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c, 0x0e7e, + 0x127e, 0x2071, 0xa700, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001, + 0x0048, 0x91c9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, + 0x91b5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x91b1, 0x0078, + 0x91a4, 0x2061, 0xae00, 0x0078, 0x91a4, 0x6003, 0x0008, 0x8529, + 0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x91c5, 0x754e, + 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xae00, 0x0078, + 0x91c0, 0xa006, 0x0078, 0x91c2, 0x0c7e, 0x027e, 0x017e, 0xa186, + 0x0035, 0x0040, 0x91d6, 0x6a34, 0x0078, 0x91d7, 0x6a28, 0x1078, + 0x8d02, 0x0040, 0x9200, 0x2260, 0x611c, 0xa186, 0x0003, 0x0040, + 0x91e5, 0xa186, 0x0006, 0x00c0, 0x91fc, 0x6834, 0xa206, 0x0040, + 0x91f4, 0x6838, 0xa206, 0x00c0, 0x91fc, 0x6108, 0x6834, 0xa106, + 0x00c0, 0x91fc, 0x0078, 0x91f9, 0x6008, 0x6938, 0xa106, 0x00c0, + 0x91fc, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f, 0x007c, + 0xa085, 0x0001, 0x0078, 0x91fc, 0x6944, 0xd1cc, 0x0040, 0x921d, + 0xa18c, 0x00ff, 0xa18e, 0x0002, 0x00c0, 0x921d, 0xad88, 0x001e, + 0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001, 0x00c0, 0x921d, + 0x6810, 0x6914, 0xa115, 0x10c0, 0x84e2, 0x007c, 0x067e, 0x6000, + 0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9228, 0x067f, 0x007c, + 0x9238, 0x96ef, 0x980b, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238, + 0x9272, 0x989e, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238, + 0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332, + 0x1079, 0x9244, 0x067f, 0x007c, 0x9254, 0x9d63, 0x9254, 0x9254, + 0x9254, 0x9254, 0x9254, 0x9254, 0x9d21, 0x9db1, 0x9254, 0xa3c0, + 0xa3f4, 0xa3c0, 0xa3f4, 0x9254, 0x1078, 0x1332, 0x067e, 0x6000, + 0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9260, 0x067f, 0x007c, + 0x9270, 0x99fb, 0x9ad7, 0x9b05, 0x9b80, 0x9270, 0x9c86, 0x9c2e, + 0x98aa, 0x9cf5, 0x9d0b, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270, + 0x1078, 0x1332, 0xa1b2, 0x0044, 0x10c8, 0x1332, 0x2100, 0x0079, + 0x9279, 0x92b9, 0x94a8, 0x92b9, 0x92b9, 0x92b9, 0x94b0, 0x92b9, + 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, + 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, + 0x92bb, 0x9321, 0x9330, 0x9387, 0x93a6, 0x9425, 0x9495, 0x92b9, + 0x92b9, 0x94b4, 0x92b9, 0x92b9, 0x94c7, 0x94d2, 0x92b9, 0x92b9, + 0x92b9, 0x92b9, 0x92b9, 0x950a, 0x92b9, 0x92b9, 0x9519, 0x92b9, + 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x9532, 0x92b9, 0x92b9, + 0x92b9, 0x95bf, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, + 0x9639, 0x1078, 0x1332, 0x1078, 0x4967, 0x00c0, 0x92cb, 0x2001, + 0xa733, 0x2004, 0xd0cc, 0x00c0, 0x92cb, 0xa084, 0x0009, 0xa086, + 0x0008, 0x00c0, 0x92d3, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, + 0x0000, 0x0078, 0x94a3, 0x1078, 0x4957, 0x0e7e, 0x0c7e, 0x037e, + 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, + 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08, + 0x1078, 0x9f9b, 0x077f, 0x017f, 0x2e60, 0x1078, 0x47e9, 0x017f, + 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x6618, 0x0c7e, 0x2660, 0x1078, + 0x45d6, 0x0c7f, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, + 0x0006, 0x0048, 0x9313, 0x1078, 0x9ecf, 0x00c0, 0x9381, 0x1078, + 0x9e60, 0x00c0, 0x930f, 0x6007, 0x0008, 0x0078, 0x94a3, 0x6007, + 0x0009, 0x0078, 0x94a3, 0x1078, 0xa0af, 0x0040, 0x931d, 0x1078, + 0x9ecf, 0x0040, 0x9307, 0x0078, 0x9381, 0x6013, 0x1900, 0x0078, + 0x930f, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6106, 0x1078, 0x9e15, + 0x6007, 0x0006, 0x0078, 0x94a3, 0x6007, 0x0007, 0x0078, 0x94a3, + 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0, 0x9674, + 0x0d7e, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082, 0x0006, + 0x00c8, 0x9346, 0x2001, 0x0001, 0x1078, 0x44ee, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x0040, 0x9363, 0xa686, 0x0004, 0x0040, + 0x9363, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9363, + 0xa686, 0x0004, 0x0040, 0x9363, 0xa686, 0x0005, 0x0040, 0x9363, + 0x0d7f, 0x0078, 0x9381, 0x1078, 0x9f35, 0x00c0, 0x937c, 0xa686, + 0x0006, 0x00c0, 0x9375, 0x027e, 0x6218, 0xa290, 0x0028, 0x2214, + 0x2009, 0x0000, 0x1078, 0x28c8, 0x027f, 0x1078, 0x4649, 0x6007, + 0x000a, 0x0d7f, 0x0078, 0x94a3, 0x6007, 0x000b, 0x0d7f, 0x0078, + 0x94a3, 0x1078, 0x2880, 0x6007, 0x0001, 0x0078, 0x94a3, 0x1078, + 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6618, + 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x9381, + 0x027e, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, + 0x28c8, 0x027f, 0x6007, 0x000c, 0x0078, 0x94a3, 0x1078, 0x4967, + 0x00c0, 0x93b3, 0x2001, 0xa733, 0x2004, 0xa084, 0x0009, 0xa086, + 0x0008, 0x00c0, 0x93bb, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, + 0x0000, 0x0078, 0x94a3, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001, + 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x93ff, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x93d2, 0xa686, 0x0006, + 0x00c0, 0x9381, 0x1078, 0x9f44, 0x00c0, 0x93da, 0x6007, 0x000e, + 0x0078, 0x94a3, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, + 0x00ff, 0x8427, 0x047e, 0x1078, 0x2880, 0x047f, 0x017e, 0xa006, + 0x2009, 0xa753, 0x210c, 0xd1a4, 0x0040, 0x93f9, 0x2009, 0x0029, + 0x1078, 0xa22d, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, + 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x94a3, 0x2001, + 0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, + 0x0004, 0x2019, 0xa705, 0x2011, 0xac90, 0x1078, 0x80de, 0x037f, + 0x027f, 0x017f, 0x157f, 0xa005, 0x0040, 0x941f, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x0040, 0x93d2, 0x0078, 0x9381, 0x6013, + 0x1900, 0x6007, 0x0009, 0x0078, 0x94a3, 0x1078, 0x4967, 0x00c0, + 0x9432, 0x2001, 0xa733, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, + 0x00c0, 0x943a, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, + 0x0078, 0x94a3, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001, 0x2634, + 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x9482, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0004, 0x0040, 0x9451, 0xa686, 0x0006, 0x00c0, + 0x9381, 0x1078, 0x9f6f, 0x00c0, 0x945d, 0x1078, 0x9e60, 0x00c0, + 0x945d, 0x6007, 0x0010, 0x0078, 0x94a3, 0x047e, 0x6418, 0xa4a0, + 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2880, + 0x047f, 0x017e, 0xa006, 0x2009, 0xa753, 0x210c, 0xd1a4, 0x0040, + 0x947c, 0x2009, 0x0029, 0x1078, 0xa22d, 0x6018, 0x0d7e, 0x2068, + 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, + 0x0078, 0x94a3, 0x1078, 0xa0af, 0x0040, 0x948f, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x0040, 0x9451, 0x0078, 0x9381, 0x6013, + 0x1900, 0x6007, 0x0009, 0x0078, 0x94a3, 0x1078, 0x29bb, 0x00c0, + 0x9674, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0, + 0x9381, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c, + 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x0078, 0x94a7, + 0x6007, 0x0005, 0x0078, 0x94aa, 0x1078, 0xa42c, 0x00c0, 0x9674, + 0x1078, 0x29bb, 0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0, 0x9381, + 0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c, 0x1078, + 0x29bb, 0x00c0, 0x9674, 0x6007, 0x0023, 0x6003, 0x0001, 0x1078, + 0x5dd7, 0x007c, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, + 0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0, 0x9381, 0x017e, 0x027e, + 0x2011, 0xac90, 0x2214, 0x2c08, 0xa006, 0x1078, 0xa1f6, 0x00c0, + 0x94f9, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xac89, + 0x2214, 0xa296, 0xffff, 0x00c0, 0x9503, 0x6007, 0x0025, 0x0078, + 0x9503, 0x6004, 0xa086, 0x0024, 0x00c0, 0x9500, 0x1078, 0x772d, + 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x027f, + 0x017f, 0x007c, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6106, 0x1078, + 0x9697, 0x6007, 0x002b, 0x0078, 0x94a3, 0x6007, 0x002c, 0x0078, + 0x94a3, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0, + 0x9674, 0x1078, 0x9677, 0x00c0, 0x9381, 0x6106, 0x1078, 0x969c, + 0x00c0, 0x952e, 0x6007, 0x002e, 0x0078, 0x94a3, 0x6007, 0x002f, + 0x0078, 0x94a3, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x0e7e, 0x0d7e, + 0x0c7e, 0x6018, 0xa080, 0x0001, 0x200c, 0xa184, 0x00ff, 0xa086, + 0x0006, 0x0040, 0x954f, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006, + 0x0040, 0x954f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0078, 0x94a8, 0x2001, + 0xa772, 0x2004, 0xd0e4, 0x0040, 0x95bb, 0x2071, 0xac8c, 0x7010, + 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xa753, 0x2004, + 0xd0a4, 0x0040, 0x956d, 0x6018, 0x2068, 0x6810, 0xa106, 0x00c0, + 0x956d, 0x6814, 0xa206, 0x0040, 0x9591, 0x2001, 0xa753, 0x2004, + 0xd0ac, 0x00c0, 0x95af, 0x2069, 0xa700, 0x6870, 0xa206, 0x00c0, + 0x95af, 0x686c, 0xa106, 0x00c0, 0x95af, 0x7210, 0x1078, 0x8d02, + 0x0040, 0x95b5, 0x1078, 0xa29e, 0x0040, 0x95b5, 0x622a, 0x6007, + 0x0036, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0c7f, 0x0d7f, 0x0e7f, + 0x007c, 0x7214, 0xa286, 0xffff, 0x0040, 0x95a3, 0x1078, 0x8d02, + 0x0040, 0x95b5, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x00c0, + 0x95b5, 0x0078, 0x957e, 0x7210, 0x2c08, 0xa085, 0x0001, 0x1078, + 0xa1f6, 0x2c10, 0x2160, 0x0040, 0x95b5, 0x0078, 0x957e, 0x6007, + 0x0037, 0x6013, 0x1500, 0x0078, 0x9589, 0x6007, 0x0037, 0x6013, + 0x1700, 0x0078, 0x9589, 0x6007, 0x0012, 0x0078, 0x9589, 0x1078, + 0x29bb, 0x00c0, 0x9674, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, + 0xff00, 0x8007, 0xa086, 0x0006, 0x00c0, 0x94a8, 0x0e7e, 0x0d7e, + 0x0c7e, 0x2001, 0xa772, 0x2004, 0xd0e4, 0x0040, 0x9631, 0x2069, + 0xa700, 0x2071, 0xac8c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, + 0xffff, 0x00c0, 0x95ee, 0x7208, 0x0c7e, 0x2c08, 0xa085, 0x0001, + 0x1078, 0xa1f6, 0x2c10, 0x0c7f, 0x0040, 0x9625, 0x1078, 0x8d02, + 0x0040, 0x9625, 0x0c7e, 0x027e, 0x2260, 0x1078, 0x8a03, 0x027f, + 0x0c7f, 0x7118, 0xa18c, 0xff00, 0x810f, 0xa186, 0x0001, 0x0040, + 0x960f, 0xa186, 0x0005, 0x0040, 0x9609, 0xa186, 0x0007, 0x00c0, + 0x9619, 0xa280, 0x0004, 0x2004, 0xa005, 0x0040, 0x9619, 0x057e, + 0x7510, 0x7614, 0x1078, 0xa2b3, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, + 0x007c, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, + 0x0001, 0x1078, 0x5d8a, 0x0078, 0x9615, 0x6007, 0x003b, 0x602b, + 0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0078, + 0x9615, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0078, + 0x9589, 0x0e7e, 0x027e, 0x1078, 0x4967, 0x0040, 0x966e, 0x1078, + 0x4957, 0x1078, 0xa4b9, 0x00c0, 0x966c, 0x2071, 0xa700, 0x70cc, + 0xc085, 0x70ce, 0x0f7e, 0x2079, 0x0100, 0x7298, 0xa284, 0x00ff, + 0x706e, 0x78e6, 0xa284, 0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, + 0x0f7f, 0x70d7, 0x0000, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, + 0x9665, 0x2011, 0xa9ca, 0x2013, 0x07d0, 0xd0ac, 0x00c0, 0x966e, + 0x1078, 0x2677, 0x0078, 0x966e, 0x1078, 0xa4e9, 0x027f, 0x0e7f, + 0x1078, 0x772d, 0x0078, 0x94a7, 0x1078, 0x772d, 0x007c, 0x0d7e, + 0x067e, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0006, 0x0040, 0x9694, 0xa686, 0x0004, 0x0040, 0x9694, 0x6e04, + 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9694, 0xa686, 0x0004, + 0x0040, 0x9694, 0xa085, 0x0001, 0x067f, 0x0d7f, 0x007c, 0x0d7e, + 0x1078, 0x96cb, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x96da, 0x00c0, + 0x96c4, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff, 0xa115, + 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0040, 0x96b2, 0x2009, 0x0001, + 0x0078, 0x96c0, 0xd1ec, 0x0040, 0x96c4, 0x6920, 0xa18c, 0x00ff, + 0x6824, 0x1078, 0x254d, 0x00c0, 0x96c4, 0x2110, 0x2009, 0x0000, + 0x1078, 0x28c8, 0x0078, 0x96c8, 0xa085, 0x0001, 0x0078, 0x96c9, + 0xa006, 0x0d7f, 0x007c, 0x2069, 0xac8d, 0x6800, 0xa082, 0x0010, + 0x00c8, 0x96d8, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x96d9, + 0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0xac8c, 0x6808, 0xa084, + 0xff00, 0xa086, 0x0800, 0x00c0, 0x96ee, 0x6800, 0xa084, 0x00ff, + 0xa08e, 0x0014, 0x0040, 0x96ee, 0xa08e, 0x0010, 0x007c, 0x6004, + 0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0, 0x96fb, + 0x2008, 0x0079, 0x970e, 0xa1b6, 0x0027, 0x0040, 0x9703, 0xa1b6, + 0x0014, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, + 0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c, 0x974e, 0x9750, + 0x974e, 0x974e, 0x974e, 0x9750, 0x975c, 0x97e6, 0x97a9, 0x97e6, + 0x97bd, 0x97e6, 0x975c, 0x97e6, 0x97de, 0x97e6, 0x97de, 0x97e6, + 0x97e6, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, + 0x974e, 0x974e, 0x974e, 0x974e, 0x9750, 0x974e, 0x97e6, 0x974e, + 0x974e, 0x97e6, 0x974e, 0x97e6, 0x97e6, 0x974e, 0x974e, 0x974e, + 0x974e, 0x97e6, 0x97e6, 0x974e, 0x97e6, 0x97e6, 0x974e, 0x974e, + 0x974e, 0x974e, 0x974e, 0x9750, 0x97e6, 0x97e6, 0x974e, 0x974e, + 0x97e6, 0x97e6, 0x974e, 0x974e, 0x974e, 0x974e, 0x1078, 0x1332, + 0x1078, 0x61cd, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x6003, 0x0002, + 0x1078, 0x62d1, 0x0078, 0x97ec, 0x0f7e, 0x2079, 0xa752, 0x7804, + 0x0f7f, 0xd0ac, 0x00c0, 0x97e6, 0x2001, 0x0000, 0x1078, 0x44ee, + 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x97e6, + 0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9780, 0x6010, + 0xa005, 0x0040, 0x9780, 0x0c7f, 0x1078, 0x3699, 0x0078, 0x97e6, + 0x0c7f, 0x2001, 0xa700, 0x2004, 0xa086, 0x0002, 0x00c0, 0x978f, + 0x0f7e, 0x2079, 0xa700, 0x7890, 0x8000, 0x7892, 0x0f7f, 0x2001, + 0x0002, 0x1078, 0x4502, 0x1078, 0x61cd, 0x601f, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0c7e, + 0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x5a52, 0x0c7f, 0x0078, + 0x97ec, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, + 0x8637, 0xa686, 0x0006, 0x0040, 0x97e6, 0xa686, 0x0004, 0x0040, + 0x97e6, 0x2001, 0x0004, 0x0078, 0x97e4, 0x2001, 0xa700, 0x2004, + 0xa086, 0x0003, 0x00c0, 0x97c6, 0x1078, 0x3699, 0x2001, 0x0006, + 0x1078, 0x97ed, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x97e6, 0x2001, 0x0006, + 0x0078, 0x97e4, 0x2001, 0x0004, 0x0078, 0x97e4, 0x2001, 0x0006, + 0x1078, 0x97ed, 0x0078, 0x97e6, 0x1078, 0x4535, 0x1078, 0x61cd, + 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0x017e, 0x0d7e, 0x6118, + 0x2168, 0x6900, 0xd184, 0x0040, 0x9808, 0x6104, 0xa18e, 0x000a, + 0x00c0, 0x9800, 0x699c, 0xd1a4, 0x00c0, 0x9800, 0x2001, 0x0007, + 0x1078, 0x4502, 0x2001, 0x0000, 0x1078, 0x44ee, 0x1078, 0x28a6, + 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, + 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0xa1b6, + 0x0015, 0x00c0, 0x981f, 0x1079, 0x9826, 0x0078, 0x9825, 0xa1b6, + 0x0016, 0x10c0, 0x1332, 0x1079, 0x9832, 0x007c, 0x7d4e, 0x7d4e, + 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x9887, 0x983e, 0x7d4e, 0x7d4e, + 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, + 0x9887, 0x988f, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x0f7e, 0x2079, + 0xa752, 0x7804, 0xd0ac, 0x00c0, 0x9865, 0x6018, 0xa07d, 0x0040, + 0x9865, 0x7800, 0xd0f4, 0x00c0, 0x9851, 0x7810, 0xa005, 0x00c0, + 0x9865, 0x2001, 0x0000, 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, + 0x4502, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, + 0x5dd7, 0x1078, 0x62d1, 0x0078, 0x9885, 0x2011, 0xac83, 0x2204, + 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9885, 0x0c7e, 0x1078, + 0x45c4, 0x0040, 0x9878, 0x0c7f, 0x1078, 0x772d, 0x0078, 0x9885, + 0x6010, 0x007e, 0x6014, 0x007e, 0x1078, 0x42f8, 0x007f, 0x6016, + 0x007f, 0x6012, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c, 0x6604, + 0xa6b6, 0x001e, 0x00c0, 0x988e, 0x1078, 0x772d, 0x007c, 0x1078, + 0x7f8e, 0x00c0, 0x989b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, + 0x5dd7, 0x0078, 0x989d, 0x1078, 0x772d, 0x007c, 0x6004, 0xa08a, + 0x0044, 0x10c8, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078, + 0x62d1, 0x007c, 0xa182, 0x0040, 0x0079, 0x98ae, 0x98c1, 0x98c1, + 0x98c1, 0x98c1, 0x98c3, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, + 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, + 0x98c1, 0x1078, 0x1332, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, + 0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x98d4, + 0x2021, 0x0000, 0x1078, 0xa482, 0x6106, 0x2071, 0xac80, 0x7444, + 0xa4a4, 0xff00, 0x0040, 0x992b, 0xa486, 0x2000, 0x00c0, 0x98e6, + 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5bf1, 0x1078, 0x138b, + 0x1040, 0x1332, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, + 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2, + 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084, + 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4a73, + 0x017f, 0xa486, 0x2000, 0x00c0, 0x9913, 0x2019, 0x0017, 0x1078, + 0xa1a5, 0x0078, 0x998d, 0xa486, 0x0400, 0x00c0, 0x991d, 0x2019, + 0x0002, 0x1078, 0xa156, 0x0078, 0x998d, 0xa486, 0x0200, 0x00c0, + 0x9923, 0x1078, 0xa13b, 0xa486, 0x1000, 0x00c0, 0x9929, 0x1078, + 0xa18a, 0x0078, 0x998d, 0x2069, 0xaa33, 0x6a00, 0xd284, 0x0040, + 0x99f7, 0xa284, 0x0300, 0x00c0, 0x99ef, 0x6804, 0xa005, 0x0040, + 0x99d5, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1370, 0x0040, 0x9994, + 0x7800, 0xd08c, 0x00c0, 0x9947, 0x7804, 0x8001, 0x7806, 0x6013, + 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, + 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, + 0x6986, 0x6846, 0x7928, 0x698a, 0x792c, 0x698e, 0x7930, 0x6992, + 0x7934, 0x6996, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, + 0x0002, 0x00c0, 0x996f, 0x684f, 0x0040, 0x0078, 0x9979, 0xa286, + 0x0001, 0x00c0, 0x9977, 0x684f, 0x0080, 0x0078, 0x9979, 0x684f, + 0x0000, 0x20a9, 0x000a, 0x2001, 0xac90, 0xad90, 0x0015, 0x200c, + 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x997f, 0x200c, 0x6982, + 0x8000, 0x200c, 0x697e, 0x1078, 0x4a73, 0x027f, 0x047f, 0x157f, + 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x2001, 0xa70e, 0x2004, 0xd084, + 0x0040, 0x999e, 0x1078, 0x138b, 0x00c0, 0x9940, 0x6013, 0x0100, + 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, + 0x0078, 0x998d, 0x2069, 0xac92, 0x2d04, 0xa084, 0xff00, 0xa086, + 0x1200, 0x00c0, 0x99c9, 0x2069, 0xac80, 0x686c, 0xa084, 0x00ff, + 0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, + 0x0001, 0x6007, 0x0043, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, + 0x998d, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, + 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x998d, 0x2001, 0xa70d, 0x2004, + 0xd0ec, 0x0040, 0x99df, 0x2011, 0x8049, 0x1078, 0x361b, 0x6013, + 0x0300, 0x0078, 0x99e5, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, + 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x998d, 0x6013, + 0x0500, 0x0078, 0x99e5, 0x6013, 0x0600, 0x0078, 0x99aa, 0x6013, + 0x0200, 0x0078, 0x99aa, 0xa186, 0x0013, 0x00c0, 0x9a0d, 0x6004, + 0xa08a, 0x0040, 0x1048, 0x1332, 0xa08a, 0x0053, 0x10c8, 0x1332, + 0xa082, 0x0040, 0x2008, 0x0079, 0x9a92, 0xa186, 0x0051, 0x0040, + 0x9a1a, 0xa186, 0x0047, 0x00c0, 0x9a33, 0x6004, 0xa086, 0x0041, + 0x0040, 0x9a41, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x9a41, + 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x5c56, + 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0, + 0x9a41, 0x0078, 0x9ad7, 0xa186, 0x0027, 0x0040, 0x9a3b, 0xa186, + 0x0014, 0x10c0, 0x1332, 0x6004, 0xa082, 0x0040, 0x2008, 0x0079, + 0x9a44, 0x1078, 0x7773, 0x007c, 0x9a57, 0x9a59, 0x9a59, 0x9a81, + 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, + 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x1078, + 0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x037e, 0x0d7e, 0x6010, + 0xa06d, 0x0040, 0x9a7e, 0xad84, 0xf000, 0x0040, 0x9a7e, 0x6003, + 0x0002, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x9a7e, 0x2019, 0x0004, + 0x1078, 0xa1da, 0x6013, 0x0000, 0x6014, 0xa005, 0x00c0, 0x9a7c, + 0x2001, 0xa9a3, 0x2004, 0x6016, 0x6003, 0x0007, 0x0d7f, 0x037f, + 0x007c, 0x0d7e, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x1078, 0x8d16, + 0x0040, 0x9a8e, 0x6010, 0x2068, 0x1078, 0x13a4, 0x1078, 0x8ed6, + 0x0d7f, 0x007c, 0x9aa5, 0x9ac4, 0x9aae, 0x9ad1, 0x9aa5, 0x9aa5, + 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, + 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x1078, 0x1332, 0x6010, + 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x61cd, + 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x9abf, 0x6003, + 0x0007, 0x2009, 0x0043, 0x1078, 0x775c, 0x0078, 0x9ac1, 0x6003, + 0x0002, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0xa433, + 0x00c0, 0x9ace, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x1078, 0x62d1, + 0x007c, 0x1078, 0x61cd, 0x2009, 0x0041, 0x0078, 0x9c2e, 0xa182, + 0x0040, 0x0079, 0x9adb, 0x9aee, 0x9af0, 0x9aee, 0x9aee, 0x9aee, + 0x9aee, 0x9aee, 0x9af1, 0x9aee, 0x9aee, 0x9aee, 0x9aee, 0x9aee, + 0x9aee, 0x9aee, 0x9aee, 0x9aee, 0x9afc, 0x9aee, 0x1078, 0x1332, + 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x1078, 0x15fa, 0x007c, 0x0d7e, 0x1078, 0x5bc1, 0x0d7f, + 0x1078, 0xa4a5, 0x1078, 0x772d, 0x007c, 0xa182, 0x0040, 0x0079, + 0x9b09, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, + 0x9b1e, 0x9b1c, 0x9b21, 0x9b4c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, + 0x9b4c, 0x9b1c, 0x9b1c, 0x9b1c, 0x1078, 0x1332, 0x1078, 0x7773, + 0x007c, 0x1078, 0x627a, 0x1078, 0x639b, 0x6010, 0x0d7e, 0x2068, + 0x684c, 0xd0fc, 0x0040, 0x9b37, 0xa08c, 0x0003, 0xa18e, 0x0002, + 0x0040, 0x9b3f, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c2e, 0x6003, + 0x0007, 0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x1078, + 0xa433, 0x0040, 0x9b45, 0x0d7f, 0x007c, 0x1078, 0x5bc1, 0x1078, + 0x772d, 0x0d7f, 0x0078, 0x9b3e, 0x037e, 0x1078, 0x627a, 0x1078, + 0x639b, 0x6010, 0x0d7e, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0040, + 0x9b6c, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x9b68, + 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a, + 0x6003, 0x0002, 0x0078, 0x9b7d, 0x2019, 0x0004, 0x1078, 0xa1da, + 0x6014, 0xa005, 0x00c0, 0x9b79, 0x2001, 0xa9a3, 0x2004, 0x8003, + 0x6016, 0x6013, 0x0000, 0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, + 0xa186, 0x0013, 0x00c0, 0x9b8e, 0x6004, 0xa086, 0x0042, 0x10c0, + 0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0027, + 0x0040, 0x9b96, 0xa186, 0x0014, 0x00c0, 0x9ba6, 0x6004, 0xa086, + 0x0042, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, + 0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040, + 0x0079, 0x9baa, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, + 0x9bbd, 0x9bbf, 0x9bcb, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, + 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x1078, 0x1332, 0x037e, + 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15fa, + 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x6810, 0x6a14, + 0x6118, 0x210c, 0xd1bc, 0x0040, 0x9bea, 0x6124, 0xd1f4, 0x00c0, + 0x9bea, 0x007e, 0x047e, 0x057e, 0x6c7c, 0xa422, 0x6d80, 0x2200, + 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a, 0x057f, + 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9bfe, 0x684c, 0xd0fc, 0x0040, + 0x9bf6, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c2e, 0x6003, 0x0007, + 0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x007e, 0x0f7e, + 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x007f, 0x0040, 0x9c0b, 0x6003, + 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa70d, 0x210c, 0xd19c, 0x0040, + 0x9c15, 0x6003, 0x0007, 0x0078, 0x9c17, 0x6003, 0x0006, 0x1078, + 0x9c1d, 0x1078, 0x5bc3, 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x9c29, + 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0078, + 0x9c2b, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040, + 0x0048, 0x9c34, 0x0079, 0x9c41, 0xa186, 0x0013, 0x0040, 0x9c3c, + 0xa186, 0x0014, 0x10c0, 0x1332, 0x6024, 0xd0dc, 0x1040, 0x1332, + 0x007c, 0x9c54, 0x9c5b, 0x9c67, 0x9c73, 0x9c54, 0x9c54, 0x9c54, + 0x9c82, 0x9c54, 0x9c56, 0x9c56, 0x9c54, 0x9c54, 0x9c54, 0x9c54, + 0x9c54, 0x9c54, 0x9c54, 0x9c54, 0x1078, 0x1332, 0x6024, 0xd0dc, + 0x1040, 0x1332, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, + 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x6003, + 0x0001, 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078, + 0x62d1, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, + 0x1cf0, 0x127e, 0x2091, 0x8000, 0x1078, 0x5df6, 0x1078, 0x639b, + 0x127f, 0x007c, 0xa016, 0x1078, 0x15fa, 0x007c, 0x127e, 0x2091, + 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x9c93, 0x0d7f, + 0x037f, 0x127f, 0x007c, 0x9ca3, 0x9ca5, 0x9cba, 0x9cd9, 0x9ca3, + 0x9ca3, 0x9ca3, 0x9cf1, 0x9ca3, 0x9ca3, 0x9ca3, 0x9ca3, 0x9ca3, + 0x9ca3, 0x9ca3, 0x9ca3, 0x1078, 0x1332, 0x6010, 0x2068, 0x684c, + 0xd0fc, 0x0040, 0x9ccf, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, + 0x9ccf, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1, + 0x0078, 0x9cf4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9ccf, + 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9ccf, 0x6003, 0x0001, + 0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x9cf4, 0x6013, + 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0xa1da, 0x0078, + 0x9cf4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9ccf, 0xa09c, + 0x0003, 0xa39e, 0x0003, 0x0040, 0x9ccf, 0x6003, 0x0003, 0x6106, + 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, 0x1078, 0x639b, 0x0078, + 0x9cf4, 0xa016, 0x1078, 0x15fa, 0x007c, 0x1078, 0x61cd, 0x6110, + 0x81ff, 0x0040, 0x9d06, 0x0d7e, 0x2168, 0x1078, 0xa4f2, 0x037e, + 0x2019, 0x0029, 0x1078, 0xa1da, 0x037f, 0x0d7f, 0x1078, 0x8ed6, + 0x1078, 0x62d1, 0x007c, 0x1078, 0x627a, 0x6110, 0x81ff, 0x0040, + 0x9d1c, 0x0d7e, 0x2168, 0x1078, 0xa4f2, 0x037e, 0x2019, 0x0029, + 0x1078, 0xa1da, 0x037f, 0x0d7f, 0x1078, 0x8ed6, 0x1078, 0x639b, + 0x007c, 0xa182, 0x0085, 0x0079, 0x9d25, 0x9d2e, 0x9d2c, 0x9d2c, + 0x9d3a, 0x9d2c, 0x9d2c, 0x9d2c, 0x1078, 0x1332, 0x6003, 0x000b, + 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, + 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078, 0xa42c, 0x0040, 0x9d44, + 0x1078, 0x772d, 0x0078, 0x9d60, 0x2071, 0xac80, 0x7224, 0x6212, + 0x7220, 0x1078, 0xa079, 0x0040, 0x9d51, 0x6007, 0x0086, 0x0078, + 0x9d5a, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0, 0x9d5a, + 0x6007, 0x0086, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, + 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9d74, 0x6004, + 0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332, + 0xa082, 0x0085, 0x0079, 0x9d8b, 0xa186, 0x0027, 0x0040, 0x9d80, + 0xa186, 0x0014, 0x0040, 0x9d80, 0x1078, 0x7773, 0x0078, 0x9d8a, + 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x61cd, 0x1078, 0x8ed6, + 0x1078, 0x62d1, 0x007c, 0x9d92, 0x9d94, 0x9d94, 0x9d92, 0x9d92, + 0x9d92, 0x9d92, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6, + 0x1078, 0x62d1, 0x007c, 0xa182, 0x0085, 0x1048, 0x1332, 0xa182, + 0x008c, 0x10c8, 0x1332, 0xa182, 0x0085, 0x0079, 0x9da7, 0x9dae, + 0x9dae, 0x9dae, 0x9db0, 0x9dae, 0x9dae, 0x9dae, 0x1078, 0x1332, + 0x007c, 0xa186, 0x0013, 0x0040, 0x9dc1, 0xa186, 0x0014, 0x0040, + 0x9dc1, 0xa186, 0x0027, 0x0040, 0x9dc1, 0x1078, 0x7773, 0x0078, + 0x9dc7, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c, + 0x037e, 0x1078, 0xa4a5, 0x603f, 0x0000, 0x2019, 0x000b, 0x1078, + 0x9dd7, 0x601f, 0x0006, 0x6003, 0x0007, 0x037f, 0x007c, 0x127e, + 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40, 0x097e, 0x2049, 0x0000, + 0x1078, 0x7246, 0x097f, 0x087f, 0x00c0, 0x9e12, 0x077e, 0x2c38, + 0x1078, 0x72f3, 0x077f, 0x00c0, 0x9e12, 0x6000, 0xa086, 0x0000, + 0x0040, 0x9e12, 0x601c, 0xa086, 0x0007, 0x0040, 0x9e12, 0x0d7e, + 0x6000, 0xa086, 0x0004, 0x00c0, 0x9e03, 0x1078, 0xa4a5, 0x601f, + 0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, + 0x9e0b, 0x1078, 0xa1da, 0x0d7f, 0x6013, 0x0000, 0x1078, 0xa4a5, + 0x601f, 0x0007, 0x037f, 0x127f, 0x007c, 0x0f7e, 0x0c7e, 0x037e, + 0x157e, 0x2079, 0xac80, 0x7938, 0x783c, 0x1078, 0x254d, 0x00c0, + 0x9e59, 0x017e, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x9e59, 0x017f, + 0x027f, 0x027e, 0x017e, 0x2019, 0x0029, 0x1078, 0x73d0, 0x1078, + 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x077f, 0x017f, + 0x077e, 0x2039, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x1078, 0x47e9, + 0x027e, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, + 0x9e4d, 0xa286, 0x0004, 0x00c0, 0x9e50, 0x62a0, 0x1078, 0x2942, + 0x027f, 0x017f, 0x1078, 0x42f8, 0x6612, 0x6516, 0xa006, 0x0078, + 0x9e5b, 0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, + 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x2009, 0xa720, 0x2104, 0xa086, + 0x0074, 0x00c0, 0x9ec3, 0x2069, 0xac8e, 0x690c, 0xa182, 0x0100, + 0x0048, 0x9eb3, 0x6908, 0xa184, 0x8000, 0x0040, 0x9ebf, 0x6018, + 0x2070, 0x7010, 0xa084, 0x00ff, 0x0040, 0x9e82, 0x7000, 0xd0f4, + 0x0040, 0x9e86, 0xa184, 0x0800, 0x0040, 0x9ebf, 0x6910, 0xa18a, + 0x0001, 0x0048, 0x9eb7, 0x6914, 0x2069, 0xacae, 0x6904, 0x81ff, + 0x00c0, 0x9eab, 0x690c, 0xa182, 0x0100, 0x0048, 0x9eb3, 0x6908, + 0x81ff, 0x00c0, 0x9eaf, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9eb7, + 0x6918, 0xa18a, 0x0001, 0x0048, 0x9ebf, 0x0078, 0x9ec9, 0x6013, + 0x0100, 0x0078, 0x9ec5, 0x6013, 0x0300, 0x0078, 0x9ec5, 0x6013, + 0x0500, 0x0078, 0x9ec5, 0x6013, 0x0700, 0x0078, 0x9ec5, 0x6013, + 0x0900, 0x0078, 0x9ec5, 0x6013, 0x0b00, 0x0078, 0x9ec5, 0x6013, + 0x0f00, 0x0078, 0x9ec5, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, + 0x9eca, 0xa006, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, + 0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, + 0x00ff, 0xa286, 0x0006, 0x0040, 0x9ef3, 0xa286, 0x0004, 0x0040, + 0x9ef3, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9ef3, + 0xa286, 0x0004, 0x0040, 0x9ef3, 0x0c7e, 0x2d60, 0x1078, 0x45d6, + 0x0c7f, 0x0078, 0x9f2e, 0x2011, 0xac96, 0xad98, 0x000a, 0x20a9, + 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f2f, 0x2011, 0xac9a, 0xad98, + 0x0006, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f2f, 0x047e, + 0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xa753, + 0x210c, 0xd1a4, 0x0040, 0x9f1b, 0x2009, 0x0029, 0x1078, 0xa22d, + 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, + 0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f, + 0x2001, 0x0007, 0x1078, 0x4535, 0x017f, 0x047f, 0xa006, 0x157f, + 0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xac8e, + 0x6800, 0xa086, 0x0800, 0x0040, 0x9f41, 0x6013, 0x0000, 0x0078, + 0x9f42, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, + 0x037e, 0x157e, 0x2079, 0xac8c, 0x7930, 0x7834, 0x1078, 0x254d, + 0x00c0, 0x9f68, 0x1078, 0x45c4, 0x00c0, 0x9f68, 0x2011, 0xac90, + 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f68, + 0x2011, 0xac94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x80de, + 0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, + 0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0xac83, 0x2204, + 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9f94, 0x1078, 0x45c4, + 0x00c0, 0x9f94, 0x2011, 0xac96, 0xac98, 0x000a, 0x20a9, 0x0004, + 0x1078, 0x80de, 0x00c0, 0x9f94, 0x2011, 0xac9a, 0xac98, 0x0006, + 0x20a9, 0x0004, 0x1078, 0x80de, 0x157f, 0x037f, 0x027f, 0x017f, + 0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, + 0x057e, 0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2029, + 0xa9ba, 0x252c, 0x2021, 0xa9c0, 0x2424, 0x2061, 0xae00, 0x2071, + 0xa700, 0x7648, 0x7064, 0x81ff, 0x0040, 0x9fc2, 0x007e, 0xa186, + 0xaab3, 0x007f, 0x0040, 0x9fc2, 0x8001, 0xa602, 0x00c8, 0xa02c, + 0x0078, 0x9fc5, 0xa606, 0x0040, 0xa02c, 0x2100, 0xac06, 0x0040, + 0xa022, 0x1078, 0xa252, 0x0040, 0xa022, 0x671c, 0xa786, 0x0001, + 0x0040, 0xa047, 0xa786, 0x0004, 0x0040, 0xa047, 0xa786, 0x0007, + 0x0040, 0xa022, 0x2500, 0xac06, 0x0040, 0xa022, 0x2400, 0xac06, + 0x0040, 0xa022, 0x1078, 0xa266, 0x00c0, 0xa022, 0x88ff, 0x0040, + 0x9fed, 0x6020, 0xa906, 0x00c0, 0xa022, 0x0d7e, 0x6000, 0xa086, + 0x0004, 0x00c0, 0x9ff7, 0x017e, 0x1078, 0x1757, 0x017f, 0xa786, + 0x0008, 0x00c0, 0xa006, 0x1078, 0x8f10, 0x00c0, 0xa006, 0x1078, + 0x7c83, 0x0d7f, 0x1078, 0x8ed6, 0x0078, 0xa022, 0x6010, 0x2068, + 0x1078, 0x8d16, 0x0040, 0xa01f, 0xa786, 0x0003, 0x00c0, 0xa036, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa4f2, 0x017e, + 0x1078, 0x8f8d, 0x1078, 0x4a73, 0x017f, 0x1078, 0x8ec9, 0x0d7f, + 0x1078, 0x8ed6, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02, + 0x00c8, 0xa02c, 0x0078, 0x9faf, 0x127f, 0x027f, 0x047f, 0x057f, + 0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, + 0x00c0, 0xa010, 0xa386, 0x0005, 0x0040, 0xa044, 0x1078, 0xa4f2, + 0x1078, 0xa1da, 0x0078, 0xa01f, 0x0d7f, 0x0078, 0xa022, 0x1078, + 0xa266, 0x00c0, 0xa022, 0x81ff, 0x0040, 0xa022, 0xa180, 0x0001, + 0x2004, 0xa086, 0x0018, 0x0040, 0xa05c, 0xa180, 0x0001, 0x2004, + 0xa086, 0x002d, 0x00c0, 0xa022, 0x6000, 0xa086, 0x0002, 0x00c0, + 0xa022, 0x1078, 0x8efc, 0x0040, 0xa06d, 0x1078, 0x8f10, 0x00c0, + 0xa022, 0x1078, 0x7c83, 0x0078, 0xa075, 0x1078, 0x28a6, 0x1078, + 0x8f10, 0x00c0, 0xa075, 0x1078, 0x7c83, 0x1078, 0x8ed6, 0x0078, + 0xa022, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0xa006, 0x1078, + 0xa1f6, 0x017f, 0x0040, 0xa089, 0x601c, 0xa084, 0x000f, 0x1079, + 0xa08c, 0x0e7f, 0x0c7f, 0x007c, 0xa094, 0xa094, 0xa094, 0xa094, + 0xa094, 0xa094, 0xa096, 0xa094, 0xa006, 0x007c, 0x047e, 0x017e, + 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, + 0x2009, 0x0020, 0x1078, 0xa22d, 0x017f, 0x047f, 0x037e, 0x2019, + 0x0002, 0x1078, 0x9dd7, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, + 0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, + 0x0004, 0x2019, 0xa705, 0x2011, 0xac96, 0x1078, 0x80de, 0x037f, + 0x027f, 0x017f, 0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, + 0x087e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, + 0x2061, 0xae00, 0x2079, 0x0001, 0x8fff, 0x0040, 0xa12d, 0x2071, + 0xa700, 0x7648, 0x7064, 0x8001, 0xa602, 0x00c8, 0xa12d, 0x88ff, + 0x0040, 0xa0e8, 0x2800, 0xac06, 0x00c0, 0xa123, 0x2079, 0x0000, + 0x1078, 0xa252, 0x0040, 0xa123, 0x2400, 0xac06, 0x0040, 0xa123, + 0x671c, 0xa786, 0x0006, 0x00c0, 0xa123, 0xa786, 0x0007, 0x0040, + 0xa123, 0x88ff, 0x00c0, 0xa107, 0x6018, 0xa206, 0x00c0, 0xa123, + 0x85ff, 0x0040, 0xa107, 0x6020, 0xa106, 0x00c0, 0xa123, 0x0d7e, + 0x6000, 0xa086, 0x0004, 0x00c0, 0xa113, 0x1078, 0xa4a5, 0x601f, + 0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, + 0xa11d, 0x047e, 0x1078, 0xa1da, 0x047f, 0x0d7f, 0x1078, 0x8ed6, + 0x88ff, 0x00c0, 0xa137, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, + 0xac02, 0x00c8, 0xa12d, 0x0078, 0xa0d4, 0xa006, 0x127f, 0x027f, + 0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, + 0x0001, 0x0078, 0xa12e, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, + 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, + 0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, + 0x72f3, 0x1078, 0xa0c5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, + 0x057e, 0x077e, 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, + 0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa17e, + 0x2c10, 0x057e, 0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, + 0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039, + 0x0000, 0x1078, 0x72f3, 0x1078, 0xa0c5, 0x057f, 0x037f, 0x017f, + 0x8108, 0x00f0, 0xa162, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, + 0x027f, 0x007c, 0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, + 0x2029, 0x0001, 0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, + 0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x72f3, 0x2c20, + 0x1078, 0xa0c5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, + 0x077e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, + 0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa1ce, 0x2c10, 0x087e, + 0x2041, 0x0000, 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa482, + 0x047f, 0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f, + 0x2039, 0x0000, 0x1078, 0x72f3, 0x1078, 0xa0c5, 0x037f, 0x017f, + 0x8108, 0x00f0, 0xa1b0, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, + 0x027f, 0x007c, 0x017e, 0x0f7e, 0xad82, 0xce00, 0x0048, 0xa1f3, + 0xad82, 0xffff, 0x00c8, 0xa1f3, 0x6800, 0xa07d, 0x0040, 0xa1f0, + 0x6803, 0x0000, 0x6b52, 0x1078, 0x4a73, 0x2f68, 0x0078, 0xa1e4, + 0x6b52, 0x1078, 0x4a73, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, + 0x037e, 0x2061, 0xae00, 0xa005, 0x00c0, 0xa206, 0x2071, 0xa700, + 0x7448, 0x7064, 0x8001, 0xa402, 0x00c8, 0xa228, 0x2100, 0xac06, + 0x0040, 0xa21a, 0x6000, 0xa086, 0x0000, 0x0040, 0xa21a, 0x6008, + 0xa206, 0x00c0, 0xa21a, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406, + 0x0040, 0xa224, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02, + 0x00c8, 0xa228, 0x0078, 0xa206, 0xa085, 0x0001, 0x0078, 0xa229, + 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, 0x007e, 0x1078, + 0x138b, 0x007f, 0x1040, 0x1332, 0x6837, 0x010d, 0x685e, 0x027e, + 0x2010, 0x1078, 0x8d02, 0x2001, 0x0000, 0x0040, 0xa243, 0x2200, + 0xa080, 0x0008, 0x2004, 0x027f, 0x684a, 0x6956, 0x6c46, 0x684f, + 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x1078, 0x4a73, + 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0xa265, 0xa786, + 0x0001, 0x0040, 0xa265, 0xa786, 0x000a, 0x0040, 0xa265, 0xa786, + 0x0009, 0x0040, 0xa265, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018, + 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x017e, 0x6004, 0xa08e, + 0x001e, 0x00c0, 0xa287, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, + 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005, 0x2001, + 0xa9a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x017f, + 0x007c, 0x0005, 0x0005, 0x007c, 0x6024, 0xd0e4, 0x0040, 0xa29d, + 0xd0cc, 0x0040, 0xa297, 0x1078, 0x8fcf, 0x0078, 0xa29d, 0x1078, + 0xa4a5, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x007c, 0xa280, 0x0007, + 0x2004, 0xa084, 0x000f, 0x0079, 0xa2a5, 0xa2ae, 0xa2ae, 0xa2ae, + 0xa2b0, 0xa2ae, 0xa2b0, 0xa2b0, 0xa2ae, 0xa2b0, 0xa006, 0x007c, + 0xa085, 0x0001, 0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, + 0x0079, 0xa2ba, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3, + 0xa2ce, 0xa2c3, 0xa2c3, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, + 0x2a00, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x007c, 0x0c7e, 0x2260, + 0x1078, 0xa4a5, 0x603f, 0x0000, 0x6024, 0xc0f4, 0xc0cc, 0x6026, + 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007, 0x00c0, 0xa32f, 0x6810, + 0xa005, 0x0040, 0xa2ec, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x00c0, + 0xa2ec, 0x0d7f, 0x0078, 0xa2c3, 0x6007, 0x003a, 0x6003, 0x0001, + 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100, 0xa186, + 0x0002, 0x00c0, 0xa3bd, 0x6010, 0xa005, 0x00c0, 0xa306, 0x6000, + 0xa086, 0x0007, 0x10c0, 0x1332, 0x0078, 0xa3bd, 0xa08c, 0xf000, + 0x00c0, 0xa312, 0x0078, 0xa312, 0x2068, 0x6800, 0xa005, 0x00c0, + 0xa30c, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086, + 0x0002, 0x00c0, 0xa32b, 0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4, + 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043, 0x1078, + 0x9c2e, 0x0078, 0xa3bd, 0x2009, 0x0041, 0x0078, 0xa3b7, 0xa186, + 0x0005, 0x00c0, 0xa376, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc, + 0x00c0, 0xa33d, 0x0d7f, 0x0078, 0xa2c3, 0xd0b4, 0x0040, 0xa345, + 0xd0fc, 0x1040, 0x1332, 0x0078, 0xa2df, 0x6007, 0x003a, 0x6003, + 0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100, + 0xa186, 0x0002, 0x0040, 0xa358, 0xa186, 0x0004, 0x00c0, 0xa3bd, + 0x2071, 0xa9e7, 0x7000, 0xa086, 0x0003, 0x00c0, 0xa365, 0x7004, + 0xac06, 0x00c0, 0xa365, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013, + 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc, + 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078, 0xa3b7, 0x037e, 0x0d7e, + 0x0d7e, 0x1078, 0x138b, 0x037f, 0x1040, 0x1332, 0x6837, 0x010d, + 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857, + 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872, 0x2360, 0x6024, 0xc0dd, + 0x6026, 0x6018, 0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007, + 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000, 0x6d6a, 0x6e66, 0x686f, + 0x0001, 0x1078, 0x4a73, 0x2019, 0x0045, 0x6008, 0x2068, 0x1078, + 0x9dd7, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, 0x6017, + 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f, 0x0078, 0xa3be, 0x603f, + 0x0000, 0x6003, 0x0007, 0x1078, 0x9c2e, 0x0c7f, 0x0d7f, 0x007c, + 0xa186, 0x0013, 0x00c0, 0xa3ca, 0x6004, 0xa082, 0x0085, 0x2008, + 0x0079, 0xa3e4, 0xa186, 0x0027, 0x00c0, 0xa3dd, 0x1078, 0x61cd, + 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019, 0x0004, 0x1078, 0xa1da, + 0x0d7f, 0x037f, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0014, 0x0040, + 0xa3ce, 0x1078, 0x7773, 0x007c, 0xa3ed, 0xa3eb, 0xa3eb, 0xa3eb, + 0xa3eb, 0xa3eb, 0xa3ed, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6003, + 0x000c, 0x1078, 0x62d1, 0x007c, 0xa182, 0x008c, 0x00c8, 0xa3fe, + 0xa182, 0x0085, 0x0048, 0xa3fe, 0x0079, 0xa401, 0x1078, 0x7773, + 0x007c, 0xa408, 0xa408, 0xa408, 0xa408, 0xa40a, 0xa429, 0xa408, + 0x1078, 0x1332, 0x0d7e, 0x2c68, 0x1078, 0x76c7, 0x0040, 0xa424, + 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xac8e, 0x210c, 0x6136, + 0x2009, 0xac8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a, + 0x601f, 0x0004, 0x1078, 0x5d8a, 0x2d60, 0x1078, 0x772d, 0x0d7f, + 0x007c, 0x1078, 0x772d, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, + 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa08c, 0xf000, 0x0040, 0xa481, + 0xa080, 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa481, 0x2001, 0xa772, + 0x2004, 0xd0ec, 0x0040, 0xa481, 0x6003, 0x0002, 0x6024, 0xc0e5, + 0x6026, 0xd1ac, 0x0040, 0xa45f, 0x0f7e, 0x2c78, 0x1078, 0x495f, + 0x0f7f, 0x0040, 0xa45f, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x2009, + 0xa772, 0x210c, 0xd1f4, 0x00c0, 0xa47f, 0x0078, 0xa471, 0x2009, + 0xa772, 0x210c, 0xd1f4, 0x0040, 0xa46b, 0x6024, 0xc0e4, 0x6026, + 0xa006, 0x0078, 0xa481, 0x2001, 0xa9a4, 0x200c, 0x8103, 0xa100, + 0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa47c, + 0xa088, 0x0003, 0x0078, 0xa474, 0x2c0a, 0x600f, 0x0000, 0xa085, + 0x0001, 0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, + 0x2e04, 0x2060, 0x8cff, 0x0040, 0xa4a1, 0x84ff, 0x00c0, 0xa494, + 0x6020, 0xa106, 0x00c0, 0xa49c, 0x600c, 0x2072, 0x1078, 0x5bc1, + 0x1078, 0x772d, 0x0078, 0xa49e, 0xacf0, 0x0003, 0x2e64, 0x0078, + 0xa48a, 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, + 0x002b, 0x2d04, 0xa005, 0x0040, 0xa4b7, 0xac06, 0x0040, 0xa4b5, + 0x2d04, 0xa0e8, 0x0003, 0x0078, 0xa4a9, 0x600c, 0x206a, 0x0d7f, + 0x007c, 0x027e, 0x037e, 0x157e, 0x2011, 0xa726, 0x2204, 0xa084, + 0x00ff, 0x2019, 0xac8e, 0x2334, 0xa636, 0x00c0, 0xa4e5, 0x8318, + 0x2334, 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa4e5, 0x2011, + 0xac90, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de, + 0x00c0, 0xa4e5, 0x2011, 0xac94, 0x6018, 0xa098, 0x0006, 0x20a9, + 0x0004, 0x1078, 0x80de, 0x00c0, 0xa4e5, 0x157f, 0x037f, 0x027f, + 0x007c, 0x0e7e, 0x2071, 0xa700, 0x1078, 0x42b8, 0x1078, 0x2677, + 0x0e7f, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, + 0xa4fb, 0x1078, 0xa4fd, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, + 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, + 0x017e, 0x127e, 0x2091, 0x8000, 0x2029, 0xa9ba, 0x252c, 0x2021, + 0xa9c0, 0x2424, 0x2061, 0xae00, 0x2071, 0xa700, 0x7648, 0x7064, + 0xa606, 0x0040, 0xa555, 0x671c, 0xa786, 0x0001, 0x0040, 0xa524, + 0xa786, 0x0008, 0x00c0, 0xa54b, 0x2500, 0xac06, 0x0040, 0xa54b, + 0x2400, 0xac06, 0x0040, 0xa54b, 0x1078, 0xa252, 0x0040, 0xa54b, + 0x1078, 0xa266, 0x00c0, 0xa54b, 0x6000, 0xa086, 0x0004, 0x00c0, + 0xa53d, 0x017e, 0x1078, 0x1757, 0x017f, 0x1078, 0x8efc, 0x00c0, + 0xa543, 0x1078, 0x28a6, 0x1078, 0x8f10, 0x00c0, 0xa549, 0x1078, + 0x7c83, 0x1078, 0x8ed6, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, + 0xac02, 0x00c8, 0xa555, 0x0078, 0xa514, 0x127f, 0x017f, 0x027f, + 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, + 0x007e, 0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa740, 0xd5a4, + 0x0040, 0xa56d, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa573, + 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0xa589, 0x2500, 0xa084, + 0x0007, 0xa08e, 0x0003, 0x0040, 0xa589, 0xa08e, 0x0004, 0x0040, + 0xa589, 0xa08e, 0x0005, 0x0040, 0xa589, 0x2071, 0xa74a, 0x1078, + 0xa5ca, 0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, + 0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa740, 0xd5a4, 0x0040, + 0xa59c, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa5a2, 0x7030, + 0x8000, 0x7032, 0xd5ac, 0x0040, 0xa5b8, 0x2500, 0xa084, 0x0007, + 0xa08e, 0x0003, 0x0040, 0xa5b8, 0xa08e, 0x0004, 0x0040, 0xa5b8, + 0xa08e, 0x0005, 0x0040, 0xa5b8, 0x2071, 0xa74a, 0x1078, 0xa5ca, + 0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, + 0x2091, 0x8000, 0x2071, 0xa742, 0x1078, 0xa5ca, 0x0e7f, 0x007f, + 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8, 0xa5d3, 0x8e70, + 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071, 0xa740, 0x1078, + 0xa5ca, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa744, 0x1078, 0xa5ca, + 0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, + 0xa740, 0x7044, 0x8000, 0x7046, 0x0e7f, 0x007f, 0x127f, 0x007c, + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, + 0x4811 +}; +#ifdef UNIQUE_FW_NAME +unsigned short fw2100tp_length01 = 0x9601; +#else +unsigned short risc_code_length01 = 0x9601; +#endif + diff --git a/trunk/drivers/scsi/qla2xxx/ql2200.c b/trunk/drivers/scsi/qla2xxx/ql2200.c new file mode 100644 index 000000000000..0eef72dc8da0 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2200.c @@ -0,0 +1,91 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2200"; + +extern unsigned char fw2200tp_version[]; +extern unsigned char fw2200tp_version_str[]; +extern unsigned short fw2200tp_addr01; +extern unsigned short fw2200tp_code01[]; +extern unsigned short fw2200tp_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2200tp_code01[0], + .fwlen = &fw2200tp_length01, + .fwstart = &fw2200tp_addr01, + }, + + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl = { + .drv_name = qla_driver_name, + + .isp_name = "ISP2200", + .fw_info = qla_fw_tbl, +}; + +static struct pci_device_id qla2200_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2200, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl, + }, + + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla2200_pci_tbl); + +static int __devinit +qla2200_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla2200_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla2200_pci_driver = { + .name = "qla2200", + .id_table = qla2200_pci_tbl, + .probe = qla2200_probe_one, + .remove = __devexit_p(qla2200_remove_one), +}; + +static int __init +qla2200_init(void) +{ + return pci_module_init(&qla2200_pci_driver); +} + +static void __exit +qla2200_exit(void) +{ + pci_unregister_driver(&qla2200_pci_driver); +} + +module_init(qla2200_init); +module_exit(qla2200_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP22xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/trunk/drivers/scsi/qla2xxx/ql2200_fw.c b/trunk/drivers/scsi/qla2xxx/ql2200_fw.c new file mode 100644 index 000000000000..ac07e18abb1d --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2200_fw.c @@ -0,0 +1,5333 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 2.02.08 (17:06 Mar 22, 2005) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2200tp_version = 2*1024+2; +#else +unsigned short risc_code_version = 2*1024+2; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2200tp_version_str[] = {2,2,8}; +#else +unsigned char firmware_version[] = {2,2,8}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2200tp_VERSION_STRING "2.02.08" +#else +#define FW_VERSION_STRING "2.02.08" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2200tp_addr01 = 0x1000 ; +#else +unsigned short risc_code_addr01 = 0x1000 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2200tp_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0470, 0x0000, 0x0000, 0xa52b, 0x0000, 0x0002, 0x0002, 0x0008, + 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x322e, 0x3032, 0x2e30, 0x3820, 0x2020, 0x2020, 0x2400, 0x20c1, + 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xbbff, 0x2091, + 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x299f, + 0x2051, 0xb600, 0x2a70, 0x2029, 0xee00, 0x2031, 0xffff, 0x2039, + 0xede9, 0x2021, 0x0200, 0x0804, 0x146d, 0x20a1, 0xb52b, 0xa00e, + 0x20a9, 0x08d5, 0x41a4, 0x3400, 0x7562, 0x7666, 0x775e, 0x746a, + 0x746e, 0x20a1, 0xbe00, 0x7164, 0x810d, 0x810d, 0x810d, 0x810d, + 0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4, + 0x3400, 0x8211, 0x1dd8, 0x7164, 0x3400, 0xa102, 0x0120, 0x0218, + 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xb600, + 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001, + 0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0, + 0x2009, 0xb600, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e, + 0x41a4, 0x080c, 0x1416, 0x080c, 0x1637, 0x080c, 0x17d4, 0x080c, + 0x1fbe, 0x080c, 0x4c72, 0x080c, 0x8646, 0x080c, 0x15c0, 0x080c, + 0x2ef9, 0x080c, 0x5dfc, 0x080c, 0x53b3, 0x080c, 0x6940, 0x080c, + 0x2545, 0x080c, 0x6bd3, 0x080c, 0x642d, 0x080c, 0x23ff, 0x080c, + 0x2513, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820, + 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b, + 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, + 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3f4f, 0x080c, + 0x2f20, 0x080c, 0x5e4a, 0x080c, 0x5562, 0x080c, 0x696b, 0x0c80, + 0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1215, 0x10e2, 0x12e2, 0x1413, + 0x1414, 0x1415, 0x080c, 0x151a, 0x0005, 0x0126, 0x00f6, 0x2091, + 0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11f2, 0x080c, 0x158d, + 0x080c, 0x5b41, 0x0150, 0x080c, 0x5b67, 0x15c0, 0x2079, 0x0100, + 0x7828, 0xa085, 0x1800, 0x782a, 0x0488, 0x080c, 0x5a79, 0x7000, + 0xa086, 0x0001, 0x1904, 0x11f2, 0x708c, 0xa086, 0x0028, 0x1904, + 0x11f2, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827, + 0xffff, 0x7a28, 0xa295, 0x1e2f, 0x7a2a, 0x2011, 0x5a14, 0x080c, + 0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x2011, 0x5a56, 0x080c, + 0x6a0e, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x2011, 0x8030, 0x2019, + 0x0000, 0x708b, 0x0000, 0x080c, 0x1e05, 0x00e8, 0x080c, 0x44d6, + 0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11f2, 0x2011, 0x4b23, + 0x080c, 0x6a0e, 0x2011, 0x5a56, 0x080c, 0x6a0e, 0x080c, 0x1e05, + 0x2001, 0xb88d, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842, + 0x2011, 0x8010, 0x73cc, 0x080c, 0x3f13, 0x723c, 0xc284, 0x723e, + 0x2001, 0xb60c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x7fbc, 0x2011, + 0x0004, 0x080c, 0x9d1c, 0x080c, 0x52bf, 0x080c, 0x5b41, 0x0158, + 0x080c, 0x4c4a, 0x0140, 0x708b, 0x0001, 0x70c7, 0x0000, 0x080c, + 0x4673, 0x0804, 0x11f2, 0x080c, 0x537b, 0x0120, 0x7a0c, 0xc2b4, + 0x7a0e, 0x0060, 0x7073, 0x0000, 0x080c, 0xa0c4, 0x70d4, 0xd09c, + 0x1128, 0x70a0, 0xa005, 0x0110, 0x080c, 0x4c28, 0x70df, 0x0000, + 0x70db, 0x0000, 0x72d4, 0x080c, 0x5b41, 0x1180, 0x2011, 0x0000, + 0x0016, 0x080c, 0x2920, 0x2019, 0xb88f, 0x211a, 0x001e, 0x7053, + 0xffff, 0x7057, 0x00ef, 0x7077, 0x0000, 0x0020, 0x2019, 0xb88f, + 0x201b, 0x0000, 0x2079, 0xb652, 0x7804, 0xd0ac, 0x0108, 0xc295, + 0x72d6, 0x080c, 0x5b41, 0x0118, 0xa296, 0x0004, 0x0548, 0x2011, + 0x0001, 0x080c, 0x9d1c, 0x709b, 0x0000, 0x709f, 0xffff, 0x7003, + 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0xa085, 0x0003, + 0x782a, 0x00fe, 0x080c, 0x2aed, 0x2011, 0x0005, 0x080c, 0x80fc, + 0x080c, 0x71e5, 0x080c, 0x5b41, 0x0148, 0x00c6, 0x2061, 0x0100, + 0x0016, 0x080c, 0x2920, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420, + 0x709b, 0x0000, 0x709f, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079, + 0x0100, 0x7827, 0x0003, 0x7828, 0xa085, 0x0003, 0x782a, 0x00fe, + 0x2011, 0x0005, 0x080c, 0x80fc, 0x080c, 0x71e5, 0x080c, 0x5b41, + 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2920, 0x61e2, + 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x5b41, + 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x5b41, + 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x080c, 0x2dcc, + 0x8108, 0x1f04, 0x1206, 0x00ce, 0x7073, 0x0000, 0x7074, 0xa084, + 0x00ff, 0x7076, 0x70a3, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, + 0x7000, 0xa086, 0x0002, 0x1904, 0x12e0, 0x709c, 0xa086, 0xffff, + 0x0130, 0x080c, 0x2aed, 0x080c, 0x71e5, 0x0804, 0x12e0, 0x70d4, + 0xd0ac, 0x1110, 0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, + 0x2001, 0x0103, 0x2009, 0xb88d, 0x210c, 0x2102, 0x001e, 0x000e, + 0xd08c, 0x01d0, 0x70d8, 0xa086, 0xffff, 0x0190, 0x080c, 0x2c4c, + 0x080c, 0x71e5, 0x70d4, 0xd094, 0x1904, 0x12e0, 0x2011, 0x0001, + 0x2019, 0x0000, 0x080c, 0x2c84, 0x080c, 0x71e5, 0x0804, 0x12e0, + 0x70dc, 0xa005, 0x1904, 0x12e0, 0x7098, 0xa005, 0x1904, 0x12e0, + 0x70d4, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x12e0, 0x080c, 0x537b, + 0x1904, 0x12e0, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x01c8, 0x0156, + 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, + 0x1118, 0x6000, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x126d, + 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12e0, + 0x0006, 0x0016, 0x2001, 0x0103, 0x2009, 0xb88d, 0x210c, 0x2102, + 0x001e, 0x000e, 0x71a8, 0x81ff, 0x11b0, 0xa006, 0x2009, 0x0200, + 0x20a9, 0x0002, 0x20a1, 0xb8df, 0x40a1, 0x2009, 0x0700, 0x20a9, + 0x0002, 0x20a1, 0xb8cf, 0x40a1, 0x7070, 0x8007, 0x7174, 0x810f, + 0x20a9, 0x0002, 0x40a1, 0x20a1, 0xb8d3, 0x2009, 0x0000, 0x080c, + 0x1500, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x7030, + 0xc08c, 0x7032, 0x7003, 0x0003, 0x709f, 0xffff, 0x080c, 0x1586, + 0xa006, 0x080c, 0x27f8, 0x080c, 0x3f85, 0x00f6, 0x2079, 0x0100, + 0x080c, 0x5b67, 0x0150, 0x080c, 0x5b41, 0x7828, 0x0118, 0xa084, + 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0xb8e2, + 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x80fc, + 0x2011, 0x0000, 0x080c, 0x8106, 0x080c, 0x71e5, 0x080c, 0x72a2, + 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, + 0x2079, 0x0100, 0x2009, 0xb634, 0x2104, 0xa005, 0x1110, 0x080c, + 0x294c, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x7940, 0xa18c, 0x0010, + 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, + 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, + 0x1350, 0x080c, 0x5b53, 0x0158, 0x080c, 0x5b67, 0x1128, 0x2001, + 0xb89e, 0x2003, 0x0000, 0x0070, 0x080c, 0x5b49, 0x0dc0, 0x2001, + 0xb89e, 0x2003, 0xaaaa, 0x2001, 0xb89f, 0x2003, 0x0001, 0x080c, + 0x5a79, 0x0058, 0x080c, 0x5b41, 0x0140, 0x2009, 0x00f8, 0x080c, + 0x4c11, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, + 0xd09c, 0x1138, 0x080c, 0x5b41, 0x0138, 0x7824, 0xd0ac, 0x1904, + 0x13fa, 0x1f04, 0x132f, 0x0070, 0x7824, 0x080c, 0x5b5d, 0x0118, + 0xd0ac, 0x1904, 0x13fa, 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, + 0x0804, 0x13fa, 0x2001, 0x0001, 0x080c, 0x27f8, 0x0804, 0x1409, + 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020, 0x20a9, 0x0046, + 0x1d04, 0x1358, 0x080c, 0x6ab6, 0x1f04, 0x1358, 0x7850, 0xa084, + 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000, 0x080c, 0x5b53, + 0x0158, 0x080c, 0x5b67, 0x1128, 0x2001, 0xb89e, 0x2003, 0x0000, + 0x0070, 0x080c, 0x5b49, 0x0dc0, 0x2001, 0xb89e, 0x2003, 0xaaaa, + 0x2001, 0xb89f, 0x2003, 0x0001, 0x080c, 0x5a79, 0x0020, 0x2009, + 0x00f8, 0x080c, 0x4c11, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x1385, + 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852, 0x080c, 0x5b41, + 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, + 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x5b41, 0x05d8, 0x7824, + 0xd0ac, 0x1904, 0x13fa, 0x080c, 0x5b67, 0x1508, 0x0046, 0x2021, + 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8, 0x7827, 0x0048, + 0x20a9, 0x01f4, 0x1d04, 0x13b2, 0x080c, 0x6ab6, 0x1f04, 0x13b2, + 0x7824, 0xa084, 0x0068, 0x15c8, 0x2001, 0xb89e, 0x2003, 0xaaaa, + 0x2001, 0xb89f, 0x2003, 0x0001, 0x7003, 0x0001, 0x0498, 0x1d04, + 0x13cb, 0x080c, 0x6ab6, 0x8319, 0x1960, 0x2009, 0xb634, 0x2104, + 0x8000, 0x200a, 0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, + 0x294c, 0x00d8, 0x080c, 0x5b53, 0x1140, 0xa4a2, 0x0064, 0x1128, + 0x080c, 0x5b18, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, + 0xe000, 0x7824, 0x080c, 0x5b5d, 0x0110, 0xd0ac, 0x1158, 0xa084, + 0x1800, 0x09a8, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, + 0x27f8, 0x0048, 0x2001, 0xb634, 0x2003, 0x0000, 0x7827, 0x0048, + 0x7828, 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, + 0x7852, 0x015e, 0x003e, 0x000e, 0x080c, 0x155d, 0x012e, 0x00fe, + 0x004e, 0x001e, 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2061, + 0xb8c2, 0x2063, 0x0002, 0x6007, 0x0002, 0x600b, 0x0008, 0x600f, + 0x0017, 0x2001, 0xb89e, 0x2003, 0x0000, 0x708b, 0x0000, 0x2009, + 0x0100, 0x2104, 0xa082, 0x0002, 0x0218, 0x7053, 0xffff, 0x0010, + 0x7053, 0x0000, 0x705b, 0xffff, 0x7073, 0x0000, 0x7077, 0x0000, + 0x080c, 0xa0c4, 0x2061, 0xb88e, 0x6003, 0x0909, 0x6007, 0x0000, + 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f, + 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0xb896, 0x6003, 0x8000, + 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, + 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000, 0x2061, 0xb8b9, + 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, + 0x2001, 0xb628, 0x2003, 0x0000, 0x0005, 0x04a0, 0x2011, 0x0000, + 0x81ff, 0x0570, 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039, + 0xd601, 0x2021, 0x0100, 0x2029, 0xd600, 0x00e8, 0xa186, 0x0002, + 0x1118, 0x2011, 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011, + 0x0001, 0x0088, 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058, + 0xa186, 0x000a, 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055, + 0x1110, 0x2011, 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, + 0x0804, 0x104d, 0xa00e, 0x2011, 0x0003, 0x2019, 0x14a9, 0x0804, + 0x14fa, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, + 0xe000, 0x2c04, 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011, + 0x0000, 0x2019, 0x14bc, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff, + 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000, + 0xe000, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d, + 0x0008, 0xc185, 0x2011, 0x0002, 0x2019, 0x14d7, 0x0418, 0x2061, + 0xffff, 0x2019, 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, + 0x2262, 0xa306, 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, + 0x2061, 0x7fff, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110, + 0xc195, 0x0008, 0xc19d, 0x2011, 0x0001, 0x2019, 0x14f8, 0x0010, + 0x0804, 0x146e, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837, + 0x2011, 0x0000, 0x080c, 0x501b, 0x1178, 0x6004, 0xa0c4, 0x00ff, + 0xa8c6, 0x0006, 0x0128, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x1120, + 0xa186, 0x0080, 0x0108, 0x8210, 0x8108, 0xa186, 0x0100, 0x1d50, + 0x2208, 0x0005, 0x2091, 0x8000, 0x0e04, 0x151c, 0x0006, 0x0016, + 0x2079, 0x0000, 0x7818, 0xd084, 0x1de8, 0x001e, 0x792e, 0x000e, + 0x782a, 0x000e, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, + 0x0001, 0x2091, 0x5000, 0x0126, 0x0156, 0x0146, 0x20a9, 0x0010, + 0x20a1, 0xba0d, 0x2091, 0x2000, 0x40a1, 0x20a9, 0x0010, 0x2091, + 0x2200, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2400, 0x40a1, 0x20a9, + 0x0010, 0x2091, 0x2600, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2800, + 0x40a1, 0x014e, 0x015e, 0x012e, 0x2079, 0xb600, 0x7803, 0x0005, + 0x2091, 0x4080, 0x04c9, 0x0cf8, 0x0005, 0x0006, 0x080c, 0x15a8, + 0x1518, 0x00f6, 0x2079, 0xb624, 0x2f04, 0x8000, 0x207a, 0xa082, + 0x000f, 0x0258, 0xa006, 0x207a, 0x2079, 0xb626, 0x2f04, 0xa084, + 0x0001, 0xa086, 0x0001, 0x207a, 0x0070, 0x2079, 0xb626, 0x2f7c, + 0x8fff, 0x1128, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0020, 0x2001, + 0x0c03, 0x2003, 0x00c0, 0x00fe, 0x000e, 0x0005, 0x0409, 0x1120, + 0x2001, 0x0c03, 0x2003, 0x0080, 0x0005, 0x00d1, 0x1120, 0x2001, + 0x0c03, 0x2003, 0x0040, 0x0005, 0x0006, 0x0091, 0x1178, 0x2001, + 0x0c03, 0x2003, 0x0040, 0x2009, 0x0fff, 0x00a1, 0x2001, 0x0c03, + 0x2003, 0x0080, 0x2009, 0x0fff, 0x0069, 0x0c88, 0x000e, 0x0005, + 0x00c6, 0x2061, 0x0c00, 0x2c04, 0xa084, 0x00ff, 0xa086, 0x00aa, + 0x00ce, 0x0005, 0x0156, 0x0126, 0xa18c, 0x0fff, 0x21a8, 0x1d04, + 0x15b7, 0x2091, 0x6000, 0x1f04, 0x15b7, 0x012e, 0x015e, 0x0005, + 0x2071, 0xb600, 0x7160, 0x712e, 0x2021, 0x0001, 0xa190, 0x0030, + 0xa298, 0x0030, 0x0240, 0x7064, 0xa302, 0x1228, 0x220a, 0x2208, + 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c, 0x0148, 0x7064, 0xa086, + 0xb600, 0x0128, 0x7067, 0xb600, 0x2011, 0x1000, 0x0c48, 0x200b, + 0x0000, 0x74b2, 0x74b6, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x2071, 0xb600, 0x70b4, 0xa0ea, 0x0010, 0x0268, 0x8001, 0x70b6, + 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, + 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x2071, 0xb600, + 0x0126, 0x2091, 0x8000, 0x70b4, 0x8001, 0x0260, 0x70b6, 0x702c, + 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, + 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x2071, 0xb600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70b4, 0x8000, + 0x70b6, 0x012e, 0x00ee, 0x0005, 0x8dff, 0x0138, 0x6804, 0x6807, + 0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8, 0x0005, 0x00e6, 0x2071, + 0xb600, 0x70b4, 0xa08a, 0x0010, 0xa00d, 0x00ee, 0x0005, 0x00e6, + 0x2071, 0xb913, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, + 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x00ee, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00e6, 0x2270, 0x700b, 0x0000, 0x2071, + 0xb913, 0x7018, 0xa088, 0xb91c, 0x220a, 0x8000, 0xa084, 0x0007, + 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0089, + 0x00fe, 0x00ee, 0x012e, 0x0005, 0x00e6, 0x2071, 0xb913, 0x7004, + 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee, + 0x0005, 0x7000, 0x0002, 0x1677, 0x16db, 0x16f8, 0x16f8, 0x7018, + 0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180, + 0xb91c, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, + 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, + 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de, + 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, + 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, + 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, + 0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014, + 0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, + 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, + 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e, + 0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xb6fa, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, + 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, + 0x7002, 0x700b, 0xb6f5, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, + 0x0136, 0x0146, 0x0156, 0x2001, 0xb729, 0x209c, 0x20a1, 0x0014, + 0x7803, 0x0026, 0x2001, 0xb72a, 0x20ac, 0x53a6, 0x2099, 0xb72b, + 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, + 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, + 0x7002, 0x700b, 0xb726, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, + 0x0016, 0x00e6, 0x2071, 0xb913, 0x00f6, 0x2079, 0x0010, 0x7904, + 0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023, + 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1671, 0x173b, 0x1769, 0x1793, + 0x17c3, 0x173a, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146, + 0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, + 0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, + 0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x16a2, + 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, + 0x080c, 0x1671, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, + 0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830, + 0x7832, 0x7834, 0x7836, 0x080c, 0x16b7, 0x0005, 0x7008, 0xa080, + 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1671, 0x0005, + 0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, + 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, + 0x080c, 0x1671, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, + 0x0156, 0x2001, 0xb6f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, + 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xb6fa, + 0x2004, 0xd0bc, 0x0148, 0x2001, 0xb703, 0x2004, 0xa080, 0x000d, + 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, + 0x0000, 0x080c, 0x5ee1, 0x080c, 0x1671, 0x0005, 0x2011, 0x8003, + 0x080c, 0x3f13, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xb728, + 0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1671, 0x0005, 0x2011, + 0x8004, 0x080c, 0x3f13, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, + 0x0030, 0x2071, 0xb924, 0x7003, 0x0000, 0x700f, 0xb930, 0x7013, + 0xb930, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934, + 0xa184, 0x0007, 0x0002, 0x17f3, 0x1831, 0x17f3, 0x17f3, 0x17f3, + 0x1819, 0x1800, 0x17f7, 0xa085, 0x0001, 0x0804, 0x184b, 0x684c, + 0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8, + 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58, + 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d, + 0x2004, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005, 0x6832, 0x6858, + 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac, + 0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, + 0xa080, 0x2308, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, + 0x0080, 0x684c, 0xd0ac, 0x0904, 0x17f3, 0xa006, 0x682e, 0x682a, + 0x6858, 0xa18c, 0x000f, 0xa188, 0x2308, 0x210d, 0x6932, 0x2d08, + 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, + 0x6912, 0x6980, 0x6916, 0x0005, 0x684c, 0xd0ac, 0x090c, 0x151a, + 0x6833, 0x2305, 0x2d08, 0x691a, 0x6858, 0x8001, 0x6826, 0x684c, + 0xc0dd, 0x684e, 0xa006, 0x680a, 0x682e, 0x682a, 0x697c, 0x6912, + 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, + 0x020a, 0x2004, 0x82ff, 0x01e8, 0xa280, 0x0004, 0x00d6, 0x206c, + 0x684c, 0xd0dc, 0x1190, 0xa280, 0x0007, 0x2004, 0xa086, 0x000a, + 0x1110, 0x0891, 0x0010, 0x080c, 0x17e7, 0x0138, 0x00de, 0xa280, + 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000, 0x680a, + 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200, 0x002e, + 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a, 0x8108, + 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb94b, 0x0210, 0x2009, + 0xb930, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118, 0xa080, + 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005, 0x7206, + 0x2001, 0x18ad, 0x0006, 0x2260, 0x0804, 0x19da, 0x0126, 0x0026, + 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e, 0x003e, + 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, + 0xa005, 0x0904, 0x190f, 0x6808, 0xa005, 0x0904, 0x1946, 0x7000, + 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904, 0x194e, + 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0168, + 0x0046, 0x080c, 0x1b22, 0x004e, 0x2460, 0x6010, 0xa080, 0x0002, + 0x2004, 0xa005, 0x0904, 0x1946, 0x0c10, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086, 0x6000, + 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x1904, + 0x194e, 0x2009, 0x0048, 0x080c, 0x86d3, 0x0804, 0x194e, 0x6808, + 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110, 0xa106, + 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004, 0xd08c, + 0x0160, 0x0046, 0x080c, 0x1b22, 0x004e, 0x2460, 0x6010, 0xa080, + 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207, 0x2004, + 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50, 0x7804, + 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818, 0x6812, + 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, + 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x86d3, 0x00ce, 0x00de, + 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046, 0x0056, + 0x2071, 0xb924, 0x7000, 0xa086, 0x0000, 0x0904, 0x19b8, 0x7004, + 0xac06, 0x1904, 0x19aa, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, + 0x0904, 0x19aa, 0x7804, 0xd0fc, 0x15c8, 0x20e1, 0x6000, 0x2011, + 0x0032, 0x2001, 0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, + 0x1d88, 0x8211, 0x1db0, 0x7804, 0xd0fc, 0x1540, 0x080c, 0x1e8a, + 0x0026, 0x0056, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8, 0x7803, + 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, 0x0000, 0x005e, + 0x002e, 0x2001, 0x015d, 0x2003, 0x0000, 0x080c, 0x5b41, 0x1138, + 0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3, 0x006e, 0x0058, 0x2001, + 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0020, 0x080c, 0x1b22, + 0x0804, 0x195a, 0x0156, 0x20a9, 0x0009, 0x2009, 0xb930, 0x2104, + 0xac06, 0x1108, 0x200a, 0xa188, 0x0003, 0x1f04, 0x19af, 0x015e, + 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c, + 0x7110, 0xa106, 0x0904, 0x1a4e, 0x2104, 0x7006, 0x2060, 0x8108, + 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb94b, 0x0210, 0x2009, + 0xb930, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2920, 0x2001, + 0x0138, 0x2102, 0x8cff, 0x0598, 0x6010, 0x2068, 0x2d58, 0x6828, + 0xa406, 0x1590, 0x682c, 0xa306, 0x1578, 0x7004, 0x2060, 0x6020, + 0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813, + 0xffff, 0x00e8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810, + 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, + 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x080c, 0x1a51, + 0x0120, 0x2009, 0x0001, 0x080c, 0x1a51, 0x2d58, 0x0005, 0x080c, + 0x1df9, 0x0904, 0x19bf, 0x0cd0, 0x6020, 0xd0f4, 0x11e0, 0xd0d4, + 0x01b8, 0x6038, 0xa402, 0x6034, 0xa303, 0x0108, 0x1288, 0x643a, + 0x6336, 0x6c2a, 0x6b2e, 0x0046, 0x0036, 0x2400, 0x6c7c, 0xa402, + 0x6812, 0x2300, 0x6b80, 0xa303, 0x6816, 0x003e, 0x004e, 0x0018, + 0x080c, 0xa056, 0x09e0, 0x601c, 0xa08e, 0x0008, 0x0904, 0x19e5, + 0xa08e, 0x000a, 0x0904, 0x19e5, 0x2001, 0xb674, 0x2004, 0xd0b4, + 0x1140, 0x6018, 0x2004, 0xd0bc, 0x1120, 0x6817, 0x7fff, 0x6813, + 0xffff, 0x080c, 0x2328, 0x1918, 0x0804, 0x19e5, 0x7003, 0x0000, + 0x0005, 0x8aff, 0x0904, 0x1afc, 0xa03e, 0x2730, 0xc9fc, 0x6850, + 0xd0fc, 0x11b8, 0xd0f4, 0x1588, 0x00d6, 0x2805, 0xac68, 0x2900, + 0x0002, 0x1aba, 0x1a93, 0x1a93, 0x1aba, 0x1aba, 0x1ab2, 0x1aba, + 0x1a93, 0x1aba, 0x1a9b, 0x1a9b, 0x1aba, 0x1aba, 0x1aba, 0x1aaa, + 0x1a9b, 0x7803, 0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, + 0x6c20, 0x00d6, 0xd99c, 0x0140, 0x2805, 0xac68, 0x6f08, 0x6e0c, + 0x080c, 0x23ed, 0x0120, 0x04d0, 0x080c, 0x23ed, 0x15b0, 0x6850, + 0xc0fd, 0x6852, 0x00de, 0xa006, 0x0005, 0xc0f4, 0x6852, 0x6b6c, + 0x6a70, 0x00d6, 0x04c0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x080c, + 0x23ed, 0x0d80, 0x0410, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, + 0x6e0c, 0x080c, 0x23ed, 0x0d30, 0x00c8, 0x6d00, 0x6c04, 0x6f08, + 0x6e0c, 0x00a0, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, + 0x001e, 0x1140, 0x00de, 0x080c, 0x22ca, 0x1904, 0x1a51, 0xa00e, + 0x0804, 0x1afc, 0x00de, 0x080c, 0x151a, 0xc9fd, 0x7b22, 0x7a26, + 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7316, 0x721a, 0x751e, 0x7422, + 0x7726, 0x762a, 0x7902, 0x7100, 0x8108, 0x7102, 0x00de, 0x6828, + 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x8109, 0x2d08, 0x1500, + 0xd9fc, 0x0160, 0xc9fc, 0x080c, 0x22ca, 0x01e8, 0x2805, 0xac68, + 0x6800, 0xa506, 0x11c0, 0x6804, 0xa406, 0x00a8, 0xc9fc, 0x080c, + 0x22ca, 0x0188, 0x2805, 0xac68, 0x6800, 0xa506, 0x1160, 0x6804, + 0xa406, 0x1148, 0x6808, 0xa706, 0x1130, 0x680c, 0xa606, 0x0018, + 0xc9fc, 0x080c, 0x22ca, 0x2168, 0x0005, 0x080c, 0x151a, 0x080c, + 0x1f71, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x7003, 0x0000, + 0x080c, 0x1e1a, 0x080c, 0x9d16, 0x0170, 0x6808, 0x8001, 0x680a, + 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff, + 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x99e6, 0x0804, 0x1d47, + 0x080c, 0x151a, 0x0126, 0x2091, 0x2200, 0x0006, 0x0016, 0x2b68, + 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1978, + 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000, 0x0002, 0x1b3f, + 0x1b45, 0x1c56, 0x1d22, 0x1d36, 0x1b3f, 0x1b3f, 0x1b3f, 0x7804, + 0xd09c, 0x1904, 0x1d47, 0x080c, 0x151a, 0x8001, 0x7002, 0xd1bc, + 0x11a0, 0xd19c, 0x1904, 0x1bda, 0xd1dc, 0x1178, 0x8aff, 0x0904, + 0x1bda, 0x2009, 0x0001, 0x080c, 0x1a51, 0x0904, 0x1d47, 0x2009, + 0x0001, 0x080c, 0x1a51, 0x0804, 0x1d47, 0x7803, 0x0004, 0x7003, + 0x0000, 0xd1bc, 0x1904, 0x1bba, 0x0026, 0x0036, 0x7c20, 0x7d24, + 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, + 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, + 0x7003, 0x0004, 0x0010, 0x080c, 0x1d4b, 0x6b28, 0x6a2c, 0x2400, + 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x00c6, + 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236, 0x00ce, + 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x2500, 0xa405, 0x0128, 0x080c, + 0x22e0, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, + 0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, + 0x0130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x86d3, 0x7000, + 0xa086, 0x0004, 0x0904, 0x1d47, 0x7003, 0x0000, 0x080c, 0x19bf, + 0x0804, 0x1d47, 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xb4c3, + 0x005e, 0x080c, 0x1e1a, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5377, + 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, + 0x0804, 0x1d47, 0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, + 0x0120, 0x6808, 0x8001, 0x680a, 0x04c0, 0x7818, 0x6812, 0x7a1c, + 0x6a16, 0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, + 0x2004, 0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1b5d, 0x684c, + 0xc0f5, 0x684e, 0x7814, 0xa005, 0x1520, 0x7003, 0x0000, 0x6808, + 0x8001, 0x680a, 0x01a0, 0x7004, 0x2060, 0x601c, 0xa086, 0x000a, + 0x11a0, 0x0156, 0x20a9, 0x0009, 0x2009, 0xb930, 0x2104, 0xac06, + 0x1108, 0x200a, 0xa188, 0x0003, 0x1f04, 0x1c0e, 0x015e, 0x7004, + 0x2060, 0x2009, 0x0048, 0x080c, 0x86d3, 0x080c, 0x19bf, 0x0804, + 0x1d47, 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908, 0xa18c, + 0x0fff, 0xa192, 0x0841, 0x1a04, 0x1aff, 0xa188, 0x0007, 0x8114, + 0x8214, 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, + 0x810b, 0x810b, 0x080c, 0x1eb5, 0x7803, 0x0004, 0x780f, 0xffff, + 0x7803, 0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, + 0x0004, 0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, + 0x0048, 0x080c, 0x86d3, 0x080c, 0x1f0b, 0x0838, 0x8001, 0x7002, + 0xd194, 0x01b0, 0x7804, 0xd0fc, 0x1904, 0x1cf2, 0xd09c, 0x0138, + 0x7804, 0xd0fc, 0x1904, 0x1cf2, 0xd09c, 0x1904, 0x1cf6, 0x8aff, + 0x0904, 0x1d47, 0x2009, 0x0001, 0x080c, 0x1a51, 0x0804, 0x1d47, + 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, 0x1d47, 0x2009, 0x0001, + 0x080c, 0x1a51, 0x0804, 0x1d47, 0x7818, 0x6812, 0x7a1c, 0x6a16, + 0xa205, 0x0904, 0x1bf7, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, + 0x1904, 0x1cd4, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0029, 0x1118, + 0xd19c, 0x1904, 0x1bf7, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30, + 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004, + 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003, + 0x0004, 0x0020, 0x0016, 0x080c, 0x1d4b, 0x001e, 0x6b28, 0x6a2c, + 0x080c, 0x22e0, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, + 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, + 0xa213, 0x00de, 0xd194, 0x0904, 0x1b7f, 0x2a00, 0x6826, 0x2c00, + 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x6b2a, 0x6a2e, + 0x003e, 0x002e, 0x0804, 0x1c1d, 0x0056, 0x7d0c, 0x080c, 0xb4c3, + 0x005e, 0x080c, 0x1e1a, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5377, + 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, + 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, + 0x0804, 0x1d47, 0x7804, 0xd09c, 0x0904, 0x1b2a, 0x7c20, 0x7824, + 0xa405, 0x1904, 0x1b2a, 0x7818, 0x6812, 0x7c1c, 0x6c16, 0xa405, + 0x1120, 0x7803, 0x0002, 0x0804, 0x1bf7, 0x751c, 0x7420, 0x7724, + 0x7628, 0x7014, 0xa528, 0x7018, 0xa421, 0xa7b9, 0x0000, 0xa6b1, + 0x0000, 0x7830, 0xa506, 0x1150, 0x7834, 0xa406, 0x1138, 0x7838, + 0xa706, 0x1120, 0x783c, 0xa606, 0x0904, 0x1b2a, 0x7803, 0x0002, + 0x0804, 0x1c83, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, + 0x0150, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, + 0x0048, 0x080c, 0x86d3, 0x080c, 0x19bf, 0x0088, 0x7803, 0x0004, + 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, + 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x19da, 0x001e, + 0x000e, 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ded, + 0x7004, 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ded, 0x00d6, + 0x00c6, 0x216c, 0x2d00, 0xa005, 0x0904, 0x1deb, 0x681c, 0xa086, + 0x0008, 0x0904, 0x1deb, 0x6820, 0xd0d4, 0x1904, 0x1deb, 0x6810, + 0x2068, 0x6850, 0xd0fc, 0x05a8, 0x8108, 0x2104, 0x6b2c, 0xa306, + 0x1904, 0x1deb, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904, 0x1deb, + 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x7016, 0x6870, + 0x7826, 0x701a, 0x681c, 0x7832, 0x701e, 0x6820, 0x7836, 0x7022, + 0x6818, 0x2060, 0x6034, 0xd09c, 0x0168, 0x6830, 0x2005, 0x00d6, + 0xac68, 0x6808, 0x783a, 0x7026, 0x680c, 0x783e, 0x702a, 0x00de, + 0x0804, 0x1de5, 0xa006, 0x783a, 0x783e, 0x7026, 0x702a, 0x0804, + 0x1de5, 0x8108, 0x2104, 0xa005, 0x1904, 0x1deb, 0x6b2c, 0xa306, + 0x1904, 0x1deb, 0x8108, 0x2104, 0xa005, 0x15e8, 0x6a28, 0xa206, + 0x15d0, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, + 0xa180, 0x000d, 0x2004, 0xd09c, 0x11a0, 0x6008, 0x7822, 0x7016, + 0x686e, 0x600c, 0x7826, 0x701a, 0x6872, 0x6000, 0x7832, 0x701e, + 0x6004, 0x7836, 0x7022, 0xa006, 0x783a, 0x783e, 0x7026, 0x702a, + 0x00a0, 0x6010, 0x7822, 0x7016, 0x686e, 0x6014, 0x7826, 0x701a, + 0x6872, 0x6000, 0x7832, 0x701e, 0x6004, 0x7836, 0x7022, 0x6008, + 0x783a, 0x7026, 0x600c, 0x783e, 0x702a, 0x6810, 0x781a, 0x6814, + 0x781e, 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011, 0x0201, + 0x2009, 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8, 0x0005, + 0x0005, 0x0ca1, 0x0118, 0x780c, 0xd0a4, 0x0120, 0x00d9, 0xa085, + 0x0001, 0x0010, 0x080c, 0x1f0b, 0x0005, 0x0126, 0x2091, 0x2200, + 0x7000, 0xa086, 0x0003, 0x1160, 0x700c, 0x7110, 0xa106, 0x0140, + 0x080c, 0x2991, 0x20e1, 0x9028, 0x700f, 0xb930, 0x7013, 0xb930, + 0x012e, 0x0005, 0x00c6, 0x080c, 0x5b41, 0x11b8, 0x2001, 0x0160, + 0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8, + 0xe000, 0xe000, 0x8211, 0x1de0, 0x04b1, 0x0066, 0x2031, 0x0000, + 0x080c, 0x5bc3, 0x006e, 0x00ce, 0x0005, 0x080c, 0x1e8a, 0x080c, + 0x2991, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01c0, 0x2104, + 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, + 0xa188, 0x0003, 0xa182, 0xb94b, 0x0210, 0x2009, 0xb930, 0x7112, + 0x700c, 0xa106, 0x1d40, 0x080c, 0x2920, 0x2110, 0x0c20, 0x2001, + 0x015d, 0x2003, 0x0000, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, + 0x2202, 0x00ce, 0x0005, 0x080c, 0x2991, 0x20e1, 0x9028, 0x2001, + 0x015d, 0x2003, 0x0000, 0x00e6, 0x00c6, 0x0016, 0x2071, 0xb924, + 0x700c, 0x7110, 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, + 0x6010, 0x2060, 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, + 0xb94b, 0x0210, 0x2009, 0xb930, 0x7112, 0x0c50, 0x001e, 0x00ce, + 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, + 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x5b41, 0x1148, 0x2021, + 0x0002, 0x1d04, 0x1e99, 0x2091, 0x6000, 0x8421, 0x1dd0, 0x0005, + 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, + 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c, + 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200, + 0x7808, 0xa084, 0xf000, 0xa10d, 0x0869, 0x2001, 0x0105, 0x2004, + 0xa084, 0x0003, 0x1130, 0x2001, 0xb94b, 0x2004, 0xa086, 0x0000, + 0x0548, 0xa026, 0x2019, 0xf000, 0x8319, 0x1148, 0x2001, 0x012b, + 0x2003, 0x95f5, 0x2001, 0x0129, 0x2003, 0x95f5, 0x00d8, 0x2001, + 0x0105, 0x2004, 0xa084, 0x0003, 0x1130, 0x2001, 0xb94b, 0x2004, + 0xa086, 0x0000, 0x0178, 0x2001, 0x0132, 0x2004, 0xa436, 0x0110, + 0x2020, 0x0c00, 0x2001, 0x0021, 0x2004, 0xd0fc, 0x09e8, 0x080c, + 0x216d, 0x08c0, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, 0x7028, + 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, 0x7037, + 0x0008, 0x7326, 0x7422, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, + 0x2202, 0x00ee, 0x0005, 0x0026, 0x2001, 0x015d, 0x2003, 0x0000, + 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0ffd, 0x0210, 0x2009, 0x0000, + 0xa190, 0x0007, 0xa294, 0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001, + 0x020a, 0x82ff, 0x0140, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, + 0x200c, 0x8211, 0x1dd0, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, + 0x0000, 0x20e1, 0x6000, 0x2001, 0x0208, 0x200c, 0x2001, 0x0209, + 0x2004, 0xa106, 0x0158, 0x080c, 0x1dee, 0x0130, 0x7908, 0xd1ec, + 0x1128, 0x790c, 0xd1a4, 0x0960, 0x080c, 0x1e1a, 0xa006, 0x002e, + 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xb924, 0x2079, + 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8, 0x8211, + 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904, 0xa18c, + 0x0780, 0x0016, 0x080c, 0x1b22, 0x001e, 0x81ff, 0x1118, 0x2011, + 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee, 0x00fe, + 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0904, + 0x1fbd, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, + 0x0a0c, 0x151a, 0x080c, 0x2274, 0x00e6, 0x00f6, 0x2071, 0xb913, + 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800, 0x0006, + 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838, 0x0006, + 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079, 0x0030, + 0x7804, 0xd0ac, 0x190c, 0x151a, 0x2079, 0x0010, 0x000e, 0x783e, + 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e, 0x7822, + 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee, 0x7804, + 0xd0ac, 0x190c, 0x151a, 0x080c, 0x72a2, 0x0005, 0x00e6, 0x2071, + 0xb94b, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280, 0x0004, + 0x206c, 0x694c, 0xd1dc, 0x1904, 0x203b, 0x6934, 0xa184, 0x0007, + 0x0002, 0x1fd9, 0x2026, 0x1fd9, 0x1fd9, 0x1fd9, 0x200d, 0x1fec, + 0x1fdb, 0x080c, 0x151a, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6860, + 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, + 0x680e, 0x6958, 0x0804, 0x202e, 0x6834, 0xa084, 0x00ff, 0xa086, + 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6860, 0x682e, + 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e, + 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, + 0x2308, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff, 0xa186, + 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6804, 0x681a, + 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005, + 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c, 0xd0b4, + 0x0904, 0x1afd, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, + 0x6834, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005, 0x6832, 0x6926, + 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079, 0x0020, + 0x7804, 0xd0fc, 0x190c, 0x216d, 0x00e6, 0x00d6, 0x2071, 0xb94b, + 0x7000, 0xa005, 0x1904, 0x20aa, 0x00c6, 0x7206, 0xa280, 0x0004, + 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6, 0x2068, + 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079, 0x0200, + 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de, 0x2b68, + 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, + 0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a, 0xa006, + 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928, + 0x6810, 0xa106, 0x0190, 0x2001, 0xb674, 0x2004, 0xd0cc, 0x0110, + 0x00ce, 0x0400, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x2328, + 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, + 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020, + 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e, + 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, + 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x2123, 0x700c, + 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x2122, 0xa705, + 0x0904, 0x2122, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, + 0x2805, 0xac68, 0x2900, 0x0002, 0x2105, 0x20ea, 0x20ea, 0x2105, + 0x2105, 0x20fe, 0x2105, 0x20ea, 0x2105, 0x20ef, 0x20ef, 0x2105, + 0x2105, 0x2105, 0x20f6, 0x20ef, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, + 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08, + 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10, + 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, + 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, + 0x22ca, 0x1904, 0x20b4, 0xa00e, 0x00f0, 0x00de, 0x080c, 0x151a, + 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, + 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, + 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x080c, + 0x22ca, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e, + 0x007e, 0x0005, 0x080c, 0x151a, 0x0026, 0x2001, 0x0105, 0x2003, + 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, + 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0118, 0x6850, + 0xc0bd, 0x6852, 0x601c, 0xa086, 0x0006, 0x1180, 0x2061, 0x0100, + 0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, 0xa206, 0x1dc0, + 0x60c4, 0x686a, 0x60c8, 0x6866, 0x7004, 0x2060, 0x00de, 0x00c6, + 0x080c, 0x99e6, 0x00ce, 0x2001, 0xb8f0, 0x2004, 0xac06, 0x1150, + 0x20e1, 0x9040, 0x080c, 0x82e4, 0x2011, 0x0000, 0x080c, 0x8106, + 0x080c, 0x72a2, 0x002e, 0x0804, 0x2227, 0x0126, 0x2091, 0x2400, + 0x0006, 0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, + 0x2071, 0xb94b, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, + 0xa184, 0x0700, 0x1904, 0x212c, 0x7000, 0x0002, 0x2227, 0x218a, + 0x21fa, 0x2225, 0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, + 0x2009, 0x0001, 0x080c, 0x20ae, 0x0904, 0x2227, 0x2009, 0x0001, + 0x080c, 0x20ae, 0x0804, 0x2227, 0x7803, 0x0004, 0xd194, 0x0148, + 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, + 0x00b8, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, + 0x7824, 0x6872, 0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, + 0x6a2e, 0x003e, 0x002e, 0x080c, 0x22e0, 0x6850, 0xc0fd, 0x6852, + 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, + 0x0804, 0x2227, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, + 0x2079, 0x0100, 0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, + 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x151a, 0x7820, 0xd0bc, + 0x1dd0, 0x003e, 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, + 0x79c4, 0x000e, 0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, + 0xa085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, + 0x0000, 0x0468, 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, + 0x1904, 0x217d, 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, + 0x080c, 0x20ae, 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, + 0x22e0, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, + 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, + 0x00de, 0x0804, 0x21ad, 0x0804, 0x21a9, 0x080c, 0x151a, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, + 0x00e6, 0x2071, 0xb94b, 0x7000, 0xa086, 0x0000, 0x05d0, 0x2079, + 0x0020, 0x0016, 0x2009, 0x0207, 0x210c, 0xd194, 0x0198, 0x2009, + 0x020c, 0x210c, 0xa184, 0x0003, 0x0168, 0x080c, 0xb50c, 0x2001, + 0x0133, 0x2004, 0xa005, 0x090c, 0x151a, 0x20e1, 0x9040, 0x2001, + 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, + 0xa106, 0x1110, 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x09d8, 0x080c, + 0x216d, 0x7000, 0xa086, 0x0000, 0x19a8, 0x001e, 0x7803, 0x0004, + 0x7804, 0xd0ac, 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, + 0x0000, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x2071, 0xb94b, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, + 0x0540, 0x7004, 0x2060, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0158, + 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, + 0x7a18, 0xa206, 0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, + 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, + 0x99e6, 0x20e1, 0x9040, 0x080c, 0x82e4, 0x2011, 0x0000, 0x080c, + 0x8106, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, + 0x6a14, 0xa205, 0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, + 0x1fc5, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, + 0x0004, 0x7003, 0x0000, 0x2069, 0xb8e1, 0x6833, 0x0000, 0x683f, + 0x0000, 0x08f8, 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, + 0x0168, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2308, + 0x2045, 0x88ff, 0x090c, 0x151a, 0x8a51, 0x0005, 0x2050, 0x0005, + 0x8a50, 0x8841, 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, + 0x6000, 0xa005, 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, + 0x000f, 0xa080, 0x2318, 0x2045, 0x88ff, 0x090c, 0x151a, 0x0005, + 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, + 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, + 0x0000, 0x22fd, 0x22f9, 0x0000, 0x0000, 0x2307, 0x0000, 0x22fd, + 0x0000, 0x2304, 0x2301, 0x0000, 0x0000, 0x0000, 0x2307, 0x2304, + 0x0000, 0x22ff, 0x22ff, 0x0000, 0x0000, 0x2307, 0x0000, 0x22ff, + 0x0000, 0x2305, 0x2305, 0x0000, 0x0000, 0x0000, 0x2307, 0x2305, + 0x00a6, 0x0096, 0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, + 0x23b9, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2308, 0xa986, + 0x0007, 0x0130, 0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, + 0x605c, 0xa422, 0x6060, 0xa31b, 0x2805, 0xa045, 0x1140, 0x0310, + 0x0804, 0x23b9, 0x6004, 0xa065, 0x0904, 0x23b9, 0x0c18, 0x2805, + 0xa005, 0x01a8, 0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, + 0xa31b, 0x0020, 0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, + 0xa405, 0x0150, 0x8a51, 0x0904, 0x23b9, 0x8840, 0x0c40, 0x6004, + 0xa065, 0x0904, 0x23b9, 0x0830, 0x8a51, 0x0904, 0x23b9, 0x8840, + 0x2805, 0xa005, 0x1158, 0x6004, 0xa065, 0x0904, 0x23b9, 0x6034, + 0xa0cc, 0x000f, 0xa9c0, 0x2308, 0x2805, 0x2040, 0x2b68, 0x6850, + 0xc0fc, 0x6852, 0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, + 0x00d6, 0x2b68, 0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, + 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x0a0c, 0x151a, 0x6800, + 0xa420, 0x6804, 0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, + 0x2300, 0xa11b, 0x0a0c, 0x151a, 0x6800, 0xa420, 0x6804, 0xa319, + 0x2b68, 0x6c1e, 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, + 0x2800, 0x6832, 0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, + 0x0028, 0x008e, 0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, + 0x0005, 0x2004, 0xa084, 0x0007, 0x0002, 0x23cd, 0x23ce, 0x23d1, + 0x23d4, 0x23d9, 0x23dc, 0x23e1, 0x23e6, 0x0005, 0x080c, 0x216d, + 0x0005, 0x080c, 0x1b22, 0x0005, 0x080c, 0x1b22, 0x080c, 0x216d, + 0x0005, 0x080c, 0x1720, 0x0005, 0x080c, 0x216d, 0x080c, 0x1720, + 0x0005, 0x080c, 0x1b22, 0x080c, 0x1720, 0x0005, 0x080c, 0x1b22, + 0x080c, 0x216d, 0x080c, 0x1720, 0x0005, 0x0006, 0x7000, 0xa086, + 0x0001, 0x1158, 0x701c, 0xa506, 0x1140, 0x7020, 0xa406, 0x1128, + 0x7024, 0xa706, 0x1110, 0x7028, 0xa606, 0x000e, 0x0005, 0x0126, + 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0xbc80, 0x2069, 0xb600, + 0x080c, 0x24f5, 0x080c, 0x24e5, 0x2009, 0x0004, 0x7912, 0x7817, + 0x0004, 0x080c, 0x282d, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x241b, 0x20e1, + 0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126, + 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x24e2, 0xa084, 0x0007, + 0x0002, 0x244b, 0x2439, 0x243c, 0x243f, 0x2444, 0x2446, 0x2448, + 0x244a, 0x080c, 0x6436, 0x0078, 0x080c, 0x6475, 0x0060, 0x080c, + 0x6436, 0x080c, 0x6475, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018, + 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026, + 0x080c, 0xb50c, 0x7930, 0xa184, 0x0003, 0x01b0, 0x2001, 0xb8f0, + 0x2004, 0xa005, 0x0170, 0x2001, 0x0133, 0x2004, 0xa005, 0x090c, + 0x151a, 0x00c6, 0x2001, 0xb8f0, 0x2064, 0x080c, 0x99e6, 0x00ce, + 0x04b8, 0x20e1, 0x9040, 0x04a0, 0xa184, 0x0030, 0x01e0, 0x6a00, + 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c, 0x5b41, 0x1178, 0x2001, + 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, + 0x0001, 0x080c, 0x5b85, 0x080c, 0x5a79, 0x0010, 0x080c, 0x4b7b, + 0x080c, 0x24e5, 0x00a8, 0xa184, 0x00c0, 0x0168, 0x00e6, 0x0036, + 0x0046, 0x0056, 0x2071, 0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e, + 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300, 0x0110, 0x20e1, 0x9020, + 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6, 0x00f6, + 0x2071, 0xb600, 0x7128, 0x2001, 0xb891, 0x2102, 0x2001, 0xb899, + 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, + 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, + 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, + 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, + 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x2079, + 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x282d, 0x00fe, 0x00ee, + 0x001e, 0x0005, 0x7938, 0x080c, 0x151a, 0x00e6, 0x0026, 0x2071, + 0x0200, 0x20e1, 0x1000, 0x7220, 0x7028, 0x7020, 0xa206, 0x0de0, + 0x20e1, 0x9010, 0x002e, 0x00ee, 0x0005, 0x20e1, 0xa000, 0x7837, + 0x0001, 0x782f, 0x0000, 0x782f, 0x0000, 0x782f, 0x0000, 0x782f, + 0x0000, 0x7837, 0x0005, 0x20a9, 0x0210, 0x7830, 0xd0bc, 0x1110, + 0x1f04, 0x2505, 0x7837, 0x0001, 0x7837, 0x0000, 0xe000, 0xe000, + 0x20e1, 0xa000, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, + 0x2071, 0xb600, 0x6024, 0x6026, 0x6053, 0x0030, 0x080c, 0x286c, + 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, + 0x080c, 0x287c, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, + 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, + 0x0e9f, 0x601b, 0x001e, 0x600f, 0x00ff, 0x2001, 0xb88d, 0x2003, + 0x00ff, 0x602b, 0x002f, 0x012e, 0x0005, 0x2001, 0xb632, 0x2003, + 0x0000, 0x2001, 0xb631, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, + 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, + 0xa184, 0x0007, 0x002a, 0xa195, 0x0004, 0xa284, 0x0007, 0x0002, + 0x2582, 0x2568, 0x256b, 0x256e, 0x2573, 0x2575, 0x2579, 0x257d, + 0x080c, 0x6be6, 0x00b8, 0x080c, 0x6cc1, 0x00a0, 0x080c, 0x6cc1, + 0x080c, 0x6be6, 0x0078, 0x0099, 0x0068, 0x080c, 0x6be6, 0x0079, + 0x0048, 0x080c, 0x6cc1, 0x0059, 0x0028, 0x080c, 0x6cc1, 0x080c, + 0x6be6, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x6124, + 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x279b, 0x080c, 0x5b41, + 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, 0xa084, 0x1800, + 0x0178, 0x080c, 0x5b67, 0x0118, 0x080c, 0x5b53, 0x1148, 0x6027, + 0x0020, 0x6043, 0x0000, 0x2001, 0xb89e, 0x2003, 0xaaaa, 0x0458, + 0x080c, 0x5b67, 0x15d0, 0x6024, 0xa084, 0x1800, 0x1108, 0x04a8, + 0x2001, 0xb89e, 0x2003, 0xaaaa, 0x2001, 0xb89f, 0x2003, 0x0001, + 0x2001, 0xb600, 0x2003, 0x0001, 0x080c, 0x5a79, 0x0804, 0x279b, + 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1188, 0xd0d4, + 0x11a0, 0xd0cc, 0x0130, 0x708c, 0xa086, 0x0028, 0x1110, 0x080c, + 0x5cd0, 0x0804, 0x279b, 0x2001, 0xb89f, 0x2003, 0x0000, 0x0048, + 0x2001, 0xb89f, 0x2003, 0x0002, 0x0020, 0x080c, 0x5c43, 0x0804, + 0x279b, 0x080c, 0x5d75, 0x0804, 0x279b, 0xd1ac, 0x0904, 0x26e3, + 0x080c, 0x5b41, 0x11d8, 0x6027, 0x0020, 0x0006, 0x0026, 0x0036, + 0x080c, 0x5b5d, 0x1170, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, + 0xb600, 0x2003, 0x0001, 0x080c, 0x5a79, 0x003e, 0x002e, 0x000e, + 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5b18, 0x0016, 0x0046, + 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x74ce, 0xa48c, 0xff00, 0x7034, + 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x703c, 0xd084, 0x1148, + 0xc085, 0x703e, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x3f13, + 0x003e, 0xa196, 0xff00, 0x05b8, 0x7054, 0xa084, 0x00ff, 0x810f, + 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011, 0xb653, 0x2214, + 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xb653, 0x2214, 0xd2ac, + 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248, 0xa294, 0xff00, + 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x26b0, 0x7034, + 0xd08c, 0x1140, 0x2001, 0xb60c, 0x200c, 0xd1ac, 0x1904, 0x26b0, + 0xc1ad, 0x2102, 0x0036, 0x73cc, 0x2011, 0x8013, 0x080c, 0x3f13, + 0x003e, 0x0804, 0x26b0, 0x7034, 0xd08c, 0x1140, 0x2001, 0xb60c, + 0x200c, 0xd1ac, 0x1904, 0x26b0, 0xc1ad, 0x2102, 0x0036, 0x73cc, + 0x2011, 0x8013, 0x080c, 0x3f13, 0x003e, 0x7130, 0xc185, 0x7132, + 0x2011, 0xb653, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009, 0x0001, + 0x2011, 0x0100, 0x080c, 0x6b8c, 0x2019, 0x000e, 0x080c, 0xb121, + 0xa484, 0x00ff, 0xa080, 0x2df9, 0x200d, 0xa18c, 0xff00, 0x810f, + 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xb1a4, 0x001e, 0xd1ac, + 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2ca4, + 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, + 0x501b, 0x1110, 0x080c, 0x4c7e, 0x8108, 0x1f04, 0x26a7, 0x015e, + 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, + 0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, + 0x806b, 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001, 0xb600, 0x2014, + 0xa296, 0x0004, 0x1128, 0xd19c, 0x11b0, 0x6228, 0xc29d, 0x622a, + 0x2003, 0x0001, 0x2001, 0xb623, 0x2003, 0x0000, 0x6027, 0x0020, + 0x080c, 0x5b67, 0x1140, 0x0016, 0x2009, 0x07d0, 0x2011, 0x5a56, + 0x080c, 0x6a94, 0x001e, 0xd194, 0x0904, 0x279b, 0x0016, 0x6220, + 0xd2b4, 0x0904, 0x274c, 0x080c, 0x6a82, 0x080c, 0x7df3, 0x6027, + 0x0004, 0x00f6, 0x2019, 0xb8ea, 0x2304, 0xa07d, 0x0570, 0x7804, + 0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6, 0x00e6, 0x2069, 0x0140, + 0x618c, 0x6288, 0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, + 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x6803, 0x1000, + 0x6803, 0x0000, 0x618e, 0x628a, 0x080c, 0x7102, 0x080c, 0x71e5, + 0x7810, 0x2070, 0x7037, 0x0103, 0x2f60, 0x080c, 0x86a4, 0x00ee, + 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe, 0x00d6, 0x2069, + 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, + 0x0000, 0x00de, 0x00c6, 0x2061, 0xb8e1, 0x6028, 0xa09a, 0x00c8, + 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x7de6, 0x0804, 0x279a, + 0x2019, 0xb8ea, 0x2304, 0xa065, 0x0120, 0x2009, 0x0027, 0x080c, + 0x86d3, 0x00ce, 0x0804, 0x279a, 0xd2bc, 0x0904, 0x279a, 0x080c, + 0x6a8f, 0x6014, 0xa084, 0x0184, 0xa085, 0x0010, 0x6016, 0x6027, + 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, + 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0xb8e1, + 0x6044, 0xa09a, 0x00c8, 0x12f0, 0x8000, 0x6046, 0x603c, 0x00ce, + 0xa005, 0x0540, 0x2009, 0x07d0, 0x080c, 0x6a87, 0xa080, 0x0007, + 0x2004, 0xa086, 0x0006, 0x1138, 0x6114, 0xa18c, 0x0184, 0xa18d, + 0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c, 0x0184, 0xa18d, 0x0016, + 0x6116, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b, 0x003e, + 0x2019, 0xb8f0, 0x2304, 0xa065, 0x0120, 0x2009, 0x004f, 0x080c, + 0x86d3, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27f4, 0x7034, 0xd0ac, + 0x1560, 0x0016, 0x0156, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9, + 0x0006, 0x1d04, 0x27a9, 0x2091, 0x6000, 0x1f04, 0x27a9, 0x602f, + 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04, + 0x27b7, 0x2091, 0x6000, 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152, + 0x001e, 0x6027, 0x0008, 0x0480, 0x080c, 0x293c, 0x1f04, 0x27b7, + 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c, + 0x602a, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, + 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b, + 0x003e, 0x60e3, 0x0000, 0x080c, 0xb4eb, 0x080c, 0xb506, 0xa085, + 0x0001, 0x080c, 0x5b85, 0x2001, 0xb600, 0x2003, 0x0004, 0x6027, + 0x0008, 0x080c, 0x12e2, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, + 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, + 0x2071, 0xb600, 0x71c4, 0x70c6, 0xa116, 0x0500, 0x81ff, 0x0128, + 0x2011, 0x8011, 0x080c, 0x3f13, 0x00c8, 0x2011, 0x8012, 0x080c, + 0x3f13, 0x2001, 0xb672, 0x2004, 0xd0fc, 0x1180, 0x0036, 0x00c6, + 0x080c, 0x28c7, 0x080c, 0x7fbc, 0x2061, 0x0100, 0x2019, 0x0028, + 0x2009, 0x0000, 0x080c, 0x2ca4, 0x00ce, 0x003e, 0x012e, 0x00fe, + 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6, 0x0006, + 0x0026, 0x2061, 0x0100, 0xa190, 0x2840, 0x2205, 0x60f2, 0x2011, + 0x284d, 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce, 0x0005, + 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, + 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, + 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, 0xff00, + 0x1110, 0x81ff, 0x0118, 0x080c, 0x6723, 0x0038, 0xa080, 0x2df9, + 0x200d, 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080, 0x2df9, + 0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, + 0xb615, 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852, 0x6856, + 0x1f04, 0x2877, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, + 0x0140, 0x2001, 0xb615, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, + 0x20a9, 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128, 0xa184, + 0x000f, 0xa080, 0xb51a, 0x2005, 0x6856, 0x8211, 0x1f04, 0x288c, + 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0xb600, 0x6030, + 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, + 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0xa116, + 0x0180, 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, + 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x28bc, 0x680f, + 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x2001, + 0xb653, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, + 0x2020, 0x2009, 0x002e, 0x080c, 0xb1a4, 0x004e, 0x0005, 0x00f6, + 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0548, 0xa084, + 0x0700, 0xa08e, 0x0300, 0x1520, 0x2011, 0x0000, 0x2009, 0x0002, + 0x2300, 0xa080, 0x0020, 0x2018, 0x2300, 0x080c, 0x6bb2, 0x2011, + 0x0030, 0x2200, 0x8007, 0xa085, 0x004c, 0x78c2, 0x2009, 0x0204, + 0x210c, 0x2200, 0xa100, 0x2009, 0x0138, 0x200a, 0x080c, 0x5b41, + 0x1118, 0x2009, 0xb88f, 0x200a, 0x002e, 0x001e, 0x00fe, 0x0005, + 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, + 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0xa184, 0x0003, + 0x0110, 0x0804, 0x1b20, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, + 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e, 0x0268, + 0x2001, 0x0170, 0x200c, 0xa18c, 0x00ff, 0xa18e, 0x004c, 0x1128, + 0x200c, 0xa18c, 0xff00, 0x810f, 0x0010, 0x2009, 0x0000, 0x2001, + 0x0204, 0x2004, 0xa108, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, + 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2943, + 0x00fe, 0x015e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, + 0x0100, 0x6030, 0x0006, 0x6048, 0x0006, 0x60e4, 0x0006, 0x60e8, + 0x0006, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, + 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x60e0, 0x0006, 0x602f, + 0x0100, 0x602f, 0x0000, 0xe000, 0xe000, 0xe000, 0xe000, 0x602f, + 0x0040, 0x602f, 0x0000, 0x000e, 0x60e2, 0x000e, 0x602a, 0x000e, + 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x000e, + 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, 0x000e, + 0x6032, 0x6036, 0x2008, 0x080c, 0x287c, 0x000e, 0x00ce, 0x001e, + 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, + 0x2104, 0x200b, 0x0080, 0xe000, 0xe000, 0x200a, 0x0005, 0x2a2f, + 0x2a33, 0x2a37, 0x2a3d, 0x2a43, 0x2a49, 0x2a4f, 0x2a57, 0x2a5f, + 0x2a65, 0x2a6b, 0x2a73, 0x2a7b, 0x2a83, 0x2a8b, 0x2a95, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2aa1, + 0x2aa1, 0x2aa7, 0x2aa7, 0x2aae, 0x2aae, 0x2ab5, 0x2ab5, 0x2abe, + 0x2abe, 0x2ac5, 0x2ac5, 0x2ace, 0x2ace, 0x2ad7, 0x2ad7, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, + 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, + 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x0106, + 0x0006, 0x0804, 0x2aea, 0x0106, 0x0006, 0x0804, 0x2aea, 0x0106, + 0x0006, 0x080c, 0x254e, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, + 0x254e, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x0804, + 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106, + 0x0006, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106, + 0x0006, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106, + 0x0006, 0x080c, 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, + 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c, + 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c, + 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x080c, + 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x080c, + 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c, + 0x23bf, 0x080c, 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, + 0x254e, 0x080c, 0x23bf, 0x080c, 0x2427, 0x0804, 0x2aea, 0xe000, + 0x0cf0, 0x0106, 0x0006, 0x080c, 0x290b, 0x0804, 0x2aea, 0x0106, + 0x0006, 0x080c, 0x290b, 0x080c, 0x254e, 0x04e0, 0x0106, 0x0006, + 0x080c, 0x290b, 0x080c, 0x23bf, 0x04a8, 0x0106, 0x0006, 0x080c, + 0x290b, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0460, 0x0106, 0x0006, + 0x080c, 0x290b, 0x080c, 0x2427, 0x0428, 0x0106, 0x0006, 0x080c, + 0x290b, 0x080c, 0x254e, 0x080c, 0x2427, 0x00e0, 0x0106, 0x0006, + 0x080c, 0x290b, 0x080c, 0x23bf, 0x080c, 0x2427, 0x0098, 0x0106, + 0x0006, 0x080c, 0x290b, 0x080c, 0x254e, 0x080c, 0x23bf, 0x080c, + 0x2427, 0x0040, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, + 0x080c, 0x151a, 0x000e, 0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, + 0x2021, 0x0000, 0x080c, 0x537b, 0x1904, 0x2bca, 0x72d4, 0x2001, + 0xb89e, 0x2004, 0xa005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, + 0xd2bc, 0x1904, 0x2bca, 0x080c, 0x2bce, 0x0804, 0x2bca, 0xd2cc, + 0x1904, 0x2bca, 0x080c, 0x5b41, 0x1120, 0x709f, 0xffff, 0x0804, + 0x2bca, 0xd294, 0x0120, 0x709f, 0xffff, 0x0804, 0x2bca, 0x2001, + 0xb615, 0x203c, 0x7288, 0xd284, 0x0904, 0x2b6c, 0xd28c, 0x1904, + 0x2b6c, 0x0036, 0x739c, 0xa38e, 0xffff, 0x1110, 0x2019, 0x0001, + 0x8314, 0xa2e0, 0xbdc0, 0x2c04, 0xa38c, 0x0001, 0x0120, 0xa084, + 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, 0x0560, 0xa08e, + 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x1538, + 0x7288, 0xc28d, 0x728a, 0x709f, 0xffff, 0x003e, 0x0428, 0x2009, + 0x0000, 0x080c, 0x2852, 0x080c, 0x4fbf, 0x11b8, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c, 0x0118, 0x6000, + 0xd0bc, 0x0120, 0x080c, 0x2be1, 0x0140, 0x0028, 0x080c, 0x2d12, + 0x080c, 0x2c0f, 0x0110, 0x8318, 0x0818, 0x739e, 0x0010, 0x709f, + 0xffff, 0x003e, 0x0804, 0x2bca, 0xa780, 0x2df9, 0x203d, 0xa7bc, + 0xff00, 0x873f, 0x2041, 0x007e, 0x709c, 0xa096, 0xffff, 0x1120, + 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220, 0x2008, 0xa802, + 0x20a8, 0x0020, 0x709f, 0xffff, 0x0804, 0x2bca, 0x2700, 0x0156, + 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x501b, 0x0120, 0x080c, + 0x4fbf, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000, 0xd0bc, 0x11d0, + 0x7288, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff, 0xa082, 0x0006, + 0x02b0, 0xd484, 0x1118, 0x080c, 0x4fde, 0x0028, 0x080c, 0x2d9f, + 0x0170, 0x080c, 0x2dcc, 0x0058, 0x080c, 0x2d12, 0x080c, 0x2c0f, + 0x0170, 0x0028, 0x080c, 0x2d9f, 0x0110, 0x0419, 0x0140, 0x001e, + 0x8108, 0x015e, 0x1f04, 0x2b86, 0x709f, 0xffff, 0x0018, 0x001e, + 0x015e, 0x719e, 0x004e, 0x002e, 0x00ce, 0x0005, 0x00c6, 0x0016, + 0x709f, 0x0001, 0x2009, 0x007e, 0x080c, 0x4fbf, 0x1138, 0x080c, + 0x2d12, 0x04a9, 0x0118, 0x70d4, 0xc0bd, 0x70d6, 0x001e, 0x00ce, + 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xb657, + 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9f92, 0x01d8, 0x2d00, + 0x601a, 0x080c, 0xa0e3, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, + 0x4f5d, 0x2001, 0x0000, 0x080c, 0x4f6f, 0x0126, 0x2091, 0x8000, + 0x7098, 0x8000, 0x709a, 0x012e, 0x2009, 0x0004, 0x080c, 0x86d3, + 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, + 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xb657, 0x2004, 0xa084, + 0x00ff, 0x6842, 0x080c, 0x9f92, 0x0550, 0x2d00, 0x601a, 0x6800, + 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140, 0x6804, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2cd1, 0x080c, 0xa0e3, + 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, + 0x080c, 0x4f6f, 0x0126, 0x2091, 0x8000, 0x7098, 0x8000, 0x709a, + 0x012e, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, 0x0080, + 0x080c, 0x4fbf, 0x1120, 0x0031, 0x0110, 0x70db, 0xffff, 0x002e, + 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, + 0x864e, 0x01e8, 0x2d00, 0x601a, 0x080c, 0xa0e3, 0x601f, 0x0001, + 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, + 0x0126, 0x2091, 0x8000, 0x080c, 0x2cd1, 0x70dc, 0x8000, 0x70de, + 0x012e, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2009, 0x007f, 0x080c, 0x4fbf, 0x1190, 0x2c68, 0x080c, + 0x864e, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a, + 0x080c, 0xa0e3, 0x2009, 0x0022, 0x080c, 0x86d3, 0xa085, 0x0001, + 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, + 0x0026, 0x080c, 0x6e73, 0x080c, 0x6e16, 0x080c, 0x90fb, 0x2130, + 0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9, + 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1120, 0x080c, + 0x521c, 0x080c, 0x4c7e, 0x001e, 0x8108, 0x1f04, 0x2cbb, 0x86ff, + 0x1110, 0x080c, 0x11f5, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, + 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270, + 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076, 0x2039, + 0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c, 0xaf3e, 0x007e, 0x001e, + 0x2e60, 0x080c, 0x521c, 0x6210, 0x6314, 0x080c, 0x4c7e, 0x6212, + 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150, + 0x2071, 0xb600, 0x7098, 0xa005, 0x0110, 0x8001, 0x709a, 0x000e, + 0x00ee, 0x0005, 0x2071, 0xb600, 0x70dc, 0xa005, 0x0dc0, 0x8001, + 0x70de, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6, + 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, + 0x20a9, 0x0001, 0x0098, 0x2001, 0xb653, 0x2004, 0xd0c4, 0x0150, + 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c, + 0xb1a4, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e, + 0x007e, 0x0904, 0x2d7e, 0xa28e, 0x007f, 0x0904, 0x2d7e, 0xa28e, + 0x0080, 0x05e0, 0xa288, 0xb735, 0x210c, 0x81ff, 0x05b8, 0x8fff, + 0x1148, 0x2001, 0xb8be, 0x0006, 0x2003, 0x0001, 0x04d9, 0x000e, + 0x2003, 0x0000, 0x00c6, 0x2160, 0x2001, 0x0001, 0x080c, 0x5385, + 0x00ce, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076, 0x2039, 0x0000, + 0x080c, 0x6d74, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, + 0xa286, 0x0006, 0x1118, 0x6007, 0x0404, 0x0028, 0x2001, 0x0004, + 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, + 0xaf3e, 0x001e, 0x007e, 0x2160, 0x080c, 0x521c, 0x002e, 0x8210, + 0x1f04, 0x2d36, 0x015e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001, 0xb653, 0x2004, + 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, 0x8427, 0x2009, + 0x0029, 0x080c, 0xb1a4, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x7288, 0x82ff, 0x01f8, 0x2011, 0xb653, + 0x2214, 0xd2ac, 0x11d0, 0x2100, 0x080c, 0x2866, 0x81ff, 0x01b8, + 0x2019, 0x0001, 0x8314, 0xa2e0, 0xbdc0, 0x2c04, 0xd384, 0x0120, + 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, + 0xa096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019, 0x0029, + 0x080c, 0x8320, 0x002e, 0x080c, 0xb449, 0x003e, 0x002e, 0x001e, + 0xa180, 0xb735, 0x2004, 0xa065, 0x0158, 0x0016, 0x00c6, 0x2061, + 0xb9f5, 0x001e, 0x611a, 0x080c, 0x2cd1, 0x001e, 0x080c, 0x4fde, + 0x012e, 0x00ce, 0x001e, 0x0005, 0x2001, 0xb635, 0x2004, 0xd0cc, + 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, + 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, + 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, + 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, + 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, + 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, + 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, + 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, + 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, + 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, + 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, + 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, + 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, + 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, + 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, + 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, + 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, + 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, + 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, + 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, + 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, + 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, + 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, + 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, + 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, + 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, + 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x2071, 0xb682, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, + 0x703a, 0x703e, 0x7033, 0xb692, 0x7037, 0xb692, 0x7007, 0x0001, + 0x2061, 0xb6d2, 0x6003, 0x0002, 0x0005, 0x1004, 0x2f1f, 0x0e04, + 0x2f1f, 0x2071, 0xb682, 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, + 0x7820, 0xa08e, 0x0069, 0x1904, 0x3004, 0x0804, 0x2f9d, 0x0005, + 0x2071, 0xb682, 0x7004, 0x0002, 0x2f28, 0x2f29, 0x2f32, 0x2f43, + 0x0005, 0x1004, 0x2f31, 0x0e04, 0x2f31, 0x2b78, 0x7818, 0xd084, + 0x01e8, 0x0005, 0x2b78, 0x2061, 0xb6d2, 0x6008, 0xa08e, 0x0100, + 0x0128, 0xa086, 0x0200, 0x0904, 0x2ffe, 0x0005, 0x7014, 0x2068, + 0x2a60, 0x7018, 0x0807, 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, + 0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, + 0xa08a, 0x0040, 0x1210, 0x61c4, 0x0042, 0x2100, 0xa08a, 0x003f, + 0x1a04, 0x2ffb, 0x61c4, 0x0804, 0x2f9d, 0x2fdf, 0x300a, 0x3012, + 0x3016, 0x301e, 0x3024, 0x3028, 0x3034, 0x3037, 0x3041, 0x3044, + 0x2ffb, 0x2ffb, 0x2ffb, 0x3047, 0x2ffb, 0x3056, 0x306d, 0x3084, + 0x30fe, 0x3103, 0x312c, 0x317d, 0x318e, 0x31ad, 0x31e5, 0x31ef, + 0x31fc, 0x320f, 0x3230, 0x3239, 0x326f, 0x3275, 0x2ffb, 0x329e, + 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32a5, 0x32af, 0x2ffb, + 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32b7, + 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32c9, 0x32d3, 0x2ffb, + 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x0002, 0x32fd, 0x3351, + 0x33ac, 0x33c6, 0x2ffb, 0x33f7, 0x382a, 0x427a, 0x2ffb, 0x2ffb, + 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x3041, 0x3044, + 0x382c, 0x2ffb, 0x3839, 0x4313, 0x436e, 0x43d2, 0x2ffb, 0x4435, + 0x445f, 0x447e, 0x44b0, 0x2ffb, 0x2ffb, 0x2ffb, 0x383d, 0x39e2, + 0x39fc, 0x3a26, 0x3a87, 0x3ae7, 0x3af2, 0x3b2a, 0x3b39, 0x3b48, + 0x3b4b, 0x3b6e, 0x3bba, 0x3c34, 0x3c41, 0x3d42, 0x3e6a, 0x3e93, + 0x3f91, 0x3fb3, 0x3fbf, 0x3ff8, 0x40bc, 0x2ffb, 0x2ffb, 0x2ffb, + 0x2ffb, 0x4124, 0x413f, 0x41b1, 0x4263, 0x713c, 0x0000, 0x2021, + 0x4000, 0x080c, 0x3ef0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x2feb, + 0x7818, 0xd084, 0x0110, 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, + 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, + 0x5000, 0x012e, 0x0005, 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, + 0x0c00, 0x2021, 0x4003, 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, + 0x4006, 0x08b8, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, + 0x0804, 0x3efd, 0x7823, 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, + 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3f00, 0x7924, 0x7828, + 0x2114, 0x200a, 0x0804, 0x2fdf, 0x7924, 0x2114, 0x0804, 0x2fdf, + 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, + 0x7a28, 0x7b2c, 0x0804, 0x2fdf, 0x7824, 0x2060, 0x0090, 0x2009, + 0x0002, 0x2011, 0x0002, 0x2019, 0x0008, 0x783b, 0x0017, 0x0804, + 0x2fdf, 0x7d38, 0x7c3c, 0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, + 0x1000, 0xe10c, 0xa006, 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, + 0x2010, 0xa005, 0x0904, 0x2fdf, 0x0804, 0x3001, 0x2069, 0xb652, + 0x7824, 0x7930, 0xa11a, 0x1a04, 0x3007, 0x8019, 0x0904, 0x3007, + 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, + 0x685e, 0x080c, 0x5e17, 0x0804, 0x2fdf, 0x2069, 0xb652, 0x7824, + 0x7934, 0xa11a, 0x1a04, 0x3007, 0x8019, 0x0904, 0x3007, 0x684e, + 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, + 0x080c, 0x5447, 0x0804, 0x2fdf, 0xa02e, 0x2520, 0x81ff, 0x1904, + 0x3004, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xb689, + 0x41a1, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x2009, 0x0020, 0x080c, + 0x3efd, 0x701b, 0x309c, 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, + 0xa096, 0x0011, 0x0138, 0xa096, 0x0019, 0x0120, 0xa096, 0x0015, + 0x1904, 0x3004, 0x810f, 0xa18c, 0x00ff, 0x0904, 0x3004, 0x710e, + 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3ebc, 0x0904, 0x3004, + 0x2009, 0x0020, 0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c, 0x6530, + 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, + 0x080c, 0x3efd, 0x701b, 0x30cd, 0x0005, 0x6834, 0xa084, 0x00ff, + 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904, 0x3004, 0x08c0, + 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x4ebb, 0x1128, + 0x7007, 0x0003, 0x701b, 0x30e7, 0x0005, 0x080c, 0x554d, 0x0126, + 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xb689, 0x530a, 0x2100, + 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, + 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3f00, 0x61ac, 0x7824, + 0x60ae, 0x0804, 0x2fdf, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, + 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, + 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, + 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, + 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, + 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904, 0x3004, 0x7924, + 0x810f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1904, 0x3007, 0x7e38, + 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804, 0x3007, 0x7c28, + 0x7d2c, 0x080c, 0x51e3, 0xd28c, 0x1118, 0x080c, 0x518c, 0x0010, + 0x080c, 0x51bc, 0x1518, 0x2061, 0xbe00, 0x0126, 0x2091, 0x8000, + 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d, 0x0130, 0x683c, + 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e, 0xace0, 0x0018, + 0x2001, 0xb617, 0x2004, 0xac02, 0x1a04, 0x3004, 0x0c30, 0x080c, + 0x99e6, 0x012e, 0x0904, 0x3004, 0x0804, 0x2fdf, 0xa00e, 0x2001, + 0x0005, 0x080c, 0x554d, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f8e, + 0x080c, 0x547a, 0x012e, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, + 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1, 0x0904, 0x3004, + 0x080c, 0x51ef, 0x0904, 0x3004, 0x0804, 0x2fdf, 0x81ff, 0x1904, + 0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x080c, 0x525b, 0x0904, + 0x3004, 0x2019, 0x0005, 0x7924, 0x080c, 0x520a, 0x0904, 0x3004, + 0x7828, 0xa08a, 0x1000, 0x1a04, 0x3007, 0x8003, 0x800b, 0x810b, + 0xa108, 0x080c, 0x6a1a, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x00ff, 0x6450, + 0x2400, 0xa506, 0x01f8, 0x2508, 0x080c, 0x501b, 0x11d8, 0x080c, + 0x525b, 0x1128, 0x2009, 0x0002, 0x62b4, 0x2518, 0x00c0, 0x2019, + 0x0004, 0xa00e, 0x080c, 0x520a, 0x1118, 0x2009, 0x0006, 0x0078, + 0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108, + 0x080c, 0x6a1a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x2fdf, 0x012e, + 0x0804, 0x3004, 0x012e, 0x0804, 0x3007, 0x080c, 0x3ed1, 0x0904, + 0x3007, 0x080c, 0x5147, 0x080c, 0x51e3, 0x0804, 0x2fdf, 0x81ff, + 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x5138, + 0x080c, 0x51e3, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x080c, + 0x3ed1, 0x0904, 0x3007, 0x080c, 0x51be, 0x0904, 0x3004, 0x080c, + 0x4eff, 0x080c, 0x5185, 0x080c, 0x51e3, 0x0804, 0x2fdf, 0x080c, + 0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1, 0x0904, 0x3004, 0x62a0, + 0x2019, 0x0005, 0x00c6, 0x080c, 0x521c, 0x2061, 0x0000, 0x080c, + 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2009, 0x0000, + 0x080c, 0xaf3e, 0x007e, 0x00ce, 0x080c, 0x51e3, 0x0804, 0x2fdf, + 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x51e3, 0x2208, 0x0804, + 0x2fdf, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xb714, 0x6810, 0x6914, + 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, + 0x0000, 0x20a9, 0x007e, 0x2069, 0xb735, 0x2d04, 0xa075, 0x0130, + 0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04, + 0x324d, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2fdf, + 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c, + 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, + 0xb714, 0x6910, 0x62b0, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, + 0x6150, 0xa190, 0x2df9, 0x2215, 0xa294, 0x00ff, 0x6370, 0x83ff, + 0x0108, 0x6274, 0x67d4, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090, + 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031, + 0x0002, 0x0040, 0x080c, 0x5b41, 0x1118, 0x2031, 0x0004, 0x0010, + 0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2fdf, 0x6140, 0x6244, + 0x2019, 0xb8b6, 0x231c, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000, + 0x6134, 0xa006, 0x2010, 0x6338, 0x012e, 0x0804, 0x2fdf, 0x080c, + 0x3ee1, 0x0904, 0x3007, 0x6244, 0x6338, 0x0804, 0x2fdf, 0x6140, + 0x6244, 0x7824, 0x6042, 0x7b28, 0x6346, 0x2069, 0xb652, 0x831f, + 0xa305, 0x6816, 0x782c, 0x2069, 0xb8b6, 0x2d1c, 0x206a, 0x0804, + 0x2fdf, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x782c, 0x603a, + 0x012e, 0x0804, 0x2fdf, 0x7838, 0xa005, 0x01a8, 0x7828, 0xa025, + 0x0904, 0x3007, 0x782c, 0xa02d, 0x0904, 0x3007, 0xa00e, 0x080c, + 0x501b, 0x1120, 0x6244, 0x6338, 0x6446, 0x653a, 0xa186, 0x00ff, + 0x0190, 0x8108, 0x0ca0, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x7828, + 0xa00d, 0x0904, 0x3007, 0x782c, 0xa005, 0x0904, 0x3007, 0x6244, + 0x6146, 0x6338, 0x603a, 0x0804, 0x2fdf, 0x2001, 0xb600, 0x2004, + 0xa086, 0x0003, 0x1904, 0x3004, 0x00c6, 0x2061, 0x0100, 0x7924, + 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xb615, + 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, + 0x2df9, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xb615, 0x2004, 0xa116, + 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, + 0x864e, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, + 0x080c, 0x3ebc, 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, + 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x33a5, 0x2d00, 0x6012, + 0x2009, 0x0032, 0x080c, 0x86d3, 0x012e, 0x00ce, 0x0005, 0x012e, + 0x00ce, 0x0804, 0x3004, 0x00ce, 0x0804, 0x3007, 0x080c, 0x86a4, + 0x0cb0, 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, + 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, + 0x00ff, 0x1130, 0x2001, 0xb615, 0x2004, 0xa085, 0xff00, 0x0078, + 0xa182, 0x007f, 0x16a0, 0xa188, 0x2df9, 0x210d, 0xa18c, 0x00ff, + 0x2001, 0xb615, 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, + 0x2091, 0x8000, 0x0006, 0x080c, 0x864e, 0x000e, 0x01e0, 0x601a, + 0x600b, 0xbc05, 0x601f, 0x0001, 0x080c, 0x3ebc, 0x01d8, 0x6837, + 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x701b, 0x33a5, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x86d3, + 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3004, 0x00ce, + 0x0804, 0x3007, 0x080c, 0x86a4, 0x0cb0, 0x6830, 0xa086, 0x0100, + 0x0904, 0x3004, 0x0804, 0x2fdf, 0x2061, 0xb975, 0x0126, 0x2091, + 0x8000, 0x6000, 0xd084, 0x0178, 0x6104, 0x6208, 0x2a60, 0x6068, + 0x783a, 0x60b4, 0x783e, 0x60b0, 0x2019, 0x0072, 0x201a, 0x6348, + 0x012e, 0x0804, 0x2fdf, 0xa00e, 0x2110, 0x0c80, 0x81ff, 0x1904, + 0x3004, 0x080c, 0x5b41, 0x0904, 0x3004, 0x0126, 0x2091, 0x8000, + 0x6248, 0x6068, 0xa202, 0x0248, 0xa085, 0x0001, 0x080c, 0x289c, + 0x080c, 0x4673, 0x012e, 0x0804, 0x2fdf, 0x012e, 0x0804, 0x3007, + 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0xb8c0, 0x2070, 0x2061, + 0xb652, 0x6008, 0x2072, 0x2009, 0x0000, 0x2011, 0x1000, 0x080c, + 0x6bb2, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x7824, 0xa084, 0x0007, 0x0002, 0x3409, 0x3412, + 0x3419, 0x3406, 0x3406, 0x3406, 0x3406, 0x3406, 0x012e, 0x0804, + 0x3007, 0x2009, 0x0114, 0x2104, 0xa085, 0x0800, 0x200a, 0x080c, + 0x3584, 0x0070, 0x2009, 0x010b, 0x200b, 0x0010, 0x080c, 0x3584, + 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2fe1, + 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x080c, 0x33e0, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0138, + 0x200c, 0x2003, 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, 0x2001, + 0x007b, 0x202c, 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, 0x37cf, + 0x080c, 0x3733, 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, 0x2d60, + 0x2071, 0xb94b, 0x2079, 0x0020, 0x00d6, 0x2069, 0x0000, 0x6824, + 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004, 0x783e, 0x2001, 0x007c, + 0x2004, 0x783a, 0x00de, 0x2011, 0x0001, 0x080c, 0x36df, 0x080c, + 0x36df, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x362a, 0x080c, 0x3707, + 0x080c, 0x3684, 0x080c, 0x35e9, 0x080c, 0x361a, 0x00f6, 0x2079, + 0x0100, 0x7824, 0xd094, 0x0530, 0x7814, 0xa084, 0x0184, 0xa085, + 0x0010, 0x7816, 0x2079, 0x0140, 0x080c, 0x3562, 0x1110, 0x00fe, + 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086, + 0x7814, 0xa084, 0x0184, 0xa085, 0x0032, 0x7816, 0x080c, 0x3562, + 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc, 0x0dc0, 0x7827, 0x0080, + 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x356c, + 0x00fe, 0x0804, 0x352c, 0x00fe, 0x080c, 0x3562, 0x1150, 0x8948, + 0x2001, 0x007a, 0x2602, 0x2001, 0x007b, 0x2502, 0x080c, 0x356c, + 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201, 0x2004, 0xa005, 0x1904, + 0x3466, 0x8739, 0x0038, 0x2001, 0xb924, 0x2004, 0xa086, 0x0000, + 0x1904, 0x3466, 0x2001, 0x0033, 0x2003, 0x00f6, 0x8631, 0x1208, + 0x8529, 0x2500, 0xa605, 0x0904, 0x352c, 0x7824, 0xd0bc, 0x0128, + 0x2900, 0xaa05, 0xab05, 0x1904, 0x352c, 0x6033, 0x000d, 0x2001, + 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1148, 0x2001, 0xb924, + 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x0040, 0x6027, + 0x0001, 0x2001, 0x0075, 0x2004, 0xa005, 0x0108, 0x6026, 0x2c00, + 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a, 0x6833, 0x000d, 0x7824, + 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, + 0x0020, 0x6003, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3501, + 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001, 0x0074, 0x2004, 0xa005, + 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0020, + 0x7827, 0x0002, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x601a, + 0x0006, 0x2001, 0x0073, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, + 0x00ce, 0x00fe, 0x0804, 0x3444, 0x2061, 0x0100, 0x6027, 0x0002, + 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824, 0xa084, 0x0003, 0xa086, + 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050, 0xa084, 0xf7ef, 0x6052, + 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e, 0x604b, 0xf7f7, 0x6043, + 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0xaa05, + 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, + 0x008e, 0x1118, 0x012e, 0x0804, 0x2fdf, 0x012e, 0x2021, 0x400c, + 0x0804, 0x2fe1, 0xa085, 0x0001, 0x1d04, 0x356b, 0x2091, 0x6000, + 0x8420, 0xa486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, + 0x2001, 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, 0x2003, 0x0004, + 0x2001, 0xb924, 0x2003, 0x0000, 0x2001, 0xb94b, 0x2003, 0x0000, + 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, + 0xb615, 0x200c, 0x7932, 0x7936, 0x080c, 0x287c, 0x7850, 0xa084, + 0x0980, 0xa085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, + 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad, 0x782e, 0x20a9, 0x0046, + 0x1d04, 0x35a0, 0x2091, 0x6000, 0x1f04, 0x35a0, 0x7850, 0xa085, + 0x0400, 0x7852, 0x2001, 0x0009, 0x2004, 0xa084, 0x0003, 0xa086, + 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, 0x784b, 0xf7f7, 0x7843, + 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x35bd, + 0x7850, 0xa085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xe000, + 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850, + 0xa085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xe000, + 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7827, + 0x0020, 0x7843, 0x0000, 0x2003, 0x0000, 0x7827, 0x0048, 0x00fe, + 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0xb924, + 0x2079, 0x0030, 0x2001, 0x0201, 0x2004, 0xa005, 0x0160, 0x7000, + 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, + 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x780c, 0xa08c, + 0x0070, 0x0178, 0x2009, 0x007a, 0x260a, 0x2009, 0x007b, 0x250a, + 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108, + 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0140, + 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x0ca8, + 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0xb8c1, 0x2004, + 0x70e2, 0x2009, 0xb615, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, + 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, + 0xa080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, + 0xa006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, + 0x95d5, 0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032, + 0x7016, 0x080c, 0x3707, 0x080c, 0x3562, 0x1110, 0x8421, 0x0028, + 0x7024, 0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, + 0xb924, 0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, + 0x0120, 0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, + 0x080c, 0x36df, 0x2011, 0x0001, 0x080c, 0x36df, 0x00ee, 0x00fe, + 0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xb924, + 0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904, 0x36dc, 0x7803, 0x0002, + 0xa026, 0xd19c, 0x1904, 0x36d8, 0x7000, 0x0002, 0x36dc, 0x369a, + 0x36be, 0x36d8, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, + 0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, + 0x7820, 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, + 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3606, 0x2009, 0x0001, 0x7808, + 0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, + 0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, + 0x00b1, 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, + 0x6000, 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, + 0x7803, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, + 0xa005, 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, + 0x7832, 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, + 0x2804, 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, + 0xa802, 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, + 0x601a, 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x2071, 0xb94b, 0x2079, 0x0020, 0x7904, 0xd1fc, + 0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x372f, + 0x371a, 0x3726, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, + 0x080c, 0x36df, 0x0160, 0x080c, 0x36df, 0x0048, 0x8001, 0x7002, + 0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x36df, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, + 0x2001, 0xb8c1, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0xb8c0, + 0x2004, 0x60ce, 0x6004, 0xc0ac, 0xa085, 0x0200, 0x6006, 0x2001, + 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, 0x2001, 0x0076, 0x2024, + 0x2001, 0x0077, 0x201c, 0x080c, 0x3ebc, 0x6833, 0x000d, 0x6f26, + 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, + 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, 0x04b1, 0x1d90, + 0x2d00, 0x681a, 0x0088, 0x080c, 0x3ebc, 0x6833, 0x000d, 0x2070, + 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, 0x0076, 0x2004, 0x2072, + 0x2001, 0x0077, 0x2004, 0x7006, 0x2061, 0x0020, 0x2079, 0x0100, + 0x2001, 0xb8c0, 0x2004, 0x6012, 0x20e1, 0x9040, 0x2001, 0x0072, + 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, 0x0073, + 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, 0x603a, + 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0010, + 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, 0xa006, + 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, 0x7003, + 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, 0x0040, + 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, 0x2d60, + 0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x6018, 0x2070, 0x2d00, 0x7006, + 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, + 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, 0x0078, + 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3ebc, 0x2d60, 0x6833, + 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, + 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, + 0x080c, 0x379d, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c, 0x3ebc, + 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, 0x601a, + 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, 0x7006, + 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, 0x0073, + 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, + 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, 0x0000, + 0x2001, 0xb924, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, + 0x00ee, 0x0005, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000, 0x20a9, + 0x0012, 0x2001, 0xb640, 0x20a0, 0xa006, 0x40a4, 0x012e, 0x0804, + 0x2fdf, 0x7d38, 0x7c3c, 0x0804, 0x3086, 0x080c, 0x3ebc, 0x0904, + 0x3004, 0x080c, 0x5b41, 0x0110, 0x080c, 0x4c52, 0x2009, 0x001c, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x3851, + 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x3007, 0x6804, + 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x3007, 0xd094, 0x00c6, 0x2061, + 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, 0xa18c, + 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c, + 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, + 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x3007, + 0xa288, 0x2df9, 0x210d, 0xa18c, 0x00ff, 0x615a, 0xd0dc, 0x0130, + 0x6828, 0xa08a, 0x007f, 0x1a04, 0x3007, 0x6052, 0x6808, 0xa08a, + 0x0100, 0x0a04, 0x3007, 0xa08a, 0x0841, 0x1a04, 0x3007, 0xa084, + 0x0007, 0x1904, 0x3007, 0x680c, 0xa005, 0x0904, 0x3007, 0x6810, + 0xa005, 0x0904, 0x3007, 0x6848, 0x6940, 0xa10a, 0x1a04, 0x3007, + 0x8001, 0x0904, 0x3007, 0x684c, 0x6944, 0xa10a, 0x1a04, 0x3007, + 0x8001, 0x0904, 0x3007, 0x6804, 0xd0fc, 0x0560, 0x080c, 0x3ebc, + 0x0904, 0x3004, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3efd, 0x701b, 0x38d1, + 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xb66e, + 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xb672, 0x200c, + 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, + 0x6006, 0x00ce, 0x2009, 0xb8b1, 0x200b, 0x0000, 0x2001, 0xb674, + 0x2004, 0xd0ac, 0x0158, 0x7824, 0x200a, 0x2009, 0x017f, 0x200a, + 0x3200, 0xa084, 0x003f, 0xa085, 0x3020, 0x2090, 0x20a9, 0x001c, + 0x2d98, 0x2069, 0xb652, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, + 0x6142, 0x8007, 0xa084, 0x00ff, 0x6046, 0x080c, 0x5e17, 0x080c, + 0x53de, 0x080c, 0x5447, 0x6000, 0xa086, 0x0000, 0x1904, 0x39cc, + 0x6808, 0x602a, 0x080c, 0x24a5, 0x0006, 0x2001, 0x0100, 0x2004, + 0xa082, 0x0005, 0x000e, 0x0268, 0x2009, 0x0170, 0x200b, 0x0080, + 0xe000, 0xe000, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x28d7, + 0x003e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, + 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, + 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, + 0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, + 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0xb8c7, 0x40a1, + 0x080c, 0x6ada, 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, + 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, + 0x3508, 0x8109, 0x080c, 0x63ce, 0x6878, 0x6016, 0x6874, 0x2008, + 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, + 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x3966, + 0x00ce, 0x2069, 0xb652, 0x2001, 0xb89e, 0x6a80, 0xa294, 0x0030, + 0xa28e, 0x0000, 0x0170, 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, + 0x0140, 0x2003, 0xaaaa, 0x080c, 0x2920, 0x2001, 0xb88f, 0x2102, + 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, + 0x0000, 0x00ce, 0x080c, 0x5b41, 0x0128, 0x080c, 0x4116, 0x0110, + 0x080c, 0x289c, 0x60c8, 0xa005, 0x01d0, 0x6003, 0x0001, 0x2009, + 0x39b2, 0x00e0, 0x080c, 0x5b41, 0x1178, 0x2011, 0x5a14, 0x080c, + 0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x2001, 0xb89f, 0x2003, + 0x0000, 0x080c, 0x5a79, 0x0040, 0x080c, 0x4b7b, 0x0028, 0x6003, + 0x0004, 0x2009, 0x39cc, 0x0010, 0x0804, 0x2fdf, 0x2001, 0x0100, + 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004, 0xa084, + 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817, 0x2091, + 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x3004, 0x2069, + 0xb652, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc, 0x0118, + 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, + 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0xa006, 0x080c, 0x289c, 0x81ff, + 0x1904, 0x3004, 0x080c, 0x5b41, 0x1178, 0x2001, 0xb89f, 0x2003, + 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, + 0x5b85, 0x080c, 0x5a79, 0x0080, 0x0016, 0x2009, 0xffff, 0x8109, + 0x0130, 0x2001, 0xb8e2, 0x2004, 0xa086, 0x0000, 0x1dc0, 0x001e, + 0x080c, 0x4c52, 0x080c, 0x4b7b, 0x0804, 0x2fdf, 0x81ff, 0x1904, + 0x3004, 0x080c, 0x5b41, 0x1110, 0x0804, 0x3004, 0x6188, 0x81ff, + 0x0198, 0x703f, 0x0000, 0x2001, 0xbdc0, 0x2009, 0x0040, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, 0x080c, 0x3f00, + 0x701b, 0x2fdd, 0x012e, 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, + 0xbdc0, 0x20a9, 0x0040, 0x20a1, 0xbdc0, 0x2019, 0xffff, 0x43a4, + 0x6550, 0xa588, 0x2df9, 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, + 0x2011, 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, 0x501b, 0x1190, + 0x6014, 0x821c, 0x0238, 0xa398, 0xbdc0, 0xa085, 0xff00, 0x8007, + 0x201a, 0x0038, 0xa398, 0xbdc0, 0x2324, 0xa4a4, 0xff00, 0xa405, + 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, + 0x8007, 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, + 0xbdc0, 0x2099, 0xbdc0, 0x080c, 0x4bf1, 0x0804, 0x3a33, 0x080c, + 0x3ee1, 0x0904, 0x3007, 0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x1120, + 0x2009, 0x0002, 0x0804, 0x3004, 0x2001, 0xb653, 0x2004, 0xd0b4, + 0x0550, 0x7824, 0xa084, 0xff00, 0xa08e, 0x7e00, 0x0520, 0xa08e, + 0x7f00, 0x0508, 0xa08e, 0x8000, 0x01f0, 0x6000, 0xd08c, 0x11d8, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9e96, 0x1120, 0x2009, 0x0003, + 0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3abf, 0x0005, 0x080c, + 0x3ee1, 0x0904, 0x3007, 0x20a9, 0x002b, 0x2c98, 0xade8, 0x0002, + 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, + 0x0006, 0x20a0, 0x080c, 0x4bf1, 0x20a9, 0x0004, 0xac80, 0x000a, + 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x4bf1, 0x2d00, 0x2009, + 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x81ff, + 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x51f8, + 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x7828, 0xa08a, 0x1000, + 0x1a04, 0x3007, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x080c, 0x525b, + 0x0904, 0x3004, 0x2019, 0x0004, 0xa00e, 0x080c, 0x520a, 0x7924, + 0x810f, 0x7a28, 0x0011, 0x0804, 0x2fdf, 0xa186, 0x00ff, 0x0110, + 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xb600, 0x6450, 0x2400, + 0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, + 0x501b, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, + 0x6a1a, 0x0005, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, + 0x3007, 0x080c, 0x50e1, 0x0904, 0x3004, 0x080c, 0x5201, 0x0804, + 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007, + 0x080c, 0x50e1, 0x0904, 0x3004, 0x080c, 0x51ef, 0x0804, 0x2fdf, + 0x6100, 0x0804, 0x2fdf, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x2001, + 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x00d6, 0xace8, + 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007, + 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217, + 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2fdf, 0x7824, 0xa09c, + 0x0003, 0xd0b4, 0x1160, 0xa39a, 0x0003, 0x1a04, 0x3004, 0x6250, + 0xa294, 0x00ff, 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, + 0xb640, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, + 0x3f00, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x3004, 0x00c6, + 0x080c, 0x3ebc, 0x00ce, 0x0904, 0x3004, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x080c, 0x9e42, 0x0904, 0x3004, 0x7007, 0x0003, + 0x701b, 0x3bab, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x3004, + 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, + 0x0804, 0x3f00, 0xa006, 0x080c, 0x289c, 0x7824, 0xa084, 0x00ff, + 0xa086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x3004, 0x080c, 0x5b41, + 0x0110, 0x080c, 0x4c52, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x3007, + 0x7924, 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, + 0x007f, 0x1a04, 0x3007, 0x2100, 0x080c, 0x2866, 0x0026, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x2061, 0xb8f4, 0x601b, 0x0000, 0x601f, + 0x0000, 0x080c, 0x5b41, 0x1178, 0x2001, 0xb89f, 0x2003, 0x0001, + 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b85, + 0x080c, 0x5a79, 0x0440, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, + 0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, + 0x080c, 0x806b, 0x003e, 0x2061, 0x0100, 0x2001, 0xb615, 0x2004, + 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, + 0x0010, 0x2009, 0xb8bf, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, + 0x4bb4, 0x080c, 0x6a94, 0x7924, 0xa18c, 0xff00, 0x810f, 0x080c, + 0x5b41, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c, 0x3b0d, 0x012e, + 0x00ce, 0x002e, 0x0804, 0x2fdf, 0x7924, 0xa18c, 0xff00, 0x810f, + 0x00c6, 0x080c, 0x4fbf, 0x2c08, 0x00ce, 0x1904, 0x3007, 0x0804, + 0x2fdf, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004, 0x60d4, + 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3004, + 0x080c, 0x3ebc, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x7924, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x3c61, + 0x0005, 0x2009, 0x0080, 0x080c, 0x501b, 0x1130, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a, 0x0804, 0x2fe1, + 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, + 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3cd8, 0xa0be, 0x0112, + 0x0904, 0x3cd8, 0xa0be, 0x0113, 0x0904, 0x3cd8, 0xa0be, 0x0114, + 0x0904, 0x3cd8, 0xa0be, 0x0117, 0x0904, 0x3cd8, 0xa0be, 0x011a, + 0x0904, 0x3cd8, 0xa0be, 0x011c, 0x0904, 0x3cd8, 0xa0be, 0x0121, + 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171, 0x05c8, 0xa0be, + 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832, + 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213, 0x0528, 0xa0be, + 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be, 0x021a, 0x1120, + 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300, 0x01c8, 0x00de, + 0x0804, 0x3007, 0xad80, 0x0010, 0x20a9, 0x0007, 0x080c, 0x3d1e, + 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3d1e, 0x0048, 0xad80, + 0x000c, 0x080c, 0x3d2c, 0x0050, 0xad80, 0x000e, 0x080c, 0x3d2c, + 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3d1e, 0x00c6, 0x080c, + 0x3ebc, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, + 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, + 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, + 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, + 0x0000, 0x6804, 0x2068, 0x080c, 0x9e5e, 0x1120, 0x2009, 0x0003, + 0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3d15, 0x0005, 0x00ce, + 0x00de, 0x2009, 0x0002, 0x0804, 0x3004, 0x6820, 0xa086, 0x8001, + 0x1904, 0x2fdf, 0x2009, 0x0004, 0x0804, 0x3004, 0x0016, 0x2008, + 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, + 0x1f04, 0x3d20, 0x001e, 0x0005, 0x0016, 0x00a6, 0x00b6, 0x2008, + 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, + 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x00be, 0x00ae, + 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004, + 0x60d4, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, + 0x3004, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d4, 0xd0ac, + 0x1120, 0xa182, 0x0080, 0x0a04, 0x3007, 0xa182, 0x00ff, 0x1a04, + 0x3007, 0x7a2c, 0x7b28, 0x6070, 0xa306, 0x1140, 0x6074, 0xa24e, + 0x0904, 0x3007, 0xa9cc, 0xff00, 0x0904, 0x3007, 0x0126, 0x2091, + 0x8000, 0x00c6, 0x080c, 0x3e0c, 0x2c68, 0x00ce, 0x0538, 0xa0c6, + 0x4000, 0x1178, 0x00c6, 0x0006, 0x2d60, 0xa00e, 0x080c, 0x52bc, + 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, + 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, + 0x2001, 0x4006, 0x2020, 0x012e, 0x0804, 0x2fe1, 0x2d00, 0x7022, + 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x864e, 0x05c0, + 0x2d00, 0x601a, 0x080c, 0xa0e3, 0x2e58, 0x00ee, 0x00e6, 0x00c6, + 0x080c, 0x3ebc, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x86a4, 0x00ee, + 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x3004, + 0x6837, 0x0000, 0x683b, 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, + 0x6838, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x080c, 0x2cd1, + 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, + 0x080c, 0x4f6f, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001, + 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, + 0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3def, 0x0005, 0x6830, + 0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204, + 0xa294, 0x00ff, 0x0804, 0x3004, 0x2009, 0x0000, 0x6838, 0xd0f4, + 0x1904, 0x2fdf, 0x080c, 0x52bc, 0x1108, 0xc185, 0x6000, 0xd0bc, + 0x0108, 0xc18d, 0x0804, 0x2fdf, 0x00e6, 0x00d6, 0xa02e, 0x2001, + 0xb635, 0x2004, 0xd0ac, 0x0130, 0xa026, 0x20a9, 0x00ff, 0x2071, + 0xb735, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xb7b5, + 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1570, 0x2428, 0xc5fd, + 0x0458, 0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, + 0xa206, 0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0568, + 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1538, 0x2001, 0x4000, + 0x0428, 0x2001, 0x4007, 0x0410, 0x2400, 0xa106, 0x1168, 0x6e14, + 0x87ff, 0x1138, 0x86ff, 0x09d0, 0x2001, 0xb635, 0x2004, 0xd0ac, + 0x19a8, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x3e20, + 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, + 0x080c, 0x4fbf, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005, 0x00de, + 0x00ee, 0x0005, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ebc, 0x0904, + 0x3004, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824, 0xa005, + 0x0904, 0x3007, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004, 0x1a04, + 0x3007, 0x2010, 0x2d18, 0x080c, 0x2c84, 0x0904, 0x3004, 0x7007, + 0x0003, 0x701b, 0x3e8c, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, + 0x3004, 0x0804, 0x2fdf, 0x7924, 0xa18c, 0xff00, 0x810f, 0x60d4, + 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x3007, 0xa182, 0x00ff, + 0x1a04, 0x3007, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d46, 0x1188, + 0xa190, 0xb735, 0x2204, 0xa065, 0x0160, 0x080c, 0x4c7e, 0x2001, + 0xb635, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e, 0x0804, + 0x2fdf, 0x012e, 0x0804, 0x3004, 0x080c, 0x15fd, 0x0188, 0xa006, + 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, 0x0030, + 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, + 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1130, + 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066, 0x8cff, + 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1128, + 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, + 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c, 0x1614, + 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, + 0x2031, 0x0000, 0x2061, 0xb6d2, 0x6606, 0x6112, 0x600e, 0x6226, + 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1648, 0x7007, 0x0002, + 0x701b, 0x2fdf, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, + 0x0000, 0x2001, 0xb690, 0x2004, 0xa005, 0x1168, 0x0e04, 0x3f2b, + 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001, + 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071, 0xb682, + 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078, 0x7030, + 0xa0e0, 0x0004, 0xac82, 0xb6d2, 0x0210, 0x2061, 0xb692, 0x2c00, + 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, + 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005, 0x00e6, + 0x2071, 0xb682, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x3f82, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084, 0x1508, + 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, + 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, + 0xa005, 0x1130, 0x7033, 0xb692, 0x7037, 0xb692, 0x00ce, 0x0048, + 0xac80, 0x0004, 0xa0fa, 0xb6d2, 0x0210, 0x2001, 0xb692, 0x7036, + 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001, 0xb653, + 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3f13, 0x002e, + 0x0005, 0x81ff, 0x1904, 0x3004, 0x0126, 0x2091, 0x8000, 0x6030, + 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x5b41, 0x1178, 0x2001, + 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, + 0x0001, 0x080c, 0x5b85, 0x080c, 0x5a79, 0x0010, 0x080c, 0x4b7b, + 0x012e, 0x0804, 0x2fdf, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, + 0x61e0, 0xa10d, 0x61e2, 0x0804, 0x2fdf, 0x0804, 0x3007, 0x81ff, + 0x1904, 0x3004, 0x6000, 0xa086, 0x0003, 0x1904, 0x3004, 0x2001, + 0xb653, 0x2004, 0xd0ac, 0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904, + 0x3007, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, + 0xa005, 0x0904, 0x2fdf, 0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x0904, + 0x3004, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, + 0x080c, 0x9f27, 0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x3ff1, + 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x3004, 0x0804, 0x2fdf, + 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x7f24, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3ebc, 0x0904, 0x3004, + 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, + 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x501b, 0x1904, 0x406b, + 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4, 0xff00, + 0xa8c6, 0x0600, 0x1904, 0x406b, 0x2001, 0xb653, 0x2004, 0xd0ac, + 0x1128, 0x080c, 0x52bc, 0x1110, 0xd79c, 0x05e8, 0xd794, 0x1110, + 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, + 0x53a3, 0x080c, 0x3d2c, 0xd794, 0x0148, 0xac80, 0x000a, 0x2098, + 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3d2c, 0x21a2, 0xd794, + 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, 0x53a3, + 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, 0x3400, + 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3d1e, 0xac80, 0x0026, 0x2098, + 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110, 0xa6b0, + 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xb635, 0x2004, 0xd0ac, + 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, + 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118, 0xa686, + 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x4014, 0x86ff, + 0x1120, 0x7120, 0x810b, 0x0804, 0x2fdf, 0x702f, 0x0001, 0x711e, + 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xb6d2, 0x6007, 0x0000, + 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, + 0x080c, 0x1648, 0x7007, 0x0002, 0x701b, 0x40a7, 0x0005, 0x702c, + 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, + 0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, 0x4014, + 0x7120, 0x810b, 0x0804, 0x2fdf, 0x2029, 0x007e, 0x7924, 0x7a28, + 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, + 0x3007, 0xa502, 0x0a04, 0x3007, 0xa184, 0x00ff, 0xa0e2, 0x0020, + 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa284, 0xff00, 0x8007, + 0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa284, + 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, + 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502, + 0x0a04, 0x3007, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x3007, + 0xa502, 0x0a04, 0x3007, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, + 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa484, 0x00ff, 0xa0e2, + 0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0x2061, 0xb8b9, + 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2fdf, 0x0006, 0x2001, + 0xb653, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672, + 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6168, 0x7a24, 0x6300, 0x82ff, + 0x1118, 0x7926, 0x0804, 0x2fdf, 0x83ff, 0x1904, 0x3007, 0x2001, + 0xfff0, 0xa200, 0x1a04, 0x3007, 0x2019, 0xffff, 0x606c, 0xa302, + 0xa200, 0x0a04, 0x3007, 0x7926, 0x626a, 0x0804, 0x2fdf, 0x2001, + 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x7c28, 0x7d24, + 0x7e38, 0x7f2c, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x2009, 0x0000, + 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, + 0x7026, 0x20a0, 0xa1e0, 0xb735, 0x2c64, 0x8cff, 0x01b8, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084, 0xff00, + 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, + 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, + 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff, 0x1120, + 0x7120, 0x810c, 0x0804, 0x2fdf, 0x702f, 0x0001, 0x711e, 0x7020, + 0xa300, 0x7022, 0x2061, 0xb6d2, 0x6007, 0x0000, 0x6312, 0x7024, + 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c, 0x1648, + 0x7007, 0x0002, 0x701b, 0x419d, 0x0005, 0x702c, 0xa005, 0x1168, + 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xb6d2, 0x6424, + 0x6528, 0x662c, 0x6730, 0x0804, 0x415a, 0x7120, 0x810c, 0x0804, + 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x60d4, 0xd0ac, 0x1118, 0xd09c, + 0x0904, 0x3004, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x7924, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x41c8, 0x0005, + 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, 0xa0be, + 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, 0x3007, + 0x6820, 0x6924, 0x080c, 0x2852, 0x1510, 0x080c, 0x4fbf, 0x11f8, + 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3ebc, 0x01b8, + 0x080c, 0x3ebc, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, + 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x9e7a, + 0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x4202, 0x0005, 0x00de, + 0x0804, 0x3004, 0x7120, 0x080c, 0x2dcc, 0x6820, 0xa086, 0x8001, + 0x0904, 0x3004, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x0006, + 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4bf1, 0x000e, 0xade8, + 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xb6d2, 0x6007, + 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6, + 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x3007, 0x2009, 0x0004, + 0x0804, 0x3f00, 0xa7c6, 0x7200, 0x1904, 0x3007, 0xa6c2, 0x0054, + 0x0a04, 0x3007, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, + 0x6532, 0x2c10, 0x080c, 0x1648, 0x7007, 0x0002, 0x701b, 0x4249, + 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, + 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4bf1, + 0x000e, 0x2009, 0x002a, 0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c, + 0x6530, 0x0804, 0x3f00, 0x81ff, 0x1904, 0x3004, 0x792c, 0x2001, + 0xb8a0, 0x2102, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1, + 0x0904, 0x3004, 0x0126, 0x2091, 0x8000, 0x080c, 0x5213, 0x012e, + 0x0804, 0x2fdf, 0x7824, 0xd08c, 0x1118, 0xd084, 0x0904, 0x3a87, + 0x080c, 0x3ee1, 0x0904, 0x3007, 0x00c6, 0x080c, 0x3ebc, 0x00ce, + 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, + 0x15b8, 0x7824, 0xd08c, 0x0120, 0x6000, 0xc08c, 0x6002, 0x0030, + 0x2001, 0xb653, 0x2004, 0xd0b4, 0x0904, 0x3ac3, 0x7824, 0xa084, + 0xff00, 0xa08e, 0x7e00, 0x0904, 0x3ac3, 0xa08e, 0x7f00, 0x0904, + 0x3ac3, 0xa08e, 0x8000, 0x0904, 0x3ac3, 0x6000, 0xd08c, 0x1904, + 0x3ac3, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9e96, + 0x1120, 0x2009, 0x0003, 0x0804, 0x3004, 0x7007, 0x0003, 0x701b, + 0x42ca, 0x0005, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x0804, 0x3ac3, + 0x2009, 0xb631, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x3004, 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x0120, 0x2009, + 0x0007, 0x0804, 0x3004, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x0120, + 0x2009, 0x0008, 0x0804, 0x3004, 0x609c, 0xd0a4, 0x1118, 0xd0ac, + 0x1904, 0x3ac3, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, + 0x683a, 0x080c, 0x9f27, 0x1120, 0x2009, 0x0003, 0x0804, 0x3004, + 0x7007, 0x0003, 0x701b, 0x4305, 0x0005, 0x6830, 0xa086, 0x0100, + 0x1120, 0x2009, 0x0004, 0x0804, 0x3004, 0x080c, 0x3ee1, 0x0904, + 0x3007, 0x0804, 0x4299, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3004, + 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x3004, 0x2001, + 0xb653, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x3004, 0x080c, + 0x3ee1, 0x0904, 0x3007, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, + 0x2009, 0x0009, 0x1904, 0x3004, 0x00c6, 0x080c, 0x3ebc, 0x00ce, + 0x2009, 0x0002, 0x0904, 0x3004, 0x6837, 0x0000, 0x6833, 0x0000, + 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c, 0x00ff, + 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956, 0x0048, + 0xa28e, 0x0100, 0x1904, 0x3007, 0xc0e5, 0x6853, 0x0000, 0x6857, + 0x0000, 0x683e, 0x080c, 0xa0e4, 0x2009, 0x0003, 0x0904, 0x3004, + 0x7007, 0x0003, 0x701b, 0x4365, 0x0005, 0x6830, 0xa086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x3004, 0x0804, 0x2fdf, 0x81ff, 0x2009, + 0x0001, 0x1904, 0x3004, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, + 0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x6004, 0xa084, + 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x3004, 0x00c6, + 0x080c, 0x3ebc, 0x00ce, 0x2009, 0x0002, 0x0904, 0x3004, 0xad80, + 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, + 0x3efd, 0x701b, 0x439c, 0x0005, 0x00d6, 0xade8, 0x000f, 0x6800, + 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808, 0xa084, + 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x3007, 0x00de, 0x6837, + 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6, 0x080c, + 0x3ee1, 0x1118, 0x00ce, 0x0804, 0x3007, 0x080c, 0xa133, 0x2009, + 0x0003, 0x00ce, 0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x43c9, + 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, 0x3004, + 0x0804, 0x2fdf, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004, + 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804, 0x3004, + 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c, 0x501b, + 0x1904, 0x3007, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x3004, 0x00c6, + 0x080c, 0x3ebc, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, + 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x2001, 0x0100, 0x8007, + 0x680a, 0x080c, 0x9eb1, 0x1120, 0x2009, 0x0003, 0x0804, 0x3004, + 0x7007, 0x0003, 0x701b, 0x4415, 0x0005, 0x6808, 0x8007, 0xa086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3004, 0x68b0, 0x6836, + 0x6810, 0x8007, 0xa084, 0x00ff, 0x800c, 0x6814, 0x8007, 0xa084, + 0x00ff, 0x8004, 0xa080, 0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, + 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x080c, 0x3ebc, 0x1120, + 0x2009, 0x0002, 0x0804, 0x3004, 0x7924, 0xa194, 0xff00, 0xa18c, + 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, 0x3007, 0x2009, 0x001a, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x4451, + 0x0005, 0x2001, 0xb62a, 0x2003, 0x0001, 0xad80, 0x000d, 0x2098, + 0x20a9, 0x001a, 0x20a1, 0xb8c7, 0x53a3, 0x0804, 0x2fdf, 0x080c, + 0x3ebc, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x7924, 0xa194, + 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, 0x3007, + 0x2099, 0xb8c7, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009, 0x001a, + 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x7824, 0xa08a, + 0x1000, 0x1a04, 0x3007, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, + 0x810b, 0xa108, 0x00c6, 0x2061, 0xb8f4, 0x6142, 0x00ce, 0x012e, + 0x0804, 0x2fdf, 0x00c6, 0x080c, 0x5b41, 0x1188, 0x2001, 0xb89f, + 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, + 0x080c, 0x5b85, 0x080c, 0x5a79, 0x080c, 0x151a, 0x0038, 0x2061, + 0xb600, 0x6030, 0xc09d, 0x6032, 0x080c, 0x4b7b, 0x00ce, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0xb8f4, 0x7924, 0x6152, + 0x614e, 0x6057, 0x0000, 0x604b, 0x0009, 0x7838, 0x606a, 0x783c, + 0x6066, 0x7828, 0x6062, 0x782c, 0x605e, 0x2061, 0xb8a1, 0x2001, + 0xb909, 0x600e, 0x6013, 0x0001, 0x6017, 0x0002, 0x6007, 0x0000, + 0x6037, 0x0000, 0x00ce, 0x012e, 0x0804, 0x2fdf, 0x0126, 0x00c6, + 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x6044, 0xd0a4, 0x11b0, + 0xd084, 0x0118, 0x080c, 0x464d, 0x0068, 0xd08c, 0x0118, 0x080c, + 0x456e, 0x0040, 0xd094, 0x0118, 0x080c, 0x453f, 0x0018, 0xd09c, + 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, 0x0005, 0x0016, 0x6128, + 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0ca0, 0x624c, 0xa286, + 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, 0x0130, 0x624a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x0490, 0xa294, 0xff00, 0xa296, 0xf700, + 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240, 0xa295, 0x0100, 0x6242, + 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x00f0, + 0x6040, 0xa084, 0x0010, 0xa085, 0x0140, 0x6042, 0x6043, 0x0000, + 0x707b, 0x0000, 0x7097, 0x0001, 0x70bb, 0x0000, 0x70d7, 0x0000, + 0x2009, 0xbdc0, 0x200b, 0x0000, 0x708b, 0x0000, 0x707f, 0x000a, + 0x2009, 0x000a, 0x2011, 0x4b1c, 0x080c, 0x6a94, 0x0005, 0x0156, + 0x2001, 0xb674, 0x2004, 0xd08c, 0x0110, 0x7053, 0xffff, 0x707c, + 0xa005, 0x1510, 0x2011, 0x4b1c, 0x080c, 0x6a0e, 0x6040, 0xa094, + 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, + 0x1168, 0x1f04, 0x4556, 0x6242, 0x708f, 0x0000, 0x6040, 0xa094, + 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, 0x6242, 0x708f, + 0x0000, 0x7083, 0x0000, 0x0000, 0x015e, 0x0005, 0x7080, 0xa08a, + 0x0003, 0x1210, 0x0023, 0x0010, 0x080c, 0x151a, 0x0005, 0x457a, + 0x45ca, 0x464c, 0x00f6, 0x7083, 0x0001, 0x20e1, 0xa000, 0xe000, + 0x20e1, 0x8700, 0x080c, 0x24a5, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x2079, 0xbc00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, + 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, + 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, + 0x782f, 0x0000, 0x2079, 0xbc0c, 0x207b, 0x1101, 0x7807, 0x0000, + 0x2099, 0xb605, 0x20a1, 0xbc0e, 0x20a9, 0x0004, 0x53a3, 0x2079, + 0xbc12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xbc00, 0x20a1, + 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, + 0x080c, 0x4b55, 0x00fe, 0x7087, 0x0000, 0x6043, 0x0008, 0x6043, + 0x0000, 0x0005, 0x00d6, 0x7084, 0x7087, 0x0000, 0xa025, 0x0904, + 0x4634, 0x6020, 0xd0b4, 0x1904, 0x4632, 0x7194, 0x81ff, 0x0904, + 0x4622, 0xa486, 0x000c, 0x1904, 0x462d, 0xa480, 0x0018, 0x8004, + 0x20a8, 0x2011, 0xbc80, 0x2019, 0xbc00, 0x220c, 0x2304, 0xa106, + 0x11b8, 0x8210, 0x8318, 0x1f04, 0x45e5, 0x6043, 0x0004, 0x608b, + 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7083, 0x0002, 0x708f, + 0x0002, 0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a94, 0x0490, + 0x2069, 0xbc80, 0x6930, 0xa18e, 0x1101, 0x1538, 0x6834, 0xa005, + 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, 0x6804, 0xa005, 0x0190, + 0x2011, 0xbc8e, 0x2019, 0xb605, 0x20a9, 0x0004, 0x220c, 0x2304, + 0xa102, 0x0230, 0x1190, 0x8210, 0x8318, 0x1f04, 0x4616, 0x0068, + 0x7097, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80, + 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043, + 0x0000, 0x0010, 0x00de, 0x0005, 0x6040, 0xa085, 0x0100, 0x6042, + 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, 0xb8eb, 0x2013, + 0x0000, 0x7087, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x080c, 0x7dea, 0x0c30, 0x0005, 0x708c, 0xa08a, 0x001d, + 0x1210, 0x0023, 0x0010, 0x080c, 0x151a, 0x0005, 0x4680, 0x468f, + 0x46b7, 0x46d0, 0x46f4, 0x471c, 0x4740, 0x4771, 0x4795, 0x47bd, + 0x47f4, 0x481c, 0x4838, 0x484e, 0x486e, 0x4881, 0x4889, 0x48b9, + 0x48dd, 0x4905, 0x4929, 0x495a, 0x4997, 0x49c6, 0x49e2, 0x4a21, + 0x4a41, 0x4a5a, 0x4a5b, 0x00c6, 0x2061, 0xb600, 0x6003, 0x0007, + 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, 0x00ce, 0x0005, + 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, 0x708f, 0x0001, + 0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a94, 0x0005, 0x00f6, + 0x7084, 0xa086, 0x0014, 0x1508, 0x6043, 0x0000, 0x6020, 0xd0b4, + 0x11e0, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1102, 0x11a0, 0x7834, + 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, + 0x70bb, 0x0001, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x708f, 0x0010, + 0x080c, 0x4889, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, + 0x0003, 0x6043, 0x0004, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x080c, + 0x4bf9, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3, + 0x0000, 0x1f04, 0x46c7, 0x60c3, 0x0014, 0x080c, 0x4b55, 0x0005, + 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c, 0x6a0e, + 0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1102, + 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, + 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0004, 0x0029, 0x0010, + 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0005, 0x080c, 0x4bf9, + 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xbc8e, 0x080c, + 0x4c4a, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150, 0xa186, 0xffff, + 0x0128, 0x080c, 0x4ae7, 0x0110, 0x080c, 0x4c28, 0x20a9, 0x0008, + 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0014, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, + 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079, + 0xbc80, 0x7a30, 0xa296, 0x1103, 0x1178, 0x7834, 0xa005, 0x1160, + 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, + 0x708f, 0x0006, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, + 0x708f, 0x0007, 0x080c, 0x4bf9, 0x20a3, 0x1104, 0x20a3, 0x0000, + 0x3430, 0x2011, 0xbc8e, 0x080c, 0x4c4a, 0x11a8, 0x7078, 0xa005, + 0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180, 0x2df9, 0x200d, + 0xa18c, 0xff00, 0x810f, 0x080c, 0x4ae7, 0x0128, 0x080c, 0x411d, + 0x0110, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4b55, + 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c, + 0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296, + 0x1104, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, + 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0008, 0x0029, + 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0009, 0x080c, + 0x4bf9, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x080c, 0x4c4a, + 0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a5c, 0x1170, 0xa085, + 0x0001, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2099, 0xbc8e, 0x26a0, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, + 0x4b55, 0x0010, 0x080c, 0x4673, 0x0005, 0x00f6, 0x7084, 0xa005, + 0x0588, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x1540, + 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1105, 0x1510, 0x7834, 0x2011, + 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, + 0x1110, 0x70bb, 0x0001, 0x708f, 0x000a, 0x00b1, 0x0098, 0xa005, + 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, + 0x0001, 0x708b, 0x0000, 0x708f, 0x000e, 0x080c, 0x486e, 0x0010, + 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x000b, 0x2011, 0xbc0e, + 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, + 0x2009, 0x0000, 0x41a4, 0x080c, 0x4bf9, 0x20a3, 0x1106, 0x20a3, + 0x0000, 0x080c, 0x4c4a, 0x0118, 0x2013, 0x0000, 0x0020, 0x7054, + 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3, + 0x0084, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01b0, + 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084, 0x1168, 0x2079, + 0xbc80, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, + 0x708f, 0x000c, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, + 0x708f, 0x000d, 0x080c, 0x4bf9, 0x20a3, 0x1107, 0x20a3, 0x0000, + 0x2099, 0xbc8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0084, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, + 0xa005, 0x01d0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084, + 0x1188, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, + 0xa005, 0x1140, 0x708b, 0x0001, 0x080c, 0x4beb, 0x708f, 0x000e, + 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x000f, + 0x7087, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, + 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a02, + 0x0005, 0x7084, 0xa005, 0x0120, 0x2011, 0x4b23, 0x080c, 0x6a0e, + 0x0005, 0x708f, 0x0011, 0x080c, 0x4c4a, 0x11a0, 0x7170, 0x81ff, + 0x0188, 0x2009, 0x0000, 0x7074, 0xa084, 0x00ff, 0x080c, 0x2852, + 0xa186, 0x007e, 0x0138, 0xa186, 0x0080, 0x0120, 0x2011, 0xbc8e, + 0x080c, 0x4ae7, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80, + 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, + 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4b55, + 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c, + 0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296, + 0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, + 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0012, 0x0029, + 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0013, 0x080c, + 0x4c05, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xbc8e, + 0x080c, 0x4c4a, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150, 0xa186, + 0xffff, 0x0128, 0x080c, 0x4ae7, 0x0110, 0x080c, 0x4c28, 0x20a9, + 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, + 0x01f0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x11a8, + 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, + 0x0001, 0x708f, 0x0014, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, + 0x0005, 0x708f, 0x0015, 0x080c, 0x4c05, 0x20a3, 0x1104, 0x20a3, + 0x0000, 0x3430, 0x2011, 0xbc8e, 0x080c, 0x4c4a, 0x11a8, 0x7078, + 0xa005, 0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180, 0x2df9, + 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4ae7, 0x0128, 0x080c, + 0x411d, 0x0110, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2298, 0x26a0, + 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, + 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x05b8, 0x2011, 0x4b23, + 0x080c, 0x6a0e, 0xa086, 0x0014, 0x1570, 0x2079, 0xbc80, 0x7a30, + 0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148, + 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, + 0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, + 0x1110, 0x70bb, 0x0001, 0x708b, 0x0000, 0x7a38, 0xd2f4, 0x0138, + 0x2001, 0xb674, 0x2004, 0xd0a4, 0x1110, 0x70d7, 0x0008, 0x708f, + 0x0016, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80, 0x20a1, 0x020b, 0x20a9, + 0x000e, 0x53a6, 0x3430, 0x2011, 0xbc8e, 0x708f, 0x0017, 0x080c, + 0x4c4a, 0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a5c, 0x1170, + 0xa085, 0x0001, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2099, 0xbc8e, + 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, + 0x080c, 0x4b55, 0x0010, 0x080c, 0x4673, 0x0005, 0x00f6, 0x7084, + 0xa005, 0x01b0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084, + 0x1168, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, + 0xa005, 0x1120, 0x708f, 0x0018, 0x0029, 0x0010, 0x080c, 0x4b7b, + 0x00fe, 0x0005, 0x708f, 0x0019, 0x080c, 0x4c05, 0x20a3, 0x1106, + 0x20a3, 0x0000, 0x3430, 0x2099, 0xbc8e, 0x2039, 0xbc0e, 0x27a0, + 0x20a9, 0x0040, 0x53a3, 0x080c, 0x4c4a, 0x11e8, 0x2728, 0x2514, + 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, + 0xa205, 0x202a, 0x7054, 0x2310, 0x8214, 0xa2a0, 0xbc0e, 0x2414, + 0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff, + 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4b55, + 0x0005, 0x00f6, 0x7084, 0xa005, 0x01d0, 0x2011, 0x4b23, 0x080c, + 0x6a0e, 0xa086, 0x0084, 0x1188, 0x2079, 0xbc80, 0x7a30, 0xa296, + 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x708b, 0x0001, 0x080c, + 0x4beb, 0x708f, 0x001a, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, + 0x0005, 0x708f, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, + 0xbc80, 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080, 0x0007, + 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c, + 0x4b55, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xb653, + 0x252c, 0x20a9, 0x0008, 0x2041, 0xbc0e, 0x28a0, 0x2099, 0xbc8e, + 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011, + 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4, + 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4a71, 0x0804, 0x4adf, + 0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020, + 0xa1a6, 0x3fff, 0x0904, 0x4adf, 0xa18d, 0xc000, 0x20a9, 0x0010, + 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, + 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, + 0x0008, 0x8318, 0x1f04, 0x4a97, 0x04d0, 0x23a8, 0x2021, 0x0001, + 0x8426, 0x8425, 0x1f04, 0x4aa9, 0x2328, 0x8529, 0xa2be, 0x0007, + 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8, + 0xa5a8, 0x0010, 0x1f04, 0x4ab8, 0x7552, 0xa5c8, 0x2df9, 0x292d, + 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, + 0x287c, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405, + 0x201a, 0x707b, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006, + 0x0018, 0xa006, 0x080c, 0x151a, 0x009e, 0x008e, 0x0005, 0x2118, + 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420, + 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421, + 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, + 0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x7152, 0xa1a0, + 0x2df9, 0x242d, 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536, 0x0016, + 0x2508, 0x080c, 0x287c, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x707b, + 0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb600, 0x707f, + 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, + 0x0140, 0x080c, 0x4c61, 0x080c, 0x7df3, 0x7004, 0xa084, 0x4000, + 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, + 0x2071, 0xb623, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, + 0x00f7, 0x080c, 0x4c11, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, + 0x7842, 0x7a42, 0x2009, 0x1388, 0x2011, 0x5a14, 0x080c, 0x6a94, + 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, + 0x2011, 0xb8eb, 0x2013, 0x0000, 0x7087, 0x0000, 0x012e, 0x20e1, + 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x7dea, 0x6144, + 0xd184, 0x0120, 0x718c, 0xa18d, 0x2000, 0x0018, 0x7180, 0xa18d, + 0x1000, 0x2011, 0xb8bf, 0x2112, 0x2009, 0x07d0, 0x2011, 0x4b23, + 0x080c, 0x6a94, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, + 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b, + 0x003e, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x2061, 0xb8f4, 0x601b, + 0x0000, 0x601f, 0x0000, 0x2061, 0xb600, 0x6003, 0x0001, 0x2061, + 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0xb8bf, 0x200b, + 0x0000, 0x2009, 0x002d, 0x2011, 0x4bb4, 0x080c, 0x6a02, 0x012e, + 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, + 0x8000, 0x080c, 0x4c61, 0x2071, 0x0100, 0x080c, 0x7df3, 0x2071, + 0x0140, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, + 0x0000, 0x080c, 0x5b49, 0x01a8, 0x080c, 0x5b67, 0x1190, 0x2001, + 0xb89e, 0x2003, 0xaaaa, 0x0016, 0x080c, 0x2920, 0x2001, 0xb88f, + 0x2102, 0x001e, 0x2001, 0xb89f, 0x2003, 0x0000, 0x080c, 0x5a79, + 0x0030, 0x2001, 0x0001, 0x080c, 0x27f8, 0x080c, 0x4b7b, 0x012e, + 0x000e, 0x00ee, 0x0005, 0x20a9, 0x0040, 0x20a1, 0xbdc0, 0x2099, + 0xbc8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4bf1, + 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc00, 0x20a1, + 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x2099, 0xbc80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, + 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0xb631, + 0x2004, 0xa005, 0x1138, 0x2001, 0xb615, 0x2004, 0xa084, 0x00ff, + 0xa105, 0x0010, 0xa185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, + 0x0016, 0x0046, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0158, 0xa006, + 0x2020, 0x2009, 0x002a, 0x080c, 0xb1a4, 0x2001, 0xb60c, 0x200c, + 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x080c, 0x2ca4, + 0x004e, 0x001e, 0x0005, 0x080c, 0x4b7b, 0x708f, 0x0000, 0x7087, + 0x0000, 0x0005, 0x0006, 0x2001, 0xb60c, 0x2004, 0xd09c, 0x0100, + 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, + 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, + 0x0005, 0x2001, 0xb60d, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, + 0x2011, 0x8017, 0x2001, 0xb8bf, 0x201c, 0x080c, 0x3f13, 0x003e, + 0x002e, 0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009, 0xb735, 0xa006, + 0x200a, 0x8108, 0x1f04, 0x4c78, 0x015e, 0x0005, 0x00d6, 0x0036, + 0x0156, 0x0136, 0x0146, 0x2069, 0xb652, 0xa006, 0x6002, 0x6007, + 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2df9, 0x231d, 0xa39c, + 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, + 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, + 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, + 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, + 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x00d6, + 0x60a4, 0xa06d, 0x0110, 0x080c, 0x1614, 0x60a7, 0x0000, 0x60a8, + 0xa06d, 0x0110, 0x080c, 0x1614, 0x60ab, 0x0000, 0x00de, 0xa006, + 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084, 0x00ff, + 0x6042, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, + 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, + 0x1a04, 0x4d8c, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04, + 0x4d91, 0x2001, 0xb60c, 0x2004, 0xa084, 0x0003, 0x01c0, 0x2001, + 0xb60c, 0x2004, 0xd084, 0x1904, 0x4d74, 0xa188, 0xb735, 0x2104, + 0xa065, 0x0904, 0x4d74, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, + 0x1904, 0x4d74, 0x6000, 0xd0c4, 0x0904, 0x4d74, 0x0068, 0xa188, + 0xb735, 0x2104, 0xa065, 0x0904, 0x4d59, 0x6004, 0xa084, 0x00ff, + 0xa08e, 0x0006, 0x1904, 0x4d5e, 0x60a4, 0xa00d, 0x0118, 0x080c, + 0x5246, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, 0x5291, 0x1170, + 0x694c, 0xd1fc, 0x1118, 0x080c, 0x4f50, 0x0448, 0x080c, 0x4eff, + 0x694c, 0xd1ec, 0x1520, 0x080c, 0x5138, 0x0408, 0x694c, 0xa184, + 0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, 0x080c, 0x5147, + 0x0028, 0x080c, 0x5147, 0x0028, 0xd1fc, 0x0118, 0x080c, 0x4eff, + 0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, 0x6803, 0x0000, + 0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x080c, + 0x6d1c, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005, 0x2009, 0x0000, + 0x04e0, 0x2001, 0x0028, 0x2009, 0x0000, 0x04b8, 0xa082, 0x0006, + 0x1298, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, + 0x1140, 0x6100, 0xd1fc, 0x0128, 0x2001, 0x0029, 0x2009, 0x1000, + 0x0420, 0x2001, 0x0028, 0x00a8, 0x2009, 0xb60c, 0x210c, 0xd18c, + 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, + 0x0040, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, + 0x0060, 0x2009, 0x0000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, + 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, + 0x2008, 0xa182, 0x00ff, 0x1a04, 0x4deb, 0xa188, 0xb735, 0x2104, + 0xa065, 0x01c0, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, + 0x2c70, 0x080c, 0x864e, 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, + 0x600b, 0xffff, 0x601f, 0x000a, 0x2009, 0x0003, 0x080c, 0x86d3, + 0xa006, 0x0460, 0x2001, 0x0028, 0x0440, 0xa082, 0x0006, 0x1298, + 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, + 0x6100, 0xd1fc, 0x09e8, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, + 0x2001, 0x0028, 0x0090, 0x2009, 0xb60c, 0x210c, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, + 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, + 0x0005, 0x2001, 0x002c, 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2011, 0x0000, 0x2079, 0xb600, 0x6944, 0xa18c, 0xff00, + 0x810f, 0xa182, 0x00ff, 0x1a04, 0x4eb6, 0x080c, 0x501b, 0x11a0, + 0x6004, 0xa084, 0x00ff, 0xa082, 0x0006, 0x1270, 0x6864, 0xa0c6, + 0x006f, 0x0150, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1904, 0x4e9f, + 0x60a0, 0xd0bc, 0x1904, 0x4e9f, 0x6864, 0xa0c6, 0x006f, 0x0118, + 0x2008, 0x0804, 0x4e68, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f, + 0x78d4, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff, + 0x16b8, 0x6a70, 0x6b6c, 0x7870, 0xa306, 0x1160, 0x7874, 0xa24e, + 0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208, + 0x2310, 0x0430, 0x080c, 0x3e0c, 0x2c70, 0x0550, 0x2009, 0x0000, + 0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c, + 0x52bc, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e, + 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, + 0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0450, + 0x080c, 0x864e, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011, + 0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0xa0e3, 0x2d00, 0x6012, + 0x601f, 0x0001, 0x6838, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x0126, + 0x2091, 0x8000, 0x080c, 0x2cd1, 0x012e, 0x2001, 0x0000, 0x080c, + 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x2009, 0x0002, 0x080c, + 0x86d3, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005, 0x2001, + 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xb60c, 0x210c, 0xd18c, + 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, + 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001, 0x0029, + 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, + 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x12e0, + 0xa188, 0xb735, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084, 0x00ff, + 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c, 0x5147, + 0x0431, 0x0030, 0x0421, 0x684c, 0xd0fc, 0x0110, 0x080c, 0x5138, + 0x080c, 0x5185, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009, 0x0000, + 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20, 0x2001, + 0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, + 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005, 0x0126, + 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a, 0x6803, + 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, + 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005, 0x0170, + 0x00e6, 0x2071, 0xb8e1, 0x7004, 0xa086, 0x0002, 0x0168, 0x00ee, + 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, 0x6052, + 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80, 0x604c, + 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, + 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c, 0xa06d, + 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x0005, + 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a, 0x6086, + 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6, 0x0026, + 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110, 0xc285, + 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, 0x0126, + 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, + 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xb653, 0x2004, + 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x1110, + 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206, 0x0006, + 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c, 0x151a, + 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, + 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178, 0x609c, + 0xd0a4, 0x0160, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x1138, 0xa284, + 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0xa294, + 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026, + 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0xb735, + 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15e4, 0x2d60, + 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, + 0x0000, 0x080c, 0x4c7e, 0xa006, 0x002e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0480, + 0x00d6, 0xa190, 0xb735, 0x2204, 0xa06d, 0x0540, 0x2013, 0x0000, + 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x1614, + 0x60a8, 0xa06d, 0x0110, 0x080c, 0x1614, 0x00ce, 0x00de, 0x00d6, + 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6010, + 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0x1624, 0x080c, 0x86a4, + 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x1614, 0x00de, 0xa006, + 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085, + 0x0001, 0x0030, 0xa188, 0xb735, 0x2104, 0xa065, 0x0dc0, 0xa006, + 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000, + 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x5b41, 0x1558, + 0x60a0, 0xa086, 0x007e, 0x2069, 0xbc90, 0x0130, 0x2001, 0xb635, + 0x2004, 0xd0ac, 0x1500, 0x0098, 0x2d04, 0xd0e4, 0x01e0, 0x00d6, + 0x2069, 0xbc8e, 0x00c6, 0x2061, 0xb8b2, 0x6810, 0x2062, 0x6814, + 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69, + 0x2d04, 0x2069, 0x0140, 0xa005, 0x1110, 0x2001, 0x0001, 0x6886, + 0x2069, 0xb600, 0x68a6, 0x2069, 0xbc8e, 0x6808, 0x605e, 0x6810, + 0x6062, 0x6138, 0xa10a, 0x0208, 0x603a, 0x6814, 0x6066, 0x2099, + 0xbc96, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, + 0xbc9a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, + 0xbcae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, + 0x6076, 0x60a0, 0xa086, 0x007e, 0x1120, 0x2069, 0xbc8e, 0x690c, + 0x616e, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, + 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, + 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, + 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, + 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x6192, + 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, + 0x2071, 0xbc8d, 0x2e04, 0x6896, 0x2071, 0xbc8e, 0x7004, 0x689a, + 0x701c, 0x689e, 0x6a00, 0x2009, 0xb672, 0x210c, 0xd0bc, 0x0120, + 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, + 0x0110, 0xc2bd, 0x0008, 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, + 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, + 0x6900, 0x81ff, 0x1540, 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, + 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, + 0x1f04, 0x50f3, 0x080c, 0x151a, 0x260a, 0x8210, 0x6a06, 0x0098, + 0x080c, 0x15fd, 0x01a8, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, + 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x510b, + 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, + 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, + 0x01a0, 0x2168, 0x6800, 0xa005, 0x1160, 0x080c, 0x5246, 0x1168, + 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, + 0x0020, 0x080c, 0x1614, 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x080c, 0x52a4, 0x0010, 0x080c, 0x4eff, + 0x080c, 0x51be, 0x1dd8, 0x080c, 0x5185, 0x012e, 0x0005, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, + 0x1540, 0x6a54, 0xa282, 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, + 0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x5159, + 0x080c, 0x151a, 0x260a, 0x8210, 0x6a56, 0x0098, 0x080c, 0x15fd, + 0x01d0, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, + 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x5171, 0x6857, 0x0001, + 0x6e62, 0x0010, 0x080c, 0x4f50, 0x0089, 0x1de0, 0xa085, 0x0001, + 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6d1c, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, + 0xa00e, 0x0126, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, + 0x1170, 0x8dff, 0x01f8, 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, + 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, + 0x6800, 0x2068, 0x0c70, 0x080c, 0x81a5, 0x6a00, 0x604c, 0xad06, + 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, + 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, + 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120, 0x6848, + 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, + 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080, 0xad06, + 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, + 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x5240, 0x1110, 0x2011, + 0x0001, 0x080c, 0x528b, 0x1110, 0xa295, 0x0002, 0x0005, 0x080c, + 0x52bc, 0x0118, 0x080c, 0x9dcb, 0x0010, 0xa085, 0x0001, 0x0005, + 0x080c, 0x52bc, 0x0118, 0x080c, 0x9d5b, 0x0010, 0xa085, 0x0001, + 0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9dae, 0x0010, 0xa085, + 0x0001, 0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9d77, 0x0010, + 0xa085, 0x0001, 0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9de7, + 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006, 0x00d6, 0x2091, + 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800, 0x0006, 0x6837, 0x0103, + 0x6b4a, 0x6847, 0x0000, 0x080c, 0x9f88, 0x0006, 0x6000, 0xd0fc, + 0x0110, 0x080c, 0xb445, 0x000e, 0x080c, 0x547a, 0x000e, 0x0c50, + 0x6083, 0x0000, 0x6087, 0x0000, 0x00de, 0x000e, 0x012e, 0x0005, + 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, + 0x7000, 0xa005, 0x1168, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, + 0xa606, 0x0130, 0x8108, 0x1f04, 0x524f, 0xa085, 0x0001, 0x0008, + 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, + 0xa06d, 0x1128, 0x080c, 0x15fd, 0x01a0, 0x2d00, 0x60a6, 0x6803, + 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, + 0xffff, 0x8108, 0x1f04, 0x526f, 0xa085, 0x0001, 0x012e, 0x00de, + 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, + 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x1614, 0xa085, 0x0001, + 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085, 0x0001, + 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, 0x20a9, 0x0010, + 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x529a, + 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0c19, + 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854, 0xa08a, + 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, 0x1614, 0x60ab, + 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005, 0x00f6, + 0x080c, 0x5b41, 0x01b0, 0x71b8, 0x81ff, 0x1198, 0x71d4, 0xd19c, + 0x0180, 0x2001, 0x007e, 0xa080, 0xb735, 0x2004, 0xa07d, 0x0148, + 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118, 0x7800, 0xc0ed, + 0x7802, 0x2079, 0xb652, 0x7804, 0xd0a4, 0x01e8, 0x0156, 0x00c6, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1168, + 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086, + 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04, + 0x52e4, 0x00ce, 0x015e, 0x080c, 0x537b, 0x0120, 0x2001, 0xb8b5, + 0x200c, 0x0038, 0x2079, 0xb652, 0x7804, 0xd0a4, 0x0130, 0x2009, + 0x07d0, 0x2011, 0x530f, 0x080c, 0x6a94, 0x00fe, 0x0005, 0x2011, + 0x530f, 0x080c, 0x6a0e, 0x080c, 0x537b, 0x01f0, 0x2001, 0xb7b3, + 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xb653, + 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, 0x530f, 0x080c, + 0x6a94, 0x00e6, 0x2071, 0xb600, 0x7073, 0x0000, 0x7077, 0x0000, + 0x080c, 0x2aed, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, + 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1530, 0x6000, 0xd0ec, + 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, + 0x0029, 0x080c, 0xb1a4, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, + 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x080c, + 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2009, 0x0000, + 0x080c, 0xaf3e, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x533a, + 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060, 0x6000, 0xc0ec, + 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac, 0x0005, 0x7818, + 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xb7b3, 0x2004, 0xa07d, + 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126, 0x0026, 0x2091, + 0x8000, 0x0006, 0x62a0, 0xa290, 0xb735, 0x2204, 0xac06, 0x190c, + 0x151a, 0x000e, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, + 0x6202, 0x002e, 0x012e, 0x0005, 0x2011, 0xb635, 0x2204, 0xd0cc, + 0x0138, 0x2001, 0xb8b3, 0x200c, 0x2011, 0x53a9, 0x080c, 0x6a94, + 0x0005, 0x2011, 0x53a9, 0x080c, 0x6a0e, 0x2011, 0xb635, 0x2204, + 0xc0cc, 0x2012, 0x0005, 0x2071, 0xb714, 0x7003, 0x0001, 0x7007, + 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, + 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, + 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xb87d, 0x7003, + 0xb714, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xb85d, 0x7013, + 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005, 0x0016, 0x00e6, + 0x2071, 0xb835, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, + 0xb653, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xb653, 0x2004, 0xa00e, + 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x5444, 0x2001, 0xb672, + 0x200c, 0xa184, 0x000f, 0x2009, 0xb673, 0x210c, 0x0002, 0x53ec, + 0x541f, 0x5426, 0x5430, 0x5435, 0x53ec, 0x53ec, 0x53ec, 0x540f, + 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x7003, + 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xb676, 0x20a1, 0xb886, + 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x0428, 0x708f, + 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030, 0x708f, 0x0002, + 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, 0x0001, 0x0088, + 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007, 0x0121, 0x2001, + 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, + 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005, 0x00e6, + 0x2071, 0xb714, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, + 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, + 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, + 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006, + 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, + 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, + 0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, + 0x54d3, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0xb600, 0xa016, + 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, + 0x702e, 0x70b4, 0xa200, 0x70b6, 0x00de, 0x2071, 0xb714, 0x701c, + 0xa005, 0x1904, 0x54e3, 0x20a9, 0x0032, 0x0f04, 0x54e1, 0x0e04, + 0x549d, 0x2071, 0xb835, 0x7200, 0x82ff, 0x05d8, 0x6934, 0xa186, + 0x0103, 0x1904, 0x54f1, 0x6948, 0x6844, 0xa105, 0x1540, 0x2009, + 0x8020, 0x2200, 0x0002, 0x54e1, 0x54b8, 0x5509, 0x5515, 0x54e1, + 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x54e1, 0x7018, 0xd084, + 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, + 0x2091, 0x4080, 0x2071, 0xb600, 0x702c, 0x206a, 0x2d00, 0x702e, + 0x70b4, 0x8000, 0x70b6, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844, + 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, + 0x0880, 0x2071, 0xb714, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, + 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, + 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, + 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850, + 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804, + 0x54b1, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90, + 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092, + 0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, + 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x54ca, + 0x718c, 0x7084, 0xa10a, 0x0a04, 0x54ca, 0x2071, 0x0000, 0x7018, + 0xd084, 0x1904, 0x54ca, 0x2071, 0xb835, 0x7000, 0xa086, 0x0002, + 0x1150, 0x080c, 0x5794, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, + 0x4080, 0x0804, 0x54ca, 0x080c, 0x57be, 0x2071, 0x0000, 0x701b, + 0x0001, 0x2091, 0x4080, 0x0804, 0x54ca, 0x0006, 0x684c, 0x0006, + 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, + 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a, + 0x6952, 0x0005, 0x2071, 0xb714, 0x7004, 0x0002, 0x5570, 0x5581, + 0x577f, 0x5780, 0x578d, 0x5793, 0x5571, 0x5770, 0x5706, 0x575c, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5580, 0x2009, 0x000d, + 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x700b, 0x0000, + 0x012e, 0x2069, 0xb8f4, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126, + 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xb720, 0x2004, + 0xa10a, 0x0170, 0x0e04, 0x55a4, 0x2069, 0x0000, 0x6818, 0xd084, + 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, + 0x2069, 0xb8f4, 0x683f, 0xffff, 0x012e, 0x2069, 0xb600, 0x6848, + 0x6968, 0xa102, 0x2069, 0xb835, 0x688a, 0x6984, 0x701c, 0xa06d, + 0x0120, 0x81ff, 0x0904, 0x55fa, 0x00a0, 0x81ff, 0x0904, 0x56c0, + 0x2071, 0xb835, 0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071, + 0xb8f4, 0x7038, 0xa005, 0x0128, 0x1b04, 0x56c0, 0x713a, 0x0804, + 0x56c0, 0x2071, 0xb835, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084, + 0xa10a, 0x0a04, 0x56db, 0x0e04, 0x567c, 0x2071, 0x0000, 0x7018, + 0xd084, 0x1904, 0x567c, 0x2001, 0xffff, 0x2071, 0xb8f4, 0x703a, + 0x2071, 0xb835, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x5794, + 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x567c, + 0x080c, 0x57be, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, + 0x0804, 0x567c, 0x2071, 0xb835, 0x7000, 0xa005, 0x0904, 0x56a2, + 0x6934, 0xa186, 0x0103, 0x1904, 0x567f, 0x684c, 0xd0bc, 0x1904, + 0x56a2, 0x6948, 0x6844, 0xa105, 0x1904, 0x5697, 0x2009, 0x8020, + 0x2071, 0xb835, 0x7000, 0x0002, 0x56a2, 0x5662, 0x563a, 0x564c, + 0x5619, 0x0136, 0x0146, 0x0156, 0x2099, 0xb676, 0x20a1, 0xb886, + 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x2071, 0xb87d, + 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, + 0x0000, 0x2e10, 0x080c, 0x1648, 0x2071, 0xb714, 0x7007, 0x0009, + 0x0804, 0x56c0, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x56c0, + 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xb714, + 0x080c, 0x5815, 0x0804, 0x56c0, 0x7084, 0x8008, 0xa092, 0x000f, + 0x1a04, 0x56c0, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, + 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xb714, 0x080c, 0x5815, + 0x0804, 0x56c0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x567c, 0x2071, + 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840, + 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0xb714, + 0x080c, 0x5815, 0x0804, 0x56c0, 0x012e, 0x0804, 0x56c0, 0xa18c, + 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, + 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850, 0xa084, 0x00ff, + 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804, 0x5610, 0x6844, + 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120, 0x2009, 0x8020, + 0x0804, 0x5610, 0x2071, 0xb714, 0x080c, 0x5827, 0x01c8, 0x2071, + 0xb714, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, + 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007, + 0x0003, 0x080c, 0x5840, 0x7050, 0xa086, 0x0100, 0x0904, 0x5780, + 0x0126, 0x2091, 0x8000, 0x2071, 0xb714, 0x7008, 0xa086, 0x0001, + 0x1180, 0x0e04, 0x56d9, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, + 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006, 0x1110, 0x7007, + 0x0001, 0x012e, 0x0005, 0x2071, 0xb714, 0x080c, 0x5827, 0x0518, + 0x2071, 0xb835, 0x7084, 0x700a, 0x20a9, 0x0020, 0x2099, 0xb836, + 0x20a1, 0xb85d, 0x53a3, 0x7087, 0x0000, 0x2071, 0xb714, 0x2069, + 0xb87d, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, + 0x6832, 0x2d10, 0x080c, 0x1648, 0x7007, 0x0008, 0x2001, 0xffff, + 0x2071, 0xb8f4, 0x703a, 0x012e, 0x0804, 0x56c0, 0x2069, 0xb87d, + 0x6808, 0xa08e, 0x0000, 0x0904, 0x575b, 0xa08e, 0x0200, 0x0904, + 0x5759, 0xa08e, 0x0100, 0x1904, 0x575b, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x5757, 0x2069, 0x0000, 0x6818, 0xd084, 0x15c0, 0x702c, + 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, + 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, + 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001, + 0xb85a, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, 0xb835, 0x689c, + 0x699e, 0x2069, 0xb8f4, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368, + 0x2001, 0xb85b, 0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040, + 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, + 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xb87f, 0x2004, 0xa08e, + 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x5815, 0x0005, 0xa08e, + 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007, 0x0005, 0x0005, + 0x701c, 0xa06d, 0x0158, 0x080c, 0x5827, 0x0140, 0x7007, 0x0003, + 0x080c, 0x5840, 0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005, + 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086, + 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c, 0x57e3, 0x7006, + 0x080c, 0x5815, 0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0xb835, + 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, + 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04, 0x57b8, 0x2014, + 0x722a, 0x8000, 0x0f04, 0x57b8, 0x2014, 0x722e, 0x8000, 0x0f04, + 0x57b8, 0x2014, 0x723a, 0x8000, 0x0f04, 0x57b8, 0x2014, 0x723e, + 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156, + 0x2071, 0xb835, 0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80, + 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, + 0x722a, 0x8000, 0x0f04, 0x57da, 0x2014, 0x723a, 0x8000, 0x2014, + 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001, 0x8042, 0x7022, + 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, + 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, + 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, + 0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091, 0x8000, 0x0e04, + 0x580f, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, + 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001, + 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, + 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, + 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1614, 0x0005, 0x2019, + 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, + 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, + 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, + 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, + 0x2091, 0x8000, 0x2009, 0xb913, 0x2104, 0xc08d, 0x200a, 0x012e, + 0x080c, 0x1664, 0x0005, 0x708c, 0xa08a, 0x0029, 0x1220, 0xa082, + 0x001d, 0x0033, 0x0010, 0x080c, 0x151a, 0x6027, 0x1e00, 0x0005, + 0x594e, 0x58c9, 0x58e1, 0x591e, 0x593f, 0x5979, 0x598b, 0x58e1, + 0x5965, 0x586d, 0x589b, 0x586c, 0x0005, 0x00d6, 0x2069, 0x0200, + 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028, + 0x2069, 0xb8c6, 0x2d04, 0x7002, 0x080c, 0x5c43, 0x6028, 0xa085, + 0x0600, 0x602a, 0x00b0, 0x708f, 0x0028, 0x2069, 0xb8c6, 0x2d04, + 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, + 0x0056, 0x2071, 0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e, 0x003e, + 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0xa005, + 0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028, 0x2069, 0xb8c6, + 0x2d04, 0x7002, 0x080c, 0x5cd0, 0x6028, 0xa085, 0x0600, 0x602a, + 0x00b0, 0x708f, 0x0028, 0x2069, 0xb8c6, 0x2d04, 0x7002, 0x6028, + 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, + 0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, + 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x59f6, + 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x708f, 0x0020, + 0x080c, 0x59f6, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f, + 0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x1590, 0xd1dc, 0x1568, + 0xd1e4, 0x1540, 0xa184, 0x1e00, 0x1580, 0x60e3, 0x0001, 0x600c, + 0xc0b4, 0x600e, 0x080c, 0x5b71, 0x080c, 0x24e5, 0x0156, 0x6803, + 0x0100, 0x20a9, 0x0014, 0x6804, 0xd0dc, 0x1118, 0x1f04, 0x58fb, + 0x0048, 0x20a9, 0x0014, 0x6803, 0x0080, 0x6804, 0xd0d4, 0x1130, + 0x1f04, 0x5905, 0x080c, 0x5b92, 0x015e, 0x0078, 0x015e, 0x708f, + 0x0028, 0x0058, 0x708f, 0x001e, 0x0040, 0x708f, 0x001d, 0x0028, + 0x708f, 0x0020, 0x0010, 0x708f, 0x001f, 0x0005, 0x60e3, 0x0001, + 0x600c, 0xc0b4, 0x600e, 0x080c, 0x5b71, 0x080c, 0x24e5, 0x6803, + 0x0080, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, + 0xa184, 0x1e00, 0x1158, 0x708f, 0x0028, 0x0040, 0x708f, 0x001e, + 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f, 0x0005, 0x6803, + 0x00a0, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1e63, + 0x708f, 0x001e, 0x0010, 0x708f, 0x001d, 0x0005, 0x080c, 0x5a68, + 0x6124, 0xd1dc, 0x1188, 0x080c, 0x59f6, 0x0016, 0x080c, 0x1e63, + 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x708f, 0x001e, 0x0020, + 0x708f, 0x001f, 0x080c, 0x59f6, 0x0005, 0x6803, 0x00a0, 0x6124, + 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, + 0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x0021, + 0x0005, 0x080c, 0x5a68, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, + 0xd1e4, 0x0140, 0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010, + 0x708f, 0x001f, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, + 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x708f, 0x001e, + 0x0040, 0x708f, 0x001d, 0x0028, 0x708f, 0x0020, 0x0010, 0x708f, + 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0xb600, 0x2091, 0x8000, 0x080c, + 0x5b41, 0x11e8, 0x2001, 0xb60c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, + 0x2102, 0x6027, 0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, + 0x6803, 0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, + 0x2003, 0x0001, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, + 0x5b5d, 0x0150, 0x080c, 0x5b53, 0x1138, 0x2001, 0x0001, 0x080c, + 0x27f8, 0x080c, 0x5b18, 0x00a0, 0x080c, 0x5a65, 0x0178, 0x2001, + 0x0001, 0x080c, 0x27f8, 0x708c, 0xa086, 0x001e, 0x0120, 0x708c, + 0xa086, 0x0022, 0x1118, 0x708f, 0x0025, 0x0010, 0x708f, 0x0021, + 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, + 0x5a07, 0x080c, 0x6ace, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, + 0x2011, 0x5a07, 0x080c, 0x6ac5, 0x002e, 0x001e, 0x0005, 0x00e6, + 0x00f6, 0x0016, 0x080c, 0x7df3, 0x2071, 0xb600, 0x080c, 0x59a2, + 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x080c, 0x7df3, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0xb600, 0x2091, 0x8000, 0x6028, 0xc09c, + 0x602a, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, + 0x8106, 0x080c, 0x7fe0, 0x080c, 0x6a82, 0x0036, 0x2019, 0x0000, + 0x080c, 0x806b, 0x003e, 0x60e3, 0x0000, 0x080c, 0xb4eb, 0x080c, + 0xb506, 0x2001, 0xb600, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c, + 0x12e2, 0x2001, 0x0001, 0x080c, 0x27f8, 0x012e, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x2001, 0xb600, + 0x2004, 0xa086, 0x0004, 0x0140, 0x2001, 0xb89e, 0x2003, 0xaaaa, + 0x2001, 0xb89f, 0x2003, 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, + 0x6800, 0xa086, 0x00c0, 0x0160, 0x6803, 0x00c0, 0x0156, 0x20a9, + 0x002d, 0x1d04, 0x5a71, 0x2091, 0x6000, 0x1f04, 0x5a71, 0x015e, + 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0xb600, 0x2001, 0xb89f, 0x200c, 0xa186, 0x0000, 0x0158, + 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003, + 0x0158, 0x0804, 0x5b06, 0x708f, 0x0022, 0x0040, 0x708f, 0x0021, + 0x0028, 0x708f, 0x0023, 0x0020, 0x708f, 0x0024, 0x6043, 0x0000, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28a7, + 0x0026, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, + 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b, + 0x003e, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028, + 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, + 0x0005, 0x6024, 0xd0ac, 0x0120, 0x012e, 0x015e, 0x0804, 0x5b14, + 0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130, + 0x6803, 0x0100, 0x1f04, 0x5ac9, 0x080c, 0x5b92, 0x012e, 0x015e, + 0x080c, 0x5b53, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, + 0xa085, 0x0020, 0x6052, 0x080c, 0x5b92, 0xa006, 0x8001, 0x1df0, + 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x5b92, + 0x0016, 0x0026, 0x2009, 0x00c8, 0x2011, 0x5a14, 0x080c, 0x6a94, + 0x002e, 0x001e, 0x2001, 0xb89f, 0x2003, 0x0004, 0x080c, 0x5853, + 0x080c, 0x5b53, 0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, + 0x2001, 0xb89f, 0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, + 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, + 0xb600, 0x2001, 0xb89e, 0x2003, 0x0000, 0x2001, 0xb88f, 0x2003, + 0x0000, 0x708f, 0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, + 0x0000, 0x080c, 0x28a7, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, + 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, + 0x0005, 0x0006, 0x2001, 0xb89e, 0x2004, 0xa086, 0xaaaa, 0x000e, + 0x0005, 0x0006, 0x2001, 0xb672, 0x2004, 0xa084, 0x0030, 0xa086, + 0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672, 0x2004, 0xa084, + 0x0030, 0xa086, 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672, + 0x2004, 0xa084, 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, + 0x2001, 0xb672, 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, + 0x0005, 0x2001, 0xb60c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x28c7, + 0x0036, 0x0016, 0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2ca4, + 0x001e, 0x003e, 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xb60c, + 0x2e04, 0x0118, 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, + 0x00ee, 0x0005, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, + 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, + 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, + 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28a7, + 0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, + 0x6052, 0x6050, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb600, + 0x6020, 0xa084, 0x0080, 0x0138, 0x2001, 0xb60c, 0x200c, 0xc1bd, + 0x2102, 0x0804, 0x5c3b, 0x2001, 0xb60c, 0x200c, 0xc1bc, 0x2102, + 0x6028, 0xa084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, + 0x20a9, 0x0384, 0x6024, 0xd0cc, 0x1508, 0x1d04, 0x5bea, 0x2091, + 0x6000, 0x1f04, 0x5bea, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, + 0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x2019, 0x0000, 0x080c, + 0x806b, 0x6803, 0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, + 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x0468, 0x86ff, 0x1120, + 0x080c, 0x1e63, 0x080c, 0x24e5, 0x60e3, 0x0000, 0x2001, 0xb88f, + 0x2004, 0x080c, 0x28a7, 0x60e2, 0x6803, 0x0080, 0x20a9, 0x0384, + 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0138, + 0x1d04, 0x5c20, 0x2091, 0x6000, 0x1f04, 0x5c20, 0x0820, 0x6028, + 0xa085, 0x1e00, 0x602a, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, + 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x2069, 0x0140, + 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005, 0x1904, 0x5c97, + 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, + 0x080c, 0x28a7, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808, + 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400, + 0x2069, 0xb8c6, 0x7000, 0x206a, 0x708f, 0x0026, 0x7003, 0x0001, + 0x20a9, 0x0002, 0x1d04, 0x5c7a, 0x2091, 0x6000, 0x1f04, 0x5c7a, + 0x0804, 0x5cc8, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, + 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0520, 0xa084, 0x1a00, + 0x1508, 0x1d04, 0x5c86, 0x2091, 0x6000, 0x1f04, 0x5c86, 0x2011, + 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, 0x8106, 0x080c, + 0x7fe0, 0x2019, 0x0000, 0x080c, 0x806b, 0x6803, 0x00a0, 0x2001, + 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, + 0x0001, 0x00b0, 0x080c, 0x24e5, 0x6803, 0x0080, 0x2069, 0x0140, + 0x60e3, 0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, + 0x6886, 0x2001, 0xb88f, 0x2004, 0x080c, 0x28a7, 0x60e2, 0xa006, + 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, + 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2071, 0xb600, 0x6020, 0xa084, 0x00c0, 0x01e0, 0x2011, + 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, 0x8106, 0x080c, + 0x7fe0, 0x2019, 0x0000, 0x080c, 0x806b, 0x2069, 0x0140, 0x6803, + 0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, + 0x0001, 0x0804, 0x5d6d, 0x2001, 0xb60c, 0x200c, 0xd1b4, 0x1160, + 0xc1b5, 0x2102, 0x080c, 0x59fc, 0x2069, 0x0140, 0x080c, 0x24e5, + 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0xa005, + 0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfdff, 0x602a, + 0x6027, 0x0200, 0x2069, 0xb8c6, 0x7000, 0x206a, 0x708f, 0x0027, + 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5d24, 0x2091, 0x6000, + 0x1f04, 0x5d24, 0x0804, 0x5d6d, 0x6027, 0x1e00, 0x2009, 0x1e00, + 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0, 0x1d04, + 0x5d2c, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x696b, + 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0xb8f4, + 0x7018, 0x00ee, 0xa005, 0x1d00, 0x0500, 0x0026, 0x2011, 0x5a14, + 0x080c, 0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x002e, 0x2069, + 0x0140, 0x60e3, 0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, + 0x0008, 0x6886, 0x2001, 0xb88f, 0x2004, 0x080c, 0x28a7, 0x60e2, + 0x2001, 0xb60c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, + 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, + 0x7130, 0xd184, 0x1180, 0x2011, 0xb653, 0x2214, 0xd2ec, 0x0138, + 0xc18d, 0x7132, 0x2011, 0xb653, 0x2214, 0xd2ac, 0x1120, 0x7030, + 0xd08c, 0x0904, 0x5dda, 0x7130, 0xc185, 0x7132, 0x2011, 0xb653, + 0x220c, 0xd1a4, 0x0530, 0x0016, 0x2019, 0x000e, 0x080c, 0xb121, + 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0xa186, 0x007e, 0x01a0, + 0xa186, 0x0080, 0x0188, 0x080c, 0x501b, 0x1170, 0x8127, 0xa006, + 0x0016, 0x2009, 0x000e, 0x080c, 0xb1a4, 0x2009, 0x0001, 0x2011, + 0x0100, 0x080c, 0x6b8c, 0x001e, 0x8108, 0x1f04, 0x5da5, 0x015e, + 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, + 0x080c, 0x2ca4, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, + 0x0000, 0x080c, 0x501b, 0x1110, 0x080c, 0x4c7e, 0x8108, 0x1f04, + 0x5dd1, 0x015e, 0x080c, 0x1e63, 0x2011, 0x0003, 0x080c, 0x80fc, + 0x2011, 0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, + 0x0000, 0x080c, 0x806b, 0x003e, 0x60e3, 0x0000, 0x2001, 0xb600, + 0x2003, 0x0001, 0x080c, 0x5a79, 0x00ee, 0x00ce, 0x004e, 0x003e, + 0x002e, 0x001e, 0x015e, 0x0005, 0x2071, 0xb6e2, 0x7003, 0x0000, + 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, + 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, + 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, + 0x2071, 0xb6e2, 0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, + 0xa085, 0x0001, 0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, + 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, + 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, + 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, + 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, + 0x00ee, 0x0005, 0x2b78, 0x2071, 0xb6e2, 0x7004, 0x0043, 0x700c, + 0x0002, 0x5e56, 0x5e4d, 0x5e4d, 0x5e4d, 0x5e4d, 0x0005, 0x5eac, + 0x5ead, 0x5edf, 0x5ee0, 0x5eaa, 0x5f2e, 0x5f33, 0x5f64, 0x5f65, + 0x5f80, 0x5f81, 0x5f82, 0x5f83, 0x5f84, 0x5f85, 0x603b, 0x6062, + 0x700c, 0x0002, 0x5e6f, 0x5eaa, 0x5eaa, 0x5eab, 0x5eab, 0x7830, + 0x7930, 0xa106, 0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, + 0xa10a, 0x01f8, 0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, + 0x080c, 0x15e4, 0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, + 0x0003, 0x7057, 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, + 0xb913, 0x2104, 0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, + 0x1664, 0x0005, 0x080c, 0x15e4, 0x0de0, 0x2d00, 0x705a, 0x080c, + 0x15e4, 0x1108, 0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, + 0x0004, 0x08f8, 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x5eb4, + 0x5eb7, 0x5ec5, 0x5ede, 0x5ede, 0x080c, 0x5e68, 0x0005, 0x0126, + 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x63b5, 0x0120, 0x2091, + 0x8000, 0x080c, 0x5e68, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, + 0x080c, 0x63b5, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, + 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, + 0x00db, 0x012e, 0x0005, 0x012e, 0x080c, 0x5f86, 0x0005, 0x0005, + 0x0005, 0x00e6, 0x2071, 0xb6e2, 0x700c, 0x0002, 0x5eeb, 0x5eeb, + 0x5eeb, 0x5eed, 0x5ef0, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, + 0x700f, 0x0002, 0x00ee, 0x0005, 0x5f86, 0x5f86, 0x5fa2, 0x5f86, + 0x611f, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fa2, 0x6161, + 0x61a4, 0x61ed, 0x6201, 0x5f86, 0x5f86, 0x5fbe, 0x5fa2, 0x5f86, + 0x5f86, 0x6018, 0x62ad, 0x62c8, 0x5f86, 0x5fbe, 0x5f86, 0x5f86, + 0x5f86, 0x5f86, 0x600e, 0x62c8, 0x5f86, 0x5f86, 0x5f86, 0x5f86, + 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fd2, 0x5f86, 0x5f86, + 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x63d3, + 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fe7, 0x7020, 0x2068, + 0x080c, 0x1614, 0x0005, 0x700c, 0x0002, 0x5f3a, 0x5f3d, 0x5f4b, + 0x5f63, 0x5f63, 0x080c, 0x5e68, 0x0005, 0x0126, 0x8001, 0x700e, + 0x7058, 0x0006, 0x080c, 0x63b5, 0x0120, 0x2091, 0x8000, 0x080c, + 0x5e68, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x63b5, + 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, + 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, + 0x0005, 0x012e, 0x0419, 0x0005, 0x0005, 0x0005, 0x5f86, 0x5fa2, + 0x610b, 0x5f86, 0x5fa2, 0x5f86, 0x5fa2, 0x5fa2, 0x5f86, 0x5fa2, + 0x610b, 0x5fa2, 0x5fa2, 0x5fa2, 0x5fa2, 0x5fa2, 0x5f86, 0x5fa2, + 0x610b, 0x5f86, 0x5f86, 0x5fa2, 0x5f86, 0x5f86, 0x5f86, 0x5fa2, + 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, + 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, + 0x080c, 0x547a, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, + 0x00ff, 0xc0e5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, + 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, + 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e, 0x0005, + 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, + 0x2091, 0x8000, 0x080c, 0x547a, 0x012e, 0x0005, 0x6834, 0x8007, + 0xa084, 0x00ff, 0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, + 0x60cb, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, + 0x60cb, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0904, 0x5f94, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x60e8, 0x7007, 0x0006, + 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x60e8, 0x0005, 0x6834, + 0x8007, 0xa084, 0x00ff, 0xa086, 0x0001, 0x1904, 0x5f94, 0x7007, + 0x0001, 0x2009, 0xb631, 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, + 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4df4, 0x1108, 0x0005, + 0x0126, 0x2091, 0x8000, 0x6837, 0x0139, 0x684a, 0x6952, 0x080c, + 0x547a, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, + 0x00c0, 0xa086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x62e0, + 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, + 0x20a1, 0xb70d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, + 0x5fb0, 0x6a84, 0xa28a, 0x0002, 0x1a04, 0x5fb0, 0x82ff, 0x1138, + 0x6888, 0x698c, 0xa105, 0x0118, 0x2001, 0x609e, 0x0018, 0xa280, + 0x6094, 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, 0x6080, 0x080c, + 0x15e4, 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, + 0x2060, 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, + 0x1210, 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, + 0x0004, 0x0108, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, + 0x080c, 0x1648, 0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, + 0x0118, 0x7007, 0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x1614, + 0x7014, 0x2068, 0x0804, 0x5fb0, 0x7020, 0x2068, 0x7018, 0x6802, + 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x603b, + 0x7014, 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x1128, 0x6888, + 0x698c, 0xa105, 0x0108, 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, + 0x001e, 0x0904, 0x62e0, 0x04b8, 0x6096, 0x609a, 0x0002, 0x0011, + 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x000a, 0x0011, + 0x0005, 0x0004, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, + 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, + 0x0005, 0x700c, 0x7816, 0x7008, 0x7812, 0x7004, 0x7806, 0x7000, + 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, + 0x0006, 0x0c78, 0x6004, 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, + 0x00ee, 0x00fe, 0x0005, 0x2009, 0xb631, 0x210c, 0x81ff, 0x1198, + 0x6838, 0xa084, 0x00ff, 0x683a, 0x080c, 0x4cd7, 0x1108, 0x0005, + 0x080c, 0x554d, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f88, 0x080c, + 0x547a, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, + 0x2009, 0xb631, 0x210c, 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01c0, + 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4d98, + 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0x684a, 0x6952, 0x080c, + 0x547a, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c90, + 0x2001, 0x0000, 0x0c78, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, + 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030, + 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, + 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, + 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9, + 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005, 0x11f0, 0x6944, 0x810f, + 0xa18c, 0x00ff, 0x080c, 0x501b, 0x11b8, 0x0066, 0x6e50, 0x080c, + 0x511a, 0x006e, 0x0088, 0x0046, 0x2011, 0xb60c, 0x2224, 0xc484, + 0x2412, 0x004e, 0x00c6, 0x080c, 0x501b, 0x1110, 0x080c, 0x527b, + 0x8108, 0x1f04, 0x614b, 0x00ce, 0x684c, 0xd084, 0x1118, 0x080c, + 0x1614, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xb653, + 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb975, 0x6100, 0xd184, 0x0178, + 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, + 0xa005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, + 0x0001, 0x6860, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, + 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, + 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, + 0x012e, 0x0804, 0x63a4, 0x012e, 0x0804, 0x639e, 0x012e, 0x0804, + 0x6398, 0x012e, 0x0804, 0x639b, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0xb975, + 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, + 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, + 0x2100, 0xa210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, + 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, + 0xa082, 0x0004, 0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, + 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, + 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x63a4, 0x012e, + 0x0804, 0x63a1, 0x012e, 0x0804, 0x639e, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x2061, 0xb975, 0x6300, 0xd38c, 0x1120, 0x6308, + 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x63b2, 0x012e, 0x0804, + 0x63a1, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, + 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb975, 0x6000, 0xa084, 0xfcff, + 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005, 0x05d0, 0x685c, 0xa065, + 0x0598, 0x2001, 0xb631, 0x2004, 0xa005, 0x0118, 0x080c, 0x9ed9, + 0x0068, 0x6013, 0x0400, 0x6057, 0x0000, 0x694c, 0xd1a4, 0x0110, + 0x6950, 0x6156, 0x2009, 0x0041, 0x080c, 0x86d3, 0x6958, 0xa18c, + 0xff00, 0xa186, 0x2000, 0x1140, 0x0026, 0x2009, 0x0000, 0x2011, + 0xfdff, 0x080c, 0x6b8c, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061, + 0xb975, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, + 0x00ce, 0x012e, 0x0804, 0x63a4, 0x00ce, 0x012e, 0x0804, 0x639e, + 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186, + 0x0045, 0x0528, 0xa186, 0x002a, 0x1130, 0x2001, 0xb60c, 0x200c, + 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029, + 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x501b, 0x1960, + 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c, 0xa065, 0x09a8, 0x6007, + 0x0024, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x0804, 0x623c, 0x685c, + 0xa065, 0x0950, 0x00e6, 0x6860, 0xa075, 0x2001, 0xb631, 0x2004, + 0xa005, 0x0150, 0x080c, 0x9ed9, 0x8eff, 0x0118, 0x2e60, 0x080c, + 0x9ed9, 0x00ee, 0x0804, 0x623c, 0x6020, 0xc0dc, 0xc0d5, 0x6022, + 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b, + 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x6cff, + 0x080c, 0x71e5, 0x00ee, 0x0804, 0x623c, 0x2061, 0xb975, 0x6000, + 0xd084, 0x0190, 0xd08c, 0x1904, 0x63b2, 0x0126, 0x2091, 0x8000, + 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x63b2, 0x012e, + 0x6853, 0x0016, 0x0804, 0x63ab, 0x6853, 0x0007, 0x0804, 0x63ab, + 0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5f94, 0x0078, + 0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, + 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x62e0, 0x0005, + 0x00e6, 0x0126, 0x2091, 0x8000, 0xa03e, 0x2009, 0xb631, 0x210c, + 0x81ff, 0x1904, 0x635e, 0x2009, 0xb60c, 0x210c, 0xd194, 0x1904, + 0x6388, 0x6848, 0x2070, 0xae82, 0xbe00, 0x0a04, 0x6352, 0x2001, + 0xb617, 0x2004, 0xae02, 0x1a04, 0x6352, 0x711c, 0xa186, 0x0006, + 0x1904, 0x6341, 0x7018, 0xa005, 0x0904, 0x635e, 0x2004, 0xd0e4, + 0x1904, 0x6383, 0x2061, 0xb975, 0x6100, 0xa184, 0x0301, 0xa086, + 0x0001, 0x1550, 0x7020, 0xd0dc, 0x1904, 0x638b, 0x6853, 0x0000, + 0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, + 0xd0f4, 0x1904, 0x638e, 0x2e60, 0x080c, 0x6ae8, 0x012e, 0x00ee, + 0x0005, 0x2068, 0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, + 0xd0f4, 0x1904, 0x638e, 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, + 0x6853, 0x0006, 0x0804, 0x63ab, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, + 0x00b8, 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x501b, 0x15d8, + 0x6000, 0xd0e4, 0x15c0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, + 0x0002, 0x0498, 0x6853, 0x0008, 0x0480, 0x6853, 0x000e, 0x0468, + 0x6853, 0x0017, 0x0450, 0x6853, 0x0035, 0x0438, 0x2001, 0xb672, + 0x2004, 0xd0fc, 0x01e8, 0x6848, 0x2070, 0xae82, 0xbe00, 0x02c0, + 0x605c, 0xae02, 0x12a8, 0x711c, 0xa186, 0x0006, 0x1188, 0x7018, + 0xa005, 0x0170, 0x2004, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, + 0xa086, 0x0007, 0x1904, 0x62eb, 0x7003, 0x0002, 0x0804, 0x62eb, + 0x6853, 0x0028, 0x0010, 0x6853, 0x0029, 0x012e, 0x00ee, 0x0418, + 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045, 0x0cb8, 0x2e60, 0x2019, + 0x0002, 0x6017, 0x0014, 0x080c, 0xad9c, 0x012e, 0x00ee, 0x0005, + 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, + 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084, + 0xff00, 0xa105, 0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, + 0x012e, 0x0005, 0x080c, 0x1614, 0x0005, 0x702c, 0x7130, 0x8108, + 0xa102, 0x0230, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058, + 0x7070, 0xa080, 0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000, + 0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c, + 0x6adf, 0x00de, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, + 0x7007, 0x0001, 0x6a44, 0xa282, 0x0004, 0x1a04, 0x641e, 0xd284, + 0x0170, 0x6a4c, 0xa290, 0xb735, 0x2204, 0xa065, 0x6004, 0x05e0, + 0x8007, 0xa084, 0x00ff, 0xa084, 0x0006, 0x1108, 0x04a8, 0x2c10, + 0x080c, 0x864e, 0x1118, 0x080c, 0x9f92, 0x05a0, 0x621a, 0x6844, + 0x0002, 0x63fd, 0x6402, 0x6405, 0x640b, 0x2019, 0x0002, 0x080c, + 0xb121, 0x0060, 0x080c, 0xb0b8, 0x0048, 0x2019, 0x0002, 0x6950, + 0x080c, 0xb0d3, 0x0018, 0x6950, 0x080c, 0xb0b8, 0x080c, 0x86a4, + 0x6857, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e, + 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0x6857, 0x0006, + 0x0c88, 0x6857, 0x0002, 0x0c70, 0x6857, 0x0005, 0x0c58, 0x6857, + 0x0004, 0x0c40, 0x6857, 0x0007, 0x0c28, 0x00d6, 0x2011, 0x0004, + 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002, + 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086, + 0x1000, 0x1570, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, + 0xa084, 0xf000, 0xa086, 0x3000, 0x1160, 0xa184, 0xff00, 0x8007, + 0xa086, 0x0008, 0x11e8, 0x080c, 0x2df4, 0x11d0, 0x080c, 0x6675, + 0x0098, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, + 0x0007, 0x1170, 0xac82, 0xbe00, 0x0258, 0x685c, 0xac02, 0x1240, + 0x2009, 0x0047, 0x080c, 0x86d3, 0x7a1c, 0xd284, 0x1938, 0x0005, + 0xa016, 0x080c, 0x1863, 0x0cc0, 0x0cd8, 0x781c, 0xd08c, 0x0500, + 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, + 0x0076, 0x1538, 0xa484, 0x7000, 0xa086, 0x1000, 0x11a8, 0x080c, + 0x64f0, 0x01f8, 0x20e1, 0x3000, 0x7828, 0x7828, 0x080c, 0x650c, + 0x014e, 0x013e, 0x015e, 0x2009, 0xb8e9, 0x2104, 0xa005, 0x1108, + 0x0005, 0x080c, 0x71e5, 0x0ce0, 0xa484, 0x7000, 0x1548, 0x080c, + 0x64f0, 0x01d8, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0d10, + 0x00a0, 0xd5a4, 0x0178, 0x0056, 0x0046, 0x080c, 0x1e8a, 0x080c, + 0x24e5, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x004e, + 0x005e, 0x0048, 0x04a9, 0x6887, 0x0000, 0x080c, 0xb49b, 0x20e1, + 0x3000, 0x7828, 0x7828, 0x00b9, 0x014e, 0x013e, 0x015e, 0x0880, + 0x0439, 0x1130, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x1d68, + 0x080c, 0xb49b, 0x20e1, 0x3000, 0x7828, 0x7828, 0x0056, 0x080c, + 0x68e6, 0x005e, 0x0c40, 0x2001, 0xb60e, 0x2004, 0xd08c, 0x0178, + 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1148, 0x0026, 0x0036, + 0x2011, 0x8048, 0x2518, 0x080c, 0x3f13, 0x003e, 0x002e, 0x0005, + 0xa484, 0x01ff, 0x6886, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, + 0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, + 0x0005, 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, + 0x53a5, 0xa085, 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, + 0xf000, 0x8007, 0xa196, 0x0000, 0x1118, 0x0804, 0x677a, 0x0005, + 0xa196, 0x2000, 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, + 0x44d6, 0x0ca8, 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, + 0x6826, 0x0c68, 0x00c6, 0x6a84, 0x82ff, 0x0904, 0x666f, 0x7110, + 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, + 0x1904, 0x666f, 0xa08e, 0x0023, 0x1570, 0x080c, 0x68c1, 0x0904, + 0x666f, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, + 0xa005, 0x1904, 0x666f, 0x2009, 0x0015, 0x080c, 0x86d3, 0x0804, + 0x666f, 0xa08e, 0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, + 0x0015, 0x080c, 0x86d3, 0x0804, 0x666f, 0xa08e, 0x0100, 0x1904, + 0x666f, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x0016, 0x080c, + 0x86d3, 0x0804, 0x666f, 0xa08e, 0x0022, 0x1904, 0x666f, 0x7030, + 0xa08e, 0x0300, 0x1580, 0x68d4, 0xd0a4, 0x0528, 0xc0b5, 0x68d6, + 0x7100, 0xa18c, 0x00ff, 0x6972, 0x7004, 0x6876, 0x00f6, 0x2079, + 0x0100, 0x79e6, 0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, + 0x080c, 0x287c, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, + 0x2852, 0x6952, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, + 0xb600, 0x70a6, 0x00ee, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, + 0x0017, 0x0804, 0x6635, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, + 0x1904, 0x666f, 0x68d4, 0xc0a5, 0x68d6, 0x2009, 0x0030, 0x0804, + 0x6635, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x666f, + 0x2009, 0x0018, 0x0804, 0x6635, 0xa08e, 0x2010, 0x1120, 0x2009, + 0x0019, 0x0804, 0x6635, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, + 0x0804, 0x6635, 0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, + 0x666f, 0x2009, 0x001b, 0x0804, 0x6635, 0xa08e, 0x5000, 0x1140, + 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x001c, 0x0804, 0x6635, + 0xa08e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x6635, 0xa08e, + 0x1200, 0x1140, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x0024, + 0x0804, 0x6635, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, + 0x002d, 0x04d8, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, + 0x002a, 0x0498, 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, + 0xa08e, 0x5300, 0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, + 0xbc8d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, + 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3f13, + 0x004e, 0x8108, 0x1f04, 0x6618, 0x2009, 0x0023, 0x0070, 0xa08e, + 0x6000, 0x1118, 0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, + 0x2009, 0x0045, 0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xbc83, + 0x2204, 0x8211, 0x220c, 0x080c, 0x2852, 0x1598, 0x080c, 0x4fbf, + 0x1580, 0x6612, 0x6516, 0x86ff, 0x01e8, 0x001e, 0x0016, 0xa186, + 0x0017, 0x1158, 0x6870, 0xa606, 0x11a8, 0x6874, 0xa506, 0xa084, + 0xff00, 0x1180, 0x6000, 0xc0f5, 0x6002, 0xa186, 0x0046, 0x1150, + 0x6870, 0xa606, 0x1138, 0x6874, 0xa506, 0xa084, 0xff00, 0x1110, + 0x001e, 0x0068, 0x00c6, 0x080c, 0x864e, 0x0168, 0x001e, 0x611a, + 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x86d3, 0x00ce, + 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046, 0x080c, + 0x66c9, 0x1904, 0x66c6, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x68c1, + 0x0904, 0x66c6, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140, + 0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x86d3, 0x04b0, + 0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016, + 0x080c, 0x86d3, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e, + 0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xbc83, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2852, 0x11c0, 0x080c, 0x4fbf, 0x11a8, + 0x6612, 0x6516, 0x00c6, 0x080c, 0x864e, 0x0170, 0x001e, 0x611a, + 0x080c, 0xa0e3, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, + 0x86d3, 0x080c, 0x71e5, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, + 0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156, + 0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1f49, + 0x1590, 0x080c, 0x1dee, 0x05e0, 0x04f1, 0x1130, 0x7908, 0xa18c, + 0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000, + 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, + 0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0419, + 0x1120, 0xa08a, 0x0140, 0x1a0c, 0x151a, 0x80ac, 0x20e1, 0x6000, + 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, + 0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e, + 0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa016, 0x080c, 0x1863, + 0xa085, 0x0001, 0x0c80, 0x0006, 0x2001, 0x0111, 0x2004, 0xa084, + 0x0003, 0x000e, 0x0005, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, + 0xa696, 0x00ff, 0x1198, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, + 0x0804, 0x6775, 0xa596, 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, + 0xa596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, + 0x2019, 0xb635, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, + 0x00ff, 0x2071, 0xb735, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, + 0x2071, 0xb7b6, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, + 0xc2fd, 0x0080, 0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, + 0x6b14, 0x1120, 0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, + 0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x6752, 0x82ff, 0x1118, + 0xa085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, + 0x004e, 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x6786, 0x6786, + 0x6786, 0x68d3, 0x6786, 0x6787, 0x679c, 0x6811, 0x0005, 0x7110, + 0xd1bc, 0x0188, 0x7120, 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, + 0xbe00, 0x0248, 0x685c, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, + 0x0046, 0x080c, 0x86d3, 0x0005, 0x00c6, 0xa484, 0x01ff, 0x0904, + 0x67ef, 0x7110, 0xd1bc, 0x1904, 0x67ef, 0x2011, 0xbc83, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2852, 0x1904, 0x67ef, 0x080c, 0x4fbf, + 0x15f0, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15c8, 0x6204, 0xa294, + 0xff00, 0x8217, 0xa286, 0x0006, 0x0148, 0x6204, 0xa294, 0x00ff, + 0xa286, 0x0006, 0x11a0, 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, + 0x864e, 0x001e, 0x0530, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, + 0x7130, 0x6152, 0x2009, 0x0044, 0x080c, 0x86d3, 0x00c0, 0x00c6, + 0x080c, 0x864e, 0x001e, 0x0198, 0x611a, 0x601f, 0x0004, 0x7120, + 0x610a, 0xa286, 0x0004, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00ce, + 0x0005, 0x2001, 0xb60d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x3f13, 0x00c6, 0x080c, 0x9f92, 0x001e, 0x0d80, 0x611a, + 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x6013, 0x0300, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5, + 0x08f0, 0x7110, 0xd1bc, 0x0188, 0x7020, 0x2060, 0xac84, 0x0007, + 0x1160, 0xac82, 0xbe00, 0x0248, 0x685c, 0xac02, 0x1230, 0x7124, + 0x610a, 0x2009, 0x0045, 0x080c, 0x86d3, 0x0005, 0x0006, 0x080c, + 0x2df4, 0x000e, 0x1168, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, + 0x0000, 0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, + 0x0005, 0x683f, 0x6840, 0x683f, 0x683f, 0x68a9, 0x68b5, 0x0005, + 0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x68a8, 0x700c, + 0x7108, 0x080c, 0x2852, 0x1904, 0x68a8, 0x080c, 0x4fbf, 0x1904, + 0x68a8, 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, + 0x00ff, 0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, + 0x080c, 0x68c1, 0x00ce, 0x0904, 0x68a8, 0x00c6, 0x080c, 0x864e, + 0x001e, 0x05f0, 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0002, 0x7120, + 0x610a, 0x2009, 0x0088, 0x080c, 0x86d3, 0x0490, 0xa28c, 0x00ff, + 0xa186, 0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, + 0x8217, 0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, + 0x080c, 0x864e, 0x001e, 0x01e0, 0x611a, 0x080c, 0xa0e3, 0x601f, + 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x86d3, 0x0080, + 0x00c6, 0x080c, 0x864e, 0x001e, 0x0158, 0x611a, 0x080c, 0xa0e3, + 0x601f, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x86d3, + 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, + 0x2009, 0x0089, 0x080c, 0x86d3, 0x0005, 0x7110, 0xd1bc, 0x0140, + 0x0041, 0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x86d3, + 0x0005, 0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xbe00, + 0x0240, 0x2001, 0xb617, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, + 0x0005, 0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, + 0xac84, 0x0007, 0x1150, 0xac82, 0xbe00, 0x0238, 0x685c, 0xac02, + 0x1220, 0x2009, 0x0051, 0x080c, 0x86d3, 0x0005, 0x2031, 0x0105, + 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, + 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, + 0x00f6, 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, + 0x864e, 0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xbc83, 0x2204, + 0x8211, 0x220c, 0x080c, 0x2852, 0x1580, 0x080c, 0x4fbf, 0x1568, + 0x6612, 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0xa0e3, + 0x080c, 0x15fd, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, + 0x0000, 0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, + 0x53a3, 0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, + 0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00fe, 0x00de, 0x00ce, + 0x0005, 0x080c, 0x86a4, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, + 0x2071, 0xb8f4, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, + 0x7076, 0x7012, 0x7017, 0xbe00, 0x7007, 0x0000, 0x7026, 0x702b, + 0x7e0a, 0x7032, 0x7037, 0x7e6a, 0x703b, 0xffff, 0x703f, 0xffff, + 0x7042, 0x7047, 0x4492, 0x704a, 0x705b, 0x6a9d, 0x2001, 0xb8a1, + 0x2003, 0x0003, 0x2001, 0xb8a3, 0x2003, 0x0100, 0x3a00, 0xa084, + 0x0005, 0x706e, 0x0005, 0x2071, 0xb8f4, 0x1d04, 0x69fd, 0x2091, + 0x6000, 0x700c, 0x8001, 0x700e, 0x1518, 0x700f, 0x0361, 0x7007, + 0x0001, 0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0128, 0x8109, + 0x7142, 0x1110, 0x7044, 0x080f, 0x00c6, 0x2061, 0xb600, 0x6034, + 0x00ce, 0xd0cc, 0x0180, 0x3a00, 0xa084, 0x0005, 0x726c, 0xa216, + 0x0150, 0x706e, 0x2011, 0x8043, 0x2018, 0x080c, 0x3f13, 0x0018, + 0x0126, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0188, 0x7020, 0x8001, + 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, + 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, + 0xa00d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009, + 0x8109, 0x7132, 0x0128, 0xa184, 0x007f, 0x090c, 0x7eaf, 0x0010, + 0x7034, 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, + 0x703c, 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x704c, 0xa00d, + 0x0168, 0x7048, 0x8001, 0x704a, 0x1148, 0x704b, 0x0009, 0x8109, + 0x714e, 0x1120, 0x7150, 0x714e, 0x7058, 0x080f, 0x7018, 0xa00d, + 0x01d8, 0x0016, 0x7074, 0xa00d, 0x0158, 0x7070, 0x8001, 0x7072, + 0x1138, 0x7073, 0x0009, 0x8109, 0x7176, 0x1110, 0x7078, 0x080f, + 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, + 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6a23, + 0x6a24, 0x6a3c, 0x00e6, 0x2071, 0xb8f4, 0x7018, 0xa005, 0x1120, + 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, + 0x2071, 0xb8f4, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0xb8f4, 0x6088, 0xa102, 0x0208, + 0x618a, 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x501b, 0x1158, + 0x6088, 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, + 0x080c, 0x71e5, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, + 0x7007, 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, + 0x8000, 0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, + 0x9fd1, 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, + 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, + 0x6854, 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, + 0x6116, 0x0010, 0x080c, 0x9aa1, 0x012e, 0xac88, 0x0018, 0x7116, + 0x2001, 0xee00, 0xa102, 0x0220, 0x7017, 0xbe00, 0x7007, 0x0000, + 0x0005, 0x00e6, 0x2071, 0xb8f4, 0x7027, 0x07d0, 0x7023, 0x0009, + 0x00ee, 0x0005, 0x2001, 0xb8fd, 0x2003, 0x0000, 0x0005, 0x00e6, + 0x2071, 0xb8f4, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, + 0xb900, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb8f4, 0x711a, + 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x0026, 0x7054, + 0x8000, 0x7056, 0x2061, 0xb8a1, 0x6008, 0xa086, 0x0000, 0x0158, + 0x7068, 0x6032, 0x7064, 0x602e, 0x7060, 0x602a, 0x705c, 0x6026, + 0x2c10, 0x080c, 0x1648, 0x002e, 0x00ce, 0x0005, 0x0006, 0x0016, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x696b, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0xb8f4, + 0x7176, 0x727a, 0x7073, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, + 0x2071, 0xb8f4, 0x7078, 0xa206, 0x1110, 0x7076, 0x707a, 0x000e, + 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb975, 0x00ce, 0x0005, 0xa184, + 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb975, 0x2060, 0x0005, + 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0xa005, 0x1150, + 0x00c6, 0x2061, 0xb975, 0x6014, 0x00ce, 0xa005, 0x1138, 0x2001, + 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006, 0x8003, 0x800b, + 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, + 0x05e8, 0xd0b4, 0x1138, 0xd0bc, 0x1550, 0x2009, 0x0006, 0x080c, + 0x6b63, 0x0005, 0xd0fc, 0x0138, 0xa084, 0x0003, 0x0120, 0xa086, + 0x0003, 0x1904, 0x6b5d, 0x6020, 0xd0d4, 0x0130, 0xc0d4, 0x6022, + 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xb674, 0x2104, 0xd084, + 0x0138, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0x86d3, 0x0005, + 0x87ff, 0x1120, 0x2009, 0x0043, 0x080c, 0x86d3, 0x0005, 0xd0fc, + 0x0130, 0xa084, 0x0003, 0x0118, 0xa086, 0x0003, 0x11f0, 0x87ff, + 0x1120, 0x2009, 0x0042, 0x080c, 0x86d3, 0x0005, 0xd0fc, 0x0160, + 0xa084, 0x0003, 0xa08e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, + 0x0041, 0x080c, 0x86d3, 0x0005, 0x0061, 0x0ce8, 0x87ff, 0x1dd8, + 0x2009, 0x0043, 0x080c, 0x86d3, 0x0cb0, 0x2009, 0x0004, 0x0019, + 0x0005, 0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x0510, + 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, + 0xa18c, 0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb975, + 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, + 0x080c, 0x547a, 0x6010, 0xa06d, 0x0076, 0x2039, 0x0000, 0x190c, + 0x6ae8, 0x007e, 0x00de, 0x0005, 0x0156, 0x00c6, 0x2061, 0xb975, + 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce, + 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120, + 0x8001, 0x680a, 0xa085, 0x0001, 0x0005, 0x20a9, 0x0010, 0xa006, + 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x6ba9, 0x8086, + 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, + 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x6bb9, + 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x6bb9, 0x0006, 0x3200, + 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, + 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091, 0x2800, 0x2079, 0xb8e1, + 0x012e, 0x00d6, 0x2069, 0xb8e1, 0x6803, 0x0005, 0x2069, 0x0004, + 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027, + 0x0001, 0x7804, 0xa084, 0x0007, 0x0002, 0x6bf7, 0x6c18, 0x6c6b, + 0x6bfd, 0x6c18, 0x6bf7, 0x6bf5, 0x6bf5, 0x080c, 0x151a, 0x080c, + 0x6a82, 0x080c, 0x71e5, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, + 0x00ce, 0x0005, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x7828, 0xa092, + 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x4b65, 0x0c88, 0x080c, + 0x4b23, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40, + 0x080c, 0x6a82, 0x3c00, 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000, + 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160, + 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x151a, 0x2009, 0x0013, + 0x080c, 0x86d3, 0x00ce, 0x0005, 0x3900, 0xa082, 0xba2d, 0x1210, + 0x080c, 0x83b9, 0x00c6, 0x7824, 0xa065, 0x090c, 0x151a, 0x7804, + 0xa086, 0x0004, 0x0904, 0x6cab, 0x7828, 0xa092, 0x2710, 0x1230, + 0x8000, 0x782a, 0x00ce, 0x080c, 0x7de6, 0x0c20, 0x6104, 0xa186, + 0x0003, 0x1188, 0x00e6, 0x2071, 0xb600, 0x70e0, 0x00ee, 0xd08c, + 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x080c, + 0x4b7b, 0x00ee, 0x00ce, 0x080c, 0xb500, 0x2009, 0x0014, 0x080c, + 0x86d3, 0x00ce, 0x0838, 0x2001, 0xb8fd, 0x2003, 0x0000, 0x62c0, + 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x151a, + 0x2009, 0x0013, 0x080c, 0x872c, 0x00ce, 0x0005, 0x00c6, 0x00d6, + 0x3900, 0xa082, 0xba2d, 0x1210, 0x080c, 0x83b9, 0x7824, 0xa005, + 0x090c, 0x151a, 0x781c, 0xa06d, 0x090c, 0x151a, 0x6800, 0xc0dc, + 0x6802, 0x7924, 0x2160, 0x080c, 0x86a4, 0x693c, 0x81ff, 0x090c, + 0x151a, 0x8109, 0x693e, 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010, + 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, + 0x080c, 0x71e5, 0x0888, 0x6104, 0xa186, 0x0002, 0x0128, 0xa186, + 0x0004, 0x0110, 0x0804, 0x6c44, 0x7808, 0xac06, 0x0904, 0x6c44, + 0x080c, 0x7102, 0x080c, 0x6d45, 0x00ce, 0x080c, 0x71e5, 0x0804, + 0x6c32, 0x00c6, 0x6027, 0x0002, 0x62c8, 0x60c4, 0xa205, 0x1178, + 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009, 0x0049, 0x080c, 0x86d3, + 0x00ce, 0x0005, 0x2011, 0xb900, 0x2013, 0x0000, 0x0cc8, 0x3908, + 0xa192, 0xba2d, 0x1210, 0x080c, 0x83b9, 0x793c, 0x81ff, 0x0d90, + 0x7944, 0xa192, 0x7530, 0x12b8, 0x8108, 0x7946, 0x793c, 0xa188, + 0x0007, 0x210c, 0xa18e, 0x0006, 0x1138, 0x6014, 0xa084, 0x0184, + 0xa085, 0x0012, 0x6016, 0x08e0, 0x6014, 0xa084, 0x0184, 0xa085, + 0x0016, 0x6016, 0x08a8, 0x7848, 0xc085, 0x784a, 0x0888, 0x0006, + 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, + 0x2061, 0xb8e1, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, 0x0148, + 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, + 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xb8e1, 0x6000, + 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x1110, + 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x71eb, 0xc0d5, + 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000, 0x0006, + 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xb8e1, 0x0c18, 0x6056, + 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb8e1, + 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080, 0x0003, + 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, + 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb8e1, + 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136, 0x00ce, + 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, + 0xa02e, 0x2071, 0xb8e1, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, + 0x8cff, 0x0904, 0x6ded, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, + 0x1904, 0x6de8, 0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6de8, + 0x703c, 0xac06, 0x1190, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b, + 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, + 0x704b, 0x0000, 0x003e, 0x2029, 0x0001, 0x7038, 0xac36, 0x1110, + 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, + 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, + 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, + 0x9d16, 0x01c8, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x1580, + 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x0016, 0x0036, 0x0076, + 0x080c, 0x9f88, 0x080c, 0xb43c, 0x080c, 0x547a, 0x007e, 0x003e, + 0x001e, 0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x00ce, 0x0804, 0x6d88, + 0x2c78, 0x600c, 0x2060, 0x0804, 0x6d88, 0x85ff, 0x0120, 0x0036, + 0x080c, 0x72a2, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, + 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x601c, 0xa086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, + 0xb43c, 0x080c, 0xb155, 0x007e, 0x003e, 0x001e, 0x08a0, 0x601c, + 0xa086, 0x000a, 0x0904, 0x6dd2, 0x0804, 0x6dd0, 0x0006, 0x0066, + 0x00c6, 0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, + 0x2079, 0xb8e1, 0x7838, 0xa065, 0x0568, 0x600c, 0x0006, 0x600f, + 0x0000, 0x783c, 0xac06, 0x1180, 0x0036, 0x2019, 0x0001, 0x080c, + 0x806b, 0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, + 0x0000, 0x784b, 0x0000, 0x003e, 0x080c, 0x9d16, 0x0178, 0x6010, + 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, + 0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0x9ed9, + 0x000e, 0x0888, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, + 0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c, + 0xb155, 0x0c60, 0x601c, 0xa086, 0x000a, 0x0d08, 0x08f0, 0x0016, + 0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x6f35, 0x008e, + 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xb8e1, 0x2091, + 0x8000, 0x080c, 0x6fc2, 0x080c, 0x7034, 0x012e, 0x00fe, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0xb8e1, 0x7614, 0x2660, 0x2678, 0x8cff, + 0x0904, 0x6f0b, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, + 0x6f06, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6f06, 0x7024, + 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, + 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, + 0x04e8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, + 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, + 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, + 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9d16, 0x01b8, + 0x601c, 0xa086, 0x0003, 0x1540, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0x9f88, 0x080c, 0xb43c, + 0x080c, 0x547a, 0x008e, 0x003e, 0x001e, 0x080c, 0x9ecd, 0x080c, + 0x9ed9, 0x080c, 0x81a5, 0x00ce, 0x0804, 0x6e8f, 0x2c78, 0x600c, + 0x2060, 0x0804, 0x6e8f, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1158, + 0x0016, 0x0036, 0x0086, 0x080c, 0xb43c, 0x080c, 0xb155, 0x008e, + 0x003e, 0x001e, 0x08e0, 0x601c, 0xa086, 0x0002, 0x1128, 0x6004, + 0xa086, 0x0085, 0x0908, 0x0898, 0x601c, 0xa086, 0x0005, 0x1978, + 0x6004, 0xa086, 0x0085, 0x0d20, 0x0850, 0x00c6, 0x0006, 0x0126, + 0x2091, 0x8000, 0xa280, 0xb735, 0x2004, 0xa065, 0x0904, 0x6fbe, + 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0xb8e1, 0x6654, 0x7018, + 0xac06, 0x1108, 0x761a, 0x701c, 0xac06, 0x1130, 0x86ff, 0x1118, + 0x7018, 0x701e, 0x0008, 0x761e, 0x6058, 0xa07d, 0x0108, 0x7e56, + 0xa6ed, 0x0000, 0x0110, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, + 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4f46, 0x0904, + 0x6fba, 0x7624, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, + 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, + 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, + 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x9ed9, 0x00ce, 0x0048, + 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, + 0x6f65, 0x8dff, 0x0158, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x080c, 0x9f88, 0x080c, 0xb43c, 0x080c, 0x547a, 0x080c, 0x81a5, + 0x0804, 0x6f65, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, + 0x00ce, 0x0005, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x2031, 0x0000, + 0x7814, 0xa065, 0x0904, 0x7014, 0x600c, 0x0006, 0x600f, 0x0000, + 0x7824, 0xac06, 0x1540, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, + 0x080c, 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, + 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, + 0x630a, 0x2c30, 0x00b0, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0168, + 0x601c, 0xa086, 0x0003, 0x11b8, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x080c, + 0x81a5, 0x000e, 0x0804, 0x6fc9, 0x7e16, 0x7e12, 0x00de, 0x00ce, + 0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c, + 0xb155, 0x0c58, 0x601c, 0xa086, 0x0002, 0x1128, 0x6004, 0xa086, + 0x0085, 0x09d0, 0x0c10, 0x601c, 0xa086, 0x0005, 0x19f0, 0x6004, + 0xa086, 0x0085, 0x0d60, 0x08c8, 0x0006, 0x0066, 0x00c6, 0x00d6, + 0x7818, 0xa065, 0x0904, 0x709a, 0x6054, 0x0006, 0x6057, 0x0000, + 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4f46, + 0x0904, 0x7097, 0x7e24, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, + 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, + 0x080c, 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, + 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, + 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, + 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x9ed9, 0x00ce, + 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, + 0x0804, 0x7046, 0x8dff, 0x0138, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x080c, 0x547a, 0x080c, 0x81a5, 0x0804, 0x7046, 0x000e, + 0x0804, 0x7039, 0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e, + 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc, 0x01a0, 0x604c, + 0xa06d, 0x0188, 0x6848, 0xa606, 0x1170, 0x2071, 0xb8e1, 0x7024, + 0xa035, 0x0148, 0xa080, 0x0004, 0x2004, 0xad06, 0x1120, 0x6000, + 0xc0dc, 0x6002, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, + 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, + 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7df3, 0x78c3, 0x0000, + 0x080c, 0x82d4, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, + 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, + 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0x82d4, + 0x003e, 0x080c, 0x4f46, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, + 0x603e, 0x2660, 0x080c, 0x86a4, 0x00ce, 0x6837, 0x0103, 0x6b4a, + 0x6847, 0x0000, 0x080c, 0x9f88, 0x080c, 0x547a, 0x080c, 0x81a5, + 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xb8e1, 0x7004, 0xa084, + 0x0007, 0x0002, 0x7114, 0x7117, 0x712d, 0x7146, 0x7183, 0x7114, + 0x7112, 0x7112, 0x080c, 0x151a, 0x00ce, 0x00ee, 0x0005, 0x7024, + 0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, + 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, + 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, + 0x4f46, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, + 0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, + 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, + 0x05b8, 0x700c, 0xac06, 0x1160, 0x080c, 0x81a5, 0x600c, 0xa015, + 0x0120, 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, + 0x7014, 0xac06, 0x1160, 0x080c, 0x81a5, 0x600c, 0xa015, 0x0120, + 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x601c, + 0xa086, 0x0003, 0x1198, 0x6018, 0x2060, 0x080c, 0x4f46, 0x6000, + 0xc0dc, 0x6002, 0x080c, 0x81a5, 0x701c, 0xa065, 0x0138, 0x6054, + 0xa015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, + 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0140, 0x080c, 0x81a5, + 0x600c, 0xa015, 0x0150, 0x720e, 0x600f, 0x0000, 0x080c, 0x82d4, + 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, + 0x00d6, 0x2069, 0xb8e1, 0x6830, 0xa084, 0x0003, 0x0002, 0x71a5, + 0x71a7, 0x71cb, 0x71a3, 0x080c, 0x151a, 0x00de, 0x0005, 0x00c6, + 0x6840, 0xa086, 0x0001, 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, + 0xa015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, + 0x0000, 0x2011, 0xb900, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, + 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, + 0x6003, 0x0003, 0x0c50, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, + 0x684b, 0x0000, 0x683c, 0xa065, 0x0168, 0x600c, 0xa015, 0x0130, + 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0020, 0x683f, 0x0000, + 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x00d6, 0x2069, 0xb8e1, + 0x6804, 0xa084, 0x0007, 0x0002, 0x71f6, 0x7292, 0x7292, 0x7292, + 0x7292, 0x7294, 0x71f4, 0x71f4, 0x080c, 0x151a, 0x6820, 0xa005, + 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0150, 0x6807, + 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x72e4, 0x00ce, 0x00de, + 0x0005, 0x6814, 0xa065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, + 0x0000, 0x080c, 0x72e4, 0x00ce, 0x00de, 0x0005, 0x00e6, 0x0036, + 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x728e, 0x704c, 0xa00d, 0x0118, + 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075, 0x0120, 0xa20e, 0x0904, + 0x728e, 0x0028, 0x6818, 0xa20e, 0x0904, 0x728e, 0x2070, 0x704c, + 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70, 0x2e00, 0x681e, 0x733c, + 0x7038, 0xa302, 0x1e40, 0x080c, 0x867b, 0x0904, 0x728e, 0x8318, + 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, + 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, + 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, + 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0, 0x2001, + 0xb635, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100, 0xd1f4, + 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, + 0xa1e0, 0x2df9, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, + 0x080c, 0x7914, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, + 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, + 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e, 0x00ee, + 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0138, + 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x72e4, 0x00ce, + 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0xb8e1, 0x6830, 0xa086, + 0x0000, 0x11d0, 0x2001, 0xb60c, 0x200c, 0xd1bc, 0x1560, 0x6838, + 0xa07d, 0x0190, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, + 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x203d, + 0x1130, 0x012e, 0x080c, 0x7c5d, 0x00de, 0x00fe, 0x0005, 0x012e, + 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0140, + 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c60, + 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x0066, 0x2031, 0x0001, + 0x080c, 0x5bc3, 0x006e, 0x0858, 0x601c, 0xa084, 0x000f, 0x000b, + 0x0005, 0x72f2, 0x72f7, 0x77b5, 0x78d1, 0x72f7, 0x77b5, 0x78d1, + 0x72f2, 0x72f7, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0x0156, + 0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, + 0x151a, 0x6118, 0x2178, 0x79a0, 0x2011, 0xb635, 0x2214, 0xd2ac, + 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, + 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2df9, 0x2f0d, + 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, + 0x1a04, 0x736b, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, + 0x0005, 0x741a, 0x7465, 0x7492, 0x755f, 0x758d, 0x7595, 0x75bb, + 0x75cc, 0x75dd, 0x75e5, 0x75fb, 0x75e5, 0x765c, 0x75cc, 0x767d, + 0x7685, 0x75dd, 0x7685, 0x7696, 0x7369, 0x7369, 0x7369, 0x7369, + 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7efe, + 0x7f23, 0x7f46, 0x7f69, 0x7f8a, 0x75bb, 0x7369, 0x75bb, 0x75e5, + 0x7369, 0x7492, 0x755f, 0x7369, 0x83d6, 0x75e5, 0x7369, 0x83f6, + 0x75e5, 0x7369, 0x75dd, 0x7413, 0x737e, 0x7369, 0x841b, 0x8490, + 0x8567, 0x7369, 0x8578, 0x75b6, 0x8594, 0x7369, 0x7f9f, 0x85ef, + 0x7369, 0x080c, 0x151a, 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, + 0x013e, 0x015e, 0x0005, 0x737c, 0x737c, 0x737c, 0x73b2, 0x73d0, + 0x73e6, 0x737c, 0x737c, 0x737c, 0x080c, 0x151a, 0x00d6, 0x20a1, + 0x020b, 0x080c, 0x76b3, 0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3, + 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854, + 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, + 0x7de0, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068, 0x68a0, 0x2069, + 0xb600, 0x6ad4, 0xd2ac, 0x1110, 0xd0bc, 0x0110, 0xa085, 0x0001, + 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3, + 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2, + 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, + 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7de0, 0x00de, 0x0005, + 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3, 0x7800, + 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3, + 0x0008, 0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0000, + 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xb605, 0x20a9, 0x0004, + 0x53a6, 0x2099, 0xb601, 0x20a9, 0x0004, 0x53a6, 0x2099, 0xb8c7, + 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398, 0x1f04, 0x7402, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c, 0x080c, 0x7de0, + 0x014e, 0x015e, 0x0005, 0x2001, 0xb615, 0x2004, 0x609a, 0x080c, + 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3, 0x5200, + 0x20a3, 0x0000, 0x00d6, 0x2069, 0xb652, 0x6804, 0xd084, 0x0150, + 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x2866, 0x21a2, 0x001e, + 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, + 0x0004, 0x2099, 0xb605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb601, + 0x53a6, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, + 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001, 0xb61c, 0x20a6, + 0x2001, 0xb61d, 0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xb615, + 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x001c, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x76b3, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0xb635, 0x2004, + 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, + 0x0238, 0x2001, 0xb61c, 0x20a6, 0x2001, 0xb61d, 0x20a6, 0x0040, + 0x20a3, 0x0000, 0x2001, 0xb615, 0x2004, 0xa084, 0x00ff, 0x20a2, + 0x20a9, 0x0004, 0x2099, 0xb605, 0x53a6, 0x60c3, 0x0010, 0x080c, + 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x00c6, 0x7818, + 0x2060, 0x2001, 0x0000, 0x080c, 0x5385, 0x00ce, 0x7818, 0xa080, + 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3, 0x0400, 0x620c, + 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, + 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904, 0x7521, 0x2001, + 0xb635, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xb88e, 0x33a6, 0x9398, + 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000, 0x20a2, 0x9398, + 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001, 0x2710, 0x20a2, + 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099, 0xb88e, 0x33a6, + 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x5b41, 0x1118, 0xa084, + 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, + 0x0004, 0x2099, 0xb605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb601, + 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x74fb, 0x20a9, + 0x0008, 0x20a3, 0x0000, 0x1f04, 0x7501, 0x2099, 0xb896, 0x3304, + 0xc0dd, 0x20a2, 0x2001, 0xb672, 0x2004, 0xd0e4, 0x0158, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, + 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x1f04, 0x751c, + 0x0468, 0x2001, 0xb635, 0x2004, 0xd0a4, 0x0140, 0x2001, 0xb88f, + 0x2004, 0x60e3, 0x0000, 0x080c, 0x28a7, 0x60e2, 0x2099, 0xb88e, + 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb605, 0x53a6, + 0x20a9, 0x0004, 0x2099, 0xb601, 0x53a6, 0x20a9, 0x0008, 0x20a3, + 0x0000, 0x1f04, 0x753f, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, + 0x7545, 0x2099, 0xb896, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, + 0x20a3, 0x0000, 0x1f04, 0x7550, 0x20a9, 0x000a, 0x20a3, 0x0000, + 0x1f04, 0x7556, 0x60c3, 0x0074, 0x080c, 0x7de0, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x76b3, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, + 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x00f6, 0x2079, 0xb652, 0x7904, 0x00fe, 0xd1ac, 0x1110, + 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0xa085, 0x0002, + 0x00d6, 0x0804, 0x763e, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x76b3, 0x20a3, 0x5000, 0x0804, 0x74ad, 0x20a1, 0x020b, 0x080c, + 0x76b3, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, + 0x0000, 0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x7747, 0x0020, 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, + 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, + 0x0004, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x774f, + 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, + 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x774f, 0x20a3, 0x0200, 0x0804, 0x74ad, 0x20a1, 0x020b, 0x080c, + 0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0110, + 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, + 0x080c, 0x7de0, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x774f, + 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, + 0x6894, 0xa086, 0x0014, 0x1198, 0x699c, 0xa184, 0x0030, 0x0190, + 0x6998, 0xa184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, + 0x0058, 0x20a3, 0x0100, 0x0040, 0x20a3, 0x0400, 0x0028, 0x20a3, + 0x0700, 0x0010, 0x700f, 0x0800, 0xa006, 0x20a2, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xb652, 0x7904, 0x00fe, 0xd1ac, + 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, + 0xb674, 0x210c, 0xd184, 0x1110, 0xa085, 0x0002, 0x0026, 0x2009, + 0xb672, 0x210c, 0xd1e4, 0x0130, 0xc0c5, 0xa094, 0x0030, 0xa296, + 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094, 0x0030, 0xa296, 0x0010, + 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, + 0x080c, 0x7de0, 0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x774f, + 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, + 0x774f, 0x20a3, 0x0200, 0x0804, 0x7420, 0x20a1, 0x020b, 0x080c, + 0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, + 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, + 0x080c, 0x7de0, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3200, + 0x2021, 0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2200, + 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, + 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0, 0xa385, 0x00ff, 0x20a2, + 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x2001, + 0xb89e, 0x2004, 0xa005, 0x0118, 0x2011, 0xb61d, 0x2214, 0x22a2, + 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6, 0xa385, 0x00ff, 0x20a2, + 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110, + 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, 0x1130, 0xa385, 0x00ff, + 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8, 0xb735, 0x2d6c, 0x6810, + 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, + 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8, 0xb735, 0x2d6c, 0x6810, + 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, + 0xb615, 0x2214, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x004e, 0x003e, + 0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x2fa2, + 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, + 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, + 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100, + 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026, + 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0038, 0x0026, + 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, + 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x02d8, 0x00d6, 0xa0e8, + 0xb735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x6810, + 0xa005, 0x1140, 0x6814, 0xa005, 0x1128, 0x20a3, 0x00ff, 0x20a3, + 0xfffe, 0x0028, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0080, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa305, 0x20a2, + 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, + 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x004e, 0x003e, + 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x080c, 0x7dcf, + 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6, 0x6004, + 0xa08a, 0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c, 0x1a0c, 0x151a, + 0x6118, 0x2178, 0x79a0, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, + 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, + 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2df9, 0x2f0d, 0xa18c, + 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, 0x001b, + 0x00fe, 0x00ce, 0x0005, 0x77ec, 0x77f6, 0x7811, 0x77ea, 0x77ea, + 0x77ea, 0x77ec, 0x080c, 0x151a, 0x0146, 0x20a1, 0x020b, 0x04a1, + 0x60c3, 0x0000, 0x080c, 0x7de0, 0x014e, 0x0005, 0x0146, 0x20a1, + 0x020b, 0x080c, 0x785d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, + 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x014e, + 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x7897, 0x20a3, 0x0003, + 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, + 0x080c, 0x7de0, 0x014e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, 0x2214, + 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xb735, + 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, + 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, + 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, + 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2, 0x20a3, + 0x0009, 0x20a3, 0x0000, 0x0804, 0x771a, 0x0026, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, + 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, + 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, + 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, + 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2, + 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804, 0x77a6, 0x0026, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, + 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, + 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8500, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, + 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804, + 0x77a6, 0x00c6, 0x00f6, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c, + 0x151a, 0xa08a, 0x0053, 0x1a0c, 0x151a, 0x7918, 0x2160, 0x61a0, + 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100, + 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, + 0x0028, 0xa1e0, 0x2df9, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, + 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7914, + 0x7a20, 0x79bd, 0x7bd2, 0x7912, 0x7912, 0x7912, 0x7912, 0x7912, + 0x7912, 0x7912, 0x815e, 0x816e, 0x817e, 0x818e, 0x7912, 0x85a5, + 0x7912, 0x814d, 0x080c, 0x151a, 0x00d6, 0x0156, 0x0146, 0x780b, + 0xffff, 0x20a1, 0x020b, 0x080c, 0x7974, 0x7910, 0x2168, 0x6948, + 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, + 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, + 0x0004, 0x0018, 0xa084, 0x0006, 0x8004, 0x0016, 0x2008, 0x7858, + 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e, 0x20a2, 0xd1ac, 0x0118, + 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020, + 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008, + 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e, + 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, + 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xb8fd, + 0x2003, 0x07d0, 0x2001, 0xb8fc, 0x2003, 0x0009, 0x080c, 0x17e7, + 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, + 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, + 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0x2019, 0xb635, 0x231c, + 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, + 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c, + 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb735, + 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x00de, + 0x20a3, 0x0000, 0x2009, 0xb615, 0x210c, 0x21a2, 0x20a3, 0x0829, + 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156, 0x0136, + 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, 0x2068, 0x6860, 0x20a2, + 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x014e, + 0x013e, 0x015e, 0x00de, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, + 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, 0x2214, + 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, + 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c, + 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb735, + 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x00de, + 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2, 0x20a3, 0x0889, + 0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08, + 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, + 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810, 0xa0ec, 0xf000, 0x0168, + 0xa06d, 0x080c, 0x5373, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086, + 0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c, + 0x7b88, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, + 0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043, + 0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, + 0x7a5a, 0x7aef, 0x7aff, 0x7b31, 0x7b44, 0x7b5f, 0x7b68, 0x7a58, + 0x080c, 0x151a, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118, + 0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5, + 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, + 0x7b3b, 0xa186, 0x0001, 0x190c, 0x151a, 0x6b78, 0x7820, 0xd0cc, + 0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, + 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, + 0x0300, 0x0904, 0x7ae9, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc, + 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020, + 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x7a98, 0x015e, 0x22a2, + 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7ae9, 0x20a1, 0x020b, + 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, + 0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889, + 0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7dcf, 0x22a2, 0x20a3, + 0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7de0, 0x0005, 0x2011, + 0x0008, 0x2001, 0xb60d, 0x2004, 0xd0f4, 0x0110, 0x2011, 0x0028, + 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x04d0, 0x2011, + 0x0302, 0x0016, 0x0036, 0x7828, 0x792c, 0xa11d, 0x0108, 0xc2dd, + 0x7b20, 0xd3cc, 0x0108, 0xc2e5, 0x22a2, 0x20a2, 0x21a2, 0x003e, + 0x001e, 0xa016, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, + 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, + 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7de0, + 0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, + 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, + 0x0018, 0x080c, 0x7de0, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc, + 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, + 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2, + 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7de0, 0x0005, 0x2011, + 0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888, + 0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, + 0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808, + 0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108, + 0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7b3b, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, + 0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010, + 0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, + 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036, + 0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e, + 0x013e, 0x015e, 0x00de, 0x0005, 0x7bec, 0x7bec, 0x7bee, 0x7bec, + 0x7bec, 0x7bec, 0x7c10, 0x7bec, 0x080c, 0x151a, 0x7910, 0xa18c, + 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, + 0x00f9, 0x00d6, 0x2069, 0xb652, 0x6804, 0xd0bc, 0x0130, 0x682c, + 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de, + 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7de0, 0x0005, + 0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80, + 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, + 0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, + 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, + 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, + 0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0100, + 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, + 0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c, + 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, + 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, + 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xb600, 0x7154, + 0x7818, 0x2068, 0x68a0, 0x2028, 0x76d4, 0xd6ac, 0x1130, 0xd0bc, + 0x1120, 0x6910, 0x6a14, 0x7454, 0x0020, 0x6910, 0x6a14, 0x7370, + 0x7474, 0x781c, 0xa0be, 0x0006, 0x0904, 0x7d1a, 0xa0be, 0x000a, + 0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, + 0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, + 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, + 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, + 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0x609f, 0x0000, 0x080c, 0x8640, 0x2009, 0x07d0, 0x60c4, 0xa084, + 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6a87, 0x003e, + 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d4, 0xd0ac, + 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, + 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, + 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, + 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, + 0x700c, 0x60c6, 0x7008, 0x60ca, 0x792c, 0xa108, 0x792e, 0x700c, + 0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, + 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8640, + 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, 0x2009, + 0x1b58, 0x080c, 0x6a87, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, + 0x0002, 0x0904, 0x7d70, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110, + 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, + 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, + 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, + 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086, 0x7808, + 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, + 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, 0xa109, + 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, + 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, + 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x863d, 0x0804, 0x7d08, + 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, + 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, 0x0700, + 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5373, 0x0180, + 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020, 0xa086, + 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889, 0x0010, + 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, + 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, + 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, + 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, + 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, + 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120, 0x080c, + 0x8640, 0x0804, 0x7d08, 0x080c, 0x863d, 0x0804, 0x7d08, 0x7a18, + 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, + 0x0005, 0x00d6, 0x2069, 0xb8e1, 0x6843, 0x0001, 0x00de, 0x0005, + 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019, 0x080c, + 0x6a79, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, + 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, + 0x61a4, 0x60a7, 0x95f5, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, + 0x6016, 0x000e, 0xe000, 0xe000, 0xe000, 0xe000, 0x61a6, 0x00ce, + 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, + 0x2069, 0x0140, 0x080c, 0x5b41, 0x1198, 0x2001, 0xb8fd, 0x2004, + 0xa005, 0x15b8, 0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3, 0x006e, + 0x1118, 0x080c, 0x6a79, 0x0468, 0x00c6, 0x2061, 0xb8e1, 0x00d8, + 0x6904, 0xa194, 0x4000, 0x0550, 0x0831, 0x6803, 0x1000, 0x6803, + 0x0000, 0x00c6, 0x2061, 0xb8e1, 0x6128, 0xa192, 0x00c8, 0x1258, + 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x6a79, + 0x080c, 0x7dea, 0x0070, 0x6124, 0xa1e5, 0x0000, 0x0140, 0x080c, + 0xb500, 0x080c, 0x6a82, 0x2009, 0x0014, 0x080c, 0x86d3, 0x00ce, + 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0xb8fd, + 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061, 0xb8e1, 0x6128, 0xa192, + 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x6a79, 0x080c, + 0x4b7b, 0x0c38, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, + 0x6a8f, 0x2071, 0xb8e1, 0x713c, 0x81ff, 0x0590, 0x2061, 0x0100, + 0x2069, 0x0140, 0x080c, 0x5b41, 0x11a8, 0x0036, 0x2019, 0x0002, + 0x080c, 0x806b, 0x003e, 0x713c, 0x2160, 0x080c, 0xb500, 0x2009, + 0x004a, 0x080c, 0x86d3, 0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3, + 0x006e, 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, + 0x6803, 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b, 0x003e, + 0x713c, 0x2160, 0x080c, 0xb500, 0x2009, 0x004a, 0x080c, 0x86d3, + 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x0026, + 0x00e6, 0x2071, 0xb8e1, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, + 0x01a8, 0x2071, 0x0100, 0xa188, 0x0007, 0x2114, 0xa28e, 0x0006, + 0x1138, 0x7014, 0xa084, 0x0184, 0xa085, 0x0012, 0x7016, 0x0030, + 0x7014, 0xa084, 0x0184, 0xa085, 0x0016, 0x7016, 0x00ee, 0x002e, + 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, + 0x0126, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071, 0xb8e1, + 0x7018, 0x2068, 0x8dff, 0x0188, 0x68a0, 0xa406, 0x0118, 0x6854, + 0x2068, 0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60, + 0x080c, 0x518c, 0x0110, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, + 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x76b3, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x781c, 0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xb615, + 0x2004, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, + 0xa006, 0x20a2, 0x1f04, 0x7f19, 0x20a2, 0x20a2, 0x60c3, 0x002c, + 0x080c, 0x7de0, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, + 0x76b3, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x7808, 0xd09c, 0x1150, + 0x20a3, 0x0000, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x014e, + 0x015e, 0x0005, 0x00d6, 0x7818, 0xa06d, 0x090c, 0x151a, 0x6810, + 0xa084, 0x00ff, 0x20a2, 0x6814, 0x00de, 0x0c60, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0000, + 0x20a9, 0x0006, 0x2011, 0xb640, 0x2019, 0xb641, 0x23a6, 0x22a6, + 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7f56, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7de0, 0x014e, 0x015e, + 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, + 0x7728, 0x080c, 0x773e, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, + 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, + 0x0004, 0x8003, 0x60c2, 0x080c, 0x7de0, 0x002e, 0x001e, 0x014e, + 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x76b3, + 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, + 0x60c3, 0x0008, 0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x0156, + 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x7810, + 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808, 0xa088, + 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7de0, 0x002e, + 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0xb8e1, 0x700c, 0x2060, 0x8cff, 0x0178, + 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x600c, 0x0006, 0x080c, + 0xa0db, 0x080c, 0x86a4, 0x080c, 0x81a5, 0x00ce, 0x0c78, 0x700f, + 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, + 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, + 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0xb8e1, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7df3, 0x68c3, + 0x0000, 0x080c, 0x6a82, 0x2009, 0x0013, 0x080c, 0x86d3, 0x20a9, + 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, + 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084, + 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x8001, 0x7804, 0xa084, + 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, + 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, + 0x0005, 0x2001, 0xb600, 0x2004, 0xa096, 0x0001, 0x0590, 0xa096, + 0x0004, 0x0578, 0x080c, 0x6a82, 0x6814, 0xa084, 0x0001, 0x0110, + 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x4b23, + 0x080c, 0x6a0e, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, + 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, + 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, + 0x8044, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, + 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, + 0x2079, 0x0140, 0x2071, 0xb8e1, 0x703c, 0x2060, 0x8cff, 0x0904, + 0x80f2, 0xa386, 0x0002, 0x1128, 0x6814, 0xa084, 0x0002, 0x0904, + 0x80f2, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, + 0x1df0, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x6a8f, 0x080c, + 0x222f, 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, + 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x1500, 0x68af, 0x95f5, + 0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, + 0x2071, 0xb94b, 0x6814, 0xa084, 0x0184, 0xa085, 0x0012, 0x6816, + 0x7803, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0xa386, 0x0002, + 0x1128, 0x7884, 0xa005, 0x1110, 0x7887, 0x0001, 0x2001, 0xb8b1, + 0x2004, 0x200a, 0x004e, 0xa39d, 0x0000, 0x1120, 0x2009, 0x0049, + 0x080c, 0x86d3, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0158, 0x6827, + 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, + 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, + 0x80d4, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, + 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, + 0x2069, 0xb8e1, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x2069, 0xb8e1, 0x6a32, 0x012e, 0x00de, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2071, 0xb8e1, + 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0538, 0x601c, + 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, + 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, + 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9ed9, 0x080c, 0x81a5, + 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, 0x08b8, 0x012e, 0x000e, + 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0156, 0x0146, 0x20a1, + 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, + 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, 0x819d, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0478, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x00f8, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x0156, 0x0146, + 0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, + 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x0089, 0x60c3, 0x0020, + 0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x00e6, 0x2071, 0xb8e1, + 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x20a9, + 0x0008, 0x20a2, 0x1f04, 0x81b1, 0x20a2, 0x20a2, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0xb8e1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0904, 0x824d, 0x8cff, 0x0904, 0x824d, 0x601c, 0xa086, + 0x0006, 0x1904, 0x8248, 0x88ff, 0x0138, 0x2800, 0xac06, 0x1904, + 0x8248, 0x2039, 0x0000, 0x0050, 0x6018, 0xa206, 0x1904, 0x8248, + 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x8248, 0x7024, 0xac06, + 0x1598, 0x2069, 0x0100, 0x68c0, 0xa005, 0x1160, 0x6824, 0xd084, + 0x0148, 0x6827, 0x0001, 0x080c, 0x6a82, 0x080c, 0x82d4, 0x7027, + 0x0000, 0x0410, 0x080c, 0x6a82, 0x6820, 0xd0b4, 0x0110, 0x68a7, + 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x7014, 0xac36, 0x1110, 0x660c, + 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, + 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, + 0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155, 0x080c, + 0x9ed9, 0x080c, 0x81a5, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x81c8, + 0x2c78, 0x600c, 0x2060, 0x0804, 0x81c8, 0xa006, 0x012e, 0x000e, + 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, + 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0xb8e1, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x82c4, 0x601c, + 0xa086, 0x0006, 0x1904, 0x82bf, 0x87ff, 0x0128, 0x2700, 0xac06, + 0x1904, 0x82bf, 0x0048, 0x6018, 0xa206, 0x1904, 0x82bf, 0x85ff, + 0x0118, 0x6050, 0xa106, 0x15d8, 0x703c, 0xac06, 0x1180, 0x0036, + 0x2019, 0x0001, 0x080c, 0x806b, 0x7033, 0x0000, 0x703f, 0x0000, + 0x7043, 0x0000, 0x7047, 0x0000, 0x704b, 0x0000, 0x003e, 0x7038, + 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, + 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155, + 0x080c, 0x9ed9, 0x87ff, 0x1190, 0x00ce, 0x0804, 0x826c, 0x2c78, + 0x600c, 0x2060, 0x0804, 0x826c, 0xa006, 0x012e, 0x000e, 0x002e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, + 0x00ce, 0xa7bd, 0x0001, 0x0c88, 0x00e6, 0x2071, 0xb8e1, 0x2001, + 0xb600, 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, + 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb8e1, 0x2c10, + 0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0xac06, 0x11e0, + 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, + 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, + 0x660c, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, + 0x0000, 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08d8, + 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0xb8e1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, + 0x83aa, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x83a5, + 0x7024, 0xac06, 0x1508, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0904, + 0x8381, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, + 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0xac36, 0x1110, 0x660c, + 0x760e, 0x7008, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, + 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9f03, + 0x1158, 0x080c, 0x2cf7, 0x080c, 0x9f14, 0x11f0, 0x080c, 0x8ca5, + 0x00d8, 0x080c, 0x82d4, 0x08c0, 0x080c, 0x9f14, 0x1118, 0x080c, + 0x8ca5, 0x0090, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0168, 0x601c, + 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, + 0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0xa0db, 0x080c, 0x9ed9, + 0x080c, 0x81a5, 0x00ce, 0x0804, 0x832e, 0x2c78, 0x600c, 0x2060, + 0x0804, 0x832e, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xb155, + 0x0c18, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006, 0xa190, + 0x0020, 0x221c, 0xa39e, 0x2aec, 0x1118, 0x8210, 0x8000, 0x0cc8, + 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, + 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6, 0x20a1, + 0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, + 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0xb8b9, 0x20a9, + 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x080c, 0x7de0, 0x00de, 0x0005, 0x20a1, 0x020b, + 0x080c, 0x774f, 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, + 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, + 0x7828, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, + 0x080c, 0x7de0, 0x0005, 0x00d6, 0x0016, 0x2f68, 0x2009, 0x0035, + 0x080c, 0xa1c6, 0x1904, 0x8489, 0x20a1, 0x020b, 0x080c, 0x76b3, + 0x20a3, 0x1300, 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, + 0x0003, 0x0580, 0x7818, 0xa080, 0x0028, 0x2014, 0x2001, 0xb635, + 0x2004, 0xd0ac, 0x11d0, 0xa286, 0x007e, 0x1128, 0x20a3, 0x00ff, + 0x20a3, 0xfffe, 0x04b8, 0xa286, 0x007f, 0x1128, 0x20a3, 0x00ff, + 0x20a3, 0xfffd, 0x0478, 0xd2bc, 0x0180, 0xa286, 0x0080, 0x1128, + 0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0428, 0xa2e8, 0xb735, 0x2d6c, + 0x6810, 0x20a2, 0x6814, 0x20a2, 0x00e8, 0x20a3, 0x0000, 0x6098, + 0x20a2, 0x00c0, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1138, 0x7818, + 0xa080, 0x0028, 0x2004, 0xa082, 0x007e, 0x0240, 0x00d6, 0x2069, + 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0020, 0x20a3, 0x0000, + 0x6034, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000, + 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x001e, 0x00de, + 0x0005, 0x7817, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x0005, + 0x00d6, 0x0026, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x01c0, + 0xa186, 0x0003, 0x0904, 0x84ff, 0xa186, 0x0005, 0x0904, 0x84e8, + 0xa186, 0x0004, 0x05b8, 0xa186, 0x0008, 0x0904, 0x84f0, 0x7807, + 0x0037, 0x7813, 0x1700, 0x080c, 0x8567, 0x002e, 0x00de, 0x0005, + 0x080c, 0x8523, 0x2009, 0x4000, 0x6800, 0x0002, 0x84c9, 0x84d4, + 0x84cb, 0x84d4, 0x84d0, 0x84c9, 0x84c9, 0x84d4, 0x84d4, 0x84d4, + 0x84d4, 0x84c9, 0x84c9, 0x84c9, 0x84c9, 0x84c9, 0x84d4, 0x84c9, + 0x84d4, 0x080c, 0x151a, 0x6820, 0xd0e4, 0x0110, 0xd0cc, 0x0110, + 0xa00e, 0x0010, 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, + 0x0804, 0x8519, 0x080c, 0x8523, 0x20a3, 0x0000, 0x20a3, 0x0000, + 0x2009, 0x4000, 0x6a00, 0xa286, 0x0002, 0x1108, 0xa00e, 0x0488, + 0x04d1, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x0448, + 0x0491, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0xa286, + 0x0005, 0x0118, 0xa286, 0x0002, 0x1108, 0xa00e, 0x00d0, 0x0419, + 0x6810, 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, + 0x20a2, 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, + 0x0130, 0xa08e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0010, 0x2009, + 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7de0, + 0x002e, 0x00de, 0x0005, 0x0036, 0x0046, 0x0056, 0x0066, 0x20a1, + 0x020b, 0x080c, 0x774f, 0xa006, 0x20a3, 0x0200, 0x20a2, 0x7934, + 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, + 0xb635, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0268, 0x00d6, + 0x2069, 0xb61c, 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xb735, 0x2d6c, + 0x6b10, 0x6c14, 0x00de, 0x0030, 0x2019, 0x0000, 0x6498, 0x2029, + 0x0000, 0x6634, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, + 0x1128, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0020, 0x23a2, 0x24a2, + 0x25a2, 0x26a2, 0x006e, 0x005e, 0x004e, 0x003e, 0x0005, 0x20a1, + 0x020b, 0x080c, 0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, + 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, + 0x20a1, 0x020b, 0x080c, 0x76ab, 0x20a3, 0x1400, 0x20a3, 0x0000, + 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c, 0x20a2, + 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3, + 0x0010, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7747, + 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810, 0x20a2, + 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x0146, 0x20a1, 0x020b, + 0x0031, 0x60c3, 0x0000, 0x080c, 0x7de0, 0x014e, 0x0005, 0x20e1, + 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, + 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, + 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, + 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0078, 0x00d6, + 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, + 0x20a2, 0x00de, 0x20a3, 0x0000, 0x6234, 0x22a2, 0x20a3, 0x0819, + 0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x2fa2, + 0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x20a1, + 0x020b, 0x0079, 0x7910, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0000, + 0x20e1, 0x9080, 0x60a7, 0x9575, 0x080c, 0x7dea, 0x080c, 0x6a79, + 0x0005, 0x0156, 0x0136, 0x0036, 0x00d6, 0x00e6, 0x20e1, 0x9080, + 0x20e1, 0x4000, 0x7854, 0x2068, 0xadf0, 0x000f, 0x7210, 0xa296, + 0x00c0, 0xa294, 0xfffd, 0x7212, 0x7214, 0xa294, 0x0300, 0x7216, + 0x7100, 0xa194, 0x00ff, 0x7308, 0xa384, 0x00ff, 0xa08d, 0xc200, + 0x7102, 0xa384, 0xff00, 0xa215, 0x720a, 0x7004, 0x720c, 0x700e, + 0x7206, 0x20a9, 0x000a, 0x2e98, 0x53a6, 0x60a3, 0x0035, 0x6a38, + 0xa294, 0x7000, 0xa286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, + 0x00de, 0x003e, 0x013e, 0x015e, 0x0005, 0x2009, 0x0092, 0x0010, + 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2061, 0xbe00, + 0x2a70, 0x7068, 0x704a, 0x704f, 0xbe00, 0x0005, 0x00e6, 0x0126, + 0x2071, 0xb600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010, 0x0608, + 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, + 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbe00, 0x0c98, 0x6003, + 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, 0xa502, 0x1230, + 0x754e, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704f, 0xbe00, + 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb600, 0x7548, 0xa582, + 0x0010, 0x0600, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, + 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbe00, + 0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, + 0xa502, 0x1228, 0x754e, 0xa085, 0x0001, 0x00ee, 0x0005, 0x704f, + 0xbe00, 0x0cc8, 0xa006, 0x0cc8, 0xac82, 0xbe00, 0x0a0c, 0x151a, + 0x2001, 0xb617, 0x2004, 0xac02, 0x1a0c, 0x151a, 0xa006, 0x6006, + 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, + 0x0000, 0x6052, 0x6056, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, + 0x6036, 0x603a, 0x603e, 0x2061, 0xb600, 0x6048, 0x8000, 0x604a, + 0xa086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x71e5, 0x012e, 0x0cc0, 0x601c, 0xa084, 0x000f, 0x0002, 0x86e7, + 0x86f6, 0x8711, 0x872c, 0xa20e, 0xa229, 0xa244, 0x86e7, 0x86f6, + 0x86e7, 0x8747, 0x86e7, 0x86e7, 0x86e7, 0x86e7, 0x86e7, 0xa186, + 0x0013, 0x1128, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0xa18e, + 0x0047, 0x1118, 0xa016, 0x080c, 0x1863, 0x0005, 0x0066, 0x6000, + 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0x870f, + 0x8b27, 0x8cdf, 0x870f, 0x8d54, 0x8805, 0x870f, 0x870f, 0x8ab9, + 0x917b, 0x870f, 0x870f, 0x870f, 0x870f, 0x870f, 0x870f, 0x080c, + 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, + 0x006e, 0x0005, 0x872a, 0x97de, 0x872a, 0x872a, 0x872a, 0x872a, + 0x872a, 0x872a, 0x9789, 0x994a, 0x872a, 0x980b, 0x9882, 0x980b, + 0x9882, 0x872a, 0x080c, 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, + 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0x8745, 0x91bc, 0x9286, + 0x93c4, 0x954d, 0x8745, 0x8745, 0x8745, 0x9196, 0x9739, 0x973c, + 0x8745, 0x8745, 0x8745, 0x8745, 0x9766, 0x080c, 0x151a, 0x0066, + 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, + 0x8760, 0x8760, 0x8760, 0x878e, 0x87db, 0x8760, 0x8760, 0x8760, + 0x8762, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760, + 0x080c, 0x151a, 0xa186, 0x0003, 0x190c, 0x151a, 0x00d6, 0x6003, + 0x0003, 0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, + 0x6880, 0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x6854, 0xa092, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0xa210, + 0x6216, 0x00de, 0x2c10, 0x080c, 0x1fc5, 0x080c, 0x6d62, 0x0126, + 0x2091, 0x8000, 0x080c, 0x72a2, 0x012e, 0x0005, 0xa182, 0x0047, + 0x0002, 0x879a, 0x879a, 0x879c, 0x87b5, 0x879a, 0x879a, 0x879a, + 0x879a, 0x87c7, 0x080c, 0x151a, 0x00d6, 0x0016, 0x080c, 0x7198, + 0x080c, 0x72a2, 0x6003, 0x0004, 0x6110, 0x2168, 0x684f, 0x0020, + 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882, 0x6897, 0x0000, + 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c, 0x7198, 0x00d6, + 0x6110, 0x2168, 0x080c, 0x9d16, 0x0120, 0x684b, 0x0006, 0x080c, + 0x547a, 0x00de, 0x080c, 0x86a4, 0x080c, 0x72a2, 0x0005, 0x080c, + 0x7198, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16, + 0x0120, 0x684b, 0x0029, 0x080c, 0x547a, 0x00de, 0x080c, 0x86a4, + 0x080c, 0x72a2, 0x0005, 0xa182, 0x0047, 0x0002, 0x87e9, 0x87f8, + 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x080c, + 0x151a, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4, 0x684e, 0x00de, + 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005, + 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853, 0x0000, 0x080c, + 0x547a, 0x00de, 0x080c, 0x86a4, 0x0005, 0xa1b6, 0x0015, 0x1118, + 0x080c, 0x86a4, 0x0030, 0xa1b6, 0x0016, 0x190c, 0x151a, 0x080c, + 0x86a4, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, + 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318, 0x3428, + 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398, 0x0002, + 0xa4a0, 0x0002, 0x1f04, 0x8820, 0x00e6, 0x080c, 0x9d16, 0x0130, + 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x00ee, 0x080c, + 0x86a4, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386, 0x0200, 0x1130, + 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, + 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x080c, + 0x86a4, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9, 0x002a, 0xae80, + 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, + 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, + 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x00ee, + 0x080c, 0x86a4, 0x001e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, + 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff, 0x800c, 0x703c, + 0xa084, 0x00ff, 0x8004, 0xa080, 0x0004, 0xa108, 0x21a8, 0xae80, + 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x080c, 0x4bf1, + 0x00e6, 0x080c, 0x9d16, 0x0140, 0x6010, 0x2070, 0x7007, 0x0000, + 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c, 0x86a4, 0x001e, + 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68, 0x0016, 0x2009, + 0x0035, 0x080c, 0xa1c6, 0x001e, 0x1168, 0x0026, 0x6228, 0x2268, + 0x002e, 0x2071, 0xbc8c, 0x6b1c, 0xa386, 0x0003, 0x0130, 0xa386, + 0x0006, 0x0128, 0x080c, 0x86a4, 0x0020, 0x0031, 0x0010, 0x080c, + 0x8982, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810, 0x2078, 0xa186, + 0x0015, 0x0904, 0x8969, 0xa18e, 0x0016, 0x1904, 0x8980, 0x700c, + 0xa08c, 0xff00, 0xa186, 0x1700, 0x0120, 0xa186, 0x0300, 0x1904, + 0x8948, 0x8fff, 0x1138, 0x6800, 0xa086, 0x000f, 0x0904, 0x892c, + 0x0804, 0x897e, 0x6808, 0xa086, 0xffff, 0x1904, 0x896b, 0x784c, + 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810, 0xa106, + 0x1904, 0x896b, 0x7980, 0x7814, 0xa106, 0x1904, 0x896b, 0x080c, + 0x9ecd, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e, + 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6bb2, 0x7854, + 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138, 0x00c6, + 0x2d60, 0x080c, 0x9ac5, 0x00ce, 0x0804, 0x897e, 0x00c6, 0x00d6, + 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4cd7, 0x0010, 0x080c, + 0x4ebb, 0x00de, 0x00ce, 0x1904, 0x896b, 0x00c6, 0x2d60, 0x080c, + 0x86a4, 0x00ce, 0x0804, 0x897e, 0x00c6, 0x080c, 0x9f92, 0x0190, + 0x6013, 0x0000, 0x6818, 0x601a, 0x080c, 0xa0e3, 0x601f, 0x0003, + 0x6904, 0x00c6, 0x2d60, 0x080c, 0x86a4, 0x00ce, 0x080c, 0x86d3, + 0x00ce, 0x04e0, 0x2001, 0xb8b8, 0x2004, 0x683e, 0x00ce, 0x04b0, + 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018, 0x200c, 0xc1bc, 0x2102, + 0x00c6, 0x2d60, 0x784b, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, + 0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ce, 0x00f0, + 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001, 0xb8b8, 0x2004, 0x683e, + 0x00a8, 0x0481, 0x00a8, 0x8fff, 0x090c, 0x151a, 0x00c6, 0x00d6, + 0x2d60, 0x2f68, 0x6837, 0x0103, 0x684b, 0x0003, 0x080c, 0x99b9, + 0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x00de, 0x00ce, 0x080c, 0x86a4, + 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xb8b8, 0x2004, + 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, + 0x080c, 0xb3f6, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x00ce, 0x080c, + 0x86a4, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80, 0x7b7c, + 0xd2f4, 0x0130, 0x2001, 0xb8b8, 0x2004, 0x683e, 0x0804, 0x89fc, + 0x00c6, 0x2d60, 0x080c, 0x99d9, 0x00ce, 0x6804, 0xa086, 0x0050, + 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, + 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ce, 0x04f0, 0x6800, 0xa086, + 0x000f, 0x01c8, 0x8fff, 0x090c, 0x151a, 0x6820, 0xd0dc, 0x1198, + 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180, 0x784c, + 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, + 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0, 0x784c, + 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0, 0x0c38, + 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406, 0x0d58, + 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x080c, + 0xa01f, 0x080c, 0x71e5, 0x0010, 0x080c, 0x86a4, 0x004e, 0x003e, + 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068, 0x6a1c, + 0xa286, 0x0007, 0x0904, 0x8a60, 0xa286, 0x0002, 0x0904, 0x8a60, + 0xa286, 0x0000, 0x0904, 0x8a60, 0x6808, 0x6338, 0xa306, 0x1904, + 0x8a60, 0x2071, 0xbc8c, 0xa186, 0x0015, 0x05e0, 0xa18e, 0x0016, + 0x1190, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, + 0xa086, 0x2a00, 0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, + 0xc1f5, 0x2102, 0x0438, 0x00c6, 0x6034, 0x2060, 0x6104, 0xa186, + 0x004b, 0x01a0, 0xa186, 0x004c, 0x0188, 0xa186, 0x004d, 0x0170, + 0xa186, 0x004e, 0x0158, 0xa186, 0x0052, 0x0140, 0x6010, 0x2068, + 0x080c, 0x9d16, 0x090c, 0x151a, 0x684b, 0x0003, 0x6007, 0x0085, + 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5, + 0x00ce, 0x0030, 0x6034, 0x2070, 0x2001, 0xb8b8, 0x2004, 0x703e, + 0x080c, 0x86a4, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, + 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1558, + 0x6018, 0x2068, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c, 0xa290, + 0x0004, 0x20a9, 0x0004, 0xad98, 0x000a, 0x080c, 0x9166, 0x002e, + 0x003e, 0x015e, 0x11d8, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c, + 0xa290, 0x0008, 0x20a9, 0x0004, 0xad98, 0x0006, 0x080c, 0x9166, + 0x002e, 0x003e, 0x015e, 0x1150, 0x7038, 0x680a, 0x703c, 0x680e, + 0x6800, 0xc08d, 0x6802, 0x00de, 0x0804, 0x882c, 0x080c, 0x2cd1, + 0x00c6, 0x080c, 0x864e, 0x2f00, 0x601a, 0x6013, 0x0000, 0x601f, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, + 0x4f6f, 0x080c, 0x4f9c, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00ce, + 0x0c10, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x151a, 0xa1b2, 0x0040, + 0x1a04, 0x8b1d, 0x0002, 0x8b11, 0x8b05, 0x8b11, 0x8b11, 0x8b11, + 0x8b11, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, + 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, + 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, + 0x8b03, 0x8b03, 0x8b11, 0x8b03, 0x8b11, 0x8b11, 0x8b03, 0x8b03, + 0x8b03, 0x8b03, 0x8b03, 0x8b11, 0x8b03, 0x8b03, 0x8b03, 0x8b03, + 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b11, 0x8b11, 0x8b03, + 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, + 0x8b11, 0x8b03, 0x8b03, 0x080c, 0x151a, 0x6003, 0x0001, 0x6106, + 0x080c, 0x6d45, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e, + 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x6d45, 0x0126, 0x2091, + 0x8000, 0x080c, 0x71e5, 0x012e, 0x0005, 0x2600, 0x0002, 0x8b11, + 0x8b11, 0x8b25, 0x8b11, 0x8b11, 0x8b25, 0x080c, 0x151a, 0x6004, + 0xa0b2, 0x0080, 0x1a0c, 0x151a, 0xa1b6, 0x0013, 0x0904, 0x8bd7, + 0xa1b6, 0x0027, 0x1904, 0x8b9d, 0x080c, 0x7102, 0x6004, 0x080c, + 0x9f03, 0x0190, 0x080c, 0x9f14, 0x0904, 0x8b97, 0xa08e, 0x0021, + 0x0904, 0x8b9a, 0xa08e, 0x0022, 0x0904, 0x8b97, 0xa08e, 0x003d, + 0x0904, 0x8b9a, 0x0804, 0x8b90, 0x080c, 0x2cf7, 0x2001, 0x0007, + 0x080c, 0x4f6f, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8ca5, + 0xa186, 0x007e, 0x1148, 0x2001, 0xb635, 0x2014, 0xc285, 0x080c, + 0x5b41, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, + 0x0026, 0x2019, 0x0028, 0x080c, 0x8320, 0x002e, 0x080c, 0xb449, + 0x003e, 0x002e, 0x001e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, + 0x0028, 0x080c, 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, + 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x521c, 0x00ce, 0x2c08, + 0x080c, 0xaf3e, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0x4fde, + 0x080c, 0xa0db, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0x080c, + 0x8ca5, 0x0cb0, 0x080c, 0x8cd3, 0x0c98, 0xa186, 0x0014, 0x1db0, + 0x080c, 0x7102, 0x080c, 0x2cd1, 0x080c, 0x9f03, 0x1188, 0x080c, + 0x2cf7, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8ca5, 0xa186, + 0x007e, 0x1128, 0x2001, 0xb635, 0x200c, 0xc185, 0x2102, 0x08c0, + 0x080c, 0x9f14, 0x1118, 0x080c, 0x8ca5, 0x0890, 0x6004, 0xa08e, + 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xb682, 0x2079, 0x0000, + 0x080c, 0x3004, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, 0x0021, + 0x0d50, 0xa08e, 0x0022, 0x090c, 0x8ca5, 0x0804, 0x8b90, 0xa0b2, + 0x0040, 0x1a04, 0x8c9a, 0x2008, 0x0002, 0x8c1f, 0x8c20, 0x8c23, + 0x8c26, 0x8c29, 0x8c2c, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, + 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, + 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, + 0x8c1d, 0x8c1d, 0x8c1d, 0x8c2f, 0x8c3e, 0x8c1d, 0x8c40, 0x8c3e, + 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c3e, 0x8c3e, 0x8c1d, + 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c7a, + 0x8c3e, 0x8c1d, 0x8c3a, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c3b, 0x8c1d, + 0x8c1d, 0x8c1d, 0x8c3e, 0x8c71, 0x8c1d, 0x080c, 0x151a, 0x00f0, + 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001, 0x0005, + 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400, 0x080c, + 0x7102, 0x6003, 0x0005, 0x2001, 0xb8b8, 0x2004, 0x603e, 0x080c, + 0x71e5, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4f6f, 0x0804, 0x8c8b, + 0x080c, 0x7102, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x2001, 0xb8b8, + 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x71e5, 0x0005, 0x080c, + 0x4f6f, 0x080c, 0x7102, 0x6003, 0x0002, 0x2001, 0xb8b8, 0x2004, + 0x603e, 0x0036, 0x2019, 0xb65d, 0x2304, 0xa084, 0xff00, 0x1120, + 0x2001, 0xb8b6, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004, 0x0ec0, + 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c, 0x71e5, + 0x08e8, 0x080c, 0x7102, 0x080c, 0xa0db, 0x080c, 0x86a4, 0x080c, + 0x71e5, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xb682, 0x2079, 0x0000, + 0x080c, 0x3004, 0x00fe, 0x00ee, 0x080c, 0x7102, 0x080c, 0x86a4, + 0x080c, 0x71e5, 0x0818, 0x080c, 0x7102, 0x2001, 0xb8b8, 0x2004, + 0x603e, 0x6003, 0x0002, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x080c, + 0x71e5, 0x0005, 0x2600, 0x2008, 0x0002, 0x8ca3, 0x8ca3, 0x8ca3, + 0x8c8b, 0x8c8b, 0x8ca3, 0x080c, 0x151a, 0x00e6, 0x0026, 0x0016, + 0x080c, 0x9d16, 0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, + 0x1148, 0x2001, 0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, + 0xa192, 0x0090, 0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, + 0x6004, 0xa08e, 0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, + 0x7037, 0x0103, 0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, + 0x001e, 0x0009, 0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, + 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, + 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, + 0x1a0c, 0x151a, 0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0xa14e, + 0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0xa0fe, + 0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x9f44, + 0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x9f5b, + 0x04d8, 0x6604, 0xa6b6, 0x001f, 0x1118, 0x080c, 0x8812, 0x04a0, + 0x6604, 0xa6b6, 0x0000, 0x1118, 0x080c, 0x8a66, 0x0468, 0x6604, + 0xa6b6, 0x0022, 0x1118, 0x080c, 0x883a, 0x0430, 0x6604, 0xa6b6, + 0x0035, 0x1118, 0x080c, 0x88a1, 0x00f8, 0x6604, 0xa6b6, 0x0039, + 0x1118, 0x080c, 0x8a02, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, + 0x080c, 0x8854, 0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, + 0x8874, 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, + 0x0016, 0x1118, 0x0804, 0x8f08, 0x0005, 0x080c, 0x86ef, 0x0ce0, + 0x8d6b, 0x8d6e, 0x8d6b, 0x8db0, 0x8d6b, 0x8e95, 0x8f16, 0x8d6b, + 0x8d6b, 0x8ee4, 0x8d6b, 0x8ef8, 0xa1b6, 0x0048, 0x0140, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005, 0x00e6, + 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, + 0x080c, 0x86a4, 0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, + 0xb600, 0x7084, 0xa086, 0x0074, 0x1530, 0x080c, 0xaf15, 0x11b0, + 0x00d6, 0x6018, 0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, + 0x0110, 0xc0c5, 0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, + 0x4f6f, 0x080c, 0x2cf7, 0x080c, 0x86a4, 0x0078, 0x2001, 0x000a, + 0x080c, 0x4f6f, 0x080c, 0x2cf7, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x6d45, 0x0010, 0x080c, 0x8e82, 0x00ee, 0x0005, 0x6800, + 0xd084, 0x0168, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2069, 0xb652, + 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x4f9c, 0x0005, + 0x00d6, 0x2011, 0xb621, 0x2204, 0xa086, 0x0074, 0x1904, 0x8e7f, + 0x6018, 0x2068, 0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x902e, + 0x0804, 0x8e1e, 0x080c, 0x9024, 0x6018, 0x2068, 0xa080, 0x0028, + 0x2014, 0xa286, 0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, + 0x6010, 0xa005, 0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, + 0x6833, 0x0200, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x080c, 0x2cf7, + 0x080c, 0x86a4, 0x0804, 0x8e80, 0x00e6, 0x2071, 0xb635, 0x2e04, + 0xd09c, 0x0188, 0x2071, 0xbc80, 0x7108, 0x720c, 0xa18c, 0x00ff, + 0x1118, 0xa284, 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, + 0x1110, 0x7112, 0x7216, 0x00ee, 0x6010, 0xa005, 0x0198, 0x2068, + 0x6838, 0xd0f4, 0x0178, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0039, + 0x1958, 0x2001, 0x0000, 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, + 0xa192, 0x0840, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x6003, 0x0001, + 0x6007, 0x0003, 0x080c, 0x6d45, 0x0804, 0x8e80, 0x685c, 0xd0e4, + 0x01d8, 0x080c, 0xa08e, 0x080c, 0x5b41, 0x0118, 0xd0dc, 0x1904, + 0x8dda, 0x2011, 0xb635, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xb88f, + 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x28a7, + 0x78e2, 0x00fe, 0x0804, 0x8dda, 0x080c, 0xa0c4, 0x2011, 0xb635, + 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xb037, 0x000e, 0x1904, + 0x8dda, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x2001, + 0x0000, 0x080c, 0x4f5d, 0x00c6, 0x2009, 0x00ef, 0x00f6, 0x2079, + 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe, 0x080c, 0x287c, 0x00f6, + 0x2079, 0xb600, 0x7976, 0x2100, 0x2009, 0x0000, 0x080c, 0x2852, + 0x7952, 0x00fe, 0x8108, 0x080c, 0x4fbf, 0x2c00, 0x00ce, 0x1904, + 0x8dda, 0x601a, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x601f, 0x0001, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x0008, 0x0011, + 0x00de, 0x0005, 0x2001, 0x0007, 0x080c, 0x4f6f, 0x2001, 0xb600, + 0x2004, 0xa086, 0x0003, 0x1120, 0x2001, 0x0007, 0x080c, 0x4f9c, + 0x080c, 0x2cf7, 0x080c, 0x86a4, 0x0005, 0x00e6, 0x0026, 0x0016, + 0x2071, 0xb600, 0x7084, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, + 0x0003, 0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3f85, 0x00d6, + 0x6018, 0x2068, 0x080c, 0x50bd, 0x080c, 0x8d9f, 0x00de, 0x080c, + 0x90dd, 0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, + 0x0518, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x00e6, 0x6010, 0xa075, + 0x01a8, 0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, + 0x0000, 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0xa192, 0x0030, + 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, + 0x2cf7, 0x080c, 0x86a4, 0x0020, 0x080c, 0x8ca5, 0x080c, 0x8e82, + 0x001e, 0x002e, 0x00ee, 0x0005, 0x2011, 0xb621, 0x2204, 0xa086, + 0x0014, 0x1158, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x6d45, 0x0010, 0x080c, 0x8e82, 0x0005, + 0x2011, 0xb621, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, + 0x080c, 0x4f6f, 0x080c, 0x86a4, 0x0010, 0x080c, 0x8e82, 0x0005, + 0x000b, 0x0005, 0x8d6b, 0x8f21, 0x8d6b, 0x8f55, 0x8d6b, 0x8fe0, + 0x8f16, 0x8d6b, 0x8d6b, 0x8ff3, 0x8d6b, 0x9003, 0x6604, 0xa686, + 0x0003, 0x0904, 0x8e95, 0xa6b6, 0x001e, 0x1110, 0x080c, 0x86a4, + 0x0005, 0x00d6, 0x00c6, 0x080c, 0x9013, 0x1178, 0x2001, 0x0000, + 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001, + 0x6007, 0x0002, 0x080c, 0x6d45, 0x00e8, 0x2009, 0xbc8e, 0x2104, + 0xa086, 0x0009, 0x1160, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, + 0xa005, 0x0170, 0x8001, 0x6842, 0x6017, 0x000a, 0x0058, 0x2009, + 0xbc8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x1108, 0x08d0, + 0x080c, 0x8e82, 0x00ce, 0x00de, 0x0005, 0x0026, 0x2011, 0x0000, + 0x080c, 0x9021, 0x00d6, 0x2069, 0xb89e, 0x2d04, 0xa005, 0x0168, + 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138, 0x2069, 0xb61d, + 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, + 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x0480, 0x00d6, 0x6010, + 0x2068, 0x080c, 0x9d16, 0x00de, 0x0108, 0x6a34, 0x080c, 0x8ca5, + 0x2009, 0xbc8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0500, + 0xa686, 0x000b, 0x01c8, 0x2009, 0xbc8f, 0x2104, 0xa084, 0xff00, + 0x1118, 0xa686, 0x0009, 0x01a0, 0xa086, 0x1900, 0x1168, 0xa686, + 0x0009, 0x0170, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x2001, 0x0028, + 0x6016, 0x6007, 0x004b, 0x0010, 0x080c, 0x8e82, 0x002e, 0x0005, + 0x00d6, 0xa286, 0x0139, 0x0160, 0x6010, 0x2068, 0x080c, 0x9d16, + 0x0148, 0x6834, 0xa086, 0x0139, 0x0118, 0x6838, 0xd0fc, 0x0110, + 0x00de, 0x0c50, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, + 0x0140, 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, + 0x08e8, 0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xb600, + 0x080c, 0x4c28, 0x00ee, 0x0010, 0x080c, 0x2cd1, 0x00de, 0x0860, + 0x080c, 0x9021, 0x1158, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x6003, + 0x0001, 0x6007, 0x0003, 0x080c, 0x6d45, 0x0020, 0x080c, 0x8ca5, + 0x080c, 0x8e82, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, + 0x4f6f, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x6d45, 0x0010, + 0x080c, 0x8e82, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, + 0x4f6f, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6d45, 0x0010, + 0x080c, 0x8e82, 0x0005, 0x2009, 0xbc8e, 0x2104, 0xa086, 0x0003, + 0x1138, 0x2009, 0xbc8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, + 0x0005, 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, + 0x2164, 0x080c, 0x502a, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, + 0x00d6, 0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xb635, 0x2e04, + 0xa085, 0x0003, 0x2072, 0x080c, 0x90b2, 0x0560, 0x2009, 0xb635, + 0x2104, 0xc0cd, 0x200a, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0158, + 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xb1a4, 0x2001, 0xb60c, + 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, + 0x2ca4, 0x2071, 0xb600, 0x080c, 0x2aed, 0x00c6, 0x0156, 0x20a9, + 0x0081, 0x2009, 0x007f, 0x080c, 0x2dcc, 0x8108, 0x1f04, 0x9063, + 0x015e, 0x00ce, 0x080c, 0x9024, 0x6813, 0x00ff, 0x6817, 0xfffe, + 0x2071, 0xbc80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, + 0xb61c, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0xb61d, + 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084, 0xff00, 0x001e, + 0xa105, 0x2009, 0xb628, 0x200a, 0x2200, 0xa084, 0x00ff, 0x2008, + 0x080c, 0x287c, 0x080c, 0x5b41, 0x0170, 0x2069, 0xbc8e, 0x2071, + 0xb8b2, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818, 0x700a, 0x681c, + 0x700e, 0x080c, 0xa08e, 0x0040, 0x2001, 0x0006, 0x080c, 0x4f6f, + 0x080c, 0x2cf7, 0x080c, 0x86a4, 0x001e, 0x003e, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0xb628, + 0x231c, 0x83ff, 0x01e8, 0x2071, 0xbc80, 0x2e14, 0xa294, 0x00ff, + 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190, 0x2011, 0xbc96, + 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1148, 0x2011, + 0xbc9a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1100, + 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0xbc8c, + 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800, 0x1188, + 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086, 0x0100, 0x1138, + 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006, 0x0010, 0xa085, + 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0056, + 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0xb8ea, + 0x252c, 0x2021, 0xb8f0, 0x2424, 0x2061, 0xbe00, 0x2071, 0xb600, + 0x7248, 0x7068, 0xa202, 0x16f0, 0x080c, 0xb1cc, 0x05a0, 0x671c, + 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568, 0x2500, 0xac06, + 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000, 0xa086, 0x0004, + 0x1110, 0x080c, 0x1952, 0xa786, 0x0008, 0x1148, 0x080c, 0x9f14, + 0x1130, 0x00ce, 0x080c, 0x8ca5, 0x080c, 0x9ed9, 0x00a0, 0x6010, + 0x2068, 0x080c, 0x9d16, 0x0160, 0xa786, 0x0003, 0x11e8, 0x6837, + 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, + 0x080c, 0x9ed9, 0x00ce, 0xace0, 0x0018, 0x705c, 0xac02, 0x1210, + 0x0804, 0x9110, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006, 0x1118, 0x080c, + 0xb155, 0x0c30, 0xa786, 0x000a, 0x09e0, 0x08c8, 0x220c, 0x2304, + 0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x9166, 0xa006, 0x0005, + 0x2304, 0xa102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, + 0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x151a, + 0x080c, 0x9f03, 0x0120, 0x080c, 0x9f14, 0x0168, 0x0028, 0x080c, + 0x2cf7, 0x080c, 0x9f14, 0x0138, 0x080c, 0x7102, 0x080c, 0x86a4, + 0x080c, 0x71e5, 0x0005, 0x080c, 0x8ca5, 0x0cb0, 0xa182, 0x0040, + 0x0002, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac, + 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ae, 0x91ae, 0x91ae, 0x91ae, + 0x91ac, 0x91ac, 0x91ac, 0x91ae, 0x080c, 0x151a, 0x600b, 0xffff, + 0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091, 0x8000, + 0x080c, 0x71e5, 0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, + 0xa082, 0x0040, 0x0804, 0x9248, 0xa186, 0x0027, 0x11e8, 0x080c, + 0x7102, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16, + 0x0168, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, + 0xc1c5, 0x694e, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, + 0x86a4, 0x080c, 0x71e5, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, + 0xa082, 0x0040, 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, + 0x0120, 0xa186, 0x0047, 0x190c, 0x151a, 0x2001, 0x0109, 0x2004, + 0xd084, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, + 0x080c, 0x6be6, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, + 0xa086, 0x0002, 0x1110, 0x0804, 0x9286, 0x080c, 0x86ef, 0x0005, + 0x0002, 0x9226, 0x9224, 0x9224, 0x9224, 0x9224, 0x9224, 0x9224, + 0x9224, 0x9224, 0x9224, 0x9224, 0x9241, 0x9241, 0x9241, 0x9241, + 0x9224, 0x9241, 0x9224, 0x9241, 0x080c, 0x151a, 0x080c, 0x7102, + 0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16, 0x0168, 0x6837, 0x0103, + 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, + 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5, + 0x0005, 0x080c, 0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, + 0x0002, 0x925e, 0x925c, 0x925c, 0x925c, 0x925c, 0x925c, 0x925c, + 0x925c, 0x925c, 0x925c, 0x925c, 0x9270, 0x9270, 0x9270, 0x9270, + 0x925c, 0x927f, 0x925c, 0x9270, 0x080c, 0x151a, 0x080c, 0x7102, + 0x2001, 0xb8b8, 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x71e5, + 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, + 0x080c, 0x7102, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x2001, 0xb8b8, + 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x71e5, 0x0005, 0x080c, + 0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0040, + 0x0002, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929e, 0x9386, + 0x93b5, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, + 0x929c, 0x929c, 0x929c, 0x929c, 0x080c, 0x151a, 0x00e6, 0x00d6, + 0x603f, 0x0000, 0x2071, 0xbc80, 0x7124, 0x610a, 0x2071, 0xbc8c, + 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0904, 0x934c, + 0xa68c, 0x0c00, 0x0518, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, + 0x01c8, 0x684c, 0xd0ac, 0x01b0, 0x6020, 0xd0dc, 0x1198, 0x6850, + 0xd0bc, 0x1180, 0x7318, 0x6814, 0xa306, 0x1904, 0x935f, 0x731c, + 0x6810, 0xa31e, 0x0138, 0xd6d4, 0x0904, 0x935f, 0x6b14, 0xa305, + 0x1904, 0x935f, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, + 0xa186, 0x0002, 0x0518, 0xa186, 0x0028, 0x1128, 0x080c, 0x9ef2, + 0x684b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0x684b, 0x0015, 0x684c, + 0xd0ac, 0x0170, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0148, 0x7018, + 0xa106, 0x1118, 0x701c, 0xa206, 0x0118, 0x6962, 0x6a5e, 0xc6dc, + 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, + 0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x01f0, 0xa686, 0x0100, + 0x1140, 0x2001, 0xbc99, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x0804, + 0x92ad, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, 0x0009, + 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xbc98, 0xad90, + 0x0019, 0x080c, 0x99c9, 0x003e, 0xd6cc, 0x0904, 0x9375, 0x7124, + 0x695a, 0x81ff, 0x0904, 0x9375, 0xa192, 0x0021, 0x1260, 0x2071, + 0xbc98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x99c9, + 0x080c, 0xa1f3, 0x04d0, 0x6838, 0xd0fc, 0x0120, 0x2009, 0x0020, + 0x695a, 0x0c68, 0x00f6, 0x2d78, 0x080c, 0x996e, 0x00fe, 0x080c, + 0xa1f3, 0x080c, 0x99b9, 0x0458, 0x00f6, 0x2c78, 0x080c, 0x5377, + 0x00fe, 0x0190, 0x684c, 0xd0ac, 0x0178, 0x6020, 0xd0dc, 0x1160, + 0x6850, 0xd0bc, 0x1148, 0x6810, 0x6914, 0xa105, 0x0128, 0x080c, + 0x9ff1, 0x00de, 0x00ee, 0x0408, 0x684b, 0x0000, 0x6837, 0x0103, + 0x6e46, 0x080c, 0x9523, 0x1148, 0x684c, 0xd0ac, 0x0130, 0x6810, + 0x6914, 0xa115, 0x0110, 0x080c, 0x953f, 0x080c, 0x547a, 0x6218, + 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x080c, 0x9fbf, + 0x00de, 0x00ee, 0x1110, 0x080c, 0x86a4, 0x0005, 0x00f6, 0x6003, + 0x0003, 0x2079, 0xbc8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, + 0x2078, 0x784c, 0xd0ac, 0x0138, 0x6003, 0x0002, 0x00fe, 0x0005, + 0x2130, 0x2228, 0x0058, 0x2400, 0x797c, 0xa10a, 0x2300, 0x7a80, + 0xa213, 0x2600, 0xa102, 0x2500, 0xa203, 0x0e90, 0x7c12, 0x7b16, + 0x7e0a, 0x7d0e, 0x00fe, 0x603f, 0x0000, 0x2c10, 0x080c, 0x1fc5, + 0x080c, 0x6d62, 0x080c, 0x72a2, 0x0005, 0x2001, 0xb8b8, 0x2004, + 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x080c, 0x1863, 0x0005, 0xa182, 0x0040, 0x0002, 0x93da, + 0x93da, 0x93da, 0x93da, 0x93da, 0x93dc, 0x946f, 0x93da, 0x93da, + 0x9485, 0x94eb, 0x93da, 0x93da, 0x93da, 0x93da, 0x9509, 0x93da, + 0x93da, 0x93da, 0x080c, 0x151a, 0x0076, 0x00f6, 0x00e6, 0x00d6, + 0x2071, 0xbc8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, + 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, + 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x946a, 0xa694, 0xff00, 0xa284, + 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, + 0x0904, 0x946a, 0x080c, 0x15fd, 0x090c, 0x151a, 0x2d00, 0x784a, + 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, + 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, + 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, + 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, + 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, + 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, + 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, + 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xbc98, + 0xad90, 0x0019, 0x080c, 0x99c9, 0x003e, 0xd6cc, 0x01d8, 0x7124, + 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xbc98, + 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x99c9, 0x0050, + 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, + 0x080c, 0x996e, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6, + 0x6003, 0x0003, 0x2079, 0xbc8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, + 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, + 0x080c, 0x1fc5, 0x080c, 0x7dd9, 0x0005, 0x00d6, 0x00f6, 0x2c78, + 0x080c, 0x5377, 0x00fe, 0x0120, 0x2001, 0xb8b8, 0x2004, 0x603e, + 0x6003, 0x0002, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6110, 0x2168, + 0x694c, 0xd1e4, 0x0904, 0x94e9, 0xd1cc, 0x0540, 0x6948, 0x6838, + 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850, 0x0006, 0xad90, + 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, + 0x2012, 0x8318, 0x8210, 0x1f04, 0x94af, 0x015e, 0x000e, 0x6852, + 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1624, 0x0428, 0x0016, + 0x080c, 0x1624, 0x00de, 0x080c, 0x99b9, 0x00f0, 0x6837, 0x0103, + 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028, + 0x1118, 0x684b, 0x001c, 0x0070, 0xd1dc, 0x0118, 0x684b, 0x0015, + 0x0048, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0020, 0x684b, 0x0000, + 0x080c, 0x9523, 0x080c, 0x547a, 0x080c, 0x9fbf, 0x1110, 0x080c, + 0x86a4, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x806b, 0x6003, + 0x0002, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0140, 0x6808, + 0x612c, 0xa10a, 0x612e, 0x680c, 0x6128, 0xa10b, 0x612a, 0x00de, + 0x2001, 0xb8b8, 0x2004, 0x603e, 0x080c, 0x7198, 0x080c, 0x72a2, + 0x0005, 0x080c, 0x7198, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168, + 0x080c, 0x9d16, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, + 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4, + 0x080c, 0x72a2, 0x0005, 0x684c, 0xd0b4, 0x01c0, 0x602c, 0x697c, + 0xa112, 0x6028, 0x6980, 0xa10b, 0x2100, 0xa205, 0x0168, 0x684b, + 0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8212, 0x8210, 0x810a, + 0xa189, 0x0000, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x0005, 0x684b, + 0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, + 0xa189, 0x0000, 0x6962, 0x685e, 0x0005, 0xa182, 0x0040, 0x0002, + 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9565, 0x9563, 0x9620, + 0x962c, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, + 0x9563, 0x9563, 0x9563, 0x080c, 0x151a, 0x0076, 0x00f6, 0x00e6, + 0x00d6, 0x2071, 0xbc8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, + 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x0150, 0xa684, 0x00ff, + 0x1138, 0x6020, 0xd0f4, 0x0120, 0x080c, 0x9ff1, 0x0804, 0x961b, + 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, + 0x0110, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x9611, 0xa694, 0xff00, + 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, + 0x0300, 0x0904, 0x960f, 0xa686, 0x0100, 0x1140, 0x2001, 0xbc99, + 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x15fd, + 0x090c, 0x151a, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, + 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, + 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, + 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, + 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, + 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, + 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, + 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0xbc98, 0xad90, 0x0019, 0x080c, + 0x99c9, 0x003e, 0xd6cc, 0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, + 0xa192, 0x0021, 0x1250, 0x2071, 0xbc98, 0x831c, 0x2300, 0xae18, + 0xad90, 0x001d, 0x080c, 0x99c9, 0x0050, 0x7838, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x996e, 0xd6dc, + 0x1110, 0xa006, 0x0030, 0x2001, 0x0001, 0x2071, 0xbc8c, 0x7218, + 0x731c, 0x080c, 0x18b6, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, + 0x2001, 0xb8b8, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20, + 0x2c10, 0x080c, 0x1863, 0x0005, 0x2001, 0xb8b8, 0x2004, 0x603e, + 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, + 0x9737, 0x603f, 0x0000, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, + 0x0560, 0x6814, 0x6910, 0xa115, 0x0540, 0x6a60, 0xa206, 0x1118, + 0x685c, 0xa106, 0x0510, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, + 0x6863, 0x0000, 0x685f, 0x0000, 0x6020, 0xd0f4, 0x1158, 0x697c, + 0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020, + 0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e, + 0x00de, 0x080c, 0x9ff1, 0x0804, 0x9737, 0x694c, 0xd1cc, 0x0904, + 0x9707, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x96ca, 0x0016, 0x684c, + 0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, + 0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, + 0x0015, 0x080c, 0xa17b, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, + 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, + 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f, + 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d, + 0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012, + 0x8318, 0x8210, 0x1f04, 0x96b6, 0x015e, 0x00fe, 0x000e, 0x6852, + 0x000e, 0x684e, 0x080c, 0xa1f3, 0x001e, 0x2168, 0x080c, 0x1624, + 0x0804, 0x9732, 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, + 0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, + 0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, + 0x0015, 0x080c, 0xa17b, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, + 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, + 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f, + 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, + 0x1624, 0x00de, 0x080c, 0xa1f3, 0x080c, 0x99b9, 0x0458, 0x6837, + 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01b0, 0xa086, + 0x0028, 0x1118, 0x684b, 0x001c, 0x00d8, 0xd1dc, 0x0148, 0x684b, + 0x0015, 0x080c, 0xa17b, 0x0118, 0x6944, 0xc1dc, 0x6946, 0x0080, + 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b, 0x0000, 0x684c, + 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f, + 0x080c, 0x547a, 0x080c, 0x9fbf, 0x1110, 0x080c, 0x86a4, 0x00de, + 0x0005, 0x080c, 0x7102, 0x0010, 0x080c, 0x7198, 0x080c, 0x9d16, + 0x01c0, 0x00d6, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xb60c, + 0x210c, 0xd18c, 0x11c0, 0xd184, 0x1198, 0x6108, 0x694a, 0xa18e, + 0x0029, 0x1110, 0x080c, 0xb43c, 0x6847, 0x0000, 0x080c, 0x547a, + 0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x080c, 0x72a2, 0x0005, + 0x684b, 0x0004, 0x0c88, 0x684b, 0x0004, 0x0c70, 0xa182, 0x0040, + 0x0002, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977e, 0x977c, + 0x9781, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, + 0x977c, 0x977c, 0x977c, 0x977c, 0x080c, 0x151a, 0x080c, 0x86a4, + 0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x1863, 0x002e, 0x000e, + 0x0005, 0xa182, 0x0085, 0x0002, 0x9795, 0x9793, 0x9793, 0x97a1, + 0x9793, 0x9793, 0x9793, 0x080c, 0x151a, 0x6003, 0x0001, 0x6106, + 0x080c, 0x6cff, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e, + 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0xbc80, 0x7224, + 0x6212, 0x7220, 0x080c, 0x9d06, 0x01a0, 0x2268, 0x6800, 0xa086, + 0x0000, 0x0178, 0x6018, 0x6d18, 0xa52e, 0x1158, 0x00c6, 0x2d60, + 0x080c, 0x99d9, 0x00ce, 0x0128, 0x6803, 0x0002, 0x6007, 0x0086, + 0x0010, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, + 0x71e5, 0x00f6, 0x2278, 0x080c, 0x5377, 0x00fe, 0x0150, 0x6820, + 0xd0ec, 0x0138, 0x00c6, 0x2260, 0x603f, 0x0000, 0x080c, 0x9ff1, + 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0xa186, 0x0013, + 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c, + 0x1a0c, 0x151a, 0xa082, 0x0085, 0x0072, 0xa186, 0x0027, 0x0120, + 0xa186, 0x0014, 0x190c, 0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9, + 0x080c, 0x71e5, 0x0005, 0x9802, 0x9804, 0x9804, 0x9802, 0x9802, + 0x9802, 0x9802, 0x080c, 0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9, + 0x080c, 0x71e5, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, + 0x0085, 0x2008, 0x04a8, 0xa186, 0x0027, 0x11e8, 0x080c, 0x7102, + 0x080c, 0x2cd1, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0150, + 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0029, 0x080c, 0x547a, + 0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, + 0x080c, 0x86ef, 0x0ce0, 0xa186, 0x0014, 0x1dd0, 0x080c, 0x7102, + 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0d60, 0x6837, 0x0103, + 0x6847, 0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x08f0, + 0x0002, 0x9852, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x986a, + 0x080c, 0x151a, 0x080c, 0x7102, 0x6030, 0xa08c, 0xff00, 0x810f, + 0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x2001, 0xb8b6, + 0x0010, 0x2001, 0xb8b7, 0x2004, 0x6016, 0x6003, 0x000c, 0x080c, + 0x71e5, 0x0005, 0x080c, 0x7102, 0x6030, 0xa08c, 0xff00, 0x810f, + 0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x2001, 0xb8b6, + 0x0010, 0x2001, 0xb8b7, 0x2004, 0x6016, 0x6003, 0x000e, 0x080c, + 0x71e5, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, + 0x001a, 0x080c, 0x86ef, 0x0005, 0x9893, 0x9893, 0x9893, 0x9893, + 0x9895, 0x98ee, 0x9893, 0x080c, 0x151a, 0x00d6, 0x00f6, 0x2c78, + 0x080c, 0x5377, 0x00fe, 0x0168, 0x6030, 0xa08c, 0xff00, 0x810f, + 0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x00de, 0x0804, + 0x9901, 0x080c, 0x9d16, 0x1118, 0x080c, 0x9ecd, 0x00f0, 0x6010, + 0x2068, 0x684c, 0xd0e4, 0x1110, 0x080c, 0x9ecd, 0x6837, 0x0103, + 0x6850, 0xd0b4, 0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, + 0xd0bc, 0x0118, 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, + 0x9f8e, 0x6847, 0x0000, 0x080c, 0x547a, 0x2c68, 0x080c, 0x864e, + 0x01c0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, + 0xbc8e, 0x210c, 0x6136, 0x2009, 0xbc8f, 0x210c, 0x613a, 0x6918, + 0x611a, 0x080c, 0xa0e3, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, + 0x6cff, 0x2d60, 0x080c, 0x86a4, 0x00de, 0x0005, 0x00f6, 0x2c78, + 0x080c, 0x5377, 0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, + 0xa186, 0x0035, 0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, + 0x1530, 0x00d6, 0x2c68, 0x080c, 0xa1c6, 0x1904, 0x9946, 0x080c, + 0x864e, 0x01d8, 0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, + 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, + 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, + 0xa0e3, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x2d60, 0x00f8, 0x00d6, + 0x6010, 0x2068, 0x080c, 0x9d16, 0x01c8, 0x6837, 0x0103, 0x6850, + 0xd0b4, 0x0128, 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, + 0x0118, 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9f8e, + 0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, + 0x86a4, 0x0005, 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, + 0x0140, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, + 0x547a, 0x00de, 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, + 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x86ef, 0x0030, 0x080c, + 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0x0056, 0x0066, + 0x00d6, 0x00f6, 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, + 0x2009, 0x0100, 0x2130, 0x2069, 0xbc98, 0x831c, 0x2300, 0xad18, + 0x2009, 0x0020, 0xaf90, 0x001d, 0x080c, 0x99c9, 0xa6b2, 0x0020, + 0x7804, 0xa06d, 0x0110, 0x080c, 0x1624, 0x080c, 0x15fd, 0x0500, + 0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, + 0x003d, 0x1228, 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, + 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, + 0x00fe, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, + 0x00fe, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, + 0x0005, 0x00f6, 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, + 0x0000, 0x080c, 0x547a, 0x2f68, 0x0cb8, 0x080c, 0x547a, 0x00fe, + 0x0005, 0x0156, 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, + 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x1f04, 0x99d0, 0x015e, + 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, + 0xa084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x0066, 0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, + 0x006e, 0x012e, 0x0005, 0x9a10, 0x9a10, 0x9a0b, 0x9a32, 0x99fe, + 0x9a0b, 0x9a32, 0x9a0b, 0x9a0b, 0x99fe, 0x9a0b, 0x080c, 0x151a, + 0x0036, 0x2019, 0x0010, 0x080c, 0xad9c, 0x601f, 0x0006, 0x6003, + 0x0007, 0x003e, 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, + 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068, 0x080c, 0x9d16, 0x01c0, + 0x6834, 0xa086, 0x0139, 0x1128, 0x684b, 0x0005, 0x6853, 0x0000, + 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c, 0x554d, 0x080c, 0x9f8e, + 0x080c, 0x547a, 0x080c, 0x86a4, 0xa085, 0x0001, 0x00de, 0x0005, + 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b, + 0x0005, 0x9a49, 0x9a6a, 0x9a4b, 0x9a89, 0x9a67, 0x9a49, 0x9a0b, + 0x9a10, 0x9a10, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b, + 0x9a0b, 0x080c, 0x151a, 0x86ff, 0x11b8, 0x601c, 0xa086, 0x0006, + 0x0198, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, + 0x9f8e, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, + 0x080c, 0x6cff, 0x080c, 0x71e5, 0xa085, 0x0001, 0x0005, 0x080c, + 0x1952, 0x0c08, 0x00e6, 0x2071, 0xb8e1, 0x7024, 0xac06, 0x1110, + 0x080c, 0x7fe0, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, + 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x81b7, 0x009e, + 0x008e, 0x0010, 0x080c, 0x7ed1, 0x00ee, 0x1928, 0x080c, 0x9a0b, + 0x0005, 0x0036, 0x00e6, 0x2071, 0xb8e1, 0x703c, 0xac06, 0x1140, + 0x2019, 0x0000, 0x080c, 0x806b, 0x00ee, 0x003e, 0x0804, 0x9a4b, + 0x080c, 0x82e4, 0x00ee, 0x003e, 0x1904, 0x9a4b, 0x080c, 0x9a0b, + 0x0005, 0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, + 0x9aba, 0x9b27, 0x9c75, 0x9ac5, 0x9ed9, 0x9aba, 0xad8e, 0xa20a, + 0x9b27, 0x9ab3, 0x9ce0, 0x080c, 0x151a, 0x080c, 0x9f14, 0x1110, + 0x080c, 0x8ca5, 0x0005, 0x080c, 0x7102, 0x080c, 0x71e5, 0x080c, + 0x86a4, 0x0005, 0x6017, 0x0001, 0x0005, 0x080c, 0x9d16, 0x0120, + 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a, 0x0010, 0x1a0c, + 0x151a, 0x000b, 0x0005, 0x9ae3, 0x9ae5, 0x9b05, 0x9b17, 0x9b24, + 0x9ae3, 0x9aba, 0x9aba, 0x9aba, 0x9b17, 0x9b17, 0x9ae3, 0x9ae3, + 0x9ae3, 0x9ae3, 0x9b21, 0x080c, 0x151a, 0x00e6, 0x6010, 0x2070, + 0x7050, 0xc0b5, 0x7052, 0x2071, 0xb8e1, 0x7024, 0xac06, 0x0190, + 0x080c, 0x7ed1, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, + 0x2001, 0xb8b7, 0x2004, 0x6016, 0x080c, 0x6cff, 0x080c, 0x71e5, + 0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8, 0x00d6, 0x6010, 0x2068, + 0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, + 0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0005, 0x00d6, + 0x6017, 0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, + 0x0005, 0x080c, 0x86a4, 0x0005, 0x080c, 0x1952, 0x08f0, 0x6000, + 0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9b3e, 0x9ac2, + 0x9b40, 0x9b3e, 0x9b40, 0x9b40, 0x9abb, 0x9b3e, 0x9ab5, 0x9ab5, + 0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x080c, 0x151a, + 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa08a, + 0x000c, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9b59, 0x9c1b, 0x9b5b, + 0x9b99, 0x9b5b, 0x9b99, 0x9b5b, 0x9b69, 0x9b59, 0x9b99, 0x9b59, + 0x9b85, 0x080c, 0x151a, 0x6004, 0xa08e, 0x0016, 0x05a8, 0xa08e, + 0x0004, 0x0590, 0xa08e, 0x0002, 0x0578, 0xa08e, 0x004b, 0x0904, + 0x9c17, 0x6004, 0x080c, 0x9f14, 0x0904, 0x9c34, 0xa08e, 0x0021, + 0x0904, 0x9c38, 0xa08e, 0x0022, 0x0904, 0x9c34, 0xa08e, 0x003d, + 0x0904, 0x9c38, 0xa08e, 0x0039, 0x0904, 0x9c3c, 0xa08e, 0x0035, + 0x0904, 0x9c3c, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150, + 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086, + 0x0006, 0x0110, 0x080c, 0x2cd1, 0x080c, 0x8ca5, 0x080c, 0x9ed9, + 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9c08, + 0xa186, 0x0002, 0x15d8, 0x2001, 0xb635, 0x2004, 0xd08c, 0x1198, + 0x080c, 0x5b41, 0x1180, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, + 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b85, 0x080c, + 0x5a79, 0x0804, 0x9c5e, 0x6018, 0x2068, 0x2001, 0xb635, 0x2004, + 0xd0ac, 0x1904, 0x9c5e, 0x68a0, 0xd0bc, 0x1904, 0x9c5e, 0x6840, + 0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000, + 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x864e, + 0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce, + 0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004, + 0xa086, 0x007e, 0x1170, 0x2009, 0xb635, 0x2104, 0xc085, 0x200a, + 0x00e6, 0x2071, 0xb600, 0x080c, 0x4c28, 0x00ee, 0x080c, 0x8ca5, + 0x0020, 0x080c, 0x8ca5, 0x080c, 0x2cd1, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x080c, 0x2cf7, 0x012e, 0x00ee, 0x080c, 0x9ed9, 0x0005, + 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001, 0x6007, 0x0002, + 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00de, 0x00ce, 0x0c80, 0x080c, + 0x2cf7, 0x0804, 0x9b94, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, + 0x0d38, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0904, + 0x9bde, 0x8001, 0x6842, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c, + 0x71e5, 0x00de, 0x00ce, 0x0898, 0x080c, 0x8ca5, 0x0804, 0x9b96, + 0x080c, 0x8cd3, 0x0804, 0x9b96, 0x00d6, 0x2c68, 0x6104, 0x080c, + 0xa1c6, 0x00de, 0x0118, 0x080c, 0x86a4, 0x00b8, 0x6004, 0x8007, + 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, + 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001, 0xb8b7, 0x2004, + 0x6016, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0005, 0x00de, 0x00ce, + 0x080c, 0x8ca5, 0x080c, 0x2cd1, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x080c, 0x2cf7, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0398, + 0x603f, 0x0000, 0x012e, 0x00ee, 0x0005, 0x6000, 0xa08a, 0x0010, + 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c, + 0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c, 0x9aba, 0x9c8c, 0x9ac2, + 0x9c8e, 0x9ac2, 0x9c9b, 0x9c8c, 0x080c, 0x151a, 0x6004, 0xa086, + 0x008b, 0x0148, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x6cff, + 0x080c, 0x71e5, 0x0005, 0x080c, 0x9ecd, 0x080c, 0x9d16, 0x0580, + 0x080c, 0x2cd1, 0x00d6, 0x080c, 0x9d16, 0x0168, 0x6010, 0x2068, + 0x6837, 0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, + 0x6852, 0x080c, 0x547a, 0x2c68, 0x080c, 0x864e, 0x0150, 0x6818, + 0x601a, 0x080c, 0xa0e3, 0x00c6, 0x2d60, 0x080c, 0x9ed9, 0x00ce, + 0x0008, 0x2d60, 0x00de, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, + 0x0001, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x0078, + 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186, + 0x0035, 0x1118, 0x080c, 0x2cd1, 0x08b0, 0x080c, 0x9ed9, 0x0005, + 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9cf7, + 0x9cf7, 0x9cf7, 0x9cf9, 0x9cf9, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, + 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x080c, + 0x151a, 0x080c, 0x82e4, 0x190c, 0x151a, 0x6110, 0x2168, 0x684b, + 0x0006, 0x080c, 0x547a, 0x080c, 0x86a4, 0x0005, 0xa284, 0x0007, + 0x1158, 0xa282, 0xbe00, 0x0240, 0x2001, 0xb617, 0x2004, 0xa202, + 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210, + 0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, + 0x0126, 0x2091, 0x8000, 0x2061, 0xbe00, 0x2071, 0xb600, 0x7348, + 0x7068, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0xa06e, + 0x0148, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x00c6, 0x080c, + 0x86a4, 0x00ce, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0c38, + 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, + 0x0016, 0xa188, 0xb735, 0x210c, 0x81ff, 0x0128, 0x2061, 0xb9f5, + 0x611a, 0x080c, 0x2cd1, 0xa006, 0x0010, 0xa085, 0x0001, 0x001e, + 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, + 0x00c6, 0x080c, 0x864e, 0x005e, 0x0180, 0x6612, 0x651a, 0x080c, + 0xa0e3, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x86d3, 0xa085, + 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, + 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x9f92, + 0x005e, 0x0550, 0x6013, 0x0000, 0x651a, 0x080c, 0xa0e3, 0x601f, + 0x0003, 0x0016, 0x00c6, 0x2560, 0x080c, 0x521c, 0x00ce, 0x080c, + 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c, + 0xaf3e, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x86a4, 0xa085, + 0x0001, 0x0030, 0x2009, 0x004c, 0x080c, 0x86d3, 0xa085, 0x0001, + 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6, + 0x0046, 0x00c6, 0x080c, 0x864e, 0x2c78, 0x00ce, 0x0180, 0x7e12, + 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9e0c, + 0x2f60, 0x2009, 0x004d, 0x080c, 0x86d3, 0xa085, 0x0001, 0x004e, + 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c, + 0x864e, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f, + 0x0003, 0x2021, 0x0005, 0x0481, 0x2f60, 0x2009, 0x004e, 0x080c, + 0x86d3, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, + 0x00c6, 0x0046, 0x00c6, 0x080c, 0x864e, 0x2c78, 0x00ce, 0x01c0, + 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x00a1, + 0x2001, 0xb8a0, 0x2004, 0xd0fc, 0x0120, 0x2f60, 0x080c, 0x86a4, + 0x0028, 0x2f60, 0x2009, 0x0052, 0x080c, 0x86d3, 0xa085, 0x0001, + 0x004e, 0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, + 0x8000, 0x080c, 0x51be, 0x0118, 0x2001, 0x9e11, 0x0028, 0x080c, + 0x518e, 0x0158, 0x2001, 0x9e17, 0x0006, 0xa00e, 0x2400, 0x080c, + 0x554d, 0x080c, 0x547a, 0x000e, 0x0807, 0x2418, 0x080c, 0x70a1, + 0x62a0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, + 0x6e80, 0x008e, 0x080c, 0x6d74, 0x2f08, 0x2648, 0x080c, 0xaf3e, + 0x613c, 0x81ff, 0x090c, 0x6f35, 0x080c, 0x71e5, 0x012e, 0x007e, + 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, + 0x864e, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x080c, 0x86d3, 0xa085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x00c6, 0x080c, 0x864e, 0x001e, 0x0188, 0x660a, + 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, + 0x0021, 0x080c, 0x86d3, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, + 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, + 0x864e, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x86d3, 0xa085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x00c6, 0x080c, 0x9f92, 0x001e, 0x0180, 0x611a, + 0x080c, 0xa0e3, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, + 0x080c, 0x86d3, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, + 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x864e, + 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0001, + 0x2d00, 0x6012, 0x2009, 0x0044, 0x080c, 0x86d3, 0xa085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, + 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, + 0x0005, 0x0006, 0x6000, 0xa086, 0x0000, 0x0190, 0x6013, 0x0000, + 0x601f, 0x0007, 0x2001, 0xb8b6, 0x2004, 0x0006, 0xa082, 0x0051, + 0x000e, 0x0208, 0x8004, 0x6016, 0x080c, 0xb3f6, 0x603f, 0x0000, + 0x000e, 0x0005, 0x0066, 0x00c6, 0x00d6, 0x2031, 0xb653, 0x2634, + 0xd6e4, 0x0128, 0x6618, 0x2660, 0x6e48, 0x080c, 0x5147, 0x00de, + 0x00ce, 0x006e, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, + 0x0140, 0xa08e, 0x0003, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, + 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, + 0x0148, 0x6834, 0xa086, 0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, + 0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x864e, 0x001e, 0x0190, + 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, + 0x2cd1, 0x2009, 0x0028, 0x080c, 0x86d3, 0xa085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, + 0xb621, 0x2204, 0xa086, 0x0074, 0x1148, 0x080c, 0x9024, 0x6003, + 0x0001, 0x6007, 0x0029, 0x080c, 0x6d45, 0x0020, 0x080c, 0x8ca5, + 0x080c, 0x86a4, 0x0005, 0xa186, 0x0016, 0x1128, 0x2001, 0x0004, + 0x080c, 0x4f6f, 0x00e8, 0xa186, 0x0015, 0x11e8, 0x2011, 0xb621, + 0x2204, 0xa086, 0x0014, 0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, + 0x50bd, 0x00de, 0x080c, 0x90dd, 0x1170, 0x00d6, 0x6018, 0x2068, + 0x6890, 0x00de, 0xa005, 0x0138, 0x2001, 0x0006, 0x080c, 0x4f6f, + 0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5, 0x080c, 0x86a4, 0x0005, + 0x6848, 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, + 0x6852, 0x0005, 0x00e6, 0x0126, 0x2071, 0xb600, 0x2091, 0x8000, + 0x7548, 0xa582, 0x0001, 0x0608, 0x704c, 0x2060, 0x6000, 0xa086, + 0x0000, 0x0148, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, + 0x2061, 0xbe00, 0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, + 0x0018, 0x705c, 0xa502, 0x1230, 0x754e, 0xa085, 0x0001, 0x012e, + 0x00ee, 0x0005, 0x704f, 0xbe00, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, + 0x2071, 0xbc8c, 0x7014, 0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, + 0x0001, 0x6007, 0x0050, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ee, + 0x0005, 0x00c6, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x0120, + 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9aba, 0x9fe9, + 0x9fec, 0x9fef, 0xb1e3, 0xb1fe, 0xb201, 0x9aba, 0x9aba, 0x080c, + 0x151a, 0xe000, 0xe000, 0x0005, 0xe000, 0xe000, 0x0005, 0x0009, + 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x0538, 0x080c, 0x864e, + 0x1128, 0x2001, 0xb8b8, 0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, + 0x080c, 0xa0e3, 0x781c, 0xa086, 0x0003, 0x0128, 0x7808, 0x6036, + 0x2f00, 0x603a, 0x0020, 0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, + 0x601f, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7950, 0x6152, + 0x080c, 0x6cff, 0x080c, 0x71e5, 0x2f60, 0x00fe, 0x0005, 0x0016, + 0x00f6, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, + 0x0140, 0xa006, 0x602a, 0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, + 0x6822, 0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, + 0xa103, 0x1e78, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, + 0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6950, + 0x6152, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, + 0x6cff, 0x6803, 0x0002, 0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, + 0x080c, 0x5377, 0x1118, 0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, + 0x1150, 0xc0f5, 0x6022, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c, + 0x6036, 0x080c, 0x1952, 0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, + 0x6004, 0xa08e, 0x0034, 0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, + 0x0036, 0x0188, 0xa08e, 0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, + 0xa08e, 0x0039, 0x0140, 0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, + 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x2001, 0xb8b2, 0x200c, 0x8000, 0x2014, + 0x2001, 0x0032, 0x080c, 0x6bb2, 0x2001, 0xb8b6, 0x82ff, 0x1110, + 0x2011, 0x0014, 0x2202, 0x2001, 0xb8b4, 0x200c, 0x8000, 0x2014, + 0x2071, 0xb88e, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x6bb2, + 0x2001, 0xb8b7, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2009, + 0xb8b8, 0xa280, 0x000a, 0x200a, 0x080c, 0x539c, 0x00ee, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x00e6, 0x2001, 0xb8b6, + 0x2003, 0x0028, 0x2001, 0xb8b7, 0x2003, 0x0014, 0x2071, 0xb88e, + 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xb8b8, 0x2003, 0x001e, + 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054, 0xa06d, 0x0110, 0x080c, + 0x1614, 0x00de, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x00c6, 0x080c, 0x864e, 0x001e, 0x0178, 0x611a, 0x0ca1, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x080c, 0x86d3, 0xa085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6, + 0x00f6, 0x2071, 0xb600, 0xa186, 0x0015, 0x1500, 0x7084, 0xa086, + 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c, 0xd2e4, 0x1160, 0x2c78, + 0x080c, 0x73a3, 0x01d8, 0x7070, 0x6a50, 0xa206, 0x1160, 0x7074, + 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, + 0x0000, 0x080c, 0x2d16, 0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5, + 0x080c, 0x86a4, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x7054, 0x6a54, + 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, + 0x080c, 0x864e, 0x001e, 0x0180, 0x611a, 0x080c, 0xa0e3, 0x601f, + 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043, 0x080c, 0x86d3, 0xa085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6, + 0x00f6, 0x2071, 0xb600, 0xa186, 0x0015, 0x11c0, 0x7084, 0xa086, + 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x080c, 0x73a3, + 0x01a8, 0x7070, 0x6a08, 0xa206, 0x1130, 0x7074, 0x6a0c, 0xa206, + 0x1110, 0x080c, 0x2cd1, 0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5, + 0x080c, 0x86a4, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x7054, 0x6a0c, + 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026, 0x684c, 0xd0ac, 0x0178, + 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150, 0x6860, 0xa106, 0x1118, + 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x002e, + 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310, 0x2368, 0x684a, 0x6952, + 0xa29e, 0x4000, 0x11a0, 0x00c6, 0x6318, 0x2360, 0x2009, 0x0000, + 0x6838, 0xd0f4, 0x1140, 0x080c, 0x52bc, 0x1108, 0xc185, 0x6000, + 0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66, + 0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6, + 0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c, + 0x547a, 0x6013, 0x0000, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, + 0x0016, 0xa186, 0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, + 0x9d06, 0x01f0, 0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, + 0x0006, 0x1190, 0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, + 0x6108, 0x6834, 0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, + 0x1118, 0x6018, 0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, + 0xa085, 0x0001, 0x0cc8, 0x6944, 0xd1cc, 0x0198, 0xa18c, 0x00ff, + 0xa18e, 0x0002, 0x1170, 0xad88, 0x001e, 0x210c, 0xa18c, 0x0f00, + 0x810f, 0xa18e, 0x0001, 0x1128, 0x6810, 0x6914, 0xa115, 0x190c, + 0x953f, 0x0005, 0x080c, 0x86a4, 0x0804, 0x71e5, 0x0066, 0x6000, + 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0xa227, + 0xa702, 0xa828, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0xa25f, + 0xa8ac, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0x080c, + 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, + 0x006e, 0x0005, 0xa242, 0xad33, 0xa242, 0xa242, 0xa242, 0xa242, + 0xa242, 0xa242, 0xacf5, 0xad7b, 0xa242, 0xb328, 0xb358, 0xb328, + 0xb358, 0xa242, 0x080c, 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, + 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0xa25d, 0xa9fc, 0xaac9, + 0xaaf6, 0xab7a, 0xa25d, 0xac67, 0xac12, 0xa8b8, 0xaccb, 0xace0, + 0xa25d, 0xa25d, 0xa25d, 0xa25d, 0xa25d, 0x080c, 0x151a, 0xa1b2, + 0x0080, 0x1a0c, 0x151a, 0x2100, 0xa1b2, 0x0040, 0x1a04, 0xa676, + 0x0002, 0xa2a9, 0xa474, 0xa2a9, 0xa2a9, 0xa2a9, 0xa47b, 0xa2a9, + 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, + 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, + 0xa2ab, 0xa309, 0xa318, 0xa366, 0xa384, 0xa402, 0xa461, 0xa2a9, + 0xa2a9, 0xa47e, 0xa2a9, 0xa2a9, 0xa491, 0xa49c, 0xa2a9, 0xa2a9, + 0xa2a9, 0xa2a9, 0xa2a9, 0xa527, 0xa2a9, 0xa2a9, 0xa53a, 0xa2a9, + 0xa2a9, 0xa4f2, 0xa2a9, 0xa2a9, 0xa2a9, 0xa552, 0xa2a9, 0xa2a9, + 0xa2a9, 0xa5cc, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, + 0xa63d, 0x080c, 0x151a, 0x080c, 0x537b, 0x1150, 0x2001, 0xb635, + 0x2004, 0xd0cc, 0x1128, 0xa084, 0x0009, 0xa086, 0x0008, 0x1140, + 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804, 0xa46f, + 0x080c, 0x536b, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, + 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076, + 0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c, 0xaf3e, 0x007e, + 0x001e, 0x2e60, 0x080c, 0x521c, 0x001e, 0x002e, 0x003e, 0x00ce, + 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x502a, 0x00ce, 0xa6b0, + 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278, 0x080c, + 0xae82, 0x1904, 0xa360, 0x080c, 0xae22, 0x1120, 0x6007, 0x0008, + 0x0804, 0xa46f, 0x6007, 0x0009, 0x0804, 0xa46f, 0x080c, 0xb037, + 0x0128, 0x080c, 0xae82, 0x0d78, 0x0804, 0xa360, 0x6013, 0x1900, + 0x0c88, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6106, 0x080c, 0xaddc, + 0x6007, 0x0006, 0x0804, 0xa46f, 0x6007, 0x0007, 0x0804, 0xa46f, + 0x080c, 0xb38c, 0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673, + 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082, 0x0006, + 0x1220, 0x2001, 0x0001, 0x080c, 0x4f5d, 0xa6b4, 0xff00, 0x8637, + 0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4, + 0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686, + 0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xaee0, 0x11a0, 0xa686, + 0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, + 0x0000, 0x080c, 0x2d16, 0x002e, 0x080c, 0x50bd, 0x6007, 0x000a, + 0x00de, 0x0804, 0xa46f, 0x6007, 0x000b, 0x00de, 0x0804, 0xa46f, + 0x080c, 0x2cd1, 0x6007, 0x0001, 0x0804, 0xa46f, 0x080c, 0xb38c, + 0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6618, 0x00d6, + 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d50, 0x0026, 0x6218, + 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2d16, 0x002e, + 0x6007, 0x000c, 0x0804, 0xa46f, 0x080c, 0x537b, 0x1140, 0x2001, + 0xb635, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x1110, 0x0804, + 0xa2b8, 0x080c, 0x536b, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, + 0x00ff, 0xa082, 0x0006, 0x06e8, 0x1138, 0x0026, 0x2001, 0x0006, + 0x080c, 0x4f9c, 0x002e, 0x0050, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0xa360, 0x080c, 0xaeed, + 0x1120, 0x6007, 0x000e, 0x0804, 0xa46f, 0x0046, 0x6418, 0xa4a0, + 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046, 0x080c, 0x2cd1, + 0x004e, 0x0016, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4, 0x0158, + 0x2009, 0x0029, 0x080c, 0xb1a4, 0x6018, 0x00d6, 0x2068, 0x6800, + 0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, + 0xa46f, 0x2001, 0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016, 0x0026, + 0x0036, 0x20a9, 0x0004, 0x2019, 0xb605, 0x2011, 0xbc90, 0x080c, + 0x9166, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0168, 0xa6b4, + 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0xa360, 0xa682, 0x0007, + 0x0a04, 0xa3ae, 0x0804, 0xa360, 0x6013, 0x1900, 0x6007, 0x0009, + 0x0804, 0xa46f, 0x080c, 0x537b, 0x1140, 0x2001, 0xb635, 0x2004, + 0xa084, 0x0009, 0xa086, 0x0008, 0x1110, 0x0804, 0xa2b8, 0x080c, + 0x536b, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, + 0x0006, 0x06b8, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, + 0xa686, 0x0006, 0x1904, 0xa360, 0x080c, 0xaf15, 0x1138, 0x080c, + 0xae22, 0x1120, 0x6007, 0x0010, 0x0804, 0xa46f, 0x0046, 0x6418, + 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046, 0x080c, + 0x2cd1, 0x004e, 0x0016, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4, + 0x0158, 0x2009, 0x0029, 0x080c, 0xb1a4, 0x6018, 0x00d6, 0x2068, + 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001, + 0x00f0, 0x080c, 0xb037, 0x0140, 0xa6b4, 0xff00, 0x8637, 0xa686, + 0x0006, 0x0950, 0x0804, 0xa360, 0x6013, 0x1900, 0x6007, 0x0009, + 0x0070, 0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xb38c, 0x1904, + 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6007, 0x0012, 0x6003, + 0x0001, 0x080c, 0x6d45, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x6d45, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xb38c, + 0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b, + 0x1904, 0xa360, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x6d45, + 0x0005, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6007, 0x0023, 0x6003, + 0x0001, 0x080c, 0x6d45, 0x0005, 0x080c, 0xb38c, 0x1904, 0xa673, + 0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, + 0x0016, 0x0026, 0x2011, 0xbc91, 0x2214, 0xa286, 0xffff, 0x0190, + 0x2c08, 0x080c, 0x9d06, 0x01e0, 0x2260, 0x2011, 0xbc90, 0x2214, + 0x6008, 0xa206, 0x11a8, 0x6018, 0xa190, 0x0006, 0x2214, 0xa206, + 0x01e8, 0x0070, 0x2011, 0xbc90, 0x2214, 0x2c08, 0xa006, 0x080c, + 0xb176, 0x11a0, 0x2011, 0xbc91, 0x2214, 0xa286, 0xffff, 0x01c0, + 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xbc89, 0x2214, + 0xa296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x601c, 0xa086, + 0x0007, 0x1d70, 0x6004, 0xa086, 0x0024, 0x1110, 0x080c, 0x86a4, + 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x6d45, 0x002e, + 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016, + 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0xb605, 0x2011, 0xbc96, + 0x080c, 0x9166, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, + 0x0031, 0x0804, 0xa46f, 0x080c, 0x8e82, 0x080c, 0x5b41, 0x11b0, + 0x0006, 0x0026, 0x0036, 0x080c, 0x5b5d, 0x1158, 0x2001, 0xb89f, + 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0x080c, 0x5a79, + 0x0010, 0x080c, 0x5b18, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, + 0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6106, + 0x080c, 0xa6b7, 0x6007, 0x002b, 0x0804, 0xa46f, 0x6007, 0x002c, + 0x0804, 0xa46f, 0x080c, 0xb38c, 0x1904, 0xa673, 0x080c, 0x2df4, + 0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6106, 0x080c, + 0xa6bb, 0x1120, 0x6007, 0x002e, 0x0804, 0xa46f, 0x6007, 0x002f, + 0x0804, 0xa46f, 0x080c, 0x2df4, 0x1904, 0xa673, 0x00e6, 0x00d6, + 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c, 0xa184, 0x00ff, 0xa086, + 0x0006, 0x0158, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006, 0x0128, + 0x00ce, 0x00de, 0x00ee, 0x0804, 0xa474, 0x2001, 0xb672, 0x2004, + 0xd0e4, 0x0904, 0xa5c9, 0x2071, 0xbc8c, 0x7010, 0x6036, 0x7014, + 0x603a, 0x7108, 0x720c, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0140, + 0x6018, 0x2068, 0x6810, 0xa106, 0x1118, 0x6814, 0xa206, 0x01f8, + 0x2001, 0xb653, 0x2004, 0xd0ac, 0x1590, 0x2069, 0xb600, 0x6874, + 0xa206, 0x1568, 0x6870, 0xa106, 0x1550, 0x7210, 0x080c, 0x9d06, + 0x0558, 0x080c, 0xb210, 0x0540, 0x622a, 0x6007, 0x0036, 0x6003, + 0x0001, 0x080c, 0x6cff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, + 0xa286, 0xffff, 0x0150, 0x080c, 0x9d06, 0x01b0, 0xa280, 0x0002, + 0x2004, 0x7110, 0xa106, 0x1180, 0x0c08, 0x7210, 0x2c08, 0xa085, + 0x0001, 0x080c, 0xb176, 0x2c10, 0x2160, 0x0130, 0x08b8, 0x6007, + 0x0037, 0x6013, 0x1500, 0x08d8, 0x6007, 0x0037, 0x6013, 0x1700, + 0x08b0, 0x6007, 0x0012, 0x0898, 0x080c, 0x2df4, 0x1904, 0xa673, + 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007, 0xa086, + 0x0006, 0x1904, 0xa474, 0x00e6, 0x00d6, 0x00c6, 0x2001, 0xb672, + 0x2004, 0xd0e4, 0x0904, 0xa635, 0x2069, 0xb600, 0x2071, 0xbc8c, + 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x1150, 0x7208, + 0x00c6, 0x2c08, 0xa085, 0x0001, 0x080c, 0xb176, 0x2c10, 0x00ce, + 0x0588, 0x080c, 0x9d06, 0x0570, 0x00c6, 0x0026, 0x2260, 0x080c, + 0x99d9, 0x002e, 0x00ce, 0x7118, 0xa18c, 0xff00, 0x810f, 0xa186, + 0x0001, 0x0158, 0xa186, 0x0005, 0x0118, 0xa186, 0x0007, 0x1178, + 0xa280, 0x0004, 0x2004, 0xa005, 0x0150, 0x0056, 0x7510, 0x7614, + 0x080c, 0xb227, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, + 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x080c, + 0x6cff, 0x0c88, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, + 0x6003, 0x0001, 0x080c, 0x6cff, 0x0c30, 0x6007, 0x003b, 0x602b, + 0x000b, 0x6013, 0x0000, 0x0804, 0xa59f, 0x00e6, 0x0026, 0x080c, + 0x537b, 0x0558, 0x080c, 0x536b, 0x080c, 0xb407, 0x1520, 0x2071, + 0xb600, 0x70d4, 0xc085, 0x70d6, 0x00f6, 0x2079, 0x0100, 0x72a0, + 0xa284, 0x00ff, 0x7072, 0x78e6, 0xa284, 0xff00, 0x7274, 0xa205, + 0x7076, 0x78ea, 0x00fe, 0x70df, 0x0000, 0x2001, 0xb653, 0x2004, + 0xd0a4, 0x0120, 0x2011, 0xb8fa, 0x2013, 0x07d0, 0xd0ac, 0x1128, + 0x080c, 0x2aed, 0x0010, 0x080c, 0xb433, 0x002e, 0x00ee, 0x080c, + 0x86a4, 0x0804, 0xa473, 0x080c, 0x86a4, 0x0005, 0x2600, 0x0002, + 0xa681, 0xa681, 0xa681, 0xa681, 0xa681, 0xa683, 0xa681, 0xa681, + 0xa681, 0x080c, 0x151a, 0x080c, 0xb38c, 0x1d68, 0x080c, 0x2df4, + 0x1d50, 0x0089, 0x1138, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, + 0x6d45, 0x0005, 0x080c, 0x2cd1, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x6d45, 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, + 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0xa686, 0x0004, + 0x0158, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, + 0x0004, 0x0110, 0xa085, 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, + 0x0449, 0x00de, 0x0005, 0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, + 0xff00, 0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, + 0xd1e4, 0x0118, 0x2009, 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, + 0xa18c, 0x00ff, 0x6824, 0x080c, 0x2852, 0x1130, 0x2110, 0x2009, + 0x0000, 0x080c, 0x2d16, 0x0018, 0xa085, 0x0001, 0x0008, 0xa006, + 0x00de, 0x0005, 0x2069, 0xbc8d, 0x6800, 0xa082, 0x0010, 0x1228, + 0x6013, 0x0000, 0xa085, 0x0001, 0x0008, 0xa006, 0x0005, 0x6013, + 0x0000, 0x2069, 0xbc8c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, + 0x1140, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, + 0x0010, 0x0005, 0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x151a, 0xa1b6, + 0x0013, 0x1130, 0x2008, 0xa1b2, 0x0040, 0x1a04, 0xa802, 0x0092, + 0xa1b6, 0x0027, 0x0120, 0xa1b6, 0x0014, 0x190c, 0x151a, 0x2001, + 0x0007, 0x080c, 0x4f9c, 0x080c, 0x7102, 0x080c, 0x9ed9, 0x080c, + 0x71e5, 0x0005, 0xa762, 0xa764, 0xa762, 0xa762, 0xa762, 0xa764, + 0xa776, 0xa7fb, 0xa7c6, 0xa7fb, 0xa7d7, 0xa7fb, 0xa776, 0xa7fb, + 0xa7f3, 0xa7fb, 0xa7f3, 0xa7fb, 0xa7fb, 0xa762, 0xa762, 0xa762, + 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, + 0xa764, 0xa762, 0xa7fb, 0xa762, 0xa762, 0xa7fb, 0xa762, 0xa7f8, + 0xa7fb, 0xa762, 0xa762, 0xa762, 0xa762, 0xa7fb, 0xa7fb, 0xa762, + 0xa7fb, 0xa7fb, 0xa762, 0xa770, 0xa762, 0xa762, 0xa762, 0xa762, + 0xa7f7, 0xa7fb, 0xa762, 0xa762, 0xa7fb, 0xa7fb, 0xa762, 0xa762, + 0xa762, 0xa762, 0x080c, 0x151a, 0x080c, 0x7102, 0x2001, 0xb8b6, + 0x2004, 0x6016, 0x6003, 0x0002, 0x080c, 0x71e5, 0x0804, 0xa801, + 0x2001, 0x0000, 0x080c, 0x4f5d, 0x0804, 0xa7fb, 0x00f6, 0x2079, + 0xb652, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0xa7fb, 0x2001, 0x0000, + 0x080c, 0x4f5d, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, + 0x1140, 0x00f6, 0x2079, 0xb600, 0x7898, 0x8000, 0x789a, 0x00fe, + 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140, 0x6010, + 0xa005, 0x0128, 0x00ce, 0x080c, 0x3f85, 0x0804, 0xa7fb, 0x00ce, + 0x2001, 0xb600, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6, 0x2079, + 0xb600, 0x7898, 0x8000, 0x789a, 0x00fe, 0x2001, 0x0002, 0x080c, + 0x4f6f, 0x080c, 0x7102, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00c6, 0x6118, 0x2160, + 0x2009, 0x0001, 0x080c, 0x6a1a, 0x00ce, 0x04d8, 0x6618, 0x00d6, + 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, + 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410, 0x2001, + 0xb600, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3f85, 0x2001, + 0x0006, 0x04a1, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, + 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006, 0x0048, + 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0401, 0x0020, 0x0018, + 0x0010, 0x080c, 0x4f9c, 0x080c, 0x7102, 0x080c, 0x86a4, 0x080c, + 0x71e5, 0x0005, 0x2600, 0x0002, 0xa80d, 0xa80d, 0xa80d, 0xa80d, + 0xa80d, 0xa80f, 0xa80d, 0xa80d, 0xa80d, 0x080c, 0x151a, 0x080c, + 0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0x0016, 0x00d6, + 0x6118, 0x2168, 0x6900, 0xd184, 0x0140, 0x080c, 0x4f6f, 0x2001, + 0x0000, 0x080c, 0x4f5d, 0x080c, 0x2cf7, 0x00de, 0x001e, 0x0005, + 0x00d6, 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, + 0xa0b2, 0x000c, 0x1a0c, 0x151a, 0xa1b6, 0x0015, 0x1110, 0x003b, + 0x0028, 0xa1b6, 0x0016, 0x190c, 0x151a, 0x006b, 0x0005, 0x8d6b, + 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0xa898, 0xa857, 0x8d6b, + 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, + 0x8d6b, 0xa898, 0xa89f, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x00f6, + 0x2079, 0xb652, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, + 0x7800, 0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, + 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x601f, 0x0001, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x080c, 0x71e5, + 0x00e8, 0x2011, 0xbc83, 0x2204, 0x8211, 0x220c, 0x080c, 0x2852, + 0x11a8, 0x00c6, 0x080c, 0x501b, 0x0120, 0x00ce, 0x080c, 0x86a4, + 0x0068, 0x6010, 0x0006, 0x6014, 0x0006, 0x080c, 0x4c7e, 0x000e, + 0x6016, 0x000e, 0x6012, 0x00ce, 0x080c, 0x86a4, 0x00fe, 0x0005, + 0x6604, 0xa6b6, 0x001e, 0x1110, 0x080c, 0x86a4, 0x0005, 0x080c, + 0x9021, 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6d45, + 0x0010, 0x080c, 0x86a4, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, + 0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, + 0xa182, 0x0040, 0x0002, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8d0, + 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, + 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0x080c, 0x151a, + 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, + 0x002b, 0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xb3d8, + 0x6106, 0x2071, 0xbc80, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa934, + 0xa486, 0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, + 0x6b8c, 0x080c, 0x15fd, 0x090c, 0x151a, 0x6003, 0x0007, 0x2d00, + 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, + 0x685e, 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, + 0x694a, 0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6853, + 0x0000, 0x6857, 0x0036, 0x080c, 0x547a, 0x001e, 0xa486, 0x2000, + 0x1130, 0x2019, 0x0017, 0x080c, 0xb121, 0x0804, 0xa991, 0xa486, + 0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0xb0d3, 0x0804, 0xa991, + 0xa486, 0x0200, 0x1110, 0x080c, 0xb0b8, 0xa486, 0x1000, 0x1110, + 0x080c, 0xb106, 0x0804, 0xa991, 0x2069, 0xb975, 0x6a00, 0xd284, + 0x0904, 0xa9f8, 0xa284, 0x0300, 0x1904, 0xa9f1, 0x6804, 0xa005, + 0x0904, 0xa9d9, 0x2d78, 0x6003, 0x0007, 0x080c, 0x15e4, 0x0904, + 0xa998, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6013, + 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, + 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, + 0x6986, 0x6846, 0x7928, 0x698a, 0x792c, 0x698e, 0x7930, 0x6992, + 0x7934, 0x6996, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, + 0x0002, 0x1118, 0x684f, 0x0040, 0x0040, 0xa286, 0x0001, 0x1118, + 0x684f, 0x0080, 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, + 0xbc90, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, + 0x1f04, 0xa983, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x080c, + 0x547a, 0x002e, 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, + 0x2001, 0xb60e, 0x2004, 0xd084, 0x0120, 0x080c, 0x15fd, 0x1904, + 0xa949, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, + 0x6cff, 0x080c, 0x71e5, 0x0c28, 0x2069, 0xbc92, 0x2d04, 0xa084, + 0xff00, 0xa086, 0x1200, 0x11a8, 0x2069, 0xbc80, 0x686c, 0xa084, + 0x00ff, 0x0016, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e, + 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x6cff, 0x080c, 0x71e5, + 0x0840, 0x6868, 0x602a, 0x686c, 0x602e, 0x6013, 0x0200, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0804, + 0xa991, 0x2001, 0xb60d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x3f13, 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0804, + 0xa991, 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, 0x0804, 0xa9ac, + 0x6013, 0x0200, 0x0804, 0xa9ac, 0xa186, 0x0013, 0x1170, 0x6004, + 0xa08a, 0x0040, 0x0a0c, 0x151a, 0xa08a, 0x0053, 0x1a0c, 0x151a, + 0xa082, 0x0040, 0x2008, 0x0804, 0xaa86, 0xa186, 0x0051, 0x0138, + 0xa186, 0x0047, 0x11d8, 0x6004, 0xa086, 0x0041, 0x0518, 0x2001, + 0x0109, 0x2004, 0xd084, 0x01f0, 0x0126, 0x2091, 0x2800, 0x0006, + 0x0016, 0x0026, 0x080c, 0x6be6, 0x002e, 0x001e, 0x000e, 0x012e, + 0x6000, 0xa086, 0x0002, 0x1170, 0x0804, 0xaac9, 0xa186, 0x0027, + 0x0120, 0xa186, 0x0014, 0x190c, 0x151a, 0x6004, 0xa082, 0x0040, + 0x2008, 0x001a, 0x080c, 0x86ef, 0x0005, 0xaa50, 0xaa52, 0xaa52, + 0xaa76, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, + 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, + 0x080c, 0x151a, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0036, 0x00d6, + 0x6010, 0xa06d, 0x01c0, 0xad84, 0xf000, 0x01a8, 0x6003, 0x0002, + 0x6018, 0x2004, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xb155, + 0x6013, 0x0000, 0x6014, 0xa005, 0x1120, 0x2001, 0xb8b7, 0x2004, + 0x6016, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0x00d6, 0x080c, + 0x7102, 0x080c, 0x71e5, 0x080c, 0x9d16, 0x0120, 0x6010, 0x2068, + 0x080c, 0x1614, 0x080c, 0x9ed9, 0x00de, 0x0005, 0x0002, 0xaa9a, + 0xaab7, 0xaaa3, 0xaac3, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, + 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, + 0xaa9a, 0xaa9a, 0x080c, 0x151a, 0x6010, 0xa088, 0x0013, 0x2104, + 0xa085, 0x0400, 0x200a, 0x080c, 0x7102, 0x6010, 0xa080, 0x0013, + 0x2004, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, + 0x86d3, 0x0010, 0x6003, 0x0002, 0x080c, 0x71e5, 0x0005, 0x080c, + 0x7102, 0x080c, 0xb393, 0x1120, 0x080c, 0x6b61, 0x080c, 0x86a4, + 0x080c, 0x71e5, 0x0005, 0x080c, 0x7102, 0x2009, 0x0041, 0x0804, + 0xac12, 0xa182, 0x0040, 0x0002, 0xaadf, 0xaae1, 0xaadf, 0xaadf, + 0xaadf, 0xaadf, 0xaadf, 0xaae2, 0xaadf, 0xaadf, 0xaadf, 0xaadf, + 0xaadf, 0xaadf, 0xaadf, 0xaadf, 0xaadf, 0xaaed, 0xaadf, 0x080c, + 0x151a, 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, + 0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005, 0x00d6, 0x080c, 0x6b61, + 0x00de, 0x080c, 0xb3f6, 0x080c, 0x86a4, 0x0005, 0xa182, 0x0040, + 0x0002, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c, + 0xab0e, 0xab0c, 0xab11, 0xab4a, 0xab0c, 0xab0c, 0xab0c, 0xab0c, + 0xab4a, 0xab0c, 0xab0c, 0xab0c, 0x080c, 0x151a, 0x080c, 0x86ef, + 0x0005, 0x2001, 0xb672, 0x2004, 0xd0e4, 0x0158, 0x2001, 0x0100, + 0x2004, 0xa082, 0x0005, 0x0228, 0x2001, 0x011f, 0x2004, 0x6036, + 0x0010, 0x6037, 0x0000, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6010, + 0x00d6, 0x2068, 0x684c, 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e, + 0x0002, 0x0168, 0x2009, 0x0041, 0x00de, 0x0804, 0xac12, 0x6003, + 0x0007, 0x6017, 0x0000, 0x080c, 0x6b61, 0x00de, 0x0005, 0x080c, + 0xb393, 0x0110, 0x00de, 0x0005, 0x080c, 0x6b61, 0x080c, 0x86a4, + 0x00de, 0x0ca0, 0x0036, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6010, + 0x00d6, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0188, 0x684c, 0xa084, + 0x0003, 0xa086, 0x0002, 0x0140, 0x687c, 0x632c, 0xa31a, 0x632e, + 0x6880, 0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0080, 0x2019, + 0x0004, 0x080c, 0xb155, 0x6014, 0xa005, 0x1128, 0x2001, 0xb8b7, + 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007, 0x00de, + 0x003e, 0x0005, 0xa186, 0x0013, 0x1150, 0x6004, 0xa086, 0x0042, + 0x190c, 0x151a, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0xa186, + 0x0027, 0x0118, 0xa186, 0x0014, 0x1180, 0x6004, 0xa086, 0x0042, + 0x190c, 0x151a, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x080c, 0x7102, + 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0040, 0x0002, + 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb5, + 0xabc1, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, + 0xabb3, 0xabb3, 0xabb3, 0x080c, 0x151a, 0x0036, 0x0046, 0x20e1, + 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x004e, 0x003e, + 0x0005, 0x6010, 0x00d6, 0x2068, 0x6810, 0x6a14, 0x0006, 0x0046, + 0x0056, 0x6c7c, 0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, + 0x642e, 0x6028, 0xa529, 0x652a, 0x005e, 0x004e, 0x000e, 0xa20d, + 0x1178, 0x684c, 0xd0fc, 0x0120, 0x2009, 0x0041, 0x00de, 0x0490, + 0x6003, 0x0007, 0x6017, 0x0000, 0x080c, 0x6b61, 0x00de, 0x0005, + 0x0006, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x000e, 0x0120, + 0x6003, 0x0002, 0x00de, 0x0005, 0x2009, 0xb60d, 0x210c, 0xd19c, + 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x0021, 0x080c, + 0x6b63, 0x00de, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, + 0xa291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, 0x6a6a, + 0x6866, 0x0005, 0xa182, 0x0040, 0x0208, 0x0062, 0xa186, 0x0013, + 0x0120, 0xa186, 0x0014, 0x190c, 0x151a, 0x6020, 0xd0dc, 0x090c, + 0x151a, 0x0005, 0xac35, 0xac3c, 0xac48, 0xac54, 0xac35, 0xac35, + 0xac35, 0xac63, 0xac35, 0xac37, 0xac37, 0xac35, 0xac35, 0xac35, + 0xac35, 0xac37, 0xac35, 0xac37, 0xac35, 0x080c, 0x151a, 0x6020, + 0xd0dc, 0x090c, 0x151a, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, + 0x6cff, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e, 0x0005, + 0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091, 0x8000, + 0x080c, 0x71e5, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, + 0x080c, 0x1fc5, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d62, 0x080c, + 0x72a2, 0x012e, 0x0005, 0xa016, 0x080c, 0x1863, 0x0005, 0x0126, + 0x2091, 0x8000, 0x0036, 0x00d6, 0xa182, 0x0040, 0x0023, 0x00de, + 0x003e, 0x012e, 0x0005, 0xac83, 0xac85, 0xac97, 0xacb2, 0xac83, + 0xac83, 0xac83, 0xacc7, 0xac83, 0xac83, 0xac83, 0xac83, 0xac83, + 0xac83, 0xac83, 0xac83, 0x080c, 0x151a, 0x6010, 0x2068, 0x684c, + 0xd0fc, 0x01f8, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x01d0, 0x6003, + 0x0001, 0x6106, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0498, 0x6010, + 0x2068, 0x684c, 0xd0fc, 0x0168, 0xa09c, 0x0003, 0xa39e, 0x0003, + 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x080c, 0x71e5, + 0x0408, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x080c, + 0xb155, 0x00c0, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0d90, 0xa09c, + 0x0003, 0xa39e, 0x0003, 0x0d68, 0x6003, 0x0003, 0x6106, 0x2c10, + 0x080c, 0x1fc5, 0x080c, 0x6d62, 0x080c, 0x72a2, 0x0018, 0xa016, + 0x080c, 0x1863, 0x0005, 0x080c, 0x7102, 0x6110, 0x81ff, 0x0158, + 0x00d6, 0x2168, 0x080c, 0xb43c, 0x0036, 0x2019, 0x0029, 0x080c, + 0xb155, 0x003e, 0x00de, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, + 0x080c, 0x7198, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, + 0xb43c, 0x0036, 0x2019, 0x0029, 0x080c, 0xb155, 0x003e, 0x00de, + 0x080c, 0x9ed9, 0x080c, 0x72a2, 0x0005, 0xa182, 0x0085, 0x0002, + 0xad01, 0xacff, 0xacff, 0xad0d, 0xacff, 0xacff, 0xacff, 0x080c, + 0x151a, 0x6003, 0x000b, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091, + 0x8000, 0x080c, 0x71e5, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, + 0xb38c, 0x0118, 0x080c, 0x86a4, 0x00d8, 0x2071, 0xbc80, 0x7224, + 0x6212, 0x7220, 0x080c, 0xb003, 0x0118, 0x6007, 0x0086, 0x0040, + 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x1110, 0x6007, 0x0086, + 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x080c, 0x72a2, + 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, + 0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c, 0x1a0c, 0x151a, 0xa082, + 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, 0x0118, + 0x080c, 0x86ef, 0x0050, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x080c, + 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xad5d, 0xad5f, + 0xad5f, 0xad5d, 0xad5d, 0xad5d, 0xad5d, 0x080c, 0x151a, 0x080c, + 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0085, + 0x0a0c, 0x151a, 0xa182, 0x008c, 0x1a0c, 0x151a, 0xa182, 0x0085, + 0x0002, 0xad78, 0xad78, 0xad78, 0xad7a, 0xad78, 0xad78, 0xad78, + 0x080c, 0x151a, 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, + 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x86ef, 0x0030, 0x080c, + 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0x0036, 0x080c, + 0xb3f6, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031, 0x601f, 0x0006, + 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, + 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c, 0x81b7, 0x009e, + 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x825d, 0x007e, 0x1548, + 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086, 0x0007, 0x0508, + 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xb3f6, 0x601f, + 0x0007, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x080c, 0x1952, 0x6010, + 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155, 0x00de, 0x6013, + 0x0000, 0x080c, 0xb3f6, 0x601f, 0x0007, 0x2001, 0xb8b6, 0x2004, + 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156, + 0x2079, 0xbc80, 0x7938, 0x783c, 0x080c, 0x2852, 0x15b0, 0x0016, + 0x00c6, 0x080c, 0x501b, 0x1578, 0x001e, 0x002e, 0x0026, 0x0016, + 0x2019, 0x0029, 0x080c, 0x8320, 0x080c, 0x6e67, 0x0076, 0x2039, + 0x0000, 0x080c, 0x6d74, 0x007e, 0x001e, 0x0076, 0x2039, 0x0000, + 0x080c, 0xaf3e, 0x007e, 0x080c, 0x521c, 0x0026, 0x6204, 0xa294, + 0xff00, 0x8217, 0xa286, 0x0006, 0x0118, 0xa286, 0x0004, 0x1118, + 0x62a0, 0x080c, 0x2d8a, 0x002e, 0x001e, 0x080c, 0x4c7e, 0x6612, + 0x6516, 0xa006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00ce, + 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x2009, 0xb621, + 0x2104, 0xa086, 0x0074, 0x1904, 0xae77, 0x2069, 0xbc8e, 0x690c, + 0xa182, 0x0100, 0x06c0, 0x6908, 0xa184, 0x8000, 0x05e8, 0x2001, + 0xb89e, 0x2004, 0xa005, 0x1160, 0x6018, 0x2070, 0x7010, 0xa084, + 0x00ff, 0x0118, 0x7000, 0xd0f4, 0x0118, 0xa184, 0x0800, 0x0560, + 0x6910, 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, 0xbcae, 0x6904, + 0x81ff, 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, 0x6908, 0x81ff, + 0x1178, 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, 0xa18a, 0x0001, + 0x0298, 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, 0x0300, 0x0088, + 0x6013, 0x0500, 0x0070, 0x6013, 0x0700, 0x0058, 0x6013, 0x0900, + 0x0040, 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, 0x0010, 0x6013, + 0x2d00, 0xa085, 0x0001, 0x0008, 0xa006, 0x001e, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, 0x6218, + 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, 0xa286, + 0x0004, 0x0178, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0148, + 0xa286, 0x0004, 0x0130, 0x00c6, 0x2d60, 0x080c, 0x502a, 0x00ce, + 0x04c0, 0x2011, 0xbc96, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, + 0x9166, 0x1580, 0x2011, 0xbc9a, 0xad98, 0x0006, 0x20a9, 0x0004, + 0x080c, 0x9166, 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, 0x00ff, + 0x8227, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4, 0x0138, 0x2009, + 0x0029, 0x080c, 0xb1a4, 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, + 0x080c, 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08, + 0x080c, 0xaf3e, 0x007e, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x001e, + 0x004e, 0xa006, 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, 0x0005, + 0x00d6, 0x2069, 0xbc8e, 0x6800, 0xa086, 0x0800, 0x0118, 0x6013, + 0x0000, 0x0008, 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, 0x0016, + 0x0026, 0x0036, 0x0156, 0x2079, 0xbc8c, 0x7930, 0x7834, 0x080c, + 0x2852, 0x11a0, 0x080c, 0x501b, 0x1188, 0x2011, 0xbc90, 0xac98, + 0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1140, 0x2011, 0xbc94, + 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x015e, 0x003e, + 0x002e, 0x001e, 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, 0x0016, + 0x0026, 0x0036, 0x0156, 0x2011, 0xbc83, 0x2204, 0x8211, 0x220c, + 0x080c, 0x2852, 0x11a0, 0x080c, 0x501b, 0x1188, 0x2011, 0xbc96, + 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1140, 0x2011, + 0xbc9a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x015e, + 0x003e, 0x002e, 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, + 0x8000, 0x2740, 0x2029, 0xb8ea, 0x252c, 0x2021, 0xb8f0, 0x2424, + 0x2061, 0xbe00, 0x2071, 0xb600, 0x7648, 0x7068, 0x81ff, 0x0150, + 0x0006, 0xa186, 0xb9f5, 0x000e, 0x0128, 0x8001, 0xa602, 0x1a04, + 0xafbf, 0x0018, 0xa606, 0x0904, 0xafbf, 0x2100, 0xac06, 0x0904, + 0xafb6, 0x080c, 0xb1cc, 0x0904, 0xafb6, 0x671c, 0xa786, 0x0001, + 0x0904, 0xafda, 0xa786, 0x0004, 0x0904, 0xafda, 0xa786, 0x0007, + 0x05e8, 0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, + 0xb1dc, 0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, + 0x6000, 0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1952, 0x001e, + 0xa786, 0x0008, 0x1148, 0x080c, 0x9f14, 0x1130, 0x080c, 0x8ca5, + 0x00de, 0x080c, 0x9ed9, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9d16, + 0x0190, 0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, + 0x0000, 0x080c, 0xb43c, 0x0016, 0x080c, 0x9f88, 0x080c, 0x547a, + 0x001e, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x9ed9, 0xace0, 0x0018, + 0x2001, 0xb617, 0x2004, 0xac02, 0x1210, 0x0804, 0xaf52, 0x012e, + 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, + 0x0005, 0xa786, 0x0006, 0x1150, 0xa386, 0x0005, 0x0128, 0x080c, + 0xb43c, 0x080c, 0xb155, 0x08f8, 0x00de, 0x0c00, 0xa786, 0x000a, + 0x0968, 0x0850, 0x080c, 0xb1dc, 0x19c8, 0x81ff, 0x09b8, 0xa180, + 0x0001, 0x2004, 0xa086, 0x0018, 0x0130, 0xa180, 0x0001, 0x2004, + 0xa086, 0x002d, 0x1958, 0x6000, 0xa086, 0x0002, 0x1938, 0x080c, + 0x9f03, 0x0130, 0x080c, 0x9f14, 0x1908, 0x080c, 0x8ca5, 0x0038, + 0x080c, 0x2cf7, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x080c, + 0x9ed9, 0x0804, 0xafb6, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, + 0xa006, 0x080c, 0xb176, 0x001e, 0x0120, 0x601c, 0xa084, 0x000f, + 0x001b, 0x00ee, 0x00ce, 0x0005, 0xb01c, 0xb01c, 0xb01c, 0xb01c, + 0xb01c, 0xb01c, 0xb01e, 0xb01c, 0xa006, 0x0005, 0x0046, 0x0016, + 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, + 0x2009, 0x0020, 0x080c, 0xb1a4, 0x001e, 0x004e, 0x0036, 0x2019, + 0x0002, 0x080c, 0xad9c, 0x003e, 0xa085, 0x0001, 0x0005, 0x2001, + 0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, + 0x0004, 0x2019, 0xb605, 0x2011, 0xbc96, 0x080c, 0x9166, 0x003e, + 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6, + 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, + 0x2061, 0xbe00, 0x2079, 0x0001, 0x8fff, 0x0904, 0xb0ab, 0x2071, + 0xb600, 0x7648, 0x7068, 0x8001, 0xa602, 0x1a04, 0xb0ab, 0x88ff, + 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000, 0x080c, 0xb1cc, + 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786, 0x0006, 0x1550, + 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018, 0xa206, 0x1510, + 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6, 0x6000, 0xa086, + 0x0004, 0x1150, 0x080c, 0xb3f6, 0x601f, 0x0007, 0x2001, 0xb8b6, + 0x2004, 0x6016, 0x080c, 0x1952, 0x6010, 0x2068, 0x080c, 0x9d16, + 0x0120, 0x0046, 0x080c, 0xb155, 0x004e, 0x00de, 0x080c, 0x9ed9, + 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xb617, 0x2004, 0xac02, + 0x1210, 0x0804, 0xb05c, 0xa006, 0x012e, 0x002e, 0x006e, 0x007e, + 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, 0x0001, 0x0ca0, + 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20, + 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000, 0x080c, 0x81b7, + 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c, 0xb04d, + 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, + 0x0036, 0x080c, 0x501b, 0x11b0, 0x2c10, 0x0056, 0x0086, 0x2041, + 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049, 0x0000, 0x080c, + 0x81b7, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c, + 0xb04d, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xb0df, 0x015e, + 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0076, 0x0056, + 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, 0x0048, + 0x0096, 0x2049, 0x0000, 0x080c, 0x81b7, 0x009e, 0x008e, 0x2039, + 0x0000, 0x080c, 0x825d, 0x2c20, 0x080c, 0xb04d, 0x005e, 0x007e, + 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, + 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x501b, + 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828, 0x0046, 0x2021, + 0x0001, 0x080c, 0xb3d8, 0x004e, 0x0096, 0x2049, 0x0000, 0x080c, + 0x81b7, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c, + 0xb04d, 0x003e, 0x001e, 0x8108, 0x1f04, 0xb12c, 0x015e, 0x00ce, + 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016, 0x00f6, 0x3800, + 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82, 0xb600, 0x0230, + 0xad82, 0xee00, 0x0280, 0xad82, 0xffff, 0x1268, 0x6800, 0xa07d, + 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x547a, 0x2f68, 0x0cb0, + 0x6b52, 0x080c, 0x547a, 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046, + 0x0036, 0x2061, 0xbe00, 0xa005, 0x1138, 0x2071, 0xb600, 0x7448, + 0x7068, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000, + 0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0, + 0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xb617, + 0x2004, 0xac02, 0x1220, 0x0c40, 0xa085, 0x0001, 0x0008, 0xa006, + 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15fd, + 0x000e, 0x090c, 0x151a, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010, + 0x080c, 0x9d06, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014, + 0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0x2001, + 0xb8be, 0x2004, 0x6852, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, + 0x080c, 0x547a, 0x00de, 0x0005, 0x6700, 0xa786, 0x0000, 0x0158, + 0xa786, 0x0001, 0x0140, 0xa786, 0x000a, 0x0128, 0xa786, 0x0009, + 0x0110, 0xa085, 0x0001, 0x0005, 0x00e6, 0x6018, 0x2070, 0x70a0, + 0xa206, 0x00ee, 0x0005, 0x0016, 0x6004, 0xa08e, 0x001e, 0x11a0, + 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, + 0x6003, 0x000b, 0x601f, 0x0005, 0x2001, 0xb8b7, 0x2004, 0x6016, + 0x080c, 0x6cff, 0x080c, 0x71e5, 0x001e, 0x0005, 0xe000, 0xe000, + 0x0005, 0x6020, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0x9ff1, + 0x0030, 0x080c, 0xb3f6, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x0005, + 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0002, 0xb21f, 0xb21f, + 0xb21f, 0xb224, 0xb21f, 0xb221, 0xb221, 0xb21f, 0xb221, 0xa006, + 0x0005, 0x00c6, 0x2260, 0x00ce, 0xa085, 0x0001, 0x0005, 0xa280, + 0x0007, 0x2004, 0xa084, 0x000f, 0x0002, 0xb236, 0xb236, 0xb236, + 0xb236, 0xb236, 0xb236, 0xb241, 0xb236, 0xb236, 0x6007, 0x003b, + 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x080c, 0x6cff, + 0x0005, 0x00c6, 0x2260, 0x080c, 0xb3f6, 0x603f, 0x0000, 0x6020, + 0xc0f4, 0xc0cc, 0x6022, 0x6037, 0x0000, 0x00ce, 0x00d6, 0x2268, + 0xa186, 0x0007, 0x1904, 0xb29c, 0x6810, 0xa005, 0x0138, 0xa080, + 0x0013, 0x2004, 0xd0fc, 0x1110, 0x00de, 0x08c0, 0x6007, 0x003a, + 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00c6, 0x2d60, + 0x6100, 0xa186, 0x0002, 0x1904, 0xb325, 0x6010, 0xa005, 0x1138, + 0x6000, 0xa086, 0x0007, 0x190c, 0x151a, 0x0804, 0xb325, 0xa08c, + 0xf000, 0x1130, 0x0028, 0x2068, 0x6800, 0xa005, 0x1de0, 0x2d00, + 0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086, 0x0002, 0x1180, + 0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, + 0xc0fc, 0x6852, 0x2009, 0x0043, 0x080c, 0xac12, 0x0804, 0xb325, + 0x2009, 0x0041, 0x0804, 0xb31f, 0xa186, 0x0005, 0x15f0, 0x6810, + 0xa080, 0x0013, 0x2004, 0xd0bc, 0x1118, 0x00de, 0x0804, 0xb236, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x151a, 0x0804, 0xb254, 0x6007, + 0x003a, 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00c6, + 0x2d60, 0x6100, 0xa186, 0x0002, 0x0120, 0xa186, 0x0004, 0x1904, + 0xb325, 0x2071, 0xb924, 0x7000, 0xa086, 0x0003, 0x1128, 0x7004, + 0xac06, 0x1110, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013, 0x200c, + 0xc1f4, 0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, + 0x2102, 0x2009, 0x0042, 0x0804, 0xb31f, 0x0036, 0x00d6, 0x00d6, + 0x080c, 0x15fd, 0x003e, 0x090c, 0x151a, 0x6837, 0x010d, 0x6803, + 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857, 0x0045, + 0x2c00, 0x6862, 0x6034, 0x6872, 0x2360, 0x6020, 0xc0dd, 0x6022, + 0x6018, 0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007, 0x6350, + 0x6b4a, 0x6846, 0x684f, 0x0000, 0x6853, 0x0000, 0x6d6a, 0x6e66, + 0x686f, 0x0001, 0x080c, 0x547a, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xad9c, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, + 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e, 0x0038, 0x603f, + 0x0000, 0x6003, 0x0007, 0x080c, 0xac12, 0x00ce, 0x00de, 0x0005, + 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2, + 0xa186, 0x0027, 0x1178, 0x080c, 0x7102, 0x0036, 0x00d6, 0x6010, + 0x2068, 0x2019, 0x0004, 0x080c, 0xb155, 0x00de, 0x003e, 0x080c, + 0x71e5, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, 0x86ef, 0x0005, + 0xb351, 0xb34f, 0xb34f, 0xb34f, 0xb34f, 0xb34f, 0xb351, 0x080c, + 0x151a, 0x080c, 0x7102, 0x6003, 0x000c, 0x080c, 0x71e5, 0x0005, + 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, + 0x86ef, 0x0005, 0xb369, 0xb369, 0xb369, 0xb369, 0xb36b, 0xb389, + 0xb369, 0x080c, 0x151a, 0x00d6, 0x2c68, 0x080c, 0x864e, 0x01a0, + 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xbc8e, 0x210c, 0x6136, + 0x2009, 0xbc8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a, + 0x601f, 0x0004, 0x080c, 0x6cff, 0x2d60, 0x080c, 0x86a4, 0x00de, + 0x0005, 0x080c, 0x86a4, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, + 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa08c, 0xf000, 0x0904, 0xb3d7, + 0xa080, 0x0013, 0x200c, 0xd1ec, 0x05d0, 0x2001, 0xb672, 0x2004, + 0xd0ec, 0x05a8, 0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, + 0x0180, 0x00f6, 0x2c78, 0x080c, 0x5373, 0x00fe, 0x0150, 0x2001, + 0xb8b8, 0x2004, 0x603e, 0x2009, 0xb672, 0x210c, 0xd1f4, 0x11e8, + 0x0080, 0x2009, 0xb672, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, + 0x6022, 0xa006, 0x00a0, 0x2001, 0xb8b8, 0x200c, 0x8103, 0xa100, + 0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, + 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, + 0x0016, 0x00c6, 0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, + 0x8cff, 0x0180, 0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, + 0x2072, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x0010, 0xacf0, 0x0003, + 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, + 0xa0e8, 0x002b, 0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, + 0xa0e8, 0x0003, 0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, + 0x0036, 0x0156, 0x2011, 0xb628, 0x2204, 0xa084, 0x00ff, 0x2019, + 0xbc8e, 0x2334, 0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, + 0xff00, 0xa636, 0x11a0, 0x2011, 0xbc90, 0x6018, 0xa098, 0x000a, + 0x20a9, 0x0004, 0x080c, 0x9166, 0x1150, 0x2011, 0xbc94, 0x6018, + 0xa098, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1100, 0x015e, + 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0xb600, 0x080c, 0x4c28, + 0x080c, 0x2aed, 0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, + 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, + 0x0005, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, + 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0xb8ea, 0x252c, 0x2021, + 0xb8f0, 0x2424, 0x2061, 0xbe00, 0x2071, 0xb600, 0x7648, 0x7068, + 0xa606, 0x0578, 0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, + 0x1500, 0x2500, 0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, + 0xb1cc, 0x01b8, 0x080c, 0xb1dc, 0x11a0, 0x6000, 0xa086, 0x0004, + 0x1120, 0x0016, 0x080c, 0x1952, 0x001e, 0x080c, 0x9f03, 0x1110, + 0x080c, 0x2cf7, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x080c, + 0x9ed9, 0xace0, 0x0018, 0x2001, 0xb617, 0x2004, 0xac02, 0x1208, + 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, + 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, + 0x8000, 0x2071, 0xb640, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, + 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500, + 0xa084, 0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130, + 0xa08e, 0x0005, 0x0118, 0x2071, 0xb64a, 0x04c9, 0x001e, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, + 0x8000, 0x2071, 0xb640, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, + 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500, + 0xa084, 0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130, + 0xa08e, 0x0005, 0x0118, 0x2071, 0xb64a, 0x0089, 0x001e, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, + 0x2071, 0xb642, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, + 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, + 0x00e6, 0x2071, 0xb640, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, + 0xb644, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, + 0x8000, 0x2071, 0xb640, 0x7044, 0x8000, 0x7046, 0x00ee, 0x000e, + 0x012e, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, + 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, + 0x4000, 0x8000, 0xdb06 +}; +#ifdef UNIQUE_FW_NAME +unsigned short fw2200tp_length01 = 0xa52b; +#else +unsigned short risc_code_length01 = 0xa52b; +#endif + diff --git a/trunk/drivers/scsi/qla2xxx/ql2300.c b/trunk/drivers/scsi/qla2xxx/ql2300.c new file mode 100644 index 000000000000..e7a93ddda79a --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2300.c @@ -0,0 +1,114 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (C) 2003 Christoph Hellwig. + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2300"; + +extern unsigned char fw2300ipx_version[]; +extern unsigned char fw2300ipx_version_str[]; +extern unsigned short fw2300ipx_addr01; +extern unsigned short fw2300ipx_code01[]; +extern unsigned short fw2300ipx_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2300ipx_code01[0], + .fwlen = &fw2300ipx_length01, + .fwstart = &fw2300ipx_addr01, + }, + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl[] = { + { + .drv_name = qla_driver_name, + .isp_name = "ISP2300", + .fw_info = qla_fw_tbl, + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP2312", + .fw_info = qla_fw_tbl, + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP6312", + .fw_info = qla_fw_tbl, + }, +}; + +static struct pci_device_id qla2300_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2300, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[0], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2312, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[1], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP6312, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[2], + }, + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl); + +static int __devinit +qla2300_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla2300_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla2300_pci_driver = { + .name = "qla2300", + .id_table = qla2300_pci_tbl, + .probe = qla2300_probe_one, + .remove = __devexit_p(qla2300_remove_one), +}; + +static int __init +qla2300_init(void) +{ + return pci_module_init(&qla2300_pci_driver); +} + +static void __exit +qla2300_exit(void) +{ + pci_unregister_driver(&qla2300_pci_driver); +} + +module_init(qla2300_init); +module_exit(qla2300_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP23xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/trunk/drivers/scsi/qla2xxx/ql2300_fw.c b/trunk/drivers/scsi/qla2xxx/ql2300_fw.c new file mode 100644 index 000000000000..b8ce7fe5d8de --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2300_fw.c @@ -0,0 +1,7746 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 3.03.20 (15:39 Feb 01, 2006) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300ipx_version = 3*1024+3; +#else +unsigned short risc_code_version = 3*1024+3; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2300ipx_version_str[] = {3, 3,20}; +#else +unsigned char firmware_version[] = {3, 3,20}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2300ipx_VERSION_STRING "3.03.20" +#else +#define FW_VERSION_STRING "3.03.20" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300ipx_addr01 = 0x0800 ; +#else +unsigned short risc_code_addr01 = 0x0800 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2300ipx_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0470, 0x0000, 0x0000, 0xf091, 0x0000, 0x0003, 0x0003, 0x0014, + 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x332e, 0x3033, 0x2e32, 0x3020, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, + 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, + 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, + 0x400f, 0x2091, 0x2800, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, + 0x2091, 0x2a00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, + 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, + 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, + 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78, + 0x7883, 0x0004, 0x2089, 0x2d93, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e52, 0x2029, + 0x4d00, 0x2031, 0xffff, 0x2039, 0x4cd0, 0x2021, 0x0200, 0x20e9, + 0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9, + 0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff, + 0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8, + 0x4104, 0x8001, 0x1de0, 0x756e, 0x7672, 0x776a, 0x7476, 0x747a, + 0x00e6, 0x2071, 0x1ad1, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170, + 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001, + 0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x7170, 0x3400, + 0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009, + 0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f, + 0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e, + 0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f26, 0x080c, + 0x613c, 0x080c, 0xb269, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c, + 0x1bd7, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34b6, 0x080c, + 0x7946, 0x080c, 0x6b7c, 0x080c, 0x8a69, 0x080c, 0x874a, 0x080c, + 0x24b7, 0x080c, 0x93a5, 0x080c, 0x8066, 0x080c, 0x22e8, 0x080c, + 0x241c, 0x080c, 0x24ac, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, + 0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, + 0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, + 0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, + 0x1178, 0x080c, 0x4d09, 0x080c, 0x34dd, 0x080c, 0x79b7, 0x080c, + 0x7122, 0x080c, 0x8b50, 0x080c, 0x8776, 0x080c, 0x2cdd, 0x0c58, + 0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae0, 0x0942, 0x0ba0, 0x0d56, + 0x0d56, 0x0d56, 0x080c, 0x0dc5, 0x0005, 0x0126, 0x00f6, 0x2091, + 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x080c, 0x0e94, + 0x080c, 0x7637, 0x0150, 0x080c, 0x765a, 0x15a0, 0x2079, 0x0100, + 0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x7563, 0x7000, + 0x9086, 0x0001, 0x1904, 0x0ab3, 0x7098, 0x9086, 0x0029, 0x1904, + 0x0ab3, 0x080c, 0x8733, 0x080c, 0x8725, 0x2001, 0x0161, 0x2003, + 0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f, + 0x7a2a, 0x2011, 0x74b2, 0x080c, 0x883d, 0x2011, 0x74a5, 0x080c, + 0x8917, 0x2011, 0x5f97, 0x080c, 0x883d, 0x2011, 0x8030, 0x901e, + 0x7396, 0x04d0, 0x080c, 0x583f, 0x2079, 0x0100, 0x7844, 0x9005, + 0x1904, 0x0ab3, 0x2011, 0x5f97, 0x080c, 0x883d, 0x2011, 0x74b2, + 0x080c, 0x883d, 0x2011, 0x74a5, 0x080c, 0x8917, 0x2001, 0x0265, + 0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, + 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, + 0x080c, 0x60e4, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28, + 0x080c, 0x763f, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, + 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001, + 0x080c, 0x2b82, 0x080c, 0x4c44, 0x7248, 0xc284, 0x724a, 0x2001, + 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa9b0, 0x2011, + 0x0004, 0x080c, 0xd0e8, 0x080c, 0x6947, 0x080c, 0x7637, 0x1120, + 0x080c, 0x2bc6, 0x02e0, 0x0400, 0x080c, 0x60eb, 0x0140, 0x7097, + 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a11, 0x0804, 0x0ab3, 0x080c, + 0x57d5, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, + 0x080c, 0x57d9, 0xd0d4, 0x1118, 0x080c, 0x2bc6, 0x1270, 0x2011, + 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d9, 0xd0d4, 0x1db8, + 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, + 0xc0bd, 0x2012, 0x080c, 0x6a9b, 0x1128, 0xd0a4, 0x0118, 0x2204, + 0xc0fd, 0x2012, 0x080c, 0x6a61, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, + 0x00a8, 0x707f, 0x0000, 0x080c, 0x7637, 0x1130, 0x70b0, 0x9005, + 0x1168, 0x080c, 0xd52b, 0x0050, 0x080c, 0xd52b, 0x70dc, 0xd09c, + 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60c1, 0x70e7, 0x0000, + 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2bce, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7637, 0x1178, + 0x9016, 0x0016, 0x080c, 0x298b, 0x2019, 0x196d, 0x211a, 0x001e, + 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, + 0x196d, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, + 0xc295, 0x72de, 0x080c, 0x7637, 0x0118, 0x9296, 0x0004, 0x0548, + 0x2011, 0x0001, 0x080c, 0xd0e8, 0x70ab, 0x0000, 0x70af, 0xffff, + 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, + 0x0003, 0x782a, 0x00fe, 0x080c, 0x3000, 0x2011, 0x0005, 0x080c, + 0xaabf, 0x080c, 0x9ab1, 0x080c, 0x7637, 0x0148, 0x00c6, 0x2061, + 0x0100, 0x0016, 0x080c, 0x298b, 0x61e2, 0x001e, 0x00ce, 0x012e, + 0x0420, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6, + 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, + 0x00fe, 0x2011, 0x0005, 0x080c, 0xaabf, 0x080c, 0x9ab1, 0x080c, + 0x7637, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x298b, + 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, + 0x080c, 0x7637, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, + 0x080c, 0x7637, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, + 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, + 0x090c, 0x334c, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080, + 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, + 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, + 0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3000, 0x080c, + 0x9ab1, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, + 0xd084, 0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, + 0xd08c, 0x0508, 0x080c, 0x33af, 0x11d0, 0x70e0, 0x9086, 0xffff, + 0x01b0, 0x080c, 0x31bc, 0x080c, 0x9ab1, 0x70dc, 0xd094, 0x1904, + 0x0b9d, 0x2011, 0x0001, 0x080c, 0xd7e3, 0x0110, 0x2011, 0x0003, + 0x901e, 0x080c, 0x31f6, 0x080c, 0x9ab1, 0x0804, 0x0b9d, 0x70e4, + 0x9005, 0x1904, 0x0b9d, 0x70a8, 0x9005, 0x1904, 0x0b9d, 0x70dc, + 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a61, 0x1904, + 0x0b9d, 0x080c, 0x6ab4, 0x1904, 0x0b9d, 0x080c, 0x6a9b, 0x01c0, + 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, + 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b3d, + 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b9d, + 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b4, + 0x080c, 0x0f96, 0x2011, 0x19ce, 0x080c, 0x0f96, 0x7030, 0xc08c, + 0x7032, 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e76, 0x9006, + 0x080c, 0x281c, 0x080c, 0x33af, 0x0118, 0x080c, 0x4de1, 0x0050, + 0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4dfb, + 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x765a, 0x0150, + 0x080c, 0x7637, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, + 0xffdf, 0x782a, 0x00fe, 0x2001, 0x19e9, 0x2004, 0x9086, 0x0005, + 0x1120, 0x2011, 0x0000, 0x080c, 0xaabf, 0x2011, 0x0000, 0x080c, + 0xaac9, 0x080c, 0x9ab1, 0x080c, 0x9bd3, 0x012e, 0x00be, 0x0005, + 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, + 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x60aa, + 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, + 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, + 0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a8, 0x2004, 0x9005, + 0x1518, 0x080c, 0x2c49, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bb1, + 0x2001, 0x0001, 0x080c, 0x2b94, 0x00b8, 0x080c, 0x2c51, 0x1138, + 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x0068, 0x080c, + 0x2c59, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, 0x0020, + 0x080c, 0x29bf, 0x0804, 0x0d0d, 0x080c, 0x7648, 0x0148, 0x080c, + 0x765a, 0x1118, 0x080c, 0x7941, 0x0050, 0x080c, 0x763f, 0x0dd0, + 0x080c, 0x793c, 0x080c, 0x7932, 0x080c, 0x7563, 0x0058, 0x080c, + 0x7637, 0x0140, 0x2009, 0x00f8, 0x080c, 0x60aa, 0x7843, 0x0090, + 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, + 0x7637, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c, + 0x0070, 0x7824, 0x080c, 0x7651, 0x0118, 0xd0ac, 0x1904, 0x0d12, + 0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d12, 0x2001, + 0x0001, 0x080c, 0x281c, 0x0804, 0x0d25, 0x2001, 0x19a8, 0x2004, + 0x9005, 0x1518, 0x080c, 0x2c49, 0x1148, 0x2001, 0x0001, 0x080c, + 0x2bb1, 0x2001, 0x0001, 0x080c, 0x2b94, 0x00b8, 0x080c, 0x2c51, + 0x1138, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x0068, + 0x080c, 0x2c59, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, + 0x0020, 0x080c, 0x29bf, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040, + 0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c61, + 0x9085, 0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c66, + 0x080c, 0x88f7, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084, + 0xdfbf, 0x7852, 0x793a, 0x080c, 0x7648, 0x0148, 0x080c, 0x765a, + 0x1118, 0x080c, 0x7941, 0x0050, 0x080c, 0x763f, 0x0dd0, 0x080c, + 0x793c, 0x080c, 0x7932, 0x080c, 0x7563, 0x0020, 0x2009, 0x00f8, + 0x080c, 0x60aa, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850, + 0x9085, 0x1400, 0x7852, 0x080c, 0x7637, 0x0120, 0x7843, 0x0090, + 0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x88f7, + 0x7820, 0xd09c, 0x1588, 0x080c, 0x7637, 0x0904, 0x0cf2, 0x7824, + 0xd0ac, 0x1904, 0x0d12, 0x080c, 0x765a, 0x1530, 0x0046, 0x2021, + 0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c61, + 0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, + 0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d33, 0x8421, + 0x1158, 0x1d04, 0x0ccd, 0x080c, 0x88f7, 0x080c, 0x793c, 0x080c, + 0x7932, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda, + 0x080c, 0x88f7, 0x2009, 0x199b, 0x2104, 0x9005, 0x0118, 0x8001, + 0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, + 0x080c, 0x2c42, 0x7924, 0x080c, 0x2c61, 0xd19c, 0x0110, 0x080c, + 0x2b82, 0x00d8, 0x080c, 0x7648, 0x1140, 0x94a2, 0x03e8, 0x1128, + 0x080c, 0x760f, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, + 0x2c61, 0x7824, 0x080c, 0x7651, 0x0110, 0xd0ac, 0x1158, 0x9084, + 0x1800, 0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, + 0x281c, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, + 0x918d, 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, + 0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a8, 0x2003, + 0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, + 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x88f7, + 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, + 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, + 0x0001, 0x1110, 0x080c, 0x34dd, 0x00ee, 0x0005, 0x0005, 0x2a70, + 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0014, + 0x600f, 0x0137, 0x2001, 0x197c, 0x900e, 0x2102, 0x7196, 0x2001, + 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, + 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd52b, 0x70eb, + 0x00c0, 0x2061, 0x196c, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, + 0x07d0, 0x2061, 0x1974, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, + 0x1989, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, + 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6724, + 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, + 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, + 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, + 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, + 0x0dc7, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, + 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, + 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, + 0x681c, 0x78b2, 0x2001, 0x1a09, 0x2004, 0x78b6, 0x2001, 0x1a86, + 0x2004, 0x78ba, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, + 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, + 0x1aa9, 0x7a08, 0x226a, 0x2069, 0x1aaa, 0x7a18, 0x226a, 0x8d68, + 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1ab7, 0x201a, 0x2019, 0x1aba, + 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, + 0x9386, 0x1acf, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, + 0xdead, 0x2019, 0x1ab8, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, + 0x0000, 0x2069, 0x1a89, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, + 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e26, 0x002e, 0x003e, 0x00de, + 0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1c, 0x2004, 0x9005, + 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, + 0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57e4, 0x1108, 0x0099, + 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, + 0x0600, 0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001, + 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, + 0x0eee, 0x20a9, 0x0900, 0x080c, 0x0f0f, 0x2011, 0x0040, 0x080c, + 0x0eee, 0x20a9, 0x0900, 0x080c, 0x0f0f, 0x0c78, 0x0026, 0x080c, + 0x0efb, 0x1118, 0x2011, 0x0040, 0x0098, 0x2011, 0x010e, 0x2214, + 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, + 0x2011, 0x6840, 0xd0e4, 0x70ef, 0x0000, 0x1120, 0x70ef, 0x0fa0, + 0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x080c, 0x0efb, 0x0128, + 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, + 0x0f00, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0efb, + 0x1148, 0x080c, 0x2c59, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011, + 0x8282, 0x0040, 0x080c, 0x2c59, 0x1118, 0x2011, 0xcdc5, 0x0010, + 0x2011, 0xcac2, 0x080c, 0x0f00, 0x002e, 0x0005, 0x00e6, 0x0006, + 0x2071, 0x1800, 0xd0b4, 0x70e8, 0x1110, 0xc0e4, 0x0048, 0x0006, + 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5, + 0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, + 0x70e8, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0011, 0x00ee, 0x0005, + 0x70ea, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, 0x0ebd, 0x0e94, + 0x0e94, 0x0e76, 0x0ea3, 0x0e94, 0x0e94, 0x0ea3, 0x0016, 0x3b08, + 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, + 0x20d0, 0x001e, 0x0005, 0x2001, 0x183a, 0x2004, 0xd0dc, 0x0005, + 0x9e86, 0x1800, 0x190c, 0x0dc5, 0x70e8, 0xd0e4, 0x0108, 0xc2e5, + 0x72ea, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04, + 0x0f0f, 0x2091, 0x6000, 0x1f04, 0x0f0f, 0x0005, 0x890e, 0x810e, + 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, + 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, + 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f, 0x0000, + 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, + 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, + 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, 0x9306, + 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, + 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, 0x0006, + 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, + 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, 0x0000, + 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, + 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, + 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, + 0x0096, 0x3348, 0x080c, 0x0f16, 0x2100, 0x9300, 0x2098, 0x22e0, + 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, + 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, + 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, + 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, + 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180, 0x810f, + 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, + 0x0da5, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, + 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x1040, + 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x10b9, + 0x090c, 0x0dc5, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, + 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, 0x73c0, + 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, 0x0dc5, + 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0dc5, 0xa000, 0x0c98, 0x012e, + 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010, 0x9005, + 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0dc5, 0xa000, + 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270, 0x70c2, + 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, 0x0000, + 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, + 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca, 0x0020, + 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0xa803, + 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f, + 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, + 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x012e, + 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049, + 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, + 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040, + 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001, 0x0534, + 0xa802, 0x2048, 0x2009, 0x4d00, 0x8940, 0x2800, 0xa802, 0xa95e, + 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, 0x9188, + 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff, 0x01d0, + 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, 0x2001, + 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, + 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, 0x9291, + 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be, 0x74c2, + 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, + 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, + 0x0534, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800, + 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001, + 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a1b, + 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000, + 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x20a9, + 0x0040, 0x7022, 0x1f04, 0x10f1, 0x702b, 0x0020, 0x00ee, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a1b, + 0x701c, 0x9088, 0x1a25, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, + 0x7120, 0x9106, 0x090c, 0x0dc5, 0x7004, 0x9005, 0x1128, 0x00f6, + 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a1b, 0x7004, 0x9005, 0x1128, + 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, + 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, + 0x113a, 0x12bd, 0x1138, 0x1138, 0x12b1, 0x12b1, 0x12b1, 0x12b1, + 0x080c, 0x0dc5, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, + 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, + 0x9180, 0x1a25, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, + 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, + 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, + 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, + 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, + 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, + 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, + 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, + 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, + 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, + 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, + 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, + 0x001e, 0x0005, 0x2009, 0x1a1b, 0x2104, 0xc095, 0x200a, 0x080c, + 0x1117, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a1b, 0x00f6, 0x2079, + 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dbe, 0x782b, 0x0002, 0xd1fc, + 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, + 0x0005, 0x1128, 0x11d0, 0x1204, 0x12dc, 0x0dc5, 0x12f7, 0x0dc5, + 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, + 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, + 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, + 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, + 0x116d, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, + 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7008, 0x0096, 0x2048, + 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, + 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x1182, + 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, + 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, + 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, + 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, + 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, + 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, + 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, + 0x1117, 0x0005, 0x00de, 0x009e, 0x080c, 0x1117, 0x0005, 0xa8a8, + 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c, + 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, + 0x4002, 0x080c, 0x6e92, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, + 0x080c, 0x1040, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, + 0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, + 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, + 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, + 0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6e92, + 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, + 0x080c, 0xb2d3, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, + 0x0000, 0x080c, 0x1040, 0x7007, 0x0000, 0x080c, 0x1117, 0x00ae, + 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, + 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x192f, + 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, + 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, + 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, + 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, + 0x782b, 0x0040, 0x0096, 0x2001, 0x192f, 0x204c, 0xaa7c, 0x009e, + 0x080c, 0x8d91, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, + 0x080c, 0x8bf3, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007, + 0x0000, 0x080c, 0x1128, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, + 0x0300, 0x2071, 0x1a65, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b, + 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03ea, + 0x2061, 0xf0ae, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, + 0x1f04, 0x1312, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, + 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0120, + 0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a66, 0x2003, 0x0000, + 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, + 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, + 0x1a89, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004, + 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a89, 0x602f, 0x1cd0, + 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20c7, + 0x2001, 0x33b6, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004, + 0xd0c4, 0x1128, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f, + 0x33b6, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3b6, 0x604f, 0x193d, + 0x2001, 0x1928, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d, + 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, + 0xd0c6, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, + 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, + 0xb352, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, + 0x9184, 0x0070, 0x190c, 0x0dbe, 0xd19c, 0x0158, 0x7820, 0x908c, + 0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0dc5, 0x0023, 0x012e, + 0x0005, 0x012e, 0x0005, 0x13cf, 0x13cf, 0x13e6, 0x13eb, 0x13ef, + 0x13f4, 0x141c, 0x1420, 0x142e, 0x1432, 0x13cf, 0x14ff, 0x1503, + 0x1575, 0x157c, 0x13cf, 0x157d, 0x157e, 0x1589, 0x1590, 0x13cf, + 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13f6, 0x13cf, + 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13d3, 0x13d1, 0x080c, + 0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7e, 0x2104, + 0x8000, 0x200a, 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0005, 0x2009, + 0x0048, 0x2060, 0x080c, 0xb352, 0x012e, 0x0005, 0x7004, 0xc085, + 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, + 0x159b, 0x080c, 0x16fb, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x159b, + 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, + 0x0048, 0x080c, 0xb352, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, + 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x15a0, 0x2001, + 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, + 0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, + 0x009e, 0x2009, 0x0048, 0x080c, 0xb352, 0x0005, 0x080c, 0x159b, + 0x080c, 0x0dc5, 0x080c, 0x159b, 0x080c, 0x14ea, 0x7827, 0x0018, + 0x79ac, 0xd1dc, 0x0904, 0x149b, 0x7827, 0x0015, 0x7828, 0x782b, + 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0804, 0x14a1, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab, + 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0dc5, + 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x14cf, + 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x0005, 0x7827, + 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, + 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, + 0x0140, 0x00ee, 0x080c, 0x1ad9, 0x080c, 0x1322, 0x7803, 0x0001, + 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, + 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, + 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x2001, 0x020d, + 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, + 0x0dc5, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, + 0x080c, 0x813a, 0x080c, 0x1ad9, 0x080c, 0xd0d8, 0x0158, 0xa9ac, + 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, + 0xc0bd, 0xa882, 0x080c, 0xccf3, 0x0005, 0x6020, 0x9086, 0x0009, + 0x1128, 0x2009, 0x004c, 0x080c, 0xb352, 0x0048, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd4c4, 0x2029, + 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x7dbc, 0x080c, 0xf057, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005, + 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0005, 0x781f, 0x0300, 0x7803, + 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, + 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, + 0x080c, 0x1611, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, + 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0dc5, + 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, + 0x16de, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x080c, 0x15a0, 0x0005, 0x81ff, 0x190c, 0x0dc5, 0x0005, + 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, + 0x156a, 0x2071, 0x0200, 0x080c, 0x16cb, 0x05e0, 0x080c, 0x16de, + 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, + 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, + 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, + 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x18fd, 0x00fe, 0x2009, 0x01f4, + 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, + 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x15a0, 0x0040, 0x2001, + 0x020d, 0x2003, 0x0020, 0x080c, 0x1322, 0x7803, 0x0001, 0x00ee, + 0x001e, 0x0005, 0x080c, 0x16de, 0x0dd0, 0x2001, 0x020d, 0x2003, + 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, + 0x0053, 0x080c, 0xb352, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, + 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x90de, + 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ce2, 0x0cd0, 0x0005, + 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, + 0x080c, 0x1611, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, + 0x080c, 0x14ea, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, + 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, + 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, + 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, + 0x810c, 0x080c, 0x1603, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, + 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, + 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, + 0x080c, 0x813a, 0x080c, 0x1ad9, 0x0090, 0x7827, 0x0015, 0x782b, + 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, + 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, + 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, + 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, + 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, + 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, + 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140, + 0x0016, 0x0026, 0x00c6, 0x080c, 0x1394, 0x00ce, 0x002e, 0x001e, + 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, + 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0dc5, 0x2009, 0x180c, 0x2104, 0xc0f4, 0x200a, + 0x2009, 0xff00, 0x8109, 0x0904, 0x168f, 0x7a18, 0x9284, 0x0030, + 0x0904, 0x168a, 0x9284, 0x0048, 0x9086, 0x0008, 0x1904, 0x168a, + 0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026, + 0x0016, 0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, + 0x94b1, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e, + 0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x01d0, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x00f6, + 0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, + 0x1eeb, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, + 0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x163a, 0x0005, 0x2001, + 0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284, 0x0030, 0x0508, + 0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f7, 0x2004, + 0x9005, 0x01b8, 0x2001, 0x1a69, 0x2004, 0x9086, 0x0000, 0x0188, + 0x2009, 0x1a80, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa767, + 0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804, + 0x163a, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, + 0x8080, 0x080c, 0x1633, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, + 0x2004, 0x080c, 0x0dc5, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, + 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, + 0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, + 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, + 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a7f, 0x2404, 0x8000, + 0x0208, 0x2022, 0x080c, 0x813a, 0x080c, 0x1ad9, 0x9006, 0x00ee, + 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, + 0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, + 0x0904, 0x175d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, + 0x0904, 0x175d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, + 0x00ce, 0x918e, 0x0039, 0x1904, 0x175d, 0x9c06, 0x15f0, 0x0126, + 0x2091, 0x2600, 0x080c, 0x8081, 0x012e, 0x7358, 0x745c, 0x6014, + 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x190c, 0xd49f, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, + 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, + 0x080c, 0x20e7, 0x1190, 0x080c, 0x195a, 0x2a00, 0xa816, 0x0130, + 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, + 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, + 0x0020, 0x001e, 0x00ee, 0x080c, 0x15a0, 0x0005, 0x080c, 0x0dc5, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x190c, 0x6b5e, 0x2ff0, 0x0126, + 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, + 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, + 0x20c7, 0x2165, 0x0002, 0x179a, 0x1808, 0x179a, 0x179a, 0x179e, + 0x17e9, 0x179a, 0x17be, 0x1793, 0x17ff, 0x179a, 0x179a, 0x17a3, + 0x18f5, 0x17d2, 0x17c8, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, + 0x0904, 0x17ff, 0x9085, 0x0001, 0x0804, 0x18eb, 0xa87c, 0xd0ac, + 0x0dc8, 0x0804, 0x180f, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x187a, + 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, + 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x933d, 0x2005, 0x9005, + 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18d3, 0xa87c, 0xd0bc, + 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x180f, + 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, + 0x0804, 0x187a, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, + 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, + 0x000f, 0x9d80, 0x20c7, 0x2065, 0xa888, 0xd19c, 0x1904, 0x187a, + 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x179a, 0xa804, 0x9045, 0x090c, + 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20c7, 0x2065, + 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x187a, 0x0080, 0xa87c, + 0xd0ac, 0x0904, 0x179a, 0x9006, 0xa842, 0xa83e, 0x0804, 0x187a, + 0xa87c, 0xd0ac, 0x0904, 0x179a, 0x9006, 0xa842, 0xa83e, 0x2c05, + 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1832, + 0x1832, 0x1834, 0x1832, 0x1832, 0x1832, 0x183e, 0x1832, 0x1832, + 0x1832, 0x1848, 0x1832, 0x1832, 0x1832, 0x1852, 0x1832, 0x1832, + 0x1832, 0x185c, 0x1832, 0x1832, 0x1832, 0x1866, 0x1832, 0x1832, + 0x1832, 0x1870, 0x080c, 0x0dc5, 0xa574, 0xa478, 0x9d86, 0x0024, + 0x0904, 0x17a8, 0xa37c, 0xa280, 0x0804, 0x18d3, 0xa584, 0xa488, + 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa38c, 0xa290, 0x0804, 0x18d3, + 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa39c, 0xa2a0, + 0x0804, 0x18d3, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17a8, + 0xa3ac, 0xa2b0, 0x0804, 0x18d3, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, + 0x0904, 0x17a8, 0xa3bc, 0xa2c0, 0x0804, 0x18d3, 0xa5c4, 0xa4c8, + 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa3cc, 0xa2d0, 0x0804, 0x18d3, + 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17a8, 0xa3dc, 0xa2e0, + 0x0804, 0x18d3, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x189d, 0x189b, 0x189b, 0x189b, 0x189b, 0x189b, + 0x18a8, 0x189b, 0x189b, 0x189b, 0x189b, 0x189b, 0x18b3, 0x189b, + 0x189b, 0x189b, 0x189b, 0x189b, 0x18be, 0x189b, 0x189b, 0x189b, + 0x189b, 0x189b, 0x18c9, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, + 0xa678, 0x9d86, 0x002c, 0x0904, 0x17a8, 0xa37c, 0xa280, 0x0458, + 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x17a8, + 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, + 0x002c, 0x0904, 0x17a8, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, + 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17a8, 0xa3c4, 0xa2c8, + 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, + 0x17a8, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, + 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, + 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, + 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, + 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x179a, 0x2001, + 0x180d, 0x2004, 0xd08c, 0x190c, 0x6b5e, 0x2ff0, 0x0126, 0x2091, + 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, + 0x2061, 0x20c2, 0xa813, 0x20c2, 0x2c05, 0xa80a, 0xa964, 0xa91a, + 0xa87c, 0xd0ac, 0x090c, 0x0dc5, 0x9006, 0xa842, 0xa83e, 0x2c05, + 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0xadcc, 0xacd0, 0xafd4, 0xaed8, + 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, + 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, + 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, + 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, + 0x9045, 0x090c, 0x0dc5, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, + 0x9080, 0x20c7, 0x2015, 0x82ff, 0x090c, 0x0dc5, 0xaa12, 0x2205, + 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, + 0x0002, 0x1a4f, 0x19b1, 0x19b1, 0x1a4f, 0x1a4f, 0x1a49, 0x1a4f, + 0x19b1, 0x1a00, 0x1a00, 0x1a00, 0x1a4f, 0x1a4f, 0x1a4f, 0x1a46, + 0x1a00, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, + 0x0904, 0x1a51, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x199d, 0x199b, 0x199b, 0x199b, 0x199b, 0x199b, + 0x19a1, 0x199b, 0x199b, 0x199b, 0x199b, 0x199b, 0x19a5, 0x199b, + 0x199b, 0x199b, 0x199b, 0x199b, 0x19a9, 0x199b, 0x199b, 0x199b, + 0x199b, 0x199b, 0x19ad, 0x080c, 0x0dc5, 0xa774, 0xa678, 0x0804, + 0x1a51, 0xa78c, 0xa690, 0x0804, 0x1a51, 0xa7a4, 0xa6a8, 0x0804, + 0x1a51, 0xa7bc, 0xa6c0, 0x0804, 0x1a51, 0xa7d4, 0xa6d8, 0x0804, + 0x1a51, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x19d4, 0x19d4, 0x19d6, 0x19d4, 0x19d4, 0x19d4, 0x19dc, + 0x19d4, 0x19d4, 0x19d4, 0x19e2, 0x19d4, 0x19d4, 0x19d4, 0x19e8, + 0x19d4, 0x19d4, 0x19d4, 0x19ee, 0x19d4, 0x19d4, 0x19d4, 0x19f4, + 0x19d4, 0x19d4, 0x19d4, 0x19fa, 0x080c, 0x0dc5, 0xa574, 0xa478, + 0xa37c, 0xa280, 0x0804, 0x1a51, 0xa584, 0xa488, 0xa38c, 0xa290, + 0x0804, 0x1a51, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1a51, + 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1a51, 0xa5b4, 0xa4b8, + 0xa3bc, 0xa2c0, 0x0804, 0x1a51, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, + 0x0804, 0x1a51, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1a51, + 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, + 0x1a23, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a2a, 0x1a21, + 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a31, 0x1a21, 0x1a21, 0x1a21, + 0x1a21, 0x1a21, 0x1a38, 0x1a21, 0x1a21, 0x1a21, 0x1a21, 0x1a21, + 0x1a3f, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, + 0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, + 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, + 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, + 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, + 0x1130, 0x080c, 0x207f, 0x1904, 0x195a, 0x900e, 0x0050, 0x080c, + 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, + 0x207f, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, + 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, + 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, + 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, + 0xb352, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, + 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, + 0x601e, 0x2009, 0x0048, 0x0804, 0xb352, 0x0005, 0x0126, 0x00c6, + 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, + 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, + 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, + 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, + 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce, 0x2001, + 0x0038, 0x080c, 0x1b69, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, + 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, + 0x1d40, 0x080c, 0x1b78, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, + 0x1b65, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, + 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, + 0x2001, 0xf000, 0x8001, 0x090c, 0x0dc5, 0x7aac, 0xd2ac, 0x1dd0, + 0x00fe, 0x080c, 0x7637, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, + 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, + 0x8211, 0x1de0, 0x0059, 0x0804, 0x76e4, 0x0479, 0x0039, 0x2001, + 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, + 0x0200, 0x080c, 0x2c6d, 0x2009, 0x003c, 0x080c, 0x2409, 0x2001, + 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, + 0x8725, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, + 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1322, + 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, + 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, + 0x7637, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, + 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, + 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, + 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, + 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, + 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, + 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005, 0x2c08, + 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, + 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, + 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bd6, 0x2001, 0x001e, 0x0c69, + 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001, 0x015d, + 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, + 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, + 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, + 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, + 0x080c, 0x1b6f, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6, 0x2069, + 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, + 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, + 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, + 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, + 0x2091, 0x2400, 0x2071, 0x1a69, 0x2079, 0x0090, 0x012e, 0x0005, + 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1c78, + 0xa964, 0x9184, 0x0007, 0x0002, 0x1bf4, 0x1c63, 0x1c0b, 0x1c0d, + 0x1c0b, 0x1c4b, 0x1c2b, 0x1c1a, 0x918c, 0x00ff, 0x9186, 0x0008, + 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0x9006, 0xa842, 0xa83e, + 0xa988, 0x2900, 0xa85a, 0xa813, 0x20c2, 0x0804, 0x1c74, 0x9186, + 0x0048, 0x0904, 0x1c63, 0x080c, 0x0dc5, 0x9184, 0x00ff, 0x9086, + 0x0013, 0x0904, 0x1c63, 0x9184, 0x00ff, 0x9086, 0x001b, 0x0904, + 0x1c63, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa890, 0xa842, + 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, + 0xa988, 0x0804, 0x1c6b, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, + 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa890, 0xa842, 0xa83a, + 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa804, + 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20c7, 0x2005, + 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015, 0x1540, + 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa804, 0xa85a, 0x2040, 0xa064, + 0x9084, 0x000f, 0x9080, 0x20c7, 0x2005, 0xa812, 0xa988, 0x9006, + 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ea5, 0xa988, + 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084, 0x000f, + 0x9080, 0x20c7, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, + 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c, 0x1eeb, + 0x00e6, 0x2071, 0x1a69, 0x7000, 0x9005, 0x1904, 0x1cdf, 0x7206, + 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b, 0x0004, + 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, + 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200, 0x7803, + 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x781a, + 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040, 0xa810, + 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116, 0xa848, + 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940, 0xa838, + 0x9106, 0x1500, 0xa93c, 0xa834, 0x9106, 0x11e0, 0x0006, 0x0016, + 0xa938, 0xa834, 0x9105, 0x0118, 0x001e, 0x000e, 0x0098, 0x001e, + 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009, 0x0306, + 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006, 0x00ee, + 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c, 0x20e7, + 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x2009, + 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076, 0x0066, + 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1e9e, 0x700c, + 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1e9d, 0x9705, + 0x0904, 0x1e9d, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, + 0x0002, 0x1e22, 0x1d61, 0x1d61, 0x1e22, 0x1e22, 0x1dff, 0x1e22, + 0x1d61, 0x1e06, 0x1db0, 0x1db0, 0x1e22, 0x1e22, 0x1e22, 0x1df9, + 0x1db0, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, + 0x0904, 0x1e2f, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x1d4d, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, + 0x1d51, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d55, 0x1d4b, + 0x1d4b, 0x1d4b, 0x1d4b, 0x1d4b, 0x1d59, 0x1d4b, 0x1d4b, 0x1d4b, + 0x1d4b, 0x1d4b, 0x1d5d, 0x080c, 0x0dc5, 0xa774, 0xa678, 0x0804, + 0x1e2f, 0xa78c, 0xa690, 0x0804, 0x1e2f, 0xa7a4, 0xa6a8, 0x0804, + 0x1e2f, 0xa7bc, 0xa6c0, 0x0804, 0x1e2f, 0xa7d4, 0xa6d8, 0x0804, + 0x1e2f, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x1d84, 0x1d84, 0x1d86, 0x1d84, 0x1d84, 0x1d84, 0x1d8c, + 0x1d84, 0x1d84, 0x1d84, 0x1d92, 0x1d84, 0x1d84, 0x1d84, 0x1d98, + 0x1d84, 0x1d84, 0x1d84, 0x1d9e, 0x1d84, 0x1d84, 0x1d84, 0x1da4, + 0x1d84, 0x1d84, 0x1d84, 0x1daa, 0x080c, 0x0dc5, 0xa574, 0xa478, + 0xa37c, 0xa280, 0x0804, 0x1e2f, 0xa584, 0xa488, 0xa38c, 0xa290, + 0x0804, 0x1e2f, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1e2f, + 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e2f, 0xa5b4, 0xa4b8, + 0xa3bc, 0xa2c0, 0x0804, 0x1e2f, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, + 0x0804, 0x1e2f, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1e2f, + 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, + 0x1dd3, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1ddb, 0x1dd1, + 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1de3, 0x1dd1, 0x1dd1, 0x1dd1, + 0x1dd1, 0x1dd1, 0x1deb, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, 0x1dd1, + 0x1df2, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, + 0xa280, 0x0804, 0x1e2f, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, + 0xa298, 0x0804, 0x1e2f, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, + 0xa2b0, 0x0804, 0x1e2f, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, + 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, + 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518, 0x080c, + 0x207f, 0x1904, 0x1cfc, 0x900e, 0x0804, 0x1e9e, 0xab64, 0x939c, + 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, + 0x9086, 0x0043, 0x00ce, 0x0904, 0x1db0, 0xab9c, 0x9016, 0xad8c, + 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904, 0x1db0, + 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013, 0x0904, + 0x1d61, 0x9186, 0x001b, 0x0904, 0x1db0, 0x080c, 0x0dc5, 0x2009, + 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306, 0x2134, + 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031, 0x1000, + 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278, 0x9105, + 0x0168, 0x2011, 0x0000, 0x2618, 0x2600, 0x9500, 0xa81e, 0x9481, + 0x0000, 0xa822, 0xa880, 0xc0fd, 0xa882, 0x0020, 0xa82f, 0x0000, + 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, + 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, + 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e, 0x7010, + 0x9201, 0x7012, 0x080c, 0x207f, 0x0448, 0xd6b4, 0x0110, 0x200b, + 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, 0x7124, + 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, 0x0306, + 0x2104, 0xd0b4, 0x1904, 0x1e40, 0x200b, 0x4040, 0x2009, 0x1a83, + 0x2104, 0x8000, 0x0a04, 0x1e40, 0x200a, 0x0804, 0x1e40, 0xc18d, + 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e40, 0x9006, 0x002e, 0x003e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5, 0x0026, + 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, + 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0118, 0xa880, + 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1cef, 0x6020, + 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, + 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, + 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xccf3, 0x00ce, 0x2001, + 0x19f7, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, 0x2409, + 0x080c, 0xac2b, 0x2011, 0x0000, 0x080c, 0xaac9, 0x080c, 0x9bd3, + 0x002e, 0x0804, 0x202f, 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, + 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ea7, 0x7000, + 0x0002, 0x202f, 0x1efd, 0x1f7d, 0x202d, 0x8001, 0x7002, 0x7027, + 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f4a, 0x080c, 0x1cf6, + 0x0904, 0x202f, 0x080c, 0x1cf6, 0x0804, 0x202f, 0x782b, 0x0004, + 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518, 0xa87c, + 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x0016, + 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101, 0xa832, + 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e, 0x7804, + 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x209a, 0xa880, + 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, + 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, + 0x0804, 0x202f, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, + 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, + 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820, 0xd0bc, + 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, + 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, + 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003, + 0x0000, 0x080c, 0x1cef, 0x0804, 0x202f, 0x8001, 0x7002, 0x7024, + 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1ef0, + 0xd19c, 0x1904, 0x202b, 0x8aff, 0x0904, 0x202f, 0x080c, 0x1cf6, + 0x0804, 0x202f, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x209a, + 0xdd9c, 0x1904, 0x1fea, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, + 0x9082, 0x001b, 0x0002, 0x1fbe, 0x1fbe, 0x1fc0, 0x1fbe, 0x1fbe, + 0x1fbe, 0x1fc6, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fcc, 0x1fbe, 0x1fbe, + 0x1fbe, 0x1fd2, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fd8, 0x1fbe, 0x1fbe, + 0x1fbe, 0x1fde, 0x1fbe, 0x1fbe, 0x1fbe, 0x1fe4, 0x080c, 0x0dc5, + 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f1f, 0xa08c, 0x931a, + 0xa090, 0x9213, 0x0804, 0x1f1f, 0xa09c, 0x931a, 0xa0a0, 0x9213, + 0x0804, 0x1f1f, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f1f, + 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f1f, 0xa0cc, 0x931a, + 0xa0d0, 0x9213, 0x0804, 0x1f1f, 0xa0dc, 0x931a, 0xa0e0, 0x9213, + 0x0804, 0x1f1f, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x200d, 0x200b, 0x200b, 0x200b, 0x200b, 0x200b, + 0x2013, 0x200b, 0x200b, 0x200b, 0x200b, 0x200b, 0x2019, 0x200b, + 0x200b, 0x200b, 0x200b, 0x200b, 0x201f, 0x200b, 0x200b, 0x200b, + 0x200b, 0x200b, 0x2025, 0x080c, 0x0dc5, 0xa07c, 0x931a, 0xa080, + 0x9213, 0x0804, 0x1f1f, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, + 0x1f1f, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f1f, 0xa0c4, + 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f1f, 0xa0dc, 0x931a, 0xa0e0, + 0x9213, 0x0804, 0x1f1f, 0x0804, 0x1f1b, 0x080c, 0x0dc5, 0x012e, + 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a69, 0x7000, 0x9086, 0x0000, + 0x0904, 0x207a, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, + 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, + 0xf0a0, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5, 0x0016, + 0x2009, 0x0040, 0x080c, 0x2409, 0x001e, 0x2001, 0x020c, 0x2102, + 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, + 0x2009, 0x0040, 0x080c, 0x2409, 0x782c, 0xd0fc, 0x09a8, 0x080c, + 0x1eeb, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, + 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2409, 0x782b, 0x0002, + 0x7003, 0x0000, 0x080c, 0x1cef, 0x00ee, 0x00fe, 0x0005, 0xa880, + 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, + 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, + 0x9080, 0x20c7, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51, 0x0005, + 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61, 0x2c05, + 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, + 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x20d7, + 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d, 0x0021, + 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, + 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, + 0x20ba, 0x20b6, 0x20ba, 0x20ba, 0x20c4, 0x0000, 0x20ba, 0x20c1, + 0x20c1, 0x20be, 0x20c1, 0x20c1, 0x0000, 0x20c4, 0x20c1, 0x0000, + 0x20bc, 0x20bc, 0x0000, 0x20bc, 0x20c4, 0x0000, 0x20bc, 0x20c2, + 0x20c2, 0x20c2, 0x0000, 0x20c2, 0x0000, 0x20c4, 0x20c2, 0x00c6, + 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x22c6, + 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, + 0x1118, 0x2061, 0x20c2, 0x00d0, 0x9de0, 0x20c7, 0x9d86, 0x0007, + 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, + 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, + 0x22c6, 0xa004, 0x9045, 0x0904, 0x22c6, 0x08d8, 0x2c05, 0x9005, + 0x0904, 0x21ae, 0xdd9c, 0x1904, 0x216a, 0x908a, 0x0036, 0x1a0c, + 0x0dc5, 0x9082, 0x001b, 0x0002, 0x213f, 0x213f, 0x2141, 0x213f, + 0x213f, 0x213f, 0x2147, 0x213f, 0x213f, 0x213f, 0x214d, 0x213f, + 0x213f, 0x213f, 0x2153, 0x213f, 0x213f, 0x213f, 0x2159, 0x213f, + 0x213f, 0x213f, 0x215f, 0x213f, 0x213f, 0x213f, 0x2165, 0x080c, + 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21a4, 0xa08c, + 0x9422, 0xa090, 0x931b, 0x0804, 0x21a4, 0xa09c, 0x9422, 0xa0a0, + 0x931b, 0x0804, 0x21a4, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, + 0x21a4, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21a4, 0xa0cc, + 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21a4, 0xa0dc, 0x9422, 0xa0e0, + 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, + 0x0002, 0x218c, 0x218a, 0x218a, 0x218a, 0x218a, 0x218a, 0x2191, + 0x218a, 0x218a, 0x218a, 0x218a, 0x218a, 0x2196, 0x218a, 0x218a, + 0x218a, 0x218a, 0x218a, 0x219b, 0x218a, 0x218a, 0x218a, 0x218a, + 0x218a, 0x21a0, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, + 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, + 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, + 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, + 0x8a51, 0x0904, 0x22c6, 0x8c60, 0x0804, 0x2116, 0xa004, 0x9045, + 0x0904, 0x22c6, 0x0804, 0x20f1, 0x8a51, 0x0904, 0x22c6, 0x8c60, + 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22c6, 0xa064, + 0x90ec, 0x000f, 0x9de0, 0x20c7, 0x2c05, 0x2060, 0xa880, 0xc0fc, + 0xa882, 0x0804, 0x22bb, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, + 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2258, 0x9082, 0x001b, + 0x0002, 0x21f4, 0x21f4, 0x21f6, 0x21f4, 0x21f4, 0x21f4, 0x2204, + 0x21f4, 0x21f4, 0x21f4, 0x2212, 0x21f4, 0x21f4, 0x21f4, 0x2220, + 0x21f4, 0x21f4, 0x21f4, 0x222e, 0x21f4, 0x21f4, 0x21f4, 0x223c, + 0x21f4, 0x21f4, 0x21f4, 0x224a, 0x080c, 0x0dc5, 0xa17c, 0x2400, + 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074, 0x9420, + 0xa078, 0x9319, 0x0804, 0x22b6, 0xa18c, 0x2400, 0x9122, 0xa190, + 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319, + 0x0804, 0x22b6, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, + 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x22b6, + 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, + 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22b6, 0xa1bc, 0x2400, + 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420, + 0xa0b8, 0x9319, 0x0804, 0x22b6, 0xa1cc, 0x2400, 0x9122, 0xa1d0, + 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8, 0x9319, + 0x0804, 0x22b6, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, + 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x22b6, + 0x9082, 0x001b, 0x0002, 0x2276, 0x2274, 0x2274, 0x2274, 0x2274, + 0x2274, 0x2283, 0x2274, 0x2274, 0x2274, 0x2274, 0x2274, 0x2290, + 0x2274, 0x2274, 0x2274, 0x2274, 0x2274, 0x229d, 0x2274, 0x2274, + 0x2274, 0x2274, 0x2274, 0x22aa, 0x080c, 0x0dc5, 0xa17c, 0x2400, + 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c, 0x9420, + 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, + 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, + 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, + 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, + 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420, 0xa0b8, + 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, + 0x0a0c, 0x0dc5, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, + 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, + 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, + 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, + 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x22e7, 0x1eeb, 0x22e7, + 0x22dd, 0x22e0, 0x22e3, 0x22e0, 0x22e3, 0x080c, 0x1eeb, 0x0005, + 0x080c, 0x11b2, 0x0005, 0x080c, 0x1eeb, 0x080c, 0x11b2, 0x0005, + 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, + 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, + 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, + 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, + 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2406, 0x7900, 0xd1dc, 0x1118, + 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x232e, 0x2326, + 0x8081, 0x2326, 0x2328, 0x2328, 0x2328, 0x2328, 0x8067, 0x2326, + 0x232a, 0x2326, 0x2328, 0x2326, 0x2328, 0x2326, 0x080c, 0x0dc5, + 0x0031, 0x0020, 0x080c, 0x8067, 0x080c, 0x8081, 0x0005, 0x0006, + 0x0016, 0x0026, 0x080c, 0xf0a0, 0x7930, 0x9184, 0x0003, 0x01c0, + 0x2001, 0x19f7, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, + 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f7, 0x2064, 0x080c, + 0xccf3, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2409, 0x00d0, + 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, + 0x7637, 0x1138, 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x7563, + 0x0010, 0x080c, 0x5fed, 0x080c, 0x8130, 0x0041, 0x0018, 0x9184, + 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, + 0x0046, 0x0056, 0x2071, 0x1a65, 0x080c, 0x1ad9, 0x005e, 0x004e, + 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, + 0x7128, 0x2001, 0x196f, 0x2102, 0x2001, 0x1977, 0x2102, 0x2001, + 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, + 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, + 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, + 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, + 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, + 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, + 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, + 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, + 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, + 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, + 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, + 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, + 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, + 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, + 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, + 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, + 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, + 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c67, 0x080c, + 0x2b82, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, + 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, + 0x9085, 0x2000, 0x6052, 0x2009, 0x199d, 0x2011, 0x199e, 0x6358, + 0x939c, 0x38f0, 0x2320, 0x080c, 0x2bc6, 0x1238, 0x939d, 0x4003, + 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, + 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, + 0x2b94, 0x20a9, 0x0012, 0x1d04, 0x245b, 0x2091, 0x6000, 0x1f04, + 0x245b, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, + 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28ac, 0x2009, + 0x00ef, 0x6132, 0x6136, 0x080c, 0x28bc, 0x60e7, 0x0000, 0x61ea, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1110, 0x2001, + 0x0008, 0x60e2, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, + 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, 0x0018, + 0x60bf, 0x0000, 0x1f04, 0x2490, 0x60bb, 0x0000, 0x60bf, 0x0108, + 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, + 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, + 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, + 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, + 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x0066, + 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, + 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, + 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, + 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0d70, + 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, 0x0d30, + 0x0c58, 0x2513, 0x24f9, 0x24fc, 0x24ff, 0x2504, 0x2506, 0x250a, + 0x250e, 0x080c, 0x93e2, 0x00b8, 0x080c, 0x94b1, 0x00a0, 0x080c, + 0x94b1, 0x080c, 0x93e2, 0x0078, 0x0099, 0x0068, 0x080c, 0x93e2, + 0x0079, 0x0048, 0x080c, 0x94b1, 0x0059, 0x0028, 0x080c, 0x94b1, + 0x080c, 0x93e2, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, + 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2784, + 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7637, 0x0904, 0x256e, 0x080c, + 0xd7e3, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, + 0x1800, 0x0550, 0x080c, 0x765a, 0x0118, 0x080c, 0x7648, 0x1520, + 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd7e3, 0x0168, 0x080c, + 0x765a, 0x1150, 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, + 0x080c, 0x74b2, 0x0804, 0x2787, 0x70a4, 0x9005, 0x1150, 0x70a7, + 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x768b, 0x00de, 0x1904, + 0x2787, 0x080c, 0x793c, 0x0428, 0x080c, 0x765a, 0x1590, 0x6024, + 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x793c, 0x080c, 0x7932, + 0x080c, 0x612e, 0x080c, 0x7563, 0x0804, 0x2784, 0xd1ac, 0x1508, + 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, + 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x7818, 0x0804, + 0x2784, 0x080c, 0x7937, 0x0048, 0x2001, 0x197d, 0x2003, 0x0002, + 0x0020, 0x080c, 0x7774, 0x0804, 0x2784, 0x080c, 0x78ba, 0x0804, + 0x2784, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27e1, 0xd2b4, + 0x1904, 0x27f4, 0x0000, 0xd1ac, 0x0904, 0x2699, 0x0036, 0x6328, + 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7637, 0x11c0, 0x6027, 0x0020, + 0x0006, 0x0026, 0x0036, 0x080c, 0x7651, 0x1158, 0x080c, 0x7932, + 0x080c, 0x612e, 0x080c, 0x7563, 0x003e, 0x002e, 0x000e, 0x00ae, + 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x760f, 0x0016, 0x0046, + 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, + 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, + 0xd084, 0x0190, 0x080c, 0xd7e3, 0x1118, 0x9186, 0xf800, 0x1160, + 0x7048, 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, + 0x8016, 0x080c, 0x4c44, 0x003e, 0x080c, 0xd7dc, 0x1904, 0x2676, + 0x9196, 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, + 0x0110, 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33aa, + 0x0128, 0xc18d, 0x7132, 0x080c, 0x6a9b, 0x1510, 0x6240, 0x9294, + 0x0010, 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, + 0x7030, 0xd08c, 0x0904, 0x2676, 0x7038, 0xd08c, 0x1140, 0x2001, + 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2676, 0xc1ad, 0x2102, 0x0036, + 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c44, 0x003e, 0x0804, 0x2676, + 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, + 0x2676, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, + 0x4c44, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, + 0xd1a4, 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, + 0x8a50, 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xeba1, + 0x00ce, 0x9484, 0x00ff, 0x9080, 0x33b6, 0x200d, 0x918c, 0xff00, + 0x810f, 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xec31, 0x001e, + 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x321b, 0x001e, + 0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6724, + 0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, + 0x6148, 0x8108, 0x1f04, 0x2666, 0x00be, 0x015e, 0x00ce, 0x004e, + 0x080c, 0xb244, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, + 0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, + 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, + 0x622a, 0x2003, 0x0001, 0x2001, 0x1826, 0x2003, 0x0000, 0x6027, + 0x0020, 0xd194, 0x0904, 0x2784, 0x0016, 0x6220, 0xd2b4, 0x0904, + 0x2721, 0x080c, 0x88c3, 0x080c, 0xa6e9, 0x6027, 0x0004, 0x00f6, + 0x2019, 0x19f1, 0x2304, 0x907d, 0x0904, 0x26f0, 0x7804, 0x9086, + 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, + 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, + 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, + 0x080c, 0x2d49, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, + 0x080c, 0x2c42, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, + 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x080c, 0x99a5, 0x080c, + 0x9ab1, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xb2d3, + 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, + 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, + 0x080c, 0x2d49, 0x00de, 0x00c6, 0x2061, 0x19e8, 0x6028, 0x080c, + 0xd7e3, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, + 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0xa6c5, 0x0804, 0x2783, + 0x2061, 0x0100, 0x62c0, 0x080c, 0xb0ca, 0x2019, 0x19f1, 0x2304, + 0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xb352, 0x00ce, 0x0804, + 0x2783, 0xd2bc, 0x0904, 0x276a, 0x080c, 0x88d0, 0x6014, 0x9084, + 0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, + 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d49, 0x00de, + 0x00c6, 0x2061, 0x19e8, 0x6044, 0x080c, 0xd7e3, 0x0120, 0x909a, + 0x0003, 0x1658, 0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, + 0x603c, 0x00ce, 0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x88c8, + 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, + 0x1984, 0x918d, 0x0012, 0x6116, 0x0430, 0x9080, 0x0008, 0x2004, + 0x9086, 0x0009, 0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, 0x0016, + 0x6116, 0x00c8, 0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, + 0x080c, 0xaa49, 0x003e, 0x2019, 0x19f7, 0x2304, 0x9065, 0x0150, + 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, + 0x080c, 0xb352, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27dc, 0x7038, + 0xd0ac, 0x1538, 0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2d73, + 0x20a9, 0x0028, 0xa001, 0x1f04, 0x2792, 0x6150, 0x9185, 0x1400, + 0x6052, 0x20a9, 0x0366, 0x1d04, 0x279b, 0x080c, 0x88f7, 0x6020, + 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0, + 0x080c, 0x2c29, 0x1f04, 0x279b, 0x015e, 0x6152, 0x001e, 0x6027, + 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xb244, 0x60e3, + 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x080c, 0x57d9, 0xd0fc, + 0x1138, 0x080c, 0xd7dc, 0x1120, 0x9085, 0x0001, 0x080c, 0x767b, + 0x9006, 0x080c, 0x2d39, 0x2009, 0x0002, 0x080c, 0x2c67, 0x00e6, + 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, 0x6027, + 0x0008, 0x080c, 0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, + 0x0005, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0904, + 0x259b, 0x0016, 0x2009, 0x27ed, 0x00d0, 0x2001, 0x188b, 0x200c, + 0xc184, 0x2102, 0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, 0x200c, + 0xd194, 0x001e, 0x0904, 0x259b, 0x0016, 0x2009, 0x2800, 0x0038, + 0x2001, 0x188b, 0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, 0x6028, + 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, + 0xffff, 0x6043, 0x0001, 0x080c, 0x2c61, 0x6027, 0x0080, 0x6017, + 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, + 0x70d2, 0x9116, 0x0904, 0x286b, 0x81ff, 0x01a0, 0x2009, 0x0000, + 0x080c, 0x2c67, 0x2011, 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, + 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, + 0x4c44, 0x0448, 0x2001, 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, + 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, + 0x2011, 0x8012, 0x080c, 0x4c44, 0x080c, 0x0ea3, 0x080c, 0x57d9, + 0xd0fc, 0x1188, 0x080c, 0xd7dc, 0x1170, 0x00c6, 0x080c, 0x2907, + 0x080c, 0xa9b0, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, + 0x080c, 0x321b, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, + 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, + 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, + 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, + 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, + 0x2500, 0x080c, 0x83a5, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b6, + 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b6, + 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, + 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, + 0x1f04, 0x28b7, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, + 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, + 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, + 0x000f, 0x9080, 0xf880, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28cc, + 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, + 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, + 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, + 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, + 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x28fc, 0x680f, + 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, + 0x57d5, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, + 0x2009, 0x002e, 0x080c, 0xec31, 0x004e, 0x0005, 0x00f6, 0x0016, + 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2973, 0x080c, + 0x2bc6, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, + 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, + 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, + 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, + 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, + 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, + 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, + 0x0020, 0x2018, 0x080c, 0x9375, 0x928c, 0xff00, 0x0110, 0x2011, + 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, + 0x220a, 0x080c, 0x7637, 0x1118, 0x2009, 0x196d, 0x220a, 0x002e, + 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, + 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, + 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, 0x001e, + 0x000e, 0x012e, 0x0005, 0x2001, 0x180d, 0x2004, 0xd08c, 0x0118, + 0x2009, 0x0002, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, + 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, + 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, + 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, + 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, + 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, + 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1990, 0x2004, 0x908a, + 0x0007, 0x1a0c, 0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, + 0x015e, 0x0005, 0x29d9, 0x29f7, 0x2a1b, 0x2a1d, 0x2a46, 0x2a48, + 0x2a4a, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, 0x2c24, 0x2001, + 0x1992, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, + 0x20a9, 0x0009, 0x080c, 0x2be2, 0x2001, 0x1990, 0x2003, 0x0006, + 0x2009, 0x001e, 0x2011, 0x2a4b, 0x080c, 0x88d5, 0x0005, 0x2009, + 0x1995, 0x200b, 0x0000, 0x2001, 0x199a, 0x2003, 0x0036, 0x2001, + 0x1999, 0x2003, 0x002a, 0x2001, 0x1992, 0x2003, 0x0001, 0x9006, + 0x080c, 0x2b94, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2be2, + 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a4b, + 0x080c, 0x88d5, 0x0005, 0x080c, 0x0dc5, 0x2001, 0x199a, 0x2003, + 0x0036, 0x2001, 0x1992, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, + 0x2b94, 0x2001, 0x1996, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, + 0x0009, 0x080c, 0x2be2, 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, + 0x001e, 0x2011, 0x2a4b, 0x080c, 0x88d5, 0x0005, 0x080c, 0x0dc5, + 0x080c, 0x0dc5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, + 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1992, + 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, 0x015e, + 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a6d, 0x2a89, + 0x2ac5, 0x2af1, 0x2b11, 0x2b1d, 0x2b1f, 0x080c, 0x2bd6, 0x1190, + 0x2009, 0x1998, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, + 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1990, 0x2003, + 0x0001, 0x0030, 0x080c, 0x2b43, 0x2001, 0xffff, 0x080c, 0x29e8, + 0x0005, 0x080c, 0x2b21, 0x05c0, 0x2009, 0x1999, 0x2104, 0x8001, + 0x200a, 0x080c, 0x2bd6, 0x1158, 0x7a38, 0x9294, 0x0005, 0x9296, + 0x0005, 0x0518, 0x2009, 0x1998, 0x2104, 0xc085, 0x200a, 0x2009, + 0x1995, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, + 0x2b29, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, + 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, + 0x2001, 0x1992, 0x2003, 0x0002, 0x0028, 0x2001, 0x1990, 0x2003, + 0x0003, 0x0010, 0x080c, 0x2a0a, 0x0005, 0x080c, 0x2b21, 0x0540, + 0x2009, 0x1999, 0x2104, 0x8001, 0x200a, 0x080c, 0x2bd6, 0x1148, + 0x2001, 0x1990, 0x2003, 0x0003, 0x2001, 0x1991, 0x2003, 0x0000, + 0x00b8, 0x2009, 0x1999, 0x2104, 0x9005, 0x1118, 0x080c, 0x2b66, + 0x0010, 0x080c, 0x2b36, 0x080c, 0x2b29, 0x2009, 0x1995, 0x200b, + 0x0000, 0x2001, 0x1992, 0x2003, 0x0001, 0x080c, 0x2a0a, 0x0000, + 0x0005, 0x0479, 0x01e8, 0x080c, 0x2bd6, 0x1198, 0x2009, 0x1996, + 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, + 0x199b, 0x2003, 0x000a, 0x2009, 0x1998, 0x2104, 0xc0fd, 0x200a, + 0x0038, 0x00f9, 0x2001, 0x1992, 0x2003, 0x0004, 0x080c, 0x2a35, + 0x0005, 0x0079, 0x0148, 0x080c, 0x2bd6, 0x1118, 0x080c, 0x2a21, + 0x0018, 0x0079, 0x080c, 0x2a35, 0x0005, 0x080c, 0x0dc5, 0x080c, + 0x0dc5, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x090c, 0x2b82, + 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, + 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, 0x0005, 0x7a38, 0x9294, + 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x2b94, 0x0005, 0x2009, 0x1995, 0x2104, 0x8000, 0x200a, + 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, + 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, + 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb1, 0x0005, 0x0086, 0x2001, + 0x1998, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5, 0x2009, 0x1997, + 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, + 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, + 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1990, 0x20a9, 0x0009, + 0x2003, 0x0000, 0x8000, 0x1f04, 0x2b88, 0x2001, 0x1997, 0x2003, + 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, + 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, + 0x2009, 0x199d, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, + 0x9085, 0x0006, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0138, 0x7838, + 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030, 0x7838, 0x9084, + 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005, 0x0006, 0x2001, + 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, + 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, + 0x0064, 0x7820, 0x080c, 0x2c61, 0xd09c, 0x1110, 0x1f04, 0x2bd9, + 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x7850, + 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, + 0x2c61, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008, 0x9186, 0x0000, + 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, + 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, + 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, + 0x2c0f, 0x080c, 0x88f7, 0x1f04, 0x2c0f, 0x7850, 0x9085, 0x0400, + 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c61, 0x9085, 0x1000, 0x7852, + 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084, 0xffcf, 0x7852, + 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, + 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2c33, + 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c39, 0x00fe, 0x015e, + 0x000e, 0x0005, 0x1d04, 0x2c42, 0x080c, 0x88f7, 0x1f04, 0x2c42, + 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0000, 0x000e, + 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0001, 0x000e, + 0x0005, 0x0006, 0x2001, 0x199c, 0x2004, 0x9086, 0x0002, 0x000e, + 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, + 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, + 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, + 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, + 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, + 0x9186, 0x0100, 0x1904, 0x2cda, 0x0048, 0x0016, 0x2009, 0x1a87, + 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, + 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, + 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, + 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, + 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a88, + 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, + 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, + 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, + 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1981, 0x200c, + 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, + 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, + 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, + 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, + 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006, 0x2001, 0x0161, + 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001, 0x602f, 0x0008, + 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010, 0x6106, 0x6017, + 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, + 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120, 0x2304, 0x9084, + 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, + 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, + 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, + 0x0005, 0x0016, 0x0026, 0x080c, 0x7651, 0x0108, 0xc0bc, 0x2009, + 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, + 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, + 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, + 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, + 0x1128, 0x080c, 0x7651, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, + 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, + 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c61, 0x9085, + 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2d84, 0x080c, 0x88f7, + 0x1f04, 0x2d84, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, + 0x015e, 0x000e, 0x0005, 0x2fff, 0x2fff, 0x2e23, 0x2e23, 0x2e2f, + 0x2e2f, 0x2e3b, 0x2e3b, 0x2e49, 0x2e49, 0x2e55, 0x2e55, 0x2e63, + 0x2e63, 0x2e71, 0x2e71, 0x2e83, 0x2e83, 0x2e8f, 0x2e8f, 0x2e9d, + 0x2e9d, 0x2ebb, 0x2ebb, 0x2edb, 0x2edb, 0x2eab, 0x2eab, 0x2ecb, + 0x2ecb, 0x2ee9, 0x2ee9, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2efb, 0x2efb, 0x2f07, 0x2f07, 0x2f15, + 0x2f15, 0x2f23, 0x2f23, 0x2f33, 0x2f33, 0x2f41, 0x2f41, 0x2f51, + 0x2f51, 0x2f61, 0x2f61, 0x2f73, 0x2f73, 0x2f81, 0x2f81, 0x2f91, + 0x2f91, 0x2fb3, 0x2fb3, 0x2fd5, 0x2fd5, 0x2fa1, 0x2fa1, 0x2fc4, + 0x2fc4, 0x2fe4, 0x2fe4, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, 0x2e81, + 0x2e81, 0x2e81, 0x2e81, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x0804, 0x2ff7, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x22cc, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804, 0x2ff7, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x24c0, 0x080c, 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, + 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, + 0x1394, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x22cc, 0x080c, 0x1394, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x0804, 0x2ff7, 0x0106, + 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, + 0x2976, 0x080c, 0x24c0, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, + 0x22cc, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, + 0x24c0, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x2307, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x24c0, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x1394, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x1394, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, 0x1394, 0x0804, + 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x2976, 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, + 0x2307, 0x0804, 0x2ff7, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, 0x080c, + 0x24c0, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, + 0x080c, 0x1394, 0x080c, 0x2307, 0x0410, 0x0106, 0x0006, 0x0126, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, + 0x1394, 0x080c, 0x2307, 0x0098, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2976, 0x080c, 0x22cc, + 0x080c, 0x24c0, 0x080c, 0x1394, 0x080c, 0x2307, 0x0000, 0x015e, + 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, + 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a61, 0x1904, + 0x3137, 0x72dc, 0x2001, 0x197c, 0x2004, 0x9005, 0x1110, 0xd29c, + 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3137, 0x080c, 0x313c, + 0x0804, 0x3137, 0xd2cc, 0x1904, 0x3137, 0x080c, 0x7637, 0x1120, + 0x70af, 0xffff, 0x0804, 0x3137, 0xd294, 0x0120, 0x70af, 0xffff, + 0x0804, 0x3137, 0x080c, 0x33a5, 0x0160, 0x080c, 0xd7e3, 0x0128, + 0x2001, 0x1818, 0x203c, 0x0804, 0x30b0, 0x70af, 0xffff, 0x0804, + 0x3137, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x30b0, + 0xd28c, 0x1904, 0x30b0, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0x938c, 0x0001, + 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, + 0x0904, 0x30a6, 0x908e, 0x0000, 0x0904, 0x30a6, 0x908e, 0x00ff, + 0x1160, 0x7230, 0xd284, 0x1904, 0x30ab, 0x7294, 0xc28d, 0x7296, + 0x70af, 0xffff, 0x003e, 0x0804, 0x30b0, 0x2009, 0x180d, 0x210c, + 0xd18c, 0x0150, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, + 0x0118, 0x70af, 0xffff, 0x0488, 0x900e, 0x080c, 0x2873, 0x080c, + 0x66b9, 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, + 0x00c6, 0x2060, 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, + 0x0000, 0x080c, 0x6aa3, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, + 0xd0bc, 0x0138, 0x080c, 0x6944, 0x0120, 0x080c, 0x3155, 0x0148, + 0x0028, 0x080c, 0x3295, 0x080c, 0x3181, 0x0118, 0x8318, 0x0804, + 0x304a, 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3137, + 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, + 0x70ac, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, + 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, + 0x3137, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x312c, 0x2001, + 0x180d, 0x2004, 0xd08c, 0x0158, 0x0026, 0x2011, 0x0010, 0x080c, + 0x6ac7, 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x3134, 0xc484, + 0x080c, 0x6724, 0x0168, 0x080c, 0xd7e3, 0x1904, 0x312c, 0x080c, + 0x33a5, 0x1904, 0x312c, 0x080c, 0x66b9, 0x1904, 0x3134, 0x0008, + 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, + 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, 0x0000, 0x080c, + 0x6aa3, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, + 0x7294, 0xd28c, 0x0180, 0x080c, 0x6aa3, 0x9082, 0x0006, 0x02e0, + 0xd484, 0x1118, 0x080c, 0x66de, 0x0028, 0x080c, 0x3321, 0x01a0, + 0x080c, 0x334c, 0x0088, 0x080c, 0x3295, 0x080c, 0xd7e3, 0x1160, + 0x080c, 0x3181, 0x0188, 0x0040, 0x080c, 0xd7e3, 0x1118, 0x080c, + 0x3321, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, + 0x30c9, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, + 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, + 0x2009, 0x007e, 0x080c, 0x66b9, 0x1168, 0xb813, 0x00ff, 0xb817, + 0xfffe, 0x080c, 0x3295, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, + 0x080c, 0xd52b, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, + 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, + 0xb325, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd554, 0x6023, 0x0001, + 0x9006, 0x080c, 0x6656, 0x2001, 0x0000, 0x080c, 0x666a, 0x0126, + 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, + 0x080c, 0xb352, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, + 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, + 0x9084, 0x00ff, 0xb842, 0x080c, 0xb325, 0x0548, 0x2b00, 0x6012, + 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x3250, 0x080c, + 0xd554, 0x6023, 0x0001, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, + 0x080c, 0x666a, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, + 0x012e, 0x2009, 0x0002, 0x080c, 0xb352, 0x9085, 0x0001, 0x00ce, + 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, + 0x0080, 0x080c, 0x66b9, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, + 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, + 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xb27d, 0x01d0, 0x2b00, + 0x6012, 0x080c, 0xd554, 0x6023, 0x0001, 0x9006, 0x080c, 0x6656, + 0x2001, 0x0002, 0x080c, 0x666a, 0x0126, 0x2091, 0x8000, 0x70e4, + 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, 0xb352, 0x9085, + 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x66b9, 0x11b8, + 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xb27d, + 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, + 0xd554, 0x2009, 0x0022, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, + 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, + 0x00b6, 0x21f0, 0x080c, 0x96af, 0x080c, 0x962f, 0x080c, 0xb111, + 0x080c, 0xc2d3, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, + 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, + 0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, + 0x6148, 0x001e, 0x8108, 0x1f04, 0x3235, 0x9686, 0x0001, 0x190c, + 0x3379, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, + 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, + 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, + 0x2039, 0x0000, 0x080c, 0x9577, 0x2c08, 0x080c, 0xe91c, 0x007e, + 0x001e, 0xba10, 0xbb14, 0xbcc0, 0x080c, 0x6148, 0xba12, 0xbb16, + 0xbcc2, 0x00be, 0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, + 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, + 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, + 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, + 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, + 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, + 0x080c, 0x57d5, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, + 0x2009, 0x002d, 0x080c, 0xec31, 0x20a9, 0x0800, 0x9016, 0x0026, + 0x928e, 0x007e, 0x0904, 0x3300, 0x928e, 0x007f, 0x0904, 0x3300, + 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, + 0x8fff, 0x1148, 0x2001, 0x198e, 0x0006, 0x2003, 0x0001, 0x04f1, + 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, + 0x080c, 0x6a6d, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x96a4, + 0x0076, 0x2039, 0x0000, 0x080c, 0x9577, 0x00b6, 0x00c6, 0x0026, + 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, + 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, + 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe91c, 0x001e, 0x007e, + 0x002e, 0x8210, 0x1f04, 0x32b7, 0x015e, 0x001e, 0x002e, 0x003e, + 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, + 0x0016, 0x080c, 0x57d5, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, + 0x2220, 0x2009, 0x0029, 0x080c, 0xec31, 0x001e, 0x002e, 0x004e, + 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, + 0x080c, 0x6a9b, 0x11d0, 0x2100, 0x080c, 0x28a6, 0x81ff, 0x01b8, + 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, + 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, + 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, + 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, + 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab7, 0x001e, + 0x6112, 0x080c, 0x3250, 0x001e, 0x080c, 0x66de, 0x012e, 0x00ce, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, 0xac6c, 0x080c, + 0xef94, 0x002e, 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, + 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7637, 0x1118, 0x20a9, 0x0800, + 0x0010, 0x20a9, 0x0782, 0x080c, 0x7637, 0x1110, 0x900e, 0x0010, + 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, + 0x0110, 0xb800, 0xd0bc, 0x090c, 0x66de, 0x8108, 0x1f04, 0x338a, + 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, + 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, + 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, + 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, + 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, + 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, + 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, + 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, + 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, + 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, + 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, + 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, + 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, + 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, + 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, + 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, + 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, + 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, + 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, + 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, + 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, + 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, + 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, + 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, + 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, + 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, + 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, + 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, + 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, + 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, + 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, + 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706a, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x706e, + 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, + 0x0002, 0x34e5, 0x34e6, 0x34f9, 0x350d, 0x0005, 0x1004, 0x34f6, + 0x0e04, 0x34f6, 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, + 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, + 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, + 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, 0x35e1, 0x0005, 0x7018, + 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, + 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, + 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, + 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, + 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35de, + 0x61d0, 0x0804, 0x3573, 0x35b5, 0x35ed, 0x35de, 0x35f9, 0x3603, + 0x3609, 0x360d, 0x361d, 0x3621, 0x3637, 0x363d, 0x3643, 0x364e, + 0x3659, 0x3668, 0x3677, 0x3685, 0x369c, 0x36b7, 0x35de, 0x3762, + 0x37a0, 0x3846, 0x3857, 0x387a, 0x35de, 0x35de, 0x35de, 0x38b2, + 0x38ce, 0x38d7, 0x3906, 0x390c, 0x35de, 0x3952, 0x35de, 0x35de, + 0x35de, 0x35de, 0x35de, 0x395d, 0x3966, 0x396e, 0x3970, 0x35de, + 0x35de, 0x35de, 0x35de, 0x35de, 0x35de, 0x399c, 0x35de, 0x35de, + 0x35de, 0x35de, 0x35de, 0x39b9, 0x3a40, 0x35de, 0x35de, 0x35de, + 0x35de, 0x35de, 0x35de, 0x0002, 0x3a6a, 0x3a6d, 0x3acc, 0x3ae5, + 0x3b15, 0x3db7, 0x35de, 0x5398, 0x35de, 0x35de, 0x35de, 0x35de, + 0x35de, 0x35de, 0x35de, 0x35de, 0x3637, 0x363d, 0x42ec, 0x57f9, + 0x430a, 0x5427, 0x5479, 0x5584, 0x35de, 0x55e6, 0x5622, 0x5653, + 0x575b, 0x5680, 0x56db, 0x35de, 0x430e, 0x44e1, 0x44f7, 0x451c, + 0x4581, 0x45f5, 0x4615, 0x468c, 0x46e8, 0x4744, 0x4747, 0x476c, + 0x4823, 0x4889, 0x4891, 0x49c6, 0x4b6e, 0x4ba2, 0x4e06, 0x35de, + 0x4e24, 0x4eeb, 0x4fd4, 0x502e, 0x35de, 0x50c1, 0x35de, 0x50d7, + 0x50f2, 0x4891, 0x5338, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, + 0x4c20, 0x0126, 0x2091, 0x8000, 0x0e04, 0x35bf, 0x0010, 0x012e, + 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, + 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, + 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, + 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, + 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, + 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, + 0x4c2d, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, + 0x7990, 0x0804, 0x4c30, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, + 0x35b5, 0x7984, 0x2114, 0x0804, 0x35b5, 0x20e1, 0x0000, 0x2099, + 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, + 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b5, 0x7884, 0x2060, 0x0804, + 0x366a, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0014, 0x789b, + 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, + 0x7896, 0x0804, 0x35b5, 0x7897, 0x0001, 0x0804, 0x35b5, 0x2039, + 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f1, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x35fd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, + 0x35ea, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f1, 0x79a0, 0x9182, + 0x0040, 0x0210, 0x0804, 0x35ea, 0x2138, 0x7d98, 0x7c9c, 0x0804, + 0x35fd, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35ea, 0x21e8, + 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x35b5, + 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, + 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b5, 0x0804, 0x35e4, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x35ea, 0x21e0, 0x20a9, 0x0001, + 0x7984, 0x2198, 0x4012, 0x0804, 0x35b5, 0x2069, 0x1847, 0x7884, + 0x7990, 0x911a, 0x1a04, 0x35ea, 0x8019, 0x0904, 0x35ea, 0x684a, + 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, + 0x080c, 0x7963, 0x0804, 0x35b5, 0x2069, 0x1847, 0x7884, 0x7994, + 0x911a, 0x1a04, 0x35ea, 0x8019, 0x0904, 0x35ea, 0x684e, 0x6946, + 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6bf8, 0x012e, 0x0804, 0x35b5, 0x902e, + 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e7, 0x7984, + 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, + 0x4101, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, + 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, + 0x701f, 0x36db, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, + 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, + 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x35e7, 0x810f, + 0x918c, 0x00ff, 0x0904, 0x35e7, 0x7112, 0x7010, 0x8001, 0x0560, + 0x7012, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, + 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, + 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x3719, + 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, + 0x000a, 0x1904, 0x35e7, 0x0888, 0x0126, 0x2091, 0x8000, 0x7014, + 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, + 0x0029, 0x1148, 0xc2fd, 0xaa7a, 0x080c, 0x629f, 0x0138, 0xa87a, + 0xa982, 0x012e, 0x0060, 0x080c, 0x65cf, 0x1130, 0x7007, 0x0003, + 0x701f, 0x3747, 0x012e, 0x0005, 0x080c, 0x710b, 0x012e, 0x0126, + 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a6, + 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, + 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, + 0x0804, 0x4c30, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, + 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, + 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, + 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, + 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1c, 0x2004, 0x9005, + 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, + 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, + 0x81ff, 0x1904, 0x35e7, 0x7984, 0x080c, 0x6724, 0x1904, 0x35ea, + 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35ea, 0x7c88, + 0x7d8c, 0x080c, 0x6887, 0x080c, 0x6856, 0x0000, 0x1518, 0x2061, + 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, + 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, + 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1a04, 0x35e7, 0x0c30, 0x080c, 0xccf3, 0x012e, 0x0904, 0x35e7, + 0x0804, 0x35b5, 0x900e, 0x2001, 0x0005, 0x080c, 0x710b, 0x0126, + 0x2091, 0x8000, 0x080c, 0xd3d4, 0x080c, 0x6e9f, 0x012e, 0x0804, + 0x35b5, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6724, 0x1904, 0x3833, + 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, + 0x080c, 0x6887, 0x080c, 0x6856, 0x1520, 0x2061, 0x1cd0, 0x0126, + 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, + 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, + 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, + 0x12b0, 0x0c28, 0x080c, 0xccf3, 0x012e, 0x2009, 0x0003, 0x0178, + 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x710b, 0x0126, 0x2091, + 0x8000, 0x080c, 0xd3d4, 0x080c, 0x6e92, 0x012e, 0x0070, 0xb097, + 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, + 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, + 0x35e7, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x67eb, 0x0904, + 0x35e7, 0x080c, 0x688d, 0x0904, 0x35e7, 0x0804, 0x460c, 0x81ff, + 0x1904, 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x691b, + 0x0904, 0x35e7, 0x2019, 0x0005, 0x79a8, 0x080c, 0x68a8, 0x0904, + 0x35e7, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ea, 0x8003, 0x800b, + 0x810b, 0x9108, 0x080c, 0x884b, 0x79a8, 0xd184, 0x1904, 0x35b5, + 0x0804, 0x460c, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, + 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, + 0x2508, 0x080c, 0x6724, 0x11d8, 0x080c, 0x691b, 0x1128, 0x2009, + 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, + 0x68a8, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, + 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x884b, 0x8529, + 0x1ae0, 0x012e, 0x0804, 0x35b5, 0x012e, 0x0804, 0x35e7, 0x012e, + 0x0804, 0x35ea, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x67eb, + 0x0904, 0x35e7, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, + 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, 0x900e, 0x080c, 0xe91c, + 0x007e, 0x00ce, 0x080c, 0x6887, 0x0804, 0x35b5, 0x080c, 0x4bfb, + 0x0904, 0x35ea, 0x080c, 0x6887, 0x2208, 0x0804, 0x35b5, 0x0156, + 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a, 0x1208, + 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069, 0x1000, + 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68, 0x1f04, + 0x38e8, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x35b5, + 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, + 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, + 0x6910, 0x62bc, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x35e7, 0x0126, 0x2091, 0x8000, 0x080c, 0x57e9, 0x0128, + 0x2009, 0x0007, 0x012e, 0x0804, 0x35e7, 0x012e, 0x615c, 0x9190, + 0x33b6, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, 0x6280, + 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, + 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, + 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, + 0x0068, 0x080c, 0x7637, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, + 0x0120, 0x2009, 0x0005, 0x0804, 0x35e7, 0x9036, 0x7e9a, 0x7f9e, + 0x0804, 0x35b5, 0x614c, 0x6250, 0x2019, 0x1986, 0x231c, 0x2001, + 0x1987, 0x2004, 0x789a, 0x0804, 0x35b5, 0x0126, 0x2091, 0x8000, + 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x35b5, 0x080c, 0x4c17, + 0x0904, 0x35ea, 0xba44, 0xbb38, 0x0804, 0x35b5, 0x080c, 0x0dc5, + 0x080c, 0x4c17, 0x2110, 0x0904, 0x35ea, 0xb804, 0x908c, 0x00ff, + 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, + 0x0009, 0x1904, 0x35e7, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, + 0x00c6, 0x9066, 0x080c, 0xac6c, 0x080c, 0x96a4, 0x0076, 0x903e, + 0x080c, 0x9577, 0x900e, 0x080c, 0xe91c, 0x007e, 0x00ce, 0xb807, + 0x0407, 0x012e, 0x0804, 0x35b5, 0x614c, 0x6250, 0x7884, 0x604e, + 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816, 0x788c, + 0x2069, 0x1986, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, + 0x2031, 0x07d0, 0x2069, 0x1987, 0x2d04, 0x266a, 0x789a, 0x0804, + 0x35b5, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, + 0xd1b4, 0x190c, 0x0ebe, 0xd094, 0x0148, 0x00e6, 0x2071, 0x19fb, + 0x79b4, 0x9192, 0x07d0, 0x1208, 0x713e, 0x00ee, 0xd0c4, 0x01a8, + 0x00d6, 0x78a8, 0x2009, 0x199d, 0x200a, 0x78ac, 0x2011, 0x199e, + 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, + 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7888, 0xd0ec, 0x0178, + 0x6034, 0xc08d, 0x6036, 0x2001, 0x0050, 0x6076, 0x607a, 0x6056, + 0x606b, 0x2450, 0x00c6, 0x2061, 0x1ad1, 0x2062, 0x00ce, 0x2011, + 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010, + 0x918c, 0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, + 0x788c, 0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, + 0x190c, 0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, + 0x0001, 0x090c, 0x42ec, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, + 0x0114, 0x2012, 0x012e, 0x0804, 0x35b5, 0x00f6, 0x2079, 0x1800, + 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, + 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, + 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, + 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x35ea, 0x788c, + 0x902d, 0x0904, 0x35ea, 0x900e, 0x080c, 0x6724, 0x1120, 0xba44, + 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, + 0x080c, 0x4c17, 0x0904, 0x35ea, 0x7888, 0x900d, 0x0904, 0x35ea, + 0x788c, 0x9005, 0x0904, 0x35ea, 0xba44, 0xb946, 0xbb38, 0xb83a, + 0x0804, 0x35b5, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, + 0x57e9, 0x1904, 0x35e7, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, + 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, + 0x9182, 0x007f, 0x16e0, 0x9188, 0x33b6, 0x210d, 0x918c, 0x00ff, + 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, + 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb27d, 0x000e, + 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x66bf, 0x2b08, + 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4be4, 0x01d0, + 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, + 0x701f, 0x3ac5, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xb352, + 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35e7, 0x00ce, + 0x0804, 0x35ea, 0x080c, 0xb2d3, 0x0cb0, 0xa830, 0x9086, 0x0100, + 0x0904, 0x35e7, 0x0804, 0x35b5, 0x2061, 0x1a74, 0x0126, 0x2091, + 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, + 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, + 0x0804, 0x35b5, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35e7, + 0x080c, 0x7637, 0x0904, 0x35e7, 0x0126, 0x2091, 0x8000, 0x6254, + 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x28dc, 0x080c, + 0x5a11, 0x012e, 0x0804, 0x35b5, 0x012e, 0x0804, 0x35ea, 0x0006, + 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, 0x1847, + 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x9375, 0x7206, + 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x35b7, 0x7884, + 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, + 0x00e1, 0x0298, 0x012e, 0x0804, 0x35ea, 0x2001, 0x002a, 0x2004, + 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, + 0x0804, 0x35ea, 0x012e, 0x0804, 0x35e7, 0x080c, 0xb23d, 0x0dd0, + 0x7884, 0xd0fc, 0x0904, 0x3b94, 0x00c6, 0x080c, 0x4be4, 0x00ce, + 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, + 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, + 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, + 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, + 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, + 0x8004, 0xa816, 0x080c, 0x3d1a, 0x0928, 0x7014, 0x2048, 0xad2c, + 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, + 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c2d, 0x701f, 0x3c57, + 0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aff, 0x2001, + 0x19a0, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, + 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, + 0x3d89, 0x080c, 0x3d48, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, + 0x1a69, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, + 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, + 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4130, 0x008e, 0x00ee, + 0x00fe, 0x080c, 0x4052, 0x080c, 0x3f57, 0x05b8, 0x2001, 0x020b, + 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x41a4, 0x00f6, 0x2079, + 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, + 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, + 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, + 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, + 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, + 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3f61, 0x080c, + 0x3d43, 0x0058, 0x080c, 0x3d43, 0x080c, 0x40c8, 0x080c, 0x4048, + 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, + 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, + 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, + 0x12fc, 0x2009, 0x0028, 0x080c, 0x2409, 0x2001, 0x0227, 0x200c, + 0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, + 0x008e, 0x004e, 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, + 0x0804, 0x35b5, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b7, 0x0016, + 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, + 0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, + 0x9005, 0x0904, 0x3cb3, 0x2048, 0x1f04, 0x3c67, 0x7068, 0x2040, + 0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, + 0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, + 0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c2d, 0x701f, + 0x3c57, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, + 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c, 0x4c30, 0x701f, 0x3c57, + 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, + 0x1118, 0x701f, 0x3d18, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, + 0xa86a, 0x2009, 0x007f, 0x080c, 0x66b9, 0x0110, 0x9006, 0x0030, + 0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd5a7, 0x015e, 0x00de, + 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, + 0x0904, 0x35e7, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, + 0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3cea, 0x7007, 0x0003, + 0x0804, 0x3ca8, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, + 0x35b7, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, + 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, + 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, + 0x080c, 0x4c30, 0x007e, 0x701f, 0x3c57, 0x7023, 0x0001, 0x0005, + 0x0804, 0x35b5, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, + 0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, + 0x080c, 0x4be4, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, + 0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, + 0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, + 0x00fe, 0x000e, 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, + 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, + 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, + 0xc1ac, 0x6106, 0x080c, 0x4be4, 0xa813, 0x0019, 0xa817, 0x0001, + 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, + 0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, + 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2409, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, + 0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x00e6, 0x080c, 0x4be4, 0x2940, 0xa013, 0x0019, 0xa017, + 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, + 0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, + 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, + 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c59, 0x1130, 0x9006, + 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, 0x2001, 0x199f, 0x2003, + 0x0000, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dd8, 0x3de1, 0x3dea, + 0x3dd5, 0x3dd5, 0x3dd5, 0x3dd5, 0x3dd5, 0x012e, 0x0804, 0x35ea, + 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3fab, + 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, + 0x3fab, 0x0078, 0x080c, 0x7637, 0x1128, 0x012e, 0x2009, 0x0016, + 0x0804, 0x35e7, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, + 0x35b7, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0db0, 0x0086, 0x0096, + 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aff, + 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, + 0x2060, 0x2058, 0x080c, 0x427f, 0x080c, 0x41cf, 0x903e, 0x2720, + 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a69, 0x2079, 0x0090, + 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, + 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x4130, 0x080c, + 0x2c61, 0x080c, 0x2c61, 0x080c, 0x2c61, 0x080c, 0x2c61, 0x080c, + 0x4130, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x4052, 0x2009, 0x9c40, + 0x8109, 0x11b0, 0x080c, 0x3f61, 0x2001, 0x0004, 0x200c, 0x918c, + 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, + 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35e7, 0x0cf8, + 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, + 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, + 0x81ff, 0x0150, 0x080c, 0x4030, 0x2d00, 0x9c05, 0x9b05, 0x0120, + 0x080c, 0x3f61, 0x0804, 0x3f0e, 0x080c, 0x41a4, 0x080c, 0x40c8, + 0x080c, 0x4013, 0x080c, 0x4048, 0x00f6, 0x2079, 0x0100, 0x7824, + 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3f61, 0x00fe, 0x0804, 0x3f0e, + 0x00fe, 0x080c, 0x3f57, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, + 0x2001, 0x0033, 0x2502, 0x080c, 0x3f61, 0x0080, 0x87ff, 0x0138, + 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, + 0x1a65, 0x2004, 0x9086, 0x0000, 0x1904, 0x3e5e, 0x2001, 0x032f, + 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, + 0x3f0e, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, + 0x3f0e, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, + 0xd0ac, 0x1148, 0x2001, 0x1a65, 0x2003, 0x0003, 0x2001, 0x032a, + 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, + 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2409, 0x2900, + 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, + 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, + 0x0203, 0x2004, 0x1f04, 0x3ee5, 0x00ce, 0x0030, 0xa817, 0x0001, + 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, + 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, + 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3e18, 0x001e, 0x00c6, + 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, + 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, + 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, 0x9084, 0x0003, + 0x9086, 0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x2409, 0x2001, + 0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, 0x6052, 0x602f, + 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, + 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, + 0x0804, 0x35b5, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b7, 0x9085, + 0x0001, 0x1d04, 0x3f60, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, + 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, + 0x0004, 0x2001, 0x1a65, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, + 0x080c, 0x2409, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, + 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a69, + 0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, + 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, + 0x080c, 0x2409, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x41a4, 0x7000, + 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, + 0x2009, 0x0040, 0x080c, 0x2409, 0x782b, 0x0002, 0x7003, 0x0000, + 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, + 0x200c, 0x7932, 0x7936, 0x080c, 0x28bc, 0x7850, 0x9084, 0xfbff, + 0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, + 0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3fc6, + 0x2091, 0x6000, 0x1f04, 0x3fc6, 0x7850, 0x9085, 0x0400, 0x9084, + 0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, + 0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, + 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, + 0x3fe6, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, + 0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, + 0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, + 0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d39, + 0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d39, 0x7827, + 0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, + 0x2071, 0x1a65, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, + 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, + 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, + 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, + 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, + 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, + 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ab, 0x2004, + 0x70e2, 0x080c, 0x3d39, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, + 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, + 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, + 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, + 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, + 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, + 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, + 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, + 0x41a4, 0x00f6, 0x2071, 0x1a65, 0x2079, 0x0320, 0x00d6, 0x2069, + 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, + 0x00de, 0x080c, 0x3d39, 0x0140, 0x2001, 0x199f, 0x200c, 0x2003, + 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, 0x03e8, 0x8109, 0x1df0, + 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c, + 0x4130, 0x2011, 0x0001, 0x080c, 0x4130, 0x00fe, 0x00ee, 0x0005, + 0x00f6, 0x00e6, 0x2071, 0x1a65, 0x2079, 0x0320, 0x792c, 0xd1fc, + 0x0904, 0x412d, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x4129, + 0x7000, 0x0002, 0x412d, 0x40de, 0x410e, 0x4129, 0xd1bc, 0x1170, + 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x4130, + 0x0904, 0x412d, 0x080c, 0x4130, 0x0804, 0x412d, 0x00f6, 0x2079, + 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, + 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, + 0x4030, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, + 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, + 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x40d2, 0x2011, + 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015, + 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, + 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, + 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058, + 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a, + 0x0007, 0x1a0c, 0x0dc5, 0x9398, 0x415e, 0x231d, 0x083f, 0x9080, + 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a, + 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, + 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x419b, 0x4192, + 0x4189, 0x4180, 0x4177, 0x416e, 0x4165, 0xa964, 0x7902, 0xa968, + 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902, + 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984, + 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, + 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, + 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, + 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, + 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, + 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, + 0x1a69, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, + 0x2940, 0x9026, 0x7000, 0x0002, 0x41cb, 0x41b7, 0x41c2, 0x8001, + 0x7002, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x4130, 0x190c, + 0x4130, 0x0048, 0x8001, 0x7002, 0x782c, 0xd0fc, 0x1d38, 0x2011, + 0x0001, 0x080c, 0x4130, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, + 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, + 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038, + 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4be4, + 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, + 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, + 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4247, 0x1d68, + 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4be4, 0xa813, 0x0019, 0xa817, + 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, + 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079, + 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c, + 0x2409, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, + 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, + 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, + 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, + 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e, + 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c, + 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400, + 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c, + 0x4be4, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, + 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, + 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030, + 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4be4, 0x2940, 0xa813, + 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, + 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, + 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x4247, 0x1d68, 0x2900, + 0xa85a, 0x00d8, 0x080c, 0x4be4, 0x2940, 0xa013, 0x0019, 0xa017, + 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001, + 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003, + 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d, + 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a65, 0x2003, 0x0003, + 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000, + 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, + 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, + 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9, + 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009, + 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005, + 0x0804, 0x35b5, 0x7d98, 0x7c9c, 0x0804, 0x36b9, 0x080c, 0x7637, + 0x190c, 0x60f3, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847, + 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, + 0x0001, 0x080c, 0x4c2d, 0x701f, 0x4326, 0x0005, 0x080c, 0x57e4, + 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069, + 0x1847, 0x6800, 0x9005, 0x0904, 0x35ea, 0x2001, 0x180d, 0x2004, + 0xd08c, 0x6804, 0x0118, 0xc0a4, 0xc0ac, 0x6806, 0xd0ac, 0x0118, + 0xd0a4, 0x0904, 0x35ea, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, + 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010, + 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, + 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106, + 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x35ea, + 0x9288, 0x33b6, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130, + 0x6828, 0x908a, 0x007f, 0x1a04, 0x35ea, 0x605e, 0x6888, 0x9084, + 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b2, + 0x9080, 0x29b7, 0x2005, 0x200a, 0x000e, 0x2009, 0x19b3, 0x9080, + 0x29bb, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04, 0x35ea, + 0x908a, 0x0841, 0x1a04, 0x35ea, 0x9084, 0x0007, 0x1904, 0x35ea, + 0x680c, 0x9005, 0x0904, 0x35ea, 0x6810, 0x9005, 0x0904, 0x35ea, + 0x6848, 0x6940, 0x910a, 0x1a04, 0x35ea, 0x8001, 0x0904, 0x35ea, + 0x684c, 0x6944, 0x910a, 0x1a04, 0x35ea, 0x8001, 0x0904, 0x35ea, + 0x2009, 0x1981, 0x200b, 0x0000, 0x2001, 0x1869, 0x2004, 0xd0c4, + 0x0140, 0x7884, 0x200a, 0x2008, 0x080c, 0x0e52, 0x3b00, 0xc085, + 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff, + 0x6052, 0x080c, 0x7963, 0x080c, 0x6b8e, 0x080c, 0x6bf8, 0x6808, + 0x602a, 0x080c, 0x237b, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001, + 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2916, 0x003e, + 0x6000, 0x9086, 0x0000, 0x1904, 0x44cf, 0x6818, 0x691c, 0x6a20, + 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, + 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, + 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006, + 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, + 0x0004, 0x20a1, 0x19b4, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004, + 0x20a1, 0x19ce, 0x20e9, 0x0001, 0x4001, 0x080c, 0x8962, 0x00c6, + 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0510, 0x0068, 0x2009, + 0x0100, 0x210c, 0x918e, 0x0008, 0x1110, 0x839d, 0x0010, 0x83f5, + 0x3e18, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7f6f, 0x6878, 0x6016, + 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, + 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, + 0x1f04, 0x441f, 0x00ce, 0x00c6, 0x2061, 0x199c, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x11a8, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, + 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bb1, + 0x2001, 0x0001, 0x080c, 0x2b94, 0x0088, 0x9286, 0x4000, 0x1148, + 0x2063, 0x0001, 0x9006, 0x080c, 0x2bb1, 0x9006, 0x080c, 0x2b94, + 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, + 0x2c70, 0x080c, 0x0ea3, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, + 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, + 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, + 0x2001, 0x197c, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, + 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, + 0x080c, 0x298b, 0x2001, 0x196d, 0x2102, 0x0008, 0x2102, 0x00c6, + 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, + 0x7637, 0x0128, 0x080c, 0x50cb, 0x0110, 0x080c, 0x28dc, 0x60d4, + 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x44b7, 0x00e0, 0x080c, + 0x7637, 0x1168, 0x2011, 0x74b2, 0x080c, 0x883d, 0x2011, 0x74a5, + 0x080c, 0x8917, 0x080c, 0x7937, 0x080c, 0x7563, 0x0040, 0x080c, + 0x5fed, 0x0028, 0x6003, 0x0004, 0x2009, 0x44cf, 0x0020, 0x080c, + 0x6a05, 0x0804, 0x35b5, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, + 0x9086, 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, + 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x35e7, 0x2069, 0x1847, + 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4c30, 0x9006, + 0x080c, 0x28dc, 0x81ff, 0x1904, 0x35e7, 0x080c, 0x7637, 0x11b0, + 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x33aa, 0x0118, 0x6130, + 0xc18d, 0x6132, 0x080c, 0xd7e3, 0x0130, 0x080c, 0x765a, 0x1118, + 0x080c, 0x760f, 0x0038, 0x080c, 0x7563, 0x0020, 0x080c, 0x60f3, + 0x080c, 0x5fed, 0x0804, 0x35b5, 0x81ff, 0x1904, 0x35e7, 0x080c, + 0x7637, 0x1110, 0x0804, 0x35e7, 0x0126, 0x2091, 0x8000, 0x6194, + 0x81ff, 0x0190, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c30, + 0x701f, 0x35b3, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, + 0x1c80, 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, + 0xffff, 0x4304, 0x655c, 0x9588, 0x33b6, 0x210d, 0x918c, 0x00ff, + 0x216a, 0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, + 0x6724, 0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, + 0xff00, 0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, + 0xff00, 0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, + 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, + 0x0040, 0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x607e, 0x0804, + 0x452c, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x4be4, 0x1120, + 0x2009, 0x0002, 0x0804, 0x35e7, 0x080c, 0x57d5, 0xd0b4, 0x0558, + 0x7884, 0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, + 0x0080, 0x0508, 0x080c, 0x33a5, 0x1148, 0xb800, 0xd08c, 0x11d8, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2a3, 0x1120, 0x2009, 0x0003, + 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x45b7, 0x0005, 0x080c, + 0x4c17, 0x0904, 0x35ea, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, + 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, + 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, + 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x080c, 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c30, 0x81ff, 0x1904, 0x35e7, + 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6896, 0x0904, 0x35e7, + 0x0058, 0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x35e7, + 0xa974, 0xaa94, 0x0804, 0x35b5, 0x080c, 0x57dd, 0x0904, 0x35b5, + 0x701f, 0x4601, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x35e7, + 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ea, 0x080c, 0x4c17, 0x0904, + 0x35ea, 0x080c, 0x6aa3, 0x0120, 0x080c, 0x6aab, 0x1904, 0x35ea, + 0x080c, 0x691b, 0x0904, 0x35e7, 0x2019, 0x0004, 0x900e, 0x080c, + 0x68a8, 0x0904, 0x35e7, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, + 0x908a, 0x1000, 0x12f8, 0x080c, 0x4c15, 0x01e0, 0x080c, 0x6aa3, + 0x0118, 0x080c, 0x6aab, 0x11b0, 0x080c, 0x691b, 0x2009, 0x0002, + 0x0168, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x68a8, 0x2009, + 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x0005, 0xa897, 0x4000, 0x080c, 0x57dd, 0x0110, 0x9006, + 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, + 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, + 0x645c, 0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, + 0x0005, 0x080c, 0x6724, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, + 0x9108, 0x080c, 0x884b, 0x0005, 0x81ff, 0x1904, 0x35e7, 0x798c, + 0x2001, 0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4bfb, 0x0904, + 0x35ea, 0x080c, 0x6aa3, 0x0120, 0x080c, 0x6aab, 0x1904, 0x35ea, + 0x080c, 0x67eb, 0x0904, 0x35e7, 0x080c, 0x689f, 0x0904, 0x35e7, + 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904, 0x35b5, 0x0804, 0x460c, + 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, + 0x4c08, 0x01a0, 0x080c, 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1170, + 0x080c, 0x67eb, 0x2009, 0x0002, 0x0128, 0x080c, 0x689f, 0x1170, + 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, + 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57dd, 0x0110, + 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, + 0x81ff, 0x1904, 0x35e7, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, + 0x2102, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x0120, + 0x080c, 0x6aab, 0x1904, 0x35ea, 0x080c, 0x67eb, 0x0904, 0x35e7, + 0x080c, 0x688d, 0x0904, 0x35e7, 0x2001, 0x197f, 0x2004, 0xd0fc, + 0x1904, 0x35b5, 0x0804, 0x460c, 0xa9a0, 0x2001, 0x197f, 0x918c, + 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c08, 0x01a0, 0x080c, 0x6aa3, + 0x0118, 0x080c, 0x6aab, 0x1170, 0x080c, 0x67eb, 0x2009, 0x0002, + 0x0128, 0x080c, 0x688d, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, + 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, + 0x1128, 0x080c, 0x57dd, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x35b5, 0x080c, + 0x4c17, 0x0904, 0x35ea, 0x080c, 0x57e9, 0x1904, 0x35e7, 0x79a8, + 0xd184, 0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, + 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, + 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, + 0x918c, 0x0202, 0x0804, 0x35b5, 0x78a8, 0x909c, 0x0003, 0xd0ac, + 0x1158, 0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x35e7, 0x625c, + 0x7884, 0x9206, 0x1904, 0x47c7, 0x080c, 0x894c, 0x2001, 0xffec, + 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, + 0x0006, 0x78a8, 0x9084, 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, + 0x1a83, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a84, 0x201c, + 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7bae, 0x2003, + 0x0000, 0x2001, 0x1a7f, 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, + 0x1a86, 0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, + 0x0804, 0x4c30, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, + 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, + 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x47e7, 0x0005, 0x81ff, + 0x1904, 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x6aa3, + 0x1904, 0x35e7, 0x00c6, 0x080c, 0x4be4, 0x00ce, 0x0904, 0x35e7, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xd249, + 0x0904, 0x35e7, 0x7007, 0x0003, 0x701f, 0x480d, 0x0005, 0x080c, + 0x42ec, 0x0006, 0x0036, 0x2001, 0x1a83, 0x201c, 0x7b9a, 0x2003, + 0x0000, 0x2001, 0x1a84, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, + 0x1a85, 0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a7f, 0x201c, + 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bb2, 0x2003, + 0x0000, 0x003e, 0x000e, 0x0804, 0x35b5, 0xa830, 0x9086, 0x0100, + 0x0904, 0x35e7, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c30, 0x9006, 0x080c, 0x28dc, 0x78a8, 0x9084, + 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x35e7, 0x080c, + 0x7637, 0x0110, 0x080c, 0x60f3, 0x7888, 0x908a, 0x1000, 0x1a04, + 0x35ea, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, + 0x35ea, 0x2100, 0x080c, 0x28a6, 0x0026, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x2061, 0x19fb, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, + 0x0000, 0x607f, 0x0000, 0x080c, 0x7637, 0x1158, 0x080c, 0x7932, + 0x080c, 0x612e, 0x9085, 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, + 0x00d0, 0x080c, 0xb244, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, + 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, + 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, + 0x6019, 0x080c, 0x88d5, 0x7984, 0x080c, 0x7637, 0x1110, 0x2009, + 0x00ff, 0x7a88, 0x080c, 0x466f, 0x012e, 0x00ce, 0x002e, 0x0804, + 0x35b5, 0x7984, 0x080c, 0x66b9, 0x2b08, 0x1904, 0x35ea, 0x0804, + 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e7, 0x60dc, + 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e7, + 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x7984, + 0x81ff, 0x0904, 0x35ea, 0x9192, 0x0021, 0x1a04, 0x35ea, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, + 0x7736, 0x080c, 0x4c2d, 0x701f, 0x48c4, 0x7880, 0x9086, 0x006e, + 0x0110, 0x701f, 0x527d, 0x0005, 0x2009, 0x0080, 0x080c, 0x6724, + 0x1118, 0x080c, 0x6aa3, 0x0120, 0x2021, 0x400a, 0x0804, 0x35b7, + 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, + 0xa884, 0x90be, 0x0100, 0x0904, 0x495d, 0x90be, 0x0112, 0x0904, + 0x495d, 0x90be, 0x0113, 0x0904, 0x495d, 0x90be, 0x0114, 0x0904, + 0x495d, 0x90be, 0x0117, 0x0904, 0x495d, 0x90be, 0x011a, 0x0904, + 0x495d, 0x90be, 0x011c, 0x0904, 0x495d, 0x90be, 0x0121, 0x0904, + 0x4944, 0x90be, 0x0131, 0x0904, 0x4944, 0x90be, 0x0171, 0x0904, + 0x495d, 0x90be, 0x0173, 0x0904, 0x495d, 0x90be, 0x01a1, 0x1128, + 0xa894, 0x8007, 0xa896, 0x0804, 0x4968, 0x90be, 0x0212, 0x0904, + 0x4951, 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, + 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, + 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, + 0x00de, 0x0804, 0x35ea, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, + 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x49a6, 0x7028, + 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, + 0x0001, 0x080c, 0x49a6, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49b3, + 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49b3, 0x7028, 0x9080, 0x000c, + 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, + 0x00c6, 0x080c, 0x4be4, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, + 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, + 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, + 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, + 0xa804, 0x2048, 0x080c, 0xd264, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35e7, 0x7007, 0x0003, 0x701f, 0x499d, 0x0005, 0x00ce, 0x009e, + 0x00de, 0x2009, 0x0002, 0x0804, 0x35e7, 0xa820, 0x9086, 0x8001, + 0x1904, 0x35b5, 0x2009, 0x0004, 0x0804, 0x35e7, 0x0016, 0x0026, + 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, + 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, + 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, + 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x35e7, 0x60dc, 0xd0ac, 0x1188, 0x2009, + 0x180d, 0x210c, 0xd18c, 0x0130, 0xd09c, 0x0120, 0x2009, 0x0016, + 0x0804, 0x35e7, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e7, + 0x7984, 0x78a8, 0x2040, 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, + 0x0a04, 0x35ea, 0x9186, 0x00ff, 0x0904, 0x35ea, 0x9182, 0x0800, + 0x1a04, 0x35ea, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, + 0x924e, 0x0904, 0x35ea, 0x080c, 0xb23d, 0x1120, 0x99cc, 0xff00, + 0x0904, 0x35ea, 0x0126, 0x2091, 0x8000, 0x2001, 0x180d, 0x2004, + 0xd08c, 0x0198, 0x9386, 0x00ff, 0x0180, 0x0026, 0x2011, 0x8008, + 0x080c, 0x6ac7, 0x002e, 0x0148, 0x918d, 0x8000, 0x080c, 0x6b11, + 0x1120, 0x2001, 0x4009, 0x0804, 0x4a64, 0x080c, 0x4af7, 0x0904, + 0x4a6a, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, + 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, + 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, + 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6aa3, 0x0110, 0xc89d, + 0x0438, 0x900e, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, + 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, + 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, + 0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x35b7, + 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, + 0x2c70, 0x080c, 0xb325, 0x0904, 0x4abf, 0x2b00, 0x6012, 0x080c, + 0xd554, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4be4, 0x00ce, + 0x2b70, 0x1158, 0x080c, 0xb2d3, 0x00ee, 0x00ce, 0x00be, 0x001e, + 0x012e, 0x2009, 0x0002, 0x0804, 0x35e7, 0x900e, 0xa966, 0xa96a, + 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, + 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3250, 0x6023, 0x0001, 0x9006, + 0x080c, 0x6656, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x666a, + 0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x666a, 0x2009, + 0x0002, 0x080c, 0xb352, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, + 0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, 0x0001, 0x00ee, + 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, + 0x35e7, 0x7007, 0x0003, 0x701f, 0x4ace, 0x0005, 0xa830, 0x2009, + 0x180d, 0x210c, 0xd18c, 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, + 0x2021, 0x4009, 0x0804, 0x35b7, 0x9086, 0x0100, 0x7024, 0x2058, + 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x5729, + 0x900e, 0xa868, 0xd0f4, 0x1904, 0x35b5, 0x080c, 0x6944, 0x1108, + 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b5, 0x00e6, + 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4b46, 0x902e, 0x080c, 0xb23d, + 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, + 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, + 0x2100, 0x9406, 0x1904, 0x4b57, 0x2428, 0x94ce, 0x007f, 0x1120, + 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, + 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, + 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, + 0x2400, 0x9106, 0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, + 0x6a43, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c, 0x6aa3, 0x1540, + 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, + 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, + 0x0918, 0x080c, 0xb23d, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, + 0x8e70, 0x1f04, 0x4b0d, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, + 0x2001, 0x0001, 0x0030, 0x080c, 0x66b9, 0x1dd0, 0xbb12, 0xba16, + 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, + 0x0002, 0x0804, 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x7884, 0x9005, 0x0904, 0x35ea, 0x9096, 0x00ff, 0x0120, 0x9092, + 0x0004, 0x1a04, 0x35ea, 0x2010, 0x2918, 0x080c, 0x31f6, 0x1120, + 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x4b99, + 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x35b5, 0x2009, 0x0004, + 0x0804, 0x35e7, 0x7984, 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, + 0x0a04, 0x35ea, 0x9186, 0x00ff, 0x0904, 0x35ea, 0x9182, 0x0800, + 0x1a04, 0x35ea, 0x2001, 0x9400, 0x080c, 0x5784, 0x1904, 0x35e7, + 0x0804, 0x35b5, 0xa998, 0x080c, 0xb23d, 0x1118, 0x9182, 0x007f, + 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, + 0x9400, 0x080c, 0x5784, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, + 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, + 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, + 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, + 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6724, 0x1130, 0x7e88, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, + 0xa998, 0x080c, 0x6724, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, + 0x2608, 0x080c, 0x6724, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, + 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, + 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, + 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, + 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, + 0x0002, 0x701f, 0x35b5, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, + 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, + 0x4c61, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, + 0x4cc7, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, + 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, + 0x2060, 0x080c, 0x100e, 0x0904, 0x4cbf, 0xa84b, 0x0000, 0x2900, + 0x7046, 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa846, 0x0098, + 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, + 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, + 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, + 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, + 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, + 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, + 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, + 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa846, 0x0058, 0x2262, + 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, + 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4ce9, 0x4ce9, + 0x4ceb, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cef, 0x4ce9, 0x4ce9, 0x4ce9, + 0x4cf3, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cf7, 0x4ce9, 0x4ce9, 0x4ce9, + 0x4cfb, 0x4ce9, 0x4ce9, 0x4ce9, 0x4cff, 0x4ce9, 0x4ce9, 0x4ce9, + 0x4d04, 0x080c, 0x0dc5, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, + 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, + 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, + 0xa3ca, 0xa4ce, 0x0804, 0x4cc2, 0xa2d6, 0xa3da, 0xa4de, 0x0804, + 0x4cc2, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4d9b, + 0x0126, 0x2091, 0x8000, 0x0e04, 0x4d9a, 0x00f6, 0x2079, 0x0000, + 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, + 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, + 0x0dc5, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, + 0x4d9d, 0xa804, 0x9005, 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, + 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x20c7, 0x2005, 0xa04a, + 0x0804, 0x4d9d, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, + 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, + 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x87ff, 0x0118, 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, + 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, + 0x1040, 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, + 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, + 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, + 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, + 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, + 0x9080, 0x20c7, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, + 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, + 0x0002, 0x4dbc, 0x4dbc, 0x4dbe, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dc3, + 0x4dbc, 0x4dbc, 0x4dbc, 0x4dc8, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dcd, + 0x4dbc, 0x4dbc, 0x4dbc, 0x4dd2, 0x4dbc, 0x4dbc, 0x4dbc, 0x4dd7, + 0x4dbc, 0x4dbc, 0x4dbc, 0x4ddc, 0x080c, 0x0dc5, 0xaa74, 0xab78, + 0xac7c, 0x0804, 0x4d48, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4d48, + 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4d48, 0xaaa4, 0xaba8, 0xacac, + 0x0804, 0x4d48, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4d48, 0xaac4, + 0xabc8, 0xaccc, 0x0804, 0x4d48, 0xaad4, 0xabd8, 0xacdc, 0x0804, + 0x4d48, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, + 0x080c, 0x6724, 0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, + 0x0000, 0x2011, 0x801b, 0x080c, 0x4c44, 0x00ce, 0x00be, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x57d5, 0xd0c4, 0x0120, + 0x2011, 0x8014, 0x080c, 0x4c44, 0x002e, 0x0005, 0x81ff, 0x1904, + 0x35e7, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, + 0x6032, 0x080c, 0x7637, 0x1158, 0x080c, 0x7932, 0x080c, 0x612e, + 0x9085, 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, 0x0010, 0x080c, + 0x5fed, 0x012e, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, + 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, 0x35e7, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x0178, 0x0026, 0x2011, 0x0010, + 0x080c, 0x6ac7, 0x002e, 0x0140, 0x7984, 0x080c, 0x6b11, 0x1120, + 0x2009, 0x4009, 0x0804, 0x35e7, 0x7984, 0x080c, 0x66b9, 0x1904, + 0x35ea, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x2b00, 0x7026, 0x080c, + 0x6aa3, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, + 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, + 0x35b5, 0x080c, 0x4be4, 0x0904, 0x35e7, 0x9006, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd302, 0x0904, 0x35e7, 0x7888, + 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003, 0x701f, + 0x4ecb, 0x0005, 0x2061, 0x1800, 0x080c, 0x57e9, 0x2009, 0x0007, + 0x1560, 0x080c, 0x6a9b, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, + 0x080c, 0x66b9, 0x1530, 0x080c, 0x4c15, 0x0518, 0x080c, 0x6aa3, + 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6944, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, + 0xc0fc, 0xa86a, 0x080c, 0xd302, 0x11e0, 0xa89c, 0xd094, 0x0118, + 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, + 0x0005, 0x9006, 0x0005, 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, + 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, + 0x35b7, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5729, + 0x900e, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, + 0xc18d, 0x0804, 0x35b5, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, + 0x0804, 0x35e7, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, + 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x900e, 0x2130, + 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, + 0x702a, 0x20a0, 0x080c, 0x6724, 0x1904, 0x4f81, 0x080c, 0x6aa3, + 0x0138, 0x080c, 0x6aab, 0x0120, 0x080c, 0x6a43, 0x1904, 0x4f81, + 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, + 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x49b3, + 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, + 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, + 0x49b3, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, + 0x6aa3, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6944, + 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, + 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, + 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, + 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, + 0x20e0, 0x080c, 0x49a6, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, + 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, + 0x0005, 0x8108, 0x080c, 0xb23d, 0x0118, 0x9186, 0x0800, 0x0040, + 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, + 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, + 0x0150, 0x0804, 0x4f0a, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, + 0x35b5, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, + 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, + 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, + 0x7007, 0x0002, 0x701f, 0x4fbd, 0x0005, 0x7030, 0x9005, 0x1180, + 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, + 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4f0a, + 0x7124, 0x810b, 0x0804, 0x35b5, 0x2029, 0x007e, 0x7984, 0x7a88, + 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, + 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9184, 0x00ff, 0x90e2, 0x0020, + 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9284, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9284, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, + 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35ea, 0x9502, + 0x0a04, 0x35ea, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ea, + 0x9502, 0x0a04, 0x35ea, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, + 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x9484, 0x00ff, 0x90e2, + 0x0020, 0x0a04, 0x35ea, 0x9502, 0x0a04, 0x35ea, 0x2061, 0x1989, + 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x35b5, 0x080c, 0x4be4, + 0x0904, 0x35e7, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x5041, + 0x0005, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, + 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, + 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x50a8, + 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x50a8, 0x680c, 0x9005, + 0x0904, 0x50a8, 0x9082, 0xff01, 0x1a04, 0x50a8, 0x6810, 0x9082, + 0x005c, 0x06f0, 0x6824, 0x2008, 0x9082, 0x0008, 0x06c8, 0x9182, + 0x0400, 0x16b0, 0x0056, 0x2029, 0x0000, 0x080c, 0x8e80, 0x005e, + 0x6944, 0x6820, 0x9102, 0x0660, 0x6820, 0x9082, 0x0019, 0x1640, + 0x6828, 0x6944, 0x810c, 0x9102, 0x0618, 0x6840, 0x9082, 0x000f, + 0x12f8, 0x080c, 0x1027, 0x2900, 0x0590, 0x684e, 0x00e6, 0x2071, + 0x1931, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8d3c, 0x00be, 0x00ee, + 0x01e8, 0x080c, 0x8a84, 0x080c, 0x8ad3, 0x1160, 0x6857, 0x0000, + 0x00c6, 0x6b10, 0x2061, 0x1a65, 0x630a, 0x00ce, 0x0804, 0x35b5, + 0x0804, 0x35ea, 0x080c, 0x8acc, 0x00e6, 0x2071, 0x1931, 0x080c, + 0x8f00, 0x080c, 0x8f0f, 0x080c, 0x8d21, 0x00ee, 0x2001, 0x188a, + 0x204c, 0x080c, 0x1040, 0x2001, 0x188a, 0x2003, 0x0000, 0x0804, + 0x35e7, 0x0126, 0x2091, 0x8000, 0x080c, 0x92bf, 0x080c, 0x8acc, + 0x012e, 0x0804, 0x35b5, 0x0006, 0x080c, 0x57d5, 0xd0cc, 0x000e, + 0x0005, 0x0006, 0x080c, 0x57d9, 0xd0bc, 0x000e, 0x0005, 0x6174, + 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x35b5, 0x83ff, + 0x1904, 0x35ea, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35ea, 0x2019, + 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35ea, 0x7986, 0x6276, + 0x0804, 0x35b5, 0x080c, 0x57e9, 0x1904, 0x35e7, 0x7c88, 0x7d84, + 0x7e98, 0x7f8c, 0x080c, 0x4be4, 0x0904, 0x35e7, 0x900e, 0x901e, + 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, + 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, + 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1148, 0x20a9, 0x0001, 0xb814, + 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, + 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, + 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x9375, 0x2208, 0x0804, + 0x35b5, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, + 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, + 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007, + 0x0002, 0x701f, 0x514c, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, + 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, + 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x510a, 0x7224, 0x900e, + 0x2001, 0x0003, 0x080c, 0x9375, 0x2208, 0x0804, 0x35b5, 0x00f6, + 0x00e6, 0x080c, 0x57e9, 0x2009, 0x0007, 0x1904, 0x51df, 0x2071, + 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x51df, 0xac9c, + 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002, + 0x0904, 0x51df, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, + 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6aa3, 0x0118, 0x080c, + 0x6aab, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, + 0x0003, 0x080c, 0x9375, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, + 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006, + 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, + 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, + 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, + 0x51eb, 0x000e, 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e, + 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5, + 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, + 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, + 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, + 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x9375, + 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, + 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6e9f, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, + 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6aa3, + 0x0118, 0x080c, 0x6aab, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, + 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, + 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, + 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5, + 0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, + 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, + 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, + 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, + 0x080c, 0x10f8, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, + 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, + 0x009e, 0x0804, 0x35ea, 0xa884, 0xa988, 0x080c, 0x2873, 0x1518, + 0x080c, 0x66b9, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, + 0x4be4, 0x01c8, 0x080c, 0x4be4, 0x01b0, 0x009e, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, + 0xd284, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, + 0x701f, 0x52b8, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35e7, + 0x7124, 0x080c, 0x334c, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, + 0x0004, 0x0804, 0x35e7, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, + 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, + 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, + 0x20a9, 0x002a, 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78, + 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, + 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, + 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4c30, 0x97c6, 0x7200, + 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, + 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, + 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x5314, 0x0005, + 0x000e, 0x007e, 0x0804, 0x35ea, 0x7020, 0x2048, 0xa804, 0x2048, + 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, + 0x002a, 0x080c, 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, + 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4c30, + 0x81ff, 0x1904, 0x35e7, 0x798c, 0x2001, 0x197e, 0x918c, 0x8000, + 0x2102, 0x080c, 0x4bfb, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x0120, + 0x080c, 0x6aab, 0x1904, 0x35ea, 0x080c, 0x67eb, 0x0904, 0x35e7, + 0x0126, 0x2091, 0x8000, 0x080c, 0x68b1, 0x012e, 0x0904, 0x35e7, + 0x2001, 0x197e, 0x2004, 0xd0fc, 0x1904, 0x35b5, 0x0804, 0x460c, + 0xa9a0, 0x2001, 0x197e, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, + 0x4c08, 0x01a0, 0x080c, 0x6aa3, 0x0118, 0x080c, 0x6aab, 0x1170, + 0x080c, 0x67eb, 0x2009, 0x0002, 0x0128, 0x080c, 0x68b1, 0x1170, + 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, + 0x2001, 0x197e, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57dd, 0x0110, + 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, + 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x4581, 0x080c, 0x4c17, + 0x0904, 0x35ea, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, + 0x35e7, 0x080c, 0x6aa3, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, + 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, + 0x0028, 0x080c, 0x57d5, 0xd0b4, 0x0904, 0x45bb, 0x7884, 0x908e, + 0x007e, 0x0904, 0x45bb, 0x908e, 0x007f, 0x0904, 0x45bb, 0x908e, + 0x0080, 0x0904, 0x45bb, 0xb800, 0xd08c, 0x1904, 0x45bb, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2a3, 0x1120, 0x2009, + 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x53e0, 0x0005, + 0x080c, 0x4c17, 0x0904, 0x35ea, 0x0804, 0x45bb, 0x080c, 0x33a5, + 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, + 0x0001, 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, + 0x0804, 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, + 0x35e7, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x45bb, 0x9006, + 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd302, 0x1120, + 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x5419, + 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, + 0x5729, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x0804, 0x53b2, 0x81ff, + 0x2009, 0x0001, 0x1904, 0x35e7, 0x080c, 0x57e9, 0x2009, 0x0007, + 0x1904, 0x35e7, 0x080c, 0x6a9b, 0x0120, 0x2009, 0x0008, 0x0804, + 0x35e7, 0x080c, 0x4c17, 0x0904, 0x35ea, 0x080c, 0x6aa3, 0x2009, + 0x0009, 0x1904, 0x35e7, 0x080c, 0x4be4, 0x2009, 0x0002, 0x0904, + 0x35e7, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, + 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, + 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, + 0x35ea, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd555, 0x2009, + 0x0003, 0x0904, 0x35e7, 0x7007, 0x0003, 0x701f, 0x5470, 0x0005, + 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35e7, 0x0804, + 0x35b5, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, + 0x57e9, 0x1188, 0x2009, 0x0014, 0x0804, 0x35e7, 0xd2dc, 0x1578, + 0x81ff, 0x2009, 0x0001, 0x1904, 0x35e7, 0x080c, 0x57e9, 0x2009, + 0x0007, 0x1904, 0x35e7, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, + 0x080c, 0x57af, 0x0804, 0x35b5, 0xd2fc, 0x0160, 0x080c, 0x4c17, + 0x0904, 0x35ea, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5784, + 0x0804, 0x35b5, 0x080c, 0x4c17, 0x0904, 0x35ea, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x555f, 0x080c, + 0x4be4, 0x2009, 0x0002, 0x0904, 0x555f, 0xa85c, 0x9080, 0x001b, + 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, + 0x4c2d, 0x701f, 0x54cc, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, + 0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, + 0x35ea, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4c17, + 0x1110, 0x0804, 0x35ea, 0x2009, 0x0043, 0x080c, 0xd5c1, 0x2009, + 0x0003, 0x0904, 0x555f, 0x7007, 0x0003, 0x701f, 0x54f0, 0x0005, + 0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x555f, 0x7984, + 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, 0x5784, 0x0804, 0x35b5, + 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, + 0x57e9, 0x1158, 0x2009, 0x0014, 0x0804, 0x554e, 0x2061, 0x1800, + 0x080c, 0x57e9, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, + 0x5000, 0xc0d5, 0x080c, 0x57af, 0x0058, 0xd2fc, 0x0180, 0x080c, + 0x4c15, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x5784, + 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, + 0x4c15, 0x0510, 0x080c, 0x6aa3, 0x2009, 0x0009, 0x11b8, 0xa8c4, + 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, + 0xff00, 0x1190, 0x080c, 0x4c15, 0x1108, 0x0070, 0x2009, 0x004b, + 0x080c, 0xd5c1, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, + 0xd2dc, 0x0904, 0x35e7, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, + 0x080c, 0x5784, 0x001e, 0x1904, 0x35e7, 0x0804, 0x35b5, 0x00f6, + 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, + 0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x5784, + 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, + 0x35e7, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6724, 0x1904, + 0x35ea, 0x9186, 0x007f, 0x0138, 0x080c, 0x6aa3, 0x0120, 0x2009, + 0x0009, 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, + 0x0804, 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, + 0x0100, 0x8007, 0xa80a, 0x080c, 0xd2bd, 0x1120, 0x2009, 0x0003, + 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, 0x55bf, 0x0005, 0xa808, + 0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35e7, + 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, + 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c30, 0x080c, 0x4be4, + 0x1120, 0x2009, 0x0002, 0x0804, 0x35e7, 0x7984, 0x9194, 0xff00, + 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b4, 0x0040, + 0x92c6, 0x0001, 0x1118, 0x7023, 0x19ce, 0x0010, 0x0804, 0x35ea, + 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, + 0x0019, 0xaf60, 0x080c, 0x4c2d, 0x701f, 0x560f, 0x0005, 0x2001, + 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, + 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, + 0x0804, 0x35b5, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, + 0x35e7, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, + 0x1118, 0x2099, 0x19b4, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, + 0x19ce, 0x0010, 0x0804, 0x35ea, 0xa85c, 0x9080, 0x0019, 0x20a0, + 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, + 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, + 0xaf60, 0x0804, 0x4c30, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35ea, + 0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, + 0x2061, 0x19fb, 0x614a, 0x00ce, 0x012e, 0x0804, 0x35b5, 0x00c6, + 0x080c, 0x7637, 0x1160, 0x080c, 0x7932, 0x080c, 0x612e, 0x9085, + 0x0001, 0x080c, 0x767b, 0x080c, 0x7563, 0x080c, 0x0dc5, 0x2061, + 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5fed, 0x00ce, 0x0005, + 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35e7, + 0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199c, 0x2c0c, 0x2062, + 0x080c, 0x2c49, 0x01a0, 0x080c, 0x2c51, 0x0188, 0x080c, 0x2c59, + 0x0170, 0x2162, 0x0804, 0x35ea, 0x2061, 0x0100, 0x6038, 0x9086, + 0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, + 0x9086, 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, + 0x0026, 0x2011, 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, + 0xaac9, 0x002e, 0x080c, 0xa9d3, 0x0036, 0x901e, 0x080c, 0xaa49, + 0x003e, 0x60e3, 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x9085, + 0x0001, 0x080c, 0x767b, 0x9006, 0x080c, 0x2d39, 0x2001, 0x1800, + 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x6027, 0x0008, + 0x00ce, 0x0804, 0x35b5, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x35e7, 0x080c, 0x57e9, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e7, + 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6724, 0x1904, 0x35ea, + 0x9186, 0x007f, 0x0138, 0x080c, 0x6aa3, 0x0120, 0x2009, 0x0009, + 0x0804, 0x35e7, 0x080c, 0x4be4, 0x1120, 0x2009, 0x0002, 0x0804, + 0x35e7, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd2c0, + 0x1120, 0x2009, 0x0003, 0x0804, 0x35e7, 0x7007, 0x0003, 0x701f, + 0x5712, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, + 0x0804, 0x35e7, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, + 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, + 0x4c30, 0xa898, 0x9086, 0x000d, 0x1904, 0x35e7, 0x2021, 0x4005, + 0x0126, 0x2091, 0x8000, 0x0e04, 0x5736, 0x0010, 0x012e, 0x0cc0, + 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, + 0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, + 0x799e, 0x080c, 0x4c20, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, + 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, + 0x19fb, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, + 0x7898, 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, + 0x2001, 0x1a0b, 0x2044, 0x2001, 0x1a12, 0xa076, 0xa060, 0xa072, + 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, + 0x00ce, 0x012e, 0x0804, 0x35b5, 0x0126, 0x2091, 0x8000, 0x00b6, + 0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, + 0x2019, 0x0029, 0x080c, 0x336a, 0x003e, 0x080c, 0xd125, 0x000e, + 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, + 0x080c, 0x6148, 0x080c, 0xb23d, 0x0110, 0xb817, 0x0000, 0x9006, + 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, + 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, + 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, + 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, + 0x0128, 0x0026, 0x2200, 0x080c, 0x5784, 0x002e, 0x001e, 0x8108, + 0x1f04, 0x57b7, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004, + 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, + 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, + 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, + 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, + 0x0005, 0x79a4, 0x81ff, 0x0904, 0x35ea, 0x9182, 0x0081, 0x1a04, + 0x35ea, 0x810c, 0x0016, 0x080c, 0x4be4, 0x0170, 0x080c, 0x0f16, + 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, + 0x4c2d, 0x701f, 0x5819, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, + 0x35e7, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, + 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, + 0x080c, 0x4c30, 0x701f, 0x582d, 0x0005, 0x2061, 0x18b8, 0x2c44, + 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e, + 0x080c, 0x0fcb, 0x9006, 0xa802, 0xa806, 0x0804, 0x35b5, 0x0126, + 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, + 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x59ed, 0x0068, 0xd08c, + 0x0118, 0x080c, 0x58f6, 0x0040, 0xd094, 0x0118, 0x080c, 0x58c6, + 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, + 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x7030, + 0xd09c, 0x1120, 0x6004, 0x9085, 0x0002, 0x6006, 0x7098, 0x9005, + 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, + 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, + 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, + 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, + 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x60aa, 0x00f0, 0x6040, + 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, + 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, + 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, + 0x000f, 0x2011, 0x5f90, 0x080c, 0x88d5, 0x0005, 0x2001, 0x1869, + 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, + 0x2011, 0x5f90, 0x080c, 0x883d, 0x6040, 0x9094, 0x0010, 0x9285, + 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, + 0x58dc, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, + 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, + 0x0000, 0x9006, 0x080c, 0x6133, 0x0000, 0x0005, 0x708c, 0x908a, + 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5900, 0x5951, 0x59ec, + 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, + 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, + 0x9084, 0x00fc, 0x0120, 0x1f04, 0x590f, 0x080c, 0x0dc5, 0x68a0, + 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, + 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x610f, 0x2079, 0x1c00, + 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, + 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, + 0xaf8e, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, + 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, + 0x080c, 0x5fc1, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, + 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x59c9, + 0x6020, 0xd0b4, 0x1904, 0x59c7, 0x71a0, 0x81ff, 0x0904, 0x59b5, + 0x9486, 0x000c, 0x1904, 0x59c2, 0x9480, 0x0018, 0x8004, 0x20a8, + 0x080c, 0x6108, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, + 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x596e, 0x6043, 0x0004, + 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, + 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, + 0x2011, 0x5f97, 0x080c, 0x88d5, 0x080c, 0x610f, 0x04c0, 0x080c, + 0x6108, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, + 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, + 0x0190, 0x080c, 0x6108, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, + 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, + 0x1f04, 0x59a9, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6108, 0x20e1, + 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x20a9, + 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, + 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, + 0x080c, 0xaf8e, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, + 0x19f2, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x080c, 0xa6e0, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, + 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a1e, 0x5a31, 0x5a5a, 0x5a7a, + 0x5aa0, 0x5acf, 0x5af5, 0x5b2d, 0x5b53, 0x5b81, 0x5bbc, 0x5bf4, + 0x5c12, 0x5c3d, 0x5c5f, 0x5c7a, 0x5c84, 0x5cb8, 0x5cde, 0x5d0d, + 0x5d33, 0x5d6b, 0x5daf, 0x5dec, 0x5e0d, 0x5e66, 0x5e88, 0x5eb6, + 0x5eb6, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, + 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, + 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, + 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5f97, 0x080c, 0x88d5, + 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, + 0xd0b4, 0x11f0, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, + 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f97, 0x080c, + 0x883d, 0x709b, 0x0010, 0x080c, 0x5c84, 0x0010, 0x7093, 0x0000, + 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, + 0x5f97, 0x080c, 0x883d, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, + 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, + 0x0000, 0x8108, 0x1f04, 0x5a6f, 0x60c3, 0x0014, 0x080c, 0x5fc1, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, + 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, + 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, + 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x0005, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, + 0x1103, 0x7837, 0x0000, 0x080c, 0x6108, 0x080c, 0x60eb, 0x1170, + 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, + 0x0008, 0x080c, 0x5f44, 0x0168, 0x080c, 0x60c1, 0x20a9, 0x0008, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, + 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, + 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, + 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, + 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, + 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, + 0x080c, 0x6108, 0x080c, 0x60eb, 0x11b8, 0x7084, 0x9005, 0x11a0, + 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b6, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f44, 0x0180, 0x080c, + 0x50d1, 0x0110, 0x080c, 0x28dc, 0x20a9, 0x0008, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, + 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, + 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, + 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, + 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x608c, + 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x60eb, + 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5eb7, 0x1188, 0x9085, + 0x0001, 0x080c, 0x28dc, 0x20a9, 0x0008, 0x080c, 0x6108, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x0010, 0x080c, 0x5a11, 0x00fe, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f97, 0x080c, + 0x883d, 0x9086, 0x0014, 0x1560, 0x080c, 0x6108, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, + 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, + 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5c5f, 0x0010, + 0x080c, 0x60e4, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, + 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, + 0x4304, 0x080c, 0x608c, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, + 0x0000, 0x080c, 0x60eb, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, + 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, + 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, + 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5be1, 0x60c3, 0x0084, + 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, + 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1178, 0x080c, + 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, + 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x60e4, + 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x608c, 0x2079, + 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6108, 0x20a9, + 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, + 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, + 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c25, 0x60c3, + 0x0084, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x01e0, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1198, + 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, + 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x605e, 0x709b, + 0x000e, 0x0029, 0x0010, 0x080c, 0x60e4, 0x00fe, 0x0005, 0x918d, + 0x0001, 0x080c, 0x6133, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, + 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, + 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f97, 0x080c, + 0x8831, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f97, 0x080c, + 0x883d, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xaf8e, + 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, + 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, + 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x60eb, 0x11a0, 0x717c, + 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, + 0x2873, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, + 0x0008, 0x080c, 0x5f44, 0x60c3, 0x0014, 0x080c, 0x5fc1, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0013, 0x080c, 0x609a, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, + 0x0000, 0x080c, 0x6108, 0x080c, 0x60eb, 0x1170, 0x7084, 0x9005, + 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, + 0x5f44, 0x0168, 0x080c, 0x60c1, 0x20a9, 0x0008, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, + 0x0014, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x0500, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x11b8, + 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, + 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x609a, + 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6108, + 0x080c, 0x60eb, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, + 0xffff, 0x0180, 0x9180, 0x33b6, 0x200d, 0x918c, 0xff00, 0x810f, + 0x2011, 0x0008, 0x080c, 0x5f44, 0x0180, 0x080c, 0x50d1, 0x0110, + 0x080c, 0x28dc, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, + 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, + 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, + 0x5f97, 0x080c, 0x883d, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6108, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, + 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, + 0x6133, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x6133, + 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, + 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, + 0xaf8e, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, + 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, + 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, + 0x709b, 0x0017, 0x080c, 0x60eb, 0x1150, 0x7084, 0x9005, 0x1138, + 0x080c, 0x5eb7, 0x1188, 0x9085, 0x0001, 0x080c, 0x28dc, 0x20a9, + 0x0008, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fc1, + 0x0010, 0x080c, 0x5a11, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, + 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, 0x1190, 0x080c, + 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, + 0x9005, 0x1138, 0x9006, 0x080c, 0x6133, 0x709b, 0x0018, 0x0029, + 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, + 0x080c, 0x609a, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, + 0x080c, 0x6108, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, + 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, + 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e20, 0x2039, 0x1c0e, 0x080c, + 0x60eb, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, + 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, + 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, + 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, + 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, + 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5e53, + 0x60c3, 0x0084, 0x080c, 0x5fc1, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x01e0, 0x2011, 0x5f97, 0x080c, 0x883d, 0x9086, 0x0084, + 0x1198, 0x080c, 0x6108, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, + 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x605e, + 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x9085, 0x0001, 0x080c, 0x6133, 0x709b, 0x001b, 0x080c, 0xaf8e, + 0x080c, 0x6108, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, + 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, + 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, + 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, + 0x5e9f, 0x60c3, 0x0084, 0x080c, 0x5fc1, 0x0005, 0x0005, 0x0086, + 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1c0e, + 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6108, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, + 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, + 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5ed1, 0x0804, 0x5f40, + 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, + 0x91a6, 0x3fff, 0x0904, 0x5f40, 0x918d, 0xc000, 0x20a9, 0x0010, + 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, + 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, + 0x0008, 0x8318, 0x1f04, 0x5ef7, 0x04d8, 0x23a8, 0x2021, 0x0001, + 0x8426, 0x8425, 0x1f04, 0x5f09, 0x2328, 0x8529, 0x92be, 0x0007, + 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, + 0x95a8, 0x0010, 0x1f04, 0x5f18, 0x755e, 0x95c8, 0x33b6, 0x292d, + 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, + 0x28bc, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, + 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, + 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, + 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, + 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, + 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, + 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, + 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, + 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, + 0x9405, 0x203a, 0x715e, 0x91a0, 0x33b6, 0x242d, 0x95ac, 0x00ff, + 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28bc, 0x001e, + 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, + 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x604d, 0x080c, + 0xa6e9, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d49, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, + 0x0016, 0x2009, 0x00f7, 0x080c, 0x60aa, 0x001e, 0x9094, 0x0010, + 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, + 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x2bce, 0x0228, 0x2011, + 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f2, 0x2013, 0x0000, + 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, + 0xa6e0, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, + 0x718c, 0x918d, 0x1000, 0x2011, 0x1999, 0x2112, 0x2009, 0x07d0, + 0x2011, 0x5f97, 0x080c, 0x88d5, 0x0005, 0x0016, 0x0026, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xb244, 0x2009, 0x00f7, 0x080c, + 0x60aa, 0x2061, 0x19fb, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e, + 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, + 0x6043, 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, + 0x2011, 0x6019, 0x080c, 0x8831, 0x012e, 0x00ce, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, + 0x0100, 0x080c, 0xa6e9, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, + 0x0110, 0x080c, 0x2d49, 0x080c, 0x763f, 0x0188, 0x080c, 0x765a, + 0x1170, 0x080c, 0x793c, 0x0016, 0x080c, 0x298b, 0x2001, 0x196d, + 0x2102, 0x001e, 0x080c, 0x7937, 0x080c, 0x7563, 0x0050, 0x2009, + 0x0001, 0x080c, 0x2c67, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, + 0x5fed, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, + 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1999, + 0x201c, 0x080c, 0x4c44, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, + 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x6108, 0x20e9, 0x0000, + 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6102, 0x2099, + 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6105, + 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, 0x0026, + 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, + 0x6082, 0x002e, 0x001e, 0x0005, 0x080c, 0xaf8e, 0x20e1, 0x0001, + 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, + 0x4003, 0x0005, 0x080c, 0xaf8e, 0x080c, 0x6108, 0x20e1, 0x0000, + 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, + 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, + 0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, + 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, + 0x0005, 0x0016, 0x0046, 0x080c, 0x6a9f, 0x0158, 0x9006, 0x2020, + 0x2009, 0x002a, 0x080c, 0xec31, 0x2001, 0x180c, 0x200c, 0xc195, + 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x321b, 0x080c, 0xd7e3, + 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4dfb, + 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5fed, 0x709b, 0x0000, + 0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, + 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, + 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, + 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, + 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, + 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, + 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, 0x7807, + 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, + 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, + 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001, + 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, + 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x6142, 0x015e, 0x0005, + 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, + 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, + 0x33b6, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8c2, + 0x080c, 0xb23d, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, 0x20a9, + 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, + 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, + 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, 0xb85e, + 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, + 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, + 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, 0xb8a7, + 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, + 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, + 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, + 0x0dc5, 0x080c, 0x8cf7, 0x00ce, 0x090c, 0x9096, 0xb8af, 0x0000, + 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, + 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, + 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6230, 0x9182, 0x0800, 0x1a04, + 0x6234, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x623a, + 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, 0x00ff, + 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x624c, 0xb850, + 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, 0x951c, + 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, 0xa803, + 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, 0x04b8, + 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, + 0xb23d, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, + 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, + 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, + 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, + 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, + 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, + 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, + 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x6aa3, 0x1990, 0xb800, + 0xd0bc, 0x0978, 0x0804, 0x61e3, 0x080c, 0x68c0, 0x0904, 0x61fc, + 0x0804, 0x61e7, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, + 0x908e, 0x00ff, 0x1120, 0x2001, 0x196b, 0x205c, 0x0060, 0xa974, + 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, + 0x080c, 0x6a43, 0x11d0, 0x080c, 0xb27d, 0x0570, 0x2b00, 0x6012, + 0x2900, 0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, 0x908e, + 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, 0xb352, + 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, + 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, + 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, + 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, + 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, + 0x631d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x62f5, 0xb8a0, + 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6aab, + 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, + 0x0005, 0x0118, 0x080c, 0x6aa3, 0x1598, 0xa87c, 0xd0fc, 0x01e0, + 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xd0c6, + 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x631f, 0x6020, 0x9086, + 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x631f, 0x601a, 0x6003, + 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xb27d, 0x05e8, 0x2b00, + 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, + 0x0003, 0x080c, 0xb352, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, + 0x9082, 0x0006, 0x1290, 0x080c, 0xb23d, 0x1160, 0xb8a0, 0x9084, + 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, + 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, + 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, + 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, + 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, + 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, + 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, + 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, + 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, + 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, + 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, + 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x63b4, + 0x636f, 0x6386, 0x63b4, 0x63b4, 0x63b4, 0x63b4, 0x63b4, 0x2100, + 0x9082, 0x007e, 0x1278, 0x080c, 0x66b9, 0x0148, 0x9046, 0xb810, + 0x9306, 0x1904, 0x63bc, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, + 0xba16, 0x0010, 0x080c, 0x4af7, 0x0150, 0x04b0, 0x080c, 0x6724, + 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, + 0xb27d, 0x0530, 0x2b00, 0x6012, 0x080c, 0xd554, 0x2900, 0x6016, + 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, + 0x080c, 0x3250, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, 0x080c, + 0x666a, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, + 0x080c, 0xb352, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, + 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, + 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, + 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x65a7, + 0x90c6, 0x0056, 0x0904, 0x65ab, 0x90c6, 0x0066, 0x0904, 0x65af, + 0x90c6, 0x0067, 0x0904, 0x65b3, 0x90c6, 0x0068, 0x0904, 0x65b7, + 0x90c6, 0x0071, 0x0904, 0x65bb, 0x90c6, 0x0074, 0x0904, 0x65bf, + 0x90c6, 0x007c, 0x0904, 0x65c3, 0x90c6, 0x007e, 0x0904, 0x65c7, + 0x90c6, 0x0037, 0x0904, 0x65cb, 0x9016, 0x2079, 0x1800, 0xa974, + 0x9186, 0x00ff, 0x0904, 0x65a2, 0x9182, 0x0800, 0x1a04, 0x65a2, + 0x080c, 0x6724, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, + 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xb23d, 0x1904, + 0x658b, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x658b, 0xa894, 0x90c6, + 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x64eb, 0x90c6, 0x0064, + 0x0904, 0x6514, 0x2008, 0x0804, 0x64ad, 0xa998, 0xa8b0, 0x2040, + 0x080c, 0xb23d, 0x1120, 0x9182, 0x007f, 0x0a04, 0x64ad, 0x9186, + 0x00ff, 0x0904, 0x64ad, 0x9182, 0x0800, 0x1a04, 0x64ad, 0xaaa0, + 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, + 0x2208, 0x2310, 0x009e, 0x0804, 0x64ad, 0x080c, 0xb23d, 0x1140, + 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x64ad, + 0x009e, 0x080c, 0x4af7, 0x0904, 0x64b7, 0x900e, 0x9016, 0x90c6, + 0x4000, 0x15e0, 0x0006, 0x080c, 0x6944, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, + 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, + 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, + 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, + 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, + 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, + 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, + 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, + 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, + 0xb27d, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, + 0x2b00, 0x6012, 0x080c, 0xd554, 0x2900, 0x6016, 0x6023, 0x0001, + 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, + 0x080c, 0x3250, 0x012e, 0x9006, 0x080c, 0x6656, 0x2001, 0x0002, + 0x080c, 0x666a, 0x2009, 0x0002, 0x080c, 0xb352, 0xa8b0, 0xd094, + 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e, 0x00ee, + 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e9, 0x0118, 0x2009, 0x0007, + 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6724, 0x1904, 0x64a8, 0x9186, + 0x007f, 0x0130, 0x080c, 0x6aa3, 0x0118, 0x2009, 0x0009, 0x0080, + 0x0096, 0x080c, 0x100e, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, + 0x2900, 0x009e, 0xa806, 0x080c, 0xd2c0, 0x19b0, 0x2009, 0x0003, + 0x2001, 0x4005, 0x0804, 0x64af, 0xa998, 0xaeb0, 0x080c, 0x6724, + 0x1904, 0x64a8, 0x0096, 0x080c, 0x100e, 0x1128, 0x009e, 0x2009, + 0x0002, 0x0804, 0x6568, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, + 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, + 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0f8b, + 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, + 0x1168, 0x080c, 0x57d5, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, + 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6aa3, + 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x57e9, 0x0118, 0xa89b, + 0x0007, 0x0050, 0x080c, 0xd2a3, 0x1904, 0x64e4, 0x2009, 0x0003, + 0x2001, 0x4005, 0x0804, 0x64af, 0xa87b, 0x0030, 0xa897, 0x4005, + 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, + 0x2031, 0x0000, 0x2041, 0x1252, 0x080c, 0xb7f1, 0x1904, 0x64e4, + 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x64e5, + 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, + 0x0804, 0x64e5, 0x2001, 0x0029, 0x900e, 0x0804, 0x64e5, 0x080c, + 0x37e9, 0x0804, 0x64e6, 0x080c, 0x5500, 0x0804, 0x64e6, 0x080c, + 0x4637, 0x0804, 0x64e6, 0x080c, 0x46b0, 0x0804, 0x64e6, 0x080c, + 0x470c, 0x0804, 0x64e6, 0x080c, 0x4bba, 0x0804, 0x64e6, 0x080c, + 0x4e82, 0x0804, 0x64e6, 0x080c, 0x5167, 0x0804, 0x64e6, 0x080c, + 0x5360, 0x0804, 0x64e6, 0x080c, 0x3a25, 0x0804, 0x64e6, 0x00b6, + 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, 0x9182, + 0x0800, 0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140, 0x080c, + 0x6aa3, 0x1148, 0x00e9, 0x080c, 0x684f, 0x9006, 0x00b0, 0x2001, + 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, 0xd1fc, + 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, + 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, 0x0005, + 0x0126, 0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900, 0x0096, + 0x2148, 0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e, 0x0005, + 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, 0x2091, + 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e8, 0x7004, + 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, 0xb84e, + 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, + 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, 0xa802, + 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, + 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, 0xa800, + 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, 0x0126, + 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, + 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, + 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, + 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, + 0x0158, 0x080c, 0x6a9f, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, + 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, + 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, + 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, + 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, + 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a9b, 0x1138, + 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, + 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, + 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, + 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, + 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, + 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x6148, 0x9006, + 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, + 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, + 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1040, 0x00d6, + 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, + 0x2048, 0x080c, 0xd0d8, 0x0110, 0x080c, 0x0fc0, 0x080c, 0xb2d3, + 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, + 0x621c, 0xd2c4, 0x0110, 0x080c, 0x9096, 0x00ce, 0x2b48, 0xb8c8, + 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050, 0x00de, 0x9006, 0x002e, + 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, + 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, + 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x7637, 0x1510, + 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb23d, 0x11d8, 0x0078, + 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1982, 0x7048, 0x2062, + 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, + 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, + 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, + 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, + 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, + 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, + 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, + 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, + 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, + 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, + 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, + 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, + 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, + 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, + 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, + 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384, 0xba00, 0x2009, 0x1867, + 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, + 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, + 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbce, 0x003e, 0x00ee, + 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, + 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, + 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, + 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, + 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00, 0x20e8, 0x3300, 0x8001, + 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, + 0x0060, 0x080c, 0x100e, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, + 0x080c, 0x68e0, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, + 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, + 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x68ef, + 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, + 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x080c, 0x951c, 0x012e, 0x0005, 0x901e, 0x0010, + 0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, + 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, + 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, + 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0xaaf1, 0xaa00, + 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, + 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, + 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6944, 0x0128, + 0x080c, 0xd195, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6944, + 0x0128, 0x080c, 0xd13a, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, + 0x6944, 0x0128, 0x080c, 0xd192, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x6944, 0x0128, 0x080c, 0xd159, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x6944, 0x0128, 0x080c, 0xd1d8, 0x0010, 0x9085, + 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005, + 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, + 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, + 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, + 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, + 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136, + 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, + 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, + 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, + 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, + 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006, + 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x1128, 0x080c, 0x100e, 0x0168, 0x2900, 0xb8a6, 0x080c, + 0x68e0, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e, + 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, + 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1040, 0x9085, + 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, + 0x00f6, 0x080c, 0x7637, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, + 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d, + 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, + 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156, + 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, 0x1168, 0xb804, + 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, + 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x696b, + 0x015e, 0x080c, 0x6a61, 0x0120, 0x2001, 0x1985, 0x200c, 0x0098, + 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0190, 0x2009, 0x07d0, 0x2001, + 0x182c, 0x2004, 0x9005, 0x0138, 0x2001, 0x1867, 0x2004, 0xd0e4, + 0x0110, 0x2009, 0x5dc0, 0x2011, 0x69a2, 0x080c, 0x88d5, 0x00fe, + 0x00be, 0x0005, 0x00b6, 0x2011, 0x69a2, 0x080c, 0x883d, 0x080c, + 0x6a61, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, + 0xb902, 0x080c, 0x6a9f, 0x0130, 0x2009, 0x07d0, 0x2011, 0x69a2, + 0x080c, 0x88d5, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, + 0x7082, 0x080c, 0x3000, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x6724, 0x1538, 0xb800, 0xd0ec, + 0x0520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, + 0xec31, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a9b, 0x2001, + 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, + 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, + 0x900e, 0x080c, 0xe91c, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, + 0x69ca, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, + 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, + 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001, 0x196b, + 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, + 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x6148, + 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, + 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, + 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, + 0x00be, 0xd0bc, 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, + 0x00ff, 0x9196, 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, + 0x0005, 0x0158, 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, + 0x9196, 0x0004, 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, + 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, + 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, + 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, + 0x0dc5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, + 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, + 0x0138, 0x2001, 0x1983, 0x200c, 0x2011, 0x6a91, 0x080c, 0x88d5, + 0x0005, 0x2011, 0x6a91, 0x080c, 0x883d, 0x2011, 0x1837, 0x2204, + 0xc0cc, 0x2012, 0x0005, 0x080c, 0x57d5, 0xd0ac, 0x0005, 0x080c, + 0x57d5, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, + 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, + 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd7e3, + 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, + 0x905d, 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, + 0x0016, 0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1818, 0x203c, + 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, + 0x2008, 0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, + 0x2100, 0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, + 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, + 0xb89c, 0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, + 0x9182, 0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, + 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, + 0x0005, 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, + 0x0005, 0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, + 0x9080, 0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1818, + 0x203c, 0x9780, 0x33b6, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, + 0x2020, 0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, + 0x0178, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, + 0xd0a4, 0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, + 0x8420, 0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, + 0x007e, 0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, + 0x00be, 0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x0006, 0x2001, + 0x00a0, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, + 0x0006, 0x2001, 0x00f8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, + 0x000e, 0x0005, 0x0006, 0x2001, 0x00e8, 0x8001, 0xa001, 0xa001, + 0xa001, 0x1dd8, 0x000e, 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, + 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, + 0x7046, 0x2001, 0x1922, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, + 0x2071, 0x1948, 0x900e, 0x710a, 0x080c, 0x57d5, 0xd0fc, 0x1140, + 0x080c, 0x57d5, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0470, + 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0006, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x000e, 0x0108, 0x9006, 0x0002, 0x6b98, 0x6b98, + 0x6b98, 0x6b98, 0x6b98, 0x6bb6, 0x6bcb, 0x6bd9, 0x7003, 0x0003, + 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, + 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, + 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, + 0x704f, 0x0000, 0x2071, 0x1800, 0x70f3, 0x0001, 0x00ee, 0x001e, + 0x0005, 0x7003, 0x0000, 0x2071, 0x1910, 0x2009, 0x1868, 0x210c, + 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, 0x8004, + 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, 0x0128, + 0x70f2, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70f3, 0x0005, 0x08f0, + 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, + 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, + 0x6844, 0x9005, 0x0158, 0x080c, 0x79a4, 0x6a60, 0x9200, 0x7002, + 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, + 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, + 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, + 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, + 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, + 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, + 0x9015, 0x0904, 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, + 0x0005, 0x0904, 0x6d3e, 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, + 0x6c99, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6ea5, 0xa878, 0xd084, + 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, + 0x701c, 0x9005, 0x1904, 0x7073, 0x0e04, 0x70e1, 0x2071, 0x0000, + 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, + 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, + 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, + 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11aa, 0x0804, 0x6d21, 0xa853, 0x001b, 0x2001, 0x8027, + 0x0820, 0x7004, 0xd08c, 0x1904, 0x6ea5, 0xa853, 0x001a, 0x2001, + 0x8024, 0x0804, 0x6c5d, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, + 0x9015, 0x0904, 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, + 0x0005, 0x0904, 0x6d3e, 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, + 0x6d06, 0xa868, 0xd0fc, 0x1508, 0x00e6, 0x0026, 0x2001, 0x1948, + 0x2004, 0x9015, 0x0904, 0x6ea5, 0xa978, 0xa874, 0x9105, 0x1904, + 0x6ea5, 0x9286, 0x0003, 0x0904, 0x6d3e, 0x9286, 0x0005, 0x0904, + 0x6d3e, 0xa87c, 0xd0bc, 0x1904, 0x6ea5, 0x2200, 0x0002, 0x6ea5, + 0x6d02, 0x6d3e, 0x6d3e, 0x6ea5, 0x6d3e, 0x0005, 0xa868, 0xd0fc, + 0x1500, 0x00e6, 0x0026, 0x2009, 0x1948, 0x210c, 0x81ff, 0x0904, + 0x6ea5, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x6ea5, + 0x9186, 0x0003, 0x0904, 0x6d3e, 0x9186, 0x0005, 0x0904, 0x6d3e, + 0xa87c, 0xd0cc, 0x0904, 0x6ea5, 0xa84f, 0x8021, 0xa853, 0x0017, + 0x0028, 0x0005, 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, + 0x701c, 0x9005, 0x1904, 0x7073, 0x0e04, 0x70e1, 0x2071, 0x0000, + 0xa84c, 0x7082, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, + 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x2071, 0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, + 0x1158, 0xa802, 0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x8725, 0x002e, 0x00ee, 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, + 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, + 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, + 0x9005, 0x1904, 0x6e29, 0x782c, 0x908c, 0x0780, 0x190c, 0x722f, + 0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6d5c, 0x6e29, + 0x6d80, 0x6dc6, 0x080c, 0x0dc5, 0x2071, 0x1800, 0x2900, 0x7822, + 0xa804, 0x900d, 0x1168, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, + 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0c18, + 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1578, 0x7824, + 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, + 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, + 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, + 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, + 0x19f0, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, + 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0808, 0x0096, 0x00e6, + 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, + 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, + 0x190c, 0x722f, 0xd09c, 0x1198, 0x009e, 0x2900, 0x7822, 0xa804, + 0x900d, 0x1550, 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, + 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e, + 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, + 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1168, 0x2071, + 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, + 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, + 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, + 0x6e7d, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x1198, + 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, + 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, + 0x722f, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, + 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, + 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, + 0x2071, 0x19fb, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, + 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x00ee, + 0x0804, 0x6e39, 0xa868, 0xd0fc, 0x1904, 0x6ef3, 0x0096, 0xa804, + 0xa807, 0x0000, 0x904d, 0x190c, 0x0fc0, 0x009e, 0x0020, 0xa868, + 0xd0fc, 0x1904, 0x6ef3, 0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, + 0x2079, 0x0050, 0x2071, 0x1800, 0x70ec, 0x8001, 0x0558, 0x1a04, + 0x6ef0, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864, 0x9084, 0x00ff, + 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904, 0x6fef, 0x782c, + 0x908c, 0x0780, 0x190c, 0x722f, 0x8004, 0x8004, 0x8004, 0x9084, + 0x0003, 0x0002, 0x6ef4, 0x6fef, 0x6f0f, 0x6f80, 0x080c, 0x0dc5, + 0x2009, 0x1948, 0x2104, 0x0002, 0x6ebb, 0x6ebb, 0x6ebb, 0x6d47, + 0x6ebb, 0x6d47, 0x70ef, 0x0fa0, 0x71e8, 0x8107, 0x9106, 0x9094, + 0x00c0, 0x9184, 0xff3f, 0x9205, 0x70ea, 0x3b08, 0x3a00, 0x9104, + 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x0808, + 0x70ee, 0x0804, 0x6eb1, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, + 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0c60, 0x2071, + 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6f6f, 0x7830, + 0x8007, 0x908c, 0x001f, 0x70f0, 0x9102, 0x1220, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, + 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, + 0x190c, 0x722f, 0xd0a4, 0x19f0, 0x0e04, 0x6f66, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2001, 0x1922, + 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2001, 0x1921, + 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, 0x0804, 0x6f22, + 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, + 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, + 0x6fc2, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, + 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, + 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x1170, + 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e, 0x2908, + 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, + 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x8725, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, + 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x705e, 0x782c, + 0x9094, 0x0780, 0x190c, 0x722f, 0xd09c, 0x11b0, 0x701c, 0x904d, + 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012, 0x1108, + 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, + 0x190c, 0x722f, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780, 0x190c, + 0x722f, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x8725, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d60, + 0x00ee, 0x0e04, 0x7057, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084, + 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x11aa, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, + 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, + 0x00ee, 0x0804, 0x6fff, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, + 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, + 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x709e, + 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, + 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, + 0x9200, 0x70c2, 0x080c, 0x8725, 0x0e04, 0x7088, 0x2071, 0x1910, + 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, + 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, + 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, 0x721b, 0x002e, + 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, + 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, + 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, + 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, + 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, + 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, + 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8725, + 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, + 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, + 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, + 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002, 0x712e, 0x712f, + 0x721a, 0x712f, 0x712c, 0x721a, 0x080c, 0x0dc5, 0x0005, 0x2001, + 0x1948, 0x2004, 0x0002, 0x7139, 0x7139, 0x71b3, 0x71b4, 0x7139, + 0x71b4, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x723a, 0x701c, 0x904d, + 0x0508, 0xa84c, 0x9005, 0x0904, 0x7184, 0x0e04, 0x7162, 0xa94c, + 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, + 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1910, + 0x080c, 0x721b, 0x012e, 0x0804, 0x71b2, 0xa850, 0x9082, 0x001c, + 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, + 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, + 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, + 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b, 0x2004, 0x9094, + 0x0780, 0x190c, 0x722f, 0xd09c, 0x2071, 0x1910, 0x1510, 0x2071, + 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, + 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, + 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1910, 0x701c, + 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, + 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x19fb, + 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, + 0x1815, 0x2004, 0x2009, 0x1ad1, 0x210c, 0x9102, 0x1500, 0x0126, + 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, + 0x0e04, 0x71e6, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, + 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x11aa, 0x2069, 0x19fb, 0x6847, 0xffff, 0x012e, 0x00de, + 0x0126, 0x2091, 0x8000, 0x1e0c, 0x72a5, 0x701c, 0x904d, 0x0540, + 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, + 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, + 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, + 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x701c, 0x2048, + 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, + 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, + 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, + 0x701a, 0x012e, 0x080c, 0x1040, 0x0005, 0x012e, 0x0005, 0x2091, + 0x8000, 0x0e04, 0x7231, 0x0006, 0x0016, 0x2001, 0x8004, 0x0006, + 0x0804, 0x0dce, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, + 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, + 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, + 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780, 0x1981, 0xd0a4, + 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102, 0x0e88, 0x00e6, + 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, + 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, 0x9094, 0x0780, + 0x190c, 0x722f, 0xd0a4, 0x19f0, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x00ee, + 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, + 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, + 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, + 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8725, 0x782c, + 0x9094, 0x0780, 0x190c, 0x722f, 0xd0a4, 0x1d70, 0x00d6, 0x2069, + 0x0050, 0x693c, 0x2069, 0x1948, 0x6808, 0x690a, 0x2069, 0x19fb, + 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x1949, 0x200c, + 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, + 0x1a0c, 0x0dc5, 0x9082, 0x001d, 0x001b, 0x6027, 0x1e00, 0x0005, + 0x73e6, 0x7353, 0x736f, 0x7399, 0x73d5, 0x7415, 0x7427, 0x736f, + 0x73fd, 0x730e, 0x733c, 0x73bf, 0x730d, 0x0005, 0x00d6, 0x2069, + 0x0200, 0x6804, 0x9005, 0x1180, 0x6808, 0x9005, 0x1518, 0x709b, + 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x080c, 0x7774, 0x6028, + 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b, 0x0029, 0x2069, 0x198f, + 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, + 0x0046, 0x0056, 0x2071, 0x1a65, 0x080c, 0x1ad9, 0x005e, 0x004e, + 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, + 0x9005, 0x1178, 0x6808, 0x9005, 0x1160, 0x709b, 0x0029, 0x2069, + 0x198f, 0x2d04, 0x7002, 0x080c, 0x7818, 0x6028, 0x9085, 0x0600, + 0x602a, 0x00de, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d39, + 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x7494, 0xd1d4, 0x1160, + 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b, 0x0020, 0x080c, 0x7494, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, + 0x0088, 0x080c, 0x2d39, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, + 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8, 0x080c, 0x1b06, 0x60e3, + 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7663, 0x2001, 0x0080, + 0x080c, 0x2d39, 0x709b, 0x0029, 0x0058, 0x709b, 0x001e, 0x0040, + 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, + 0x0005, 0x080c, 0x1b06, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, + 0x080c, 0x7663, 0x2001, 0x0080, 0x080c, 0x2d39, 0x6124, 0xd1d4, + 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148, 0x9184, 0x1e00, 0x1118, + 0x709b, 0x0029, 0x0058, 0x709b, 0x0028, 0x0040, 0x709b, 0x001e, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x6124, + 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0x9184, 0x1e00, + 0x1158, 0x709b, 0x0029, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, + 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x00a0, 0x080c, + 0x2d39, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1b06, + 0x709b, 0x001e, 0x0010, 0x709b, 0x001d, 0x0005, 0x080c, 0x7517, + 0x6124, 0xd1dc, 0x1188, 0x080c, 0x7494, 0x0016, 0x080c, 0x1b06, + 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x709b, 0x001e, 0x0020, + 0x709b, 0x001f, 0x080c, 0x7494, 0x0005, 0x0006, 0x2001, 0x00a0, + 0x080c, 0x2d39, 0x000e, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, + 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, + 0x001d, 0x0010, 0x709b, 0x0021, 0x0005, 0x080c, 0x7517, 0x6124, + 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, + 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x0006, + 0x2001, 0x0090, 0x080c, 0x2d39, 0x000e, 0x6124, 0xd1d4, 0x1178, + 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x709b, 0x001e, + 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020, 0x0010, 0x709b, + 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, 0x8000, 0x080c, + 0x7637, 0x11d8, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x01b0, 0xc1b4, + 0x2102, 0x6027, 0x0200, 0x080c, 0x2c61, 0x6024, 0xd0cc, 0x0148, + 0x2001, 0x00a0, 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, + 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x7651, 0x0150, + 0x080c, 0x7648, 0x1138, 0x2001, 0x0001, 0x080c, 0x281c, 0x080c, + 0x760f, 0x00a0, 0x080c, 0x7514, 0x0178, 0x2001, 0x0001, 0x080c, + 0x281c, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, + 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, + 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x74a5, 0x080c, + 0x8917, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x74a5, + 0x080c, 0x890e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, + 0x080c, 0xa6e9, 0x2071, 0x1800, 0x080c, 0x7442, 0x001e, 0x00fe, + 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa6e9, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x2011, + 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, + 0xa9d3, 0x080c, 0x88c3, 0x0036, 0x901e, 0x080c, 0xaa49, 0x003e, + 0x60e3, 0x0000, 0x080c, 0xf07f, 0x080c, 0xf09a, 0x2009, 0x0004, + 0x080c, 0x2c67, 0x080c, 0x2b82, 0x2001, 0x1800, 0x2003, 0x0004, + 0x6027, 0x0008, 0x2011, 0x74a5, 0x080c, 0x8917, 0x080c, 0x7651, + 0x0118, 0x9006, 0x080c, 0x2d39, 0x080c, 0x0ba0, 0x2001, 0x0001, + 0x080c, 0x281c, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, 0x74b2, 0x2071, + 0x19fb, 0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, + 0x0001, 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, + 0x9084, 0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, + 0x2d39, 0x0156, 0x20a9, 0x002d, 0x1d04, 0x7524, 0x2091, 0x6000, + 0x1f04, 0x7524, 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, + 0x0220, 0x0118, 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68e8, + 0xd0dc, 0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x8923, + 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, + 0x2071, 0x1800, 0x080c, 0x7941, 0x2001, 0x196d, 0x2003, 0x0000, + 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28e7, 0x9006, 0x080c, + 0x2d39, 0x080c, 0x5fed, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, + 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197d, 0x200c, 0x9186, + 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, 0x0158, + 0x9186, 0x0003, 0x0158, 0x0804, 0x75ff, 0x709b, 0x0022, 0x0040, + 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b, 0x0024, + 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28e7, + 0x0026, 0x080c, 0xb244, 0x002e, 0x7000, 0x908e, 0x0004, 0x0118, + 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, + 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, + 0x080c, 0xd7e3, 0x0118, 0x9006, 0x080c, 0x2d63, 0x0804, 0x760b, + 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2c61, 0x6904, + 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2d39, 0x1f04, 0x75a3, + 0x080c, 0x768b, 0x012e, 0x015e, 0x080c, 0x7648, 0x01d8, 0x6044, + 0x9005, 0x0198, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, + 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x768b, 0x9006, + 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, + 0x080c, 0x768b, 0x080c, 0xd7e3, 0x0118, 0x9006, 0x080c, 0x2d63, + 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, + 0x2011, 0x74b2, 0x080c, 0x88d5, 0x002e, 0x001e, 0x080c, 0x871c, + 0x7034, 0xc085, 0x7036, 0x2001, 0x197d, 0x2003, 0x0004, 0x080c, + 0x72f5, 0x080c, 0x7648, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, + 0x1100, 0x080c, 0x7937, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, + 0x080c, 0x8733, 0x080c, 0x8725, 0x080c, 0x7941, 0x2001, 0x196d, + 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28e7, + 0x9006, 0x080c, 0x2d39, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, + 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, + 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, + 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, + 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, + 0x0005, 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, 0x0010, + 0x000e, 0x0005, 0x0006, 0x080c, 0x57d9, 0x9084, 0x0030, 0x9086, + 0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, + 0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2907, 0x900e, 0x0010, + 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x321b, 0x9006, 0x0019, + 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, + 0x080c, 0xd7dc, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, + 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, + 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016, 0x6138, 0x6050, + 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, + 0x1d04, 0x76a0, 0x2091, 0x6000, 0x1f04, 0x76a0, 0x602f, 0x0100, + 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, + 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, + 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, + 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28e7, 0x2001, 0x00a0, + 0x0006, 0x080c, 0xd7e3, 0x000e, 0x0130, 0x080c, 0x2d57, 0x9006, + 0x080c, 0x2d63, 0x0010, 0x080c, 0x2d39, 0x000e, 0x6052, 0x6050, + 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2bd6, + 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, + 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001, 0x180c, 0x200c, + 0xc1c5, 0x2102, 0x0804, 0x7766, 0x2001, 0x180c, 0x200c, 0xc1c4, + 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x2001, + 0x0090, 0x080c, 0x2d39, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1518, + 0x1d04, 0x770d, 0x2091, 0x6000, 0x1f04, 0x770d, 0x2011, 0x0003, + 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, 0xa9d3, + 0x901e, 0x080c, 0xaa49, 0x2001, 0x00a0, 0x080c, 0x2d39, 0x080c, + 0x7932, 0x080c, 0x612e, 0x080c, 0xd7e3, 0x0110, 0x080c, 0x0d33, + 0x9085, 0x0001, 0x04c8, 0x080c, 0x1b06, 0x60e3, 0x0000, 0x2001, + 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, 0x196d, + 0x2004, 0x080c, 0x28e7, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2d39, + 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, + 0x6024, 0x910c, 0x0140, 0x1d04, 0x774a, 0x2091, 0x6000, 0x1f04, + 0x774a, 0x0804, 0x7716, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, + 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd7e3, + 0x0110, 0x080c, 0x0d33, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, + 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, + 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, + 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, + 0x1904, 0x77d9, 0x2001, 0x0088, 0x080c, 0x2d39, 0x9006, 0x60e2, + 0x6886, 0x080c, 0x28e7, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, + 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x6027, + 0x0400, 0x2069, 0x198f, 0x7000, 0x206a, 0x709b, 0x0026, 0x7003, + 0x0001, 0x20a9, 0x0002, 0x1d04, 0x77bb, 0x2091, 0x6000, 0x1f04, + 0x77bb, 0x0804, 0x7810, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, + 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, 0x6024, 0x910c, 0x0508, + 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x77c7, 0x2091, 0x6000, 0x1f04, + 0x77c7, 0x2011, 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, + 0xaac9, 0x080c, 0xa9d3, 0x901e, 0x080c, 0xaa49, 0x2001, 0x00a0, + 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, 0x9085, 0x0001, + 0x00f8, 0x080c, 0x1b06, 0x2001, 0x0080, 0x080c, 0x2d39, 0x2069, + 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, + 0x0008, 0x6886, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, + 0x1118, 0x2001, 0x196d, 0x2004, 0x080c, 0x28e7, 0x60e2, 0x9006, + 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, + 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, + 0x0003, 0x080c, 0xaabf, 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, + 0xa9d3, 0x901e, 0x080c, 0xaa49, 0x2069, 0x0140, 0x2001, 0x00a0, + 0x080c, 0x2d39, 0x080c, 0x7932, 0x080c, 0x612e, 0x0804, 0x78b2, + 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, + 0x749a, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2d39, 0x60e3, + 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, + 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, + 0x198f, 0x7000, 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, + 0x78b2, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c61, 0x6024, + 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x7869, 0x0006, + 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8776, 0x00ee, 0x00de, + 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19fb, 0x7078, 0x00ee, + 0x9005, 0x19f8, 0x0438, 0x0026, 0x2011, 0x74b2, 0x080c, 0x883d, + 0x2011, 0x74a5, 0x080c, 0x8917, 0x002e, 0x2069, 0x0140, 0x60e3, + 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, + 0x196d, 0x2004, 0x080c, 0x28e7, 0x60e2, 0x2001, 0x180c, 0x200c, + 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, + 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd7dc, 0x1904, + 0x7920, 0x7130, 0xd184, 0x1170, 0x080c, 0x33aa, 0x0138, 0xc18d, + 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, + 0x0904, 0x7920, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, + 0x2019, 0x000e, 0x080c, 0xeba1, 0x0156, 0x00b6, 0x20a9, 0x007f, + 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, + 0x6724, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, + 0xec31, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8a50, 0x001e, + 0x8108, 0x1f04, 0x78e9, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, + 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x321b, 0x001e, + 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6724, + 0x1110, 0x080c, 0x6148, 0x8108, 0x1f04, 0x7916, 0x00be, 0x015e, + 0x080c, 0x1b06, 0x080c, 0xb244, 0x60e3, 0x0000, 0x080c, 0x612e, + 0x080c, 0x7563, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x2001, 0x197d, 0x2003, 0x0001, 0x0005, 0x2001, + 0x197d, 0x2003, 0x0000, 0x0005, 0x2001, 0x197c, 0x2003, 0xaaaa, + 0x0005, 0x2001, 0x197c, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, + 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1027, 0x090c, 0x0dc5, + 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1027, 0x090c, 0x0dc5, + 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, + 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, + 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, + 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, + 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, + 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, + 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, + 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, + 0x2102, 0x00d6, 0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, + 0x7f74, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, + 0x8003, 0x2011, 0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, + 0x0010, 0x81f5, 0x3e08, 0x1f04, 0x79a8, 0x015e, 0x0005, 0x2079, + 0x0040, 0x2071, 0x18fa, 0x7004, 0x0002, 0x79c7, 0x79c8, 0x7a00, + 0x7a5b, 0x7bbb, 0x79c5, 0x79c5, 0x7be5, 0x080c, 0x0dc5, 0x0005, + 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x8056, 0xd0a4, + 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, + 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, + 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x79f0, 0x79ca, 0x79f0, + 0x79ee, 0x79f0, 0x79f0, 0x79f0, 0x79f0, 0x79f0, 0x080c, 0x7a5b, + 0x782c, 0xd09c, 0x090c, 0x7f74, 0x0005, 0x9082, 0x005a, 0x1218, + 0x2100, 0x003b, 0x0c10, 0x080c, 0x7a91, 0x0c90, 0x00e3, 0x08e8, + 0x0005, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7ab3, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a9d, 0x7a91, 0x7cdb, + 0x7a91, 0x7a91, 0x7a91, 0x7ab3, 0x7a91, 0x7a9d, 0x7d1c, 0x7d5d, + 0x7da4, 0x7db8, 0x7a91, 0x7a91, 0x7ab3, 0x7a9d, 0x7ac7, 0x7a91, + 0x7b8f, 0x7e63, 0x7e7e, 0x7a91, 0x7ab3, 0x7a91, 0x7ac7, 0x7a91, + 0x7a91, 0x7b85, 0x7e7e, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7adb, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7a91, 0x7ffa, 0x7a91, + 0x7fa4, 0x7a91, 0x7fa4, 0x7a91, 0x7af0, 0x7a91, 0x7a91, 0x7a91, + 0x7a91, 0x7a91, 0x7a91, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, + 0x1198, 0x782c, 0x080c, 0x7f9d, 0xd0a4, 0x0170, 0x7824, 0x2048, + 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, + 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7f74, 0x0005, 0x7a91, + 0x7a9d, 0x7cc7, 0x7a91, 0x7a9d, 0x7a91, 0x7a9d, 0x7a9d, 0x7a91, + 0x7a9d, 0x7cc7, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a9d, 0x7a91, + 0x7a9d, 0x7cc7, 0x7a91, 0x7a91, 0x7a9d, 0x7a91, 0x7a91, 0x7a91, + 0x7a9d, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, + 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, + 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, + 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6e9f, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c64, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c64, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, + 0x0804, 0x7c7f, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, + 0x704b, 0x7c7f, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, + 0x7a99, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c9b, 0x7007, + 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c9b, 0x0005, + 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7a99, + 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1904, 0x7b5c, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x0904, 0x7b47, 0xa99c, 0x9186, + 0x00ff, 0x05e8, 0xa994, 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, + 0x15b0, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, 0x0578, + 0x0016, 0xa998, 0x080c, 0x6b11, 0x001e, 0x1548, 0x0400, 0x080c, + 0x7637, 0x0140, 0xa897, 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, + 0x900e, 0x0438, 0x0026, 0x2011, 0x8008, 0x080c, 0x6ac7, 0x002e, + 0x01b0, 0x0016, 0x0026, 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, + 0x8000, 0x080c, 0x6b11, 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, + 0x4005, 0xa89b, 0x4009, 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, + 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x63c5, 0x1108, + 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, + 0x080c, 0x6e9f, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, + 0x7b00, 0x9186, 0x0064, 0x0904, 0x7b00, 0x9186, 0x007c, 0x0904, + 0x7b00, 0x9186, 0x0028, 0x0904, 0x7b00, 0x9186, 0x0038, 0x0904, + 0x7b00, 0x9186, 0x0078, 0x0904, 0x7b00, 0x9186, 0x005f, 0x0904, + 0x7b00, 0x9186, 0x0056, 0x0904, 0x7b00, 0xa897, 0x4005, 0xa89b, + 0x0001, 0x2001, 0x0030, 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, + 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7e95, 0x2900, + 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, + 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, + 0x7aa1, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7aa1, 0x82ff, 0x1138, + 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c22, 0x0018, 0x9280, + 0x7c18, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c03, 0x080c, + 0x1027, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, + 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, + 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, + 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, + 0xa17a, 0x810b, 0xa17e, 0x080c, 0x10f8, 0xa06c, 0x908e, 0x0100, + 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, + 0x2048, 0x080c, 0x1040, 0x7014, 0x2048, 0x0804, 0x7aa1, 0x7020, + 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, + 0x711a, 0x0804, 0x7bbb, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, + 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7e95, 0x0804, 0x7c64, + 0x7c1a, 0x7c1e, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, + 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, + 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, + 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, + 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, + 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, + 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, + 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, + 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, + 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, + 0x1178, 0x080c, 0x61c2, 0x1108, 0x0005, 0x080c, 0x710b, 0x0126, + 0x2091, 0x8000, 0x080c, 0xd3ce, 0x080c, 0x6e9f, 0x012e, 0x0ca0, + 0x080c, 0xd7dc, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, + 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, + 0x0000, 0x080c, 0x6252, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, + 0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, + 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6327, 0x1138, + 0x0005, 0x9006, 0xa87a, 0x080c, 0x629f, 0x1108, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6e9f, 0x012e, 0x0cb0, + 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, + 0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, + 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, + 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, + 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, + 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, + 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, + 0x9005, 0x11d8, 0xa974, 0x080c, 0x6724, 0x11b8, 0x0066, 0xae80, + 0x080c, 0x6834, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, + 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6724, 0x1110, 0x080c, + 0x6934, 0x8108, 0x1f04, 0x7d04, 0x00ce, 0xa87c, 0xd084, 0x1120, + 0x080c, 0x1040, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x6e9f, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x6a9f, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184, + 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, + 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, + 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, + 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, + 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, + 0x6202, 0x012e, 0x0804, 0x7f5e, 0x012e, 0x0804, 0x7f58, 0x012e, + 0x0804, 0x7f52, 0x012e, 0x0804, 0x7f55, 0x0126, 0x2091, 0x8000, + 0x7007, 0x0001, 0x080c, 0x6a9f, 0x05e0, 0x2061, 0x1a74, 0x6000, + 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, + 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, + 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, + 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, + 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, + 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, + 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f5e, 0x012e, 0x0804, + 0x7f5b, 0x012e, 0x0804, 0x7f58, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, + 0x0220, 0x630a, 0x012e, 0x0804, 0x7f6c, 0x012e, 0x0804, 0x7f5b, + 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, + 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff, + 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, + 0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb306, + 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, + 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xb352, 0xa988, 0x918c, + 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, + 0x080c, 0x8a50, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74, + 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, + 0x012e, 0x00be, 0x0804, 0x7f5e, 0x00ce, 0x012e, 0x00be, 0x0804, + 0x7f58, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, + 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, + 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, + 0x0029, 0x1d10, 0xa974, 0x080c, 0x6724, 0x1968, 0xb800, 0xc0e4, + 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, + 0x1986, 0x2004, 0x601a, 0x0804, 0x7df3, 0xa88c, 0x9065, 0x0960, + 0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, + 0x080c, 0xb306, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb306, 0x00ee, + 0x0804, 0x7df3, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, + 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, + 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, + 0x00ee, 0x0804, 0x7df3, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190, + 0xd08c, 0x1904, 0x7f6c, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, + 0x0220, 0x6206, 0x012e, 0x0804, 0x7f6c, 0x012e, 0xa883, 0x0016, + 0x0804, 0x7f65, 0xa883, 0x0007, 0x0804, 0x7f65, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, + 0x0005, 0x080c, 0x7a99, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, + 0x7016, 0x701a, 0x704b, 0x7e95, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, + 0x7f17, 0x6130, 0xd194, 0x1904, 0x7f41, 0xa878, 0x2070, 0x9e82, + 0x1cd0, 0x0a04, 0x7f0b, 0x6068, 0x9e02, 0x1a04, 0x7f0b, 0x7120, + 0x9186, 0x0006, 0x1904, 0x7efd, 0x7010, 0x905d, 0x0904, 0x7f17, + 0xb800, 0xd0e4, 0x1904, 0x7f3b, 0x2061, 0x1a74, 0x6100, 0x9184, + 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f44, + 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, + 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f47, 0x080c, 0x57d5, 0xd09c, + 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8970, 0x012e, + 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, + 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f47, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f65, + 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6724, + 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, + 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, + 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, + 0x57d9, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, + 0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, + 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, + 0x9086, 0x0007, 0x1904, 0x7ea1, 0x7003, 0x0002, 0x0804, 0x7ea1, + 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, + 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, + 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe754, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, + 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, + 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6e9f, 0x012e, 0x0005, 0x080c, 0x1040, 0x0005, 0x00d6, + 0x080c, 0x8967, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, + 0x190c, 0x8056, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, + 0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, + 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, + 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, + 0x190c, 0x8056, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, + 0x080c, 0xb27d, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0035, 0x1138, 0x6008, 0xc0fd, 0x600a, 0x2001, 0x196b, + 0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, + 0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x2873, 0x1540, 0x00b6, + 0x080c, 0x6724, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, + 0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, + 0x2009, 0x0041, 0x080c, 0xb352, 0x0005, 0xa87b, 0x0101, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0005, 0xa87b, 0x002c, + 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x0005, 0xa87b, + 0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, 0x080c, + 0xb2d3, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, + 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x8047, 0xa97c, + 0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, + 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, + 0x080c, 0xb27d, 0x1118, 0x080c, 0xb325, 0x05a8, 0x6212, 0xa874, + 0x0002, 0x8025, 0x802a, 0x802d, 0x8033, 0x2019, 0x0002, 0x080c, + 0xeba1, 0x0060, 0x080c, 0xeb38, 0x0048, 0x2019, 0x0002, 0xa980, + 0x080c, 0xeb53, 0x0018, 0xa980, 0x080c, 0xeb38, 0x080c, 0xb2d3, + 0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, + 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, + 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, + 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, + 0x0e04, 0x8058, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, + 0x0dce, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, + 0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, + 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x15a0, 0x00fe, + 0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, + 0x0005, 0x781c, 0xd08c, 0x0904, 0x80d8, 0x68c0, 0x90aa, 0x0005, + 0x0a04, 0x871c, 0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, + 0x7000, 0x0140, 0x908a, 0x2000, 0x1260, 0x9584, 0x0700, 0x8007, + 0x0804, 0x80df, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, + 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, + 0x8100, 0x11c0, 0x080c, 0xf057, 0x080c, 0x8601, 0x7817, 0x0140, + 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x865f, 0x19c0, 0xd5a4, + 0x0148, 0x0046, 0x0056, 0x080c, 0x813a, 0x080c, 0x236e, 0x005e, + 0x004e, 0x0020, 0x080c, 0xf057, 0x7817, 0x0140, 0x080c, 0x7637, + 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, + 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, 0x080c, 0x811b, + 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, 0x0005, 0x0002, + 0x80f1, 0x8409, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, + 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, + 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, + 0x0fff, 0x6892, 0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, + 0x1118, 0x080c, 0x583f, 0x0070, 0x080c, 0x815a, 0x0058, 0x9286, + 0x3000, 0x1118, 0x080c, 0x8341, 0x0028, 0x9286, 0x8000, 0x1110, + 0x080c, 0x8528, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, + 0x090c, 0x9ab1, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, + 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, + 0x2011, 0x8048, 0x2518, 0x080c, 0x4c44, 0x003e, 0x002e, 0x0005, + 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, + 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, + 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, + 0x0160, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, + 0x2011, 0x8048, 0x080c, 0x4c44, 0x002e, 0x00fe, 0x005e, 0x004e, + 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, + 0x9096, 0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8312, 0x9186, + 0x0023, 0x15c0, 0x080c, 0x85c6, 0x0904, 0x8312, 0x6120, 0x9186, + 0x0001, 0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, + 0x9186, 0x000a, 0x1904, 0x8312, 0x7124, 0x610a, 0x7030, 0x908e, + 0x0200, 0x1130, 0x2009, 0x0015, 0x080c, 0xb352, 0x0804, 0x8312, + 0x908e, 0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, + 0x080c, 0xb352, 0x0804, 0x8312, 0x908e, 0x0100, 0x1904, 0x8312, + 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0016, 0x080c, 0xb352, + 0x0804, 0x8312, 0x9186, 0x0022, 0x1904, 0x8312, 0x7030, 0x908e, + 0x0300, 0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, + 0x918c, 0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, + 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, + 0x28bc, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2873, + 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, + 0x70b6, 0x00ee, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0017, + 0x0804, 0x82c2, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, + 0x8312, 0x080c, 0x7637, 0x0120, 0x2009, 0x001d, 0x0804, 0x82c2, + 0x68dc, 0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82c2, 0x908e, + 0x0500, 0x1140, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0018, + 0x0804, 0x82c2, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, + 0x82c2, 0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82c2, + 0x908e, 0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, + 0x001b, 0x0804, 0x82c2, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, + 0x1904, 0x8312, 0x2009, 0x001c, 0x0804, 0x82c2, 0x908e, 0x1300, + 0x1120, 0x2009, 0x0034, 0x0804, 0x82c2, 0x908e, 0x1200, 0x1140, + 0x7034, 0x9005, 0x1904, 0x8312, 0x2009, 0x0024, 0x0804, 0x82c2, + 0x908c, 0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, + 0x1810, 0x2004, 0xd09c, 0x0904, 0x82c2, 0x080c, 0xdf1a, 0x1904, + 0x8312, 0x0804, 0x82c0, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, + 0x2009, 0x002a, 0x0804, 0x82c2, 0x908e, 0x0f00, 0x1120, 0x2009, + 0x0020, 0x0804, 0x82c2, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, + 0x2011, 0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, + 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, + 0x4c44, 0x004e, 0x8108, 0x0f04, 0x8276, 0x9186, 0x0280, 0x1d88, + 0x2504, 0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, + 0x2009, 0x0023, 0x0804, 0x82c2, 0x908e, 0x6000, 0x1120, 0x2009, + 0x003f, 0x0804, 0x82c2, 0x908e, 0x5400, 0x1138, 0x080c, 0x86cc, + 0x1904, 0x8312, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, + 0x080c, 0x86f4, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, + 0x0448, 0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, + 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, + 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, + 0x2009, 0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, + 0x2009, 0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, + 0x2009, 0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x2873, 0x1904, 0x8315, 0x080c, 0x66b9, 0x1904, 0x8315, + 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c, 0x7637, 0x01c0, 0x68dc, + 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, + 0xff00, 0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, + 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, + 0x9005, 0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, + 0x6880, 0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, + 0xb27d, 0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, + 0x001e, 0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, + 0x080c, 0xb352, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, + 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, + 0x080c, 0xb325, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, + 0x610a, 0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, + 0x1128, 0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, + 0x6017, 0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x9547, + 0x08a0, 0x080c, 0x873b, 0x1158, 0x080c, 0x3374, 0x1140, 0x7010, + 0x9084, 0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, + 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, + 0x0033, 0x11e8, 0x080c, 0x85c6, 0x0904, 0x83a1, 0x7124, 0x610a, + 0x7030, 0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, + 0x0015, 0x080c, 0xb352, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, + 0x9005, 0x1578, 0x2009, 0x0016, 0x080c, 0xb352, 0x0450, 0x9186, + 0x0032, 0x1538, 0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, + 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, + 0x11b8, 0x080c, 0x66b9, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xb27d, + 0x0178, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0004, 0x7120, + 0x610a, 0x001e, 0x080c, 0xb352, 0x080c, 0x9ab1, 0x0010, 0x00ce, + 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, + 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, + 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x8403, + 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, 0x8403, 0x9596, + 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, + 0x1837, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, + 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, + 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, + 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, + 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, + 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, + 0x8420, 0x8e70, 0x1f04, 0x83d8, 0x82ff, 0x1118, 0x9085, 0x0001, + 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, + 0x0005, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, + 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x004a, + 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, + 0x0005, 0x8431, 0x8431, 0x8431, 0x85d8, 0x8431, 0x843a, 0x8465, + 0x84f3, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, 0x8431, + 0x8431, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, + 0x9ab1, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, + 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, + 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, + 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, + 0x0046, 0x080c, 0xb352, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, + 0x9005, 0x090c, 0x9ab1, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, + 0x0fff, 0x0904, 0x84c9, 0x7110, 0xd1bc, 0x1904, 0x84c9, 0x7108, + 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, + 0x81ff, 0x15a0, 0x9080, 0x33b6, 0x200d, 0x918c, 0xff00, 0x810f, + 0x2001, 0x0080, 0x9106, 0x0904, 0x84c9, 0x080c, 0x66b9, 0x1904, + 0x84c9, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, + 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c, 0xb27d, 0x05e8, 0x2b08, + 0x7028, 0x6046, 0x702c, 0x604a, 0x6112, 0x6023, 0x0006, 0x7120, + 0x610a, 0x7130, 0x6156, 0x2009, 0x0044, 0x080c, 0xe192, 0x0408, + 0x080c, 0x6aa3, 0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x83a5, + 0x11c0, 0x0898, 0x080c, 0xb27d, 0x2b08, 0x0198, 0x6112, 0x6023, + 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, + 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, + 0x9ab1, 0x7817, 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, + 0x9ab1, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, + 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, 0x080c, 0xb325, 0x0d48, + 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, + 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x08b0, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, + 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, + 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, + 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, + 0x2009, 0x0045, 0x080c, 0xb352, 0x7817, 0x0140, 0x2001, 0x19f1, + 0x2004, 0x9005, 0x090c, 0x9ab1, 0x00be, 0x0005, 0x6120, 0x9186, + 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, + 0x080c, 0x873b, 0x1180, 0x080c, 0x3374, 0x1168, 0x7010, 0x9084, + 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, + 0x0006, 0x1208, 0x000b, 0x0005, 0x8542, 0x8543, 0x8542, 0x8542, + 0x85a8, 0x85b7, 0x0005, 0x00b6, 0x700c, 0x7108, 0x080c, 0x2873, + 0x1904, 0x85a6, 0x080c, 0x66b9, 0x1904, 0x85a6, 0xbe12, 0xbd16, + 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, + 0x1904, 0x85a6, 0x080c, 0x6aa3, 0x0148, 0x9086, 0x0004, 0x0130, + 0x080c, 0x6aab, 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, + 0x85c6, 0x00ce, 0x05d8, 0x080c, 0xb27d, 0x2b08, 0x05b8, 0x6112, + 0x080c, 0xd554, 0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, + 0x080c, 0xb352, 0x0458, 0x080c, 0x6aa3, 0x0148, 0x9086, 0x0004, + 0x0130, 0x080c, 0x6aab, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, + 0xb27d, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xd554, 0x6023, 0x0005, + 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb352, 0x0078, 0x080c, + 0xb27d, 0x2b08, 0x0158, 0x6112, 0x080c, 0xd554, 0x6023, 0x0004, + 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xb352, 0x00be, 0x0005, + 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, 0x851e, 0x1130, + 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xb352, 0x0005, 0x7110, + 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x851e, 0x1130, 0x7124, + 0x610a, 0x2009, 0x008a, 0x080c, 0xb352, 0x0005, 0x7020, 0x2060, + 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, + 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, + 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, + 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, + 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, + 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c, 0xb352, 0x7817, + 0x0140, 0x2001, 0x19f1, 0x2004, 0x9005, 0x090c, 0x9ab1, 0x00be, + 0x0005, 0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, + 0x0005, 0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, + 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, + 0xc000, 0x05d0, 0x080c, 0xb27d, 0x05b8, 0x0066, 0x00c6, 0x0046, + 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, 0x15a0, + 0x080c, 0x66b9, 0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, + 0x6012, 0x080c, 0xd554, 0x080c, 0x100e, 0x0510, 0x2900, 0x605a, + 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, + 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, + 0x006e, 0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, + 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00fe, 0x009e, 0x00ce, 0x0005, + 0x080c, 0xb2d3, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, + 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, + 0x1904, 0x86b6, 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, + 0x9005, 0x1904, 0x86b8, 0x7030, 0x908e, 0x0400, 0x0904, 0x86b8, + 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, + 0x11d8, 0x2009, 0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, + 0x080c, 0x6a61, 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, + 0x00ff, 0x9106, 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, + 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, + 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, + 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x85c6, + 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, + 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, + 0x908e, 0x5200, 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, + 0x9086, 0x0008, 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, + 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x027a, 0x080c, 0xc365, 0x1178, + 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, + 0x080c, 0xc365, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, + 0x001e, 0x004e, 0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, + 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, + 0x0004, 0x2019, 0x1805, 0x2011, 0x0272, 0x080c, 0xc365, 0x1178, + 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, + 0x080c, 0xc365, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, + 0x001e, 0x004e, 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, + 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, + 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, + 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, + 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, + 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, + 0x0001, 0x0cd8, 0x2071, 0x19fb, 0x7003, 0x0003, 0x700f, 0x0361, + 0x9006, 0x701a, 0x707a, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, + 0x7026, 0x702b, 0xa6ff, 0x7032, 0x703a, 0x703f, 0x0064, 0x7037, + 0xa767, 0x7047, 0xffff, 0x704a, 0x704f, 0x5667, 0x7052, 0x7063, + 0x88de, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900, 0x7042, 0xa867, + 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19fb, + 0x1d04, 0x882c, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1540, + 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x894c, 0x2001, 0x1869, + 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, + 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0dc5, 0x700f, 0x0361, + 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c, 0x8923, 0x7048, + 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, + 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, + 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, + 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, + 0x900d, 0x05a8, 0x702c, 0x8001, 0x702e, 0x1588, 0x0016, 0x2009, + 0x0306, 0x210c, 0x9184, 0x0030, 0x01e8, 0x9184, 0x0048, 0x9086, + 0x0008, 0x11c0, 0x7038, 0x9005, 0x01a8, 0x8001, 0x703a, 0x1190, + 0x080c, 0x7637, 0x0178, 0x00e6, 0x2071, 0x19e8, 0x080c, 0xa7f5, + 0x00ee, 0x1140, 0x2009, 0x1a86, 0x2104, 0x8000, 0x0208, 0x200a, + 0x001e, 0x0068, 0x001e, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, + 0x9184, 0x007f, 0x090c, 0xa8ab, 0x0010, 0x7034, 0x080f, 0x7044, + 0x9005, 0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, + 0x7050, 0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, + 0x1120, 0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, + 0x0016, 0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, + 0x7077, 0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, + 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, + 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x8854, 0x8855, + 0x8871, 0x00e6, 0x2071, 0x19fb, 0x7018, 0x9005, 0x1120, 0x711a, + 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, + 0x19fb, 0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, + 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x19fb, 0xb888, 0x9102, + 0x0208, 0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, + 0x6724, 0x1168, 0xb888, 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, + 0x2091, 0x8000, 0x0016, 0x080c, 0x9ab1, 0x001e, 0x012e, 0x8108, + 0x9182, 0x0800, 0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, + 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, + 0x0128, 0x8001, 0x6042, 0x1110, 0x080c, 0xd3e5, 0x6018, 0x9005, + 0x0558, 0x8001, 0x601a, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, + 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, + 0x1100, 0x080c, 0xd0d8, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, + 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, + 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, + 0xd0e4, 0x0110, 0x080c, 0xcdbc, 0x012e, 0x9c88, 0x0018, 0x7116, + 0x2001, 0x181a, 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, + 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fb, 0x7027, 0x07d0, 0x7023, + 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a04, 0x2003, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x19fb, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, + 0x2011, 0x1a07, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fb, + 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, + 0x705c, 0x8000, 0x705e, 0x2001, 0x1a0b, 0x2044, 0xa06c, 0x9086, + 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, + 0x7064, 0xa08e, 0x080c, 0x10f8, 0x002e, 0x008e, 0x0005, 0x0006, + 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x0156, 0x080c, 0x8776, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, + 0x19fb, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x2071, 0x19fb, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, + 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69e8, 0xd1e4, 0x1518, + 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, + 0x9294, 0x00c0, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, + 0x0007, 0x0110, 0x69ea, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, + 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68ea, + 0x080c, 0x0eee, 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, + 0x210d, 0x2061, 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, + 0xfff4, 0x200f, 0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, + 0x001e, 0x0005, 0x00c6, 0x2061, 0x1a74, 0x00ce, 0x0005, 0x9184, + 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a74, 0x2060, 0x0005, + 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, + 0x1a74, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, + 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, + 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x89fa, 0xd0b4, + 0x1168, 0xd0bc, 0x1904, 0x89d3, 0x2009, 0x0006, 0x080c, 0x8a27, + 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, + 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8a21, 0x908c, + 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, + 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, + 0x0804, 0xb352, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, + 0xb352, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, + 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, + 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, + 0x918e, 0x0003, 0x1904, 0x8a21, 0x908c, 0x2020, 0x918e, 0x2020, + 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x007e, + 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xb352, 0x0005, 0x6110, + 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, + 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, + 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, + 0x2009, 0x0041, 0x080c, 0xb352, 0x0005, 0x00b9, 0x0ce8, 0x87ff, + 0x1dd8, 0x2009, 0x0043, 0x080c, 0xb352, 0x0cb0, 0x6110, 0x00b6, + 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, + 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, + 0x080c, 0xd0d8, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, + 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, + 0x1158, 0x00c6, 0x2061, 0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, + 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6cde, 0x6014, 0x904d, + 0x0076, 0x2039, 0x0000, 0x190c, 0x8970, 0x007e, 0x009e, 0x0005, + 0x0156, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, + 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, + 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, + 0x0005, 0x2071, 0x1924, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, + 0x0000, 0x7013, 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa867, + 0x0006, 0xa86b, 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, + 0x702e, 0x7033, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, + 0x00e6, 0x2071, 0x1924, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, + 0x7322, 0x6834, 0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, + 0x7016, 0x683c, 0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, + 0x900e, 0x9188, 0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, + 0x8318, 0xaa8e, 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, + 0x0001, 0x700f, 0x0000, 0x0006, 0x2009, 0x1ad1, 0x2104, 0x9082, + 0x0007, 0x200a, 0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, + 0x080c, 0x1611, 0x9006, 0x2071, 0x193d, 0x7002, 0x7006, 0x702a, + 0x00ee, 0x009e, 0x012e, 0x0005, 0x2009, 0x1ad1, 0x2104, 0x9080, + 0x0007, 0x200a, 0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, + 0x2071, 0x1800, 0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, + 0x187d, 0x20ac, 0x9006, 0x9080, 0x0008, 0x1f04, 0x8ae3, 0x71c0, + 0x9102, 0x02e0, 0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, + 0xb27d, 0x6023, 0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, + 0x0126, 0x2091, 0x8000, 0x080c, 0x8c61, 0x012e, 0x1f04, 0x8aef, + 0x9006, 0x00ce, 0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, + 0x0cc8, 0x00e6, 0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, + 0x7118, 0x720c, 0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, + 0x2029, 0x0002, 0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, + 0x100e, 0x090c, 0x0dc5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, + 0xa802, 0xa806, 0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, + 0x0020, 0x7008, 0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, + 0xa8b3, 0x0000, 0x8109, 0x0160, 0x080c, 0x100e, 0x090c, 0x0dc5, + 0xad66, 0x2b00, 0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, + 0x002e, 0x004e, 0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, + 0x2079, 0x0000, 0x2071, 0x1924, 0x7004, 0x004b, 0x700c, 0x0002, + 0x8b5b, 0x8b54, 0x8b54, 0x0005, 0x8b65, 0x8bbb, 0x8bbb, 0x8bbb, + 0x8bbc, 0x8bcd, 0x8bcd, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, + 0x78a0, 0x79a0, 0x9106, 0x1904, 0x8bad, 0x7814, 0xd0bc, 0x1904, + 0x8bb6, 0x012e, 0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, + 0x8bff, 0x0005, 0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, + 0x2009, 0x000a, 0x2001, 0x1888, 0x2014, 0x2001, 0x1936, 0x2004, + 0x9100, 0x9202, 0x0e50, 0x080c, 0x8d5c, 0x2200, 0x9102, 0x0208, + 0x2208, 0x0096, 0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, + 0x8e65, 0x2100, 0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, + 0x8000, 0x2009, 0x1a1b, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, + 0x012e, 0x080c, 0x1117, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, + 0x0904, 0x8b6d, 0x080c, 0x8d34, 0x012e, 0x0005, 0x7810, 0xc0c5, + 0x7812, 0x0804, 0x8b6d, 0x0005, 0x700c, 0x0002, 0x8bc1, 0x8bc4, + 0x8bc3, 0x080c, 0x8b63, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, + 0x2048, 0xa974, 0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, + 0x2048, 0x7018, 0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, + 0x7020, 0xa892, 0x9006, 0x0068, 0x0006, 0x080c, 0x8e65, 0x2100, + 0xaa8c, 0x9210, 0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, + 0x000e, 0x009e, 0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, + 0x8d34, 0x012e, 0x0005, 0x00e6, 0x2071, 0x1924, 0x700c, 0x0002, + 0x8bfd, 0x8bfd, 0x8bfb, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, + 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8c6a, 0x00be, 0x01b0, + 0x00e6, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x00ee, 0x0178, 0x0096, + 0x080c, 0x1027, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, + 0x2001, 0x1947, 0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, + 0x00d6, 0x00c6, 0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, + 0x0180, 0xa864, 0x9084, 0x000f, 0x2068, 0x9d88, 0x20c7, 0x2165, + 0x0056, 0x2029, 0x0000, 0x080c, 0x8dea, 0x080c, 0x207f, 0x1dd8, + 0x005e, 0x00ae, 0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1768, + 0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8cc0, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, + 0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1947, 0x2003, 0x0001, + 0x0005, 0x00e6, 0x2071, 0x1924, 0x7030, 0x600e, 0x2c00, 0x7032, + 0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8f33, 0x2005, + 0x906d, 0x090c, 0x0dc5, 0x9b80, 0x8f2b, 0x2005, 0x9065, 0x090c, + 0x0dc5, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, + 0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, + 0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, + 0x080c, 0x4c44, 0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa804, + 0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, + 0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c44, 0x684c, + 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa800, 0x8000, 0xa802, 0x009e, + 0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, + 0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, + 0x00d6, 0x7814, 0x9005, 0x090c, 0x0dc5, 0x781c, 0x9084, 0x0101, + 0x9086, 0x0101, 0x190c, 0x0dc5, 0x7827, 0x0000, 0x2069, 0x193d, + 0x6804, 0x9080, 0x193f, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, + 0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x193f, 0x2003, 0x0000, + 0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, + 0x0096, 0x2048, 0x9005, 0x190c, 0x1040, 0x009e, 0xa8ab, 0x0000, + 0x080c, 0x0fc0, 0x080c, 0xb2d3, 0x00ce, 0x009e, 0x0005, 0x6020, + 0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, + 0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, + 0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x9067, 0x00be, 0x6013, + 0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, + 0x1928, 0x210c, 0xd194, 0x0005, 0x2009, 0x1928, 0x210c, 0xd1c4, + 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1924, 0x7110, + 0xc194, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, + 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, + 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, + 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, + 0x0000, 0x080c, 0x8eb3, 0x0170, 0x080c, 0x8ee8, 0x0158, 0x2900, + 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, + 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, + 0x00c6, 0x2071, 0x1931, 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, + 0x8ee8, 0x090c, 0x0dc5, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, + 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, + 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, + 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, + 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, + 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x1931, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, + 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, + 0x8e65, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, + 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, + 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8e6e, 0x2130, 0x7014, + 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, + 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, + 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8d5c, 0x002e, 0x7000, + 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, + 0x9212, 0x1904, 0x8d9b, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, + 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x9580, 0x8f2b, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x080c, 0x8e40, + 0x012e, 0x9580, 0x8f27, 0x2005, 0x9075, 0x090c, 0x0dc5, 0x0156, + 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, + 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, + 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, + 0x2d00, 0x0002, 0x8e2a, 0x8e2a, 0x8e2c, 0x8e2a, 0x8e2c, 0x8e2a, + 0x8e2a, 0x8e2a, 0x8e2a, 0x8e2a, 0x8e32, 0x8e2a, 0x8e32, 0x8e2a, + 0x8e2a, 0x8e2a, 0x080c, 0x0dc5, 0x4104, 0x20a9, 0x0002, 0x4002, + 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, + 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, + 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, + 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, + 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8ef7, 0x009e, + 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, + 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, + 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, + 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, + 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, + 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8eb1, 0x901e, 0x6808, 0x9005, + 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, + 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, + 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, + 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, + 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, + 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, + 0x2b00, 0x9080, 0x8f2f, 0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, + 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0, 0x2900, 0x7026, 0xa803, + 0x0000, 0xa807, 0x0000, 0x080c, 0x1027, 0x0188, 0x7024, 0xa802, + 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, + 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, + 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1040, 0x2400, 0x0cc0, + 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, + 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, + 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, + 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, + 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, + 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1040, + 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, + 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a67, + 0x0000, 0x0000, 0x0000, 0x1931, 0x0000, 0x0000, 0x0000, 0x1888, + 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, + 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, + 0x9053, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x9028, 0xb814, + 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, + 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, + 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, + 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, + 0x908c, 0x000f, 0x91e0, 0x20c7, 0x2c65, 0x9786, 0x0024, 0x2c05, + 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, + 0x8f93, 0x8f93, 0x8f95, 0x8f93, 0x8f93, 0x8f93, 0x8f97, 0x8f93, + 0x8f93, 0x8f93, 0x8f99, 0x8f93, 0x8f93, 0x8f93, 0x8f9b, 0x8f93, + 0x8f93, 0x8f93, 0x8f9d, 0x8f93, 0x8f93, 0x8f93, 0x8f9f, 0x8f93, + 0x8f93, 0x8f93, 0x8fa1, 0x080c, 0x0dc5, 0xa180, 0x04b8, 0xa190, + 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, + 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, + 0x001b, 0x0002, 0x8fc5, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, + 0x8fc7, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc9, 0x8fc3, + 0x8fc3, 0x8fc3, 0x8fc3, 0x8fc3, 0x8fcb, 0x8fc3, 0x8fc3, 0x8fc3, + 0x8fc3, 0x8fc3, 0x8fcd, 0x080c, 0x0dc5, 0xa180, 0x0038, 0xa198, + 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, + 0x8fe9, 0x8feb, 0x8fed, 0x8fef, 0x8ff1, 0x8ff3, 0x8ff5, 0x8ff7, + 0x8ff9, 0x8ffb, 0x8ffd, 0x8fff, 0x9001, 0x9003, 0x9005, 0x9007, + 0x9009, 0x900b, 0x900d, 0x900f, 0x9011, 0x9013, 0x9015, 0x9017, + 0x9019, 0x080c, 0x0dc5, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, + 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, + 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, + 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, + 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, + 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, + 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x207f, 0x090c, + 0x0dc5, 0x0804, 0x8f6d, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, + 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, + 0x8f4f, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, + 0x01b0, 0x2001, 0x1925, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, + 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, + 0x0004, 0x2011, 0x8014, 0x080c, 0x4c44, 0x004e, 0x003e, 0x00be, + 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, + 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0230, 0x0128, 0x7010, + 0x8210, 0x910a, 0x0208, 0x1de0, 0xaa8a, 0xa26a, 0x0005, 0x00f6, + 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, + 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, + 0xb8ac, 0x906d, 0x0198, 0x2079, 0x0000, 0x9c1e, 0x1118, 0x680c, + 0xb8ae, 0x0050, 0x9c06, 0x0130, 0x2d78, 0x680c, 0x906d, 0x1dd0, + 0x080c, 0x0dc5, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, + 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, + 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, + 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, + 0x1f04, 0x90a3, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, + 0x1d90, 0xb8ac, 0x9065, 0x01f0, 0x600c, 0xb8ae, 0x6024, 0xc08d, + 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, + 0x0101, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa88b, 0x0000, 0xa8a8, + 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, + 0x8c61, 0x08f8, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, + 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, + 0x0016, 0x0006, 0x0156, 0x080c, 0x2873, 0x015e, 0x11b0, 0x080c, + 0x66b9, 0x190c, 0x0dc5, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, + 0xb27d, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, + 0x080c, 0xb352, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, + 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, + 0x0005, 0x9119, 0x9119, 0x9119, 0x911b, 0x916c, 0x9119, 0x9119, + 0x9119, 0x91e6, 0x9119, 0x9223, 0x9119, 0x9119, 0x9119, 0x9119, + 0x9119, 0x080c, 0x0dc5, 0x9182, 0x0040, 0x0002, 0x912e, 0x912e, + 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x912e, 0x9130, + 0x9145, 0x912e, 0x912e, 0x912e, 0x912e, 0x9158, 0x080c, 0x0dc5, + 0x0096, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, 0x2148, 0xa87b, + 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, + 0x6ca3, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x080c, 0x9a61, 0x00d6, + 0x6114, 0x080c, 0xd0d8, 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, + 0x6e9f, 0x009e, 0x00de, 0x080c, 0xb2d3, 0x080c, 0x9bd3, 0x0005, + 0x080c, 0x9a61, 0x080c, 0x3250, 0x6114, 0x0096, 0x2148, 0x080c, + 0xd0d8, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, 0x080c, + 0xb2d3, 0x080c, 0x9bd3, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, + 0x0096, 0x0002, 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, + 0x9187, 0x9187, 0x9189, 0x9187, 0x9187, 0x9187, 0x91e2, 0x9187, + 0x9187, 0x9187, 0x9187, 0x9187, 0x9187, 0x9190, 0x9187, 0x080c, + 0x0dc5, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x91e2, + 0x6024, 0xd08c, 0x15d8, 0x080c, 0x8d17, 0x05e0, 0x00e6, 0x6114, + 0x2148, 0x080c, 0x8f37, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6c3b, + 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, + 0x080c, 0x9067, 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, + 0x8c6a, 0x00be, 0x01e0, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x01b8, + 0x9086, 0x0001, 0x1128, 0x2001, 0x1947, 0x2004, 0x9005, 0x1178, + 0x0096, 0x080c, 0x100e, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, + 0x2c78, 0x080c, 0x8c28, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, + 0x8c61, 0x0cd0, 0x080c, 0x8d1c, 0x1160, 0x6010, 0x9005, 0x0130, + 0x2058, 0xb8ac, 0x9005, 0x190c, 0x0dc5, 0x6012, 0x2c00, 0x080c, + 0x8ce2, 0x0005, 0x080c, 0x9290, 0x009e, 0x0005, 0x9182, 0x0040, + 0x0096, 0x0002, 0x91fa, 0x91fa, 0x91fa, 0x91fc, 0x91fa, 0x91fa, + 0x91fa, 0x9221, 0x91fa, 0x91fa, 0x91fa, 0x91fa, 0x91fa, 0x91fa, + 0x91fa, 0x91fa, 0x080c, 0x0dc5, 0x6003, 0x0003, 0x6106, 0x6014, + 0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837, 0x0000, 0xa83b, + 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, + 0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c, 0x1be0, 0x080c, + 0x9564, 0x0126, 0x2091, 0x8000, 0x080c, 0x9bd3, 0x012e, 0x009e, + 0x0005, 0x080c, 0x0dc5, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, + 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, + 0x00be, 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005, + 0x9250, 0x9250, 0x9250, 0x9252, 0x9263, 0x9250, 0x9250, 0x9250, + 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, 0x9250, + 0x080c, 0x0dc5, 0x080c, 0xac2b, 0x6114, 0x2148, 0xa87b, 0x0006, + 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6e9f, + 0x080c, 0xb2d3, 0x0005, 0x0461, 0x0005, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0dc5, 0x0096, 0x0013, 0x009e, 0x0005, 0x927e, 0x927e, + 0x927e, 0x9280, 0x9290, 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, + 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, 0x927e, 0x080c, 0x0dc5, + 0x0036, 0x00e6, 0x2071, 0x19e8, 0x703c, 0x9c06, 0x1120, 0x2019, + 0x0000, 0x080c, 0xaa49, 0x080c, 0xac2b, 0x00ee, 0x003e, 0x0005, + 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014, + 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x9067, + 0x00be, 0x2071, 0x193d, 0x080c, 0x8cb1, 0x0160, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8c28, 0x00ee, + 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c, + 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8c61, 0x0c80, 0x2001, + 0x1925, 0x200c, 0x918e, 0x0000, 0x190c, 0x8d17, 0x05c8, 0x00e6, + 0x2071, 0x1924, 0x7110, 0xc1c5, 0x7112, 0x080c, 0x8d21, 0x00f6, + 0x00c6, 0x2071, 0x1000, 0x00b6, 0x2e04, 0x905d, 0x0138, 0xb8ac, + 0x9065, 0x0120, 0x080c, 0x8cf7, 0x090c, 0x9096, 0x8e70, 0x9e86, + 0x1800, 0x1d90, 0x00be, 0x00d6, 0x0096, 0x0046, 0x2061, 0x1cd0, + 0x2001, 0x181a, 0x2024, 0x6020, 0x9086, 0x0000, 0x1191, 0x9ce0, + 0x0018, 0x2400, 0x9c06, 0x1db8, 0x004e, 0x009e, 0x00de, 0x00d1, + 0x00ce, 0x00fe, 0x2071, 0x1924, 0x7110, 0xc1c4, 0x7112, 0x00ee, + 0x0005, 0x6020, 0x9086, 0x0009, 0x1160, 0x6100, 0x9186, 0x0004, + 0x1138, 0x6110, 0x81ff, 0x190c, 0x0dc5, 0x2c00, 0x080c, 0x8ce2, + 0x9006, 0x0005, 0x2071, 0x193f, 0x2073, 0x0000, 0x8e70, 0x9e86, + 0x1947, 0x1dd0, 0x2071, 0x193d, 0x7006, 0x7002, 0x2001, 0x1930, + 0x2064, 0x8cff, 0x0130, 0x6120, 0x918e, 0x0000, 0x190c, 0x0dc5, + 0x2102, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0148, 0x0096, 0x2148, + 0x080c, 0x1040, 0x009e, 0x2001, 0x188a, 0x2003, 0x0000, 0x2071, + 0x1931, 0x080c, 0x8f00, 0x0804, 0x8f0f, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, + 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, 0x2019, 0x0100, + 0x231c, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, + 0x3e00, 0x81f6, 0x3e08, 0x1208, 0x9200, 0x1f04, 0x9356, 0x93a6, + 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, + 0x3e08, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x0510, 0x911a, 0x1600, + 0x8213, 0x2039, 0x0100, 0x273c, 0x97be, 0x0008, 0x1110, 0x818d, + 0x0010, 0x81f5, 0x3e08, 0x0228, 0x911a, 0x1220, 0x1f04, 0x9380, + 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x9380, 0x0006, 0x3200, + 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, + 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, + 0x2079, 0x19e8, 0x012e, 0x00d6, 0x2069, 0x19e8, 0x6803, 0x0005, + 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, + 0xaf8e, 0x0401, 0x080c, 0xaf79, 0x00e9, 0x080c, 0xaf7c, 0x00d1, + 0x080c, 0xaf7f, 0x00b9, 0x080c, 0xaf82, 0x00a1, 0x080c, 0xaf85, + 0x0089, 0x080c, 0xaf88, 0x0071, 0x080c, 0xaf8b, 0x0059, 0x01de, + 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, + 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, + 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, + 0x0002, 0x93f3, 0x9417, 0x9458, 0x93f9, 0x9417, 0x93f3, 0x93f1, + 0x93f1, 0x080c, 0x0dc5, 0x080c, 0x88c3, 0x080c, 0x9ab1, 0x00ce, + 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5f97, + 0x080c, 0x883d, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, + 0x080c, 0x5fd7, 0x0c88, 0x62c0, 0x080c, 0xb0ca, 0x080c, 0x5f97, + 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, + 0x88c3, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, + 0x7824, 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb352, + 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x7828, + 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x2bce, + 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0dc5, + 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x9ab1, 0x0c00, + 0x080c, 0xa6c5, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0xb0ca, + 0x080c, 0xf094, 0x2009, 0x0014, 0x080c, 0xb352, 0x00ce, 0x0880, + 0x2001, 0x1a04, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, + 0x0000, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, + 0xb3a4, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, + 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, + 0x00de, 0x00ce, 0x00be, 0x080c, 0x2bce, 0x02f0, 0x00b6, 0x00c6, + 0x00d6, 0x781c, 0x905d, 0x090c, 0x0dc5, 0xb800, 0xc0dc, 0xb802, + 0x7924, 0x2160, 0x080c, 0xb2d3, 0xb93c, 0x81ff, 0x090c, 0x0dc5, + 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, + 0x00be, 0x080c, 0x9ab1, 0x0868, 0x080c, 0xa6c5, 0x0850, 0x2011, + 0x0130, 0x2214, 0x080c, 0xb0ca, 0x080c, 0xf094, 0x7824, 0x9065, + 0x2009, 0x0014, 0x080c, 0xb352, 0x00de, 0x00ce, 0x00be, 0x0804, + 0x9469, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1eeb, + 0x6024, 0x6027, 0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4, 0x9205, + 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xb352, + 0x00ce, 0x0005, 0x2011, 0x1a07, 0x2013, 0x0000, 0x0cc8, 0x793c, + 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x1628, 0x8108, 0x7946, + 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x793c, 0x9188, + 0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, + 0x9085, 0x0016, 0x6016, 0x08a0, 0x793c, 0x2160, 0x2009, 0x004a, + 0x080c, 0xb352, 0x0868, 0x7848, 0xc085, 0x784a, 0x0848, 0x0006, + 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, + 0x2061, 0x19e8, 0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, + 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, + 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19e8, 0xb800, + 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, + 0x2b00, 0x681e, 0x00de, 0x0804, 0x9ab1, 0x00de, 0x0005, 0xc0d5, + 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, 0x0086, + 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, 0x19e8, + 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, 0x0006, + 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, + 0x2061, 0x19e8, 0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, + 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, + 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, + 0x2061, 0x19e8, 0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, + 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, + 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e8, + 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x95f3, + 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x95ee, 0x87ff, 0x0120, + 0x6054, 0x9106, 0x1904, 0x95ee, 0x703c, 0x9c06, 0x1178, 0x0036, + 0x2019, 0x0001, 0x080c, 0xaa49, 0x7033, 0x0000, 0x9006, 0x703e, + 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, + 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x080c, 0xd0d8, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, + 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0xac1b, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd3ce, + 0x080c, 0xef85, 0x080c, 0x6e9f, 0x007e, 0x003e, 0x001e, 0x080c, + 0xd2c3, 0x080c, 0xb306, 0x00ce, 0x0804, 0x958d, 0x2c78, 0x600c, + 0x2060, 0x0804, 0x958d, 0x85ff, 0x0120, 0x0036, 0x080c, 0x9bd3, + 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, + 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, + 0xef85, 0x080c, 0xebd4, 0x007e, 0x003e, 0x001e, 0x0890, 0x6020, + 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, + 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x007e, 0x003e, 0x001e, 0x0818, + 0x6020, 0x9086, 0x000a, 0x0904, 0x95d8, 0x0804, 0x95d1, 0x0006, + 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, + 0x8000, 0x2079, 0x19e8, 0x7838, 0x9065, 0x0904, 0x9684, 0x600c, + 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, + 0x0001, 0x080c, 0xaa49, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, + 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xd0d8, 0x0548, 0x6014, 0x2048, + 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, + 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1988, 0x2004, 0x6042, + 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0xac1b, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e92, 0x080c, 0xd2c3, 0x080c, + 0xb306, 0x000e, 0x0804, 0x963c, 0x7e3a, 0x7e36, 0x012e, 0x00fe, + 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c50, 0x6020, 0x9086, 0x0009, + 0x1130, 0xab7a, 0x080c, 0x6e9f, 0x080c, 0xb2d3, 0x0c10, 0x6020, + 0x9086, 0x000a, 0x09a8, 0x0868, 0x0016, 0x0026, 0x0086, 0x9046, + 0x0099, 0x080c, 0x978f, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, + 0x0126, 0x2079, 0x19e8, 0x2091, 0x8000, 0x080c, 0x9826, 0x080c, + 0x98b6, 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, + 0x2071, 0x19e8, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9754, + 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x974f, 0x88ff, 0x0120, + 0x6054, 0x9106, 0x1904, 0x974f, 0x7024, 0x9c06, 0x1568, 0x2069, + 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88c3, + 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, + 0x0009, 0x630a, 0x0804, 0x974f, 0x7014, 0x9c36, 0x1110, 0x660c, + 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, + 0x080c, 0xd0d8, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, + 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0098, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xd3ce, 0x080c, + 0xef85, 0x080c, 0x6e9f, 0x008e, 0x003e, 0x001e, 0x080c, 0xd2c3, + 0x080c, 0xb306, 0x080c, 0xaaf1, 0x00ce, 0x0804, 0x96cd, 0x2c78, + 0x600c, 0x2060, 0x0804, 0x96cd, 0x012e, 0x000e, 0x001e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, + 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xef85, + 0x080c, 0xebd4, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xbcb6, + 0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, + 0x000e, 0x0904, 0x9735, 0x9086, 0x008b, 0x0904, 0x9735, 0x0840, + 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, + 0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x9748, 0x00b6, + 0x00a6, 0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, + 0x1000, 0x2004, 0x905d, 0x0904, 0x981f, 0x00f6, 0x00e6, 0x00d6, + 0x0066, 0x2071, 0x19e8, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, + 0x701c, 0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, + 0x761e, 0xb858, 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, + 0x2900, 0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, + 0xc0dc, 0xb802, 0x080c, 0x664c, 0x0904, 0x981b, 0x7624, 0x86ff, + 0x0904, 0x980a, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, + 0x2069, 0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x88c3, 0x080c, + 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, + 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, + 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xb306, 0x00ce, + 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, + 0x0804, 0x97c2, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x080c, 0xd3ce, 0x080c, 0xef85, 0x080c, 0x6e9f, 0x080c, + 0xaaf1, 0x0804, 0x97c2, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, + 0x000e, 0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, + 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x9889, + 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, + 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88c3, + 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7827, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, + 0x6a3b, 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, + 0x2048, 0x080c, 0xd0d6, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, + 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0060, 0x080c, 0x6a3b, + 0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, + 0x080c, 0xd2c3, 0x080c, 0xb306, 0x080c, 0xaaf1, 0x000e, 0x0804, + 0x982d, 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c50, + 0x080c, 0xbcb6, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, + 0x9086, 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, + 0x6020, 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, + 0x000e, 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, + 0x0096, 0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x9936, + 0xb854, 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, + 0xb802, 0x080c, 0x664c, 0x0904, 0x9933, 0x7e24, 0x86ff, 0x0904, + 0x9926, 0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x9926, 0x00d6, + 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x991d, 0x080c, 0x88c3, + 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7827, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, + 0x3e08, 0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, + 0x0010, 0x200c, 0x81ff, 0x1518, 0x2009, 0x1988, 0x210c, 0x2102, + 0x00f0, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, + 0x0000, 0x080c, 0xb306, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, + 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x98c9, 0x89ff, 0x0138, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x080c, + 0xaaf1, 0x0804, 0x98c9, 0x000e, 0x0804, 0x98bd, 0x781e, 0x781a, + 0x00de, 0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, + 0x00d6, 0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, + 0x0188, 0xa878, 0x9606, 0x1170, 0x2071, 0x19e8, 0x7024, 0x9035, + 0x0148, 0x9080, 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, + 0xb802, 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, + 0x2079, 0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, + 0x0009, 0x630a, 0x00ce, 0x04b8, 0x080c, 0xa6e9, 0x78c3, 0x0000, + 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, + 0x080c, 0x2d39, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, + 0x0001, 0x080c, 0xac1b, 0x003e, 0x080c, 0x664c, 0x00c6, 0xb83c, + 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xb2d3, 0x00ce, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd3ce, 0x080c, + 0x6e9f, 0x080c, 0xaaf1, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, + 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, + 0xc2e4, 0x2202, 0x2071, 0x19e8, 0x7004, 0x9084, 0x0007, 0x0002, + 0x99c2, 0x99c6, 0x99e4, 0x9a0d, 0x9a4b, 0x99c2, 0x99dd, 0x99c0, + 0x080c, 0x0dc5, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, + 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, + 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, + 0x0000, 0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x664c, + 0xb800, 0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, + 0x8001, 0x7022, 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, + 0x00ce, 0x00ee, 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, + 0x080c, 0x9ab1, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x9ab1, 0x0c80, + 0xc2ec, 0x2202, 0x080c, 0x9bd3, 0x0c58, 0x7024, 0x9065, 0x05b8, + 0x700c, 0x9c06, 0x1160, 0x080c, 0xaaf1, 0x600c, 0x9015, 0x0120, + 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, + 0x9c06, 0x1160, 0x080c, 0xaaf1, 0x600c, 0x9015, 0x0120, 0x7216, + 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, + 0x0003, 0x1198, 0x6010, 0x2058, 0x080c, 0x664c, 0xb800, 0xc0dc, + 0xb802, 0x080c, 0xaaf1, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, + 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, + 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0xaaf1, + 0x600c, 0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0xac1b, + 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, + 0x0ca8, 0x00d6, 0x2069, 0x19e8, 0x6830, 0x9084, 0x0003, 0x0002, + 0x9a6e, 0x9a70, 0x9a94, 0x9a6c, 0x080c, 0x0dc5, 0x00de, 0x0005, + 0x00c6, 0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, + 0x600c, 0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, + 0x683f, 0x0000, 0x2011, 0x1a07, 0x2013, 0x0000, 0x00ce, 0x00de, + 0x0005, 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, + 0x0d68, 0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, + 0x684a, 0x683c, 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, + 0x600f, 0x0000, 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, + 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, + 0x0005, 0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, + 0x080c, 0x9bd3, 0x2001, 0x19f4, 0x2004, 0x9086, 0x0001, 0x0d58, + 0x00d6, 0x2069, 0x19e8, 0x6804, 0x9084, 0x0007, 0x0006, 0x9005, + 0x11c8, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1198, 0x2001, + 0x197c, 0x2004, 0x9086, 0xaaaa, 0x0168, 0x2001, 0x188b, 0x2004, + 0xd08c, 0x1118, 0xd084, 0x1118, 0x0028, 0x080c, 0x9bd3, 0x000e, + 0x00de, 0x0005, 0x000e, 0x0002, 0x9aee, 0x9ba7, 0x9ba7, 0x9ba7, + 0x9ba7, 0x9ba9, 0x9ba7, 0x9aec, 0x080c, 0x0dc5, 0x6820, 0x9005, + 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065, 0x01f0, 0x6104, + 0x918e, 0x0040, 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, + 0x1150, 0x080c, 0x7637, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, + 0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, + 0x080c, 0x9c7c, 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, + 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x9c7c, 0x00ce, + 0x00de, 0x0005, 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, + 0x9b91, 0xb84c, 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, + 0x905d, 0x0120, 0x920e, 0x0904, 0x9b91, 0x0028, 0x6818, 0x920e, + 0x0904, 0x9b91, 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, + 0x1d70, 0x2b00, 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, + 0xb2aa, 0x0904, 0x9b91, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, + 0x0096, 0x2148, 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, + 0xa884, 0x009e, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, + 0x801b, 0x831b, 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, + 0x009e, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, + 0x2061, 0x0100, 0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, + 0x080c, 0xa219, 0x2069, 0x19e8, 0xbb00, 0xc3dd, 0xbb02, 0x6807, + 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, + 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, + 0x0005, 0x00ee, 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, + 0x6b26, 0x6820, 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x664c, + 0x080c, 0xb0ea, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, + 0x0005, 0x00c6, 0x680c, 0x9065, 0x01d8, 0x6104, 0x918e, 0x0040, + 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, + 0x7637, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, + 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9c7c, + 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, + 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e8, 0x6830, + 0x9086, 0x0000, 0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, + 0xc2e4, 0x2202, 0x080c, 0x9ac0, 0x2069, 0x19e8, 0x2001, 0x180c, + 0x200c, 0xd1c4, 0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, + 0x0000, 0x1904, 0x9c70, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, + 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, + 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x1158, 0x012e, 0x080c, + 0xa546, 0x00de, 0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x76e4, + 0x08d0, 0x012e, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, + 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, + 0x0c40, 0x683a, 0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198, 0x6833, + 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, + 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x19d8, 0x012e, 0x080c, + 0xa4c7, 0x0878, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, + 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19e9, + 0x2004, 0x9005, 0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, + 0x2102, 0x2f00, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, + 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, + 0x1904, 0x9c11, 0x012e, 0x6a3c, 0x2278, 0x080c, 0xa451, 0x0804, + 0x9c09, 0x2011, 0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x9c09, + 0x6a04, 0x9296, 0x0006, 0x1904, 0x9bcb, 0x6a30, 0x9296, 0x0000, + 0x0904, 0x9bf3, 0x0804, 0x9bcb, 0x6020, 0x9084, 0x000f, 0x000b, + 0x0005, 0x9c90, 0x9c95, 0xa149, 0xa1e2, 0x9c95, 0xa149, 0xa1e2, + 0x9c90, 0x9c95, 0x9c90, 0x9c90, 0x9c90, 0x9c90, 0x9c90, 0x9c90, + 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0005, 0x00b6, 0x0156, 0x0136, + 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, + 0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, + 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, + 0x0040, 0x1a04, 0x9d01, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9eaa, + 0x9ee5, 0x9f0e, 0x9fd8, 0x9ffa, 0xa000, 0xa00d, 0xa015, 0xa021, + 0xa027, 0xa038, 0xa027, 0xa090, 0xa015, 0xa09c, 0xa0a2, 0xa021, + 0xa0a2, 0xa0ae, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, + 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0x9cff, 0xa900, 0xa923, 0xa934, + 0xa954, 0xa986, 0xa00d, 0x9cff, 0xa00d, 0xa027, 0x9cff, 0x9f0e, + 0x9fd8, 0x9cff, 0xad12, 0xa027, 0x9cff, 0xad2e, 0xa027, 0x9cff, + 0xa021, 0x9ea4, 0x9d22, 0x9cff, 0xad4a, 0xadb7, 0xae92, 0x9cff, + 0xae9f, 0xa00a, 0xaeca, 0x9cff, 0xa990, 0xaef7, 0x9cff, 0x080c, + 0x0dc5, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xaf92, 0xb044, + 0x9d20, 0x9d5a, 0x9e06, 0x9e11, 0x9d20, 0xa00d, 0x9d20, 0x9e6b, + 0x9e77, 0x9d75, 0x9d20, 0x9d90, 0x9dc4, 0xb1b1, 0xb1f6, 0xa027, + 0x080c, 0x0dc5, 0x00d6, 0x0096, 0x080c, 0xa0c1, 0x0026, 0x0036, + 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, + 0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, + 0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, + 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa6bd, 0x003e, + 0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, + 0x00be, 0x080c, 0xb23d, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, + 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0xa0c1, 0x7003, 0x0500, + 0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, + 0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, + 0x080c, 0xa6bd, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, + 0xa0c1, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, + 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, + 0x701e, 0x60c3, 0x0010, 0x080c, 0xa6bd, 0x009e, 0x00de, 0x0005, + 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0xa0c1, 0x20e9, + 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, + 0x080c, 0x23ee, 0x080c, 0xde7c, 0x9006, 0x080c, 0x23ee, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa6bd, + 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, + 0x8000, 0x080c, 0xa10c, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, + 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, + 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xde7c, + 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, + 0x2048, 0x080c, 0x0fc0, 0x080c, 0xa6bd, 0x012e, 0x009e, 0x00de, + 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, + 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0xa0c1, + 0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, + 0xa6bd, 0x00d6, 0x00e6, 0x080c, 0xa10c, 0x7814, 0x9084, 0xff00, + 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, + 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, + 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9e31, 0x2069, 0x1801, + 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9e3a, 0x9096, + 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, + 0x2069, 0x19b4, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19ce, 0x20a9, + 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, + 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, + 0x8d68, 0x8e70, 0x1f04, 0x9e51, 0x60c3, 0x004c, 0x080c, 0xa6bd, + 0x00ee, 0x00de, 0x0005, 0x080c, 0xa0c1, 0x7003, 0x6300, 0x7007, + 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x00d6, + 0x0026, 0x0016, 0x080c, 0xa10c, 0x7003, 0x0200, 0x7814, 0x700e, + 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, + 0x1924, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, + 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, + 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa6bd, + 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, + 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x5200, 0x2069, 0x1847, + 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x28a6, 0x710e, + 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, + 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x0254, 0x4003, 0x080c, 0xb23d, 0x1120, 0xb8a0, 0x9082, + 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, + 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, + 0x7036, 0x60c3, 0x001c, 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, + 0x0500, 0x080c, 0xb23d, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, + 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, + 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, + 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa6bd, 0x080c, 0xa0c1, + 0x9006, 0x080c, 0x6a6d, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, + 0x0240, 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, + 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, + 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, + 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9f98, 0x00d6, 0x2069, 0x196c, + 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, + 0x9084, 0x2000, 0x7012, 0x080c, 0xb254, 0x680c, 0x7016, 0x701f, + 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0428, 0x6800, 0x700a, + 0x6804, 0x700e, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0110, 0x2001, + 0x0002, 0x00f6, 0x2079, 0x0100, 0x080c, 0x7637, 0x1128, 0x78e3, + 0x0000, 0x080c, 0x28e7, 0x78e2, 0x00fe, 0x6808, 0x080c, 0x7637, + 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, + 0xb254, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, + 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, + 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, + 0xaf79, 0x2069, 0x1974, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, + 0x080c, 0x57d9, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04e0, + 0x2001, 0x1837, 0x2004, 0xd0a4, 0x01a8, 0x0016, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x2009, 0x0002, 0x1118, 0x2001, 0x196d, 0x200c, + 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x28e7, + 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196c, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, + 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, + 0x20a1, 0x025a, 0x4003, 0x080c, 0xaf79, 0x20a1, 0x024e, 0x20a9, + 0x0008, 0x2099, 0x1974, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa6bd, + 0x080c, 0xa0c1, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, + 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, + 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, + 0x9085, 0x0002, 0x00d6, 0x0804, 0xa071, 0x7026, 0x60c3, 0x0014, + 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x5000, 0x0804, 0x9f30, + 0x080c, 0xa0c1, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, + 0x0804, 0xa6bd, 0x080c, 0xa103, 0x0010, 0x080c, 0xa10c, 0x7003, + 0x0200, 0x60c3, 0x0004, 0x0804, 0xa6bd, 0x080c, 0xa10c, 0x7003, + 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, + 0xa6bd, 0x080c, 0xa10c, 0x7003, 0x0200, 0x0804, 0x9f30, 0x080c, + 0xa10c, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, + 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, + 0x00d6, 0x080c, 0xa10c, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, + 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, + 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, + 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, + 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, + 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, + 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, + 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, + 0xbacc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, + 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, + 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa6bd, + 0x080c, 0xa10c, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, + 0x60c3, 0x0014, 0x0804, 0xa6bd, 0x080c, 0xa10c, 0x7003, 0x0200, + 0x0804, 0x9eae, 0x080c, 0xa10c, 0x7003, 0x0100, 0x700b, 0x0003, + 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x080c, 0xa10c, + 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa6bd, + 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, + 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, + 0x0100, 0x080c, 0xaf8e, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, + 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa6ab, 0x721a, 0x9f95, + 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, + 0x0026, 0x080c, 0xaf8e, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, + 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, + 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, + 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, + 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xaf8e, 0xb810, 0x9305, + 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, + 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, + 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, + 0x004e, 0x003e, 0x00de, 0x080c, 0xa6ab, 0x721a, 0x7a08, 0x7222, + 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa6ab, + 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, + 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, + 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, + 0x0092, 0x1a0c, 0x0dc5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061, + 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x0005, 0xa17a, 0xa189, 0xa194, 0xa178, 0xa178, + 0xa178, 0xa17a, 0xa178, 0xa178, 0xa178, 0xa178, 0xa178, 0xa178, + 0x080c, 0x0dc5, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2bce, + 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, + 0xa6bd, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, + 0x60c3, 0x000c, 0x0804, 0xa6bd, 0x04a1, 0x7003, 0x0003, 0x7007, + 0x0300, 0x60c3, 0x0004, 0x0804, 0xa6bd, 0x0026, 0x080c, 0xaf8e, + 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0xa0dc, + 0x0026, 0x080c, 0xaf8e, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, + 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, + 0xa13e, 0x0026, 0x080c, 0xaf8e, 0xb810, 0x9085, 0x8500, 0x7002, + 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, + 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, + 0x0804, 0xa13e, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, + 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, + 0x0dc5, 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x7910, 0x2158, 0xb9c0, + 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x00be, 0x0005, 0xa219, 0xa2e0, 0xa2b3, 0xa402, + 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xa217, 0xaad8, + 0xaadd, 0xaae2, 0xaae7, 0xa217, 0xaed6, 0xa217, 0xaad3, 0x080c, + 0x0dc5, 0x0096, 0x780b, 0xffff, 0x080c, 0xa284, 0x7914, 0x2148, + 0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, + 0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, + 0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005, + 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006, + 0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, + 0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c, + 0x18f7, 0x0010, 0x080c, 0x1768, 0x0050, 0xd1b4, 0x0118, 0x7047, + 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, + 0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, + 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, + 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, + 0x6017, 0x0009, 0x2001, 0x1a04, 0x2003, 0x07d0, 0x2001, 0x1a03, + 0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, + 0xb8cc, 0xd084, 0x0180, 0x2001, 0x1ad0, 0x200c, 0x8108, 0x2102, + 0x2001, 0x1acf, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x794a, + 0x712e, 0x7b46, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, + 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, + 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, + 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, + 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, + 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0xa6bd, 0x6813, 0x0008, + 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0889, 0x080c, 0xa6ab, + 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, + 0x00d6, 0x0096, 0x080c, 0xa3e0, 0x7814, 0x2048, 0x080c, 0xd0d6, + 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033, 0x0010, 0x9006, + 0x001b, 0x009e, 0x00de, 0x0005, 0xa2fe, 0xa367, 0xa377, 0xa39d, + 0xa3a9, 0xa3ba, 0xa3c2, 0xa2fc, 0x080c, 0x0dc5, 0x0016, 0x0036, + 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, + 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, + 0x003e, 0x001e, 0x2001, 0x19b2, 0x2004, 0x60c2, 0x0804, 0xa6bd, + 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0dc5, 0xaba8, 0x7824, + 0xd0cc, 0x1904, 0xa364, 0x7316, 0xa898, 0x701a, 0xa894, 0x701e, + 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384, 0x0300, + 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, + 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, + 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000, 0x6812, 0x2011, + 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4, 0x6812, + 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, + 0x003e, 0x001e, 0x0804, 0xa6bd, 0xc3e5, 0x0804, 0xa323, 0x2011, + 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, + 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, + 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105, 0x0108, + 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, + 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500, 0x704f, + 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240, 0x700b, + 0x2500, 0x60c3, 0x0032, 0x0804, 0xa6bd, 0x2011, 0x0028, 0x7824, + 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804, 0xa6bd, 0x0cd0, + 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, + 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, + 0x0804, 0xa6bd, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, + 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, + 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, + 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, + 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e, 0x0818, + 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7824, + 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0xa6ab, 0x721a, 0x7a08, + 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x7013, + 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, + 0x001e, 0x0005, 0xa412, 0xa412, 0xa414, 0xa412, 0xa412, 0xa412, + 0xa42e, 0xa412, 0x080c, 0x0dc5, 0x7914, 0x918c, 0x08ff, 0x918d, + 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, + 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, + 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0xa6bd, 0x2009, 0x0003, + 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xaf8e, 0x001e, + 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, + 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, + 0x7116, 0x080c, 0xa6ab, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, + 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, + 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, + 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, + 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, + 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, + 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, + 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, + 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, + 0xffff, 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, + 0xa848, 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, + 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0048, + 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, + 0x00b2, 0x6016, 0x2009, 0x07d0, 0x080c, 0x88c8, 0x003e, 0x004e, + 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, + 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, + 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, + 0x76dc, 0xd6ac, 0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, + 0xff80, 0x1130, 0x9080, 0x33b6, 0x2015, 0x9294, 0x00ff, 0x0020, + 0xb910, 0xba14, 0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, + 0x007e, 0x1218, 0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, + 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, + 0x0000, 0x616e, 0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, + 0x0110, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, + 0x8007, 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, + 0x6087, 0xffff, 0x7814, 0x0096, 0x2048, 0xa838, 0x608a, 0xa834, + 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, + 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, + 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, + 0x6116, 0x2009, 0x07d0, 0x080c, 0x88c8, 0x003e, 0x004e, 0x005e, + 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, + 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, + 0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, + 0x737c, 0x7480, 0x7820, 0x90be, 0x0006, 0x0904, 0xa61a, 0x90be, + 0x000a, 0x1904, 0xa5d6, 0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, + 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, + 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, + 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, + 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, + 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, + 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, + 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, + 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, + 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, + 0x607f, 0x0000, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, + 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0x080c, 0xaf73, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, + 0x0110, 0x2009, 0x1b58, 0x080c, 0x88c8, 0x003e, 0x004e, 0x005e, + 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7804, 0x9086, + 0x0040, 0x0904, 0xa656, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, + 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, + 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7814, 0x2048, + 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, + 0xb86c, 0x60ce, 0xbac0, 0x629e, 0x080c, 0xaf73, 0x2009, 0x07d0, + 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, + 0x88c8, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, + 0x00be, 0x0005, 0x7814, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, + 0x0002, 0x0904, 0xa672, 0x9185, 0x0100, 0x6062, 0x6266, 0x636a, + 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, + 0x00ff, 0xb88e, 0x8007, 0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, + 0x7808, 0x6082, 0xa890, 0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, + 0xa8ac, 0x60ca, 0xa8ac, 0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, + 0x9109, 0x792e, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xbac0, 0x629e, 0x080c, 0xaf50, 0x0804, 0xa606, 0xb8cc, 0xd084, + 0x0148, 0xb88c, 0x7814, 0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, + 0xa83a, 0xb046, 0x9185, 0x0600, 0x6062, 0x6266, 0x636a, 0x646e, + 0x6073, 0x0829, 0x6077, 0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, + 0x0804, 0xa5e9, 0x9185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, + 0x7824, 0xd0cc, 0x7826, 0x0118, 0x6073, 0x0889, 0x0010, 0x6073, + 0x0898, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, + 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, + 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, + 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, + 0x7824, 0xd0cc, 0x0120, 0x080c, 0xaf73, 0x0804, 0xa606, 0x080c, + 0xaf50, 0x0804, 0xa606, 0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, + 0x9294, 0x00ff, 0xba8e, 0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, + 0x19e8, 0x6843, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x00f1, 0x080c, 0x88ba, 0x0005, 0x0016, 0x2001, 0x180c, + 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, + 0x88ba, 0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, + 0x19e9, 0x2003, 0x0000, 0x2001, 0x19f1, 0x2003, 0x0000, 0x0c88, + 0x0006, 0x6014, 0x9084, 0x1804, 0x9085, 0x0009, 0x6016, 0x000e, + 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, + 0x95f5, 0x6014, 0x9084, 0x1804, 0x9085, 0x0008, 0x6016, 0x000e, + 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, + 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, + 0x7637, 0x11c0, 0x2001, 0x1a04, 0x2004, 0x9005, 0x15d0, 0x080c, + 0x76e4, 0x1160, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, + 0xd084, 0x090c, 0x0dc5, 0x080c, 0x88ba, 0x0458, 0x00c6, 0x2061, + 0x19e8, 0x00c8, 0x6904, 0x9194, 0x4000, 0x0540, 0x0811, 0x080c, + 0x2d49, 0x00c6, 0x2061, 0x19e8, 0x6128, 0x9192, 0x0008, 0x1258, + 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x88ba, + 0x080c, 0xa6e0, 0x0070, 0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, + 0xf094, 0x080c, 0x88c3, 0x2009, 0x0014, 0x080c, 0xb352, 0x00ce, + 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a04, + 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e8, 0x6128, 0x9192, + 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x88ba, 0x080c, + 0x5fed, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, + 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88d0, 0x2071, + 0x19e8, 0x713c, 0x81ff, 0x0904, 0xa7e9, 0x2061, 0x0100, 0x2069, + 0x0140, 0x080c, 0x7637, 0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, + 0xaa49, 0x003e, 0x713c, 0x2160, 0x080c, 0xf094, 0x2009, 0x004a, + 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, + 0x2009, 0x004a, 0x080c, 0xb352, 0x080c, 0x76e4, 0x0804, 0xa7e9, + 0x080c, 0xa7f5, 0x0904, 0xa7e9, 0x6904, 0xd1f4, 0x0904, 0xa7f0, + 0x080c, 0x2d49, 0x00c6, 0x703c, 0x9065, 0x090c, 0x0dc5, 0x6020, + 0x00ce, 0x9086, 0x0006, 0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, + 0x2009, 0x180c, 0x2104, 0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, + 0x1128, 0x6224, 0x9294, 0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, + 0xd0cc, 0x0110, 0x080c, 0x2c7b, 0x6014, 0x9084, 0xe7fd, 0x9085, + 0x0010, 0x6016, 0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xb352, + 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xaa49, 0x003e, 0x713c, + 0x2160, 0x080c, 0xf094, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, + 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, + 0xb352, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, + 0xd1ec, 0x1904, 0xa7a0, 0x0804, 0xa7a2, 0x00d6, 0x00c6, 0x0096, + 0x703c, 0x9065, 0x090c, 0x0dc5, 0x2001, 0x0306, 0x200c, 0x9184, + 0x0030, 0x0904, 0xa8a8, 0x9184, 0x0048, 0x9086, 0x0008, 0x1904, + 0xa8a8, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, + 0x1904, 0xa8a8, 0x2009, 0x022a, 0x2104, 0x2009, 0x022f, 0x210c, + 0x9116, 0x9084, 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, + 0x9102, 0x0030, 0x2010, 0x2100, 0x9202, 0x2009, 0x0228, 0x9102, + 0x9082, 0x0005, 0x0250, 0x2008, 0x2001, 0x013b, 0x2004, 0x8004, + 0x8004, 0x8004, 0x9102, 0x1a04, 0xa8a8, 0x2009, 0x1a84, 0x2104, + 0x8000, 0x0208, 0x200a, 0x2069, 0x0100, 0x6914, 0x918c, 0x1984, + 0x918d, 0x0010, 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, + 0x15c0, 0x8211, 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800, 0x2001, + 0x009a, 0x2003, 0x0004, 0x2001, 0x1a69, 0x2003, 0x0000, 0x2001, + 0x1a72, 0x2003, 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105, 0x1170, + 0x0096, 0x6014, 0x2048, 0xa87c, 0xc0dc, 0xa87e, 0xa880, 0xc0fc, + 0xa882, 0x009e, 0x2c10, 0x080c, 0x1be0, 0x0040, 0x6014, 0x2048, + 0xaa3a, 0xa936, 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, + 0x2091, 0x2400, 0x002e, 0x080c, 0x1c79, 0x190c, 0x0dc5, 0x012e, + 0x0090, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, + 0x2011, 0x0020, 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, + 0x68c8, 0x9105, 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, + 0x7048, 0xc085, 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, + 0x07d0, 0x080c, 0x88c8, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, + 0x9085, 0x0001, 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19e8, 0x7048, + 0xd084, 0x01d8, 0x713c, 0x81ff, 0x01c0, 0x2071, 0x0100, 0x9188, + 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, + 0x9085, 0x0012, 0x7016, 0x0048, 0x928e, 0x0009, 0x0db0, 0x7014, + 0x9084, 0x1984, 0x9085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005, + 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, + 0x0126, 0x2091, 0x8000, 0x6010, 0x2058, 0xbca0, 0x2071, 0x19e8, + 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0, 0x9406, 0x0118, 0xb854, + 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048, 0xac6c, 0xad70, 0xae78, + 0x009e, 0x080c, 0x6856, 0x0110, 0x9085, 0x0001, 0x012e, 0x000e, + 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, + 0x080c, 0xa0c1, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, 0x7016, + 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, 0x0130, + 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, 0x1800, + 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, 0x60c3, + 0x002c, 0x0804, 0xa6bd, 0x080c, 0xa0c1, 0x7003, 0x0f00, 0x7808, + 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, 0x700e, + 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x0156, 0x080c, 0xa10c, 0x7003, + 0x0200, 0x080c, 0x894c, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, + 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, + 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xa943, 0x60c3, + 0x001c, 0x015e, 0x0804, 0xa6bd, 0x0016, 0x0026, 0x080c, 0xa0e8, + 0x080c, 0xa0fa, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, 0x7814, + 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, 0x9192, + 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, 0x080c, + 0xa6bd, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, 0x080c, + 0xaf79, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, 0xa0c1, + 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, + 0x0016, 0x0026, 0x080c, 0xa0c1, 0x20e9, 0x0000, 0x20a1, 0x024c, + 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, + 0x4003, 0x8003, 0x60c2, 0x080c, 0xa6bd, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, + 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c, 0xd2e0, 0x1110, 0x080c, + 0xbcb6, 0x600c, 0x0006, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x080c, + 0xaaf1, 0x00ce, 0x0c78, 0x2c00, 0x700e, 0x700a, 0x012e, 0x000e, + 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, + 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, + 0x0140, 0x2071, 0x19e8, 0x7024, 0x2060, 0x8cff, 0x01f8, 0x080c, + 0xa6e9, 0x6ac0, 0x68c3, 0x0000, 0x080c, 0x88c3, 0x00c6, 0x2061, + 0x0100, 0x080c, 0xb0ca, 0x00ce, 0x20a9, 0x01f4, 0x0461, 0x2009, + 0x0013, 0x080c, 0xb352, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, + 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, + 0x88c3, 0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, + 0x0008, 0x68c3, 0x0000, 0x2011, 0x5f97, 0x080c, 0x883d, 0x20a9, + 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, + 0x7804, 0x9084, 0x4000, 0x190c, 0x2d49, 0x0090, 0xd084, 0x0118, + 0x6827, 0x4001, 0x0010, 0x1f04, 0xaa2b, 0x7804, 0x9084, 0x1000, + 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, + 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, + 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, + 0x19e8, 0x703c, 0x2060, 0x8cff, 0x0904, 0xaab4, 0x9386, 0x0002, + 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xaab4, 0x68af, 0x95f5, + 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, + 0x0008, 0x080c, 0x88d0, 0x080c, 0x2031, 0x2001, 0x0032, 0x6920, + 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, + 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, + 0x9084, 0x4000, 0x190c, 0x2d49, 0x0090, 0xd08c, 0x0118, 0x6827, + 0x0002, 0x0010, 0x1f04, 0xaa8a, 0x7804, 0x9084, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x6827, + 0x4000, 0x6824, 0x83ff, 0x1140, 0x2009, 0x0049, 0x6020, 0x9086, + 0x0009, 0x0110, 0x080c, 0xb352, 0x000e, 0x001e, 0x002e, 0x006e, + 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, + 0x0126, 0x2091, 0x8000, 0x2069, 0x19e8, 0x6a06, 0x012e, 0x00de, + 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e8, 0x6a32, + 0x012e, 0x00de, 0x0005, 0x080c, 0xa284, 0x7047, 0x1000, 0x0098, + 0x080c, 0xa284, 0x7047, 0x4000, 0x0070, 0x080c, 0xa284, 0x7047, + 0x2000, 0x0048, 0x080c, 0xa284, 0x7047, 0x0400, 0x0020, 0x080c, + 0xa284, 0x7047, 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, + 0xa6bd, 0x00e6, 0x2071, 0x19e8, 0x7020, 0x9005, 0x0110, 0x8001, + 0x7022, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, + 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7614, + 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xab96, 0x8cff, + 0x0904, 0xab96, 0x6020, 0x9086, 0x0006, 0x1904, 0xab91, 0x88ff, + 0x0138, 0x2800, 0x9c06, 0x1904, 0xab91, 0x2039, 0x0000, 0x0050, + 0x6010, 0x9b06, 0x1904, 0xab91, 0x85ff, 0x0120, 0x6054, 0x9106, + 0x1904, 0xab91, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, + 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, + 0x88c3, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0428, 0x080c, 0x88c3, + 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, + 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, + 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, + 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, + 0x6827, 0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, + 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, + 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, + 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, + 0x0096, 0x2048, 0x080c, 0xd0d6, 0x0110, 0x080c, 0xebd4, 0x009e, + 0x080c, 0xb306, 0x080c, 0xaaf1, 0x88ff, 0x1190, 0x00ce, 0x0804, + 0xab0c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xab0c, 0x9006, 0x012e, + 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, + 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19e8, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, + 0xac0a, 0x6020, 0x9086, 0x0006, 0x1904, 0xac05, 0x87ff, 0x0128, + 0x2700, 0x9c06, 0x1904, 0xac05, 0x0040, 0x6010, 0x9b06, 0x15e8, + 0x85ff, 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, + 0x0036, 0x2019, 0x0001, 0x080c, 0xaa49, 0x7033, 0x0000, 0x9006, + 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, + 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, + 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, + 0x2048, 0x080c, 0xd0d6, 0x0110, 0x080c, 0xebd4, 0x080c, 0xb306, + 0x87ff, 0x1198, 0x00ce, 0x0804, 0xabb6, 0x2c78, 0x600c, 0x2060, + 0x0804, 0xabb6, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, + 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, + 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e8, 0x2001, 0x1800, + 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, + 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x2c10, 0x7638, + 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, + 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x6004, 0x9086, 0x0040, 0x090c, 0x99a5, 0x9085, 0x0001, 0x0020, + 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, + 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19e8, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xad01, 0x6010, + 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xacfc, 0x7024, + 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xacd3, + 0x080c, 0xa6e9, 0x68c3, 0x0000, 0x080c, 0xac1b, 0x7027, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2d39, 0x9006, 0x080c, 0x2d39, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, + 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x080c, 0xd2cf, 0x1180, 0x080c, 0x3279, 0x080c, 0xd2e0, 0x1518, + 0x080c, 0xbcb6, 0x0400, 0x080c, 0xac1b, 0x6824, 0xd084, 0x09b0, + 0x6827, 0x0001, 0x0898, 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, + 0x0090, 0x6014, 0x2048, 0x080c, 0xd0d6, 0x0168, 0x6020, 0x9086, + 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6e92, 0x080c, 0xd2c3, 0x080c, 0xd54c, 0x080c, 0xb306, 0x080c, + 0xaaf1, 0x00ce, 0x0804, 0xac7c, 0x2c78, 0x600c, 0x2060, 0x0804, + 0xac7c, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, + 0xebd4, 0x0c08, 0x00d6, 0x080c, 0xa10c, 0x7003, 0x0200, 0x7007, + 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1989, 0x20e9, + 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, + 0x7027, 0x7878, 0x080c, 0xa6bd, 0x00de, 0x0005, 0x080c, 0xa10c, + 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, + 0x00ff, 0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, + 0x0200, 0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, + 0x0804, 0xa6bd, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, + 0x0035, 0x080c, 0xd759, 0x00de, 0x1904, 0xadaf, 0x080c, 0xa0c1, + 0x7003, 0x1300, 0x782c, 0x080c, 0xaeb5, 0x2068, 0x6820, 0x9086, + 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb23d, 0x11d8, + 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, + 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, + 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, + 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, + 0xb814, 0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xb23d, + 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, + 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, + 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, + 0x000c, 0x001e, 0x00de, 0x080c, 0xa6bd, 0x00be, 0x0005, 0x781b, + 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, + 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, + 0x0904, 0xae2a, 0x9186, 0x0005, 0x0904, 0xae12, 0x9186, 0x0004, + 0x05d8, 0x9186, 0x0008, 0x0904, 0xae1b, 0x7807, 0x0037, 0x782f, + 0x0003, 0x7817, 0x1700, 0x080c, 0xae92, 0x0005, 0x080c, 0xae53, + 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, + 0xadf3, 0xadfe, 0xadf5, 0xadfe, 0xadfa, 0xadf3, 0xadf3, 0xadfe, + 0xadfe, 0xadfe, 0xadfe, 0xadf3, 0xadf3, 0xadf3, 0xadf3, 0xadf3, + 0xadfe, 0xadf3, 0xadfe, 0x080c, 0x0dc5, 0x6824, 0xd0e4, 0x0110, + 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, + 0x6830, 0x7026, 0x0804, 0xae4c, 0x080c, 0xae53, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, + 0x900e, 0x04d0, 0x080c, 0xae53, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, + 0x2009, 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, + 0x900e, 0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, + 0x6924, 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, + 0xa9b0, 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, + 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, + 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, + 0x00de, 0x0804, 0xa6bd, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, + 0x080c, 0xa10c, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, + 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xb23d, 0x1118, 0x9092, + 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, + 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, + 0x6498, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, + 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, + 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, + 0x00be, 0x0005, 0x080c, 0xa10c, 0x7003, 0x0100, 0x782c, 0x700a, + 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x080c, + 0xa0b8, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, + 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, + 0x701a, 0x60c3, 0x0010, 0x0804, 0xa6bd, 0x00e6, 0x2071, 0x0240, + 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084, + 0x0120, 0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, + 0x00ee, 0x0005, 0x080c, 0xa103, 0x7003, 0x0100, 0x782c, 0x700a, + 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa6bd, 0x0021, 0x60c3, + 0x0000, 0x0804, 0xa6bd, 0x00d6, 0x080c, 0xaf8e, 0xb810, 0x9085, + 0x0300, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, + 0x6880, 0x700e, 0x7013, 0x0819, 0x080c, 0xa6ab, 0x721a, 0x2f10, + 0x7222, 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, + 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, + 0x2bce, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, + 0x080c, 0xa6e0, 0x080c, 0x88ba, 0x0005, 0x0036, 0x0096, 0x00d6, + 0x00e6, 0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, + 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, + 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, + 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, + 0x0200, 0x080c, 0xaf8e, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, + 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, + 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, + 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, + 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, + 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, + 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, + 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b3, 0x210c, 0x009e, + 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, + 0x0005, 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, + 0x000b, 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, + 0x2009, 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, + 0x6912, 0x0005, 0x080c, 0xa0c1, 0x0016, 0x0026, 0x0096, 0x00d6, + 0x7814, 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, + 0x0028, 0x1138, 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, 0x1904, + 0xb033, 0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, + 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, + 0x700e, 0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, + 0x1805, 0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, + 0x1f04, 0xafc4, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, + 0x8108, 0x8210, 0x1f04, 0xafce, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, + 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, + 0xaf79, 0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, + 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, + 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, + 0x8109, 0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, + 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, + 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x7637, 0x0150, + 0x6028, 0xc0bd, 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029, + 0x6016, 0x0010, 0x080c, 0xa6bd, 0x080c, 0x88ba, 0x00de, 0x009e, + 0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, + 0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, + 0x00ff, 0x00ee, 0x0804, 0xafa9, 0x080c, 0xa0c1, 0x0016, 0x0026, + 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, + 0x00c6, 0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, + 0x9105, 0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, + 0x9105, 0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, + 0x9084, 0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, + 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, + 0x1dc0, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xb085, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, + 0x2012, 0x8108, 0x8210, 0x1f04, 0xb08f, 0x00d6, 0x0016, 0x2069, + 0x0200, 0x080c, 0xaf79, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, + 0x0002, 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, + 0x8210, 0x1f04, 0xb0a5, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, + 0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, + 0x1f04, 0xb0b6, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, + 0x9575, 0x080c, 0xa6bd, 0x080c, 0x88ba, 0x00de, 0x009e, 0x002e, + 0x001e, 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, + 0x2069, 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, + 0x20a9, 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, + 0x9006, 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, + 0x00de, 0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, + 0x9006, 0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, + 0x6007, 0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, + 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa813, 0x20c5, 0x080c, 0x9564, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9bd3, 0x012e, 0x009e, 0x00de, + 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, + 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x760c, 0x2660, 0x2678, + 0x8cff, 0x0904, 0xb19d, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, + 0x68c0, 0x9005, 0x0904, 0xb16f, 0x080c, 0xa6e9, 0x68c3, 0x0000, + 0x080c, 0xac1b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, + 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d39, 0x9006, + 0x080c, 0x2d39, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, + 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, + 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, + 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, + 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd2cf, 0x1180, 0x080c, + 0x3279, 0x080c, 0xd2e0, 0x1518, 0x080c, 0xbcb6, 0x0400, 0x080c, + 0xac1b, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, + 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0090, 0x6014, 0x2048, 0x080c, + 0xd0d6, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, + 0xab7a, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x080c, + 0xd54c, 0x080c, 0xb306, 0x080c, 0xaaf1, 0x00ce, 0x0804, 0xb120, + 0x2c78, 0x600c, 0x2060, 0x0804, 0xb120, 0x700f, 0x0000, 0x700b, + 0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, + 0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xebd4, + 0x08f0, 0x00d6, 0x0156, 0x080c, 0xa10c, 0x7a14, 0x82ff, 0x0138, + 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, + 0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, + 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, 0x7637, 0x1110, 0xc3ad, + 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, + 0x730e, 0x080c, 0x894c, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, + 0xffed, 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, + 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xb1e3, 0x60c3, + 0x0020, 0x080c, 0xa6bd, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, + 0xa10c, 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, + 0x000e, 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, + 0x0488, 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, + 0x19be, 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, + 0x0421, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, + 0x2004, 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, + 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, + 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, + 0x60c3, 0x001c, 0x015e, 0x0804, 0xa6bd, 0x0006, 0x2001, 0x1837, + 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xaabf, + 0x2011, 0x0002, 0x080c, 0xaac9, 0x080c, 0xa9d3, 0x0036, 0x901e, + 0x080c, 0xaa49, 0x003e, 0x0005, 0x080c, 0x33af, 0x0188, 0x0016, + 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, + 0x080c, 0x6724, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, + 0x0005, 0x2071, 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976, + 0x2071, 0x1800, 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800, + 0x7074, 0x7056, 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071, + 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058, + 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, + 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, + 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, + 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, + 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010, + 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, + 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, + 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, + 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0, + 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0dc5, 0x9006, 0x6006, 0x600a, + 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000, + 0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, + 0x603a, 0x603e, 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000, + 0x6056, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, + 0x0016, 0x080c, 0x9ab1, 0x001e, 0x012e, 0x0cb0, 0x0006, 0x6000, + 0x9086, 0x0000, 0x01c0, 0x601c, 0xd084, 0x190c, 0x1a8e, 0x6017, + 0x0000, 0x6023, 0x0007, 0x2001, 0x1986, 0x2004, 0x0006, 0x9082, + 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xee87, 0x6043, + 0x0000, 0x6013, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126, 0x2071, + 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, + 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, + 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, + 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a, + 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0, + 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xb365, 0xb36e, + 0xb389, 0xb3a4, 0xd82b, 0xd848, 0xd863, 0xb365, 0xb36e, 0x9100, + 0xb3bd, 0xb365, 0xb365, 0xb365, 0xb365, 0x9186, 0x0013, 0x1128, + 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0005, 0x0005, 0x0066, 0x6000, + 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb387, + 0xbb05, 0xbcfd, 0xb387, 0xbd93, 0xb6a0, 0xb387, 0xb387, 0xba87, + 0xc3b1, 0xb387, 0xb387, 0xb387, 0xb387, 0xb387, 0xb387, 0x080c, + 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, + 0x006e, 0x0005, 0xb3a2, 0xca7e, 0xb3a2, 0xb3a2, 0xb3a2, 0xb3a2, + 0xb3a2, 0xb3a2, 0xca15, 0xcc00, 0xb3a2, 0xcabf, 0xcb3e, 0xcabf, + 0xcb3e, 0xb3a2, 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, + 0x0dc5, 0x6000, 0x0002, 0xb3bb, 0xc3f8, 0xc4c0, 0xc5f3, 0xc7a2, + 0xb3bb, 0xb3bb, 0xb3bb, 0xc3cc, 0xc9a1, 0xc9a4, 0xb3bb, 0xb3bb, + 0xb3bb, 0xb3bb, 0xc9d3, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, + 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb3d6, 0xb3d6, + 0xb419, 0xb4b8, 0xb54d, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d8, 0xb3d6, + 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0xb3d6, 0x080c, 0x0dc5, + 0x9186, 0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, + 0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, + 0xa87c, 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, + 0xa84a, 0x9006, 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, + 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, + 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x0126, 0x2091, 0x8000, + 0x080c, 0x9bd3, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, + 0x00be, 0x2c00, 0x080c, 0xb56f, 0x080c, 0xd7fb, 0x6003, 0x0007, + 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, + 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, + 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, + 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, + 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, + 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, + 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, + 0x8423, 0x9405, 0x0002, 0xb480, 0xb480, 0xb47b, 0xb47e, 0xb480, + 0xb478, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, 0xb46b, + 0xb46b, 0xb46b, 0xb46b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, + 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, + 0x080c, 0xbfab, 0x0028, 0x080c, 0xc0e9, 0x0010, 0x080c, 0xc1df, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, + 0x000e, 0x080c, 0xb62d, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, + 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, + 0x0000, 0x2041, 0x126c, 0x080c, 0xb7f1, 0x0160, 0x000e, 0x9005, + 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, + 0x0804, 0xb2d3, 0x2001, 0x002c, 0x900e, 0x080c, 0xb693, 0x0c70, + 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, + 0x0a0c, 0x0dc5, 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, + 0x00ca, 0x2001, 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, + 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x94b1, 0x002e, 0x001e, + 0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, + 0xb419, 0x0005, 0xb4eb, 0xb4eb, 0xb4ed, 0xb523, 0xb4eb, 0xb4eb, + 0xb4eb, 0xb4eb, 0xb536, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, + 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6003, 0x0004, 0x6114, 0x2148, + 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, + 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb693, 0x080c, + 0xb2d3, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, + 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, + 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, + 0x001e, 0x00de, 0x0005, 0x080c, 0x9a61, 0x00d6, 0x0096, 0x6114, + 0x2148, 0x080c, 0xd0d8, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6e9f, + 0x009e, 0x00de, 0x080c, 0xb2d3, 0x0804, 0x9bd3, 0x080c, 0x9a61, + 0x080c, 0x3250, 0x080c, 0xd7f8, 0x00d6, 0x0096, 0x6114, 0x2148, + 0x080c, 0xd0d8, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, + 0x00de, 0x080c, 0xb2d3, 0x0804, 0x9bd3, 0x9182, 0x0047, 0x0002, + 0xb55d, 0xb55f, 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55d, + 0xb55d, 0xb55d, 0xb55d, 0xb55d, 0xb55f, 0x080c, 0x0dc5, 0x00d6, + 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, + 0x0000, 0x080c, 0x6e9f, 0x009e, 0x00de, 0x0804, 0xb2d3, 0x0026, + 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, + 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, + 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, + 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, + 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xcc85, + 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xcc85, + 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, + 0x100e, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, + 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, + 0xcc85, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, + 0x001b, 0x080c, 0xcc85, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, + 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, + 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, + 0x6e9f, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, + 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, + 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, + 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, + 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, + 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, + 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, + 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, + 0x6e9f, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, + 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, + 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, + 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, + 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, + 0x100e, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, + 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, + 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, + 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, + 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, + 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb642, + 0x0804, 0xb644, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, + 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, + 0xa87a, 0xa982, 0x080c, 0x6e92, 0x009e, 0x003e, 0x00de, 0x0005, + 0x91b6, 0x0015, 0x1118, 0x080c, 0xb2d3, 0x0030, 0x91b6, 0x0016, + 0x190c, 0x0dc5, 0x080c, 0xb2d3, 0x0005, 0x20a9, 0x000e, 0x20e1, + 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, + 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, + 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, + 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, + 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, + 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xd0d8, 0x0130, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, + 0xb2d3, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, + 0x6010, 0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, + 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, + 0xb2d3, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, + 0x0006, 0x0016, 0x080c, 0xd7e3, 0x0188, 0x6014, 0x9005, 0x1170, + 0x600b, 0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, + 0x080c, 0xbadd, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, + 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, + 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, + 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, + 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, + 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, + 0x080c, 0xb2d3, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, + 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, + 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, + 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xcc85, + 0x080c, 0xd0d8, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, + 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb2d3, 0x001e, 0x009e, 0x0005, + 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, + 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, + 0x6e9f, 0x009e, 0x080c, 0xb2d3, 0x001e, 0x0005, 0x0016, 0x0096, + 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, + 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, + 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xcc85, 0x009e, + 0x080c, 0xd0d8, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, + 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb2d3, 0x009e, 0x001e, + 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, + 0x080c, 0xbcb6, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, + 0x0898, 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, + 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, + 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, + 0x080c, 0x10f8, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, + 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, + 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, + 0x2009, 0x0035, 0x080c, 0xd759, 0x001e, 0x1158, 0x622c, 0x2268, + 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, + 0x0128, 0x080c, 0xb2d3, 0x0020, 0x0039, 0x0010, 0x080c, 0xb910, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, + 0x0015, 0x0904, 0xb8f8, 0x918e, 0x0016, 0x1904, 0xb90e, 0x700c, + 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, + 0xb8d2, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb8b5, + 0x0804, 0xb90c, 0x6808, 0x9086, 0xffff, 0x1904, 0xb8fa, 0xa87c, + 0x9084, 0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, + 0x1904, 0xb8fa, 0x6824, 0xd084, 0x1904, 0xb8fa, 0xd0b4, 0x0158, + 0x0016, 0x2001, 0x1986, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, + 0x001e, 0x1a04, 0xb8fa, 0x080c, 0xd2c3, 0x685c, 0xa882, 0xa87c, + 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, + 0x000a, 0x080c, 0x9375, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, + 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcde3, 0x00ce, + 0x0804, 0xb90c, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61c2, + 0x0010, 0x080c, 0x65cf, 0x00ce, 0x1904, 0xb8fa, 0x00c6, 0x2d60, + 0x080c, 0xb2d3, 0x00ce, 0x0804, 0xb90c, 0x00c6, 0x080c, 0xb325, + 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd554, 0x6023, + 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xb2d3, 0x00ce, 0x080c, + 0xb352, 0x00ce, 0x0804, 0xb90c, 0x2001, 0x1988, 0x2004, 0x6842, + 0x00ce, 0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, + 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, + 0x0003, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x00e8, 0x700c, + 0x9086, 0x2a00, 0x1138, 0x2001, 0x1988, 0x2004, 0x6842, 0x00a0, + 0x0479, 0x00a0, 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, + 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6cb9, 0x080c, 0xd2c3, + 0x080c, 0xb306, 0x00de, 0x00ce, 0x080c, 0xb2d3, 0x009e, 0x0005, + 0x9186, 0x0015, 0x1128, 0x2001, 0x1988, 0x2004, 0x6842, 0x0068, + 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xee87, + 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x00ce, 0x080c, 0xb2d3, 0x0005, + 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, + 0x2001, 0x1988, 0x2004, 0x6842, 0x0804, 0xb98a, 0x00c6, 0x2d60, + 0x080c, 0xcce6, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, + 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, + 0x89ff, 0x090c, 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, + 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, + 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, + 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, + 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, + 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, + 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd44b, 0x080c, + 0x9ab1, 0x0010, 0x080c, 0xb2d3, 0x004e, 0x003e, 0x002e, 0x0005, + 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, + 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb9f5, 0x700c, 0x6210, + 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb9f5, 0x6038, + 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, + 0xb9f5, 0x9286, 0x0002, 0x0904, 0xb9f5, 0x9286, 0x0000, 0x05e8, + 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, + 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, + 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, + 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, + 0x0096, 0x2048, 0x080c, 0xd0d8, 0x090c, 0x0dc5, 0xa87b, 0x0003, + 0x009e, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x0030, 0x6038, + 0x2070, 0x2001, 0x1988, 0x2004, 0x7042, 0x080c, 0xb2d3, 0x002e, + 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, + 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, + 0xc48c, 0xbc02, 0x0470, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, + 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc379, + 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xba66, 0x0096, 0x0156, + 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, + 0x0004, 0x080c, 0xc379, 0x002e, 0x003e, 0x015e, 0x009e, 0x15b0, + 0x7238, 0xba0a, 0x733c, 0xbb0e, 0x83ff, 0x0118, 0xbc00, 0xc48d, + 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, + 0xb6dc, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, + 0x2041, 0x1252, 0x080c, 0xb7f1, 0x0130, 0x00fe, 0x009e, 0x080c, + 0xb2d3, 0x00be, 0x0005, 0x080c, 0xbcb6, 0x0cb8, 0x2b78, 0x00f6, + 0x080c, 0x3250, 0x080c, 0xd7f8, 0x00fe, 0x00c6, 0x080c, 0xb27d, + 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, + 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x666a, 0x080c, 0x6696, + 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00ce, 0x0804, 0xba39, 0x2100, + 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b2, 0x0040, 0x1a04, 0xbaef, + 0x0002, 0xbadd, 0xbadd, 0xbad3, 0xbadd, 0xbadd, 0xbadd, 0xbad1, + 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, + 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, + 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, + 0xbadd, 0xbad1, 0xbadd, 0xbadd, 0xbad1, 0xbad1, 0xbad1, 0xbad1, + 0xbad1, 0xbad3, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, + 0xbad1, 0xbad1, 0xbad1, 0xbadd, 0xbadd, 0xbad1, 0xbad1, 0xbad1, + 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbad1, 0xbadd, 0xbad1, + 0xbad1, 0x080c, 0x0dc5, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, + 0xc08c, 0xb8ce, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, + 0x9186, 0x0032, 0x0118, 0x080c, 0x9547, 0x0010, 0x080c, 0x94ff, + 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, 0x2600, + 0x0002, 0xbadd, 0xbadd, 0xbb03, 0xbadd, 0xbadd, 0xbb03, 0xbb03, + 0xbb03, 0xbb03, 0xbadd, 0xbb03, 0xbadd, 0xbb03, 0xbadd, 0xbb03, + 0xbb03, 0xbb03, 0xbb03, 0x080c, 0x0dc5, 0x6004, 0x90b2, 0x0053, + 0x1a0c, 0x0dc5, 0x91b6, 0x0013, 0x0904, 0xbbd8, 0x91b6, 0x0027, + 0x1904, 0xbb82, 0x080c, 0x99a5, 0x6004, 0x080c, 0xd2cf, 0x01b0, + 0x080c, 0xd2e0, 0x01a8, 0x908e, 0x0021, 0x0904, 0xbb7f, 0x908e, + 0x0022, 0x1130, 0x080c, 0xb708, 0x0904, 0xbb7b, 0x0804, 0xbb7c, + 0x908e, 0x003d, 0x0904, 0xbb7f, 0x0804, 0xbb75, 0x080c, 0x3279, + 0x2001, 0x0007, 0x080c, 0x666a, 0x6010, 0x00b6, 0x2058, 0xb9a0, + 0x00be, 0x080c, 0xbcb6, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, + 0x2014, 0xc285, 0x080c, 0x7637, 0x1108, 0xc2ad, 0x2202, 0x0036, + 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xef94, 0x002e, 0x003e, + 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x96a4, + 0x0076, 0x903e, 0x080c, 0x9577, 0x6010, 0x00b6, 0x905d, 0x0100, + 0x00be, 0x2c08, 0x080c, 0xe91c, 0x007e, 0x003e, 0x002e, 0x001e, + 0x080c, 0xd7f8, 0x0016, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x001e, + 0x080c, 0x334c, 0x080c, 0x9ab1, 0x0030, 0x080c, 0xd54c, 0x080c, + 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, 0xbcb6, 0x0cb0, 0x080c, + 0xbcf2, 0x0c98, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, + 0x080c, 0xd809, 0x0d80, 0x6000, 0x9086, 0x0002, 0x0904, 0xbcfd, + 0x0c50, 0x9186, 0x0014, 0x1d38, 0x080c, 0x99a5, 0x6004, 0x908e, + 0x0022, 0x1118, 0x080c, 0xb708, 0x09f0, 0x080c, 0x3250, 0x080c, + 0xd7f8, 0x080c, 0xd2cf, 0x1198, 0x080c, 0x3279, 0x6010, 0x00b6, + 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbcb6, 0x9186, 0x007e, 0x1128, + 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0804, 0xbb75, 0x080c, + 0xd2e0, 0x1120, 0x080c, 0xbcb6, 0x0804, 0xbb75, 0x6004, 0x908e, + 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, + 0x080c, 0x35e7, 0x00fe, 0x00ee, 0x0804, 0xbb75, 0x6004, 0x908e, + 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xbcb6, 0x0804, 0xbb75, + 0x90b2, 0x0040, 0x1a04, 0xbc92, 0x2008, 0x0002, 0xbc20, 0xbc21, + 0xbc24, 0xbc27, 0xbc2a, 0xbc37, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, + 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, + 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, + 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc3a, 0xbc47, 0xbc1e, 0xbc49, + 0xbc47, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc47, 0xbc47, + 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc1e, + 0xbc79, 0xbc47, 0xbc1e, 0xbc43, 0xbc1e, 0xbc1e, 0xbc1e, 0xbc44, + 0xbc1e, 0xbc1e, 0xbc1e, 0xbc47, 0xbc70, 0xbc1e, 0x080c, 0x0dc5, + 0x0430, 0x2001, 0x000b, 0x0470, 0x2001, 0x0003, 0x0458, 0x2001, + 0x0005, 0x0440, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, + 0x00ff, 0x9086, 0x0000, 0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, + 0x0009, 0x00c0, 0x080c, 0x99a5, 0x6003, 0x0005, 0x080c, 0xd7fb, + 0x080c, 0x9ab1, 0x0070, 0x0018, 0x0010, 0x080c, 0x666a, 0x0804, + 0xbc8a, 0x080c, 0x99a5, 0x080c, 0xd7fb, 0x6003, 0x0004, 0x080c, + 0x9ab1, 0x0005, 0x080c, 0x666a, 0x080c, 0x99a5, 0x6003, 0x0002, + 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, + 0x1986, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, + 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, 0x9ab1, 0x0c08, + 0x080c, 0x99a5, 0x080c, 0xd54c, 0x080c, 0xb2d3, 0x080c, 0x9ab1, + 0x08c0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, + 0x35e7, 0x00fe, 0x00ee, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, + 0x9ab1, 0x0838, 0x080c, 0x99a5, 0x6003, 0x0002, 0x080c, 0xd7fb, + 0x0804, 0x9ab1, 0x2600, 0x2008, 0x0002, 0xbca9, 0xbc8a, 0xbca7, + 0xbc8a, 0xbc8a, 0xbca7, 0xbca7, 0xbca7, 0xbca7, 0xbc8a, 0xbca7, + 0xbc8a, 0xbca7, 0xbc8a, 0xbca7, 0xbca7, 0xbca7, 0xbca7, 0x080c, + 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6014, 0x2048, 0x080c, 0x6e9f, + 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x00e6, 0x0096, + 0x0026, 0x0016, 0x080c, 0xd0d8, 0x0568, 0x6014, 0x2048, 0xa864, + 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, + 0x556f, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, + 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd6bd, 0x0090, + 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, + 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, + 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, + 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, + 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, + 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x6604, + 0x96b6, 0x004d, 0x1120, 0x080c, 0xd5dc, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x0043, 0x1120, 0x080c, 0xd625, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x004b, 0x1120, 0x080c, 0xd651, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x0033, 0x1120, 0x080c, 0xd56e, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x0028, 0x1120, 0x080c, 0xd31e, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x0029, 0x1120, 0x080c, 0xd35f, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x001f, 0x1120, 0x080c, 0xb6ad, 0x0804, 0xbd82, 0x6604, + 0x96b6, 0x0000, 0x1118, 0x080c, 0xb9fb, 0x04e0, 0x6604, 0x96b6, + 0x0022, 0x1118, 0x080c, 0xb6e9, 0x04a8, 0x6604, 0x96b6, 0x0035, + 0x1118, 0x080c, 0xb80f, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, + 0x080c, 0xb990, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, + 0xb721, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb75d, + 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb79e, 0x0090, + 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb788, 0x0058, 0x91b6, + 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, + 0x0804, 0xc08e, 0x00be, 0x0005, 0x080c, 0xb36d, 0x0cd8, 0xbd9f, + 0xbdad, 0xbd9f, 0xbdf4, 0xbd9f, 0xbfab, 0xc09b, 0xbd9f, 0xbd9f, + 0xc064, 0xbd9f, 0xc07a, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, + 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xb2d3, 0xa001, + 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, + 0x080c, 0x6656, 0x0804, 0xb2d3, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe8ed, 0x11b0, 0x6010, + 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, + 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x666a, + 0x080c, 0x3279, 0x080c, 0xb2d3, 0x0098, 0x2001, 0x000a, 0x080c, + 0x666a, 0x080c, 0x3279, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, + 0x9547, 0x080c, 0x9ab1, 0x0020, 0x2001, 0x0001, 0x080c, 0xbf7b, + 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, + 0x6656, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, + 0x080c, 0x6696, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, + 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xbf50, 0x6010, 0x2058, + 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xc1ea, 0x0804, 0xbebd, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x0904, 0xbe5f, 0x00d6, 0x080c, + 0x7637, 0x01a0, 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, + 0x0904, 0xbe5e, 0x080c, 0x57e9, 0x1598, 0x6014, 0x2048, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, + 0x2058, 0xb910, 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, + 0x8008, 0x080c, 0x6ac7, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, + 0x0dc5, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, + 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c, 0xd6bd, 0x0040, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, + 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x3279, 0x080c, 0xb2d3, + 0x001e, 0x080c, 0x334c, 0x00de, 0x0804, 0xbf55, 0x00de, 0x080c, + 0xc1df, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, + 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd6bd, + 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, + 0x0006, 0x080c, 0x666a, 0x080c, 0x3279, 0x080c, 0xb2d3, 0x0804, + 0xbf55, 0x080c, 0xbf63, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, + 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd6bd, 0x08f8, + 0x080c, 0xbf59, 0x0160, 0x9006, 0x080c, 0x6656, 0x2001, 0x0004, + 0x080c, 0x6696, 0x2001, 0x0007, 0x080c, 0x666a, 0x08a0, 0x2001, + 0x0004, 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x9547, 0x080c, 0x9ab1, 0x0804, 0xbf55, 0xb85c, 0xd0e4, 0x0178, + 0x080c, 0xd4ee, 0x080c, 0x7637, 0x0118, 0xd0dc, 0x1904, 0xbe7f, + 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbe7f, 0x080c, + 0xd52b, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, + 0xeab9, 0x000e, 0x1904, 0xbe7f, 0xc0b5, 0x2012, 0x2001, 0x0006, + 0x080c, 0x666a, 0x9006, 0x080c, 0x6656, 0x00c6, 0x2001, 0x180f, + 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, + 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, + 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, + 0x080c, 0x28bc, 0x00f6, 0x2100, 0x900e, 0x080c, 0x2873, 0x795e, + 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, + 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, + 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28bc, 0x00f6, + 0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x2873, + 0x795e, 0x00fe, 0x8108, 0x080c, 0x66b9, 0x2b00, 0x00ce, 0x1904, + 0xbe7f, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, + 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, + 0xb916, 0x2001, 0x0002, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0028, + 0x080c, 0xbcb6, 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, + 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xefed, 0x0190, 0x2071, + 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, + 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, + 0xba16, 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, + 0x080c, 0x666a, 0x080c, 0x57e9, 0x1120, 0x2001, 0x0007, 0x080c, + 0x6696, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, + 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, + 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c44, + 0x004e, 0x003e, 0x080c, 0x3279, 0x6020, 0x9086, 0x000a, 0x1108, + 0x0005, 0x0804, 0xb2d3, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, + 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xc05a, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x0904, 0xc00d, 0x00d6, 0x080c, 0x7637, 0x01a0, + 0x0026, 0x2011, 0x0010, 0x080c, 0x6ac7, 0x002e, 0x0904, 0xc00c, + 0x080c, 0x57e9, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, + 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, + 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, + 0x6ac7, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0dc5, 0x2048, + 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, + 0x900e, 0x2011, 0x4009, 0x080c, 0xd6bd, 0x0040, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, + 0xb9a0, 0x0016, 0x080c, 0x3279, 0x080c, 0xb2d3, 0x001e, 0x080c, + 0x334c, 0x00de, 0x0804, 0xc05f, 0x00de, 0x080c, 0x57e9, 0x1170, + 0x6014, 0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, + 0x2021, 0x0006, 0x080c, 0x4dfb, 0x004e, 0x003e, 0x00d6, 0x6010, + 0x2058, 0x080c, 0x67bf, 0x080c, 0xbde2, 0x00de, 0x080c, 0xc2b5, + 0x1588, 0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, + 0x080c, 0x666a, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, + 0x4000, 0x080c, 0xd6bd, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0029, 0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, + 0x009e, 0x080c, 0x3279, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, + 0xb2d3, 0x0028, 0x080c, 0xbcb6, 0x9006, 0x080c, 0xbf7b, 0x001e, + 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, + 0x0014, 0x1160, 0x2001, 0x0002, 0x080c, 0x666a, 0x6003, 0x0001, + 0x6007, 0x0001, 0x080c, 0x9547, 0x0804, 0x9ab1, 0x2001, 0x0001, + 0x0804, 0xbf7b, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, + 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x666a, + 0x0804, 0xb2d3, 0x2001, 0x0001, 0x0804, 0xbf7b, 0x0002, 0xbd9f, + 0xc0a6, 0xbd9f, 0xc0e9, 0xbd9f, 0xc196, 0xc09b, 0xbda2, 0xbd9f, + 0xc1aa, 0xbd9f, 0xc1bc, 0x6604, 0x9686, 0x0003, 0x0904, 0xbfab, + 0x96b6, 0x001e, 0x1110, 0x080c, 0xb2d3, 0x0005, 0x00b6, 0x00d6, + 0x00c6, 0x080c, 0xc1ce, 0x11a0, 0x9006, 0x080c, 0x6656, 0x080c, + 0x3250, 0x080c, 0xd7f8, 0x2001, 0x0002, 0x080c, 0x666a, 0x6003, + 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0428, + 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, + 0x000a, 0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, + 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3250, 0x080c, + 0xd7f8, 0x2001, 0x0001, 0x080c, 0xbf7b, 0x00ce, 0x00de, 0x00be, + 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xc1dc, 0x00d6, + 0x2069, 0x197c, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, + 0x9086, 0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, + 0x00de, 0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x6656, 0x2001, + 0x0002, 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, + 0x9547, 0x080c, 0x9ab1, 0x0804, 0xc166, 0x080c, 0xd0d8, 0x01b0, + 0x6014, 0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, + 0x0016, 0x2001, 0x0002, 0x080c, 0xd71a, 0x00b0, 0x6014, 0x2048, + 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, + 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, + 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c, 0xbcb6, 0x2009, 0x026e, + 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, + 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, + 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, + 0x2001, 0x0004, 0x080c, 0x666a, 0x2001, 0x0028, 0x601a, 0x6007, + 0x0052, 0x0020, 0x2001, 0x0001, 0x080c, 0xbf7b, 0x002e, 0x00be, + 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, + 0xd0d8, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, + 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, + 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, + 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x60c1, 0x00ee, 0x0010, 0x080c, 0x3250, 0x0860, 0x2001, 0x0004, + 0x080c, 0x666a, 0x080c, 0xc1dc, 0x1140, 0x6003, 0x0001, 0x6007, + 0x0003, 0x080c, 0x9547, 0x0804, 0x9ab1, 0x080c, 0xbcb6, 0x9006, + 0x0804, 0xbf7b, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x666a, + 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x9547, 0x0804, 0x9ab1, + 0x2001, 0x0001, 0x0804, 0xbf7b, 0x00f9, 0x1160, 0x2001, 0x000a, + 0x080c, 0x666a, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9547, + 0x0804, 0x9ab1, 0x2001, 0x0001, 0x0804, 0xbf7b, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, + 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, + 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c, 0x6733, 0x001e, 0x00ce, + 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, + 0x6010, 0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, + 0x080c, 0xc287, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, + 0x080c, 0x6a9f, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, + 0xec31, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, + 0x2009, 0x0001, 0x080c, 0x321b, 0x00e6, 0x2071, 0x1800, 0x080c, + 0x3000, 0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, + 0x080c, 0x334c, 0x8108, 0x1f04, 0xc220, 0x015e, 0x00ce, 0x080c, + 0xc1df, 0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, + 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, + 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, + 0x2102, 0x9184, 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, + 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, + 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, + 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, + 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x28bc, 0x080c, 0x7637, + 0x0170, 0x2071, 0x0260, 0x2069, 0x1982, 0x7048, 0x206a, 0x704c, + 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd4ee, 0x0040, + 0x2001, 0x0006, 0x080c, 0x666a, 0x080c, 0x3279, 0x080c, 0xb2d3, + 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, + 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, + 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, + 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, 0x1148, 0x2011, 0x027a, + 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xc379, 0x1100, 0x015e, + 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, + 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, + 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, + 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, + 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, + 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f1, + 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, + 0x7254, 0x7074, 0x9202, 0x1a04, 0xc345, 0x080c, 0x8cf7, 0x0904, + 0xc33e, 0x080c, 0xec62, 0x0904, 0xc33e, 0x6720, 0x9786, 0x0007, + 0x0904, 0xc33e, 0x2500, 0x9c06, 0x0904, 0xc33e, 0x2400, 0x9c06, + 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, + 0x9086, 0x0004, 0x1110, 0x080c, 0x1a8e, 0x9786, 0x000a, 0x0148, + 0x080c, 0xd2e0, 0x1130, 0x00ce, 0x080c, 0xbcb6, 0x080c, 0xb306, + 0x00e8, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x01a8, 0x9786, 0x0003, + 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, + 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x6e92, 0x080c, 0xd2c3, 0x080c, 0xb306, 0x00ce, 0x9ce0, 0x0018, + 0x7068, 0x9c02, 0x1210, 0x0804, 0xc2e8, 0x012e, 0x000e, 0x002e, + 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, + 0x0006, 0x1118, 0x080c, 0xebd4, 0x0c30, 0x9786, 0x0009, 0x1148, + 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb352, + 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, + 0x1130, 0x8210, 0x8318, 0x1f04, 0xc365, 0x9006, 0x0005, 0x2304, + 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, + 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, + 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, + 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, + 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, + 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, + 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, + 0x8210, 0x8318, 0x1f04, 0xc3a3, 0x9006, 0x0005, 0x918d, 0x0001, + 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd2cf, + 0x0120, 0x080c, 0xd2e0, 0x0168, 0x0028, 0x080c, 0x3279, 0x080c, + 0xd2e0, 0x0138, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, 0x9ab1, + 0x0005, 0x080c, 0xbcb6, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, + 0x0040, 0x0208, 0x000a, 0x0005, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, + 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3ea, + 0xc3ea, 0xc3ea, 0xc3ea, 0xc3e8, 0xc3e8, 0xc3e8, 0xc3ea, 0xc3e8, + 0x080c, 0x0dc5, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, + 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, + 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc482, + 0x9186, 0x0027, 0x1520, 0x080c, 0x99a5, 0x080c, 0x3250, 0x080c, + 0xd7f8, 0x0096, 0x6114, 0x2148, 0x080c, 0xd0d8, 0x0198, 0x080c, + 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0068, 0xa867, 0x0103, 0xa87b, + 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6e9f, + 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb2d3, 0x0804, 0x9ab1, 0x9186, + 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, + 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, + 0x0048, 0x190c, 0x0dc5, 0x080c, 0xd809, 0x0130, 0x6000, 0x9086, + 0x0002, 0x1110, 0x0804, 0xc4c0, 0x0005, 0x0002, 0xc45c, 0xc45a, + 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, 0xc45a, + 0xc45a, 0xc477, 0xc477, 0xc477, 0xc477, 0xc45a, 0xc477, 0xc45a, + 0xc477, 0xc45a, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6114, + 0x2148, 0x080c, 0xd0d8, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c, 0x6e9f, 0x080c, + 0xd2c3, 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, + 0x99a5, 0x080c, 0xd2e0, 0x090c, 0xbcb6, 0x080c, 0xb2d3, 0x080c, + 0x9ab1, 0x0005, 0x0002, 0xc499, 0xc497, 0xc497, 0xc497, 0xc497, + 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc497, 0xc4b0, 0xc4b0, + 0xc4b0, 0xc4b0, 0xc497, 0xc4ba, 0xc497, 0xc4b0, 0xc497, 0x080c, + 0x0dc5, 0x0096, 0x080c, 0x99a5, 0x6014, 0x2048, 0x2001, 0x1988, + 0x2004, 0x6042, 0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, + 0x9085, 0x0400, 0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, + 0x080c, 0x99a5, 0x080c, 0xd7fb, 0x080c, 0xd800, 0x6003, 0x000f, + 0x0804, 0x9ab1, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x0804, 0x9ab1, + 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4de, 0xc5be, 0xc4dc, + 0xc5f2, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, + 0xc4dc, 0xc4dc, 0xc4dc, 0xc5f2, 0x080c, 0x0dc5, 0x00b6, 0x0096, + 0x6114, 0x2148, 0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc5ad, 0xa87b, 0x0000, 0xa867, + 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xc78b, 0x080c, 0x6cb9, 0x6210, 0x2258, 0xba3c, 0x82ff, + 0x0110, 0x8211, 0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc58e, 0x080c, + 0xb2d3, 0x009e, 0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, + 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc592, 0x7348, 0xab92, 0x734c, + 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, + 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, + 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, + 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, + 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, + 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc4e5, + 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, + 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, + 0xcc85, 0x003e, 0xd6cc, 0x0904, 0xc4fa, 0x7154, 0xa98a, 0x81ff, + 0x0904, 0xc4fa, 0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, + 0x2011, 0x0029, 0x080c, 0xcc85, 0x2011, 0x0205, 0x2013, 0x0000, + 0x080c, 0xd786, 0x0804, 0xc4fa, 0xa868, 0xd0fc, 0x0120, 0x2009, + 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, 0xcc24, 0x00ae, + 0x080c, 0xd786, 0x080c, 0xcc75, 0x0804, 0xc4fc, 0x080c, 0xd3d8, + 0x0804, 0xc509, 0xa87c, 0xd0ac, 0x0904, 0xc515, 0xa880, 0xd0bc, + 0x1904, 0xc515, 0x9684, 0x0400, 0x0130, 0xa838, 0xab34, 0x9305, + 0x0904, 0xc515, 0x00b8, 0x7348, 0xa838, 0x9306, 0x1198, 0x734c, + 0xa834, 0x931e, 0x0904, 0xc515, 0x0068, 0xa87c, 0xd0ac, 0x0904, + 0xc4ed, 0xa838, 0xa934, 0x9105, 0x0904, 0xc4ed, 0xa880, 0xd0bc, + 0x1904, 0xc4ed, 0x080c, 0xd412, 0x0804, 0xc509, 0x0096, 0x00f6, + 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04, 0x7b00, + 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140, 0x6003, + 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, + 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, + 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe, 0x6043, + 0x0000, 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x080c, 0x9bd3, + 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xc60f, 0xc60f, 0xc60f, 0xc60f, 0xc60f, + 0xc611, 0xc6a7, 0xc60f, 0xc60f, 0xc6be, 0xc74e, 0xc60f, 0xc60f, + 0xc60f, 0xc60f, 0xc763, 0xc60f, 0xc60f, 0xc60f, 0xc60f, 0x080c, + 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, + 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, + 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, + 0x00be, 0x86ff, 0x0904, 0xc6a2, 0x9694, 0xff00, 0x9284, 0x0c00, + 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, + 0xc6a2, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, + 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, + 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, + 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, + 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, + 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, + 0x080c, 0xcc85, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, + 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, + 0x0029, 0x080c, 0xcc85, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, + 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, + 0x080c, 0xcc24, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x00f6, + 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, + 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a, 0x00ae, + 0x00fe, 0x2c10, 0x080c, 0x1be0, 0x0804, 0xa6b6, 0x6003, 0x0002, + 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048, 0xa87c, + 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00, 0x2078, + 0x080c, 0x1768, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003, 0x0002, + 0x009e, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0096, 0x2001, 0x1988, + 0x2004, 0x6042, 0x080c, 0x9a61, 0x080c, 0x9bd3, 0x6114, 0x2148, + 0xa97c, 0xd1e4, 0x0904, 0xc749, 0xd1cc, 0x05c8, 0xa978, 0xa868, + 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e, 0x810f, + 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019, 0x2098, + 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882, 0x000e, + 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, + 0x001e, 0x0458, 0x0016, 0x080c, 0x0fc0, 0x009e, 0xa87c, 0xc0cc, + 0xa87e, 0xa974, 0x0016, 0x080c, 0xcc75, 0x001e, 0x00f0, 0xa867, + 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180, 0x9086, + 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0xa87b, + 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, + 0x0000, 0x0016, 0x080c, 0x6cb9, 0x001e, 0xd1e4, 0x1120, 0x080c, + 0xb2d3, 0x009e, 0x0005, 0x080c, 0xd3d8, 0x0cd8, 0x6004, 0x9086, + 0x0040, 0x1120, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x2019, 0x0001, + 0x080c, 0xaa49, 0x6003, 0x0002, 0x080c, 0xd800, 0x080c, 0x9a61, + 0x080c, 0x9bd3, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, + 0x99a5, 0x080c, 0x9ab1, 0x2019, 0x0001, 0x080c, 0xaa49, 0x080c, + 0x9a61, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x0096, 0x6114, 0x2148, + 0x080c, 0xd0d8, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, + 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb2d3, + 0x080c, 0x9bd3, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, + 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, + 0x2009, 0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, + 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, + 0x000a, 0x0005, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7c0, + 0xc7be, 0xc7be, 0xc866, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, + 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc7be, 0xc998, 0x080c, 0x0dc5, + 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150, + 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, + 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, + 0x86ff, 0x0904, 0xc85f, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, + 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc85f, + 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, + 0x0c38, 0x080c, 0x100e, 0x090c, 0x0dc5, 0x2900, 0xb07a, 0xb77c, + 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, + 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, + 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, + 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, + 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, + 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, + 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xcc85, 0x003e, + 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, + 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xcc85, + 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xcc24, 0x080c, + 0x1a5a, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1988, + 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c, 0xd1e4, + 0x0904, 0xc993, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc962, 0xa978, 0xa868, + 0xd0fc, 0x0904, 0xc923, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, + 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, + 0xc8f0, 0x9086, 0x0028, 0x1904, 0xc8dc, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x0804, 0xc8f8, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, + 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, + 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, + 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, + 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x9006, + 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140, + 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, + 0x080c, 0xd412, 0x0804, 0xc993, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc78b, + 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006, + 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019, + 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, + 0x080c, 0xd786, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0fc0, + 0x001e, 0x0804, 0xc98f, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184, + 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b, + 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015, + 0xb07b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xb174, 0xc1dc, 0xb176, + 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040, + 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc78b, + 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c, + 0x0fc0, 0x009e, 0x080c, 0xd786, 0xa974, 0x0016, 0x080c, 0xcc75, + 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, + 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0, + 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xd6a6, 0x0118, 0xa974, + 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050, + 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, + 0x190c, 0xc78b, 0xa974, 0x0016, 0x080c, 0x6cb9, 0x001e, 0xd1e4, + 0x1120, 0x080c, 0xb2d3, 0x009e, 0x0005, 0x080c, 0xd3d8, 0x0cd8, + 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1a7a, 0x009e, + 0x0005, 0x080c, 0x99a5, 0x0010, 0x080c, 0x9a61, 0x080c, 0xd0d8, + 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xd2e0, 0x1118, 0x080c, + 0xbcb6, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, + 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, + 0x080c, 0xef85, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x009e, 0x080c, + 0xb2d3, 0x080c, 0x9ab1, 0x0804, 0x9bd3, 0xa87b, 0x0004, 0x0c90, + 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, + 0xc9f1, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, + 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0xc9ef, 0x080c, + 0x0dc5, 0x080c, 0x57dd, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, + 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, + 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, + 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, + 0x080c, 0x6e9f, 0x009e, 0x0804, 0xb2d3, 0x9182, 0x0085, 0x0002, + 0xca27, 0xca25, 0xca25, 0xca33, 0xca25, 0xca25, 0xca25, 0xca25, + 0xca25, 0xca25, 0xca25, 0xca25, 0xca25, 0x080c, 0x0dc5, 0x6003, + 0x0001, 0x6106, 0x080c, 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, + 0x9ab1, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, + 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xd0c6, 0x01f8, 0x2268, + 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, + 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xcce6, 0x00de, 0x00ce, 0x0158, + 0x702c, 0xd084, 0x1118, 0x080c, 0xccb0, 0x0010, 0x6803, 0x0002, + 0x6007, 0x0086, 0x0028, 0x080c, 0xccd2, 0x0d90, 0x6007, 0x0087, + 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x7220, 0x080c, + 0xd0c6, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd412, + 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, + 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, + 0x1a0c, 0x0dc5, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, + 0x9186, 0x0014, 0x190c, 0x0dc5, 0x080c, 0x99a5, 0x0096, 0x6014, + 0x2048, 0x080c, 0xd0d8, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x009e, 0x080c, 0xb306, 0x0804, + 0x9ab1, 0xcab6, 0xcab8, 0xcab8, 0xcab6, 0xcab6, 0xcab6, 0xcab6, + 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0xcab6, 0x080c, 0x0dc5, + 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x9186, + 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8, 0x9186, + 0x0027, 0x11f8, 0x080c, 0x99a5, 0x080c, 0x3250, 0x080c, 0xd7f8, + 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0150, 0xa867, 0x0103, + 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6e9f, 0x080c, 0xd2c3, + 0x009e, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x080c, 0xb36d, + 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x99a5, 0x0096, 0x6014, + 0x2048, 0x080c, 0xd0d8, 0x0d60, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002, 0xcb0e, + 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0xcb26, 0xcb0c, 0xcb0c, + 0xcb0c, 0xcb0c, 0xcb0c, 0xcb0c, 0x080c, 0x0dc5, 0x080c, 0x99a5, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, + 0x601a, 0x6003, 0x000c, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x99a5, + 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, + 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, + 0x601a, 0x6003, 0x000e, 0x080c, 0x9ab1, 0x0005, 0x9182, 0x0092, + 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xb36d, 0xcb54, + 0xcb54, 0xcb54, 0xcb54, 0xcb56, 0xcba3, 0xcb54, 0xcb54, 0xcb54, + 0xcb54, 0xcb54, 0xcb54, 0xcb54, 0x080c, 0x0dc5, 0x0096, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x009e, 0x0804, 0xcbb7, 0x080c, 0xd0d8, 0x1118, 0x080c, 0xd2c3, + 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c, 0xd2c3, + 0xa867, 0x0103, 0x080c, 0xd7c3, 0x080c, 0x6e9f, 0x00d6, 0x2c68, + 0x080c, 0xb27d, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, + 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x6910, 0x6112, 0x080c, 0xd554, 0x6954, 0x6156, 0x6023, + 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x2d60, 0x00de, 0x080c, + 0xb2d3, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, + 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, + 0x2c68, 0x080c, 0xd759, 0x11f0, 0x080c, 0xb27d, 0x01d8, 0x6106, + 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, + 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, + 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xd554, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x2d60, 0x00de, 0x0804, 0xb2d3, 0x0096, 0x6014, + 0x2048, 0x080c, 0xd0d8, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, + 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, + 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd3d4, 0xa877, + 0x0000, 0x080c, 0x6e9f, 0x080c, 0xd2c3, 0x009e, 0x0804, 0xb2d3, + 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0140, 0xa867, + 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6e9f, 0x009e, + 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, + 0x0027, 0x0118, 0x080c, 0xb36d, 0x0030, 0x080c, 0x99a5, 0x080c, + 0xb306, 0x080c, 0x9ab1, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, + 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, + 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, + 0x080c, 0xcc85, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, + 0x0fc0, 0x080c, 0x100e, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, + 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, + 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, + 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, + 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, + 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, + 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6e9f, 0x2a48, + 0x0cb8, 0x080c, 0x6e9f, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, + 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, + 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, + 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, + 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, + 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, + 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, + 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xd0d8, + 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x710b, 0x080c, + 0x6e92, 0x080c, 0xd2c3, 0x009e, 0x080c, 0xb306, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, + 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, + 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, + 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, + 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, + 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, + 0xcd1d, 0xcd1d, 0xcd18, 0xcd3f, 0xcd0f, 0xcd18, 0xcd3f, 0xcd18, + 0xcd18, 0x9265, 0xcd18, 0xcd18, 0xcd18, 0xcd0f, 0xcd0f, 0x080c, + 0x0dc5, 0x0036, 0x2019, 0x0010, 0x080c, 0xe746, 0x003e, 0x0005, + 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, + 0x6014, 0x2048, 0x080c, 0xd0d8, 0x01c0, 0xa864, 0x9086, 0x0139, + 0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, + 0x0005, 0x080c, 0x710b, 0x080c, 0xd3d4, 0x080c, 0x6e92, 0x080c, + 0xb306, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0002, 0xcd55, 0xcd85, 0xcd57, + 0xcda6, 0xcd80, 0xcd55, 0xcd18, 0xcd1d, 0xcd1d, 0xcd18, 0xcd18, + 0xcd18, 0xcd18, 0xcd18, 0xcd18, 0xcd18, 0x080c, 0x0dc5, 0x86ff, + 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, + 0x080c, 0xd0d8, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, + 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd3d4, + 0x009e, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0002, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x9085, 0x0001, 0x0005, + 0x0066, 0x080c, 0x1a8e, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e8, + 0x7024, 0x9c06, 0x1120, 0x080c, 0xa9d3, 0x00ee, 0x0840, 0x6020, + 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, + 0x0001, 0x2c40, 0x080c, 0xaafb, 0x009e, 0x008e, 0x0010, 0x080c, + 0xa8d0, 0x00ee, 0x1904, 0xcd57, 0x0804, 0xcd18, 0x0036, 0x00e6, + 0x2071, 0x19e8, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xaa49, + 0x00ee, 0x003e, 0x0804, 0xcd57, 0x080c, 0xac2b, 0x00ee, 0x003e, + 0x1904, 0xcd57, 0x0804, 0xcd18, 0x00c6, 0x6020, 0x9084, 0x000f, + 0x0013, 0x00ce, 0x0005, 0xcdd9, 0xcea3, 0xd011, 0xcde3, 0xb306, + 0xcdd9, 0xe73c, 0xd805, 0xcea3, 0x9237, 0xd09d, 0xcdd2, 0xcdd2, + 0xcdd2, 0xcdd2, 0x080c, 0x0dc5, 0x080c, 0xd2e0, 0x1110, 0x080c, + 0xbcb6, 0x0005, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0804, 0xb2d3, + 0x601b, 0x0001, 0x0005, 0x080c, 0xd0d8, 0x0130, 0x6014, 0x0096, + 0x2048, 0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0010, 0x1a0c, + 0x0dc5, 0x0002, 0xce02, 0xce04, 0xce28, 0xce3c, 0xce62, 0xce02, + 0xcdd9, 0xcdd9, 0xcdd9, 0xce3c, 0xce3c, 0xce02, 0xce02, 0xce02, + 0xce02, 0xce46, 0x080c, 0x0dc5, 0x00e6, 0x6014, 0x0096, 0x2048, + 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e8, 0x7024, 0x9c06, + 0x01a0, 0x080c, 0xa8d0, 0x080c, 0xd79d, 0x6007, 0x0085, 0x6003, + 0x000b, 0x6023, 0x0002, 0x2001, 0x1987, 0x2004, 0x601a, 0x080c, + 0x94ff, 0x080c, 0x9ab1, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, + 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, + 0xd79d, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, + 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, + 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x57dd, + 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, + 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, + 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6e9f, 0x009e, + 0x0804, 0xb2d3, 0x6014, 0x0096, 0x904d, 0x05c0, 0xa97c, 0xd1e4, + 0x05a8, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, + 0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, + 0x0030, 0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, 0x2004, 0x9086, + 0x0041, 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa880, + 0xd0f4, 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0068, + 0x009e, 0x00c6, 0x080c, 0x236e, 0x00ce, 0x6000, 0x9086, 0x0004, + 0x1120, 0x2009, 0x0048, 0x080c, 0xb352, 0x0005, 0x009e, 0x080c, + 0x1a8e, 0x0804, 0xce28, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, + 0x000b, 0x0005, 0xceba, 0xcde0, 0xcebc, 0xceba, 0xcebc, 0xcebc, + 0xcdda, 0xceba, 0xcdd4, 0xcdd4, 0xceba, 0xceba, 0xceba, 0xceba, + 0xceba, 0xceba, 0x080c, 0x0dc5, 0x6010, 0x00b6, 0x2058, 0xb804, + 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dc5, 0x00b6, + 0x0013, 0x00be, 0x0005, 0xced7, 0xcfa8, 0xced9, 0xcf19, 0xced9, + 0xcf19, 0xced9, 0xcee7, 0xced7, 0xcf19, 0xced7, 0xcf08, 0x080c, + 0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, + 0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcfa4, 0x6004, + 0x080c, 0xd2e0, 0x0904, 0xcfc1, 0x908e, 0x0004, 0x1110, 0x080c, + 0x3279, 0x908e, 0x0021, 0x0904, 0xcfc5, 0x908e, 0x0022, 0x0904, + 0xd00c, 0x908e, 0x003d, 0x0904, 0xcfc5, 0x908e, 0x0039, 0x0904, + 0xcfc9, 0x908e, 0x0035, 0x0904, 0xcfc9, 0x908e, 0x001e, 0x0178, + 0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, + 0x9086, 0x0006, 0x0110, 0x080c, 0x3250, 0x080c, 0xbcb6, 0x0804, + 0xb306, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcf95, + 0x9186, 0x0002, 0x1904, 0xcf6a, 0x2001, 0x1837, 0x2004, 0xd08c, + 0x11c8, 0x080c, 0x7637, 0x11b0, 0x080c, 0xd7e3, 0x0138, 0x080c, + 0x765a, 0x1120, 0x080c, 0x7541, 0x0804, 0xcff5, 0x2001, 0x197d, + 0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x7563, + 0x0804, 0xcff5, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x0080, 0x0130, + 0x2001, 0x1837, 0x2004, 0xd0ac, 0x1904, 0xcff5, 0xb8a0, 0x9082, + 0x0081, 0x1a04, 0xcff5, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, + 0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, + 0x6043, 0x0000, 0x080c, 0xb27d, 0x0128, 0x2b00, 0x6012, 0x6023, + 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, + 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, + 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60c1, + 0x00ee, 0x080c, 0xbcb6, 0x0030, 0x080c, 0xbcb6, 0x080c, 0x3250, + 0x080c, 0xd7f8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3279, + 0x012e, 0x00ee, 0x080c, 0xb306, 0x0005, 0x2001, 0x0002, 0x080c, + 0x666a, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, + 0x9ab1, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x3279, 0x0804, 0xcf15, + 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, + 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xcf6a, 0x8001, 0xb842, + 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00de, 0x00ce, + 0x0898, 0x080c, 0xbcb6, 0x0804, 0xcf17, 0x080c, 0xbcf2, 0x0804, + 0xcf17, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd759, 0x00de, 0x0118, + 0x080c, 0xb2d3, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, + 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x603c, 0x600a, 0x2001, 0x1987, 0x2004, 0x601a, 0x602c, 0x2c08, + 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, + 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x00de, 0x00ce, 0x080c, + 0xbcb6, 0x080c, 0x3250, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, + 0x3279, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043, + 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xb708, 0x1904, 0xcfc1, + 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x0096, 0x00d6, + 0x001b, 0x00de, 0x009e, 0x0005, 0xd02c, 0xd02c, 0xd02c, 0xd02c, + 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xd02c, 0xcdd9, 0xd02c, 0xcde0, + 0xd02e, 0xcde0, 0xd048, 0xd02c, 0x080c, 0x0dc5, 0x6004, 0x9086, + 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, + 0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, + 0x008b, 0x6003, 0x000d, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, + 0x080c, 0xd7d7, 0x0118, 0x080c, 0xd7ea, 0x0010, 0x080c, 0xd7f8, + 0x080c, 0xd2c3, 0x080c, 0xd0d8, 0x0570, 0x080c, 0x3250, 0x080c, + 0xd0d8, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, + 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6e9f, 0x2c68, + 0x080c, 0xb27d, 0x0150, 0x6810, 0x6012, 0x080c, 0xd554, 0x00c6, + 0x2d60, 0x080c, 0xb306, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, + 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, + 0x080c, 0x9ab1, 0x00c8, 0x080c, 0xd7d7, 0x0138, 0x6034, 0x9086, + 0x4000, 0x1118, 0x080c, 0x3250, 0x08d0, 0x6034, 0x908c, 0xff00, + 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, + 0x3250, 0x0868, 0x080c, 0xb306, 0x0005, 0x6000, 0x908a, 0x0010, + 0x1a0c, 0x0dc5, 0x0002, 0xd0b3, 0xd0b3, 0xd0b7, 0xd0b5, 0xd0c1, + 0xd0b3, 0xd0b3, 0xb306, 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b3, 0xd0b3, + 0xd0b3, 0xd0b3, 0xd0b3, 0x080c, 0x0dc5, 0x080c, 0xac2b, 0x6114, + 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6e9f, 0x009e, 0x0804, + 0xb2d3, 0x601c, 0xd084, 0x190c, 0x1a8e, 0x0c88, 0x9284, 0x0007, + 0x1158, 0x9282, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, + 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, + 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, + 0x9086, 0xf000, 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, + 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, + 0x1cd0, 0x2071, 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, + 0x9206, 0x11f8, 0x080c, 0xd7e3, 0x0180, 0x9286, 0x0001, 0x1168, + 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, 0x3250, 0x080c, 0xd7f8, + 0x00c6, 0x080c, 0xb306, 0x00ce, 0x0060, 0x080c, 0xd4ce, 0x0148, + 0x080c, 0xd2e0, 0x1110, 0x080c, 0xbcb6, 0x00c6, 0x080c, 0xb2d3, + 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, + 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, + 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab7, 0x6112, + 0x080c, 0x3250, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, + 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, + 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c, 0x57dd, 0x0118, 0x080c, + 0xd207, 0x0168, 0x080c, 0xd554, 0x6023, 0x0003, 0x2009, 0x004b, + 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb325, + 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xd554, 0x6023, + 0x0003, 0x0016, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, 0x9577, + 0x2c08, 0x080c, 0xe91c, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, + 0xb2d3, 0x9085, 0x0001, 0x0070, 0x080c, 0x57dd, 0x0128, 0xd18c, + 0x1170, 0x080c, 0xd207, 0x0148, 0x2009, 0x004c, 0x080c, 0xb352, + 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, + 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, + 0x00c6, 0x0046, 0x0016, 0x080c, 0xb27d, 0x2c78, 0x05a0, 0x7e56, + 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, + 0xd219, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, + 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb2d3, + 0x00d0, 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, + 0xb2d3, 0x0088, 0x2f60, 0x080c, 0x57dd, 0x0138, 0xd18c, 0x1118, + 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, + 0xb352, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, + 0x00f6, 0x00c6, 0x0046, 0x080c, 0xb27d, 0x2c78, 0x0508, 0x7e56, + 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, + 0x009e, 0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, + 0xb2d3, 0x0060, 0x2f60, 0x080c, 0x57dd, 0x0120, 0xd18c, 0x1160, + 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xb352, 0x9085, 0x0001, + 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, + 0x080c, 0x4be4, 0x00ce, 0x1120, 0x080c, 0xb2d3, 0x9006, 0x0005, + 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, + 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x6858, + 0x0158, 0x2001, 0xd21e, 0x0006, 0x900e, 0x2400, 0x080c, 0x710b, + 0x080c, 0x6e9f, 0x000e, 0x0807, 0x2418, 0x080c, 0x993f, 0xbaa0, + 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x96bc, + 0x008e, 0x080c, 0x9577, 0x2f08, 0x2648, 0x080c, 0xe91c, 0xb93c, + 0x81ff, 0x090c, 0x978f, 0x080c, 0x9ab1, 0x012e, 0x007e, 0x009e, + 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0190, + 0x660a, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, + 0x6016, 0x2009, 0x001f, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x080c, 0xb325, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd554, + 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, + 0x00fe, 0x2009, 0x0021, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, + 0x0016, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0198, 0x660a, 0x2b08, + 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, + 0x0016, 0x080c, 0xb352, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, + 0xb325, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, + 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xb352, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, + 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, + 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, + 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, + 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, + 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, + 0x904d, 0x080c, 0xd0d8, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, + 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, + 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, + 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb325, + 0x0198, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, + 0x6016, 0x080c, 0x3250, 0x2009, 0x0028, 0x080c, 0xb352, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, + 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, + 0x080c, 0xbf63, 0x00be, 0x080c, 0xc1df, 0x6003, 0x0001, 0x6007, + 0x0029, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0078, 0x6014, 0x0096, + 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, + 0xd71a, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x0005, 0x0096, 0x6014, + 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, + 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6e9f, 0x012e, 0x009e, 0x080c, 0xb2d3, 0x0c30, 0x0096, + 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x666a, 0x00e8, + 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, + 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x67bf, 0x00be, 0x080c, + 0xc2b5, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, + 0x0160, 0x2001, 0x0006, 0x080c, 0x666a, 0x6014, 0x2048, 0xa868, + 0xd0fc, 0x0170, 0x080c, 0xb6dc, 0x0048, 0x6014, 0x2048, 0xa868, + 0xd0fc, 0x0528, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x009e, 0x0005, + 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6944, 0x1108, + 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x08f8, 0x6014, + 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, + 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x0840, 0xa878, 0x9086, + 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, + 0x6043, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, + 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x00c6, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, + 0x0013, 0x00ce, 0x0005, 0xcdd9, 0xd404, 0xd404, 0xd407, 0xec80, + 0xec9b, 0xec9e, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, 0xcdd9, + 0xcdd9, 0xcdd9, 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, + 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, + 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0550, 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, + 0x080c, 0xb27d, 0x0508, 0x7810, 0x6012, 0x080c, 0xd554, 0x7820, + 0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, + 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, + 0x0035, 0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x94ff, 0x080c, + 0x9ab1, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1988, + 0x2004, 0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, + 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, + 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, + 0x080c, 0x0fc0, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, + 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, + 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, + 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, + 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, + 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, + 0x6954, 0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, + 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x009e, 0x001e, 0x0005, 0x6024, + 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, + 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, + 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, + 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, + 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, + 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, + 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, + 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, + 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, + 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00e6, 0x2001, 0x1982, 0x200c, 0x8000, 0x2014, + 0x2001, 0x0032, 0x080c, 0x9375, 0x2001, 0x1986, 0x82ff, 0x1110, + 0x2011, 0x0014, 0x2202, 0x2001, 0x1984, 0x200c, 0x8000, 0x2014, + 0x2071, 0x196c, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x9375, + 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, + 0x1988, 0x9288, 0x000a, 0x2102, 0x2001, 0x1a98, 0x2102, 0x2001, + 0x0032, 0x080c, 0x1611, 0x080c, 0x6a84, 0x00ee, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1986, + 0x2003, 0x0028, 0x2001, 0x1987, 0x2003, 0x0014, 0x2071, 0x196c, + 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0x1988, 0x2009, 0x001e, + 0x2102, 0x2001, 0x1a98, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, + 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, + 0x080c, 0x1040, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xb27d, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, + 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xb352, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, + 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, + 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, + 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9d4c, 0x01d8, 0x707c, + 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, + 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x3299, 0x080c, + 0xb6dc, 0x0020, 0x080c, 0xbcb6, 0x080c, 0xb2d3, 0x00fe, 0x00ee, + 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xb27d, 0x0188, 0x2b08, 0x6112, + 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, + 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, + 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb27d, + 0x0180, 0x2b08, 0x6112, 0x080c, 0xd554, 0x6023, 0x0001, 0x2900, + 0x6016, 0x001e, 0x080c, 0xb352, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, + 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, + 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, + 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, + 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, + 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, + 0x0016, 0x200c, 0x080c, 0xde2e, 0x001e, 0xa804, 0x9005, 0x0110, + 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, + 0xbcb6, 0x080c, 0xb2d3, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, + 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, + 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, + 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9d4c, 0x01a8, 0x707c, + 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, + 0x3250, 0x080c, 0xb6dc, 0x0020, 0x080c, 0xbcb6, 0x080c, 0xb2d3, + 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, + 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, + 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, + 0x080c, 0x9d4c, 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, + 0xaad0, 0x9206, 0x1160, 0x080c, 0x3250, 0x0016, 0xa998, 0xaab0, + 0x9284, 0x1000, 0xc0fd, 0x080c, 0x5784, 0x001e, 0x0010, 0x080c, + 0x556f, 0x080c, 0xd0d8, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0x0080, 0x080c, 0xd0d8, 0x01b8, 0x6014, 0x2048, + 0x080c, 0x556f, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, + 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, + 0x080c, 0x6e9f, 0x012e, 0x080c, 0xb2d3, 0x00fe, 0x00ee, 0x009e, + 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, + 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, + 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, + 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, + 0x080c, 0xd0d8, 0x0904, 0xd716, 0x0096, 0x6314, 0x2348, 0xa87a, + 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, + 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6944, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, + 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, + 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, + 0x080c, 0x0f8b, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, + 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, + 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, + 0xa86a, 0x080c, 0x6e92, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, + 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, + 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, + 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x2873, 0x2118, + 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, + 0x2011, 0x8018, 0x080c, 0x4c44, 0x00a8, 0x9096, 0x0001, 0x1148, + 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, + 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, + 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, + 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, + 0x0008, 0x6a2c, 0x080c, 0xd0c6, 0x01f0, 0x2260, 0x6120, 0x9186, + 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, + 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, + 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, + 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, + 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170, 0xa9a8, 0x918c, + 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac, 0x0128, 0xa834, + 0xa938, 0x9115, 0x190c, 0xc78b, 0x0005, 0x0036, 0x2019, 0x0001, + 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xd0d8, 0x01c8, + 0x080c, 0xd2c3, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, + 0x2048, 0xa87c, 0x080c, 0xd2e0, 0x1118, 0x080c, 0xbcb6, 0x0040, + 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6e9f, + 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, + 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, + 0xa87b, 0x0005, 0x080c, 0xd3d4, 0xa877, 0x0000, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, + 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, + 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, + 0x00be, 0x2021, 0x0007, 0x080c, 0x4dfb, 0x004e, 0x003e, 0x0005, + 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1986, 0x2004, 0x601a, 0x0005, + 0x2001, 0x1988, 0x2004, 0x6042, 0x0005, 0x080c, 0xb2d3, 0x0804, + 0x9ab1, 0x2001, 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, + 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, + 0x2079, 0x19e8, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c, 0x93e2, + 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e, 0x012e, + 0x9085, 0x0001, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, + 0x1a0c, 0x0dc5, 0x001b, 0x006e, 0x00be, 0x0005, 0xd846, 0xdf8d, + 0xe102, 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0xd87d, 0xe186, + 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0xd846, 0x080c, 0x0dc5, + 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0dc5, 0x0013, 0x006e, + 0x0005, 0xd861, 0xe6d5, 0xd861, 0xd861, 0xd861, 0xd861, 0xd861, + 0xd861, 0xe682, 0xe729, 0xd861, 0xedb4, 0xedea, 0xedb4, 0xedea, + 0xd861, 0x080c, 0x0dc5, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0dc5, + 0x6000, 0x000a, 0x0005, 0xd87b, 0xe364, 0xe433, 0xe456, 0xe516, + 0xd87b, 0xe5f5, 0xe59e, 0xe192, 0xe658, 0xe66d, 0xd87b, 0xd87b, + 0xd87b, 0xd87b, 0xd87b, 0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, + 0x0dc5, 0x2100, 0x91b2, 0x0040, 0x1a04, 0xdcfd, 0x0002, 0xd8c7, + 0xdacb, 0xd8c7, 0xd8c7, 0xd8c7, 0xdad4, 0xd8c7, 0xd8c7, 0xd8c7, + 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, + 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c9, 0xd92c, + 0xd93b, 0xd99f, 0xd9ca, 0xda43, 0xdab6, 0xd8c7, 0xd8c7, 0xdad7, + 0xd8c7, 0xd8c7, 0xdaec, 0xdaf9, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, + 0xd8c7, 0xdb9f, 0xd8c7, 0xd8c7, 0xdbb3, 0xd8c7, 0xd8c7, 0xdb6e, + 0xd8c7, 0xd8c7, 0xd8c7, 0xdbcb, 0xd8c7, 0xd8c7, 0xd8c7, 0xdc48, + 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xd8c7, 0xdcc5, 0x080c, + 0x0dc5, 0x080c, 0x6a61, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, + 0x1128, 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, + 0x602f, 0x0009, 0x6017, 0x0000, 0x0804, 0xdac4, 0x080c, 0x69fd, + 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, + 0x0026, 0x2019, 0x0029, 0x080c, 0x96a4, 0x0076, 0x903e, 0x080c, + 0x9577, 0x2c08, 0x080c, 0xe91c, 0x007e, 0x001e, 0x001e, 0x002e, + 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x6733, 0xbe04, + 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, + 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xf015, 0x002e, + 0x001e, 0x1178, 0x080c, 0xe84e, 0x1904, 0xd997, 0x080c, 0xe7ea, + 0x1120, 0x6007, 0x0008, 0x0804, 0xdac4, 0x6007, 0x0009, 0x0804, + 0xdac4, 0x080c, 0xeab9, 0x0128, 0x080c, 0xe84e, 0x0d78, 0x0804, + 0xd997, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3374, 0x1904, 0xdcfa, + 0x6106, 0x080c, 0xe78e, 0x6007, 0x0006, 0x0804, 0xdac4, 0x6007, + 0x0007, 0x0804, 0xdac4, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, + 0x3374, 0x1904, 0xdcfa, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, + 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x6656, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, + 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, + 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, + 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, + 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, + 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe8b2, 0x1190, + 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, + 0x080c, 0x3299, 0x002e, 0x080c, 0x67bf, 0x6007, 0x000a, 0x00de, + 0x0804, 0xdac4, 0x6007, 0x000b, 0x00de, 0x0804, 0xdac4, 0x080c, + 0x3250, 0x080c, 0xd7f8, 0x6007, 0x0001, 0x0804, 0xdac4, 0x080c, + 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2071, + 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, + 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, + 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, + 0x3299, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xeff4, + 0x0804, 0xdac4, 0x080c, 0x6a61, 0x1140, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd8d6, 0x080c, + 0x69fd, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, + 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x6696, 0x002e, + 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, + 0x0006, 0x1904, 0xd997, 0x080c, 0xe8bf, 0x1120, 0x6007, 0x000e, + 0x0804, 0xdac4, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, + 0x3250, 0x080c, 0xd7f8, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, + 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xec31, 0x6010, + 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, + 0x0804, 0xdac4, 0x2001, 0x0001, 0x080c, 0x6656, 0x0156, 0x0016, + 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, + 0x080c, 0xc365, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, + 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd997, 0x9682, + 0x0007, 0x0a04, 0xd9f3, 0x0804, 0xd997, 0x6017, 0x1900, 0x6007, + 0x0009, 0x0804, 0xdac4, 0x080c, 0x6a61, 0x1140, 0x2001, 0x1837, + 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd8d6, + 0x080c, 0x69fd, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, + 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e, + 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, + 0x1904, 0xd997, 0x080c, 0xe8ed, 0x1138, 0x080c, 0xe7ea, 0x1120, + 0x6007, 0x0010, 0x0804, 0xdac4, 0x0046, 0x6410, 0x2458, 0xbca0, + 0x0046, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x004e, 0x0016, 0x9006, + 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, + 0xec31, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, + 0x6007, 0x0001, 0x0448, 0x080c, 0xeab9, 0x0198, 0x0016, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920, 0x0804, 0xd997, + 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x3374, + 0x1904, 0xdcfa, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, 0xdecb, + 0x1904, 0xd997, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x9547, + 0x080c, 0x9ab1, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, + 0x9547, 0x080c, 0x9ab1, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, + 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x080c, + 0xdecb, 0x1904, 0xd997, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, + 0x9547, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x3374, 0x1904, 0xdcfa, + 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, + 0x0005, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, 0x3374, 0x1904, + 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x0016, 0x0026, 0x00e6, + 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, + 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, + 0x11a0, 0x7240, 0x080c, 0xd0c6, 0x0570, 0x2260, 0x6008, 0x9086, + 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, + 0x0007, 0x1508, 0x080c, 0xb2d3, 0x04a0, 0x7244, 0x9286, 0xffff, + 0x0180, 0x2c08, 0x080c, 0xd0c6, 0x01b0, 0x2260, 0x7240, 0x6008, + 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, + 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xebfb, 0x1180, 0x7244, + 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, + 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, + 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, + 0xb2d3, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x9547, + 0x080c, 0x9ab1, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, + 0x080c, 0x6656, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, + 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xc365, 0x003e, 0x002e, + 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xdac4, 0x080c, + 0xbf7b, 0x080c, 0x7637, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, + 0x7651, 0x1138, 0x080c, 0x7932, 0x080c, 0x612e, 0x080c, 0x7563, + 0x0010, 0x080c, 0x760f, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, + 0x3374, 0x1904, 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x6106, + 0x080c, 0xdee7, 0x1120, 0x6007, 0x002b, 0x0804, 0xdac4, 0x6007, + 0x002c, 0x0804, 0xdac4, 0x080c, 0xee26, 0x1904, 0xdcfa, 0x080c, + 0x3374, 0x1904, 0xdcfa, 0x080c, 0xdecb, 0x1904, 0xd997, 0x6106, + 0x080c, 0xdeec, 0x1120, 0x6007, 0x002e, 0x0804, 0xdac4, 0x6007, + 0x002f, 0x0804, 0xdac4, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x00e6, + 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, + 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, + 0x00ce, 0x00de, 0x00ee, 0x0804, 0xdacb, 0x080c, 0x57d9, 0xd0e4, + 0x0904, 0xdc45, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, + 0x7108, 0x720c, 0x080c, 0x6a9f, 0x0140, 0x6010, 0x2058, 0xb810, + 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6a9b, 0x15b8, + 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, + 0x7210, 0x080c, 0xd0c6, 0x0590, 0x080c, 0xddb8, 0x0578, 0x080c, + 0xecad, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, + 0x94ff, 0x080c, 0x9ab1, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, + 0x9286, 0xffff, 0x0150, 0x080c, 0xd0c6, 0x01c0, 0x9280, 0x0002, + 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, + 0x0001, 0x080c, 0xebfb, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, + 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, + 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, + 0x080c, 0x3374, 0x1904, 0xdcfa, 0x6010, 0x2058, 0xb804, 0x9084, + 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xdacb, 0x00e6, 0x00d6, + 0x00c6, 0x080c, 0x57d9, 0xd0e4, 0x0904, 0xdcbd, 0x2069, 0x1800, + 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, + 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xebfb, + 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xd0c6, 0x05d0, 0x7108, 0x9280, + 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, + 0xcce6, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, + 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, + 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xddb8, 0x0904, + 0xdc3e, 0x0056, 0x7510, 0x7614, 0x080c, 0xecc6, 0x005e, 0x00ce, + 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, + 0x2a00, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0c78, + 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, + 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0c10, 0x6007, 0x003b, 0x602f, + 0x000b, 0x6017, 0x0000, 0x0804, 0xdc15, 0x00e6, 0x0026, 0x080c, + 0x6a61, 0x0550, 0x080c, 0x69fd, 0x080c, 0xee97, 0x1518, 0x2071, + 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, + 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, + 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a9f, + 0x0120, 0x2011, 0x1a01, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, + 0x3000, 0x0010, 0x080c, 0xeecb, 0x002e, 0x00ee, 0x080c, 0xb2d3, + 0x0804, 0xdaca, 0x080c, 0xb2d3, 0x0005, 0x2600, 0x0002, 0xdd11, + 0xdd3f, 0xdd50, 0xdd11, 0xdd11, 0xdd13, 0xdd61, 0xdd11, 0xdd11, + 0xdd11, 0xdd2d, 0xdd11, 0xdd11, 0xdd11, 0xdd6c, 0xdd82, 0xddb3, + 0xdd11, 0x080c, 0x0dc5, 0x080c, 0xee26, 0x1d20, 0x080c, 0x3374, + 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, + 0x9547, 0x0005, 0x080c, 0x3250, 0x080c, 0xd7f8, 0x6007, 0x0001, + 0x6003, 0x0001, 0x080c, 0x9547, 0x0005, 0x080c, 0xee26, 0x1950, + 0x080c, 0x3374, 0x1938, 0x080c, 0xdecb, 0x1d60, 0x703c, 0x6016, + 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x9547, 0x0005, 0x080c, + 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0041, 0x080c, 0xeed4, 0x6007, + 0x0047, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0005, + 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0042, 0x080c, 0xeed4, + 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, + 0x0005, 0x080c, 0x3374, 0x1904, 0xdcfa, 0x2009, 0x0046, 0x080c, + 0xeed4, 0x080c, 0xb2d3, 0x0005, 0x2001, 0x1824, 0x2004, 0x9082, + 0x00e1, 0x1268, 0x080c, 0xddd5, 0x0904, 0xdcfa, 0x6007, 0x004e, + 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0005, 0x6007, + 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134, 0x918c, + 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140, 0x2001, + 0x19be, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19bf, 0x2004, + 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, + 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc379, + 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, + 0x080c, 0x9ab1, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, + 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, + 0x2058, 0xb8cc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106, 0x1120, + 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, + 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096, 0x0086, + 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, + 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x080c, 0x1027, + 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a, 0x001e, + 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x0471, + 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, + 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x00b1, + 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x7093, + 0x0000, 0x6014, 0x2048, 0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, + 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, + 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0, 0x080c, 0x23e2, + 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x0108, 0x1218, + 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, + 0x23e2, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x23e2, 0x2061, 0x19a1, + 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, + 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x23e2, + 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, 0x2019, 0x0280, 0x3300, + 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, + 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x23fa, 0x20a1, 0x024c, 0x2001, + 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, + 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x23fa, 0x20a1, + 0x0240, 0x0c98, 0x080c, 0x23fa, 0x2061, 0x19a4, 0x6004, 0x20a0, + 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, + 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x23fa, 0x20a1, + 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, 0x0260, 0x3400, 0x931e, + 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, + 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, + 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, + 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, + 0x080c, 0xdf63, 0x00de, 0x0005, 0x00d6, 0x080c, 0xdf70, 0x1520, + 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, + 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xeff4, 0x2009, + 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, + 0x080c, 0x2873, 0x1148, 0x2001, 0x0001, 0x080c, 0xeff4, 0x2110, + 0x900e, 0x080c, 0x3299, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, + 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xb325, 0x05a8, 0x0016, + 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, + 0x2873, 0x1578, 0x080c, 0x66b9, 0x1560, 0xbe12, 0xbd16, 0x00ce, + 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xee26, 0x11d8, 0x080c, + 0x3374, 0x11c0, 0x080c, 0xdecb, 0x0510, 0x2001, 0x0007, 0x080c, + 0x666a, 0x2001, 0x0007, 0x080c, 0x6696, 0x6017, 0x0000, 0x6023, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x9547, 0x080c, + 0x9ab1, 0x0010, 0x080c, 0xb2d3, 0x9085, 0x0001, 0x00ce, 0x00be, + 0x0005, 0x080c, 0xb2d3, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, + 0xb2d3, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010, + 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005, + 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086, + 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014, + 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, + 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, + 0x1a0c, 0x0dc5, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, + 0x1a04, 0xe0d2, 0x040a, 0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, + 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd809, 0x0128, 0x6000, + 0x9086, 0x0002, 0x0904, 0xbcfd, 0x0005, 0x91b6, 0x0014, 0x190c, + 0x0dc5, 0x2001, 0x0007, 0x080c, 0x6696, 0x080c, 0x99a5, 0x080c, + 0xb306, 0x080c, 0x9ab1, 0x0005, 0xdffc, 0xdffe, 0xdffc, 0xdffc, + 0xdffc, 0xdffe, 0xe00d, 0xe0cb, 0xe051, 0xe0cb, 0xe079, 0xe0cb, + 0xe00d, 0xe0cb, 0xe0c3, 0xe0cb, 0xe0c3, 0xe0cb, 0xe0cb, 0xdffc, + 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xdffc, + 0xdffc, 0xdffc, 0xdffe, 0xdffc, 0xe0cb, 0xdffc, 0xdffc, 0xe0cb, + 0xdffc, 0xe0c8, 0xe0cb, 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0xe0cb, + 0xe0cb, 0xdffc, 0xe0cb, 0xe0cb, 0xdffc, 0xe008, 0xdffc, 0xdffc, + 0xdffc, 0xdffc, 0xe0c7, 0xe0cb, 0xdffc, 0xdffc, 0xe0cb, 0xe0cb, + 0xdffc, 0xdffc, 0xdffc, 0xdffc, 0x080c, 0x0dc5, 0x080c, 0x99a5, + 0x080c, 0xd7fb, 0x6003, 0x0002, 0x080c, 0x9ab1, 0x0804, 0xe0d1, + 0x9006, 0x080c, 0x6656, 0x0804, 0xe0cb, 0x080c, 0x6a9b, 0x1904, + 0xe0cb, 0x9006, 0x080c, 0x6656, 0x6010, 0x2058, 0xb810, 0x9086, + 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, + 0x00fe, 0x00b8, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0904, 0xe0cb, + 0x080c, 0x33a5, 0x1904, 0xe0cb, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, + 0x00fe, 0x2001, 0x0002, 0x080c, 0x666a, 0x080c, 0x99a5, 0x6023, + 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x9547, 0x080c, + 0x9ab1, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x884b, 0x0804, + 0xe0d1, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, + 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, 0x9031, 0x2001, + 0x0004, 0x080c, 0x6696, 0x080c, 0xf043, 0x0904, 0xe0cb, 0x080c, + 0x99a5, 0x2001, 0x0004, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, + 0x0001, 0x6007, 0x0003, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x0804, + 0xe0d1, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, + 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4dfb, + 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, 0xe0ef, 0x6610, 0x2658, + 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, + 0x0180, 0x2001, 0x0006, 0x080c, 0x6696, 0x9284, 0x00ff, 0x908e, + 0x0007, 0x0118, 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, + 0x666a, 0x080c, 0x6a9b, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, + 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, + 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xe039, + 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018, + 0x0010, 0x080c, 0x6696, 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, + 0x9ab1, 0x0005, 0x2600, 0x0002, 0xe0e6, 0xe0e6, 0xe0e6, 0xe0e6, + 0xe0e6, 0xe0e8, 0xe0e6, 0xe0e8, 0xe0e6, 0xe0e6, 0xe0e8, 0xe0e6, + 0xe0e6, 0xe0e6, 0xe0e8, 0xe0e8, 0xe0e8, 0xe0e8, 0x080c, 0x0dc5, + 0x080c, 0x99a5, 0x080c, 0xb2d3, 0x080c, 0x9ab1, 0x0005, 0x0016, + 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, + 0x666a, 0x9006, 0x080c, 0x6656, 0x080c, 0x3279, 0x00de, 0x00be, + 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, + 0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b, + 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbd9f, + 0xbd9f, 0xbd9f, 0xbd9f, 0xe184, 0xbd9f, 0xe16e, 0xe12f, 0xbd9f, + 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0xe184, + 0xbd9f, 0xe16e, 0xe175, 0xbd9f, 0xbd9f, 0xbd9f, 0xbd9f, 0x00f6, + 0x080c, 0x6a9b, 0x11d8, 0x080c, 0xd7e3, 0x11c0, 0x6010, 0x905d, + 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c, 0x6656, 0x2001, + 0x0002, 0x080c, 0x666a, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x9547, 0x080c, 0x9ab1, 0x00f0, 0x2011, 0x0263, + 0x2204, 0x8211, 0x220c, 0x080c, 0x2873, 0x11b0, 0x080c, 0x6724, + 0x0118, 0x080c, 0xb2d3, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, + 0xb8c0, 0x0006, 0x080c, 0x6148, 0x000e, 0xb8c2, 0x000e, 0xb816, + 0x000e, 0xb812, 0x080c, 0xb2d3, 0x00fe, 0x0005, 0x6604, 0x96b6, + 0x001e, 0x1110, 0x080c, 0xb2d3, 0x0005, 0x080c, 0xc1dc, 0x1148, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x9547, 0x080c, 0x9ab1, + 0x0010, 0x080c, 0xb2d3, 0x0005, 0x0804, 0xb2d3, 0x6004, 0x908a, + 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, + 0x9ab1, 0x0005, 0x9182, 0x0040, 0x0002, 0xe1a9, 0xe1a9, 0xe1a9, + 0xe1a9, 0xe1ab, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, + 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, 0xe1a9, + 0xe1a9, 0x080c, 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, + 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106, + 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xe211, 0x080c, + 0xefe8, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, + 0x0200, 0x080c, 0x8a50, 0x0020, 0x9026, 0x080c, 0xee6b, 0x0c38, + 0x080c, 0x100e, 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d, + 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, + 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, + 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6e9f, 0x001e, + 0x080c, 0xefe8, 0x1904, 0xe271, 0x9486, 0x2000, 0x1130, 0x2019, + 0x0017, 0x080c, 0xeba1, 0x0804, 0xe271, 0x9486, 0x0200, 0x1120, + 0x080c, 0xeb38, 0x0804, 0xe271, 0x9486, 0x0400, 0x0120, 0x9486, + 0x1000, 0x1904, 0xe271, 0x2019, 0x0002, 0x080c, 0xeb53, 0x0804, + 0xe271, 0x2069, 0x1a74, 0x6a00, 0xd284, 0x0904, 0xe2db, 0x9284, + 0x0300, 0x1904, 0xe2d4, 0x6804, 0x9005, 0x0904, 0xe2bc, 0x2d78, + 0x6003, 0x0007, 0x080c, 0x1027, 0x0904, 0xe27d, 0x7800, 0xd08c, + 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, + 0x2004, 0xd084, 0x1904, 0xe2df, 0x9006, 0xa802, 0xa867, 0x0116, + 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, + 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, + 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, + 0x9080, 0xe279, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, + 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, + 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, + 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, + 0x6e9f, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, + 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, + 0xd084, 0x0120, 0x080c, 0x100e, 0x1904, 0xe226, 0x6017, 0xf100, + 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, 0x080c, 0x9ab1, + 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, + 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, + 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, + 0x94ff, 0x080c, 0x9ab1, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, + 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x0804, 0xe271, 0x2001, 0x180e, 0x2004, 0xd0ec, + 0x0120, 0x2011, 0x8049, 0x080c, 0x4c44, 0x6017, 0xf300, 0x0010, + 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x0804, 0xe271, 0x6017, 0xf500, 0x0c98, 0x6017, + 0xf600, 0x0804, 0xe291, 0x6017, 0xf200, 0x0804, 0xe291, 0xa867, + 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, + 0x9084, 0x0003, 0x9080, 0xe279, 0x2005, 0xa87e, 0x2928, 0x6010, + 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, + 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, + 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, + 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210, + 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0029, 0x20a0, 0x2011, 0xe35b, 0x2041, 0x0001, 0x223d, 0x9784, + 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, + 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, + 0x0c68, 0x2950, 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867, + 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, + 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, + 0x1040, 0x0cc8, 0x080c, 0x1040, 0x0804, 0xe27d, 0x2548, 0x8847, + 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, + 0xebd4, 0x0804, 0xe271, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, + 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, + 0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5, + 0x2008, 0x0804, 0xe3ea, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c, + 0xd809, 0x0500, 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe433, + 0x9186, 0x0027, 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, + 0x0160, 0x190c, 0x0dc5, 0x080c, 0xd809, 0x0160, 0x6000, 0x9086, + 0x0004, 0x190c, 0x0dc5, 0x0804, 0xe516, 0x6004, 0x9082, 0x0040, + 0x2008, 0x001a, 0x080c, 0xb36d, 0x0005, 0xe3b1, 0xe3b3, 0xe3b3, + 0xe3da, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, + 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, 0xe3b1, + 0xe3b1, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x0036, + 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xd0d8, 0x01c0, 0x6003, + 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, + 0x2019, 0x0004, 0x080c, 0xebd4, 0x6017, 0x0000, 0x6018, 0x9005, + 0x1120, 0x2001, 0x1987, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, + 0x003e, 0x0005, 0x0096, 0x080c, 0x99a5, 0x080c, 0x9ab1, 0x080c, + 0xd0d8, 0x0120, 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb306, + 0x009e, 0x0005, 0x0002, 0xe3ff, 0xe416, 0xe401, 0xe42d, 0xe3ff, + 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, + 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0xe3ff, 0x080c, + 0x0dc5, 0x0096, 0x080c, 0x99a5, 0x6014, 0x2048, 0xa87c, 0xd0b4, + 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xb352, 0x0010, + 0x6003, 0x0004, 0x080c, 0x9ab1, 0x009e, 0x0005, 0x080c, 0x99a5, + 0x080c, 0xd0d8, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, + 0xd1ec, 0x1138, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x080c, 0x9ab1, + 0x0005, 0x080c, 0xee2f, 0x0db0, 0x0cc8, 0x080c, 0x99a5, 0x2009, + 0x0041, 0x0804, 0xe59e, 0x9182, 0x0040, 0x0002, 0xe44a, 0xe44c, + 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, + 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44d, + 0xe44a, 0xe44a, 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x8a25, + 0x00de, 0x080c, 0xee87, 0x080c, 0xb2d3, 0x0005, 0x9182, 0x0040, + 0x0002, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0xe46d, + 0xe46d, 0xe46d, 0xe46f, 0xe4de, 0xe46d, 0xe46d, 0xe46d, 0xe46d, + 0xe4de, 0xe46d, 0xe46d, 0xe46d, 0xe46d, 0x080c, 0x0dc5, 0x2001, + 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, + 0x2001, 0x0131, 0x2004, 0x9105, 0x1904, 0xe4de, 0x2009, 0x180c, + 0x2104, 0xd0d4, 0x0904, 0xe4de, 0xc0d4, 0x200a, 0x2009, 0x0105, + 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, + 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, 0x080c, 0x9a61, 0x6014, + 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, + 0x0002, 0x0508, 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, + 0x9bd3, 0x2009, 0x0041, 0x009e, 0x0804, 0xe59e, 0x080c, 0x9bd3, + 0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8a25, 0x009e, 0x0005, + 0x2001, 0x0100, 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, + 0x2004, 0x603a, 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, + 0xd1cc, 0x0110, 0x080c, 0x2c7b, 0x080c, 0x9bd3, 0x6014, 0x2048, + 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x009e, + 0x0005, 0x080c, 0xee2f, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, + 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9a61, 0x080c, 0x9bd3, + 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, + 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, + 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xebd4, 0x6018, + 0x9005, 0x1128, 0x2001, 0x1987, 0x2004, 0x8003, 0x601a, 0x6017, + 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, + 0x0002, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, + 0xe52d, 0xe52f, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe52d, + 0xe52d, 0xe52d, 0xe52d, 0xe52d, 0xe57a, 0x080c, 0x0dc5, 0x6014, + 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, + 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, + 0x2009, 0x0041, 0x009e, 0x0804, 0xe59e, 0x6003, 0x0007, 0x601b, + 0x0000, 0x080c, 0x8a25, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, + 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, + 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, + 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, + 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, + 0x0006, 0x00e9, 0x080c, 0x8a27, 0x009e, 0x0005, 0x6003, 0x0002, + 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904, + 0xe52f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, + 0x9105, 0x1120, 0x080c, 0x1608, 0x1904, 0xe52f, 0x0005, 0xd2fc, + 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, + 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, + 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, + 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe5c2, 0xe5ce, + 0xe5da, 0xe5e6, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c9, 0xe5c4, + 0xe5c4, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c2, 0xe5c4, 0xe5c2, 0xe5c4, + 0xe5c2, 0xe5c9, 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, + 0x0005, 0x6014, 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001, + 0x6106, 0x080c, 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, + 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, 0x0126, + 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, 0x6003, 0x0003, + 0x6106, 0x2c10, 0x080c, 0x1be0, 0x0126, 0x2091, 0x8000, 0x080c, + 0x9564, 0x080c, 0x9bd3, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, + 0x0005, 0xe615, 0xe617, 0xe629, 0xe643, 0xe615, 0xe615, 0xe615, + 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, + 0xe615, 0xe615, 0xe615, 0xe615, 0xe615, 0x080c, 0x0dc5, 0x6014, + 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, + 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, 0x080c, 0x9ab1, + 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, + 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x94ff, + 0x080c, 0x9ab1, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, + 0x080c, 0xebd4, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, + 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, + 0x2c10, 0x080c, 0x1be0, 0x080c, 0x9564, 0x080c, 0x9bd3, 0x0005, + 0x080c, 0x99a5, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, + 0xef85, 0x0036, 0x2019, 0x0029, 0x080c, 0xebd4, 0x003e, 0x009e, + 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x080c, 0x9a61, 0x6114, + 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xef85, 0x0036, 0x2019, + 0x0029, 0x080c, 0xebd4, 0x003e, 0x009e, 0x080c, 0xb306, 0x080c, + 0x9bd3, 0x0005, 0x9182, 0x0085, 0x0002, 0xe694, 0xe692, 0xe692, + 0xe6a0, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, 0xe692, + 0xe692, 0xe692, 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c, + 0x94ff, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ab1, 0x012e, 0x0005, + 0x0026, 0x00e6, 0x080c, 0xee26, 0x0118, 0x080c, 0xb2d3, 0x0450, + 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, + 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, + 0x014e, 0x080c, 0xb5f5, 0x7220, 0x080c, 0xea29, 0x0118, 0x6007, + 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, + 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, + 0x080c, 0x9bd3, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, + 0x0dc5, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, + 0x0014, 0x0118, 0x080c, 0xb36d, 0x0050, 0x2001, 0x0007, 0x080c, + 0x6696, 0x080c, 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, + 0xe705, 0xe707, 0xe707, 0xe705, 0xe705, 0xe705, 0xe705, 0xe705, + 0xe705, 0xe705, 0xe705, 0xe705, 0xe705, 0x080c, 0x0dc5, 0x080c, + 0x99a5, 0x080c, 0xb306, 0x080c, 0x9ab1, 0x0005, 0x9182, 0x0085, + 0x0a0c, 0x0dc5, 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085, + 0x0002, 0xe726, 0xe726, 0xe726, 0xe728, 0xe726, 0xe726, 0xe726, + 0xe726, 0xe726, 0xe726, 0xe726, 0xe726, 0xe726, 0x080c, 0x0dc5, + 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, + 0x0027, 0x0118, 0x080c, 0xb36d, 0x0030, 0x080c, 0x99a5, 0x080c, + 0xb306, 0x080c, 0x9ab1, 0x0005, 0x0036, 0x080c, 0xee87, 0x6043, + 0x0000, 0x2019, 0x000b, 0x0011, 0x003e, 0x0005, 0x6010, 0x0006, + 0x0059, 0x000e, 0x6012, 0x6023, 0x0006, 0x6003, 0x0007, 0x601b, + 0x0000, 0x6043, 0x0000, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, + 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, + 0x1550, 0x0076, 0x2c38, 0x080c, 0xaba6, 0x007e, 0x1520, 0x6000, + 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, 0x0096, + 0x601c, 0xd084, 0x0140, 0x080c, 0xee87, 0x080c, 0xd7fb, 0x080c, + 0x1a8e, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xd0d8, 0x0110, + 0x080c, 0xebd4, 0x009e, 0x6017, 0x0000, 0x080c, 0xee87, 0x6023, + 0x0007, 0x080c, 0xd7fb, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, + 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, + 0x2873, 0x1904, 0xe7e4, 0x0016, 0x00c6, 0x080c, 0x6724, 0x1904, + 0xe7e2, 0x001e, 0x00c6, 0x080c, 0xd7e3, 0x1130, 0xb8c0, 0x9005, + 0x0118, 0x080c, 0x33a5, 0x0148, 0x2b10, 0x2160, 0x6010, 0x0006, + 0x6212, 0x080c, 0xd7ea, 0x000e, 0x6012, 0x00ce, 0x002e, 0x0026, + 0x0016, 0x2019, 0x0029, 0x080c, 0xac6c, 0x080c, 0x96a4, 0x0076, + 0x903e, 0x080c, 0x9577, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, + 0xe91c, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, + 0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x330e, + 0x002e, 0xbcc0, 0x001e, 0x080c, 0x6148, 0xbe12, 0xbd16, 0xbcc2, + 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, + 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, + 0x2104, 0x9086, 0x0074, 0x1904, 0xe843, 0x2069, 0x0260, 0x6944, + 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe840, + 0x2001, 0x197c, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb8c0, + 0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, + 0x0648, 0x080c, 0xefed, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, + 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, + 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, + 0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, + 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, + 0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, + 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, + 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, + 0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, + 0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, + 0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, + 0x6733, 0x0804, 0xe8ab, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, 0x009e, 0x15a8, 0x2011, + 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, + 0xc379, 0x009e, 0x1548, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, + 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, + 0xec31, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c, 0x96a4, + 0x0076, 0x2039, 0x0000, 0x080c, 0x9577, 0x2c08, 0x080c, 0xe91c, + 0x007e, 0x2001, 0x0007, 0x080c, 0x6696, 0x2001, 0x0007, 0x080c, + 0x666a, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, + 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, + 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, + 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, + 0x7834, 0x080c, 0x2873, 0x11d0, 0x080c, 0x6724, 0x11b8, 0x2011, + 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, + 0xc379, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x015e, 0x003e, + 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, + 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, + 0x080c, 0x2873, 0x11d0, 0x080c, 0x6724, 0x11b8, 0x2011, 0x0276, + 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xc379, + 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, + 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x015e, 0x003e, 0x002e, + 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, + 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, + 0x2029, 0x19f1, 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, + 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, + 0x1ab7, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe9ba, 0x0018, + 0x9606, 0x0904, 0xe9ba, 0x080c, 0x8cf7, 0x0904, 0xe9b1, 0x2100, + 0x9c06, 0x0904, 0xe9b1, 0x6720, 0x9786, 0x0007, 0x0904, 0xe9b1, + 0x080c, 0xec72, 0x1904, 0xe9b1, 0x080c, 0xf00b, 0x0904, 0xe9b1, + 0x080c, 0xec62, 0x0904, 0xe9b1, 0x6720, 0x9786, 0x0001, 0x1148, + 0x080c, 0x33a5, 0x0904, 0xe9f9, 0x6004, 0x9086, 0x0000, 0x1904, + 0xe9f9, 0x9786, 0x0004, 0x0904, 0xe9f9, 0x2500, 0x9c06, 0x0904, + 0xe9b1, 0x2400, 0x9c06, 0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, + 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, + 0x1a8e, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xd2e0, 0x1130, + 0x080c, 0xbcb6, 0x009e, 0x080c, 0xb306, 0x0418, 0x6014, 0x2048, + 0x080c, 0xd0d8, 0x01d8, 0x9786, 0x0003, 0x1570, 0xa867, 0x0103, + 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, + 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xef85, 0x0016, 0x080c, + 0xd3ce, 0x080c, 0x6e92, 0x001e, 0x080c, 0xd2c3, 0x009e, 0x080c, + 0xb306, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, + 0x0804, 0xe930, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, + 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, + 0x0005, 0x0128, 0x080c, 0xef85, 0x080c, 0xebd4, 0x08f8, 0x009e, + 0x0c00, 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, + 0x6000, 0x9086, 0x0003, 0x11a0, 0x080c, 0x9a61, 0x0096, 0x6114, + 0x2148, 0x080c, 0xd0d8, 0x0118, 0x6010, 0x080c, 0x6e9f, 0x009e, + 0x00c6, 0x080c, 0xb2d3, 0x00ce, 0x0036, 0x080c, 0x9bd3, 0x003e, + 0x009e, 0x0804, 0xe9b1, 0x9786, 0x000a, 0x0904, 0xe9a1, 0x0804, + 0xe996, 0x81ff, 0x0904, 0xe9b1, 0x9180, 0x0001, 0x2004, 0x9086, + 0x0018, 0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, + 0xe9b1, 0x6000, 0x9086, 0x0002, 0x1904, 0xe9b1, 0x080c, 0xd2cf, + 0x0138, 0x080c, 0xd2e0, 0x1904, 0xe9b1, 0x080c, 0xbcb6, 0x0038, + 0x080c, 0x3279, 0x080c, 0xd2e0, 0x1110, 0x080c, 0xbcb6, 0x080c, + 0xb306, 0x0804, 0xe9b1, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, + 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, + 0xebfb, 0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, + 0x00ce, 0x0005, 0xea48, 0xea48, 0xea48, 0xea48, 0xea48, 0xea48, + 0xea4a, 0xea48, 0xea48, 0xea48, 0xea73, 0xb306, 0xb306, 0xea48, + 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, + 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xec31, 0x001e, + 0x004e, 0x2019, 0x0002, 0x080c, 0xe754, 0x003e, 0x9085, 0x0001, + 0x0005, 0x0096, 0x080c, 0xd0d8, 0x0140, 0x6014, 0x904d, 0x080c, + 0xccf3, 0x687b, 0x0005, 0x080c, 0x6e9f, 0x009e, 0x080c, 0xb306, + 0x9085, 0x0001, 0x0005, 0x0019, 0x9085, 0x0001, 0x0005, 0x6000, + 0x908a, 0x0010, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0xea8e, 0xea8e, + 0xeaa5, 0xea95, 0xeab4, 0xea8e, 0xea8e, 0xea90, 0xea8e, 0xea8e, + 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0xea8e, 0x080c, 0x0dc5, + 0x080c, 0xb306, 0x9085, 0x0001, 0x0005, 0x0036, 0x00e6, 0x2071, + 0x19e8, 0x703c, 0x9c06, 0x1128, 0x2019, 0x0001, 0x080c, 0xaa49, + 0x0010, 0x080c, 0xac2b, 0x00ee, 0x003e, 0x0096, 0x00d6, 0x6014, + 0x2048, 0xa87b, 0x0005, 0x080c, 0x6e9f, 0x080c, 0xb306, 0x00de, + 0x009e, 0x9085, 0x0001, 0x0005, 0x601c, 0xd084, 0x190c, 0x1a8e, + 0x0c60, 0x2001, 0x0001, 0x080c, 0x6656, 0x0156, 0x0016, 0x0026, + 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, + 0xc365, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, + 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, + 0x8000, 0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, + 0xeb2b, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, + 0xeb2b, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, + 0xec62, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, + 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, + 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, + 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xee87, 0x080c, 0xd7fb, + 0x080c, 0x1a8e, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xd0d8, + 0x0120, 0x0046, 0x080c, 0xebd4, 0x004e, 0x009e, 0x080c, 0xb306, + 0x88ff, 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1210, 0x0804, 0xeade, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, + 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, + 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, + 0x2019, 0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xaafb, + 0x009e, 0x008e, 0x903e, 0x080c, 0xaba6, 0x080c, 0xeacf, 0x005e, + 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, + 0x080c, 0x6724, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, + 0x0001, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, + 0x080c, 0xaba6, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xeb5e, + 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xeacf, 0x003e, 0x015e, + 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, + 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, + 0x0048, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, + 0x080c, 0xaba6, 0x2c20, 0x080c, 0xeacf, 0x005e, 0x007e, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, + 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6724, 0x1190, + 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xee6b, + 0x004e, 0x0096, 0x904e, 0x080c, 0xaafb, 0x009e, 0x008e, 0x903e, + 0x080c, 0xaba6, 0x003e, 0x001e, 0x8108, 0x1f04, 0xebab, 0x0036, + 0x2029, 0x0002, 0x080c, 0xeacf, 0x003e, 0x015e, 0x00ce, 0x007e, + 0x005e, 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xd0d6, + 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, + 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6e9f, 0x2f48, + 0x0cb0, 0xab82, 0x080c, 0x6e9f, 0x00fe, 0x001e, 0x0005, 0xa800, + 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6e9f, 0x2f48, 0x0cb8, + 0x080c, 0x6e9f, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, + 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, + 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, + 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, 0x6010, + 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, + 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, + 0x0c30, 0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, + 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xd0c6, + 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, + 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, + 0xa87f, 0x0000, 0x2001, 0x198e, 0x2004, 0xa882, 0x9006, 0xa802, + 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6e9f, 0x012e, + 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, + 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, + 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, + 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, + 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, + 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, + 0x0005, 0x2001, 0x1987, 0x2004, 0x601a, 0x080c, 0x94ff, 0x080c, + 0x9ab1, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, + 0x0158, 0xd0cc, 0x0118, 0x080c, 0xd412, 0x0030, 0x080c, 0xee87, + 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x0005, 0x9280, 0x0008, 0x2004, + 0x9084, 0x000f, 0x0002, 0xecc1, 0xecc1, 0xecc1, 0xecc3, 0xecc1, + 0xecc3, 0xecc3, 0xecc1, 0xecc3, 0xecc1, 0xecc1, 0xecc1, 0xecc1, + 0xecc1, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, + 0x2004, 0x9084, 0x000f, 0x0002, 0xecda, 0xecda, 0xecda, 0xecda, + 0xecda, 0xecda, 0xece7, 0xecda, 0xecda, 0xecda, 0xecda, 0xecda, + 0xecda, 0xecda, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, + 0x6003, 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x0005, 0x0096, + 0x00c6, 0x2260, 0x080c, 0xee87, 0x6043, 0x0000, 0x6024, 0xc0f4, + 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, + 0x0007, 0x1904, 0xed40, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, + 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, + 0x0001, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x00c6, 0x2d60, 0x6100, + 0x9186, 0x0002, 0x1904, 0xedb0, 0x6014, 0x9005, 0x1138, 0x6000, + 0x9086, 0x0007, 0x190c, 0x0dc5, 0x0804, 0xedb0, 0x2048, 0x080c, + 0xd0d8, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, + 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, + 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, + 0x080c, 0xe59e, 0x0804, 0xedb0, 0x2009, 0x0041, 0x0804, 0xedaa, + 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, + 0x00de, 0x009e, 0x0804, 0xecda, 0xd0b4, 0x0128, 0xd0fc, 0x090c, + 0x0dc5, 0x0804, 0xecfb, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, + 0x94ff, 0x080c, 0x9ab1, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, + 0x0120, 0x9186, 0x0004, 0x1904, 0xedb0, 0x6814, 0x2048, 0xa97c, + 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, + 0x2c78, 0x080c, 0x1768, 0x00fe, 0x2009, 0x0042, 0x0498, 0x0036, + 0x080c, 0x100e, 0x090c, 0x0dc5, 0xa867, 0x010d, 0x9006, 0xa802, + 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, + 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, + 0x2058, 0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, + 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6e9f, + 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe746, 0x2d00, 0x600a, + 0x003e, 0x0038, 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe59e, + 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, + 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, + 0x99a5, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, + 0xebd4, 0x009e, 0x003e, 0x080c, 0x9ab1, 0x0005, 0x9186, 0x0014, + 0x0d70, 0x080c, 0xb36d, 0x0005, 0xede3, 0xede1, 0xede1, 0xede1, + 0xede1, 0xede1, 0xede3, 0xede1, 0xede1, 0xede1, 0xede1, 0xede1, + 0xede1, 0x080c, 0x0dc5, 0x080c, 0x99a5, 0x6003, 0x000c, 0x080c, + 0x9ab1, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, + 0x001a, 0x080c, 0xb36d, 0x0005, 0xee01, 0xee01, 0xee01, 0xee01, + 0xee03, 0xee23, 0xee01, 0xee01, 0xee01, 0xee01, 0xee01, 0xee01, + 0xee01, 0x080c, 0x0dc5, 0x00d6, 0x2c68, 0x080c, 0xb27d, 0x01b0, + 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, + 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, + 0x6023, 0x0004, 0x080c, 0x94ff, 0x080c, 0x9ab1, 0x2d60, 0x080c, + 0xb2d3, 0x00de, 0x0005, 0x080c, 0xb2d3, 0x0005, 0x00e6, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, + 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, + 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1988, 0x2004, 0x6042, 0x2009, + 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, + 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, + 0x1988, 0x200c, 0x2001, 0x1986, 0x2004, 0x9100, 0x9080, 0x000a, + 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, + 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, + 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc, + 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, + 0x600c, 0x2072, 0x080c, 0x8a25, 0x080c, 0xb2d3, 0x0010, 0x9cf0, + 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, + 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, + 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, + 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, + 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, + 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, + 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc379, + 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, + 0x2048, 0x2019, 0x0006, 0x080c, 0xc379, 0x009e, 0x1100, 0x015e, + 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60c1, + 0x080c, 0x3000, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x100e, + 0x090c, 0x0dc5, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, + 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, + 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, + 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, + 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, + 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, + 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, + 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, + 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, + 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, + 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, + 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, + 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, + 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, + 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, + 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, + 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, + 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, + 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, + 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, + 0x002e, 0x080c, 0x6e9f, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, + 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, + 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, + 0x2029, 0x19f1, 0x252c, 0x2021, 0x19f7, 0x2424, 0x2061, 0x1cd0, + 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, + 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, + 0x2400, 0x9c06, 0x01d0, 0x080c, 0xec62, 0x01b8, 0x080c, 0xec72, + 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1a8e, + 0x001e, 0x080c, 0xd2cf, 0x1110, 0x080c, 0x3279, 0x080c, 0xd2e0, + 0x1110, 0x080c, 0xbcb6, 0x080c, 0xb306, 0x9ce0, 0x0018, 0x2001, + 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, + 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, + 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, + 0xd7e3, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, + 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4dfb, 0x004e, + 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, + 0xac6c, 0x080c, 0xb306, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, + 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, + 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, + 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, + 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, + 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, + 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, + 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, + 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, + 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, + 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, + 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, + 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, + 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, + 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, + 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, + 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, + 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, + 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0003, 0x000b, + 0x07d2, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, 0x0010, 0x0000, + 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, 0x0003, 0x8060, 0x0000, + 0x0400, 0x0000, 0x580d, 0x000b, 0x79c0, 0x0003, 0x5106, 0x0003, + 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, 0x0c0a, 0x000b, + 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, + 0xffa0, 0x0001, 0x2000, 0x0000, 0x1680, 0x000b, 0x808c, 0x0008, + 0x0001, 0x0000, 0x0000, 0x0007, 0x4028, 0x0000, 0x4047, 0x000a, + 0x808c, 0x0008, 0x0002, 0x0000, 0x0822, 0x0003, 0x4022, 0x0000, + 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0, 0x0009, 0xff00, 0x0008, + 0xffe0, 0x0009, 0x0500, 0x0008, 0x0aab, 0x0003, 0x4447, 0x0002, + 0x0ea8, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x1286, 0x0003, + 0x0ca0, 0x0001, 0x1286, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, + 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x0009, 0x0008, 0x4436, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, + 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, + 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, + 0x0e83, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, + 0x0e83, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, + 0x444d, 0x000b, 0x0240, 0x0002, 0x0a80, 0x0003, 0x00fe, 0x0000, + 0x3283, 0x000b, 0x0248, 0x000a, 0x085c, 0x0003, 0x9180, 0x0001, + 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002, 0x0008, 0x0003, 0x0008, + 0x8066, 0x0000, 0x020a, 0x0000, 0x445b, 0x0003, 0x112a, 0x0000, + 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x0c0a, 0x000b, + 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, 0x8062, 0x0008, + 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, 0x4468, 0x0003, + 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e74, 0x0003, 0x00fe, 0x0000, + 0x43e0, 0x0001, 0x0e74, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, + 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, + 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a, 0x0008, 0x0003, 0x0008, + 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x5880, 0x000b, + 0x8066, 0x0000, 0x3679, 0x0000, 0x4483, 0x0003, 0x5884, 0x0003, + 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a, 0x000b, 0x0d00, 0x0000, + 0x0092, 0x000c, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, + 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x00e0, 0x000c, + 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a, 0x0003, 0x1a60, 0x0000, + 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, + 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0, 0x0001, 0x0cd4, 0x000b, + 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, 0x0001, 0x0400, 0x0000, + 0x08b2, 0x0003, 0x14dc, 0x0003, 0x01fe, 0x0008, 0x0580, 0x0009, + 0x7f06, 0x0000, 0x8690, 0x0009, 0x0000, 0x0008, 0x7f0c, 0x0000, + 0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x0680, 0x0009, + 0x10b2, 0x0003, 0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008, + 0x08d4, 0x0003, 0xb9c0, 0x0009, 0x0030, 0x0008, 0x0cc3, 0x000b, + 0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, 0x0008, 0x1a0a, 0x0009, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, 0x0000, 0x44bc, 0x0003, + 0x80fe, 0x0008, 0x1a09, 0x0009, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x040a, 0x0000, 0x44c2, 0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, + 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002, 0x08c5, 0x0003, + 0x00ce, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008, 0x3945, 0x000a, + 0x08ca, 0x0003, 0x3946, 0x000a, 0x0cdb, 0x000b, 0x0000, 0x0007, + 0x3943, 0x000a, 0x08db, 0x0003, 0x00ce, 0x0003, 0x00fe, 0x0000, + 0x34d9, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x00db, 0x000b, + 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f, 0x86c0, 0x0009, + 0xfc00, 0x0008, 0x08d4, 0x0003, 0x00b2, 0x000b, 0x1c60, 0x0000, + 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x44e4, 0x000b, + 0x58e5, 0x000b, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, + 0x0cf3, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, + 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000, 0x0d06, 0x0000, + 0x0d08, 0x0008, 0x00f7, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008, + 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a, 0x08fa, 0x0003, + 0x0d4a, 0x0008, 0x58fa, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, + 0x0901, 0x0003, 0x8000, 0x0000, 0x0001, 0x0000, 0x0092, 0x000c, + 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008, + 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008, + 0x2b24, 0x0008, 0x590a, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, + 0x1242, 0x0002, 0x0958, 0x0003, 0x3a45, 0x000a, 0x0947, 0x000b, + 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a, 0x0917, 0x000b, + 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000, + 0x0942, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4520, 0x000b, + 0x00fe, 0x0000, 0x353f, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008, + 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4528, 0x0003, + 0x00fe, 0x0000, 0x325b, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, + 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, + 0x4531, 0x000b, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, + 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, + 0x8066, 0x0000, 0x0009, 0x0008, 0x453b, 0x000b, 0x003a, 0x0008, + 0x1dfe, 0x0000, 0x011c, 0x000b, 0x0036, 0x0008, 0x00e0, 0x000c, + 0x0158, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000, + 0x2000, 0x0000, 0x0158, 0x000b, 0x3a44, 0x0002, 0x0a89, 0x0003, + 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000, + 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3658, 0x0003, 0x26fe, 0x0008, + 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009, + 0x0d6a, 0x0003, 0x8074, 0x0000, 0x4040, 0x0008, 0x5958, 0x0003, + 0x5106, 0x0003, 0x3a46, 0x000a, 0x0d6a, 0x0003, 0x3a47, 0x0002, + 0x0965, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, + 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x01b4, 0x0003, + 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, + 0x0e52, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, + 0x8066, 0x0000, 0x362a, 0x0000, 0x456f, 0x0003, 0x2000, 0x0000, + 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000, + 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000, + 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000, + 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000, + 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000, + 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000, + 0x4589, 0x000b, 0x92c0, 0x0009, 0x0780, 0x0008, 0x0e6e, 0x000b, + 0x124b, 0x0002, 0x0992, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, + 0x0a58, 0x0003, 0x3a46, 0x000a, 0x0da2, 0x000b, 0x5994, 0x0003, + 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a, 0x09b0, 0x0003, + 0x8010, 0x0008, 0x000d, 0x0000, 0x0233, 0x000c, 0x1948, 0x000a, + 0x099f, 0x000b, 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, + 0x01b0, 0x000b, 0x1948, 0x000a, 0x09a6, 0x000b, 0x1243, 0x000a, + 0x0a5b, 0x0003, 0x194d, 0x000a, 0x09aa, 0x000b, 0x1243, 0x000a, + 0x0a62, 0x0003, 0x59aa, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000, + 0x0228, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, + 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, + 0x3a42, 0x0002, 0x0dba, 0x000b, 0x15fe, 0x0008, 0x3461, 0x000b, + 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008, + 0x000c, 0x0008, 0x0233, 0x000c, 0x000a, 0x000b, 0xbbe0, 0x0009, + 0x0030, 0x0008, 0x0dd0, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, + 0x09cd, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x09cd, 0x0003, + 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0220, 0x000b, + 0x8076, 0x0008, 0x0041, 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, + 0x0032, 0x0000, 0x0dd5, 0x000b, 0x3c1e, 0x0008, 0x0220, 0x000b, + 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dda, 0x000b, 0x3c20, 0x0000, + 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0035, 0x0008, 0x0de0, 0x000b, + 0x8072, 0x0000, 0x8000, 0x0000, 0x039e, 0x0003, 0xbbe0, 0x0009, + 0x0036, 0x0008, 0x0abd, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, + 0x0e01, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0dcd, 0x000b, + 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, + 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008, + 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000, + 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x45f8, 0x000b, + 0x0228, 0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, + 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000, 0x01b4, 0x0003, + 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e13, 0x000b, 0x18fe, 0x0000, + 0x3ce0, 0x0009, 0x0a10, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, + 0x0dc9, 0x0003, 0x0223, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, + 0x8072, 0x0000, 0x8000, 0x0000, 0x0280, 0x000b, 0x8076, 0x0008, + 0x0042, 0x0008, 0x0220, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, + 0x0e20, 0x000b, 0x8074, 0x0000, 0x0808, 0x0008, 0x3a44, 0x0002, + 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, + 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, + 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, + 0xbc80, 0x0001, 0x0007, 0x0000, 0x022c, 0x000b, 0x1930, 0x000a, + 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, + 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, + 0x4631, 0x000b, 0x4000, 0x000f, 0x2236, 0x000b, 0x0870, 0x0008, + 0x4000, 0x000f, 0x7e33, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, + 0x0e33, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a44, 0x000b, + 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a44, 0x000b, 0x0223, 0x0004, + 0x8076, 0x0008, 0x0040, 0x0000, 0x0246, 0x000b, 0x8076, 0x0008, + 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0233, 0x0003, + 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4f, 0x0003, 0x8074, 0x0000, + 0x0706, 0x0000, 0x0251, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, + 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x028e, 0x0003, + 0x8010, 0x0008, 0x0008, 0x0000, 0x028e, 0x0003, 0x8010, 0x0008, + 0x0022, 0x0008, 0x028e, 0x0003, 0x0228, 0x000c, 0x8010, 0x0008, + 0x0007, 0x0000, 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, + 0x029a, 0x0003, 0x0228, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, + 0x0233, 0x000c, 0x1810, 0x0000, 0x0233, 0x000c, 0x8074, 0x0000, + 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, + 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008, 0x028e, 0x0003, + 0x8010, 0x0008, 0x0005, 0x0008, 0x028e, 0x0003, 0x1648, 0x000a, + 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, + 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003, 0x3a44, 0x0002, + 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028e, 0x0003, 0x8010, 0x0008, + 0x0003, 0x0008, 0x0292, 0x000b, 0x8010, 0x0008, 0x000b, 0x0000, + 0x0292, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000, 0x0292, 0x000b, + 0x3a47, 0x0002, 0x0d58, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, + 0x0292, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, + 0x3000, 0x0008, 0x0233, 0x000c, 0x0249, 0x0004, 0x3a40, 0x000a, + 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008, 0x0233, 0x000c, + 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, + 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, + 0x0aa5, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, + 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, + 0x0c0a, 0x000b, 0x0283, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, + 0x4447, 0x0002, 0x0ad1, 0x000b, 0xc0c0, 0x0001, 0x00ff, 0x0008, + 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea8, 0x000b, 0xc1e0, 0x0001, + 0xffff, 0x0008, 0x0ea8, 0x000b, 0x8010, 0x0008, 0x0013, 0x0000, + 0x0233, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008, 0x000a, 0x000b, + 0x3a40, 0x000a, 0x0ece, 0x000b, 0x8074, 0x0000, 0x0200, 0x0000, + 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, + 0x43e0, 0x0001, 0x0ecc, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001, + 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa8, 0x0003, 0x0d08, 0x0008, + 0x0321, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, + 0x03a7, 0x000c, 0x808c, 0x0008, 0x0001, 0x0000, 0x04fe, 0x0008, + 0x338a, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000, + 0x8066, 0x0000, 0x0009, 0x0008, 0x46db, 0x0003, 0x0004, 0x0000, + 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0x80e0, 0x0001, + 0x0004, 0x0000, 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0005, 0x0008, + 0x0af5, 0x000b, 0x80e0, 0x0001, 0x0006, 0x0008, 0x0af5, 0x000b, + 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x82e0, 0x0009, + 0x0600, 0x0008, 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0500, 0x0008, + 0x0af5, 0x000b, 0x82e0, 0x0009, 0x0400, 0x0000, 0x0f8a, 0x0003, + 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009, 0x1000, 0x0000, + 0x0b21, 0x0003, 0x0398, 0x000c, 0x3941, 0x0002, 0x0b00, 0x0003, + 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0460, 0x0000, + 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x2209, 0x0008, 0x4706, 0x000b, 0x11fe, 0x0000, 0x331c, 0x0003, + 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x4710, 0x0003, + 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x03e0, 0x0009, + 0x0f19, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, + 0x9180, 0x0001, 0x0003, 0x0008, 0x0303, 0x000b, 0x8072, 0x0000, + 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000, 0x037b, 0x000b, + 0x0398, 0x000c, 0x3941, 0x0002, 0x0b27, 0x0003, 0x8072, 0x0000, + 0x0400, 0x0000, 0x000a, 0x000b, 0x1042, 0x000a, 0x0b2c, 0x000b, + 0x0360, 0x0004, 0x11fe, 0x0000, 0x3731, 0x000b, 0x8072, 0x0000, + 0x0400, 0x0000, 0x8010, 0x0008, 0x000e, 0x0000, 0x037b, 0x000b, + 0x8060, 0x0000, 0x0400, 0x0000, 0x04fe, 0x0008, 0x3746, 0x000b, + 0x808c, 0x0008, 0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x473c, 0x000b, + 0x0060, 0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, + 0x4206, 0x0008, 0x8066, 0x0000, 0x0412, 0x0000, 0x4744, 0x000b, + 0x035d, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, + 0x8062, 0x0008, 0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, + 0x474d, 0x000b, 0x8066, 0x0000, 0x220a, 0x0008, 0x4750, 0x000b, + 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, + 0x8060, 0x0000, 0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x041a, 0x0008, 0x475c, 0x000b, + 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, + 0x0400, 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, + 0x4765, 0x000b, 0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f6b, 0x0003, + 0x0d22, 0x0000, 0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, + 0x1380, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, + 0x4771, 0x000b, 0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, + 0x7f06, 0x0000, 0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, + 0x4779, 0x0003, 0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, + 0x2f44, 0x000a, 0x2f44, 0x000a, 0x0e83, 0x000b, 0x808a, 0x0008, + 0x0003, 0x0008, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, + 0x3000, 0x0008, 0x5b86, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000, + 0x000a, 0x000b, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, + 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, 0x0008, 0x0233, 0x000c, + 0x42fe, 0x0000, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, + 0x0233, 0x000c, 0x4310, 0x0008, 0x0292, 0x000b, 0x3941, 0x0002, + 0x0b9b, 0x000b, 0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, + 0x4000, 0x000f, 0x8010, 0x0008, 0x0012, 0x0008, 0x0233, 0x000c, + 0x0360, 0x0004, 0x1110, 0x0000, 0x0233, 0x000c, 0x11fe, 0x0000, + 0x37a1, 0x000b, 0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, + 0x7f00, 0x0000, 0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, + 0x0bcc, 0x0003, 0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, + 0x7f62, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, + 0x0809, 0x0000, 0x47b6, 0x0003, 0x04fe, 0x0008, 0x33c5, 0x000b, + 0x0460, 0x0000, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, + 0x0211, 0x0000, 0x47be, 0x000b, 0x01fe, 0x0008, 0x00e0, 0x0009, + 0x0fc5, 0x000b, 0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bcb, 0x000b, + 0x0500, 0x0002, 0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, + 0x0faf, 0x000b, 0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, + 0x3e80, 0x0001, 0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, + 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47d4, 0x000b, + 0x8060, 0x0000, 0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, + 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, + 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, + 0xff80, 0x0009, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, + 0x0809, 0x0000, 0x47e6, 0x0003, 0x4000, 0x000f, 0x8d5b, 0xeac4, + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, + 0x12b0 +}; +#ifdef UNIQUE_FW_NAME +unsigned short fw2300ipx_length01 = 0xf091; +#else +unsigned short risc_code_length01 = 0xf091; +#endif + diff --git a/trunk/drivers/scsi/qla2xxx/ql2322.c b/trunk/drivers/scsi/qla2xxx/ql2322.c new file mode 100644 index 000000000000..3c8cafc12eee --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2322.c @@ -0,0 +1,119 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2322"; + +extern unsigned char fw2322ipx_version[]; +extern unsigned char fw2322ipx_version_str[]; +extern unsigned short fw2322ipx_addr01; +extern unsigned short fw2322ipx_code01[]; +extern unsigned short fw2322ipx_length01; +extern unsigned long rseqipx_code_addr01; +extern unsigned short rseqipx_code01[]; +extern unsigned short rseqipx_code_length01; +extern unsigned long xseqipx_code_addr01; +extern unsigned short xseqipx_code01[]; +extern unsigned short xseqipx_code_length01; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_NORMAL, + .fwcode = &fw2322ipx_code01[0], + .fwlen = &fw2322ipx_length01, + .fwstart = &fw2322ipx_addr01, + }, + { + .addressing = FW_INFO_ADDR_EXTENDED, + .fwcode = &rseqipx_code01[0], + .fwlen = &rseqipx_code_length01, + .lfwstart = &rseqipx_code_addr01, + }, + { + .addressing = FW_INFO_ADDR_EXTENDED, + .fwcode = &xseqipx_code01[0], + .fwlen = &xseqipx_code_length01, + .lfwstart = &xseqipx_code_addr01, + }, + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl[] = { + { + .drv_name = qla_driver_name, + .isp_name = "ISP2322", + .fw_info = qla_fw_tbl, + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP6322", + .fw_info = qla_fw_tbl, + }, +}; + +static struct pci_device_id qla2322_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2322, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[0], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP6322, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[1], + }, + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla2322_pci_tbl); + +static int __devinit +qla2322_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla2322_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla2322_pci_driver = { + .name = "qla2322", + .id_table = qla2322_pci_tbl, + .probe = qla2322_probe_one, + .remove = __devexit_p(qla2322_remove_one), +}; + +static int __init +qla2322_init(void) +{ + return pci_module_init(&qla2322_pci_driver); +} + +static void __exit +qla2322_exit(void) +{ + pci_unregister_driver(&qla2322_pci_driver); +} + +module_init(qla2322_init); +module_exit(qla2322_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP2322 FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/trunk/drivers/scsi/qla2xxx/ql2322_fw.c b/trunk/drivers/scsi/qla2xxx/ql2322_fw.c new file mode 100644 index 000000000000..53599a8e2a92 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2322_fw.c @@ -0,0 +1,8376 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ + +/* + * Firmware Version 3.03.20 (15:42 Feb 01, 2006) + */ + +#ifdef UNIQUE_FW_NAME +unsigned short fw2322ipx_version = 3*1024+3; +#else +unsigned short risc_code_version = 3*1024+3; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw2322ipx_version_str[] = {3, 3,20}; +#else +unsigned char firmware_version[] = {3, 3,20}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2322ipx_VERSION_STRING "3.03.20" +#else +#define FW_VERSION_STRING "3.03.20" +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2322ipx_addr01 = 0x0800 ; +#else +unsigned short risc_code_addr01 = 0x0800 ; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned short fw2322ipx_code01[] = { +#else +unsigned short risc_code01[] = { +#endif + 0x0470, 0x0000, 0x0000, 0xe719, 0x0000, 0x0003, 0x0003, 0x0014, + 0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030, + 0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241, + 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972, + 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, + 0x332e, 0x3033, 0x2e32, 0x3020, 0x2020, 0x2020, 0x2400, 0x20a9, + 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f, + 0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001, + 0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000, + 0x400f, 0x2091, 0x2800, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, + 0x2091, 0x2a00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, + 0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00, + 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001, + 0x0000, 0x20c1, 0x0004, 0x20c9, 0x1cff, 0x2059, 0x0000, 0x2b78, + 0x7883, 0x0004, 0x2089, 0x2bc2, 0x2051, 0x1800, 0x2a70, 0x20e1, + 0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e74, 0x00f6, + 0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20c6, 0x1170, + 0x2079, 0x0300, 0x080c, 0x20dc, 0x2061, 0xe000, 0x080c, 0x20c6, + 0x1128, 0x2079, 0x0380, 0x080c, 0x20dc, 0x0060, 0x00fe, 0x7883, + 0x4010, 0x7837, 0x4010, 0x7833, 0x0011, 0x2091, 0x5000, 0x2091, + 0x4080, 0x0cf8, 0x00fe, 0x2029, 0x5600, 0x2031, 0xffff, 0x2039, + 0x55dc, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9, + 0x0800, 0x900e, 0x4104, 0x20e9, 0x0001, 0x20a1, 0x1000, 0x900e, + 0x2001, 0x0dc1, 0x9084, 0x0fff, 0x20a8, 0x4104, 0x2001, 0x0000, + 0x9086, 0x0000, 0x0120, 0x21a8, 0x4104, 0x8001, 0x1de0, 0x756e, + 0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b73, 0x2472, + 0x00ee, 0x20a1, 0x1ddc, 0x7170, 0x810d, 0x810d, 0x810d, 0x810d, + 0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104, + 0x8211, 0x1de0, 0x7170, 0x3400, 0x8001, 0x9102, 0x0120, 0x0218, + 0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d, + 0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9, + 0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211, + 0x1dd8, 0x080c, 0x0f71, 0x080c, 0x61ab, 0x080c, 0xb102, 0x080c, + 0x1128, 0x080c, 0x1352, 0x080c, 0x1c1c, 0x080c, 0x9582, 0x080c, + 0x0d17, 0x080c, 0x10ad, 0x080c, 0x358e, 0x080c, 0x7aca, 0x080c, + 0x6cea, 0x080c, 0x8c5d, 0x080c, 0x88be, 0x080c, 0x22bf, 0x080c, + 0x81f5, 0x080c, 0x20f5, 0x080c, 0x2233, 0x080c, 0x22b4, 0x2091, + 0x3009, 0x7883, 0x0000, 0x1004, 0x0943, 0x7880, 0x9086, 0x0002, + 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04, + 0x0937, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x190c, 0x1200, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c, + 0x9084, 0x0030, 0x9086, 0x0020, 0x1168, 0x7034, 0xc08d, 0x7036, + 0x2001, 0x0050, 0x7076, 0x707a, 0x7056, 0x606b, 0x269c, 0x2071, + 0x1b73, 0x2072, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, + 0x080c, 0x4d66, 0x080c, 0x35b5, 0x080c, 0x7b32, 0x080c, 0x7275, + 0x080c, 0x8d44, 0x080c, 0x88e7, 0x0c68, 0x000b, 0x0c88, 0x0979, + 0x097a, 0x0b15, 0x0977, 0x0bcf, 0x0d16, 0x0d16, 0x0d16, 0x080c, + 0x0d85, 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, + 0x0001, 0x1904, 0x0ae8, 0x080c, 0x0ec4, 0x080c, 0x779e, 0x0150, + 0x080c, 0x77c1, 0x15b0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, + 0x782a, 0x0478, 0x080c, 0x76cd, 0x7000, 0x9086, 0x0001, 0x1904, + 0x0ae8, 0x7098, 0x9086, 0x0029, 0x1904, 0x0ae8, 0x080c, 0x88a7, + 0x080c, 0x8899, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, + 0x2011, 0xffff, 0x080c, 0x2ad3, 0x7a28, 0x9295, 0x5e2c, 0x7a2a, + 0x2011, 0x7612, 0x080c, 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, + 0x2011, 0x6002, 0x080c, 0x8993, 0x2011, 0x8030, 0x901e, 0x7396, + 0x04d0, 0x080c, 0x58aa, 0x2079, 0x0100, 0x7844, 0x9005, 0x1904, + 0x0ae8, 0x2011, 0x6002, 0x080c, 0x8993, 0x2011, 0x7612, 0x080c, + 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, 0x2001, 0x0265, 0x2001, + 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, + 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, + 0x6153, 0x00ce, 0x0804, 0x0ae8, 0x780f, 0x006b, 0x7a28, 0x080c, + 0x77a6, 0x0118, 0x9295, 0x5e2c, 0x0010, 0x9295, 0x402c, 0x7a2a, + 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001, 0x080c, + 0x299b, 0x080c, 0x4ca1, 0x7248, 0xc284, 0x724a, 0x2001, 0x180c, + 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x2001, 0x0390, 0x2003, 0x0400, + 0x080c, 0xacfc, 0x080c, 0xa4f1, 0x2011, 0x0004, 0x080c, 0xcf2b, + 0x080c, 0xad18, 0x080c, 0x6ab1, 0x080c, 0x779e, 0x1120, 0x080c, + 0x29fc, 0x0600, 0x0420, 0x080c, 0x615a, 0x0140, 0x7097, 0x0001, + 0x70d3, 0x0000, 0x080c, 0x5a7c, 0x0804, 0x0ae8, 0x2001, 0x0390, + 0x2003, 0x0404, 0x080c, 0x5840, 0xd094, 0x0188, 0x2011, 0x180c, + 0x2204, 0xc0cd, 0x2012, 0x080c, 0x5844, 0xd0d4, 0x1118, 0x080c, + 0x29fc, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, + 0x5844, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, + 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x6c09, 0x1128, + 0xd0a4, 0x0118, 0x2204, 0xc0fd, 0x2012, 0x080c, 0x6bcf, 0x0120, + 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8, 0x707f, 0x0000, 0x080c, 0x779e, + 0x1130, 0x70b0, 0x9005, 0x1168, 0x080c, 0xd389, 0x0050, 0x080c, + 0xd389, 0x70dc, 0xd09c, 0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, + 0x6130, 0x70e7, 0x0000, 0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, + 0x2a04, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, + 0x080c, 0x779e, 0x1178, 0x9016, 0x0016, 0x080c, 0x27a4, 0x2019, + 0x196d, 0x211a, 0x001e, 0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, + 0x0000, 0x0020, 0x2019, 0x196d, 0x201b, 0x0000, 0x2079, 0x1847, + 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72de, 0x080c, 0x779e, 0x0118, + 0x9296, 0x0004, 0x0518, 0x2011, 0x0001, 0x080c, 0xcf2b, 0x70ab, + 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00fe, 0x080c, 0x30bf, + 0x080c, 0xacfc, 0x2011, 0x0005, 0x080c, 0xa62b, 0x080c, 0xad18, + 0x080c, 0x779e, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, + 0x27a4, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x00e0, 0x70ab, 0x0000, + 0x70af, 0xffff, 0x7003, 0x0002, 0x080c, 0xacfc, 0x2011, 0x0005, + 0x080c, 0xa62b, 0x080c, 0xad18, 0x080c, 0x779e, 0x0148, 0x00c6, + 0x2061, 0x0100, 0x0016, 0x080c, 0x27a4, 0x61e2, 0x001e, 0x00ce, + 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x779e, 0x1118, + 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x779e, 0x1110, + 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x341e, 0x8108, + 0x1f04, 0x0afc, 0x707f, 0x0000, 0x7080, 0x9084, 0x00ff, 0x7082, + 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6, 0x0126, 0x2091, + 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, 0x0bcc, 0x70ac, 0x9086, + 0xffff, 0x0120, 0x080c, 0x30bf, 0x0804, 0x0bcc, 0x70dc, 0xd0ac, + 0x1110, 0xd09c, 0x0538, 0xd084, 0x0528, 0x0006, 0x2001, 0x0103, + 0x2003, 0x002b, 0x000e, 0xd08c, 0x01e8, 0x080c, 0x3487, 0x11b0, + 0x70e0, 0x9086, 0xffff, 0x0190, 0x080c, 0x327b, 0x70dc, 0xd094, + 0x1904, 0x0bcc, 0x2011, 0x0001, 0x080c, 0xd645, 0x0110, 0x2011, + 0x0003, 0x901e, 0x080c, 0x32b5, 0x0804, 0x0bcc, 0x70e4, 0x9005, + 0x1904, 0x0bcc, 0x70a8, 0x9005, 0x1904, 0x0bcc, 0x70dc, 0xd0a4, + 0x0118, 0xd0b4, 0x0904, 0x0bcc, 0x080c, 0x6bcf, 0x1904, 0x0bcc, + 0x080c, 0x6c22, 0x1904, 0x0bcc, 0x080c, 0x6c09, 0x01c0, 0x0156, + 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1118, + 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b6c, 0x00ce, + 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0bcc, 0x0006, + 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b4, 0x080c, + 0x0fe1, 0x2011, 0x19ce, 0x080c, 0x0fe1, 0x7030, 0xc08c, 0x7032, + 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e98, 0x9006, 0x080c, + 0x2631, 0x080c, 0x3487, 0x0118, 0x080c, 0x4e3e, 0x0050, 0x0036, + 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4e58, 0x004e, + 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x77c1, 0x0150, 0x080c, + 0x779e, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, + 0x782a, 0x00fe, 0x080c, 0xacfc, 0x2001, 0x19e9, 0x2004, 0x9086, + 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0xa62b, 0x2011, 0x0000, + 0x080c, 0xa635, 0x080c, 0xad18, 0x012e, 0x00be, 0x0005, 0x0016, + 0x0026, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, + 0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x6119, + 0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0120, 0x2011, + 0x0040, 0x080c, 0x2ad3, 0xd19c, 0x0120, 0x2011, 0x0008, 0x080c, + 0x2ad3, 0x0006, 0x0036, 0x0156, 0x0000, 0x2001, 0x19a8, 0x2004, + 0x9005, 0x1518, 0x080c, 0x2a67, 0x1148, 0x2001, 0x0001, 0x080c, + 0x29ca, 0x2001, 0x0001, 0x080c, 0x29ad, 0x00b8, 0x080c, 0x2a6f, + 0x1138, 0x9006, 0x080c, 0x29ca, 0x9006, 0x080c, 0x29ad, 0x0068, + 0x080c, 0x2a77, 0x1d50, 0x2001, 0x1998, 0x2004, 0xd0fc, 0x0108, + 0x0020, 0x080c, 0x27d8, 0x0804, 0x0cc9, 0x20a9, 0x003a, 0x1d04, + 0x0c1f, 0x080c, 0x8a7f, 0x1f04, 0x0c1f, 0x080c, 0x77af, 0x0148, + 0x080c, 0x77c1, 0x1118, 0x080c, 0x7ac5, 0x0050, 0x080c, 0x77a6, + 0x0dd0, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x080c, 0x76cd, 0x0020, + 0x2009, 0x00f8, 0x080c, 0x6119, 0x7850, 0xc0e5, 0x7852, 0x080c, + 0x779e, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, + 0x2019, 0xea60, 0x0d0c, 0x8a7f, 0x7820, 0xd09c, 0x15a0, 0x080c, + 0x779e, 0x0904, 0x0cab, 0x7824, 0xd0ac, 0x1904, 0x0cce, 0x080c, + 0x77c1, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e, + 0x2011, 0x1800, 0x080c, 0x2ad3, 0x080c, 0x2a7f, 0x7824, 0x9084, + 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004, + 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x8421, 0x1160, 0x1d04, + 0x0c7b, 0x080c, 0x8a7f, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x7003, + 0x0001, 0x0804, 0x0cce, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004, + 0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x1d04, 0x0c91, 0x080c, + 0x8a7f, 0x2009, 0x199b, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, + 0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2ad3, 0x20a9, + 0x0002, 0x080c, 0x2a60, 0x7924, 0x080c, 0x2a7f, 0xd19c, 0x0110, + 0x080c, 0x299b, 0x00f0, 0x080c, 0x77af, 0x1140, 0x94a2, 0x03e8, + 0x1128, 0x080c, 0x7772, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800, + 0x080c, 0x2ad3, 0x080c, 0x2a7f, 0x7824, 0x080c, 0x77b8, 0x0110, + 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c83, 0x7003, 0x0001, + 0x0028, 0x2001, 0x0001, 0x080c, 0x2631, 0x00a0, 0x7850, 0xc0e4, + 0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, + 0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2ad3, 0x7828, 0x9085, + 0x0028, 0x782a, 0x2001, 0x19a8, 0x2003, 0x0000, 0x9006, 0x78f2, + 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x002e, 0x001e, + 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x00b6, 0x00c6, + 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x8a7f, 0x015e, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e, + 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086, + 0x0001, 0x1110, 0x080c, 0x35b5, 0x00ee, 0x0005, 0x0005, 0x2a70, + 0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0014, + 0x600f, 0x0137, 0x2001, 0x197c, 0x900e, 0x2102, 0x7196, 0x2001, + 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008, + 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd389, 0x70ef, + 0x00c0, 0x2061, 0x196c, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800, + 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f, + 0x07d0, 0x2061, 0x1974, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f, + 0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061, + 0x1989, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, + 0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x67b4, + 0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, + 0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210, + 0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, + 0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, + 0x0d87, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000, + 0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e, + 0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, + 0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091, + 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, + 0x1b2b, 0x7a08, 0x226a, 0x2069, 0x1b2c, 0x7a18, 0x226a, 0x8d68, + 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1b39, 0x201a, 0x2019, 0x1b3c, + 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, + 0x9386, 0x1b55, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, + 0xdead, 0x2019, 0x1b3a, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, + 0x0000, 0x2069, 0x1a81, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, + 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dde, 0x2069, 0x1aa1, 0x2019, + 0x0050, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, + 0x1f04, 0x0deb, 0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, + 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, + 0xd084, 0x0180, 0x2001, 0x1a25, 0x2004, 0x9005, 0x0128, 0x2001, + 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, + 0x2003, 0x1001, 0x080c, 0x584f, 0x1170, 0x080c, 0x0f32, 0x0110, + 0x080c, 0x0e85, 0x080c, 0x584f, 0x1130, 0x2071, 0x1800, 0x2011, + 0x8000, 0x080c, 0x0f46, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c, + 0xaced, 0x2079, 0x0380, 0x2069, 0x1b0b, 0x7818, 0x6802, 0x781c, + 0x6806, 0x7840, 0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, + 0x1b16, 0x9016, 0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210, + 0x8318, 0x8210, 0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a, + 0x7830, 0x681a, 0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826, + 0x7803, 0x0000, 0x2069, 0x1acb, 0x901e, 0x20a9, 0x0020, 0x7b26, + 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e5f, 0x2069, 0x1aeb, + 0x2019, 0x00b0, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, + 0x8318, 0x1f04, 0x0e6c, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, + 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, + 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, + 0x0080, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x2011, + 0x0040, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x0c78, + 0x0026, 0x080c, 0x0f32, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294, + 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011, + 0x1b47, 0x080c, 0x0f46, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214, + 0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, + 0x2011, 0x6840, 0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0, + 0x080c, 0x0f37, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f32, 0x0148, + 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, + 0x0f37, 0x002e, 0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f32, + 0x1130, 0x2011, 0x8040, 0x080c, 0x0f46, 0x002e, 0x0005, 0x080c, + 0x2a77, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, + 0x0f37, 0x002e, 0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800, + 0xd0b4, 0x70ec, 0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006, + 0x3b00, 0x9084, 0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5, + 0xc1f5, 0x0099, 0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071, + 0x1800, 0xd0e4, 0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016, + 0x71e8, 0x0019, 0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000, + 0x9084, 0x0007, 0x000b, 0x0005, 0x0eea, 0x0ec4, 0x0ec4, 0x0e98, + 0x0ed3, 0x0ec4, 0x0ec4, 0x0ed3, 0xc284, 0x0016, 0x3b08, 0x3a00, + 0x9104, 0x918d, 0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0, + 0x001e, 0x0005, 0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86, + 0x1800, 0x190c, 0x0d85, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee, + 0xd0e4, 0x1118, 0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800, + 0x190c, 0x0d85, 0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4, + 0x1140, 0x9284, 0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1, + 0x0861, 0x0005, 0x1d04, 0x0f5a, 0x2091, 0x6000, 0x1f04, 0x0f5a, + 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, + 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, + 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, + 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, + 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, + 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, + 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, + 0x000e, 0x200f, 0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, + 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, + 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, + 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, + 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, + 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, + 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f61, 0x2100, + 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, + 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, + 0x0005, 0x20e9, 0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, + 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, + 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, + 0x8007, 0x7180, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, + 0x23a0, 0x900e, 0x080c, 0x0d65, 0x2001, 0x0000, 0x810f, 0x20a9, + 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, + 0x0006, 0x080c, 0x108b, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, + 0x1800, 0x080c, 0x1104, 0x090c, 0x0d85, 0x00ee, 0x0005, 0x0086, + 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, + 0x2071, 0x1800, 0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, + 0x9906, 0x090c, 0x0d85, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d85, + 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, + 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1910, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, + 0x090c, 0x0d85, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, + 0x8001, 0x0270, 0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, + 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, + 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, + 0x70c0, 0x90ca, 0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, + 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, + 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, + 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, + 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, + 0x080c, 0x8899, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, + 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, + 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, + 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, + 0x11a0, 0x2001, 0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940, + 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, + 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, + 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, + 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, + 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, + 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, + 0x1800, 0x74be, 0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, + 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, + 0x0440, 0x0278, 0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270, + 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, + 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, + 0x00e6, 0x2071, 0x1a24, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, + 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, + 0x0080, 0x9006, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, + 0x113e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, + 0x1f04, 0x1147, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, + 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a24, 0x701c, 0x9088, + 0x1a2e, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, + 0x090c, 0x0d85, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, + 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, + 0x00e6, 0x2071, 0x1a24, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, + 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, + 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1190, 0x1313, + 0x118e, 0x118e, 0x1307, 0x1307, 0x1307, 0x1307, 0x080c, 0x0d85, + 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, + 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2e, + 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, + 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, + 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, + 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, + 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, + 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, + 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, + 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, + 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, + 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, + 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, + 0x2009, 0x1a24, 0x2104, 0xc095, 0x200a, 0x080c, 0x116d, 0x0005, + 0x0016, 0x00e6, 0x2071, 0x1a24, 0x00f6, 0x2079, 0x0080, 0x792c, + 0xd1bc, 0x190c, 0x0d7e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, + 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x117e, + 0x1226, 0x125a, 0x1332, 0x0d85, 0x134d, 0x0d85, 0x918c, 0x0700, + 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, + 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, + 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, + 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11c3, 0x0005, + 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, + 0x080c, 0x117e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, + 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, + 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11d8, 0x0005, 0x7008, + 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, + 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, + 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, + 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906, + 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, + 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, + 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, + 0x00de, 0x009e, 0x080c, 0x116d, 0x0005, 0xa8a8, 0xd08c, 0x0005, + 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, 0x908e, 0x0100, + 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, + 0x7006, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x108b, + 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, + 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, + 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, + 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x114e, 0x00e8, + 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x7006, 0x000e, 0x001e, + 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xb16c, + 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, + 0x108b, 0x7007, 0x0000, 0x080c, 0x116d, 0x00ae, 0x0005, 0x0126, + 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, + 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x192f, 0x204c, 0xa87c, + 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, + 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041, + 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, + 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, + 0x0096, 0x2001, 0x192f, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8f88, + 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8de7, + 0x7007, 0x0000, 0x080c, 0x117e, 0x0005, 0x7007, 0x0000, 0x080c, + 0x117e, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, + 0x1a6e, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007, + 0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, + 0x0000, 0x2001, 0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0120, + 0x7820, 0x080c, 0x13b6, 0x0cc8, 0x2001, 0x1a6f, 0x2003, 0x0000, + 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, + 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b, + 0x1a81, 0x78e3, 0xff00, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001, + 0x1a70, 0x2003, 0x0000, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, + 0x781f, 0x0303, 0x2061, 0x1a81, 0x602f, 0x1ddc, 0x2001, 0x181a, + 0x2004, 0x9082, 0x1ddc, 0x6032, 0x603b, 0x1ec1, 0x602b, 0x1ac1, + 0x6007, 0x1aa1, 0x2061, 0x1aa1, 0x606f, 0x193d, 0x2001, 0x1928, + 0x2004, 0x607a, 0x783f, 0x348e, 0x00ce, 0x0005, 0x9086, 0x000d, + 0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, + 0xcf09, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, + 0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, + 0xb20a, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, + 0x9184, 0x0070, 0x190c, 0x0d7e, 0xd19c, 0x05a0, 0x7820, 0x908c, + 0xf000, 0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000, + 0x9086, 0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867, + 0x0103, 0x080c, 0x6e27, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, + 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x190c, 0x68df, 0x00be, 0x6044, + 0xd0fc, 0x190c, 0xad25, 0x080c, 0xb195, 0x7808, 0xd09c, 0x19b0, + 0x012e, 0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d85, 0x002b, 0x012e, + 0x0005, 0x04b0, 0x012e, 0x0005, 0x1438, 0x145e, 0x148e, 0x1493, + 0x1497, 0x149c, 0x14c4, 0x14c8, 0x14d6, 0x14da, 0x1438, 0x15a7, + 0x15ab, 0x161d, 0x1624, 0x1438, 0x1625, 0x1626, 0x1631, 0x1638, + 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x149e, + 0x1438, 0x1466, 0x148b, 0x1452, 0x1438, 0x1472, 0x143c, 0x143a, + 0x080c, 0x0d85, 0x080c, 0x0d7e, 0x080c, 0x1643, 0x2009, 0x1a7d, + 0x2104, 0x8000, 0x200a, 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0005, + 0x6044, 0xd0fc, 0x190c, 0xad25, 0x2009, 0x0055, 0x080c, 0xb20a, + 0x012e, 0x0005, 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, + 0xad25, 0x2009, 0x0055, 0x080c, 0xb20a, 0x0005, 0x2009, 0x0048, + 0x080c, 0x1643, 0x2060, 0x080c, 0xb20a, 0x0005, 0x2009, 0x0054, + 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xad25, 0x080c, + 0xb20a, 0x0005, 0x080c, 0x1643, 0x2060, 0x0056, 0x0066, 0x080c, + 0x1643, 0x2028, 0x080c, 0x1643, 0x2030, 0x0036, 0x0046, 0x2021, + 0x0000, 0x2418, 0x2009, 0x0056, 0x080c, 0xb20a, 0x004e, 0x003e, + 0x006e, 0x005e, 0x0005, 0x080c, 0x1643, 0x0005, 0x7004, 0xc085, + 0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, + 0x1643, 0x080c, 0x1740, 0x0005, 0x080c, 0x0d85, 0x080c, 0x1643, + 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, + 0x0048, 0x080c, 0xb20a, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, + 0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1648, 0x2001, + 0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, + 0x080c, 0x1643, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, + 0x009e, 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0x080c, 0x1643, + 0x080c, 0x0d85, 0x080c, 0x1643, 0x080c, 0x1592, 0x7827, 0x0018, + 0x79ac, 0xd1dc, 0x0904, 0x1543, 0x7827, 0x0015, 0x7828, 0x782b, + 0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x0804, 0x1549, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab, + 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d85, + 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x1577, + 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x0005, 0x7827, + 0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, + 0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, + 0x0140, 0x00ee, 0x080c, 0x1b1e, 0x080c, 0x1366, 0x7803, 0x0001, + 0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, + 0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, + 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x2001, 0x020d, + 0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, + 0x0d85, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, + 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x080c, 0xcf1b, 0x0158, 0xa9ac, + 0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, + 0xc0bd, 0xa882, 0x080c, 0xcae9, 0x0005, 0x6020, 0x9086, 0x0009, + 0x1128, 0x2009, 0x004c, 0x080c, 0xb20a, 0x0048, 0x6010, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd31e, 0x2029, + 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, + 0x7dbc, 0x080c, 0xeeb1, 0xd5a4, 0x1118, 0x080c, 0x1648, 0x0005, + 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0005, 0x781f, 0x0300, 0x7803, + 0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, + 0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, + 0x080c, 0x16b9, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, + 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d85, + 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, + 0x1723, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, + 0x0020, 0x080c, 0x1648, 0x0005, 0x81ff, 0x190c, 0x0d85, 0x0005, + 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, + 0x1612, 0x2071, 0x0200, 0x080c, 0x1710, 0x05e0, 0x080c, 0x1723, + 0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, + 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, + 0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, + 0x00b0, 0x00f6, 0x2c78, 0x080c, 0x1942, 0x00fe, 0x2009, 0x01f4, + 0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, + 0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x1648, 0x0040, 0x2001, + 0x020d, 0x2003, 0x0020, 0x080c, 0x1366, 0x7803, 0x0001, 0x00ee, + 0x001e, 0x0005, 0x080c, 0x1723, 0x0dd0, 0x2001, 0x020d, 0x2003, + 0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, + 0x0053, 0x080c, 0xb20a, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, + 0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x92d5, + 0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ed9, 0x0cd0, 0x0005, + 0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, + 0x080c, 0x16b9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, + 0x080c, 0x1592, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, + 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, + 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, + 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, + 0x810c, 0x080c, 0x16ab, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, + 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, + 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, + 0x080c, 0x82b8, 0x080c, 0x1b1e, 0x0090, 0x7827, 0x0015, 0x782b, + 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, + 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, + 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, + 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, + 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, + 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, + 0x0005, 0x00f6, 0x00e6, 0x2079, 0x0300, 0x0006, 0x2071, 0x1a6e, + 0x7008, 0x9005, 0x1110, 0x78e3, 0x0c0c, 0x8000, 0x700a, 0x0026, + 0x2011, 0x0006, 0x7808, 0xd09c, 0x0150, 0x0016, 0x0026, 0x00c6, + 0x080c, 0x13d4, 0x00ce, 0x002e, 0x001e, 0x8211, 0x1d98, 0x002e, + 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x00b9, + 0x1178, 0x2071, 0x1a6e, 0x7008, 0x9005, 0x0130, 0x8001, 0x0a0c, + 0x0d85, 0x700a, 0x78e3, 0x0c00, 0x000e, 0x00ee, 0x00fe, 0x0005, + 0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, 0x2009, + 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, + 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, + 0x1108, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, + 0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, + 0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, + 0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, + 0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, + 0x1158, 0x2021, 0x1a7e, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, + 0x82b8, 0x080c, 0x1b1e, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, + 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, + 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x17a2, 0x7017, + 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x17a2, 0x2001, + 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, + 0x1904, 0x17a2, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, + 0x8210, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xd2f9, + 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, + 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1ee1, 0x1190, + 0x080c, 0x199f, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, + 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, + 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, + 0x080c, 0x1648, 0x0005, 0x080c, 0x0d85, 0x2001, 0x180d, 0x2004, + 0xd08c, 0x190c, 0x6ccc, 0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, + 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730, 0xa864, + 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ec1, 0x2165, 0x0002, + 0x17df, 0x184d, 0x17df, 0x17df, 0x17e3, 0x182e, 0x17df, 0x1803, + 0x17d8, 0x1844, 0x17df, 0x17df, 0x17e8, 0x193a, 0x1817, 0x180d, + 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x1844, 0x9085, + 0x0001, 0x0804, 0x1930, 0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1854, + 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x18bf, 0xa898, 0x901d, 0x1108, + 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, + 0x2004, 0x9080, 0x9536, 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, + 0xa8ae, 0x0804, 0x1918, 0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, + 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1854, 0xa87c, 0xd0bc, 0x0978, + 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x18bf, 0xa87c, + 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, + 0x090c, 0x0d85, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ec1, + 0x2065, 0xa888, 0xd19c, 0x1904, 0x18bf, 0x0430, 0xa87c, 0xd0ac, + 0x0904, 0x17df, 0xa804, 0x9045, 0x090c, 0x0d85, 0xa164, 0xa91a, + 0x91ec, 0x000f, 0x9d80, 0x1ec1, 0x2065, 0x9006, 0xa842, 0xa83e, + 0xd19c, 0x1904, 0x18bf, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17df, + 0x9006, 0xa842, 0xa83e, 0x0804, 0x18bf, 0xa87c, 0xd0ac, 0x0904, + 0x17df, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, + 0x0d85, 0x9082, 0x001b, 0x0002, 0x1877, 0x1877, 0x1879, 0x1877, + 0x1877, 0x1877, 0x1883, 0x1877, 0x1877, 0x1877, 0x188d, 0x1877, + 0x1877, 0x1877, 0x1897, 0x1877, 0x1877, 0x1877, 0x18a1, 0x1877, + 0x1877, 0x1877, 0x18ab, 0x1877, 0x1877, 0x1877, 0x18b5, 0x080c, + 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa37c, + 0xa280, 0x0804, 0x1918, 0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, + 0x17ed, 0xa38c, 0xa290, 0x0804, 0x1918, 0xa594, 0xa498, 0x9d86, + 0x0024, 0x0904, 0x17ed, 0xa39c, 0xa2a0, 0x0804, 0x1918, 0xa5a4, + 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa3ac, 0xa2b0, 0x0804, + 0x1918, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x17ed, 0xa3bc, + 0xa2c0, 0x0804, 0x1918, 0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, + 0x17ed, 0xa3cc, 0xa2d0, 0x0804, 0x1918, 0xa5d4, 0xa4d8, 0x9d86, + 0x0024, 0x0904, 0x17ed, 0xa3dc, 0xa2e0, 0x0804, 0x1918, 0x2c05, + 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x18e2, + 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18ed, 0x18e0, 0x18e0, + 0x18e0, 0x18e0, 0x18e0, 0x18f8, 0x18e0, 0x18e0, 0x18e0, 0x18e0, + 0x18e0, 0x1903, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x18e0, 0x190e, + 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, + 0x0904, 0x17ed, 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, + 0xa690, 0x9d86, 0x002c, 0x0904, 0x17ed, 0xa394, 0xa298, 0x0400, + 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17ed, + 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, + 0x002c, 0x0904, 0x17ed, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, + 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x17ed, 0xa3dc, 0xa2e0, + 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, + 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, + 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, + 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, + 0xa812, 0x0c70, 0x0804, 0x17df, 0x2001, 0x180d, 0x2004, 0xd08c, + 0x190c, 0x6ccc, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, + 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ebc, 0xa813, + 0x1ebc, 0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, + 0x0d85, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, + 0x0d85, 0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, + 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, + 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, + 0x8109, 0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, + 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, + 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d85, + 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1ec1, 0x2015, + 0x82ff, 0x090c, 0x0d85, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, + 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a94, 0x19f6, + 0x19f6, 0x1a94, 0x1a94, 0x1a8e, 0x1a94, 0x19f6, 0x1a45, 0x1a45, + 0x1a45, 0x1a94, 0x1a94, 0x1a94, 0x1a8b, 0x1a45, 0xc0fc, 0xa882, + 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a96, 0x2c05, + 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x19e2, + 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e6, 0x19e0, 0x19e0, + 0x19e0, 0x19e0, 0x19e0, 0x19ea, 0x19e0, 0x19e0, 0x19e0, 0x19e0, + 0x19e0, 0x19ee, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19e0, 0x19f2, + 0x080c, 0x0d85, 0xa774, 0xa678, 0x0804, 0x1a96, 0xa78c, 0xa690, + 0x0804, 0x1a96, 0xa7a4, 0xa6a8, 0x0804, 0x1a96, 0xa7bc, 0xa6c0, + 0x0804, 0x1a96, 0xa7d4, 0xa6d8, 0x0804, 0x1a96, 0x2c05, 0x908a, + 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a19, 0x1a19, + 0x1a1b, 0x1a19, 0x1a19, 0x1a19, 0x1a21, 0x1a19, 0x1a19, 0x1a19, + 0x1a27, 0x1a19, 0x1a19, 0x1a19, 0x1a2d, 0x1a19, 0x1a19, 0x1a19, + 0x1a33, 0x1a19, 0x1a19, 0x1a19, 0x1a39, 0x1a19, 0x1a19, 0x1a19, + 0x1a3f, 0x080c, 0x0d85, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, + 0x1a96, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x1a96, 0xa594, + 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1a96, 0xa5a4, 0xa4a8, 0xa3ac, + 0xa2b0, 0x0804, 0x1a96, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, + 0x1a96, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1a96, 0xa5d4, + 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1a96, 0x2c05, 0x908a, 0x0034, + 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a68, 0x1a66, 0x1a66, + 0x1a66, 0x1a66, 0x1a66, 0x1a6f, 0x1a66, 0x1a66, 0x1a66, 0x1a66, + 0x1a66, 0x1a76, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a7d, + 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a66, 0x1a84, 0x080c, 0x0d85, + 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0438, 0xa584, + 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, + 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, 0xa7bc, + 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, + 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, 0x1e97, + 0x1904, 0x199f, 0x900e, 0x0050, 0x080c, 0x0d85, 0xab2e, 0xaa32, + 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1e97, 0x0005, 0x6014, + 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, + 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, + 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, + 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0xa974, + 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, + 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, + 0x0804, 0xb20a, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, + 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, + 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, + 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x13d4, 0x8631, + 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, + 0xd09c, 0x190c, 0x13d4, 0x00ce, 0x2001, 0x0038, 0x080c, 0x1bae, + 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c, 0x0d85, + 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1bbd, + 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1baa, 0x7827, 0x0015, + 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, + 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x2001, 0xf000, 0x8001, + 0x090c, 0x0d85, 0x7aac, 0xd2ac, 0x1dd0, 0x00fe, 0x080c, 0x779e, + 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, + 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, + 0x0804, 0x7840, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, + 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, 0x2a8b, + 0x2009, 0x003c, 0x080c, 0x2220, 0x2001, 0x015d, 0x2003, 0x0000, + 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x8899, 0x70a0, 0x70a2, + 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, + 0x00f6, 0x2079, 0x0300, 0x080c, 0x1366, 0x7803, 0x0001, 0x00fe, + 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, + 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x779e, 0x1108, 0x0005, + 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, + 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, + 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, + 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, + 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, + 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, + 0x080c, 0x16b9, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1702, + 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, + 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, + 0x0904, 0x1c1b, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, + 0x0d85, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, + 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, + 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, + 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, + 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1bb4, 0x9186, + 0x0040, 0x190c, 0x0d85, 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, + 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, + 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, + 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0d85, 0xa001, + 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400, 0x2079, + 0x0380, 0x2001, 0x19e8, 0x2070, 0x012e, 0x0005, 0x2cf0, 0x0126, + 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964, 0xa91a, 0x918c, + 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c50, 0x1c50, 0x1c50, 0x1c52, + 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c44, 0x1c5a, 0x1c50, 0x1c56, + 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x9086, 0x0008, 0x1148, 0xa87c, + 0xd0b4, 0x0904, 0x1dca, 0x2011, 0x1ebc, 0x2205, 0xab88, 0x00a8, + 0x080c, 0x0d85, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186, 0x001b, + 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1dca, 0x9184, 0x000f, + 0x9080, 0x1ec1, 0x2015, 0x2205, 0xab88, 0x2908, 0xa80a, 0xa90e, + 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e, 0x0005, 0x2cf0, + 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa88c, 0xa990, + 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942, 0xa846, 0xa94a, + 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198, 0x2940, 0xa064, + 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1ec1, 0x2065, 0x2c05, 0x2808, + 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x012e, 0x3e60, + 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126, 0x2091, 0x2400, + 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc, 0x1904, 0x1d94, + 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109, 0xa916, + 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1ec1, 0x2145, 0x0002, + 0x1cc8, 0x1cd6, 0x1cc8, 0x1cc8, 0x1cc8, 0x1cca, 0x1cc8, 0x1cc8, + 0x1d2b, 0x1d2b, 0x1cc8, 0x1cc8, 0x1cc8, 0x1d29, 0x1cc8, 0x1cc8, + 0x080c, 0x0d85, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184, 0x000f, + 0x9080, 0x1ec1, 0x2045, 0xd19c, 0x1904, 0x1d2b, 0x9036, 0x2638, + 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, + 0x1cfb, 0x1cfb, 0x1cfd, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d03, 0x1cfb, + 0x1cfb, 0x1cfb, 0x1d09, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d0f, 0x1cfb, + 0x1cfb, 0x1cfb, 0x1d15, 0x1cfb, 0x1cfb, 0x1cfb, 0x1d1b, 0x1cfb, + 0x1cfb, 0x1cfb, 0x1d21, 0x080c, 0x0d85, 0xb574, 0xb478, 0xb37c, + 0xb280, 0x0804, 0x1d70, 0xb584, 0xb488, 0xb38c, 0xb290, 0x0804, + 0x1d70, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d70, 0xb5a4, + 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d70, 0xb5b4, 0xb4b8, 0xb3bc, + 0xb2c0, 0x0804, 0x1d70, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0, 0x0804, + 0x1d70, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d70, 0x0804, + 0x1d70, 0x080c, 0x0d85, 0x2805, 0x908a, 0x0034, 0x1a0c, 0x0d85, + 0x9082, 0x001b, 0x0002, 0x1d4e, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, + 0x1d4c, 0x1d55, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d5c, + 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d4c, 0x1d63, 0x1d4c, 0x1d4c, + 0x1d4c, 0x1d4c, 0x1d4c, 0x1d6a, 0x080c, 0x0d85, 0xb56c, 0xb470, + 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584, 0xb488, 0xb78c, + 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0, 0xb7a4, 0xb6a8, + 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0, 0xb3c4, + 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc, 0xb2e0, + 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8109, + 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840, 0x2805, 0x9005, + 0x1168, 0xb004, 0x9005, 0x090c, 0x0d85, 0x2050, 0xb164, 0xa91a, + 0x9184, 0x000f, 0x9080, 0x1ec1, 0x2045, 0x2805, 0x2810, 0x2a08, + 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344, 0xd3fc, 0x190c, + 0x0d85, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118, 0xa848, 0x9206, + 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c, 0x1ee1, 0x1998, + 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140, 0xa810, 0x2005, + 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070, 0x00c6, 0x3e60, + 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce, 0x8319, 0xab16, + 0x1904, 0x1d7d, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105, 0x6046, + 0x0804, 0x1d7a, 0x080c, 0x0d85, 0x00f6, 0x00e6, 0x0096, 0x00c6, + 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x2079, 0x0090, 0x2001, + 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000, 0x6014, + 0x2048, 0x080c, 0xcf1b, 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, + 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, + 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, + 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xcae9, 0x080c, 0xacfc, + 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c, 0x2220, + 0x080c, 0xa7a1, 0x2011, 0x0000, 0x080c, 0xa635, 0x002e, 0x00ce, + 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0090, 0x781c, + 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, + 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319, 0x090c, 0x0d85, + 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, + 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, + 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090, 0x782b, 0x0008, + 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x19e8, + 0x7054, 0x9086, 0x0000, 0x0904, 0x1e92, 0x2079, 0x0090, 0x2009, + 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, + 0x0003, 0x0188, 0x080c, 0xeefa, 0x2001, 0x0133, 0x2004, 0x9005, + 0x090c, 0x0d85, 0x0016, 0x2009, 0x0040, 0x080c, 0x2220, 0x001e, + 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, + 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2220, 0x782c, + 0xd0fc, 0x09a8, 0x080c, 0xad18, 0x782c, 0xd0fc, 0x1de8, 0x080c, + 0xacfc, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004, 0x782c, + 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2220, 0x782b, 0x0002, + 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d85, 0x8c60, + 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005, 0x0168, + 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ec1, 0x2065, + 0x8cff, 0x090c, 0x0d85, 0x8a51, 0x0005, 0x2050, 0x0005, 0x0000, + 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, + 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, + 0x0000, 0x0000, 0x1eb4, 0x1eb0, 0x1eb4, 0x1eb4, 0x1ebe, 0x0000, + 0x1eb4, 0x1ebb, 0x1ebb, 0x1eb8, 0x1ebb, 0x1ebb, 0x0000, 0x1ebe, + 0x1ebb, 0x0000, 0x1eb6, 0x1eb6, 0x0000, 0x1eb6, 0x1ebe, 0x0000, + 0x1eb6, 0x1ebc, 0x1ebc, 0x1ebc, 0x0000, 0x1ebc, 0x0000, 0x1ebe, + 0x1ebc, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, + 0x0904, 0x20c0, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, + 0x9086, 0x0008, 0x1118, 0x2061, 0x1ebc, 0x00d0, 0x9de0, 0x1ec1, + 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, + 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, + 0x0310, 0x0804, 0x20c0, 0xa004, 0x9045, 0x0904, 0x20c0, 0x08d8, + 0x2c05, 0x9005, 0x0904, 0x1fa8, 0xdd9c, 0x1904, 0x1f64, 0x908a, + 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1f39, 0x1f39, + 0x1f3b, 0x1f39, 0x1f39, 0x1f39, 0x1f41, 0x1f39, 0x1f39, 0x1f39, + 0x1f47, 0x1f39, 0x1f39, 0x1f39, 0x1f4d, 0x1f39, 0x1f39, 0x1f39, + 0x1f53, 0x1f39, 0x1f39, 0x1f39, 0x1f59, 0x1f39, 0x1f39, 0x1f39, + 0x1f5f, 0x080c, 0x0d85, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, + 0x1f9e, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f9e, 0xa09c, + 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f9e, 0xa0ac, 0x9422, 0xa0b0, + 0x931b, 0x0804, 0x1f9e, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, + 0x1f9e, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f9e, 0xa0dc, + 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0d85, + 0x9082, 0x001b, 0x0002, 0x1f86, 0x1f84, 0x1f84, 0x1f84, 0x1f84, + 0x1f84, 0x1f8b, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f90, + 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f84, 0x1f95, 0x1f84, 0x1f84, + 0x1f84, 0x1f84, 0x1f84, 0x1f9a, 0x080c, 0x0d85, 0xa07c, 0x9422, + 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, + 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, + 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, + 0x9405, 0x0160, 0x8a51, 0x0904, 0x20c0, 0x8c60, 0x0804, 0x1f10, + 0xa004, 0x9045, 0x0904, 0x20c0, 0x0804, 0x1eeb, 0x8a51, 0x0904, + 0x20c0, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, + 0x20c0, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ec1, 0x2c05, 0x2060, + 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20b5, 0x2c05, 0x8422, 0x8420, + 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2052, + 0x9082, 0x001b, 0x0002, 0x1fee, 0x1fee, 0x1ff0, 0x1fee, 0x1fee, + 0x1fee, 0x1ffe, 0x1fee, 0x1fee, 0x1fee, 0x200c, 0x1fee, 0x1fee, + 0x1fee, 0x201a, 0x1fee, 0x1fee, 0x1fee, 0x2028, 0x1fee, 0x1fee, + 0x1fee, 0x2036, 0x1fee, 0x1fee, 0x1fee, 0x2044, 0x080c, 0x0d85, + 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d85, + 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20b0, 0xa18c, 0x2400, + 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420, + 0xa088, 0x9319, 0x0804, 0x20b0, 0xa19c, 0x2400, 0x9122, 0xa1a0, + 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa094, 0x9420, 0xa098, 0x9319, + 0x0804, 0x20b0, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, + 0x0a0c, 0x0d85, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x20b0, + 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0d85, + 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20b0, 0xa1cc, 0x2400, + 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0c4, 0x9420, + 0xa0c8, 0x9319, 0x0804, 0x20b0, 0xa1dc, 0x2400, 0x9122, 0xa1e0, + 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0d4, 0x9420, 0xa0d8, 0x9319, + 0x0804, 0x20b0, 0x9082, 0x001b, 0x0002, 0x2070, 0x206e, 0x206e, + 0x206e, 0x206e, 0x206e, 0x207d, 0x206e, 0x206e, 0x206e, 0x206e, + 0x206e, 0x208a, 0x206e, 0x206e, 0x206e, 0x206e, 0x206e, 0x2097, + 0x206e, 0x206e, 0x206e, 0x206e, 0x206e, 0x20a4, 0x080c, 0x0d85, + 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0d85, + 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, + 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420, 0xa088, + 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, + 0x0a0c, 0x0d85, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, + 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0b4, + 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, + 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0cc, 0x9420, 0xa0d0, 0x9319, + 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, + 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, + 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x00c6, 0x610c, + 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291, 0x0000, 0x2c04, + 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8, 0x9284, 0x000f, + 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003, 0x780f, 0x0000, + 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002, 0x918a, 0x0002, + 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c, 0x0d7e, + 0xd094, 0x0110, 0x080c, 0x1208, 0x0005, 0x0126, 0x2091, 0x2600, + 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, + 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, + 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, + 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, + 0x190c, 0x221d, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, + 0x9084, 0x000e, 0x0002, 0x213b, 0x2133, 0x8210, 0x2133, 0x2135, + 0x2135, 0x2135, 0x2135, 0x81f6, 0x2133, 0x2137, 0x2133, 0x2135, + 0x2133, 0x2135, 0x2133, 0x080c, 0x0d85, 0x0031, 0x0020, 0x080c, + 0x81f6, 0x080c, 0x8210, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, + 0xeefa, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xacfc, 0x2001, + 0x19fb, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004, 0x9005, + 0x090c, 0x0d85, 0x00c6, 0x2001, 0x19fb, 0x2064, 0x080c, 0xad18, + 0x080c, 0xcae9, 0x2009, 0x0040, 0x080c, 0x2220, 0x00ce, 0x0408, + 0x2009, 0x0040, 0x080c, 0x2220, 0x080c, 0xad18, 0x00d0, 0x9184, + 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x779e, + 0x1138, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, 0x76cd, 0x0010, + 0x080c, 0x6058, 0x080c, 0x82ae, 0x0041, 0x0018, 0x9184, 0x9540, + 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046, + 0x0056, 0x2071, 0x1a6e, 0x080c, 0x1b1e, 0x005e, 0x004e, 0x003e, + 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128, + 0x2001, 0x196f, 0x2102, 0x2001, 0x1977, 0x2102, 0x2001, 0x013b, + 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200, + 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320, + 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423, + 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003, + 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011, + 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c, + 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182, + 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182, + 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011, + 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402, + 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0, + 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200, + 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de, + 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8, + 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0d7e, + 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, + 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, + 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a85, 0x080c, 0x299b, + 0x2001, 0x199d, 0x2003, 0x0700, 0x2001, 0x199e, 0x2003, 0x0700, + 0x080c, 0x2af6, 0x9006, 0x080c, 0x29ca, 0x9006, 0x080c, 0x29ad, + 0x20a9, 0x0012, 0x1d04, 0x2252, 0x2091, 0x6000, 0x1f04, 0x2252, + 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, + 0xdfff, 0x6052, 0x6224, 0x080c, 0x2ad3, 0x080c, 0x26c5, 0x2009, + 0x00ef, 0x6132, 0x6136, 0x080c, 0x26d5, 0x60e7, 0x0000, 0x61ea, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1110, 0x2001, + 0x0008, 0x60e2, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, + 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061, 0x0140, 0x608b, + 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097, 0x0198, 0x00ce, + 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000, 0x20a9, 0x0018, + 0x60bf, 0x0000, 0x1f04, 0x2298, 0x60bb, 0x0000, 0x60bf, 0x0108, + 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, + 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, + 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, + 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, + 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, + 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x6028, + 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, + 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, + 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, + 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4, + 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, + 0x001e, 0x0d30, 0x0c58, 0x2306, 0x2303, 0x2303, 0x2303, 0x2305, + 0x2303, 0x2303, 0x2303, 0x080c, 0x0d85, 0x0029, 0x002e, 0x001e, + 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, + 0xd19c, 0x1904, 0x258b, 0xd1f4, 0x190c, 0x0d7e, 0x080c, 0x779e, + 0x0904, 0x2363, 0x080c, 0xd645, 0x1120, 0x7000, 0x9086, 0x0003, + 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x77c1, 0x0118, + 0x080c, 0x77af, 0x1530, 0x2011, 0x0020, 0x080c, 0x2ad3, 0x6043, + 0x0000, 0x080c, 0xd645, 0x0168, 0x080c, 0x77c1, 0x1150, 0x2001, + 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7612, 0x0804, + 0x258e, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6, 0x2069, + 0x0140, 0x080c, 0x77f2, 0x00de, 0x1904, 0x258e, 0x080c, 0x7ac0, + 0x0428, 0x080c, 0x77c1, 0x1590, 0x6024, 0x9084, 0x1800, 0x1108, + 0x0468, 0x080c, 0x7ac0, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, + 0x76cd, 0x0804, 0x258b, 0xd1ac, 0x1508, 0x6024, 0xd0dc, 0x1170, + 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098, 0x9086, + 0x0029, 0x1110, 0x080c, 0x7990, 0x0804, 0x258b, 0x080c, 0x7abb, + 0x0048, 0x2001, 0x197d, 0x2003, 0x0002, 0x0020, 0x080c, 0x78e4, + 0x0804, 0x258b, 0x080c, 0x7a3a, 0x0804, 0x258b, 0x6220, 0xd1bc, + 0x0138, 0xd2bc, 0x1904, 0x25f6, 0xd2b4, 0x1904, 0x2608, 0x0000, + 0xd1ac, 0x0904, 0x2498, 0x0036, 0x6328, 0xc3bc, 0x632a, 0x003e, + 0x080c, 0x779e, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2ad3, 0x0006, + 0x0026, 0x0036, 0x080c, 0x77b8, 0x1158, 0x080c, 0x7ab6, 0x080c, + 0x619d, 0x080c, 0x76cd, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005, + 0x003e, 0x002e, 0x000e, 0x080c, 0x7772, 0x0016, 0x0046, 0x00c6, + 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, + 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, 0xd084, + 0x0190, 0x080c, 0xd645, 0x1118, 0x9186, 0xf800, 0x1160, 0x7048, + 0xd084, 0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, + 0x080c, 0x4ca1, 0x003e, 0x080c, 0xd63e, 0x1904, 0x246d, 0x9196, + 0xff00, 0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, + 0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3482, 0x0128, + 0xc18d, 0x7132, 0x080c, 0x6c09, 0x1510, 0x6240, 0x9294, 0x0010, + 0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, + 0xd08c, 0x0904, 0x246d, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, + 0x200c, 0xd1ac, 0x1904, 0x246d, 0xc1ad, 0x2102, 0x0036, 0x73d8, + 0x2011, 0x8013, 0x080c, 0x4ca1, 0x003e, 0x0804, 0x246d, 0x7038, + 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x246d, + 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4ca1, + 0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, + 0x01f0, 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8c44, + 0x2019, 0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe9f9, 0x00ce, + 0x9484, 0x00ff, 0x9080, 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, + 0x2120, 0x9006, 0x2009, 0x000e, 0x080c, 0xea8d, 0x001e, 0x0016, + 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32da, 0x001e, 0x00a8, + 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x67b4, 0x1140, + 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x61b7, + 0x8108, 0x1f04, 0x245d, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, + 0xacfc, 0x080c, 0xafd2, 0x080c, 0xb09b, 0x080c, 0xad18, 0x60e3, + 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, + 0xd19c, 0x11b0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, + 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, + 0x2001, 0x1826, 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2ad3, + 0xd194, 0x0904, 0x258b, 0x0016, 0x080c, 0xacfc, 0x6220, 0xd2b4, + 0x0904, 0x2526, 0x080c, 0x8a4b, 0x080c, 0xa2a0, 0x2011, 0x0004, + 0x080c, 0x2ad3, 0x00f6, 0x2019, 0x19f4, 0x2304, 0x907d, 0x0904, + 0x24f3, 0x7804, 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, + 0x0096, 0x2069, 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, + 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, + 0x003c, 0x8001, 0x1df0, 0x080c, 0x2aa9, 0x2001, 0x001e, 0x8001, + 0x0240, 0x20a9, 0x0009, 0x080c, 0x2a60, 0x6904, 0xd1dc, 0x1140, + 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, + 0x080c, 0x99ed, 0x080c, 0xad18, 0x7814, 0x2048, 0xa867, 0x0103, + 0x2f60, 0x080c, 0xb16c, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, + 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, + 0x9084, 0x4000, 0x0110, 0x080c, 0x2aa9, 0x00de, 0x00c6, 0x2061, + 0x19e8, 0x6034, 0x080c, 0xd645, 0x0120, 0x909a, 0x0003, 0x1258, + 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, + 0xa278, 0x0804, 0x2588, 0x2061, 0x0100, 0x62c0, 0x080c, 0xac2d, + 0x2019, 0x19f4, 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, + 0x0027, 0x080c, 0xb20a, 0x00ce, 0x0804, 0x2588, 0xd2bc, 0x0904, + 0x256b, 0x080c, 0x8a58, 0x2011, 0x0004, 0x080c, 0x2ad3, 0x00d6, + 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2aa9, + 0x00de, 0x00c6, 0x2061, 0x19e8, 0x6050, 0x080c, 0xd645, 0x0120, + 0x909a, 0x0003, 0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, + 0x6052, 0x604c, 0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, + 0x8a50, 0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, + 0x1984, 0x2011, 0x0012, 0x080c, 0x2ae2, 0x0450, 0x9080, 0x0008, + 0x2004, 0x9086, 0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, + 0x080c, 0x2ae2, 0x00e8, 0x2011, 0x0004, 0x080c, 0x2ad3, 0x00c0, + 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x2019, 0x19fb, + 0x2304, 0x9065, 0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, + 0x1110, 0x2009, 0x004f, 0x6003, 0x0003, 0x080c, 0xb20a, 0x00ce, + 0x080c, 0xad18, 0x001e, 0xd19c, 0x0904, 0x25ef, 0x7038, 0xd0ac, + 0x1558, 0x0016, 0x0156, 0x2011, 0x0008, 0x080c, 0x2ad3, 0x080c, + 0x2af6, 0x080c, 0x2b29, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, + 0x0f04, 0x25ba, 0x1d04, 0x25a2, 0x080c, 0x8a7f, 0x6020, 0xd09c, + 0x1db8, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2a0c, 0x00fe, 0x1d80, + 0x6050, 0xc0e4, 0x6052, 0x2011, 0x0008, 0x080c, 0x2ad3, 0x015e, + 0x001e, 0x04a8, 0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, + 0x080c, 0xacfc, 0x080c, 0xafd2, 0x080c, 0xb09b, 0x080c, 0xad18, + 0x60e3, 0x0000, 0x080c, 0xeed9, 0x080c, 0xeef4, 0x080c, 0x5844, + 0xd0fc, 0x1138, 0x080c, 0xd63e, 0x1120, 0x9085, 0x0001, 0x080c, + 0x77e2, 0x9006, 0x080c, 0x2a99, 0x2009, 0x0002, 0x080c, 0x2a85, + 0x00e6, 0x2071, 0x1800, 0x7003, 0x0004, 0x080c, 0x0ed3, 0x00ee, + 0x2011, 0x0008, 0x080c, 0x2ad3, 0x080c, 0x0bcf, 0x001e, 0x918c, + 0xffd0, 0x2110, 0x080c, 0x2ad3, 0x00ae, 0x0005, 0x0016, 0x2001, + 0x0387, 0x200c, 0xd1a4, 0x001e, 0x0904, 0x2390, 0x0016, 0x2009, + 0x2602, 0x00c0, 0x2001, 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, + 0x0016, 0x2001, 0x0387, 0x200c, 0xd1b4, 0x001e, 0x0904, 0x2390, + 0x0016, 0x2009, 0x2614, 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, + 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, + 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2a7f, + 0x2011, 0x0080, 0x080c, 0x2ad3, 0x6017, 0x0000, 0x6043, 0x0000, + 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, + 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, + 0x2684, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2a85, 0x2011, + 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, + 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x4ca1, 0x0468, 0x2001, + 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, + 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, + 0x4ca1, 0x080c, 0x0ed3, 0x080c, 0x5844, 0xd0fc, 0x11a8, 0x080c, + 0xd63e, 0x1190, 0x00c6, 0x080c, 0x2720, 0x080c, 0xacfc, 0x080c, + 0xa4f1, 0x080c, 0xad18, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, + 0x0002, 0x080c, 0x32da, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, + 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, + 0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, + 0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, + 0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, + 0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, + 0x1120, 0x2500, 0x080c, 0x8521, 0x0048, 0x9584, 0x00ff, 0x9080, + 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, + 0x348e, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, + 0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, + 0x6856, 0x1f04, 0x26d0, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, + 0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, + 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, + 0x9184, 0x000f, 0x9080, 0xef08, 0x2005, 0x6856, 0x8211, 0x1f04, + 0x26e5, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, + 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, + 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, + 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, + 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2715, + 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, + 0x080c, 0x5840, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, + 0x2020, 0x2009, 0x002e, 0x080c, 0xea8d, 0x004e, 0x0005, 0x00f6, + 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x278c, + 0x080c, 0x29fc, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, + 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, + 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, + 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, + 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, + 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, + 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, + 0x9080, 0x0020, 0x2018, 0x080c, 0x955b, 0x928c, 0xff00, 0x0110, + 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, + 0x0138, 0x220a, 0x080c, 0x779e, 0x1118, 0x2009, 0x196d, 0x220a, + 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, + 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, + 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e, 0x002e, + 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x180d, 0x2004, 0xd08c, + 0x0118, 0x2009, 0x0002, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, + 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, + 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, + 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, + 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, + 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, + 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x1990, 0x2004, + 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0033, 0x00ee, 0x002e, 0x001e, + 0x000e, 0x015e, 0x0005, 0x27f2, 0x2810, 0x2834, 0x2836, 0x285f, + 0x2861, 0x2863, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, 0x2a4a, + 0x2001, 0x1992, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, + 0x9006, 0x20a9, 0x0009, 0x080c, 0x2a18, 0x2001, 0x1990, 0x2003, + 0x0006, 0x2009, 0x001e, 0x2011, 0x2864, 0x080c, 0x8a5d, 0x0005, + 0x2009, 0x1995, 0x200b, 0x0000, 0x2001, 0x199a, 0x2003, 0x0036, + 0x2001, 0x1999, 0x2003, 0x002a, 0x2001, 0x1992, 0x2003, 0x0001, + 0x9006, 0x080c, 0x29ad, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, + 0x2a18, 0x2001, 0x1990, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, + 0x2864, 0x080c, 0x8a5d, 0x0005, 0x080c, 0x0d85, 0x2001, 0x199a, + 0x2003, 0x0036, 0x2001, 0x1992, 0x2003, 0x0003, 0x7a38, 0x9294, + 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, + 0x080c, 0x29ad, 0x2001, 0x1996, 0x2003, 0x0000, 0x2001, 0xffff, + 0x20a9, 0x0009, 0x080c, 0x2a18, 0x2001, 0x1990, 0x2003, 0x0006, + 0x2009, 0x001e, 0x2011, 0x2864, 0x080c, 0x8a5d, 0x0005, 0x080c, + 0x0d85, 0x080c, 0x0d85, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, + 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, + 0x1992, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0043, 0x012e, + 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2886, + 0x28a2, 0x28de, 0x290a, 0x292a, 0x2936, 0x2938, 0x080c, 0x2a0c, + 0x1190, 0x2009, 0x1998, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, + 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1990, + 0x2003, 0x0001, 0x0030, 0x080c, 0x295c, 0x2001, 0xffff, 0x080c, + 0x2801, 0x0005, 0x080c, 0x293a, 0x05c0, 0x2009, 0x1999, 0x2104, + 0x8001, 0x200a, 0x080c, 0x2a0c, 0x1158, 0x7a38, 0x9294, 0x0005, + 0x9296, 0x0005, 0x0518, 0x2009, 0x1998, 0x2104, 0xc085, 0x200a, + 0x2009, 0x1995, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, + 0x080c, 0x2942, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, + 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, + 0x29ca, 0x2001, 0x1992, 0x2003, 0x0002, 0x0028, 0x2001, 0x1990, + 0x2003, 0x0003, 0x0010, 0x080c, 0x2823, 0x0005, 0x080c, 0x293a, + 0x0540, 0x2009, 0x1999, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a0c, + 0x1148, 0x2001, 0x1990, 0x2003, 0x0003, 0x2001, 0x1991, 0x2003, + 0x0000, 0x00b8, 0x2009, 0x1999, 0x2104, 0x9005, 0x1118, 0x080c, + 0x297f, 0x0010, 0x080c, 0x294f, 0x080c, 0x2942, 0x2009, 0x1995, + 0x200b, 0x0000, 0x2001, 0x1992, 0x2003, 0x0001, 0x080c, 0x2823, + 0x0000, 0x0005, 0x0479, 0x01e8, 0x080c, 0x2a0c, 0x1198, 0x2009, + 0x1996, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, + 0x2001, 0x199b, 0x2003, 0x000a, 0x2009, 0x1998, 0x2104, 0xc0fd, + 0x200a, 0x0038, 0x00f9, 0x2001, 0x1992, 0x2003, 0x0004, 0x080c, + 0x284e, 0x0005, 0x0079, 0x0148, 0x080c, 0x2a0c, 0x1118, 0x080c, + 0x283a, 0x0018, 0x0079, 0x080c, 0x284e, 0x0005, 0x080c, 0x0d85, + 0x080c, 0x0d85, 0x2009, 0x199a, 0x2104, 0x8001, 0x200a, 0x090c, + 0x299b, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ca, 0x0005, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x080c, 0x29ad, 0x0005, 0x2009, 0x1995, 0x2104, 0x8000, + 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, + 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, + 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, + 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ca, 0x0005, 0x0086, + 0x2001, 0x1998, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0d85, 0x2009, + 0x1997, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, + 0xd084, 0x1120, 0x080c, 0x0d85, 0x9006, 0x0010, 0x2001, 0x0001, + 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1990, 0x20a9, + 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x29a1, 0x2001, 0x1997, + 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, + 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, + 0x783a, 0x2009, 0x199d, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, + 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, + 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x7850, 0x9084, + 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, + 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009, 0x017f, 0x210c, + 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c, 0x918c, 0x0600, + 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010, 0x9085, 0x0000, + 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, + 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, + 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, + 0x080c, 0x2a7f, 0xd09c, 0x1110, 0x1f04, 0x2a0f, 0x015e, 0x0005, + 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x000e, 0x2008, 0x9186, + 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, + 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, + 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, + 0x1d04, 0x2a38, 0x080c, 0x8a7f, 0x1f04, 0x2a38, 0x080c, 0x2af6, + 0x080c, 0x2b29, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, + 0x012e, 0x0005, 0x080c, 0x2b29, 0x0005, 0x0006, 0x0156, 0x00f6, + 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100, 0x7854, + 0xd08c, 0x1110, 0x1f04, 0x2a57, 0x00fe, 0x015e, 0x000e, 0x0005, + 0x1d04, 0x2a60, 0x080c, 0x8a7f, 0x1f04, 0x2a60, 0x0005, 0x0006, + 0x2001, 0x199c, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x2001, 0x199c, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006, + 0x2001, 0x199c, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001, + 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x19a9, + 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, + 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a, + 0x0005, 0x0016, 0x0026, 0x080c, 0x77b8, 0x0108, 0xc0bc, 0x2009, + 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, + 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, + 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, + 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, + 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, + 0x1128, 0x080c, 0x77b8, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, + 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0101, + 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843, 0x0100, + 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202, 0x7844, + 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205, 0x7a16, + 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016, 0x0026, + 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff, 0x9085, + 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a60, 0x6050, 0x9085, + 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c, 0x2a60, + 0x6054, 0xd0bc, 0x090c, 0x0d85, 0x20a9, 0x0005, 0x080c, 0x2a60, + 0x6054, 0xd0ac, 0x090c, 0x0d85, 0x2009, 0x19b0, 0x9084, 0x7e00, + 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd, 0x6052, + 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x0006, 0x2061, + 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048, 0x0006, 0x60e4, + 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, + 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009, 0x0800, 0x2001, + 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d85, 0x2001, 0x0338, + 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0, 0x0006, 0x6888, + 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c, 0x779e, 0x1110, + 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xa001, 0xa001, + 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000, 0x080c, 0x779e, + 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897, 0x4198, 0x000e, + 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e, 0x60e2, 0x000e, + 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, + 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, 0x000e, + 0x6032, 0x6036, 0x2008, 0x080c, 0x26d5, 0x000e, 0x00de, 0x00ce, + 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085, 0x0040, 0x6052, + 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2a7f, 0x9085, 0x2000, + 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bb3, 0x080c, 0x8a7f, 0x1f04, + 0x2bb3, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x015e, + 0x000e, 0x0005, 0x30be, 0x30be, 0x2cc2, 0x2cc2, 0x2cce, 0x2cce, + 0x2cda, 0x2cda, 0x2ce8, 0x2ce8, 0x2cf4, 0x2cf4, 0x2d02, 0x2d02, + 0x2d10, 0x2d10, 0x2d22, 0x2d22, 0x2d2e, 0x2d2e, 0x2d3c, 0x2d3c, + 0x2d5a, 0x2d5a, 0x2d7a, 0x2d7a, 0x2d4a, 0x2d4a, 0x2d6a, 0x2d6a, + 0x2d88, 0x2d88, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d9a, 0x2d9a, 0x2da6, 0x2da6, 0x2db4, 0x2db4, + 0x2dc2, 0x2dc2, 0x2dd2, 0x2dd2, 0x2de0, 0x2de0, 0x2df0, 0x2df0, + 0x2e00, 0x2e00, 0x2e12, 0x2e12, 0x2e20, 0x2e20, 0x2e30, 0x2e30, + 0x2e52, 0x2e52, 0x2e76, 0x2e76, 0x2e40, 0x2e40, 0x2e64, 0x2e64, + 0x2e86, 0x2e86, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2e9a, 0x2e9a, 0x2ea6, 0x2ea6, 0x2eb4, 0x2eb4, + 0x2ec2, 0x2ec2, 0x2ed2, 0x2ed2, 0x2ee0, 0x2ee0, 0x2ef0, 0x2ef0, + 0x2f00, 0x2f00, 0x2f12, 0x2f12, 0x2f20, 0x2f20, 0x2f30, 0x2f30, + 0x2f40, 0x2f40, 0x2f52, 0x2f52, 0x2f62, 0x2f62, 0x2f74, 0x2f74, + 0x2f86, 0x2f86, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2f9a, 0x2f9a, 0x2fa8, 0x2fa8, 0x2fb8, 0x2fb8, + 0x2fc8, 0x2fc8, 0x2fda, 0x2fda, 0x2fea, 0x2fea, 0x2ffc, 0x2ffc, + 0x300e, 0x300e, 0x3022, 0x3022, 0x3032, 0x3032, 0x3044, 0x3044, + 0x3056, 0x3056, 0x306a, 0x306a, 0x307b, 0x307b, 0x308e, 0x308e, + 0x30a1, 0x30a1, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, 0x2d20, + 0x2d20, 0x2d20, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22c8, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, + 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22c8, + 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x13d4, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0x22c8, + 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, + 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x20ea, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0xad62, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xad62, + 0x080c, 0x22c8, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, + 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, 0x080c, 0xad62, + 0x080c, 0x13d4, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20ea, + 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x0804, 0x30b6, + 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, + 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, + 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, + 0x080c, 0xad62, 0x080c, 0x2114, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x2114, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x13d4, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x22c8, + 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, + 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, + 0x080c, 0xad62, 0x080c, 0x13d4, 0x0804, 0x30b6, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, 0x22c8, 0x080c, 0x13d4, + 0x0804, 0x30b6, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, + 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, 0x13d4, + 0x080c, 0x2114, 0x04d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, + 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, 0x080c, 0xad62, 0x080c, + 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0440, 0x0106, 0x0006, + 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x278f, + 0x080c, 0x20ea, 0x080c, 0x13d4, 0x080c, 0xad62, 0x080c, 0x2114, + 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, + 0x0156, 0x080c, 0x278f, 0x080c, 0x20ea, 0x080c, 0xad62, 0x080c, + 0x22c8, 0x080c, 0x13d4, 0x080c, 0x2114, 0x0000, 0x015e, 0x014e, + 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, + 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6bcf, 0x1904, 0x31f6, + 0x72dc, 0x2001, 0x197c, 0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, + 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31f6, 0x080c, 0x31fb, 0x0804, + 0x31f6, 0xd2cc, 0x1904, 0x31f6, 0x080c, 0x779e, 0x1120, 0x70af, + 0xffff, 0x0804, 0x31f6, 0xd294, 0x0120, 0x70af, 0xffff, 0x0804, + 0x31f6, 0x080c, 0x347d, 0x0160, 0x080c, 0xd645, 0x0128, 0x2001, + 0x1818, 0x203c, 0x0804, 0x316f, 0x70af, 0xffff, 0x0804, 0x31f6, + 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904, 0x316f, 0xd28c, + 0x1904, 0x316f, 0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, 0x2019, + 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c, 0x0001, 0x0120, + 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, 0x0904, + 0x3165, 0x908e, 0x0000, 0x0904, 0x3165, 0x908e, 0x00ff, 0x1160, + 0x7230, 0xd284, 0x1904, 0x316a, 0x7294, 0xc28d, 0x7296, 0x70af, + 0xffff, 0x003e, 0x0804, 0x316f, 0x2009, 0x180d, 0x210c, 0xd18c, + 0x0150, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0118, + 0x70af, 0xffff, 0x0488, 0x900e, 0x080c, 0x268c, 0x080c, 0x6749, + 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, + 0x2060, 0x080c, 0x8eee, 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, + 0x080c, 0x6c11, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, + 0x0138, 0x080c, 0x6aae, 0x0120, 0x080c, 0x3214, 0x0148, 0x0028, + 0x080c, 0x3360, 0x080c, 0x3240, 0x0118, 0x8318, 0x0804, 0x3109, + 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x31f6, 0x9780, + 0x348e, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, + 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, + 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31f6, + 0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x31eb, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x0158, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, + 0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x31f3, 0xc484, 0x080c, + 0x67b4, 0x0168, 0x080c, 0xd645, 0x1904, 0x31eb, 0x080c, 0x347d, + 0x1904, 0x31eb, 0x080c, 0x6749, 0x1904, 0x31f3, 0x0008, 0xc485, + 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, + 0x8eee, 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, 0x080c, 0x6c11, + 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, + 0xd28c, 0x0180, 0x080c, 0x6c11, 0x9082, 0x0006, 0x02e0, 0xd484, + 0x1118, 0x080c, 0x676e, 0x0028, 0x080c, 0x33f3, 0x01a0, 0x080c, + 0x341e, 0x0088, 0x080c, 0x3360, 0x080c, 0xd645, 0x1160, 0x080c, + 0x3240, 0x0188, 0x0040, 0x080c, 0xd645, 0x1118, 0x080c, 0x33f3, + 0x0110, 0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x3188, + 0x70af, 0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, + 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, + 0x007e, 0x080c, 0x6749, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, + 0x080c, 0x3360, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, + 0xd389, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, + 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb1dd, + 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x9006, + 0x080c, 0x66e6, 0x2001, 0x0000, 0x080c, 0x66fa, 0x0126, 0x2091, + 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, + 0xb20a, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, + 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, + 0x00ff, 0xb842, 0x080c, 0xb1dd, 0x0548, 0x2b00, 0x6012, 0xb800, + 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c, 0x3315, 0x080c, 0xd3b6, + 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0002, 0x080c, + 0x66fa, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, + 0x2009, 0x0002, 0x080c, 0xb20a, 0x9085, 0x0001, 0x00ce, 0x00de, + 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, + 0x080c, 0x6749, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, + 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, + 0x0076, 0x00d6, 0x00c6, 0x080c, 0xb116, 0x01d0, 0x2b00, 0x6012, + 0x080c, 0xd3b6, 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0x2001, + 0x0002, 0x080c, 0x66fa, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, + 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, + 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x6749, 0x11b8, 0xb813, + 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004, 0x080c, 0xb116, 0x0170, + 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd3b6, + 0x2009, 0x0022, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, 0x00de, + 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, + 0x21f0, 0x080c, 0xacfc, 0x0106, 0x080c, 0x97bb, 0x080c, 0x9727, + 0x080c, 0xac4d, 0x080c, 0xc179, 0x010e, 0x090c, 0xad18, 0x3e08, + 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, + 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1140, 0x9686, 0x0002, + 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x61b7, 0x001e, 0x8108, + 0x1f04, 0x32fa, 0x9686, 0x0001, 0x190c, 0x3451, 0x00be, 0x002e, + 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, + 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c, 0xacfc, 0x0106, 0x6210, + 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, + 0x2039, 0x0000, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, + 0x001e, 0x010e, 0x090c, 0xad18, 0xba10, 0xbb14, 0xbc84, 0x080c, + 0x61b7, 0xba12, 0xbb16, 0xbc86, 0x00be, 0x001e, 0x002e, 0x003e, + 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010, + 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800, + 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005, + 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8, + 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6, + 0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x080c, 0xacfc, + 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x5840, + 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d, + 0x080c, 0xea8d, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e, + 0x0904, 0x33cf, 0x928e, 0x007f, 0x0904, 0x33cf, 0x928e, 0x0080, + 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c8, 0x8fff, 0x1150, + 0x2001, 0x198e, 0x0006, 0x2003, 0x0001, 0x080c, 0x33e0, 0x000e, + 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, + 0x6bdb, 0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, + 0x2039, 0x0000, 0x080c, 0x966d, 0x00b6, 0x00c6, 0x0026, 0x2158, + 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, + 0x0028, 0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, + 0x00be, 0x0016, 0x2c08, 0x080c, 0xe75d, 0x001e, 0x007e, 0x002e, + 0x8210, 0x1f04, 0x3385, 0x010e, 0x090c, 0xad18, 0x015e, 0x001e, + 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005, + 0x0046, 0x0026, 0x0016, 0x080c, 0x5840, 0xd0c4, 0x0140, 0xd0a4, + 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xea8d, 0x001e, + 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7294, + 0x82ff, 0x01e8, 0x080c, 0x6c09, 0x11d0, 0x2100, 0x080c, 0x26bf, + 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, + 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff, + 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085, + 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, 0x0106, 0x0036, 0x2019, + 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c, 0xad18, 0x9180, 0x1000, + 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061, 0x1b39, 0x001e, + 0x6112, 0x080c, 0x3315, 0x001e, 0x080c, 0x676e, 0x012e, 0x00ce, + 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c, 0xa7e2, 0x080c, + 0xedee, 0x002e, 0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, + 0x0005, 0x00c6, 0x00b6, 0x080c, 0x779e, 0x1118, 0x20a9, 0x0800, + 0x0010, 0x20a9, 0x0782, 0x080c, 0x779e, 0x1110, 0x900e, 0x0010, + 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, + 0x0110, 0xb800, 0xd0bc, 0x090c, 0x676e, 0x8108, 0x1f04, 0x3462, + 0x2061, 0x1800, 0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, + 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, + 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, + 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, + 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, + 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, + 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, + 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, + 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, + 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, + 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, + 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, + 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, + 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, + 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, + 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, + 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, + 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, + 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, + 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, + 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, + 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, + 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, + 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, + 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, + 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, + 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, + 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, + 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, + 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, + 0x7003, 0x0002, 0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, + 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, + 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x706a, 0xa867, 0x0002, + 0xa8ab, 0xdcb0, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x706e, + 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, + 0x0002, 0x35bd, 0x35be, 0x35d1, 0x35e5, 0x0005, 0x1004, 0x35ce, + 0x0e04, 0x35ce, 0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, + 0x9005, 0x1128, 0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, + 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, + 0x0100, 0x0128, 0x9086, 0x0200, 0x0904, 0x36b9, 0x0005, 0x7018, + 0x2048, 0x2061, 0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, + 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, + 0x0005, 0x9086, 0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, + 0x1800, 0x701c, 0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, + 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x36b6, + 0x61d0, 0x0804, 0x364b, 0x368d, 0x36c5, 0x36b6, 0x36d1, 0x36db, + 0x36e1, 0x36e5, 0x36f5, 0x36f9, 0x370f, 0x3715, 0x371b, 0x3726, + 0x3731, 0x3740, 0x374f, 0x375d, 0x3774, 0x378f, 0x36b6, 0x383a, + 0x3878, 0x391d, 0x392e, 0x3951, 0x36b6, 0x36b6, 0x36b6, 0x3989, + 0x39a9, 0x39b2, 0x39de, 0x39e4, 0x36b6, 0x3a2a, 0x36b6, 0x36b6, + 0x36b6, 0x36b6, 0x36b6, 0x3a35, 0x3a3e, 0x3a46, 0x3a48, 0x36b6, + 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x3a78, 0x36b6, 0x36b6, + 0x36b6, 0x36b6, 0x36b6, 0x3a95, 0x3b19, 0x36b6, 0x36b6, 0x36b6, + 0x36b6, 0x36b6, 0x36b6, 0x0002, 0x3b43, 0x3b46, 0x3ba5, 0x3bbe, + 0x3bee, 0x3e94, 0x36b6, 0x53f5, 0x36b6, 0x36b6, 0x36b6, 0x36b6, + 0x36b6, 0x36b6, 0x36b6, 0x36b6, 0x370f, 0x3715, 0x4397, 0x5864, + 0x43b5, 0x5484, 0x54d6, 0x55e1, 0x36b6, 0x5643, 0x567f, 0x56b0, + 0x57c0, 0x56dd, 0x5740, 0x36b6, 0x43b9, 0x457f, 0x4595, 0x45ba, + 0x461f, 0x4693, 0x46b3, 0x472a, 0x4786, 0x47e2, 0x47e5, 0x480a, + 0x487c, 0x48e6, 0x48ee, 0x4a23, 0x4bcb, 0x4bff, 0x4e63, 0x36b6, + 0x4e81, 0x4f48, 0x5031, 0x508b, 0x36b6, 0x511e, 0x36b6, 0x5134, + 0x514f, 0x48ee, 0x5395, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, + 0x4c7d, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3697, 0x0010, 0x012e, + 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, + 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x7007, 0x0001, + 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, + 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, + 0x4005, 0x0868, 0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, + 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x81ff, 0x0d98, 0x0804, + 0x4c8a, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, + 0x7990, 0x0804, 0x4c8d, 0x7984, 0x7888, 0x2114, 0x200a, 0x0804, + 0x368d, 0x7984, 0x2114, 0x0804, 0x368d, 0x20e1, 0x0000, 0x2099, + 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f, 0x4003, + 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x368d, 0x7884, 0x2060, 0x0804, + 0x3742, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0014, 0x789b, + 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005, 0x0118, + 0x7896, 0x0804, 0x368d, 0x7897, 0x0001, 0x0804, 0x368d, 0x2039, + 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36c9, 0x2039, 0x0001, 0x7d98, + 0x7c9c, 0x0804, 0x36d5, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, + 0x36c2, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x36c9, 0x79a0, 0x9182, + 0x0040, 0x0210, 0x0804, 0x36c2, 0x2138, 0x7d98, 0x7c9c, 0x0804, + 0x36d5, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36c2, 0x21e8, + 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804, 0x368d, + 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60, 0x8109, + 0x1dd8, 0x2010, 0x9005, 0x0904, 0x368d, 0x0804, 0x36bc, 0x79a0, + 0x9182, 0x0040, 0x0210, 0x0804, 0x36c2, 0x21e0, 0x20a9, 0x0001, + 0x7984, 0x2198, 0x4012, 0x0804, 0x368d, 0x2069, 0x1847, 0x7884, + 0x7990, 0x911a, 0x1a04, 0x36c2, 0x8019, 0x0904, 0x36c2, 0x684a, + 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a, 0x685e, + 0x080c, 0x7ae7, 0x0804, 0x368d, 0x2069, 0x1847, 0x7884, 0x7994, + 0x911a, 0x1a04, 0x36c2, 0x8019, 0x0904, 0x36c2, 0x684e, 0x6946, + 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e, 0x0126, + 0x2091, 0x8000, 0x080c, 0x6d66, 0x012e, 0x0804, 0x368d, 0x902e, + 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x7984, + 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1, 0x18a6, + 0x4101, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, + 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c8a, + 0x701f, 0x37b3, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff, 0x9096, + 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015, 0x0138, + 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x36bf, 0x810f, + 0x918c, 0x00ff, 0x0904, 0x36bf, 0x7112, 0x7010, 0x8001, 0x0560, + 0x7012, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, + 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, 0xa598, + 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000, + 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c8a, 0x701f, 0x37f1, + 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120, 0x9096, + 0x000a, 0x1904, 0x36bf, 0x0888, 0x0126, 0x2091, 0x8000, 0x7014, + 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, + 0x0029, 0x1148, 0xc2fd, 0xaa7a, 0x080c, 0x630a, 0x0138, 0xa87a, + 0xa982, 0x012e, 0x0060, 0x080c, 0x663a, 0x1130, 0x7007, 0x0003, + 0x701f, 0x381f, 0x012e, 0x0005, 0x080c, 0x725e, 0x012e, 0x0126, + 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a6, + 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, + 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, + 0x0804, 0x4c8d, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, + 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, + 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, + 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, + 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a25, 0x2004, 0x9005, + 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, + 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, + 0x81ff, 0x1904, 0x36bf, 0x7984, 0x080c, 0x67b4, 0x1904, 0x36c2, + 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x36c2, 0x7c88, + 0x7d8c, 0x080c, 0x69f1, 0x080c, 0x697e, 0x1518, 0x2061, 0x1ddc, + 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, + 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, + 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, + 0x36bf, 0x0c30, 0x080c, 0xcae9, 0x012e, 0x0904, 0x36bf, 0x0804, + 0x368d, 0x900e, 0x2001, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, + 0x8000, 0x080c, 0xd226, 0x080c, 0x7012, 0x012e, 0x0804, 0x368d, + 0x00a6, 0x2950, 0xb198, 0x080c, 0x67b4, 0x1904, 0x390a, 0xb6a4, + 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, + 0x69f1, 0x080c, 0x697e, 0x1520, 0x2061, 0x1ddc, 0x0126, 0x2091, + 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, + 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, + 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, + 0x0c28, 0x080c, 0xcae9, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, + 0x900e, 0x2001, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, 0x8000, + 0x080c, 0xd226, 0x080c, 0x7006, 0x012e, 0x0070, 0xb097, 0x4005, + 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, + 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, 0x36bf, + 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, + 0x080c, 0x69f7, 0x0904, 0x36bf, 0x0804, 0x46aa, 0x81ff, 0x1904, + 0x36bf, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, 0x6a85, 0x0904, + 0x36bf, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6a12, 0x0904, 0x36bf, + 0x7888, 0x908a, 0x1000, 0x1a04, 0x36c2, 0x8003, 0x800b, 0x810b, + 0x9108, 0x080c, 0x89a1, 0x79a8, 0xd184, 0x1904, 0x368d, 0x0804, + 0x46aa, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, + 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, + 0x080c, 0x67b4, 0x11d8, 0x080c, 0x6a85, 0x1128, 0x2009, 0x0002, + 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, 0x6a12, + 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, + 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x89a1, 0x8529, 0x1ae0, + 0x012e, 0x0804, 0x368d, 0x012e, 0x0804, 0x36bf, 0x012e, 0x0804, + 0x36c2, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x687b, 0x0904, + 0x36bf, 0x080c, 0xacfc, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, + 0x080c, 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, + 0xe75d, 0x007e, 0x00ce, 0x080c, 0xad18, 0x080c, 0x69f1, 0x0804, + 0x368d, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, 0x69f1, 0x2208, + 0x0804, 0x368d, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069, 0x1910, + 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, + 0x2071, 0x19e8, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c, 0x0cd8, + 0x2300, 0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804, 0x368d, + 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, + 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, + 0x6910, 0x62bc, 0x0804, 0x368d, 0x81ff, 0x0120, 0x2009, 0x0001, + 0x0804, 0x36bf, 0x0126, 0x2091, 0x8000, 0x080c, 0x5854, 0x0128, + 0x2009, 0x0007, 0x012e, 0x0804, 0x36bf, 0x012e, 0x615c, 0x9190, + 0x348e, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, 0x6280, + 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, + 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, + 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, + 0x0068, 0x080c, 0x779e, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, + 0x0120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x9036, 0x7e9a, 0x7f9e, + 0x0804, 0x368d, 0x614c, 0x6250, 0x2019, 0x1986, 0x231c, 0x2001, + 0x1987, 0x2004, 0x789a, 0x0804, 0x368d, 0x0126, 0x2091, 0x8000, + 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x368d, 0x080c, 0x4c74, + 0x0904, 0x36c2, 0xba44, 0xbb38, 0x0804, 0x368d, 0x080c, 0x0d85, + 0x080c, 0x4c74, 0x2110, 0x0904, 0x36c2, 0xb804, 0x908c, 0x00ff, + 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, + 0x0009, 0x1904, 0x36bf, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, + 0x00c6, 0x9066, 0x080c, 0xacfc, 0x080c, 0xa7e2, 0x080c, 0x97b0, + 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, 0xe75d, 0x007e, + 0x00ce, 0x080c, 0xad18, 0xb807, 0x0407, 0x012e, 0x0804, 0x368d, + 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, + 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1986, 0x2d1c, 0x206a, + 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1987, + 0x2d04, 0x266a, 0x789a, 0x0804, 0x368d, 0x0126, 0x2091, 0x8000, + 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0eeb, 0xd0c4, + 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199d, 0x200a, 0x78ac, 0x2011, + 0x199e, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, + 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7888, 0xd0ec, + 0x0178, 0x6034, 0xc08d, 0x6036, 0x2001, 0x0050, 0x6076, 0x607a, + 0x6056, 0x606b, 0x269c, 0x00c6, 0x2061, 0x1b73, 0x2062, 0x00ce, + 0x2011, 0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, + 0x0010, 0x918c, 0xff7f, 0x2112, 0x6134, 0xd18c, 0x2001, 0x0000, + 0x0108, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, 0x6042, + 0x6234, 0xd28c, 0x0120, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, + 0xd1e4, 0x190c, 0x0f06, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, + 0x9084, 0x0001, 0x090c, 0x4397, 0x6040, 0xd0cc, 0x0120, 0x78b0, + 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x368d, 0x00f6, 0x2079, + 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, + 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, + 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, + 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x36c2, + 0x788c, 0x902d, 0x0904, 0x36c2, 0x900e, 0x080c, 0x67b4, 0x1120, + 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, + 0x0ca0, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x7888, 0x900d, 0x0904, + 0x36c2, 0x788c, 0x9005, 0x0904, 0x36c2, 0xba44, 0xb946, 0xbb38, + 0xb83a, 0x0804, 0x368d, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, + 0x080c, 0x5854, 0x1904, 0x36bf, 0x00c6, 0x2061, 0x0100, 0x7984, + 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, + 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x348e, 0x210d, 0x918c, + 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, + 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb116, + 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x674f, + 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4c41, + 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, + 0xa86a, 0x701f, 0x3b9e, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, + 0xb20a, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x36bf, + 0x00ce, 0x0804, 0x36c2, 0x080c, 0xb16c, 0x0cb0, 0xa830, 0x9086, + 0x0100, 0x0904, 0x36bf, 0x0804, 0x368d, 0x2061, 0x1a73, 0x0126, + 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, + 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, + 0x012e, 0x0804, 0x368d, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, + 0x36bf, 0x080c, 0x779e, 0x0904, 0x36bf, 0x0126, 0x2091, 0x8000, + 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x26f5, + 0x080c, 0x5a7c, 0x012e, 0x0804, 0x368d, 0x012e, 0x0804, 0x36c2, + 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, + 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x955b, + 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x368f, + 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, + 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x36c2, 0x2001, 0x002a, + 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, + 0x012e, 0x0804, 0x36c2, 0x012e, 0x0804, 0x36bf, 0x080c, 0xb094, + 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3c6d, 0x00c6, 0x080c, 0x4c41, + 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, + 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, + 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, + 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, + 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, + 0x00fc, 0x8004, 0xa816, 0x080c, 0x3df7, 0x0928, 0x7014, 0x2048, + 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, + 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c8a, 0x701f, + 0x3d34, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xacfc, 0x0046, + 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x080c, 0x3bd8, 0x2001, 0x19a0, 0x2003, 0x0000, 0x2021, 0x000a, + 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, + 0x60bf, 0x0012, 0x080c, 0x3e66, 0x080c, 0x3e25, 0x00f6, 0x00e6, + 0x0086, 0x2940, 0x2071, 0x19e8, 0x2079, 0x0090, 0x00d6, 0x2069, + 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004, 0x780e, + 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, + 0x41db, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40fd, 0x080c, 0x402a, + 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, + 0x424f, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, + 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084, 0xff00, + 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084, 0xff00, + 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037, 0x0000, + 0x715c, 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106, 0x1168, + 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, + 0x080c, 0x4034, 0x080c, 0x3e20, 0x0058, 0x080c, 0x3e20, 0x080c, + 0x4173, 0x080c, 0x40f3, 0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, + 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, + 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, + 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c, 0x918c, + 0xfffd, 0x2102, 0x080c, 0x1352, 0x2009, 0x0028, 0x080c, 0x2220, + 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xad18, 0x00fe, 0x00ee, + 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e, 0x2001, + 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x368d, 0x012e, + 0x2021, 0x400c, 0x0804, 0x368f, 0x0016, 0x0026, 0x0036, 0x0046, + 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014, 0x2048, + 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904, 0x3d90, + 0x2048, 0x1f04, 0x3d44, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494, + 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, + 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086, 0x0103, + 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, + 0x9080, 0x001b, 0x080c, 0x4c8a, 0x701f, 0x3d34, 0x00b0, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, + 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fd6, + 0x000e, 0x080c, 0x4c8d, 0x701f, 0x3d34, 0x015e, 0x00de, 0x009e, + 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, + 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f, 0x3df5, + 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009, 0x007f, + 0x080c, 0x6749, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff, 0xb817, + 0xfffd, 0x080c, 0xd409, 0x015e, 0x00de, 0x009e, 0x008e, 0x007e, + 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x36bf, 0x0016, + 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, + 0x0156, 0x701f, 0x3dc7, 0x7007, 0x0003, 0x0804, 0x3d85, 0xa830, + 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x368f, 0x0076, 0xad10, + 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, + 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, + 0x20a0, 0x0006, 0x080c, 0x0fd6, 0x000e, 0x080c, 0x4c8d, 0x007e, + 0x701f, 0x3d34, 0x7023, 0x0001, 0x0005, 0x0804, 0x368d, 0x0156, + 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e, 0x0010, + 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4c41, 0x001e, + 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58, 0x9006, + 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006, 0x00f6, + 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e, 0x0005, + 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, + 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, + 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x080c, + 0x4c41, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, + 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2061, + 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, + 0x0040, 0x080c, 0x2220, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca, 0x9006, + 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x080c, + 0x4c41, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, + 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004, 0xa86a, + 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873, 0x0000, + 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003, 0x0000, + 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d, + 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, + 0x0148, 0x080c, 0x2a77, 0x1130, 0x9006, 0x080c, 0x29ca, 0x9006, + 0x080c, 0x29ad, 0x2001, 0x199f, 0x2003, 0x0000, 0x7884, 0x9084, + 0x0007, 0x0002, 0x3eb5, 0x3eb6, 0x3eb7, 0x3eb2, 0x3eb2, 0x3eb2, + 0x3eb2, 0x3eb2, 0x012e, 0x0804, 0x36c2, 0x0ce0, 0x0cd8, 0x080c, + 0x779e, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x36bf, 0x81ff, + 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x368f, 0x2001, 0x0141, + 0x2004, 0xd0dc, 0x0db0, 0x080c, 0xacfc, 0x0086, 0x0096, 0x00a6, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3bd8, 0x2009, + 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060, + 0x2058, 0x080c, 0x432a, 0x080c, 0x427a, 0x903e, 0x2720, 0x00f6, + 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e8, 0x2079, 0x0090, 0x00d6, + 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0, + 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x41db, 0x080c, 0x2a7f, + 0x080c, 0x2a7f, 0x080c, 0x2a7f, 0x080c, 0x2a7f, 0x080c, 0x41db, + 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40fd, 0x2009, 0x9c40, 0x8109, + 0x11b0, 0x080c, 0x4034, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, + 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, + 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x36bf, 0x0cf8, 0x2001, + 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000, + 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff, + 0x0150, 0x080c, 0x40db, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c, + 0x4034, 0x0804, 0x3fdd, 0x080c, 0x424f, 0x080c, 0x4173, 0x080c, + 0x40be, 0x080c, 0x40f3, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac, + 0x0130, 0x8b58, 0x080c, 0x4034, 0x00fe, 0x0804, 0x3fdd, 0x00fe, + 0x080c, 0x402a, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001, + 0x0033, 0x2502, 0x080c, 0x4034, 0x0080, 0x87ff, 0x0138, 0x2001, + 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a6e, + 0x2004, 0x9086, 0x0000, 0x1904, 0x3f2d, 0x2001, 0x032f, 0x2003, + 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3fdd, + 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3fdd, + 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, + 0x1148, 0x2001, 0x1a6e, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, + 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016, + 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2220, 0x2900, 0xa85a, + 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6, + 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203, + 0x2004, 0x1f04, 0x3fb4, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0, + 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, + 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, + 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, + 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3ee7, 0x001e, 0x00c6, 0x2001, + 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106, + 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c, + 0xfffd, 0x2102, 0x080c, 0x1352, 0x7884, 0x9084, 0x0003, 0x9086, + 0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x2220, 0x2001, 0x0227, + 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b29, 0x6052, + 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, + 0x080c, 0xad18, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, + 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, + 0x008e, 0x1118, 0x012e, 0x0804, 0x368d, 0x012e, 0x2021, 0x400c, + 0x0804, 0x368f, 0x9085, 0x0001, 0x1d04, 0x4033, 0x2091, 0x6000, + 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, + 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6e, 0x2003, 0x0000, + 0x0071, 0x2009, 0x0048, 0x080c, 0x2220, 0x2001, 0x0227, 0x2024, + 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, + 0x00e6, 0x2071, 0x19e8, 0x7054, 0x9086, 0x0000, 0x0520, 0x2079, + 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, + 0x1120, 0x2009, 0x0040, 0x080c, 0x2220, 0x782c, 0xd0fc, 0x0d88, + 0x080c, 0x424f, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, + 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2220, 0x782b, + 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, + 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x26d5, + 0x080c, 0x2af6, 0x080c, 0x2b29, 0x784b, 0xf7f7, 0x7843, 0x0090, + 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8, 0x7820, + 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852, 0x2011, + 0x0048, 0x080c, 0x2ad3, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001, + 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2a99, 0x2011, + 0x0020, 0x080c, 0x2ad3, 0x7843, 0x0000, 0x9006, 0x080c, 0x2a99, + 0x2011, 0x0048, 0x080c, 0x2ad3, 0x00fe, 0x0005, 0x7884, 0xd0ac, + 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6e, 0x2079, 0x0320, 0x2001, + 0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140, + 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019, + 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, + 0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033, + 0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, + 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, + 0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, + 0x2001, 0x19ab, 0x2004, 0x70e2, 0x080c, 0x3e16, 0x1188, 0x2001, + 0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e, + 0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080, + 0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e, + 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, + 0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000, + 0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, + 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, + 0x0092, 0x7016, 0x080c, 0x424f, 0x00f6, 0x2071, 0x1a6e, 0x2079, + 0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, + 0x780e, 0x6898, 0x780a, 0x00de, 0x080c, 0x3e16, 0x0140, 0x2001, + 0x199f, 0x200c, 0x2003, 0x0001, 0x918e, 0x0001, 0x0120, 0x2009, + 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, + 0x2011, 0x0011, 0x080c, 0x41db, 0x2011, 0x0001, 0x080c, 0x41db, + 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6e, 0x2079, + 0x0320, 0x792c, 0xd1fc, 0x0904, 0x41d8, 0x782b, 0x0002, 0x9026, + 0xd19c, 0x1904, 0x41d4, 0x7000, 0x0002, 0x41d8, 0x4189, 0x41b9, + 0x41d4, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, + 0x0001, 0x080c, 0x41db, 0x0904, 0x41d8, 0x080c, 0x41db, 0x0804, + 0x41d8, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, + 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, + 0x81ff, 0x0de8, 0x080c, 0x40db, 0x2009, 0x0001, 0x00f6, 0x2079, + 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, + 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, + 0x1904, 0x417d, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, + 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, + 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, + 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, + 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, + 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0d85, 0x9398, 0x4209, + 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, + 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, + 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, + 0x0005, 0x4246, 0x423d, 0x4234, 0x422b, 0x4222, 0x4219, 0x4210, + 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, + 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, + 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, + 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, + 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, + 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, + 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, + 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, + 0x00e6, 0x0086, 0x2071, 0x19e8, 0x2079, 0x0090, 0x792c, 0xd1fc, + 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7054, 0x0002, 0x4276, + 0x4262, 0x426d, 0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, + 0x080c, 0x41db, 0x190c, 0x41db, 0x0048, 0x8001, 0x7056, 0x782c, + 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x41db, 0x008e, 0x00ee, + 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, + 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, + 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, + 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, + 0x201c, 0x080c, 0x4c41, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, + 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, + 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, + 0x080c, 0x42f2, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4c41, + 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, + 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, + 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, + 0x2009, 0x0040, 0x080c, 0x2220, 0x2001, 0x002a, 0x2004, 0x9084, + 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, + 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, + 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, + 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, + 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, + 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, + 0x2940, 0x0086, 0x080c, 0x4c41, 0x008e, 0xa058, 0x00a6, 0x2050, + 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, + 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, + 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, + 0x4c41, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, + 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, + 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, + 0x42f2, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4c41, 0x2940, + 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, + 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, + 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, + 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, + 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, + 0x1a6e, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, + 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, + 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, + 0x2091, 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, + 0x9006, 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, + 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, + 0x0052, 0x0108, 0x0005, 0x0804, 0x368d, 0x7d98, 0x7c9c, 0x0804, + 0x3791, 0x080c, 0x779e, 0x190c, 0x6162, 0x6040, 0x9084, 0x0020, + 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c8a, 0x701f, 0x43d1, + 0x0005, 0x080c, 0x584f, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, + 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x36c2, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x6804, 0x0118, 0xc0a4, 0xc0ac, + 0x6806, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x36c2, 0xd094, 0x00c6, + 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, + 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, + 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, + 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, + 0x007f, 0x1a04, 0x36c2, 0x9288, 0x348e, 0x210d, 0x918c, 0x00ff, + 0x6166, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x36c2, + 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, + 0x0006, 0x2009, 0x19b2, 0x9080, 0x27d0, 0x2005, 0x200a, 0x2008, + 0x2001, 0x0018, 0x080c, 0xaced, 0x2009, 0x0390, 0x200b, 0x0400, + 0x000e, 0x2009, 0x19b3, 0x9080, 0x27d4, 0x2005, 0x200a, 0x6808, + 0x908a, 0x0100, 0x0a04, 0x36c2, 0x908a, 0x0841, 0x1a04, 0x36c2, + 0x9084, 0x0007, 0x1904, 0x36c2, 0x680c, 0x9005, 0x0904, 0x36c2, + 0x6810, 0x9005, 0x0904, 0x36c2, 0x6848, 0x6940, 0x910a, 0x1a04, + 0x36c2, 0x8001, 0x0904, 0x36c2, 0x684c, 0x6944, 0x910a, 0x1a04, + 0x36c2, 0x8001, 0x0904, 0x36c2, 0x6814, 0x908c, 0x00ff, 0x614e, + 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7ae7, 0x080c, 0x6cfc, + 0x080c, 0x6d66, 0x6808, 0x602a, 0x080c, 0x2192, 0x2009, 0x0170, + 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, + 0x080c, 0x272f, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x456d, + 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, + 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, + 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, + 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, + 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b4, 0x20e9, 0x0001, + 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19ce, 0x20e9, 0x0001, 0x4001, + 0x080c, 0x8b26, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, + 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x80fe, + 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, + 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, + 0x6003, 0x0001, 0x1f04, 0x44c2, 0x00ce, 0x00c6, 0x2061, 0x199c, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x11a8, 0x6a88, 0x9284, 0xc000, + 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001, + 0x080c, 0x29ca, 0x2001, 0x0001, 0x080c, 0x29ad, 0x0088, 0x9286, + 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ca, 0x9006, + 0x080c, 0x29ad, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, + 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed3, 0x00ee, 0x080c, 0x2af6, + 0x080c, 0x2b29, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, + 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, + 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001, 0x197c, + 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e, 0x0010, + 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x27a4, + 0x2001, 0x196d, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, + 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x779e, 0x0128, + 0x080c, 0x5128, 0x0110, 0x080c, 0x26f5, 0x60d4, 0x9005, 0x01c0, + 0x6003, 0x0001, 0x2009, 0x4555, 0x00e0, 0x080c, 0x779e, 0x1168, + 0x2011, 0x7612, 0x080c, 0x8993, 0x2011, 0x7605, 0x080c, 0x8a9f, + 0x080c, 0x7abb, 0x080c, 0x76cd, 0x0040, 0x080c, 0x6058, 0x0028, + 0x6003, 0x0004, 0x2009, 0x456d, 0x0020, 0x080c, 0x6b73, 0x0804, + 0x368d, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, + 0x1118, 0x2091, 0x31bd, 0x0817, 0x2091, 0x313d, 0x0817, 0x6000, + 0x9086, 0x0000, 0x0904, 0x36bf, 0x2069, 0x1847, 0x7890, 0x6842, + 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x2039, 0x0001, 0x0804, 0x4c8d, 0x9006, 0x080c, 0x26f5, + 0x81ff, 0x1904, 0x36bf, 0x080c, 0x779e, 0x11b0, 0x080c, 0x7ab6, + 0x080c, 0x619d, 0x080c, 0x3482, 0x0118, 0x6130, 0xc18d, 0x6132, + 0x080c, 0xd645, 0x0130, 0x080c, 0x77c1, 0x1118, 0x080c, 0x7772, + 0x0038, 0x080c, 0x76cd, 0x0020, 0x080c, 0x6162, 0x080c, 0x6058, + 0x0804, 0x368d, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x779e, 0x1110, + 0x0804, 0x36bf, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, + 0x704f, 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4c8d, 0x701f, 0x368b, + 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, + 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, + 0x655c, 0x9588, 0x348e, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, + 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x67b4, 0x1190, + 0xb814, 0x821c, 0x0238, 0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, + 0x201a, 0x0038, 0x9398, 0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, + 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, + 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, + 0x1d80, 0x2099, 0x1d80, 0x080c, 0x60ed, 0x0804, 0x45ca, 0x080c, + 0x4c74, 0x0904, 0x36c2, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, + 0x0804, 0x36bf, 0x080c, 0x5840, 0xd0b4, 0x0558, 0x7884, 0x908e, + 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508, + 0x080c, 0x347d, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0x080c, 0xd0ec, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, + 0x7007, 0x0003, 0x701f, 0x4655, 0x0005, 0x080c, 0x4c74, 0x0904, + 0x36c2, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, + 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, + 0x2098, 0x080c, 0x0fd6, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, + 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, + 0x080c, 0x0fd6, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, + 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c8d, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x4c58, + 0x0904, 0x36c2, 0x080c, 0x6a00, 0x0904, 0x36bf, 0x0058, 0xa878, + 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa974, 0xaa94, + 0x0804, 0x368d, 0x080c, 0x5848, 0x0904, 0x368d, 0x701f, 0x469f, + 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x7888, 0x908a, + 0x1000, 0x1a04, 0x36c2, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, + 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, 0x36c2, 0x080c, 0x6a85, + 0x0904, 0x36bf, 0x2019, 0x0004, 0x900e, 0x080c, 0x6a12, 0x0904, + 0x36bf, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, + 0x12f8, 0x080c, 0x4c72, 0x01e0, 0x080c, 0x6c11, 0x0118, 0x080c, + 0x6c19, 0x11b0, 0x080c, 0x6a85, 0x2009, 0x0002, 0x0168, 0x2009, + 0x0002, 0x2019, 0x0004, 0x080c, 0x6a12, 0x2009, 0x0003, 0x0120, + 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, + 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, + 0xa897, 0x4000, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, + 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c, 0x2400, + 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, + 0x67b4, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, + 0x89a1, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x798c, 0x2001, 0x1980, + 0x918c, 0x8000, 0x2102, 0x080c, 0x4c58, 0x0904, 0x36c2, 0x080c, + 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, 0x36c2, 0x080c, 0x687b, + 0x0904, 0x36bf, 0x080c, 0x6a09, 0x0904, 0x36bf, 0x2001, 0x1980, + 0x2004, 0xd0fc, 0x1904, 0x368d, 0x0804, 0x46aa, 0xa9a0, 0x2001, + 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c65, 0x01a0, + 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1170, 0x080c, 0x687b, + 0x2009, 0x0002, 0x0128, 0x080c, 0x6a09, 0x1170, 0x2009, 0x0003, + 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, + 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x1980, + 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, + 0x36bf, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c, + 0x4c58, 0x0904, 0x36c2, 0x080c, 0x6c11, 0x0120, 0x080c, 0x6c19, + 0x1904, 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, 0x080c, 0x69f7, + 0x0904, 0x36bf, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x368d, + 0x0804, 0x46aa, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, + 0x2102, 0x080c, 0x4c65, 0x01a0, 0x080c, 0x6c11, 0x0118, 0x080c, + 0x6c19, 0x1170, 0x080c, 0x687b, 0x2009, 0x0002, 0x0128, 0x080c, + 0x69f7, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, + 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, + 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, + 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, + 0x0000, 0x0005, 0x6100, 0x0804, 0x368d, 0x080c, 0x4c74, 0x0904, + 0x36c2, 0x080c, 0x5854, 0x1904, 0x36bf, 0x79a8, 0xd184, 0x1158, + 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, + 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007, + 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202, + 0x0804, 0x368d, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, + 0x1140, 0x939a, 0x0003, 0x1a04, 0x36bf, 0x625c, 0x7884, 0x9206, + 0x1548, 0x080c, 0x8b10, 0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, + 0x0080, 0x1118, 0x000e, 0x0804, 0x4c8d, 0x000e, 0x2031, 0x0000, + 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, + 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, + 0x4862, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x080c, 0x4c74, 0x0904, + 0x36c2, 0x080c, 0x6c11, 0x1904, 0x36bf, 0x00c6, 0x080c, 0x4c41, + 0x00ce, 0x0904, 0x36bf, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0x7ea8, 0x080c, 0xd092, 0x0904, 0x36bf, 0x7007, 0x0003, 0x701f, + 0x4866, 0x0005, 0x080c, 0x4397, 0x0804, 0x368d, 0xa830, 0x9086, + 0x0100, 0x0904, 0x36bf, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, + 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0x0804, 0x4c8d, 0x9006, 0x080c, 0x26f5, 0x78a8, + 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x36bf, + 0x080c, 0x779e, 0x0110, 0x080c, 0x6162, 0x7888, 0x908a, 0x1000, + 0x1a04, 0x36c2, 0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, + 0x1a04, 0x36c2, 0x2100, 0x080c, 0x26bf, 0x0026, 0x00c6, 0x0126, + 0x2091, 0x8000, 0x2061, 0x1a04, 0x601b, 0x0000, 0x601f, 0x0000, + 0x607b, 0x0000, 0x607f, 0x0000, 0x080c, 0x779e, 0x1158, 0x080c, + 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, 0x77e2, 0x080c, + 0x76cd, 0x00f0, 0x080c, 0xacfc, 0x080c, 0xb09b, 0x080c, 0xad18, + 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, + 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1999, + 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x6088, 0x080c, 0x8a5d, + 0x7984, 0x080c, 0x779e, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, + 0x470d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x368d, 0x7984, 0x080c, + 0x6749, 0x2b08, 0x1904, 0x36c2, 0x0804, 0x368d, 0x81ff, 0x0120, + 0x2009, 0x0001, 0x0804, 0x36bf, 0x60dc, 0xd0ac, 0x1130, 0xd09c, + 0x1120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x080c, 0x4c41, 0x1120, + 0x2009, 0x0002, 0x0804, 0x36bf, 0x7984, 0x81ff, 0x0904, 0x36c2, + 0x9192, 0x0021, 0x1a04, 0x36c2, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, + 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4c8a, + 0x701f, 0x4921, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x52da, + 0x0005, 0x2009, 0x0080, 0x080c, 0x67b4, 0x1118, 0x080c, 0x6c11, + 0x0120, 0x2021, 0x400a, 0x0804, 0x368f, 0x00d6, 0x0096, 0xa964, + 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, + 0x0904, 0x49ba, 0x90be, 0x0112, 0x0904, 0x49ba, 0x90be, 0x0113, + 0x0904, 0x49ba, 0x90be, 0x0114, 0x0904, 0x49ba, 0x90be, 0x0117, + 0x0904, 0x49ba, 0x90be, 0x011a, 0x0904, 0x49ba, 0x90be, 0x011c, + 0x0904, 0x49ba, 0x90be, 0x0121, 0x0904, 0x49a1, 0x90be, 0x0131, + 0x0904, 0x49a1, 0x90be, 0x0171, 0x0904, 0x49ba, 0x90be, 0x0173, + 0x0904, 0x49ba, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, + 0x0804, 0x49c5, 0x90be, 0x0212, 0x0904, 0x49ae, 0x90be, 0x0213, + 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, + 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, + 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x36c2, + 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, + 0x20a9, 0x0007, 0x080c, 0x4a03, 0x7028, 0x9080, 0x000e, 0x2098, + 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4a03, + 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, + 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4a10, 0x00b8, 0x7028, 0x9080, + 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, + 0x080c, 0x4a10, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, + 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4c41, + 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, + 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, + 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, + 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, + 0xd0ad, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, + 0x701f, 0x49fa, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, + 0x0804, 0x36bf, 0xa820, 0x9086, 0x8001, 0x1904, 0x368d, 0x2009, + 0x0004, 0x0804, 0x36bf, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, + 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, + 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, + 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, + 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x36bf, 0x60dc, 0xd0ac, 0x1188, 0x2009, 0x180d, 0x210c, 0xd18c, + 0x0130, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x36bf, 0xd09c, + 0x1120, 0x2009, 0x0005, 0x0804, 0x36bf, 0x7984, 0x78a8, 0x2040, + 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36c2, 0x9186, + 0x00ff, 0x0904, 0x36c2, 0x9182, 0x0800, 0x1a04, 0x36c2, 0x7a8c, + 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x36c2, + 0x080c, 0xb094, 0x1120, 0x99cc, 0xff00, 0x0904, 0x36c2, 0x0126, + 0x2091, 0x8000, 0x2001, 0x180d, 0x2004, 0xd08c, 0x0198, 0x9386, + 0x00ff, 0x0180, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, + 0x0148, 0x918d, 0x8000, 0x080c, 0x6c7f, 0x1120, 0x2001, 0x4009, + 0x0804, 0x4ac1, 0x080c, 0x4b54, 0x0904, 0x4ac7, 0x0086, 0x90c6, + 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, + 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, + 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, + 0x1128, 0x080c, 0x6c11, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, + 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, + 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, + 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, + 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, + 0x000a, 0x2020, 0x012e, 0x0804, 0x368f, 0x000e, 0x00ce, 0x2b00, + 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb1dd, + 0x0904, 0x4b1c, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x2e58, 0x00ee, + 0x00e6, 0x00c6, 0x080c, 0x4c41, 0x00ce, 0x2b70, 0x1158, 0x080c, + 0xb16c, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, + 0x0804, 0x36bf, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, + 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, + 0x080c, 0x3315, 0x6023, 0x0001, 0x9006, 0x080c, 0x66e6, 0xd89c, + 0x0138, 0x2001, 0x0004, 0x080c, 0x66fa, 0x2009, 0x0003, 0x0030, + 0x2001, 0x0002, 0x080c, 0x66fa, 0x2009, 0x0002, 0x080c, 0xb20a, + 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8d4, + 0xc08d, 0xb8d6, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, + 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, + 0x701f, 0x4b2b, 0x0005, 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, + 0x0140, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, + 0x368f, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, + 0xba04, 0x9294, 0x00ff, 0x0804, 0x578e, 0x900e, 0xa868, 0xd0f4, + 0x1904, 0x368d, 0x080c, 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, + 0x0108, 0xc18d, 0x0804, 0x368d, 0x00e6, 0x00d6, 0x0096, 0x83ff, + 0x0904, 0x4ba3, 0x902e, 0x080c, 0xb094, 0x0130, 0x9026, 0x20a9, + 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, + 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, + 0x4bb4, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, + 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, + 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, + 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, + 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6bb1, 0x1570, 0x2001, + 0x4000, 0x0460, 0x080c, 0x6c11, 0x1540, 0x2001, 0x4000, 0x0430, + 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, + 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xb094, + 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4b6a, + 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, + 0x080c, 0x6749, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, + 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, + 0x36bf, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, + 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, + 0x36c2, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x36c2, + 0x2010, 0x2918, 0x080c, 0x32b5, 0x1120, 0x2009, 0x0003, 0x0804, + 0x36bf, 0x7007, 0x0003, 0x701f, 0x4bf6, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1904, 0x368d, 0x2009, 0x0004, 0x0804, 0x36bf, 0x7984, + 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, 0x0a04, 0x36c2, 0x9186, + 0x00ff, 0x0904, 0x36c2, 0x9182, 0x0800, 0x1a04, 0x36c2, 0x2001, + 0x9400, 0x080c, 0x57e9, 0x1904, 0x36bf, 0x0804, 0x368d, 0xa998, + 0x080c, 0xb094, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, + 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x57e9, + 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, + 0x0c48, 0x080c, 0x1059, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, + 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, + 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, + 0x7984, 0x080c, 0x67b4, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x67b4, + 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, + 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x67b4, + 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, + 0x0128, 0x2148, 0xa904, 0x080c, 0x108b, 0x0cc8, 0x7116, 0x711a, + 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, + 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, + 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x368d, + 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, + 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4cbe, 0x7a36, 0x7833, + 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x1200, 0x0804, 0x4d24, 0x0016, 0x0086, + 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, + 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1059, + 0x0904, 0x4d1c, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, + 0x9080, 0x1ec1, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, + 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, + 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, + 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, + 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, + 0x9005, 0xa146, 0x1520, 0x080c, 0x1059, 0x1130, 0x8109, 0xa946, + 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, + 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, + 0x1ec1, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, + 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, + 0x9082, 0x001b, 0x0002, 0x4d46, 0x4d46, 0x4d48, 0x4d46, 0x4d46, + 0x4d46, 0x4d4c, 0x4d46, 0x4d46, 0x4d46, 0x4d50, 0x4d46, 0x4d46, + 0x4d46, 0x4d54, 0x4d46, 0x4d46, 0x4d46, 0x4d58, 0x4d46, 0x4d46, + 0x4d46, 0x4d5c, 0x4d46, 0x4d46, 0x4d46, 0x4d61, 0x080c, 0x0d85, + 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, + 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, + 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, + 0x4d1f, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4d1f, 0x00e6, 0x2071, + 0x189e, 0x7048, 0x9005, 0x0904, 0x4df8, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x4df7, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, + 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, + 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, + 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4dfa, 0xa804, 0x9005, + 0x090c, 0x0d85, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, + 0x0002, 0x9080, 0x1ec1, 0x2005, 0xa04a, 0x0804, 0x4dfa, 0x703c, + 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, + 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x87ff, 0x0118, + 0x2748, 0x080c, 0x108b, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, + 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x108b, 0x9006, 0x7042, + 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, + 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, + 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, + 0x703a, 0x7044, 0x9005, 0x090c, 0x0d85, 0x2048, 0xa800, 0x9005, + 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ec1, 0x2005, + 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, + 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4e19, 0x4e19, + 0x4e1b, 0x4e19, 0x4e19, 0x4e19, 0x4e20, 0x4e19, 0x4e19, 0x4e19, + 0x4e25, 0x4e19, 0x4e19, 0x4e19, 0x4e2a, 0x4e19, 0x4e19, 0x4e19, + 0x4e2f, 0x4e19, 0x4e19, 0x4e19, 0x4e34, 0x4e19, 0x4e19, 0x4e19, + 0x4e39, 0x080c, 0x0d85, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4da5, + 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4da5, 0xaa94, 0xab98, 0xac9c, + 0x0804, 0x4da5, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4da5, 0xaab4, + 0xabb8, 0xacbc, 0x0804, 0x4da5, 0xaac4, 0xabc8, 0xaccc, 0x0804, + 0x4da5, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4da5, 0x0016, 0x0026, + 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x67b4, 0x2019, + 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, + 0x080c, 0x4ca1, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, + 0x0026, 0x080c, 0x5840, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, + 0x4ca1, 0x002e, 0x0005, 0x81ff, 0x1904, 0x36bf, 0x0126, 0x2091, + 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x779e, + 0x1158, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, + 0x77e2, 0x080c, 0x76cd, 0x0010, 0x080c, 0x6058, 0x012e, 0x0804, + 0x368d, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, + 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x080c, 0x6c09, + 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0x2001, 0x180d, 0x2004, + 0xd08c, 0x0178, 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, + 0x0140, 0x7984, 0x080c, 0x6c7f, 0x1120, 0x2009, 0x4009, 0x0804, + 0x36bf, 0x7984, 0x080c, 0x6749, 0x1904, 0x36c2, 0x080c, 0x4c74, + 0x0904, 0x36c2, 0x2b00, 0x7026, 0x080c, 0x6c11, 0x7888, 0x1170, + 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6aae, 0x1108, 0xc185, + 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x368d, 0x080c, 0x4c41, + 0x0904, 0x36bf, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, + 0x080c, 0xd154, 0x0904, 0x36bf, 0x7888, 0xd094, 0x0118, 0xb8d4, + 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4f28, 0x0005, 0x2061, + 0x1800, 0x080c, 0x5854, 0x2009, 0x0007, 0x1560, 0x080c, 0x6c09, + 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6749, 0x1530, + 0x080c, 0x4c72, 0x0518, 0x080c, 0x6c11, 0xa89c, 0x1168, 0x9084, + 0x0005, 0x1150, 0x900e, 0x080c, 0x6aae, 0x1108, 0xc185, 0xb800, + 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, + 0xd154, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, + 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, + 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, + 0xa830, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0140, 0x2008, 0x918e, + 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x368f, 0x9086, 0x0100, + 0x7024, 0x2058, 0x1110, 0x0804, 0x578e, 0x900e, 0x080c, 0x6aae, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x368d, + 0x080c, 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7f84, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c41, 0x1120, 0x2009, + 0x0002, 0x0804, 0x36bf, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860, + 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, + 0x67b4, 0x1904, 0x4fde, 0x080c, 0x6c11, 0x0138, 0x080c, 0x6c19, + 0x0120, 0x080c, 0x6bb1, 0x1904, 0x4fde, 0xd794, 0x1110, 0xd784, + 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, + 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, + 0x20e0, 0x20a9, 0x0002, 0x080c, 0x4a10, 0x0080, 0xb8c4, 0x20e0, + 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x4003, + 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4a10, 0x9186, 0x007e, + 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6c11, 0x90c2, 0x0006, + 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6aae, 0x1108, 0xc1fd, 0x4104, + 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, + 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, + 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, + 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4a03, + 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, + 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, + 0xb094, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, + 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, + 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4f67, + 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x368d, 0x7033, 0x0001, + 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, + 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, + 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, + 0x501a, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, + 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, + 0xa390, 0xa494, 0xa598, 0x0804, 0x4f67, 0x7124, 0x810b, 0x0804, + 0x368d, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, + 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, + 0x36c2, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, + 0x0a04, 0x36c2, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, + 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9284, 0x00ff, 0x90e2, 0x0020, + 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9384, 0xff00, 0x8007, + 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, 0x9384, + 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, 0x0a04, 0x36c2, + 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36c2, 0x9502, + 0x0a04, 0x36c2, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36c2, + 0x9502, 0x0a04, 0x36c2, 0x2061, 0x1989, 0x6102, 0x6206, 0x630a, + 0x640e, 0x0804, 0x368d, 0x080c, 0x4c41, 0x0904, 0x36bf, 0x2009, + 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, + 0xaf60, 0x080c, 0x4c8a, 0x701f, 0x509e, 0x0005, 0x20a9, 0x0016, + 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, 0x2098, + 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, 0x2da0, + 0x4003, 0x6800, 0x9005, 0x0904, 0x5105, 0x6804, 0x2008, 0x918c, + 0xfff8, 0x1904, 0x5105, 0x680c, 0x9005, 0x0904, 0x5105, 0x9082, + 0xff01, 0x1a04, 0x5105, 0x6810, 0x9082, 0x005c, 0x06f0, 0x6824, + 0x2008, 0x9082, 0x0008, 0x06c8, 0x9182, 0x0400, 0x16b0, 0x0056, + 0x2029, 0x0000, 0x080c, 0x9077, 0x005e, 0x6944, 0x6820, 0x9102, + 0x0660, 0x6820, 0x9082, 0x0019, 0x1640, 0x6828, 0x6944, 0x810c, + 0x9102, 0x0618, 0x6840, 0x9082, 0x000f, 0x12f8, 0x080c, 0x1072, + 0x2900, 0x0590, 0x684e, 0x00e6, 0x2071, 0x1931, 0x00b6, 0x2059, + 0x0000, 0x080c, 0x8f33, 0x00be, 0x00ee, 0x01e8, 0x080c, 0x8c78, + 0x080c, 0x8cc7, 0x1160, 0x6857, 0x0000, 0x00c6, 0x6b10, 0x2061, + 0x1a6e, 0x630e, 0x00ce, 0x0804, 0x368d, 0x0804, 0x36c2, 0x080c, + 0x8cc0, 0x00e6, 0x2071, 0x1931, 0x080c, 0x90f7, 0x080c, 0x9106, + 0x080c, 0x8f18, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x108b, + 0x2001, 0x188a, 0x2003, 0x0000, 0x0804, 0x36bf, 0x0126, 0x2091, + 0x8000, 0x080c, 0x94b8, 0x080c, 0x8cc0, 0x012e, 0x0804, 0x368d, + 0x0006, 0x080c, 0x5840, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, + 0x5844, 0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, + 0x1118, 0x7986, 0x0804, 0x368d, 0x83ff, 0x1904, 0x36c2, 0x2001, + 0xfff0, 0x9200, 0x1a04, 0x36c2, 0x2019, 0xffff, 0x6078, 0x9302, + 0x9200, 0x0a04, 0x36c2, 0x7986, 0x6276, 0x0804, 0x368d, 0x080c, + 0x5854, 0x1904, 0x36bf, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, + 0x4c41, 0x0904, 0x36bf, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, + 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, + 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, + 0x6c19, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, + 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, + 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, + 0x0003, 0x080c, 0x955b, 0x2208, 0x0804, 0x368d, 0x7033, 0x0001, + 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, + 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, + 0xa696, 0xa79a, 0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x51a9, + 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, + 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, + 0xa798, 0x0804, 0x5167, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, + 0x955b, 0x2208, 0x0804, 0x368d, 0x00f6, 0x00e6, 0x080c, 0x5854, + 0x2009, 0x0007, 0x1904, 0x523c, 0x2071, 0x189e, 0x745c, 0x84ff, + 0x2009, 0x000e, 0x1904, 0x523c, 0xac9c, 0xad98, 0xaea4, 0xafa0, + 0x0096, 0x080c, 0x1072, 0x2009, 0x0002, 0x0904, 0x523c, 0x2900, + 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, + 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, + 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1148, 0xb814, + 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, + 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, + 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x955b, + 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, + 0x0d85, 0x2148, 0x080c, 0x108b, 0x9006, 0x705e, 0x918d, 0x0001, + 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, + 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, + 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x5248, 0x000e, 0xa0a2, + 0x080c, 0x114e, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, + 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, + 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0x00e6, 0x2071, 0x189e, + 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, + 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, + 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, + 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, + 0x900e, 0x2001, 0x0003, 0x080c, 0x955b, 0xaa9a, 0x715c, 0x81ff, + 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, 0x705f, 0x0000, 0xa0a0, + 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0xa09f, + 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, + 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6c11, 0x0118, 0x080c, 0x6c19, + 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, + 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, + 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, + 0x4000, 0x715c, 0x81ff, 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, + 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, + 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0xa09f, 0x0000, 0xa0a3, + 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, + 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x114e, 0x9006, + 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, + 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36c2, + 0xa884, 0xa988, 0x080c, 0x268c, 0x1518, 0x080c, 0x6749, 0x1500, + 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4c41, 0x01c8, 0x080c, + 0x4c41, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, + 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xd0cd, 0x1120, 0x2009, + 0x0003, 0x0804, 0x36bf, 0x7007, 0x0003, 0x701f, 0x5315, 0x0005, + 0x009e, 0x2009, 0x0002, 0x0804, 0x36bf, 0x7124, 0x080c, 0x341e, + 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, + 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, + 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, + 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, + 0x0fd6, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, + 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, + 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, + 0x007e, 0x0804, 0x4c8d, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, + 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, + 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, + 0x7007, 0x0002, 0x701f, 0x5371, 0x0005, 0x000e, 0x007e, 0x0804, + 0x36c2, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, + 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, + 0xa598, 0x2009, 0x002a, 0x0804, 0x4c8d, 0x81ff, 0x1904, 0x36bf, + 0x798c, 0x2001, 0x197e, 0x918c, 0x8000, 0x2102, 0x080c, 0x4c58, + 0x0904, 0x36c2, 0x080c, 0x6c11, 0x0120, 0x080c, 0x6c19, 0x1904, + 0x36c2, 0x080c, 0x687b, 0x0904, 0x36bf, 0x0126, 0x2091, 0x8000, + 0x080c, 0x6a1b, 0x012e, 0x0904, 0x36bf, 0x2001, 0x197e, 0x2004, + 0xd0fc, 0x1904, 0x368d, 0x0804, 0x46aa, 0xa9a0, 0x2001, 0x197e, + 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4c65, 0x01a0, 0x080c, + 0x6c11, 0x0118, 0x080c, 0x6c19, 0x1170, 0x080c, 0x687b, 0x2009, + 0x0002, 0x0128, 0x080c, 0x6a1b, 0x1170, 0x2009, 0x0003, 0xa897, + 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, + 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197e, 0x2004, + 0xd0fc, 0x1128, 0x080c, 0x5848, 0x0110, 0x9006, 0x0018, 0x900e, + 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, + 0xd084, 0x0904, 0x461f, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x080c, + 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0x080c, 0x6c11, + 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, + 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5840, + 0xd0b4, 0x0904, 0x4659, 0x7884, 0x908e, 0x007e, 0x0904, 0x4659, + 0x908e, 0x007f, 0x0904, 0x4659, 0x908e, 0x0080, 0x0904, 0x4659, + 0xb800, 0xd08c, 0x1904, 0x4659, 0xa867, 0x0000, 0xa868, 0xc0fd, + 0xa86a, 0x080c, 0xd0ec, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, + 0x7007, 0x0003, 0x701f, 0x543d, 0x0005, 0x080c, 0x4c74, 0x0904, + 0x36c2, 0x0804, 0x4659, 0x080c, 0x347d, 0x0108, 0x0005, 0x2009, + 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, + 0x080c, 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x080c, + 0x6c09, 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0xb89c, 0xd0a4, + 0x1118, 0xd0ac, 0x1904, 0x4659, 0x9006, 0xa866, 0xa832, 0xa868, + 0xc0fd, 0xa86a, 0x080c, 0xd154, 0x1120, 0x2009, 0x0003, 0x0804, + 0x36bf, 0x7007, 0x0003, 0x701f, 0x5476, 0x0005, 0xa830, 0x9086, + 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x578e, 0x080c, 0x4c74, + 0x0904, 0x36c2, 0x0804, 0x540f, 0x81ff, 0x2009, 0x0001, 0x1904, + 0x36bf, 0x080c, 0x5854, 0x2009, 0x0007, 0x1904, 0x36bf, 0x080c, + 0x6c09, 0x0120, 0x2009, 0x0008, 0x0804, 0x36bf, 0x080c, 0x4c74, + 0x0904, 0x36c2, 0x080c, 0x6c11, 0x2009, 0x0009, 0x1904, 0x36bf, + 0x080c, 0x4c41, 0x2009, 0x0002, 0x0904, 0x36bf, 0x9006, 0xa866, + 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, + 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, + 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x36c2, 0xc0e5, 0xa952, + 0xa956, 0xa83e, 0x080c, 0xd3b7, 0x2009, 0x0003, 0x0904, 0x36bf, + 0x7007, 0x0003, 0x701f, 0x54cd, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x36bf, 0x0804, 0x368d, 0x7aa8, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x5854, 0x1188, 0x2009, + 0x0014, 0x0804, 0x36bf, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, + 0x1904, 0x36bf, 0x080c, 0x5854, 0x2009, 0x0007, 0x1904, 0x36bf, + 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x581a, 0x0804, + 0x368d, 0xd2fc, 0x0160, 0x080c, 0x4c74, 0x0904, 0x36c2, 0x7984, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57e9, 0x0804, 0x368d, 0x080c, + 0x4c74, 0x0904, 0x36c2, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x2009, 0x0009, 0x1904, 0x55bc, 0x080c, 0x4c41, 0x2009, 0x0002, + 0x0904, 0x55bc, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, + 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4c8a, 0x701f, 0x5529, + 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, + 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x36c2, 0xa866, 0xa832, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4c74, 0x1110, 0x0804, 0x36c2, + 0x2009, 0x0043, 0x080c, 0xd423, 0x2009, 0x0003, 0x0904, 0x55bc, + 0x7007, 0x0003, 0x701f, 0x554d, 0x0005, 0xa830, 0x9086, 0x0100, + 0x2009, 0x0004, 0x0904, 0x55bc, 0x7984, 0x7aa8, 0x9284, 0x1000, + 0xc0d5, 0x080c, 0x57e9, 0x0804, 0x368d, 0x00c6, 0xaab0, 0x9284, + 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x5854, 0x1158, 0x2009, + 0x0014, 0x0804, 0x55ab, 0x2061, 0x1800, 0x080c, 0x5854, 0x2009, + 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, + 0x581a, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4c72, 0x0590, 0xa998, + 0x9284, 0x9000, 0xc0d5, 0x080c, 0x57e9, 0xa87b, 0x0000, 0xa883, + 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4c72, 0x0510, 0x080c, + 0x6c11, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, + 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, + 0x4c72, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xd423, 0x2009, + 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, + 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, + 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36bf, + 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57e9, 0x001e, + 0x1904, 0x36bf, 0x0804, 0x368d, 0x00f6, 0x2d78, 0xaab0, 0x0021, + 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, + 0x9284, 0x1400, 0xc0fd, 0x080c, 0x57e9, 0x001e, 0x9085, 0x0001, + 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, + 0x5854, 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7984, 0x7ea8, + 0x96b4, 0x00ff, 0x080c, 0x67b4, 0x1904, 0x36c2, 0x9186, 0x007f, + 0x0138, 0x080c, 0x6c11, 0x0120, 0x2009, 0x0009, 0x0804, 0x36bf, + 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0xa867, + 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, + 0x080c, 0xd106, 0x1120, 0x2009, 0x0003, 0x0804, 0x36bf, 0x7007, + 0x0003, 0x701f, 0x561c, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, + 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa8e0, 0xa866, 0xa810, + 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, + 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, + 0x7d98, 0x0804, 0x4c8d, 0x080c, 0x4c41, 0x1120, 0x2009, 0x0002, + 0x0804, 0x36bf, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, + 0x82ff, 0x1118, 0x7023, 0x19b4, 0x0040, 0x92c6, 0x0001, 0x1118, + 0x7023, 0x19ce, 0x0010, 0x0804, 0x36c2, 0x2009, 0x001a, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, + 0x4c8a, 0x701f, 0x566c, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, + 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, + 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x368d, 0x080c, + 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0x7984, 0x9194, + 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b4, + 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19ce, 0x0010, 0x0804, + 0x36c2, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, + 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, + 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c8d, + 0x7884, 0x908a, 0x1000, 0x1a04, 0x36c2, 0x0126, 0x2091, 0x8000, + 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x1a04, 0x614a, + 0x00ce, 0x012e, 0x0804, 0x368d, 0x00c6, 0x080c, 0x779e, 0x1160, + 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, 0x080c, 0x77e2, + 0x080c, 0x76cd, 0x080c, 0x0d85, 0x2061, 0x1800, 0x6030, 0xc09d, + 0x6032, 0x080c, 0x6058, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, + 0x2004, 0x908e, 0x0000, 0x0904, 0x36bf, 0x7884, 0x9005, 0x0188, + 0x7888, 0x2061, 0x199c, 0x2c0c, 0x2062, 0x080c, 0x2a67, 0x01a0, + 0x080c, 0x2a6f, 0x0188, 0x080c, 0x2a77, 0x0170, 0x2162, 0x0804, + 0x36c2, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, + 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, + 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x080c, 0xacfc, 0x0026, + 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, 0xa635, + 0x002e, 0x080c, 0xa516, 0x0036, 0x901e, 0x080c, 0xa596, 0x003e, + 0x080c, 0xad18, 0x60e3, 0x0000, 0x080c, 0xeed9, 0x080c, 0xeef4, + 0x9085, 0x0001, 0x080c, 0x77e2, 0x9006, 0x080c, 0x2a99, 0x2001, + 0x1800, 0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x0026, + 0x2011, 0x0008, 0x080c, 0x2ad3, 0x002e, 0x00ce, 0x0804, 0x368d, + 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36bf, 0x080c, 0x5854, + 0x0120, 0x2009, 0x0007, 0x0804, 0x36bf, 0x7984, 0x7ea8, 0x96b4, + 0x00ff, 0x080c, 0x67b4, 0x1904, 0x36c2, 0x9186, 0x007f, 0x0138, + 0x080c, 0x6c11, 0x0120, 0x2009, 0x0009, 0x0804, 0x36bf, 0x080c, + 0x4c41, 0x1120, 0x2009, 0x0002, 0x0804, 0x36bf, 0xa867, 0x0000, + 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd109, 0x1120, 0x2009, 0x0003, + 0x0804, 0x36bf, 0x7007, 0x0003, 0x701f, 0x5777, 0x0005, 0xa830, + 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x36bf, 0xa8e0, + 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, + 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4c8d, 0xa898, 0x9086, + 0x000d, 0x1904, 0x36bf, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, + 0x0e04, 0x579b, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, + 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, + 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c7d, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x1a04, 0x7984, 0x615a, + 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, + 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001, 0x1a14, 0x2044, + 0x2001, 0x1a1b, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, + 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, + 0x368d, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, + 0x0198, 0x0006, 0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, + 0xacfc, 0x0106, 0x080c, 0x3442, 0x010e, 0x090c, 0xad18, 0x003e, + 0x080c, 0xcf68, 0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, + 0x2004, 0x905d, 0x0160, 0x080c, 0x61b7, 0x080c, 0xb094, 0x0110, + 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, + 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, + 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, + 0x9186, 0x007e, 0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, + 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57e9, + 0x002e, 0x001e, 0x8108, 0x1f04, 0x5822, 0x015e, 0x012e, 0x0005, + 0x2001, 0x1848, 0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, + 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, + 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, + 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36c2, + 0x9182, 0x0081, 0x1a04, 0x36c2, 0x810c, 0x0016, 0x080c, 0x4c41, + 0x0170, 0x080c, 0x0f61, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, + 0x7a90, 0x001e, 0x080c, 0x4c8a, 0x701f, 0x5884, 0x0005, 0x001e, + 0x2009, 0x0002, 0x0804, 0x36bf, 0x2079, 0x0000, 0x7d94, 0x7c98, + 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, + 0xa074, 0x2071, 0x189e, 0x080c, 0x4c8d, 0x701f, 0x5898, 0x0005, + 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, + 0x0f69, 0x002e, 0x001e, 0x080c, 0x1016, 0x9006, 0xa802, 0xa806, + 0x0804, 0x368d, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, + 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, + 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, + 0x5a58, 0x0068, 0xd08c, 0x0118, 0x080c, 0x5961, 0x0040, 0xd094, + 0x0118, 0x080c, 0x5931, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, + 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, + 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, + 0x001e, 0x0c68, 0x7030, 0xd09c, 0x1120, 0x6004, 0x9085, 0x0002, + 0x6006, 0x7098, 0x9005, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000, + 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, + 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, + 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, + 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, + 0x6119, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, + 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, + 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000, 0x7097, 0x0000, + 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5ffb, 0x080c, 0x8a5d, + 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, + 0x7088, 0x9005, 0x1528, 0x2011, 0x5ffb, 0x080c, 0x8993, 0x6040, + 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, + 0xd08c, 0x1168, 0x1f04, 0x5947, 0x6242, 0x709b, 0x0000, 0x6040, + 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, + 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x61a2, 0x0000, + 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d85, 0x000b, 0x0005, + 0x596b, 0x59bc, 0x5a57, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, + 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, + 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x597a, + 0x080c, 0x0d85, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, + 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, + 0x617e, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, + 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e, 0x20a9, + 0x0004, 0x4003, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, 0x1d00, + 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, + 0x000c, 0x600f, 0x0000, 0x080c, 0x602c, 0x00fe, 0x9006, 0x7092, + 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, + 0x9025, 0x0904, 0x5a34, 0x6020, 0xd0b4, 0x1904, 0x5a32, 0x71a0, + 0x81ff, 0x0904, 0x5a20, 0x9486, 0x000c, 0x1904, 0x5a2d, 0x9480, + 0x0018, 0x8004, 0x20a8, 0x080c, 0x6177, 0x2011, 0x0260, 0x2019, + 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, + 0x59d9, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, + 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b, + 0x0002, 0x2009, 0x07d0, 0x2011, 0x6002, 0x080c, 0x8a5d, 0x080c, + 0x617e, 0x04c0, 0x080c, 0x6177, 0x2079, 0x0260, 0x7930, 0x918e, + 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, + 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x6177, 0x2011, 0x026e, + 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, + 0x11a0, 0x8210, 0x8318, 0x1f04, 0x5a14, 0x0078, 0x70a3, 0x0000, + 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, + 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, + 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, + 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, + 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, + 0x60c3, 0x000c, 0x2011, 0x19f5, 0x2013, 0x0000, 0x7093, 0x0000, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa293, 0x08d8, 0x0005, + 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d85, 0x000b, 0x0005, 0x5a89, + 0x5a9c, 0x5ac5, 0x5ae5, 0x5b0b, 0x5b3a, 0x5b60, 0x5b98, 0x5bbe, + 0x5bec, 0x5c27, 0x5c5f, 0x5c7d, 0x5ca8, 0x5cca, 0x5ce5, 0x5cef, + 0x5d23, 0x5d49, 0x5d78, 0x5d9e, 0x5dd6, 0x5e1a, 0x5e57, 0x5e78, + 0x5ed1, 0x5ef3, 0x5f21, 0x5f21, 0x00c6, 0x2061, 0x1800, 0x6003, + 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, + 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, + 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, + 0x6002, 0x080c, 0x8a5d, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, + 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6177, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, + 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, + 0x2011, 0x6002, 0x080c, 0x8993, 0x709b, 0x0010, 0x080c, 0x5cef, + 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, + 0x6043, 0x0004, 0x2011, 0x6002, 0x080c, 0x8993, 0x080c, 0x60fb, + 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, + 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5ada, 0x60c3, + 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, + 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, + 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, + 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, + 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c, + 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x60fb, + 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6177, + 0x080c, 0x615a, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, + 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5faf, 0x0168, 0x080c, + 0x6130, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, + 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, + 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, + 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, + 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, + 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, + 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x0007, 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, + 0x1104, 0x7837, 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, 0x11b8, + 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, + 0x348e, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, + 0x5faf, 0x0180, 0x080c, 0x512e, 0x0110, 0x080c, 0x26f5, 0x20a9, + 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, + 0x0029, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0009, 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, + 0x0100, 0x080c, 0x615a, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c, + 0x5f22, 0x1188, 0x9085, 0x0001, 0x080c, 0x26f5, 0x20a9, 0x0008, + 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x0010, + 0x080c, 0x5a7c, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, + 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x1560, 0x080c, + 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, + 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, + 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e, + 0x080c, 0x5cca, 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, + 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, + 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x60fb, 0x2079, 0x0240, + 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x615a, 0x0118, 0x2013, + 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, + 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210, 0x8108, 0x9186, + 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, + 0x5c4c, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x01c0, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, + 0x0084, 0x1178, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029, + 0x0010, 0x080c, 0x6153, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, + 0x080c, 0x60fb, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, + 0x080c, 0x6177, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, + 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, + 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, + 0x1f04, 0x5c90, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x6002, 0x080c, 0x8993, + 0x9086, 0x0084, 0x1198, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, + 0x080c, 0x60cd, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x6153, + 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x61a2, 0x709b, 0x000f, + 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, + 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, + 0x2011, 0x6002, 0x080c, 0x8987, 0x0005, 0x7090, 0x9005, 0x0130, + 0x2011, 0x6002, 0x080c, 0x8993, 0x709b, 0x0000, 0x0005, 0x709b, + 0x0011, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, + 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, + 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, + 0x615a, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, + 0x00ff, 0x0160, 0x080c, 0x268c, 0x9186, 0x007e, 0x0138, 0x9186, + 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5faf, 0x60c3, 0x0014, + 0x080c, 0x602c, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, + 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, + 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, + 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, + 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, + 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x6109, 0x2079, 0x0240, + 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, + 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, + 0x2011, 0x0008, 0x080c, 0x5faf, 0x0168, 0x080c, 0x6130, 0x20a9, + 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, + 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x6002, 0x080c, 0x8993, + 0x9086, 0x0014, 0x11b8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, + 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, + 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, + 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, + 0x0015, 0x080c, 0x6109, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, + 0x0000, 0x080c, 0x6177, 0x080c, 0x615a, 0x11b8, 0x7084, 0x9005, + 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x348e, 0x200d, + 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5faf, 0x0180, + 0x080c, 0x512e, 0x0110, 0x080c, 0x26f5, 0x20a9, 0x0008, 0x20e1, + 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, + 0x60c3, 0x0014, 0x080c, 0x602c, 0x00fe, 0x0005, 0x00f6, 0x7090, + 0x9005, 0x05f0, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, 0x0014, + 0x15a8, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, + 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, + 0x9085, 0x0001, 0x080c, 0x61a2, 0x7a38, 0xd2fc, 0x0128, 0x70c4, + 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, + 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, + 0x0001, 0x080c, 0x61a2, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, + 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000, + 0x00fe, 0x0005, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, + 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, + 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, + 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x615a, 0x1150, + 0x7084, 0x9005, 0x1138, 0x080c, 0x5f22, 0x1188, 0x9085, 0x0001, + 0x080c, 0x26f5, 0x20a9, 0x0008, 0x080c, 0x6177, 0x20e1, 0x0000, + 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, + 0x0014, 0x080c, 0x602c, 0x0010, 0x080c, 0x5a7c, 0x0005, 0x00f6, + 0x7090, 0x9005, 0x01d8, 0x2011, 0x6002, 0x080c, 0x8993, 0x9086, + 0x0084, 0x1190, 0x080c, 0x6177, 0x2079, 0x0260, 0x7a30, 0x9296, + 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x61a2, + 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, + 0x00f6, 0x709b, 0x0019, 0x080c, 0x6109, 0x2079, 0x0240, 0x7833, + 0x1106, 0x7837, 0x0000, 0x080c, 0x6177, 0x2009, 0x026e, 0x2039, + 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, + 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e8b, + 0x2039, 0x1d0e, 0x080c, 0x615a, 0x11e8, 0x2728, 0x2514, 0x8207, + 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, + 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1d0e, 0x2414, 0x938c, + 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, + 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, + 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, + 0x0240, 0x1f04, 0x5ebe, 0x60c3, 0x0084, 0x080c, 0x602c, 0x00fe, + 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x6002, 0x080c, + 0x8993, 0x9086, 0x0084, 0x1198, 0x080c, 0x6177, 0x2079, 0x0260, + 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, + 0x0001, 0x080c, 0x60cd, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093, + 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x61a2, 0x709b, + 0x001b, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x2011, 0x0260, 0x2009, + 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, + 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, + 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, + 0x2011, 0x0260, 0x1f04, 0x5f0a, 0x60c3, 0x0084, 0x080c, 0x602c, + 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, + 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x6177, + 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, + 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, + 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, + 0x5f3c, 0x0804, 0x5fab, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, + 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5fab, 0x918d, + 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, + 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, + 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5f62, 0x04d8, + 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f74, 0x2328, + 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, + 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f83, 0x755e, + 0x95c8, 0x348e, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, + 0x0016, 0x2508, 0x080c, 0x26d5, 0x001e, 0x60e7, 0x0000, 0x65ea, + 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, + 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, + 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, + 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, + 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, + 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, + 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, + 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, + 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, + 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x348e, + 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, + 0x080c, 0x26d5, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, + 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, + 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, + 0x080c, 0x60bc, 0x080c, 0xa2a0, 0x7004, 0x9084, 0x4000, 0x0110, + 0x080c, 0x2aa9, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073, + 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x6119, + 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, + 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, + 0x2a04, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, + 0x19f5, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x080c, 0xa293, 0x6144, 0xd184, 0x0120, 0x7198, + 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x1999, + 0x2112, 0x2009, 0x07d0, 0x2011, 0x6002, 0x080c, 0x8a5d, 0x0005, + 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, + 0x080c, 0xb09b, 0x080c, 0xad18, 0x2009, 0x00f7, 0x080c, 0x6119, + 0x2061, 0x1a04, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e, 0x2061, + 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, + 0x0010, 0x2009, 0x1999, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, + 0x6088, 0x080c, 0x8987, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, + 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100, + 0x080c, 0xa2a0, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110, + 0x080c, 0x2aa9, 0x080c, 0x77a6, 0x0188, 0x080c, 0x77c1, 0x1170, + 0x080c, 0x7ac0, 0x0016, 0x080c, 0x27a4, 0x2001, 0x196d, 0x2102, + 0x001e, 0x080c, 0x7abb, 0x080c, 0x76cd, 0x0050, 0x2009, 0x0001, + 0x080c, 0x2a85, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, 0x6058, + 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc, + 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1999, 0x201c, + 0x080c, 0x4ca1, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9, + 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6177, 0x20e9, 0x0000, 0x2099, + 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6171, 0x2099, 0x0260, + 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6174, 0x2099, + 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410, + 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x60f1, + 0x002e, 0x001e, 0x0005, 0x080c, 0xaaf1, 0x20e1, 0x0001, 0x2099, + 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, + 0x0005, 0x080c, 0xaaf1, 0x080c, 0x6177, 0x20e1, 0x0000, 0x2099, + 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, + 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0x1834, + 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, + 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, + 0x0016, 0x0046, 0x080c, 0x6c0d, 0x0158, 0x9006, 0x2020, 0x2009, + 0x002a, 0x080c, 0xea8d, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, + 0x2019, 0x002a, 0x900e, 0x080c, 0x32da, 0x080c, 0xd645, 0x0140, + 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4e58, 0x003e, + 0x004e, 0x001e, 0x0005, 0x080c, 0x6058, 0x709b, 0x0000, 0x7093, + 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, 0x0100, + 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, + 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, + 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, 0x900e, + 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, 0x0156, + 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1, + 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, 0x2200, 0x7807, 0x00ef, + 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, 0xffff, + 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, 0x2003, + 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001, 0x0010, + 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, 0x1000, + 0x9006, 0x200a, 0x8108, 0x1f04, 0x61b1, 0x015e, 0x0005, 0x00d6, + 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, 0xb802, + 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x348e, + 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886, 0x080c, + 0xb094, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86, 0x20a9, 0x0004, + 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, 0x4004, + 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, 0x001e, + 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, 0xb862, 0xb866, 0xb86a, + 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, + 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, + 0x904d, 0x0110, 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e, 0x9006, + 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, + 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1ddc, 0x0a0c, 0x0d85, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x080c, 0x8eee, + 0x00ce, 0x090c, 0x928d, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, + 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, + 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, + 0x1a04, 0x628d, 0x9182, 0x0800, 0x1a04, 0x6291, 0x2001, 0x180c, + 0x2004, 0x9084, 0x0003, 0x1904, 0x6297, 0x9188, 0x1000, 0x2104, + 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1188, + 0xb8a4, 0x900d, 0x1904, 0x62a9, 0x080c, 0x6669, 0x9006, 0x012e, + 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, + 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xb094, 0x1160, 0xb8a0, + 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0d10, 0x2001, 0x0029, + 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, + 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, + 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, + 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, + 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, + 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x9065, + 0x09a8, 0x080c, 0x6c11, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, + 0x6250, 0x080c, 0x6a2a, 0x0904, 0x6259, 0x0804, 0x6254, 0x00e6, + 0x2071, 0x19e8, 0x7004, 0x9086, 0x0002, 0x1128, 0x7030, 0x9080, + 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6, 0x00e6, 0x0126, + 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196b, + 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000, + 0x2104, 0x905d, 0x01d0, 0x080c, 0x6bb1, 0x11d0, 0x080c, 0xb116, + 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x602b, + 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000, 0x2009, + 0x0043, 0x080c, 0xb20a, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, + 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, + 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, + 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, + 0x9182, 0x0800, 0x1a04, 0x6388, 0x9188, 0x1000, 0x2104, 0x905d, + 0x0904, 0x6360, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, + 0x1178, 0x080c, 0x6c19, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, + 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6c11, 0x1598, + 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, + 0x2010, 0x080c, 0xcf09, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804, + 0x638a, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804, + 0x638a, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c, + 0xb116, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff, + 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xb20a, 0x9006, 0x0458, + 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb094, + 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, + 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, + 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, + 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010, + 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, + 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, + 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, + 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, + 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, + 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, + 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, + 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be, + 0x00fe, 0x0005, 0x641f, 0x63da, 0x63f1, 0x641f, 0x641f, 0x641f, + 0x641f, 0x641f, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x6749, + 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6427, 0xb814, 0x9206, + 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4b54, 0x0150, + 0x04b0, 0x080c, 0x67b4, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814, + 0x9206, 0x1568, 0x080c, 0xb116, 0x0530, 0x2b00, 0x6012, 0x080c, + 0xd3b6, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878, + 0x9086, 0x0001, 0x1170, 0x080c, 0x3315, 0x9006, 0x080c, 0x66e6, + 0x2001, 0x0002, 0x080c, 0x66fa, 0x2001, 0x0200, 0xb86e, 0xb893, + 0x0002, 0x2009, 0x0003, 0x080c, 0xb20a, 0x9006, 0x0068, 0x2001, + 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, + 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, + 0x0015, 0x0904, 0x6612, 0x90c6, 0x0056, 0x0904, 0x6616, 0x90c6, + 0x0066, 0x0904, 0x661a, 0x90c6, 0x0067, 0x0904, 0x661e, 0x90c6, + 0x0068, 0x0904, 0x6622, 0x90c6, 0x0071, 0x0904, 0x6626, 0x90c6, + 0x0074, 0x0904, 0x662a, 0x90c6, 0x007c, 0x0904, 0x662e, 0x90c6, + 0x007e, 0x0904, 0x6632, 0x90c6, 0x0037, 0x0904, 0x6636, 0x9016, + 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x660d, 0x9182, + 0x0800, 0x1a04, 0x660d, 0x080c, 0x67b4, 0x1198, 0xb804, 0x9084, + 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, + 0x080c, 0xb094, 0x1904, 0x65f6, 0xb8a0, 0x9084, 0xff80, 0x1904, + 0x65f6, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, + 0x6556, 0x90c6, 0x0064, 0x0904, 0x657f, 0x2008, 0x0804, 0x6518, + 0xa998, 0xa8b0, 0x2040, 0x080c, 0xb094, 0x1120, 0x9182, 0x007f, + 0x0a04, 0x6518, 0x9186, 0x00ff, 0x0904, 0x6518, 0x9182, 0x0800, + 0x1a04, 0x6518, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, + 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x6518, + 0x080c, 0xb094, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, + 0x2310, 0x0804, 0x6518, 0x009e, 0x080c, 0x4b54, 0x0904, 0x6522, + 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x6aae, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, + 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, 0x20a9, 0x0004, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, + 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0xa8c4, 0xabc8, + 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, + 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, + 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, + 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, + 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010, + 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, + 0x0478, 0x000e, 0x080c, 0xb116, 0x1130, 0x2001, 0x4005, 0x2009, + 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd3b6, 0x2900, + 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x3315, 0x012e, 0x9006, 0x080c, + 0x66e6, 0x2001, 0x0002, 0x080c, 0x66fa, 0x2009, 0x0002, 0x080c, + 0xb20a, 0xa8b0, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x9006, + 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x5854, + 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x67b4, + 0x1904, 0x6513, 0x9186, 0x007f, 0x0130, 0x080c, 0x6c11, 0x0118, + 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1059, 0x1120, 0x009e, + 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd109, + 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x651a, 0xa998, + 0xaeb0, 0x080c, 0x67b4, 0x1904, 0x6513, 0x0096, 0x080c, 0x1059, + 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x65d3, 0x2900, 0x009e, + 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, + 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, + 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, + 0x2398, 0x080c, 0x0fd6, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, + 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x5840, 0xd0b4, 0x1118, + 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, + 0x00b0, 0x080c, 0x6c11, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, + 0x5854, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xd0ec, 0x1904, + 0x654f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x651a, 0xa87b, + 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, + 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, + 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8, 0x080c, + 0xb691, 0x1904, 0x654f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, + 0x900e, 0x0804, 0x6550, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, + 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, + 0x2001, 0x0029, 0x900e, 0x0804, 0x6550, 0x2001, 0x0029, 0x900e, + 0x0804, 0x6550, 0x080c, 0x38c0, 0x0804, 0x6551, 0x080c, 0x555d, + 0x0804, 0x6551, 0x080c, 0x46d5, 0x0804, 0x6551, 0x080c, 0x474e, + 0x0804, 0x6551, 0x080c, 0x47aa, 0x0804, 0x6551, 0x080c, 0x4c17, + 0x0804, 0x6551, 0x080c, 0x4edf, 0x0804, 0x6551, 0x080c, 0x51c4, + 0x0804, 0x6551, 0x080c, 0x53bd, 0x0804, 0x6551, 0x080c, 0x3afe, + 0x0804, 0x6551, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, + 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000, 0x2104, + 0x905d, 0x0130, 0x080c, 0x6c11, 0x1138, 0x00d9, 0x9006, 0x00b0, + 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, + 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, + 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, + 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, 0x1904, 0x66da, 0xb888, + 0x9005, 0x1904, 0x66da, 0xb838, 0xb93c, 0x9102, 0x1a04, 0x66da, + 0x2b10, 0x080c, 0xb143, 0x0904, 0x66d6, 0x8108, 0xb93e, 0x6212, + 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, + 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, + 0x05b8, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1560, 0x2011, 0x180d, + 0x2214, 0xd28c, 0x190c, 0x6cd6, 0xa816, 0xa864, 0x9094, 0x00f7, + 0x9296, 0x0011, 0x11f8, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, + 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, + 0x8004, 0x6003, 0x0004, 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, + 0xd0bc, 0x1de8, 0x7833, 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, + 0x00fe, 0x0005, 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x0c38, + 0x2009, 0x180d, 0x210c, 0xd18c, 0x190c, 0x6ce0, 0xd0b4, 0x190c, + 0x1c9c, 0x2001, 0x8004, 0x6003, 0x0002, 0x08e8, 0x81ff, 0x1110, + 0xb88b, 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, + 0x0020, 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, + 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, + 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, + 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, + 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, + 0x0158, 0x080c, 0x6c0d, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, + 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, + 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, + 0x0d85, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, + 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, + 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6c09, 0x1138, + 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, + 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, + 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, + 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, + 0x1059, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, + 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x61b7, 0x9006, + 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, + 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, + 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0568, + 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x108b, 0x00d6, + 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, + 0x2048, 0x080c, 0xcf1b, 0x0110, 0x080c, 0x100b, 0x080c, 0xb16c, + 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, + 0x621c, 0xd2c4, 0x0110, 0x080c, 0x928d, 0x00ce, 0x2b48, 0xb8c8, + 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x109b, 0x00de, 0x9006, 0x002e, + 0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, + 0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, + 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, + 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x779e, 0x1510, + 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0xb094, 0x11d8, 0x0078, + 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1982, 0x7048, 0x2062, + 0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, + 0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, + 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, + 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, + 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, + 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, + 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, + 0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, + 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, + 0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, + 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, + 0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, + 0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, + 0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, + 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, + 0x7054, 0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, + 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, + 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, + 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, + 0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, + 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, + 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, + 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, + 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, + 0x8109, 0x1dd0, 0x080c, 0x0d85, 0x3c00, 0x20e8, 0x3300, 0x8001, + 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, + 0x0060, 0x080c, 0x1059, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, + 0x080c, 0x6a4a, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, + 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, + 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6a59, + 0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, + 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, + 0x00c6, 0xb888, 0x9005, 0x1904, 0x693f, 0xb8d0, 0x904d, 0x0904, + 0x693f, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, + 0x1904, 0x693d, 0x080c, 0xb143, 0x0904, 0x693d, 0x8210, 0xba3e, + 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, + 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, + 0x605e, 0xa880, 0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, + 0xd0ac, 0x01c8, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1558, 0xa816, + 0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x1520, 0x9084, 0x00ff, + 0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, + 0x6003, 0x0004, 0x0030, 0x080c, 0x1c9c, 0x2001, 0x8004, 0x6003, + 0x0002, 0x6046, 0x2001, 0x0010, 0x2c08, 0x080c, 0xaced, 0xb838, + 0xba3c, 0x9202, 0x0a04, 0x68e5, 0x0010, 0xb88b, 0x0001, 0x00ce, + 0x009e, 0x0005, 0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x08f0, + 0x00b6, 0x0096, 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, + 0x67b4, 0x1158, 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, + 0x1118, 0xb800, 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, + 0x694e, 0x001e, 0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, + 0x904d, 0x0188, 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, + 0xa802, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd220, + 0x080c, 0x7012, 0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, + 0xb8d0, 0x904d, 0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, + 0x0128, 0x2940, 0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, + 0x1128, 0xb8d2, 0x9005, 0x1118, 0xb8ce, 0x0008, 0xa002, 0xa803, + 0x0000, 0x008e, 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x0126, + 0x2091, 0x8000, 0x00e6, 0x0096, 0x00c6, 0x0086, 0x0026, 0x2071, + 0x19e8, 0x9046, 0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, + 0x0120, 0x605c, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, + 0xa870, 0x9506, 0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, + 0x0006, 0x0066, 0x2830, 0x080c, 0xa420, 0x006e, 0x000e, 0x83ff, + 0x0508, 0x0c08, 0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, + 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, + 0x9506, 0x0120, 0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, + 0x0026, 0x9906, 0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, + 0x0108, 0x0c10, 0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, + 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, + 0x6aae, 0x0128, 0x080c, 0xcfdc, 0x0010, 0x9085, 0x0001, 0x0005, + 0x080c, 0x6aae, 0x0128, 0x080c, 0xcf7d, 0x0010, 0x9085, 0x0001, + 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xcfd9, 0x0010, 0x9085, + 0x0001, 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xcf9c, 0x0010, + 0x9085, 0x0001, 0x0005, 0x080c, 0x6aae, 0x0128, 0x080c, 0xd01f, + 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, + 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, + 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, + 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, + 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, + 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, + 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, + 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, + 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, + 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, + 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, + 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, + 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x1059, 0x0168, 0x2900, + 0xb8a6, 0x080c, 0x6a4a, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, + 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, + 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, + 0x108b, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, + 0x0005, 0x00b6, 0x00f6, 0x080c, 0x779e, 0x01b0, 0x71c4, 0x81ff, + 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, + 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, + 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, + 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, + 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, + 0x1f04, 0x6ad5, 0x015e, 0x080c, 0x6bcf, 0x0120, 0x2001, 0x1985, + 0x200c, 0x0098, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0190, 0x2009, + 0x07d0, 0x2001, 0x182c, 0x2004, 0x9005, 0x0138, 0x2001, 0x1867, + 0x2004, 0xd0e4, 0x0110, 0x2009, 0x5dc0, 0x2011, 0x6b0c, 0x080c, + 0x8a5d, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6b0c, 0x080c, + 0x8993, 0x080c, 0x6bcf, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, + 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6c0d, 0x0130, 0x2009, 0x07d0, + 0x2011, 0x6b0c, 0x080c, 0x8a5d, 0x00e6, 0x2071, 0x1800, 0x9006, + 0x707e, 0x7060, 0x7082, 0x080c, 0x30bf, 0x00ee, 0x04d0, 0x0156, + 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x67b4, 0x1558, + 0xb800, 0xd0ec, 0x0540, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, + 0x0029, 0x080c, 0xea8d, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, + 0x6c09, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, + 0x0700, 0xb806, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0x97b0, + 0x0076, 0x903e, 0x080c, 0x966d, 0x900e, 0x080c, 0xe75d, 0x007e, + 0x004e, 0x080c, 0xad18, 0x001e, 0x8108, 0x1f04, 0x6b34, 0x00ce, + 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, + 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x0096, 0x080c, 0x1072, + 0x090c, 0x0d85, 0x2958, 0x009e, 0x2001, 0x196b, 0x2b02, 0x8b07, + 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6, 0x908c, 0xffc0, 0xb9ca, + 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c, 0x61b7, 0xb807, 0x0006, + 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f, 0x0200, 0xb86c, 0xb893, + 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff, 0xb8af, 0x0000, 0x00ce, + 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, + 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, + 0x0005, 0x0006, 0x0016, 0x0026, 0xb804, 0x908c, 0x00ff, 0x9196, + 0x0006, 0x0188, 0x9196, 0x0004, 0x0170, 0x9196, 0x0005, 0x0158, + 0x908c, 0xff00, 0x810f, 0x9196, 0x0006, 0x0128, 0x9196, 0x0004, + 0x0110, 0x9196, 0x0005, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, + 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0ec, + 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006, + 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0d85, 0x000e, + 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02, 0x002e, + 0x012e, 0x0005, 0x2011, 0x1837, 0x2204, 0xd0cc, 0x0138, 0x2001, + 0x1983, 0x200c, 0x2011, 0x6bff, 0x080c, 0x8a5d, 0x0005, 0x2011, + 0x6bff, 0x080c, 0x8993, 0x2011, 0x1837, 0x2204, 0xc0cc, 0x2012, + 0x0005, 0x080c, 0x5840, 0xd0ac, 0x0005, 0x080c, 0x5840, 0xd0a4, + 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006, 0x001e, + 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e, 0x0006, + 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xd645, 0x0158, 0x70dc, + 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d, 0x0110, + 0xb8d4, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016, 0x0036, + 0x0046, 0x0076, 0x00b6, 0x2001, 0x1818, 0x203c, 0x9780, 0x348e, + 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008, 0x9284, + 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100, 0x9706, + 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804, 0x9084, + 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c, 0xd0a4, + 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182, 0x0800, + 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be, 0x007e, + 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005, 0x00be, + 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005, 0x0046, + 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080, 0x1000, + 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, + 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1818, 0x203c, 0x9780, + 0x348e, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020, 0x2400, + 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178, 0xb804, + 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4, 0x0130, + 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420, 0x9482, + 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e, 0x005e, + 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be, 0x007e, + 0x005e, 0x004e, 0x9006, 0x0005, 0x0006, 0x2001, 0x00a0, 0x8001, + 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, 0x0006, 0x2001, + 0x00f8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x000e, 0x0005, + 0x0006, 0x2001, 0x00e8, 0x8001, 0xa001, 0xa001, 0xa001, 0x1dd8, + 0x000e, 0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, + 0x9006, 0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, + 0x1922, 0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1948, + 0x900e, 0x710a, 0x080c, 0x5840, 0xd0fc, 0x1140, 0x080c, 0x5840, + 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0470, 0x2001, 0x1867, + 0x200c, 0x9184, 0x0007, 0x0006, 0x2001, 0x180d, 0x2004, 0xd08c, + 0x000e, 0x0108, 0x9006, 0x0002, 0x6d06, 0x6d06, 0x6d06, 0x6d06, + 0x6d06, 0x6d24, 0x6d39, 0x6d47, 0x7003, 0x0003, 0x2009, 0x1868, + 0x210c, 0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, + 0x1110, 0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, + 0x0018, 0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, + 0x2071, 0x1800, 0x70f7, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, + 0x0000, 0x2071, 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, + 0x8007, 0x908c, 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, + 0x8004, 0x2071, 0x1800, 0x908c, 0x0007, 0x0128, 0x70f6, 0x0c20, + 0x704f, 0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, + 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, + 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, + 0x0158, 0x080c, 0x7b28, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, + 0x7006, 0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, + 0x6868, 0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, + 0x7016, 0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, + 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, + 0x702a, 0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, + 0x0005, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, 0x9015, 0x0904, + 0x7017, 0x9286, 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, + 0x6eac, 0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6e07, 0x7140, + 0xa868, 0x9102, 0x0a04, 0x7017, 0xa878, 0xd084, 0x15d8, 0xa853, + 0x0019, 0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, + 0x1904, 0x71c6, 0x0e04, 0x7234, 0x2071, 0x0000, 0xa850, 0x7032, + 0xa84c, 0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, + 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, + 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, + 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0x0804, 0x6e8f, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, + 0xd08c, 0x1904, 0x7017, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, + 0x6dcb, 0x00e6, 0x0026, 0x2071, 0x1948, 0x7000, 0x9015, 0x0904, + 0x7017, 0x9286, 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, + 0x6eac, 0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6e74, 0xa868, + 0xd0fc, 0x1508, 0x00e6, 0x0026, 0x2001, 0x1948, 0x2004, 0x9015, + 0x0904, 0x7017, 0xa978, 0xa874, 0x9105, 0x1904, 0x7017, 0x9286, + 0x0003, 0x0904, 0x6eac, 0x9286, 0x0005, 0x0904, 0x6eac, 0xa87c, + 0xd0bc, 0x1904, 0x7017, 0x2200, 0x0002, 0x7017, 0x6e70, 0x6eac, + 0x6eac, 0x7017, 0x6eac, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, + 0x0026, 0x2009, 0x1948, 0x210c, 0x81ff, 0x0904, 0x7017, 0xa880, + 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7017, 0x9186, 0x0003, + 0x0904, 0x6eac, 0x9186, 0x0005, 0x0904, 0x6eac, 0xa87c, 0xd0cc, + 0x0904, 0x7017, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, + 0xa84f, 0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, + 0x1904, 0x71c6, 0x0e04, 0x7234, 0x2071, 0x0000, 0xa84c, 0x7082, + 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, + 0x1800, 0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x002e, + 0x00ee, 0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, + 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, + 0x6f9d, 0x782c, 0x908c, 0x0780, 0x190c, 0x7382, 0x8004, 0x8004, + 0x8004, 0x9084, 0x0003, 0x0002, 0x6eca, 0x6f9d, 0x6eee, 0x6f3a, + 0x080c, 0x0d85, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, + 0x1168, 0x2071, 0x1a04, 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, + 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, + 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, + 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x0c18, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, + 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, + 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x2071, 0x1a04, 0x7044, 0x9005, + 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, + 0x0804, 0x6ef5, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, + 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, + 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x1d60, + 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x1198, + 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a04, + 0x7044, 0x9005, 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, + 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, + 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, + 0xa804, 0x900d, 0x1168, 0x2071, 0x1a04, 0x7044, 0x9005, 0x1320, + 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x8899, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, + 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, + 0x2148, 0xa804, 0x900d, 0x1904, 0x6ff1, 0x782c, 0x9094, 0x0780, + 0x190c, 0x7382, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, + 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x0d68, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x01b0, 0x00e6, 0x7824, + 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7382, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a04, 0x7044, 0x9005, + 0x1320, 0x2001, 0x1949, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, + 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x8899, 0x00ee, 0x0804, 0x6fad, 0xa868, 0xd0fc, + 0x15e0, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x100b, + 0x009e, 0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, + 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, + 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, + 0x1904, 0x7142, 0x782c, 0x908c, 0x0780, 0x190c, 0x7382, 0x8004, + 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x7046, 0x7142, 0x7061, + 0x70d3, 0x080c, 0x0d85, 0x2009, 0x1948, 0x2104, 0x0002, 0x7026, + 0x7026, 0x7026, 0x6eb5, 0x7026, 0x6eb5, 0x0005, 0x2071, 0x1800, + 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, + 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, + 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, + 0x70c2, 0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, + 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, + 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, + 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, + 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x0e04, + 0x70b9, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, + 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, + 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x1200, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, + 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, + 0x8899, 0x0804, 0x7070, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, + 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, + 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, + 0x1d60, 0x00ee, 0x0e04, 0x7115, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, + 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, + 0x190c, 0x1200, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7382, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, + 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, + 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, + 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, + 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1904, 0x71b1, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, + 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, + 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, + 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x0d50, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x05b8, 0x00e6, 0x7824, + 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, + 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, 0x190c, + 0x7382, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x71aa, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, + 0x2004, 0xd084, 0x190c, 0x1200, 0x704b, 0x0000, 0x00fe, 0x002e, + 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, + 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x8899, 0x00ee, 0x0804, 0x7152, 0x2071, 0x1910, + 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, + 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, + 0x1128, 0x1e04, 0x71f1, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, + 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, + 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x8899, 0x0e04, + 0x71db, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, + 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, + 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, + 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1910, + 0x080c, 0x736e, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, + 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, + 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, + 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, + 0x013e, 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, + 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, + 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, + 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, + 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, + 0x70c2, 0x080c, 0x8899, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, + 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, + 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, + 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, + 0x0002, 0x7281, 0x7282, 0x736d, 0x7282, 0x727f, 0x736d, 0x080c, + 0x0d85, 0x0005, 0x2001, 0x1948, 0x2004, 0x0002, 0x728c, 0x728c, + 0x7306, 0x7307, 0x728c, 0x7307, 0x0126, 0x2091, 0x8000, 0x1e0c, + 0x738d, 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x72d7, + 0x0e04, 0x72b5, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, + 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, + 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x1200, 0x2071, 0x1910, 0x080c, 0x736e, 0x012e, 0x0804, 0x7305, + 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, + 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, + 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, + 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, + 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x7382, 0xd09c, 0x2071, + 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, + 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, + 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, + 0x2071, 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, + 0x2008, 0x2069, 0x1a04, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, + 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b73, 0x210c, + 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, + 0x6838, 0x9106, 0x0190, 0x0e04, 0x7339, 0x2069, 0x0000, 0x6837, + 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, + 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2069, 0x1a04, 0x6847, + 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x73fd, + 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, + 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, + 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, + 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, + 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, + 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, + 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, + 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x108b, 0x0005, + 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x7384, 0x0006, 0x0016, + 0x2001, 0x8004, 0x0006, 0x0804, 0x0d8e, 0x0096, 0x00f6, 0x2079, + 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, + 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, + 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, + 0x1200, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, + 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, + 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, + 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, + 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, + 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, + 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, 0x9094, 0x0780, + 0x190c, 0x7382, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, + 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, + 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00ee, + 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, + 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, + 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, + 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, + 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, + 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, + 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x8899, 0x782c, + 0x9094, 0x0780, 0x190c, 0x7382, 0xd0a4, 0x1d70, 0x00d6, 0x2069, + 0x0050, 0x693c, 0x2069, 0x1948, 0x6808, 0x690a, 0x2069, 0x1a04, + 0x9102, 0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x1949, 0x200c, + 0x6946, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, + 0x1a0c, 0x0d85, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, + 0x080c, 0x2ad3, 0x002e, 0x0005, 0x7542, 0x74af, 0x74cb, 0x74f5, + 0x7531, 0x7571, 0x7583, 0x74cb, 0x7559, 0x746a, 0x7498, 0x751b, + 0x7469, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, + 0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, + 0x7002, 0x080c, 0x78e4, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, + 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x6028, 0x9085, + 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6e, + 0x080c, 0x1b1e, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, + 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, + 0x1160, 0x709b, 0x0029, 0x2069, 0x198f, 0x2d04, 0x7002, 0x080c, + 0x7990, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, + 0x2001, 0x0090, 0x080c, 0x2a99, 0x000e, 0x6124, 0xd1e4, 0x1190, + 0x080c, 0x75f4, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, + 0x709b, 0x0020, 0x080c, 0x75f4, 0x0028, 0x709b, 0x001d, 0x0010, + 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2a99, 0x6124, + 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, + 0x11d8, 0x080c, 0x1b4b, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, + 0x080c, 0x77ca, 0x2001, 0x0080, 0x080c, 0x2a99, 0x709b, 0x0029, + 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, + 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b4b, 0x60e3, + 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x77ca, 0x2001, 0x0080, + 0x080c, 0x2a99, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, + 0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, + 0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, + 0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, + 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, + 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, + 0x0005, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x6124, 0xd1dc, 0x1138, + 0xd1e4, 0x0138, 0x080c, 0x1b4b, 0x709b, 0x001e, 0x0010, 0x709b, + 0x001d, 0x0005, 0x080c, 0x767d, 0x6124, 0xd1dc, 0x1188, 0x080c, + 0x75f4, 0x0016, 0x080c, 0x1b4b, 0x001e, 0xd1d4, 0x1128, 0xd1e4, + 0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x75f4, + 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x000e, 0x6124, + 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, + 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, + 0x0005, 0x080c, 0x767d, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, + 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, + 0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2a99, + 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, + 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, + 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, + 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, + 0x1800, 0x2091, 0x8000, 0x080c, 0x779e, 0x11f8, 0x2001, 0x180c, + 0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, + 0x080c, 0x2ad3, 0x002e, 0x080c, 0x2a7f, 0x6024, 0xd0cc, 0x0148, + 0x2001, 0x00a0, 0x080c, 0x2a99, 0x080c, 0x7ab6, 0x080c, 0x619d, + 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x77b8, 0x0150, + 0x080c, 0x77af, 0x1138, 0x2001, 0x0001, 0x080c, 0x2631, 0x080c, + 0x7772, 0x00a0, 0x080c, 0x767a, 0x0178, 0x2001, 0x0001, 0x080c, + 0x2631, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, + 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, + 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x7605, 0x080c, + 0x8a9f, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x7605, + 0x080c, 0x8a96, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, + 0x080c, 0xa2a0, 0x2071, 0x1800, 0x080c, 0x759e, 0x001e, 0x00fe, + 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x0126, 0x2071, 0x1800, 0x080c, 0xa2a0, 0x2061, 0x0100, + 0x2069, 0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, + 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, + 0xa635, 0x080c, 0xa516, 0x080c, 0x8a4b, 0x0036, 0x901e, 0x080c, + 0xa596, 0x003e, 0x080c, 0xad18, 0x60e3, 0x0000, 0x080c, 0xeed9, + 0x080c, 0xeef4, 0x2009, 0x0004, 0x080c, 0x2a85, 0x080c, 0x299b, + 0x2001, 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2ad3, + 0x2011, 0x7605, 0x080c, 0x8a9f, 0x080c, 0x77b8, 0x0118, 0x9006, + 0x080c, 0x2a99, 0x080c, 0x0bcf, 0x2001, 0x0001, 0x080c, 0x2631, + 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x0005, 0x0026, 0x00e6, 0x2011, 0x7612, 0x2071, 0x1a04, 0x701c, + 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, + 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, + 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2a99, 0x0156, + 0x20a9, 0x002d, 0x1d04, 0x768a, 0x2091, 0x6000, 0x1f04, 0x768a, + 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, + 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, + 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x8aab, 0x0c90, 0x00c6, + 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, + 0x080c, 0x7ac5, 0x2001, 0x196d, 0x2003, 0x0000, 0x9006, 0x709a, + 0x60e2, 0x6886, 0x080c, 0x2700, 0x9006, 0x080c, 0x2a99, 0x080c, + 0x6058, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x002e, 0x602b, + 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, + 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197d, + 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, + 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7762, 0x709b, + 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, + 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, + 0x080c, 0x2700, 0x080c, 0xacfc, 0x0026, 0x080c, 0xafd2, 0x080c, + 0xb09b, 0x002e, 0x080c, 0xad18, 0x7000, 0x908e, 0x0004, 0x0118, + 0x602b, 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, + 0x8000, 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, + 0x080c, 0xd645, 0x0118, 0x9006, 0x080c, 0x2ac3, 0x0804, 0x776e, + 0x6800, 0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a7f, 0x6904, + 0xd1d4, 0x1140, 0x2001, 0x0100, 0x080c, 0x2a99, 0x1f04, 0x7713, + 0x080c, 0x77f2, 0x012e, 0x015e, 0x080c, 0x77af, 0x0170, 0x6044, + 0x9005, 0x0130, 0x080c, 0x77f2, 0x9006, 0x8001, 0x1df0, 0x0028, + 0x6804, 0xd0d4, 0x1110, 0x080c, 0x77f2, 0x080c, 0xd645, 0x0118, + 0x9006, 0x080c, 0x2ac3, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, + 0x0130, 0x2009, 0x00c8, 0x2011, 0x7612, 0x080c, 0x8a5d, 0x002e, + 0x001e, 0x080c, 0x8890, 0x7034, 0xc085, 0x7036, 0x2001, 0x197d, + 0x2003, 0x0004, 0x080c, 0x744d, 0x080c, 0x77af, 0x0138, 0x6804, + 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x7abb, 0x00ee, 0x00de, + 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, + 0x0140, 0x2071, 0x1800, 0x080c, 0x88a7, 0x080c, 0x8899, 0x080c, + 0x7ac5, 0x2001, 0x196d, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, + 0x6886, 0x080c, 0x2700, 0x9006, 0x080c, 0x2a99, 0x6043, 0x0090, + 0x6043, 0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x002e, + 0x602b, 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, + 0x197c, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, + 0x5844, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, + 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, + 0x0006, 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, + 0x0005, 0x0006, 0x080c, 0x5844, 0x9084, 0x0030, 0x9086, 0x0020, + 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, + 0x0013, 0x0168, 0x0020, 0x080c, 0x2720, 0x900e, 0x0010, 0x2009, + 0x0002, 0x2019, 0x0028, 0x080c, 0x32da, 0x9006, 0x0019, 0x001e, + 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, + 0xd63e, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, + 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, + 0x6004, 0x0006, 0x6028, 0x0006, 0x080c, 0x2af6, 0x080c, 0x2b29, + 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, + 0x20a9, 0x0002, 0x080c, 0x2a60, 0x0026, 0x2011, 0x0040, 0x080c, + 0x2ad3, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, + 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, + 0x080c, 0x2700, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd645, 0x000e, + 0x0130, 0x080c, 0x2ab7, 0x9006, 0x080c, 0x2ac3, 0x0010, 0x080c, + 0x2a99, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, + 0x2079, 0x0100, 0x080c, 0x2a0c, 0x00fe, 0x000e, 0x6052, 0x0005, + 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xad5a, 0x0158, + 0x2001, 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, + 0xaced, 0x0804, 0x78d6, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, + 0x6028, 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2ad3, + 0x2001, 0x0090, 0x080c, 0x2a99, 0x20a9, 0x0366, 0x6024, 0xd0cc, + 0x1560, 0x1d04, 0x786e, 0x2091, 0x6000, 0x1f04, 0x786e, 0x080c, + 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, + 0xa635, 0x080c, 0xa516, 0x901e, 0x080c, 0xa596, 0x2001, 0x0386, + 0x2003, 0x7000, 0x080c, 0xad18, 0x2001, 0x00a0, 0x080c, 0x2a99, + 0x080c, 0x7ab6, 0x080c, 0x619d, 0x080c, 0xd645, 0x0110, 0x080c, + 0x0cf1, 0x9085, 0x0001, 0x0804, 0x78dc, 0x080c, 0x1b4b, 0x60e3, + 0x0000, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, + 0x2001, 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x2001, 0x0080, + 0x080c, 0x2a99, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2ad3, + 0x2009, 0x1e00, 0x080c, 0x2a7f, 0x6024, 0x910c, 0x0140, 0x1d04, + 0x78b4, 0x2091, 0x6000, 0x1f04, 0x78b4, 0x0804, 0x7877, 0x2001, + 0x0386, 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, + 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd645, + 0x0110, 0x080c, 0x0cf1, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, + 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, + 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, + 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, + 0x9086, 0x5540, 0x1128, 0x2069, 0x1a7b, 0x2d04, 0x8000, 0x206a, + 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, + 0x1904, 0x794d, 0x2001, 0x0088, 0x080c, 0x2a99, 0x9006, 0x60e2, + 0x6886, 0x080c, 0x2700, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, + 0x6808, 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, + 0x0400, 0x080c, 0x2ad3, 0x2069, 0x198f, 0x7000, 0x206a, 0x709b, + 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x792d, 0x2091, + 0x6000, 0x1f04, 0x792d, 0x0804, 0x7988, 0x2069, 0x0140, 0x20a9, + 0x0384, 0x2011, 0x1e00, 0x080c, 0x2ad3, 0x2009, 0x1e00, 0x080c, + 0x2a7f, 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, + 0x7939, 0x2091, 0x6000, 0x1f04, 0x7939, 0x080c, 0xacfc, 0x2011, + 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, 0xa635, 0x080c, + 0xa516, 0x901e, 0x080c, 0xa596, 0x080c, 0xad18, 0x2001, 0x00a0, + 0x080c, 0x2a99, 0x080c, 0x7ab6, 0x080c, 0x619d, 0x9085, 0x0001, + 0x00f8, 0x080c, 0x1b4b, 0x2001, 0x0080, 0x080c, 0x2a99, 0x2069, + 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, + 0x0008, 0x6886, 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, + 0x1118, 0x2001, 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x9006, + 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, + 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, + 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8, 0x080c, + 0xacfc, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, 0x0002, 0x080c, + 0xa635, 0x080c, 0xa516, 0x901e, 0x080c, 0xa596, 0x080c, 0xad18, + 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2a99, 0x080c, 0x7ab6, + 0x080c, 0x619d, 0x0804, 0x7a32, 0x2001, 0x180c, 0x200c, 0xd1b4, + 0x1160, 0xc1b5, 0x2102, 0x080c, 0x75fa, 0x2069, 0x0140, 0x2001, + 0x0080, 0x080c, 0x2a99, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, + 0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff, + 0x602a, 0x2011, 0x0200, 0x080c, 0x2ad3, 0x2069, 0x198f, 0x7000, + 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x7a32, 0x2011, + 0x1e00, 0x080c, 0x2ad3, 0x2009, 0x1e00, 0x080c, 0x2a7f, 0x6024, + 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x79e7, 0x0006, + 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x88e7, 0x00ee, 0x00de, + 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a04, 0x7078, 0x00ee, + 0x9005, 0x19e8, 0x0438, 0x0026, 0x2011, 0x7612, 0x080c, 0x8993, + 0x2011, 0x7605, 0x080c, 0x8a9f, 0x002e, 0x2069, 0x0140, 0x60e3, + 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, + 0x2001, 0x180d, 0x2004, 0xd08c, 0x2001, 0x0002, 0x1118, 0x2001, + 0x196d, 0x2004, 0x080c, 0x2700, 0x60e2, 0x2001, 0x180c, 0x200c, + 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, + 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, + 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd63e, 0x1904, + 0x7aa0, 0x7130, 0xd184, 0x1170, 0x080c, 0x3482, 0x0138, 0xc18d, + 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, + 0x0904, 0x7aa0, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, + 0x2019, 0x000e, 0x080c, 0xe9f9, 0x0156, 0x00b6, 0x20a9, 0x007f, + 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, + 0x67b4, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, + 0xea8d, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8c44, 0x001e, + 0x8108, 0x1f04, 0x7a69, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, + 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32da, 0x001e, + 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x67b4, + 0x1110, 0x080c, 0x61b7, 0x8108, 0x1f04, 0x7a96, 0x00be, 0x015e, + 0x080c, 0x1b4b, 0x080c, 0xacfc, 0x080c, 0xb09b, 0x080c, 0xad18, + 0x60e3, 0x0000, 0x080c, 0x619d, 0x080c, 0x76cd, 0x00ee, 0x00ce, + 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197d, + 0x2003, 0x0001, 0x0005, 0x2001, 0x197d, 0x2003, 0x0000, 0x0005, + 0x2001, 0x197c, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197c, 0x2003, + 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000, + 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, 0x704e, + 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900, 0x7052, + 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, + 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, + 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, + 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, + 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, + 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, + 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, + 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa, + 0x6807, 0x0001, 0x00de, 0x080c, 0x8103, 0x9006, 0x00ee, 0x0005, + 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04, 0x7b2c, + 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, 0x0002, + 0x7b42, 0x7b43, 0x7b8f, 0x7bea, 0x7d4a, 0x7b40, 0x7b40, 0x7d74, + 0x080c, 0x0d85, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0, 0x2003, + 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x81e5, 0xd0a4, 0x0578, + 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04, 0x7b60, + 0x2001, 0x1a07, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000, 0x2102, + 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, + 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, + 0x0003, 0x1168, 0x7004, 0x0002, 0x7b7f, 0x7b49, 0x7b7f, 0x7b7d, + 0x7b7f, 0x7b7f, 0x7b7f, 0x7b7f, 0x7b7f, 0x080c, 0x7bea, 0x782c, + 0xd09c, 0x090c, 0x8103, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, + 0x003b, 0x0c10, 0x080c, 0x7c20, 0x0c90, 0x00e3, 0x08e8, 0x0005, + 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c42, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c2c, 0x7c20, 0x7e6a, 0x7c20, + 0x7c20, 0x7c20, 0x7c42, 0x7c20, 0x7c2c, 0x7eab, 0x7eec, 0x7f33, + 0x7f47, 0x7c20, 0x7c20, 0x7c42, 0x7c2c, 0x7c56, 0x7c20, 0x7d1e, + 0x7ff2, 0x800d, 0x7c20, 0x7c42, 0x7c20, 0x7c56, 0x7c20, 0x7c20, + 0x7d14, 0x800d, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c20, 0x7c20, 0x7c20, 0x7c6a, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x7c20, 0x8189, 0x7c20, 0x8133, + 0x7c20, 0x8133, 0x7c20, 0x7c7f, 0x7c20, 0x7c20, 0x7c20, 0x7c20, + 0x7c20, 0x7c20, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, + 0x782c, 0x080c, 0x812c, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, + 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, + 0x002b, 0x0c50, 0x00e9, 0x080c, 0x8103, 0x0005, 0x7c20, 0x7c2c, + 0x7e56, 0x7c20, 0x7c2c, 0x7c20, 0x7c2c, 0x7c2c, 0x7c20, 0x7c2c, + 0x7e56, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c2c, 0x7c20, 0x7c2c, + 0x7e56, 0x7c20, 0x7c20, 0x7c2c, 0x7c20, 0x7c20, 0x7c20, 0x7c2c, + 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, + 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, + 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, + 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, + 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, + 0x1120, 0x7007, 0x0001, 0x0804, 0x7df3, 0x7007, 0x0003, 0x7012, + 0x2900, 0x7016, 0x701a, 0x704b, 0x7df3, 0x0005, 0xa864, 0x8007, + 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, + 0x7e0e, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, + 0x7e0e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x7c28, + 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7e2a, 0x7007, 0x0003, + 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7e2a, 0x0005, 0xa864, + 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7c28, 0x7007, + 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1904, 0x7ceb, 0x2001, + 0x180d, 0x2004, 0xd08c, 0x0904, 0x7cd6, 0xa99c, 0x9186, 0x00ff, + 0x05e8, 0xa994, 0x9186, 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, + 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0578, 0x0016, + 0xa998, 0x080c, 0x6c7f, 0x001e, 0x1548, 0x0400, 0x080c, 0x779e, + 0x0140, 0xa897, 0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, + 0x0438, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, 0x01b0, + 0x0016, 0x0026, 0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, + 0x080c, 0x6c7f, 0x003e, 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, + 0xa89b, 0x4009, 0x2001, 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, + 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6430, 0x1108, 0x0005, + 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, + 0x7012, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, 0x7c8f, + 0x9186, 0x0064, 0x0904, 0x7c8f, 0x9186, 0x007c, 0x0904, 0x7c8f, + 0x9186, 0x0028, 0x0904, 0x7c8f, 0x9186, 0x0038, 0x0904, 0x7c8f, + 0x9186, 0x0078, 0x0904, 0x7c8f, 0x9186, 0x005f, 0x0904, 0x7c8f, + 0x9186, 0x0056, 0x0904, 0x7c8f, 0xa897, 0x4005, 0xa89b, 0x0001, + 0x2001, 0x0030, 0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, + 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x8024, 0x2900, 0x7016, + 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, + 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, + 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x7c30, + 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7c30, 0x82ff, 0x1138, 0xa8b8, + 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7db1, 0x0018, 0x9280, 0x7da7, + 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7d92, 0x080c, 0x1072, + 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, + 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, + 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, + 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, + 0x810b, 0xa17e, 0x080c, 0x114e, 0xa06c, 0x908e, 0x0100, 0x0170, + 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, + 0x080c, 0x108b, 0x7014, 0x2048, 0x0804, 0x7c30, 0x7020, 0x2048, + 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, + 0x0804, 0x7d4a, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, + 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x001e, 0x0904, 0x8024, 0x0804, 0x7df3, 0x7da9, + 0x7dad, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, + 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, + 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, + 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, + 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, + 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, + 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, + 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, + 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, + 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, + 0x080c, 0x622f, 0x1108, 0x0005, 0x080c, 0x725e, 0x0126, 0x2091, + 0x8000, 0x080c, 0xd220, 0x080c, 0x7012, 0x012e, 0x0ca0, 0x080c, + 0xd63e, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, + 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, + 0x080c, 0x62bd, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, + 0x080c, 0x7012, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, + 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, + 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6392, 0x1138, 0x0005, + 0x9006, 0xa87a, 0x080c, 0x630a, 0x1108, 0x0005, 0x0126, 0x2091, + 0x8000, 0xa87a, 0xa982, 0x080c, 0x7012, 0x012e, 0x0cb0, 0x2001, + 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, + 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, + 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, + 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, + 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, + 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, + 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, + 0x11d8, 0xa974, 0x080c, 0x67b4, 0x11b8, 0x0066, 0xae80, 0x080c, + 0x68c4, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, + 0x2412, 0x004e, 0x00c6, 0x080c, 0x67b4, 0x1110, 0x080c, 0x6a9e, + 0x8108, 0x1f04, 0x7e93, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, + 0x108b, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, + 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, + 0x080c, 0x6c0d, 0x0580, 0x2061, 0x1a73, 0x6100, 0xd184, 0x0178, + 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, + 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, + 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, + 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, + 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, + 0x012e, 0x0804, 0x80ed, 0x012e, 0x0804, 0x80e7, 0x012e, 0x0804, + 0x80e1, 0x012e, 0x0804, 0x80e4, 0x0126, 0x2091, 0x8000, 0x7007, + 0x0001, 0x080c, 0x6c0d, 0x05e0, 0x2061, 0x1a73, 0x6000, 0xd084, + 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, + 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, + 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, + 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, + 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, + 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, + 0x6206, 0x630a, 0x012e, 0x0804, 0x80ed, 0x012e, 0x0804, 0x80ea, + 0x012e, 0x0804, 0x80e7, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, + 0x2061, 0x1a73, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, + 0x630a, 0x012e, 0x0804, 0x80fb, 0x012e, 0x0804, 0x80ea, 0x00b6, + 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, + 0x0148, 0x00c6, 0x2061, 0x1a73, 0x6000, 0x9084, 0xfcff, 0x6002, + 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, + 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb1a7, 0x0068, + 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, + 0x6162, 0x2009, 0x0041, 0x080c, 0xb20a, 0xa988, 0x918c, 0xff00, + 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, + 0x8c44, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a73, 0x6000, + 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, + 0x00be, 0x0804, 0x80ed, 0x00ce, 0x012e, 0x00be, 0x0804, 0x80e7, + 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, + 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, + 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, + 0x1d10, 0xa974, 0x080c, 0x67b4, 0x1968, 0xb800, 0xc0e4, 0xb802, + 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1986, + 0x2004, 0x601a, 0x0804, 0x7f82, 0xa88c, 0x9065, 0x0960, 0x00e6, + 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, + 0xb1a7, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xb1a7, 0x00ee, 0x0804, + 0x7f82, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, + 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, + 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00ee, + 0x0804, 0x7f82, 0x2061, 0x1a73, 0x6000, 0xd084, 0x0190, 0xd08c, + 0x1904, 0x80fb, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, + 0x6206, 0x012e, 0x0804, 0x80fb, 0x012e, 0xa883, 0x0016, 0x0804, + 0x80f4, 0xa883, 0x0007, 0x0804, 0x80f4, 0xa864, 0x8007, 0x9084, + 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, + 0x080c, 0x7c28, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, + 0x701a, 0x704b, 0x8024, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, + 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x80a6, + 0x6130, 0xd194, 0x1904, 0x80d0, 0xa878, 0x2070, 0x9e82, 0x1ddc, + 0x0a04, 0x809a, 0x6068, 0x9e02, 0x1a04, 0x809a, 0x7120, 0x9186, + 0x0006, 0x1904, 0x808c, 0x7010, 0x905d, 0x0904, 0x80a6, 0xb800, + 0xd0e4, 0x1904, 0x80ca, 0x2061, 0x1a73, 0x6100, 0x9184, 0x0301, + 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x80d3, 0xa883, + 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, + 0xa87c, 0xd0f4, 0x1904, 0x80d6, 0x080c, 0x5840, 0xd09c, 0x1118, + 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8b34, 0x012e, 0x00ee, + 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, + 0xa87c, 0xd0f4, 0x1904, 0x80d6, 0x012e, 0x00ee, 0x00be, 0x0005, + 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x80f4, 0xd184, + 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x67b4, 0x15d0, + 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, + 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, + 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x5844, + 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0, 0x6068, + 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, + 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, + 0x0007, 0x1904, 0x8030, 0x7003, 0x0002, 0x0804, 0x8030, 0xa883, + 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, + 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, + 0x0002, 0x601b, 0x0014, 0x080c, 0xe586, 0x012e, 0x00ee, 0x00be, + 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, + 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, + 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, + 0x7012, 0x012e, 0x0005, 0x080c, 0x108b, 0x0005, 0x00d6, 0x080c, + 0x8b2b, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, + 0x81e5, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, + 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, + 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, + 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, + 0x81e5, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, + 0xb116, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196b, 0x2004, + 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, + 0xa99c, 0x918c, 0x00ff, 0x080c, 0x268c, 0x1540, 0x00b6, 0x080c, + 0x67b4, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, + 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, + 0x0041, 0x080c, 0xb20a, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, + 0x8000, 0x080c, 0x7012, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, + 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x0005, 0xa87b, 0x0028, + 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, + 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, + 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x81d6, 0xa97c, 0x9188, + 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, + 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, + 0xb116, 0x1118, 0x080c, 0xb1dd, 0x05a8, 0x6212, 0xa874, 0x0002, + 0x81b4, 0x81b9, 0x81bc, 0x81c2, 0x2019, 0x0002, 0x080c, 0xe9f9, + 0x0060, 0x080c, 0xe984, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, + 0xe9a3, 0x0018, 0xa980, 0x080c, 0xe984, 0x080c, 0xb16c, 0xa887, + 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x00be, + 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, + 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, + 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, + 0x81e7, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0d8e, + 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, + 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, + 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x1648, 0x00fe, 0x0005, + 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, + 0x781c, 0xd08c, 0x0904, 0x8268, 0x68c0, 0x90aa, 0x0005, 0x0a04, + 0x8890, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d85, 0x9584, 0x00f6, + 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258, 0x9584, + 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, + 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, + 0x9086, 0x8100, 0x11c0, 0x080c, 0xeeb1, 0x080c, 0x8777, 0x7817, + 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x87d3, 0x19c8, + 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x82b8, 0x080c, 0x2185, + 0x005e, 0x004e, 0x0020, 0x080c, 0xeeb1, 0x7817, 0x0140, 0x080c, + 0x779e, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, + 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000, 0x0489, + 0x0005, 0x0002, 0x8275, 0x8585, 0x8272, 0x8272, 0x8272, 0x8272, + 0x8272, 0x8272, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c, 0xff00, + 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, + 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x58aa, 0x0070, + 0x080c, 0x82d8, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x84bf, + 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x86a4, 0x7817, 0x0140, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, + 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, + 0x2518, 0x080c, 0x4ca1, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, + 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, + 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, + 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, + 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, + 0x080c, 0x4ca1, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, + 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, + 0x0120, 0x9096, 0x0023, 0x1904, 0x8490, 0x9186, 0x0023, 0x15c0, + 0x080c, 0x8742, 0x0904, 0x8490, 0x6120, 0x9186, 0x0001, 0x0150, + 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, + 0x1904, 0x8490, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, + 0x2009, 0x0015, 0x080c, 0xb20a, 0x0804, 0x8490, 0x908e, 0x0214, + 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb20a, + 0x0804, 0x8490, 0x908e, 0x0100, 0x1904, 0x8490, 0x7034, 0x9005, + 0x1904, 0x8490, 0x2009, 0x0016, 0x080c, 0xb20a, 0x0804, 0x8490, + 0x9186, 0x0022, 0x1904, 0x8490, 0x7030, 0x908e, 0x0300, 0x1580, + 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, + 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, + 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26d5, 0x7932, + 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x268c, 0x695e, 0x703c, + 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, + 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x0017, 0x0804, 0x8440, + 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8490, 0x080c, + 0x779e, 0x0120, 0x2009, 0x001d, 0x0804, 0x8440, 0x68dc, 0xc0a5, + 0x68de, 0x2009, 0x0030, 0x0804, 0x8440, 0x908e, 0x0500, 0x1140, + 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x0018, 0x0804, 0x8440, + 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x8440, 0x908e, + 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x8440, 0x908e, 0x5200, + 0x1140, 0x7034, 0x9005, 0x1904, 0x8490, 0x2009, 0x001b, 0x0804, + 0x8440, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x8490, + 0x2009, 0x001c, 0x0804, 0x8440, 0x908e, 0x1300, 0x1120, 0x2009, + 0x0034, 0x0804, 0x8440, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, + 0x1904, 0x8490, 0x2009, 0x0024, 0x0804, 0x8440, 0x908c, 0xff00, + 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, + 0xd09c, 0x0904, 0x8440, 0x080c, 0xdd8d, 0x1904, 0x8490, 0x0804, + 0x843e, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, + 0x0804, 0x8440, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, + 0x8440, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, + 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, + 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4ca1, 0x004e, + 0x8108, 0x0f04, 0x83f4, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, + 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, + 0x0804, 0x8440, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, + 0x8440, 0x908e, 0x5400, 0x1138, 0x080c, 0x8840, 0x1904, 0x8490, + 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x8868, + 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, + 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, + 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, + 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, + 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, + 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, + 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, + 0x1904, 0x8493, 0x080c, 0x6749, 0x1904, 0x8493, 0xbe12, 0xbd16, + 0x001e, 0x0016, 0x080c, 0x779e, 0x01c0, 0x68dc, 0xd08c, 0x1148, + 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, + 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, + 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005, 0x1168, + 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, + 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xb116, 0x01a8, + 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, + 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb20a, + 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, + 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4ca1, 0x080c, 0xb1dd, + 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, + 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, + 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, + 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x961e, 0x08a0, 0x080c, + 0x88af, 0x1158, 0x080c, 0x344c, 0x1140, 0x7010, 0x9084, 0xff00, + 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, + 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, + 0x080c, 0x8742, 0x0904, 0x851d, 0x7124, 0x610a, 0x7030, 0x908e, + 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015, 0x080c, + 0xb20a, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005, 0x1568, + 0x2009, 0x0016, 0x080c, 0xb20a, 0x0440, 0x9186, 0x0032, 0x1528, + 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016, 0x2011, + 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x11a8, 0x080c, + 0x6749, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xb116, 0x0168, 0x2b08, + 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, + 0x080c, 0xb20a, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, + 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, + 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, + 0x2009, 0x007f, 0x0804, 0x857f, 0x9596, 0xfffe, 0x1120, 0x2009, + 0x007e, 0x0804, 0x857f, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, + 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, + 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, + 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, + 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, + 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, + 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, + 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x8554, + 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, + 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837, 0x200c, + 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, + 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005, 0x85a7, + 0x85a7, 0x85a7, 0x8754, 0x85a7, 0x85aa, 0x85cf, 0x8658, 0x85a7, + 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x85a7, 0x7817, + 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, + 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868, 0x9c02, + 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, + 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, + 0x0046, 0x080c, 0xb20a, 0x7817, 0x0140, 0x00be, 0x0005, 0x00b6, + 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8634, 0x7110, 0xd1bc, 0x1904, + 0x8634, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, + 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x348e, 0x200d, 0x918c, + 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x8634, 0x9182, + 0x0801, 0x1a04, 0x8634, 0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, + 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294, 0xff00, + 0x9286, 0x0600, 0x1190, 0x080c, 0xb116, 0x0598, 0x2b08, 0x7028, + 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, + 0x7130, 0x615e, 0x080c, 0xe009, 0x00f8, 0x080c, 0x6c11, 0x1138, + 0xb807, 0x0606, 0x0c40, 0x190c, 0x8521, 0x11b0, 0x0880, 0x080c, + 0xb116, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, + 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, + 0x6003, 0x0001, 0x080c, 0x961e, 0x7817, 0x0140, 0x00ce, 0x00be, + 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, + 0x080c, 0x4ca1, 0x080c, 0xb1dd, 0x0d78, 0x2b08, 0x6112, 0x6023, + 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x08e0, + 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84, 0x0003, + 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678, 0x9484, + 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff, 0x6110, + 0x2158, 0xb910, 0x9106, 0x1510, 0x700c, 0xb914, 0x9106, 0x11f0, + 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271, 0x2004, + 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158, 0x0066, + 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e, 0x601c, + 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xb20a, 0x7817, 0x0140, + 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, + 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x88af, 0x1180, 0x080c, + 0x344c, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, + 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, + 0x86be, 0x86bf, 0x86be, 0x86be, 0x8724, 0x8733, 0x0005, 0x00b6, + 0x700c, 0x7108, 0x080c, 0x268c, 0x1904, 0x8722, 0x080c, 0x6749, + 0x1904, 0x8722, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, + 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8722, 0x080c, 0x6c11, + 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6c19, 0x0118, 0x9086, + 0x0004, 0x1588, 0x00c6, 0x080c, 0x8742, 0x00ce, 0x05d8, 0x080c, + 0xb116, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0002, + 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb20a, 0x0458, 0x080c, + 0x6c11, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6c19, 0x0118, + 0x9086, 0x0004, 0x1180, 0x080c, 0xb116, 0x2b08, 0x01d8, 0x6112, + 0x080c, 0xd3b6, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, + 0x080c, 0xb20a, 0x0078, 0x080c, 0xb116, 0x2b08, 0x0158, 0x6112, + 0x080c, 0xd3b6, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, + 0x080c, 0xb20a, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, + 0x0148, 0x080c, 0x869a, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, + 0x080c, 0xb20a, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, + 0x080c, 0x869a, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, + 0xb20a, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158, 0x9c82, + 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, + 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, + 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc, 0x0298, + 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, + 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, + 0x0051, 0x080c, 0xb20a, 0x7817, 0x0140, 0x00be, 0x0005, 0x2031, + 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, + 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, + 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05c0, + 0x080c, 0xb116, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, + 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x1590, 0x080c, 0x6749, + 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, + 0xd3b6, 0x080c, 0x1059, 0x0500, 0x2900, 0x6062, 0x9006, 0xa802, + 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, + 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, + 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, + 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb16c, 0x006e, 0x0cc0, + 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, + 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x882a, 0x9186, 0x0022, + 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x882c, 0x7030, + 0x908e, 0x0400, 0x0904, 0x882c, 0x908e, 0x6000, 0x05e8, 0x908e, + 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837, 0x210c, + 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6bcf, 0x0588, 0x68b0, + 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, + 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, + 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, + 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, + 0x0023, 0x1140, 0x080c, 0x8742, 0x0128, 0x6004, 0x9086, 0x0002, + 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, + 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x027a, 0x080c, 0xc20e, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc20e, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, + 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, + 0x0272, 0x080c, 0xc20e, 0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, + 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc20e, 0x1120, 0xd494, + 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e, 0x0005, + 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, + 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130, 0x2079, + 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, + 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, + 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, + 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x1a04, + 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, + 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa2c0, 0x7032, + 0x7037, 0xa33d, 0x7047, 0xffff, 0x704a, 0x704f, 0x56c4, 0x7052, + 0x7063, 0x8a66, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900, 0x7042, + 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, + 0x1a04, 0x1d04, 0x8982, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, + 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x8b10, 0x2001, + 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, + 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d85, 0x700f, + 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069, 0x1800, + 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x8ad4, 0x0010, + 0x080c, 0x8aab, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, + 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, + 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, + 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, + 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, + 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, + 0x090c, 0xa3eb, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, + 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, + 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, + 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, + 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, + 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, + 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, + 0x080f, 0x012e, 0x7004, 0x0002, 0x89aa, 0x89ab, 0x89d5, 0x00e6, + 0x2071, 0x1a04, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, + 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a04, 0x701c, + 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, + 0x0005, 0x00e6, 0x2071, 0x1a04, 0xb888, 0x9102, 0x0208, 0xb98a, + 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110, 0x080c, + 0x67b4, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180, 0x0126, + 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026, 0xba3c, + 0x0016, 0x080c, 0x68df, 0x001e, 0x002e, 0x006e, 0x012e, 0x8108, + 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00, 0x900e, + 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010, 0x7014, + 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128, 0x8001, + 0x604a, 0x1110, 0x080c, 0xd237, 0x6018, 0x9005, 0x0904, 0x8a2d, + 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x8a40, 0x781b, + 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000, 0x0804, + 0x8a40, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001, 0x7918, + 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186, 0x0003, + 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, + 0xd1c4, 0x1100, 0x080c, 0xcf1b, 0x01b0, 0x6014, 0x2048, 0xa884, + 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, + 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, + 0x080c, 0xd671, 0x0110, 0x080c, 0xcbd9, 0x012e, 0x9c88, 0x001c, + 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631, 0x0138, + 0x2160, 0x0804, 0x89d9, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x0005, + 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a04, 0x7027, 0x07d0, 0x7023, + 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0d, 0x2003, 0x0000, 0x0005, + 0x00e6, 0x2071, 0x1a04, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, + 0x2011, 0x1a10, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1a04, + 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, + 0x705c, 0x8000, 0x705e, 0x2001, 0x1a14, 0x2044, 0xa06c, 0x9086, + 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, + 0x7064, 0xa08e, 0x080c, 0x114e, 0x002e, 0x008e, 0x0005, 0x0006, + 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, + 0x0156, 0x080c, 0x88e7, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, + 0x1a04, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, + 0x0006, 0x2071, 0x1a04, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, + 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69ec, 0xd1e4, 0x1518, + 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, + 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, + 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, + 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205, 0x68ee, + 0x080c, 0x0f24, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f, 0x05b8, + 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202, 0x0220, + 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd, 0x2110, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x0400, 0x69ea, + 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001, 0x8007, + 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004, 0x9084, + 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040, 0x2010, + 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x002e, 0x0005, + 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, + 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, + 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, + 0x1a73, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, + 0x9080, 0x1a73, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, + 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a73, 0x6014, 0x00ce, 0x9005, + 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, + 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, + 0x00c0, 0x0904, 0x8bee, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8bc7, + 0x2009, 0x0006, 0x080c, 0x8c1b, 0x0005, 0x900e, 0x0c60, 0x2001, + 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568, 0x87ff, + 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500, 0x1520, + 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c, 0xd184, + 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035, 0x080c, + 0x1c6f, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6, 0x2079, + 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00, 0x7836, + 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120, 0x918e, + 0x0003, 0x1904, 0x8c15, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, + 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, + 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb20a, 0x0005, 0x87ff, + 0x1de8, 0x2009, 0x0042, 0x0804, 0xb20a, 0x6110, 0x00b6, 0x2158, + 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, + 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, + 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8c15, + 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, + 0x080c, 0x17ad, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, + 0x080c, 0xb20a, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, + 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, + 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xb20a, + 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, + 0xb20a, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, + 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, + 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcf1b, 0x0518, 0x6014, + 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, + 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a73, + 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, + 0x080c, 0x6e4c, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, + 0x8b34, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a73, + 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, + 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, + 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1924, 0x7003, + 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c, + 0x1072, 0x090c, 0x0d85, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, + 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, + 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1924, 0x702c, + 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0xa896, + 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, + 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c, 0x8001, + 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92, 0x7010, + 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000, 0x0006, + 0x2009, 0x1b73, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e, 0xc095, + 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16b9, 0x9006, 0x2071, + 0x193d, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e, 0x0005, + 0x2009, 0x1b73, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005, 0x00e6, + 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154, 0x2001, + 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006, 0x9080, + 0x0008, 0x1f04, 0x8cd7, 0x71c0, 0x9102, 0x02e0, 0x2071, 0x1877, + 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb116, 0x6023, 0x0009, 0x6003, + 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000, 0x080c, + 0x8e58, 0x012e, 0x1f04, 0x8ce3, 0x9006, 0x00ce, 0x015e, 0x012e, + 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6, 0x0096, + 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620, 0x7004, + 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, + 0x002c, 0x2029, 0x000a, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, + 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a, 0xa87a, + 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a, 0x7010, + 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109, 0x0160, + 0x080c, 0x1059, 0x090c, 0x0d85, 0xad66, 0x2b00, 0xa802, 0x2900, + 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e, 0x008e, + 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071, 0x1924, + 0x7004, 0x004b, 0x700c, 0x0002, 0x8d4f, 0x8d48, 0x8d48, 0x0005, + 0x8d59, 0x8daf, 0x8daf, 0x8daf, 0x8db0, 0x8dc1, 0x8dc1, 0x700c, + 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106, 0x1904, + 0x8da1, 0x7814, 0xd0bc, 0x1904, 0x8daa, 0x012e, 0x7018, 0x910a, + 0x1128, 0x7030, 0x9005, 0x1904, 0x8df3, 0x0005, 0x1210, 0x7114, + 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001, 0x1888, + 0x2014, 0x2001, 0x1936, 0x2004, 0x9100, 0x9202, 0x0e50, 0x080c, + 0x8f53, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c, 0x2048, + 0xa873, 0x0001, 0xa976, 0x080c, 0x905c, 0x2100, 0xa87e, 0xa86f, + 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a24, 0x2104, + 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x116d, 0x1de8, + 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8d61, 0x080c, 0x8f2b, + 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8d61, 0x0005, + 0x700c, 0x0002, 0x8db5, 0x8db8, 0x8db7, 0x080c, 0x8d57, 0x0005, + 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e, 0x0011, + 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100, 0x7214, + 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006, 0x0068, + 0x0006, 0x080c, 0x905c, 0x2100, 0xaa8c, 0x9210, 0xaa8e, 0x1220, + 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126, 0x2091, + 0x8000, 0x78a2, 0x701a, 0x080c, 0x8f2b, 0x012e, 0x0005, 0x00e6, + 0x2071, 0x1924, 0x700c, 0x0002, 0x8df1, 0x8df1, 0x8def, 0x700f, + 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030, 0x9005, + 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059, 0x0000, + 0x080c, 0x8e61, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193d, 0x080c, + 0x8ea8, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1072, 0x2900, 0x009e, + 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1947, 0x2003, 0x0000, + 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086, 0x00a6, + 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084, 0x000f, + 0x2068, 0x9d88, 0x1ec1, 0x2165, 0x0056, 0x2029, 0x0000, 0x080c, + 0x8fe1, 0x080c, 0x1e97, 0x1dd8, 0x005e, 0x00ae, 0x2001, 0x187f, + 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17ad, 0x00ce, 0x781f, + 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8eb7, + 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, + 0x2078, 0x780c, 0x7032, 0x2001, 0x1947, 0x2003, 0x0001, 0x0005, + 0x00e6, 0x2071, 0x1924, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, + 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x912a, 0x2005, 0x906d, + 0x090c, 0x0d85, 0x9b80, 0x9122, 0x2005, 0x9065, 0x090c, 0x0d85, + 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, + 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, + 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, + 0x4ca1, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa804, 0x8000, + 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, + 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4ca1, 0x684c, 0x0096, + 0x904d, 0x090c, 0x0d85, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, + 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, + 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, + 0x7814, 0x9005, 0x090c, 0x0d85, 0x781c, 0x9084, 0x0101, 0x9086, + 0x0101, 0x190c, 0x0d85, 0x7827, 0x0000, 0x2069, 0x193d, 0x6804, + 0x9080, 0x193f, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, + 0x0208, 0x900e, 0x6906, 0x9180, 0x193f, 0x2003, 0x0000, 0x00de, + 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, + 0x2048, 0x9005, 0x190c, 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, + 0x100b, 0x080c, 0xb16c, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, + 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, + 0x0150, 0x00b6, 0x2058, 0x080c, 0x925e, 0x00be, 0x6013, 0x0000, + 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1928, + 0x210c, 0xd194, 0x0005, 0x2009, 0x1928, 0x210c, 0xd1c4, 0x0005, + 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1924, 0x7110, 0xc194, + 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16b9, + 0x00ee, 0x012e, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, + 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, + 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, + 0x080c, 0x90aa, 0x0170, 0x080c, 0x90df, 0x0158, 0x2900, 0x7002, + 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, + 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, + 0x2071, 0x1931, 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x90df, + 0x090c, 0x0d85, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, + 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, + 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, + 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, 0x721c, + 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, + 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, + 0x2071, 0x1931, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, + 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x905c, + 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, + 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, + 0xa001, 0x4005, 0x2508, 0x080c, 0x9065, 0x2130, 0x7014, 0x9600, + 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, + 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, + 0x2009, 0x0001, 0x0026, 0x080c, 0x8f53, 0x002e, 0x7000, 0x2048, + 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, + 0x1904, 0x8f92, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, + 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, + 0x9122, 0x2005, 0x9075, 0x090c, 0x0d85, 0x080c, 0x9037, 0x012e, + 0x9580, 0x911e, 0x2005, 0x9075, 0x090c, 0x0d85, 0x0156, 0x0136, + 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, + 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, + 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, + 0x0002, 0x9021, 0x9021, 0x9023, 0x9021, 0x9023, 0x9021, 0x9021, + 0x9021, 0x9021, 0x9021, 0x9029, 0x9021, 0x9029, 0x9021, 0x9021, + 0x9021, 0x080c, 0x0d85, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, + 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, + 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, + 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, + 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, + 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x90ee, 0x009e, 0xa807, + 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, + 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, + 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, + 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, + 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, + 0x90b8, 0x0008, 0x2031, 0x90a8, 0x901e, 0x6808, 0x9005, 0x0108, + 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, + 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, + 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, + 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, + 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, + 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, + 0x9080, 0x9126, 0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, 0x90a0, + 0x000a, 0x080c, 0x1072, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, + 0xa807, 0x0000, 0x080c, 0x1072, 0x0188, 0x7024, 0xa802, 0xa807, + 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, + 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, + 0x0dc8, 0x2048, 0xac00, 0x080c, 0x108b, 0x2400, 0x0cc0, 0x0126, + 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, + 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, + 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, + 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, + 0x080c, 0x108b, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, + 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x108b, 0x000e, + 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, + 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a71, 0x0000, + 0x0000, 0x0000, 0x1931, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, + 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, + 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x924a, + 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x921f, 0xb814, 0xa06e, + 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, + 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, + 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, + 0x0d85, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, + 0x000f, 0x91e0, 0x1ec1, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, + 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x918a, + 0x918a, 0x918c, 0x918a, 0x918a, 0x918a, 0x918e, 0x918a, 0x918a, + 0x918a, 0x9190, 0x918a, 0x918a, 0x918a, 0x9192, 0x918a, 0x918a, + 0x918a, 0x9194, 0x918a, 0x918a, 0x918a, 0x9196, 0x918a, 0x918a, + 0x918a, 0x9198, 0x080c, 0x0d85, 0xa180, 0x04b8, 0xa190, 0x04a8, + 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, + 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, + 0x0002, 0x91bc, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91be, + 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91ba, 0x91c0, 0x91ba, 0x91ba, + 0x91ba, 0x91ba, 0x91ba, 0x91c2, 0x91ba, 0x91ba, 0x91ba, 0x91ba, + 0x91ba, 0x91c4, 0x080c, 0x0d85, 0xa180, 0x0038, 0xa198, 0x0028, + 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x91e0, + 0x91e2, 0x91e4, 0x91e6, 0x91e8, 0x91ea, 0x91ec, 0x91ee, 0x91f0, + 0x91f2, 0x91f4, 0x91f6, 0x91f8, 0x91fa, 0x91fc, 0x91fe, 0x9200, + 0x9202, 0x9204, 0x9206, 0x9208, 0x920a, 0x920c, 0x920e, 0x9210, + 0x080c, 0x0d85, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, + 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, + 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, + 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, + 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, + 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, + 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x1e97, 0x090c, 0x0d85, + 0x0804, 0x9164, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, + 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x9146, + 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, + 0x2001, 0x1925, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, + 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, + 0x2011, 0x8014, 0x080c, 0x4ca1, 0x004e, 0x003e, 0x00be, 0x001e, + 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, + 0x9005, 0x0120, 0x8210, 0x910a, 0x0230, 0x0128, 0x7010, 0x8210, + 0x910a, 0x0208, 0x1de0, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, + 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, + 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, + 0x906d, 0x0198, 0x2079, 0x0000, 0x9c1e, 0x1118, 0x680c, 0xb8ae, + 0x0050, 0x9c06, 0x0130, 0x2d78, 0x680c, 0x906d, 0x1dd0, 0x080c, + 0x0d85, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, + 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, + 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, + 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, + 0x929a, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, + 0xb8ac, 0x9065, 0x01f0, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, + 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, + 0x6014, 0x904d, 0x090c, 0x0d85, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, + 0x0000, 0x904d, 0x090c, 0x0d85, 0x080c, 0x108b, 0x080c, 0x8e58, + 0x08f8, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, + 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, + 0x0006, 0x0156, 0x080c, 0x268c, 0x015e, 0x11b0, 0x080c, 0x6749, + 0x190c, 0x0d85, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb116, + 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, + 0xb20a, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, + 0x9310, 0x9310, 0x9310, 0x9312, 0x935b, 0x9310, 0x9310, 0x9310, + 0x93d5, 0x9310, 0x940d, 0x9310, 0x9310, 0x9310, 0x9310, 0x9310, + 0x080c, 0x0d85, 0x9182, 0x0040, 0x0002, 0x9325, 0x9325, 0x9325, + 0x9325, 0x9325, 0x9325, 0x9325, 0x9325, 0x9325, 0x9327, 0x9338, + 0x9325, 0x9325, 0x9325, 0x9325, 0x9349, 0x080c, 0x0d85, 0x0096, + 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, + 0x0500, 0x00be, 0x080c, 0x6e11, 0x080c, 0xb16c, 0x009e, 0x0005, + 0x080c, 0x9a48, 0x00d6, 0x6114, 0x080c, 0xcf1b, 0x0130, 0x0096, + 0x6114, 0x2148, 0x080c, 0x7012, 0x009e, 0x00de, 0x080c, 0xb16c, + 0x0005, 0x080c, 0x9a48, 0x080c, 0x3315, 0x6114, 0x0096, 0x2148, + 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0029, 0x080c, 0x7012, 0x009e, + 0x080c, 0xb16c, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, + 0x0002, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, 0x9376, + 0x9376, 0x9378, 0x9376, 0x9376, 0x9376, 0x93d1, 0x9376, 0x9376, + 0x9376, 0x9376, 0x9376, 0x9376, 0x937f, 0x9376, 0x080c, 0x0d85, + 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x93d1, 0x6024, + 0xd08c, 0x15d8, 0x080c, 0x8f0e, 0x05e0, 0x00e6, 0x6114, 0x2148, + 0x080c, 0x912e, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6da9, 0x009e, + 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, + 0x925e, 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8e61, + 0x00be, 0x01e0, 0x2071, 0x193d, 0x080c, 0x8ea8, 0x01b8, 0x9086, + 0x0001, 0x1128, 0x2001, 0x1947, 0x2004, 0x9005, 0x1178, 0x0096, + 0x080c, 0x1059, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, + 0x080c, 0x8e1c, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8e58, + 0x0cd0, 0x080c, 0x8f13, 0x1160, 0x6010, 0x9005, 0x0130, 0x2058, + 0xb8ac, 0x9005, 0x190c, 0x0d85, 0x6012, 0x2c00, 0x080c, 0x8ed9, + 0x0005, 0x080c, 0x9489, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, + 0x0002, 0x93e9, 0x93e9, 0x93e9, 0x93eb, 0x93e9, 0x93e9, 0x93e9, + 0x940b, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, 0x93e9, + 0x93e9, 0x080c, 0x0d85, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, + 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, + 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, + 0x8213, 0x9210, 0x621a, 0x080c, 0x1c26, 0x2009, 0x8030, 0x080c, + 0x965e, 0x009e, 0x0005, 0x080c, 0x0d85, 0x080c, 0x9a48, 0x6114, + 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, + 0x00be, 0x080c, 0x7012, 0x080c, 0xb16c, 0x009e, 0x0005, 0x080c, + 0xacfc, 0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x0096, 0x0023, 0x009e, + 0x080c, 0xad18, 0x0005, 0x9443, 0x9443, 0x9443, 0x9445, 0x9456, + 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, 0x9443, + 0x9443, 0x9443, 0x9443, 0x080c, 0x0d85, 0x080c, 0xaee3, 0x6114, + 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, + 0x00be, 0x080c, 0x7012, 0x080c, 0xb16c, 0x0005, 0x0491, 0x0005, + 0x080c, 0xacfc, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, + 0x6003, 0x0003, 0x2009, 0x0003, 0x908a, 0x0010, 0x1a0c, 0x0d85, + 0x0096, 0x0033, 0x009e, 0x0106, 0x080c, 0xad18, 0x010e, 0x0005, + 0x9480, 0x9480, 0x9480, 0x9482, 0x9489, 0x9480, 0x9480, 0x9480, + 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, 0x9480, + 0x080c, 0x0d85, 0x0036, 0x00e6, 0x080c, 0xaee3, 0x00ee, 0x003e, + 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, + 0x6014, 0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, + 0x925e, 0x00be, 0x2071, 0x193d, 0x080c, 0x8ea8, 0x0160, 0x2001, + 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8e1c, + 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, + 0x080c, 0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8e58, 0x0c80, + 0x2001, 0x1925, 0x200c, 0x918e, 0x0000, 0x190c, 0x8f0e, 0x05c8, + 0x00e6, 0x2071, 0x1924, 0x7110, 0xc1c5, 0x7112, 0x080c, 0x8f18, + 0x00f6, 0x00c6, 0x2071, 0x1000, 0x00b6, 0x2e04, 0x905d, 0x0138, + 0xb8ac, 0x9065, 0x0120, 0x080c, 0x8eee, 0x090c, 0x928d, 0x8e70, + 0x9e86, 0x1800, 0x1d90, 0x00be, 0x00d6, 0x0096, 0x0046, 0x2061, + 0x1ddc, 0x2001, 0x181a, 0x2024, 0x6020, 0x9086, 0x0000, 0x1191, + 0x9ce0, 0x001c, 0x2400, 0x9c06, 0x1db8, 0x004e, 0x009e, 0x00de, + 0x00d1, 0x00ce, 0x00fe, 0x2071, 0x1924, 0x7110, 0xc1c4, 0x7112, + 0x00ee, 0x0005, 0x6020, 0x9086, 0x0009, 0x1160, 0x6100, 0x9186, + 0x0004, 0x1138, 0x6110, 0x81ff, 0x190c, 0x0d85, 0x2c00, 0x080c, + 0x8ed9, 0x9006, 0x0005, 0x2071, 0x193f, 0x2073, 0x0000, 0x8e70, + 0x9e86, 0x1947, 0x1dd0, 0x2071, 0x193d, 0x7006, 0x7002, 0x2001, + 0x1930, 0x2064, 0x8cff, 0x0130, 0x6120, 0x918e, 0x0000, 0x190c, + 0x0d85, 0x2102, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0148, 0x0096, + 0x2148, 0x080c, 0x108b, 0x009e, 0x2001, 0x188a, 0x2003, 0x0000, + 0x2071, 0x1931, 0x080c, 0x90f7, 0x0804, 0x9106, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x187a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126, 0x2091, + 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004, 0x8086, + 0x818e, 0x1208, 0x9200, 0x1f04, 0x954f, 0x8086, 0x818e, 0x004e, + 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156, + 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213, 0x818d, + 0x0228, 0x911a, 0x1220, 0x1f04, 0x9566, 0x0028, 0x911a, 0x2308, + 0x8210, 0x1f04, 0x9566, 0x0006, 0x3200, 0x9084, 0xefff, 0x2080, + 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200, 0x9085, + 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e8, 0x012e, + 0x00d6, 0x2069, 0x19e8, 0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, + 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xaaf1, 0x04c9, 0x080c, + 0xaadc, 0x04b1, 0x080c, 0xaadf, 0x0499, 0x080c, 0xaae2, 0x0481, + 0x080c, 0xaae5, 0x0469, 0x080c, 0xaae8, 0x0451, 0x080c, 0xaaeb, + 0x0439, 0x080c, 0xaaee, 0x0421, 0x01de, 0x014e, 0x015e, 0x6857, + 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003, 0x7803, + 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084, 0xfffe, + 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084, 0xfffc, + 0x682a, 0x00fe, 0x2001, 0x1b5d, 0x2003, 0x0000, 0x00de, 0x0005, + 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005, + 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b, 0x0400, + 0x7827, 0x0031, 0x782b, 0x1af6, 0x781f, 0xff00, 0x781b, 0xff00, + 0x2061, 0x1aeb, 0x602f, 0x19e8, 0x6033, 0x1800, 0x6037, 0x1a04, + 0x603b, 0x1ec1, 0x603f, 0x1ed1, 0x6042, 0x6047, 0x1ac1, 0x00ce, + 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, + 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e8, + 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080, 0x0003, + 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8, 0x6146, + 0x2c08, 0x2001, 0x0012, 0x080c, 0xaced, 0x0005, 0x0016, 0x2009, + 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, + 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaced, 0x0088, + 0x00c6, 0x2061, 0x19e8, 0x602c, 0x8000, 0x602e, 0x600c, 0x9005, + 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112, 0x610e, + 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, + 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, + 0x2061, 0x19e8, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, + 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146, 0x600f, + 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaced, 0x0005, 0x6044, + 0xd0dc, 0x0110, 0x080c, 0xa78a, 0x0005, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026, + 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e8, 0x7648, 0x2660, + 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x96f1, 0x9c86, 0x1b55, + 0x0904, 0x96ec, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x96ec, + 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x96ec, 0x704c, 0x9c06, + 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x703f, 0x0000, + 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xaff4, 0x003e, + 0x2029, 0x0001, 0x080c, 0x9667, 0x7048, 0x9c36, 0x1110, 0x660c, + 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xcf1b, + 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588, 0x6004, + 0x9086, 0x0040, 0x090c, 0xa78a, 0xa867, 0x0103, 0xab7a, 0xa877, + 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd220, 0x080c, 0xeddf, + 0x080c, 0x7012, 0x007e, 0x003e, 0x001e, 0x080c, 0xd10c, 0x080c, + 0xb1a7, 0x00ce, 0x0804, 0x9683, 0x2c78, 0x600c, 0x2060, 0x0804, + 0x9683, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, + 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, + 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, + 0xeddf, 0x080c, 0xea30, 0x007e, 0x003e, 0x001e, 0x08c0, 0x6020, + 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, + 0x080c, 0x7012, 0x080c, 0xb16c, 0x007e, 0x003e, 0x001e, 0x0848, + 0x6020, 0x9086, 0x000a, 0x0904, 0x96d6, 0x0804, 0x96cf, 0x0006, + 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, + 0x8000, 0x2079, 0x19e8, 0x7848, 0x9065, 0x0904, 0x9790, 0x600c, + 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036, 0x2019, + 0x0001, 0x080c, 0xa596, 0x783f, 0x0000, 0x901e, 0x7b4e, 0x7b6a, + 0x7b52, 0x7b6e, 0x080c, 0xaff4, 0x003e, 0x000e, 0x9005, 0x1118, + 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b55, 0x05b0, 0x00e6, + 0x2f70, 0x080c, 0x9667, 0x00ee, 0x080c, 0xcf1b, 0x0548, 0x6014, + 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e, 0x0002, + 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1988, 0x2004, + 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa78a, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7006, 0x080c, 0xd10c, + 0x6044, 0xc0fc, 0x6046, 0x080c, 0xb1a7, 0x000e, 0x0804, 0x9734, + 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, + 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xea30, + 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x7012, + 0x080c, 0xb16c, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990, 0x0850, + 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x98a3, 0x008e, + 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e8, 0x2091, + 0x8000, 0x080c, 0x98ec, 0x080c, 0x9982, 0x080c, 0x6948, 0x012e, + 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, + 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, + 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9868, 0x6010, 0x2058, + 0xb8a0, 0x9206, 0x1904, 0x9863, 0x88ff, 0x0120, 0x605c, 0x9106, + 0x1904, 0x9863, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, + 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8a4b, 0x080c, 0xa2a0, + 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad, 0x700a, + 0x6003, 0x0009, 0x630a, 0x0804, 0x9863, 0x7020, 0x9c36, 0x1110, + 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, + 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6044, + 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x01e8, 0x6020, + 0x9086, 0x0003, 0x1580, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, + 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, + 0x0086, 0x080c, 0xd220, 0x080c, 0xeddf, 0x080c, 0x7012, 0x008e, + 0x003e, 0x001e, 0x080c, 0xd10c, 0x080c, 0xb1a7, 0x080c, 0xa65d, + 0x00ce, 0x0804, 0x97db, 0x2c78, 0x600c, 0x2060, 0x0804, 0x97db, + 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, + 0x0036, 0x0086, 0x080c, 0xeddf, 0x080c, 0xea30, 0x008e, 0x003e, + 0x001e, 0x08d0, 0x080c, 0xbb5c, 0x6020, 0x9086, 0x0002, 0x1160, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x9849, 0x9086, + 0x008b, 0x0904, 0x9849, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, + 0x09b0, 0x0804, 0x985c, 0x0006, 0x00f6, 0x00e6, 0x0096, 0x00b6, + 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, + 0x2004, 0x905d, 0x2079, 0x19e8, 0x9036, 0x7828, 0x2060, 0x8cff, + 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c, 0xaf2e, + 0x01d8, 0x610c, 0x0016, 0x080c, 0xa420, 0x6014, 0x2048, 0xa867, + 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, + 0xd220, 0x080c, 0xeddf, 0x080c, 0x7012, 0x008e, 0x003e, 0x001e, + 0x080c, 0xb1a7, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060, 0x08b8, + 0x080c, 0x6965, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be, 0x009e, + 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, + 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x9955, 0x600c, 0x0006, + 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06, 0x1598, + 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, + 0x8a4b, 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7833, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0058, + 0x080c, 0x6ba9, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808, 0xc0ad, + 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcf19, 0x01b0, + 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd132, 0x1118, 0x080c, + 0xbb5c, 0x0060, 0x080c, 0x6ba9, 0x1168, 0xa867, 0x0103, 0xab7a, + 0xa877, 0x0000, 0x080c, 0x7012, 0x080c, 0xd10c, 0x080c, 0xb1a7, + 0x080c, 0xa65d, 0x000e, 0x0804, 0x98f3, 0x7e22, 0x7e1e, 0x00de, + 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, + 0x1118, 0x080c, 0xea30, 0x0c50, 0x080c, 0xbb5c, 0x6020, 0x9086, + 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, + 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, + 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, + 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066, 0x9036, + 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006, 0x3e08, + 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043, 0xffff, + 0x080c, 0xaf2e, 0x0180, 0x610c, 0x080c, 0xa420, 0x6014, 0x2048, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7012, 0x080c, + 0xb1a7, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce, 0x00be, + 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0x080c, + 0x62af, 0x11b0, 0x2071, 0x19e8, 0x7030, 0x9080, 0x0005, 0x2004, + 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e8, 0x7030, + 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108, 0x0029, + 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660, 0x6043, + 0xffff, 0x080c, 0xaf2e, 0x0178, 0x080c, 0xa420, 0x6014, 0x2048, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xd220, 0x080c, + 0x7012, 0x080c, 0xb1a7, 0x00ce, 0x0005, 0x00b6, 0x00e6, 0x00c6, + 0x080c, 0xacfc, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4, 0x2072, + 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xad18, 0x00ce, 0x00ee, + 0x00be, 0x0005, 0x2071, 0x19e8, 0x7030, 0x9005, 0x0da0, 0x9c06, + 0x190c, 0x0d85, 0x7036, 0x080c, 0x8a4b, 0x7004, 0x9084, 0x0007, + 0x0002, 0x9a1b, 0x9a1d, 0x9a24, 0x9a2e, 0x9a3c, 0x9a1b, 0x9a29, + 0x9a19, 0x080c, 0x0d85, 0x0428, 0x0005, 0x080c, 0xaf19, 0x7007, + 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c, 0xa420, + 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c, 0xaf04, + 0x0140, 0x080c, 0xaf19, 0x0128, 0x0066, 0x9036, 0x080c, 0xa420, + 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xaf04, 0x080c, 0xa78a, + 0x0000, 0x010e, 0x090c, 0xad18, 0x00ce, 0x00ee, 0x00be, 0x0005, + 0x00d6, 0x00c6, 0x080c, 0xacfc, 0x0106, 0x6044, 0xd0fc, 0x1130, + 0x010e, 0x090c, 0xad18, 0x00ce, 0x00de, 0x0005, 0x2069, 0x19e8, + 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d85, 0x6852, 0x00e6, + 0x2d70, 0x080c, 0x9667, 0x00ee, 0x080c, 0x8a58, 0x0016, 0x2009, + 0x0040, 0x080c, 0x2220, 0x001e, 0x683c, 0x9084, 0x0003, 0x0002, + 0x9a76, 0x9a77, 0x9a96, 0x9a74, 0x080c, 0x0d85, 0x0490, 0x6868, + 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a, 0x600f, + 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, + 0x683f, 0x0000, 0x00f0, 0x684a, 0x6846, 0x0c98, 0x686b, 0x0000, + 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x6044, 0x9084, + 0x7f7f, 0x6046, 0x9006, 0x6842, 0x684e, 0x686a, 0x6852, 0x686e, + 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f, 0x0000, 0x0010, 0x684a, + 0x6846, 0x080c, 0xaff4, 0x684f, 0x0000, 0x010e, 0x090c, 0xad18, + 0x00ce, 0x00de, 0x0005, 0x0005, 0x6020, 0x9084, 0x000f, 0x000b, + 0x0005, 0x9ac9, 0x9acc, 0x9f80, 0xa019, 0x9acc, 0x9f80, 0xa019, + 0x9ac9, 0x9acc, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, 0x9ac9, + 0x9ac9, 0x080c, 0x99ed, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, + 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, + 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x6110, + 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, + 0x1a04, 0x9b38, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, + 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9ce1, 0x9d1c, + 0x9d45, 0x9e0f, 0x9e31, 0x9e37, 0x9e44, 0x9e4c, 0x9e58, 0x9e5e, + 0x9e6f, 0x9e5e, 0x9ec7, 0x9e4c, 0x9ed3, 0x9ed9, 0x9e58, 0x9ed9, + 0x9ee5, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0x9b36, + 0x9b36, 0x9b36, 0x9b36, 0x9b36, 0xa441, 0xa464, 0xa475, 0xa495, + 0xa4c7, 0x9e44, 0x9b36, 0x9e44, 0x9e5e, 0x9b36, 0x9d45, 0x9e0f, + 0x9b36, 0xa888, 0x9e5e, 0x9b36, 0xa8a4, 0x9e5e, 0x9b36, 0x9e58, + 0x9cdb, 0x9b59, 0x9b36, 0xa8c0, 0xa92d, 0xaa11, 0x9b36, 0xaa1e, + 0x9e41, 0xaa49, 0x9b36, 0xa4d1, 0xaa55, 0x9b36, 0x080c, 0x0d85, + 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, + 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0xaaf5, 0xaba7, 0x9b57, + 0x9b91, 0x9c3d, 0x9c48, 0x9b57, 0x9e44, 0x9b57, 0x9ca2, 0x9cae, + 0x9bac, 0x9b57, 0x9bc7, 0x9bfb, 0xb008, 0xb04d, 0x9e5e, 0x080c, + 0x0d85, 0x00d6, 0x0096, 0x080c, 0x9ef8, 0x0026, 0x0036, 0x7814, + 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, + 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, + 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, + 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0xa270, 0x003e, 0x002e, + 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, + 0x080c, 0xb094, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, + 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ef8, 0x7003, 0x0500, 0x7814, + 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, + 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, + 0xa270, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ef8, + 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, + 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, + 0x60c3, 0x0010, 0x080c, 0xa270, 0x009e, 0x00de, 0x0005, 0x00d6, + 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9ef8, 0x20e9, 0x0000, + 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, + 0x2205, 0x080c, 0xdcef, 0x9006, 0x080c, 0x2205, 0x001e, 0xa804, + 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa270, 0x012e, + 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, + 0x080c, 0x9f43, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, + 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, + 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, + 0x2098, 0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xdcef, 0x001e, + 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, + 0x080c, 0x100b, 0x080c, 0xa270, 0x012e, 0x009e, 0x00de, 0x0005, + 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, + 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9ef8, 0x7003, + 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa270, + 0x00d6, 0x00e6, 0x080c, 0x9f43, 0x7814, 0x9084, 0xff00, 0x2073, + 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, + 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, + 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, + 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c68, 0x2069, 0x1801, 0x20a9, + 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c71, 0x9096, 0xdf00, + 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, + 0x19b4, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19ce, 0x20a9, 0x001a, + 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, + 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, + 0x8e70, 0x1f04, 0x9c88, 0x60c3, 0x004c, 0x080c, 0xa270, 0x00ee, + 0x00de, 0x0005, 0x080c, 0x9ef8, 0x7003, 0x6300, 0x7007, 0x0028, + 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00d6, 0x0026, + 0x0016, 0x080c, 0x9f43, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, + 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, 0x1924, + 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, + 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, + 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa270, 0x001e, + 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, + 0xa270, 0x080c, 0x9ef8, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, + 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x26bf, 0x710e, 0x001e, + 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, + 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, + 0x0254, 0x4003, 0x080c, 0xb094, 0x1120, 0xb8a0, 0x9082, 0x007f, + 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, + 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, + 0x60c3, 0x001c, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x7003, 0x0500, + 0x080c, 0xb094, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, + 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, + 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, + 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, + 0x4003, 0x60c3, 0x0010, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x9006, + 0x080c, 0x6bdb, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2011, 0x0240, + 0x2013, 0x22ff, 0x2011, 0x0241, 0x2013, 0xfffe, 0x7003, 0x0400, + 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, + 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, + 0x9086, 0x007e, 0x1904, 0x9dcf, 0x00d6, 0x2069, 0x196c, 0x2001, + 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, + 0x2000, 0x7012, 0x080c, 0xb0ab, 0x680c, 0x7016, 0x701f, 0x2710, + 0x6818, 0x7022, 0x681c, 0x7026, 0x0428, 0x6800, 0x700a, 0x6804, + 0x700e, 0x2009, 0x180d, 0x210c, 0xd18c, 0x0110, 0x2001, 0x0002, + 0x00f6, 0x2079, 0x0100, 0x080c, 0x779e, 0x1128, 0x78e3, 0x0000, + 0x080c, 0x2700, 0x78e2, 0x00fe, 0x6808, 0x080c, 0x779e, 0x1118, + 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xb0ab, + 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, + 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, + 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xaadc, + 0x2069, 0x1974, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, + 0x5844, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04e0, 0x2001, + 0x1837, 0x2004, 0xd0a4, 0x01a8, 0x0016, 0x2001, 0x180d, 0x2004, + 0xd08c, 0x2009, 0x0002, 0x1118, 0x2001, 0x196d, 0x200c, 0x60e0, + 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x2700, 0x61e2, + 0x001e, 0x20e1, 0x0001, 0x2099, 0x196c, 0x20e9, 0x0000, 0x20a1, + 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, + 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, + 0x025a, 0x4003, 0x080c, 0xaadc, 0x20a1, 0x024e, 0x20a9, 0x0008, + 0x2099, 0x1974, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa270, 0x080c, + 0x9ef8, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, + 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, + 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, + 0x0002, 0x00d6, 0x0804, 0x9ea8, 0x7026, 0x60c3, 0x0014, 0x0804, + 0xa270, 0x080c, 0x9ef8, 0x7003, 0x5000, 0x0804, 0x9d67, 0x080c, + 0x9ef8, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, + 0xa270, 0x080c, 0x9f3a, 0x0010, 0x080c, 0x9f43, 0x7003, 0x0200, + 0x60c3, 0x0004, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, 0x0100, + 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa270, + 0x080c, 0x9f43, 0x7003, 0x0200, 0x0804, 0x9d67, 0x080c, 0x9f43, + 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, + 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00d6, + 0x080c, 0x9f43, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, + 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, + 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, + 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, + 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, + 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, + 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, + 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbad4, + 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, + 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, + 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa270, 0x080c, + 0x9f43, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, + 0x0014, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, 0x0200, 0x0804, + 0x9ce5, 0x080c, 0x9f43, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, + 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa270, 0x080c, 0x9f43, 0x7003, + 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa270, 0x0026, + 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, + 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, + 0x080c, 0xaaf1, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, + 0x004e, 0x003e, 0x00de, 0x080c, 0xa264, 0x721a, 0x9f95, 0x0000, + 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, + 0x080c, 0xaaf1, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, + 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, + 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, + 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, + 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, + 0x2300, 0x2021, 0x0100, 0x080c, 0xaaf1, 0xb810, 0x9305, 0x7002, + 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, + 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, + 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, + 0x003e, 0x00de, 0x080c, 0xa264, 0x721a, 0x7a08, 0x7222, 0x2f10, + 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa264, 0x721a, + 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, + 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, + 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, + 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, + 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, + 0x00be, 0x0005, 0x9fb1, 0x9fc0, 0x9fcb, 0x9faf, 0x9faf, 0x9faf, + 0x9fb1, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x9faf, 0x080c, + 0x0d85, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2a04, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0xa270, + 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, + 0x000c, 0x0804, 0xa270, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, + 0x60c3, 0x0004, 0x0804, 0xa270, 0x0026, 0x080c, 0xaaf1, 0xb810, + 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, + 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9f13, 0x0026, + 0x080c, 0xaaf1, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, + 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, + 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f75, + 0x0026, 0x080c, 0xaaf1, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, + 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, + 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, + 0x9f75, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, + 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0d85, + 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x7910, 0x2158, 0xb984, 0x2061, + 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x00be, 0x0005, 0xa04e, 0xa04e, 0xa04e, 0xa07f, 0xa04e, + 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa04e, 0xa644, 0xa649, + 0xa64e, 0xa653, 0xa04e, 0xa04e, 0xa04e, 0xa63f, 0x080c, 0x0d85, + 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084, 0x0180, 0x2001, + 0x1b72, 0x200c, 0x8108, 0x2102, 0x2001, 0x1b71, 0x201c, 0x1218, + 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, 0x7b4e, 0x732a, 0x9294, + 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, + 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e, + 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x0016, + 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa08f, + 0xa08f, 0xa091, 0xa08f, 0xa08f, 0xa08f, 0xa0ab, 0xa08f, 0x080c, + 0x0d85, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, + 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c, + 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, + 0x0001, 0x0804, 0xa270, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, + 0x0cb0, 0x0016, 0x080c, 0xaaf1, 0x001e, 0xb810, 0x9085, 0x0100, + 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, + 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa264, + 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, + 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, + 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028, + 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140, + 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, + 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, + 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c, + 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, + 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, + 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, + 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, + 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128, + 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, 0x6028, 0xc0bd, 0x602a, + 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, 0x2ad3, 0x2001, 0x00b2, + 0x2010, 0x900e, 0x080c, 0x2ae2, 0x2009, 0x07d0, 0x080c, 0x8a50, + 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, + 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, + 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, + 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582, 0x007e, 0x1250, + 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x348e, 0x2015, 0x9294, + 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480, 0x70dc, 0xd0ac, + 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80, 0x0138, 0x9185, + 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400, + 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072, 0x6077, 0x0000, + 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, + 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, + 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, + 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, + 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, + 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, + 0x900e, 0x2011, 0x0092, 0x080c, 0x2ae2, 0x2009, 0x07d0, 0x080c, + 0x8a50, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, + 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056, + 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058, + 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820, 0x0002, + 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, + 0xa1ef, 0xa1ef, 0xa1f1, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0x080c, + 0x0d85, 0xb884, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, + 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, + 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, + 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, + 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, + 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, 0x0050, 0x2039, 0x0029, + 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, + 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, + 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, + 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, + 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834, 0x60ca, + 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xaad1, + 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, + 0x1b58, 0x080c, 0x8a50, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, + 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294, 0x00ff, 0x8217, + 0x0005, 0x00d6, 0x2069, 0x19e8, 0x686b, 0x0001, 0x00de, 0x0005, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8a42, 0x0005, + 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086, 0x0600, + 0x0128, 0x0089, 0x080c, 0x8a42, 0x001e, 0x0005, 0xc1e5, 0x2001, + 0x180c, 0x2102, 0x2001, 0x19e9, 0x2003, 0x0000, 0x2001, 0x19f4, + 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026, 0x2009, 0x1804, + 0x2011, 0x0009, 0x080c, 0x2ae2, 0x002e, 0x001e, 0x000e, 0x0005, + 0x0016, 0x00c6, 0x0006, 0x080c, 0xacfc, 0x0106, 0x2061, 0x0100, + 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009, 0x1804, 0x2011, + 0x0008, 0x080c, 0x2ae2, 0x002e, 0x001e, 0x010e, 0x090c, 0xad18, + 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce, 0x001e, 0x0005, + 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069, 0x0140, + 0x080c, 0x779e, 0x1510, 0x2001, 0x1a0d, 0x2004, 0x9005, 0x1904, + 0xa31f, 0x080c, 0x7840, 0x11a8, 0x2069, 0x0380, 0x6843, 0x0101, + 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020, 0xd0b4, 0x1120, + 0x6024, 0xd084, 0x090c, 0x0d85, 0x6843, 0x0100, 0x080c, 0x8a42, + 0x04b0, 0x00c6, 0x2061, 0x19e8, 0x00f0, 0x6904, 0x9194, 0x4000, + 0x0598, 0x080c, 0xa2a0, 0x080c, 0x2aa9, 0x00c6, 0x2061, 0x19e8, + 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136, 0x080c, 0xacfc, + 0x6130, 0x080c, 0xad18, 0x00ce, 0x81ff, 0x01c8, 0x080c, 0x8a42, + 0x080c, 0xa293, 0x00a0, 0x080c, 0xacfc, 0x6130, 0x91e5, 0x0000, + 0x0150, 0x080c, 0xeeee, 0x080c, 0x8a4b, 0x6003, 0x0001, 0x2009, + 0x0014, 0x080c, 0xb20a, 0x080c, 0xad18, 0x00ce, 0x0000, 0x002e, + 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0d, 0x2004, 0x9005, + 0x1db0, 0x00c6, 0x2061, 0x19e8, 0x6134, 0x9192, 0x0003, 0x1ad8, + 0x8108, 0x6136, 0x00ce, 0x080c, 0x8a42, 0x080c, 0x6058, 0x2009, + 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, + 0x00e6, 0x0016, 0x0026, 0x080c, 0x8a58, 0x080c, 0xacfc, 0x2001, + 0x0387, 0x2003, 0x0202, 0x2071, 0x19e8, 0x714c, 0x81ff, 0x0904, + 0xa3d9, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x779e, 0x1518, + 0x0036, 0x2019, 0x0002, 0x080c, 0xa596, 0x003e, 0x080c, 0xeeee, + 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, + 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, + 0x0003, 0x080c, 0xb20a, 0x2001, 0x0386, 0x2003, 0x5040, 0x080c, + 0x7840, 0x0804, 0xa3d9, 0x6904, 0xd1f4, 0x0904, 0xa3e6, 0x080c, + 0x2aa9, 0x00c6, 0x704c, 0x9065, 0x090c, 0x0d85, 0x6020, 0x00ce, + 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, 0x9105, 0x1500, 0x714c, + 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, 0x6214, 0x9294, 0x1800, + 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, 0x0010, 0xc0e4, 0x200a, + 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x704c, 0x2060, + 0x080c, 0x9a48, 0x2009, 0x0049, 0x080c, 0xb20a, 0x0450, 0x080c, + 0xeeee, 0x704c, 0x9065, 0x9086, 0x1b55, 0x1158, 0x080c, 0xafd2, + 0x1500, 0x2061, 0x1b55, 0x6064, 0x8000, 0x6066, 0x080c, 0x6058, + 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x714c, + 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, + 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003, 0x0003, 0x080c, + 0xb20a, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c, 0xad18, 0x002e, + 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, + 0xa37f, 0x0804, 0xa381, 0x0026, 0x00e6, 0x2071, 0x19e8, 0x706c, + 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff, 0x01c0, 0x2071, + 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138, 0x2009, + 0x1984, 0x2011, 0x0012, 0x080c, 0x2ae2, 0x0048, 0x928e, 0x0009, + 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2ae2, 0x00ee, + 0x002e, 0x0005, 0x9036, 0x2001, 0x19f2, 0x2004, 0x9005, 0x0128, + 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085, 0x0001, 0x0005, + 0x00f6, 0x2079, 0x19e8, 0x610c, 0x9006, 0x600e, 0x6044, 0xc0fc, + 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, 0x1118, 0x7826, 0x782a, + 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, 0x610e, 0x00ce, 0x7824, + 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa65d, 0x080c, 0xd10c, 0x00fe, + 0x0005, 0x080c, 0x9ef8, 0x7003, 0x1200, 0x7838, 0x7012, 0x783c, + 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148, 0x7810, 0x9005, + 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be, 0x0020, 0x2061, + 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a, 0x710e, 0x00ce, + 0x60c3, 0x002c, 0x0804, 0xa270, 0x080c, 0x9ef8, 0x7003, 0x0f00, + 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff, 0x700a, 0xb814, + 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x0156, 0x080c, 0x9f43, + 0x7003, 0x0200, 0x080c, 0x8b10, 0x20a9, 0x0006, 0x2011, 0xffec, + 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072, 0x8e70, 0x2205, + 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xa484, + 0x60c3, 0x001c, 0x015e, 0x0804, 0xa270, 0x0016, 0x0026, 0x080c, + 0x9f1f, 0x080c, 0x9f31, 0x9e80, 0x0004, 0x20e9, 0x0000, 0x20a0, + 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, 0xa85c, + 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, 0x21a8, + 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004, 0x8003, 0x60c2, + 0x080c, 0xa270, 0x002e, 0x001e, 0x0005, 0x20a9, 0x0010, 0x4003, + 0x080c, 0xaadc, 0x20a1, 0x0240, 0x22a8, 0x4003, 0x0c68, 0x080c, + 0x9ef8, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, + 0xa270, 0x0016, 0x0026, 0x080c, 0x9ef8, 0x20e9, 0x0000, 0x20a1, + 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860, 0x20e0, + 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808, 0x9088, 0x0002, + 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa270, 0x002e, 0x001e, + 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19e8, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c, 0xd132, 0x1110, + 0x080c, 0xbb5c, 0x600c, 0x0006, 0x080c, 0xd3ae, 0x600f, 0x0000, + 0x080c, 0xb16c, 0x080c, 0xa65d, 0x00ce, 0x0c68, 0x2c00, 0x7012, + 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, + 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102, + 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e8, 0x7030, 0x2060, + 0x8cff, 0x0548, 0x080c, 0xa2a0, 0x6ac0, 0x68c3, 0x0000, 0x080c, + 0x8a4b, 0x00c6, 0x2061, 0x0100, 0x080c, 0xac2d, 0x00ce, 0x20a9, + 0x01f4, 0x04b1, 0x080c, 0x99ed, 0x6044, 0xd0ac, 0x1128, 0x2001, + 0x1988, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013, 0x080c, 0xb20a, + 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, + 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x8a4b, 0x6814, 0x9084, + 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, + 0x2011, 0x6002, 0x080c, 0x8993, 0x20a9, 0x01f4, 0x0009, 0x08c0, + 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, + 0x190c, 0x2aa9, 0x0090, 0xd084, 0x0118, 0x6827, 0x4001, 0x0010, + 0x1f04, 0xa578, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x0005, 0x0126, 0x0156, + 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, + 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, + 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x0380, 0x701c, 0x0006, + 0x701f, 0x0202, 0x2071, 0x19e8, 0x704c, 0x2060, 0x8cff, 0x0904, + 0xa619, 0x080c, 0xaf84, 0x0904, 0xa619, 0x9386, 0x0002, 0x1128, + 0x6814, 0x9084, 0x0002, 0x0904, 0xa619, 0x68af, 0x95f5, 0x6817, + 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, + 0x080c, 0x8a58, 0x080c, 0x1e44, 0x2001, 0x0032, 0x6920, 0xd1bc, + 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x0016, + 0x2009, 0x0040, 0x080c, 0x2220, 0x001e, 0x20a9, 0x03e8, 0x6824, + 0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, + 0x2aa9, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, + 0xa5e7, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2a99, 0x9006, 0x080c, 0x2a99, 0x6827, 0x4000, 0x6824, 0x83ff, + 0x1180, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0150, 0x080c, + 0x9a48, 0x6044, 0xd0ac, 0x1118, 0x6003, 0x0002, 0x0010, 0x080c, + 0xb20a, 0x000e, 0x2071, 0x0380, 0xd08c, 0x1110, 0x701f, 0x0200, + 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, + 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, + 0x19e8, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, + 0x8000, 0x2069, 0x19e8, 0x6a3e, 0x012e, 0x00de, 0x0005, 0x080c, + 0xa050, 0x7047, 0x1000, 0x0098, 0x080c, 0xa050, 0x7047, 0x4000, + 0x0070, 0x080c, 0xa050, 0x7047, 0x2000, 0x0048, 0x080c, 0xa050, + 0x7047, 0x0400, 0x0020, 0x080c, 0xa050, 0x7047, 0x0200, 0x785c, + 0x7032, 0x60c3, 0x0020, 0x0804, 0xa270, 0x00e6, 0x2071, 0x19e8, + 0x702c, 0x9005, 0x0110, 0x8001, 0x702e, 0x00ee, 0x0005, 0x00f6, + 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091, + 0x8000, 0x2071, 0x19e8, 0x7620, 0x2660, 0x2678, 0x2039, 0x0001, + 0x87ff, 0x0904, 0xa702, 0x8cff, 0x0904, 0xa702, 0x6020, 0x9086, + 0x0006, 0x1904, 0xa6fd, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, + 0xa6fd, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa6fd, + 0x85ff, 0x0120, 0x605c, 0x9106, 0x1904, 0xa6fd, 0x7030, 0x9c06, + 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, + 0x0148, 0x6827, 0x0001, 0x080c, 0x8a4b, 0x080c, 0xa78a, 0x7033, + 0x0000, 0x0428, 0x080c, 0x8a4b, 0x6820, 0xd0b4, 0x0110, 0x68a7, + 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, + 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, + 0x2001, 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, + 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7020, + 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, + 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, + 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, + 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xcf19, + 0x0110, 0x080c, 0xea30, 0x009e, 0x080c, 0xb1a7, 0x080c, 0xa65d, + 0x88ff, 0x1190, 0x00ce, 0x0804, 0xa678, 0x2c78, 0x600c, 0x2060, + 0x0804, 0xa678, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, + 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7648, + 0x2660, 0x2678, 0x8cff, 0x0904, 0xa779, 0x6020, 0x9086, 0x0006, + 0x1904, 0xa774, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xa774, + 0x0048, 0x6010, 0x9b06, 0x1904, 0xa774, 0x85ff, 0x0118, 0x605c, + 0x9106, 0x15d0, 0x704c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001, + 0x080c, 0xa596, 0x703f, 0x0000, 0x9006, 0x704e, 0x706a, 0x7052, + 0x706e, 0x080c, 0xaff4, 0x003e, 0x7048, 0x9c36, 0x1110, 0x660c, + 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, + 0x080c, 0xcf19, 0x0110, 0x080c, 0xea30, 0x080c, 0xb1a7, 0x87ff, + 0x1198, 0x00ce, 0x0804, 0xa722, 0x2c78, 0x600c, 0x2060, 0x0804, + 0xa722, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, + 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, + 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e8, 0x9006, 0x7032, 0x700a, + 0x7004, 0x9086, 0x0003, 0x0158, 0x2001, 0x1800, 0x2004, 0x9086, + 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, + 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2071, 0x19e8, 0x2c10, 0x7648, 0x2660, 0x2678, + 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7048, 0x9c36, 0x1110, + 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, + 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, + 0x0040, 0x090c, 0x99ed, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, + 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, + 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, + 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e8, 0x7610, + 0x2660, 0x2678, 0x8cff, 0x0904, 0xa877, 0x6010, 0x00b6, 0x2058, + 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa872, 0x7030, 0x9c06, 0x1520, + 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xa849, 0x080c, 0xa2a0, + 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, 0x0036, 0x2069, + 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, + 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, 0xd084, + 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, + 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, + 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, + 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd121, + 0x1180, 0x080c, 0x3344, 0x080c, 0xd132, 0x1518, 0x080c, 0xbb5c, + 0x0400, 0x080c, 0xa78a, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, + 0x0898, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, 0x0090, 0x6014, + 0x2048, 0x080c, 0xcf19, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, + 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x7006, 0x080c, + 0xd10c, 0x080c, 0xd3ae, 0x080c, 0xb1a7, 0x080c, 0xa65d, 0x00ce, + 0x0804, 0xa7f2, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa7f2, 0x012e, + 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, + 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xea30, 0x0c08, + 0x00d6, 0x080c, 0x9f43, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, + 0x0014, 0x20e1, 0x0001, 0x2099, 0x1989, 0x20e9, 0x0000, 0x20a1, + 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, + 0x080c, 0xa270, 0x00de, 0x0005, 0x080c, 0x9f43, 0x700b, 0x0800, + 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, + 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, + 0x7860, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa270, + 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, + 0xd5bb, 0x00de, 0x1904, 0xa925, 0x080c, 0x9ef8, 0x7003, 0x1300, + 0x782c, 0x080c, 0xaa34, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, + 0x7810, 0x2058, 0xbaa0, 0x080c, 0xb094, 0x11d8, 0x9286, 0x007e, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, + 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, + 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, + 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, + 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c, 0xb094, 0x1130, 0x7810, + 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, + 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, + 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, + 0x00de, 0x080c, 0xa270, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, + 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, + 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xa9a4, + 0x9186, 0x0005, 0x0904, 0xa98c, 0x9186, 0x0004, 0x05f0, 0x9186, + 0x0008, 0x0904, 0xa995, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, + 0x1700, 0x080c, 0xaa11, 0x0005, 0x080c, 0xa9d2, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x6a44, 0xd2fc, 0x11f8, + 0x0002, 0xa96c, 0xa977, 0xa96e, 0xa977, 0xa973, 0xa96c, 0xa96c, + 0xa977, 0xa977, 0xa977, 0xa977, 0xa96c, 0xa96c, 0xa96c, 0xa96c, + 0xa96c, 0xa977, 0xa96c, 0xa977, 0x080c, 0x0d85, 0x6824, 0xd0e4, + 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, + 0x7022, 0x6830, 0x7026, 0x0804, 0xa9cb, 0x080c, 0xa9d2, 0x00d6, + 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, + 0x1108, 0x900e, 0x0804, 0xa9cb, 0x080c, 0xa9d2, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0, 0x04e1, 0x00d6, 0x0026, + 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, + 0x0002, 0x1108, 0x900e, 0x0438, 0x0469, 0x00d6, 0x0026, 0x792c, + 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, + 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, + 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc, 0x1148, 0x9180, 0x0000, + 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, + 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, + 0x0804, 0xa270, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, + 0x9f43, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, + 0x7810, 0x2058, 0xb8a0, 0x080c, 0xb094, 0x1118, 0x9092, 0x007e, + 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, + 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0xbc84, + 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, + 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, + 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, + 0x0005, 0x080c, 0x9f43, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, + 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x080c, 0x9eef, + 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, + 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, + 0x60c3, 0x0010, 0x0804, 0xa270, 0x00e6, 0x2071, 0x0240, 0x0006, + 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8d4, 0xd084, 0x0120, + 0x784c, 0x702a, 0x7850, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, + 0x0005, 0x080c, 0x9f3a, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, + 0x700e, 0x60c3, 0x0008, 0x0804, 0xa270, 0x00a9, 0x7914, 0x712a, + 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2a04, 0x0228, + 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa293, + 0x080c, 0x8a42, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7860, + 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, + 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, + 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, + 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, + 0xaaf1, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, + 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, + 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, + 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, + 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, + 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, + 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, + 0xc1d5, 0x2102, 0x2009, 0x19b3, 0x210c, 0x009e, 0x918d, 0x0092, + 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x0026, 0x2110, 0x900e, + 0x080c, 0x2ae2, 0x002e, 0x0005, 0x2009, 0x0009, 0x00a0, 0x2009, + 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c, 0x0058, + 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009, 0x000f, + 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c, 0x9ef8, 0x0016, + 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x2001, + 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197c, 0x2004, + 0x9086, 0xaaaa, 0x1904, 0xab96, 0x7003, 0x5400, 0x00c6, 0x2061, + 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, + 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c, 0xff00, 0x7112, + 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290, 0x0006, 0x2104, + 0x2012, 0x8108, 0x8210, 0x1f04, 0xab27, 0x20a9, 0x0004, 0x2009, + 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xab31, 0xa860, + 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, + 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, + 0x2069, 0x0200, 0x080c, 0xaadc, 0x00de, 0x2071, 0x0240, 0x2011, + 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, + 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, + 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c, 0x9080, 0x0031, + 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, + 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, + 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1168, + 0x080c, 0x779e, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x2009, 0x1804, + 0x2011, 0x0029, 0x080c, 0x2ae2, 0x0010, 0x080c, 0xa270, 0x080c, + 0x8a42, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, + 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, + 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xab0c, 0x080c, + 0x9ef8, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, + 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084, 0x00ff, 0xa998, + 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c, 0x918c, 0xff00, + 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998, 0x918c, 0xff00, + 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d, 0x7112, 0x6180, + 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, + 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, + 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004, 0x2009, 0x1805, + 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xabe8, 0x20a9, 0x0002, + 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xabf2, + 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xaadc, 0x001e, 0x00de, + 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011, 0x0240, + 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xac08, 0x2009, 0x0008, + 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, + 0x0008, 0x2012, 0x8210, 0x1f04, 0xac19, 0x00ce, 0x60c3, 0x004c, + 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa270, 0x080c, 0x8a42, + 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x9290, 0x0018, + 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000, 0x22a8, + 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020, 0x0008, + 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120, 0x6810, + 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6, + 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071, + 0x19e8, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xacd9, 0x7030, + 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xacab, + 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, 0x7033, 0x0000, + 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, + 0x0100, 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, + 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, 0x9c36, + 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, 0x9f36, + 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, 0x0066, + 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, + 0x080c, 0xd121, 0x1180, 0x080c, 0x3344, 0x080c, 0xd132, 0x1518, + 0x080c, 0xbb5c, 0x0400, 0x080c, 0xa78a, 0x6824, 0xd084, 0x09b0, + 0x6827, 0x0001, 0x0898, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, + 0x0090, 0x6014, 0x2048, 0x080c, 0xcf19, 0x0168, 0x6020, 0x9086, + 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, + 0x7012, 0x080c, 0xd10c, 0x080c, 0xd3ae, 0x080c, 0xb1a7, 0x080c, + 0xa65d, 0x00ce, 0x0804, 0xac5c, 0x2c78, 0x600c, 0x2060, 0x0804, + 0xac5c, 0x7013, 0x0000, 0x700f, 0x0000, 0x012e, 0x006e, 0x009e, + 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086, + 0x0006, 0x1d08, 0x080c, 0xea30, 0x08f0, 0x00f6, 0x0036, 0x2079, + 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832, 0x7936, 0x7a3a, 0x781b, + 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016, 0x2001, 0x0382, 0x2004, + 0x9084, 0x0007, 0x9086, 0x0001, 0x1188, 0x2001, 0x0015, 0x0c29, + 0x2009, 0x1000, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, + 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c, 0x0d85, 0x001e, 0x0005, + 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x1120, + 0x2001, 0x0380, 0x2003, 0x0001, 0x0005, 0x0156, 0x0016, 0x0026, + 0x00e6, 0x900e, 0x2071, 0x19e8, 0x0469, 0x0106, 0x0190, 0x7004, + 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000, 0x6044, 0xd0fc, 0x01d8, + 0x1f04, 0xad35, 0x080c, 0x0d85, 0x080c, 0xacfc, 0x6044, 0xd0fc, + 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c, 0x99ed, 0x6044, 0xd0dc, + 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042, 0x704c, 0x9c06, 0x190c, + 0x0d85, 0x080c, 0x9a48, 0x010e, 0x1919, 0x00ee, 0x002e, 0x001e, + 0x015e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, + 0x0003, 0x0005, 0x0126, 0x2091, 0x2400, 0x7808, 0xd0a4, 0x190c, + 0x0d7e, 0xd09c, 0x0128, 0x7820, 0x908c, 0xf000, 0x11b8, 0x0012, + 0x012e, 0x0005, 0xad82, 0xadc0, 0xadef, 0xae37, 0xae47, 0xae58, + 0xae67, 0xae75, 0xaea2, 0xaea6, 0xad82, 0xad82, 0xaea9, 0xaec5, + 0xad82, 0xad82, 0x080c, 0x0d85, 0x012e, 0x0005, 0x2060, 0x6044, + 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000, 0x908a, 0x0010, 0x1a0c, + 0x0d85, 0x0012, 0x012e, 0x0005, 0xada7, 0xada9, 0xada7, 0xadaf, + 0xada7, 0xada7, 0xada7, 0xada7, 0xada7, 0xada9, 0xada7, 0xada9, + 0xada7, 0xada9, 0xada7, 0xada7, 0xada7, 0xada9, 0xada7, 0x080c, + 0x0d85, 0x2009, 0x0013, 0x080c, 0xb20a, 0x012e, 0x0005, 0x6014, + 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c, 0x8c19, 0x080c, 0xb16c, + 0x012e, 0x0005, 0x2009, 0x0049, 0x080c, 0xb20a, 0x012e, 0x0005, + 0x080c, 0xacfc, 0x2001, 0x1a0d, 0x2003, 0x0000, 0x7030, 0x9065, + 0x1130, 0x7004, 0x9086, 0x0003, 0x01e0, 0x080c, 0x0d85, 0x7034, + 0x9092, 0xc350, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, + 0x0110, 0x7007, 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xb0c0, + 0x0140, 0x080c, 0xeeee, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, + 0xb20a, 0x781f, 0x0100, 0x080c, 0xad18, 0x012e, 0x0005, 0x080c, + 0xacfc, 0x714c, 0x81ff, 0x1128, 0x2011, 0x1a10, 0x2013, 0x0000, + 0x04c0, 0x2061, 0x0100, 0x7150, 0x9192, 0x7530, 0x1678, 0x8108, + 0x7152, 0x714c, 0x9186, 0x1b55, 0x0120, 0x2001, 0x0391, 0x2003, + 0x0400, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1160, 0x6014, + 0x9084, 0x1984, 0x9085, 0x0012, 0x714c, 0x918e, 0x1b55, 0x1108, + 0xc0fd, 0x6016, 0x00b0, 0x714c, 0x9188, 0x0008, 0x210c, 0x918e, + 0x0009, 0x0d68, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016, 0x714c, + 0x918e, 0x1b55, 0x1108, 0xc0fd, 0x6016, 0x0018, 0x706c, 0xc085, + 0x706e, 0x781f, 0x0200, 0x080c, 0xad18, 0x012e, 0x0005, 0x080c, + 0xacfc, 0x714c, 0x2160, 0x6003, 0x0003, 0x2009, 0x004a, 0x080c, + 0xb20a, 0x781f, 0x0200, 0x080c, 0xad18, 0x012e, 0x0005, 0x7808, + 0xd09c, 0x0de8, 0x7820, 0x2060, 0x6003, 0x0003, 0x080c, 0xacfc, + 0x080c, 0x1dcc, 0x781f, 0x0400, 0x080c, 0xad18, 0x012e, 0x0005, + 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060, 0x080c, 0xacfc, 0x080c, + 0x1e14, 0x781f, 0x0400, 0x080c, 0xad18, 0x012e, 0x0005, 0x7030, + 0x9065, 0x0148, 0x6044, 0xc0bc, 0x6046, 0x7104, 0x9186, 0x0003, + 0x0110, 0x080c, 0x9ab4, 0x012e, 0x0005, 0x00f6, 0x703c, 0x9086, + 0x0002, 0x0528, 0x704c, 0x907d, 0x0510, 0x7844, 0xc0bc, 0x7846, + 0x7820, 0x9086, 0x0009, 0x0118, 0x080c, 0xa1ca, 0x00c0, 0x7828, + 0xd0fc, 0x1118, 0x080c, 0xa149, 0x0090, 0x2001, 0x1837, 0x2004, + 0x9084, 0x0028, 0x1130, 0x2001, 0x197c, 0x2004, 0x9086, 0xaaaa, + 0x1120, 0x2001, 0x0387, 0x2003, 0x1000, 0x080c, 0xa0ce, 0x00fe, + 0x012e, 0x0005, 0x080c, 0x7840, 0x012e, 0x0005, 0x080c, 0x0d85, + 0x0005, 0x2009, 0x1b66, 0x2104, 0xd0bc, 0x01a8, 0xc0bc, 0x200a, + 0x2009, 0x010b, 0x2104, 0x9085, 0x0002, 0x200a, 0x2009, 0x0101, + 0x2104, 0xc0ac, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0x1984, + 0x9085, 0x8092, 0x200a, 0x012e, 0x0005, 0x080c, 0x8a58, 0x2009, + 0x010b, 0x2104, 0xd08c, 0x01a8, 0xc08c, 0x200a, 0x2001, 0x1848, + 0x2004, 0xd094, 0x1130, 0x2009, 0x0101, 0x2104, 0x9085, 0x0020, + 0x200a, 0x2009, 0x1b66, 0x200b, 0x0000, 0x2001, 0x001b, 0x080c, + 0xaced, 0x012e, 0x0005, 0x00e6, 0x2071, 0x19e8, 0x6044, 0xc0bc, + 0x6046, 0xd0fc, 0x01b8, 0x704c, 0x9c06, 0x1190, 0x2019, 0x0001, + 0x080c, 0xa596, 0x704f, 0x0000, 0x2001, 0x0109, 0x2004, 0xd08c, + 0x1138, 0x2001, 0x0108, 0x2004, 0xd0bc, 0x1110, 0x703f, 0x0000, + 0x080c, 0xa7a1, 0x00ee, 0x0005, 0x0026, 0x7010, 0x9c06, 0x1178, + 0x080c, 0xa65d, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, + 0x7212, 0x600f, 0x0000, 0x0010, 0x7212, 0x720e, 0x9006, 0x002e, + 0x0005, 0x0026, 0x7020, 0x9c06, 0x1178, 0x080c, 0xa65d, 0x6044, + 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7222, 0x600f, 0x0000, + 0x0010, 0x7222, 0x721e, 0x9006, 0x002e, 0x0005, 0x00d6, 0x0036, + 0x7830, 0x9c06, 0x1558, 0x2069, 0x0100, 0x68c0, 0x9005, 0x01f8, + 0x080c, 0x8a4b, 0x080c, 0xa2a0, 0x68c3, 0x0000, 0x080c, 0xa78a, + 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, + 0x080c, 0x2a99, 0x9006, 0x080c, 0x2a99, 0x2069, 0x0100, 0x6824, + 0xd084, 0x0110, 0x6827, 0x0001, 0x9085, 0x0001, 0x0038, 0x7808, + 0xc0ad, 0x780a, 0x6003, 0x0009, 0x630a, 0x9006, 0x003e, 0x00de, + 0x0005, 0x0016, 0x0026, 0x0036, 0x6100, 0x2019, 0x0100, 0x2001, + 0x0382, 0x2004, 0xd09c, 0x0190, 0x00c6, 0x0126, 0x2091, 0x2800, + 0x0016, 0x0036, 0x080c, 0xad62, 0x003e, 0x001e, 0x012e, 0x00ce, + 0x6200, 0x2200, 0x9106, 0x0d58, 0x2200, 0x0010, 0x8319, 0x1d38, + 0x003e, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x080c, + 0xacfc, 0x0106, 0x2071, 0x19e8, 0x2069, 0x0100, 0x704c, 0x2060, + 0x9086, 0x1b55, 0x15b8, 0x6814, 0xd08c, 0x0188, 0x6817, 0x0010, + 0x2009, 0x0019, 0x8109, 0x1df0, 0x2001, 0x0032, 0x6920, 0xd1bc, + 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x6824, + 0xd08c, 0x0110, 0x6827, 0x0002, 0x68d0, 0x9005, 0x0118, 0x9082, + 0x0005, 0x0238, 0x6060, 0x8000, 0x6062, 0x2001, 0x0391, 0x2003, + 0x0400, 0x080c, 0x9a48, 0x682c, 0x9084, 0xfffd, 0x682e, 0x2001, + 0x1848, 0x2004, 0xd094, 0x1120, 0x6804, 0x9085, 0x0020, 0x6806, + 0x2069, 0x0000, 0x010e, 0x090c, 0xad18, 0x8dff, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0xacfc, 0x0106, + 0x2071, 0x19e8, 0x2069, 0x0100, 0x080c, 0xaf84, 0x68d0, 0x9005, + 0x0158, 0x9082, 0x0005, 0x1240, 0x080c, 0x2b33, 0x2001, 0x0391, + 0x2003, 0x0400, 0x2069, 0x0000, 0x010e, 0x090c, 0xad18, 0x8dff, + 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0016, 0x2001, 0x0134, 0x2004, + 0x9005, 0x0140, 0x9082, 0x0005, 0x1228, 0x2001, 0x0391, 0x2003, + 0x0404, 0x0020, 0x2001, 0x0391, 0x2003, 0x0400, 0x001e, 0x0005, + 0x00d6, 0x0156, 0x080c, 0x9f43, 0x7a14, 0x82ff, 0x0138, 0x7003, + 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, + 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, + 0x1110, 0xc38d, 0x0060, 0x080c, 0x779e, 0x1110, 0xc3ad, 0x0008, + 0xc3a5, 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, + 0x080c, 0x8b10, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, + 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, + 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xb03a, 0x60c3, 0x0020, + 0x080c, 0xa270, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9f43, + 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, + 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, + 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19be, + 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, + 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, + 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, + 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, + 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, + 0x001c, 0x015e, 0x0804, 0xa270, 0x0006, 0x2001, 0x1837, 0x2004, + 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa62b, 0x2011, + 0x0002, 0x080c, 0xa635, 0x080c, 0xa516, 0x0036, 0x901e, 0x080c, + 0xa596, 0x003e, 0x0005, 0x080c, 0x3487, 0x0188, 0x0016, 0x00b6, + 0x00c6, 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, + 0x67b4, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, + 0x00d6, 0x00f6, 0x7104, 0x9186, 0x0004, 0x1130, 0x7410, 0x9e90, + 0x0004, 0x9e98, 0x0003, 0x0088, 0x9186, 0x0001, 0x1130, 0x7420, + 0x9e90, 0x0008, 0x9e98, 0x0007, 0x0040, 0x9186, 0x0002, 0x1538, + 0x7428, 0x9e90, 0x000a, 0x9e98, 0x0009, 0x6110, 0x2468, 0x680c, + 0x907d, 0x01e8, 0x7810, 0x9106, 0x1128, 0x2f68, 0x780c, 0x907d, + 0x1dc8, 0x00a8, 0x780c, 0x680e, 0x7c0e, 0x2f12, 0x2304, 0x9f06, + 0x1108, 0x2d1a, 0x9006, 0x7032, 0x7036, 0x7004, 0x9086, 0x0003, + 0x0110, 0x7007, 0x0000, 0x9006, 0x00fe, 0x00de, 0x0005, 0x9085, + 0x0001, 0x0cd0, 0x2071, 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, + 0x0812, 0x2071, 0x1800, 0x7076, 0x707a, 0x706b, 0xffd4, 0x2071, + 0x1800, 0x7074, 0x7056, 0x705b, 0x1ddc, 0x0005, 0x00e6, 0x0126, + 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, + 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, + 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, + 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1230, + 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1ddc, + 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, + 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, + 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, + 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, + 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, + 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc, 0x0a0c, 0x0d85, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x9006, 0x6006, + 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, + 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a, 0x602e, 0x6032, + 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046, 0x6042, 0x2061, + 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x9006, 0x600e, 0x6016, + 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e, 0x6062, 0x604a, + 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x0006, + 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084, 0x190c, 0x1ad3, + 0x6023, 0x0007, 0x2001, 0x1986, 0x2004, 0x0006, 0x9082, 0x0051, + 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xece1, 0x604b, 0x0000, + 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016, 0x6012, 0x000e, + 0x0005, 0x080c, 0xacfc, 0x0106, 0x2001, 0x19fb, 0x2004, 0x9c06, + 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa596, 0x003e, 0x080c, + 0xa7a1, 0x010e, 0x090c, 0xad18, 0x0005, 0x00e6, 0x0126, 0x2071, + 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001, 0x0608, 0x7058, + 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, + 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, + 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1230, 0x755a, + 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc0, + 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xb21e, 0xb228, + 0xb243, 0xb25e, 0xd69a, 0xd6b7, 0xd6d2, 0xb21e, 0xb228, 0x92f7, + 0xb277, 0xb21e, 0xb21e, 0xb21e, 0xb21e, 0xb21e, 0x9186, 0x0013, + 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x99ed, 0x0005, 0x0005, + 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, + 0x0005, 0xb241, 0xb9bc, 0xbba3, 0xb241, 0xbc39, 0xb540, 0xb241, + 0xb241, 0xb93e, 0xc25a, 0xb241, 0xb241, 0xb241, 0xb241, 0xb241, + 0xb241, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0d85, 0x0013, 0x006e, 0x0005, 0xb25c, 0xc875, 0xb25c, 0xb25c, + 0xb25c, 0xb25c, 0xb25c, 0xb25c, 0xc80c, 0xc9f8, 0xb25c, 0xc8b2, + 0xc936, 0xc8b2, 0xc936, 0xb25c, 0x080c, 0x0d85, 0x6000, 0x9082, + 0x0010, 0x1a0c, 0x0d85, 0x6000, 0x0002, 0xb275, 0xc2a4, 0xc33e, + 0xc4c1, 0xc530, 0xb275, 0xb275, 0xb275, 0xc273, 0xc78d, 0xc790, + 0xb275, 0xb275, 0xb275, 0xb275, 0xc7c0, 0x080c, 0x0d85, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, + 0xb290, 0xb290, 0xb2ce, 0xb36d, 0xb3ed, 0xb290, 0xb290, 0xb290, + 0xb292, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, 0xb290, + 0x080c, 0x0d85, 0x9186, 0x004c, 0x0560, 0x9186, 0x0003, 0x190c, + 0x0d85, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, + 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, + 0xa836, 0xa8b0, 0xa83a, 0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, + 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, + 0x621a, 0x009e, 0x080c, 0x1c26, 0x2009, 0x8030, 0x080c, 0x965e, + 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, + 0xb40f, 0x080c, 0xd65d, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, + 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, + 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, + 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, + 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, + 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, + 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, + 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, + 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, + 0xb335, 0xb335, 0xb330, 0xb333, 0xb335, 0xb32d, 0xb320, 0xb320, + 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, 0xb320, + 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, + 0x00fe, 0x009e, 0x00de, 0x080c, 0x0d85, 0x080c, 0xbe51, 0x0028, + 0x080c, 0xbf8f, 0x0010, 0x080c, 0xc085, 0x00fe, 0x00ee, 0x00de, + 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xb4cd, + 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, + 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, + 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12c2, + 0x080c, 0xb691, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, + 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xb16c, 0x2001, + 0x002c, 0x900e, 0x080c, 0xb533, 0x0c70, 0x91b6, 0x0015, 0x0170, + 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0d85, 0x91b2, + 0x0050, 0x1a0c, 0x0d85, 0x9182, 0x0047, 0x0042, 0x080c, 0xaf61, + 0x0120, 0x9086, 0x0002, 0x0904, 0xb2ce, 0x0005, 0xb38f, 0xb38f, + 0xb391, 0xb3c3, 0xb38f, 0xb38f, 0xb38f, 0xb38f, 0xb3d6, 0x080c, + 0x0d85, 0x00d6, 0x0016, 0x0096, 0x6003, 0x0004, 0x6114, 0x2148, + 0xa87c, 0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, + 0x9005, 0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb533, 0x080c, + 0xb16c, 0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, + 0xa8ae, 0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, + 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, + 0x001e, 0x00de, 0x0005, 0x080c, 0x9a48, 0x00d6, 0x0096, 0x6114, + 0x2148, 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0006, 0x080c, 0x7012, + 0x009e, 0x00de, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x080c, 0x9a48, + 0x080c, 0x3315, 0x080c, 0xd65a, 0x00d6, 0x0096, 0x6114, 0x2148, + 0x080c, 0xcf1b, 0x0120, 0xa87b, 0x0029, 0x080c, 0x7012, 0x009e, + 0x00de, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x9182, 0x0047, 0x0002, + 0xb3fd, 0xb3ff, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, + 0xb3fd, 0xb3fd, 0xb3fd, 0xb3fd, 0xb3ff, 0x080c, 0x0d85, 0x00d6, + 0x0096, 0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, + 0x0000, 0x080c, 0x7012, 0x009e, 0x00de, 0x0804, 0xb16c, 0x0026, + 0x0036, 0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, + 0x1059, 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, + 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, + 0x1800, 0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, + 0x2950, 0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, + 0x0001, 0x9182, 0x0035, 0x1228, 0x2011, 0x001f, 0x080c, 0xca7b, + 0x04c0, 0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xca7b, + 0x96b2, 0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, + 0x1059, 0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, + 0xb406, 0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, + 0xca7b, 0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, + 0x001b, 0x080c, 0xca7b, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, + 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, + 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, + 0x0050, 0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, + 0x7012, 0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, + 0x006e, 0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, + 0x0006, 0x080c, 0x1059, 0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, + 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, + 0xaa66, 0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, + 0x9182, 0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, + 0xac76, 0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, + 0x200c, 0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, + 0x7012, 0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, + 0x0096, 0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, + 0x001e, 0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, + 0x000c, 0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, + 0x2011, 0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, + 0x1059, 0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, + 0xa85c, 0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, + 0x2009, 0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, + 0x2200, 0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, + 0x2020, 0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, + 0x83ff, 0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, + 0x9085, 0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb4e2, + 0x0804, 0xb4e4, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, + 0x00de, 0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, + 0xa87a, 0xa982, 0x080c, 0x7006, 0x009e, 0x003e, 0x00de, 0x0005, + 0x91b6, 0x0015, 0x1118, 0x080c, 0xb16c, 0x0030, 0x91b6, 0x0016, + 0x190c, 0x0d85, 0x080c, 0xb16c, 0x0005, 0x20a9, 0x000e, 0x20e1, + 0x0000, 0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, + 0x20a0, 0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, + 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, + 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, + 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, + 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xcf1b, 0x0130, + 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, + 0xb16c, 0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, + 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000, 0x00be, 0x6014, 0x9005, + 0x0130, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, + 0xb16c, 0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, + 0x0006, 0x0016, 0x080c, 0xd645, 0x0188, 0x6014, 0x9005, 0x1170, + 0x600b, 0x0003, 0x601b, 0x0000, 0x604b, 0x0000, 0x2009, 0x0022, + 0x080c, 0xb994, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, + 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, + 0x0000, 0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, + 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, + 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, + 0x0205, 0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, + 0x2003, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, + 0x080c, 0xb16c, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, + 0x7030, 0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, + 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, + 0x2011, 0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xca7b, + 0x080c, 0xcf1b, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, + 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb16c, 0x001e, 0x009e, 0x0005, + 0x0016, 0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, + 0x0001, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa97a, 0x080c, + 0x7012, 0x009e, 0x080c, 0xb16c, 0x001e, 0x0005, 0x0016, 0x0096, + 0x7030, 0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, + 0x800c, 0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, + 0xa804, 0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xca7b, 0x009e, + 0x080c, 0xcf1b, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, + 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xb16c, 0x009e, 0x001e, + 0x0005, 0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, + 0x080c, 0xbb5c, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, + 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, + 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8, 0x0019, 0x0d08, 0x008e, + 0x0898, 0x0096, 0x0006, 0x080c, 0x1059, 0x000e, 0x01b0, 0xa8ab, + 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, + 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, + 0x080c, 0x114e, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, + 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, + 0xba10, 0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, + 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b, 0x0000, 0x2c68, 0x0016, + 0x2009, 0x0035, 0x080c, 0xd5bb, 0x001e, 0x1158, 0x622c, 0x2268, + 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, + 0x0128, 0x080c, 0xb16c, 0x0020, 0x0039, 0x0010, 0x080c, 0xb7c7, + 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, + 0x0015, 0x0904, 0xb7a6, 0x918e, 0x0016, 0x1904, 0xb7c5, 0x700c, + 0x908c, 0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, + 0xb780, 0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb762, + 0x0804, 0xb7c3, 0x6808, 0x9086, 0xffff, 0x1904, 0xb7a8, 0xa87c, + 0x9084, 0x0060, 0x9086, 0x0020, 0x1150, 0xa8ac, 0xa934, 0x9106, + 0x1904, 0xb7a8, 0xa8b0, 0xa938, 0x9106, 0x1904, 0xb7a8, 0x6824, + 0xd084, 0x1904, 0xb7a8, 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1986, + 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, 0xb7a8, + 0x080c, 0xd10c, 0x6810, 0x0096, 0x2048, 0xa9a0, 0x009e, 0x685c, + 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, + 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, 0x955b, + 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, + 0x00c6, 0x2d60, 0x080c, 0xcc01, 0x00ce, 0x0804, 0xb7c3, 0x00c6, + 0xa868, 0xd0fc, 0x1118, 0x080c, 0x622f, 0x0010, 0x080c, 0x663a, + 0x00ce, 0x1904, 0xb7a8, 0x00c6, 0x2d60, 0x080c, 0xb16c, 0x00ce, + 0x0804, 0xb7c3, 0x00c6, 0x080c, 0xb1dd, 0x0198, 0x6017, 0x0000, + 0x6810, 0x6012, 0x080c, 0xd3b6, 0x6023, 0x0003, 0x6904, 0x00c6, + 0x2d60, 0x080c, 0xb16c, 0x00ce, 0x080c, 0xb20a, 0x00ce, 0x0804, + 0xb7c3, 0x2001, 0x1988, 0x2004, 0x684a, 0x00ce, 0x0804, 0xb7c3, + 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, + 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, + 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, + 0x8020, 0x080c, 0x9617, 0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, + 0x1138, 0x2001, 0x1988, 0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, + 0x89ff, 0x090c, 0x0d85, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, + 0xa87b, 0x0003, 0x080c, 0x6e27, 0x080c, 0xd10c, 0x080c, 0xb1a7, + 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c, 0x080c, 0x68df, 0x00be, + 0x002e, 0x00de, 0x00ce, 0x080c, 0xb16c, 0x009e, 0x0005, 0x9186, + 0x0015, 0x1128, 0x2001, 0x1988, 0x2004, 0x684a, 0x0068, 0x918e, + 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xece1, 0x080c, + 0x8c19, 0x080c, 0xb16c, 0x00ce, 0x080c, 0xb16c, 0x0005, 0x0026, + 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, + 0x1988, 0x2004, 0x684a, 0x0804, 0xb841, 0x00c6, 0x2d60, 0x080c, + 0xcadc, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, + 0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, + 0x9617, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, + 0x090c, 0x0d85, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, + 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, + 0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, + 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, + 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, + 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, + 0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd2a0, 0x080c, 0x9ab3, + 0x0010, 0x080c, 0xb16c, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, + 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, + 0xba10, 0x00be, 0x9206, 0x1904, 0xb8ac, 0x700c, 0x6210, 0x00b6, + 0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb8ac, 0x6038, 0x2068, + 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb8ac, + 0x9286, 0x0002, 0x0904, 0xb8ac, 0x9286, 0x0000, 0x05e8, 0x6808, + 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, + 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, + 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, + 0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, + 0x2048, 0x080c, 0xcf1b, 0x090c, 0x0d85, 0xa87b, 0x0003, 0x009e, + 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x2009, 0x8020, 0x080c, 0x9617, 0x00ce, 0x0030, 0x6038, 0x2070, + 0x2001, 0x1988, 0x2004, 0x704a, 0x080c, 0xb16c, 0x002e, 0x00de, + 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, + 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, + 0xbc02, 0x0470, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, + 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc222, 0x002e, + 0x003e, 0x015e, 0x009e, 0x1904, 0xb91d, 0x0096, 0x0156, 0x0036, + 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, + 0x080c, 0xc222, 0x002e, 0x003e, 0x015e, 0x009e, 0x15b0, 0x7238, + 0xba0a, 0x733c, 0xbb0e, 0x83ff, 0x0118, 0xbc00, 0xc48d, 0xbc02, + 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb57c, + 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, + 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, + 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, + 0x12a8, 0x080c, 0xb691, 0x0130, 0x00fe, 0x009e, 0x080c, 0xb16c, + 0x00be, 0x0005, 0x080c, 0xbb5c, 0x0cb8, 0x2b78, 0x00f6, 0x080c, + 0x3315, 0x080c, 0xd65a, 0x00fe, 0x00c6, 0x080c, 0xb116, 0x2f00, + 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, + 0x0001, 0x2001, 0x0007, 0x080c, 0x66fa, 0x080c, 0x6726, 0x080c, + 0x961e, 0x080c, 0x9ab3, 0x00ce, 0x0804, 0xb8f0, 0x2100, 0x91b2, + 0x0053, 0x1a0c, 0x0d85, 0x91b2, 0x0040, 0x1a04, 0xb9a6, 0x0002, + 0xb994, 0xb994, 0xb98a, 0xb994, 0xb994, 0xb994, 0xb988, 0xb988, + 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, + 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, + 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb994, + 0xb988, 0xb994, 0xb994, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, + 0xb98a, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, + 0xb988, 0xb988, 0xb994, 0xb994, 0xb988, 0xb988, 0xb988, 0xb988, + 0xb988, 0xb988, 0xb988, 0xb988, 0xb988, 0xb994, 0xb988, 0xb988, + 0x080c, 0x0d85, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4, 0xc08c, + 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, + 0x0032, 0x0118, 0x080c, 0x961e, 0x0010, 0x080c, 0x9617, 0x0126, + 0x2091, 0x8000, 0x080c, 0x9ab3, 0x012e, 0x0005, 0x2600, 0x0002, + 0xb994, 0xb994, 0xb9ba, 0xb994, 0xb994, 0xb9ba, 0xb9ba, 0xb9ba, + 0xb9ba, 0xb994, 0xb9ba, 0xb994, 0xb9ba, 0xb994, 0xb9ba, 0xb9ba, + 0xb9ba, 0xb9ba, 0x080c, 0x0d85, 0x6004, 0x90b2, 0x0053, 0x1a0c, + 0x0d85, 0x91b6, 0x0013, 0x0904, 0xba91, 0x91b6, 0x0027, 0x1904, + 0xba3d, 0x080c, 0x99ed, 0x6004, 0x080c, 0xd121, 0x01b0, 0x080c, + 0xd132, 0x01a8, 0x908e, 0x0021, 0x0904, 0xba3a, 0x908e, 0x0022, + 0x1130, 0x080c, 0xb5a8, 0x0904, 0xba36, 0x0804, 0xba37, 0x908e, + 0x003d, 0x0904, 0xba3a, 0x0804, 0xba30, 0x080c, 0x3344, 0x2001, + 0x0007, 0x080c, 0x66fa, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, + 0x080c, 0xbb5c, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, + 0xc285, 0x080c, 0x779e, 0x1108, 0xc2ad, 0x2202, 0x080c, 0xacfc, + 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xedee, 0x002e, + 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, + 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x6010, 0x00b6, 0x905d, + 0x0100, 0x00be, 0x2c08, 0x080c, 0xe75d, 0x007e, 0x003e, 0x002e, + 0x001e, 0x080c, 0xad18, 0x080c, 0xd65a, 0x0016, 0x080c, 0xd3ae, + 0x080c, 0xb16c, 0x001e, 0x080c, 0x341e, 0x080c, 0x9ab3, 0x0030, + 0x080c, 0xd3ae, 0x080c, 0xb16c, 0x080c, 0x9ab3, 0x0005, 0x080c, + 0xbb5c, 0x0cb0, 0x080c, 0xbb98, 0x0c98, 0x9186, 0x0015, 0x0118, + 0x9186, 0x0016, 0x1140, 0x080c, 0xaf61, 0x0d80, 0x9086, 0x0002, + 0x0904, 0xbba3, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c, 0x99ed, + 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb5a8, 0x09f8, 0x080c, + 0x3315, 0x080c, 0xd65a, 0x080c, 0xd121, 0x1190, 0x080c, 0x3344, + 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbb5c, 0x9186, + 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102, 0x0800, + 0x080c, 0xd132, 0x1120, 0x080c, 0xbb5c, 0x0804, 0xba30, 0x6004, + 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, + 0x0000, 0x080c, 0x36bf, 0x00fe, 0x00ee, 0x0804, 0xba30, 0x6004, + 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xbb5c, 0x0804, + 0xba30, 0x90b2, 0x0040, 0x1a04, 0xbb3c, 0x2008, 0x0002, 0xbad9, + 0xbada, 0xbadd, 0xbae0, 0xbae3, 0xbaf0, 0xbad7, 0xbad7, 0xbad7, + 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, + 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, + 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbaf3, 0xbafe, 0xbad7, + 0xbaff, 0xbafe, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbafe, + 0xbafe, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, 0xbad7, + 0xbad7, 0xbb27, 0xbafe, 0xbad7, 0xbafa, 0xbad7, 0xbad7, 0xbad7, + 0xbafb, 0xbad7, 0xbad7, 0xbad7, 0xbafe, 0xbb22, 0xbad7, 0x080c, + 0x0d85, 0x0420, 0x2001, 0x000b, 0x0448, 0x2001, 0x0003, 0x0430, + 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6, 0x2058, 0xb804, 0x00be, + 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8, 0x2001, 0x0001, 0x00b0, + 0x2001, 0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd65d, 0x080c, + 0x9ab3, 0x0058, 0x0018, 0x0010, 0x080c, 0x66fa, 0x04b8, 0x080c, + 0xd65d, 0x6003, 0x0004, 0x080c, 0x9ab3, 0x0005, 0x080c, 0x66fa, + 0x6003, 0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, + 0x1120, 0x2001, 0x1986, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, + 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, + 0x9ab3, 0x0c18, 0x080c, 0xd3ae, 0x080c, 0xb16c, 0x08f0, 0x00e6, + 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36bf, 0x00fe, + 0x00ee, 0x080c, 0x99ed, 0x080c, 0xb16c, 0x0878, 0x6003, 0x0002, + 0x080c, 0xd65d, 0x0804, 0x9ab3, 0x2600, 0x2008, 0x0002, 0xbb53, + 0xbb36, 0xbb51, 0xbb36, 0xbb36, 0xbb51, 0xbb51, 0xbb51, 0xbb51, + 0xbb36, 0xbb51, 0xbb36, 0xbb51, 0xbb36, 0xbb51, 0xbb51, 0xbb51, + 0xbb51, 0x080c, 0x0d85, 0x0096, 0x6014, 0x2048, 0x080c, 0x7012, + 0x009e, 0x080c, 0xb16c, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, + 0x080c, 0xcf1b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, + 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x55cc, 0x0130, + 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, + 0x900e, 0x2011, 0x4005, 0x080c, 0xd51f, 0x0090, 0xa868, 0xd0fc, + 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, + 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, + 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, + 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, + 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, + 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x6604, 0x96b6, 0x004d, + 0x1120, 0x080c, 0xd43e, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0043, + 0x1120, 0x080c, 0xd487, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x004b, + 0x1120, 0x080c, 0xd4b3, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0033, + 0x1120, 0x080c, 0xd3d0, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0028, + 0x1120, 0x080c, 0xd170, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0029, + 0x1120, 0x080c, 0xd1b1, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x001f, + 0x1120, 0x080c, 0xb54d, 0x0804, 0xbc28, 0x6604, 0x96b6, 0x0000, + 0x1118, 0x080c, 0xb8b2, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, + 0x080c, 0xb589, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, + 0xb6af, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb847, + 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb5c1, 0x0400, + 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb5fd, 0x00c8, 0x6604, + 0x96b6, 0x0049, 0x1118, 0x080c, 0xb63e, 0x0090, 0x6604, 0x96b6, + 0x0041, 0x1118, 0x080c, 0xb628, 0x0058, 0x91b6, 0x0015, 0x1110, + 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbf34, + 0x00be, 0x0005, 0x080c, 0xb227, 0x0cd8, 0xbc45, 0xbc53, 0xbc45, + 0xbc9a, 0xbc45, 0xbe51, 0xbf41, 0xbc45, 0xbc45, 0xbf0a, 0xbc45, + 0xbf20, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, + 0xa867, 0x0103, 0x009e, 0x0804, 0xb16c, 0xa001, 0xa001, 0x0005, + 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x66e6, + 0x0804, 0xb16c, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, + 0x0074, 0x1540, 0x080c, 0xe72e, 0x11b0, 0x6010, 0x00b6, 0x2058, + 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, + 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c, 0x66fa, 0x080c, 0x3344, + 0x080c, 0xb16c, 0x0098, 0x2001, 0x000a, 0x080c, 0x66fa, 0x080c, + 0x3344, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x080c, + 0x9ab3, 0x0020, 0x2001, 0x0001, 0x080c, 0xbe21, 0x00ee, 0x0005, + 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x66e6, 0x2069, + 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6726, + 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, + 0x9086, 0x0074, 0x1904, 0xbdf6, 0x6010, 0x2058, 0xbaa0, 0x9286, + 0x007e, 0x1120, 0x080c, 0xc090, 0x0804, 0xbd63, 0x2001, 0x180d, + 0x2004, 0xd08c, 0x0904, 0xbd05, 0x00d6, 0x080c, 0x779e, 0x01a0, + 0x0026, 0x2011, 0x0010, 0x080c, 0x6c35, 0x002e, 0x0904, 0xbd04, + 0x080c, 0x5854, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, + 0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, + 0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, + 0x6c35, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0d85, 0x2048, + 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, + 0x900e, 0x2011, 0x4009, 0x080c, 0xd51f, 0x0040, 0x6014, 0x2048, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, + 0xb9a0, 0x0016, 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x080c, + 0x341e, 0x00de, 0x0804, 0xbdfb, 0x00de, 0x080c, 0xc085, 0x6010, + 0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, + 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, + 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd51f, 0x0030, 0xa807, + 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, + 0x66fa, 0x080c, 0x3344, 0x080c, 0xb16c, 0x0804, 0xbdfb, 0x080c, + 0xbe09, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, + 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, + 0x900e, 0x2011, 0x4000, 0x080c, 0xd51f, 0x08f8, 0x080c, 0xbdff, + 0x0160, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0004, 0x080c, 0x6726, + 0x2001, 0x0007, 0x080c, 0x66fa, 0x08a0, 0x2001, 0x0004, 0x080c, + 0x66fa, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x961e, 0x080c, + 0x9ab3, 0x0804, 0xbdfb, 0xb85c, 0xd0e4, 0x0178, 0x080c, 0xd348, + 0x080c, 0x779e, 0x0118, 0xd0dc, 0x1904, 0xbd25, 0x2011, 0x1837, + 0x2204, 0xc0ad, 0x2012, 0x0804, 0xbd25, 0x080c, 0xd389, 0x2011, + 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe905, 0x000e, + 0x1904, 0xbd25, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x66fa, + 0x9006, 0x080c, 0x66e6, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c, + 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c, + 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c, + 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26d5, + 0x00f6, 0x2100, 0x900e, 0x080c, 0x268c, 0x795e, 0x00fe, 0x9186, + 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6, + 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c, + 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26d5, 0x00f6, 0x2079, 0x1800, + 0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x268c, 0x795e, 0x00fe, + 0x8108, 0x080c, 0x6749, 0x2b00, 0x00ce, 0x1904, 0xbd25, 0x6012, + 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, + 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, + 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0028, 0x080c, 0xbb5c, + 0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, + 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, + 0x0005, 0x00e6, 0x080c, 0xee47, 0x0190, 0x2071, 0x0260, 0x7108, + 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, + 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, + 0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x66fa, + 0x080c, 0x5854, 0x1120, 0x2001, 0x0007, 0x080c, 0x6726, 0x2600, + 0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, + 0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, + 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4ca1, 0x004e, 0x003e, + 0x080c, 0x3344, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, + 0xb16c, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, + 0x9086, 0x0014, 0x1904, 0xbf00, 0x2001, 0x180d, 0x2004, 0xd08c, + 0x0904, 0xbeb3, 0x00d6, 0x080c, 0x779e, 0x01a0, 0x0026, 0x2011, + 0x0010, 0x080c, 0x6c35, 0x002e, 0x0904, 0xbeb2, 0x080c, 0x5854, + 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, + 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186, + 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x6c35, 0x002e, + 0x0548, 0x6014, 0x9005, 0x090c, 0x0d85, 0x2048, 0xa864, 0x9084, + 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, + 0x4009, 0x080c, 0xd51f, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, + 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, + 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x080c, 0x341e, 0x00de, + 0x0804, 0xbf05, 0x00de, 0x080c, 0x5854, 0x1170, 0x6014, 0x9005, + 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, + 0x080c, 0x4e58, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, + 0x684f, 0x080c, 0xbc88, 0x00de, 0x080c, 0xc15b, 0x1588, 0x6010, + 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x66fa, + 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, + 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, + 0xd51f, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, + 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, + 0x3344, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xb16c, 0x0028, + 0x080c, 0xbb5c, 0x9006, 0x080c, 0xbe21, 0x001e, 0x002e, 0x00ee, + 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, + 0x2001, 0x0002, 0x080c, 0x66fa, 0x6003, 0x0001, 0x6007, 0x0001, + 0x080c, 0x961e, 0x0804, 0x9ab3, 0x2001, 0x0001, 0x0804, 0xbe21, + 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, + 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66fa, 0x0804, 0xb16c, + 0x2001, 0x0001, 0x0804, 0xbe21, 0x0002, 0xbc45, 0xbf4c, 0xbc45, + 0xbf8f, 0xbc45, 0xc03c, 0xbf41, 0xbc48, 0xbc45, 0xc050, 0xbc45, + 0xc062, 0x6604, 0x9686, 0x0003, 0x0904, 0xbe51, 0x96b6, 0x001e, + 0x1110, 0x080c, 0xb16c, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, + 0xc074, 0x11a0, 0x9006, 0x080c, 0x66e6, 0x080c, 0x3315, 0x080c, + 0xd65a, 0x2001, 0x0002, 0x080c, 0x66fa, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0428, 0x2009, 0x026e, + 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, + 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a, 0x0098, + 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900, 0x0158, + 0x908e, 0x1e00, 0x0990, 0x080c, 0x3315, 0x080c, 0xd65a, 0x2001, + 0x0001, 0x080c, 0xbe21, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, + 0x00b6, 0x0026, 0x9016, 0x080c, 0xc082, 0x00d6, 0x2069, 0x197c, + 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, + 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, + 0x00de, 0x0088, 0x9006, 0x080c, 0x66e6, 0x2001, 0x0002, 0x080c, + 0x66fa, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x961e, 0x080c, + 0x9ab3, 0x0804, 0xc00c, 0x080c, 0xcf1b, 0x01b0, 0x6014, 0x2048, + 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, + 0x0002, 0x080c, 0xd57c, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, + 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, + 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, + 0x9006, 0x0c38, 0x080c, 0xbb5c, 0x2009, 0x026e, 0x2134, 0x96b4, + 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, + 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, + 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, + 0x080c, 0x66fa, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, + 0x2001, 0x0001, 0x080c, 0xbe21, 0x002e, 0x00be, 0x009e, 0x0005, + 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0140, + 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, + 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, + 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, + 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6130, 0x00ee, + 0x0010, 0x080c, 0x3315, 0x0860, 0x2001, 0x0004, 0x080c, 0x66fa, + 0x080c, 0xc082, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, + 0x961e, 0x0804, 0x9ab3, 0x080c, 0xbb5c, 0x9006, 0x0804, 0xbe21, + 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66fa, 0x6003, 0x0001, + 0x6007, 0x0005, 0x080c, 0x961e, 0x0804, 0x9ab3, 0x2001, 0x0001, + 0x0804, 0xbe21, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x66fa, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x0804, 0x9ab3, + 0x2001, 0x0001, 0x0804, 0xbe21, 0x2009, 0x026e, 0x2104, 0x9086, + 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, + 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, + 0x6110, 0x2158, 0x080c, 0x67c3, 0x001e, 0x00ce, 0x00be, 0x0005, + 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, + 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xc12d, + 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6c0d, + 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xea8d, 0x2001, + 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, + 0x080c, 0x32da, 0x00e6, 0x2071, 0x1800, 0x080c, 0x30bf, 0x00ee, + 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x341e, + 0x8108, 0x1f04, 0xc0c6, 0x015e, 0x00ce, 0x080c, 0xc085, 0x2071, + 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, + 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, + 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x9184, + 0x0050, 0x9086, 0x0050, 0x05d0, 0x2079, 0x0100, 0x2e04, 0x9084, + 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, + 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084, + 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084, + 0x00ff, 0x2008, 0x080c, 0x26d5, 0x080c, 0x779e, 0x0170, 0x2071, + 0x0260, 0x2069, 0x1982, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050, + 0x680a, 0x7054, 0x680e, 0x080c, 0xd348, 0x0040, 0x2001, 0x0006, + 0x080c, 0x66fa, 0x080c, 0x3344, 0x080c, 0xb16c, 0x001e, 0x003e, + 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036, + 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071, + 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205, + 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019, + 0x000a, 0x080c, 0xc222, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x2019, 0x0006, 0x080c, 0xc222, 0x1100, 0x015e, 0x00ee, 0x003e, + 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086, + 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec, + 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4, + 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee, + 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, + 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f4, 0x252c, 0x2021, + 0x19fb, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7254, 0x7074, + 0x9202, 0x1a04, 0xc1ee, 0x080c, 0x8eee, 0x0904, 0xc1e7, 0x080c, + 0xeabe, 0x0904, 0xc1e7, 0x6720, 0x9786, 0x0007, 0x0904, 0xc1e7, + 0x2500, 0x9c06, 0x0904, 0xc1e7, 0x2400, 0x9c06, 0x0904, 0xc1e7, + 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, + 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, 0x6043, 0xffff, + 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1ad3, 0x9786, 0x000a, + 0x0148, 0x080c, 0xd132, 0x1130, 0x00ce, 0x080c, 0xbb5c, 0x080c, + 0xb1a7, 0x00e8, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x01a8, 0x9786, + 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, + 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000, + 0x080c, 0x7006, 0x080c, 0xd10c, 0x080c, 0xb1a7, 0x00ce, 0x9ce0, + 0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xc18e, 0x012e, 0x000e, + 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, + 0x9786, 0x0006, 0x1118, 0x080c, 0xea30, 0x0c30, 0x9786, 0x0009, + 0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, + 0xb20a, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, + 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xc20e, 0x9006, 0x0005, + 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, + 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, + 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, + 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, + 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, + 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, + 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, + 0x1130, 0x8210, 0x8318, 0x1f04, 0xc24c, 0x9006, 0x0005, 0x918d, + 0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x080c, + 0xd121, 0x0120, 0x080c, 0xd132, 0x0158, 0x0028, 0x080c, 0x3344, + 0x080c, 0xd132, 0x0128, 0x080c, 0x99ed, 0x080c, 0xb16c, 0x0005, + 0x080c, 0xbb5c, 0x0cc0, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, + 0x0208, 0x000a, 0x0005, 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, + 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, 0xc292, 0xc294, 0xc294, + 0xc294, 0xc294, 0xc292, 0xc292, 0xc292, 0xc294, 0xc292, 0xc292, + 0xc292, 0xc292, 0x080c, 0x0d85, 0x600b, 0xffff, 0x6003, 0x000f, + 0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd65d, 0x2009, 0x8000, + 0x080c, 0x9617, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, + 0x9082, 0x0040, 0x0804, 0xc31c, 0x9186, 0x0027, 0x1520, 0x080c, + 0x99ed, 0x080c, 0x3315, 0x080c, 0xd65a, 0x0096, 0x6114, 0x2148, + 0x080c, 0xcf1b, 0x0198, 0x080c, 0xd132, 0x1118, 0x080c, 0xbb5c, + 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c, + 0xc1c5, 0xa97e, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, + 0xb16c, 0x0804, 0x9ab3, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082, + 0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c, 0x0d85, 0x0005, + 0x0002, 0xc2fa, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, + 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, 0xc313, 0xc313, 0xc313, 0xc313, + 0xc2f8, 0xc313, 0xc2f8, 0xc313, 0xc2f8, 0xc2f8, 0xc2f8, 0xc2f8, + 0x080c, 0x0d85, 0x080c, 0x99ed, 0x0096, 0x6114, 0x2148, 0x080c, + 0xcf1b, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, + 0xa880, 0xc0ec, 0xa882, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, + 0x080c, 0xb16c, 0x0005, 0x080c, 0x99ed, 0x080c, 0xd132, 0x090c, + 0xbb5c, 0x080c, 0xb16c, 0x0005, 0x0002, 0xc336, 0xc334, 0xc334, + 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, 0xc334, + 0xc338, 0xc338, 0xc338, 0xc338, 0xc334, 0xc33a, 0xc334, 0xc338, + 0xc334, 0xc334, 0xc334, 0xc334, 0x080c, 0x0d85, 0x080c, 0x0d85, + 0x080c, 0x0d85, 0x080c, 0xb16c, 0x0804, 0x9ab3, 0x9182, 0x0057, + 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc35d, 0xc35d, + 0xc35d, 0xc35d, 0xc35d, 0xc396, 0xc488, 0xc35d, 0xc494, 0xc35d, + 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, 0xc35d, + 0xc35d, 0xc494, 0xc35f, 0xc35d, 0xc492, 0x080c, 0x0d85, 0x00b6, + 0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1508, + 0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x080c, 0x6e27, + 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0, + 0x9005, 0x0110, 0x080c, 0x68df, 0x080c, 0xb16c, 0x009e, 0x00be, + 0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, 0x9105, 0x09c0, + 0xa880, 0xd0bc, 0x19a8, 0x080c, 0xd267, 0x0c80, 0x00b6, 0x0096, + 0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, 0x9036, + 0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058, 0xb800, 0xd0bc, + 0x1904, 0xc477, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, + 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x080c, + 0x6e27, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, + 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68df, 0x601c, 0xd0fc, 0x1148, + 0x7044, 0xd0e4, 0x1904, 0xc458, 0x080c, 0xb16c, 0x009e, 0x00be, + 0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d85, 0x968c, 0x0c00, + 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc45c, 0x7348, + 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508, + 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, + 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100, + 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118, + 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, + 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4, + 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, + 0x0804, 0xc3a2, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, + 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, + 0x0025, 0x080c, 0xca7b, 0x003e, 0xd6cc, 0x0904, 0xc3b7, 0x7154, + 0xa98a, 0x81ff, 0x0904, 0xc3b7, 0x9192, 0x0021, 0x1278, 0x8304, + 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca7b, 0x2011, 0x0205, + 0x2013, 0x0000, 0x080c, 0xd5e8, 0x0804, 0xc3b7, 0xa868, 0xd0fc, + 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c, + 0xca1a, 0x00ae, 0x080c, 0xd5e8, 0x080c, 0xca6b, 0x0804, 0xc3b9, + 0x080c, 0xd22a, 0x0804, 0xc3ce, 0xa87c, 0xd0ac, 0x0904, 0xc3df, + 0xa880, 0xd0bc, 0x1904, 0xc3df, 0x9684, 0x0400, 0x0130, 0xa838, + 0xab34, 0x9305, 0x0904, 0xc3df, 0x00b8, 0x7348, 0xa838, 0x9306, + 0x1198, 0x734c, 0xa834, 0x931e, 0x0904, 0xc3df, 0x0068, 0xa87c, + 0xd0ac, 0x0904, 0xc3aa, 0xa838, 0xa934, 0x9105, 0x0904, 0xc3aa, + 0xa880, 0xd0bc, 0x1904, 0xc3aa, 0x080c, 0xd267, 0x0804, 0xc3ce, + 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x00fe, + 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, 0x6003, 0x0002, + 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0128, 0x009e, + 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, + 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac46, + 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, 0xad25, 0x604b, + 0x0000, 0x080c, 0x1c9c, 0x1118, 0x6144, 0x080c, 0x9643, 0x009e, + 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, + 0x0005, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, + 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e2, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, + 0xc4f3, 0xc4e0, 0xc4e0, 0xc4e0, 0xc4e0, 0xc517, 0xc4e0, 0xc4e0, + 0x080c, 0x0d85, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, 0x99ed, + 0x2019, 0x0001, 0x080c, 0xa596, 0x6003, 0x0002, 0x080c, 0xd662, + 0x080c, 0x9a48, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c, + 0x99ed, 0x2019, 0x0001, 0x080c, 0xa596, 0x080c, 0x9a48, 0x080c, + 0x3315, 0x080c, 0xd65a, 0x0096, 0x6114, 0x2148, 0x080c, 0xcf1b, + 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, + 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, 0xb16c, 0x0005, 0x080c, + 0x0d85, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, + 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009, 0x1a7c, + 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, + 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc551, 0xc54f, 0xc54f, + 0xc60e, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, 0xc54f, + 0xc54f, 0xc54f, 0xc54f, 0xc74e, 0xc54f, 0xc758, 0xc54f, 0x080c, + 0x0d85, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4, 0x0120, + 0xc084, 0x601e, 0x0804, 0xc33e, 0x6114, 0x0096, 0x2148, 0xa87c, + 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, + 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, + 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, + 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, + 0x86ff, 0x0904, 0xc607, 0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, + 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904, 0xc607, + 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, + 0x0c38, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, 0xb07a, 0xb77c, + 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, + 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635, 0xae76, + 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, + 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, + 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, + 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, + 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, + 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, + 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xca7b, 0x003e, + 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, + 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xca7b, + 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, + 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xca1a, 0x080c, + 0x1a9f, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001, 0x1988, + 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, + 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c, 0xd66b, + 0x0904, 0xc749, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, + 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc70d, 0xa978, 0xa868, + 0xd0fc, 0x0904, 0xc6ce, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, + 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, + 0xc69b, 0x9086, 0x0028, 0x1904, 0xc687, 0xa87b, 0x001c, 0xb07b, + 0x001c, 0x0804, 0xc6a3, 0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, + 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, + 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, + 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, + 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be, 0x601c, + 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, + 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, + 0x080c, 0x100b, 0x009e, 0x080c, 0xd267, 0x0804, 0xc749, 0xd1dc, + 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd508, 0x0118, + 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, + 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, + 0x9115, 0x190c, 0xc519, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, + 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, + 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, + 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, + 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd5e8, 0x001e, 0xa874, 0x0006, + 0x2148, 0x080c, 0x100b, 0x001e, 0x0804, 0xc73a, 0x0016, 0x00a6, + 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, + 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, + 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd508, 0x0118, + 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, + 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, + 0x9115, 0x190c, 0xc519, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, + 0xb07e, 0x00ae, 0x080c, 0x100b, 0x009e, 0x080c, 0xd5e8, 0xa974, + 0x0016, 0x080c, 0xca6b, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, + 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, + 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, + 0xd508, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, + 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, + 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0xa974, 0x0016, 0x080c, + 0x6e27, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, 0xb8d0, 0x0016, + 0x9005, 0x190c, 0x68df, 0x001e, 0x00be, 0xd1e4, 0x1120, 0x080c, + 0xb16c, 0x009e, 0x0005, 0x080c, 0xd22a, 0x0cd8, 0x6114, 0x0096, + 0x2148, 0xa97c, 0x080c, 0xd66b, 0x190c, 0x1abf, 0x009e, 0x0005, + 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8, 0xa877, + 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, 0x6010, 0x2058, + 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6e27, 0xba3c, 0x8211, + 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68df, 0x080c, + 0xb16c, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e, 0x08f8, + 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc519, 0x0c28, 0xa880, + 0xd0bc, 0x1dc8, 0x080c, 0xd267, 0x0c60, 0x080c, 0x99ed, 0x0010, + 0x080c, 0x9a48, 0x601c, 0xd084, 0x0110, 0x080c, 0x1ad3, 0x080c, + 0xcf1b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xd132, 0x1118, + 0x080c, 0xbb5c, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c, + 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, 0x918e, 0x0029, + 0x1110, 0x080c, 0xeddf, 0xa877, 0x0000, 0x080c, 0x7012, 0x009e, + 0x0804, 0xb1a7, 0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004, 0x0c98, + 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, + 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7e1, 0xc7df, 0xc7df, + 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc7df, + 0xc7df, 0xc7df, 0xc7df, 0xc7df, 0xc805, 0xc7df, 0xc7df, 0x080c, + 0x0d85, 0x080c, 0x5848, 0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, + 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, + 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128, 0xa867, + 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, + 0x080c, 0x7012, 0x009e, 0x0804, 0xb16c, 0x080c, 0x5848, 0x0dd8, + 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, 0x0002, 0xc81e, + 0xc81c, 0xc81c, 0xc82a, 0xc81c, 0xc81c, 0xc81c, 0xc81c, 0xc81c, + 0xc81c, 0xc81c, 0xc81c, 0xc81c, 0x080c, 0x0d85, 0x6003, 0x0001, + 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9617, + 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, + 0x7224, 0x6216, 0x7220, 0x080c, 0xcf09, 0x01f8, 0x2268, 0x6800, + 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, + 0x2d60, 0x00d6, 0x080c, 0xcadc, 0x00de, 0x00ce, 0x0158, 0x702c, + 0xd084, 0x1118, 0x080c, 0xcaa6, 0x0010, 0x6803, 0x0002, 0x6007, + 0x0086, 0x0028, 0x080c, 0xcac8, 0x0d90, 0x6007, 0x0087, 0x6003, + 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x7220, 0x080c, 0xcf09, + 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, + 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xd267, 0x00ce, + 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, + 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, 0x1a0c, + 0x0d85, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, + 0x0014, 0x190c, 0x0d85, 0x080c, 0x99ed, 0x0096, 0x6014, 0x2048, + 0x080c, 0xcf1b, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, + 0x0029, 0x080c, 0x7012, 0x009e, 0x080c, 0xb1a7, 0x0804, 0x9ab3, + 0xc8ad, 0xc8af, 0xc8af, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, + 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0xc8ad, 0x080c, 0x0d85, 0x080c, + 0xb1a7, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082, 0x0085, + 0x2008, 0x0804, 0xc8fe, 0x9186, 0x0027, 0x1558, 0x080c, 0x99ed, + 0x080c, 0x3315, 0x080c, 0xd65a, 0x0096, 0x6014, 0x2048, 0x080c, + 0xcf1b, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, + 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x080c, 0xb16c, 0x0005, + 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c, 0xaf61, + 0x0128, 0x9086, 0x000c, 0x0904, 0xc936, 0x0000, 0x080c, 0xb227, + 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x99ed, 0x0096, 0x6014, + 0x2048, 0x080c, 0xcf1b, 0x0d00, 0xa867, 0x0103, 0xa877, 0x0000, + 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002, 0xc90e, + 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0xc922, 0xc90c, 0xc90c, + 0xc90c, 0xc90c, 0xc90c, 0xc90c, 0x080c, 0x0d85, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x2001, 0x1986, 0x0010, 0x2001, 0x1987, 0x2004, 0x601a, 0x6003, + 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, + 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1986, 0x0010, 0x2001, + 0x1987, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, 0x9182, 0x0092, + 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xb227, 0xc94c, + 0xc94c, 0xc94c, 0xc94c, 0xc94e, 0xc99b, 0xc94c, 0xc94c, 0xc94c, + 0xc94c, 0xc94c, 0xc94c, 0xc94c, 0x080c, 0x0d85, 0x0096, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, + 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, + 0x009e, 0x0804, 0xc9af, 0x080c, 0xcf1b, 0x1118, 0x080c, 0xd10c, + 0x0068, 0x6014, 0x2048, 0x080c, 0xd671, 0x1110, 0x080c, 0xd10c, + 0xa867, 0x0103, 0x080c, 0xd625, 0x080c, 0x7012, 0x00d6, 0x2c68, + 0x080c, 0xb116, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, + 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, + 0x613e, 0x6910, 0x6112, 0x080c, 0xd3b6, 0x695c, 0x615e, 0x6023, + 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x2d60, 0x00de, 0x080c, + 0xb16c, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, + 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, + 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, + 0x2c68, 0x080c, 0xd5bb, 0x11f0, 0x080c, 0xb116, 0x01d8, 0x6106, + 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c, 0x612e, + 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, + 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd3b6, 0x2009, 0x8020, + 0x080c, 0x9617, 0x2d60, 0x00de, 0x0804, 0xb16c, 0x0096, 0x6014, + 0x2048, 0x080c, 0xcf1b, 0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, + 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, + 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd226, 0xa877, + 0x0000, 0x080c, 0x7012, 0x080c, 0xd10c, 0x009e, 0x0804, 0xb16c, + 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0140, 0xa867, + 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x7012, 0x009e, + 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130, 0x9186, + 0x0027, 0x0118, 0x080c, 0xb227, 0x0020, 0x080c, 0x99ed, 0x080c, + 0xb1a7, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, + 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x8304, + 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c, 0xca7b, + 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b, 0x080c, + 0x1059, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, + 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b, 0x0499, + 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, + 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, + 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, + 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, + 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, + 0x0130, 0xa807, 0x0000, 0x080c, 0x7012, 0x2a48, 0x0cb8, 0x080c, + 0x7012, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, + 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, + 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, + 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148, 0x2018, + 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, + 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, + 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, + 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0150, 0x2001, + 0x0006, 0xa980, 0xc1d5, 0x080c, 0x725e, 0x080c, 0x7006, 0x080c, + 0xd10c, 0x009e, 0x080c, 0xb1a7, 0x00ee, 0x00de, 0x00ce, 0x0005, + 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020, 0x9086, + 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186, 0x008b, + 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091, 0x8000, + 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e, 0x006e, + 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000, 0x6020, + 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xcb2a, 0xcb2a, + 0xcb25, 0xcb4e, 0xcb06, 0xcb25, 0xcb08, 0xcb25, 0xcb25, 0x9458, + 0xcb25, 0xcb25, 0xcb25, 0xcb06, 0xcb06, 0xcb06, 0x080c, 0x0d85, + 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, 0xcb4e, 0x0036, + 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, 0x0118, 0x2019, + 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, 0x0010, 0x2019, + 0x0010, 0x080c, 0xe578, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, + 0xcf1b, 0x01d0, 0x6043, 0xffff, 0xa864, 0x9086, 0x0139, 0x1128, + 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, + 0x080c, 0x725e, 0x080c, 0xd226, 0x080c, 0x7006, 0x080c, 0xb1a7, + 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c, 0xacfc, + 0x080c, 0xd67f, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x002b, 0x0106, + 0x080c, 0xad18, 0x010e, 0x0005, 0xcb6c, 0xcb9c, 0xcb6e, 0xcbc3, + 0xcb97, 0xcb6c, 0xcb25, 0xcb2a, 0xcb2a, 0xcb25, 0xcb25, 0xcb25, + 0xcb25, 0xcb25, 0xcb25, 0xcb25, 0x080c, 0x0d85, 0x86ff, 0x1520, + 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, + 0xcf1b, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, + 0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0x080c, 0xd226, 0x009e, + 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x2009, 0x8020, 0x080c, 0x95f9, 0x9085, 0x0001, 0x0005, 0x0066, + 0x080c, 0x1ad3, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e8, 0x7030, + 0x9c06, 0x1120, 0x080c, 0xa516, 0x00ee, 0x0840, 0x6020, 0x9084, + 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, + 0x2c40, 0x080c, 0xa667, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, + 0xa412, 0x190c, 0x0d85, 0x080c, 0xa420, 0x006e, 0x00ee, 0x1904, + 0xcb6e, 0x0804, 0xcb25, 0x0036, 0x00e6, 0x2071, 0x19e8, 0x704c, + 0x9c06, 0x1138, 0x901e, 0x080c, 0xa596, 0x00ee, 0x003e, 0x0804, + 0xcb6e, 0x080c, 0xa7a1, 0x00ee, 0x003e, 0x1904, 0xcb6e, 0x0804, + 0xcb25, 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, + 0x00ce, 0x0005, 0xcbf9, 0xcce2, 0xce50, 0xcc01, 0xb1a7, 0xcbf9, + 0xe56e, 0xd667, 0xcce2, 0x941f, 0xcedc, 0xcbf2, 0xcbf2, 0xcbf2, + 0xcbf2, 0xcbf2, 0x080c, 0x0d85, 0x080c, 0xd132, 0x1110, 0x080c, + 0xbb5c, 0x0005, 0x080c, 0x99ed, 0x0804, 0xb16c, 0x601b, 0x0001, + 0x0005, 0x080c, 0xcf1b, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, + 0xa896, 0x009e, 0x080c, 0xacfc, 0x080c, 0xd67f, 0x908a, 0x0010, + 0x1a0c, 0x0d85, 0x0013, 0x0804, 0xad18, 0xcc25, 0xcc27, 0xcc51, + 0xcc65, 0xcc92, 0xcc25, 0xcbf9, 0xcbf9, 0xcbf9, 0xcc6c, 0xcc6c, + 0xcc25, 0xcc25, 0xcc25, 0xcc25, 0xcc76, 0x080c, 0x0d85, 0x00e6, + 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, + 0x19e8, 0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa412, 0x190c, + 0x0d85, 0x080c, 0xa420, 0x006e, 0x080c, 0xd5ff, 0x6007, 0x0085, + 0x6003, 0x000b, 0x6023, 0x0002, 0x2001, 0x1987, 0x2004, 0x601a, + 0x2009, 0x8020, 0x080c, 0x95f9, 0x00ee, 0x0005, 0x601b, 0x0001, + 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, + 0x080c, 0xd5ff, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, + 0x2009, 0x8020, 0x080c, 0x95f9, 0x0005, 0x080c, 0xacfc, 0x080c, + 0xaee3, 0x080c, 0xad18, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, + 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5848, + 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, + 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, + 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x7012, 0x009e, + 0x0804, 0xb16c, 0x6014, 0x0096, 0x904d, 0x0904, 0xccdd, 0xa97c, + 0xd1e4, 0x1160, 0x611c, 0xd1fc, 0x0904, 0xccdd, 0x6110, 0x00b6, + 0x2158, 0xb93c, 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c, 0xad18, + 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, + 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030, + 0x2c08, 0x080c, 0x16b9, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041, + 0x1198, 0x6014, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa880, 0xd0f4, + 0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0068, 0x009e, + 0x00c6, 0x080c, 0x2185, 0x00ce, 0x6000, 0x9086, 0x0004, 0x1120, + 0x2009, 0x0048, 0x080c, 0xb20a, 0x0005, 0x009e, 0x080c, 0x1ad3, + 0x0804, 0xcc51, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x000b, + 0x0005, 0xccf9, 0xcbfe, 0xccfb, 0xccf9, 0xccfb, 0xccfb, 0xcbfa, + 0xccf9, 0xcbf4, 0xcbf4, 0xccf9, 0xccf9, 0xccf9, 0xccf9, 0xccf9, + 0xccf9, 0x080c, 0x0d85, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, + 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0d85, 0x00b6, 0x0013, + 0x00be, 0x0005, 0xcd16, 0xcde7, 0xcd18, 0xcd58, 0xcd18, 0xcd58, + 0xcd18, 0xcd26, 0xcd16, 0xcd58, 0xcd16, 0xcd47, 0x080c, 0x0d85, + 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, + 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcde3, 0x6004, 0x080c, + 0xd132, 0x0904, 0xce00, 0x908e, 0x0004, 0x1110, 0x080c, 0x3344, + 0x908e, 0x0021, 0x0904, 0xce04, 0x908e, 0x0022, 0x0904, 0xce4b, + 0x908e, 0x003d, 0x0904, 0xce04, 0x908e, 0x0039, 0x0904, 0xce08, + 0x908e, 0x0035, 0x0904, 0xce08, 0x908e, 0x001e, 0x0178, 0x908e, + 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, + 0x0006, 0x0110, 0x080c, 0x3315, 0x080c, 0xbb5c, 0x0804, 0xb1a7, + 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcdd4, 0x9186, + 0x0002, 0x1904, 0xcda9, 0x2001, 0x1837, 0x2004, 0xd08c, 0x11c8, + 0x080c, 0x779e, 0x11b0, 0x080c, 0xd645, 0x0138, 0x080c, 0x77c1, + 0x1120, 0x080c, 0x76a7, 0x0804, 0xce34, 0x2001, 0x197d, 0x2003, + 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x76cd, 0x0804, + 0xce34, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x0080, 0x0130, 0x2001, + 0x1837, 0x2004, 0xd0ac, 0x1904, 0xce34, 0xb8a0, 0x9082, 0x0081, + 0x1a04, 0xce34, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, + 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, + 0x0000, 0x080c, 0xb116, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, + 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, + 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104, + 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6130, 0x00ee, + 0x080c, 0xbb5c, 0x0030, 0x080c, 0xbb5c, 0x080c, 0x3315, 0x080c, + 0xd65a, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3344, 0x012e, + 0x00ee, 0x080c, 0xb1a7, 0x0005, 0x2001, 0x0002, 0x080c, 0x66fa, + 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, + 0x00de, 0x00ce, 0x0c80, 0x080c, 0x3344, 0x0804, 0xcd54, 0x00c6, + 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, + 0x9084, 0x00ff, 0x9005, 0x0904, 0xcda9, 0x8001, 0xb842, 0x6003, + 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00de, 0x00ce, 0x0898, + 0x080c, 0xbb5c, 0x0804, 0xcd56, 0x080c, 0xbb98, 0x0804, 0xcd56, + 0x00d6, 0x2c68, 0x6104, 0x080c, 0xd5bb, 0x00de, 0x0118, 0x080c, + 0xb16c, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, + 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c, + 0x600a, 0x2001, 0x1987, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, + 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x2009, + 0x8020, 0x080c, 0x9617, 0x0005, 0x00de, 0x00ce, 0x080c, 0xbb5c, + 0x080c, 0x3315, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x3344, + 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000, + 0x012e, 0x00ee, 0x0005, 0x080c, 0xb5a8, 0x1904, 0xce00, 0x0005, + 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, 0x0096, 0x00d6, 0x001b, + 0x00de, 0x009e, 0x0005, 0xce6b, 0xce6b, 0xce6b, 0xce6b, 0xce6b, + 0xce6b, 0xce6b, 0xce6b, 0xce6b, 0xcbf9, 0xce6b, 0xcbfe, 0xce6d, + 0xcbfe, 0xce87, 0xce6b, 0x080c, 0x0d85, 0x6004, 0x9086, 0x008b, + 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130, + 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b, + 0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9617, 0x0005, 0x080c, + 0xd639, 0x0118, 0x080c, 0xd64c, 0x0010, 0x080c, 0xd65a, 0x080c, + 0xd10c, 0x080c, 0xcf1b, 0x0570, 0x080c, 0x3315, 0x080c, 0xcf1b, + 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, + 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x7012, 0x2c68, 0x080c, + 0xb116, 0x0150, 0x6810, 0x6012, 0x080c, 0xd3b6, 0x00c6, 0x2d60, + 0x080c, 0xb1a7, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, + 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, + 0x9ab3, 0x00c8, 0x080c, 0xd639, 0x0138, 0x6034, 0x9086, 0x4000, + 0x1118, 0x080c, 0x3315, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, + 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3315, + 0x0868, 0x080c, 0xb1a7, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, + 0x0d85, 0x0002, 0xcef2, 0xcef2, 0xcefa, 0xcef4, 0xcf04, 0xcef2, + 0xcef2, 0xb1a7, 0xcef2, 0xcef2, 0xcef2, 0xcef2, 0xcef2, 0xcef2, + 0xcef2, 0xcef2, 0x080c, 0x0d85, 0x080c, 0xacfc, 0x080c, 0xaee3, + 0x080c, 0xad18, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, + 0x7012, 0x009e, 0x0804, 0xb16c, 0x601c, 0xd084, 0x190c, 0x1ad3, + 0x0c88, 0x9284, 0x0003, 0x1158, 0x9282, 0x1ddc, 0x0240, 0x2001, + 0x181a, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, + 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, + 0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x1104, + 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, + 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7354, 0x7074, + 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd645, 0x0180, + 0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, + 0x3315, 0x080c, 0xd65a, 0x00c6, 0x080c, 0xb1a7, 0x00ce, 0x0060, + 0x080c, 0xd328, 0x0148, 0x080c, 0xd132, 0x1110, 0x080c, 0xbb5c, + 0x00c6, 0x080c, 0xb16c, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, + 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, + 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, + 0x2061, 0x1b39, 0x6112, 0x080c, 0x3315, 0x9006, 0x0010, 0x9085, + 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xb116, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, + 0x5848, 0x0118, 0x080c, 0xd04e, 0x0168, 0x080c, 0xd3b6, 0x6023, + 0x0003, 0x2009, 0x004b, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, + 0xbaa0, 0x080c, 0xb1dd, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, + 0x080c, 0xd3b6, 0x6023, 0x0003, 0x0016, 0x080c, 0xacfc, 0x080c, + 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, + 0x007e, 0x080c, 0xad18, 0x001e, 0xd184, 0x0128, 0x080c, 0xb16c, + 0x9085, 0x0001, 0x0070, 0x080c, 0x5848, 0x0128, 0xd18c, 0x1170, + 0x080c, 0xd04e, 0x0148, 0x2009, 0x004c, 0x080c, 0xb20a, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, + 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, + 0x0046, 0x0016, 0x080c, 0xb116, 0x2c78, 0x05a0, 0x7e5e, 0x2b00, + 0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xd060, + 0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, + 0x1980, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb16c, 0x00d0, + 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb16c, + 0x0088, 0x2f60, 0x080c, 0x5848, 0x0138, 0xd18c, 0x1118, 0x04f1, + 0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb20a, + 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, + 0x00c6, 0x0046, 0x080c, 0xb116, 0x2c78, 0x0508, 0x7e5e, 0x2b00, + 0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, + 0x2001, 0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb16c, + 0x0060, 0x2f60, 0x080c, 0x5848, 0x0120, 0xd18c, 0x1160, 0x0071, + 0x0130, 0x2009, 0x0052, 0x080c, 0xb20a, 0x9085, 0x0001, 0x004e, + 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, + 0x4c41, 0x00ce, 0x1120, 0x080c, 0xb16c, 0x9006, 0x0005, 0xa867, + 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, + 0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xacfc, 0x080c, + 0x699d, 0x0158, 0x2001, 0xd067, 0x0006, 0x900e, 0x2400, 0x080c, + 0x725e, 0x080c, 0x7012, 0x000e, 0x0807, 0x2418, 0x080c, 0x99b3, + 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, + 0x97ca, 0x008e, 0x080c, 0x966d, 0x2f08, 0x2648, 0x080c, 0xe75d, + 0xb93c, 0x81ff, 0x090c, 0x98a3, 0x080c, 0xad18, 0x012e, 0x007e, + 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, + 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, + 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, + 0x8000, 0x080c, 0xb1dd, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, + 0xd3b6, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, + 0x17ad, 0x00fe, 0x2009, 0x0021, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, + 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0xb116, 0x0198, 0x660a, + 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x2900, 0x6016, + 0x001e, 0x0016, 0x080c, 0xb20a, 0x9085, 0x0001, 0x001e, 0x012e, + 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x080c, 0xb1dd, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, + 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xb20a, 0x9085, + 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, + 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, + 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e, 0x1140, 0xb8d0, 0x9005, + 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b, 0x0001, 0x00be, 0x002e, + 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, + 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, + 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, + 0x01a8, 0x6014, 0x904d, 0x080c, 0xcf1b, 0x0180, 0xa864, 0x9086, + 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, + 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, + 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, + 0x080c, 0xb1dd, 0x0198, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, + 0x0001, 0x2900, 0x6016, 0x080c, 0x3315, 0x2009, 0x0028, 0x080c, + 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, + 0x1178, 0x00b6, 0x080c, 0xbe09, 0x00be, 0x080c, 0xc085, 0x6003, + 0x0001, 0x6007, 0x0029, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0078, + 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, + 0x0001, 0x080c, 0xd57c, 0x080c, 0xbb5c, 0x080c, 0xb16c, 0x0005, + 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, + 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x009e, 0x080c, 0xb16c, + 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, + 0x66fa, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, + 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x684f, + 0x00be, 0x080c, 0xc15b, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, + 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x66fa, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xb57c, 0x0048, 0x6014, + 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xbb5c, 0x080c, 0xb16c, + 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d85, + 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, + 0x6aae, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, + 0x0126, 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, + 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d85, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, + 0x2091, 0x8000, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, 0x0840, + 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, + 0xa882, 0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, + 0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9617, 0x0005, 0x00c6, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066, + 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xcbf9, + 0xd259, 0xd259, 0xd25c, 0xeadc, 0xeaf7, 0xeafa, 0xcbf9, 0xcbf9, + 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0xcbf9, 0x080c, + 0x0d85, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, + 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, + 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1834, + 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xb116, 0x0508, + 0x7810, 0x6012, 0x080c, 0xd3b6, 0x7820, 0x9086, 0x0003, 0x0128, + 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, + 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, + 0x795c, 0x615e, 0x2009, 0x8020, 0x080c, 0x9617, 0x2f60, 0x00fe, + 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1988, 0x2004, 0x604a, 0x0005, + 0x0016, 0x0096, 0x6814, 0x2048, 0x681c, 0xd0fc, 0xc0fc, 0x681e, + 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, + 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, + 0xa878, 0x2048, 0x080c, 0x100b, 0x6830, 0x6036, 0x908e, 0x0001, + 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, + 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, + 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, + 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, + 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, + 0x6910, 0x6112, 0x695c, 0x615e, 0x6023, 0x0001, 0x6007, 0x0039, + 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x009e, 0x001e, + 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, + 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, + 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, + 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, + 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, + 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, + 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, + 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, + 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, + 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, + 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1982, 0x200c, + 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x955b, 0x2001, 0x1986, + 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1984, 0x200c, + 0x8000, 0x2014, 0x2071, 0x196c, 0x711a, 0x721e, 0x2001, 0x0064, + 0x080c, 0x955b, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, + 0x2202, 0x2001, 0x1988, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017, + 0x080c, 0xaced, 0x2001, 0x1a90, 0x2102, 0x2001, 0x0032, 0x080c, + 0x16b9, 0x080c, 0x6bf2, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, + 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1986, 0x2003, 0x0028, + 0x2001, 0x1987, 0x2003, 0x0014, 0x2071, 0x196c, 0x701b, 0x0000, + 0x701f, 0x07d0, 0x2001, 0x1988, 0x2009, 0x001e, 0x2102, 0x2001, + 0x0017, 0x080c, 0xaced, 0x2001, 0x1a90, 0x2102, 0x2001, 0x0032, + 0x080c, 0x16b9, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060, + 0x904d, 0x0110, 0x080c, 0x108b, 0x009e, 0x0005, 0x0005, 0x00c6, + 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, 0x0180, 0x2b08, 0x6112, + 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, + 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, + 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1520, + 0x7090, 0x9086, 0x0018, 0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, + 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9b83, + 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, + 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, + 0x3364, 0x080c, 0xb57c, 0x0020, 0x080c, 0xbb5c, 0x080c, 0xb16c, + 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, + 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb116, 0x0188, + 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, 0x0001, 0x2900, 0x6016, + 0x2009, 0x004d, 0x080c, 0xb20a, 0x9085, 0x0001, 0x012e, 0x00ce, + 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, + 0x080c, 0xb116, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd3b6, 0x6023, + 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xb20a, 0x9085, 0x0001, + 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, + 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, + 0x1800, 0x9186, 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814, + 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, + 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, + 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, + 0x2001, 0x19a1, 0x0016, 0x200c, 0x080c, 0xdca1, 0x001e, 0xa804, + 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, + 0x0010, 0x080c, 0xbb5c, 0x080c, 0xb16c, 0x00fe, 0x00ee, 0x009e, + 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096, + 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, + 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x9b83, + 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, + 0x1110, 0x080c, 0x3315, 0x080c, 0xb57c, 0x0020, 0x080c, 0xbb5c, + 0x080c, 0xb16c, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, + 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, + 0x9186, 0x0015, 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014, + 0x2048, 0x2c78, 0x080c, 0x9b83, 0x05f0, 0x707c, 0xaacc, 0x9206, + 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x3315, 0x0016, + 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x57e9, 0x001e, + 0x0010, 0x080c, 0x55cc, 0x080c, 0xcf1b, 0x0508, 0xa87b, 0x0000, + 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcf1b, 0x01b8, + 0x6014, 0x2048, 0x080c, 0x55cc, 0x1d70, 0xa87b, 0x0030, 0xa883, + 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, + 0xa867, 0x0139, 0x080c, 0x7012, 0x012e, 0x080c, 0xb16c, 0x00fe, + 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, + 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, + 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, + 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, + 0x00d6, 0x0036, 0x080c, 0xcf1b, 0x0904, 0xd578, 0x0096, 0x6314, + 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, + 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x6aae, + 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, + 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, + 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, + 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, + 0x000a, 0x2098, 0x080c, 0x0fd6, 0x00ce, 0x0090, 0xaa96, 0x3918, + 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, + 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, + 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x7006, 0x6017, 0x0000, 0x009e, + 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, + 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, + 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, + 0x268c, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, + 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4ca1, 0x00a8, 0x9096, + 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, + 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, + 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, + 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, + 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xcf09, 0x01f0, 0x2260, + 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, + 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, + 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, + 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, + 0xa974, 0xd1cc, 0x0198, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1170, + 0xa9a8, 0x918c, 0x000f, 0x918e, 0x0001, 0x1140, 0xa87c, 0xd0ac, + 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc519, 0x0005, 0x0036, + 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, + 0xcf1b, 0x01c8, 0x080c, 0xd10c, 0x6037, 0x4000, 0x6014, 0x6017, + 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xd132, 0x1118, 0x080c, + 0xbb5c, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, + 0x080c, 0x7012, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, + 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, + 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xd226, 0xa877, 0x0000, + 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, + 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, + 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, + 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4e58, 0x004e, + 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1986, 0x2004, + 0x601a, 0x0005, 0x2001, 0x1988, 0x2004, 0x604a, 0x0005, 0x080c, + 0xb16c, 0x0804, 0x9ab3, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4, + 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x601c, + 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x6044, + 0xd0fc, 0x1138, 0xd0bc, 0x01a0, 0xc0bc, 0x6046, 0x2001, 0x0002, + 0x0080, 0xd0ac, 0x1168, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186, + 0x0005, 0x1118, 0x2001, 0x0003, 0x0020, 0x2001, 0x0001, 0x0008, + 0x6000, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0010, 0x1a0c, + 0x0d85, 0x001b, 0x006e, 0x00be, 0x0005, 0xd6b5, 0xddfe, 0xdf62, + 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6ec, 0xdfe6, 0xd6b5, + 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0xd6b5, 0x080c, 0x0d85, 0x0066, + 0x6000, 0x90b2, 0x0010, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, + 0xd6d0, 0xe50b, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, 0xd6d0, + 0xe4ba, 0xe55d, 0xd6d0, 0xec10, 0xec44, 0xec10, 0xec44, 0xd6d0, + 0x080c, 0x0d85, 0x6000, 0x9082, 0x0010, 0x1a0c, 0x0d85, 0x6000, + 0x000a, 0x0005, 0xd6ea, 0xe1c3, 0xe28e, 0xe2b1, 0xe32d, 0xd6ea, + 0xe42a, 0xe3b5, 0xdff0, 0xe492, 0xe4a7, 0xd6ea, 0xd6ea, 0xd6ea, + 0xd6ea, 0xd6ea, 0x080c, 0x0d85, 0x91b2, 0x0053, 0x1a0c, 0x0d85, + 0x2100, 0x91b2, 0x0040, 0x1a04, 0xdb70, 0x0002, 0xd736, 0xd93e, + 0xd736, 0xd736, 0xd736, 0xd947, 0xd736, 0xd736, 0xd736, 0xd736, + 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, + 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xd738, 0xd79f, 0xd7ae, + 0xd812, 0xd83d, 0xd8b6, 0xd929, 0xd736, 0xd736, 0xd94a, 0xd736, + 0xd736, 0xd95f, 0xd96c, 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, + 0xda12, 0xd736, 0xd736, 0xda26, 0xd736, 0xd736, 0xd9e1, 0xd736, + 0xd736, 0xd736, 0xda3e, 0xd736, 0xd736, 0xd736, 0xdabb, 0xd736, + 0xd736, 0xd736, 0xd736, 0xd736, 0xd736, 0xdb38, 0x080c, 0x0d85, + 0x080c, 0x6bcf, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, + 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, + 0x0009, 0x6017, 0x0000, 0x0804, 0xd937, 0x080c, 0x6b6b, 0x00e6, + 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, + 0x2019, 0x0029, 0x080c, 0xacfc, 0x080c, 0x97b0, 0x0076, 0x903e, + 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, 0x001e, 0x080c, + 0xad18, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, + 0x080c, 0x67c3, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, + 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, + 0x080c, 0xee6f, 0x002e, 0x001e, 0x1178, 0x080c, 0xe68b, 0x1904, + 0xd80a, 0x080c, 0xe627, 0x1120, 0x6007, 0x0008, 0x0804, 0xd937, + 0x6007, 0x0009, 0x0804, 0xd937, 0x080c, 0xe905, 0x0128, 0x080c, + 0xe68b, 0x0d78, 0x0804, 0xd80a, 0x6017, 0x1900, 0x0c88, 0x080c, + 0x344c, 0x1904, 0xdb6d, 0x6106, 0x080c, 0xe5c7, 0x6007, 0x0006, + 0x0804, 0xd937, 0x6007, 0x0007, 0x0804, 0xd937, 0x080c, 0xec80, + 0x1904, 0xdb6d, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x00d6, 0x6610, + 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, + 0x0001, 0x080c, 0x66e6, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, + 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, + 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, + 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, + 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, + 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, + 0x080c, 0xe6f3, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, + 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3364, 0x002e, 0x080c, 0x684f, + 0x6007, 0x000a, 0x00de, 0x0804, 0xd937, 0x6007, 0x000b, 0x00de, + 0x0804, 0xd937, 0x080c, 0x3315, 0x080c, 0xd65a, 0x6007, 0x0001, + 0x0804, 0xd937, 0x080c, 0xec80, 0x1904, 0xdb6d, 0x080c, 0x344c, + 0x1904, 0xdb6d, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, + 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, + 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, + 0xbaa0, 0x900e, 0x080c, 0x3364, 0x002e, 0x6007, 0x000c, 0x2001, + 0x0001, 0x080c, 0xee4e, 0x0804, 0xd937, 0x080c, 0x6bcf, 0x1140, + 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, + 0x0804, 0xd745, 0x080c, 0x6b6b, 0x6610, 0x2658, 0xbe04, 0x9684, + 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, + 0x080c, 0x6726, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, + 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd80a, 0x080c, 0xe700, + 0x1120, 0x6007, 0x000e, 0x0804, 0xd937, 0x0046, 0x6410, 0x2458, + 0xbca0, 0x0046, 0x080c, 0x3315, 0x080c, 0xd65a, 0x004e, 0x0016, + 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, + 0x080c, 0xea8d, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, + 0x004e, 0x6007, 0x0001, 0x0804, 0xd937, 0x2001, 0x0001, 0x080c, + 0x66e6, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0270, 0x080c, 0xc20e, 0x003e, 0x002e, 0x001e, + 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, + 0x0a04, 0xd80a, 0x9682, 0x0007, 0x0a04, 0xd866, 0x0804, 0xd80a, + 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd937, 0x080c, 0x6bcf, + 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, + 0x1110, 0x0804, 0xd745, 0x080c, 0x6b6b, 0x6610, 0x2658, 0xbe04, + 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, + 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, + 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, + 0x0120, 0x9686, 0x0006, 0x1904, 0xd80a, 0x080c, 0xe72e, 0x1138, + 0x080c, 0xe627, 0x1120, 0x6007, 0x0010, 0x0804, 0xd937, 0x0046, + 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3315, 0x080c, 0xd65a, + 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, + 0x2009, 0x0029, 0x080c, 0xea8d, 0x6010, 0x2058, 0xb800, 0xc0e5, + 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe905, + 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, + 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, + 0x0920, 0x0804, 0xd80a, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, + 0x0070, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xec80, 0x1904, + 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, 0x6007, 0x0012, 0x6003, + 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x6007, 0x0001, + 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0cb0, 0x6007, + 0x0005, 0x0c68, 0x080c, 0xec80, 0x1904, 0xdb6d, 0x080c, 0x344c, + 0x1904, 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, 0x6007, 0x0020, + 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, + 0x344c, 0x1904, 0xdb6d, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, + 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, 0xec80, 0x1904, 0xdb6d, + 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, 0x1904, 0xd80a, + 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, + 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, + 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xcf09, 0x0570, + 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, + 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xb16c, 0x04a0, + 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xcf09, 0x01b0, + 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, + 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, + 0xea57, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, + 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, + 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, + 0x0024, 0x1110, 0x080c, 0xb16c, 0x2160, 0x6007, 0x0025, 0x6003, + 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00ee, 0x002e, 0x001e, + 0x0005, 0x2001, 0x0001, 0x080c, 0x66e6, 0x0156, 0x0016, 0x0026, + 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, + 0xc20e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, + 0x0804, 0xd937, 0x080c, 0xbe21, 0x080c, 0x779e, 0x1190, 0x0006, + 0x0026, 0x0036, 0x080c, 0x77b8, 0x1138, 0x080c, 0x7ab6, 0x080c, + 0x619d, 0x080c, 0x76cd, 0x0010, 0x080c, 0x7772, 0x003e, 0x002e, + 0x000e, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, + 0x1904, 0xd80a, 0x6106, 0x080c, 0xdd5a, 0x1120, 0x6007, 0x002b, + 0x0804, 0xd937, 0x6007, 0x002c, 0x0804, 0xd937, 0x080c, 0xec80, + 0x1904, 0xdb6d, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x080c, 0xdd3e, + 0x1904, 0xd80a, 0x6106, 0x080c, 0xdd5f, 0x1120, 0x6007, 0x002e, + 0x0804, 0xd937, 0x6007, 0x002f, 0x0804, 0xd937, 0x080c, 0x344c, + 0x1904, 0xdb6d, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, + 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, + 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd93e, + 0x080c, 0x5844, 0xd0e4, 0x0904, 0xdab8, 0x2071, 0x026c, 0x7010, + 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6c0d, 0x0140, + 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, + 0x080c, 0x6c09, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, + 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xcf09, 0x0590, 0x080c, + 0xdc2b, 0x0578, 0x080c, 0xeb09, 0x0560, 0x622e, 0x6007, 0x0036, + 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcf09, + 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, + 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xea57, 0x2c10, 0x2160, + 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, + 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, + 0x6007, 0x0012, 0x0868, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x6010, + 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, + 0xd93e, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x5844, 0xd0e4, 0x0904, + 0xdb30, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, + 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, + 0x0001, 0x080c, 0xea57, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcf09, + 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, + 0x0026, 0x2260, 0x080c, 0xcadc, 0x002e, 0x00ce, 0x7118, 0x918c, + 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, + 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, + 0x080c, 0xdc2b, 0x0904, 0xdab1, 0x0056, 0x7510, 0x7614, 0x080c, + 0xeb22, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, + 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, + 0x080c, 0x9617, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, + 0x0300, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x0c10, + 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xda88, + 0x00e6, 0x0026, 0x080c, 0x6bcf, 0x0550, 0x080c, 0x6b6b, 0x080c, + 0xecf1, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, + 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, + 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, + 0x0000, 0x080c, 0x6c0d, 0x0120, 0x2011, 0x1a0a, 0x2013, 0x07d0, + 0xd0ac, 0x1128, 0x080c, 0x30bf, 0x0010, 0x080c, 0xed25, 0x002e, + 0x00ee, 0x080c, 0xb16c, 0x0804, 0xd93d, 0x080c, 0xb16c, 0x0005, + 0x2600, 0x0002, 0xdb84, 0xdbb2, 0xdbc3, 0xdb84, 0xdb84, 0xdb86, + 0xdbd4, 0xdb84, 0xdb84, 0xdb84, 0xdba0, 0xdb84, 0xdb84, 0xdb84, + 0xdbdf, 0xdbf5, 0xdc26, 0xdb84, 0x080c, 0x0d85, 0x080c, 0xec80, + 0x1d20, 0x080c, 0x344c, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, + 0x6003, 0x0001, 0x080c, 0x961e, 0x0005, 0x080c, 0x3315, 0x080c, + 0xd65a, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x961e, 0x0005, + 0x080c, 0xec80, 0x1950, 0x080c, 0x344c, 0x1938, 0x080c, 0xdd3e, + 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, + 0x961e, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x2009, 0x0041, + 0x080c, 0xed2e, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x961e, + 0x080c, 0x9ab3, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, 0x2009, + 0x0042, 0x080c, 0xed2e, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, + 0x961e, 0x080c, 0x9ab3, 0x0005, 0x080c, 0x344c, 0x1904, 0xdb6d, + 0x2009, 0x0046, 0x080c, 0xed2e, 0x080c, 0xb16c, 0x0005, 0x2001, + 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xdc48, 0x0904, + 0xdb6d, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x961e, 0x080c, + 0x9ab3, 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, + 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, + 0x1160, 0x7140, 0x2001, 0x19be, 0x2004, 0x9106, 0x11b0, 0x7144, + 0x2001, 0x19bf, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, + 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, + 0x000a, 0x080c, 0xc222, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, + 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x0005, 0x6007, 0x0050, + 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, + 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, + 0x604c, 0x9106, 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, + 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, + 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, + 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, + 0x0000, 0x080c, 0x1072, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, + 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, + 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, + 0x1072, 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, + 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, + 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, + 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x100b, + 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, + 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, + 0x11b0, 0x080c, 0x21f9, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, + 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, + 0x22a8, 0x8108, 0x080c, 0x21f9, 0x2099, 0x0260, 0x0ca8, 0x080c, + 0x21f9, 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, + 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, + 0x8108, 0x080c, 0x21f9, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, + 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, + 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, + 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, + 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2211, + 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, + 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, + 0x080c, 0x2211, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2211, 0x2061, + 0x19a4, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, + 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, + 0x080c, 0x2211, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, + 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, + 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, + 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, + 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, + 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, + 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, + 0x00be, 0x0005, 0x00d6, 0x080c, 0xddd4, 0x00de, 0x0005, 0x00d6, + 0x080c, 0xdde1, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, + 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, + 0x080c, 0xee4e, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, + 0x918c, 0x00ff, 0x6824, 0x080c, 0x268c, 0x1148, 0x2001, 0x0001, + 0x080c, 0xee4e, 0x2110, 0x900e, 0x080c, 0x3364, 0x0018, 0x9085, + 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, + 0xb1dd, 0x0598, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, + 0x8211, 0x220c, 0x080c, 0x268c, 0x1568, 0x080c, 0x6749, 0x1550, + 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, + 0xec80, 0x11c8, 0x080c, 0x344c, 0x11b0, 0x080c, 0xdd3e, 0x0500, + 0x2001, 0x0007, 0x080c, 0x66fa, 0x2001, 0x0007, 0x080c, 0x6726, + 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, + 0x080c, 0x961e, 0x0010, 0x080c, 0xb16c, 0x9085, 0x0001, 0x00ce, + 0x00be, 0x0005, 0x080c, 0xb16c, 0x00ce, 0x002e, 0x001e, 0x0ca8, + 0x080c, 0xb16c, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, + 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, + 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, + 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, + 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, + 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, + 0x0053, 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, + 0x0040, 0x1a04, 0xdf36, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, + 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xaf61, 0x0120, + 0x9086, 0x0002, 0x0904, 0xbba3, 0x0005, 0x91b6, 0x0014, 0x190c, + 0x0d85, 0x2001, 0x0007, 0x080c, 0x6726, 0x080c, 0x99ed, 0x080c, + 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0xde6c, 0xde6e, 0xde6c, 0xde6c, + 0xde6c, 0xde6e, 0xde7b, 0xdf33, 0xdebd, 0xdf33, 0xdee1, 0xdf33, + 0xde7b, 0xdf33, 0xdf2b, 0xdf33, 0xdf2b, 0xdf33, 0xdf33, 0xde6c, + 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xde6c, + 0xde6c, 0xde6c, 0xde6e, 0xde6c, 0xdf33, 0xde6c, 0xde6c, 0xdf33, + 0xde6c, 0xdf30, 0xdf33, 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0xdf33, + 0xdf33, 0xde6c, 0xdf33, 0xdf33, 0xde6c, 0xde76, 0xde6c, 0xde6c, + 0xde6c, 0xde6c, 0xdf2f, 0xdf33, 0xde6c, 0xde6c, 0xdf33, 0xdf33, + 0xde6c, 0xde6c, 0xde6c, 0xde6c, 0x080c, 0x0d85, 0x080c, 0xd65d, + 0x6003, 0x0002, 0x080c, 0x9ab3, 0x0804, 0xdf35, 0x9006, 0x080c, + 0x66e6, 0x0804, 0xdf33, 0x080c, 0x6c09, 0x1904, 0xdf33, 0x9006, + 0x080c, 0x66e6, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x00b8, + 0x6010, 0x2058, 0xb884, 0x9005, 0x0904, 0xdf33, 0x080c, 0x347d, + 0x1904, 0xdf33, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, + 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, + 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x6110, 0x2158, 0x2009, + 0x0001, 0x080c, 0x89a1, 0x0804, 0xdf35, 0x6610, 0x2658, 0xbe04, + 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, + 0x0130, 0x080c, 0x9228, 0x2001, 0x0004, 0x080c, 0x6726, 0x080c, + 0xee9d, 0x0904, 0xdf33, 0x2001, 0x0004, 0x080c, 0x66fa, 0x6023, + 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x961e, 0x0804, + 0xdf35, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, + 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4e58, + 0x004e, 0x003e, 0x2001, 0x0006, 0x080c, 0xdf4f, 0x6610, 0x2658, + 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, + 0x0180, 0x2001, 0x0006, 0x080c, 0x6726, 0x9284, 0x00ff, 0x908e, + 0x0007, 0x0118, 0x908e, 0x0004, 0x1120, 0x2001, 0x0006, 0x080c, + 0x66fa, 0x080c, 0x6c09, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4, + 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6, + 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xdea7, + 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409, 0x0020, 0x0018, + 0x0010, 0x080c, 0x6726, 0x080c, 0xb16c, 0x0005, 0x2600, 0x0002, + 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4a, 0xdf4c, + 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4a, 0xdf4a, 0xdf4a, 0xdf4c, 0xdf4c, + 0xdf4c, 0xdf4c, 0x080c, 0x0d85, 0x080c, 0xb16c, 0x0005, 0x0016, + 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c, + 0x66fa, 0x9006, 0x080c, 0x66e6, 0x080c, 0x3344, 0x00de, 0x00be, + 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007, + 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x91b6, 0x0015, 0x1110, 0x003b, + 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x006b, 0x0005, 0xbc45, + 0xbc45, 0xbc45, 0xbc45, 0xdfe4, 0xbc45, 0xdfce, 0xdf8f, 0xbc45, + 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0xdfe4, + 0xbc45, 0xdfce, 0xdfd5, 0xbc45, 0xbc45, 0xbc45, 0xbc45, 0x00f6, + 0x080c, 0x6c09, 0x11d8, 0x080c, 0xd645, 0x11c0, 0x6010, 0x905d, + 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c, 0x66e6, 0x2001, + 0x0002, 0x080c, 0x66fa, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, + 0x0002, 0x080c, 0x961e, 0x080c, 0x9ab3, 0x00f0, 0x2011, 0x0263, + 0x2204, 0x8211, 0x220c, 0x080c, 0x268c, 0x11b0, 0x080c, 0x67b4, + 0x0118, 0x080c, 0xb16c, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006, + 0xb884, 0x0006, 0x080c, 0x61b7, 0x000e, 0xb886, 0x000e, 0xb816, + 0x000e, 0xb812, 0x080c, 0xb16c, 0x00fe, 0x0005, 0x6604, 0x96b6, + 0x001e, 0x1110, 0x080c, 0xb16c, 0x0005, 0x080c, 0xc082, 0x1148, + 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x961e, 0x080c, 0x9ab3, + 0x0010, 0x080c, 0xb16c, 0x0005, 0x0804, 0xb16c, 0x6004, 0x908a, + 0x0053, 0x1a0c, 0x0d85, 0x080c, 0x99ed, 0x080c, 0xb1a7, 0x0005, + 0x9182, 0x0040, 0x0002, 0xe007, 0xe007, 0xe007, 0xe007, 0xe009, + 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, + 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0xe007, 0x080c, + 0x0d85, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, + 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044, 0x2071, + 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xe070, 0x080c, 0xee42, + 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011, 0x0200, + 0x080c, 0x8c44, 0x0020, 0x9026, 0x080c, 0xecc5, 0x0c30, 0x080c, + 0x1059, 0x090c, 0x0d85, 0x6003, 0x0007, 0xa867, 0x010d, 0x9006, + 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2, 0x6010, + 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f, 0x0000, + 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x7012, 0x001e, 0x080c, + 0xee42, 0x1904, 0xe0d0, 0x9486, 0x2000, 0x1130, 0x2019, 0x0017, + 0x080c, 0xe9f9, 0x0804, 0xe0d0, 0x9486, 0x0200, 0x1120, 0x080c, + 0xe984, 0x0804, 0xe0d0, 0x9486, 0x0400, 0x0120, 0x9486, 0x1000, + 0x1904, 0xe0d0, 0x2019, 0x0002, 0x080c, 0xe9a3, 0x0804, 0xe0d0, + 0x2069, 0x1a73, 0x6a00, 0xd284, 0x0904, 0xe13a, 0x9284, 0x0300, + 0x1904, 0xe133, 0x6804, 0x9005, 0x0904, 0xe11b, 0x2d78, 0x6003, + 0x0007, 0x080c, 0x1072, 0x0904, 0xe0dc, 0x7800, 0xd08c, 0x1118, + 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f, 0x2004, + 0xd084, 0x1904, 0xe13e, 0x9006, 0xa802, 0xa867, 0x0116, 0xa86a, + 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0, 0x7130, + 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930, 0xa9c2, + 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003, 0x9080, + 0xe0d8, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270, 0xaa5c, + 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1, 0x0000, + 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000, 0x2001, + 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c, 0x7015, + 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e, 0x0005, + 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004, 0xd084, + 0x0120, 0x080c, 0x1059, 0x1904, 0xe085, 0x6017, 0xf100, 0x6003, + 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x0c00, + 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200, 0x1198, + 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700, 0x910d, + 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x2009, 0xa025, + 0x080c, 0x9617, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032, 0x6017, + 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, + 0x9617, 0x0804, 0xe0d0, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, + 0x2011, 0x8049, 0x080c, 0x4ca1, 0x6017, 0xf300, 0x0010, 0x6017, + 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, + 0x9617, 0x0804, 0xe0d0, 0x6017, 0xf500, 0x0c98, 0x6017, 0xf600, + 0x0804, 0xe0f0, 0x6017, 0xf200, 0x0804, 0xe0f0, 0xa867, 0x0146, + 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044, 0x9084, + 0x0003, 0x9080, 0xe0d8, 0x2005, 0xa87e, 0x2928, 0x6010, 0x2058, + 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830, 0xa892, + 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104, 0x9085, + 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214, 0x9294, + 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d85, 0x8210, 0x821c, + 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0029, + 0x20a0, 0x2011, 0xe1ba, 0x2041, 0x0001, 0x223d, 0x9784, 0x00ff, + 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530, 0x8210, + 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098, 0x0c68, + 0x2950, 0x080c, 0x1072, 0x0170, 0x2900, 0xb002, 0xa867, 0x0147, + 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, + 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c, 0x108b, + 0x0cc8, 0x080c, 0x108b, 0x0804, 0xe0dc, 0x2548, 0x8847, 0x9885, + 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c, 0xea30, + 0x0804, 0xe0d0, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018, 0x0008, + 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, + 0x0057, 0x1a0c, 0x0d85, 0x9082, 0x0040, 0x0a0c, 0x0d85, 0x2008, + 0x0804, 0xe246, 0x9186, 0x0051, 0x0108, 0x0040, 0x080c, 0xaf61, + 0x01e8, 0x9086, 0x0002, 0x0904, 0xe28e, 0x00c0, 0x9186, 0x0027, + 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0150, 0x190c, + 0x0d85, 0x080c, 0xaf61, 0x0150, 0x9086, 0x0004, 0x0904, 0xe32d, + 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xb227, + 0x0005, 0xe20d, 0xe20f, 0xe20f, 0xe236, 0xe20d, 0xe20d, 0xe20d, + 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, + 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0xe20d, 0x080c, 0x0d85, 0x080c, + 0x99ed, 0x080c, 0x9ab3, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, + 0x080c, 0xcf1b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, + 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xea30, + 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1987, 0x2004, + 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, + 0x99ed, 0x080c, 0x9ab3, 0x080c, 0xcf1b, 0x0120, 0x6014, 0x2048, + 0x080c, 0x108b, 0x080c, 0xb1a7, 0x009e, 0x0005, 0x0002, 0xe25b, + 0xe270, 0xe25d, 0xe285, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, + 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, 0xe25b, + 0xe25b, 0xe25b, 0xe25b, 0x080c, 0x0d85, 0x0096, 0x6014, 0x2048, + 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, + 0xb20a, 0x0010, 0x6003, 0x0004, 0x080c, 0x9ab3, 0x009e, 0x0005, + 0x080c, 0xcf1b, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, + 0xd1ec, 0x1138, 0x080c, 0x8c19, 0x080c, 0xb16c, 0x080c, 0x9ab3, + 0x0005, 0x080c, 0xec89, 0x0db0, 0x0cc8, 0x6003, 0x0001, 0x6007, + 0x0041, 0x2009, 0xa022, 0x080c, 0x9617, 0x0005, 0x9182, 0x0040, + 0x0002, 0xe2a5, 0xe2a7, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, + 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, 0xe2a5, + 0xe2a5, 0xe2a5, 0xe2a8, 0xe2a5, 0xe2a5, 0x080c, 0x0d85, 0x0005, + 0x00d6, 0x080c, 0x8c19, 0x00de, 0x080c, 0xece1, 0x080c, 0xb16c, + 0x0005, 0x9182, 0x0040, 0x0002, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, + 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2ca, 0xe2f5, 0xe2c8, + 0xe2c8, 0xe2c8, 0xe2c8, 0xe2f5, 0xe2c8, 0xe2c8, 0xe2c8, 0xe2c8, + 0x080c, 0x0d85, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0168, + 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4, 0x1168, + 0x2009, 0x0041, 0x009e, 0x0804, 0xe3b5, 0x6003, 0x0007, 0x601b, + 0x0000, 0x080c, 0x8c19, 0x009e, 0x0005, 0x6014, 0x2048, 0xa97c, + 0xd1ec, 0x1130, 0x080c, 0x8c19, 0x080c, 0xb16c, 0x009e, 0x0005, + 0x080c, 0xec89, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, + 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9a48, 0x080c, 0x9ab3, 0x6014, + 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, + 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, + 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, + 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xea30, 0x6018, 0x9005, + 0x1128, 0x2001, 0x1987, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, + 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, + 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, + 0xe346, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, 0xe344, + 0xe344, 0xe344, 0xe344, 0xe391, 0x080c, 0x0d85, 0x6014, 0x0096, + 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, + 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, + 0x0041, 0x009e, 0x0804, 0xe3b5, 0x6003, 0x0007, 0x601b, 0x0000, + 0x080c, 0x8c19, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, + 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, + 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, + 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, + 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, + 0x00e9, 0x080c, 0x8c1b, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, + 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x16b0, 0x1904, 0xe346, + 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, + 0x1120, 0x080c, 0x16b0, 0x1904, 0xe346, 0x0005, 0xd2fc, 0x0140, + 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, + 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, + 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d85, + 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, 0xe3d9, 0xe3e5, 0xe3f1, + 0xe3fd, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3e0, 0xe3db, 0xe3db, + 0xe3d9, 0xe3d9, 0xe3d9, 0xe3d9, 0xe3db, 0xe3d9, 0xe3db, 0xe3d9, + 0xe3e0, 0x080c, 0x0d85, 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, + 0x6014, 0x9005, 0x190c, 0x0d85, 0x0005, 0x6003, 0x0001, 0x6106, + 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x95f9, 0x012e, + 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, + 0xa001, 0x080c, 0x9617, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, + 0x6047, 0x0000, 0x080c, 0x1c6f, 0x0126, 0x2091, 0x8000, 0x6014, + 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086, + 0x0002, 0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8, + 0x9005, 0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d, + 0xa035, 0x009e, 0x080c, 0x965e, 0x012e, 0x0005, 0x6144, 0x918d, + 0xa032, 0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, + 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe44a, 0xe44c, + 0xe461, 0xe47b, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, + 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, 0xe44a, + 0xe44a, 0xe44a, 0x080c, 0x0d85, 0x6014, 0x2048, 0xa87c, 0xd0fc, + 0x0510, 0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, + 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9617, + 0x0480, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, + 0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001, + 0x080c, 0x9617, 0x00f0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, + 0x080c, 0xea30, 0x00b0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, + 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, + 0x6047, 0x0000, 0x080c, 0x1c6f, 0x6144, 0x918d, 0xa035, 0x080c, + 0x965e, 0x0005, 0x080c, 0x99ed, 0x6114, 0x81ff, 0x0158, 0x0096, + 0x2148, 0x080c, 0xeddf, 0x0036, 0x2019, 0x0029, 0x080c, 0xea30, + 0x003e, 0x009e, 0x080c, 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0x080c, + 0x9a48, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xeddf, + 0x0036, 0x2019, 0x0029, 0x080c, 0xea30, 0x003e, 0x009e, 0x080c, + 0xb1a7, 0x0005, 0x9182, 0x0085, 0x0002, 0xe4cc, 0xe4ca, 0xe4ca, + 0xe4d8, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, 0xe4ca, + 0xe4ca, 0xe4ca, 0x080c, 0x0d85, 0x6003, 0x000b, 0x6106, 0x0126, + 0x2091, 0x8000, 0x2009, 0x8020, 0x080c, 0x9617, 0x012e, 0x0005, + 0x0026, 0x00e6, 0x080c, 0xec80, 0x0118, 0x080c, 0xb16c, 0x0440, + 0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, + 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, + 0x014e, 0x080c, 0xb495, 0x7220, 0x080c, 0xe875, 0x0118, 0x6007, + 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, + 0x6007, 0x0086, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, + 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, + 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x9082, + 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, + 0x080c, 0xb227, 0x0050, 0x2001, 0x0007, 0x080c, 0x6726, 0x080c, + 0x99ed, 0x080c, 0xb1a7, 0x080c, 0x9ab3, 0x0005, 0xe53b, 0xe53d, + 0xe53d, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, 0xe53b, + 0xe53b, 0xe53b, 0xe53b, 0x080c, 0x0d85, 0x080c, 0xb1a7, 0x080c, + 0x9ab3, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0d85, 0x9182, 0x0092, + 0x1a0c, 0x0d85, 0x9182, 0x0085, 0x0002, 0xe55a, 0xe55a, 0xe55a, + 0xe55c, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, 0xe55a, + 0xe55a, 0xe55a, 0x080c, 0x0d85, 0x0005, 0x9186, 0x0013, 0x0148, + 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb227, + 0x0020, 0x080c, 0x99ed, 0x080c, 0xb1a7, 0x0005, 0x0036, 0x080c, + 0xece1, 0x604b, 0x0000, 0x2019, 0x000b, 0x0011, 0x003e, 0x0005, + 0x6010, 0x0006, 0x0059, 0x000e, 0x6012, 0x6023, 0x0006, 0x6003, + 0x0007, 0x601b, 0x0000, 0x604b, 0x0000, 0x0005, 0x0126, 0x0036, + 0x2091, 0x8000, 0x080c, 0xacfc, 0x0106, 0x0086, 0x2c40, 0x0096, + 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, 0x1558, 0x0076, 0x2c38, + 0x080c, 0xa712, 0x007e, 0x1528, 0x6000, 0x9086, 0x0000, 0x0508, + 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xece1, 0x080c, 0xd65d, 0x080c, 0x1ad3, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0110, 0x080c, 0xea30, 0x009e, + 0x9006, 0x6046, 0x6016, 0x080c, 0xece1, 0x6023, 0x0007, 0x080c, + 0xd65d, 0x010e, 0x090c, 0xad18, 0x003e, 0x012e, 0x0005, 0x00f6, + 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c, + 0x080c, 0x268c, 0x1904, 0xe621, 0x0016, 0x00c6, 0x080c, 0x67b4, + 0x1904, 0xe61f, 0x001e, 0x00c6, 0x080c, 0xd645, 0x1130, 0xb884, + 0x9005, 0x0118, 0x080c, 0x347d, 0x0148, 0x2b10, 0x2160, 0x6010, + 0x0006, 0x6212, 0x080c, 0xd64c, 0x000e, 0x6012, 0x00ce, 0x002e, + 0x0026, 0x0016, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0xa7e2, + 0x080c, 0x97b0, 0x0076, 0x903e, 0x080c, 0x966d, 0x007e, 0x001e, + 0x0076, 0x903e, 0x080c, 0xe75d, 0x007e, 0x080c, 0xad18, 0x0026, + 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, + 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33e0, 0x002e, 0xbc84, 0x001e, + 0x080c, 0x61b7, 0xbe12, 0xbd16, 0xbc86, 0x9006, 0x0010, 0x00ce, + 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, + 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, + 0x1904, 0xe680, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, + 0x6940, 0x9184, 0x8000, 0x0904, 0xe67d, 0x2001, 0x197c, 0x2004, + 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, 0x9005, 0x0118, 0x9184, + 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xee47, + 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, + 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, + 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, + 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, + 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, + 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, + 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, + 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, + 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, + 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, + 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x67c3, 0x0804, 0xe6ec, + 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xc222, 0x009e, 0x15c8, 0x2011, 0x027a, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x1568, + 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, + 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xea8d, 0xb800, 0xc0e5, + 0xb802, 0x080c, 0xacfc, 0x2019, 0x0029, 0x080c, 0x97b0, 0x0076, + 0x2039, 0x0000, 0x080c, 0x966d, 0x2c08, 0x080c, 0xe75d, 0x007e, + 0x080c, 0xad18, 0x2001, 0x0007, 0x080c, 0x6726, 0x2001, 0x0007, + 0x080c, 0x66fa, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, + 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, + 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, + 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, + 0x7930, 0x7834, 0x080c, 0x268c, 0x11d0, 0x080c, 0x67b4, 0x11b8, + 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, + 0x080c, 0xc222, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, + 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x015e, + 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, + 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, + 0x220c, 0x080c, 0x268c, 0x11d0, 0x080c, 0x67b4, 0x11b8, 0x2011, + 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, + 0xc222, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, + 0x2b48, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, 0x015e, 0x003e, + 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, + 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, + 0x080c, 0xad5a, 0x0106, 0x190c, 0xacfc, 0x2740, 0x2029, 0x19f4, + 0x252c, 0x2021, 0x19fb, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, + 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1b39, 0x000e, + 0x0128, 0x8001, 0x9602, 0x1a04, 0xe803, 0x0018, 0x9606, 0x0904, + 0xe803, 0x080c, 0x8eee, 0x0904, 0xe7fa, 0x2100, 0x9c06, 0x0904, + 0xe7fa, 0x6720, 0x9786, 0x0007, 0x0904, 0xe7fa, 0x080c, 0xeace, + 0x1904, 0xe7fa, 0x080c, 0xee65, 0x0904, 0xe7fa, 0x080c, 0xeabe, + 0x0904, 0xe7fa, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x347d, + 0x0904, 0xe845, 0x6004, 0x9086, 0x0000, 0x1904, 0xe845, 0x9786, + 0x0004, 0x0904, 0xe845, 0x2500, 0x9c06, 0x0904, 0xe7fa, 0x2400, + 0x9c06, 0x0904, 0xe7fa, 0x88ff, 0x0118, 0x605c, 0x9906, 0x15d0, + 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, + 0x080c, 0x1ad3, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c, 0xd132, + 0x1130, 0x080c, 0xbb5c, 0x009e, 0x080c, 0xb1a7, 0x0418, 0x6014, + 0x2048, 0x080c, 0xcf1b, 0x01d8, 0x9786, 0x0003, 0x1588, 0xa867, + 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, + 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xeddf, 0x0016, + 0x080c, 0xd220, 0x080c, 0x7006, 0x001e, 0x080c, 0xd10c, 0x009e, + 0x080c, 0xb1a7, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, + 0x1210, 0x0804, 0xe776, 0x010e, 0x190c, 0xad18, 0x012e, 0x002e, + 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, + 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xeddf, + 0x080c, 0xea30, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009, 0x11f8, + 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, + 0x080c, 0x9a48, 0x0096, 0x6114, 0x2148, 0x080c, 0xcf1b, 0x0118, + 0x6010, 0x080c, 0x7012, 0x009e, 0x00c6, 0x080c, 0xb16c, 0x00ce, + 0x0036, 0x080c, 0x9ab3, 0x003e, 0x009e, 0x0804, 0xe7fa, 0x9786, + 0x000a, 0x0904, 0xe7ea, 0x0804, 0xe7df, 0x81ff, 0x0904, 0xe7fa, + 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, + 0x2004, 0x9086, 0x002d, 0x1904, 0xe7fa, 0x6000, 0x9086, 0x0002, + 0x1904, 0xe7fa, 0x080c, 0xd121, 0x0138, 0x080c, 0xd132, 0x1904, + 0xe7fa, 0x080c, 0xbb5c, 0x0038, 0x080c, 0x3344, 0x080c, 0xd132, + 0x1110, 0x080c, 0xbb5c, 0x080c, 0xb1a7, 0x0804, 0xe7fa, 0xa864, + 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, + 0x2c08, 0x2170, 0x9006, 0x080c, 0xea57, 0x001e, 0x0120, 0x6020, + 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe894, 0xe894, + 0xe894, 0xe894, 0xe894, 0xe894, 0xe896, 0xe894, 0xe894, 0xe894, + 0xe8bf, 0xb1a7, 0xb1a7, 0xe894, 0x9006, 0x0005, 0x0036, 0x0046, + 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, + 0x0020, 0x080c, 0xea8d, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, + 0xe586, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcf1b, + 0x0140, 0x6014, 0x904d, 0x080c, 0xcae9, 0x687b, 0x0005, 0x080c, + 0x7012, 0x009e, 0x080c, 0xb1a7, 0x9085, 0x0001, 0x0005, 0x0019, + 0x9085, 0x0001, 0x0005, 0x6000, 0x908a, 0x0010, 0x1a0c, 0x0d85, + 0x000b, 0x0005, 0xe8da, 0xe8da, 0xe8f1, 0xe8e1, 0xe900, 0xe8da, + 0xe8da, 0xe8dc, 0xe8da, 0xe8da, 0xe8da, 0xe8da, 0xe8da, 0xe8da, + 0xe8da, 0xe8da, 0x080c, 0x0d85, 0x080c, 0xb1a7, 0x9085, 0x0001, + 0x0005, 0x0036, 0x00e6, 0x2071, 0x19e8, 0x704c, 0x9c06, 0x1128, + 0x2019, 0x0001, 0x080c, 0xa596, 0x0010, 0x080c, 0xa7a1, 0x00ee, + 0x003e, 0x0096, 0x00d6, 0x6014, 0x2048, 0xa87b, 0x0005, 0x080c, + 0x7012, 0x080c, 0xb1a7, 0x00de, 0x009e, 0x9085, 0x0001, 0x0005, + 0x601c, 0xd084, 0x190c, 0x1ad3, 0x0c60, 0x2001, 0x0001, 0x080c, + 0x66e6, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, + 0x1805, 0x2011, 0x0276, 0x080c, 0xc20e, 0x003e, 0x002e, 0x001e, + 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, + 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, + 0x2079, 0x0001, 0x8fff, 0x0904, 0xe977, 0x2071, 0x1800, 0x7654, + 0x7074, 0x8001, 0x9602, 0x1a04, 0xe977, 0x88ff, 0x0120, 0x2800, + 0x9c06, 0x15a0, 0x2078, 0x080c, 0xeabe, 0x0580, 0x2400, 0x9c06, + 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007, 0x0530, + 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, + 0x0118, 0x605c, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, + 0x080c, 0xece1, 0x080c, 0xd65d, 0x080c, 0x1ad3, 0x6023, 0x0007, + 0x6014, 0x2048, 0x080c, 0xcf1b, 0x0120, 0x0046, 0x080c, 0xea30, + 0x004e, 0x009e, 0x080c, 0xb1a7, 0x88ff, 0x1198, 0x9ce0, 0x001c, + 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe92a, 0x9006, + 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, + 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xacfc, 0x00b6, 0x0076, + 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, + 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, + 0x903e, 0x080c, 0xa712, 0x080c, 0xe91b, 0x005e, 0x007e, 0x00be, + 0x080c, 0xad18, 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0046, 0x0056, + 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, + 0x0016, 0x0036, 0x080c, 0x67b4, 0x1180, 0x0056, 0x0086, 0x9046, + 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa712, 0x005e, 0x003e, 0x001e, 0x8108, + 0x1f04, 0xe9b0, 0x0036, 0x2508, 0x2029, 0x0003, 0x080c, 0xe91b, + 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, + 0xad18, 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0076, 0x0056, 0x6210, + 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, + 0x904e, 0x080c, 0xa667, 0x009e, 0x008e, 0x903e, 0x080c, 0xa712, + 0x2c20, 0x080c, 0xe91b, 0x005e, 0x007e, 0x00be, 0x080c, 0xad18, + 0x0005, 0x080c, 0xacfc, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, + 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, + 0x67b4, 0x1190, 0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, + 0x080c, 0xecc5, 0x004e, 0x0096, 0x904e, 0x080c, 0xa667, 0x009e, + 0x008e, 0x903e, 0x080c, 0xa712, 0x003e, 0x001e, 0x8108, 0x1f04, + 0xea05, 0x0036, 0x2029, 0x0002, 0x080c, 0xe91b, 0x003e, 0x015e, + 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xad18, 0x0005, + 0x0016, 0x00f6, 0x080c, 0xcf19, 0x0198, 0xa864, 0x9084, 0x00ff, + 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000, + 0xab82, 0x080c, 0x7012, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x7012, + 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000, + 0x080c, 0x7012, 0x2f48, 0x0cb8, 0x080c, 0x7012, 0x0c88, 0x00e6, + 0x0046, 0x0036, 0x2061, 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, + 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, + 0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320, + 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, + 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, + 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, + 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, + 0x1059, 0x000e, 0x090c, 0x0d85, 0xaae2, 0xa867, 0x010d, 0xa88e, + 0x0026, 0x2010, 0x080c, 0xcf09, 0x2001, 0x0000, 0x0120, 0x2200, + 0x9080, 0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, + 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198e, + 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, + 0x8000, 0x080c, 0x7012, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786, + 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128, + 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, + 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, + 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, + 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, + 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1987, 0x2004, + 0x601a, 0x2009, 0x8020, 0x080c, 0x9617, 0x001e, 0x0005, 0xa001, + 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, + 0xd267, 0x0030, 0x080c, 0xece1, 0x080c, 0x8c19, 0x080c, 0xb16c, + 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xeb1d, + 0xeb1d, 0xeb1d, 0xeb1f, 0xeb1d, 0xeb1f, 0xeb1f, 0xeb1d, 0xeb1f, + 0xeb1d, 0xeb1d, 0xeb1d, 0xeb1d, 0xeb1d, 0x9006, 0x0005, 0x9085, + 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, + 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb43, 0xeb36, + 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0xeb36, 0x6007, 0x003b, + 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, + 0x080c, 0x9617, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xece1, + 0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, + 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xeb9c, 0x6814, + 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, + 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, + 0x9617, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xec0c, + 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d85, + 0x0804, 0xec0c, 0x2048, 0x080c, 0xcf1b, 0x1130, 0x0028, 0x2048, + 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, + 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, + 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xe3b5, 0x0804, 0xec0c, + 0x2009, 0x0041, 0x0804, 0xec06, 0x9186, 0x0005, 0x15a0, 0x6814, + 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xeb36, + 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d85, 0x0804, 0xeb57, 0x6007, + 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9617, 0x00c6, + 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904, + 0xec0c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, + 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, + 0x2009, 0x0042, 0x0498, 0x0036, 0x080c, 0x1059, 0x090c, 0x0d85, + 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, + 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, + 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, + 0x635c, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, + 0xa89f, 0x0001, 0x080c, 0x7012, 0x2019, 0x0045, 0x6008, 0x2068, + 0x080c, 0xe578, 0x2d00, 0x600a, 0x003e, 0x0038, 0x604b, 0x0000, + 0x6003, 0x0007, 0x080c, 0xe3b5, 0x00ce, 0x00de, 0x009e, 0x0005, + 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, + 0x9186, 0x0027, 0x1178, 0x080c, 0x99ed, 0x0036, 0x0096, 0x6014, + 0x2048, 0x2019, 0x0004, 0x080c, 0xea30, 0x009e, 0x003e, 0x080c, + 0x9ab3, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xb227, 0x0005, + 0xec3f, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3f, 0xec3d, + 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0xec3d, 0x080c, 0x0d85, 0x6003, + 0x000c, 0x080c, 0x9ab3, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, + 0x0085, 0x0208, 0x001a, 0x080c, 0xb227, 0x0005, 0xec5b, 0xec5b, + 0xec5b, 0xec5b, 0xec5d, 0xec7d, 0xec5b, 0xec5b, 0xec5b, 0xec5b, + 0xec5b, 0xec5b, 0xec5b, 0x080c, 0x0d85, 0x00d6, 0x2c68, 0x080c, + 0xb116, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, + 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, + 0x6910, 0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x9617, + 0x2d60, 0x080c, 0xb16c, 0x00de, 0x0005, 0x080c, 0xb16c, 0x0005, + 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, + 0x0005, 0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, + 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1988, 0x2004, + 0x604a, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, + 0x1867, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, + 0x00d8, 0x2001, 0x1988, 0x200c, 0x2001, 0x1986, 0x2004, 0x9100, + 0x9080, 0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, + 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, + 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, + 0x615c, 0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, + 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x8c19, 0x080c, 0xb16c, + 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, + 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x906d, 0x0130, + 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, + 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, + 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff, 0x9636, 0x1508, + 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, + 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, + 0x080c, 0xc222, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, + 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xc222, 0x009e, + 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, + 0x080c, 0x6130, 0x080c, 0x30bf, 0x00ee, 0x0005, 0x0096, 0x0026, + 0x080c, 0x1059, 0x090c, 0x0d85, 0xa85c, 0x9080, 0x001a, 0x20a0, + 0x20a9, 0x000c, 0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, + 0x1118, 0xa867, 0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, + 0x0110, 0xa87b, 0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, + 0xff00, 0x8007, 0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, + 0x9084, 0x00ff, 0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, + 0x9294, 0x00ff, 0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, + 0x9294, 0xff00, 0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, + 0x9186, 0x0046, 0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, + 0x2204, 0x8007, 0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, + 0x2204, 0x8007, 0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, + 0x9186, 0x0046, 0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, + 0x8210, 0x2204, 0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, + 0x8210, 0x2204, 0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, + 0x0001, 0x00b0, 0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, + 0x2204, 0x8007, 0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, + 0x0260, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, + 0x9186, 0x0046, 0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, + 0x0146, 0x01d6, 0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, + 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, + 0x8210, 0x8319, 0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, + 0x2013, 0x0000, 0x002e, 0x080c, 0x7012, 0x009e, 0x0005, 0x00e6, + 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, + 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, + 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, + 0x2091, 0x8000, 0x2029, 0x19f4, 0x252c, 0x2021, 0x19fb, 0x2424, + 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, + 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, + 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xeabe, 0x01b8, + 0x080c, 0xeace, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, + 0x080c, 0x1ad3, 0x001e, 0x080c, 0xd121, 0x1110, 0x080c, 0x3344, + 0x080c, 0xd132, 0x1110, 0x080c, 0xbb5c, 0x080c, 0xb1a7, 0x9ce0, + 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, + 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, + 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, + 0x2001, 0x1837, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, + 0x0046, 0x080c, 0xd645, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, + 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, + 0x4e58, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086, 0x0001, + 0x1128, 0x080c, 0xa7e2, 0x080c, 0xb1a7, 0x9006, 0x0005, 0x00e6, + 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, + 0x7074, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, + 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, + 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, + 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, + 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, + 0xd0a4, 0x0160, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0138, 0x2001, + 0x1848, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005, 0x9006, + 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, + 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118, + 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007, + 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, + 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, + 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee, + 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077, + 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071, + 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69, + 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, + 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005, + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, + 0xaa6e +}; +#ifdef UNIQUE_FW_NAME +unsigned short fw2322ipx_length01 = 0xe719; +#else +unsigned short risc_code_length01 = 0xe719; +#endif + +/* + * + */ + +unsigned long rseqipx_code_addr01 = 0x0001c000 ; +unsigned short rseqipx_code01[] = { +0x000b, 0x0003, 0x0000, 0x0a4e, 0x0001, 0xc000, 0x0008, 0x8064, + 0x0000, 0x0010, 0x0000, 0x8066, 0x0008, 0x0101, 0x0003, 0xc007, + 0x0008, 0x80e0, 0x0008, 0xff00, 0x0000, 0x80e2, 0x0008, 0xff00, + 0x0008, 0x0162, 0x0000, 0x8066, 0x0008, 0xa101, 0x000b, 0xc00f, + 0x0008, 0x0d02, 0x0000, 0x8060, 0x0000, 0x0400, 0x000b, 0x60c6, + 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7b08, + 0x0003, 0x5241, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a, + 0x0003, 0x8813, 0x000a, 0x7042, 0x0003, 0x8813, 0x0000, 0x15fc, + 0x000b, 0xb013, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0001, 0xffa0, + 0x0000, 0x2000, 0x0003, 0x93cd, 0x0008, 0x808c, 0x0000, 0x0001, + 0x0007, 0x0000, 0x0007, 0x0000, 0x0000, 0x40d4, 0x000a, 0x4047, + 0x0008, 0x808c, 0x0000, 0x0002, 0x0007, 0x0000, 0x000b, 0x0832, + 0x0000, 0x4022, 0x0003, 0x0038, 0x0008, 0x4122, 0x0009, 0xeac0, + 0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bf4, + 0x0002, 0x4447, 0x0003, 0x8bf1, 0x0008, 0x0bfe, 0x0001, 0x11a0, + 0x000b, 0x13d3, 0x0001, 0x0ca0, 0x000b, 0x13d3, 0x0001, 0x9180, + 0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc046, 0x0008, 0x808c, + 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0004, + 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc04e, 0x0000, 0x03fe, + 0x0001, 0x43e0, 0x0003, 0x8bd0, 0x0009, 0xc2c0, 0x0008, 0x00ff, + 0x0001, 0x02e0, 0x0003, 0x8bd0, 0x0001, 0x9180, 0x0008, 0x0005, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x000b, 0x0bcd, + 0x0008, 0x00fc, 0x0003, 0x33d0, 0x000a, 0x0244, 0x0003, 0x086f, + 0x0004, 0x021a, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0002, 0x0234, 0x0008, 0x7f04, + 0x0000, 0x8066, 0x0000, 0x040a, 0x0003, 0xc06e, 0x000a, 0x0248, + 0x000b, 0x0879, 0x0001, 0x9180, 0x0008, 0x0006, 0x0008, 0x7f62, + 0x0008, 0x8002, 0x0008, 0x0003, 0x0000, 0x8066, 0x0000, 0x020a, + 0x000b, 0xc078, 0x0000, 0x112a, 0x0008, 0x002e, 0x0008, 0x022c, + 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, 0x0000, 0x0002, + 0x0008, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0000, 0x8066, + 0x0008, 0x0011, 0x0003, 0xc085, 0x0008, 0x01fe, 0x0009, 0x42e0, + 0x000b, 0x8bc0, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x000b, 0x8bc0, + 0x0000, 0x1734, 0x0000, 0x1530, 0x0008, 0x1632, 0x0008, 0x0d2a, + 0x0001, 0x9880, 0x0008, 0x0012, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc097, + 0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x1a60, 0x0008, 0x8062, + 0x0000, 0x0002, 0x000b, 0x589d, 0x0000, 0x8066, 0x0000, 0x3679, + 0x000b, 0xc0a0, 0x000b, 0x58a1, 0x0008, 0x8054, 0x0008, 0x0011, + 0x0000, 0x8074, 0x0008, 0x1010, 0x0008, 0x1efc, 0x0003, 0x3013, + 0x0004, 0x00aa, 0x0003, 0x0013, 0x0000, 0x1c60, 0x0000, 0x1b62, + 0x0000, 0x8066, 0x0008, 0x0231, 0x0003, 0xc0ae, 0x0003, 0x58af, + 0x0008, 0x0140, 0x0000, 0x0242, 0x0002, 0x1f43, 0x0003, 0x88b9, + 0x0000, 0x0d44, 0x0008, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, + 0x000b, 0x00bd, 0x0008, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, + 0x0000, 0x064a, 0x000a, 0x1948, 0x0003, 0x08c0, 0x0008, 0x0d4a, + 0x0003, 0x58c0, 0x0008, 0x8054, 0x0000, 0x0001, 0x0000, 0x8074, + 0x0008, 0x2020, 0x000f, 0x4000, 0x0002, 0x7043, 0x0003, 0x8816, + 0x0002, 0x7040, 0x000b, 0x8949, 0x0000, 0x4820, 0x0008, 0x0bfe, + 0x0009, 0x10a0, 0x0003, 0x1140, 0x0001, 0x0ca0, 0x0003, 0x1140, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0008, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0d7, + 0x0001, 0x80e0, 0x0008, 0x0003, 0x000b, 0x8940, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0004, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0e2, 0x0008, 0x0060, + 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, + 0x000b, 0xc0e8, 0x0008, 0x4afe, 0x0009, 0x03e0, 0x000b, 0x8940, + 0x0009, 0xcbc0, 0x0008, 0x00ff, 0x0001, 0x02e0, 0x000b, 0x8940, + 0x0000, 0x49b4, 0x0002, 0x4b4e, 0x000b, 0x8951, 0x0008, 0x808a, + 0x0000, 0x0004, 0x0000, 0x18fe, 0x0001, 0x10e0, 0x000b, 0x88fa, + 0x0002, 0x192f, 0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, + 0x000b, 0x88ff, 0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc106, 0x000a, 0x004f, + 0x000b, 0x8937, 0x000a, 0x0040, 0x000b, 0x0921, 0x0002, 0x004e, + 0x000b, 0x0921, 0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00, + 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc112, 0x0008, 0x1010, + 0x0004, 0x0201, 0x0003, 0xb11a, 0x0004, 0x0387, 0x000c, 0x01eb, + 0x0003, 0x7816, 0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010, + 0x0000, 0x001f, 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387, + 0x0003, 0x0118, 0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066, + 0x0008, 0x000a, 0x000b, 0xc125, 0x0004, 0x01c4, 0x000a, 0x0040, + 0x000b, 0x093a, 0x0004, 0x0231, 0x0000, 0x8000, 0x0000, 0x0002, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc133, + 0x0000, 0x8072, 0x0000, 0x4000, 0x0003, 0x0118, 0x0008, 0x8010, + 0x0008, 0x001e, 0x0003, 0x013c, 0x0008, 0x8010, 0x0008, 0x001d, + 0x0004, 0x0387, 0x0008, 0x1010, 0x0004, 0x0387, 0x0003, 0x0016, + 0x0002, 0x4b4e, 0x0003, 0x0946, 0x0008, 0x808a, 0x0000, 0x0004, + 0x000b, 0x6146, 0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, + 0x0003, 0x0016, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6149, + 0x000b, 0x0014, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, + 0x000b, 0xc158, 0x000a, 0x004f, 0x000b, 0x89b5, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc162, 0x0008, 0x0060, + 0x0008, 0x8062, 0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, + 0x000b, 0xc168, 0x000a, 0x014b, 0x0003, 0x09b5, 0x0008, 0x8062, + 0x0008, 0x000f, 0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc16f, + 0x0008, 0x01fe, 0x0001, 0x02d0, 0x000b, 0x89b5, 0x0004, 0x01cd, + 0x0003, 0x09b5, 0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002, + 0x0000, 0x8006, 0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a, + 0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, + 0x0003, 0xc184, 0x0003, 0xe185, 0x0008, 0x4908, 0x0008, 0x480a, + 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0008, 0x002b, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc18f, + 0x0008, 0x04fe, 0x0009, 0x02a0, 0x0003, 0x9196, 0x0002, 0x0500, + 0x000b, 0x09b2, 0x000b, 0x0197, 0x0000, 0x05fe, 0x0001, 0x03a0, + 0x000b, 0x11b2, 0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10, + 0x0000, 0x0d12, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0000, 0x8066, 0x0008, 0x0832, 0x000b, 0xc1a2, 0x0000, 0x800a, + 0x0000, 0x8005, 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, + 0x0008, 0x0011, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, + 0x0003, 0xc1ac, 0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01d8, + 0x0003, 0x7816, 0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, + 0x0003, 0x0199, 0x0004, 0x01c4, 0x0008, 0x808a, 0x0000, 0x0004, + 0x0008, 0x8010, 0x0008, 0x0021, 0x0004, 0x0387, 0x0008, 0x1010, + 0x0004, 0x0387, 0x0000, 0x4810, 0x0004, 0x0387, 0x0008, 0x4910, + 0x0004, 0x0387, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1cb, + 0x000f, 0x4000, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62, + 0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc1d2, 0x0002, 0x0210, + 0x0001, 0xffc0, 0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002, + 0x0009, 0x0a80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, + 0x000b, 0xc1e0, 0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007, + 0x0000, 0x7f06, 0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x060a, 0x000b, 0xc1e9, 0x000f, 0x4000, 0x0000, 0x0da0, + 0x0008, 0x0da2, 0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001, + 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, + 0x0008, 0xa012, 0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa, + 0x0000, 0x0dac, 0x0003, 0xc1f9, 0x0009, 0x8880, 0x0008, 0x0009, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0xa03a, 0x0003, 0xc1ff, + 0x000f, 0x4000, 0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060, + 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, + 0x000b, 0xc208, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0000, 0x8066, 0x0008, 0x0021, 0x000b, 0xc20e, 0x0000, 0x00fe, + 0x0001, 0x01d0, 0x0003, 0x8a17, 0x0008, 0x02fe, 0x0009, 0x03d0, + 0x000b, 0x0a17, 0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006, + 0x0000, 0x0001, 0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0xa041, 0x000b, 0xc21f, + 0x0002, 0x0243, 0x000b, 0x8a26, 0x0000, 0x54ac, 0x0000, 0x55ae, + 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2, + 0x0000, 0x0db4, 0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0000, 0x0007, 0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc22f, + 0x000f, 0x4000, 0x000a, 0x3945, 0x000b, 0x8a3b, 0x0000, 0x8072, + 0x0008, 0x4040, 0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a39, + 0x000f, 0x4000, 0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a33, + 0x000b, 0x023b, 0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0, + 0x0008, 0x0000, 0x0000, 0x7f24, 0x0003, 0x5a46, 0x0008, 0x8054, + 0x0000, 0x0002, 0x0002, 0x1242, 0x0003, 0x0a8c, 0x000a, 0x3a45, + 0x000b, 0x0a7b, 0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a78, + 0x0002, 0x1d00, 0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc256, 0x0008, 0x00fc, + 0x0003, 0xb275, 0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001, + 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc25e, 0x0008, 0x00fc, + 0x000b, 0x33a9, 0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0000, 0x0019, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc267, + 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60, + 0x0008, 0x0efe, 0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x0009, 0x0003, 0xc271, 0x0008, 0x003a, 0x0000, 0x1dfe, + 0x000b, 0x0252, 0x0008, 0x0036, 0x0004, 0x00aa, 0x000b, 0x028c, + 0x0000, 0x8074, 0x0000, 0x2000, 0x000b, 0x028c, 0x0002, 0x3a44, + 0x000b, 0x0bd6, 0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0, + 0x0008, 0x0000, 0x0008, 0x7f0e, 0x0003, 0xb3a6, 0x0001, 0xa7d0, + 0x0008, 0x0000, 0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000, + 0x0009, 0x00d0, 0x0003, 0x8a9c, 0x0000, 0x8074, 0x0008, 0x4040, + 0x0003, 0x5a8c, 0x0003, 0x5241, 0x000a, 0x3a46, 0x0003, 0x8a9c, + 0x0002, 0x3a47, 0x0003, 0x0a97, 0x0008, 0x8054, 0x0000, 0x0004, + 0x0000, 0x8074, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0x92c0, + 0x0000, 0x0fc8, 0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8ba0, + 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066, + 0x0000, 0x367a, 0x000b, 0xc2a1, 0x0009, 0x92c0, 0x0008, 0x0780, + 0x0003, 0x8bba, 0x0002, 0x124b, 0x000b, 0x0aaa, 0x0002, 0x2e4d, + 0x0002, 0x2e4d, 0x0003, 0x0ba6, 0x000a, 0x3a46, 0x000b, 0x8aba, + 0x000b, 0x5aac, 0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, + 0x000b, 0x0afa, 0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0387, + 0x000a, 0x1948, 0x000b, 0x0ab7, 0x000c, 0x037c, 0x0000, 0x1810, + 0x0004, 0x0387, 0x0003, 0x02fa, 0x000a, 0x1948, 0x000b, 0x0abe, + 0x000a, 0x1243, 0x0003, 0x0ba9, 0x000a, 0x194d, 0x0003, 0x0ac2, + 0x000a, 0x1243, 0x000b, 0x0bb0, 0x0003, 0x5ac2, 0x0008, 0x8054, + 0x0000, 0x0004, 0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, + 0x0003, 0x0af4, 0x0002, 0x194f, 0x000b, 0x0ad2, 0x000c, 0x037c, + 0x0000, 0x1810, 0x0004, 0x0201, 0x000b, 0xb2ed, 0x0004, 0x0387, + 0x000c, 0x01eb, 0x0003, 0x02fa, 0x0000, 0x1a60, 0x0008, 0x8062, + 0x0000, 0x001f, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc2d7, + 0x000a, 0x004c, 0x000b, 0x8af4, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x9880, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0000, 0x320a, 0x0003, 0xc2e1, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x9880, 0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x1e0a, 0x000b, 0xc2e9, 0x0000, 0x1826, 0x0000, 0x1928, + 0x0003, 0x02fa, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, + 0x0004, 0x0387, 0x0000, 0x0310, 0x0004, 0x0387, 0x0003, 0x02fa, + 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0387, + 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0008, 0xf000, + 0x0000, 0x0d30, 0x0002, 0x3a42, 0x0003, 0x8b02, 0x0000, 0x15fc, + 0x0003, 0xb07e, 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501, + 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387, 0x0003, 0x0013, + 0x0009, 0xbbe0, 0x0008, 0x0030, 0x000b, 0x8b1e, 0x0000, 0x18fe, + 0x0009, 0x3ce0, 0x0003, 0x0b1b, 0x0008, 0x15fe, 0x0009, 0x3ce0, + 0x0003, 0x0b1b, 0x0008, 0x13fe, 0x0009, 0x3ce0, 0x000b, 0x8b17, + 0x000c, 0x0375, 0x0008, 0x0d26, 0x000b, 0x0318, 0x0004, 0x0377, + 0x0008, 0x8076, 0x0000, 0x0040, 0x000b, 0x0372, 0x0008, 0x8076, + 0x0008, 0x0041, 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0032, + 0x0003, 0x8b23, 0x0008, 0x3c1e, 0x000b, 0x0372, 0x0009, 0xbbe0, + 0x0000, 0x003b, 0x000b, 0x8b28, 0x0000, 0x3cdc, 0x000b, 0x0372, + 0x0009, 0xbbe0, 0x0008, 0x0035, 0x000b, 0x8b2e, 0x0000, 0x8072, + 0x0000, 0x8000, 0x000b, 0x04e5, 0x0009, 0xbbe0, 0x0008, 0x0036, + 0x000b, 0x0c06, 0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b53, + 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x8b1b, 0x0008, 0x8076, + 0x0000, 0x0040, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, + 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0, + 0x0008, 0x0000, 0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000, + 0x0008, 0x7f08, 0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a, + 0x0000, 0x8066, 0x0000, 0x0422, 0x0003, 0xc34a, 0x000c, 0x037c, + 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x02fc, 0x0009, 0xbbe0, + 0x0000, 0x0038, 0x000b, 0x8b65, 0x0000, 0x18fe, 0x0009, 0x3ce0, + 0x000b, 0x0b62, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x000b, 0x8b11, + 0x0004, 0x0377, 0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0003, 0x03cd, 0x0008, 0x8076, 0x0008, 0x0042, + 0x000b, 0x0372, 0x0009, 0xbbe0, 0x0000, 0x0016, 0x000b, 0x8b72, + 0x0000, 0x8074, 0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818, + 0x0000, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000, + 0x000f, 0x8000, 0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, + 0x0003, 0x0013, 0x0002, 0x1430, 0x000b, 0x0378, 0x000a, 0x3d30, + 0x0000, 0x7f00, 0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x0380, + 0x000a, 0x1930, 0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x000a, 0x0003, 0xc385, 0x000f, 0x4000, 0x000b, 0x238a, + 0x0008, 0x0870, 0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b87, + 0x000b, 0xe394, 0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, + 0x0007, 0x0000, 0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x638d, + 0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x0387, 0x0009, 0xbac0, + 0x0008, 0x0090, 0x000b, 0x0b9d, 0x0000, 0x8074, 0x0000, 0x0706, + 0x000b, 0x039f, 0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000, + 0x0008, 0x8010, 0x0000, 0x0023, 0x000b, 0x03db, 0x0008, 0x8010, + 0x0000, 0x0008, 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0022, + 0x000b, 0x03db, 0x000c, 0x037c, 0x0008, 0x8010, 0x0000, 0x0007, + 0x0004, 0x0387, 0x0000, 0x1810, 0x0004, 0x0387, 0x0003, 0x03e5, + 0x000c, 0x037c, 0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0387, + 0x0000, 0x1810, 0x0004, 0x0387, 0x0000, 0x8074, 0x0000, 0xf080, + 0x0000, 0x0d30, 0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009, + 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03db, + 0x000a, 0x1648, 0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001, + 0x0007, 0x0000, 0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143, + 0x000b, 0x088c, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a, + 0x000b, 0x03db, 0x0008, 0x8010, 0x0008, 0x0003, 0x000b, 0x03dd, + 0x0008, 0x8010, 0x0000, 0x000b, 0x000b, 0x03dd, 0x0008, 0x8010, + 0x0000, 0x0002, 0x000b, 0x03dd, 0x0002, 0x3a47, 0x000b, 0x8a8c, + 0x0008, 0x8010, 0x0008, 0x0006, 0x000b, 0x03dd, 0x0000, 0x8074, + 0x0008, 0xf000, 0x0004, 0x0387, 0x000c, 0x0397, 0x000a, 0x3a40, + 0x000b, 0x0813, 0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0387, + 0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, + 0x0002, 0x2e4d, 0x0002, 0x2e4d, 0x0003, 0x0bee, 0x0008, 0x8054, + 0x0000, 0x0019, 0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009, + 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0003, 0x03d0, + 0x0008, 0x808c, 0x0008, 0x0000, 0x0002, 0x4447, 0x0003, 0x0c1a, + 0x0001, 0xc0c0, 0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff, + 0x0003, 0x8bf1, 0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bf1, + 0x0008, 0x8010, 0x0000, 0x0013, 0x0004, 0x0387, 0x0000, 0x8074, + 0x0008, 0x0202, 0x0003, 0x0013, 0x000a, 0x3a40, 0x0003, 0x8c17, + 0x0000, 0x8074, 0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, + 0x0000, 0x8072, 0x0000, 0x8000, 0x0001, 0x43e0, 0x000b, 0x8c15, + 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, + 0x000b, 0x0bf1, 0x0008, 0x0d08, 0x0003, 0x046a, 0x0000, 0x8072, + 0x0000, 0x8000, 0x0003, 0x0013, 0x000c, 0x04ee, 0x0008, 0x808c, + 0x0000, 0x0001, 0x0000, 0x04fc, 0x0003, 0x34d1, 0x0000, 0x0460, + 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, + 0x0003, 0xc424, 0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, + 0x0000, 0x7f00, 0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c3e, + 0x0001, 0x80e0, 0x0008, 0x0005, 0x0003, 0x0c3e, 0x0001, 0x80e0, + 0x0008, 0x0006, 0x0003, 0x0c3e, 0x0001, 0x82c0, 0x0008, 0xff00, + 0x0008, 0x7f04, 0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c3e, + 0x0009, 0x82e0, 0x0008, 0x0500, 0x0003, 0x0c3e, 0x0009, 0x82e0, + 0x0000, 0x0400, 0x0003, 0x8cd1, 0x0009, 0xc4c0, 0x0000, 0x7000, + 0x0009, 0xffe0, 0x0000, 0x1000, 0x000b, 0x0c6a, 0x0004, 0x04df, + 0x0002, 0x3941, 0x0003, 0x0c49, 0x0000, 0x8072, 0x0000, 0x0400, + 0x0003, 0x0013, 0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, + 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc44f, + 0x0008, 0x11fc, 0x0003, 0x3465, 0x0001, 0x9180, 0x0000, 0x0002, + 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x0609, 0x0003, 0xc459, 0x0000, 0x42fe, 0x0001, 0xffc0, + 0x0008, 0xff00, 0x0009, 0x03e0, 0x000b, 0x8c62, 0x0000, 0x8072, + 0x0000, 0x0400, 0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, + 0x000b, 0x044c, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, + 0x0000, 0x0010, 0x000b, 0x04c4, 0x0004, 0x04df, 0x0002, 0x3941, + 0x0003, 0x0c70, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, + 0x000a, 0x6e42, 0x0003, 0x0c75, 0x000c, 0x04a9, 0x0008, 0x11fc, + 0x0003, 0xb47a, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, + 0x0000, 0x000e, 0x000b, 0x04c4, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0000, 0x04fc, 0x0003, 0xb48f, 0x0008, 0x808c, 0x0008, 0x0000, + 0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x0009, 0x000b, 0xc485, 0x0008, 0x0060, 0x0008, 0x8062, + 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0000, 0x8066, + 0x0000, 0x0412, 0x0003, 0xc48d, 0x0003, 0x04a6, 0x0008, 0x808c, + 0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062, 0x0008, 0x002b, + 0x0000, 0x8066, 0x0008, 0x0609, 0x0003, 0xc496, 0x0000, 0x8066, + 0x0008, 0x220a, 0x0003, 0xc499, 0x0000, 0x42fe, 0x0001, 0xffc0, + 0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0008, 0x041a, 0x0003, 0xc4a5, 0x0000, 0x8072, 0x0000, 0x0400, + 0x000b, 0x0056, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x6b62, + 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc4ae, 0x0008, 0x02fe, + 0x0009, 0x03e0, 0x0003, 0x8cb4, 0x0000, 0x0d22, 0x000f, 0x4000, + 0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80, 0x0008, 0x7f62, + 0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc4ba, 0x000a, 0x0200, + 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06, 0x0008, 0x6b62, + 0x0000, 0x8066, 0x0008, 0x060a, 0x000b, 0xc4c2, 0x000f, 0x4000, + 0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44, 0x000a, 0x2f44, + 0x0003, 0x8bd0, 0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x8074, + 0x0000, 0xf080, 0x0003, 0x5ccd, 0x0008, 0x8054, 0x0000, 0x0019, + 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, + 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, 0x0004, 0x0387, + 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0008, 0x7f10, + 0x0004, 0x0387, 0x0008, 0x4310, 0x000b, 0x03dd, 0x0002, 0x3941, + 0x000b, 0x0ce2, 0x000f, 0x4000, 0x0000, 0x8072, 0x0008, 0x0404, + 0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012, 0x0004, 0x0387, + 0x000c, 0x04a9, 0x0000, 0x1110, 0x0004, 0x0387, 0x0008, 0x11fc, + 0x000b, 0xb4e8, 0x0003, 0x0013, 0x0009, 0xc2c0, 0x0008, 0x00ff, + 0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00, 0x0009, 0x00d0, + 0x000b, 0x0d13, 0x0000, 0x0d0a, 0x0001, 0x8580, 0x0000, 0x1000, + 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, + 0x0000, 0x0809, 0x000b, 0xc4fd, 0x0000, 0x04fc, 0x000b, 0x350c, + 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066, + 0x0000, 0x0211, 0x000b, 0xc505, 0x0008, 0x01fe, 0x0009, 0x00e0, + 0x000b, 0x8d0c, 0x0008, 0x02fe, 0x0001, 0x43e0, 0x0003, 0x0d12, + 0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0, 0x0000, 0x0800, + 0x0003, 0x8cf6, 0x0008, 0x0d08, 0x000f, 0x4000, 0x0008, 0x43fe, + 0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066, + 0x0000, 0x0809, 0x0003, 0xc519, 0x0000, 0x8060, 0x0000, 0x0400, + 0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70, 0x0009, 0xff80, + 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809, + 0x000b, 0xc524, 0x000f, 0x4000, 0xe4a8, 0xa3b9 +}; +unsigned short rseqipx_code_length01 = 0x0a4e; +/* + * + */ + +unsigned long xseqipx_code_addr01 = 0x0001e000 ; +unsigned short xseqipx_code01[] = { +0x0013, 0x0003, 0x0000, 0x1252, 0x0001, 0xe000, 0x0005, 0x0032, + 0x0000, 0x0010, 0x0015, 0x0033, 0x0010, 0xbb39, 0x000b, 0x8007, + 0x0004, 0x0113, 0x0004, 0x0125, 0x0010, 0xc000, 0x0000, 0xc001, + 0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0010, 0xc0b2, 0x0000, 0xc0b3, + 0x0010, 0xc0b4, 0x0000, 0xc0b5, 0x0000, 0xc0b6, 0x0010, 0xc0b7, + 0x0010, 0xc0b8, 0x0000, 0xc0b9, 0x0000, 0xc0ba, 0x0000, 0xc0c2, + 0x0010, 0xc0c3, 0x0000, 0xc0c4, 0x0010, 0xc0c5, 0x0010, 0xc0c6, + 0x0000, 0xc0c7, 0x0000, 0xc0c8, 0x0010, 0xc0c9, 0x0010, 0xc0ca, + 0x0000, 0xc0cb, 0x0010, 0xc0cc, 0x0000, 0xc0cd, 0x0000, 0xc0ce, + 0x0010, 0xc0cf, 0x0015, 0x0039, 0x0010, 0xff00, 0x0015, 0x003a, + 0x0010, 0xff00, 0x0005, 0x00d0, 0x0010, 0xff00, 0x0015, 0x00d1, + 0x0010, 0xff00, 0x0012, 0x3a40, 0x000b, 0x1031, 0x0002, 0x7940, + 0x001b, 0x1137, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035, + 0x0003, 0xa1e2, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941, + 0x001b, 0x1317, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001, + 0x0013, 0x1054, 0x0000, 0x0cfe, 0x0013, 0x6047, 0x0002, 0x3a44, + 0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13cd, + 0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x145f, 0x0012, 0x3a46, + 0x000b, 0x1054, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x104f, + 0x0011, 0x02e8, 0x0010, 0x0005, 0x000b, 0x1054, 0x0000, 0x12fe, + 0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x1695, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131, 0x0015, 0x0033, + 0x0010, 0xb211, 0x001b, 0x8059, 0x0010, 0xb2ff, 0x0001, 0xb3e0, + 0x001c, 0x10d5, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010, + 0x001b, 0x1071, 0x0000, 0x0afe, 0x000b, 0x6065, 0x0000, 0x3c0b, + 0x0003, 0x006d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x0a88, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, + 0x001b, 0x806c, 0x0010, 0x3c0a, 0x0002, 0x0c00, 0x0010, 0xff0c, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084, + 0x0010, 0x08fe, 0x000b, 0x6078, 0x0010, 0x3c09, 0x0003, 0x0080, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x000b, 0x807f, + 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00d2, + 0x0011, 0x3be8, 0x0000, 0x0013, 0x000b, 0x108a, 0x0000, 0x3cb0, + 0x0014, 0x00e5, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0019, + 0x000b, 0x109d, 0x0010, 0x04fe, 0x001b, 0x6091, 0x0010, 0x3c05, + 0x0013, 0x0099, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0488, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, + 0x000b, 0x8098, 0x0000, 0x3c04, 0x0002, 0x0c00, 0x0010, 0xff0c, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a6, + 0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0015, 0x000f, + 0x0010, 0x0000, 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0000, 0x0015, + 0x001b, 0x10b2, 0x0004, 0x011c, 0x0014, 0x012e, 0x0015, 0x0039, + 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0113, 0x0004, 0x0125, + 0x0014, 0x00fe, 0x0013, 0x002d, 0x0011, 0x3be8, 0x0000, 0x0016, + 0x000b, 0x10c4, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x10be, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10be, 0x0015, 0x0039, + 0x0010, 0x1010, 0x0013, 0x00d2, 0x0015, 0x0039, 0x0000, 0x5040, + 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0013, 0x00d2, + 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c9, 0x0010, 0x3cc3, + 0x0013, 0x00d2, 0x0011, 0x3be8, 0x0010, 0x0018, 0x000b, 0x10ce, + 0x0000, 0x3cc2, 0x0013, 0x00d2, 0x0005, 0x00ce, 0x0000, 0x0001, + 0x0000, 0x3bcf, 0x0014, 0x08e7, 0x0015, 0x0039, 0x0000, 0x8000, + 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, 0x0001, 0xc180, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x80db, + 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, 0x0010, 0xffb2, + 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, 0x0001, 0xb0d0, + 0x001b, 0x80e4, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xb088, + 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, + 0x000b, 0x80ec, 0x0001, 0xb1e8, 0x0010, 0xffff, 0x0013, 0x10fd, + 0x0000, 0x11fe, 0x001b, 0x60f4, 0x0000, 0xb012, 0x0013, 0x00fc, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x80fb, + 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xc411, 0x000b, 0x8105, 0x0011, 0xbc88, 0x0010, 0x0018, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, 0x001b, 0x810b, + 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xc709, 0x000b, 0x8111, 0x0017, 0x4000, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0x0269, 0x001b, 0x811a, 0x0017, 0x4000, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, 0x001b, 0x8123, + 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, + 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0f59, + 0x001b, 0x812c, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0x0f5a, 0x000b, 0x8135, 0x0017, 0x4000, 0x0000, 0xd0ff, + 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, 0x0010, 0x0101, + 0x0003, 0x913c, 0x0005, 0x0079, 0x0000, 0x0001, 0x0003, 0x913f, + 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, 0x0000, 0x0002, + 0x0003, 0x1167, 0x0011, 0x02e8, 0x0000, 0x0001, 0x0003, 0x117f, + 0x0011, 0x02e8, 0x0000, 0x0004, 0x0003, 0x119d, 0x0011, 0x02e8, + 0x0010, 0x0003, 0x0003, 0x11ce, 0x0005, 0x0002, 0x0010, 0x0000, + 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x815a, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815e, 0x0012, 0x3a45, + 0x0013, 0x1166, 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a, + 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x004f, 0x0012, 0x7849, + 0x0003, 0x11dc, 0x0010, 0x0dfe, 0x0003, 0x6150, 0x0012, 0x0c10, + 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, + 0x000b, 0x8174, 0x0010, 0xb3fe, 0x0013, 0x617c, 0x0010, 0xb30b, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x817a, 0x0003, 0x01d1, + 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0003, 0x01d1, 0x0000, 0x78b0, + 0x0012, 0xb044, 0x0003, 0x11dc, 0x0002, 0xb049, 0x0003, 0x11dc, + 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, + 0x0003, 0x614e, 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x8192, 0x0010, 0xb3fe, + 0x0003, 0x619a, 0x0000, 0xb309, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x001b, 0x8198, 0x0003, 0x01d1, 0x0010, 0xc009, 0x0000, 0xc008, + 0x0003, 0x01d1, 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11dc, + 0x0002, 0xb049, 0x0003, 0x11dc, 0x0010, 0x71ff, 0x0012, 0xff38, + 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614e, 0x0012, 0x0c10, + 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, + 0x001b, 0x81b0, 0x0010, 0xb3fe, 0x0003, 0x61b8, 0x0000, 0xb305, + 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b6, 0x0013, 0x01ba, + 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f, 0x0002, 0xff27, + 0x0000, 0x0db8, 0x0014, 0x03c2, 0x0000, 0x0db8, 0x0014, 0x0925, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88, 0x0010, 0x0000, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x81c7, + 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114e, 0x0005, 0x0002, + 0x0010, 0x0005, 0x0003, 0x0150, 0x0012, 0x7849, 0x0003, 0x11dc, + 0x0003, 0x0150, 0x0000, 0x0db8, 0x0012, 0x0345, 0x000b, 0x11d7, + 0x0002, 0x033f, 0x0014, 0x03c2, 0x0003, 0x014e, 0x0002, 0x033f, + 0x0002, 0xff27, 0x0014, 0x03c2, 0x0014, 0x0925, 0x0003, 0x014e, + 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a, 0x0010, 0x0101, + 0x0014, 0x0925, 0x0003, 0x015f, 0x0001, 0x2bd8, 0x0010, 0x0000, + 0x0000, 0xffba, 0x0003, 0xb1e5, 0x0005, 0x002a, 0x0000, 0x0002, + 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12d2, 0x0011, 0x15e8, + 0x0000, 0x0002, 0x0013, 0x1248, 0x0011, 0x15e8, 0x0000, 0x0001, + 0x0003, 0x11f4, 0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x022b, + 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43, 0x0003, 0x122c, + 0x0003, 0xb1f8, 0x0005, 0x002a, 0x0000, 0x0004, 0x0012, 0xba42, + 0x0003, 0x1232, 0x0012, 0x104b, 0x000b, 0x122b, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, + 0x001b, 0x8204, 0x0011, 0x20d8, 0x0010, 0x0000, 0x0000, 0xffb0, + 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1, 0x0001, 0x22d8, + 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8, 0x0010, 0x0000, + 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000, 0x0010, 0xffb4, + 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5, 0x0001, 0x28d8, + 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, + 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0007, + 0x0015, 0x0033, 0x0010, 0xb032, 0x000b, 0x8222, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0010, 0xb812, + 0x000b, 0x8228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x0035, + 0x0000, 0x1efe, 0x0013, 0x6240, 0x0014, 0x0277, 0x0000, 0x1efe, + 0x000c, 0x6277, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8237, + 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031, 0x0000, 0x0020, + 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823e, 0x0003, 0x01ff, + 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x0925, 0x0000, 0x13b8, + 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0003, 0x022b, + 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42, 0x0013, 0x1256, + 0x0003, 0xb24c, 0x0001, 0x2bd8, 0x0010, 0x0000, 0x0012, 0xff4f, + 0x000b, 0x11e2, 0x0002, 0xba43, 0x001b, 0x1232, 0x0000, 0x1efe, + 0x000c, 0x6277, 0x0003, 0x022b, 0x0001, 0x28d8, 0x0010, 0x0000, + 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000, 0x0000, 0xffb9, + 0x0014, 0x02e8, 0x0002, 0x3a42, 0x000b, 0x122b, 0x0000, 0x1c30, + 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43, 0x001b, 0x1267, + 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0269, 0x0001, 0xff88, + 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011, + 0x000b, 0x826c, 0x0000, 0xb0ff, 0x0011, 0x16a0, 0x0000, 0xff16, + 0x001b, 0x2273, 0x0002, 0xb100, 0x0003, 0x0274, 0x0010, 0xb1ff, + 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x0232, 0x0000, 0x16ff, + 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227e, 0x0002, 0x1700, + 0x0013, 0x12d1, 0x0013, 0x027f, 0x0010, 0x17ff, 0x0011, 0x19a0, + 0x0013, 0x22d1, 0x0011, 0x00d0, 0x0013, 0x12d1, 0x0000, 0x1c30, + 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x000b, 0x8287, + 0x0013, 0xb288, 0x0000, 0xb120, 0x0010, 0xb221, 0x0002, 0x1f43, + 0x001b, 0x1294, 0x0010, 0xc022, 0x0000, 0xc023, 0x0000, 0xb324, + 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0013, 0x0298, + 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625, + 0x0003, 0xb298, 0x0005, 0x002a, 0x0000, 0x0001, 0x0012, 0x1500, + 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580, 0x0000, 0xff16, + 0x000b, 0x22a3, 0x0002, 0x1700, 0x0013, 0x02a4, 0x0010, 0x17ff, + 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10, 0x0010, 0xff1e, + 0x0003, 0x62d1, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0010, 0xc030, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82af, + 0x0010, 0xb0fe, 0x000b, 0x62d0, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82b7, + 0x0010, 0xb0fe, 0x001b, 0x62bd, 0x0005, 0x00ce, 0x0010, 0x0005, + 0x0003, 0x08e7, 0x0010, 0xb01c, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82c3, + 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f, 0x0010, 0xc030, + 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x82cc, 0x0000, 0xb01d, 0x0010, 0x1dff, 0x0013, 0x02ab, + 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41, 0x0003, 0x12da, + 0x0013, 0xb2d4, 0x0005, 0x002a, 0x0000, 0x0004, 0x0005, 0x0015, + 0x0010, 0x0000, 0x0003, 0x022b, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a, 0x001b, 0x82df, + 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x0925, 0x0000, 0x13b8, + 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x0925, 0x0013, 0x0039, + 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10, 0x0010, 0xff1d, + 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x82f0, 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0000, 0x1cff, + 0x0001, 0x1ae0, 0x0013, 0x12ff, 0x0000, 0x1c30, 0x0005, 0x0031, + 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82fb, + 0x0010, 0xb0fe, 0x001b, 0x62ff, 0x0000, 0x1aff, 0x0000, 0xff1c, + 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, + 0x0000, 0xb009, 0x001b, 0x8305, 0x0001, 0xb0c8, 0x0010, 0x000f, + 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d, 0x0010, 0xc030, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x830f, + 0x0010, 0xb0fe, 0x001b, 0x6315, 0x0005, 0x00ce, 0x0010, 0x0006, + 0x0003, 0x08e7, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0010, 0x79b0, + 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039, 0x0015, 0x00d1, + 0x0010, 0x0101, 0x0013, 0x931d, 0x0005, 0x0079, 0x0000, 0x0002, + 0x0003, 0x9320, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0010, 0x13fe, + 0x0013, 0x6371, 0x0012, 0xb04e, 0x001b, 0x139a, 0x0000, 0x78b0, + 0x0002, 0xb045, 0x0003, 0x13a0, 0x0012, 0x784a, 0x0003, 0x13a0, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800, 0x001b, 0x13a0, + 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x133c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0x8f0a, 0x001b, 0x833a, 0x0013, 0x03a6, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1347, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x000b, 0x8345, 0x0013, 0x03a6, 0x0001, 0x0fe8, + 0x0010, 0x0000, 0x0003, 0x134e, 0x0005, 0x00ce, 0x0000, 0x0007, + 0x0010, 0x0fcf, 0x0003, 0x08e1, 0x0002, 0xd142, 0x0013, 0x1367, + 0x0015, 0x00d1, 0x0000, 0x0400, 0x0011, 0x13e8, 0x0001, 0x1b55, + 0x000b, 0x1367, 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, + 0x0010, 0xb409, 0x001b, 0x8359, 0x0002, 0xb400, 0x0010, 0xffb4, + 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033, 0x0010, 0xb40a, + 0x001b, 0x8360, 0x0012, 0xd042, 0x0003, 0x1371, 0x0015, 0x00b8, + 0x0000, 0x000d, 0x0014, 0x0925, 0x0003, 0x0054, 0x0000, 0x13b8, + 0x0002, 0x1045, 0x0003, 0x136f, 0x0012, 0x103f, 0x0002, 0xff27, + 0x0014, 0x03c2, 0x0014, 0x0925, 0x0013, 0x0371, 0x0012, 0x103f, + 0x0014, 0x03c2, 0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, + 0x0013, 0x137a, 0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, + 0x0000, 0x0008, 0x0014, 0x0925, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0010, 0x000c, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x001b, 0x8381, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xc00a, 0x000b, 0x8385, 0x0010, 0xc014, 0x0000, 0xc013, + 0x0000, 0xc010, 0x0000, 0xa4ff, 0x0003, 0x6392, 0x0011, 0xffa8, + 0x0010, 0x0005, 0x000b, 0x2392, 0x0015, 0x00d1, 0x0010, 0x0404, + 0x0015, 0x003a, 0x0000, 0x8000, 0x0002, 0x3a47, 0x0003, 0x1399, + 0x0015, 0x003a, 0x0000, 0x8000, 0x0015, 0x003a, 0x0010, 0x4040, + 0x0004, 0x08ec, 0x0013, 0x0039, 0x0015, 0x00b8, 0x0010, 0x0003, + 0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x0925, 0x0003, 0x0389, + 0x0015, 0x00b8, 0x0000, 0x0002, 0x0015, 0x003a, 0x0010, 0x0202, + 0x0014, 0x0925, 0x0003, 0x0389, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x83ad, 0x0011, 0x1388, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x83b3, + 0x0010, 0xb0fe, 0x0013, 0x63b8, 0x0000, 0xb012, 0x0003, 0x03ba, + 0x0010, 0xc012, 0x0010, 0xc011, 0x0012, 0x104b, 0x0003, 0x134e, + 0x0002, 0x103b, 0x0010, 0xff03, 0x0005, 0x0002, 0x0010, 0x0000, + 0x0000, 0xc00d, 0x0013, 0x034e, 0x0000, 0xffb0, 0x0010, 0xc3b1, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xb888, 0x0010, 0x0011, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x83cb, + 0x0017, 0x4000, 0x0002, 0xd142, 0x001b, 0x1485, 0x0012, 0x3a43, + 0x0003, 0x13de, 0x0015, 0x003a, 0x0000, 0x0800, 0x0010, 0x0db0, + 0x0013, 0x63de, 0x0000, 0x0bff, 0x0001, 0xb0e0, 0x0003, 0x1407, + 0x0010, 0x09ff, 0x0001, 0xb0e0, 0x0003, 0x13eb, 0x0010, 0x05ff, + 0x0001, 0xb0e0, 0x0003, 0x13e2, 0x0000, 0xc00e, 0x0000, 0x05fe, + 0x0013, 0x63e8, 0x0000, 0x050d, 0x0005, 0x0002, 0x0000, 0x0004, + 0x0014, 0x046c, 0x0002, 0x3a47, 0x001b, 0x146b, 0x0013, 0x0402, + 0x0000, 0x09fe, 0x0013, 0x6404, 0x0000, 0x090d, 0x0005, 0x0002, + 0x0000, 0x0001, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x001b, 0x83f5, 0x0011, 0x03c8, 0x0010, 0x000f, + 0x0000, 0xffb6, 0x0011, 0xb6e8, 0x0000, 0x0001, 0x0003, 0x153f, + 0x0011, 0xb6e8, 0x0000, 0x0002, 0x0013, 0x1561, 0x0011, 0xb6e8, + 0x0010, 0x0003, 0x0003, 0x1653, 0x0004, 0x08ec, 0x0013, 0x046b, + 0x0010, 0x0bfe, 0x0013, 0x646b, 0x0010, 0x0b0d, 0x0005, 0x0002, + 0x0000, 0x0002, 0x0014, 0x049a, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x000b, 0x8411, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0010, 0x0021, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8417, + 0x0001, 0xb0a8, 0x0000, 0x199a, 0x0013, 0x241d, 0x0005, 0x00b0, + 0x0000, 0x1999, 0x0012, 0xb050, 0x0000, 0xffb0, 0x0002, 0xff50, + 0x0002, 0xff50, 0x0001, 0xb080, 0x0000, 0xffb0, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0006, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x842a, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x8430, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0001, 0xffe8, + 0x0010, 0x0048, 0x000b, 0x14a9, 0x0005, 0x0002, 0x0010, 0x0006, + 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb109, 0x000b, 0x8441, 0x0000, 0xb10b, 0x000b, 0x6445, + 0x0010, 0xb10a, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8447, + 0x0002, 0x032b, 0x0010, 0xff03, 0x0011, 0x0d88, 0x0010, 0x0011, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x030a, 0x001b, 0x844f, + 0x0000, 0x11fe, 0x000b, 0x6454, 0x0000, 0x0d12, 0x0013, 0x045d, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003, + 0x0000, 0xff31, 0x0010, 0x0db0, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x000b, 0x845c, 0x0000, 0x0d11, 0x0013, 0x046b, 0x0002, 0xd142, + 0x0003, 0x1462, 0x0013, 0x0485, 0x0000, 0x05fe, 0x0013, 0x646b, + 0x0005, 0x0002, 0x0000, 0x0004, 0x0000, 0x050d, 0x0014, 0x046c, + 0x0002, 0x3a47, 0x001b, 0x146b, 0x0004, 0x08ec, 0x0013, 0x0047, + 0x0001, 0xc7c8, 0x0010, 0x0028, 0x000b, 0x1484, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x000a, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8476, 0x0002, 0xb04f, + 0x0013, 0x1484, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x1482, + 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0013, 0x1482, 0x0015, 0x003a, + 0x0010, 0x8080, 0x0003, 0x0484, 0x0015, 0x003a, 0x0010, 0x4040, + 0x0017, 0x4000, 0x0000, 0x12fe, 0x001b, 0x604f, 0x0015, 0x0012, + 0x0001, 0x1b55, 0x0015, 0x0011, 0x0001, 0x1b55, 0x0001, 0x1288, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x000b, 0x8490, 0x0005, 0x00b0, 0x0000, 0x8000, 0x0001, 0x1288, + 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x001b, 0x8498, 0x0003, 0x004f, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0x0309, 0x001b, 0x84a1, 0x0011, 0x0d88, 0x0010, 0x0005, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb909, 0x001b, 0x84a7, + 0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0600, 0x0014, 0x0683, + 0x0004, 0x051b, 0x0000, 0xb05a, 0x0000, 0xb15b, 0x0005, 0x0054, + 0x0010, 0x0829, 0x0010, 0x0d58, 0x0015, 0x0059, 0x0010, 0xffff, + 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x001e, 0x0015, 0x0033, + 0x0000, 0xb009, 0x001b, 0x84b9, 0x0000, 0xb05c, 0x0005, 0x0031, + 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84bf, + 0x0001, 0xb0c8, 0x0010, 0x000f, 0x000b, 0x14c6, 0x0015, 0x00ff, + 0x0010, 0x0005, 0x0013, 0x04ce, 0x0002, 0xb040, 0x0003, 0x14cb, + 0x0015, 0x00ff, 0x0000, 0x0004, 0x0013, 0x04ce, 0x0001, 0xb0c8, + 0x0010, 0x0006, 0x0002, 0xff60, 0x0010, 0xffb2, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0019, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x84d6, 0x0012, 0xb170, + 0x0011, 0xffc8, 0x0010, 0xff00, 0x0011, 0xb2d0, 0x0010, 0xff60, + 0x0002, 0xb045, 0x0013, 0x14e1, 0x0015, 0x00b2, 0x0000, 0x0002, + 0x0003, 0x04eb, 0x0002, 0xb046, 0x0003, 0x14e6, 0x0015, 0x00b2, + 0x0000, 0x0001, 0x0003, 0x04eb, 0x0015, 0x00b2, 0x0010, 0x0000, + 0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0013, 0x04f1, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011, + 0x000b, 0x84f0, 0x0010, 0xb16a, 0x0010, 0xb06b, 0x0000, 0xb261, + 0x0015, 0x0044, 0x0010, 0x0018, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0x6241, 0x001b, 0x84fb, + 0x0003, 0x94fc, 0x0015, 0x00a0, 0x0000, 0x0020, 0x0012, 0xd041, + 0x000b, 0x14ff, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9503, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8, + 0x0010, 0x0009, 0x0013, 0x9509, 0x0000, 0xff75, 0x0003, 0x950b, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x00b1, + 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0033, + 0x0000, 0xb012, 0x000b, 0x8519, 0x0013, 0x046b, 0x0000, 0xba30, + 0x0005, 0x0031, 0x0010, 0x0035, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x8520, 0x0002, 0xb040, 0x0003, 0x153c, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0005, 0x0031, 0x0001, 0x1b71, 0x0015, 0x0033, + 0x0000, 0xb011, 0x000b, 0x8529, 0x0002, 0xb100, 0x0010, 0xffb1, + 0x001b, 0x2530, 0x0012, 0xb000, 0x0000, 0xffb0, 0x0013, 0x252a, + 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8532, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0013, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x853a, 0x0003, 0x053e, + 0x0010, 0xc0b1, 0x0000, 0xc0b0, 0x0017, 0x4000, 0x0005, 0x00b6, + 0x0010, 0x0500, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0889, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x854b, + 0x0010, 0xb058, 0x0000, 0x0d59, 0x0000, 0xb930, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x8553, + 0x0010, 0xb15c, 0x0010, 0xb05d, 0x0005, 0x0031, 0x0010, 0x002b, + 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x855a, 0x0000, 0xb15e, + 0x0000, 0xb05f, 0x0003, 0x955d, 0x0015, 0x00a0, 0x0010, 0x000c, + 0x0003, 0x0668, 0x0005, 0x00b6, 0x0000, 0x0700, 0x0014, 0x0683, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb709, 0x000b, 0x856b, + 0x0012, 0xb749, 0x0003, 0x1571, 0x0005, 0x0054, 0x0010, 0x0889, + 0x0003, 0x0573, 0x0005, 0x0054, 0x0010, 0x0898, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x857a, 0x0010, 0xb058, + 0x0000, 0x0d59, 0x0001, 0xb9c8, 0x0010, 0xf000, 0x0001, 0xffe8, + 0x0010, 0xf000, 0x001b, 0x15a3, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x8589, 0x0001, 0xb0c8, 0x0000, 0xf700, + 0x0000, 0xffb0, 0x0011, 0xb0e8, 0x0000, 0xf100, 0x0013, 0x15ea, + 0x0011, 0xb0e8, 0x0000, 0xf200, 0x0013, 0x15ef, 0x0011, 0xb0e8, + 0x0010, 0xf300, 0x0003, 0x1614, 0x0011, 0xb0e8, 0x0000, 0xf400, + 0x0013, 0x1619, 0x0011, 0xb0e8, 0x0010, 0xf500, 0x0013, 0x15ea, + 0x0011, 0xb0e8, 0x0010, 0xf600, 0x0003, 0x162b, 0x0005, 0x00ce, + 0x0010, 0x0009, 0x0000, 0xb0cf, 0x0003, 0x08e1, 0x0000, 0xb930, + 0x0005, 0x0031, 0x0000, 0x0025, 0x0015, 0x0033, 0x0000, 0xb039, + 0x000b, 0x85a8, 0x0012, 0xb749, 0x0013, 0x15ad, 0x0002, 0xb52c, + 0x0000, 0xffb5, 0x0000, 0xb162, 0x0000, 0xb063, 0x0005, 0x0031, + 0x0000, 0x001f, 0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x85b3, + 0x0001, 0xb3c8, 0x0010, 0x0003, 0x0003, 0x15bb, 0x0010, 0xffb2, + 0x0001, 0xffe8, 0x0010, 0x0003, 0x001b, 0x15bd, 0x0000, 0xc2b7, + 0x0013, 0x0647, 0x0001, 0xb2e8, 0x0000, 0x0001, 0x0013, 0x15c4, + 0x0005, 0x00ce, 0x0010, 0x000a, 0x0010, 0xb2cf, 0x0003, 0x08e1, + 0x0010, 0xb465, 0x0010, 0xb667, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0001, 0xb5c8, 0x0010, 0x0300, 0x0013, 0x15e9, 0x0012, 0xb548, + 0x0013, 0x15d0, 0x0000, 0xb6ff, 0x0011, 0xb780, 0x0010, 0xffb7, + 0x0002, 0xb549, 0x0013, 0x15d5, 0x0010, 0xb4ff, 0x0011, 0xb780, + 0x0010, 0xffb7, 0x0015, 0x0044, 0x0010, 0x0018, 0x0005, 0x0031, + 0x0000, 0x002c, 0x0015, 0x0033, 0x0000, 0x6841, 0x001b, 0x85db, + 0x0015, 0x0044, 0x0000, 0x0019, 0x0005, 0x0031, 0x0000, 0x0034, + 0x0015, 0x0033, 0x0000, 0x5029, 0x001b, 0x85e2, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0011, 0xb7c8, 0x0010, 0x0003, 0x0013, 0x15e9, + 0x0010, 0xff55, 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0008, + 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x000b, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x85f6, 0x0010, 0xb1ff, + 0x0001, 0xb0d0, 0x0003, 0x15ff, 0x0005, 0x00b5, 0x0010, 0x0b02, + 0x0010, 0xb062, 0x0010, 0xb163, 0x0003, 0x0601, 0x0005, 0x00b5, + 0x0000, 0x0302, 0x0015, 0x0065, 0x0010, 0x0012, 0x0005, 0x0067, + 0x0000, 0x0008, 0x0015, 0x006c, 0x0000, 0x7000, 0x0005, 0x006d, + 0x0010, 0x0500, 0x0015, 0x006f, 0x0010, 0x000a, 0x0015, 0x0044, + 0x0000, 0x0001, 0x0005, 0x0052, 0x0000, 0x2500, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0015, 0x00b7, 0x0000, 0x0032, 0x0013, 0x0647, + 0x0005, 0x00b5, 0x0010, 0x0028, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0013, 0x0647, 0x0005, 0x00b5, 0x0000, 0x0100, 0x0005, 0x0067, + 0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x001b, 0x8624, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0010, 0xff69, + 0x0015, 0x00b7, 0x0000, 0x0020, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb609, 0x000b, 0x8632, 0x0001, 0xb6c8, + 0x0010, 0xff00, 0x0000, 0xffb0, 0x0015, 0x0033, 0x0000, 0xb00a, + 0x000b, 0x8638, 0x0001, 0xb6c8, 0x0010, 0x00ff, 0x0012, 0xff10, + 0x001b, 0x1641, 0x0000, 0xffb5, 0x0015, 0x00b7, 0x0010, 0x0018, + 0x0013, 0x0647, 0x0010, 0xff63, 0x0005, 0x00b5, 0x0000, 0x0800, + 0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0647, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x864e, 0x0010, 0xb561, + 0x0013, 0x9650, 0x0010, 0xb7a0, 0x0003, 0x0668, 0x0005, 0x00b6, + 0x0010, 0x0300, 0x0014, 0x0683, 0x0005, 0x0054, 0x0010, 0x0819, + 0x0010, 0x0d58, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x001b, 0x8660, 0x0000, 0xb059, 0x0003, 0x9662, 0x0010, 0xc0a0, + 0x0010, 0x71ff, 0x0002, 0xff28, 0x0010, 0xff71, 0x0003, 0x0668, + 0x0012, 0xd041, 0x000b, 0x1668, 0x0015, 0x00d1, 0x0010, 0x0202, + 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8, + 0x0010, 0x0009, 0x0013, 0x9671, 0x0000, 0xff75, 0x0003, 0x9673, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0xbd88, 0x0000, 0x0008, 0x0000, 0xff31, 0x0005, 0x00b0, + 0x0010, 0x0009, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0015, 0x0033, + 0x0000, 0xb012, 0x001b, 0x8681, 0x0013, 0x046b, 0x0015, 0x0044, + 0x0000, 0x0008, 0x0005, 0x0098, 0x0010, 0x0056, 0x0015, 0x0099, + 0x0000, 0x9575, 0x0004, 0x08a8, 0x0000, 0xb096, 0x0012, 0xb270, + 0x0010, 0xff56, 0x0014, 0x08ca, 0x0010, 0xb052, 0x0010, 0xb153, + 0x0000, 0xb6ff, 0x0011, 0xb2d0, 0x0010, 0xff50, 0x0010, 0xb351, + 0x0017, 0x4000, 0x0001, 0x12e8, 0x0001, 0x1b55, 0x0003, 0x1845, + 0x0015, 0x00d1, 0x0000, 0x0400, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0x1009, 0x000b, 0x86a1, 0x0015, 0x000f, 0x0000, 0x0001, + 0x0010, 0xc014, 0x0000, 0x1213, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xba09, 0x000b, 0x86ad, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0x1a09, 0x000b, 0x86b5, 0x0012, 0x104b, 0x001b, 0x16be, + 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000b, 0x0015, 0x0033, + 0x0000, 0x1621, 0x001b, 0x86bd, 0x0010, 0x15fe, 0x000b, 0x66dd, + 0x0004, 0x0704, 0x0002, 0x3a42, 0x000b, 0x1703, 0x0001, 0x10c8, + 0x0010, 0x000f, 0x000b, 0x1766, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x86cd, 0x0011, 0xb0e8, 0x0010, 0x0009, + 0x0003, 0x16d4, 0x0011, 0xb0e8, 0x0000, 0x0001, 0x001b, 0x1702, + 0x0011, 0x1388, 0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb009, 0x000b, 0x86d9, 0x0002, 0xb04f, 0x001b, 0x16f9, + 0x0013, 0x0702, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, + 0x001b, 0x86e4, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x86e7, + 0x0010, 0xb0fe, 0x0003, 0x66ec, 0x0000, 0xb012, 0x0013, 0x06ee, + 0x0010, 0xc012, 0x0010, 0xc011, 0x0015, 0x000f, 0x0010, 0x0000, + 0x0002, 0x3944, 0x0013, 0x16f7, 0x0015, 0x0039, 0x0000, 0x5040, + 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x0925, 0x0000, 0xc013, + 0x0003, 0x0703, 0x0010, 0x02fe, 0x0003, 0x66fe, 0x0015, 0x003a, + 0x0010, 0x2020, 0x0003, 0x0703, 0x0015, 0x003a, 0x0000, 0x2000, + 0x0015, 0x003a, 0x0010, 0x1010, 0x0004, 0x0911, 0x0003, 0x0054, + 0x0003, 0xb704, 0x0005, 0x002a, 0x0000, 0x0004, 0x0000, 0xba30, + 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, 0x0000, 0xb009, + 0x000b, 0x870c, 0x0000, 0xc02c, 0x0000, 0xb02d, 0x0012, 0x104b, + 0x0013, 0x1727, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0023, + 0x0015, 0x0033, 0x0000, 0xb129, 0x001b, 0x8716, 0x0000, 0xb120, + 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, + 0x0000, 0xc025, 0x0010, 0xb526, 0x0010, 0xc027, 0x0010, 0xb516, + 0x0010, 0xc017, 0x0000, 0xb518, 0x0000, 0xc019, 0x0010, 0xc028, + 0x0000, 0xc029, 0x0010, 0xc01e, 0x0013, 0x075d, 0x0012, 0x1044, + 0x0003, 0x1757, 0x0002, 0x1034, 0x0000, 0xff10, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b29, + 0x000b, 0x8730, 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033, + 0x0000, 0xb131, 0x000b, 0x8735, 0x0002, 0x1f43, 0x000b, 0x173c, + 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0000, 0xc0b3, 0x0010, 0xc0b4, + 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423, + 0x0000, 0xb524, 0x0010, 0xb625, 0x0010, 0xb516, 0x0000, 0xb617, + 0x0000, 0x1826, 0x0000, 0x1927, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x874b, + 0x0000, 0xb028, 0x0000, 0xb129, 0x0012, 0x1e10, 0x0010, 0xff1e, + 0x0013, 0x675d, 0x0002, 0x1d00, 0x0010, 0xff1d, 0x0004, 0x02ab, + 0x0002, 0x3a42, 0x0003, 0x175d, 0x0003, 0x0765, 0x0000, 0x1a30, + 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b79, + 0x000b, 0x875c, 0x0003, 0xb75d, 0x0005, 0x002a, 0x0000, 0x0001, + 0x0005, 0x0015, 0x0000, 0x0001, 0x0000, 0x1efe, 0x0003, 0x6765, + 0x0003, 0x0277, 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031, + 0x0010, 0x001b, 0x0015, 0x0033, 0x0010, 0xb051, 0x001b, 0x876b, + 0x0000, 0xb0a3, 0x0010, 0xb697, 0x0010, 0xb946, 0x0015, 0x00a5, + 0x0000, 0x0010, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, + 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb509, + 0x000b, 0x8778, 0x0014, 0x08ca, 0x0004, 0x08b9, 0x0012, 0xb470, + 0x0010, 0xffb4, 0x0010, 0xb48e, 0x0010, 0xb08a, 0x0010, 0xb18b, + 0x0012, 0x104d, 0x0003, 0x1783, 0x0013, 0x07b0, 0x0012, 0x104b, + 0x0013, 0x1796, 0x0005, 0x008c, 0x0010, 0x0829, 0x0010, 0xc08d, + 0x0001, 0xb2d8, 0x0010, 0x0600, 0x0010, 0xff88, 0x0010, 0xb389, + 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0010, 0x1ab9, + 0x0004, 0x051b, 0x0013, 0x9791, 0x0010, 0xb092, 0x0010, 0xb193, + 0x0013, 0x9794, 0x0013, 0x07ab, 0x0005, 0x008c, 0x0000, 0x0809, + 0x0015, 0x008d, 0x0000, 0x0008, 0x0001, 0xb2d8, 0x0000, 0x0100, + 0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591, + 0x0000, 0xc08f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, + 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x87a6, 0x0013, 0x97a7, + 0x0000, 0xb192, 0x0000, 0xb093, 0x0003, 0x97aa, 0x0010, 0x19a1, + 0x0000, 0x18a2, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0003, 0x0821, + 0x0000, 0xb590, 0x0010, 0x1391, 0x0001, 0x10c8, 0x0010, 0x000f, + 0x0001, 0xffe8, 0x0010, 0x0005, 0x0013, 0x17d7, 0x0001, 0xb2d8, + 0x0000, 0x0700, 0x0010, 0xff88, 0x0010, 0xb389, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0009, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87c2, 0x0002, 0xb049, + 0x0013, 0x17ca, 0x0005, 0x008c, 0x0010, 0x0889, 0x0015, 0x00b1, + 0x0010, 0x0096, 0x0013, 0x07ce, 0x0005, 0x008c, 0x0010, 0x0898, + 0x0015, 0x00b1, 0x0000, 0x0092, 0x0010, 0xc08d, 0x0000, 0xc08f, + 0x0013, 0x97d0, 0x0000, 0xc092, 0x0010, 0xc093, 0x0013, 0x97d3, + 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0003, 0x0821, 0x0001, 0xb2d8, + 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389, 0x0005, 0x008c, + 0x0010, 0x0880, 0x0015, 0x008d, 0x0000, 0x0008, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x87e6, 0x0010, 0xb08f, + 0x0000, 0xb590, 0x0010, 0x1391, 0x0000, 0x1a30, 0x0005, 0x0031, + 0x0000, 0x000d, 0x0015, 0x0033, 0x0000, 0xb021, 0x001b, 0x87ef, + 0x0003, 0x97f0, 0x0010, 0xb392, 0x0010, 0xb293, 0x0003, 0x97f3, + 0x0000, 0xb1a1, 0x0010, 0xb0a2, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb211, 0x001b, 0x87fd, 0x0000, 0xb3ff, 0x0001, 0xb080, + 0x0000, 0xffb3, 0x001b, 0x2804, 0x0002, 0xb200, 0x0003, 0x0805, + 0x0010, 0xb2ff, 0x0011, 0xb180, 0x0010, 0xffb2, 0x0011, 0x1388, + 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb212, + 0x000b, 0x880c, 0x0015, 0x00b1, 0x0000, 0x0092, 0x0002, 0x104c, + 0x0003, 0x181f, 0x0011, 0xc2e8, 0x0010, 0x000c, 0x000b, 0x1817, + 0x0015, 0x00ff, 0x0000, 0x0800, 0x0013, 0x081f, 0x0011, 0xc2e8, + 0x0000, 0x0020, 0x000b, 0x181d, 0x0015, 0x00ff, 0x0010, 0x1800, + 0x0013, 0x081f, 0x0015, 0x00ff, 0x0000, 0x1000, 0x0011, 0xb1d0, + 0x0010, 0xffb1, 0x0015, 0x009a, 0x0010, 0x0036, 0x0005, 0x009b, + 0x0000, 0x95d5, 0x0012, 0xd041, 0x001b, 0x1825, 0x0015, 0x00d1, + 0x0010, 0x0202, 0x0013, 0x9829, 0x0012, 0x104e, 0x0013, 0x182e, + 0x0012, 0xb12f, 0x0010, 0xffb1, 0x0000, 0xb175, 0x0013, 0x982f, + 0x0015, 0x00d1, 0x0000, 0x0200, 0x0001, 0x19c8, 0x0010, 0xfff0, + 0x001b, 0x1838, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0003, 0x083a, + 0x0015, 0x00b1, 0x0000, 0x1b58, 0x0005, 0x00b0, 0x0010, 0x0009, + 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x000b, + 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x8843, + 0x0003, 0x0703, 0x0015, 0x0030, 0x0000, 0x0400, 0x0000, 0xa4ff, + 0x0003, 0x6893, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x2893, + 0x0005, 0x0031, 0x0001, 0x1b6c, 0x0015, 0x0033, 0x0010, 0xb211, + 0x000b, 0x8850, 0x0002, 0xb200, 0x0010, 0xffb2, 0x0005, 0x0031, + 0x0001, 0x1b6c, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8857, + 0x0015, 0x000f, 0x0000, 0x0001, 0x0000, 0x1213, 0x0005, 0x0010, + 0x0000, 0x8000, 0x0015, 0x00a3, 0x0000, 0x0200, 0x0000, 0xc697, + 0x0005, 0x0046, 0x0000, 0x0002, 0x0015, 0x00a5, 0x0000, 0x0010, + 0x0011, 0xc4d8, 0x0000, 0x3200, 0x0010, 0xff88, 0x0000, 0xc589, + 0x0010, 0xc48a, 0x0010, 0xc58b, 0x0010, 0xc08e, 0x0005, 0x008c, + 0x0010, 0xe109, 0x0010, 0xc08d, 0x0015, 0x0090, 0x0001, 0x1b55, + 0x0005, 0x0091, 0x0010, 0xffff, 0x0000, 0xb292, 0x0000, 0xb393, + 0x0015, 0x009a, 0x0010, 0x0056, 0x0005, 0x009b, 0x0010, 0x95f5, + 0x0012, 0xd042, 0x0003, 0x1886, 0x0005, 0x00b0, 0x0010, 0x8080, + 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb00a, 0x000b, 0x8881, 0x0015, 0x00b8, 0x0010, 0x000c, + 0x0014, 0x0925, 0x0003, 0x0888, 0x0005, 0x0075, 0x0010, 0x8092, + 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0, 0x0010, 0x0009, + 0x0001, 0xbd88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0000, 0xb012, 0x001b, 0x8891, 0x0003, 0x0703, 0x0015, 0x00d1, + 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x889a, 0x0001, 0x1288, + 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, + 0x000b, 0x88a0, 0x0010, 0xb0fe, 0x0003, 0x68a5, 0x0000, 0xb012, + 0x0003, 0x0703, 0x0010, 0xc012, 0x0010, 0xc011, 0x0003, 0x0703, + 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033, + 0x0010, 0xb019, 0x001b, 0x88ad, 0x0002, 0xb200, 0x0011, 0xffc8, + 0x0010, 0x00ff, 0x0010, 0xffb2, 0x0010, 0xb2b7, 0x0005, 0x0031, + 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x88b7, + 0x0017, 0x4000, 0x0000, 0xba30, 0x0005, 0x0031, 0x0000, 0x0023, + 0x0015, 0x0033, 0x0010, 0xb409, 0x000b, 0x88be, 0x0002, 0xb400, + 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb4, 0x0010, 0xb4b7, + 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb40a, + 0x001b, 0x88c8, 0x0017, 0x4000, 0x0000, 0xba30, 0x0001, 0xc7c8, + 0x0000, 0x0020, 0x001b, 0x18d6, 0x0005, 0x0031, 0x0010, 0x0028, + 0x0015, 0x0033, 0x0010, 0xb209, 0x000b, 0x88d2, 0x0011, 0xb2c8, + 0x0000, 0xff80, 0x0003, 0x18d9, 0x0010, 0xc4b0, 0x0010, 0xc5b1, + 0x0003, 0x08db, 0x0010, 0xc6b1, 0x0000, 0xc0b0, 0x0005, 0x0031, + 0x0000, 0x0004, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x88df, + 0x0017, 0x4000, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a, + 0x0010, 0x0707, 0x0014, 0x0925, 0x0013, 0x002d, 0x0015, 0x00b8, + 0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0003, 0x0925, + 0x0004, 0x011c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, + 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, + 0x001b, 0x88f4, 0x0004, 0x08a8, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb20a, 0x001b, 0x88fd, 0x0015, 0x0030, 0x0000, 0x0400, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0x0309, 0x001b, 0x8905, 0x0002, 0x0327, 0x0010, 0xffb2, + 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, + 0x0010, 0xb20a, 0x000b, 0x890d, 0x0015, 0x00b8, 0x0010, 0x0006, + 0x0003, 0x0925, 0x0014, 0x012e, 0x0004, 0x08a8, 0x0015, 0x0030, + 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0010, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x891a, 0x0012, 0x1027, + 0x0010, 0xffb2, 0x0011, 0x1388, 0x0010, 0x0011, 0x0000, 0xff31, + 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x8922, 0x0015, 0x00b8, + 0x0000, 0x0007, 0x0013, 0x4925, 0x0000, 0xb838, 0x0017, 0x4000, + 0x9a8c, 0xaf3d +}; +unsigned short xseqipx_code_length01 = 0x1252; diff --git a/trunk/drivers/scsi/qla2xxx/ql2400.c b/trunk/drivers/scsi/qla2xxx/ql2400.c new file mode 100644 index 000000000000..77914fcfa2bc --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2400.c @@ -0,0 +1,138 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include +#include +#include + +#include "qla_def.h" + +static char qla_driver_name[] = "qla2400"; + +extern uint32_t fw2400_version_str[]; +extern uint32_t fw2400_addr01; +extern uint32_t fw2400_code01[]; +extern uint32_t fw2400_length01; +extern uint32_t fw2400_addr02; +extern uint32_t fw2400_code02[]; +extern uint32_t fw2400_length02; + +static struct qla_fw_info qla_fw_tbl[] = { + { + .addressing = FW_INFO_ADDR_EXTENDED, + .fwcode = (unsigned short *)&fw2400_code01[0], + .fwlen = (unsigned short *)&fw2400_length01, + .lfwstart = (unsigned long *)&fw2400_addr01, + }, + { + .addressing = FW_INFO_ADDR_EXTENDED, + .fwcode = (unsigned short *)&fw2400_code02[0], + .fwlen = (unsigned short *)&fw2400_length02, + .lfwstart = (unsigned long *)&fw2400_addr02, + }, + { FW_INFO_ADDR_NOMORE, }, +}; + +static struct qla_board_info qla_board_tbl[] = { + { + .drv_name = qla_driver_name, + .isp_name = "ISP2422", + .fw_info = qla_fw_tbl, + .fw_fname = "ql2400_fw.bin", + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP2432", + .fw_info = qla_fw_tbl, + .fw_fname = "ql2400_fw.bin", + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP5422", + .fw_info = qla_fw_tbl, + .fw_fname = "ql2400_fw.bin", + }, + { + .drv_name = qla_driver_name, + .isp_name = "ISP5432", + .fw_info = qla_fw_tbl, + .fw_fname = "ql2400_fw.bin", + }, +}; + +static struct pci_device_id qla24xx_pci_tbl[] = { + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2422, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[0], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP2432, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[1], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP5422, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[2], + }, + { + .vendor = PCI_VENDOR_ID_QLOGIC, + .device = PCI_DEVICE_ID_QLOGIC_ISP5432, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (unsigned long)&qla_board_tbl[3], + }, + + {0, 0}, +}; +MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl); + +static int __devinit +qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return qla2x00_probe_one(pdev, + (struct qla_board_info *)id->driver_data); +} + +static void __devexit +qla24xx_remove_one(struct pci_dev *pdev) +{ + qla2x00_remove_one(pdev); +} + +static struct pci_driver qla24xx_pci_driver = { + .name = "qla2400", + .id_table = qla24xx_pci_tbl, + .probe = qla24xx_probe_one, + .remove = __devexit_p(qla24xx_remove_one), +}; + +static int __init +qla24xx_init(void) +{ + return pci_module_init(&qla24xx_pci_driver); +} + +static void __exit +qla24xx_exit(void) +{ + pci_unregister_driver(&qla24xx_pci_driver); +} + +module_init(qla24xx_init); +module_exit(qla24xx_exit); + +MODULE_AUTHOR("QLogic Corporation"); +MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(QLA2XXX_VERSION); diff --git a/trunk/drivers/scsi/qla2xxx/ql2400_fw.c b/trunk/drivers/scsi/qla2xxx/ql2400_fw.c new file mode 100644 index 000000000000..282b2d33ebf2 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/ql2400_fw.c @@ -0,0 +1,12346 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include + +/* + * Firmware Version 4.00.18 (14:53 Jan 30, 2006) + */ + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_version = 4*1024+0; +#else +uint32_t risc_code_version = 4*1024+0; +#endif + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_version_str[] = {4, 0,18}; +#else +uint32_t firmware_version[] = {4, 0,18}; +#endif + +#ifdef UNIQUE_FW_NAME +#define fw2400_VERSION_STRING "4.00.18" +#else +#define FW_VERSION_STRING "4.00.18" +#endif + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_addr01 = 0x00100000 ; +#else +uint32_t risc_code_addr01 = 0x00100000 ; +#endif + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_code01[] = { +#else +uint32_t risc_code01[] = { +#endif + 0x0401f17c, 0x0010d000, 0x00100000, 0x0000a971, + 0x00000004, 0x00000000, 0x00000012, 0x00000002, + 0x00000003, 0x00000000, 0x20434f50, 0x59524947, + 0x48542032, 0x30303520, 0x514c4f47, 0x49432043, + 0x4f52504f, 0x52415449, 0x4f4e2020, 0x20495350, + 0x32347878, 0x20466972, 0x6d776172, 0x65202020, + 0x56657273, 0x696f6e20, 0x342e302e, 0x31382020, + 0x20202024, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x42001800, 0x0010014f, 0x42002000, 0x0010b6fd, + 0x500c0800, 0x800c1800, 0x500c1000, 0x800c1800, + 0x54042000, 0x80102000, 0x80040800, 0x80081040, + 0x040207fc, 0x500c0800, 0x800409c0, 0x040207f6, + 0x44002000, 0x80102000, 0x40100000, 0x44040000, + 0x80000000, 0x44080000, 0x80000000, 0x440c0000, + 0x80000000, 0x44100000, 0x80000000, 0x44140000, + 0x80000000, 0x44180000, 0x80000000, 0x441c0000, + 0x80000000, 0x44200000, 0x80000000, 0x44240000, + 0x80000000, 0x44280000, 0x80000000, 0x442c0000, + 0x80000000, 0x44300000, 0x80000000, 0x44340000, + 0x80000000, 0x44380000, 0x80000000, 0x443c0000, + 0x80000000, 0x44400000, 0x80000000, 0x44440000, + 0x80000000, 0x44480000, 0x80000000, 0x444c0000, + 0x80000000, 0x44500000, 0x80000000, 0x44540000, + 0x80000000, 0x44580000, 0x80000000, 0x445c0000, + 0x80000000, 0x44600000, 0x80000000, 0x44640000, + 0x80000000, 0x44680000, 0x80000000, 0x446c0000, + 0x80000000, 0x44700000, 0x80000000, 0x44740000, + 0x80000000, 0x44780000, 0x80000000, 0x447c0000, + 0x80000000, 0x44800000, 0x80000000, 0x44840000, + 0x80000000, 0x44880000, 0x80000000, 0x448c0000, + 0x80000000, 0x44900000, 0x80000000, 0x44940000, + 0x80000000, 0x44980000, 0x80000000, 0x449c0000, + 0x80000000, 0x44a00000, 0x80000000, 0x44a40000, + 0x80000000, 0x44a80000, 0x80000000, 0x44ac0000, + 0x80000000, 0x44b00000, 0x80000000, 0x44b40000, + 0x80000000, 0x44b80000, 0x80000000, 0x44bc0000, + 0x80000000, 0x44c00000, 0x80000000, 0x44c40000, + 0x80000000, 0x44c80000, 0x80000000, 0x44cc0000, + 0x80000000, 0x44d00000, 0x80000000, 0x44d80000, + 0x80000000, 0x44d40000, 0x80000000, 0x44dc0000, + 0x80000000, 0x44e00000, 0x80000000, 0x44e40000, + 0x80000000, 0x44e80000, 0x80000000, 0x44ec0000, + 0x80000000, 0x44f00000, 0x80000000, 0x44f40000, + 0x80000000, 0x44f80000, 0x80000000, 0x44fc0000, + 0x80000000, 0x45000000, 0x80000000, 0x45040000, + 0x80000000, 0x45080000, 0x80000000, 0x450c0000, + 0x80000000, 0x45100000, 0x80000000, 0x45140000, + 0x80000000, 0x45180000, 0x80000000, 0x451c0000, + 0x80000000, 0x45200000, 0x80000000, 0x45240000, + 0x80000000, 0x45280000, 0x80000000, 0x452c0000, + 0x80000000, 0x45300000, 0x80000000, 0x45340000, + 0x80000000, 0x45380000, 0x80000000, 0x453c0000, + 0x80000000, 0x45400000, 0x80000000, 0x45440000, + 0x80000000, 0x45480000, 0x80000000, 0x454c0000, + 0x80000000, 0x45500000, 0x80000000, 0x45540000, + 0x80000000, 0x45580000, 0x80000000, 0x455c0000, + 0x80000000, 0x45600000, 0x80000000, 0x45640000, + 0x80000000, 0x45680000, 0x80000000, 0x456c0000, + 0x80000000, 0x45700000, 0x80000000, 0x45740000, + 0x80000000, 0x45780000, 0x80000000, 0x457c0000, + 0x80000000, 0x45800000, 0x80000000, 0x45840000, + 0x80000000, 0x45880000, 0x80000000, 0x458c0000, + 0x80000000, 0x45900000, 0x80000000, 0x45940000, + 0x80000000, 0x45980000, 0x80000000, 0x459c0000, + 0x80000000, 0x45a00000, 0x80000000, 0x45a40000, + 0x80000000, 0x45a80000, 0x80000000, 0x45ac0000, + 0x80000000, 0x45b00000, 0x80000000, 0x45b40000, + 0x80000000, 0x45b80000, 0x80000000, 0x45bc0000, + 0x80000000, 0x45c00000, 0x80000000, 0x45c40000, + 0x80000000, 0x45c80000, 0x80000000, 0x45cc0000, + 0x80000000, 0x45d00000, 0x80000000, 0x45d40000, + 0x80000000, 0x45d80000, 0x80000000, 0x45dc0000, + 0x80000000, 0x45e00000, 0x80000000, 0x45e40000, + 0x80000000, 0x45e80000, 0x80000000, 0x45ec0000, + 0x80000000, 0x45f00000, 0x80000000, 0x45f40000, + 0x80000000, 0x45f80000, 0x80000000, 0x45fc0000, + 0x4a03c020, 0x00004000, 0x4a03c011, 0x40000010, + 0x04006000, 0x4203e000, 0x40000000, 0x59e00017, + 0x8c000508, 0x04000003, 0x4a03c017, 0x00000000, + 0x4203e000, 0x30000001, 0x0401f000, 0x0000bf00, + 0x00000080, 0x0000bfe0, 0x00000020, 0x0000ff00, + 0x00000080, 0x0000ffd0, 0x00000030, 0x00007100, + 0x00000010, 0x00007200, 0x00000008, 0x00007209, + 0x00000007, 0x00007300, 0x00000008, 0x00007309, + 0x00000007, 0x00007400, 0x00000008, 0x00007409, + 0x00000007, 0x00007600, 0x000000b0, 0x00007700, + 0x00000040, 0x00003000, 0x00000070, 0x00004000, + 0x000000c0, 0x00006000, 0x00000050, 0x00006100, + 0x00000010, 0x00006130, 0x00000010, 0x00006150, + 0x00000010, 0x00006170, 0x00000010, 0x00006190, + 0x00000010, 0x000061b0, 0x00000010, 0x00000000, + 0x42000000, 0x00000100, 0x4202f000, 0x00000000, + 0x42000800, 0x00021f00, 0x45780800, 0x80040800, + 0x80000040, 0x040207fd, 0x4203f000, 0x00021fff, + 0x40000000, 0x4203e000, 0x90000100, 0x40000000, + 0x0201f800, 0x00100743, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24320002, 0x04020015, + 0x42000800, 0x00000064, 0x80040840, 0x04000007, + 0x4a030000, 0x00000001, 0x40000000, 0x59800000, + 0x8c000500, 0x040007f9, 0x04000008, 0x42000800, + 0x00007a17, 0x50040000, 0x8c00050e, 0x04020003, + 0x8400054e, 0x44000800, 0x4a030000, 0x00000000, + 0x4a03c020, 0x00000004, 0x4203e000, 0x6000000f, + 0x59e00023, 0x8c000500, 0x04020039, 0x42000000, + 0x00100001, 0x50000800, 0x82040c00, 0x00000004, + 0x58042003, 0x42001000, 0xffffffff, 0x0201f800, + 0x0010073a, 0x0402004e, 0x58042003, 0x42001000, + 0xffffffff, 0x0201f800, 0x0010073a, 0x04020048, + 0x58042003, 0x42001000, 0x00ffffff, 0x0201f800, + 0x0010073a, 0x04020042, 0x58042003, 0x42001000, + 0x00ffffff, 0x0201f800, 0x0010073a, 0x0402003c, + 0x42000000, 0x00100001, 0x5000a000, 0x8250a400, + 0x00000004, 0x4200a800, 0x00020000, 0x5850b003, + 0x0201f800, 0x0010a93e, 0x8250a400, 0x00000005, + 0x4a0370e8, 0x00000003, 0x4200a800, 0x0000c000, + 0x5850b003, 0x0201f800, 0x0010a93e, 0x4a0378e8, + 0x00000003, 0x4200a800, 0x00008000, 0x5850b003, + 0x0201f800, 0x0010a93e, 0x0401f02b, 0x42000800, + 0x00020000, 0x58042003, 0x42001000, 0xffffffff, + 0x0201f800, 0x0010073a, 0x04020019, 0x4a0370e8, + 0x00000003, 0x42000800, 0x0000c000, 0x58042003, + 0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff, + 0x0201f800, 0x0010073a, 0x0402000d, 0x4a0378e8, + 0x00000003, 0x42000800, 0x00008000, 0x58042003, + 0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff, + 0x0201f800, 0x0010073a, 0x0400000b, 0x4a03c020, + 0x00004010, 0x4a03c011, 0x40100011, 0x04006000, + 0x4203e000, 0x40000000, 0x4203e000, 0x30000001, + 0x0401f000, 0x0201f800, 0x001007d7, 0x42001000, + 0x0010a971, 0x40080000, 0x80140480, 0x82001d00, + 0xffffff00, 0x04020003, 0x40001800, 0x0401f003, + 0x42001800, 0x000000ff, 0x480bc840, 0x480fc842, + 0x04011000, 0x400c0000, 0x80081400, 0x40140000, + 0x80080580, 0x040207f0, 0x4817500d, 0x45782800, + 0x59c40000, 0x82000500, 0xffff0000, 0x80000120, + 0x82000580, 0x00002422, 0x04020005, 0x59a8006f, + 0x84000540, 0x4803506f, 0x0401f00a, 0x59e00003, + 0x82000500, 0x00030000, 0x82000580, 0x00010000, + 0x04020004, 0x59a8006f, 0x84000542, 0x4803506f, + 0x42000800, 0x00000040, 0x59a8006f, 0x8c000502, + 0x0402000e, 0x42000800, 0x00001000, 0x82141480, + 0x0017ffff, 0x04021009, 0x80040902, 0x82141480, + 0x0013ffff, 0x04021005, 0x80040902, 0x82141480, + 0x0011ffff, 0x04001bc8, 0x4807500e, 0x42001000, + 0x00000024, 0x0201f800, 0x001063cf, 0x82040c00, + 0x0010cfc0, 0x4807500b, 0x4a03c810, 0x00100000, + 0x4a03c811, 0x0010a971, 0x4a03c829, 0x00000004, + 0x59e40001, 0x82000540, 0x0003001d, 0x4803c801, + 0x4a03c014, 0x001c001c, 0x42001000, 0x0000001c, + 0x0201f800, 0x00100728, 0x4202c000, 0x0010cfc0, + 0x59aab00b, 0x59aaa00b, 0x59aaa80b, 0x59aac80e, + 0x49675069, 0x59a8000b, 0x4803500c, 0x0201f800, + 0x001006a3, 0x0201f800, 0x0010768a, 0x0201f800, + 0x00100804, 0x0201f800, 0x0010084d, 0x0201f800, + 0x00101a60, 0x0201f800, 0x001013a4, 0x0201f800, + 0x001009b6, 0x0201f800, 0x001013a4, 0x0201f800, + 0x00100f9a, 0x0201f800, 0x0010640f, 0x0401fb54, + 0x0201f800, 0x00101fb5, 0x0201f800, 0x0010508b, + 0x0201f800, 0x00104b36, 0x0201f800, 0x00105ecd, + 0x0201f800, 0x00105c61, 0x0201f800, 0x0010143d, + 0x0201f800, 0x001012bf, 0x4203e000, 0xf0000001, + 0x4a035070, 0x00000014, 0x4a035071, 0x0000000b, + 0x4a035072, 0x00000001, 0x4a035073, 0x00000000, + 0x42000000, 0x00001000, 0x50000000, 0x82000480, + 0x24220001, 0x0400004a, 0x59e00002, 0x8c00051e, + 0x42000000, 0x7ffe00fe, 0x04000003, 0x42000000, + 0x7ffe01fe, 0x50000800, 0x48075058, 0x80040920, + 0x82040580, 0x0000013e, 0x0402000b, 0x59a8006f, + 0x84000548, 0x4803506f, 0x4a035070, 0x00000055, + 0x4a035071, 0x00000051, 0x4a035073, 0x0000000f, + 0x0401f033, 0x82040580, 0x0000013f, 0x0402000b, + 0x59a8006f, 0x8400054a, 0x4803506f, 0x4a035070, + 0x00000055, 0x4a035071, 0x00000051, 0x4a035073, + 0x0000000f, 0x0401f026, 0x59e00003, 0x82000500, + 0x00030000, 0x82000580, 0x00000000, 0x04020020, + 0x82040580, 0x00000147, 0x04000010, 0x82040580, + 0x00000145, 0x0402001a, 0x59a8006f, 0x84000546, + 0x4803506f, 0x4a035070, 0x00000033, 0x4a035071, + 0x00000030, 0x4a035072, 0x00000020, 0x4a035073, + 0x00000001, 0x0401f00c, 0x59a8006f, 0x84000544, + 0x4803506f, 0x4a035070, 0x00000033, 0x4a035071, + 0x00000030, 0x4a035072, 0x00000020, 0x4a035073, + 0x00000001, 0x4a0378e4, 0x000c0000, 0x59a8006f, + 0x8c000502, 0x04000004, 0x82000500, 0x00000030, + 0x04000b25, 0x4a03c018, 0x0000000f, 0x4203e000, + 0x20000511, 0x4203e000, 0x50010000, 0x4a03c020, + 0x00000000, 0x04027013, 0x59e00020, 0x82000580, + 0x00000002, 0x0402000f, 0x4a03c020, 0x00004000, + 0x4a03c011, 0x40000010, 0x04006000, 0x4203e000, + 0x40000000, 0x59e00017, 0x8c000508, 0x04000003, + 0x4a03c017, 0x00000000, 0x4203e000, 0x30000001, + 0x4202d800, 0x00000000, 0x4203e000, 0xb0600000, + 0x59a80873, 0x4007f800, 0x0201f000, 0x00020004, + 0x4df00000, 0x4203e000, 0x50000000, 0x416c0000, + 0x82000c80, 0x00000008, 0x04021afb, 0x0c01f804, + 0x5c03e000, 0x0201f000, 0x00020008, 0x00100328, + 0x0010033b, 0x00100411, 0x00100327, 0x0010048c, + 0x00100327, 0x00100327, 0x001005d0, 0x0401faee, + 0x42000800, 0x0010b2a0, 0x5804001d, 0x4803c857, + 0x8c000500, 0x0400000d, 0x84000500, 0x4800081d, + 0x4202d800, 0x00000004, 0x0401fbe8, 0x49f3c857, + 0x5c000800, 0x5c000000, 0x82000540, 0x00003e00, + 0x4c000000, 0x4c040000, 0x1c01f000, 0x0401fbd2, + 0x0201f800, 0x00104e0d, 0x04000010, 0x0201f800, + 0x00104e23, 0x04020035, 0x59940023, 0x82000580, + 0x0010401b, 0x04020004, 0x59940022, 0x800001c0, + 0x0402002e, 0x59c40006, 0x82000540, 0x000000c0, + 0x48038806, 0x0401f029, 0x0201f800, 0x00104d76, + 0x836c0580, 0x00000001, 0x040200be, 0x59a80017, + 0x82000580, 0x00000009, 0x040200ba, 0x497b5010, + 0x4a038893, 0x00000001, 0x42001000, 0x000000f0, + 0x0201f800, 0x001019aa, 0x0201f800, 0x00104e1b, + 0x59c41006, 0x04020006, 0x82081540, 0x000000f1, + 0x82081500, 0xbbffffff, 0x0401f003, 0x82081540, + 0x440000f1, 0x480b8806, 0x0201f800, 0x00105de2, + 0x0201f800, 0x001069b8, 0x42000000, 0x0010b638, + 0x0201f800, 0x0010a86e, 0x42001000, 0x00008030, + 0x497b5013, 0x0401f037, 0x0201f800, 0x00103951, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000480, + 0x00000007, 0x04021093, 0x0201f800, 0x00105de2, + 0x59c400a3, 0x82000500, 0xffefffff, 0x480388a3, + 0x59a8004b, 0x800001c0, 0x04020004, 0x0201f800, + 0x00103f53, 0x0401f087, 0x59a80015, 0x84000546, + 0x48035015, 0x0201f800, 0x00104e13, 0x59c41006, + 0x04020006, 0x82081540, 0x44000001, 0x82081500, + 0xffffff0f, 0x0401f003, 0x82081540, 0x440000f1, + 0x480b8806, 0x497b9005, 0x4a038802, 0x0000ffff, + 0x4a0378e4, 0x00003000, 0x4a0378e4, 0x000c0000, + 0x42000000, 0x0010b60a, 0x0201f800, 0x0010a86e, + 0x59a81010, 0x42000800, 0x00000003, 0x0201f800, + 0x001069af, 0x42001000, 0x00008010, 0x59a8180a, + 0x0201f800, 0x00103857, 0x0201f800, 0x00101886, + 0x59a80805, 0x82040d00, 0xffffffdf, 0x48075005, + 0x0201f800, 0x0010468b, 0x0201f800, 0x00104e0d, + 0x0400000a, 0x0201f800, 0x00103f58, 0x04000007, + 0x4a035013, 0x00000001, 0x497b5021, 0x0201f800, + 0x00103a9f, 0x0401f04f, 0x0201f800, 0x0010473b, + 0x04000005, 0x59c41002, 0x8408150c, 0x480b8802, + 0x0401f012, 0x0201f800, 0x00104e0d, 0x04020006, + 0x59a8001d, 0x80000540, 0x02000800, 0x001090d5, + 0x0401f00a, 0x0201f800, 0x001090d5, 0x59a80026, + 0x8c000506, 0x04020005, 0x59a8001d, 0x80000540, + 0x02020800, 0x00104075, 0x497b5028, 0x497b5027, + 0x497b5018, 0x0201f800, 0x00104e0d, 0x59a81026, + 0x0402000a, 0x0201f800, 0x00101694, 0x80001580, + 0x59a8002a, 0x82000500, 0xffff0000, 0x80040d40, + 0x4807502a, 0x0401f005, 0x59a8002a, 0x82000500, + 0xffff0000, 0x4803502a, 0x599c0017, 0x8c00050a, + 0x04000002, 0x84081544, 0x480b5026, 0x0201f800, + 0x00104e0d, 0x04000004, 0x0201f800, 0x00101694, + 0x48078880, 0x42001000, 0x00000005, 0x0201f800, + 0x00106e07, 0x497b5028, 0x497b501b, 0x4a03501c, + 0x0000ffff, 0x4a0378e4, 0x000000c0, 0x4202d800, + 0x00000002, 0x0201f800, 0x00104e0d, 0x04000007, + 0x59a80026, 0x82000500, 0x0000000c, 0x82000580, + 0x00000004, 0x04000003, 0x0201f800, 0x00101bf0, + 0x1c01f000, 0x59a8001c, 0x82000580, 0x0000ffff, + 0x04000004, 0x0201f800, 0x00101bf0, 0x0401f074, + 0x59a80026, 0x8c00050a, 0x04020003, 0x8c000506, + 0x0400001c, 0x8c000500, 0x0400001a, 0x4a038802, + 0x0000ffbf, 0x8c000502, 0x04000016, 0x599c0018, + 0x8c000516, 0x04020010, 0x59a80027, 0x82000580, + 0x0000ffff, 0x0400000c, 0x0201f800, 0x00101d45, + 0x59a80026, 0x8c000504, 0x0402005d, 0x42001000, + 0x00000003, 0x417a5800, 0x0201f800, 0x00101d6a, + 0x0401f057, 0x59a80028, 0x80000540, 0x04020054, + 0x59a80026, 0x8c000508, 0x04020005, 0x59a8001b, + 0x80000540, 0x0402004e, 0x0401f003, 0x8c000516, + 0x0400004b, 0x0201f800, 0x0010473b, 0x04020048, + 0x599c0018, 0x8c000516, 0x04020004, 0x0201f800, + 0x00104abe, 0x04020042, 0x599c0017, 0x8c00050a, + 0x0400000d, 0x4200b000, 0x000007f0, 0x417a8800, + 0x0201f800, 0x00020267, 0x04020004, 0x59340200, + 0x8c00051a, 0x04020036, 0x81468800, 0x8058b040, + 0x040207f8, 0x4a038802, 0x0000ffff, 0x42001800, + 0x0010b2e7, 0x0401fb98, 0x42001800, 0x0010b2f4, + 0x0401fb95, 0x59a80005, 0x84000502, 0x48035005, + 0x4a0378e4, 0x00000080, 0x4202d800, 0x00000003, + 0x4a03501c, 0x0000ffff, 0x0401fa8b, 0x80000580, + 0x0201f800, 0x001015fa, 0x599c0018, 0x8c000516, + 0x04000004, 0x0201f800, 0x00103929, 0x0401f009, + 0x42001800, 0x0000ffff, 0x42002000, 0x00000006, + 0x42003000, 0x00000000, 0x0201f800, 0x001038c7, + 0x0201f800, 0x00104e23, 0x0400000b, 0x59c40006, + 0x0201f800, 0x00104e0d, 0x04000004, 0x82000500, + 0xffffff0f, 0x0401f003, 0x82000500, 0xfbffffff, + 0x48038806, 0x0201f800, 0x00106c8a, 0x1c01f000, + 0x4c040000, 0x4c080000, 0x4c100000, 0x59a8003e, + 0x82000c80, 0x00000004, 0x04021983, 0x0c01f805, + 0x5c002000, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x0010049c, 0x00100527, 0x00100553, 0x001005b4, + 0x42000000, 0x00000001, 0x0201f800, 0x001015fa, + 0x0201f800, 0x00105de2, 0x59c408a3, 0x82040d00, + 0xfffffff7, 0x480788a3, 0x0201f800, 0x00104e13, + 0x0400000e, 0x0201f800, 0x00104e23, 0x0400000b, + 0x0201f800, 0x00104e1b, 0x04020967, 0x59c400a3, + 0x84000532, 0x84000570, 0x480388a3, 0x4a038808, + 0x00000008, 0x0401f013, 0x59c400a3, 0x84000530, + 0x82000500, 0xbf7fffff, 0x480388a3, 0x42000800, + 0x000000f8, 0x0201f800, 0x00104030, 0x59c400a3, + 0x82000540, 0x00018000, 0x8400051c, 0x480388a3, + 0x82000500, 0xfffeffff, 0x480388a3, 0x497b8808, + 0x59c40006, 0x82000500, 0xfbffff0e, 0x48038806, + 0x497b2822, 0x497b2823, 0x42000800, 0x000001f4, + 0x42001000, 0x001005ce, 0x0201f800, 0x00105cbc, + 0x59c40805, 0x42001000, 0x00000001, 0x0201f800, + 0x001019aa, 0x0201f800, 0x001016ac, 0x0402000a, + 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, + 0x42000000, 0x00000001, 0x0201f800, 0x00101892, + 0x0401f022, 0x0201f800, 0x001016b3, 0x04020008, + 0x41780000, 0x0201f800, 0x001018fa, 0x41780000, + 0x0201f800, 0x00101892, 0x0401f018, 0x0201f800, + 0x001016ba, 0x0402000a, 0x42000000, 0x00000002, + 0x0201f800, 0x001018fa, 0x42000000, 0x00000002, + 0x0201f800, 0x00101892, 0x0401f00c, 0x0201f800, + 0x001016c1, 0x04020918, 0x59a80049, 0x800001c0, + 0x04000006, 0x0201f800, 0x001016c7, 0x4a03503e, + 0x00000001, 0x0401f021, 0x0201f800, 0x00101994, + 0x4a03503e, 0x00000001, 0x0201f800, 0x00104e13, + 0x0400000c, 0x0201f800, 0x00104e23, 0x04000009, + 0x0201f800, 0x00104e1b, 0x04020903, 0x4a035033, + 0x00000001, 0x0201f800, 0x00104d76, 0x0401f00f, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x00000008, 0x04000003, 0x4a038805, 0x04000000, + 0x59c400a3, 0x82000540, 0x0001c000, 0x480388a3, + 0x84000520, 0x480388a3, 0x1c01f000, 0x0401f8a3, + 0x04020004, 0x4a03503e, 0x00000003, 0x0401f027, + 0x0201f800, 0x001016c1, 0x04020011, 0x59a80049, + 0x800001c0, 0x0400000e, 0x0201f800, 0x001016c7, + 0x59a80048, 0x8c00051e, 0x0400001c, 0x0201f800, + 0x00104e1b, 0x04020009, 0x4a035033, 0x00000001, + 0x0201f800, 0x00104d76, 0x0401f004, 0x0201f800, + 0x00101941, 0x04020011, 0x0201f800, 0x00101886, + 0x4a03503e, 0x00000002, 0x497b5049, 0x59c400a3, + 0x84000520, 0x480388a3, 0x497b2822, 0x497b2823, + 0x42000800, 0x0000002d, 0x42001000, 0x001005ce, + 0x0201f800, 0x00105cbc, 0x1c01f000, 0x0401f877, + 0x04020004, 0x4a03503e, 0x00000003, 0x0401f05b, + 0x4a038805, 0x000000f0, 0x0201f800, 0x00101941, + 0x04020050, 0x0201f800, 0x00104e1b, 0x04000044, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x00000008, 0x04000020, 0x59c40005, 0x8c000534, + 0x0402001d, 0x59940022, 0x82000580, 0x00000001, + 0x04020046, 0x0201f800, 0x00104e23, 0x04020043, + 0x4a038805, 0x000000f0, 0x0201f800, 0x00104e67, + 0x4a035032, 0x0000aaaa, 0x4a035033, 0x00000000, + 0x59c408a3, 0x82040d40, 0x00000008, 0x480788a3, + 0x4202d800, 0x00000001, 0x4a03503e, 0x00000000, + 0x4a038805, 0x00000001, 0x497b2822, 0x497b2823, + 0x0401f01f, 0x0201f800, 0x00104e23, 0x04020007, + 0x59a80032, 0x82000580, 0x0000aaaa, 0x04020003, + 0x4a035010, 0x00ffffff, 0x497b5032, 0x59c40006, + 0x82000540, 0x04000001, 0x48038806, 0x59a80805, + 0x8c040d06, 0x04020005, 0x59c408a3, 0x82040d40, + 0x00000008, 0x480788a3, 0x4202d800, 0x00000001, + 0x4a03503e, 0x00000000, 0x4a038805, 0x00000001, + 0x497b2822, 0x497b2823, 0x0401f010, 0x59c40005, + 0x82000500, 0x000000c0, 0x0400000c, 0x59c40006, + 0x82000540, 0x000000f1, 0x48038806, 0x0401f7ef, + 0x0201f800, 0x001016c1, 0x04020004, 0x59a80049, + 0x800001c0, 0x040207a4, 0x497b8885, 0x1c01f000, + 0x4803c856, 0x42000000, 0x00000001, 0x0201f800, + 0x001015fa, 0x4a03503e, 0x00000000, 0x0201f800, + 0x001016c1, 0x0402000b, 0x59a80052, 0x800001c0, + 0x04000004, 0x80000040, 0x48035052, 0x04020005, + 0x4a035052, 0x0000000a, 0x4a035049, 0x00000001, + 0x497b8885, 0x0401f0f6, 0x59940022, 0x59940823, + 0x80040540, 0x1c01f000, 0x497b2823, 0x1c01f000, + 0x4c080000, 0x42001000, 0x000000f0, 0x0201f800, + 0x001019aa, 0x5c001000, 0x1c01f000, 0x4a03505c, + 0x00000004, 0x4a03505d, 0x00000000, 0x4a03505e, + 0x00000012, 0x4a03505f, 0x00000002, 0x4a035010, + 0x00ffffff, 0x0201f800, 0x001090d5, 0x4a03502a, + 0x20200000, 0x4a03502b, 0x88000200, 0x4a03502c, + 0x00ff001f, 0x4a03502d, 0x000007d0, 0x4a03502e, + 0x80000000, 0x4a03502f, 0x00000200, 0x4a035030, + 0x00ff0000, 0x4a035031, 0x00010000, 0x4a03503a, + 0x514c4f47, 0x4a03503b, 0x49432020, 0x1c01f000, + 0x4d440000, 0x417a8800, 0x41780800, 0x0201f800, + 0x00020267, 0x04020005, 0x0201f800, 0x00104836, + 0x04020002, 0x80040800, 0x81468800, 0x83440580, + 0x000007f0, 0x040207f6, 0x5c028800, 0x1c01f000, + 0x4803c857, 0x5c000000, 0x4c000000, 0x4803c857, + 0x0401f809, 0x485fc857, 0x4203e000, 0x50000000, + 0x5c000000, 0x4d780000, 0x4200b800, 0x00008002, + 0x0401f006, 0x485fc857, 0x4203e000, 0x50000000, + 0x4200b800, 0x00008002, 0x04006000, 0x4c000000, + 0x4c040000, 0x59bc00ea, 0x82000500, 0x00000007, + 0x82000580, 0x00000001, 0x04020005, 0x42000800, + 0x00000000, 0x0201f800, 0x001069a3, 0x5c000800, + 0x4807c025, 0x80040920, 0x4807c026, 0x5c000000, + 0x4803c023, 0x80000120, 0x4803c024, 0x5c000000, + 0x4803c857, 0x4803c021, 0x80000120, 0x4803c022, + 0x41f80000, 0x4803c027, 0x80000120, 0x4803c028, + 0x42000000, 0x00001000, 0x50000000, 0x82000480, + 0x24320001, 0x4803c857, 0x04001053, 0x42000800, + 0x00000064, 0x80040840, 0x04000007, 0x4a030000, + 0x00000001, 0x40000000, 0x59800000, 0x8c000500, + 0x040007f9, 0x04000046, 0x42000800, 0x0010bfa2, + 0x46000800, 0xfaceface, 0x80040800, 0x4c080000, + 0x4c0c0000, 0x42001000, 0x00007a00, 0x58080013, + 0x44000800, 0x80040800, 0x58080019, 0x44000800, + 0x80040800, 0x5808001a, 0x44000800, 0x80040800, + 0x5808001b, 0x44000800, 0x80040800, 0x5808001c, + 0x44000800, 0x80040800, 0x5808001f, 0x44000800, + 0x80040800, 0x42001000, 0x00007a40, 0x42001800, + 0x0000000b, 0x50080000, 0x44000800, 0x80081000, + 0x80040800, 0x800c1840, 0x040207fb, 0x42001800, + 0x00000003, 0x42001000, 0x00007b00, 0x480c1003, + 0x58080005, 0x44000800, 0x80040800, 0x800c1840, + 0x040217fb, 0x42001000, 0x00007c00, 0x58080002, + 0x44000800, 0x80040800, 0x58080003, 0x44000800, + 0x80040800, 0x58080020, 0x44000800, 0x80040800, + 0x58080021, 0x44000800, 0x80040800, 0x58080022, + 0x44000800, 0x80040800, 0x58080023, 0x44000800, + 0x80040800, 0x5c001800, 0x5c001000, 0x4a030000, + 0x00000000, 0x485fc020, 0x905cb9c0, 0x825cbd40, + 0x00000012, 0x485fc011, 0x4203e000, 0x40000000, + 0x4202d800, 0x00000005, 0x59e00017, 0x8c000508, + 0x04000003, 0x4a03c017, 0x00000002, 0x4203e000, + 0x30000001, 0x0401f81f, 0x0401f7ff, 0x4a03c850, + 0x0010bfbe, 0x4a03c851, 0x0010cfbd, 0x4a03c853, + 0x00000800, 0x4a03c855, 0x0001eb5a, 0x59e40001, + 0x82000540, 0x00003f00, 0x4803c801, 0x4a03b104, + 0x70000002, 0x4a03a804, 0x70000002, 0x4a03b004, + 0x70000002, 0x42000000, 0x0010b6eb, 0x49780001, + 0x49780002, 0x1c01f000, 0x5c036000, 0x4db00000, + 0x49b3c857, 0x4803c857, 0x1c01f000, 0x1c01f000, + 0x59a8006b, 0x8c000530, 0x040207fe, 0x4c080000, + 0x42001000, 0x00000004, 0x0401f862, 0x5c001000, + 0x4201d000, 0x00028b0a, 0x0201f800, 0x00105dd2, + 0x4c080000, 0x42001000, 0x00000008, 0x0401f859, + 0x5c001000, 0x4201d000, 0x00028b0a, 0x0201f800, + 0x00105dd2, 0x4c080000, 0x42001000, 0x00000010, + 0x0401f850, 0x5c001000, 0x4201d000, 0x00028b0a, + 0x0201f800, 0x00105dd2, 0x0401f7e2, 0x8c00050c, + 0x59a8086b, 0x04020003, 0x84040d30, 0x0401f006, + 0x84040d70, 0x4807506b, 0x42001000, 0x00000000, + 0x0401f040, 0x4807506b, 0x836c0500, 0x00000007, + 0x0c01f001, 0x00100727, 0x0010070d, 0x0010070d, + 0x001006f5, 0x0010071a, 0x0010070d, 0x0010070d, + 0x0010071a, 0x59a8006f, 0x8c000502, 0x04020013, + 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, + 0x00010000, 0x0400000a, 0x82040580, 0x00008000, + 0x04000004, 0x42001000, 0x42004000, 0x0401f006, + 0x42001000, 0x22002000, 0x0401f003, 0x42001000, + 0x12001000, 0x0401f025, 0x42001000, 0x00001004, + 0x0401f022, 0x59a8006f, 0x8c000502, 0x04020008, + 0x59a8006b, 0x8c000534, 0x04020004, 0x42001000, + 0x74057005, 0x0401f819, 0x1c01f000, 0x42001000, + 0x00002008, 0x0401f7fc, 0x59a8006b, 0x8c000534, + 0x0402000a, 0x59a8006f, 0x8c000502, 0x04000004, + 0x42001000, 0x24052005, 0x0401f00c, 0x42001000, + 0x74057005, 0x0401f009, 0x1c01f000, 0x1c01f000, + 0x82081500, 0x0000001c, 0x82081540, 0x001c0000, + 0x480bc013, 0x1c01f000, 0x59a8006b, 0x8c000530, + 0x04000002, 0x84081570, 0x480b506b, 0x8c000530, + 0x04020005, 0x82081500, 0x00007000, 0x80081114, + 0x0401fff0, 0x1c01f000, 0x41780000, 0x50041800, + 0x800c0400, 0x80040800, 0x80102040, 0x040207fc, + 0x80080500, 0x80000540, 0x1c01f000, 0x4202f000, + 0x00000000, 0x41780000, 0x41780800, 0x41781000, + 0x41781800, 0x41782000, 0x41782800, 0x41783000, + 0x41783800, 0x41784000, 0x41784800, 0x41785000, + 0x41785800, 0x41786000, 0x41786800, 0x41787000, + 0x41787800, 0x41788000, 0x41788800, 0x41789000, + 0x41789800, 0x4178a000, 0x4178a800, 0x4178b000, + 0x4178b800, 0x4178c000, 0x4178c800, 0x4178d000, + 0x4178d800, 0x4178e000, 0x4178e800, 0x4178f000, + 0x4178f800, 0x41790000, 0x41790800, 0x41791000, + 0x41791800, 0x41792000, 0x41792800, 0x41793000, + 0x41793800, 0x41794000, 0x41794800, 0x41795000, + 0x41795800, 0x41796000, 0x41796800, 0x41797000, + 0x41797800, 0x41798000, 0x41798800, 0x42019000, + 0x0010b333, 0x42019800, 0x0010b30a, 0x4179a000, + 0x4179a800, 0x4179b000, 0x4179b800, 0x4179c800, + 0x4179c000, 0x4179d000, 0x4179d800, 0x4179e000, + 0x4179e800, 0x4179f000, 0x4179f800, 0x417a0000, + 0x417a0800, 0x417a1000, 0x417a1800, 0x417a2000, + 0x42022800, 0x00006100, 0x417a3000, 0x417a3800, + 0x417a4000, 0x417a4800, 0x417a5000, 0x417a5800, + 0x417a6000, 0x417a6800, 0x417a7000, 0x417a7800, + 0x417a8000, 0x417a8800, 0x417a9000, 0x417a9800, + 0x417ae800, 0x417af800, 0x42030000, 0x00007c00, + 0x42031000, 0x0010b604, 0x42031800, 0x0000bf1d, + 0x42032000, 0x0000bf32, 0x42032800, 0x0010b5cc, + 0x42033000, 0x0010b274, 0x42034000, 0x0010b2a0, + 0x42033800, 0x0010b2bf, 0x42034800, 0x0010b342, + 0x42035000, 0x0010b200, 0x42035800, 0x0010aa00, + 0x42030800, 0x0010b301, 0x417b6000, 0x42036800, + 0x00006f00, 0x4203c800, 0x00003000, 0x42037000, + 0x0000ff00, 0x42037800, 0x0000bf00, 0x42038000, + 0x00007700, 0x42038800, 0x00004000, 0x42039000, + 0x00006000, 0x42039800, 0x0010bcda, 0x4203a000, + 0x00007600, 0x4203a800, 0x00007400, 0x4203b000, + 0x00007200, 0x4203b800, 0x00007100, 0x4203c000, + 0x00007000, 0x4203d000, 0x00000000, 0x4203e800, + 0x000200f9, 0x417bd800, 0x1c01f000, 0x42000800, + 0x00100000, 0x50040000, 0x4c000000, 0x42000000, + 0x0000aaaa, 0x44000800, 0x42001800, 0x00005555, + 0x41782000, 0x82102400, 0x00010000, 0x40100000, + 0x80042c00, 0x440c2800, 0x42003000, 0x0000000a, + 0x80183040, 0x040207ff, 0x50140000, 0x800c0580, + 0x04020004, 0x50040000, 0x800c0580, 0x040207f2, + 0x5c000000, 0x44000800, 0x80142840, 0x4817c861, + 0x1c01f000, 0x59a8081f, 0x800409c0, 0x04020009, + 0x49781c0c, 0x4a001a0c, 0x00000200, 0x4a001804, + 0x07000000, 0x59a80010, 0x9c0001c0, 0x48001805, + 0x0401fdf8, 0x9c0409c0, 0x48041806, 0x1c01f000, + 0x59a8080c, 0x4006d000, 0x4202b800, 0x00000001, + 0x59a8180d, 0x480fc857, 0x82041400, 0x00000014, + 0x82082400, 0x00000014, 0x40100000, 0x800c0480, + 0x04001006, 0x44080800, 0x40080800, 0x40101000, + 0x815eb800, 0x0401f7f7, 0x45780800, 0x495f5020, + 0x1c01f000, 0x835c0480, 0x00000020, 0x04001009, + 0x496bc857, 0x815eb840, 0x416a5800, 0x592ed000, + 0x497a5800, 0x497a5801, 0x812e59c0, 0x1c01f000, + 0x42000000, 0x0010b652, 0x0201f800, 0x0010a86e, + 0x417a5800, 0x0401f7f9, 0x815eb840, 0x04001008, + 0x416a5800, 0x492fc857, 0x592ed000, 0x497a5800, + 0x497a5801, 0x812e59c0, 0x1c01f000, 0x42000000, + 0x0010b652, 0x0201f800, 0x0010a86e, 0x417ab800, + 0x417a5800, 0x0401f7f8, 0x492fc857, 0x496a5800, + 0x412ed000, 0x815eb800, 0x59c80000, 0x82000540, + 0x00001200, 0x48039000, 0x1c01f000, 0x492fc857, + 0x812e59c0, 0x04000007, 0x592c0001, 0x497a5801, + 0x4c000000, 0x0401fff1, 0x5c025800, 0x0401f7f9, + 0x1c01f000, 0x4807c856, 0x42007000, 0x0010b5f6, + 0x4a007001, 0x00000000, 0x59e00003, 0x82000540, + 0x00008080, 0x4803c003, 0x4a03b805, 0x90000001, + 0x59dc0006, 0x4a03b805, 0x70000000, 0x59dc0006, + 0x4a03b805, 0x30000000, 0x59dc0006, 0x4a03b805, + 0x80000000, 0x4200b000, 0x00000020, 0x497bb807, + 0x8058b040, 0x040207fe, 0x4a03b805, 0x30000000, + 0x59dc0006, 0x4a03b805, 0x60000001, 0x59dc0006, + 0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805, + 0x30000002, 0x4200b000, 0x00000020, 0x497bb807, + 0x8058b040, 0x040207fe, 0x4a03b805, 0x30000000, + 0x59dc0006, 0x4a03b805, 0x60000001, 0x0401ff9e, + 0x04000d99, 0x42001000, 0x0010b5f4, 0x452c1000, + 0x4a025801, 0x00000001, 0x4a025802, 0x00000100, + 0x4a025809, 0x00106eac, 0x497a580a, 0x497a580b, + 0x497a580c, 0x0401ff90, 0x04000d8b, 0x42001000, + 0x0010b5f5, 0x452c1000, 0x4a025801, 0x00000000, + 0x4a025802, 0x00000100, 0x4a025809, 0x0010120c, + 0x497a5803, 0x497a5807, 0x497a5808, 0x497a580a, + 0x59a8006f, 0x8c000500, 0x04000006, 0x4a03b805, + 0xe0000001, 0x59dc0006, 0x8c000522, 0x040007fc, + 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, + 0x4c380000, 0x40087000, 0x4a007002, 0x00000000, + 0x42007000, 0x0010b5f6, 0x82080400, 0x00000000, + 0x45780000, 0x58380005, 0x48087005, 0x80000540, + 0x04000006, 0x480bc857, 0x82000400, 0x00000000, + 0x44080000, 0x0401f003, 0x480bc857, 0x48087006, + 0x58380001, 0x80000540, 0x0400080c, 0x5c007000, + 0x5c03e000, 0x1c01f000, 0x4c380000, 0x42007000, + 0x0010b5f6, 0x58380001, 0x80000540, 0x04000803, + 0x5c007000, 0x1c01f000, 0x42007000, 0x0010b5f6, + 0x58380001, 0x82000580, 0x00000000, 0x04020012, + 0x58380000, 0x0c01f001, 0x001008d7, 0x001008d6, + 0x001008d6, 0x001008d6, 0x001008d6, 0x001008d6, + 0x001008d6, 0x001008d6, 0x0401fd3f, 0x58380808, + 0x800409c0, 0x04020027, 0x58380006, 0x80000540, + 0x04020002, 0x1c01f000, 0x4803c857, 0x48007002, + 0x40006800, 0x58340000, 0x80000540, 0x04020002, + 0x48007005, 0x48007006, 0x4a03b805, 0x20000000, + 0x59dc0006, 0x4a03b805, 0x30000000, 0x58340007, + 0x4803b800, 0x4803c857, 0x58340008, 0x4803b801, + 0x4803c857, 0x58340004, 0x48007003, 0x58340003, + 0x48007004, 0x4803b803, 0x4803c857, 0x58340001, + 0x8c000500, 0x04000004, 0x4a007001, 0x00000001, + 0x0401f028, 0x4a007001, 0x00000002, 0x0401f03e, + 0x0201f800, 0x001091b3, 0x0201f800, 0x0010a4b8, + 0x04000017, 0x4a03b805, 0x20000000, 0x59dc0006, + 0x4a03b805, 0x30000000, 0x4807b800, 0x480bb801, + 0x4a007003, 0x00000010, 0x480c7009, 0x42001000, + 0x001008be, 0x0201f800, 0x00105cd3, 0x58380008, + 0x82000400, 0x00000004, 0x48007004, 0x4803b803, + 0x4a007001, 0x00000007, 0x0401f023, 0x0201f800, + 0x001091cb, 0x42000800, 0x00000001, 0x42001000, + 0x001008be, 0x0201f800, 0x00105caf, 0x0401f7b7, + 0x4c040000, 0x4c080000, 0x58380803, 0x42001000, + 0x00003fff, 0x82040480, 0x00003fff, 0x04021003, + 0x40041000, 0x80000580, 0x48007003, 0x4803c857, + 0x800800c4, 0x4803b802, 0x4a03b805, 0x30000002, + 0x59dc0006, 0x4a03b805, 0x70000001, 0x59dc0006, + 0x4a03b805, 0x10000000, 0x5c001000, 0x5c000800, + 0x1c01f000, 0x483bc857, 0x4c040000, 0x4c080000, + 0x58380803, 0x42001000, 0x00003fff, 0x82040480, + 0x00003fff, 0x04021003, 0x40041000, 0x80000580, + 0x48007003, 0x800800c4, 0x4803b802, 0x4803c857, + 0x4a03b805, 0x10000002, 0x5c001000, 0x5c000800, + 0x1c01f000, 0x4c040000, 0x4c380000, 0x42007000, + 0x0010b5f6, 0x59dc0806, 0x4807c857, 0x4a03b805, + 0x20000000, 0x8c040d3e, 0x04000007, 0x8c040d08, + 0x04020cb9, 0x58380001, 0x82000500, 0x00000007, + 0x0c01f804, 0x5c007000, 0x5c000800, 0x1c01f000, + 0x001008c6, 0x0010096c, 0x0010097c, 0x00100615, + 0x00100615, 0x00100615, 0x00100615, 0x0010123a, + 0x4807c856, 0x82040d00, 0x43000f80, 0x04020009, + 0x58380003, 0x80000540, 0x0400001c, 0x59dc0000, + 0x4803b800, 0x59dc0001, 0x4803b801, 0x0401f7ad, + 0x58380802, 0x4a000802, 0x00000200, 0x0401f01d, + 0x4807c856, 0x82040d00, 0x43000f80, 0x04020009, + 0x58380003, 0x80000540, 0x0400000c, 0x59dc0000, + 0x4803b800, 0x59dc0001, 0x4803b801, 0x0401f7b6, + 0x58380002, 0x82000400, 0x00000002, 0x46000000, + 0x00000200, 0x0401f00b, 0x4c340000, 0x58386802, + 0x59dc0000, 0x4803c857, 0x48006807, 0x59dc0001, + 0x48006808, 0x4a006802, 0x00000100, 0x5c006800, + 0x4a007001, 0x00000000, 0x4c300000, 0x58386002, + 0x4833c857, 0x0401f80c, 0x04000009, 0x58300009, + 0x82000c80, 0x0010a971, 0x04021c73, 0x82000c80, + 0x00020000, 0x04001c70, 0x0801f800, 0x5c006000, + 0x0401f71e, 0x803061c0, 0x04000009, 0x59a8000c, + 0x80300480, 0x04001007, 0x59a8000d, 0x80300480, + 0x04021004, 0x82000540, 0x00000001, 0x1c01f000, + 0x80000580, 0x1c01f000, 0x4803c856, 0x4dc00000, + 0x42007000, 0x0010b601, 0x4a007400, 0x00000000, + 0x49787001, 0x42038000, 0x00007720, 0x4a038006, + 0x60000001, 0x4a038009, 0xf4f60000, 0x42038000, + 0x00007700, 0x4a038006, 0x60000001, 0x4a038009, + 0xf4f60000, 0x4a03c822, 0x00000010, 0x4a0370e8, + 0x00000000, 0x0401f809, 0x4a0370e9, 0x00003a0f, + 0x4a0370e8, 0x00000000, 0x4a0370e8, 0x00000001, + 0x5c038000, 0x1c01f000, 0x4c5c0000, 0x4178b800, + 0x0401f80a, 0x5c00b800, 0x1c01f000, 0x4803c856, + 0x4c5c0000, 0x825cbd40, 0x00000001, 0x0401f803, + 0x5c00b800, 0x1c01f000, 0x4803c856, 0x4dc00000, + 0x4c500000, 0x4c580000, 0x4c540000, 0x4a0370e8, + 0x00000000, 0x805cb9c0, 0x04000009, 0x4a038807, + 0x00000004, 0x59b800ea, 0x8c000510, 0x04000004, + 0x59b800e0, 0x0401f87b, 0x0401f7fb, 0x42038000, + 0x00007720, 0x0201f800, 0x00100f0f, 0x59c00007, + 0x4a038006, 0x20000000, 0x59c00007, 0x4a038006, + 0x8000000a, 0x59c00007, 0x4a038006, 0x8000000b, + 0x59c00007, 0x4a038006, 0x40000001, 0x83c00580, + 0x00007700, 0x04000004, 0x42038000, 0x00007700, + 0x0401f7ed, 0x42038000, 0x00007720, 0x42000800, + 0x00000800, 0x59c00007, 0x8c00051e, 0x04000006, + 0x4a038006, 0x90000001, 0x80040840, 0x040207fa, + 0x0401fc01, 0x83c00580, 0x00007700, 0x04000004, + 0x42038000, 0x00007700, 0x0401f7f1, 0x805cb9c0, + 0x0402001d, 0x4200b000, 0x00000020, 0x83b8ac00, + 0x00000020, 0x0201f800, 0x0010a947, 0x4a0370fb, + 0x00000001, 0x4a037020, 0x0010110d, 0x59a80039, + 0x82000500, 0x0000ffff, 0x48037021, 0x4a037035, + 0x0010bbda, 0x4a037030, 0x0010b210, 0x4a037031, + 0x0010aa00, 0x4a037032, 0x0010b315, 0x4a037036, + 0x0010b320, 0x59840002, 0x48037034, 0x4a037038, + 0x00101104, 0x4a0370fb, 0x00000001, 0x4178a000, + 0x4200b000, 0x00000020, 0x83b8ac00, 0x00000000, + 0x0201f800, 0x0010a947, 0x4200b000, 0x00000040, + 0x83b8ac00, 0x00000040, 0x0201f800, 0x0010a947, + 0x805cb9c0, 0x04020004, 0x4a0370e4, 0xaaaaaaaa, + 0x0401f003, 0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, + 0xaaaaaaaa, 0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, + 0x00000000, 0x4a0370e6, 0xaaaaaaaa, 0x42038000, + 0x00007720, 0x4a038006, 0x90000000, 0x59c00007, + 0x8c00051e, 0x02020800, 0x00100615, 0x42038000, + 0x00007700, 0x4a038006, 0x90000000, 0x59c00007, + 0x8c00051e, 0x02020800, 0x00100615, 0x5c00a800, + 0x5c00b000, 0x5c00a000, 0x5c038000, 0x1c01f000, + 0x4d300000, 0x4d380000, 0x40026000, 0x82000500, + 0x7f000000, 0x82000580, 0x00000003, 0x0402000f, + 0x83326500, 0x00ffffff, 0x59300203, 0x82000580, + 0x00000004, 0x04020009, 0x59300c06, 0x82040580, + 0x00000009, 0x04020005, 0x42027000, 0x00000047, + 0x0201f800, 0x000208d8, 0x5c027000, 0x5c026000, + 0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000, + 0x4d400000, 0x4cfc0000, 0x4d380000, 0x4d3c0000, + 0x4d440000, 0x4d4c0000, 0x4d480000, 0x4c5c0000, + 0x4c600000, 0x4c640000, 0x4d040000, 0x4cc80000, + 0x4ccc0000, 0x4cf40000, 0x4cf80000, 0x4cfc0000, + 0x0201f800, 0x00020016, 0x5c01f800, 0x5c01f000, + 0x5c01e800, 0x5c019800, 0x5c019000, 0x5c020800, + 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x5c029000, + 0x5c029800, 0x5c028800, 0x5c027800, 0x5c027000, + 0x5c01f800, 0x5c028000, 0x5c026800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x493bc857, 0x0201f000, + 0x00020045, 0x83300500, 0x1f000000, 0x04000008, + 0x81326580, 0x80000130, 0x82000c80, 0x00000014, + 0x02021800, 0x00100615, 0x0c01f013, 0x83300500, + 0x000000ff, 0x82000c80, 0x00000007, 0x02021800, + 0x00100615, 0x0c01f025, 0x1c01f000, 0x82000d00, + 0xc0000038, 0x02020800, 0x0010060d, 0x0201f800, + 0x00100615, 0x00000000, 0x00000048, 0x00000054, + 0x00000053, 0x00100ae4, 0x00100b08, 0x00100b03, + 0x00100b28, 0x00100aef, 0x00100afb, 0x00100ae4, + 0x00100b23, 0x00100b64, 0x00100ae4, 0x00100ae4, + 0x00100ae4, 0x00100ae4, 0x00100b67, 0x00100b6d, + 0x00100b7e, 0x00100b8f, 0x00100ae4, 0x00100b98, + 0x00100ba4, 0x00100ae4, 0x00100ae4, 0x00100ae4, + 0x0201f800, 0x00100615, 0x00100aed, 0x00100c3f, + 0x00100b35, 0x00100b59, 0x00100aed, 0x00100aed, + 0x00100aed, 0x0201f800, 0x00100615, 0x4803c856, + 0x59300004, 0x8c00053e, 0x04020005, 0x42027000, + 0x00000055, 0x0201f000, 0x000208d8, 0x0201f800, + 0x00106cb4, 0x040007fa, 0x1c01f000, 0x4803c856, + 0x0401f8aa, 0x40002800, 0x41782000, 0x42027000, + 0x00000056, 0x0201f000, 0x000208d8, 0x4803c856, + 0x42027000, 0x00000057, 0x0201f000, 0x000208d8, + 0x4803c856, 0x59300007, 0x8c00051a, 0x04020010, + 0x59325808, 0x812e59c0, 0x04000014, 0x592c0408, + 0x8c00051c, 0x04020003, 0x4a026011, 0xffffffff, + 0x59300004, 0x8c00053e, 0x04020009, 0x42027000, + 0x00000048, 0x0201f000, 0x000208d8, 0x59325808, + 0x4a025a06, 0x00000007, 0x0401f7f4, 0x0201f800, + 0x00106cb4, 0x040007f6, 0x1c01f000, 0x4803c856, + 0x83300500, 0x00ffffff, 0x0201f000, 0x0010620f, + 0x1c01f000, 0x4c040000, 0x59b808ea, 0x82040d00, + 0x00000007, 0x82040580, 0x00000003, 0x04000004, + 0x42000000, 0x60000000, 0x0401f8ac, 0x5c000800, + 0x1c01f000, 0x0401f8fa, 0x0400001b, 0x59325808, + 0x812e59c0, 0x04000018, 0x592c0204, 0x82000500, + 0x000000ff, 0x82000d80, 0x00000029, 0x04020012, + 0x59300203, 0x82000580, 0x00000003, 0x0400000b, + 0x59300807, 0x84040d26, 0x48066007, 0x0201f800, + 0x00020087, 0x4a03900d, 0x00000040, 0x4a0370e5, + 0x00000008, 0x1c01f000, 0x0201f800, 0x00106cb4, + 0x040007f4, 0x59880053, 0x80000000, 0x48031053, + 0x4a03900d, 0x00000040, 0x42000000, 0xc0000000, + 0x0401f05a, 0x42007800, 0x0010bbe1, 0x42002000, + 0x00003000, 0x42003000, 0x00000105, 0x0201f800, + 0x00105b3d, 0x4a0370e4, 0x02000000, 0x1c01f000, + 0x4933c857, 0x0201f000, 0x000208b4, 0x41300800, + 0x800409c0, 0x02020800, 0x00100615, 0x0201f800, + 0x0010060d, 0x4933c857, 0x813261c0, 0x02000800, + 0x00100615, 0x0401f835, 0x40002800, 0x0201f800, + 0x0010a7c3, 0x0401f8ae, 0x04000007, 0x59326809, + 0x59340200, 0x8c00050e, 0x59300414, 0x02020800, + 0x00109094, 0x1c01f000, 0x4933c857, 0x813261c0, + 0x02000800, 0x00100615, 0x0401f8a1, 0x0400000b, + 0x59325808, 0x0201f800, 0x00108df4, 0x04000007, + 0x592c0208, 0x8400054e, 0x48025a08, 0x417a7800, + 0x0201f800, 0x00108997, 0x1c01f000, 0x485fc857, + 0x5c000000, 0x4d780000, 0x4203e000, 0x50000000, + 0x4200b800, 0x00008005, 0x0201f000, 0x0010061a, + 0x4933c857, 0x83300480, 0x00000020, 0x02021800, + 0x00100615, 0x83300c00, 0x0010b6cb, 0x50040000, + 0x80000000, 0x04001002, 0x44000800, 0x1c01f000, + 0x4933c857, 0x0401f7f4, 0x4807c856, 0x59b800ea, + 0x8c000510, 0x040007fd, 0x59b800e0, 0x4803c857, + 0x1c01f000, 0x4803c856, 0x42000000, 0x10000000, + 0x41300800, 0x0401f02d, 0x82000500, 0xf0000000, + 0x82040d00, 0x0fffffff, 0x80040d40, 0x4807c857, + 0x59b800ea, 0x8c000516, 0x04020003, 0x480770e1, + 0x1c01f000, 0x8c000510, 0x040007fa, 0x4c040000, + 0x0401f809, 0x5c000800, 0x82100480, 0x00000008, + 0x040017f4, 0x4c040000, 0x0401febf, 0x5c000800, + 0x0401f7f0, 0x59b800e2, 0x59b820e2, 0x80100580, + 0x040207fd, 0x80102114, 0x0401f006, 0x59b800e2, + 0x59b820e2, 0x80100580, 0x040207fd, 0x0401f001, + 0x40101800, 0x800c190a, 0x82100500, 0x0000001f, + 0x820c1d00, 0x0000001f, 0x800c2480, 0x82102500, + 0x0000001f, 0x1c01f000, 0x82000500, 0xf0000000, + 0x82040d00, 0x0fffffff, 0x80040d40, 0x4807c857, + 0x42001000, 0x0010b602, 0x50080000, 0x80000540, + 0x04020005, 0x4a0370e5, 0x00000003, 0x4a0370e4, + 0x00000300, 0x80000000, 0x44001000, 0x42001000, + 0x00000400, 0x59b800ea, 0x8c000510, 0x0400000c, + 0x0401ffd5, 0x82100480, 0x00000008, 0x04001007, + 0x4c040000, 0x4c080000, 0x0401fe8b, 0x5c001000, + 0x5c000800, 0x0401f020, 0x59b800ea, 0x8c000516, + 0x0402001d, 0x4a0370e4, 0x00300000, 0x480770e1, + 0x42001000, 0x0000ff00, 0x80081040, 0x04000012, + 0x59b808e4, 0x8c040d28, 0x040207fc, 0x42001000, + 0x0010b602, 0x50080000, 0x80000040, 0x04020005, + 0x4a0370e5, 0x00000002, 0x4a0370e4, 0x00000200, + 0x02001800, 0x00100615, 0x44001000, 0x8c040d2c, + 0x1c01f000, 0x41f80000, 0x50000000, 0x0201f800, + 0x00100615, 0x80081040, 0x040207d3, 0x41f80000, + 0x50000000, 0x0201f800, 0x00100615, 0x4d380000, + 0x59300c06, 0x82040580, 0x00000009, 0x04020006, + 0x42027000, 0x00000047, 0x0201f800, 0x000208d8, + 0x80000580, 0x5c027000, 0x1c01f000, 0x4c500000, + 0x4a03900d, 0x00000001, 0x59c8a020, 0x4a03900d, + 0x00000002, 0x59c80820, 0x8c50a52e, 0x04000002, + 0x900409c0, 0x82040d00, 0x0000ffff, 0x0201f800, + 0x00105b0f, 0x5c00a000, 0x1c01f000, 0x0401fff0, + 0x04000045, 0x4933c857, 0x59300406, 0x82000580, + 0x00000000, 0x04000040, 0x59c82021, 0x4a03900d, + 0x00000001, 0x59c82821, 0x82142d00, 0x0000ffff, + 0x59325808, 0x812e59c0, 0x04000037, 0x59326809, + 0x0201f800, 0x00104728, 0x02020800, 0x0010907c, + 0x599c0019, 0x8c00050c, 0x04020018, 0x0201f800, + 0x00104728, 0x04020015, 0x59300811, 0x4807c857, + 0x592c0408, 0x8c00051c, 0x0402000e, 0x8400055c, + 0x48025c08, 0x592c0a04, 0x82040d00, 0x000000ff, + 0x82040580, 0x00000048, 0x04000004, 0x82040580, + 0x00000018, 0x04020003, 0x59300811, 0x48065803, + 0x4a026011, 0x7fffffff, 0x48166013, 0x0201f800, + 0x0010112d, 0x04020014, 0x0401fa07, 0x40280000, + 0x4802600d, 0x04000005, 0x4832600b, 0x50200000, + 0x4802600a, 0x4822600c, 0x59300414, 0x8c00051c, + 0x04020004, 0x599c0019, 0x8c00050c, 0x0402086e, + 0x4a03900d, 0x00000040, 0x4a0370e5, 0x00000008, + 0x1c01f000, 0x59880053, 0x80000000, 0x48031053, + 0x4a03900d, 0x00000040, 0x42000000, 0xc0000000, + 0x0401f726, 0x4cf80000, 0x58f40000, 0x8001f540, + 0x0401f820, 0x41781800, 0x0401f8e7, 0x04020014, + 0x44140800, 0x0401f82a, 0x04000011, 0x40043800, + 0x42001800, 0x00000001, 0x40142000, 0x0401f8de, + 0x0402000b, 0x801c3800, 0x501c0000, 0x44000800, + 0x0401f810, 0x801c0580, 0x04000004, 0x44103800, + 0x801c3840, 0x44143800, 0x0401f819, 0x5c01f000, + 0x1c01f000, 0x80f9f1c0, 0x04020003, 0x58f41202, + 0x0401f003, 0x42001000, 0x00000007, 0x1c01f000, + 0x80f9f1c0, 0x04020006, 0x58f40401, 0x82000480, + 0x00000002, 0x80f40400, 0x0401f005, 0x58f80401, + 0x82000480, 0x00000002, 0x80f80400, 0x50002800, + 0x80000000, 0x50002000, 0x1c01f000, 0x80f9f1c0, + 0x04020008, 0x58f40401, 0x82000480, 0x00000002, + 0x02001800, 0x00100615, 0x4801ec01, 0x0401f00b, + 0x58f80401, 0x82000480, 0x00000002, 0x02001800, + 0x00100615, 0x4801f401, 0x82000580, 0x00000002, + 0x04020002, 0x0401f809, 0x58f40202, 0x80000040, + 0x4801ea02, 0x02000800, 0x00100615, 0x82000580, + 0x00000001, 0x1c01f000, 0x4d2c0000, 0x40fa5800, + 0x0201f800, 0x0010083a, 0x4979e800, 0x4179f000, + 0x5c025800, 0x1c01f000, 0x80f5e9c0, 0x04000009, + 0x80f9f1c0, 0x04020ff5, 0x4d2c0000, 0x40f65800, + 0x0201f800, 0x0010083a, 0x4179e800, 0x5c025800, + 0x1c01f000, 0x4cf40000, 0x0201f800, 0x00104728, + 0x04020036, 0x59300807, 0x82040500, 0x00003100, + 0x04020032, 0x8c040d22, 0x04000032, 0x5930001f, + 0x8001ed40, 0x02000800, 0x00100615, 0x82000580, + 0xffffffff, 0x04000029, 0x58f40201, 0x82000580, + 0x0000dcb3, 0x02020800, 0x00100615, 0x58f40a02, + 0x82040500, 0x0000fffe, 0x04000003, 0x0401ff86, + 0x58f40a02, 0x82040480, 0x0000000f, 0x04021059, + 0x80040800, 0x4805ea02, 0x82040580, 0x00000008, + 0x0400005d, 0x82040480, 0x00000008, 0x0400100a, + 0x58f40000, 0x8001ed40, 0x02000800, 0x00100615, + 0x58f40201, 0x82000580, 0x0000ddb9, 0x02020800, + 0x00100615, 0x58f40401, 0x82000c00, 0x00000002, + 0x4805ec01, 0x80f40400, 0x59300812, 0x44040000, + 0x80000000, 0x45780000, 0x5c01e800, 0x1c01f000, + 0x42001000, 0x00000400, 0x59b800e4, 0x8c000524, + 0x04020023, 0x4a0370e4, 0x00030000, 0x40000000, + 0x59b800e4, 0x8c000524, 0x0402001b, 0x59300807, + 0x84040d62, 0x48066007, 0x4a0370e4, 0x00020000, + 0x4d2c0000, 0x0201f800, 0x00100819, 0x04000025, + 0x492e601f, 0x4a025a01, 0x0000dcb3, 0x59300008, + 0x80001d40, 0x02000800, 0x00100615, 0x580c080f, + 0x48065803, 0x59301811, 0x40040000, 0x800c0580, + 0x0402000d, 0x497a5a02, 0x4a025c01, 0x00000004, + 0x0401f011, 0x4a0370e4, 0x00020000, 0x40000000, + 0x40000000, 0x80081040, 0x02000800, 0x00100615, + 0x0401f7d6, 0x4a025a02, 0x00000001, 0x4a025c01, + 0x00000006, 0x497a5804, 0x400c0000, 0x80040480, + 0x48025805, 0x412de800, 0x5c025800, 0x0401f7a9, + 0x5c025800, 0x4a02601f, 0xffffffff, 0x0401f7c3, + 0x4d2c0000, 0x58f65800, 0x0201f800, 0x0010083a, + 0x40f65800, 0x0201f800, 0x0010083a, 0x5c025800, + 0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x00100819, + 0x040007f8, 0x4a025a01, 0x0000ddb9, 0x4a025c01, + 0x00000002, 0x492de800, 0x412de800, 0x5c025800, + 0x0401f7a5, 0x0401ff30, 0x82f40400, 0x00000004, + 0x800c0400, 0x40000800, 0x50040000, 0x80100580, + 0x04000016, 0x82040c00, 0x00000002, 0x80081040, + 0x040207fa, 0x80f9f1c0, 0x04000011, 0x58f41202, + 0x82081480, 0x00000007, 0x82f80400, 0x00000002, + 0x800c0400, 0x40000800, 0x50040000, 0x80100580, + 0x04000006, 0x82040c00, 0x00000002, 0x80081040, + 0x040207fa, 0x0401f002, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fd, 0x4cf40000, 0x4cf80000, + 0x4001e800, 0x592c0a06, 0x800409c0, 0x04020021, + 0x82f40580, 0xffffffff, 0x0400001b, 0x58f40201, + 0x82000580, 0x0000dcb3, 0x02020800, 0x00100615, + 0x58f40000, 0x8001f540, 0x04000006, 0x58f80201, + 0x82000580, 0x0000ddb9, 0x02020800, 0x00100615, + 0x41783800, 0x58f44003, 0x0401f83d, 0x04020009, + 0x0401ff2e, 0x497a601f, 0x59300807, 0x84040d22, + 0x48066007, 0x5c01f000, 0x5c01e800, 0x1c01f000, + 0x0401ff26, 0x4a025a06, 0x00000011, 0x0401f7f6, + 0x82f40580, 0xffffffff, 0x04020f20, 0x0401f7f2, + 0x4cf40000, 0x4cf80000, 0x4001e800, 0x82040580, + 0x00000001, 0x04020020, 0x82f40580, 0xffffffff, + 0x0400001a, 0x58f40201, 0x82000580, 0x0000dcb3, + 0x02020800, 0x00100615, 0x58f40000, 0x8001f540, + 0x04000006, 0x58f80201, 0x82000580, 0x0000ddb9, + 0x02020800, 0x00100615, 0x41783800, 0x58f44003, + 0x0401f813, 0x04020008, 0x0401ff04, 0x42000800, + 0x00000001, 0x497a601f, 0x5c01f000, 0x5c01e800, + 0x1c01f000, 0x0401fefd, 0x42000800, 0x00000011, + 0x0401f7f9, 0x4c040000, 0x82f40580, 0xffffffff, + 0x04020ef6, 0x5c000800, 0x0401f7f3, 0x4803c856, + 0x401c2000, 0x41781800, 0x4c200000, 0x0401ff86, + 0x5c004000, 0x0402002c, 0x40202000, 0x42001800, + 0x00000001, 0x0401ff80, 0x04020027, 0x0401feae, + 0x40082800, 0x82f40400, 0x00000004, 0x40003000, + 0x50182000, 0x40100000, 0x801c0580, 0x04000005, + 0x42001800, 0x00000001, 0x0401ff73, 0x0402001a, + 0x82183400, 0x00000002, 0x80142840, 0x040207f5, + 0x80f9f1c0, 0x04000013, 0x58f42a02, 0x82142c80, + 0x00000007, 0x82f80400, 0x00000003, 0x40003000, + 0x50182000, 0x40100000, 0x801c0580, 0x04000005, + 0x42001800, 0x00000001, 0x0401ff5f, 0x04020006, + 0x82183400, 0x00000002, 0x80142840, 0x040207f5, + 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd, + 0x0201f800, 0x00100615, 0x58380207, 0x8c000502, + 0x040007fc, 0x50200000, 0x80387c00, 0x583c2800, + 0x583c2001, 0x58380404, 0x80001540, 0x04020002, + 0x58381407, 0x58c83401, 0x58380c08, 0x59303807, + 0x497a6012, 0x497a6013, 0x0201f000, 0x000200bf, + 0x592c0408, 0x8c000502, 0x040007ea, 0x592c0409, + 0x80000540, 0x040007e7, 0x82000c80, 0x00000002, + 0x04001011, 0x58380001, 0x80007540, 0x02000800, + 0x00100615, 0x58380204, 0x82000500, 0x0000000f, + 0x82000400, 0x0010110d, 0x50004000, 0x40040000, + 0x800409c0, 0x04000005, 0x82040c80, 0x00000005, + 0x040217f1, 0x80204400, 0x50200000, 0x80387c00, + 0x583c2800, 0x583c2001, 0x583c1002, 0x592c0a07, + 0x592c4c08, 0x592c300d, 0x59303807, 0x497a6012, + 0x497a6013, 0x4816600e, 0x4812600f, 0x480a6010, + 0x481a6011, 0x80040840, 0x4806600d, 0x02000000, + 0x000200c7, 0x80204000, 0x50201800, 0x800c19c0, + 0x0402000c, 0x58380001, 0x80007540, 0x02000800, + 0x00100615, 0x58380204, 0x82000500, 0x0000000f, + 0x82000400, 0x0010110d, 0x50004000, 0x50201800, + 0x483a600b, 0x480e600a, 0x4822600c, 0x0201f000, + 0x000200c7, 0x4803c856, 0x592c0208, 0x8c00051e, + 0x04020017, 0x50200000, 0x80306c00, 0x40240000, + 0x0c01f001, 0x00100e91, 0x00100e91, 0x00100e9a, + 0x00100e91, 0x00100e91, 0x00100e91, 0x00100e91, + 0x00100e91, 0x00100e9a, 0x00100e91, 0x00100e9a, + 0x00100e91, 0x00100e91, 0x00100e9a, 0x00100e91, + 0x00100e91, 0x0201f800, 0x00100615, 0x8400051e, + 0x48025a08, 0x50200000, 0x80306c00, 0x58343801, + 0x481e600f, 0x0401f007, 0x58341802, 0x58342800, + 0x58343801, 0x480e6010, 0x4816600e, 0x481e600f, + 0x0401f24b, 0x4933c857, 0x5931f808, 0x59300a06, + 0x800409c0, 0x04000005, 0x80040906, 0x04020002, + 0x80040800, 0x4805fc06, 0x4a026206, 0x00000002, + 0x592c0409, 0x82000500, 0x00000008, 0x0400000b, + 0x0401f834, 0x59300203, 0x82000580, 0x00000004, + 0x04020005, 0x42027000, 0x00000048, 0x0201f800, + 0x000208d8, 0x1c01f000, 0x4cfc0000, 0x58fc0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000048, + 0x0402000c, 0x58fc000b, 0x800001c0, 0x04000009, + 0x58fc0407, 0x800001c0, 0x04000006, 0x58fc080b, + 0x8c040d16, 0x04000017, 0x58fc0007, 0x0401f00a, + 0x58fc0408, 0x8c000512, 0x04020014, 0x58fc0c09, + 0x8c040d16, 0x04020003, 0x5c01f800, 0x1c01f000, + 0x58fc000a, 0x59300811, 0x80040580, 0x04020009, + 0x59300007, 0x84000500, 0x48026007, 0x42027000, + 0x00000048, 0x5c01f800, 0x0201f000, 0x000208d8, + 0x5c01f800, 0x1c01f000, 0x58fdf809, 0x0401f7ec, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857, + 0x59b808ea, 0x82040d00, 0x00000007, 0x82040580, + 0x00000000, 0x0400001e, 0x82040580, 0x00000003, + 0x0400001b, 0x59300406, 0x4c000000, 0x4a026406, + 0x00000000, 0x42003000, 0x00000041, 0x42000000, + 0x50000000, 0x41300800, 0x4c180000, 0x0401fce3, + 0x5c003000, 0x0400000b, 0x42000000, 0x0000001e, + 0x80000040, 0x040207ff, 0x80183040, 0x040207f4, + 0x42000000, 0x40000000, 0x41300800, 0x0401fcd7, + 0x5c000000, 0x48026406, 0x1c01f000, 0x59300007, + 0x84000500, 0x48026007, 0x0401f7fc, 0x59c00007, + 0x4a038006, 0x30000000, 0x40000000, 0x59c00007, + 0x8c00050a, 0x040207fe, 0x1c01f000, 0x5c000000, + 0x4c000000, 0x4803c857, 0x4dc00000, 0x4a0370e8, + 0x00000000, 0x42038000, 0x00007720, 0x0401fff0, + 0x42038000, 0x00007700, 0x0401ffed, 0x0201f800, + 0x00104e0d, 0x04020013, 0x4a038891, 0x0000ffff, + 0x497b8880, 0x497b8892, 0x42001000, 0x00000190, + 0x40000000, 0x40000000, 0x80081040, 0x040207fd, + 0x42000000, 0x0010b6a5, 0x0201f800, 0x0010a86e, + 0x0401f80e, 0x5c038000, 0x0201f000, 0x00104f29, + 0x0401f82d, 0x42000000, 0x0010b6a6, 0x0201f800, + 0x0010a86e, 0x0401f805, 0x48178892, 0x480b8880, + 0x5c038000, 0x1c01f000, 0x496fc857, 0x836c0580, + 0x00000003, 0x0402000b, 0x4c080000, 0x4c0c0000, + 0x42001000, 0x00008048, 0x42001800, 0x0000ffff, + 0x0201f800, 0x00103857, 0x5c001800, 0x5c001000, + 0x42000800, 0x0000003c, 0x0201f800, 0x00101395, + 0x59a8006c, 0x80000540, 0x04000006, 0x59a8106d, + 0x800811c0, 0x04000003, 0x0201f800, 0x00101b0a, + 0x4a038891, 0x0000ffff, 0x4a03900d, 0x00000040, + 0x0201f800, 0x001009db, 0x4a0370e8, 0x00000001, + 0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857, + 0x59c41080, 0x497b8880, 0x59c42892, 0x497b8892, + 0x0201f800, 0x00104e0d, 0x04020002, 0x1c01f000, + 0x42002000, 0x00000260, 0x59c418a4, 0x820c1d00, + 0x0000000f, 0x820c0580, 0x00000000, 0x04000010, + 0x59c41805, 0x820c1d00, 0x00000001, 0x0402000e, + 0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0480, + 0x00000007, 0x04001004, 0x820c0480, 0x0000000c, + 0x04001003, 0x80102040, 0x040207ec, 0x497b8891, + 0x1c01f000, 0x4c100000, 0x42002000, 0x00000019, + 0x46000000, 0x00000001, 0x0201f800, 0x001019a4, + 0x50001800, 0x820c1d00, 0x00000001, 0x04000005, + 0x80102040, 0x040207f7, 0x5c002000, 0x0401f7f0, + 0x5c002000, 0x0401f7ec, 0x4803c856, 0x1c01f000, + 0x4d2c0000, 0x59325808, 0x592c0a04, 0x4807c857, + 0x82040d00, 0x000000ff, 0x82040500, 0x0000000f, + 0x0c01f001, 0x00100fb5, 0x00100fb5, 0x00100fb5, + 0x00100fcd, 0x00100fb5, 0x00100fb5, 0x00100fb5, + 0x00100fb5, 0x00100fb5, 0x00100fcd, 0x00100fb5, + 0x00100fb7, 0x00100fb5, 0x00100fb5, 0x00100fb5, + 0x00100fb5, 0x0201f800, 0x00100615, 0x82040580, + 0x0000003b, 0x02020800, 0x00100615, 0x592c020a, + 0x8c000500, 0x0400005f, 0x592c1a07, 0x82040500, + 0x0000000f, 0x82000400, 0x0010110d, 0x50001000, + 0x50080000, 0x59302013, 0x4802600a, 0x492e600b, + 0x480a600c, 0x480e600d, 0x48126012, 0x5c025800, + 0x1c01f000, 0x82040500, 0x0000000f, 0x82000400, + 0x0010110d, 0x50001000, 0x50080000, 0x592c1a07, + 0x4802600a, 0x492e600b, 0x480a600c, 0x480e600d, + 0x497a6012, 0x0401f7f2, 0x8c040d00, 0x04020041, + 0x82040d00, 0x00000080, 0x0400003e, 0x0201f000, + 0x000200d0, 0x59300013, 0x59301012, 0x80080580, + 0x0402000c, 0x42007800, 0x80000005, 0x592c1208, + 0x82080500, 0xffff7fff, 0x48025a08, 0x8c08151e, + 0x0402002d, 0x823c7d40, 0x00000020, 0x0401f02a, + 0x480bc857, 0x42000000, 0x0010b64f, 0x0201f800, + 0x0010a86e, 0x59300414, 0x4803c857, 0x8c000514, + 0x04020007, 0x599c1819, 0x8c0c1d12, 0x04020004, + 0x820c1d40, 0x00000001, 0x0401f01d, 0x59302013, + 0x0401f92d, 0x0402001a, 0x42007800, 0x80000005, + 0x5930500d, 0x592c0208, 0x4803c857, 0x8c00051e, + 0x04020005, 0x823c7d40, 0x00000020, 0x5930400c, + 0x0401f004, 0x8400051e, 0x48025a08, 0x0401f8dc, + 0x50201800, 0x480e600a, 0x4832600b, 0x4822600c, + 0x482a600d, 0x480fc857, 0x4833c857, 0x4823c857, + 0x482bc857, 0x80000580, 0x483e6004, 0x1c01f000, + 0x0201f800, 0x00100615, 0x4933c857, 0x4d2c0000, + 0x59900004, 0x81300580, 0x02020800, 0x00100615, + 0x0201f800, 0x00108df4, 0x02000800, 0x00100615, + 0x59325808, 0x4d3c0000, 0x4d400000, 0x59300004, + 0x4803c857, 0x4c000000, 0x0201f800, 0x00106b13, + 0x0201f800, 0x001068c1, 0x5c000000, 0x8c000516, + 0x04000010, 0x592c000f, 0x4803c857, 0x48025807, + 0x41780800, 0x42028000, 0x00000002, 0x0201f800, + 0x00104bee, 0x4a025c06, 0x0000ffff, 0x0201f800, + 0x00020381, 0x0201f800, 0x00107698, 0x0401f015, + 0x4a026203, 0x00000002, 0x592c0208, 0x8400054e, + 0x48025a08, 0x59300406, 0x82000580, 0x00000006, + 0x04020009, 0x811800ca, 0x81c80c00, 0x58040939, + 0x592c000d, 0x80040480, 0x592c080f, 0x80040480, + 0x4802580b, 0x417a7800, 0x0201f800, 0x00108997, + 0x5c028000, 0x5c027800, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x4d2c0000, 0x59900004, 0x81300580, + 0x02020800, 0x00100615, 0x0201f800, 0x00108df4, + 0x02000800, 0x00100615, 0x59325808, 0x592c0208, + 0x84000540, 0x48025a08, 0x0401f7bf, 0x491bc857, + 0x49d3c857, 0x4dd00000, 0x41780800, 0x8007a0ca, + 0x83d3a400, 0x00007600, 0x4a03a005, 0x80000002, + 0x42000000, 0x00001000, 0x50000000, 0x82000480, + 0x24220001, 0x04020029, 0x59d01006, 0x82080500, + 0x00006000, 0x82000580, 0x00006000, 0x04000031, + 0x82080500, 0x40008000, 0x040007f8, 0x800409c0, + 0x0402002c, 0x811a31c0, 0x0400002a, 0x42000000, + 0x00001002, 0x50001000, 0x46000000, 0x00000512, + 0x42001800, 0x0000000a, 0x59e00000, 0x8c00051a, + 0x040207fc, 0x800c1840, 0x040207fc, 0x42000000, + 0x00001002, 0x46000000, 0x00000514, 0x42001800, + 0x0000000a, 0x59e00000, 0x8c00053a, 0x040207fc, + 0x800c1840, 0x040207fc, 0x42000000, 0x00001002, + 0x44080000, 0x0401f00f, 0x02004800, 0x000207c8, + 0x59d01006, 0x82080500, 0x00006000, 0x82000580, + 0x00006000, 0x04000007, 0x8c08151e, 0x040007f7, + 0x59d01006, 0x82080500, 0x00006000, 0x040207f3, + 0x83d3a400, 0x00000020, 0x80040800, 0x82040480, + 0x00000005, 0x040017bd, 0x5c03a000, 0x1c01f000, + 0x491bc857, 0x49d3c857, 0x4dd00000, 0x41780800, + 0x8007a0ca, 0x83d3a400, 0x00007600, 0x4a03a005, + 0x80000001, 0x59d00006, 0x83d3a400, 0x00000020, + 0x80040800, 0x82040480, 0x00000005, 0x040017f8, + 0x5c03a000, 0x1c01f000, 0x59d00006, 0x8c00053e, + 0x0400001e, 0x59902804, 0x4817c857, 0x801429c0, + 0x04000013, 0x5990000a, 0x5990080b, 0x5990100c, + 0x5990180d, 0x4800280a, 0x4804280b, 0x4808280c, + 0x480c280d, 0x59d00000, 0x59d00801, 0x59d01002, + 0x59d01803, 0x59d02004, 0x4800280e, 0x4804280f, + 0x48082810, 0x480c2811, 0x48102812, 0x59900006, + 0x82000500, 0xffff0000, 0x48032006, 0x4a03a005, + 0x30000000, 0x59d00006, 0x1c01f000, 0x4803c856, + 0x80204000, 0x50200000, 0x80000540, 0x04000003, + 0x80285040, 0x1c01f000, 0x58300001, 0x80000540, + 0x0400000e, 0x4802600b, 0x40006000, 0x58300204, + 0x82000500, 0x0000000f, 0x82000400, 0x0010110d, + 0x50004000, 0x802041c0, 0x02000800, 0x00100615, + 0x80285040, 0x1c01f000, 0x40005000, 0x1c01f000, + 0x00000005, 0x00000008, 0x0000000b, 0x0000000e, + 0x00000011, 0x00000000, 0x00000000, 0x0000000b, + 0x00000000, 0x00000000, 0x00000000, 0x00101108, + 0x00101107, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00101108, 0x00101107, 0x00101104, + 0x00101108, 0x00101107, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00101108, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00101108, 0x00101108, 0x00101108, + 0x00000000, 0x00101108, 0x00000000, 0x00000000, + 0x00000000, 0x4813c857, 0x492fc857, 0x4933c857, + 0x48126012, 0x592c5207, 0x802851c0, 0x0400004a, + 0x412c6000, 0x0401f84b, 0x04000009, 0x82240580, + 0x00000002, 0x04020003, 0x5830000d, 0x80102480, + 0x50200000, 0x80004540, 0x0400003f, 0x50200000, + 0x80000540, 0x0400000b, 0x80301400, 0x58080002, + 0x80102480, 0x0400101e, 0x801021c0, 0x04000009, + 0x80285040, 0x04000034, 0x80204000, 0x0401f7f4, + 0x58300001, 0x80006540, 0x0400002f, 0x0401f7e6, + 0x80285040, 0x0400002c, 0x80204000, 0x50200000, + 0x80000540, 0x0402000a, 0x58300001, 0x80006540, + 0x04000025, 0x58300204, 0x82004d00, 0x0000000f, + 0x82244400, 0x0010110d, 0x50204000, 0x592c0208, + 0x8400051e, 0x48025a08, 0x0401f013, 0x80102080, + 0x80102000, 0x48126010, 0x4813c857, 0x58080802, + 0x40100000, 0x80042480, 0x02001800, 0x00100615, + 0x58080000, 0x58081801, 0x80102400, 0x4812600e, + 0x480e600f, 0x4813c857, 0x592c0208, 0x8400055e, + 0x48025a08, 0x4833c857, 0x4823c857, 0x482bc857, + 0x4832600b, 0x4822600c, 0x482a600d, 0x80000580, + 0x0401f003, 0x82000540, 0x00000001, 0x1c01f000, + 0x58300204, 0x82004d00, 0x0000000f, 0x82244400, + 0x0010110d, 0x82000500, 0x000000ff, 0x82000580, + 0x00000029, 0x0402001b, 0x50204000, 0x592c0409, + 0x80000540, 0x02000800, 0x00100615, 0x82000c80, + 0x00000002, 0x04001011, 0x58300001, 0x80006540, + 0x02000800, 0x00100615, 0x58300204, 0x82000500, + 0x0000000f, 0x82000400, 0x0010110d, 0x50004000, + 0x40040000, 0x800409c0, 0x04000006, 0x82040c80, + 0x00000005, 0x040217f1, 0x80204400, 0x80000580, + 0x1c01f000, 0x59e00004, 0x8c00050e, 0x02020000, + 0x00100951, 0x1c01f000, 0x4c5c0000, 0x59e4b800, + 0x485fc857, 0x825c0500, 0x0000001f, 0x04000004, + 0x59e40862, 0x0201f800, 0x00100615, 0x825c0500, + 0x000000e0, 0x02000800, 0x00100615, 0x8c5cbd0e, + 0x04020807, 0x8c5cbd0c, 0x04020809, 0x8c5cbd0a, + 0x04020878, 0x5c00b800, 0x1c01f000, 0x4803c856, + 0x4a03c800, 0x00000080, 0x1c01f000, 0x4d2c0000, + 0x42007800, 0x0010b6eb, 0x583c0001, 0x583c0802, + 0x80040540, 0x0400003f, 0x42000800, 0x0010b5f5, + 0x50065800, 0x592c0002, 0x82000580, 0x00000000, + 0x0400000e, 0x59e40850, 0x59e41853, 0x400c0000, + 0x80040400, 0x59e40852, 0x4807c857, 0x80041480, + 0x04021008, 0x40001000, 0x480bc857, 0x4a007800, + 0x00000001, 0x0401f006, 0x4803c857, 0x0401f029, + 0x59e41050, 0x480bc857, 0x49787800, 0x480bc857, + 0x480fc857, 0x592c0003, 0x80000540, 0x04000006, + 0x80080580, 0x04020004, 0x592c0003, 0x4803c857, + 0x480bc857, 0x480a5803, 0x592c0007, 0x800001c0, + 0x04000007, 0x592c1007, 0x480bc857, 0x583c0003, + 0x4803c857, 0x80080480, 0x04001003, 0x583c1001, + 0x480bc857, 0x583c0802, 0x480bc857, 0x4807c857, + 0x4a025801, 0x00000000, 0x4a025809, 0x0010120c, + 0x480a5807, 0x48065808, 0x59e40053, 0x48025804, + 0x412c1000, 0x492fc857, 0x0201f800, 0x001008a1, + 0x5c025800, 0x4a03c800, 0x00000040, 0x1c01f000, + 0x42007800, 0x0010b5f5, 0x503c7800, 0x4a007802, + 0x00000100, 0x42007800, 0x0010b6eb, 0x583c0000, + 0x4803c857, 0x82000d80, 0x00000001, 0x04000004, + 0x80000000, 0x48007800, 0x0401f019, 0x49787800, + 0x583c1806, 0x583c0005, 0x800c1800, 0x480c7806, + 0x800c0580, 0x04020002, 0x49787806, 0x583c0807, + 0x800409c0, 0x0400000e, 0x583c0008, 0x80000000, + 0x48007808, 0x80040580, 0x04020009, 0x49787808, + 0x583c2006, 0x42001800, 0x00000001, 0x42001000, + 0x00008028, 0x0201f800, 0x00103857, 0x1c01f000, + 0x4a03c800, 0x00000020, 0x0201f800, 0x0010a867, + 0x59e40000, 0x1c01f000, 0x4d2c0000, 0x4a007001, + 0x00000000, 0x82040d00, 0x43000f80, 0x02020800, + 0x00100615, 0x58380009, 0x4803c00f, 0x0201f800, + 0x001091cb, 0x583a5808, 0x592c0000, 0x48007008, + 0x800001c0, 0x04020002, 0x49787007, 0x0201f800, + 0x0010083a, 0x5c025800, 0x0201f000, 0x001008c6, + 0x4803c856, 0x4c3c0000, 0x4d2c0000, 0x4d300000, + 0x5830000a, 0x80025d40, 0x02000800, 0x00100615, + 0x592e6008, 0x4c300000, 0x0201f800, 0x001091e3, + 0x5c006000, 0x02000800, 0x00100615, 0x58300002, + 0x82000580, 0x00000100, 0x04020010, 0x5930780b, + 0x583c0001, 0x80000540, 0x0400000e, 0x4802600b, + 0x40007800, 0x82000400, 0x00000002, 0x48006003, + 0x583c0000, 0x48006004, 0x40301000, 0x0201f800, + 0x001008a1, 0x0401f00c, 0x4a025a06, 0x00000002, + 0x4c300000, 0x0201f800, 0x00020381, 0x5c006000, + 0x40325800, 0x0201f800, 0x0010083a, 0x0201f800, + 0x000208b4, 0x5c026000, 0x5c025800, 0x5c007800, + 0x1c01f000, 0x4803c856, 0x4d2c0000, 0x4d300000, + 0x42007000, 0x0010b5f6, 0x58380801, 0x82040580, + 0x00000002, 0x04020011, 0x58386002, 0x5830000a, + 0x812c0580, 0x0402000d, 0x59e00004, 0x8c00050e, + 0x040007fe, 0x59dc0006, 0x4803c857, 0x4a03b805, + 0x20000000, 0x8c00053e, 0x040007f8, 0x4a007001, + 0x00000000, 0x0401f019, 0x58386006, 0x40305000, + 0x803061c0, 0x02000800, 0x00100615, 0x5830000a, + 0x812c0580, 0x04000004, 0x40305000, 0x58306000, + 0x0401f7f8, 0x40280000, 0x80300580, 0x58300000, + 0x04000006, 0x48005000, 0x800001c0, 0x04020007, + 0x48287005, 0x0401f005, 0x800001c0, 0x04020002, + 0x48007005, 0x48007006, 0x40325800, 0x0201f800, + 0x0010083a, 0x42007000, 0x0010b5f6, 0x58380001, + 0x82000580, 0x00000000, 0x02000800, 0x001008c6, + 0x5c026000, 0x5c025800, 0x1c01f000, 0x4803c856, + 0x42000800, 0x0000003c, 0x48079000, 0x59c80000, + 0x80040500, 0x040207fe, 0x497b9005, 0x4a039035, + 0x00880200, 0x59a8000e, 0x800000e0, 0x4803900e, + 0x4a039011, 0x00000024, 0x4a03900f, 0x0010cfc0, + 0x4a039010, 0x0010cfc0, 0x4a039015, 0x0000007f, + 0x4a03900d, 0x00000040, 0x4a039000, 0x00001600, + 0x1c01f000, 0x59c80007, 0x8c000508, 0x040208b7, + 0x59c80800, 0x8c040d16, 0x04020004, 0x82000500, + 0x00000006, 0x0c01f005, 0x4807c857, 0x82000500, + 0x0000000e, 0x0c01f001, 0x001012f8, 0x001012f6, + 0x0010567d, 0x001012f6, 0x001012fa, 0x001012f6, + 0x001012fa, 0x001012fa, 0x001012f6, 0x001012f6, + 0x001012f6, 0x001012f6, 0x001012fa, 0x001012f6, + 0x001012fa, 0x001012f6, 0x0201f800, 0x00100615, + 0x4803c857, 0x1c01f000, 0x59c8080c, 0x4807c857, + 0x82040500, 0x00006000, 0x04000004, 0x0201f800, + 0x0010a82a, 0x0401f006, 0x82040500, 0x007f0000, + 0x04000006, 0x0201f800, 0x0010a7fc, 0x0201f800, + 0x00106c07, 0x0401f02b, 0x82040500, 0x00000014, + 0x04000014, 0x0201f800, 0x0010a859, 0x836c0580, + 0x00000003, 0x0400000d, 0x0201f800, 0x00104e0d, + 0x04000004, 0x0201f800, 0x00103f37, 0x0401f007, + 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, + 0x0201f800, 0x00104d76, 0x0401f817, 0x0401f015, + 0x82040500, 0x00001c00, 0x04000005, 0x0201f800, + 0x0010a838, 0x0401f810, 0x0401f00e, 0x82040500, + 0x00000140, 0x04000005, 0x0201f800, 0x0010a84b, + 0x0401f809, 0x0401f007, 0x82040500, 0x00008000, + 0x04000004, 0x0201f800, 0x0010a823, 0x0401f802, + 0x1c01f000, 0x4c0c0000, 0x4c100000, 0x4c140000, + 0x0201f800, 0x00100f17, 0x5c002800, 0x5c002000, + 0x5c001800, 0x1c01f000, 0x4803c856, 0x59a80804, + 0x59a8002b, 0x82000500, 0xfffff000, 0x80040540, + 0x4803502b, 0x59a8002f, 0x82000500, 0xfffff000, + 0x80040540, 0x4803502f, 0x48078882, 0x82041c00, + 0x0000000f, 0x800c1908, 0x820c1c00, 0x00000004, + 0x400c2000, 0x901029c0, 0x82040480, 0x000001e4, + 0x04021005, 0x42001000, 0x00000008, 0x801020c6, + 0x0401f031, 0x82040480, 0x00000230, 0x04021009, + 0x42001000, 0x00000007, 0x801000c2, 0x800000c2, + 0x80100400, 0x80100400, 0x80102400, 0x0401f026, + 0x82040480, 0x00000298, 0x04021008, 0x42001000, + 0x00000006, 0x801000c2, 0x800000c2, 0x80100400, + 0x80102400, 0x0401f01c, 0x82040480, 0x00000328, + 0x04021007, 0x42001000, 0x00000005, 0x801000c2, + 0x800000c2, 0x80102400, 0x0401f013, 0x82040480, + 0x00000404, 0x04021005, 0x42001000, 0x00000004, + 0x801020c4, 0x0401f00c, 0x82040480, 0x0000056c, + 0x04021006, 0x42001000, 0x00000003, 0x801000c2, + 0x80102400, 0x0401f004, 0x42001000, 0x00000002, + 0x801020c2, 0x82100480, 0x00000110, 0x80000080, + 0x80002000, 0x800800d0, 0x80140540, 0x80100540, + 0x48039035, 0x1c01f000, 0x59c80815, 0x0201f800, + 0x0010060d, 0x82040d00, 0x0000007c, 0x48079000, + 0x59c80000, 0x80040500, 0x040207fe, 0x8c040d04, + 0x04000003, 0x59c80035, 0x48039035, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x1c01f000, + 0x4803c856, 0x497b88a9, 0x4a038807, 0x00000001, + 0x497b8807, 0x59c40005, 0x48038805, 0x0201f800, + 0x00101886, 0x4201d000, 0x000001f4, 0x0201f800, + 0x00105dd2, 0x497b880e, 0x4200b000, 0x000001f4, + 0x42000000, 0x00000001, 0x42000800, 0x00000014, + 0x0201f800, 0x001019b1, 0x42000800, 0x00000014, + 0x0201f800, 0x001019ac, 0x8c040d00, 0x04000005, + 0x8058b040, 0x040207f3, 0x0201f800, 0x00100615, + 0x4200b000, 0x00000032, 0x42000000, 0x00000001, + 0x42000800, 0x000000b4, 0x0201f800, 0x001019b1, + 0x42000800, 0x000000b4, 0x0201f800, 0x001019ac, + 0x8c040d00, 0x04000005, 0x8058b040, 0x040207f3, + 0x0201f800, 0x00100615, 0x59c40005, 0x48038805, + 0x42000000, 0x00000089, 0x800008d0, 0x48075054, + 0x48075055, 0x48075056, 0x42000800, 0x000000e0, + 0x0201f800, 0x001019b1, 0x42000800, 0x000000f4, + 0x0201f800, 0x001019ac, 0x82040500, 0xffffffd1, + 0x82000540, 0x00000002, 0x42000800, 0x000000f4, + 0x0201f800, 0x001019b1, 0x42000800, 0x000000a0, + 0x0201f800, 0x001019ac, 0x82040540, 0x00000001, + 0x42000800, 0x000000a0, 0x0201f800, 0x001019b1, + 0x42000800, 0x00000000, 0x0201f800, 0x001019ac, + 0x82040540, 0x00000001, 0x42000800, 0x00000000, + 0x0201f800, 0x001019b1, 0x4201d000, 0x0001d4c0, + 0x0201f800, 0x00105dd2, 0x0401fa45, 0x4a0388a7, + 0x0000f7f7, 0x4a0388a3, 0x8000403c, 0x4a0388ae, + 0x000061a8, 0x4a038801, 0x00032063, 0x4a038810, + 0x00410108, 0x4a038811, 0x00520608, 0x4a038812, + 0x00450320, 0x4a038813, 0x00440405, 0x4a03881c, + 0x004132e1, 0x4a038850, 0x80000108, 0x4a038860, + 0x00000008, 0x4a038870, 0x00000008, 0x4a038851, + 0x80000508, 0x4a038861, 0x00800000, 0x4a038871, + 0x00800000, 0x4a038852, 0x80000708, 0x4a038862, + 0x00800000, 0x4a038872, 0x00800000, 0x4a038853, + 0x80000608, 0x497b8863, 0x4a038873, 0x00800000, + 0x4a038882, 0x00000840, 0x4a0388a5, 0x0000001e, + 0x4a0388a6, 0x0000001e, 0x4a0388b0, 0x00007530, + 0x4a038802, 0x0000ffff, 0x4a038806, 0xc0e00800, + 0x1c01f000, 0x497b5022, 0x4a035021, 0x00000001, + 0x42000800, 0x00000040, 0x0201f800, 0x001019ac, + 0x82040500, 0xffffffaf, 0x82000540, 0x00000000, + 0x42000800, 0x00000040, 0x0201f800, 0x001019b1, + 0x42000800, 0x000000f4, 0x0201f800, 0x001019ac, + 0x4c040000, 0x40040000, 0x84000548, 0x42000800, + 0x000000f4, 0x0201f800, 0x001019b1, 0x42000800, + 0x00000000, 0x0201f800, 0x001019ac, 0x82040500, + 0xffffffc1, 0x82000540, 0x00000038, 0x42000800, + 0x00000000, 0x0201f800, 0x001019b1, 0x5c000000, + 0x42000800, 0x000000f4, 0x0201f000, 0x001019b1, + 0x59c40805, 0x59c40006, 0x80040d00, 0x02000800, + 0x00100615, 0x82040500, 0x00e00800, 0x04020004, + 0x8c040d3e, 0x040208df, 0x0401f007, 0x82040500, + 0x00800800, 0x02020800, 0x0010060d, 0x0201f800, + 0x00100615, 0x4c5c0000, 0x4c600000, 0x59c4b805, + 0x59c40006, 0x8c000500, 0x04000003, 0x8c5cbd00, + 0x04020095, 0x485fc857, 0x0201f800, 0x00104e0d, + 0x0400001e, 0x59c40005, 0x82000500, 0x000000c0, + 0x0400004b, 0x0201f800, 0x00104e23, 0x04020048, + 0x59c40006, 0x82000500, 0x000000f0, 0x04020004, + 0x4a038805, 0x000000c0, 0x0401f041, 0x59a80015, + 0x84000506, 0x48035015, 0x42006000, 0xff203fff, + 0x42006800, 0x40000000, 0x0201f800, 0x001040ad, + 0x42000800, 0x00000010, 0x42001000, 0x00104020, + 0x0201f800, 0x00105dc7, 0x8c5cbd34, 0x04020030, + 0x4a035032, 0x0000aaaa, 0x59c40005, 0x8c00050c, + 0x04020012, 0x8c00050e, 0x0402001c, 0x8c00050a, + 0x0402001d, 0x8c000508, 0x0400000b, 0x59a80017, + 0x82000580, 0x00000009, 0x04020007, 0x42000000, + 0x0010b642, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x00104fe9, 0x0401f05a, 0x0201f800, 0x00104e23, + 0x04020007, 0x42000800, 0x0000000f, 0x42001000, + 0x00103f37, 0x0201f800, 0x00105da7, 0x4a035033, + 0x00000000, 0x0401f00b, 0x4a035033, 0x00000002, + 0x0401f008, 0x42000000, 0x0010b644, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00104f93, 0x0401f044, + 0x0201f800, 0x00105049, 0x0401f041, 0x8c5cbd34, + 0x0400003d, 0x59c40005, 0x8c00053a, 0x04020005, + 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, + 0x4a038805, 0x02000000, 0x0201f800, 0x00104e0d, + 0x04020010, 0x4a038805, 0x04000000, 0x0201f800, + 0x00104e1b, 0x04020008, 0x4a035033, 0x00000001, + 0x4202d800, 0x00000001, 0x0201f800, 0x00104d76, + 0x0401f061, 0x41780000, 0x0201f800, 0x00104de5, + 0x0201f800, 0x00101a59, 0x4000c000, 0x0201f800, + 0x001019d0, 0x836c1580, 0x00000004, 0x0402000d, + 0x8c5cbd00, 0x04020018, 0x59a81005, 0x8c081506, + 0x04020005, 0x59c410a3, 0x82081540, 0x00000008, + 0x480b88a3, 0x59c41006, 0x84081540, 0x480b8806, + 0x4a038805, 0x04000000, 0x4202d800, 0x00000001, + 0x497b5014, 0x59a80005, 0x8c000518, 0x04020004, + 0x0401f95c, 0x0201f800, 0x00103f5c, 0x0201f800, + 0x00103951, 0x8c5cbd3c, 0x04020858, 0x8c5cbd00, + 0x04000036, 0x42000000, 0x0010b6c9, 0x0201f800, + 0x0010a86e, 0x4a038805, 0x00000001, 0x4200b000, + 0x00000352, 0x4201d000, 0x00000064, 0x4c580000, + 0x0201f800, 0x00105dd2, 0x0201f800, 0x00101941, + 0x5c00b000, 0x04000004, 0x8058b040, 0x040207f6, + 0x0401f004, 0x4a038805, 0x00000001, 0x0401f01f, + 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, + 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, + 0x59c4000d, 0x8c000500, 0x02020800, 0x0010a7f5, + 0x59c400a3, 0x82000500, 0xfcf8ffff, 0x480388a3, + 0x4a03504c, 0x00000002, 0x4202d800, 0x00000004, + 0x4a038805, 0x00000001, 0x0201f800, 0x0010071a, + 0x0401fb42, 0x497b5052, 0x4a035049, 0x00000001, + 0x0201f800, 0x0010048c, 0x825cbd00, 0xbbfffffe, + 0x485f8805, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x59c41004, 0x480bc857, 0x8c081500, 0x04000006, + 0x4803c856, 0x497b2807, 0x0201f800, 0x00106cf9, + 0x0401f00a, 0x82080500, 0x000001f0, 0x04000007, + 0x4803c856, 0x417a3000, 0x0201f800, 0x00105d9b, + 0x0201f800, 0x00106d1b, 0x4a038805, 0x80000000, + 0x1c01f000, 0x59c408a3, 0x4807c857, 0x84040d40, + 0x480788a3, 0x1c01f000, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x4a038805, 0x40000000, + 0x42000000, 0x0010b6c5, 0x0201f800, 0x0010a86e, + 0x0201f800, 0x0010698c, 0x59c41004, 0x8c081500, + 0x04000054, 0x598e600d, 0x497b2807, 0x813261c0, + 0x04000032, 0x59300403, 0x82000580, 0x00000032, + 0x0402002e, 0x5930001c, 0x48038833, 0x4a038807, + 0x00018000, 0x4201d000, 0x00000002, 0x0201f800, + 0x00105dd2, 0x497b8807, 0x4201d000, 0x00000002, + 0x0201f800, 0x00105dd2, 0x0201f800, 0x00106b71, + 0x4201d000, 0x00007530, 0x0201f800, 0x00105dd2, + 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80, + 0x00000000, 0x04000005, 0x42000000, 0x00200000, + 0x0201f800, 0x001019b6, 0x0201f800, 0x001068f6, + 0x59300008, 0x80000540, 0x02000800, 0x00100615, + 0x40025800, 0x4a025a04, 0x00000103, 0x5931d821, + 0x58ef400b, 0x58ec0009, 0x0801f800, 0x0201f800, + 0x000208b4, 0x0401f047, 0x598c000f, 0x82001c80, + 0x000000c8, 0x0402100f, 0x80000000, 0x4803180f, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x00000002, 0x04020004, 0x42000000, 0x00200000, + 0x0401fbfa, 0x0201f800, 0x00105d86, 0x0401f035, + 0x4933c857, 0x0201f800, 0x00106b71, 0x813261c0, + 0x04000030, 0x4a026203, 0x00000001, 0x42027000, + 0x00000027, 0x0201f800, 0x000208d8, 0x0401f029, + 0x8c081508, 0x04000027, 0x417a3000, 0x0201f800, + 0x00106e2f, 0x42032000, 0x0000bf32, 0x0201f800, + 0x00105d9b, 0x59926004, 0x813261c0, 0x04000012, + 0x42001800, 0x000000c8, 0x0201f800, 0x00106dfb, + 0x0402000d, 0x59c400a4, 0x82000500, 0x0000000f, + 0x82000580, 0x00000002, 0x04020004, 0x42000000, + 0x00200000, 0x0401fbd1, 0x0201f800, 0x00105d8b, + 0x0401f00c, 0x4933c857, 0x0201f800, 0x00106b13, + 0x813261c0, 0x04000007, 0x42027000, 0x0000004f, + 0x4a026203, 0x00000003, 0x0201f800, 0x000208d8, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x0201f000, 0x00106982, 0x4803c857, 0x59a80821, + 0x48035021, 0x80041580, 0x04000045, 0x800409c0, + 0x04000023, 0x497b504c, 0x42000000, 0x0010b60b, + 0x0201f800, 0x0010a86e, 0x0201f800, 0x0010a920, + 0x42001000, 0x00008011, 0x59c40001, 0x82000500, + 0x00018000, 0x82001d80, 0x00000000, 0x04000009, + 0x82001d80, 0x00008000, 0x04000009, 0x82001d80, + 0x00010000, 0x04000009, 0x0201f800, 0x00100615, + 0x42001800, 0x00000000, 0x0401f006, 0x42001800, + 0x00000001, 0x0401f003, 0x42001800, 0x00000003, + 0x0201f800, 0x00103857, 0x0401f021, 0x59a8084c, + 0x800409c0, 0x04020007, 0x59c4000d, 0x8c000520, + 0x04000004, 0x42001800, 0x00000003, 0x0401f002, + 0x40041800, 0x0201f800, 0x0010a904, 0x42001000, + 0x00008012, 0x0201f800, 0x00103857, 0x0201f800, + 0x0010071a, 0x0201f800, 0x0010a95a, 0x0402000c, + 0x0401f853, 0x4d400000, 0x4d3c0000, 0x42028000, + 0x00000028, 0x42027800, 0x00000008, 0x0201f800, + 0x00101d90, 0x5c027800, 0x5c028000, 0x1c01f000, + 0x4803c857, 0x82000400, 0x00101eb5, 0x50000800, + 0x82040d00, 0x000000ff, 0x1c01f000, 0x4803c856, + 0x4c580000, 0x4200b000, 0x00000010, 0x497b88ac, + 0x497b88ad, 0x8058b040, 0x040207fe, 0x5c00b000, + 0x1c01f000, 0x4807c857, 0x48075010, 0x80041108, + 0x4200b000, 0x00000010, 0x497b88ac, 0x80000580, + 0x800811c0, 0x04020006, 0x82040500, 0x0000000f, + 0x82000400, 0x0010a95f, 0x50000000, 0x480388ad, + 0x80081040, 0x8058b040, 0x040207f5, 0x1c01f000, + 0x59a80005, 0x04000003, 0x84000546, 0x0401f002, + 0x84000506, 0x48035005, 0x4803c857, 0x1c01f000, + 0x4803c857, 0x4c080000, 0x4c040000, 0x4c000000, + 0x59c40892, 0x4807c857, 0x80041580, 0x04000010, + 0x80041480, 0x04021007, 0x80081080, 0x80081000, + 0x4008b000, 0x42000000, 0x00000201, 0x0401f004, + 0x4008b000, 0x42000000, 0x00000210, 0x48038886, + 0x8058b040, 0x040207fe, 0x497b8886, 0x5c000000, + 0x5c000800, 0x5c001000, 0x1c01f000, 0x4803c856, + 0x0201f800, 0x0010393e, 0x04000005, 0x42028000, + 0x0000002e, 0x0201f000, 0x0010a25b, 0x1c01f000, + 0x59a8086f, 0x82040500, 0x00000010, 0x04000004, + 0x42000800, 0x00000002, 0x0401f010, 0x82040500, + 0x00000020, 0x42000800, 0x00000002, 0x0402000b, + 0x59c80835, 0x82040d00, 0x00001f00, 0x80040910, + 0x80040800, 0x59a8006c, 0x80000540, 0x04000003, + 0x42000800, 0x0000025a, 0x4807c857, 0x1c01f000, + 0x4c000000, 0x59a80053, 0x4803c857, 0x82000580, + 0x00000000, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x59a80053, 0x4803c857, 0x82000580, 0x00000001, + 0x5c000000, 0x1c01f000, 0x4c000000, 0x59a80053, + 0x4803c857, 0x82000580, 0x00000003, 0x5c000000, + 0x1c01f000, 0x4c000000, 0x59a80053, 0x82000580, + 0x00000002, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x4c040000, 0x4c080000, 0x4c380000, 0x59a80040, + 0x82000c80, 0x00000007, 0x02021800, 0x00100615, + 0x0c01f806, 0x5c007000, 0x5c001000, 0x5c000800, + 0x5c000000, 0x1c01f000, 0x001016dd, 0x001016f0, + 0x00101704, 0x00101706, 0x0010172d, 0x0010172f, + 0x00101731, 0x4803c856, 0x4a035042, 0x00000000, + 0x42000000, 0x00000002, 0x0401fa18, 0x42000000, + 0x00000002, 0x0401f9ad, 0x0401faae, 0x4803c856, + 0x4a035040, 0x00000006, 0x42000800, 0x0000001e, + 0x42001000, 0x00101732, 0x0201f000, 0x00105da7, + 0x497b5045, 0x4a035050, 0x00000036, 0x4a03504f, + 0x0000002a, 0x4803c856, 0x4a035042, 0x00000001, + 0x42000000, 0x00000002, 0x0401f998, 0x4803c856, + 0x4a035040, 0x00000006, 0x42000800, 0x0000001e, + 0x42001000, 0x00101732, 0x0201f000, 0x00105da7, + 0x0201f800, 0x00100615, 0x4a035050, 0x00000036, + 0x4803c856, 0x4a035042, 0x00000003, 0x42000800, + 0x00000000, 0x0401fa9f, 0x82040d00, 0x00000090, + 0x82040580, 0x00000090, 0x04000009, 0x82040580, + 0x00000010, 0x04000009, 0x82040580, 0x00000000, + 0x04000008, 0x0201f800, 0x00100615, 0x42000000, + 0x00000001, 0x0401f005, 0x41780000, 0x0401f003, + 0x42000000, 0x00000002, 0x0401f970, 0x497b5046, + 0x4803c856, 0x4a035040, 0x00000006, 0x42000800, + 0x0000001e, 0x42001000, 0x00101732, 0x0201f000, + 0x00105da7, 0x0201f800, 0x00100615, 0x0201f800, + 0x00100615, 0x1c01f000, 0x4c000000, 0x4c040000, + 0x4c080000, 0x4c380000, 0x59a80042, 0x82000c80, + 0x00000007, 0x02021800, 0x00100615, 0x0c01f806, + 0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000, + 0x1c01f000, 0x00101748, 0x00101767, 0x001017bb, + 0x001017d2, 0x001017e9, 0x001017f2, 0x001017f4, + 0x0401f9f9, 0x0402001b, 0x59a81048, 0x42000800, + 0x00000000, 0x0401fa5f, 0x82040d00, 0x00000090, + 0x82040580, 0x00000090, 0x04000009, 0x82040580, + 0x00000010, 0x04000008, 0x82040580, 0x00000000, + 0x04000007, 0x0201f800, 0x00100615, 0x84081540, + 0x0401f004, 0x84081542, 0x0401f002, 0x84081544, + 0x480b5048, 0x4a035040, 0x00000001, 0x0401f003, + 0x0401f8cb, 0x0401ff82, 0x1c01f000, 0x0401f88f, + 0x04000052, 0x0401f9d8, 0x0402002a, 0x42000800, + 0x00000000, 0x0401fa3f, 0x82040d00, 0x00000090, + 0x82040580, 0x00000000, 0x04000044, 0x82040580, + 0x00000010, 0x04000006, 0x82040580, 0x00000090, + 0x04000009, 0x0201f800, 0x00100615, 0x59c40801, + 0x82040d00, 0x00018000, 0x82040580, 0x00000000, + 0x04000036, 0x42000800, 0x00000000, 0x0401fa29, + 0x82040d00, 0x00000090, 0x82040580, 0x00000010, + 0x04000006, 0x82040580, 0x00000090, 0x04000006, + 0x02020800, 0x00100615, 0x59a80048, 0x84000542, + 0x0401f003, 0x59a80048, 0x84000540, 0x48035048, + 0x59a80045, 0x80000000, 0x48035045, 0x82000580, + 0x00000005, 0x04000003, 0x0401f861, 0x0401f01e, + 0x497b5045, 0x59c40801, 0x82040d00, 0x00018000, + 0x82040580, 0x00000000, 0x04000009, 0x82040580, + 0x00008000, 0x04000009, 0x82040580, 0x00010000, + 0x04000008, 0x0201f800, 0x00100615, 0x42000000, + 0x00000001, 0x0401f005, 0x41780000, 0x0401f003, + 0x42000000, 0x00000002, 0x0401f948, 0x4a035042, + 0x00000002, 0x0401f004, 0x4a035040, 0x00000003, + 0x0401f002, 0x0401ff42, 0x1c01f000, 0x0401f83b, + 0x04000015, 0x59a8004f, 0x80000040, 0x4803504f, + 0x0401f981, 0x04020005, 0x4a035040, 0x00000003, + 0x497b5041, 0x0401f00c, 0x59a8004f, 0x80000540, + 0x04020003, 0x0401f89e, 0x0401f002, 0x0401f84b, + 0x0401f82f, 0x497b5045, 0x4a035042, 0x00000001, + 0x0401ff2b, 0x1c01f000, 0x0401f824, 0x04000015, + 0x0401f96d, 0x0402000f, 0x59a80046, 0x80000000, + 0x48035046, 0x82000580, 0x00000007, 0x0402000c, + 0x4a035052, 0x0000000a, 0x497b5049, 0x59a80048, + 0x8400055e, 0x48035048, 0x4803c857, 0x0401f005, + 0x0401f817, 0x4a035042, 0x00000004, 0x0401ff3d, + 0x1c01f000, 0x0401f80d, 0x04000007, 0x0401f956, + 0x04020003, 0x0401ff1b, 0x0401f003, 0x0401f80c, + 0x0401ff34, 0x1c01f000, 0x0201f800, 0x00100615, + 0x0201f800, 0x00100615, 0x59a80050, 0x80000040, + 0x48035050, 0x0400088d, 0x1c01f000, 0x4c040000, + 0x42000800, 0x00000000, 0x0401f9ae, 0x82040d00, + 0x00000090, 0x82040580, 0x00000090, 0x04000009, + 0x82040580, 0x00000010, 0x04000009, 0x82040580, + 0x00000000, 0x04000009, 0x0201f800, 0x00100615, + 0x42000000, 0x00000002, 0x0401f005, 0x42000000, + 0x00000001, 0x0401f002, 0x41780000, 0x0401f8e7, + 0x5c000800, 0x1c01f000, 0x4c040000, 0x59c40801, + 0x82040d00, 0x00018000, 0x82040580, 0x00000000, + 0x04000009, 0x82040580, 0x00008000, 0x04000009, + 0x82040580, 0x00010000, 0x04000009, 0x0201f800, + 0x00100615, 0x42000000, 0x00000002, 0x0401f005, + 0x42000000, 0x00000001, 0x0401f002, 0x41780000, + 0x0401f866, 0x5c000800, 0x1c01f000, 0x4c040000, + 0x59a80045, 0x80000000, 0x48035045, 0x82000580, + 0x00000005, 0x04020018, 0x497b5045, 0x59c40801, + 0x82040d00, 0x00018000, 0x82040580, 0x00000000, + 0x04000009, 0x82040580, 0x00008000, 0x04000009, + 0x82040580, 0x00010000, 0x04000009, 0x0201f800, + 0x00100615, 0x42000000, 0x00000002, 0x0401f005, + 0x42000000, 0x00000001, 0x0401f002, 0x41780000, + 0x0401f846, 0x42000800, 0x00000000, 0x0401f95d, + 0x82040d00, 0x00000090, 0x82040580, 0x00000090, + 0x04000009, 0x82040580, 0x00000010, 0x04000009, + 0x82040580, 0x00000000, 0x04000009, 0x0201f800, + 0x00100615, 0x42000000, 0x00000002, 0x0401f005, + 0x42000000, 0x00000001, 0x0401f002, 0x41780000, + 0x0401f896, 0x5c000800, 0x1c01f000, 0x4c200000, + 0x59a80048, 0x82000500, 0x00007fff, 0x02000800, + 0x00100615, 0x59a84047, 0x80204102, 0x02001800, + 0x00100615, 0x48235047, 0x80204500, 0x040007fa, + 0x8c000504, 0x04020007, 0x8c000502, 0x04020008, + 0x8c000500, 0x04020008, 0x0201f800, 0x00100615, + 0x42000000, 0x00000002, 0x0401f005, 0x41780000, + 0x0401f003, 0x42000000, 0x00000001, 0x0401f80f, + 0x5c004000, 0x1c01f000, 0x04011000, 0x4a03c840, + 0x0010b240, 0x4a03c842, 0x00000009, 0x40000000, + 0x040117ff, 0x4a035047, 0x00000004, 0x4a03503e, + 0x00000000, 0x1c01f000, 0x59a80858, 0x82040d80, + 0x01391077, 0x04020008, 0x59e00813, 0x8c040d00, + 0x04000005, 0x82000d80, 0x00000002, 0x04020002, + 0x41780000, 0x800001c0, 0x04000040, 0x82000d80, + 0x00000001, 0x0402001d, 0x42000800, 0x000000a0, + 0x0401f908, 0x82040540, 0x00000004, 0x42000800, + 0x000000a0, 0x0401f908, 0x42000800, 0x000000c0, + 0x0401f900, 0x82040540, 0x00000020, 0x42000800, + 0x000000c0, 0x0401f900, 0x59c40001, 0x82000500, + 0xfffe7fff, 0x82000540, 0x00000000, 0x48038801, + 0x59a80054, 0x80000110, 0x42000800, 0x000000e0, + 0x0401f8f5, 0x0401f03c, 0x82000d80, 0x00000002, + 0x02020800, 0x00100615, 0x42000800, 0x000000a0, + 0x0401f8e8, 0x82040500, 0xfffffffb, 0x42000800, + 0x000000a0, 0x0401f8e8, 0x42000800, 0x000000c0, + 0x0401f8e0, 0x82040500, 0xffffffdf, 0x42000800, + 0x000000c0, 0x0401f8e0, 0x59c40001, 0x82000500, + 0xfffe7fff, 0x82000540, 0x00010000, 0x48038801, + 0x59a80056, 0x80000110, 0x42000800, 0x000000e0, + 0x0401f8d5, 0x0401f01c, 0x42000800, 0x000000a0, + 0x0401f8cc, 0x82040540, 0x00000004, 0x42000800, + 0x000000a0, 0x0401f8cc, 0x42000800, 0x000000c0, + 0x0401f8c4, 0x82040500, 0xffffffdf, 0x42000800, + 0x000000c0, 0x0401f8c4, 0x59c40001, 0x82000500, + 0xfffe7fff, 0x82000540, 0x00008000, 0x48038801, + 0x59a80055, 0x80000110, 0x42000800, 0x000000e0, + 0x0401f8b9, 0x1c01f000, 0x4803c857, 0x59a80858, + 0x82040d80, 0x01391077, 0x04020008, 0x59e00813, + 0x8c040d00, 0x04000005, 0x82000d80, 0x00000002, + 0x04020002, 0x41780000, 0x4c000000, 0x0401f942, + 0x5c000000, 0x800001c0, 0x04000026, 0x82000d80, + 0x00000001, 0x04020010, 0x59a8006c, 0x80000540, + 0x04000004, 0x42001000, 0x00000000, 0x0401f9f7, + 0x42000800, 0x00000000, 0x0401f896, 0x82040540, + 0x00000090, 0x42000800, 0x00000000, 0x0401f896, + 0x0401f024, 0x82000d80, 0x00000002, 0x02020800, + 0x00100615, 0x59a8006c, 0x80000540, 0x04000004, + 0x42001000, 0x00010000, 0x0401f9e4, 0x42000800, + 0x00000000, 0x0401f883, 0x82040500, 0xffffff6f, + 0x42000800, 0x00000000, 0x0401f883, 0x0401f011, + 0x59a8006c, 0x80000540, 0x04000004, 0x42001000, + 0x00008000, 0x0401f9d5, 0x42000800, 0x00000000, + 0x0401f874, 0x82040500, 0xffffff6f, 0x82000540, + 0x00000010, 0x42000800, 0x00000000, 0x0401f872, + 0x0401f111, 0x4c580000, 0x4200b000, 0x00000014, + 0x8058b040, 0x04000042, 0x59c4000d, 0x8c000520, + 0x040207fc, 0x0401f85b, 0x59c4000d, 0x8c000520, + 0x040207f8, 0x59c40808, 0x84040d50, 0x48078808, + 0x4200b000, 0x000000c8, 0x8058b040, 0x040207ff, + 0x4200b000, 0x00000014, 0x8058b040, 0x04000030, + 0x59c4000d, 0x8c000520, 0x0402002d, 0x42000800, + 0x00001000, 0x50040800, 0x82040c80, 0x24220001, + 0x04020003, 0x8c000504, 0x040007f4, 0x0401f841, + 0x59c4000d, 0x8c000520, 0x04020021, 0x42000800, + 0x00001000, 0x50040800, 0x82040c80, 0x24220001, + 0x04020003, 0x8c000504, 0x040007e8, 0x4200b000, + 0x0000000a, 0x8058b040, 0x04000003, 0x0401f831, + 0x0401f7fd, 0x4200b000, 0x00000064, 0x59c4000d, + 0x8c00051e, 0x0400000e, 0x8058b040, 0x040207fc, + 0x42000000, 0x00001000, 0x50000000, 0x82000480, + 0x24220001, 0x04020004, 0x59c40808, 0x84040d10, + 0x48078808, 0x80000580, 0x0401f00c, 0x42000000, + 0x00001000, 0x50000000, 0x82000480, 0x24220001, + 0x04020004, 0x59c40808, 0x84040d10, 0x48078808, + 0x82000540, 0x00000001, 0x5c00b000, 0x1c01f000, + 0x42000800, 0x000000a0, 0x0401f816, 0x82040500, + 0xfffffffe, 0x42000800, 0x000000a0, 0x0401f816, + 0x42000800, 0x00000000, 0x0401f80e, 0x82040500, + 0xfffffffe, 0x42000800, 0x00000000, 0x0401f00e, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x1c01f000, 0x480b8805, 0x1c01f000, + 0x4807880e, 0x59c4080f, 0x82040d00, 0x000000ff, + 0x1c01f000, 0x900001c0, 0x80040d40, 0x84040d40, + 0x4807880e, 0x1c01f000, 0x82000d80, 0x00200000, + 0x04000009, 0x82000d80, 0x02000000, 0x04000006, + 0x82000d80, 0x01000000, 0x04000006, 0x59c408a3, + 0x0401f006, 0x59c408a3, 0x84040d30, 0x0401f003, + 0x59c408a3, 0x84040d32, 0x80040540, 0x480388a3, + 0x480788a3, 0x1c01f000, 0x59c400a3, 0x84000556, + 0x480388a3, 0x84000516, 0x480388a3, 0x1c01f000, + 0x485fc857, 0x4863c857, 0x4c640000, 0x4d3c0000, + 0x4d400000, 0x0201f800, 0x00106c32, 0x4863500a, + 0x0201f800, 0x0010a95a, 0x0402006a, 0x82600d00, + 0x0000ff00, 0x800409c0, 0x0400000c, 0x4200c800, + 0x00000001, 0x59a80010, 0x82000500, 0x000000ff, + 0x80041110, 0x80081580, 0x04000021, 0x82041580, + 0x0000ff00, 0x0400000a, 0x59c410a3, 0x82081500, + 0x00008000, 0x04000009, 0x59c410a7, 0x82081500, + 0x0000ff00, 0x82081580, 0x0000ff00, 0x4200c800, + 0x00000000, 0x04000012, 0x59a80005, 0x8c000502, + 0x04020008, 0x8c000500, 0x0402000d, 0x599c1017, + 0x8c08151a, 0x0400003c, 0x84000542, 0x48035005, + 0x4200c800, 0x00000002, 0x42028000, 0x00000004, + 0x42027800, 0x00000008, 0x0401f007, 0x59a80805, + 0x84040d40, 0x48075005, 0x42028000, 0x00000004, + 0x417a7800, 0x59a80006, 0x8c000502, 0x04020006, + 0x59a80805, 0x8c040d0a, 0x04020032, 0x84040d4a, + 0x48075005, 0x42000000, 0x0010b610, 0x0201f800, + 0x0010a86e, 0x59a8180a, 0x42001000, 0x00008013, + 0x0201f800, 0x00103857, 0x0201f800, 0x0010393e, + 0x04000015, 0x4d400000, 0x82600500, 0x000000ff, + 0x42028800, 0x0000ffff, 0x40643000, 0x42028000, + 0x0000000e, 0x0201f800, 0x0010a258, 0x42000800, + 0x00000001, 0x42001000, 0x00000100, 0x0201f800, + 0x00105ec4, 0x5c028000, 0x599c0817, 0x8c040d0a, + 0x04020010, 0x493fc857, 0x4943c857, 0x0401fb59, + 0x0401f00c, 0x0201f800, 0x0010393e, 0x04000009, + 0x42028000, 0x0000000f, 0x42028800, 0x0000ffff, + 0x42003000, 0x00000000, 0x0201f800, 0x0010a25b, + 0x497b8880, 0x5c028000, 0x5c027800, 0x5c00c800, + 0x1c01f000, 0x42000800, 0x00000000, 0x0401ff61, + 0x82040540, 0x00000002, 0x42000800, 0x00000000, + 0x0401f761, 0x42000800, 0x00000000, 0x0401ff59, + 0x82040500, 0xfffffffd, 0x42000800, 0x00000000, + 0x0401f759, 0x59c408a8, 0x0401ff4a, 0x0401ff49, + 0x59c400a8, 0x80040d80, 0x040207fb, 0x1c01f000, + 0x4803c856, 0x4a038807, 0x00000001, 0x497b8807, + 0x59c40005, 0x48038805, 0x497b506c, 0x497b506d, + 0x41785800, 0x42006000, 0x00000001, 0x42006800, + 0x00000003, 0x0401f824, 0x0401f82f, 0x40400000, + 0x4803c857, 0x82408580, 0x00000000, 0x0402001d, + 0x41785800, 0x42006000, 0x0000001e, 0x42006800, + 0x00000014, 0x0401f818, 0x0401f823, 0x40400000, + 0x4803c857, 0x82408580, 0x00000800, 0x04020011, + 0x42005800, 0x00000001, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401f80b, 0x0401f816, + 0x40400000, 0x4803c857, 0x82408580, 0x0000ffff, + 0x04020004, 0x4a03506c, 0x00000001, 0x4803c856, + 0x1c01f000, 0x41785000, 0x0401f812, 0x0401f838, + 0x40347000, 0x40340800, 0x0401f03d, 0x42005000, + 0x00000001, 0x0401f80b, 0x0401f831, 0x40340800, + 0x0401f037, 0x42005000, 0x00000002, 0x0401f805, + 0x0401f81d, 0x0401f835, 0x40048000, 0x1c01f000, + 0x0401f808, 0x0401f814, 0x40280800, 0x0401f826, + 0x402c0800, 0x0401f827, 0x40300800, 0x0401f025, + 0x42000800, 0x0000ffff, 0x42001000, 0x00000001, + 0x0401f829, 0x42001000, 0x00000010, 0x0401f826, + 0x42000800, 0x0000ffff, 0x42001000, 0x00000010, + 0x0401f021, 0x41780800, 0x42001000, 0x00000002, + 0x0401f01d, 0x0401f92e, 0x4a03d000, 0x00050004, + 0x0401f92b, 0x4a03d000, 0x00050005, 0x0401f928, + 0x4a03d000, 0x00050004, 0x42000800, 0x00000001, + 0x42001000, 0x00000001, 0x0401f00f, 0x42000800, + 0x00000002, 0x42001000, 0x00000002, 0x0401f00a, + 0x42001000, 0x00000005, 0x0401f007, 0x42001000, + 0x00000010, 0x0401f004, 0x42001000, 0x00000010, + 0x0401f01b, 0x0401f912, 0x82082c00, 0x0010a95f, + 0x50142800, 0x82081500, 0xffffffff, 0x04000013, + 0x0401f90b, 0x80081040, 0x80142902, 0x40040000, + 0x80140500, 0x04000007, 0x4a03d000, 0x00070006, + 0x0401f903, 0x4a03d000, 0x00070007, 0x0401f006, + 0x4a03d000, 0x00070004, 0x0401f8fd, 0x4a03d000, + 0x00070005, 0x0401f7ec, 0x1c01f000, 0x41780800, + 0x82082c00, 0x0010a95f, 0x50142800, 0x82081500, + 0xffffffff, 0x04000010, 0x0401f8f1, 0x4a03d000, + 0x00050001, 0x0401f8ee, 0x59e81800, 0x80081040, + 0x80142902, 0x8c0c1d06, 0x04000004, 0x40140000, + 0x80040d40, 0x0401f8e6, 0x4a03d000, 0x00070000, + 0x0401f7ef, 0x1c01f000, 0x480bc857, 0x480b506d, + 0x59c40001, 0x82000500, 0xffffefff, 0x48038801, + 0x41781800, 0x0401f8c4, 0x41785800, 0x42006000, + 0x0000001e, 0x42006800, 0x00000004, 0x0401ff7a, + 0x42006800, 0x0000003c, 0x0401ff7d, 0x41785800, + 0x42006000, 0x0000001e, 0x42006800, 0x00000004, + 0x0401ff71, 0x41786800, 0x0401ff75, 0x41785800, + 0x42006000, 0x0000001e, 0x41786800, 0x0401ff6a, + 0x42006800, 0x00000002, 0x0401ff6d, 0x42006800, + 0x00000001, 0x0401ff64, 0x42006800, 0x000000f5, + 0x0401ff67, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000004, 0x0401ff5b, 0x42006800, + 0x00000020, 0x0401ff5e, 0x59a8106d, 0x0401f865, + 0x42001800, 0x000200f5, 0x0401f897, 0x59a8106d, + 0x0401f879, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000004, 0x0401ff4b, 0x41786800, + 0x0401ff4f, 0x59c40001, 0x82000540, 0x00001000, + 0x48038801, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000015, 0x0401ff3f, 0x0401ff4a, + 0x40400000, 0x82000540, 0x00000002, 0x4c000000, + 0x41785800, 0x42006000, 0x0000001e, 0x42006800, + 0x00000015, 0x0401ff34, 0x5c000000, 0x40006800, + 0x0401ff37, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000015, 0x0401ff2b, 0x0401ff36, + 0x40400000, 0x82000500, 0x0000fffd, 0x4c000000, + 0x41785800, 0x42006000, 0x0000001e, 0x42006800, + 0x00000015, 0x0401ff20, 0x5c000000, 0x40006800, + 0x0401ff23, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401ff17, 0x0401ff22, + 0x40400000, 0x82000540, 0x00000040, 0x4c000000, + 0x41785800, 0x42006000, 0x0000001e, 0x42006800, + 0x00000014, 0x0401ff0c, 0x5c000000, 0x40006800, + 0x0401ff0f, 0x41785800, 0x42006000, 0x0000001e, + 0x42006800, 0x00000014, 0x0401ff03, 0x0401ff0e, + 0x40400000, 0x82000500, 0x0000ffbf, 0x4c000000, + 0x41785800, 0x42006000, 0x0000001e, 0x42006800, + 0x00000014, 0x0401fef8, 0x5c000000, 0x40006800, + 0x0401fefb, 0x4a038886, 0x00002020, 0x0401f04c, + 0x480bc857, 0x82080580, 0x00010000, 0x04020007, + 0x82040d40, 0x00010000, 0x42001800, 0x00000001, + 0x0401f82d, 0x0401f00f, 0x82080580, 0x00008000, + 0x04000007, 0x82040d40, 0x00000000, 0x42001800, + 0x00900001, 0x0401f824, 0x0401f006, 0x82040d40, + 0x00008000, 0x42001800, 0x00100001, 0x0401f81e, + 0x1c01f000, 0x480bc857, 0x82080580, 0x00010000, + 0x04020008, 0x42001800, 0x000000a1, 0x0401f816, + 0x42001800, 0x000000c1, 0x0401f813, 0x0401f011, + 0x82080580, 0x00008000, 0x04000008, 0x42001800, + 0x000400a1, 0x0401f80c, 0x42001800, 0x002000c1, + 0x0401f809, 0x0401f007, 0x42001800, 0x000400a1, + 0x0401f805, 0x42001800, 0x000000c1, 0x0401f802, + 0x1c01f000, 0x480fc857, 0x41785800, 0x42006000, + 0x0000001e, 0x41786800, 0x0401feb7, 0x400c6800, + 0x80346960, 0x0401feba, 0x42006800, 0x00000001, + 0x0401feb1, 0x400c6800, 0x0401feb5, 0x42006800, + 0x00000003, 0x0401feac, 0x0401feb7, 0x40400000, + 0x8c000504, 0x040207fc, 0x1c01f000, 0x42000000, + 0x00000064, 0x80000040, 0x040207ff, 0x1c01f000, + 0x4c5c0000, 0x4c600000, 0x4178b800, 0x0201f800, + 0x0010473b, 0x040200fd, 0x59a8c026, 0x0201f800, + 0x00104e0d, 0x04000003, 0x8c60c506, 0x0400000e, + 0x8c60c500, 0x04020004, 0x8c60c50e, 0x040008f6, + 0x0401f0f2, 0x0401faaf, 0x040200f0, 0x0201f800, + 0x00104e0d, 0x04020004, 0x4a03501c, 0x0000ffff, + 0x0401f0ea, 0x8c60c504, 0x04000004, 0x4a03501c, + 0x0000ffff, 0x0401f0e5, 0x59a8c010, 0x8260c500, + 0x000000ff, 0x59a81013, 0x8c081500, 0x0400005d, + 0x8c081502, 0x0402005b, 0x59a8b81c, 0x825c0d80, + 0x0000ffff, 0x04020003, 0x4200b800, 0x00000001, + 0x805c1104, 0x82086400, 0x0010bc20, 0x50300800, + 0x825c0500, 0x00000003, 0x0c01f001, 0x00101c2c, + 0x00101c27, 0x00101c2b, 0x00101c29, 0x80040910, + 0x0401f004, 0x80040930, 0x0401f002, 0x80040920, + 0x82040500, 0x000000ff, 0x82000d80, 0x000000ff, + 0x0400000f, 0x4c000000, 0x82000400, 0x00101eb5, + 0x50000800, 0x80040910, 0x82040580, 0x00000080, + 0x5c000000, 0x04000030, 0x80600d80, 0x0400002e, + 0x80000540, 0x0400002c, 0x0401f00b, 0x59a81005, + 0x82081500, 0x00000003, 0x0402002b, 0x59a81013, + 0x84081542, 0x480b5013, 0x4a03501c, 0x0000ffff, + 0x0401f028, 0x4c000000, 0x59a8006f, 0x8c000502, + 0x42001000, 0x00000010, 0x02020800, 0x00104ada, + 0x5c000000, 0x0402001c, 0x417a8800, 0x0201f800, + 0x001059b9, 0x04020016, 0x0201f800, 0x0010443b, + 0x04000006, 0x0201f800, 0x00104acf, 0x0401f8b1, + 0x0400000f, 0x0401f00c, 0x599c0019, 0x8c00050e, + 0x04020009, 0x0201f800, 0x001043fc, 0x04020008, + 0x0201f800, 0x00104acf, 0x0401f9dd, 0x0401f8be, + 0x04000003, 0x805cb800, 0x0401f7b2, 0x485f501c, + 0x0401f086, 0x4a03501c, 0x0000ffff, 0x0401f083, + 0x42003000, 0x0000007e, 0x59a8001c, 0x82001580, + 0x0000ffff, 0x04020005, 0x80000d80, 0x4018b000, + 0x4803c856, 0x0401f009, 0x8018b480, 0x04001004, + 0x40000800, 0x4803c856, 0x0401f004, 0x4a03501c, + 0x0000ffff, 0x0401f071, 0x4c040000, 0x4c580000, + 0x82040400, 0x00101eb5, 0x50000000, 0x82000500, + 0x000000ff, 0x80604580, 0x0400005c, 0x0201f800, + 0x001059ba, 0x04020061, 0x59a8006f, 0x8c000502, + 0x42001000, 0x00000010, 0x02020800, 0x00104ada, + 0x5c00b000, 0x5c000800, 0x040207d7, 0x4c040000, + 0x4c580000, 0x845cbd00, 0x0201f800, 0x00020267, + 0x04000008, 0x599c0019, 0x8c00050e, 0x04020047, + 0x0201f800, 0x00104401, 0x0402004c, 0x0401f002, + 0x845cbd40, 0x0201f800, 0x00104acf, 0x0201f800, + 0x00104836, 0x04020007, 0x59a80005, 0x8c000502, + 0x04000033, 0x59340200, 0x8c00050e, 0x04020030, + 0x59a81013, 0x8c081502, 0x04000025, 0x0201f800, + 0x00104858, 0x04000031, 0x8c5cbd00, 0x04020004, + 0x0201f800, 0x00104455, 0x0401f02c, 0x0401f9c8, + 0x0400002a, 0x42026000, 0x0010bbe8, 0x49366009, + 0x497a6008, 0x417a7800, 0x0401f920, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x0010393e, 0x0400001d, 0x41782800, 0x42003000, + 0x00000008, 0x4d400000, 0x4d440000, 0x59368c03, + 0x42028000, 0x00000029, 0x0201f800, 0x0010a258, + 0x5c028800, 0x5c028000, 0x0401f010, 0x4937c857, + 0x599c0019, 0x8c00050e, 0x0402000c, 0x0401f968, + 0x0401f849, 0x04000011, 0x0401f008, 0x59a80013, + 0x8c000500, 0x04000003, 0x0401f9a1, 0x04000003, + 0x0401f828, 0x04000009, 0x5c00b000, 0x5c000800, + 0x80040800, 0x8058b040, 0x04020798, 0x4a03501c, + 0x0000ffff, 0x0401f005, 0x4937c857, 0x5c00b000, + 0x5c000800, 0x4807501c, 0x5c00c000, 0x5c00b800, + 0x1c01f000, 0x4803c856, 0x4a03501c, 0x00000001, + 0x42028800, 0x000007fe, 0x42003000, 0x00fffffe, + 0x0201f800, 0x001043fc, 0x0402000c, 0x0401f944, + 0x0401f825, 0x04000009, 0x59a80026, 0x8400054e, + 0x48035026, 0x0201f800, 0x001090d5, 0x82000540, + 0x00000001, 0x1c01f000, 0x80000580, 0x0401f7fe, + 0x4937c857, 0x0201f800, 0x001076c9, 0x04000015, + 0x49366009, 0x4a026406, 0x00000001, 0x417a7800, + 0x0201f800, 0x001043bd, 0x59a8001b, 0x80000000, + 0x4803501b, 0x42027000, 0x00000004, 0x599c0019, + 0x8c00050e, 0x04000003, 0x42027000, 0x00000000, + 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, + 0x1c01f000, 0x4937c857, 0x0201f800, 0x001076c9, + 0x0400001c, 0x49366009, 0x59340403, 0x82000580, + 0x000007fe, 0x04000005, 0x4d3c0000, 0x417a7800, + 0x0401f8b2, 0x5c027800, 0x4a026406, 0x00000001, + 0x417a7800, 0x0201f800, 0x001043bd, 0x42000800, + 0x00000003, 0x0201f800, 0x001043c7, 0x59a8001b, + 0x80000000, 0x4803501b, 0x42027000, 0x00000002, + 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, + 0x1c01f000, 0x4803c856, 0x42028800, 0x000007fc, + 0x42003000, 0x00fffffc, 0x0201f800, 0x001043fc, + 0x04020005, 0x0401f805, 0x04000003, 0x4a035027, + 0x0000ffff, 0x1c01f000, 0x4937c857, 0x0201f800, + 0x001076c9, 0x04000014, 0x49366009, 0x4a026406, + 0x00000001, 0x417a7800, 0x0201f800, 0x001043bd, + 0x42000800, 0x00000003, 0x0201f800, 0x001043c7, + 0x59a80028, 0x80000000, 0x48035028, 0x42027000, + 0x00000002, 0x0201f800, 0x000208d8, 0x82000540, + 0x00000001, 0x1c01f000, 0x480bc857, 0x492fc857, + 0x4c5c0000, 0x4008b800, 0x42028800, 0x000007fd, + 0x42003000, 0x00fffffd, 0x0201f800, 0x001043fc, + 0x0402001a, 0x0201f800, 0x00020892, 0x04000017, + 0x49366009, 0x5934000a, 0x84000544, 0x4802680a, + 0x812e59c0, 0x04000005, 0x592c0404, 0x8c00051e, + 0x04000002, 0x48ee6021, 0x492e6008, 0x4a026406, + 0x00000001, 0x485e601c, 0x42027000, 0x00000022, + 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, + 0x5c00b800, 0x1c01f000, 0x80000580, 0x0401f7fd, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4943c857, + 0x493fc857, 0x4d340000, 0x4d440000, 0x4c580000, + 0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x0010698c, + 0x4df00000, 0x0201f800, 0x0010673a, 0x0201f800, + 0x001067ee, 0x0201f800, 0x0010647f, 0x0201f800, + 0x0010822b, 0x5c03e000, 0x02000800, 0x00106982, + 0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800, + 0x00020267, 0x0402001a, 0x8d3e7d06, 0x04000004, + 0x59340200, 0x8c00050e, 0x04020015, 0x8d3e7d18, + 0x04000010, 0x5934b80f, 0x805cb9c0, 0x04000009, + 0x49425a06, 0x592cb800, 0x0201f800, 0x00020381, + 0x805cb9c0, 0x040207fb, 0x497a680f, 0x497a6810, + 0x4937c857, 0x4a026c00, 0x00000707, 0x0401f004, + 0x4937c857, 0x0201f800, 0x001040e4, 0x81468800, + 0x8058b040, 0x040207e2, 0x8d3e7d02, 0x04000011, + 0x497b501d, 0x42028800, 0x000007f0, 0x4200b000, + 0x00000010, 0x0201f800, 0x00020267, 0x04020006, + 0x4937c857, 0x4a026c00, 0x00000707, 0x0201f800, + 0x001040e4, 0x81468800, 0x8058b040, 0x040207f6, + 0x5c00b800, 0x5c025800, 0x5c00b000, 0x5c028800, + 0x5c026800, 0x1c01f000, 0x5c000000, 0x4c000000, + 0x4803c857, 0x4933c857, 0x493fc857, 0x4d340000, + 0x4d400000, 0x4d440000, 0x4d2c0000, 0x4c5c0000, + 0x0201f800, 0x0010698c, 0x4df00000, 0x59326809, + 0x813669c0, 0x04000021, 0x59368c03, 0x42028000, + 0x00000029, 0x0201f800, 0x0010679b, 0x0201f800, + 0x001067f6, 0x0201f800, 0x00106543, 0x0201f800, + 0x0010a0da, 0x4937c857, 0x8d3e7d18, 0x04000011, + 0x5934b80f, 0x805cb9c0, 0x0400000a, 0x405e5800, + 0x49425a06, 0x592cb800, 0x0201f800, 0x00020381, + 0x805cb9c0, 0x040207fa, 0x497a680f, 0x497a6810, + 0x4937c857, 0x4a026c00, 0x00000707, 0x0401f003, + 0x0201f800, 0x001040e4, 0x5c03e000, 0x02000800, + 0x00106982, 0x5c00b800, 0x5c025800, 0x5c028800, + 0x5c028000, 0x5c026800, 0x1c01f000, 0x4933c857, + 0x59a80026, 0x8c000508, 0x04020012, 0x59305009, + 0x482bc857, 0x836c0580, 0x00000002, 0x0402000d, + 0x0401f813, 0x0402000b, 0x58280403, 0x82000580, + 0x000007fc, 0x04000008, 0x59a8001b, 0x80000040, + 0x4803c857, 0x02001800, 0x00100615, 0x4803501b, + 0x1c01f000, 0x59a80028, 0x80000040, 0x4803c857, + 0x040017fc, 0x48035028, 0x1c01f000, 0x59300008, + 0x800001c0, 0x04020009, 0x59300403, 0x82000580, + 0x00000001, 0x04020004, 0x82000540, 0x00000001, + 0x0401f002, 0x80000580, 0x1c01f000, 0x4937c857, + 0x59340200, 0x84000502, 0x48026a00, 0x1c01f000, + 0x4933c857, 0x493fc857, 0x4947c857, 0x4d400000, + 0x4d340000, 0x4d440000, 0x4c580000, 0x0201f800, + 0x0010698c, 0x4df00000, 0x8060c1c0, 0x04020004, + 0x4200b000, 0x00000001, 0x0401f004, 0x4200b000, + 0x000007f0, 0x417a8800, 0x41440000, 0x81ac0400, + 0x50000000, 0x80026d40, 0x0400001a, 0x4d3c0000, + 0x42027800, 0x00000001, 0x0201f800, 0x00104745, + 0x5c027800, 0x42028000, 0x00000029, 0x0201f800, + 0x0010679b, 0x0201f800, 0x001067f6, 0x0201f800, + 0x00106543, 0x0201f800, 0x00104836, 0x04020005, + 0x4937c857, 0x4a026c00, 0x00000404, 0x0401f003, + 0x0201f800, 0x00104863, 0x0201f800, 0x0010a0da, + 0x81468800, 0x8058b040, 0x040207e0, 0x5c03e000, + 0x02000800, 0x00106982, 0x5c00b000, 0x5c028800, + 0x5c026800, 0x5c028000, 0x1c01f000, 0x4937c857, + 0x4947c857, 0x4c5c0000, 0x4c600000, 0x4c640000, + 0x59a80013, 0x8c000500, 0x0400001f, 0x599c0017, + 0x8c00050a, 0x0402001c, 0x5934ba02, 0x825cbd00, + 0x000000ff, 0x485fc857, 0x4178c000, 0x4178c800, + 0x82600400, 0x0010bc20, 0x50002000, 0x8060c1c0, + 0x04000008, 0x82100500, 0x000000ff, 0x82002d80, + 0x000000ff, 0x0400000c, 0x805c0580, 0x0400000d, + 0x80102110, 0x8064c800, 0x82640580, 0x00000004, + 0x040207f5, 0x8060c000, 0x82600580, 0x00000020, + 0x040207eb, 0x4813c857, 0x82000540, 0x00000001, + 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x59a80026, 0x8c000512, 0x02020800, 0x001006ba, + 0x1c01f000, 0x00007eef, 0x00007de8, 0x00007ce4, + 0x000080e2, 0x00007be1, 0x000080e0, 0x000080dc, + 0x000080da, 0x00007ad9, 0x000080d6, 0x000080d5, + 0x000080d4, 0x000080d3, 0x000080d2, 0x000080d1, + 0x000079ce, 0x000078cd, 0x000080cc, 0x000080cb, + 0x000080ca, 0x000080c9, 0x000080c7, 0x000080c6, + 0x000077c5, 0x000076c3, 0x000080bc, 0x000080ba, + 0x000075b9, 0x000080b6, 0x000074b5, 0x000073b4, + 0x000072b3, 0x000080b2, 0x000080b1, 0x000080ae, + 0x000071ad, 0x000080ac, 0x000070ab, 0x00006faa, + 0x00006ea9, 0x000080a7, 0x00006da6, 0x00006ca5, + 0x00006ba3, 0x00006a9f, 0x0000699e, 0x0000689d, + 0x0000809b, 0x00008098, 0x00006797, 0x00006690, + 0x0000658f, 0x00006488, 0x00006384, 0x00006282, + 0x00008081, 0x00008080, 0x0000617c, 0x0000607a, + 0x00008079, 0x00005f76, 0x00008075, 0x00008074, + 0x00008073, 0x00008072, 0x00008071, 0x0000806e, + 0x00005e6d, 0x0000806c, 0x00005d6b, 0x00005c6a, + 0x00005b69, 0x00008067, 0x00005a66, 0x00005965, + 0x00005863, 0x0000575c, 0x0000565a, 0x00005559, + 0x00008056, 0x00008055, 0x00005454, 0x00005353, + 0x00005252, 0x00005151, 0x0000504e, 0x00004f4d, + 0x0000804c, 0x0000804b, 0x00004e4a, 0x00004d49, + 0x00008047, 0x00004c46, 0x00008045, 0x00008043, + 0x0000803c, 0x0000803a, 0x00008039, 0x00008036, + 0x00004b35, 0x00008034, 0x00004a33, 0x00004932, + 0x00004831, 0x0000802e, 0x0000472d, 0x0000462c, + 0x0000452b, 0x0000442a, 0x00004329, 0x00004227, + 0x00008026, 0x00008025, 0x00004123, 0x0000401f, + 0x00003f1e, 0x00003e1d, 0x00003d1b, 0x00003c18, + 0x00008017, 0x00008010, 0x00003b0f, 0x00003a08, + 0x00008004, 0x00003902, 0x00008001, 0x00008000, + 0x00008000, 0x00003800, 0x00003700, 0x00003600, + 0x00008000, 0x00003500, 0x00008000, 0x00008000, + 0x00008000, 0x00003400, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00003300, 0x00003200, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00003100, 0x00003000, 0x00008000, 0x00008000, + 0x00002f00, 0x00008000, 0x00002e00, 0x00002d00, + 0x00002c00, 0x00008000, 0x00008000, 0x00008000, + 0x00002b00, 0x00008000, 0x00002a00, 0x00002900, + 0x00002800, 0x00008000, 0x00002700, 0x00002600, + 0x00002500, 0x00002400, 0x00002300, 0x00002200, + 0x00008000, 0x00008000, 0x00002100, 0x00002000, + 0x00001f00, 0x00001e00, 0x00001d00, 0x00001c00, + 0x00008000, 0x00008000, 0x00001b00, 0x00001a00, + 0x00008000, 0x00001900, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00001800, 0x00008000, 0x00001700, 0x00001600, + 0x00001500, 0x00008000, 0x00001400, 0x00001300, + 0x00001200, 0x00001100, 0x00001000, 0x00000f00, + 0x00008000, 0x00008000, 0x00000e00, 0x00000d00, + 0x00000c00, 0x00000b00, 0x00000a00, 0x00000900, + 0x00008000, 0x00008000, 0x00000800, 0x00000700, + 0x00008000, 0x00000600, 0x00008000, 0x00008000, + 0x00008000, 0x00000500, 0x00000400, 0x00000300, + 0x00008000, 0x00000200, 0x00008000, 0x00008000, + 0x00008000, 0x00000100, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00000000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x00008000, 0x00008000, 0x00008000, + 0x00008000, 0x0201f800, 0x00100819, 0x02000800, + 0x00100615, 0x492f4016, 0x1c01f000, 0x83a0ac00, + 0x00000006, 0x83a00580, 0x0010b2a0, 0x0400000c, + 0x492fc857, 0x812e59c0, 0x02000800, 0x00100615, + 0x832ca400, 0x00000006, 0x4200b000, 0x0000000d, + 0x0201f800, 0x0010a93e, 0x0401f00f, 0x4200b000, + 0x00000010, 0x83e0a400, 0x00000020, 0x50500000, + 0x8050a000, 0x50500800, 0x900409c0, 0x80040540, + 0x4400a800, 0x8050a000, 0x8054a800, 0x8058b040, + 0x040207f7, 0x1c01f000, 0x59a00206, 0x82000c80, + 0x0000007f, 0x040210c9, 0x59a80821, 0x0c01f001, + 0x00102066, 0x001020a6, 0x001020a6, 0x001020f0, + 0x00102112, 0x001020a6, 0x00102066, 0x00102134, + 0x00102145, 0x001020a6, 0x001020a6, 0x00102152, + 0x0010216a, 0x00102182, 0x001020a6, 0x001021b1, + 0x001021e3, 0x001020a6, 0x0010220c, 0x001020a6, + 0x00102269, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001020a6, 0x00102280, 0x001022b9, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001022ee, 0x001020a6, 0x00102340, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x00102345, + 0x001023be, 0x001020a6, 0x001023c5, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001023c7, 0x00102445, 0x00102585, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x00102594, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001025b1, 0x00102604, 0x00102660, 0x00102674, + 0x00102696, 0x001028d1, 0x00102c60, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001020a6, 0x001020a6, 0x001020a6, 0x00102d9f, + 0x00102e13, 0x001020a6, 0x001020a6, 0x00102e81, + 0x001020a6, 0x00102f1f, 0x00102fd1, 0x001020a6, + 0x001020a6, 0x00103008, 0x00103064, 0x001020a6, + 0x001030bc, 0x00103220, 0x001020a6, 0x00103234, + 0x001032bf, 0x001020a6, 0x001020a6, 0x001020a6, + 0x001020a6, 0x0010332f, 0x00103333, 0x00103352, + 0x001020a6, 0x001033f4, 0x001020a6, 0x001020a6, + 0x00103421, 0x001020a6, 0x0010344f, 0x001020a6, + 0x001020a6, 0x001034b6, 0x001035c3, 0x00103620, + 0x001020a6, 0x00103686, 0x001020a6, 0x001020a6, + 0x001036db, 0x0010373e, 0x001020a6, 0x48efc857, + 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, + 0x00000200, 0x04000045, 0x48efc857, 0x4a034206, + 0x00004000, 0x0201f800, 0x0010382f, 0x83a00580, + 0x0010b2a0, 0x0400000d, 0x58ee580a, 0x4d2c0000, + 0x0401f856, 0x41a25800, 0x0201f800, 0x0010083a, + 0x40ee5800, 0x0201f800, 0x0010083a, 0x5c025800, + 0x0201f000, 0x00020381, 0x04026007, 0x59a0001d, + 0x84000542, 0x4803401d, 0x4a01d809, 0x0010207a, + 0x1c01f000, 0x59a00206, 0x82000d80, 0x00004000, + 0x04000006, 0x900001c0, 0x82000540, 0x00000011, + 0x4803c011, 0x0401f005, 0x900001c0, 0x82000540, + 0x00000010, 0x4803c011, 0x0401f844, 0x59e00017, + 0x8c000508, 0x0402000c, 0x4203e000, 0x30000001, + 0x4203e000, 0x40000000, 0x40ee5800, 0x0201f800, + 0x0010083a, 0x59a0001d, 0x84000504, 0x4803401d, + 0x1c01f000, 0x4a03c017, 0x00000000, 0x59a00206, + 0x82000d80, 0x00004000, 0x040007f0, 0x4a03c017, + 0x00000001, 0x0401f7ed, 0x4803c856, 0x4a034206, + 0x00004001, 0x0401f7c0, 0x4803c856, 0x4a034206, + 0x00004002, 0x0401f7bc, 0x4803c856, 0x4a034206, + 0x00004003, 0x0401f7b8, 0x4803c856, 0x4a034206, + 0x00004005, 0x0401f7b4, 0x4803c856, 0x4a034206, + 0x00004006, 0x0401f7b0, 0x4803c856, 0x4a034206, + 0x0000400b, 0x0401f7ac, 0x4803c856, 0x4a034206, + 0x0000400c, 0x0401f7a8, 0x4803c856, 0x4a034206, + 0x0000400c, 0x0401f7a4, 0x58eca80a, 0x8054a9c0, + 0x02000800, 0x00100615, 0x83a0a400, 0x00000006, + 0x8254ac00, 0x00000006, 0x4200b000, 0x0000000d, + 0x0201f000, 0x0010a93e, 0x59a00206, 0x4803c857, + 0x59a00406, 0x4803c857, 0x59a00207, 0x4803c857, + 0x59a00407, 0x4803c857, 0x59a00208, 0x4803c857, + 0x59a00408, 0x4803c857, 0x59a00209, 0x4803c857, + 0x83e0ac00, 0x00000020, 0x83a0a400, 0x00000006, + 0x4200b000, 0x00000010, 0x50500000, 0x4400a800, + 0x8054a800, 0x900001c0, 0x4400a800, 0x8054a800, + 0x8050a000, 0x8058b040, 0x040207f8, 0x1c01f000, + 0x59a00406, 0x800000c2, 0x59a00a07, 0x900409c0, + 0x80040540, 0x84000540, 0x59a00c07, 0x8c040d00, + 0x04000018, 0x59a8086f, 0x8c040d00, 0x040207bb, + 0x42000800, 0x00000064, 0x80040840, 0x04000007, + 0x4a030000, 0x00000001, 0x40000000, 0x59801000, + 0x8c081500, 0x040007f9, 0x04000005, 0x48030004, + 0x4a030000, 0x00000000, 0x0401f75c, 0x4a030000, + 0x00000000, 0x4a034406, 0x00000004, 0x040007a3, + 0x4803880e, 0x0401f755, 0x59a00406, 0x800000c2, + 0x59a00c07, 0x8c040d00, 0x0400001a, 0x59a8086f, + 0x8c040d00, 0x0402079d, 0x42000800, 0x00000064, + 0x80040840, 0x04000007, 0x4a030000, 0x00000001, + 0x40000000, 0x59801000, 0x8c081500, 0x040007f9, + 0x04000007, 0x48030004, 0x59800805, 0x48074406, + 0x4a030000, 0x00000000, 0x0401f73c, 0x4a030000, + 0x00000000, 0x4a034406, 0x00000004, 0x04000783, + 0x4803880e, 0x59c4080f, 0x48074406, 0x0401f733, + 0x59a01c06, 0x59a00207, 0x900c19c0, 0x800c1d40, + 0x580c0803, 0x80000580, 0x500c1000, 0x80080400, + 0x800c1800, 0x80040840, 0x040207fc, 0x48034406, + 0x900001c0, 0x48034207, 0x800001c0, 0x04000723, + 0x0401f76a, 0x4a034406, 0x00000004, 0x4a034207, + 0x00000000, 0x4a034407, 0x00000012, 0x59a8000d, + 0x48034208, 0x900001c0, 0x48034408, 0x4a034209, + 0x00000002, 0x0401f715, 0x59a00407, 0x59a01207, + 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, + 0x900c19c0, 0x800c1d40, 0x59a00a08, 0x59a00408, + 0x900409c0, 0x80040d40, 0x59a0020a, 0x82002480, + 0x00000010, 0x04001755, 0x59a02406, 0x900001c0, + 0x80100540, 0x59a8280d, 0x80142480, 0x0400174f, + 0x0201f000, 0x0010383e, 0x59a00407, 0x59a01207, + 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, + 0x900c19c0, 0x800c1d40, 0x59a00a08, 0x59a00408, + 0x900409c0, 0x80040d40, 0x59a0020a, 0x82002480, + 0x00000010, 0x0400173d, 0x59a02406, 0x900001c0, + 0x80100540, 0x59a8280d, 0x80142480, 0x04001737, + 0x0201f000, 0x00103841, 0x59a02407, 0x59a00207, + 0x901021c0, 0x80102540, 0x59a01a0a, 0x59a00406, + 0x900c19c0, 0x800c1d40, 0x41781000, 0x42000000, + 0x00001000, 0x50000000, 0x82000480, 0x24320001, + 0x04001016, 0x820c0580, 0x00007c00, 0x04000013, + 0x820c0480, 0x00007a00, 0x04001010, 0x820c0480, + 0x00007cff, 0x0402100d, 0x42000800, 0x00000064, + 0x80040840, 0x04000007, 0x4a030000, 0x00000001, + 0x40000000, 0x59800000, 0x8c000500, 0x040007f9, + 0x04000008, 0x80081000, 0x44101800, 0x800811c0, + 0x040006be, 0x4a030000, 0x00000000, 0x0401f6bb, + 0x4a030000, 0x00000000, 0x4a034406, 0x00000004, + 0x0401f702, 0x59a01a0a, 0x59a00406, 0x900c19c0, + 0x800c1d40, 0x41781000, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24320001, 0x04001016, + 0x820c0580, 0x00007c00, 0x04000013, 0x820c0480, + 0x00007a00, 0x04001010, 0x820c0480, 0x00007cff, + 0x0402100d, 0x42000800, 0x00000064, 0x80040840, + 0x04000007, 0x4a030000, 0x00000001, 0x40000000, + 0x59800000, 0x8c000500, 0x040007f9, 0x0400000f, + 0x80081000, 0x500c0000, 0x82000d00, 0x0000ffff, + 0x48074207, 0x82000d00, 0xffff0000, 0x900409c0, + 0x48074407, 0x800811c0, 0x0400068c, 0x4a030000, + 0x00000000, 0x0401f689, 0x4a030000, 0x00000000, + 0x4a034406, 0x00000004, 0x0401f6d0, 0x59a00406, + 0x8c000500, 0x04000020, 0x59a01207, 0x59a01c07, + 0x59a02208, 0x480b5054, 0x480f5055, 0x48135056, + 0x59c40801, 0x82040d00, 0x00018000, 0x82040580, + 0x00000000, 0x04000009, 0x82040580, 0x00008000, + 0x04000008, 0x82040580, 0x00010000, 0x04000007, + 0x0201f800, 0x00100615, 0x40080000, 0x0401f004, + 0x400c0000, 0x0401f002, 0x40100000, 0x80000110, + 0x42000800, 0x000000e0, 0x0201f800, 0x001019b1, + 0x0401f007, 0x59a81054, 0x59a81855, 0x59a82056, + 0x480b4207, 0x480f4407, 0x48134208, 0x0401f65b, + 0x4d2c0000, 0x4d340000, 0x4d300000, 0x4d440000, + 0x59a28c06, 0x0201f800, 0x00020267, 0x04000006, + 0x5c028800, 0x5c026000, 0x5c026800, 0x5c025800, + 0x0401f69e, 0x59a04407, 0x59a00207, 0x900001c0, + 0x80204540, 0x0401f81e, 0x04000009, 0x4a034208, + 0x00000001, 0x4a034406, 0x0000ffff, 0x4a034207, + 0x0000ffff, 0x497b4407, 0x0401f00b, 0x0401f822, + 0x0400000e, 0x4a034208, 0x00000002, 0x59300402, + 0x48034406, 0x59300202, 0x48034207, 0x59300206, + 0x48034407, 0x5c028800, 0x5c026000, 0x5c026800, + 0x5c025800, 0x0401f631, 0x5c028800, 0x5c026000, + 0x5c026800, 0x5c025800, 0x0401f678, 0x4937c856, + 0x4823c856, 0x4d2c0000, 0x5934000f, 0x80025d40, + 0x04000007, 0x592c0005, 0x80200580, 0x592c0000, + 0x040207fb, 0x82000540, 0x00000001, 0x5c025800, + 0x1c01f000, 0x4823c857, 0x4d2c0000, 0x4d300000, + 0x42026000, 0x0010cfc0, 0x59300406, 0x82000d80, + 0x00000003, 0x04000004, 0x82000d80, 0x00000006, + 0x04020007, 0x59325808, 0x812e59c0, 0x04000004, + 0x592c0005, 0x80200580, 0x0400000a, 0x83326400, + 0x00000024, 0x41580000, 0x81300480, 0x040017ef, + 0x80000580, 0x5c026000, 0x5c025800, 0x1c01f000, + 0x82000540, 0x00000001, 0x5c026000, 0x5c025800, + 0x1c01f000, 0x83a00580, 0x0010b2a0, 0x0402063b, + 0x59a8006f, 0x8c000500, 0x04020003, 0x4a030000, + 0x00000000, 0x4a034206, 0x00004000, 0x4a03c011, + 0x40000010, 0x0401fe5d, 0x59e00017, 0x8c000508, + 0x04000003, 0x4a03c017, 0x00000000, 0x4203e000, + 0x30000001, 0x4203e000, 0x40000000, 0x0401f000, + 0x59a00c06, 0x800409c0, 0x04000007, 0x836c0580, + 0x00000000, 0x04000004, 0x4a034406, 0x0000001a, + 0x0401f62a, 0x42007000, 0x0010b33f, 0x58381c01, + 0x58382202, 0x8c040d00, 0x0400000b, 0x59a01207, + 0x82080500, 0x0000f003, 0x04020624, 0x82080480, + 0x00000841, 0x04021621, 0x82080480, 0x00000100, + 0x0400161e, 0x8c040d06, 0x04000003, 0x4a0378e4, + 0x000c0000, 0x8c040d04, 0x0400000c, 0x42000000, + 0x00001000, 0x50000000, 0x82000480, 0x24220001, + 0x04020003, 0x84040d04, 0x0401f004, 0x59e00002, + 0x84000548, 0x4803c002, 0x8c040d02, 0x04000005, + 0x42002800, 0x00007600, 0x4a002805, 0xd0000000, + 0x40040000, 0x800c0540, 0x48007401, 0x8c040d00, + 0x04000002, 0x48087202, 0x480f4406, 0x48134207, + 0x0401f5ae, 0x4d440000, 0x4d340000, 0x59a28c06, + 0x0201f800, 0x00020267, 0x04020009, 0x0201f800, + 0x00104842, 0x04000009, 0x4a034406, 0x00000009, + 0x5c026800, 0x5c028800, 0x0401f5ec, 0x5c026800, + 0x5c028800, 0x0401f5ed, 0x59a01207, 0x59a01c07, + 0x5934400a, 0x82203d00, 0x0000e000, 0x801c391a, + 0x8c081500, 0x04000019, 0x820c0d00, 0x00000007, + 0x82040580, 0x00000000, 0x04000007, 0x82040580, + 0x00000001, 0x04000004, 0x82040580, 0x00000003, + 0x040207eb, 0x82204500, 0xffff1fff, 0x800400da, + 0x80200540, 0x4802680a, 0x4c1c0000, 0x0201f800, + 0x0010698c, 0x0201f800, 0x00104afd, 0x0201f800, + 0x00106982, 0x5c003800, 0x481f4407, 0x5c026800, + 0x5c028800, 0x0401f579, 0x800409c0, 0x04000004, + 0x4a034406, 0x00000001, 0x0401f5c0, 0x836c0580, + 0x00000003, 0x04020010, 0x59a80010, 0x497b4406, + 0x0201f800, 0x00104e0d, 0x0400000f, 0x82000d00, + 0x00ffff00, 0x0402000c, 0x82000c00, 0x00101eb5, + 0x50040800, 0x80040910, 0x82041580, 0x00000080, + 0x04020004, 0x4a034406, 0x00000007, 0x0401f5ab, + 0x48074406, 0x82000d00, 0x0000ffff, 0x48074207, + 0x80000120, 0x48034407, 0x59a80026, 0x82001500, + 0x00000100, 0x480b4409, 0x8c000502, 0x0400001f, + 0x8c000506, 0x04000009, 0x82000d00, 0x0000000a, + 0x82040d80, 0x0000000a, 0x04020004, 0x4a034209, + 0x00000001, 0x0401f022, 0x8c00050a, 0x04000009, + 0x82000d00, 0x00000022, 0x82040d80, 0x00000022, + 0x04020004, 0x4a034209, 0x00000003, 0x0401f018, + 0x8c000508, 0x04000009, 0x82000d00, 0x00000012, + 0x82040d80, 0x00000012, 0x04020004, 0x4a034209, + 0x00000002, 0x0401f00e, 0x0201f800, 0x00104e0d, + 0x04020004, 0x4a034209, 0x00000004, 0x0401f52f, + 0x8c000506, 0x04000004, 0x4a034406, 0x00000005, + 0x0401f576, 0x4a034209, 0x00000000, 0x0401f527, + 0x59a80037, 0x48034407, 0x59a80038, 0x48034209, + 0x0401f522, 0x42007800, 0x0010b6eb, 0x59a00406, + 0x4803c857, 0x82000c80, 0x00000007, 0x0402156b, + 0x0c01f001, 0x00102354, 0x00102355, 0x00102363, + 0x00102376, 0x00102397, 0x00102354, 0x00102354, + 0x0401f562, 0x836c0580, 0x00000000, 0x0400055b, + 0x59a00a07, 0x59a00407, 0x900001c0, 0x80040d40, + 0x4807c857, 0x59a00a08, 0x59a00408, 0x900001c0, + 0x80040d40, 0x4807c857, 0x0401f056, 0x836c0580, + 0x00000000, 0x0400054d, 0x59a00407, 0x59a01207, + 0x900001c0, 0x80081540, 0x59a00408, 0x59a01a08, + 0x900001c0, 0x800c1d40, 0x42000000, 0x0010bfbe, + 0x480fc857, 0x480bc857, 0x42000800, 0x00001000, + 0x0201f000, 0x00103841, 0x59a00a07, 0x59a00407, + 0x900001c0, 0x80041d40, 0x820c0c80, 0x0010a971, + 0x0402153a, 0x820c0c80, 0x00100000, 0x04001537, + 0x480fc857, 0x823c7c00, 0x00000009, 0x503c0800, + 0x800409c0, 0x04000006, 0x823c0580, 0x0000000d, + 0x0400052e, 0x803c7800, 0x0401f7f9, 0x59e41001, + 0x82080d00, 0xfffeffcf, 0x4807c801, 0x440c7800, + 0x46001800, 0x0201f800, 0x800c1800, 0x46001800, + 0x00100608, 0x480bc801, 0x0401f022, 0x59a01a07, + 0x59a00407, 0x900001c0, 0x800c1d40, 0x480c7801, + 0x59a02208, 0x59a00408, 0x900001c0, 0x80102540, + 0x48107802, 0x59a00209, 0x80000040, 0x04001513, + 0x48007806, 0x80000000, 0x48007805, 0x42000800, + 0x00004000, 0x40001000, 0x0201f800, 0x001063cf, + 0x80000540, 0x04000003, 0x49787801, 0x0401f507, + 0x40040000, 0x800c1c00, 0x04001504, 0x480c7803, + 0x48107804, 0x49787808, 0x59a00409, 0x48007807, + 0x59e40001, 0x4803c857, 0x82000540, 0x00040000, + 0x4803c801, 0x0401f4a9, 0x59a80006, 0x48034406, + 0x59a80007, 0x48034207, 0x59a80008, 0x48034407, + 0x0401f4a2, 0x0201f800, 0x00100615, 0x4803c856, + 0x4a03c013, 0x03800300, 0x4a03c014, 0x03800380, + 0x59a00c06, 0x82040580, 0x000000a0, 0x04000004, + 0x82040580, 0x000000a2, 0x04020028, 0x59a0140a, + 0x82080480, 0x00000100, 0x04021024, 0x59a0020b, + 0x8c000500, 0x0402002b, 0x59a00a0a, 0x800409c0, + 0x0400001e, 0x82040480, 0x00000041, 0x0402101b, + 0x82040c00, 0x00000003, 0x82040d00, 0x000000fc, + 0x80040904, 0x59a00407, 0x59a01207, 0x900811c0, + 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, + 0x800c1d40, 0x0201f800, 0x0010381a, 0x04020006, + 0x4a034406, 0x00000002, 0x4a03c014, 0x03800000, + 0x0401f4be, 0x0201f800, 0x0010383e, 0x4a01d809, + 0x001023fd, 0x1c01f000, 0x4a03c014, 0x03800000, + 0x0401f4ba, 0x4031d800, 0x58ef400b, 0x58ee580d, + 0x58ec0002, 0x82000580, 0x00000200, 0x040004a7, + 0x59a00c06, 0x59a0140a, 0x59a0020b, 0x8c000500, + 0x04020031, 0x832e5c00, 0x00000004, 0x41783800, + 0x59a04a0a, 0x401c0000, 0x812c0400, 0x50004000, + 0x82201d00, 0x000000ff, 0x4c040000, 0x0401f8af, + 0x5c000800, 0x0400002d, 0x80244840, 0x04000028, + 0x80081000, 0x82201d00, 0x0000ff00, 0x800c1910, + 0x4c040000, 0x0401f8a5, 0x5c000800, 0x04000023, + 0x80244840, 0x0400001e, 0x80081000, 0x82201d00, + 0x00ff0000, 0x800c1920, 0x4c040000, 0x0401f89b, + 0x5c000800, 0x04000019, 0x80244840, 0x04000014, + 0x80081000, 0x82201d00, 0xff000000, 0x800c1930, + 0x4c040000, 0x0401f891, 0x5c000800, 0x0400000f, + 0x80244840, 0x0400000a, 0x80081000, 0x801c3800, + 0x0401f7d5, 0x59a0020a, 0x82000500, 0x000000ff, + 0x40001800, 0x0401f885, 0x04000004, 0x4a03c014, + 0x03800000, 0x0401f425, 0x4a03c014, 0x03800000, + 0x0401f46e, 0x4803c856, 0x4a03c013, 0x03800300, + 0x4a03c014, 0x03800380, 0x59a00c06, 0x82040580, + 0x000000a0, 0x04000004, 0x82040580, 0x000000a2, + 0x0402006e, 0x59a0140a, 0x82080480, 0x00000100, + 0x0402106a, 0x59a0020b, 0x8c000500, 0x0402005c, + 0x59a01a0a, 0x800c19c0, 0x04000064, 0x820c0480, + 0x00000041, 0x04021061, 0x0201f800, 0x0010381a, + 0x04020006, 0x4a034406, 0x00000002, 0x4a03c014, + 0x03800000, 0x0401f44d, 0x832e5c00, 0x00000004, + 0x41783800, 0x59a04a0a, 0x401c0000, 0x812c0400, + 0x40004000, 0x4c040000, 0x4c080000, 0x0401f877, + 0x5c001000, 0x5c000800, 0x04000048, 0x44144000, + 0x80244840, 0x0400002b, 0x80081000, 0x4c040000, + 0x4c080000, 0x0401f86d, 0x5c001000, 0x5c000800, + 0x0400003e, 0x50200000, 0x801428d0, 0x80140540, + 0x44004000, 0x80244840, 0x0400001e, 0x80081000, + 0x4c040000, 0x4c080000, 0x0401f860, 0x5c001000, + 0x5c000800, 0x04000031, 0x50200000, 0x801428e0, + 0x80140540, 0x44004000, 0x80244840, 0x04000011, + 0x80081000, 0x4c040000, 0x4c080000, 0x0401f853, + 0x5c001000, 0x5c000800, 0x04000024, 0x50200000, + 0x801428f0, 0x80140540, 0x44004000, 0x80244840, + 0x04000004, 0x80081000, 0x801c3800, 0x0401f7cb, + 0x59a00a0a, 0x82040c00, 0x00000003, 0x82040d00, + 0x000000fc, 0x80040904, 0x59a00407, 0x59a01207, + 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, + 0x900c19c0, 0x800c1d40, 0x4a03c014, 0x03800000, + 0x412c0000, 0x0201f000, 0x00103841, 0x0401f833, + 0x04000006, 0x48174406, 0x4a03c014, 0x03800000, + 0x0201f000, 0x00102066, 0x4a03c014, 0x03800000, + 0x0201f000, 0x001020b2, 0x4a03c014, 0x03800000, + 0x0201f000, 0x001020b6, 0x0401f836, 0x04000010, + 0x0401f862, 0x0402000f, 0x40080800, 0x0401f85f, + 0x0402000c, 0x400c0800, 0x0401f85c, 0x04020009, + 0x0401f84b, 0x42000000, 0x00030d40, 0x80000040, + 0x040207ff, 0x82000540, 0x00000001, 0x1c01f000, + 0x0401f843, 0x80000580, 0x0401f7fd, 0x0401f821, + 0x0400000a, 0x82040d40, 0x00000001, 0x0401f84b, + 0x04020007, 0x0401f87e, 0x0401f898, 0x0401f838, + 0x82000540, 0x00000001, 0x1c01f000, 0x0401f834, + 0x80000580, 0x0401f7fd, 0x40041800, 0x0401f811, + 0x0400000c, 0x0401f83d, 0x0402000b, 0x40080800, + 0x0401f83a, 0x04020008, 0x400c0800, 0x0401ffe8, + 0x04000004, 0x0401f826, 0x82000540, 0x00000001, + 0x1c01f000, 0x0401f822, 0x80000580, 0x0401f7fd, + 0x4c040000, 0x42000800, 0x00000064, 0x4a03c013, + 0x03800300, 0x80040840, 0x04000016, 0x59e00013, + 0x82000500, 0x00000300, 0x82000580, 0x00000300, + 0x040207f7, 0x42000000, 0x00000064, 0x80000040, + 0x040207ff, 0x4a03c013, 0x01000000, 0x42000000, + 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, + 0x02000000, 0x82000540, 0x00000001, 0x0401f002, + 0x80000580, 0x5c000800, 0x1c01f000, 0x4a03c013, + 0x01000000, 0x42000000, 0x00000064, 0x80000040, + 0x040207ff, 0x4a03c013, 0x02000200, 0x42000000, + 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, + 0x01000100, 0x1c01f000, 0x42002000, 0x00000008, + 0x82040500, 0x00000080, 0x800000c2, 0x82000540, + 0x01000000, 0x4803c013, 0x42000000, 0x00000064, + 0x80000040, 0x040207ff, 0x4a03c013, 0x02000200, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x4a03c013, 0x02000000, 0x800408c2, 0x80102040, + 0x040207ec, 0x4a03c013, 0x01000100, 0x42000000, + 0x00000064, 0x80000040, 0x040207ff, 0x4a03c013, + 0x02000200, 0x42000000, 0x00000064, 0x80000040, + 0x040207ff, 0x59e00013, 0x82000500, 0x00000100, + 0x4a03c013, 0x02000000, 0x4c040000, 0x42000800, + 0x00000064, 0x59e00013, 0x82000500, 0x00000100, + 0x80040840, 0x04000003, 0x80000540, 0x040207fa, + 0x80000540, 0x5c000800, 0x1c01f000, 0x4a03c013, + 0x01000100, 0x42001000, 0x00000008, 0x80000d80, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x4a03c013, 0x02000200, 0x42000000, 0x00000064, + 0x80000040, 0x040207ff, 0x59e00013, 0x82000500, + 0x00000100, 0x80000110, 0x800408c2, 0x80040d40, + 0x4a03c013, 0x02000000, 0x80081040, 0x040207ed, + 0x40042800, 0x1c01f000, 0x4a03c013, 0x01000100, + 0x42000000, 0x00000064, 0x80000040, 0x040207ff, + 0x4a03c013, 0x02000200, 0x42000000, 0x00000064, + 0x80000040, 0x040207ff, 0x4a03c013, 0x02000000, + 0x1c01f000, 0x59a00407, 0x59a80837, 0x48035037, + 0x48074407, 0x59a00a09, 0x82040480, 0x00000014, + 0x04021003, 0x42000800, 0x000007d0, 0x59a80038, + 0x48075038, 0x48034209, 0x0201f000, 0x00102066, + 0x836c0580, 0x00000000, 0x0400000e, 0x59a80006, + 0x59a00c06, 0x80041580, 0x82081500, 0x00000040, + 0x02000000, 0x00102066, 0x80080580, 0x48035006, + 0x0201f800, 0x001006df, 0x0201f000, 0x00102066, + 0x59a00406, 0x59a80806, 0x48035006, 0x80040d80, + 0x8c040d0c, 0x02020800, 0x001006df, 0x59a00207, + 0x48035007, 0x59a00407, 0x48035008, 0x0201f000, + 0x00102066, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x001020b2, 0x0201f800, + 0x00104e0d, 0x04020005, 0x4a034406, 0x00000016, + 0x0201f000, 0x001020b2, 0x836c0580, 0x00000003, + 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, + 0x001020b2, 0x59a00c06, 0x82040500, 0xffffff00, + 0x02020000, 0x001020b6, 0x82041580, 0x000000ff, + 0x04020007, 0x59a80010, 0x82000500, 0x000000ff, + 0x82001540, 0x0000ff00, 0x0401f011, 0x82040400, + 0x00101eb5, 0x50000000, 0x80000110, 0x82000580, + 0x00000080, 0x02000000, 0x001020b6, 0x59a80010, + 0x82000500, 0x000000ff, 0x80041580, 0x02000000, + 0x001020b6, 0x840409c0, 0x80041540, 0x0201f800, + 0x00020892, 0x04020005, 0x4a034406, 0x00000003, + 0x0201f000, 0x001020b2, 0x48ee6021, 0x480a621c, + 0x4a02641c, 0x0000bc09, 0x4a026406, 0x00000001, + 0x0201f800, 0x0010381a, 0x04020007, 0x0201f800, + 0x000208b4, 0x4a034406, 0x00000002, 0x0201f000, + 0x001020b2, 0x497a5a04, 0x497a5805, 0x4a025c04, + 0x00008000, 0x4a01d809, 0x00102657, 0x492e6008, + 0x42027000, 0x00000032, 0x0201f000, 0x000208d8, + 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, + 0x0201f000, 0x001020b2, 0x0201f800, 0x00104e0d, + 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, + 0x001020b2, 0x836c0580, 0x00000003, 0x04000005, + 0x4a034406, 0x00000007, 0x0201f000, 0x001020b2, + 0x59a00c06, 0x82040500, 0xffffff00, 0x02020000, + 0x001020b6, 0x82041580, 0x000000ff, 0x04020007, + 0x59a80010, 0x82000500, 0x000000ff, 0x82001540, + 0x0000ff00, 0x0401f011, 0x82040400, 0x00101eb5, + 0x50000000, 0x80000110, 0x82000580, 0x00000080, + 0x02000000, 0x001020b6, 0x59a80010, 0x82000500, + 0x000000ff, 0x80041580, 0x02000000, 0x001020b6, + 0x840409c0, 0x80041540, 0x0201f800, 0x00020892, + 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, + 0x001020b2, 0x48ee6021, 0x480a621c, 0x4a02641c, + 0x0000bc05, 0x4a026406, 0x00000001, 0x0201f800, + 0x0010381a, 0x04020007, 0x0201f800, 0x000208b4, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x497a5a04, 0x497a5805, 0x4a025c04, 0x00008000, + 0x4a01d809, 0x00102657, 0x492e6008, 0x42027000, + 0x00000032, 0x0201f000, 0x000208d8, 0x592c0005, + 0x82000580, 0x01000000, 0x02020000, 0x00102066, + 0x4a034406, 0x00000004, 0x0201f000, 0x001020b2, + 0x497b4406, 0x497b4207, 0x0201f800, 0x0010393e, + 0x04000008, 0x59a80066, 0x59a8086a, 0x80040480, + 0x59a80867, 0x48074406, 0x80041480, 0x480b4207, + 0x49674407, 0x59a8000e, 0x48034209, 0x495f4409, + 0x59a80020, 0x4803420b, 0x0201f000, 0x00102066, + 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, + 0x0201f000, 0x001020b2, 0x59a00406, 0x8c000500, + 0x0402000f, 0x59a80069, 0x81640480, 0x04001008, + 0x59a8000b, 0x81500580, 0x04000009, 0x59a8006a, + 0x59a81066, 0x80080580, 0x04000005, 0x4a034406, + 0x00000018, 0x0201f000, 0x001020b2, 0x59a80005, + 0x84000558, 0x48035005, 0x82000540, 0x00000001, + 0x0201f800, 0x00101668, 0x0201f800, 0x00103a9f, + 0x0201f000, 0x00102066, 0x4803c856, 0x800409c0, + 0x02020000, 0x001020ba, 0x59a00406, 0x8c00051e, + 0x04000008, 0x4803c856, 0x59a0020b, 0x82000480, + 0x00000800, 0x04001015, 0x0201f000, 0x001020b6, + 0x4803c856, 0x59a0020b, 0x599c0a01, 0x80040480, + 0x04021003, 0x0201f000, 0x001020b6, 0x59a8000e, + 0x81640580, 0x04000009, 0x4a034406, 0x00000018, + 0x0201f000, 0x001020b2, 0x4a034406, 0x00000005, + 0x0201f000, 0x001020b2, 0x59a80026, 0x8c00050a, + 0x040007fa, 0x59a00406, 0x8c00051e, 0x04000036, + 0x0201f800, 0x00020892, 0x040007f4, 0x0201f800, + 0x0010381a, 0x040007f1, 0x497a5a04, 0x59a00406, + 0x4802620a, 0x59a00209, 0x4802640a, 0x59a00409, + 0x4802620b, 0x59a0020d, 0x4802620c, 0x59a0040d, + 0x4802640c, 0x59a0020e, 0x4802620d, 0x59a0040e, + 0x4802640d, 0x59a00210, 0x4802620e, 0x59a00410, + 0x4802640e, 0x59a0020b, 0x82000500, 0x0000fffc, + 0x80000104, 0x4802640b, 0x0401f9d9, 0x040007d7, + 0x48ee6021, 0x58ee580d, 0x5930020e, 0x59301c0e, + 0x900c19c0, 0x800c1d40, 0x5930020c, 0x5930140c, + 0x900811c0, 0x80081540, 0x592c0a05, 0x832c0400, + 0x00000006, 0x0201f800, 0x0010383e, 0x4a01d809, + 0x00102846, 0x4a034000, 0x00000001, 0x49334001, + 0x1c01f000, 0x0201f800, 0x0010698c, 0x0201f800, + 0x00100b29, 0x0401f86d, 0x497b5057, 0x4201d000, + 0x00002710, 0x0201f800, 0x00105e06, 0x59c40880, + 0x4c040000, 0x59c408a3, 0x4c040000, 0x497b4002, + 0x0401f876, 0x0401f893, 0x4a03a005, 0x10000000, + 0x0401f8b4, 0x0401f901, 0x04000048, 0x59c80001, + 0x800001c0, 0x040007fc, 0x59c80018, 0x82000500, + 0xf0000000, 0x59c00808, 0x82040d00, 0x0fffffff, + 0x80040540, 0x48038008, 0x0201f800, 0x00100f0f, + 0x59c00006, 0x4a038006, 0x10000000, 0x59c00009, + 0x82000d00, 0x00e00000, 0x04020024, 0x4a03900d, + 0x00000000, 0x59c80020, 0x82000500, 0xff000000, + 0x82000580, 0x32000000, 0x0402001c, 0x4a03900d, + 0x00000001, 0x59c80020, 0x82000500, 0xff000000, + 0x82000580, 0xe1000000, 0x04020014, 0x4a03900d, + 0x00000000, 0x59c80020, 0x82000500, 0x00ffffff, + 0x4a03900d, 0x00000000, 0x59c80821, 0x82040d00, + 0x00ffffff, 0x80040580, 0x04020008, 0x59a80010, + 0x80040580, 0x04020005, 0x59c40005, 0x82000500, + 0x000000f0, 0x04000006, 0x4803c856, 0x0401f8d7, + 0x4a035057, 0x00000001, 0x0401f002, 0x0401f8e1, + 0x42000000, 0x00000064, 0x80000040, 0x02000800, + 0x00100615, 0x59c00807, 0x82040d00, 0x0000000c, + 0x040007fa, 0x0401f003, 0x4a035057, 0x00000001, + 0x0401f8da, 0x0201f800, 0x00106c8a, 0x0401f818, + 0x4201d000, 0x000186a0, 0x0201f800, 0x00105e06, + 0x5c000800, 0x480788a3, 0x5c000800, 0x48078880, + 0x59a80057, 0x800001c0, 0x02000000, 0x00102066, + 0x0201f000, 0x001020be, 0x599c0201, 0x48035059, + 0x41780800, 0x42001000, 0x00003b10, 0x0201f800, + 0x001063ee, 0x480b505a, 0x1c01f000, 0x0201f800, + 0x00106982, 0x59b800ea, 0x82000500, 0x00000007, + 0x82000580, 0x00000003, 0x04020003, 0x4a0370e8, + 0x00000001, 0x1c01f000, 0x42038000, 0x00007700, + 0x4a038006, 0x30000000, 0x59c00007, 0x8c00050a, + 0x040207fe, 0x59c00006, 0x59a00209, 0x59a00c09, + 0x900409c0, 0x80040d40, 0x48078001, 0x59a0020e, + 0x59a00c0e, 0x900409c0, 0x80040d40, 0x48078000, + 0x59a0020b, 0x82000500, 0x0000fffc, 0x48038002, + 0x48038003, 0x48038005, 0x497b9009, 0x59e00003, + 0x82000540, 0x00008060, 0x4803c003, 0x1c01f000, + 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, + 0x42000800, 0x00000040, 0x0201f800, 0x00101395, + 0x4a03a00a, 0x00000001, 0x4a03a005, 0x20000000, + 0x59d00006, 0x4a03a005, 0x30000000, 0x59d00006, + 0x8c00050a, 0x040207fe, 0x59d00005, 0x59a00210, + 0x59a00c10, 0x900409c0, 0x80040d40, 0x4807a001, + 0x59a0020d, 0x59a00c0d, 0x900409c0, 0x80040d40, + 0x4807a000, 0x59a0020b, 0x82000500, 0x0000fffc, + 0x4803a003, 0x4803a002, 0x4803a008, 0x1c01f000, + 0x59a00002, 0x4803c857, 0x800001c0, 0x0402004a, + 0x59a8005a, 0x48038880, 0x59c400a3, 0x82000540, + 0x00002008, 0x8400053a, 0x480388a3, 0x59c40008, + 0x8400054e, 0x82000500, 0xffffffe1, 0x48038808, + 0x59c80040, 0x84000534, 0x48039040, 0x0401f902, + 0x04020013, 0x59a80010, 0x800000d0, 0x82000540, + 0x00000011, 0x48039120, 0x59a80010, 0x82000500, + 0x00ffffff, 0x82000540, 0x32000000, 0x48039121, + 0x4a039123, 0xe1290008, 0x59a80010, 0x82000500, + 0x00ffffff, 0x48039122, 0x0401f016, 0x59a80010, + 0x82000500, 0x000000ff, 0x900009c0, 0x840001c0, + 0x80040540, 0x82000540, 0x00000000, 0x48039120, + 0x59a80010, 0x82000500, 0x000000ff, 0x82000540, + 0x01000000, 0x48039121, 0x4a039123, 0x08210008, + 0x59a80010, 0x82000500, 0x000000ff, 0x48039122, + 0x497b9124, 0x59a80c5b, 0x80040800, 0x4807545b, + 0x900409c0, 0x82040540, 0x0000aaaa, 0x48039125, + 0x497b9126, 0x497b9127, 0x0401f8cf, 0x04020004, + 0x4a039100, 0x0000e980, 0x0401f003, 0x4a039100, + 0x0000e9a0, 0x1c01f000, 0x82000540, 0x00000001, + 0x0402500d, 0x4203e000, 0x80000000, 0x40e81000, + 0x41780800, 0x42000000, 0x00000064, 0x0201f800, + 0x001063ee, 0x59940024, 0x80080400, 0x48032824, + 0x80000580, 0x1c01f000, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x417a3000, 0x0201f800, + 0x00106e2f, 0x0201f800, 0x00106b13, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000, + 0x59c80007, 0x8c000500, 0x04000003, 0x4a03900d, + 0x00000030, 0x1c01f000, 0x4a038805, 0x00020000, + 0x42000800, 0x0000003c, 0x0201f800, 0x00101395, + 0x4a038891, 0x0000ffff, 0x59c80035, 0x48039035, + 0x4a03900d, 0x00000040, 0x42038000, 0x00007700, + 0x0201f800, 0x00100f0f, 0x42038000, 0x00007720, + 0x0201f800, 0x00100f0f, 0x4a03a005, 0x20000000, + 0x4a03a005, 0x30000000, 0x59d00806, 0x8c040d0a, + 0x040207fe, 0x1c01f000, 0x4d300000, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x5c026000, 0x02000000, 0x001020aa, + 0x4d300000, 0x59a26001, 0x59a00000, 0x4000b000, + 0x80000000, 0x48034000, 0x592c0001, 0x80000540, + 0x0400001e, 0x40025800, 0x8058b040, 0x040207fb, + 0x58ec1007, 0x58ec1808, 0x592c0a05, 0x4d2c0000, + 0x58ec000d, 0x40025800, 0x592c0204, 0x5c025800, + 0x82000580, 0x00000103, 0x04000008, 0x832c0400, + 0x00000006, 0x0201f800, 0x0010383e, 0x4a01d809, + 0x00102846, 0x0401f007, 0x832c0400, 0x00000006, + 0x0201f800, 0x00103841, 0x4a01d809, 0x00102846, + 0x5c026000, 0x1c01f000, 0x58ec000d, 0x40025800, + 0x592c0204, 0x82000580, 0x00000103, 0x04020006, + 0x0201f800, 0x000208b4, 0x5c026000, 0x0201f000, + 0x00102066, 0x58ec000d, 0x40025800, 0x592c0404, + 0x8400055e, 0x48025c04, 0x42028800, 0x000007fd, + 0x42003000, 0x00fffffd, 0x0201f800, 0x001043fc, + 0x04000003, 0x80000580, 0x0401f004, 0x59a26001, + 0x0201f800, 0x00109146, 0x5c026000, 0x02000000, + 0x001020b2, 0x4d300000, 0x4a01d809, 0x00102899, + 0x0401f7dc, 0x592c0005, 0x82000580, 0x01000000, + 0x02000000, 0x001020be, 0x4d300000, 0x59a26001, + 0x5930020b, 0x59301c0a, 0x900001c0, 0x800c1d40, + 0x5930040d, 0x5930120d, 0x900001c0, 0x80081540, + 0x592c0a05, 0x832c0400, 0x00000006, 0x0201f800, + 0x00103841, 0x4a01d809, 0x00102846, 0x4a034000, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, + 0x4c300000, 0x5930040b, 0x82000c80, 0x0000000e, + 0x04001004, 0x4a025a05, 0x0000000e, 0x0401f003, + 0x48025a05, 0x0401f00c, 0x800409c0, 0x0400000a, + 0x4c040000, 0x0201f800, 0x0010381a, 0x5c000800, + 0x04000003, 0x40040000, 0x0401f7f0, 0x80000580, + 0x0401f003, 0x82000540, 0x00000001, 0x5c006000, + 0x1c01f000, 0x59a00206, 0x82000580, 0x00000044, + 0x1c01f000, 0x4807c857, 0x800409c0, 0x0400000c, + 0x0201f800, 0x001016c1, 0x04020009, 0x42000000, + 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, + 0x00000002, 0x0201f800, 0x00101892, 0x59a00406, + 0x82000500, 0x00000007, 0x0c01f001, 0x001028ed, + 0x00102902, 0x00102918, 0x001028eb, 0x001028eb, + 0x001028eb, 0x001028eb, 0x001028eb, 0x0201f000, + 0x001020b6, 0x42000800, 0x000000c0, 0x0201f800, + 0x001019ac, 0x82040540, 0x00000002, 0x42000800, + 0x000000c0, 0x0201f800, 0x001019b1, 0x42000800, + 0x00000000, 0x0201f800, 0x001019ac, 0x82040540, + 0x00000008, 0x42000800, 0x00000000, 0x0201f800, + 0x001019b1, 0x0401f00b, 0x42000800, 0x000000c0, + 0x0201f800, 0x001019ac, 0x82040540, 0x00000001, + 0x42000800, 0x000000c0, 0x0201f800, 0x001019b1, + 0x59c80040, 0x4c000000, 0x59a80010, 0x4c000000, + 0x59c400a3, 0x4c000000, 0x59c40008, 0x4c000000, + 0x0401f911, 0x04000021, 0x0201f800, 0x00100615, + 0x59a80821, 0x800409c0, 0x02020000, 0x001020ba, + 0x0201f800, 0x00104e0d, 0x04020005, 0x4a034406, + 0x00000016, 0x0201f000, 0x001020b2, 0x836c0580, + 0x00000003, 0x02020000, 0x001020ba, 0x59c408a4, + 0x82040d00, 0x0000000f, 0x82040580, 0x00000000, + 0x02020000, 0x001020ba, 0x59c80040, 0x4c000000, + 0x59a80010, 0x4c000000, 0x59c400a3, 0x4c000000, + 0x59c40008, 0x4c000000, 0x59c40080, 0x4c000000, + 0x59a0020f, 0x59a0bc0f, 0x905cb9c0, 0x805cbd40, + 0x41784800, 0x41785000, 0x41785800, 0x41789000, + 0x41789800, 0x0401fe21, 0x0201f800, 0x0010698c, + 0x0201f800, 0x00100b29, 0x4178c000, 0x497b4002, + 0x0401f95c, 0x0401f9aa, 0x59a0020c, 0x59a00c0c, + 0x80040d40, 0x04000002, 0x0401f9fb, 0x0401f9fa, + 0x0401fe68, 0x8060c1c0, 0x04020014, 0x0401fa98, + 0x0401feb2, 0x0402000e, 0x0201f800, 0x00101941, + 0x04020008, 0x4a034406, 0x00000017, 0x0201f800, + 0x001020b2, 0x4203e000, 0x50000000, 0x0401f000, + 0x42005800, 0x0000aaaa, 0x0401f058, 0x59c80001, + 0x800001c0, 0x040007ee, 0x59c80801, 0x800409c0, + 0x04000006, 0x0401fa70, 0x40240000, 0x80280540, + 0x802c0540, 0x0402004d, 0x59a00002, 0x82000580, + 0xfeedbeef, 0x04000004, 0x42008800, 0x10000000, + 0x0401f003, 0x42008800, 0x10000004, 0x0401fa19, + 0x4a034002, 0xfeedbeef, 0x0401fa71, 0x0401fa97, + 0x0401fea8, 0x59c40005, 0x8c000534, 0x04000004, + 0x42005800, 0x0000bbbb, 0x0401f038, 0x0401fe83, + 0x04020007, 0x42005800, 0x0000cccc, 0x485f420f, + 0x905cb9c0, 0x485f440f, 0x0401f030, 0x59a0040c, + 0x800001c0, 0x0400000e, 0x59a26000, 0x5930000d, + 0x800001c0, 0x040207be, 0x59a26001, 0x5930080d, + 0x800409c0, 0x040207ba, 0x804891c0, 0x040207b8, + 0x804c99c0, 0x040207b6, 0x0401f87a, 0x805cb840, + 0x04000005, 0x40240000, 0x80280540, 0x802c0540, + 0x0402001a, 0x42000000, 0x00030d40, 0x80000040, + 0x04020012, 0x59c00007, 0x82000500, 0x000501c0, + 0x0402000b, 0x0201f800, 0x00101941, 0x04020008, + 0x4a034406, 0x00000017, 0x0201f800, 0x001020b2, + 0x4203e000, 0x50000000, 0x0401f000, 0x42005800, + 0x0000dddd, 0x0401f005, 0x59c00807, 0x82040d00, + 0x0000000c, 0x040007ea, 0x0401fe5c, 0x59a0040c, + 0x800001c0, 0x04000002, 0x0401f856, 0x0401fe6b, + 0x40240000, 0x80280540, 0x802c0540, 0x04020003, + 0x805cb9c0, 0x04020781, 0x0201f800, 0x00106c8a, + 0x0401fda3, 0x4201d000, 0x000186a0, 0x0201f800, + 0x00105e06, 0x5c000800, 0x48078880, 0x5c000800, + 0x48078808, 0x5c000800, 0x480788a3, 0x5c000800, + 0x48075010, 0x5c000800, 0x48079040, 0x0201f800, + 0x001009b6, 0x59a00406, 0x82000500, 0x00000003, + 0x82000580, 0x00000002, 0x0400002c, 0x42000800, + 0x000000c0, 0x0201f800, 0x001019ac, 0x82040500, + 0xfffffffc, 0x42000800, 0x000000c0, 0x0201f800, + 0x001019b1, 0x42000800, 0x00000000, 0x0201f800, + 0x001019ac, 0x82040500, 0xfffffff7, 0x42000800, + 0x00000000, 0x0201f800, 0x001019b1, 0x42000800, + 0x00000000, 0x0201f800, 0x001019ac, 0x82040500, + 0xfffffffb, 0x42000800, 0x00000000, 0x0201f800, + 0x001019b1, 0x4a0388a7, 0x0000f7f7, 0x42006000, + 0xbeffffff, 0x42006800, 0x80018000, 0x0201f800, + 0x001040ad, 0x42006000, 0xfffeffff, 0x41786800, + 0x0201f800, 0x001040ad, 0x402c0000, 0x80280540, + 0x80240540, 0x02000000, 0x00102066, 0x48274406, + 0x482b4207, 0x482f4407, 0x0201f000, 0x001020c2, + 0x59a26000, 0x813261c0, 0x0400000e, 0x59325808, + 0x812e59c0, 0x0400000b, 0x0201f800, 0x000208b4, + 0x0201f800, 0x00100843, 0x59a26001, 0x59325808, + 0x0201f800, 0x000208b4, 0x0201f800, 0x00100843, + 0x1c01f000, 0x42000800, 0x000000ef, 0x0201f800, + 0x00101655, 0x59c400a3, 0x8400055a, 0x8400053a, + 0x480388a3, 0x0201f800, 0x001016ac, 0x0402000a, + 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, + 0x42000000, 0x00000001, 0x0201f800, 0x00101892, + 0x0401f013, 0x0201f800, 0x001016b3, 0x04020008, + 0x41780000, 0x0201f800, 0x001018fa, 0x41780000, + 0x0201f800, 0x00101892, 0x0401f009, 0x42000000, + 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, + 0x00000002, 0x0201f800, 0x00101892, 0x42000800, + 0x00000000, 0x0201f800, 0x001019ac, 0x82040540, + 0x00000004, 0x42000800, 0x00000000, 0x0201f800, + 0x001019b1, 0x4201d000, 0x00000014, 0x0201f800, + 0x00105dd2, 0x59c40008, 0x8400054e, 0x82000500, + 0xffffffe1, 0x48038808, 0x4a0388a7, 0x0000f7f7, + 0x42001000, 0x04000001, 0x0201f800, 0x001019aa, + 0x42006000, 0xbe20bfff, 0x42006800, 0x80018000, + 0x0201f800, 0x001040ad, 0x42006000, 0xfffeffff, + 0x41786800, 0x0201f800, 0x001040ad, 0x4200b000, + 0x00001388, 0x4201d000, 0x00000014, 0x4c580000, + 0x0201f800, 0x00105dd2, 0x0201f800, 0x00101941, + 0x5c00b000, 0x04000004, 0x8058b040, 0x040207f6, + 0x0401f025, 0x59c40005, 0x8c000534, 0x04020007, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x00000008, 0x0402001c, 0x42006000, 0x00020000, + 0x0201f800, 0x001040b2, 0x4201d000, 0x00000064, + 0x0201f800, 0x00105dd2, 0x42006000, 0xfeffffff, + 0x42006800, 0x02000000, 0x0201f800, 0x001040ad, + 0x42006000, 0xfdffffff, 0x41786800, 0x0201f800, + 0x001040ad, 0x4a038805, 0x04000001, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x00000000, + 0x04000003, 0x82000540, 0x00000001, 0x1c01f000, + 0x4803c856, 0x42038000, 0x00007700, 0x0201f800, + 0x00100f0f, 0x59c00006, 0x59a0040c, 0x800001c0, + 0x0400003f, 0x59a03c0c, 0x59a00209, 0x59a01c09, + 0x900c19c0, 0x800c1d40, 0x59a0020e, 0x59a0240e, + 0x901021c0, 0x80102540, 0x59a0020b, 0x82000500, + 0x0000fffc, 0x59a0140b, 0x900811c0, 0x80081540, + 0x480b8003, 0x0201f800, 0x00020892, 0x02000800, + 0x00100615, 0x49334000, 0x0201f800, 0x0010082a, + 0x4a025a04, 0x00000018, 0x4a025805, 0x00abcdef, + 0x492e6008, 0x492e600b, 0x481e600d, 0x4a02600c, + 0x00000004, 0x832c0400, 0x00000011, 0x4802600a, + 0x42001000, 0x0000000c, 0x821c0d80, 0x00000001, + 0x04000004, 0x801c3840, 0x0401f963, 0x0401f004, + 0x41783800, 0x0401f960, 0x0401f011, 0x821c0c80, + 0x00000005, 0x04001005, 0x40043800, 0x42001000, + 0x0000003c, 0x0401f006, 0x80001580, 0x82081400, + 0x0000000c, 0x801c3840, 0x040207fd, 0x832c0400, + 0x00000005, 0x0401f950, 0x040207f1, 0x497b9009, + 0x59e00003, 0x82000540, 0x00008060, 0x4803c003, + 0x4a038009, 0x00e00000, 0x1c01f000, 0x4803c856, + 0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600, + 0x42000800, 0x00000040, 0x0201f800, 0x00101395, + 0x4a03a00a, 0x00000001, 0x4a03a005, 0x20000000, + 0x59d00006, 0x4a03a005, 0x30000000, 0x59d00006, + 0x8c00050a, 0x040207fe, 0x59d00005, 0x59a0020c, + 0x800001c0, 0x0400003f, 0x59a03a0c, 0x59a00210, + 0x59a01c10, 0x900c19c0, 0x800c1d40, 0x59a0020d, + 0x59a0240d, 0x901021c0, 0x80102540, 0x59a0120b, + 0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0, + 0x80081540, 0x480ba003, 0x0201f800, 0x00020892, + 0x02000800, 0x00100615, 0x49334001, 0x0201f800, + 0x0010082a, 0x4a025a04, 0x00000018, 0x4a025805, + 0x00abcdef, 0x492e6008, 0x492e600b, 0x481e600d, + 0x4a02600c, 0x00000004, 0x832c0400, 0x00000011, + 0x4802600a, 0x42001000, 0x0000000c, 0x821c0d80, + 0x00000001, 0x04000004, 0x801c3840, 0x0401f906, + 0x0401f004, 0x41783800, 0x0401f903, 0x0401f011, + 0x821c0c80, 0x00000005, 0x04001005, 0x40043800, + 0x42001000, 0x0000003c, 0x0401f006, 0x80001580, + 0x82081400, 0x0000000c, 0x801c3840, 0x040207fd, + 0x832c0400, 0x00000005, 0x0401f8f3, 0x040207f1, + 0x1c01f000, 0x4803c856, 0x59a0020c, 0x800001c0, + 0x04000024, 0x824c0580, 0x00000002, 0x04000040, + 0x59a26001, 0x5930380d, 0x801c39c0, 0x0400003c, + 0x801c3840, 0x481e600d, 0x5932580b, 0x5930080a, + 0x50042000, 0x58041801, 0x58041002, 0x82081500, + 0xfffffffc, 0x5930000c, 0x80000000, 0x82000d80, + 0x00000005, 0x04020009, 0x497a600c, 0x592e5801, + 0x812e59c0, 0x0400001a, 0x492e600b, 0x832c0c00, + 0x00000005, 0x0401f005, 0x4802600c, 0x5930080a, + 0x82040c00, 0x00000003, 0x4806600a, 0x0401f010, + 0x59a0120b, 0x82081500, 0x0000fffc, 0x59a0040b, + 0x900001c0, 0x80081540, 0x480ba003, 0x59a0020d, + 0x59a0240d, 0x901021c0, 0x80102540, 0x59a00210, + 0x59a01c10, 0x900c19c0, 0x800c1d40, 0x4201d000, + 0x00003a98, 0x0201f800, 0x00105e06, 0x480ba002, + 0x59a80059, 0x4803a008, 0x4813a000, 0x480fa001, + 0x4a03a005, 0x10000000, 0x02005800, 0x00100615, + 0x804c9800, 0x82000540, 0x00000001, 0x1c01f000, + 0x4847c857, 0x59a0040c, 0x800001c0, 0x04000024, + 0x82480580, 0x00000002, 0x04000042, 0x59a26000, + 0x5930380d, 0x801c39c0, 0x0400003e, 0x801c3840, + 0x481e600d, 0x5932580b, 0x5930080a, 0x50042000, + 0x58041801, 0x58041002, 0x82081500, 0xfffffffc, + 0x5930000c, 0x80000000, 0x82000d80, 0x00000005, + 0x04020009, 0x497a600c, 0x592e5801, 0x812e59c0, + 0x0400001d, 0x492e600b, 0x832c0c00, 0x00000005, + 0x0401f005, 0x4802600c, 0x5930080a, 0x82040c00, + 0x00000003, 0x4806600a, 0x0401f013, 0x82440580, + 0x10000000, 0x0402001f, 0x59a0020e, 0x59a0240e, + 0x901021c0, 0x80102540, 0x59a00209, 0x59a01c09, + 0x900c19c0, 0x800c1d40, 0x59a0020b, 0x82000500, + 0x0000fffc, 0x59a0140b, 0x900811c0, 0x80081540, + 0x480b8003, 0x48138000, 0x480f8001, 0x480b8002, + 0x59c80018, 0x82000500, 0xf0000000, 0x59c02008, + 0x82102500, 0x0fffffff, 0x80100540, 0x48038008, + 0x48478006, 0x80489000, 0x8260c540, 0x00000001, + 0x1c01f000, 0x59c00009, 0x4803c857, 0x82000d00, + 0x00e00000, 0x0400000d, 0x485f420f, 0x905cb9c0, + 0x485f440f, 0x8c00052e, 0x04000002, 0x80285000, + 0x8c00052c, 0x04000002, 0x80244800, 0x8c00052a, + 0x04000002, 0x802c5800, 0x1c01f000, 0x59a0020c, + 0x800001c0, 0x04000024, 0x59d00806, 0x4807c857, + 0x8c040d3e, 0x04000020, 0x4a03a005, 0x20000000, + 0x4a03a005, 0x30000000, 0x59d00806, 0x8c040d0a, + 0x040207fe, 0x824c0480, 0x00000003, 0x02021800, + 0x00100615, 0x404c0000, 0x0c01f001, 0x00102c02, + 0x00102c04, 0x00102c0a, 0x0201f800, 0x00100615, + 0x80000040, 0x40009800, 0x0401ff43, 0x0400000a, + 0x0401ff41, 0x0401f008, 0x80000040, 0x40009800, + 0x59d00806, 0x4807c857, 0x8c040d3e, 0x040207e3, + 0x0401ff39, 0x1c01f000, 0x59a0040c, 0x800001c0, + 0x04000024, 0x59c00807, 0x4807c857, 0x8c040d3e, + 0x04000020, 0x59c00807, 0x4a038006, 0x20000000, + 0x82480480, 0x00000003, 0x02021800, 0x00100615, + 0x40480000, 0x0c01f001, 0x00102c25, 0x00102c27, + 0x00102c2f, 0x0201f800, 0x00100615, 0x80000040, + 0x40009000, 0x42008800, 0x10000004, 0x0401ff65, + 0x0400000c, 0x0401ff63, 0x0401f00a, 0x80000040, + 0x40009000, 0x59c00807, 0x4807c857, 0x8c040d3e, + 0x040207e5, 0x42008800, 0x10000004, 0x0401ff59, + 0x1c01f000, 0x492fc857, 0x4000a800, 0x4a03b805, + 0x20000000, 0x59dc0006, 0x4a03b805, 0x30000000, + 0x4813b800, 0x480fb801, 0x480bb802, 0x4857b803, + 0x4a03b805, 0x30000002, 0x59dc0006, 0x4a03b805, + 0x70000001, 0x59dc0006, 0x4a03b805, 0x10000000, + 0x59dc0006, 0x8c00053e, 0x040007fe, 0x4a03b805, + 0x20000000, 0x59dc0006, 0x59dc2000, 0x59dc1801, + 0x801c39c0, 0x0400000a, 0x4d2c0000, 0x0201f800, + 0x0010082a, 0x5c000800, 0x02000800, 0x00100615, + 0x4a025a04, 0x0000000a, 0x492c0801, 0x1c01f000, + 0x42006000, 0x00102d9d, 0x42000800, 0x0000007c, + 0x0201f800, 0x00101395, 0x4a03902c, 0x00200000, + 0x4200b000, 0x000001f4, 0x59c8002c, 0x8c00052c, + 0x04000007, 0x8058b040, 0x040207fc, 0x42000000, + 0x00004003, 0x41781000, 0x0401f11e, 0x50301000, + 0x41784800, 0x4a03902d, 0x00008000, 0x4200b000, + 0x000001f4, 0x59c8002c, 0x8c000534, 0x04000007, + 0x8058b040, 0x040207fc, 0x42000000, 0x00004003, + 0x41781000, 0x0401f10f, 0x0401f895, 0x80244800, + 0x82240580, 0x000003b1, 0x040207fc, 0x0401f911, + 0x41784800, 0x0401f8bb, 0x80244800, 0x82240580, + 0x000003b1, 0x040207fc, 0x80306000, 0x82300580, + 0x00102d9f, 0x040207e2, 0x59a80863, 0x800409c0, + 0x04000007, 0x42000000, 0x00004004, 0x42001000, + 0x00000002, 0x59a81862, 0x0401f0f6, 0x42006000, + 0x00102d9d, 0x50301000, 0x41784800, 0x4a03902d, + 0x00000800, 0x0401f876, 0x80244800, 0x82240580, + 0x00000018, 0x040207fc, 0x0401f8f2, 0x41784800, + 0x0401f89c, 0x80244800, 0x82240580, 0x00000018, + 0x040207fc, 0x80306000, 0x82300580, 0x00102d9f, + 0x040207ed, 0x59a80863, 0x800409c0, 0x04000007, + 0x42000000, 0x00004004, 0x42001000, 0x00000010, + 0x59a81862, 0x0401f0d7, 0x42006000, 0x00102d9d, + 0x50301000, 0x41784800, 0x4a03902d, 0x00000400, + 0x0401f857, 0x80244800, 0x82240580, 0x00000088, + 0x040207fc, 0x0401f8d3, 0x41784800, 0x0401f87d, + 0x80244800, 0x82240580, 0x00000088, 0x040207fc, + 0x80306000, 0x82300580, 0x00102d9f, 0x040207ed, + 0x59a80863, 0x800409c0, 0x04000007, 0x42000000, + 0x00004004, 0x42001000, 0x00000008, 0x59a81862, + 0x0401f0b8, 0x42006000, 0x00102d9d, 0x50301000, + 0x41784800, 0x4a03902d, 0x00002000, 0x4200b000, + 0x000001f4, 0x59c8002c, 0x8c000530, 0x04000007, + 0x8058b040, 0x040207fc, 0x42000000, 0x00004003, + 0x41781000, 0x0401f0a7, 0x59c8002c, 0x82000500, + 0xffe0ffff, 0x82080d00, 0x001f0000, 0x80040540, + 0x4803902c, 0x0401f826, 0x80244800, 0x82240580, + 0x00000110, 0x040207fc, 0x0401f8a2, 0x41784800, + 0x0401f84c, 0x59c80034, 0x82080d00, 0x001f0000, + 0x82000500, 0x001f0000, 0x80040580, 0x04000006, + 0x59a80063, 0x80000000, 0x48035063, 0x40240000, + 0x48035062, 0x80244800, 0x82240580, 0x00000110, + 0x040207f0, 0x80306000, 0x82300580, 0x00102d9f, + 0x040207cf, 0x59a80863, 0x800409c0, 0x04000006, + 0x42000000, 0x00004004, 0x42001000, 0x00000020, + 0x59a81862, 0x0201f000, 0x00102066, 0x59c8002c, + 0x82000500, 0xffff0000, 0x82080d00, 0x0000ffff, + 0x80040540, 0x4803902c, 0x480b9028, 0x480b9029, + 0x59a80064, 0x82000580, 0x00000004, 0x04000003, + 0x480b902a, 0x480b902b, 0x59c8002d, 0x82000500, + 0xfffffc00, 0x80240540, 0x4803902d, 0x4200b000, + 0x000001f4, 0x59c8002c, 0x82000500, 0x18000000, + 0x04000007, 0x8058b040, 0x040207fb, 0x42000000, + 0x00004003, 0x41781000, 0x0401f05a, 0x4a03902e, + 0x00000001, 0x4200b000, 0x000001f4, 0x59c8002e, + 0x8c000500, 0x04000006, 0x8058b040, 0x040207fc, + 0x42000000, 0x00004003, 0x0401f04e, 0x1c01f000, + 0x41783800, 0x59c8002d, 0x82000500, 0xfffffc00, + 0x80240d40, 0x4807902d, 0x4200b000, 0x000001f4, + 0x59c8002c, 0x82000500, 0x18000000, 0x04000007, + 0x8058b040, 0x040207fb, 0x42000000, 0x00004003, + 0x41781000, 0x0401f03b, 0x59c81830, 0x59c80030, + 0x800c0d80, 0x040207fd, 0x80080d80, 0x04000002, + 0x801c3800, 0x59c82031, 0x59c80031, 0x80100d80, + 0x040207fd, 0x80080d80, 0x04000002, 0x801c3800, + 0x59a80064, 0x82000580, 0x00000004, 0x04000019, + 0x59c82832, 0x59c80032, 0x80140d80, 0x040207fd, + 0x80080d80, 0x04000002, 0x801c3800, 0x59c83033, + 0x59c80033, 0x80180d80, 0x040207fd, 0x80080d80, + 0x04000002, 0x801c3800, 0x59c80034, 0x59c80834, + 0x80040d80, 0x040207fd, 0x80080d80, 0x82040d00, + 0x0000ffff, 0x0400000c, 0x801c3800, 0x0401f00a, + 0x59c80034, 0x59c80834, 0x80040d80, 0x040207fd, + 0x80080d80, 0x82040d00, 0x000000ff, 0x04000002, + 0x801c3800, 0x801c39c0, 0x04000005, 0x59a80063, + 0x801c0400, 0x48035063, 0x48275062, 0x1c01f000, + 0x48034206, 0x48074406, 0x480b4207, 0x480f4407, + 0x48134208, 0x48174408, 0x0201f000, 0x00102069, + 0x42000000, 0x00600000, 0x80000040, 0x040207ff, + 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5, 0x59a00c0a, + 0x800409c0, 0x02000000, 0x001020b6, 0x82040480, + 0x00000021, 0x02021000, 0x001020b6, 0x82040480, + 0x00000011, 0x04001003, 0x42000800, 0x00000010, + 0x59a00208, 0x59a01407, 0x900811c0, 0x80081540, + 0x59a00207, 0x59a01c06, 0x900c19c0, 0x800c1d40, + 0x0201f800, 0x0010381a, 0x04000006, 0x0201f800, + 0x0010383e, 0x4a01d809, 0x00102dc0, 0x1c01f000, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x59a00c0a, + 0x82040480, 0x00000011, 0x04001003, 0x42000800, + 0x00000010, 0x59a0040b, 0x59a0120b, 0x900811c0, + 0x80081540, 0x59a00209, 0x59a01c08, 0x900c19c0, + 0x800c1d40, 0x58ec0003, 0x0201f800, 0x00103841, + 0x4a01d809, 0x00102ddb, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x001020aa, 0x59a00c0a, 0x82040480, + 0x00000011, 0x02001000, 0x00102066, 0x82040c80, + 0x00000010, 0x59a00208, 0x59a01407, 0x900811c0, + 0x80081540, 0x59a00207, 0x59a01c06, 0x900c19c0, + 0x800c1d40, 0x82081400, 0x00000040, 0x58ec0003, + 0x0201f800, 0x0010383e, 0x4a01d809, 0x00102df9, + 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, + 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x59a0040a, 0x82000c80, 0x00000010, 0x59a0040b, + 0x59a0120b, 0x900811c0, 0x80081540, 0x59a00209, + 0x59a01c08, 0x900c19c0, 0x800c1d40, 0x82081400, + 0x00000040, 0x58ec0003, 0x0201f800, 0x00103841, + 0x4a01d809, 0x0010205f, 0x1c01f000, 0x48efc857, + 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, + 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, + 0x59a00406, 0x48034000, 0x480b4001, 0x480f4002, + 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x001020b2, 0x42000800, + 0x00000010, 0x0201f800, 0x0010383e, 0x4a01d809, + 0x00102e2e, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x001020aa, 0x48efc857, 0x49a3c857, + 0x492fc857, 0x592c0a04, 0x80040910, 0x04020005, + 0x4a034406, 0x00000019, 0x0201f000, 0x001020b2, + 0x4805d80c, 0x0401f00a, 0x4031d800, 0x58ef400b, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x001020aa, 0x48efc857, 0x49a3c857, 0x48efc857, + 0x49a3c857, 0x58ec000c, 0x80000040, 0x04000012, + 0x4801d80c, 0x0201f800, 0x0010381a, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x42000800, 0x00000010, 0x58ec1007, 0x58ec1808, + 0x0201f800, 0x0010383e, 0x4a01d809, 0x00102e42, + 0x1c01f000, 0x58ee580d, 0x48efc857, 0x49a3c857, + 0x492fc857, 0x492f3006, 0x592c0404, 0x8400055e, + 0x48025c04, 0x4a01d809, 0x00102e6c, 0x1c01f000, + 0x4d2c0000, 0x58ee580d, 0x48efc857, 0x49a3c857, + 0x492fc857, 0x592c0404, 0x8400051e, 0x48025c04, + 0x59a00000, 0x59a01001, 0x59a01802, 0x80081400, + 0x820c1c40, 0x00000000, 0x832c0400, 0x00000004, + 0x42000800, 0x00000010, 0x5c025800, 0x0201f000, + 0x00103841, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x001020b2, 0x836c0580, + 0x00000003, 0x04000005, 0x4a034406, 0x00000007, + 0x0201f000, 0x001020b2, 0x59a0320b, 0x82183500, + 0x000000ff, 0x59a28c06, 0x0201f800, 0x00020267, + 0x02020000, 0x001020b6, 0x83440580, 0x000007fd, + 0x04000008, 0x0201f800, 0x00104836, 0x04000005, + 0x4a034406, 0x00000009, 0x0201f000, 0x001020b2, + 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x001020b2, 0x801831c0, + 0x0400000a, 0x412c0800, 0x0201f800, 0x0010381a, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x001020b2, 0x40065800, 0x4a025c04, 0x00008000, + 0x497a5a04, 0x0201f800, 0x00108ebd, 0x04020005, + 0x4a034406, 0x00000003, 0x0201f000, 0x001020b2, + 0x4a01d809, 0x00102ebf, 0x1c01f000, 0x592c0005, + 0x82000580, 0x01000000, 0x04020005, 0x4a034406, + 0x00000004, 0x0201f000, 0x001020b2, 0x592c0406, + 0x82002d00, 0x0000ff00, 0x82000500, 0x000000ff, + 0x80000904, 0x80040800, 0x82040480, 0x00000006, + 0x04001003, 0x42000800, 0x00000005, 0x4c500000, + 0x4c540000, 0x4c580000, 0x832ca400, 0x00000006, + 0x4050a800, 0x4004b000, 0x0201f800, 0x0010a94f, + 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, + 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, + 0x832c0400, 0x00000006, 0x4c140000, 0x0201f800, + 0x00103841, 0x5c002800, 0x801429c0, 0x04000003, + 0x4a01d809, 0x00102ef2, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x001020aa, 0x812e59c0, 0x02000800, + 0x00100615, 0x592c0006, 0x82000500, 0xff000000, + 0x80000904, 0x800409c0, 0x02000000, 0x001020aa, + 0x82040480, 0x0000000e, 0x04001003, 0x42000800, + 0x0000000d, 0x592e5801, 0x812e59c0, 0x02000800, + 0x00100615, 0x4c500000, 0x4c540000, 0x4c580000, + 0x832ca400, 0x00000005, 0x4050a800, 0x4004b000, + 0x0201f800, 0x0010a94f, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x58ec1007, 0x58ec1808, 0x832c0400, + 0x00000005, 0x0201f000, 0x00103841, 0x0201f800, + 0x0010381a, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x001020b2, 0x59a00c06, 0x82040500, + 0x0000ff00, 0x840001c0, 0x82001480, 0x00000007, + 0x02021000, 0x001020b6, 0x0c01f001, 0x00102f36, + 0x00102f3d, 0x00102f44, 0x00102f44, 0x00102f44, + 0x00102f46, 0x00102f4b, 0x42000800, 0x0000000d, + 0x42003800, 0x00102f5f, 0x4a034000, 0x0010b2e7, + 0x0401f013, 0x42000800, 0x0000000d, 0x42003800, + 0x00102f5f, 0x4a034000, 0x0010b2f4, 0x0401f00c, + 0x0201f000, 0x001020b6, 0x42000800, 0x00000008, + 0x42003800, 0x00102f72, 0x0401f005, 0x42000800, + 0x00000004, 0x42003800, 0x00102fbc, 0x59a00207, + 0x59a01407, 0x900001c0, 0x80081540, 0x59a00209, + 0x59a01c09, 0x900001c0, 0x800c1d40, 0x832c0400, + 0x00000005, 0x4c1c0000, 0x0201f800, 0x0010383e, + 0x5c003800, 0x481dd809, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x4a03501f, + 0x00000001, 0x4200b000, 0x0000000d, 0x59a0a800, + 0x832ca400, 0x00000005, 0x0201f800, 0x0010a93e, + 0x0201f000, 0x00102066, 0x4031d800, 0x58ef400b, + 0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200, + 0x02000000, 0x001020aa, 0x832ca400, 0x00000005, + 0x50500000, 0x82001500, 0x000c0016, 0x02020000, + 0x001020b6, 0x82500c00, 0x00000003, 0x50040000, + 0x82001500, 0x00000001, 0x02020000, 0x001020b6, + 0x50500000, 0x82001500, 0x00000028, 0x0400001d, + 0x82081580, 0x00000028, 0x02020000, 0x001020b6, + 0x80500800, 0x50040000, 0x82001500, 0x00000013, + 0x82081580, 0x00000013, 0x02020000, 0x001020b6, + 0x80040800, 0x50040000, 0x82001500, 0x00010000, + 0x82081580, 0x00010000, 0x02020000, 0x001020b6, + 0x836c0580, 0x00000000, 0x04000012, 0x599c0019, + 0x8c00050e, 0x0402000f, 0x0201f000, 0x001020b6, + 0x80500800, 0x50040000, 0x82001500, 0x00000013, + 0x02020000, 0x001020b6, 0x80040800, 0x50040000, + 0x82001500, 0x00010000, 0x02020000, 0x001020b6, + 0x4200b000, 0x00000008, 0x4200a800, 0x0010b2df, + 0x0201f800, 0x0010a93e, 0x0201f000, 0x00102066, + 0x4031d800, 0x58ef400b, 0x58ee580d, 0x58ec0002, + 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x4200b000, 0x00000004, 0x4200a800, 0x0010b6f9, + 0x832ca400, 0x00000005, 0x0201f800, 0x0010a93e, + 0x59a80005, 0x84000550, 0x48035005, 0x0201f000, + 0x00102066, 0x0201f800, 0x0010381a, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x59a00c06, 0x82040500, 0x0000ff00, 0x840001c0, + 0x82001480, 0x00000006, 0x02021000, 0x001020b6, + 0x0c01f001, 0x00102fe7, 0x00102fec, 0x00102ff1, + 0x00102ff1, 0x00102ff1, 0x00102ff3, 0x42000800, + 0x0000000d, 0x4200a000, 0x0010b2e7, 0x0401f00c, + 0x42000800, 0x0000000d, 0x4200a000, 0x0010b2f4, + 0x0401f007, 0x0201f000, 0x001020b6, 0x42000800, + 0x00000008, 0x4200a000, 0x0010b2df, 0x4004b000, + 0x832cac00, 0x00000005, 0x0201f800, 0x0010a93e, + 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, + 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, + 0x832c0400, 0x00000005, 0x0201f000, 0x00103841, + 0x836c0580, 0x00000000, 0x04020005, 0x4a034406, + 0x00000007, 0x0201f000, 0x001020b2, 0x59a01406, + 0x800811c0, 0x04020017, 0x59c40801, 0x82040d00, + 0x00018000, 0x82040580, 0x00000000, 0x04020004, + 0x4a034406, 0x00000000, 0x0401f048, 0x82040580, + 0x00008000, 0x04020004, 0x4a034406, 0x00000001, + 0x0401f042, 0x82040580, 0x00010000, 0x02020800, + 0x00100615, 0x4a034406, 0x00000003, 0x0401f03b, + 0x59a8006f, 0x8c000508, 0x04000005, 0x42000000, + 0x00000001, 0x40000800, 0x0401f003, 0x59a00207, + 0x59a80853, 0x48035053, 0x0201f800, 0x001016ac, + 0x0400000d, 0x0201f800, 0x001016b3, 0x0400000a, + 0x0201f800, 0x001016ba, 0x04000007, 0x0201f800, + 0x001016c1, 0x04000004, 0x48075053, 0x0201f000, + 0x001020b6, 0x82080580, 0x00000002, 0x0402001f, + 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, + 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, + 0x0201f800, 0x0010a7f5, 0x42000000, 0x0010b6c9, + 0x0201f800, 0x0010a86e, 0x82000540, 0x00000001, + 0x0201f800, 0x00104e5d, 0x4a038808, 0x00000000, + 0x4202d800, 0x00000004, 0x42001000, 0x00000001, + 0x0201f800, 0x001019aa, 0x4a035049, 0x00000001, + 0x0201f800, 0x0010071a, 0x0201f000, 0x00102066, + 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, + 0x0201f000, 0x001020b2, 0x836c0580, 0x00000003, + 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, + 0x001020b2, 0x59a28c06, 0x59a0320b, 0x82183500, + 0x000000ff, 0x0201f800, 0x00020267, 0x02020000, + 0x001020b6, 0x83440580, 0x000007fd, 0x04000008, + 0x0201f800, 0x00104836, 0x04000005, 0x42000800, + 0x00000009, 0x0201f000, 0x001020b2, 0x0201f800, + 0x0010381a, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x001020b2, 0x497a5a04, 0x4a025c04, + 0x00008000, 0x0201f800, 0x00108ed2, 0x04020005, + 0x4a034406, 0x00000003, 0x0201f000, 0x001020b2, + 0x4a01d809, 0x00103097, 0x1c01f000, 0x592c0005, + 0x82000d00, 0x0000ffff, 0x82000500, 0xffff0000, + 0x82000580, 0x01000000, 0x04020005, 0x4a034406, + 0x00000004, 0x0201f000, 0x001020b2, 0x80040904, + 0x4c500000, 0x4c540000, 0x4c580000, 0x832ca400, + 0x00000005, 0x4050a800, 0x4004b000, 0x0201f800, + 0x0010a94f, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x59a00207, 0x59a01407, 0x900001c0, 0x80081540, + 0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40, + 0x832c0400, 0x00000005, 0x0201f000, 0x00103841, + 0x496fc857, 0x836c0580, 0x00000000, 0x04000005, + 0x4a034406, 0x0000001a, 0x0201f000, 0x001020b2, + 0x0201f800, 0x00104e0d, 0x02020800, 0x00103f5c, + 0x42000800, 0x00000020, 0x59a00407, 0x59a01207, + 0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09, + 0x900c19c0, 0x800c1d40, 0x419c0000, 0x49a3c857, + 0x0201f800, 0x0010383e, 0x4a01d809, 0x001030d9, + 0x1c01f000, 0x4833c857, 0x4031d800, 0x58ef400b, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x001020aa, 0x599c0200, 0x800001c0, 0x02000000, + 0x001020b6, 0x59a8006f, 0x8c000504, 0x04020003, + 0x8c000506, 0x04000004, 0x599c0019, 0x8400050c, + 0x48033819, 0x0201f800, 0x001095a3, 0x59a8006f, + 0x8c000502, 0x04000004, 0x599c0017, 0x84000508, + 0x48033817, 0x0201f800, 0x0010393e, 0x04020004, + 0x8c00050a, 0x02020000, 0x001020b6, 0x4803c857, + 0x8c000504, 0x04020004, 0x59c408a3, 0x84040d7a, + 0x480788a3, 0x8c000502, 0x04020004, 0x59c408a3, + 0x84040d08, 0x480788a3, 0x599c0c02, 0x8c000500, + 0x04020004, 0x8c000516, 0x04000012, 0x0401f001, + 0x82041480, 0x0000007f, 0x02021000, 0x001020b6, + 0x82041400, 0x00101eb5, 0x50081000, 0x82081500, + 0x000000ff, 0x8c000500, 0x04020006, 0x480b5010, + 0x42000800, 0x00000003, 0x0201f800, 0x001069af, + 0x599c0019, 0x8c000506, 0x04000003, 0x4a03b805, + 0x90000000, 0x8c00050e, 0x0402000b, 0x59a80806, + 0x8c040d14, 0x04000008, 0x42000800, 0x0010b2df, + 0x50040800, 0x82040d00, 0x00000028, 0x02020000, + 0x001020b6, 0x82000500, 0x00000030, 0x04000003, + 0x80000108, 0x0401f003, 0x42000000, 0x00000002, + 0x48039040, 0x42000800, 0x00000002, 0x82000400, + 0x0010321c, 0x50001000, 0x0201f800, 0x001069af, + 0x599c0201, 0x82000c80, 0x00000100, 0x02001000, + 0x001020b6, 0x82000c80, 0x00000841, 0x02021000, + 0x001020b6, 0x82000500, 0x00000007, 0x02020000, + 0x001020b6, 0x599c0401, 0x80000540, 0x02000000, + 0x001020b6, 0x599c0409, 0x599c0c07, 0x80040c80, + 0x02021000, 0x001020b6, 0x80000040, 0x02000000, + 0x001020b6, 0x599c0209, 0x599c0a07, 0x80040c80, + 0x02021000, 0x001020b6, 0x80000040, 0x02000000, + 0x001020b6, 0x0201f800, 0x0010509d, 0x0201f800, + 0x00104b53, 0x599c0201, 0x48035004, 0x0201f800, + 0x0010133e, 0x599c020a, 0x800001c0, 0x04000003, + 0x4803504d, 0x0401f003, 0x4a03504d, 0x000000c8, + 0x0201f800, 0x0010393e, 0x04000004, 0x0201f800, + 0x00105e18, 0x417a5000, 0x836c0580, 0x00000000, + 0x0402009a, 0x599c0003, 0x599c0804, 0x9c0001c0, + 0x9c0409c0, 0x48035002, 0x48075003, 0x599c1017, + 0x8c08151c, 0x04000006, 0x599c0005, 0x599c0806, + 0x9c0001c0, 0x9c0409c0, 0x0401f003, 0x82000500, + 0xf0ffffff, 0x48035000, 0x48075001, 0x42001000, + 0x0010b2e7, 0x48001000, 0x48041001, 0x42001000, + 0x0010b2f4, 0x48001000, 0x48041001, 0x59a8006f, + 0x8c000508, 0x04020017, 0x8c00050a, 0x04020021, + 0x599c1019, 0x82081500, 0x0000e000, 0x82080580, + 0x00000000, 0x0402000c, 0x4a035053, 0x00000000, + 0x42000000, 0x00000001, 0x0201f800, 0x001018fa, + 0x42000000, 0x00000001, 0x0201f800, 0x00101892, + 0x0401f02b, 0x82080580, 0x00002000, 0x0402000a, + 0x4a035053, 0x00000001, 0x41780000, 0x0201f800, + 0x001018fa, 0x41780000, 0x0201f800, 0x00101892, + 0x0401f01f, 0x82080580, 0x00004000, 0x04020006, + 0x4a035053, 0x00000002, 0x4a035049, 0x00000001, + 0x0401f017, 0x82080580, 0x00006000, 0x02020000, + 0x001020b6, 0x59a80858, 0x82040d80, 0x01391077, + 0x04020005, 0x59e00813, 0x8c040d00, 0x02020000, + 0x001020b6, 0x4a035053, 0x00000003, 0x42000000, + 0x00000002, 0x0201f800, 0x001018fa, 0x42000000, + 0x00000002, 0x0201f800, 0x00101892, 0x599c0019, + 0x8c000520, 0x0400000d, 0x42000000, 0x00000004, + 0x42000800, 0x00000040, 0x0201f800, 0x001019b1, + 0x42000000, 0x00000010, 0x42000800, 0x000000c0, + 0x0201f800, 0x001019b1, 0x4a035032, 0x0000aaaa, + 0x599c1018, 0x82081500, 0x00000030, 0x59a8006c, + 0x80000540, 0x0400000c, 0x82080580, 0x00000000, + 0x02000000, 0x001020b6, 0x599c1018, 0x82081500, + 0xffffffcf, 0x82081540, 0x00000010, 0x480b3818, + 0x0401f010, 0x82080d80, 0x00000000, 0x04000007, + 0x82080d80, 0x00000010, 0x0400000a, 0x82080d80, + 0x00000020, 0x04020002, 0x48075032, 0x0201f800, + 0x001038d3, 0x04000008, 0x0201f800, 0x00101668, + 0x0201f800, 0x00101694, 0x59a8002a, 0x80040540, + 0x4803502a, 0x49f3c857, 0x42001000, 0x00104d39, + 0x0201f800, 0x00105cc9, 0x42001000, 0x00104d2c, + 0x0201f800, 0x00105dbd, 0x4a038805, 0xffffffff, + 0x4a03c014, 0x00400040, 0x4a03c013, 0x00400000, + 0x0201f800, 0x00104717, 0x59a0001d, 0x84000540, + 0x4803401d, 0x49f3c857, 0x0201f000, 0x00102066, + 0x00000018, 0x0000000c, 0x00000018, 0x00000020, + 0x836c0580, 0x00000000, 0x04020005, 0x42000800, + 0x00000007, 0x0201f000, 0x001020b2, 0x42000800, + 0x00000020, 0x59a00407, 0x59a01207, 0x900811c0, + 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, + 0x800c1d40, 0x419c0000, 0x0201f000, 0x00103841, + 0x800409c0, 0x04000005, 0x4a034406, 0x00000001, + 0x0201f000, 0x001020b2, 0x0201f800, 0x00104e0d, + 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, + 0x001020b2, 0x59a80013, 0x8c000500, 0x04000011, + 0x4a034406, 0x00000000, 0x42000800, 0x00000020, + 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, + 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, + 0x42000000, 0x0010bc20, 0x0201f000, 0x00103841, + 0x4a034406, 0x00000001, 0x4200b000, 0x00000020, + 0x4200a800, 0x0010bc20, 0x4200a000, 0xffffffff, + 0x4450a800, 0x8054a800, 0x8058b040, 0x040207fd, + 0x4d440000, 0x4d340000, 0x42028800, 0xffffffff, + 0x42002000, 0xffffffff, 0x42003000, 0x00000001, + 0x42003800, 0x00000001, 0x42001800, 0x0010bc20, + 0x59a81010, 0x82081500, 0x000000ff, 0x40180000, + 0x0c01f001, 0x00103275, 0x00103278, 0x0010327c, + 0x00103280, 0x82102500, 0xffffff00, 0x0401f014, + 0x82102500, 0xffff00ff, 0x840811c0, 0x0401f010, + 0x82102500, 0xff00ffff, 0x900811c0, 0x0401f00c, + 0x82102500, 0x00ffffff, 0x9c0801c0, 0x80102540, + 0x44101800, 0x42003000, 0xffffffff, 0x42002000, + 0xffffffff, 0x800c1800, 0x0401f003, 0x40080000, + 0x80102540, 0x81468800, 0x83442c80, 0x0000007f, + 0x04021014, 0x4c080000, 0x4c0c0000, 0x4c180000, + 0x4c1c0000, 0x0201f800, 0x00020267, 0x5c003800, + 0x5c003000, 0x5c001800, 0x5c001000, 0x040207f2, + 0x0201f800, 0x00104842, 0x040207ef, 0x80183000, + 0x801c3800, 0x59341202, 0x40180000, 0x0c01f7ce, + 0x82100580, 0xffffffff, 0x04000002, 0x44101800, + 0x42001800, 0x0010bc20, 0x500c0000, 0x82000500, + 0xffffff00, 0x801c0540, 0x44001800, 0x5c026800, + 0x5c028800, 0x42000800, 0x00000020, 0x59a00407, + 0x59a01207, 0x900811c0, 0x80081540, 0x59a00409, + 0x59a01a09, 0x900c19c0, 0x800c1d40, 0x42000000, + 0x0010bc20, 0x0201f000, 0x00103841, 0x59a28c06, + 0x59a0020b, 0x8c000500, 0x0400000e, 0x59a01208, + 0x59a00408, 0x82000500, 0x000000ff, 0x900001c0, + 0x80081540, 0x41784000, 0x0201f800, 0x00104768, + 0x04000008, 0x48034406, 0x0201f000, 0x001020b6, + 0x0201f800, 0x00020267, 0x02020000, 0x001020b6, + 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x001020b2, 0x59a0020b, + 0x8c000500, 0x04000005, 0x0201f800, 0x00104842, + 0x02020000, 0x001038dd, 0x59a0020b, 0x8c000502, + 0x04000019, 0x83440480, 0x000007f0, 0x04021016, + 0x0201f800, 0x0010484b, 0x04020013, 0x497a5a04, + 0x4a025c04, 0x00008000, 0x0201f800, 0x00108ea3, + 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, + 0x001020b2, 0x4a01d809, 0x001032f8, 0x1c01f000, + 0x59a28c06, 0x0201f800, 0x00020267, 0x02020000, + 0x001020b6, 0x4c580000, 0x4c500000, 0x4c540000, + 0x4200b000, 0x0000000a, 0x4134a000, 0x832e5c00, + 0x00000002, 0x412ca800, 0x0201f800, 0x0010a93e, + 0x832cac00, 0x00000006, 0x4054a000, 0x4200b000, + 0x00000004, 0x0201f800, 0x0010a94f, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x592c0802, 0x82040500, + 0x00ff00ff, 0x900001c0, 0x82041500, 0xff00ff00, + 0x80080540, 0x48025802, 0x592c0801, 0x82040500, + 0x00ff00ff, 0x900001c0, 0x82041500, 0xff00ff00, + 0x80080540, 0x48025801, 0x42000800, 0x0000000a, + 0x59a00407, 0x59a01207, 0x900811c0, 0x80081540, + 0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40, + 0x412c0000, 0x0201f000, 0x00103841, 0x496fc857, + 0x496f4406, 0x0201f000, 0x00102066, 0x59a28c06, + 0x0201f800, 0x00020267, 0x02020000, 0x001020b6, + 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, + 0x00000007, 0x0201f000, 0x001020b2, 0x83340c00, + 0x00000006, 0x59a0020b, 0x8c000500, 0x04000003, + 0x83340c00, 0x00000008, 0x58040001, 0x48034409, + 0x900001c0, 0x48034209, 0x50040000, 0x48034407, + 0x900001c0, 0x48034207, 0x59340200, 0x48034406, + 0x0201f000, 0x00102066, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x59a0220b, 0x8c102500, 0x0402002e, 0x8c102506, + 0x04020006, 0x59a03208, 0x82180480, 0x00000003, + 0x02021000, 0x001020b6, 0x59a28c06, 0x0201f800, + 0x00020267, 0x02020000, 0x001020b6, 0x0201f800, + 0x00104836, 0x04000005, 0x4a034406, 0x00000009, + 0x0201f000, 0x001020b2, 0x0201f800, 0x0010381a, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x001020b2, 0x59a0220b, 0x8c102506, 0x04000004, + 0x59343002, 0x82183500, 0x00ffffff, 0x497a5a04, + 0x4a025c04, 0x00008000, 0x0201f800, 0x00108e65, + 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, + 0x001020b2, 0x4a01d809, 0x001033de, 0x1c01f000, + 0x59a28c06, 0x0201f800, 0x00020267, 0x02020000, + 0x001020b6, 0x0201f800, 0x00104836, 0x04000005, + 0x4a034406, 0x00000009, 0x0201f000, 0x001020b2, + 0x0201f800, 0x0010381a, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x001020b2, 0x497a5a04, + 0x4a025c04, 0x00008000, 0x0201f800, 0x0010381a, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x001020b2, 0x592e5800, 0x0201f800, 0x00108e7a, + 0x04020005, 0x4a034406, 0x00000003, 0x0201f000, + 0x001020b2, 0x4a01d809, 0x001033b0, 0x1c01f000, + 0x592c2805, 0x82140d80, 0x01000000, 0x04020005, + 0x4a034406, 0x00000004, 0x0201f000, 0x001020b2, + 0x42000800, 0x00000008, 0x59a00207, 0x59a01407, + 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, + 0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005, + 0x0201f800, 0x00103841, 0x8c142d00, 0x04000003, + 0x4a01d809, 0x001033cb, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580e, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x812e59c0, + 0x02000800, 0x00100615, 0x42000800, 0x00000008, + 0x832c0400, 0x00000005, 0x58ec1007, 0x58ec1808, + 0x0201f000, 0x00103841, 0x592c0005, 0x82000580, + 0x01000000, 0x04020005, 0x4a034406, 0x00000004, + 0x0201f000, 0x001020b2, 0x59a00207, 0x59a01407, + 0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09, + 0x900001c0, 0x800c1d40, 0x42000800, 0x00000006, + 0x832c0400, 0x00000006, 0x0201f000, 0x00103841, + 0x59a00a0a, 0x800409c0, 0x02000000, 0x001020b6, + 0x82040480, 0x000000e8, 0x04001003, 0x42000800, + 0x000000e7, 0x59a00207, 0x59a01407, 0x900001c0, + 0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0, + 0x800c1d40, 0x83880400, 0x00000000, 0x0201f800, + 0x00103841, 0x4a01d809, 0x0010340c, 0x1c01f000, + 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x59a0020b, + 0x8c000500, 0x04000008, 0x83880400, 0x00000000, + 0x4803c840, 0x4a03c842, 0x00000006, 0x04011000, + 0x497b8885, 0x4a034207, 0x000000e7, 0x0201f000, + 0x00102066, 0x800409c0, 0x04000005, 0x4a034406, + 0x00000001, 0x0201f000, 0x001020b2, 0x0401fbf3, + 0x04020005, 0x4a034406, 0x00000002, 0x0201f000, + 0x001020b2, 0x497a5a04, 0x4a025c04, 0x00008000, + 0x59a00406, 0x800001c0, 0x02000000, 0x001020b6, + 0x82001580, 0x000000ff, 0x04000005, 0x82001480, + 0x00000004, 0x02021000, 0x001020b6, 0x40001000, + 0x0201f800, 0x00101d6a, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x001020b2, 0x4a01d809, + 0x00103446, 0x1c01f000, 0x592c0005, 0x82000580, + 0x01000000, 0x02020000, 0x00102066, 0x4a034406, + 0x00000004, 0x0201f000, 0x001020b2, 0x59a01406, + 0x8c081508, 0x04020007, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x59a01c07, 0x820c0480, 0x00001000, 0x02021000, + 0x001020b6, 0x497b2804, 0x497b2805, 0x497b281c, + 0x497b281d, 0x497b281f, 0x497b2820, 0x497b2822, + 0x497b2823, 0x80000580, 0x0201f800, 0x00101668, + 0x59a80805, 0x8c081500, 0x04000004, 0x82040d40, + 0x00000011, 0x0401f004, 0x8c081506, 0x04000002, + 0x84040d42, 0x84040d0a, 0x48075005, 0x4202d800, + 0x00000001, 0x82081500, 0x000000e0, 0x8008010a, + 0x0c020036, 0x0201f800, 0x00104e0d, 0x04020009, + 0x4a035033, 0x00000001, 0x0201f800, 0x00104d76, + 0x0401f01f, 0x4a035033, 0x00000000, 0x0401f7fb, + 0x497b5032, 0x0201f800, 0x00103f5c, 0x0201f800, + 0x0010698c, 0x0201f800, 0x00106c32, 0x0201f800, + 0x00106982, 0x59a00a07, 0x480788a7, 0x59c400a3, + 0x82000500, 0xfeffffff, 0x82000540, 0x80018000, + 0x40000800, 0x84040d20, 0x480388a3, 0x480788a3, + 0x497b504e, 0x42000800, 0x0000002d, 0x42001000, + 0x00103fe4, 0x0201f800, 0x00105ca2, 0x59a00407, + 0x800000c2, 0x800008c4, 0x8005d400, 0x42000000, + 0x0000ffff, 0x0201f800, 0x00104e0d, 0x04000003, + 0x59a00207, 0x80000110, 0x0201f800, 0x00103915, + 0x0201f000, 0x00102066, 0x00103479, 0x0010347c, + 0x00103484, 0x001020b6, 0x00103481, 0x001020b6, + 0x001020b6, 0x001020b6, 0x836c0580, 0x00000003, + 0x04000005, 0x4a034406, 0x00000007, 0x0201f000, + 0x001020b2, 0x59a03c06, 0x59a00407, 0x59a04a07, + 0x902449c0, 0x80244d40, 0x59a00409, 0x59a05209, + 0x902851c0, 0x80285540, 0x0401fb54, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x417a8800, 0x41783000, 0x497b4001, 0x497b4004, + 0x832c4400, 0x00000005, 0x48234002, 0x8c1c3d04, + 0x04020078, 0x0201f800, 0x00020267, 0x0402002a, + 0x0201f800, 0x00104836, 0x04000004, 0x0201f800, + 0x00104732, 0x04020024, 0x8c1c3d00, 0x04000008, + 0x59340009, 0x44004000, 0x59340008, 0x80204000, + 0x44004000, 0x80204000, 0x0401f007, 0x59340007, + 0x44004000, 0x59340006, 0x80204000, 0x44004000, + 0x80204000, 0x83440580, 0x000007fe, 0x0400000d, + 0x83440580, 0x000007fc, 0x0400000a, 0x0201f800, + 0x00104842, 0x04000003, 0x85468d5e, 0x0401f005, + 0x0201f800, 0x00104686, 0x04020002, 0x85468d5e, + 0x45444000, 0x85468d1e, 0x80204000, 0x82183400, + 0x00000003, 0x81468800, 0x83440480, 0x000007f0, + 0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580, + 0x000007f0, 0x04020004, 0x42028800, 0x000007fe, + 0x0401f006, 0x83440580, 0x000007ff, 0x04020007, + 0x42028800, 0x000007fc, 0x82180580, 0x0000000f, + 0x0400000b, 0x0401f7c0, 0x801831c0, 0x04020006, + 0x59a00801, 0x800408c4, 0x48074406, 0x0201f000, + 0x00102066, 0x4a034004, 0x00000001, 0x49474000, + 0x59a00001, 0x80180400, 0x48034001, 0x481f4003, + 0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002, + 0x4801d803, 0x4825d807, 0x4829d808, 0x4000a800, + 0x4000a000, 0x4018b000, 0x0201f800, 0x0010a93e, + 0x40ec1000, 0x0201f800, 0x001008a1, 0x4a01d809, + 0x00103536, 0x1c01f000, 0x4031d800, 0x58ef400b, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x001020aa, 0x59a00004, 0x80000540, 0x04020008, + 0x59a28800, 0x59a04002, 0x59a03803, 0x41783000, + 0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801, + 0x800408c4, 0x48074406, 0x0201f000, 0x00102066, + 0x0201f800, 0x00020267, 0x0402002f, 0x0201f800, + 0x00104836, 0x04000004, 0x0201f800, 0x00104732, + 0x04020029, 0x83440580, 0x000007fe, 0x04000011, + 0x83440580, 0x000007fc, 0x0400000e, 0x0201f800, + 0x00104842, 0x04000005, 0x59340403, 0x8400055e, + 0x48026c03, 0x0401f007, 0x0201f800, 0x00104686, + 0x04020004, 0x59340403, 0x8400055e, 0x48026c03, + 0x4134a000, 0x4020a800, 0x4200b000, 0x00000006, + 0x0201f800, 0x0010a93e, 0x59340007, 0x4400a800, + 0x59340006, 0x4800a801, 0x59340009, 0x4800a802, + 0x59340008, 0x4800a803, 0x59340403, 0x8400051e, + 0x48026c03, 0x82204400, 0x0000000a, 0x82183400, + 0x0000000a, 0x81468800, 0x83440480, 0x000007f0, + 0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580, + 0x000007f0, 0x04020004, 0x42028800, 0x000007fe, + 0x0401f006, 0x83440580, 0x000007ff, 0x04020007, + 0x42028800, 0x000007fc, 0x82180580, 0x0000000a, + 0x0400000b, 0x0401f7bb, 0x801831c0, 0x04020006, + 0x59a00801, 0x800408c4, 0x48074406, 0x0201f000, + 0x00102066, 0x4a034004, 0x00000001, 0x49474000, + 0x59a00001, 0x80180400, 0x48034001, 0x481f4003, + 0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002, + 0x4801d803, 0x4825d807, 0x4829d808, 0x40ec1000, + 0x0201f800, 0x001008a1, 0x4a01d809, 0x001035ad, + 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002, + 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x59a00004, 0x80000540, 0x04020008, 0x59a28800, + 0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807, + 0x58ec5008, 0x0401f78f, 0x59a00801, 0x800408c4, + 0x48074406, 0x0201f000, 0x00102066, 0x42002800, + 0x0000007e, 0x59a00c06, 0x59a01207, 0x59a01c07, + 0x59a02209, 0x82040500, 0x0000ff00, 0x840001c0, + 0x82003480, 0x00000020, 0x02001000, 0x001020b6, + 0x80140480, 0x02001000, 0x001020b6, 0x82040500, + 0x000000ff, 0x82003480, 0x00000020, 0x02001000, + 0x001020b6, 0x80140480, 0x02001000, 0x001020b6, + 0x82080500, 0x0000ff00, 0x840001c0, 0x82003480, + 0x00000020, 0x02001000, 0x001020b6, 0x80140480, + 0x02001000, 0x001020b6, 0x82080500, 0x000000ff, + 0x82003480, 0x00000020, 0x02001000, 0x001020b6, + 0x80140480, 0x02001000, 0x001020b6, 0x820c0500, + 0x0000ff00, 0x840001c0, 0x82003480, 0x00000020, + 0x02001000, 0x001020b6, 0x80140480, 0x02001000, + 0x001020b6, 0x820c0500, 0x000000ff, 0x82003480, + 0x00000020, 0x02001000, 0x001020b6, 0x80140480, + 0x02001000, 0x001020b6, 0x82100500, 0x0000ff00, + 0x840001c0, 0x82003480, 0x00000020, 0x02001000, + 0x001020b6, 0x80140480, 0x02001000, 0x001020b6, + 0x82100500, 0x000000ff, 0x82003480, 0x00000020, + 0x02001000, 0x001020b6, 0x80140480, 0x02001000, + 0x001020b6, 0x900401c0, 0x80080d40, 0x900c01c0, + 0x80101d40, 0x83a83400, 0x0000003a, 0x44043000, + 0x80183000, 0x440c3000, 0x0201f000, 0x00102066, + 0x0401f9fa, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x001020b2, 0x42000800, 0x0000000c, + 0x0401f853, 0x4a01d809, 0x0010362c, 0x1c01f000, + 0x4031d800, 0x58ee580d, 0x58ef400b, 0x58ec0002, + 0x82000580, 0x00000200, 0x02000000, 0x001020aa, + 0x832ca400, 0x00000004, 0x4200b000, 0x0000000c, + 0x40c8a800, 0x0201f800, 0x0010a93e, 0x58c80200, + 0x80000540, 0x04000034, 0x58c80400, 0x82000500, + 0xfffffffb, 0x04020030, 0x58c80401, 0x80000540, + 0x0400002d, 0x82000480, 0x0000ff01, 0x0402102a, + 0x58c80202, 0x82000480, 0x0000005c, 0x04001026, + 0x0201f800, 0x001060db, 0x58c80c08, 0x58c80204, + 0x80040480, 0x04001020, 0x58c80204, 0x82000480, + 0x00000005, 0x0402101c, 0x58c80205, 0x58c80c08, + 0x80040902, 0x80040480, 0x04001017, 0x58c80c08, + 0x0201f800, 0x0010602a, 0x0400001b, 0x0201f800, + 0x00105ef2, 0x04020012, 0x4979940b, 0x59c408a3, + 0x82040d40, 0x00000002, 0x480788a3, 0x4a038830, + 0x00000001, 0x4a038832, 0x01ffffff, 0x58c80202, + 0x48030804, 0x0201f800, 0x00105ed4, 0x0201f000, + 0x00102066, 0x0201f000, 0x001020b6, 0x0201f800, + 0x0010612d, 0x0201f800, 0x0010613a, 0x0201f800, + 0x0010601d, 0x0201f000, 0x001020b2, 0x4c000000, + 0x59a01207, 0x59a00407, 0x900811c0, 0x80081540, + 0x59a01a09, 0x59a00409, 0x900c19c0, 0x800c1d40, + 0x5c000000, 0x0401f1b9, 0x59840000, 0x82000580, + 0x00000000, 0x04000050, 0x59840002, 0x8c000504, + 0x0400004d, 0x84000546, 0x48030802, 0x0201f800, + 0x0010601d, 0x59c408a3, 0x82040d00, 0xfffffffd, + 0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010aa00, + 0x505e6800, 0x813669c0, 0x04000008, 0x5936600e, + 0x813261c0, 0x04000005, 0x0201f800, 0x0010600e, + 0x02000800, 0x001061e5, 0x805cb800, 0x825c0580, + 0x0010b1f0, 0x040207f3, 0x59866003, 0x813261c0, + 0x0400000b, 0x59300406, 0x82000580, 0x00000009, + 0x02020800, 0x00100615, 0x5930b800, 0x0201f800, + 0x00105ffa, 0x405e6000, 0x0401f7f5, 0x497b0803, + 0x4200b800, 0x0010b317, 0x505e6000, 0x813261c0, + 0x04000011, 0x59300406, 0x82000580, 0x00000009, + 0x0402000d, 0x59300203, 0x82000580, 0x00000004, + 0x04020009, 0x59326809, 0x813669c0, 0x02020800, + 0x00100615, 0x0201f800, 0x00100ee4, 0x0201f800, + 0x00105ffa, 0x4578b800, 0x805cb800, 0x825c0580, + 0x0010b31f, 0x040207e9, 0x42000800, 0x0010b315, + 0x49780801, 0x49780800, 0x0201f800, 0x0010612d, + 0x0201f800, 0x0010613a, 0x5c00b800, 0x0201f800, + 0x00105eed, 0x0201f000, 0x00102066, 0x836c0580, + 0x00000003, 0x04000005, 0x4a034406, 0x00000007, + 0x0201f000, 0x001020b2, 0x59a00407, 0x59a02207, + 0x901021c0, 0x80102540, 0x59a00409, 0x59a02a09, + 0x901429c0, 0x80142d40, 0x0401f930, 0x04020005, + 0x4a034406, 0x00000002, 0x0201f000, 0x001020b2, + 0x417a8800, 0x41781800, 0x497b4001, 0x497b4003, + 0x832c3400, 0x00000004, 0x481b4002, 0x41440000, + 0x81ac0400, 0x50026800, 0x813669c0, 0x0400000b, + 0x0201f800, 0x00104836, 0x04020008, 0x59340002, + 0x48003000, 0x49443001, 0x82183400, 0x00000002, + 0x820c1c00, 0x00000002, 0x81468800, 0x83440480, + 0x00000800, 0x04000005, 0x820c0480, 0x00000010, + 0x0402100b, 0x0401f7ea, 0x800c19c0, 0x04020006, + 0x59a00801, 0x80040902, 0x48074406, 0x0201f000, + 0x00102066, 0x4a034003, 0x00000001, 0x49474000, + 0x59a00001, 0x800c0400, 0x48034001, 0x40ec1000, + 0x4a001001, 0x00000000, 0x480c1004, 0x59a00002, + 0x48001003, 0x48101007, 0x48141008, 0x0201f800, + 0x001008a1, 0x4a01d809, 0x00103728, 0x1c01f000, + 0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x59a00003, + 0x80000540, 0x04020008, 0x59a28800, 0x59a03002, + 0x41781800, 0x40ec1000, 0x58082007, 0x58082808, + 0x0401f7bf, 0x59a00801, 0x80040902, 0x48074406, + 0x0201f000, 0x00102066, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x59a80026, 0x8c00050a, 0x04020007, 0x8c000506, + 0x04020005, 0x4a034406, 0x00000016, 0x0201f000, + 0x001020b2, 0x0401f8cd, 0x04020005, 0x4a034406, + 0x00000002, 0x0201f000, 0x001020b2, 0x59a00c06, + 0x80040902, 0x59a00407, 0x59a01207, 0x900811c0, + 0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0, + 0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8df, + 0x4a01d809, 0x00103763, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x592c0009, + 0x0201f800, 0x001059b9, 0x02000800, 0x001043fc, + 0x02020000, 0x001020b6, 0x49474001, 0x481a6802, + 0x592c000a, 0x82001d80, 0x70000000, 0x04020007, + 0x0401f8a2, 0x04020011, 0x4a034406, 0x00000002, + 0x0201f000, 0x001020b2, 0x82001d80, 0x72000000, + 0x02020000, 0x001020b6, 0x0401f898, 0x04020897, + 0x04020896, 0x04020005, 0x4a034406, 0x00000002, + 0x0201f000, 0x001020b2, 0x58ee580d, 0x4a025c04, + 0x00008000, 0x497a5a04, 0x592c3208, 0x80183102, + 0x592c1801, 0x4a001805, 0x01000000, 0x0201f800, + 0x00108e8e, 0x04020005, 0x4a034406, 0x00000003, + 0x0201f000, 0x001020b2, 0x4a01d809, 0x0010379d, + 0x1c01f000, 0x592c4000, 0x592c0005, 0x82000580, + 0x01000000, 0x04020005, 0x4a034406, 0x00000004, + 0x0201f000, 0x001020b2, 0x4c580000, 0x4c500000, + 0x4c540000, 0x832c3c00, 0x00000005, 0x401ca000, + 0x401ca800, 0x5820280a, 0x4200b000, 0x00000002, + 0x82143580, 0x70000000, 0x04000003, 0x4200b000, + 0x0000000f, 0x0201f800, 0x0010a94f, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x401c0000, 0x58201006, + 0x58201807, 0x58202205, 0x80102102, 0x82143580, + 0x70000000, 0x04020008, 0x82103480, 0x00000002, + 0x02001000, 0x001020b6, 0x42000800, 0x00000002, + 0x0401f079, 0x82143580, 0x72000000, 0x02020000, + 0x001020b6, 0x82103480, 0x0000002a, 0x02001000, + 0x001020b6, 0x42000800, 0x0000000f, 0x0401f86e, + 0x4a01d809, 0x001037d7, 0x1c01f000, 0x4031d800, + 0x58ef400b, 0x58ee580e, 0x58ec0002, 0x82000580, + 0x00000200, 0x02000000, 0x001020aa, 0x592e5800, + 0x832c0c00, 0x00000005, 0x4c580000, 0x4c500000, + 0x4c540000, 0x4004a000, 0x4004a800, 0x4200b000, + 0x0000000f, 0x0201f800, 0x0010a94f, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x40ec1000, 0x4a001001, + 0x00000000, 0x4a001004, 0x0000000f, 0x48041003, + 0x0201f800, 0x001008a1, 0x4a01d809, 0x001037f9, + 0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e, + 0x58ec0002, 0x82000580, 0x00000200, 0x02000000, + 0x001020aa, 0x832c0c00, 0x00000005, 0x4c580000, + 0x4c500000, 0x4c540000, 0x4004a000, 0x4004a800, + 0x4200b000, 0x0000000c, 0x0201f800, 0x0010a94f, + 0x5c00a800, 0x5c00a000, 0x5c00b000, 0x40ec1000, + 0x4a001001, 0x00000000, 0x4a001004, 0x0000000c, + 0x48041003, 0x0201f800, 0x001008a1, 0x4a01d809, + 0x0010205f, 0x1c01f000, 0x0201f800, 0x0010082a, + 0x04000010, 0x497a5800, 0x58ec000d, 0x80000540, + 0x04020004, 0x492dd80d, 0x492dd80e, 0x0401f007, + 0x58ec000e, 0x48025800, 0x82000400, 0x00000001, + 0x452c0000, 0x492dd80e, 0x832c0400, 0x00000004, + 0x492fc857, 0x4803c857, 0x1c01f000, 0x4d2c0000, + 0x58ec400d, 0x802041c0, 0x04000008, 0x4823c857, + 0x40225800, 0x592c4001, 0x497a5801, 0x0201f800, + 0x0010083a, 0x0401f7f8, 0x4979d80d, 0x4979d80e, + 0x5c025800, 0x1c01f000, 0x42003000, 0x00000001, + 0x0401f003, 0x42003000, 0x00000000, 0x4803c857, + 0x4807c857, 0x480bc857, 0x480fc857, 0x481bc857, + 0x48efc857, 0x4819d801, 0x800409c0, 0x02000800, + 0x00100615, 0x4805d804, 0x4801d803, 0x4809d807, + 0x480dd808, 0x40ec1000, 0x0201f800, 0x001008a1, + 0x4a01d809, 0x0010205f, 0x1c01f000, 0x80002d80, + 0x480bc857, 0x480fc857, 0x4813c857, 0x4817c857, + 0x4d2c0000, 0x4da00000, 0x42034000, 0x0010b2a0, + 0x59a00017, 0x800001c0, 0x04020013, 0x04006012, + 0x480bc020, 0x480fc021, 0x4813c022, 0x4817c023, + 0x900811c0, 0x82081540, 0x00000012, 0x480bc011, + 0x59e00017, 0x8c000508, 0x04020004, 0x4203e000, + 0x30000001, 0x0401f053, 0x4a03c017, 0x00000002, + 0x0401f7fb, 0x4c040000, 0x4c1c0000, 0x80000800, + 0x48074017, 0x59a0381a, 0x481fc857, 0x801c39c0, + 0x04020027, 0x82000480, 0x0000000a, 0x04021010, + 0x59a00018, 0x80000000, 0x48034018, 0x59a00219, + 0x82000400, 0x00000002, 0x82000c80, 0x00000013, + 0x48034219, 0x04001003, 0x497b4219, 0x41780000, + 0x59a03816, 0x801c3c00, 0x0401f030, 0x4803c856, + 0x0201f800, 0x0010082a, 0x04000007, 0x492f401a, + 0x492f401b, 0x412c3800, 0x497b421c, 0x497a5813, + 0x0401f026, 0x59880052, 0x80000000, 0x48031052, + 0x59a00017, 0x80000040, 0x48034017, 0x59a00219, + 0x59a03816, 0x801c3c00, 0x0401f01c, 0x59a0021c, + 0x82000400, 0x00000002, 0x82000c80, 0x00000012, + 0x04021004, 0x4803421c, 0x801c3c00, 0x0401f013, + 0x0201f800, 0x0010082a, 0x0402000b, 0x59880052, + 0x80000000, 0x48031052, 0x59a00017, 0x80000040, + 0x48034017, 0x4803c856, 0x59a0021c, 0x801c3c00, + 0x0401f006, 0x492f401a, 0x492c3813, 0x412c3800, + 0x497b421c, 0x497a5813, 0x48083c00, 0x480c3a00, + 0x48103c01, 0x48143a01, 0x5c003800, 0x5c000800, + 0x5c034000, 0x5c025800, 0x1c01f000, 0x480fc857, + 0x4813c857, 0x481bc857, 0x42000000, 0x0010b611, + 0x0201f800, 0x0010a86e, 0x801800d0, 0x40002800, + 0x42001000, 0x00008014, 0x0401f786, 0x4c000000, + 0x599c0017, 0x8c000512, 0x5c000000, 0x1c01f000, + 0x4c000000, 0x599c0018, 0x8c00050e, 0x5c000000, + 0x1c01f000, 0x59a80821, 0x800409c0, 0x04000005, + 0x4a034406, 0x00000001, 0x0201f000, 0x001020b2, + 0x836c0580, 0x00000003, 0x04000005, 0x4a034406, + 0x00000007, 0x0201f000, 0x001020b2, 0x599c0017, + 0x8c00050a, 0x04000005, 0x4a034406, 0x00000008, + 0x0201f000, 0x001020b2, 0x59340405, 0x8c000508, + 0x04020004, 0x8c00050a, 0x02020000, 0x001032e2, + 0x497a5a04, 0x497a5805, 0x4a025c04, 0x00008000, + 0x0201f800, 0x00108f2d, 0x04020005, 0x4a034406, + 0x00000003, 0x0201f000, 0x001020b2, 0x4a01d809, + 0x00103906, 0x1c01f000, 0x592c0005, 0x82000580, + 0x01000000, 0x04020005, 0x4a034406, 0x00000004, + 0x0201f000, 0x001020b2, 0x59a28c06, 0x0201f800, + 0x00020267, 0x02020000, 0x001020b6, 0x0201f000, + 0x001032e2, 0x82001580, 0x0000ffff, 0x04000009, + 0x0201f800, 0x001059b9, 0x02000800, 0x00020267, + 0x0402000c, 0x0201f800, 0x00105ce7, 0x0401f009, + 0x42028800, 0x000007ef, 0x0201f800, 0x00020267, + 0x02000800, 0x00105ce7, 0x81468840, 0x040217fb, + 0x1c01f000, 0x4803c856, 0x4c0c0000, 0x4d340000, + 0x4d440000, 0x42028800, 0x000007fe, 0x0201f800, + 0x00020267, 0x04020009, 0x5934180a, 0x820c1d00, + 0x00000001, 0x820c1d80, 0x00000001, 0x42001000, + 0x0000801b, 0x0401ff1e, 0x5c028800, 0x5c026800, + 0x5c001800, 0x1c01f000, 0x599c0017, 0x8c000508, + 0x1c01f000, 0x48efc857, 0x04011000, 0x48efc840, + 0x4a03c842, 0x00000011, 0x40000000, 0x040117ff, + 0x4a01d80f, 0xbeefbeef, 0x1c01f000, 0x497b4000, + 0x497b4001, 0x497b4002, 0x497b4003, 0x497b4004, + 0x1c01f000, 0x59c400a4, 0x4c580000, 0x4c500000, + 0x4c540000, 0x82000500, 0x0000000f, 0x82000480, + 0x00000007, 0x0400100a, 0x82006c80, 0x00000007, + 0x02021800, 0x00100615, 0x0c01f807, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x1c01f000, 0x0401f90c, + 0x0401f7fb, 0x0010396c, 0x00103972, 0x00103997, + 0x001039b9, 0x00103a78, 0x0010396b, 0x1c01f000, + 0x59c40806, 0x8c040d00, 0x04020003, 0x84040d40, + 0x48078806, 0x1c01f000, 0x59c40005, 0x8c000534, + 0x02020000, 0x001040ce, 0x4a038805, 0xffffffff, + 0x42006000, 0x00020000, 0x0201f800, 0x001040b2, + 0x59a80015, 0x82000500, 0xfffffffa, 0x84000542, + 0x48035015, 0x497b5026, 0x42000800, 0x0010bc20, + 0x45780800, 0x497b5013, 0x42006000, 0xffefffff, + 0x42006800, 0x40000000, 0x0201f800, 0x001040ad, + 0x59c40006, 0x82000500, 0xffffff0f, 0x48038806, + 0x42000800, 0x00000010, 0x42001000, 0x0010401b, + 0x0201f800, 0x00105cbc, 0x0401f001, 0x42006000, + 0xffffffff, 0x42006800, 0x00800000, 0x0201f800, + 0x001040ad, 0x4200b000, 0x000000c8, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000580, 0x0000000a, + 0x0400000f, 0x8058b040, 0x040207f9, 0x497b5014, + 0x42006000, 0xbf7fffff, 0x42006800, 0x00018000, + 0x0201f800, 0x001040ad, 0x42006000, 0xfffeffff, + 0x41786800, 0x0201f000, 0x001040ad, 0x497b5014, + 0x4a035012, 0x00000000, 0x80000580, 0x0201f000, + 0x001040b9, 0x4a038805, 0xffffffff, 0x59a80012, + 0x82000c80, 0x00000004, 0x02021800, 0x00100615, + 0x0c01f001, 0x001039c4, 0x001039f1, 0x00103a6e, + 0x4803c856, 0x59c400a3, 0x8400051e, 0x480388a3, + 0x4a035012, 0x00000001, 0x59c40008, 0x8400054e, + 0x48038808, 0x0201f800, 0x00104093, 0x42007800, + 0x0010b34a, 0x4a007806, 0x11010000, 0x4200a000, + 0x0010b202, 0x4200a800, 0x0010b351, 0x4200b000, + 0x00000002, 0x0201f800, 0x0010a93e, 0x497b8802, + 0x42000800, 0x00000003, 0x497b504a, 0x0201f800, + 0x00103f8e, 0x4a03504a, 0x00000001, 0x497b5016, + 0x0201f800, 0x001040c0, 0x42006000, 0xffffffff, + 0x42006800, 0x00080000, 0x0201f800, 0x001040ad, + 0x42006000, 0xfff7ffff, 0x41786800, 0x0201f000, + 0x001040ad, 0x59a80016, 0x497b5016, 0x80002540, + 0x0400006a, 0x59c40004, 0x82000500, 0x00000003, + 0x04020075, 0x59a80815, 0x8c040d02, 0x0400004f, + 0x82100580, 0x0000000c, 0x04020053, 0x82100400, + 0x00000018, 0x8000b104, 0x41cc1000, 0x42001800, + 0x0010b34a, 0x50080800, 0x500c0000, 0x80040580, + 0x0402001e, 0x80081000, 0x800c1800, 0x8058b040, + 0x040207f9, 0x0201f800, 0x001040c0, 0x42006000, + 0xffffffff, 0x42006800, 0x00500000, 0x0201f800, + 0x001040ad, 0x4a035012, 0x00000002, 0x4a035014, + 0x00000002, 0x0201f800, 0x0010164b, 0x42000800, + 0x000007d0, 0x42001000, 0x00103f62, 0x0201f800, + 0x00105da7, 0x59a80015, 0x84000506, 0x48035015, + 0x0201f000, 0x00104093, 0x59cc0806, 0x82040d80, + 0x11010000, 0x04020028, 0x59cc0800, 0x82040500, + 0x00ffffff, 0x0400001a, 0x82000580, 0x000000ef, + 0x04020017, 0x59cc0801, 0x82040500, 0x00ffffff, + 0x82000580, 0x000000ef, 0x04020011, 0x83cca400, + 0x00000007, 0x4200a800, 0x0010b202, 0x4200b000, + 0x00000002, 0x50500800, 0x50540000, 0x80040480, + 0x04001007, 0x04020010, 0x8050a000, 0x8054a800, + 0x8058b040, 0x040207f8, 0x0401f00b, 0x59a80015, + 0x84000502, 0x48035015, 0x41cca000, 0x4200a800, + 0x0010b34a, 0x4200b000, 0x00000009, 0x0201f800, + 0x0010a93e, 0x0201f800, 0x001040c0, 0x42006000, + 0xffffffff, 0x42006800, 0x00080000, 0x0201f800, + 0x001040ad, 0x42006000, 0xfff7ffff, 0x41786800, + 0x0201f800, 0x001040ad, 0x42006000, 0xffffffff, + 0x42006800, 0x00004000, 0x0201f800, 0x001040ad, + 0x59c40004, 0x82000500, 0x00000003, 0x04020006, + 0x497b5016, 0x42000800, 0x00000003, 0x0201f000, + 0x00103f8e, 0x1c01f000, 0x1c01f000, 0x59a80014, + 0x82006d80, 0x0000000f, 0x04000005, 0x82000580, + 0x0000001b, 0x02020800, 0x00103f53, 0x1c01f000, + 0x59a80015, 0x84000506, 0x48035015, 0x497b504a, + 0x59a80014, 0x82000c80, 0x0000001e, 0x02021800, + 0x00100615, 0x0c01f001, 0x00103ab6, 0x00103acd, + 0x00103af6, 0x00103b11, 0x00103b34, 0x00103b65, + 0x00103b87, 0x00103bba, 0x00103bdc, 0x00103c00, + 0x00103c3c, 0x00103c63, 0x00103c79, 0x00103c8b, + 0x00103ca3, 0x00103cba, 0x00103cbf, 0x00103ce7, + 0x00103d0a, 0x00103d30, 0x00103d53, 0x00103d86, + 0x00103dc8, 0x00103df2, 0x00103e0a, 0x00103e4a, + 0x00103e63, 0x00103e76, 0x00103e77, 0x4803c856, + 0x4202d800, 0x00000007, 0x0201f800, 0x00104e0d, + 0x04000007, 0x42006000, 0xffffffd7, 0x41786800, + 0x0201f800, 0x001040ad, 0x0401f00b, 0x59c40006, + 0x82000500, 0xffffff0f, 0x48038806, 0x42001000, + 0x000000f0, 0x0201f800, 0x001019aa, 0x0201f800, + 0x00104d6c, 0x1c01f000, 0x4803c856, 0x42006000, + 0xbf7fffff, 0x42006800, 0x00400000, 0x0201f800, + 0x001040ad, 0x0201f800, 0x0010164b, 0x4a035014, + 0x00000001, 0x42001000, 0x0010401b, 0x0201f800, + 0x00105cdd, 0x0201f800, 0x00104024, 0x42000800, + 0x000007d0, 0x42001000, 0x00103f62, 0x0201f000, + 0x00105da7, 0x59a80016, 0x82000580, 0x00000014, + 0x04020023, 0x4803c857, 0x42006000, 0xffbfffff, + 0x41786800, 0x0201f800, 0x001040ad, 0x59c40004, + 0x82000500, 0x00000003, 0x04020019, 0x42001000, + 0x00103f62, 0x0201f800, 0x00105cc9, 0x59cc1006, + 0x82081580, 0x11020000, 0x04020012, 0x59cc1007, + 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, + 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, + 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, + 0x4a035014, 0x00000010, 0x0401f1cd, 0x1c01f000, + 0x0201f000, 0x00103f53, 0x4803c856, 0x4a035014, + 0x00000003, 0x42006000, 0xbf3fffff, 0x42006800, + 0x00100000, 0x0201f800, 0x001040ad, 0x42001000, + 0x0010401b, 0x0201f800, 0x00105cdd, 0x0201f800, + 0x00104024, 0x42001000, 0x00103f62, 0x0201f800, + 0x00105cc9, 0x42007800, 0x0010b350, 0x46007800, + 0x11020000, 0x42000800, 0x00000005, 0x0201f000, + 0x00103f8e, 0x59a80016, 0x80000540, 0x0400001e, + 0x4803c857, 0x42001000, 0x00103f62, 0x0201f800, + 0x00105cc9, 0x59a80016, 0x82000580, 0x00000014, + 0x04020016, 0x59cc1006, 0x82081580, 0x11020000, + 0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, + 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x84000544, 0x48035015, 0x4a035014, 0x00000004, + 0x0401f004, 0x1c01f000, 0x0201f000, 0x00103f53, + 0x4803c856, 0x4a035014, 0x00000005, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b350, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010a93e, 0x42007800, + 0x0010b350, 0x46007800, 0x11030000, 0x0201f800, + 0x00103f58, 0x04020014, 0x59a80015, 0x8c000500, + 0x04020011, 0x59a80810, 0x82040580, 0x00ffffff, + 0x0400000d, 0x82040d00, 0x000000ff, 0x82040400, + 0x00101eb5, 0x50000800, 0x80040910, 0x42001000, + 0x00000004, 0x0401fb95, 0x0400000b, 0x0201f800, + 0x0010403d, 0x4200b000, 0x00000004, 0x83cca400, + 0x00000007, 0x4200a800, 0x0010b351, 0x0201f800, + 0x0010a93e, 0x42000800, 0x00000005, 0x0201f000, + 0x00103f8e, 0x59a80016, 0x80000540, 0x0400001e, + 0x4803c857, 0x42001000, 0x00103f62, 0x0201f800, + 0x00105cc9, 0x59a80016, 0x82000580, 0x00000014, + 0x04020016, 0x59cc1006, 0x82081580, 0x11030000, + 0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, + 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x84000544, 0x48035015, 0x4a035014, 0x00000006, + 0x0401f003, 0x1c01f000, 0x0401f3cd, 0x4803c856, + 0x4a035014, 0x00000007, 0x83cca400, 0x00000006, + 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, + 0x0201f800, 0x0010a93e, 0x42007800, 0x0010b350, + 0x46007800, 0x11040000, 0x0401fbc2, 0x04020020, + 0x59a80015, 0x8c000500, 0x0402001d, 0x599c0017, + 0x8c000500, 0x0400001a, 0x599c1402, 0x82080480, + 0x0000007f, 0x02021800, 0x00100615, 0x4c080000, + 0x82081400, 0x00101eb5, 0x50081000, 0x82081500, + 0x000000ff, 0x480b5010, 0x42000800, 0x00000003, + 0x0201f800, 0x001069af, 0x5c000800, 0x42001000, + 0x00000004, 0x0401fb39, 0x04000005, 0x0401fd25, + 0x04000003, 0x0201f800, 0x00101668, 0x42000800, + 0x00000005, 0x0401f3d5, 0x59a80016, 0x80000540, + 0x0400001e, 0x4803c857, 0x42001000, 0x00103f62, + 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, + 0x00000014, 0x04020016, 0x59cc1006, 0x82081580, + 0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e, + 0x0400000b, 0x59a80015, 0x8c000504, 0x04020008, + 0x42000000, 0x0010b63d, 0x0201f800, 0x0010a86e, + 0x59a80015, 0x84000544, 0x48035015, 0x4a035014, + 0x00000008, 0x0401f003, 0x1c01f000, 0x0401f378, + 0x4803c856, 0x4a035014, 0x00000009, 0x83cca400, + 0x00000006, 0x4200a800, 0x0010b350, 0x4200b000, + 0x00000005, 0x0201f800, 0x0010a93e, 0x42007800, + 0x0010b350, 0x46007800, 0x11050100, 0x0401fb6d, + 0x0402000a, 0x59a80015, 0x8c000500, 0x04020007, + 0x0401fa88, 0x04020005, 0x82000540, 0x00000001, + 0x0201f800, 0x00101668, 0x42000800, 0x00000005, + 0x0401fb96, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00109640, 0x5c027800, 0x1c01f000, + 0x59a80016, 0x80000540, 0x04000038, 0x4803c857, + 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, + 0x59a80016, 0x82000580, 0x00000014, 0x04020030, + 0x59cc1006, 0x82080500, 0x11050000, 0x82000580, + 0x11050000, 0x0402002a, 0x8c081510, 0x04000014, + 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, + 0x8c000504, 0x04020008, 0x42000000, 0x0010b63d, + 0x0201f800, 0x0010a86e, 0x59a80015, 0x84000544, + 0x48035015, 0x4a035013, 0x00000001, 0x4a035014, + 0x0000000a, 0x0401f817, 0x0401f014, 0x80000540, + 0x04020013, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, + 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x84000544, 0x48035015, 0x497b5013, 0x4a035014, + 0x0000000e, 0x0401f06a, 0x1c01f000, 0x0401f318, + 0x4803c856, 0x4a035014, 0x0000000b, 0x42001000, + 0x0010b351, 0x4008a800, 0x4200b000, 0x00000020, + 0x4600a800, 0xffffffff, 0x8054a800, 0x8058b040, + 0x040207fc, 0x42007800, 0x0010b350, 0x46007800, + 0x11060000, 0x42001000, 0x0010b351, 0x0401fb09, + 0x04000005, 0x50080000, 0x46001000, 0x00ffffff, + 0x0401f00c, 0x50080800, 0x82040d00, 0x0000ffff, + 0x59a80010, 0x82000500, 0x000000ff, 0x82000540, + 0x00000100, 0x800000e0, 0x80040d40, 0x44041000, + 0x42000800, 0x00000021, 0x0401f32c, 0x59a80016, + 0x80000540, 0x04000012, 0x4803c857, 0x59a80016, + 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, + 0x59a80016, 0x82000580, 0x00000084, 0x04020009, + 0x59cc1006, 0x82081580, 0x11060000, 0x04020005, + 0x4a035014, 0x0000000c, 0x0401f003, 0x1c01f000, + 0x0401f2db, 0x4803c856, 0x4a035014, 0x0000000d, + 0x83cca400, 0x00000006, 0x4200a800, 0x0010b350, + 0x4200b000, 0x00000021, 0x0201f800, 0x0010a93e, + 0x42007800, 0x0010b350, 0x46007800, 0x11070000, + 0x42000800, 0x00000021, 0x0401f304, 0x59a80016, + 0x80000540, 0x04000014, 0x4803c857, 0x59a80016, + 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, + 0x82000580, 0x00000084, 0x0402000c, 0x59cc1006, + 0x82081580, 0x11070000, 0x04020008, 0x4a035013, + 0x00000001, 0x0401fa91, 0x4a035014, 0x0000000e, + 0x0401f003, 0x1c01f000, 0x0401f2b1, 0x4803c856, + 0x82040d40, 0x00000001, 0x0201f800, 0x001040b9, + 0x4a035014, 0x0000000f, 0x497b5016, 0x42006000, + 0xffffffff, 0x42006800, 0x00300000, 0x0401fbfe, + 0x42006000, 0xffdfffff, 0x41786800, 0x0401fbfa, + 0x42000800, 0x000007d0, 0x42001000, 0x00103f62, + 0x0201f000, 0x00105ca2, 0x4803c856, 0x59a80016, + 0x80000540, 0x04020296, 0x1c01f000, 0x4803c856, + 0x4a035014, 0x00000011, 0x83cca400, 0x00000006, + 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, + 0x0201f800, 0x0010a93e, 0x4200a800, 0x0010b350, + 0x4600a800, 0x11020000, 0x0401fa8a, 0x04020015, + 0x59a80010, 0x82000d00, 0xffff0000, 0x04000011, + 0x82000500, 0x000000ff, 0x0400000e, 0x82000c00, + 0x00101eb5, 0x50040800, 0x80040910, 0x82040580, + 0x0000007e, 0x04000007, 0x82040580, 0x00000080, + 0x04000004, 0x42001000, 0x00000004, 0x0401fa07, + 0x42000800, 0x00000005, 0x0401f2a8, 0x59a80016, + 0x80000540, 0x04000020, 0x4803c857, 0x42001000, + 0x00103f62, 0x0201f800, 0x00105cc9, 0x59a80016, + 0x82000580, 0x00000014, 0x04020016, 0x59cc1006, + 0x82081580, 0x11030000, 0x04020012, 0x59cc1007, + 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, + 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, + 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, + 0x4a035014, 0x00000012, 0x0401f804, 0x0401f002, + 0x0401fa4b, 0x1c01f000, 0x4803c856, 0x4a035014, + 0x00000013, 0x83cca400, 0x00000006, 0x4200a800, + 0x0010b350, 0x4200b000, 0x00000005, 0x0201f800, + 0x0010a93e, 0x4200a800, 0x0010b350, 0x4600a800, + 0x11030000, 0x0401fa3f, 0x04020013, 0x59a80015, + 0x8c000500, 0x04020010, 0x59a80810, 0x82040580, + 0x00ffffff, 0x0400000c, 0x82040d00, 0x000000ff, + 0x82040400, 0x00101eb5, 0x50000800, 0x80040910, + 0x42001000, 0x00000004, 0x0401f9c0, 0x04000002, + 0x0401fb11, 0x42000800, 0x00000005, 0x0401f25f, + 0x59a80016, 0x80000540, 0x04000020, 0x4803c857, + 0x42001000, 0x00103f62, 0x0201f800, 0x00105cc9, + 0x59a80016, 0x82000580, 0x00000014, 0x04020016, + 0x59cc1006, 0x82081580, 0x11040000, 0x04020012, + 0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015, + 0x8c000504, 0x04020008, 0x42000000, 0x0010b63d, + 0x0201f800, 0x0010a86e, 0x59a80015, 0x84000544, + 0x48035015, 0x4a035014, 0x00000014, 0x0401f804, + 0x0401f002, 0x0401fa02, 0x1c01f000, 0x4803c856, + 0x4a035014, 0x00000015, 0x83cca400, 0x00000006, + 0x4200a800, 0x0010b350, 0x4200b000, 0x00000005, + 0x0201f800, 0x0010a93e, 0x4200a800, 0x0010b350, + 0x4600a800, 0x11040000, 0x0401f9f6, 0x04020020, + 0x59a80015, 0x8c000500, 0x0402001d, 0x599c0017, + 0x8c000500, 0x0400001a, 0x599c1402, 0x82080480, + 0x0000007f, 0x02021800, 0x00100615, 0x4c080000, + 0x82081400, 0x00101eb5, 0x50081000, 0x82081500, + 0x000000ff, 0x480b5010, 0x42000800, 0x00000003, + 0x0201f800, 0x001069af, 0x5c000800, 0x42001000, + 0x00000004, 0x0401f96d, 0x04000005, 0x0201f800, + 0x001038d8, 0x02020800, 0x00101668, 0x42000800, + 0x00000005, 0x0401f209, 0x59a80016, 0x80000540, + 0x0400003f, 0x4803c857, 0x42001000, 0x00103f62, + 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, + 0x00000014, 0x04020035, 0x59cc1006, 0x82080500, + 0x11050000, 0x82000580, 0x11050000, 0x0402002f, + 0x8c081510, 0x04000010, 0x0401fb1f, 0x59cc1007, + 0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504, + 0x04020008, 0x42000000, 0x0010b63d, 0x0201f800, + 0x0010a86e, 0x59a80015, 0x84000544, 0x48035015, + 0x0401f013, 0x59cc1007, 0x8c08153e, 0x0400000b, + 0x59a80015, 0x8c000504, 0x04020008, 0x42000000, + 0x0010b63d, 0x0201f800, 0x0010a86e, 0x59a80015, + 0x84000544, 0x48035015, 0x82000540, 0x00000001, + 0x0401fb01, 0x497b5013, 0x0401f003, 0x4a035013, + 0x00000001, 0x59cc1007, 0x8c08153c, 0x04000003, + 0x4a035026, 0x00000008, 0x4a035014, 0x00000016, + 0x0401f804, 0x0401f002, 0x0401f98d, 0x1c01f000, + 0x4803c856, 0x83cca400, 0x00000006, 0x4200a800, + 0x0010b350, 0x4200b000, 0x00000005, 0x0201f800, + 0x0010a93e, 0x4a035014, 0x00000017, 0x59a80013, + 0x8c000500, 0x04000006, 0x42001000, 0x0010b350, + 0x46001000, 0x11050100, 0x0401f003, 0x4a035014, + 0x0000001b, 0x0401f97b, 0x0402000a, 0x59a80015, + 0x8c000500, 0x04020007, 0x0401f896, 0x04020005, + 0x82000540, 0x00000001, 0x0201f800, 0x00101668, + 0x42000800, 0x00000005, 0x0401f9a4, 0x4d3c0000, + 0x42027800, 0x00000001, 0x0201f800, 0x00109640, + 0x5c027800, 0x1c01f000, 0x59a80016, 0x80000540, + 0x04000015, 0x4803c857, 0x42001000, 0x00103f62, + 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, + 0x00000084, 0x0402000b, 0x59cc1006, 0x82081580, + 0x11060000, 0x04020007, 0x80000580, 0x0401fab6, + 0x4a035014, 0x00000018, 0x0401f804, 0x0401f002, + 0x0401f94b, 0x1c01f000, 0x4803c856, 0x4a035014, + 0x00000019, 0x83cca400, 0x00000006, 0x4200a800, + 0x0010b350, 0x4200b000, 0x00000021, 0x0201f800, + 0x0010a93e, 0x42003800, 0x0010b351, 0x0401f941, + 0x04020018, 0x401c2800, 0x50141000, 0x80080130, + 0x80000000, 0x40001800, 0x82081500, 0x00ffffff, + 0x800000f0, 0x80080540, 0x44002800, 0x59a80810, + 0x82040d00, 0x000000ff, 0x400c1000, 0x80081104, + 0x82082400, 0x0010b351, 0x50101000, 0x820c0500, + 0x00000003, 0x0c01f806, 0x80081540, 0x44082000, + 0x42000800, 0x00000021, 0x0401f15c, 0x00103e37, + 0x00103e3c, 0x00103e41, 0x00103e46, 0x800408f0, + 0x40040000, 0x82081500, 0x00ffffff, 0x1c01f000, + 0x800408e0, 0x40040000, 0x82081500, 0xff00ffff, + 0x1c01f000, 0x800408d0, 0x40040000, 0x82081500, + 0xffff00ff, 0x1c01f000, 0x40040000, 0x82081500, + 0xffffff00, 0x1c01f000, 0x59a80016, 0x80000540, + 0x04000016, 0x4803c857, 0x42001000, 0x00103f62, + 0x0201f800, 0x00105cc9, 0x59a80016, 0x82000580, + 0x00000084, 0x0402000c, 0x59cc1006, 0x82081580, + 0x11070000, 0x04020008, 0x4a035013, 0x00000001, + 0x0401f8d2, 0x4a035014, 0x0000001a, 0x0401f804, + 0x0401f002, 0x0401f8f2, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401fa54, 0x4a035014, 0x0000001b, + 0x83cca400, 0x00000006, 0x4200a800, 0x0010b350, + 0x59a82016, 0x40100000, 0x8000b104, 0x40580800, + 0x5450a800, 0x8050a000, 0x8054a800, 0x8058b040, + 0x040207fc, 0x0401f119, 0x1c01f000, 0x1c01f000, + 0x4803c856, 0x42003000, 0x00000004, 0x42004000, + 0x0010b351, 0x599c2817, 0x8c142d14, 0x0402001f, + 0x42001000, 0x00000003, 0x40200000, 0x80080400, + 0x50000800, 0x82042580, 0xffffffff, 0x04020005, + 0x80081040, 0x80183040, 0x040207f8, 0x0401f05e, + 0x800811c0, 0x04020006, 0x82042580, 0x3fffffff, + 0x04000058, 0x82040d40, 0xc0000000, 0x4200b000, + 0x00000020, 0x42001800, 0x00000001, 0x40042000, + 0x80102102, 0x04021021, 0x800c18c2, 0x8058b040, + 0x040207fc, 0x0401f04b, 0x41781000, 0x40200000, + 0x80080400, 0x50000800, 0x82042580, 0xffffffff, + 0x04020005, 0x80081000, 0x80183040, 0x040207f8, + 0x0401f040, 0x800811c0, 0x04020003, 0x82040d40, + 0xc0000000, 0x4200b000, 0x00000001, 0x42001800, + 0x80000000, 0x40042000, 0x801020c2, 0x04021007, + 0x800c1902, 0x8058b000, 0x82580480, 0x00000021, + 0x040017fa, 0x0401f02f, 0x40200000, 0x80082400, + 0x50100000, 0x800c0540, 0x44002000, 0x59a80015, + 0x84000540, 0x48035015, 0x40580000, 0x42002800, + 0x00000020, 0x80142c80, 0x40080000, 0x42003800, + 0x00000003, 0x801c0480, 0x800000ca, 0x80142d40, + 0x82144c00, 0x00101eb5, 0x50242800, 0x82142d00, + 0x000000ff, 0x48175010, 0x4c040000, 0x40140800, + 0x0201f800, 0x00101655, 0x5c000800, 0x40001800, + 0x500c0000, 0x80100540, 0x44001800, 0x59a80015, + 0x84000540, 0x48035015, 0x4200a800, 0x0010b351, + 0x4020a000, 0x4200b000, 0x00000004, 0x0201f800, + 0x0010a93e, 0x82000540, 0x00000001, 0x0401f002, + 0x80000580, 0x1c01f000, 0x4807c857, 0x480bc857, + 0x4008b000, 0x83cca400, 0x00000007, 0x4200a800, + 0x0010b351, 0x40541000, 0x0201f800, 0x0010a93e, + 0x40041800, 0x41782000, 0x42000000, 0x00000003, + 0x820c1c80, 0x00000020, 0x04001004, 0x80102000, + 0x80000040, 0x0401f7fb, 0x40041800, 0x801021c0, + 0x04000005, 0x820c1c80, 0x00000020, 0x80102040, + 0x040207fd, 0x42002000, 0x00000001, 0x800c19c0, + 0x04000004, 0x801020c2, 0x800c1840, 0x040207fe, + 0x80083c00, 0x83cc2c00, 0x00000007, 0x80142c00, + 0x50140000, 0x80102d00, 0x04020012, 0x80100540, + 0x44003800, 0x82042400, 0x00101eb5, 0x50102800, + 0x82142d00, 0x000000ff, 0x48175010, 0x4c040000, + 0x40140800, 0x0201f800, 0x00101655, 0x5c000800, + 0x59a80015, 0x84000540, 0x48035015, 0x80000580, + 0x1c01f000, 0x4807c856, 0x42001000, 0x00008017, + 0x59a8184e, 0x0201f800, 0x0010a876, 0x0201f800, + 0x00103857, 0x1c01f000, 0x4807c856, 0x4200b000, + 0x00000020, 0x83cca400, 0x00000007, 0x4200a800, + 0x0010bc20, 0x0201f000, 0x0010a94f, 0x4807c856, + 0x0201f800, 0x00106c32, 0x42000800, 0x000000f7, + 0x0401f8f4, 0x497b2804, 0x497b2805, 0x497b281c, + 0x497b281d, 0x4202d800, 0x00000001, 0x42006000, + 0xbf7fffff, 0x42006800, 0x00018000, 0x0401f966, + 0x42006000, 0xfffeffff, 0x41786800, 0x0401f962, + 0x497b504e, 0x42000800, 0x0000002d, 0x42001000, + 0x00103fe4, 0x0201f000, 0x00105ca2, 0x4807c856, + 0x0401ffe3, 0x497b5014, 0x497b5016, 0x1c01f000, + 0x4807c856, 0x59a80005, 0x8c000506, 0x1c01f000, + 0x4807c856, 0x42006000, 0xffffffff, 0x42006800, + 0x00000028, 0x0401f14c, 0x4807c856, 0x0401ffc2, + 0x0201f800, 0x0010698c, 0x4df00000, 0x0201f800, + 0x00106b71, 0x5c03e000, 0x02000800, 0x00106982, + 0x59c400a4, 0x82000500, 0x0000000f, 0x82000580, + 0x00000002, 0x0402000a, 0x42006000, 0xffffffff, + 0x42006800, 0x00200000, 0x0401f937, 0x42006000, + 0xffdfffff, 0x41786800, 0x0401f933, 0x497b5014, + 0x42000800, 0x000000f7, 0x0401f8b2, 0x59c400a3, + 0x82000500, 0xbf20bfff, 0x82000540, 0x0001c000, + 0x480388a3, 0x84000520, 0x480388a3, 0x497b504e, + 0x42000800, 0x0000002d, 0x42001000, 0x00103fe4, + 0x0201f000, 0x00105ca2, 0x497b5016, 0x59b400f5, + 0x8c000500, 0x04020004, 0x82000540, 0x00000001, + 0x480368f5, 0x800400c4, 0x82000400, 0x00002000, + 0x4803910a, 0x59b400f6, 0x82000500, 0x00000018, + 0x040207fd, 0x4a0368f0, 0x0010b349, 0x42000000, + 0x0010b350, 0x4c040000, 0x50000800, 0x82040d80, + 0x11010000, 0x04000003, 0x50000800, 0x4807c857, + 0x5c000800, 0x480368f1, 0x82040400, 0x0000dc00, + 0x480368f3, 0x59c400a4, 0x82000500, 0x0000000f, + 0x82000580, 0x00000008, 0x04020017, 0x4c5c0000, + 0x4c600000, 0x59c4b805, 0x8c5cbd3a, 0x04020005, + 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, + 0x4a038805, 0x02000000, 0x0201f800, 0x00101a59, + 0x4000c000, 0x0201f800, 0x001019d0, 0x4202d800, + 0x00000001, 0x497b5014, 0x5c00c000, 0x5c00b800, + 0x1c01f000, 0x59c8010b, 0x8c000502, 0x040007e2, + 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80, + 0x0000000b, 0x04020005, 0x59a80814, 0x82040d40, + 0x00002000, 0x0401f004, 0x59a80812, 0x82040d40, + 0x00001000, 0x4807504e, 0x59a8084a, 0x800409c0, + 0x04020007, 0x42000800, 0x000007d0, 0x42001000, + 0x00103f62, 0x0201f800, 0x00105da7, 0x1c01f000, + 0x4807c856, 0x0401ff40, 0x0201f800, 0x0010698c, + 0x4df00000, 0x0201f800, 0x00106b71, 0x5c03e000, + 0x02000800, 0x00106982, 0x59c400a4, 0x82000500, + 0x0000000f, 0x82000580, 0x00000002, 0x0402000a, + 0x42006000, 0xffffffff, 0x42006800, 0x00200000, + 0x0401f8b5, 0x42006000, 0xffdfffff, 0x41786800, + 0x0401f8b1, 0x0201f800, 0x00104e13, 0x04000014, + 0x0201f800, 0x00104e23, 0x04020011, 0x4a035032, + 0x0000aaaa, 0x4c040000, 0x0201f800, 0x00101694, + 0x59a8002a, 0x82000500, 0xffff0000, 0x80040540, + 0x4803502a, 0x5c000800, 0x4a035033, 0x00000000, + 0x0201f800, 0x00104d76, 0x0401f008, 0x4a03504c, + 0x00000005, 0x42000000, 0x00000001, 0x0201f800, + 0x001015fa, 0x0401ff1e, 0x1c01f000, 0x0401f809, + 0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f08e, + 0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f08a, + 0x0201f800, 0x00104e23, 0x04020009, 0x59c40006, + 0x82000540, 0x000000f0, 0x48038806, 0x42006000, + 0xbfffffff, 0x41786800, 0x0401f87f, 0x1c01f000, + 0x800408d0, 0x59a80015, 0x8c000506, 0x04000006, + 0x59a80010, 0x82000500, 0x000000ff, 0x80040540, + 0x0401f003, 0x82040540, 0x000000f7, 0x480388a7, + 0x1c01f000, 0x4807c856, 0x42000000, 0x0010b639, + 0x0201f800, 0x0010a86e, 0x42003000, 0x00000005, + 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000d, + 0x42027800, 0x00000002, 0x0401f038, 0x4807c856, + 0x42000000, 0x0010b66a, 0x0201f800, 0x0010a86e, + 0x42003000, 0x00000000, 0x4d3c0000, 0x4c180000, + 0x42003000, 0x0000000f, 0x42027800, 0x00000002, + 0x0401f02a, 0x4807c856, 0x42000000, 0x0010b669, + 0x0201f800, 0x0010a86e, 0x42003000, 0x00000003, + 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000e, + 0x42027800, 0x00000202, 0x0401f01c, 0x4807c856, + 0x42000000, 0x0010b668, 0x0201f800, 0x0010a86e, + 0x42003000, 0x00000004, 0x4d3c0000, 0x4c180000, + 0x42003000, 0x00000010, 0x42027800, 0x00000202, + 0x0401f00e, 0x4807c856, 0x42000000, 0x0010b63c, + 0x0201f800, 0x0010a86e, 0x42003000, 0x00000001, + 0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000c, + 0x42027800, 0x00000202, 0x42001800, 0x0000ffff, + 0x42002000, 0x00000007, 0x0201f800, 0x001038c7, + 0x5c003000, 0x4d400000, 0x0201f800, 0x0010a784, + 0x42028000, 0x0000002a, 0x0201f800, 0x00101d90, + 0x5c028000, 0x5c027800, 0x1c01f000, 0x4807c856, + 0x04011000, 0x4a03c840, 0x0010b349, 0x4a03c842, + 0x00000040, 0x40000000, 0x040117ff, 0x42007800, + 0x0010b349, 0x46007800, 0x00000011, 0x803c7800, + 0x4a007800, 0x220000ef, 0x4a007801, 0x000000ef, + 0x4a007802, 0x01380000, 0x4a007803, 0x00000000, + 0x4a007804, 0xffffffff, 0x4a007805, 0x00000000, + 0x1c01f000, 0x59c400a3, 0x80300500, 0x80340540, + 0x480388a3, 0x1c01f000, 0x4833c857, 0x59c400a3, + 0x80300540, 0x480388a3, 0x80300580, 0x480388a3, + 0x1c01f000, 0x4803c856, 0x04000004, 0x4a03504b, + 0x00000001, 0x0401f002, 0x497b504b, 0x1c01f000, + 0x4803c856, 0x59c80002, 0x80000540, 0x0400000a, + 0x80000040, 0x04000008, 0x4a039005, 0x00000140, + 0x42000000, 0x00000006, 0x80000040, 0x040207ff, + 0x0401f7f4, 0x1c01f000, 0x4c5c0000, 0x4c600000, + 0x59c4b805, 0x485fc856, 0x8c5cbd3a, 0x04020005, + 0x42000000, 0x0010b616, 0x0201f800, 0x0010a86e, + 0x4a038805, 0x02000000, 0x0201f800, 0x00101a59, + 0x4000c000, 0x0201f800, 0x001019d0, 0x4a038805, + 0x04000000, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x497a6a00, 0x4a026c00, 0x00000707, 0x497a6801, + 0x497a6808, 0x497a6809, 0x497a6806, 0x497a6807, + 0x497a6c0b, 0x497a680c, 0x0201f800, 0x0010393e, + 0x04020006, 0x5934080f, 0x59340010, 0x80040540, + 0x02020800, 0x00100615, 0x4a026a04, 0x00000100, + 0x497a6a03, 0x59340402, 0x82000500, 0x000000ff, + 0x48026c02, 0x497a6c04, 0x497a6a05, 0x497a6c05, + 0x497a6811, 0x4d2c0000, 0x5934000d, 0x49466c03, + 0x80025d40, 0x04000004, 0x0201f800, 0x00100843, + 0x497a680d, 0x5c025800, 0x599c0401, 0x48026a0b, + 0x599c0208, 0x48026c12, 0x4a02680a, 0x00006000, + 0x0201f000, 0x00104acf, 0x42000000, 0x00000005, + 0x80000d80, 0x0401f02d, 0x0201f800, 0x00104858, + 0x04020017, 0x59a80026, 0x8c00050a, 0x04020010, + 0x59340212, 0x82000500, 0x0000ff00, 0x4803c857, + 0x0400000b, 0x59340a00, 0x8c040d1e, 0x02000000, + 0x000201f8, 0x42000000, 0x00000029, 0x42000800, + 0x00001000, 0x492fc857, 0x0401f018, 0x492fc857, + 0x42000000, 0x00000028, 0x0401f012, 0x59a80805, + 0x8c040d02, 0x04020003, 0x8c040d00, 0x04000004, + 0x42000000, 0x00000004, 0x0401f00a, 0x42000000, + 0x00000029, 0x59340a00, 0x8c040d1e, 0x04000005, + 0x492fc857, 0x42000800, 0x00001000, 0x0401f003, + 0x492fc857, 0x80000d80, 0x4803c857, 0x80028540, + 0x1c01f000, 0x4803c857, 0x59a80005, 0x8c000500, + 0x040207ec, 0x0201f800, 0x00104836, 0x040207e4, + 0x59340200, 0x8c00050e, 0x040007e1, 0x0201f000, + 0x000201f8, 0x0201f800, 0x00104639, 0x040007bf, + 0x0201f000, 0x000201fc, 0x592c0206, 0x492fc857, + 0x82000d80, 0x000007ff, 0x04020006, 0x4a025c0a, + 0x00000030, 0x42026800, 0x0010b320, 0x0401f021, + 0x82000c80, 0x000007f0, 0x04021046, 0x81ac0400, + 0x50000000, 0x80026d40, 0x04000038, 0x0201f800, + 0x00104732, 0x04020038, 0x592c040a, 0x8c00050a, + 0x04020014, 0x592e6009, 0x83300480, 0x0010cfc0, + 0x0400103b, 0x41580000, 0x81300480, 0x04021038, + 0x59300c06, 0x82040580, 0x00000009, 0x04020037, + 0x4a025a06, 0x00000000, 0x497a5800, 0x59300008, + 0x80000540, 0x04020018, 0x492e6008, 0x0401f010, + 0x0201f800, 0x00020892, 0x04000019, 0x592c0206, + 0x49366009, 0x492e6008, 0x4a026406, 0x00000009, + 0x497a6015, 0x49325809, 0x82000d80, 0x000007ff, + 0x04020003, 0x4a026015, 0x00008000, 0x42027000, + 0x00000043, 0x0201f800, 0x000208d8, 0x80000580, + 0x0401f020, 0x40000800, 0x58040000, 0x80000d40, + 0x040207fd, 0x492c0800, 0x0401f01a, 0x42000000, + 0x0000002c, 0x0401f016, 0x42000000, 0x00000028, + 0x0401f013, 0x59a80805, 0x82040500, 0x00000003, + 0x04000004, 0x42000000, 0x00000004, 0x0401f00c, + 0x42000000, 0x00000029, 0x0401f009, 0x42000000, + 0x00000008, 0x0401f006, 0x82040580, 0x00000007, + 0x040207fb, 0x42000000, 0x00000005, 0x80000540, + 0x1c01f000, 0x492fc857, 0x592e8c06, 0x83440d80, + 0x000007fc, 0x04000004, 0x83440480, 0x000007f0, + 0x04021014, 0x0201f800, 0x00020267, 0x04020011, + 0x0201f800, 0x00104842, 0x04020011, 0x0201f800, + 0x00020892, 0x0400001c, 0x49366009, 0x492e6008, + 0x4a026406, 0x0000000a, 0x42027000, 0x00000040, + 0x0201f800, 0x000208d8, 0x80000580, 0x0401f011, + 0x42000000, 0x00000028, 0x0401f00d, 0x0201f800, + 0x00104858, 0x040007fb, 0x59a80805, 0x82040d00, + 0x00000003, 0x04000004, 0x42000000, 0x00000004, + 0x0401f003, 0x42000000, 0x00000029, 0x80000540, + 0x1c01f000, 0x42000000, 0x0000002c, 0x0401f7fc, + 0x492fc857, 0x592e8c06, 0x4947c857, 0x83440c80, + 0x00000800, 0x42000000, 0x0000000a, 0x0402119c, + 0x592c4207, 0x4823c857, 0x82200500, 0x0000000f, + 0x0c01f001, 0x00104205, 0x0010428d, 0x001042dd, + 0x001042e8, 0x001042f3, 0x00104201, 0x00104201, + 0x00104201, 0x00104303, 0x00104361, 0x00104386, + 0x00104201, 0x00104201, 0x00104201, 0x00104201, + 0x00104201, 0x4803c857, 0x42000000, 0x0000000c, + 0x0401f183, 0x592c1008, 0x82081500, 0x00ffffff, + 0x59a80010, 0x80084d80, 0x42000000, 0x00000010, + 0x0400017b, 0x0201f800, 0x00104768, 0x04000036, + 0x4803c857, 0x82004d80, 0x0000001d, 0x0402001a, + 0x0201f800, 0x00105439, 0x59340405, 0x4c000000, + 0x0201f800, 0x00104836, 0x5c000000, 0x04000004, + 0x8c20450a, 0x04000028, 0x80000580, 0x44002800, + 0x59340008, 0x48002802, 0x59340009, 0x48002801, + 0x59340006, 0x48002804, 0x59340007, 0x48002803, + 0x4200b000, 0x00000005, 0x0201f800, 0x00109328, + 0x0401f18c, 0x4803c857, 0x82004d80, 0x0000001a, + 0x04020003, 0x40101000, 0x0401f15c, 0x4803c857, + 0x82004d80, 0x0000001b, 0x04020003, 0x40181000, + 0x0401f156, 0x4803c857, 0x82004d80, 0x0000001c, + 0x04000157, 0x82004d80, 0x00000019, 0x42000000, + 0x0000000a, 0x04000146, 0x42000000, 0x0000000a, + 0x0402015d, 0x59a8006f, 0x8c000502, 0x0400001b, + 0x0201f800, 0x00104836, 0x04000018, 0x59340212, + 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, + 0x0402000c, 0x42001000, 0x00000008, 0x59a80026, + 0x8c000506, 0x04020009, 0x59340002, 0x82000500, + 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000007, + 0x0201f800, 0x00104ada, 0x42000000, 0x0000001c, + 0x40181000, 0x0402012d, 0x0201f800, 0x00020892, + 0x04000137, 0x49366009, 0x492e6008, 0x4a026406, + 0x00000001, 0x8c20450a, 0x04000004, 0x592c0404, + 0x8400055c, 0x48025c04, 0x4c200000, 0x4d3c0000, + 0x42027800, 0x00001800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x5c004000, 0x8c204512, 0x0400000b, + 0x599c0018, 0x8c000518, 0x04000008, 0x592c0009, + 0x82000500, 0x00000380, 0x5934080a, 0x80040d40, + 0x84040d54, 0x4806680a, 0x417a7800, 0x0401f93a, + 0x42000800, 0x00000003, 0x0401f941, 0x42027000, + 0x00000002, 0x0201f800, 0x000208d8, 0x80000580, + 0x0401f130, 0x0201f800, 0x00020267, 0x04020112, + 0x0201f800, 0x0010483c, 0x0400000c, 0x0201f800, + 0x00104836, 0x04020112, 0x4c600000, 0x4178c000, + 0x42027800, 0x00001800, 0x417a6000, 0x0201f800, + 0x00101e48, 0x5c00c000, 0x59a8006f, 0x8c000502, + 0x0400001b, 0x0201f800, 0x00104836, 0x04000018, + 0x59340212, 0x82000500, 0x0000ff00, 0x42001000, + 0x00000010, 0x0402000c, 0x42001000, 0x00000008, + 0x59a80026, 0x8c000506, 0x04020009, 0x59340002, + 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, + 0x04000007, 0x0201f800, 0x00104ada, 0x42000000, + 0x0000001c, 0x40181000, 0x040200d4, 0x0201f800, + 0x00020892, 0x040000de, 0x5934080a, 0x8c204512, + 0x0400000c, 0x599c0018, 0x8c000518, 0x04000009, + 0x592c0009, 0x82000500, 0x00000380, 0x82041500, + 0xfffffc7f, 0x80080d40, 0x84040d54, 0x0401f002, + 0x84040d14, 0x4806680a, 0x49366009, 0x492e6008, + 0x4a026406, 0x00000001, 0x417a7800, 0x0401f8ea, + 0x42000800, 0x00000005, 0x0401f8f1, 0x42027000, + 0x00000003, 0x0201f800, 0x000208d8, 0x80000580, + 0x0401f0e0, 0x0201f800, 0x00020267, 0x040200c2, + 0x0201f800, 0x0010484b, 0x040200c5, 0x0201f800, + 0x001092e0, 0x040000b6, 0x80000580, 0x0401f0d5, + 0x0201f800, 0x00020267, 0x040200b7, 0x0201f800, + 0x0010484b, 0x040200ba, 0x0201f800, 0x00108ea3, + 0x040000ab, 0x80000580, 0x0401f0ca, 0x0201f800, + 0x00020267, 0x040200ac, 0x83444d80, 0x000007fe, + 0x42000000, 0x0000000a, 0x0402008d, 0x0201f800, + 0x00104836, 0x040200aa, 0x0201f800, 0x001092f8, + 0x0400009b, 0x80000580, 0x0401f0ba, 0x82200500, + 0x00000070, 0x04020005, 0x8c20450e, 0x42000000, + 0x0000000c, 0x0402007e, 0x8c20450a, 0x0400000d, + 0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e, + 0x04020002, 0x853e7d56, 0x82200500, 0x000000a0, + 0x0201f800, 0x00104822, 0x5c027800, 0x0401f0a1, + 0x8c204508, 0x04020024, 0x592c1008, 0x82081500, + 0x00ffffff, 0x59a80010, 0x80084d80, 0x42000000, + 0x00000010, 0x04000066, 0x0201f800, 0x00104768, + 0x0400002b, 0x4803c857, 0x82004d80, 0x0000001a, + 0x04020003, 0x40101000, 0x0401f064, 0x4803c857, + 0x82004d80, 0x0000001b, 0x04020003, 0x40181000, + 0x0401f05e, 0x4803c857, 0x82004d80, 0x0000001c, + 0x0400005f, 0x82004d80, 0x00000019, 0x42000000, + 0x0000000a, 0x0400004e, 0x42000000, 0x0000000a, + 0x0401f065, 0x0201f800, 0x00020267, 0x04020062, + 0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e, + 0x04020002, 0x853e7d56, 0x82200500, 0x00000090, + 0x0201f800, 0x0010480a, 0x5c027800, 0x42000000, + 0x0000000a, 0x0402003a, 0x0401f06a, 0x836c0580, + 0x00000003, 0x42000800, 0x00000007, 0x04020006, + 0x0201f800, 0x0010928e, 0x04000007, 0x80000580, + 0x0401f064, 0x0201f800, 0x00104871, 0x04000059, + 0x0401f05c, 0x0201f800, 0x00104871, 0x0400003c, + 0x0401f058, 0x0201f800, 0x00020267, 0x0402003e, + 0x836c0580, 0x00000003, 0x04020048, 0x8c204508, + 0x0400000a, 0x4c600000, 0x4178c000, 0x42027800, + 0x00001800, 0x417a6000, 0x0201f800, 0x00101e48, + 0x5c00c000, 0x0401f047, 0x0201f800, 0x0010483c, + 0x0400000c, 0x0201f800, 0x00104836, 0x04020030, + 0x4c600000, 0x4178c000, 0x42027800, 0x00001800, + 0x417a6000, 0x0201f800, 0x00101e48, 0x5c00c000, + 0x480bc856, 0x0201f800, 0x001090f8, 0x04000018, + 0x80000580, 0x0401f037, 0x0401f7db, 0x480bc857, + 0x42000800, 0x00000019, 0x40001000, 0x4200b000, + 0x00000002, 0x0401f00a, 0x480bc857, 0x40000800, + 0x4200b000, 0x00000002, 0x0401f005, 0x480bc857, + 0x40000800, 0x4200b000, 0x00000001, 0x480bc857, + 0x42028000, 0x00000031, 0x0401f020, 0x480bc857, + 0x42000800, 0x00000003, 0x4200b000, 0x00000001, + 0x0401f7f7, 0x480bc857, 0x42000800, 0x0000000a, + 0x4200b000, 0x00000001, 0x0401f7f1, 0x480bc857, + 0x42000800, 0x00000009, 0x40001000, 0x4200b000, + 0x00000002, 0x0401f7ea, 0x480bc857, 0x42000800, + 0x00000007, 0x4200b000, 0x00000001, 0x0401f7e4, + 0x480bc857, 0x4200b000, 0x00000001, 0x0401f7e0, + 0x80028580, 0x4178b000, 0x82000540, 0x00000001, + 0x1c01f000, 0x4937c857, 0x59326809, 0x59341200, + 0x813e79c0, 0x04000003, 0x84081540, 0x0401f002, + 0x84081500, 0x480a6a00, 0x1c01f000, 0x59326809, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4937c857, + 0x82040580, 0x00000006, 0x04020004, 0x42000000, + 0x00000606, 0x0401f021, 0x82040580, 0x00000004, + 0x04020004, 0x42000000, 0x00000404, 0x0401f01b, + 0x82040580, 0x00000007, 0x42000000, 0x00000707, + 0x04000016, 0x82040580, 0x00000003, 0x42000000, + 0x00000703, 0x04000011, 0x82040580, 0x00000005, + 0x42000000, 0x00000405, 0x0400000c, 0x82040580, + 0x00000009, 0x42000000, 0x00000409, 0x04000007, + 0x82040580, 0x0000000b, 0x42000000, 0x0000070b, + 0x02020800, 0x00100615, 0x4803c857, 0x48026c00, + 0x82040d80, 0x00000006, 0x04020005, 0x59341404, + 0x800811c0, 0x02000800, 0x00100615, 0x1c01f000, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4947c857, + 0x481bc857, 0x83440480, 0x00000800, 0x04021034, + 0x83441400, 0x0010aa00, 0x50080000, 0x80026d40, + 0x04020011, 0x4c180000, 0x4d2c0000, 0x0201f800, + 0x00100819, 0x412e6800, 0x5c025800, 0x5c003000, + 0x04000027, 0x45341000, 0x497a680d, 0x497a6810, + 0x497a680f, 0x497a680e, 0x4c180000, 0x0401fccd, + 0x5c003000, 0x59340a12, 0x4c040000, 0x0201f800, + 0x00104e0d, 0x5c000800, 0x04000009, 0x82180500, + 0x00ffff00, 0x04000008, 0x59a81010, 0x82081500, + 0x00ffff00, 0x80080580, 0x04000003, 0x80000580, + 0x0401f004, 0x82180500, 0x000000ff, 0x800000d0, + 0x80040d80, 0x04000003, 0x4803c857, 0x48026a12, + 0x59340002, 0x80180580, 0x04000003, 0x481bc857, + 0x481a6802, 0x80000580, 0x1c01f000, 0x4803c856, + 0x82000540, 0x00000001, 0x0401f7fc, 0x4947c857, + 0x83440480, 0x00000800, 0x04021011, 0x83441400, + 0x0010aa00, 0x50080000, 0x80026d40, 0x0400000b, + 0x0401fbf2, 0x0402000a, 0x59a80005, 0x8c000502, + 0x04000004, 0x59340200, 0x8c00050e, 0x04000004, + 0x82000540, 0x00000001, 0x1c01f000, 0x80000580, + 0x0401f7fe, 0x5c000000, 0x4c000000, 0x4803c857, + 0x4947c857, 0x4d2c0000, 0x4d300000, 0x83440480, + 0x00000800, 0x04021024, 0x83441400, 0x0010aa00, + 0x50080000, 0x80026d40, 0x0400001b, 0x45781000, + 0x5934000d, 0x80025d40, 0x02020800, 0x00100843, + 0x59366011, 0x813261c0, 0x0400000e, 0x4c640000, + 0x5930c800, 0x59325808, 0x0201f800, 0x00108df4, + 0x02020800, 0x00100843, 0x0201f800, 0x000208b4, + 0x82666540, 0x00000000, 0x040207f6, 0x5c00c800, + 0x0201f800, 0x00104acf, 0x41365800, 0x0201f800, + 0x0010083b, 0x80000580, 0x5c026000, 0x5c025800, + 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fb, + 0x4937c857, 0x4c580000, 0x59cc0001, 0x82000500, + 0x00ffffff, 0x48026802, 0x497a6c01, 0x497a6a01, + 0x59340200, 0x84000502, 0x48026a00, 0x0201f800, + 0x00104e0d, 0x04020017, 0x59340403, 0x82000580, + 0x000007fe, 0x04000005, 0x59a80026, 0x8c00050a, + 0x04020010, 0x0401f008, 0x59cc0408, 0x8c000518, + 0x0400000c, 0x59cc0009, 0x48035035, 0x59cc000a, + 0x48035036, 0x59cc0207, 0x80000540, 0x04020003, + 0x42000000, 0x00000001, 0x48038893, 0x4803501e, + 0x59cc0a09, 0x82040d00, 0x00000010, 0x59cc0408, + 0x82000500, 0x00000020, 0x04000002, 0x84040d40, + 0x5934000a, 0x82000500, 0xffffffee, 0x80040540, + 0x4802680a, 0x83cca400, 0x0000000b, 0x8334ac00, + 0x00000006, 0x4200b000, 0x00000002, 0x0201f800, + 0x0010a93e, 0x83cca400, 0x0000000d, 0x8334ac00, + 0x00000008, 0x4200b000, 0x00000002, 0x0201f800, + 0x0010a93e, 0x59cc0a18, 0x82040480, 0x00000800, + 0x0402100c, 0x82040480, 0x00000400, 0x04001004, + 0x42000800, 0x00000400, 0x0401f006, 0x82040480, + 0x00000200, 0x04001003, 0x42000800, 0x00000200, + 0x42001000, 0x0010b33f, 0x58080202, 0x80041480, + 0x04001002, 0x40000800, 0x48066a04, 0x59340403, + 0x82000580, 0x000007fe, 0x04020003, 0x59cc0a08, + 0x48066a04, 0x0201f800, 0x00104afd, 0x5c00b000, + 0x1c01f000, 0x4937c857, 0x59a80026, 0x8c000508, + 0x04000004, 0x84000556, 0x4803c857, 0x48035026, + 0x59cc0207, 0x4803c857, 0x48026a05, 0x59cc020a, + 0x4803c857, 0x48026c05, 0x59341200, 0x599c0818, + 0x5934180a, 0x4807c857, 0x480bc857, 0x480fc857, + 0x59cc2006, 0x82102500, 0xff000000, 0x82102580, + 0x02000000, 0x04000007, 0x8c00050e, 0x04000009, + 0x8c0c1d14, 0x04000003, 0x8c0c1d0e, 0x04000005, + 0x8c040d18, 0x04000003, 0x8408154a, 0x0401f002, + 0x8408150a, 0x8c000510, 0x04000009, 0x8c0c1d14, + 0x04000003, 0x8c0c1d10, 0x04000005, 0x8c040d18, + 0x04000003, 0x8408154e, 0x0401f002, 0x8408150e, + 0x8c000512, 0x04000009, 0x8c0c1d14, 0x04000003, + 0x8c0c1d12, 0x04000005, 0x8c040d18, 0x04000003, + 0x8408155c, 0x0401f002, 0x8408151c, 0x480a6a00, + 0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000, + 0x4c580000, 0x5934000d, 0x80025d40, 0x04000029, + 0x592c0003, 0x82000480, 0x00000008, 0x0400100b, + 0x412cb800, 0x592c0001, 0x80025d40, 0x040207f9, + 0x0201f800, 0x0010082a, 0x04000037, 0x492fc857, + 0x492cb801, 0x0401f020, 0x832c0c00, 0x00000004, + 0x4200b000, 0x00000008, 0x50040000, 0x82000580, + 0xffffffff, 0x04020006, 0x80041000, 0x50080000, + 0x82000580, 0xffffffff, 0x04000007, 0x82040c00, + 0x00000002, 0x8058b040, 0x040207f4, 0x0201f800, + 0x00100615, 0x45480800, 0x454c1000, 0x592c1803, + 0x800c1800, 0x480e5803, 0x480fc857, 0x0401f014, + 0x0201f800, 0x0010082a, 0x04000017, 0x492fc857, + 0x492e680d, 0x497a5802, 0x4a025803, 0x00000001, + 0x494a5804, 0x494e5805, 0x832c0c00, 0x00000006, + 0x4200b000, 0x0000000e, 0x46000800, 0xffffffff, + 0x80040800, 0x8058b040, 0x040207fc, 0x82000540, + 0x00000001, 0x5c00b000, 0x5c025800, 0x5c00b800, + 0x1c01f000, 0x80000580, 0x0401f7fb, 0x4803c856, + 0x4d3c0000, 0x4d2c0000, 0x5934000d, 0x80025d40, + 0x0400001f, 0x592c0002, 0x80000540, 0x0402001f, + 0x412e7800, 0x0401f8c8, 0x0402001c, 0x46000800, + 0xffffffff, 0x46001000, 0xffffffff, 0x4813c857, + 0x480fc857, 0x580c0003, 0x82000c80, 0x00000002, + 0x04021014, 0x480fc857, 0x400c0000, 0x812c0580, + 0x04020004, 0x580c0001, 0x4802680d, 0x0401f003, + 0x580c0001, 0x48002001, 0x400e5800, 0x0201f800, + 0x0010083a, 0x82000540, 0x00000001, 0x5c025800, + 0x5c027800, 0x1c01f000, 0x80000580, 0x0401f7fc, + 0x80000040, 0x48001803, 0x4803c857, 0x0401f7f6, + 0x0201f800, 0x00020087, 0x59300007, 0x8400054e, + 0x48026007, 0x592c1a04, 0x820c1d00, 0x000000ff, + 0x820c0580, 0x00000048, 0x04000013, 0x0201f000, + 0x000202b0, 0x8c000500, 0x02020800, 0x000200e6, + 0x4a026203, 0x00000002, 0x592c1a04, 0x820c1d00, + 0x000000ff, 0x820c0580, 0x00000018, 0x02000000, + 0x000202b0, 0x820c0580, 0x00000048, 0x02020000, + 0x000202b0, 0x42000800, 0x80000804, 0x0201f800, + 0x00106466, 0x0201f000, 0x000202b9, 0x4a025a06, + 0x00000008, 0x0201f000, 0x00020381, 0x4a025a06, + 0x00000029, 0x0201f000, 0x00020381, 0x4a025a06, + 0x0000002a, 0x0201f000, 0x00020381, 0x4a025a06, + 0x00000028, 0x0201f000, 0x00020381, 0x4943c857, + 0x4d440000, 0x4d340000, 0x4d2c0000, 0x4c580000, + 0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800, + 0x00020267, 0x04020007, 0x8d3e7d06, 0x04000004, + 0x59340200, 0x8c00050e, 0x04020002, 0x0401f813, + 0x81468800, 0x8058b040, 0x040207f5, 0x83440480, + 0x00000800, 0x04021008, 0x8d3e7d02, 0x04000006, + 0x42028800, 0x000007f0, 0x4200b000, 0x00000010, + 0x0401f7eb, 0x5c00b000, 0x5c025800, 0x5c026800, + 0x5c028800, 0x1c01f000, 0x4d2c0000, 0x41783000, + 0x5936580f, 0x812e59c0, 0x04000029, 0x592c0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000012, + 0x04000020, 0x8d3e7d00, 0x04000003, 0x0401f83c, + 0x0402001c, 0x592c2000, 0x497a5800, 0x801831c0, + 0x04020009, 0x59340010, 0x812c0580, 0x04020004, + 0x497a680f, 0x497a6810, 0x0401f008, 0x4812680f, + 0x0401f006, 0x48103000, 0x59340010, 0x812c0580, + 0x04020002, 0x481a6810, 0x4a025a04, 0x00000103, + 0x49425a06, 0x497a5c09, 0x0201f800, 0x00108f7d, + 0x0201f800, 0x00020381, 0x40125800, 0x0401f7da, + 0x412c3000, 0x592e5800, 0x0401f7d7, 0x5c025800, + 0x1c01f000, 0x4803c856, 0x41781800, 0x5934000f, + 0x80025d40, 0x04000010, 0x592c0005, 0x80200580, + 0x592c0000, 0x04000003, 0x412c1800, 0x0401f7f9, + 0x497a5800, 0x800c19c0, 0x04000008, 0x48001800, + 0x80000540, 0x04020004, 0x480e6810, 0x82000540, + 0x00000001, 0x1c01f000, 0x4802680f, 0x80000540, + 0x040207fd, 0x497a6810, 0x0401f7f9, 0x592c0008, + 0x81480580, 0x04020003, 0x592c0009, 0x814c0580, + 0x1c01f000, 0x4803c856, 0x4c580000, 0x413c1800, + 0x400c2000, 0x593c0002, 0x80000540, 0x04020018, + 0x4200b000, 0x00000008, 0x820c0c00, 0x00000004, + 0x50040000, 0x81480580, 0x04020005, 0x80041000, + 0x50080000, 0x814c0580, 0x0400000d, 0x82040c00, + 0x00000002, 0x8058b040, 0x040207f6, 0x400c2000, + 0x580c0001, 0x80001d40, 0x040207ee, 0x82000540, + 0x00000001, 0x5c00b000, 0x1c01f000, 0x80000580, + 0x0401f7fd, 0x4937c857, 0x4c580000, 0x4d2c0000, + 0x5934000d, 0x80025d40, 0x04020016, 0x0201f800, + 0x0010082a, 0x04000010, 0x492e680d, 0x4a025802, + 0x00000001, 0x497a5803, 0x832c0c00, 0x00000004, + 0x4200b000, 0x00000010, 0x46000800, 0xffffffff, + 0x80040800, 0x8058b040, 0x040207fc, 0x82000540, + 0x00000001, 0x5c025800, 0x5c00b000, 0x1c01f000, + 0x4d2c0000, 0x592e5801, 0x0201f800, 0x00100843, + 0x5c025800, 0x0401f7ea, 0x4d2c0000, 0x5936580d, + 0x812e59c0, 0x04000007, 0x4937c857, 0x497a680d, + 0x0201f800, 0x00100843, 0x82000540, 0x00000001, + 0x5c025800, 0x1c01f000, 0x59340405, 0x4937c857, + 0x4803c857, 0x8c000508, 0x1c01f000, 0x4803c856, + 0x0201f800, 0x00104e0d, 0x04000011, 0x59a80815, + 0x8c040d04, 0x0402000e, 0x59a80826, 0x8c040d06, + 0x0400000b, 0x83ac0400, 0x000007fe, 0x50000000, + 0x80026d40, 0x04000006, 0x0401f9a8, 0x04020004, + 0x59340200, 0x8400055a, 0x48026a00, 0x599c0017, + 0x8c000508, 0x04000015, 0x4200b000, 0x000007f0, + 0x417a8800, 0x0201f800, 0x00020267, 0x0402000c, + 0x0401f99a, 0x0402000a, 0x59a80010, 0x59340802, + 0x80040580, 0x82000500, 0x00ffff00, 0x04020004, + 0x59340200, 0x8400055a, 0x48026a00, 0x81468800, + 0x8058b040, 0x040207f0, 0x0401f885, 0x04000003, + 0x59a80836, 0x0401f006, 0x599c0017, 0x8c000508, + 0x04000007, 0x42000800, 0x000007d0, 0x42001000, + 0x001046c4, 0x0201f800, 0x00105da7, 0x1c01f000, + 0x4803c856, 0x4d300000, 0x4d340000, 0x4d440000, + 0x4d3c0000, 0x4c580000, 0x42001000, 0x001046c4, + 0x0201f800, 0x00105cc9, 0x59a80826, 0x8c040d06, + 0x04000015, 0x0401f86a, 0x04000013, 0x83ae6c00, + 0x000007fe, 0x51366800, 0x59340200, 0x8400051a, + 0x48026a00, 0x599c0017, 0x8c000508, 0x04000007, + 0x42000800, 0x000007d0, 0x42001000, 0x001046c4, + 0x0201f800, 0x00105da7, 0x0201f800, 0x00101bf0, + 0x0401f027, 0x4200b000, 0x000007f0, 0x80028d80, + 0x0201f800, 0x00020267, 0x0402001e, 0x59340200, + 0x8c00051a, 0x0400001b, 0x59368c03, 0x417a7800, + 0x42028000, 0x00000029, 0x41783000, 0x0201f800, + 0x0010a258, 0x59340200, 0x84000558, 0x8400051a, + 0x48026a00, 0x4937c857, 0x4a026c00, 0x00000707, + 0x42028000, 0x00000029, 0x0201f800, 0x001067f6, + 0x417a7800, 0x0201f800, 0x00106543, 0x417a6000, + 0x0201f800, 0x0010a0da, 0x0201f800, 0x00106982, + 0x81468800, 0x8058b040, 0x040207de, 0x5c00b000, + 0x5c027800, 0x5c028800, 0x5c026800, 0x5c026000, + 0x1c01f000, 0x4933c857, 0x59303809, 0x581c0200, + 0x8400051a, 0x48003a00, 0x1c01f000, 0x42026800, + 0x0010b320, 0x497a680e, 0x42028800, 0x000007ff, + 0x0201f800, 0x001040e4, 0x4937c857, 0x4a026c00, + 0x00000606, 0x4a026802, 0x00ffffff, 0x4a026a04, + 0x00000200, 0x4a026c04, 0x00000002, 0x1c01f000, + 0x59300009, 0x50000000, 0x4933c857, 0x4803c857, + 0x8c00050e, 0x1c01f000, 0x59300009, 0x50000000, + 0x8c00050a, 0x1c01f000, 0x4933c856, 0x0401f90f, + 0x04000006, 0x59340400, 0x82000d00, 0x000000ff, + 0x82041580, 0x00000005, 0x1c01f000, 0x4d340000, + 0x83ac0400, 0x000007fe, 0x50000000, 0x80026d40, + 0x04000003, 0x59340200, 0x8c00051a, 0x5c026800, + 0x1c01f000, 0x4937c857, 0x493fc857, 0x59340403, + 0x81ac0400, 0x50000000, 0x81340580, 0x02020800, + 0x00100615, 0x59341200, 0x813e79c0, 0x04000003, + 0x8408155e, 0x0401f002, 0x8408151e, 0x480a6a00, + 0x1c01f000, 0x4937c857, 0x0201f800, 0x00101eb0, + 0x04000006, 0x59a80835, 0x42001000, 0x0010475f, + 0x0201f800, 0x00105da7, 0x1c01f000, 0x4937c857, + 0x42001000, 0x0010475f, 0x0201f800, 0x00105cc9, + 0x59a81026, 0x84081512, 0x480b5026, 0x1c01f000, + 0x4c380000, 0x4c340000, 0x4c240000, 0x4c600000, + 0x4008c000, 0x83440480, 0x00000800, 0x04021045, + 0x80002d80, 0x41442000, 0x83447400, 0x0010aa00, + 0x4200b000, 0x000007f0, 0x83444c80, 0x000007f0, + 0x04001003, 0x4200b000, 0x00000010, 0x50380000, + 0x80000540, 0x0402001e, 0x41440000, 0x80100580, + 0x04020043, 0x40102800, 0x82104c80, 0x000007f0, + 0x04001015, 0x82104d80, 0x000007fc, 0x04020005, + 0x82604d80, 0x00fffffc, 0x0402002a, 0x0401f00e, + 0x82104d80, 0x000007fd, 0x04020005, 0x82604d80, + 0x00fffffd, 0x04020023, 0x0401f007, 0x82104d80, + 0x000007ff, 0x0402001f, 0x82604d80, 0x00ffffff, + 0x0402001c, 0x84142d5e, 0x0401f029, 0x40006800, + 0x58343002, 0x82183500, 0x00ffffff, 0x40180000, + 0x80600580, 0x04020019, 0x40100000, 0x81440580, + 0x0402000a, 0x40366800, 0x8c204508, 0x04000053, + 0x0401ff8a, 0x04020051, 0x4947c857, 0x42000000, + 0x0000001d, 0x0401f04e, 0x4947c857, 0x480bc857, + 0x4823c857, 0x42000000, 0x0000001a, 0x0401f048, + 0x4947c857, 0x4863c857, 0x4813c857, 0x42000000, + 0x00000019, 0x0401f042, 0x40100000, 0x81440580, + 0x04020007, 0x58343002, 0x4947c857, 0x481bc857, + 0x42000000, 0x0000001b, 0x0401f039, 0x80102000, + 0x80387000, 0x83444c80, 0x000007f0, 0x04001009, + 0x82104d80, 0x00000800, 0x0402000c, 0x42002000, + 0x000007f0, 0x42007000, 0x0010b1f0, 0x0401f007, + 0x82104d80, 0x000007f0, 0x04020004, 0x41782000, + 0x42007000, 0x0010aa00, 0x8058b040, 0x040207a4, + 0x801429c0, 0x04020007, 0x0201f800, 0x00100615, + 0x4947c857, 0x42000000, 0x0000000a, 0x0401f01c, + 0x4d2c0000, 0x4c180000, 0x40603000, 0x0401fc19, + 0x4947c857, 0x4937c857, 0x5c003000, 0x5c025800, + 0x040207f4, 0x497a6a12, 0x59a80026, 0x8c00050a, + 0x0402000d, 0x82600500, 0x00ffff00, 0x04000006, + 0x59a84810, 0x82244d00, 0x00ffff00, 0x80240580, + 0x04020005, 0x82600500, 0x000000ff, 0x800000d0, + 0x48026a12, 0x48626802, 0x80000580, 0x80000540, + 0x5c00c000, 0x5c004800, 0x5c006800, 0x5c007000, + 0x1c01f000, 0x5934000f, 0x5934140b, 0x80081040, + 0x04001002, 0x480a6c0b, 0x80000540, 0x02020800, + 0x00020275, 0x1c01f000, 0x4803c857, 0x4947c857, + 0x4c300000, 0x82006500, 0x00000030, 0x04000006, + 0x4c000000, 0x0201f800, 0x001091f3, 0x5c000000, + 0x0402000b, 0x8c00050e, 0x04000006, 0x0201f800, + 0x00020267, 0x04020006, 0x4937c857, 0x0401fc36, + 0x80000580, 0x5c006000, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fc, 0x4803c857, 0x4c580000, + 0x4d440000, 0x40001000, 0x80000d80, 0x4200b000, + 0x000007f0, 0x4c040000, 0x40068800, 0x4c080000, + 0x40080000, 0x0401ffdd, 0x5c001000, 0x5c000800, + 0x80040800, 0x8058b040, 0x040207f7, 0x5c028800, + 0x5c00b000, 0x1c01f000, 0x4c5c0000, 0x59340400, + 0x8200bd80, 0x00000606, 0x5c00b800, 0x1c01f000, + 0x4c5c0000, 0x59340400, 0x8200bd80, 0x00000404, + 0x5c00b800, 0x1c01f000, 0x4c5c0000, 0x59340400, + 0x8200bd80, 0x00000404, 0x04000003, 0x8200bd80, + 0x00000606, 0x5c00b800, 0x1c01f000, 0x4c5c0000, + 0x4c600000, 0x59340400, 0x8200bd00, 0x0000ff00, + 0x825cc580, 0x00000400, 0x04000003, 0x825cc580, + 0x00000600, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x4c5c0000, 0x59340400, 0x82000500, 0x000000ff, + 0x8200bd80, 0x00000003, 0x04000003, 0x8200bd80, + 0x00000005, 0x5c00b800, 0x1c01f000, 0x5c000000, + 0x4c000000, 0x4803c857, 0x4c5c0000, 0x59340400, + 0x82000500, 0x0000ff00, 0x8400b9c0, 0x805c0580, + 0x4937c857, 0x4803c857, 0x48026c00, 0x5c00b800, + 0x1c01f000, 0x4c040000, 0x4c080000, 0x592c0207, + 0x8c00050c, 0x0400000f, 0x592e8c06, 0x82000500, + 0x00000080, 0x84000548, 0x4d3c0000, 0x42027800, + 0x00001000, 0x0401ff8d, 0x5c027800, 0x82000540, + 0x00000001, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x80000580, 0x0401f7fc, 0x592c040b, 0x82000500, + 0x0000e000, 0x82000580, 0x00006000, 0x04000019, + 0x836c0580, 0x00000003, 0x04000016, 0x836c0580, + 0x00000002, 0x04020106, 0x59a80026, 0x82000d00, + 0x00000038, 0x04020005, 0x59a80832, 0x800409c0, + 0x0400000c, 0x0401f0fe, 0x82000d00, 0x00000003, + 0x82040d80, 0x00000003, 0x040200f9, 0x82000d00, + 0x00000028, 0x04020003, 0x8c00050c, 0x040000f4, + 0x592c100a, 0x82080500, 0xff000000, 0x040200d2, + 0x59a80010, 0x80080580, 0x040000cc, 0x592c0c0b, + 0x82040d00, 0x0000e000, 0x82040480, 0x00008000, + 0x040210cc, 0x592e8c06, 0x83440480, 0x00000800, + 0x04001007, 0x83440580, 0x0000ffff, 0x040200b3, + 0x800409c0, 0x040200fe, 0x0401f0b0, 0x800409c0, + 0x040200fb, 0x41784000, 0x0401feaa, 0x040200e2, + 0x59342204, 0x592c000d, 0x80100480, 0x040010bc, + 0x42027000, 0x00000053, 0x592c2409, 0x82100500, + 0xffffff00, 0x040200aa, 0x4813c857, 0x592c000c, + 0x800001c0, 0x04000083, 0x82100580, 0x00000004, + 0x040000a0, 0x82100580, 0x00000051, 0x0400009d, + 0x82100580, 0x00000003, 0x04000016, 0x82100580, + 0x00000020, 0x0400004b, 0x82100580, 0x00000024, + 0x04000042, 0x82100580, 0x00000021, 0x04000042, + 0x82100580, 0x00000050, 0x04000037, 0x82100580, + 0x00000052, 0x04000031, 0x82100580, 0x00000005, + 0x0402006b, 0x42027000, 0x00000001, 0x0401f01b, + 0x42027000, 0x00000002, 0x59a8006f, 0x8c000502, + 0x04000016, 0x0401ff45, 0x04000014, 0x59340212, + 0x82000500, 0x0000ff00, 0x42001000, 0x00000010, + 0x0402000c, 0x59a80026, 0x8c000506, 0x0402006f, + 0x42001000, 0x00000008, 0x59340002, 0x82000500, + 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003, + 0x0401f9d6, 0x04020065, 0x0201f800, 0x00020892, + 0x04000081, 0x4a026406, 0x00000010, 0x49366009, + 0x42000800, 0x00000003, 0x83380580, 0x00000002, + 0x04000003, 0x42000800, 0x0000000b, 0x0201f800, + 0x001043c7, 0x0401f044, 0x42027000, 0x00000000, + 0x0401f003, 0x42027000, 0x00000004, 0x0401ff30, + 0x04020074, 0x0401f036, 0x42027000, 0x00000033, + 0x0401f006, 0x42027000, 0x00000005, 0x0401f003, + 0x42027000, 0x00000003, 0x0401ff1c, 0x04020069, + 0x59a8006f, 0x8c000502, 0x04000016, 0x0401ff0b, + 0x04000014, 0x59340212, 0x82000500, 0x0000ff00, + 0x42001000, 0x00000010, 0x0402000c, 0x59a80026, + 0x8c000506, 0x04020035, 0x42001000, 0x00000008, + 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, + 0x00ff0000, 0x04000003, 0x0401f99c, 0x0402002b, + 0x0201f800, 0x00020892, 0x04000047, 0x4a026406, + 0x00000010, 0x49366009, 0x42000800, 0x00000005, + 0x83380580, 0x00000003, 0x04000003, 0x42000800, + 0x00000009, 0x0201f800, 0x001043c7, 0x0401f00a, + 0x82102580, 0x00000011, 0x04020030, 0x0201f800, + 0x00020892, 0x04000034, 0x4a026406, 0x00000010, + 0x49366009, 0x492e6008, 0x49325808, 0x813669c0, + 0x04000007, 0x592c0c0b, 0x8c040d18, 0x04000004, + 0x59340200, 0x84000514, 0x48026a00, 0x0201f800, + 0x000208d8, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fd, 0x42001000, 0x0000000a, + 0x0401f018, 0x42001000, 0x00000010, 0x0401f015, + 0x42001000, 0x00000016, 0x0401f012, 0x42001000, + 0x00000017, 0x0401f00f, 0x42001000, 0x00000018, + 0x0401f00c, 0x42001000, 0x0000001b, 0x0401f009, + 0x42001000, 0x0000001e, 0x0401f006, 0x42001000, + 0x00000024, 0x0401f003, 0x42001000, 0x00000020, + 0x42000800, 0x00000019, 0x42028000, 0x00000031, + 0x0401f7df, 0x42000800, 0x00000003, 0x0401f003, + 0x42000800, 0x0000000a, 0x41781000, 0x0401f7f7, + 0x42000800, 0x00000009, 0x59341400, 0x0401f7f3, + 0x42028000, 0x00000008, 0x0401f005, 0x42000800, + 0x00000007, 0x416c1000, 0x0401f7ec, 0x41780800, + 0x41781000, 0x0401f7ca, 0x42028000, 0x00000000, + 0x0401f7fb, 0x82004d80, 0x0000001d, 0x02000800, + 0x00100615, 0x82004d80, 0x0000001a, 0x04020004, + 0x40101000, 0x40000800, 0x0401f7dc, 0x82004d80, + 0x0000001b, 0x04020003, 0x40181000, 0x0401f7fa, + 0x82004d80, 0x0000001c, 0x040007f7, 0x82004d80, + 0x00000019, 0x040007b5, 0x0401f7d6, 0x592e6008, + 0x0201f800, 0x001091e3, 0x040007b3, 0x59300c06, + 0x82040580, 0x00000011, 0x040207d6, 0x83440580, + 0x0000ffff, 0x04020005, 0x59326809, 0x813669c0, + 0x0400000e, 0x0401f7cf, 0x592c100a, 0x82081500, + 0x00ffffff, 0x41784000, 0x0401fd9e, 0x040207d6, + 0x59300009, 0x800001c0, 0x04000003, 0x81340580, + 0x040207c4, 0x49366009, 0x592c0c0b, 0x82041500, + 0x0000e000, 0x82080580, 0x00006000, 0x04000011, + 0x42000800, 0x00000100, 0x813669c0, 0x04000002, + 0x59340a04, 0x592c000d, 0x80040480, 0x040017a0, + 0x59300a03, 0x82040580, 0x00000007, 0x040207b1, + 0x492e6008, 0x42027000, 0x00000054, 0x0401f774, + 0x0201f800, 0x0010a6e6, 0x040007b4, 0x0401f7a9, + 0x492fc857, 0x592e6008, 0x4933c857, 0x0201f800, + 0x001091e3, 0x04000047, 0x59301406, 0x82080580, + 0x00000005, 0x04020061, 0x592c0207, 0x8c000500, + 0x04020085, 0x59a80021, 0x800001c0, 0x0402006a, + 0x59301203, 0x82080580, 0x00000007, 0x04020057, + 0x592e8c06, 0x83440480, 0x00000800, 0x04021032, + 0x41784000, 0x592c1009, 0x82081500, 0x00ffffff, + 0x0401fd60, 0x0402005f, 0x59300009, 0x800001c0, + 0x04000003, 0x81340580, 0x04020048, 0x4d300000, + 0x592e6013, 0x4933c857, 0x83300580, 0xffffffff, + 0x0400000d, 0x0201f800, 0x001091e3, 0x5c026000, + 0x04000029, 0x591c1406, 0x82080580, 0x00000006, + 0x04000046, 0x82080580, 0x00000011, 0x04000043, + 0x0401f002, 0x5c026000, 0x59a80010, 0x592c100a, + 0x82081500, 0x00ffffff, 0x80081580, 0x04020017, + 0x592c1009, 0x82081500, 0x00ffffff, 0x80081580, + 0x0400000f, 0x49366009, 0x492e6008, 0x42027000, + 0x00000092, 0x0201f800, 0x000208d8, 0x80000580, + 0x1c01f000, 0x42001000, 0x0000000a, 0x0401f00c, + 0x42001000, 0x00000010, 0x0401f009, 0x42001000, + 0x00000014, 0x0401f006, 0x42001000, 0x00000018, + 0x0401f003, 0x42001000, 0x0000003c, 0x492fc857, + 0x480bc857, 0x42000800, 0x00000019, 0x42028000, + 0x00000031, 0x82000540, 0x00000001, 0x0401f7e9, + 0x492fc857, 0x4803c857, 0x480bc857, 0x40000800, + 0x0401f7f7, 0x492fc857, 0x42000800, 0x0000000a, + 0x41781000, 0x0401f7f2, 0x4933c857, 0x59300406, + 0x4803c857, 0x59300203, 0x4803c857, 0x59300009, + 0x4803c857, 0x42028000, 0x00000008, 0x41780800, + 0x41781000, 0x0401f7e8, 0x42000800, 0x0000001e, + 0x0401f7f0, 0x42000800, 0x00000001, 0x0401f7ed, + 0x82004d80, 0x0000001d, 0x02000800, 0x00100615, + 0x82004d80, 0x0000001a, 0x04020003, 0x40101000, + 0x0401f7dc, 0x82004d80, 0x0000001b, 0x04020003, + 0x40181000, 0x0401f7d7, 0x82004d80, 0x0000001c, + 0x040007d4, 0x82004d80, 0x00000019, 0x040007d1, + 0x0401f7d5, 0x0201f800, 0x0010a6e6, 0x040207d7, + 0x42028000, 0x00000000, 0x0401f7dd, 0x5c000000, + 0x4c000000, 0x4803c857, 0x59302009, 0x801021c0, + 0x04000035, 0x58101400, 0x4813c857, 0x480bc857, + 0x82081d00, 0x000000ff, 0x59300c03, 0x82040580, + 0x00000008, 0x04000022, 0x82040580, 0x0000000a, + 0x04000017, 0x82040580, 0x0000000c, 0x04000010, + 0x82040580, 0x00000002, 0x04000019, 0x82040580, + 0x00000001, 0x04000012, 0x82040580, 0x00000003, + 0x0400000b, 0x82040580, 0x00000005, 0x04000004, + 0x82040580, 0x00000033, 0x04020017, 0x820c0580, + 0x00000009, 0x0400000d, 0x0401f013, 0x820c0580, + 0x00000005, 0x04000009, 0x0401f00f, 0x820c0580, + 0x0000000b, 0x04000005, 0x0401f00b, 0x820c0580, + 0x00000003, 0x04020008, 0x82081d00, 0xffffff00, + 0x840c01c0, 0x800c0540, 0x4807c857, 0x4803c857, + 0x48002400, 0x1c01f000, 0x599c0017, 0x8c00050a, + 0x04000003, 0x80000580, 0x1c01f000, 0x59a80026, + 0x82000500, 0x00000028, 0x04000008, 0x42028800, + 0x000007fd, 0x0201f800, 0x00020267, 0x04020003, + 0x5934000a, 0x8c000504, 0x1c01f000, 0x4d300000, + 0x5934000e, 0x80026540, 0x04000006, 0x0201f800, + 0x0010600e, 0x02000800, 0x001061e5, 0x497a680e, + 0x5c026000, 0x1c01f000, 0x4d440000, 0x4d340000, + 0x80000580, 0x40001800, 0x40028800, 0x82080580, + 0x00000008, 0x04020003, 0x42001800, 0x00000001, + 0x0201f800, 0x00020267, 0x0402000a, 0x0401fd4f, + 0x04020008, 0x800c19c0, 0x04000004, 0x59340405, + 0x8c000508, 0x04000003, 0x80081040, 0x04000009, + 0x81468800, 0x83440480, 0x00000800, 0x040017f1, + 0x80000580, 0x5c026800, 0x5c028800, 0x1c01f000, + 0x82000540, 0x00000001, 0x5c026800, 0x5c028800, + 0x1c01f000, 0x42000800, 0x00000001, 0x0401fb0e, + 0x04020034, 0x59a80026, 0x8c000508, 0x04020031, + 0x5934100a, 0x82081500, 0x0000e000, 0x42007000, + 0x0010b33f, 0x58380401, 0x8c000504, 0x0402001c, + 0x42000800, 0x00000001, 0x82080580, 0x00006000, + 0x04000024, 0x59341a04, 0x820c0480, 0x00000800, + 0x04001004, 0x42000800, 0x00000a00, 0x0401f009, + 0x820c0480, 0x00000400, 0x04001004, 0x42000800, + 0x00000500, 0x0401f003, 0x42000800, 0x00000200, + 0x82080580, 0x00002000, 0x04000002, 0x800408c2, + 0x82040d40, 0x00000001, 0x0401f00e, 0x42000800, + 0x00000008, 0x82080580, 0x00002000, 0x04020004, + 0x42000800, 0x00000004, 0x0401f006, 0x82080580, + 0x00000000, 0x04020003, 0x42000800, 0x00000002, + 0x48066c04, 0x1c01f000, 0x4a033020, 0x00000000, + 0x4a03b104, 0x80000000, 0x497b3026, 0x497b3027, + 0x497b3028, 0x497b3029, 0x497b302b, 0x497b3021, + 0x4a03b104, 0x60000001, 0x1c01f000, 0x599c0018, + 0x4803c856, 0x497b3024, 0x497b3025, 0x82000500, + 0x0000000f, 0x48033022, 0x04000008, 0x599c0216, + 0x82000500, 0x0000ffff, 0x04020003, 0x42000000, + 0x00000002, 0x48033023, 0x1c01f000, 0x0401fff0, + 0x4a03c826, 0x00000004, 0x599c0209, 0x80000540, + 0x0400001f, 0x599c0207, 0x80000540, 0x04000007, + 0x800000cc, 0x599c080d, 0x80040400, 0x4803b100, + 0x497bb102, 0x59d80101, 0x599c000d, 0x4803b100, + 0x599c000e, 0x4803b101, 0x599c0207, 0x80000540, + 0x04020002, 0x497bb102, 0x599c0a09, 0x82040540, + 0x00400000, 0x59980822, 0x4803b103, 0x4a03b109, + 0x00000004, 0x4a03b104, 0x10000001, 0x800409c0, + 0x04020004, 0x4a033020, 0x00000001, 0x1c01f000, + 0x4a033020, 0x00000002, 0x0401f7fd, 0x592c0204, + 0x492fc857, 0x80000540, 0x04000008, 0x42034000, + 0x0010b2a0, 0x59a1d81e, 0x80edd9c0, 0x02000800, + 0x00100615, 0x0401f003, 0x5931d821, 0x58ef400b, + 0x58ec0009, 0x800001c0, 0x08020000, 0x0201f800, + 0x00100615, 0x5998002b, 0x84000540, 0x4803302b, + 0x0201f000, 0x00020403, 0x42000000, 0x0010b654, + 0x0201f800, 0x0010a86e, 0x492fc857, 0x59980026, + 0x59980828, 0x80000000, 0x48033026, 0x800409c0, + 0x492f3028, 0x04000003, 0x492c0800, 0x0401f002, + 0x492f3029, 0x592c0001, 0x80000d40, 0x02020000, + 0x000202fb, 0x1c01f000, 0x59980026, 0x59980828, + 0x80000000, 0x48033026, 0x492fc857, 0x800409c0, + 0x492f3028, 0x04000003, 0x492c0800, 0x0401f002, + 0x492f3029, 0x592c0001, 0x80000d40, 0x02020800, + 0x000202fb, 0x0402d00e, 0x59980029, 0x80025d40, + 0x0400000f, 0x59980026, 0x80000040, 0x48033026, + 0x04020002, 0x48033028, 0x592c0000, 0x48033029, + 0x492fc857, 0x492fb107, 0x0400d7f4, 0x42000000, + 0x0010b654, 0x0201f800, 0x0010a86e, 0x0402e01d, + 0x59da5908, 0x496a5800, 0x412ed000, 0x815eb800, + 0x0400e7fc, 0x59c80000, 0x82000540, 0x00001200, + 0x48039000, 0x04006019, 0x59d8010a, 0x59d8090a, + 0x80040d80, 0x040207fd, 0x900001c0, 0x82000540, + 0x00000013, 0x4803c011, 0x5998002b, 0x84000500, + 0x4803302b, 0x59e00017, 0x8c000508, 0x04000003, + 0x4a03c017, 0x00000003, 0x4203e000, 0x30000001, + 0x59d80105, 0x82000500, 0x00018780, 0x02020000, + 0x00020482, 0x1c01f000, 0x5998002b, 0x84000540, + 0x4803302b, 0x0401f7f7, 0x5c000000, 0x4c000000, + 0x4803c857, 0x492fc857, 0x4943c857, 0x4807c857, + 0x4a025a04, 0x00000103, 0x49425a06, 0x48065a08, + 0x4a025c06, 0x0000ffff, 0x813261c0, 0x04000003, + 0x59300402, 0x48025c06, 0x832c0400, 0x00000009, + 0x04011000, 0x4803c840, 0x4a03c842, 0x0000000b, + 0x04011000, 0x1c01f000, 0x42000000, 0x0010b654, + 0x0201f800, 0x0010a86e, 0x0201f000, 0x00020464, + 0x59a80017, 0x82000c80, 0x0000000a, 0x02021800, + 0x00100615, 0x0c01f809, 0x4a038805, 0x000000f0, + 0x59c400a3, 0x82000500, 0x02870000, 0x02020800, + 0x00100615, 0x1c01f000, 0x00104c99, 0x00104c25, + 0x00104c40, 0x00104c69, 0x00104c8c, 0x00104cc6, + 0x00104cd8, 0x00104c40, 0x00104caa, 0x00104c24, + 0x1c01f000, 0x4a038808, 0x00000004, 0x0401f8f9, + 0x0201f800, 0x0010507b, 0x59c40805, 0x8c040d0e, + 0x04020013, 0x8c040d0a, 0x0402000b, 0x8c040d0c, + 0x04020006, 0x8c040d08, 0x0400000d, 0x4a035017, + 0x00000003, 0x0401f00a, 0x4a035017, 0x00000000, + 0x0401f007, 0x42000000, 0x0010b642, 0x0201f800, + 0x0010a86e, 0x4a035017, 0x00000002, 0x1c01f000, + 0x4a038808, 0x00000002, 0x0401f8de, 0x59c40805, + 0x8c040d08, 0x04020021, 0x8c040d0c, 0x0402001c, + 0x8c040d0e, 0x04020017, 0x82040500, 0x000000f0, + 0x0402001c, 0x0201f800, 0x0010507b, 0x4a038808, + 0x00000080, 0x59c40002, 0x8400050c, 0x48038802, + 0x0401f9d7, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x00109640, 0x5c027800, 0x4a038808, + 0x00000080, 0x4a035017, 0x00000009, 0x0401f009, + 0x4a035017, 0x00000001, 0x0401f006, 0x4a035017, + 0x00000000, 0x0401f003, 0x4a035017, 0x00000003, + 0x1c01f000, 0x0401f8b7, 0x4a038808, 0x00000080, + 0x59c40805, 0x8c040d0a, 0x0402001b, 0x8c040d0c, + 0x04020016, 0x8c040d0e, 0x04020011, 0x82040500, + 0x000000f0, 0x04020016, 0x59c40002, 0x8400050c, + 0x48038802, 0x0401f9b2, 0x4d3c0000, 0x42027800, + 0x00000001, 0x0201f800, 0x00109640, 0x5c027800, + 0x4a035017, 0x00000009, 0x0401f009, 0x4a035017, + 0x00000001, 0x0401f006, 0x4a035017, 0x00000000, + 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, + 0x4a038808, 0x00000008, 0x59c40805, 0x8c040d0c, + 0x04020006, 0x8c040d0e, 0x04000006, 0x4a035017, + 0x00000001, 0x0401f003, 0x4a035017, 0x00000000, + 0x1c01f000, 0x0401f8d3, 0x59c40805, 0x8c040d0c, + 0x0402000d, 0x4c040000, 0x0401f882, 0x5c000800, + 0x8c040d0a, 0x04020006, 0x8c040d0e, 0x04000006, + 0x4a035017, 0x00000001, 0x0401f003, 0x4a035017, + 0x00000002, 0x1c01f000, 0x4a038808, 0x00000008, + 0x42001000, 0x00104d2c, 0x0201f800, 0x00105dbd, + 0x59c40805, 0x8c040d0a, 0x0402000d, 0x8c040d08, + 0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e, + 0x0400000d, 0x4a035017, 0x00000001, 0x0401f00a, + 0x4a035017, 0x00000000, 0x0401f007, 0x42000000, + 0x0010b642, 0x0201f800, 0x0010a86e, 0x4a035017, + 0x00000004, 0x1c01f000, 0x0401f8a6, 0x0401f859, + 0x59c40805, 0x8c040d0a, 0x0402000b, 0x8c040d0c, + 0x04020006, 0x8c040d0e, 0x04000009, 0x4a035017, + 0x00000001, 0x0401f006, 0x4a035017, 0x00000000, + 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, + 0x4a038808, 0x00000004, 0x0401f846, 0x59c40805, + 0x8c040d0a, 0x04020010, 0x8c040d08, 0x0402000b, + 0x8c040d0c, 0x04020006, 0x8c040d0e, 0x0400000c, + 0x4a035017, 0x00000001, 0x0401f009, 0x4a035017, + 0x00000000, 0x0401f006, 0x4a035017, 0x00000003, + 0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000, + 0x0401f91d, 0x02020800, 0x00100615, 0x59a80805, + 0x8c040d0c, 0x04000015, 0x84040d0c, 0x48075005, + 0x4a038805, 0x00000010, 0x0201f800, 0x001019a4, + 0x59c40005, 0x8c000508, 0x04000008, 0x4a038808, + 0x00000008, 0x4a035033, 0x00000001, 0x4202d800, + 0x00000001, 0x0401f01a, 0x59c40006, 0x84000548, + 0x48038806, 0x0401f016, 0x59a80017, 0x82000580, + 0x00000001, 0x0400000c, 0x59a80017, 0x82000580, + 0x00000005, 0x0402000c, 0x42000000, 0x0010b642, + 0x0201f800, 0x0010a86e, 0x4a035017, 0x00000008, + 0x0401f007, 0x42000000, 0x0010b642, 0x0201f800, + 0x0010a86e, 0x4a035017, 0x00000004, 0x1c01f000, + 0x4803c856, 0x4c040000, 0x4c080000, 0x42000800, + 0x00000064, 0x42001000, 0x00104d2c, 0x0201f800, + 0x00105db2, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x4803c856, 0x4c040000, 0x0201f800, 0x0010698c, + 0x4df00000, 0x0201f800, 0x00106b71, 0x5c03e000, + 0x02000800, 0x00106982, 0x0401ffba, 0x5c000800, + 0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000, + 0x0201f800, 0x0010698c, 0x4df00000, 0x0201f800, + 0x00106b71, 0x5c03e000, 0x02000800, 0x00106982, + 0x59c40006, 0x84000500, 0x48038806, 0x0201f800, + 0x00106c32, 0x497b8880, 0x0201f800, 0x0010a7e7, + 0x0201f800, 0x0010a7f5, 0x0201f800, 0x00101886, + 0x4a03504c, 0x00000004, 0x4202d800, 0x00000004, + 0x4a038805, 0x00000001, 0x42001000, 0x00104d2c, + 0x0201f800, 0x00105dbd, 0x0201f800, 0x0010071a, + 0x0401f8bf, 0x04000006, 0x42006000, 0xfeffffff, + 0x41786800, 0x0201f800, 0x001040ad, 0x0201f800, + 0x0010048c, 0x42000000, 0x00000001, 0x0201f800, + 0x001015fa, 0x5c001000, 0x5c000800, 0x1c01f000, + 0x59c40008, 0x8c000508, 0x04020007, 0x4a038808, + 0x00000010, 0x4201d000, 0x00001388, 0x0201f800, + 0x00105dd2, 0x1c01f000, 0x4c040000, 0x59a80833, + 0x82040580, 0x00000000, 0x0400000b, 0x82040580, + 0x00000001, 0x0400000b, 0x82040580, 0x00000002, + 0x0400000b, 0x82040580, 0x00000003, 0x0400000b, + 0x0401f055, 0x4a035017, 0x00000000, 0x0401f009, + 0x4a035017, 0x00000004, 0x0401f006, 0x4a035017, + 0x00000001, 0x0401f003, 0x4a035017, 0x00000007, + 0x497b8880, 0x4a038893, 0x00000001, 0x41780000, + 0x0201f800, 0x00101670, 0x0201f800, 0x00106c32, + 0x836c0d80, 0x00000004, 0x04000008, 0x59c40006, + 0x82000500, 0xffffff0f, 0x82000540, 0x04000001, + 0x48038806, 0x0401f007, 0x59c40006, 0x82000500, + 0xffffff0f, 0x82000540, 0x04000000, 0x48038806, + 0x0401f873, 0x04020005, 0x59c40806, 0x82040d00, + 0xfbffff0f, 0x48078806, 0x59c40005, 0x8c000534, + 0x04020033, 0x42006000, 0xfc18ffff, 0x42006800, + 0x01000000, 0x0201f800, 0x001040ad, 0x0201f800, + 0x001019a4, 0x59c408a4, 0x82040d00, 0x0000000f, + 0x82040d80, 0x0000000c, 0x040208a9, 0x0401f85c, + 0x04000006, 0x42006000, 0xfeffffff, 0x41786800, + 0x0201f800, 0x001040ad, 0x836c0d80, 0x00000004, + 0x0400000f, 0x0401f85a, 0x04020008, 0x59940005, + 0x82000580, 0x00103f37, 0x04020004, 0x59940004, + 0x800001c0, 0x04020006, 0x59a8084d, 0x42001000, + 0x00104d39, 0x0201f800, 0x00105da7, 0x4a035033, + 0x00000004, 0x0401fe33, 0x0401f841, 0x04020008, + 0x59c408a4, 0x82040d00, 0x0000000f, 0x82040580, + 0x0000000c, 0x02020800, 0x00100615, 0x5c000800, + 0x1c01f000, 0x4803c856, 0x4c000000, 0x0201f800, + 0x00105de2, 0x4a035010, 0x00ffffff, 0x497b5032, + 0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a, + 0x497b8880, 0x497b8893, 0x41780000, 0x0201f800, + 0x00101670, 0x59c40001, 0x82000500, 0xfffffcff, + 0x48038801, 0x42006000, 0xfc18ffff, 0x41786800, + 0x0201f800, 0x001040ad, 0x4a038808, 0x00000000, + 0x5c000000, 0x800001c0, 0x02020800, 0x00103f37, + 0x4a038805, 0x040000f0, 0x59c40006, 0x82000500, + 0xffffffcf, 0x82000540, 0x440000c1, 0x48038806, + 0x1c01f000, 0x4c5c0000, 0x59a8b832, 0x825cbd80, + 0x0000aaaa, 0x5c00b800, 0x1c01f000, 0x4c5c0000, + 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, + 0x00000000, 0x5c00b800, 0x1c01f000, 0x4c5c0000, + 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, + 0x00000010, 0x5c00b800, 0x1c01f000, 0x4c5c0000, + 0x599cb818, 0x825cbd00, 0x00000030, 0x825cbd80, + 0x00000020, 0x5c00b800, 0x1c01f000, 0x59a80005, + 0x4803c857, 0x82000d00, 0x00000013, 0x04000024, + 0x599c1017, 0x4d3c0000, 0x82000500, 0x00000011, + 0x04000006, 0x417a7800, 0x0201f800, 0x0010393e, + 0x0402000a, 0x0401f012, 0x42027800, 0x00000008, + 0x0201f800, 0x0010393e, 0x0400000d, 0x42003000, + 0x00000003, 0x0401f003, 0x42003000, 0x00000004, + 0x42028000, 0x0000000e, 0x0201f800, 0x0010a25b, + 0x599c1017, 0x8c08150a, 0x04020007, 0x42028000, + 0x00000004, 0x0201f800, 0x00101d90, 0x80000580, + 0x0401f80d, 0x5c027800, 0x0401f00a, 0x0201f800, + 0x0010393e, 0x04000007, 0x42028000, 0x0000000f, + 0x42003000, 0x00000001, 0x0201f800, 0x0010a25b, + 0x1c01f000, 0x59a80005, 0x04000004, 0x82000540, + 0x00000010, 0x0401f003, 0x82000500, 0xffffffef, + 0x48035005, 0x4803c857, 0x1c01f000, 0x4803c856, + 0x4c580000, 0x42000000, 0x0010b6ca, 0x0201f800, + 0x0010a86e, 0x42000800, 0x0010bef0, 0x59c40003, + 0x44000800, 0x59c40004, 0x48000801, 0x59c4000b, + 0x48000802, 0x59c4008e, 0x48000803, 0x59c4008f, + 0x48000804, 0x59c40090, 0x48000805, 0x59c40091, + 0x48000806, 0x59c40092, 0x48000807, 0x59c40093, + 0x48000808, 0x59c40099, 0x48000809, 0x59c4009e, + 0x4800080a, 0x59c400aa, 0x4800080b, 0x59c400af, + 0x4800080c, 0x59c400b2, 0x4800080d, 0x59c400b1, + 0x4800080e, 0x82040c00, 0x0000000f, 0x41c41800, + 0x4200b000, 0x00000030, 0x580c0050, 0x44000800, + 0x80040800, 0x800c1800, 0x8058b040, 0x040207fb, + 0x41c41800, 0x4200b000, 0x00000020, 0x580c0010, + 0x44000800, 0x80040800, 0x800c1800, 0x8058b040, + 0x040207fb, 0x497b8830, 0x4200b000, 0x00000040, + 0x59c40031, 0x44000800, 0x80040800, 0x8058b040, + 0x040207fc, 0x497b88ac, 0x4200b000, 0x00000010, + 0x59c400ad, 0x44000800, 0x80040800, 0x8058b040, + 0x040207fc, 0x59c41001, 0x4c080000, 0x8408150c, + 0x480b8801, 0x4a0370e4, 0x00000300, 0x4a0370e5, + 0xb0000000, 0x42000800, 0x00000800, 0x80040840, + 0x02000800, 0x00100615, 0x59b800e5, 0x8c000538, + 0x040207fb, 0x4a0370e4, 0x00000200, 0x42006000, + 0xffffffff, 0x42006800, 0x80000000, 0x0201f800, + 0x001040ad, 0x4a038807, 0x00000001, 0x497b8807, + 0x4a038808, 0x00000010, 0x42006000, 0xfcf8ffff, + 0x42006800, 0x01000000, 0x0201f800, 0x001040ad, + 0x5c001000, 0x480b8801, 0x42000800, 0x0010bef0, + 0x50040000, 0x48038803, 0x58040001, 0x48038804, + 0x58040002, 0x4803880b, 0x58040003, 0x4803888e, + 0x58040004, 0x4803888f, 0x58040005, 0x48038890, + 0x58040006, 0x48038891, 0x58040007, 0x48038892, + 0x58040008, 0x48038893, 0x58040009, 0x48038899, + 0x5804000a, 0x4803889e, 0x5804000b, 0x480388aa, + 0x5804000c, 0x480388af, 0x5804000d, 0x480388b2, + 0x5804000e, 0x480388b1, 0x82040c00, 0x0000000f, + 0x41c41800, 0x4200b000, 0x00000030, 0x50040000, + 0x48001850, 0x80040800, 0x800c1800, 0x8058b040, + 0x040207fb, 0x41c41800, 0x4200b000, 0x00000020, + 0x50040000, 0x48001810, 0x80040800, 0x800c1800, + 0x8058b040, 0x040207fb, 0x497b8830, 0x4200b000, + 0x00000040, 0x50040000, 0x48038831, 0x80040800, + 0x8058b040, 0x040207fc, 0x497b88ac, 0x4200b000, + 0x00000010, 0x50040000, 0x480388ad, 0x80040800, + 0x8058b040, 0x040207fc, 0x497b8880, 0x41780000, + 0x0201f800, 0x00101670, 0x59c408a4, 0x82040d00, + 0x0000000f, 0x82040580, 0x0000000c, 0x02020800, + 0x00100615, 0x4a038805, 0x04000000, 0x5c00b000, + 0x1c01f000, 0x4803c856, 0x4c580000, 0x4ce80000, + 0x42000000, 0x0010b643, 0x0201f800, 0x0010a86e, + 0x59c41008, 0x4c080000, 0x82080500, 0xffffff7f, + 0x48038808, 0x59c40004, 0x82000500, 0x00003e02, + 0x04000005, 0x4201d000, 0x00000014, 0x0201f800, + 0x00105dd2, 0x59c40006, 0x82000500, 0xffffff0f, + 0x48038806, 0x4a038805, 0x00000010, 0x4a038808, + 0x00000004, 0x4200b000, 0x00000065, 0x59c40005, + 0x8c000508, 0x04020012, 0x4201d000, 0x000003e8, + 0x0201f800, 0x00105dd2, 0x8058b040, 0x040207f8, + 0x0201f800, 0x00106c32, 0x4a038808, 0x00000008, + 0x4a035033, 0x00000001, 0x4202d800, 0x00000001, + 0x82000540, 0x00000001, 0x0401f030, 0x0201f800, + 0x00100b29, 0x42000000, 0x0010b6a7, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00100f42, 0x497b8880, + 0x59a8002a, 0x82000500, 0x0000ffff, 0x4c000000, + 0x0201f800, 0x00101670, 0x5c000000, 0x48038880, + 0x4a038808, 0x00000000, 0x4200b000, 0x00000065, + 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, + 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, + 0x04000008, 0x4201d000, 0x000003e8, 0x0201f800, + 0x00105dd2, 0x8058b040, 0x040207f2, 0x0401f7d1, + 0x59c40006, 0x82000540, 0x000000f0, 0x48038806, + 0x59a8001e, 0x80000540, 0x04020002, 0x80000000, + 0x48038893, 0x80000580, 0x5c001000, 0x4df00000, + 0x0201f800, 0x001019ca, 0x5c03e000, 0x480b8808, + 0x5c01d000, 0x5c00b000, 0x1c01f000, 0x4803c856, + 0x4c580000, 0x4ce80000, 0x59c41008, 0x82080500, + 0xffffff7f, 0x48038808, 0x4c080000, 0x59c40004, + 0x82000500, 0x00003e02, 0x04000005, 0x4201d000, + 0x00000014, 0x0201f800, 0x00105dd2, 0x0201f800, + 0x00100b29, 0x42000000, 0x0010b6a8, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00100f42, 0x4a038808, + 0x00000002, 0x80000580, 0x48038880, 0x48038893, + 0x0201f800, 0x00101670, 0x4200b000, 0x00000384, + 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, + 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, + 0x04000015, 0x82000500, 0x000000d0, 0x04020012, + 0x4201d000, 0x00000067, 0x0201f800, 0x00105dd2, + 0x8058b040, 0x040207ef, 0x0201f800, 0x00106c32, + 0x4a038808, 0x00000008, 0x4a035033, 0x00000001, + 0x4202d800, 0x00000001, 0x82000540, 0x00000001, + 0x0401f010, 0x497b8880, 0x59a8001e, 0x80000540, + 0x04020002, 0x80000000, 0x48038893, 0x59a8002a, + 0x82000500, 0x0000ffff, 0x4c000000, 0x0201f800, + 0x00101670, 0x5c000000, 0x48038880, 0x80000580, + 0x5c001000, 0x4df00000, 0x0201f800, 0x001019ca, + 0x5c03e000, 0x480b8808, 0x5c01d000, 0x5c00b000, + 0x1c01f000, 0x4803c856, 0x59c40004, 0x82000500, + 0x00003e02, 0x0400000a, 0x0201f800, 0x00106c32, + 0x4a038808, 0x00000008, 0x4a035033, 0x00000001, + 0x4202d800, 0x00000001, 0x0401f052, 0x0201f800, + 0x00100b29, 0x42000000, 0x0010b6a9, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00100f42, 0x59c40006, + 0x84000508, 0x48038806, 0x4a038805, 0x00000010, + 0x59a80805, 0x84040d4c, 0x48075005, 0x42000800, + 0x00000064, 0x42001000, 0x00104d2c, 0x0201f800, + 0x00105da7, 0x4a038808, 0x00000000, 0x497b8880, + 0x4a038805, 0x000000f0, 0x0201f800, 0x001019a4, + 0x42000800, 0x000000f0, 0x59c40005, 0x80040d00, + 0x0400000e, 0x82000500, 0x000000e0, 0x0402000b, + 0x4201d000, 0x000003e8, 0x0201f800, 0x00105dd2, + 0x0201f800, 0x00105c81, 0x59940004, 0x80000540, + 0x040207ec, 0x0401f023, 0x4c080000, 0x42001000, + 0x00104d39, 0x0201f800, 0x00105cc9, 0x42001000, + 0x00104d2c, 0x0201f800, 0x00105dbd, 0x5c001000, + 0x497b8880, 0x59a8001e, 0x80000540, 0x04020002, + 0x80000000, 0x48038893, 0x59a8002a, 0x82000500, + 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101670, + 0x5c000000, 0x48038880, 0x59a80805, 0x84040d0c, + 0x48075005, 0x59c40006, 0x84000548, 0x48038806, + 0x0201f800, 0x001019ca, 0x4a038808, 0x00000080, + 0x1c01f000, 0x4803c856, 0x4d400000, 0x4d3c0000, + 0x0201f800, 0x00106c32, 0x0201f800, 0x0010a95a, + 0x04020024, 0x599c1017, 0x59a80805, 0x8c040d00, + 0x0402000c, 0x8c08151a, 0x0400001e, 0x84040d42, + 0x48075005, 0x42028000, 0x00000004, 0x42027800, + 0x00000008, 0x8c081508, 0x04020007, 0x0401f011, + 0x42028000, 0x00000004, 0x417a7800, 0x8c081508, + 0x0400000c, 0x4d400000, 0x42028000, 0x0000000e, + 0x42028800, 0x0000ffff, 0x0201f800, 0x0010a258, + 0x5c028000, 0x599c0817, 0x8c040d0a, 0x04020005, + 0x4943c857, 0x493fc857, 0x0201f800, 0x00101d90, + 0x497b8880, 0x4202d800, 0x00000001, 0x0401fcff, + 0x5c027800, 0x5c028000, 0x1c01f000, 0x0201f800, + 0x00100b29, 0x42000000, 0x0010b6aa, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00100f42, 0x42000000, + 0x00000001, 0x0201f800, 0x00101670, 0x4a038880, + 0x00000001, 0x0201f000, 0x001019ca, 0x4202e000, + 0x00000000, 0x4a033015, 0x00000001, 0x497b301d, + 0x497b3006, 0x4a03b004, 0x60000001, 0x59d80005, + 0x4a03b004, 0x90000001, 0x4a03a804, 0x60000001, + 0x59d40005, 0x4a03a804, 0x90000001, 0x0201f000, + 0x00105667, 0x4a03c825, 0x00000004, 0x4a03c827, + 0x00000004, 0x599c0409, 0x80000d40, 0x04000020, + 0x599c0407, 0x80000540, 0x04000007, 0x800000cc, + 0x599c100b, 0x80080400, 0x4803b000, 0x497bb002, + 0x59d80001, 0x599c000b, 0x4803b000, 0x599c000c, + 0x4803b001, 0x599c0407, 0x80000540, 0x04020002, + 0x497bb002, 0x599c0c09, 0x82040540, 0x00400000, + 0x4803b003, 0x4a03b009, 0x00000004, 0x4a03b004, + 0x10000001, 0x59e00803, 0x82040d00, 0xfffffeff, + 0x82040d40, 0x00008000, 0x4807c003, 0x599c040a, + 0x80000540, 0x04000020, 0x599c0408, 0x80000540, + 0x04000007, 0x800000cc, 0x599c100f, 0x80080400, + 0x4803a800, 0x497ba802, 0x59d40001, 0x599c000f, + 0x4803a800, 0x599c0010, 0x4803a801, 0x599c0408, + 0x80000540, 0x04020002, 0x497ba802, 0x599c0c0a, + 0x82040540, 0x00400000, 0x4803a803, 0x4a03a809, + 0x00000004, 0x4a03a804, 0x10000001, 0x59e00803, + 0x82040d00, 0xfffffbff, 0x82040d40, 0x00008000, + 0x4807c003, 0x800409c0, 0x04000007, 0x4202e000, + 0x00000001, 0x0200b800, 0x00020685, 0x0200f000, + 0x0002069a, 0x1c01f000, 0x0201f800, 0x00100615, + 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, + 0x59981005, 0x800811c0, 0x0400001e, 0x58080005, + 0x82000d00, 0x43018780, 0x02020000, 0x0010552a, + 0x8c000508, 0x04000015, 0x580a5808, 0x592c0204, + 0x497a5800, 0x497a5801, 0x82000500, 0x000000ff, + 0x82000c80, 0x0000004b, 0x0402100b, 0x0c01f80f, + 0x5c03e000, 0x83700580, 0x00000003, 0x040007e6, + 0x0200f800, 0x0002069a, 0x0200b000, 0x00020685, + 0x1c01f000, 0x0401f850, 0x5c03e000, 0x0401f7f9, + 0x0401f8ee, 0x0401f7fd, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105171, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x001051f9, 0x00105161, 0x00105161, 0x00105171, + 0x00105171, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x492fc857, 0x42000000, 0x0010b65d, + 0x0201f800, 0x0010a86e, 0x42000000, 0x00000400, + 0x0401f019, 0x492fc857, 0x42000000, 0x0010b65c, + 0x0201f800, 0x0010a86e, 0x42000000, 0x00001000, + 0x0401f011, 0x492fc857, 0x42000000, 0x0010b65b, + 0x0201f800, 0x0010a86e, 0x42000000, 0x00002000, + 0x0401f009, 0x492fc857, 0x42000000, 0x0010b65e, + 0x0201f800, 0x0010a86e, 0x42000000, 0x00000800, + 0x0401f001, 0x4803c857, 0x4202e000, 0x00000001, + 0x592c0c04, 0x82040d00, 0xffff80ff, 0x80040540, + 0x48025c04, 0x0201f000, 0x00020381, 0x592c0204, + 0x492fc857, 0x80000110, 0x040007db, 0x80000040, + 0x04000035, 0x48033002, 0x492f3003, 0x492f3004, + 0x4a033008, 0x001051c5, 0x4202e000, 0x00000003, + 0x1c01f000, 0x592c0204, 0x492fc857, 0x80000110, + 0x040007cd, 0x80000040, 0x04000043, 0x48033002, + 0x492f3003, 0x492f3004, 0x4a033008, 0x001051e1, + 0x4202e000, 0x00000003, 0x1c01f000, 0x492fc857, + 0x0201f800, 0x0010a95a, 0x02020000, 0x0002060c, + 0x492fc857, 0x592e8a06, 0x83440c80, 0x000007f0, + 0x0402100b, 0x83440400, 0x0010aa00, 0x50000000, + 0x80026d40, 0x04000006, 0x4937c857, 0x59340200, + 0x8c00050e, 0x02020000, 0x0002060c, 0x42028000, + 0x00000028, 0x41780800, 0x417a6000, 0x0201f800, + 0x00104bee, 0x0201f800, 0x00108f7d, 0x0201f000, + 0x00020381, 0x592c0a0a, 0x8c040d02, 0x04020016, + 0x59a80021, 0x492fc857, 0x80000540, 0x0402000f, + 0x592c0207, 0x80000540, 0x04000005, 0x0201f800, + 0x00104156, 0x04020004, 0x1c01f000, 0x42000000, + 0x00000000, 0x592c0a06, 0x48065c06, 0x48025a06, + 0x0201f000, 0x00020381, 0x42000000, 0x00000028, + 0x0401f7f9, 0x42000800, 0x00000009, 0x0201f000, + 0x001063a9, 0x592c0208, 0x492fc857, 0x82000c80, + 0x0000199a, 0x04021794, 0x592c0408, 0x80000540, + 0x04020791, 0x59a80821, 0x800409c0, 0x04020009, + 0x592c0207, 0x80000540, 0x0400078b, 0x497a5a06, + 0x0201f800, 0x001041b5, 0x04020004, 0x1c01f000, + 0x42000000, 0x00000028, 0x48025a06, 0x0201f000, + 0x00020381, 0x59980804, 0x59980002, 0x48065800, + 0x492c0801, 0x492f3004, 0x80000040, 0x48033002, + 0x04000002, 0x1c01f000, 0x599a5803, 0x59980008, + 0x4202e000, 0x00000001, 0x0801f000, 0x592e8a06, + 0x592c0406, 0x4803c856, 0x82000500, 0x000000ff, + 0x4200b800, 0x00000001, 0x82000d80, 0x00000001, + 0x04000015, 0x417a8800, 0x4200b800, 0x000007f0, + 0x82000d80, 0x00000002, 0x0400000f, 0x80000540, + 0x02020000, 0x00020381, 0x592e8a06, 0x0201f800, + 0x00020267, 0x02020000, 0x00020381, 0x592e9008, + 0x592e9809, 0x0201f800, 0x00104567, 0x0201f000, + 0x00020381, 0x59a80805, 0x84040d00, 0x48075005, + 0x0201f800, 0x00020267, 0x02000800, 0x0010467a, + 0x81468800, 0x805cb840, 0x040207fa, 0x0201f000, + 0x00020381, 0x592c0a08, 0x4807c857, 0x82040580, + 0x0000000e, 0x04000045, 0x82040580, 0x00000046, + 0x04000046, 0x82040580, 0x00000045, 0x04000020, + 0x82040580, 0x00000029, 0x04000010, 0x82040580, + 0x0000002a, 0x04000009, 0x82040580, 0x0000000f, + 0x04000200, 0x82040580, 0x0000002e, 0x040001fd, + 0x4807c856, 0x0401f1f6, 0x59a80805, 0x84040d04, + 0x48075005, 0x0401f1f7, 0x592e8a06, 0x0201f800, + 0x00020267, 0x040201f3, 0x59340200, 0x84000518, + 0x48026a00, 0x592e6009, 0x4933c857, 0x83300580, + 0xffffffff, 0x0402002a, 0x0401f1ea, 0x592c1407, + 0x480bc857, 0x0201f800, 0x001091d9, 0x411e6000, + 0x04020003, 0x4803c856, 0x0401f1dd, 0x592e3809, + 0x591c1414, 0x84081516, 0x84081554, 0x480a3c14, + 0x4a026403, 0x0000003a, 0x592c040b, 0x80000540, + 0x04000007, 0x4a026403, 0x0000003b, 0x592c020c, + 0x4802641a, 0x592c040c, 0x4802621a, 0x4a026203, + 0x00000001, 0x42000800, 0x80000040, 0x0201f800, + 0x00020855, 0x0401f1cb, 0x59a80068, 0x84000510, + 0x48035068, 0x0401f1c7, 0x592c1207, 0x8c081500, + 0x040201c4, 0x592e8a06, 0x592e6009, 0x0201f800, + 0x001091e3, 0x04020003, 0x4803c856, 0x0401f1b8, + 0x59300c06, 0x82040580, 0x00000004, 0x04000003, + 0x4803c856, 0x0401f1b2, 0x59300a03, 0x82040580, + 0x00000007, 0x04000003, 0x4803c856, 0x0401f1ac, + 0x59300c03, 0x82040580, 0x00000001, 0x04000025, + 0x82040580, 0x00000003, 0x0400001a, 0x82040580, + 0x00000006, 0x04000024, 0x82040580, 0x00000008, + 0x04000019, 0x82040580, 0x0000000a, 0x0400000a, + 0x82040580, 0x0000000c, 0x04000004, 0x82040580, + 0x0000002e, 0x0402001c, 0x42000800, 0x00000009, + 0x0401f017, 0x59326809, 0x0201f800, 0x0010484b, + 0x04020015, 0x42000800, 0x00000005, 0x0401f010, + 0x417a7800, 0x0201f800, 0x00101de2, 0x4a026406, + 0x00000001, 0x42000800, 0x00000003, 0x0401f008, + 0x417a7800, 0x0201f800, 0x00101de2, 0x4a026406, + 0x00000001, 0x42000800, 0x0000000b, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x0201f800, + 0x00106470, 0x0401f17b, 0x40000800, 0x58040000, + 0x80000540, 0x040207fd, 0x492c0800, 0x1c01f000, + 0x492fc857, 0x59300c06, 0x82040580, 0x00000006, + 0x04020094, 0x0201f800, 0x00104836, 0x04020005, + 0x59340200, 0x8c00051a, 0x02000000, 0x00020667, + 0x59340200, 0x8c00050e, 0x0400008a, 0x59300203, + 0x42027800, 0x00000001, 0x82000580, 0x00000007, + 0x02020000, 0x00020667, 0x4a026203, 0x00000002, + 0x0201f000, 0x00020667, 0x42028000, 0x00000002, + 0x4a026206, 0x00000014, 0x4d2c0000, 0x0201f800, + 0x00109fc0, 0x5c025800, 0x59300c06, 0x4807c857, + 0x82040580, 0x00000007, 0x04020063, 0x492fc857, + 0x4a025a06, 0x00000001, 0x0201f000, 0x00020381, + 0x592c240a, 0x492fc857, 0x4813c857, 0x8c10251c, + 0x04020016, 0x8c10251a, 0x04000003, 0x8c10250a, + 0x04000069, 0x59340a00, 0x8c040d0e, 0x04000003, + 0x8c10251e, 0x04000064, 0x0201f800, 0x00020892, + 0x0400006b, 0x592c240a, 0x49366009, 0x49325809, + 0x4a026406, 0x00000006, 0x4a026203, 0x00000007, + 0x0201f000, 0x00020663, 0x592c0a0c, 0x5934000f, + 0x41784000, 0x80001540, 0x0400006d, 0x58080204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000012, + 0x04020004, 0x5808020c, 0x80040580, 0x04000004, + 0x58080000, 0x40084000, 0x0401f7f3, 0x58080000, + 0x49781000, 0x802041c0, 0x04000006, 0x48004000, + 0x80000540, 0x04020007, 0x48226810, 0x0401f005, + 0x4802680f, 0x80000540, 0x04020002, 0x497a6810, + 0x4d2c0000, 0x400a5800, 0x4a025a06, 0x00000002, + 0x0201f800, 0x00020381, 0x5c025800, 0x0401f7bc, + 0x592c040a, 0x8c00051c, 0x04000016, 0x592c0206, + 0x82000580, 0x0000ffff, 0x04020012, 0x592e6009, + 0x83300580, 0xffffffff, 0x040007b1, 0x83300480, + 0x0010cfc0, 0x04001010, 0x59a8000b, 0x81300480, + 0x0402100d, 0x59300008, 0x800001c0, 0x04020005, + 0x59300203, 0x82000580, 0x00000007, 0x04000797, + 0x492fc857, 0x4a025a06, 0x00000029, 0x0201f000, + 0x00020381, 0x492fc857, 0x4a025a06, 0x00000008, + 0x0201f000, 0x00020381, 0x492fc857, 0x4a025a06, + 0x00000045, 0x0201f000, 0x00020381, 0x492fc857, + 0x4a025a06, 0x0000002a, 0x0201f000, 0x00020381, + 0x492fc857, 0x4a025a06, 0x00000028, 0x0201f000, + 0x00020381, 0x492fc857, 0x4a025a06, 0x00000006, + 0x0201f000, 0x00020381, 0x492fc857, 0x4a025a06, + 0x0000000e, 0x0201f000, 0x00020381, 0x59340010, + 0x492e6810, 0x492fc857, 0x80000d40, 0x04000003, + 0x492c0800, 0x1c01f000, 0x5934040b, 0x492e680f, + 0x492fc857, 0x4803c857, 0x80000540, 0x04020003, + 0x4a026a03, 0x00000001, 0x1c01f000, 0x59a8000e, + 0x81640480, 0x0402176e, 0x42026000, 0x0010cfc0, + 0x59300009, 0x81340580, 0x04020004, 0x59300202, + 0x80040580, 0x04000759, 0x83326400, 0x00000024, + 0x41580000, 0x81300480, 0x040017f6, 0x0401f760, + 0x492fc857, 0x592c0407, 0x82000c80, 0x0000199a, + 0x040215dd, 0x592c0204, 0x80000112, 0x040205ca, + 0x592e8a06, 0x0201f800, 0x00020267, 0x04020059, + 0x0201f800, 0x00104836, 0x04020059, 0x592e780a, + 0x493fc857, 0x8d3e7d3e, 0x04020007, 0x59a80021, + 0x80000540, 0x0402004f, 0x0201f800, 0x00104686, + 0x040005c9, 0x833c1d00, 0x0000001f, 0x040005c6, + 0x592c0207, 0x82000c80, 0x00001000, 0x040215c2, + 0x800000c2, 0x800008c4, 0x8005d400, 0x592e9008, + 0x592e9809, 0x5934080d, 0x800409c0, 0x0402002e, + 0x833c1d00, 0x0000001f, 0x81780040, 0x80000000, + 0x800c1902, 0x040217fe, 0x040205b3, 0x0c01f001, + 0x001053cd, 0x001053d0, 0x001053dd, 0x001053e0, + 0x001053e3, 0x0201f800, 0x00108dfb, 0x0401f01a, + 0x0201f800, 0x00104659, 0x04000027, 0x80e9d1c0, + 0x02020800, 0x00105ce7, 0x42028000, 0x00000005, + 0x417a9000, 0x417a9800, 0x0201f800, 0x00108e0b, + 0x0401f00d, 0x42027000, 0x0000004d, 0x0401f006, + 0x42027000, 0x0000004e, 0x0401f003, 0x42027000, + 0x00000052, 0x0201f800, 0x0010451d, 0x02020800, + 0x00108e3b, 0x04000010, 0x8d3e7d3e, 0x04020017, + 0x1c01f000, 0x58040002, 0x80000540, 0x04020007, + 0x4d3c0000, 0x40067800, 0x0201f800, 0x00104639, + 0x5c027800, 0x040207cb, 0x4a025a06, 0x00000030, + 0x0401f00d, 0x4a025a06, 0x0000002c, 0x0401f00a, + 0x4a025a06, 0x00000028, 0x0401f007, 0x4a025a06, + 0x00000029, 0x0401f004, 0x497a5c09, 0x4a025a06, + 0x00000000, 0x4a025a04, 0x00000103, 0x0201f000, + 0x00020381, 0x492fc857, 0x592c0204, 0x80000110, + 0x80000040, 0x04000002, 0x0401f55b, 0x592c0207, + 0x82000500, 0x000003ff, 0x48025a07, 0x8c000506, + 0x04000004, 0x82000500, 0x00000070, 0x04020004, + 0x59a80821, 0x800409c0, 0x04020018, 0x4a025a06, + 0x0000dead, 0x592c0408, 0x82000500, 0x0000f0ff, + 0x48025c08, 0x0201f800, 0x001041e4, 0x04020002, + 0x1c01f000, 0x49425a06, 0x8058b1c0, 0x04000009, + 0x0201f800, 0x00109328, 0x0401f80f, 0x44042800, + 0x82580580, 0x00000002, 0x04020002, 0x48082801, + 0x0201f000, 0x00020381, 0x42028000, 0x00000031, + 0x42000800, 0x00000001, 0x4200b000, 0x00000001, + 0x0401f7ed, 0x592c0408, 0x80000118, 0x832c2c00, + 0x00000009, 0x80142c00, 0x1c01f000, 0x492fc857, + 0x4a025a08, 0x00000006, 0x0201f000, 0x00020381, + 0x492fc857, 0x4a025a08, 0x00000001, 0x0201f000, + 0x00020381, 0x492fc857, 0x592c040a, 0x82000500, + 0x00000003, 0x04000020, 0x0201f800, 0x00020892, + 0x04000021, 0x592c0204, 0x492e6008, 0x82000500, + 0x000000ff, 0x82000580, 0x00000045, 0x0400000e, + 0x592c000b, 0x0201f800, 0x001059b9, 0x02000800, + 0x00020267, 0x04020018, 0x42027000, 0x00000041, + 0x49366009, 0x4a026406, 0x00000001, 0x0201f000, + 0x000208d8, 0x59300015, 0x8400055e, 0x48026015, + 0x42026800, 0x0010b320, 0x42027000, 0x00000040, + 0x0401f7f4, 0x4a025a06, 0x00000101, 0x0201f000, + 0x00020381, 0x4a025a06, 0x0000002c, 0x0201f000, + 0x00020381, 0x4a025a06, 0x00000028, 0x0201f800, + 0x00020381, 0x0201f000, 0x000208b4, 0x492fc857, + 0x0201f800, 0x0010601a, 0x0400000b, 0x592c0204, + 0x80000110, 0x80000040, 0x040204e7, 0x592c0c06, + 0x800409c0, 0x04000009, 0x42000000, 0x00000102, + 0x0401f003, 0x42000000, 0x00000104, 0x48025a06, + 0x0201f000, 0x00020381, 0x592c0c07, 0x800409c0, + 0x04000024, 0x82040480, 0x00000005, 0x04021021, + 0x4c040000, 0x80040800, 0x0201f800, 0x0010603f, + 0x5c001000, 0x04020018, 0x832c0400, 0x00000008, + 0x4000a000, 0x0201f800, 0x00106068, 0x04020012, + 0x592c1207, 0x82cc0580, 0x0010b30a, 0x04020009, + 0x58c80c0b, 0x84040d00, 0x84040d02, 0x8c081500, + 0x04000002, 0x84040d5e, 0x4805940b, 0x0401f001, + 0x42000000, 0x00000000, 0x48025a06, 0x0201f000, + 0x00020381, 0x42000000, 0x00000103, 0x0401f7fb, + 0x42000000, 0x00000102, 0x0401f7f8, 0x492fc857, + 0x592e7c06, 0x833c0500, 0xfffffffe, 0x04020043, + 0x592c4007, 0x42026000, 0x0010cfc0, 0x41581800, + 0x400c0000, 0x81300480, 0x04021023, 0x59300203, + 0x82000580, 0x00000000, 0x04000007, 0x59300008, + 0x80000d40, 0x04000004, 0x58040005, 0x80200580, + 0x04000004, 0x83326400, 0x00000024, 0x0401f7f1, + 0x58040204, 0x82000500, 0x000000ff, 0x82000d80, + 0x00000053, 0x04000007, 0x82000d80, 0x00000048, + 0x04000004, 0x82000580, 0x00000018, 0x04020023, + 0x4d2c0000, 0x0201f800, 0x00108997, 0x5c025800, + 0x0400001e, 0x4a025a06, 0x00000000, 0x0201f000, + 0x00020381, 0x592e8a06, 0x83440480, 0x000007f0, + 0x04021016, 0x83440400, 0x0010aa00, 0x50000000, + 0x80026d40, 0x04000011, 0x4d2c0000, 0x0201f800, + 0x00104619, 0x0400000c, 0x42028000, 0x00000005, + 0x592c0a08, 0x0201f800, 0x00104bee, 0x0201f800, + 0x00108f83, 0x0201f800, 0x00020381, 0x5c025800, + 0x0401f7e5, 0x5c025800, 0x4a025a06, 0x00000031, + 0x0201f000, 0x00020381, 0x492fc857, 0x4d2c0000, + 0x0201f800, 0x0010082a, 0x04000016, 0x492fc857, + 0x412f4000, 0x0201f800, 0x0010082a, 0x0400000e, + 0x492fc857, 0x412dd800, 0x0201f800, 0x00103941, + 0x0201f800, 0x0010394b, 0x49a1d80b, 0x5c025800, + 0x492dd80a, 0x0201f800, 0x00101fbb, 0x0201f000, + 0x00101fda, 0x41a25800, 0x0201f800, 0x0010083a, + 0x5c025800, 0x4a025a06, 0x00004005, 0x4a025c06, + 0x00000002, 0x0201f000, 0x00020381, 0x4807c857, + 0x485fc857, 0x4200b800, 0x00000001, 0x5c000800, + 0x4c5c0000, 0x0401f005, 0x4807c857, 0x485fc857, + 0x5c000800, 0x4d780000, 0x4803c857, 0x492fc857, + 0x8c00050e, 0x02020800, 0x0010060d, 0x4203e000, + 0x50000000, 0x4200b800, 0x00008003, 0x0201f000, + 0x0010061a, 0x592c0204, 0x80000110, 0x80000040, + 0x0402042d, 0x0201f800, 0x00104886, 0x04020002, + 0x1c01f000, 0x49425a06, 0x4806580d, 0x480a580e, + 0x4943c857, 0x4807c857, 0x480bc857, 0x0201f000, + 0x00020381, 0x592c0204, 0x80000110, 0x80000040, + 0x0402041d, 0x0201f800, 0x001049ec, 0x04020002, + 0x1c01f000, 0x49425a06, 0x48065811, 0x480a5812, + 0x0201f000, 0x00020381, 0x592c0204, 0x80000110, + 0x04000411, 0x80000040, 0x0402000c, 0x4202e000, + 0x00000001, 0x592c020a, 0x8c000504, 0x02000000, + 0x00020603, 0x592c0207, 0x82000c80, 0x00001001, + 0x04021415, 0x0401f009, 0x4202e000, 0x00000003, + 0x48033002, 0x492f3003, 0x492f3004, 0x4a033008, + 0x00020603, 0x1c01f000, 0x4202e000, 0x00000002, + 0x42000000, 0x0010bcd9, 0x50007000, 0x492c700b, + 0x4978700e, 0x4978700c, 0x592c0011, 0x592c0812, + 0x48007007, 0x48047008, 0x592c1013, 0x82080500, + 0xffff0000, 0x04000003, 0x0201f800, 0x00100615, + 0x4978700d, 0x82080480, 0x00000180, 0x4803c857, + 0x04001007, 0x4800700f, 0x4a007005, 0x00000180, + 0x4a007004, 0x00000060, 0x0401f005, 0x4978700f, + 0x48087005, 0x80081104, 0x48087004, 0x5838000a, + 0x48007003, 0x40381000, 0x0201f000, 0x001008a1, + 0x0201f800, 0x00100819, 0x04000003, 0x59980007, + 0x0801f000, 0x1c01f000, 0x40307000, 0x5838000b, + 0x80025d40, 0x0400001b, 0x58380002, 0x82000580, + 0x00000100, 0x0400001d, 0x4c380000, 0x592c0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000012, + 0x0400000b, 0x592c0208, 0x8400054e, 0x48025a08, + 0x4a025a06, 0x00000002, 0x4a025a04, 0x00000103, + 0x0201f800, 0x00020381, 0x0401f005, 0x4a025a06, + 0x00000010, 0x0201f800, 0x00020381, 0x5c007000, + 0x4202e000, 0x00000001, 0x4a007002, 0x00000100, + 0x49787010, 0x1c01f000, 0x58380004, 0x82000480, + 0x00000003, 0x04000087, 0x58380010, 0x8c000500, + 0x04020019, 0x4200b000, 0x00000003, 0x832cac00, + 0x00000011, 0x5838000a, 0x5838100d, 0x8008a400, + 0x4c380000, 0x0201f800, 0x0010a93e, 0x5c007000, + 0x5838000d, 0x82000400, 0x00000003, 0x4800700d, + 0x4a007010, 0x00000001, 0x58380004, 0x82000480, + 0x00000003, 0x48007004, 0x82000580, 0x00000003, + 0x0400006c, 0x5838000e, 0x80001d40, 0x04020020, + 0x4c380000, 0x0201f800, 0x00100819, 0x5c007000, + 0x04000010, 0x4a025a04, 0x0000010a, 0x42001800, + 0x00000005, 0x480c700e, 0x5838000c, 0x80000540, + 0x04020002, 0x5838000b, 0x40000800, 0x492c0801, + 0x492c700c, 0x42000800, 0x0000000f, 0x0401f011, + 0x4202e000, 0x00000008, 0x4a033007, 0x001055f9, + 0x1c01f000, 0x4202e000, 0x00000002, 0x42000000, + 0x0010bcd9, 0x50007000, 0x0401f7e7, 0x583a580c, + 0x400c0000, 0x42000800, 0x00000014, 0x80040c80, + 0x58381004, 0x5838000f, 0x41783000, 0x80000540, + 0x04020005, 0x84183540, 0x82081480, 0x00000003, + 0x0400003c, 0x40080000, 0x80040480, 0x04001002, + 0x40080800, 0x4004b000, 0x412c0000, 0x800c0400, + 0x4000a800, 0x5838000a, 0x5838100d, 0x8008a400, + 0x4c080000, 0x4c040000, 0x4c0c0000, 0x4c380000, + 0x0201f800, 0x0010a93e, 0x5c007000, 0x5c001800, + 0x5c000800, 0x40040000, 0x58381004, 0x80080480, + 0x48007004, 0x82000580, 0x00000003, 0x04000002, + 0x84183500, 0x5c000000, 0x80041400, 0x82080480, + 0x00000060, 0x04020003, 0x84183542, 0x41781000, + 0x400c0000, 0x80041c00, 0x820c0480, 0x00000014, + 0x04020003, 0x84183544, 0x40001800, 0x40080800, + 0x4804700d, 0x480c700e, 0x40180000, 0x0c01f001, + 0x00105644, 0x00105648, 0x00105646, 0x00105644, + 0x001055e0, 0x00105648, 0x00105646, 0x00105644, + 0x0201f800, 0x00100615, 0x5838100f, 0x0401f739, + 0x5838080d, 0x82040400, 0x00000002, 0x5838100a, + 0x80080400, 0x50001000, 0x800811c0, 0x0402000f, + 0x4202e000, 0x00000001, 0x583a580b, 0x4978700b, + 0x49787010, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000012, 0x02000000, 0x0002063b, + 0x0201f000, 0x00020603, 0x5838000a, 0x80040c00, + 0x82381c00, 0x00000007, 0x54041800, 0x80040800, + 0x800c1800, 0x54041800, 0x0401f71a, 0x0201f800, + 0x00100819, 0x02000800, 0x00100615, 0x4a02580a, + 0x0010bc78, 0x42000800, 0x0010bcd9, 0x452c0800, + 0x497a580b, 0x497a580c, 0x497a580d, 0x497a580e, + 0x497a580f, 0x4a025809, 0x0010559a, 0x497a5810, + 0x4a025802, 0x00000100, 0x4a025801, 0x00000001, + 0x1c01f000, 0x59c80007, 0x8c000502, 0x04000071, + 0x835c2c80, 0x00000005, 0x02001000, 0x00105c5c, + 0x59c82817, 0x4817506e, 0x497b9005, 0x82140500, + 0x00e00000, 0x0402004f, 0x82140500, 0x000003ff, + 0x82001c00, 0x00000006, 0x41cc2000, 0x42003000, + 0x00006080, 0x820c0480, 0x00000040, 0x04001006, + 0x42001000, 0x00000040, 0x820c1c80, 0x00000040, + 0x0401f003, 0x400c1000, 0x41781800, 0x54182000, + 0x80102000, 0x80183000, 0x80081040, 0x040207fc, + 0x800c19c0, 0x04000005, 0x59c80005, 0x80000000, + 0x48039005, 0x0401f7ea, 0x82140500, 0x01f60000, + 0x04020029, 0x82140500, 0x0000f000, 0x0400000b, + 0x82000c80, 0x00002000, 0x0402100f, 0x4a039005, + 0x00000140, 0x82140500, 0x0e000000, 0x80000132, + 0x0c01f83e, 0x1c01f000, 0x59cc0400, 0x82000500, + 0x0000ff00, 0x82000580, 0x00008100, 0x040007f4, + 0x0401f01c, 0x4817c857, 0x82140500, 0x000003ff, + 0x04020007, 0x59cc0400, 0x82000500, 0x0000ff00, + 0x82000580, 0x00008100, 0x04020012, 0x42000000, + 0x0010b6bc, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x00105b32, 0x4803c856, 0x4a039005, 0x00000140, + 0x0401f020, 0x4817c857, 0x82140500, 0x00f60000, + 0x04020004, 0x0201f800, 0x00105b6e, 0x040207d2, + 0x0201f800, 0x00104e0d, 0x04000010, 0x59c400a4, + 0x4803c857, 0x82000500, 0x0000000f, 0x82000580, + 0x0000000a, 0x04020009, 0x497b5016, 0x59c400a3, + 0x82000540, 0x00080000, 0x480388a3, 0x82000500, + 0xfff7ffff, 0x480388a3, 0x4817c856, 0x0201f800, + 0x0010a79f, 0x4a039005, 0x00000140, 0x0401f842, + 0x4803c856, 0x1c01f000, 0x00105702, 0x00105a13, + 0x001056fa, 0x001056fa, 0x001056fa, 0x001056fa, + 0x001056fa, 0x001056fa, 0x4803c857, 0x42000000, + 0x0010b659, 0x0201f800, 0x0010a86e, 0x4a039005, + 0x00000140, 0x1c01f000, 0x59cc0400, 0x82000d00, + 0x0000ff00, 0x82041500, 0x0000f000, 0x840409c0, + 0x82140500, 0x000003ff, 0x800018c4, 0x8c142d14, + 0x04000005, 0x59cc0002, 0x82000500, 0x00000003, + 0x800c1c80, 0x480f5016, 0x82080580, 0x00002000, + 0x04020013, 0x836c0580, 0x00000001, 0x0402000e, + 0x59cc0006, 0x82000500, 0xff000000, 0x82000580, + 0x11000000, 0x02020800, 0x001006ba, 0x04020011, + 0x0201f800, 0x00103951, 0x0201f800, 0x00105c81, + 0x0401f00c, 0x0401f81f, 0x0401f00a, 0x82080580, + 0x00003000, 0x04020003, 0x0401fa40, 0x0401f005, + 0x82080580, 0x00008000, 0x04020002, 0x0401fb36, + 0x1c01f000, 0x4817c857, 0x42000000, 0x0010b658, + 0x0201f800, 0x0010a86e, 0x836c0580, 0x00000003, + 0x0402000b, 0x4c080000, 0x4c0c0000, 0x42001000, + 0x00008048, 0x40141800, 0x80142120, 0x0201f800, + 0x00103857, 0x5c001800, 0x5c001000, 0x1c01f000, + 0x59cc0002, 0x82000500, 0xff000000, 0x82001580, + 0x01000000, 0x04000006, 0x82001580, 0x23000000, + 0x02020800, 0x001006ba, 0x040201c9, 0x82040580, + 0x00000023, 0x04020055, 0x59cc0004, 0x4803c857, + 0x59cc0006, 0x82000500, 0xff000000, 0x59cc0801, + 0x82040d00, 0x00ffffff, 0x80040540, 0x4803c857, + 0x0401fbb2, 0x02000800, 0x001006ba, 0x040001b8, + 0x59300c06, 0x82040580, 0x00000010, 0x04000012, + 0x82040580, 0x00000011, 0x0400000f, 0x82040580, + 0x00000001, 0x0400000c, 0x82040580, 0x00000004, + 0x04000009, 0x82040580, 0x00000008, 0x04000006, + 0x82040580, 0x0000000a, 0x02020800, 0x001006ba, + 0x040201a3, 0x59300004, 0x82000500, 0x80010000, + 0x04000006, 0x0201f800, 0x00106cb4, 0x02020800, + 0x001006ba, 0x0402019a, 0x59cc0a04, 0x48066202, + 0x59a80016, 0x800001c0, 0x02000800, 0x001006ba, + 0x04000193, 0x59cc0006, 0x82000500, 0xffff0000, + 0x82000d80, 0x02000000, 0x04020005, 0x42027000, + 0x00000015, 0x0201f000, 0x000208d8, 0x82000d80, + 0x02140000, 0x040007fa, 0x82000d80, 0x02100000, + 0x040007f7, 0x82000d80, 0x02100000, 0x040007f4, + 0x82000d80, 0x01000000, 0x02020800, 0x001006ba, + 0x0402017b, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x02020800, 0x001006ba, 0x04020175, 0x42027000, + 0x00000016, 0x0401f7e8, 0x82040580, 0x00000022, + 0x02020800, 0x001006ba, 0x0402016d, 0x59cc0004, + 0x4803c857, 0x59cc0006, 0x4803c857, 0x59cc0001, + 0x4803c857, 0x59a80016, 0x800001c0, 0x02000800, + 0x001006ba, 0x04000162, 0x59a80806, 0x8c040d14, + 0x04000011, 0x0401f97d, 0x0402000f, 0x0401f993, + 0x0400000d, 0x42027000, 0x0000004c, 0x59cc0001, + 0x82000500, 0x00ffffff, 0x0201f800, 0x00105c25, + 0x0400013e, 0x42028800, 0x0000ffff, 0x417a6800, + 0x0401f13a, 0x59cc0006, 0x82000500, 0xffff0000, + 0x82000d80, 0x03000000, 0x04020023, 0x59a80026, + 0x8c000508, 0x04000017, 0x8400054c, 0x48035026, + 0x59cc0800, 0x82040d00, 0x00ffffff, 0x48075010, + 0x497b8830, 0x84040d70, 0x48078832, 0x59c40802, + 0x84040d4c, 0x48078802, 0x59cc0007, 0x82000500, + 0x0000ffff, 0x48038893, 0x4803501e, 0x42000800, + 0x00000003, 0x59a81010, 0x0201f800, 0x001069af, + 0x59cc0006, 0x82000500, 0x0000ffff, 0x02020800, + 0x001006ba, 0x0402012a, 0x42027000, 0x00000017, + 0x0401f0e5, 0x82000d80, 0x04000000, 0x04020013, + 0x59cc0006, 0x82000500, 0x0000ffff, 0x02020800, + 0x001006ba, 0x0402011e, 0x0201f800, 0x00104e0d, + 0x04000004, 0x42027000, 0x0000001d, 0x0401f0d6, + 0x59a80026, 0x84000548, 0x48035026, 0x42027000, + 0x00000030, 0x0401f0d0, 0x82000d80, 0x05000000, + 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x02020800, 0x001006ba, 0x04020109, 0x42027000, + 0x00000018, 0x0401f0c4, 0x82000d80, 0x20100000, + 0x04020004, 0x42027000, 0x00000019, 0x0401f0be, + 0x82000d80, 0x21100000, 0x04020004, 0x42027000, + 0x0000001a, 0x0401f0b8, 0x82000d80, 0x52000000, + 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x02020800, 0x001006ba, 0x040200f1, 0x42027000, + 0x0000001b, 0x0401f0ac, 0x82000d80, 0x50000000, + 0x0402000a, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x02020800, 0x001006ba, 0x040200e5, 0x42027000, + 0x0000001c, 0x0401f0a0, 0x82000d80, 0x13000000, + 0x04020004, 0x42027000, 0x00000034, 0x0401f09a, + 0x82000d80, 0x12000000, 0x0402000a, 0x59cc0006, + 0x82000500, 0x0000ffff, 0x02020800, 0x001006ba, + 0x040200d3, 0x42027000, 0x00000024, 0x0401f08e, + 0x82000d00, 0xff000000, 0x82040d80, 0x24000000, + 0x04020004, 0x42027000, 0x0000002d, 0x0401f086, + 0x82000d00, 0xff000000, 0x82040d80, 0x53000000, + 0x04020004, 0x42027000, 0x0000002a, 0x0401f07e, + 0x82000d80, 0x0f000000, 0x04020004, 0x42027000, + 0x00000020, 0x0401f078, 0x82000d80, 0x61040000, + 0x04020036, 0x83cc1400, 0x00000006, 0x80080800, + 0x50080000, 0x82000500, 0x0000ffff, 0x82000480, + 0x00000004, 0x4c580000, 0x8000b104, 0x8058b1c0, + 0x04000026, 0x4c100000, 0x50041800, 0x820c1500, + 0x03000000, 0x80081130, 0x42000000, 0x0010b615, + 0x82082580, 0x00000000, 0x04020004, 0x42000000, + 0x0010b612, 0x0401f00c, 0x82082580, 0x00000001, + 0x04020004, 0x42000000, 0x0010b613, 0x0401f006, + 0x82082580, 0x00000002, 0x04020003, 0x42000000, + 0x0010b614, 0x0201f800, 0x0010a86e, 0x42001000, + 0x00008015, 0x820c2500, 0x0000ffff, 0x800c1920, + 0x0201f800, 0x00103857, 0x5c002000, 0x80040800, + 0x8058b040, 0x040207da, 0x5c00b000, 0x42027000, + 0x00000023, 0x0401f040, 0x82000d80, 0x60000000, + 0x04020004, 0x42027000, 0x0000003f, 0x0401f03a, + 0x82000d80, 0x54000000, 0x04020008, 0x0401fb36, + 0x02020800, 0x001006ba, 0x04020075, 0x42027000, + 0x00000046, 0x0401f030, 0x82000d80, 0x55000000, + 0x04020009, 0x0401fb54, 0x04020004, 0x42027000, + 0x00000041, 0x0401f028, 0x42027000, 0x00000042, + 0x0401f025, 0x82000d80, 0x78000000, 0x04020004, + 0x42027000, 0x00000045, 0x0401f01f, 0x82000d80, + 0x10000000, 0x04020004, 0x42027000, 0x0000004e, + 0x0401f019, 0x82000d80, 0x63000000, 0x04020004, + 0x42027000, 0x0000004a, 0x0401f013, 0x82000d00, + 0xff000000, 0x82040d80, 0x56000000, 0x04020004, + 0x42027000, 0x0000004f, 0x0401f00b, 0x82000d00, + 0xff000000, 0x82040d80, 0x57000000, 0x04020004, + 0x42027000, 0x00000050, 0x0401f003, 0x42027000, + 0x0000001d, 0x59cc3800, 0x821c3d00, 0x00ffffff, + 0x821c0580, 0x00fffffe, 0x59cc0001, 0x04020005, + 0x40003000, 0x42028800, 0x000007fe, 0x0401f005, + 0x0401f8da, 0x02020800, 0x001006ba, 0x04020034, + 0x0201f800, 0x00104401, 0x02020800, 0x001006ba, + 0x0402002f, 0x83380580, 0x00000046, 0x04020006, + 0x59a80010, 0x80180580, 0x02000800, 0x001006ba, + 0x04000027, 0x59340200, 0x8c000514, 0x0400000f, + 0x83380580, 0x00000030, 0x0400000c, 0x83380580, + 0x0000003f, 0x04000009, 0x83380580, 0x00000034, + 0x04000006, 0x83380580, 0x00000024, 0x04000003, + 0x42027000, 0x0000004c, 0x0201f800, 0x00020892, + 0x04000018, 0x49366009, 0x4a026406, 0x00000004, + 0x59cc0c04, 0x48066202, 0x83380580, 0x0000004c, + 0x04020009, 0x4a026406, 0x00000011, 0x813669c0, + 0x04020005, 0x59cc0001, 0x82000500, 0x00ffffff, + 0x4802601e, 0x0201f000, 0x000208d8, 0x59880053, + 0x4803c857, 0x80000000, 0x48031053, 0x1c01f000, + 0x42001000, 0x00008049, 0x59cc1806, 0x800c1930, + 0x0201f800, 0x00103857, 0x0201f800, 0x001076c9, + 0x02000800, 0x001006ba, 0x040007f1, 0x49366009, + 0x4a026406, 0x00000004, 0x59cc0c04, 0x48066202, + 0x4a026403, 0x00000009, 0x4a02641a, 0x00000009, + 0x4a02621a, 0x00002900, 0x4a026203, 0x00000001, + 0x0201f000, 0x00106470, 0x59a80026, 0x4803c857, + 0x8c000508, 0x04000010, 0x59cc0006, 0x82000500, + 0xff000000, 0x82000d80, 0x03000000, 0x0400000c, + 0x82000d80, 0x20000000, 0x04000009, 0x82000d80, + 0x05000000, 0x04000006, 0x82000d80, 0x21000000, + 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fd, 0x59cc2006, 0x82102500, + 0xff000000, 0x9c1021c0, 0x0401f807, 0x820c1c00, + 0x0010b2df, 0x500c1800, 0x800c0500, 0x4803c857, + 0x1c01f000, 0x40100800, 0x41781800, 0x82040480, + 0x00000020, 0x04001004, 0x800c1800, 0x40000800, + 0x0401f7fb, 0x82040500, 0x0000000f, 0x82000400, + 0x0010a95f, 0x50000000, 0x8c040d08, 0x04000002, + 0x900001c0, 0x1c01f000, 0x4803c856, 0x0401fadd, + 0x0402000a, 0x0201f800, 0x00101eb0, 0x04020007, + 0x59cc0002, 0x82000500, 0xff000000, 0x82000d80, + 0x08000000, 0x04000802, 0x1c01f000, 0x4803c856, + 0x59cc0400, 0x82000d00, 0x0000ff00, 0x840409c0, + 0x82040580, 0x00000033, 0x0402001f, 0x0401f98f, + 0x04000038, 0x59cc0a04, 0x48066202, 0x59cc0006, + 0x4803c857, 0x82000500, 0xffff0000, 0x82000d80, + 0x02000000, 0x04020009, 0x59cc0006, 0x82000500, + 0x0000ffff, 0x0402002b, 0x42027000, 0x00000015, + 0x0201f000, 0x000208d8, 0x82000d80, 0x01000000, + 0x04020024, 0x59cc0006, 0x82000500, 0x0000ffff, + 0x04020020, 0x42027000, 0x00000016, 0x0201f000, + 0x000208d8, 0x82040580, 0x00000032, 0x04020019, + 0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80, + 0x14000000, 0x04020013, 0x42027000, 0x00000038, + 0x59cc0001, 0x0401f810, 0x0402000e, 0x0201f800, + 0x001043fc, 0x0402000b, 0x0201f800, 0x00020892, + 0x04000008, 0x49366009, 0x4a026406, 0x00000004, + 0x59cc0c04, 0x48066202, 0x0201f000, 0x000208d8, + 0x1c01f000, 0x4803c857, 0x4c580000, 0x4c100000, + 0x4c380000, 0x4c340000, 0x82003500, 0x00ffffff, + 0x82181500, 0x00ff0000, 0x82081580, 0x00ff0000, + 0x04020016, 0x82181480, 0x00fffffc, 0x04001013, + 0x82181580, 0x00fffffd, 0x04020004, 0x42028800, + 0x000007fd, 0x0401f040, 0x82181580, 0x00fffffe, + 0x04020004, 0x42028800, 0x000007fe, 0x0401f03a, + 0x82181580, 0x00fffffc, 0x04020004, 0x42028800, + 0x000007fc, 0x0401f034, 0x41781000, 0x42002000, + 0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000, + 0x50380000, 0x80006d40, 0x04020005, 0x800811c0, + 0x0402001e, 0x8410155e, 0x0401f01c, 0x58340212, + 0x82000500, 0x0000ff00, 0x04000011, 0x59a84010, + 0x82204500, 0x00ffff00, 0x82180500, 0x00ffff00, + 0x04000002, 0x80200580, 0x58340002, 0x0402000f, + 0x82000500, 0x000000ff, 0x82184500, 0x000000ff, + 0x80204580, 0x04020009, 0x0401f006, 0x58340002, + 0x82000500, 0x00ffffff, 0x80184580, 0x04020003, + 0x40128800, 0x0401f00c, 0x80102000, 0x80387000, + 0x8058b040, 0x040207db, 0x800811c0, 0x04020005, + 0x481bc857, 0x82000540, 0x00000001, 0x0401f003, + 0x840a8d1e, 0x80000580, 0x5c006800, 0x5c007000, + 0x5c002000, 0x5c00b000, 0x1c01f000, 0x59a80026, + 0x8c00050e, 0x04000003, 0x8c000502, 0x04000006, + 0x59cc0c00, 0x80040910, 0x82040500, 0x0000000f, + 0x0c01f002, 0x1c01f000, 0x00105a2e, 0x00105a2e, + 0x00105a2e, 0x00105b1d, 0x00105a2e, 0x00105a30, + 0x00105a48, 0x00105a4b, 0x00105a2e, 0x00105a2e, + 0x00105a2e, 0x00105a2e, 0x00105a2e, 0x00105a2e, + 0x00105a2e, 0x00105a2e, 0x4803c856, 0x1c01f000, + 0x0401f8de, 0x04000014, 0x82140500, 0x000003ff, + 0x800000c4, 0x82000480, 0x00000008, 0x0400100e, + 0x59cc0001, 0x59326809, 0x59340802, 0x80040580, + 0x82000500, 0x00ffffff, 0x04020007, 0x59cc0a04, + 0x48066202, 0x42027000, 0x00000046, 0x0201f000, + 0x000208d8, 0x59cc0004, 0x4803c857, 0x1c01f000, + 0x59cc0004, 0x4803c857, 0x1c01f000, 0x0401f8c3, + 0x04000016, 0x82140500, 0x000003ff, 0x800000c4, + 0x82000480, 0x0000000c, 0x04001010, 0x59cc0001, + 0x82000500, 0x00ffffff, 0x59326809, 0x59340802, + 0x82040d00, 0x00ffffff, 0x80040580, 0x04020007, + 0x59cc0a04, 0x48066202, 0x42027000, 0x00000045, + 0x0201f000, 0x000208d8, 0x59cc0004, 0x4803c857, + 0x1c01f000, 0x59cc0004, 0x4803c857, 0x59cc0000, + 0x82000500, 0xff000000, 0x59cc1001, 0x82081500, + 0x00ffffff, 0x80080540, 0x4803c857, 0x4817c857, + 0x0401f9d8, 0x02020800, 0x001006ba, 0x04020016, + 0x0201f800, 0x00101eb0, 0x02020800, 0x001006ba, + 0x04020011, 0x59cc0002, 0x82000500, 0xff000000, + 0x82000580, 0x00000000, 0x02020800, 0x001006ba, + 0x04020009, 0x82040500, 0x0000000f, 0x82000c80, + 0x00000006, 0x02021800, 0x001006ba, 0x04021002, + 0x0c01f003, 0x4803c856, 0x1c01f000, 0x00105a91, + 0x00105a93, 0x00105a91, 0x00105a91, 0x00105aec, + 0x00105afb, 0x4803c856, 0x1c01f000, 0x59a80016, + 0x800001c0, 0x02020800, 0x001006ba, 0x040207fa, + 0x59cc0802, 0x4807c856, 0x8c040d2e, 0x0402001d, + 0x0201f800, 0x001076c9, 0x02000800, 0x00100615, + 0x59cc0001, 0x0401ff18, 0x0402000d, 0x0201f800, + 0x00020267, 0x0402000a, 0x4a026406, 0x00000005, + 0x49366009, 0x59cc0804, 0x4806601c, 0x42027000, + 0x00000088, 0x0201f000, 0x000208d8, 0x4803c857, + 0x42028800, 0x0000ffff, 0x417a6800, 0x59cc0001, + 0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7ef, + 0x59cc0001, 0x4803c857, 0x0401feff, 0x02020800, + 0x001006ba, 0x040207d4, 0x0201f800, 0x001043fc, + 0x02020800, 0x001006ba, 0x040207cf, 0x59cc0005, + 0x8c000500, 0x04020006, 0x59340200, 0x8c00050e, + 0x02020800, 0x001006ba, 0x040207c7, 0x0201f800, + 0x00104842, 0x04020013, 0x0401f840, 0x02000800, + 0x001006ba, 0x040007c0, 0x0201f800, 0x00020892, + 0x02000800, 0x001006ba, 0x040007bb, 0x49366009, + 0x4a026406, 0x00000002, 0x59cc0804, 0x4806601c, + 0x42027000, 0x00000088, 0x0201f000, 0x000208d8, + 0x0201f800, 0x00020892, 0x040007af, 0x49366009, + 0x4a026406, 0x00000004, 0x59cc0c04, 0x48066202, + 0x42027000, 0x00000001, 0x0201f000, 0x000208d8, + 0x59cc0802, 0x8c040d2e, 0x0400000b, 0x0401f81f, + 0x04000009, 0x0401f961, 0x04020007, 0x59cc0a04, + 0x48066202, 0x42027000, 0x00000089, 0x0201f000, + 0x000208d8, 0x4933c857, 0x1c01f000, 0x59cc0004, + 0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b, + 0x0401f80e, 0x04000009, 0x0401f950, 0x04020007, + 0x59cc0a04, 0x48066202, 0x42027000, 0x0000008a, + 0x0201f000, 0x000208d8, 0x4933c857, 0x1c01f000, + 0x59cc0a04, 0x0401f002, 0x59cc0c04, 0x59a8000e, + 0x59a81067, 0x80080400, 0x80040480, 0x04021008, + 0x40040000, 0x800000c4, 0x800408ca, 0x80040c00, + 0x82066400, 0x0010cfc0, 0x1c01f000, 0x80000580, + 0x0401f7fe, 0x59cc0802, 0x8c040d2e, 0x04020010, + 0x0401ffec, 0x0400000e, 0x59cc0001, 0x82000500, + 0x00ffffff, 0x59326809, 0x59340802, 0x82040d00, + 0x00ffffff, 0x80040580, 0x04020005, 0x42027000, + 0x00000051, 0x0201f000, 0x000208d8, 0x59cc0004, + 0x4803c857, 0x1c01f000, 0x4803c856, 0x42003000, + 0x00000105, 0x0401f001, 0x4803c856, 0x4c3c0000, + 0x41cc7800, 0x40142000, 0x0401f803, 0x5c007800, + 0x1c01f000, 0x4803c856, 0x4c580000, 0x583c0400, + 0x82000500, 0x0000f000, 0x82000580, 0x0000c000, + 0x04000024, 0x0201f800, 0x00020892, 0x04000021, + 0x4c180000, 0x583c0001, 0x0401fe6f, 0x0402001f, + 0x0201f800, 0x001043fc, 0x0402001c, 0x49366009, + 0x0201f800, 0x0010082a, 0x04000018, 0x492e6017, + 0x497a5800, 0x497a5a04, 0x48125c04, 0x832cac00, + 0x00000005, 0x4200b000, 0x00000007, 0x403ca000, + 0x0201f800, 0x0010a93e, 0x5c003000, 0x481a641a, + 0x4a026403, 0x0000003e, 0x4a026406, 0x00000001, + 0x4a026203, 0x00000001, 0x0201f800, 0x00106470, + 0x5c00b000, 0x1c01f000, 0x0201f800, 0x000208b4, + 0x5c003000, 0x0401f7fb, 0x4803c856, 0x59cc0400, + 0x82000d00, 0x0000ff00, 0x82040500, 0x0000f000, + 0x840409c0, 0x82000580, 0x00002000, 0x04020049, + 0x82040580, 0x00000022, 0x0402003a, 0x59c400a4, + 0x82000500, 0x0000000f, 0x82000c80, 0x00000007, + 0x04001004, 0x82000480, 0x0000000c, 0x0400103f, + 0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80, + 0x04000000, 0x04000039, 0x82000d80, 0x60000000, + 0x04000036, 0x82000d80, 0x54000000, 0x04000033, + 0x82000d80, 0x03000000, 0x04020015, 0x59a80826, + 0x8c040d02, 0x0402002d, 0x8c040d08, 0x0402002b, + 0x0201f800, 0x0010473b, 0x0400002b, 0x59a8001d, + 0x800000d0, 0x59a80810, 0x82040d00, 0x000000ff, + 0x80040540, 0x59cc0800, 0x82040d00, 0x00ffffff, + 0x80040580, 0x0402001b, 0x0401f01c, 0x59c40802, + 0x8c040d0c, 0x04020017, 0x82000d80, 0x52000000, + 0x040007ec, 0x82000d80, 0x05000000, 0x040007e9, + 0x82000d80, 0x50000000, 0x040007e6, 0x0401f00d, + 0x82040580, 0x00000023, 0x0402000a, 0x0401ff57, + 0x04000008, 0x59300c03, 0x82040580, 0x00000002, + 0x04000006, 0x82040580, 0x00000051, 0x04000003, + 0x80000580, 0x0401f003, 0x82000540, 0x00000001, + 0x1c01f000, 0x59cc0006, 0x82000500, 0xffff0000, + 0x82000d80, 0x03000000, 0x04000004, 0x82000d80, + 0x52000000, 0x040207f3, 0x59a80026, 0x82000500, + 0x00000009, 0x82000580, 0x00000008, 0x040007ef, + 0x0401f7ec, 0x4803c856, 0x4c5c0000, 0x4c580000, + 0x59a80016, 0x82000580, 0x0000004c, 0x0402001f, + 0x59ccb807, 0x9c5cb9c0, 0x825cbd00, 0x00000007, + 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, + 0x83a81c00, 0x00000002, 0x83cc1400, 0x0000000d, + 0x0201f800, 0x001082ff, 0x04020010, 0x8c5cbd02, + 0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00, + 0x00000000, 0x83cc1400, 0x0000000f, 0x0201f800, + 0x001082ff, 0x04020005, 0x8c5cbd04, 0x04000003, + 0x82000540, 0x00000001, 0x5c00b000, 0x5c00b800, + 0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4c580000, + 0x59a80016, 0x82000580, 0x0000004c, 0x0402001f, + 0x59ccb807, 0x9c5cb9c0, 0x825cbd00, 0x00000007, + 0x8c5cbd00, 0x0400000a, 0x4200b000, 0x00000002, + 0x83a81c00, 0x00000002, 0x83cc1400, 0x00000009, + 0x0201f800, 0x001082ff, 0x04020010, 0x8c5cbd02, + 0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00, + 0x00000000, 0x83cc1400, 0x0000000b, 0x0201f800, + 0x001082ff, 0x04020005, 0x8c5cbd04, 0x04000003, + 0x82000540, 0x00000001, 0x5c00b000, 0x5c00b800, + 0x1c01f000, 0x4803c857, 0x4c580000, 0x40003000, + 0x42002000, 0x000007f0, 0x4200b000, 0x00000010, + 0x83ac7400, 0x000007f0, 0x50380000, 0x80026d40, + 0x04000006, 0x59340002, 0x82000500, 0x00ffffff, + 0x80180580, 0x04000010, 0x80102000, 0x80387000, + 0x8058b040, 0x040207f5, 0x82100480, 0x00000800, + 0x42002000, 0x00000000, 0x4200b000, 0x000007f0, + 0x41ac7000, 0x040217ed, 0x82000540, 0x00000001, + 0x0401f002, 0x40128800, 0x5c00b000, 0x1c01f000, + 0x59a80026, 0x8c00050e, 0x04000004, 0x8c000502, + 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fd, 0x59300c06, 0x82040580, + 0x00000002, 0x04000006, 0x82040580, 0x00000005, + 0x04000003, 0x82000540, 0x00000001, 0x1c01f000, + 0x59c80000, 0x84000558, 0x84000512, 0x48039000, + 0x1c01f000, 0x4a03281a, 0x000003e8, 0x4a032802, + 0x0010cfc0, 0x4a032800, 0x00000000, 0x4a032808, + 0x00106d9f, 0x42000000, 0x00000005, 0x83947c00, + 0x00000009, 0x49787801, 0x4a007802, 0x00106d54, + 0x823c7c00, 0x00000003, 0x80000040, 0x040207fa, + 0x4a032819, 0xffff0000, 0x4201d000, 0x00000064, + 0x0401f97c, 0x4201d000, 0x000186a0, 0x0401f18b, + 0x00000000, 0x00000003, 0x00000006, 0x00000009, + 0x0000000c, 0x4d300000, 0x4d2c0000, 0x4d340000, + 0x4d400000, 0x4cfc0000, 0x4d380000, 0x4d3c0000, + 0x4d440000, 0x4d4c0000, 0x4d480000, 0x4c5c0000, + 0x4c600000, 0x4c640000, 0x4cc80000, 0x4ccc0000, + 0x0201f800, 0x000206af, 0x5c019800, 0x5c019000, + 0x5c00c800, 0x5c00c000, 0x5c00b800, 0x5c029000, + 0x5c029800, 0x5c028800, 0x5c027800, 0x5c027000, + 0x5c01f800, 0x5c028000, 0x5c026800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x59940004, 0x80000540, + 0x0402000a, 0x59940025, 0x80040400, 0x02001800, + 0x00100615, 0x48032804, 0x480b2805, 0x4a032803, + 0x0000000a, 0x80000580, 0x1c01f000, 0x5994001f, + 0x80000540, 0x0402000a, 0x59940025, 0x80040400, + 0x02001800, 0x00100615, 0x4803281f, 0x480b2820, + 0x4a03281e, 0x00000001, 0x80000580, 0x1c01f000, + 0x59940022, 0x80000540, 0x0402000a, 0x59940025, + 0x80040400, 0x02001800, 0x00100615, 0x48032822, + 0x480b2823, 0x4a032821, 0x0000000a, 0x80000580, + 0x1c01f000, 0x4c000000, 0x59940005, 0x4803c857, + 0x480bc857, 0x80080580, 0x04020003, 0x497b2804, + 0x497b2805, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x59940020, 0x4803c857, 0x480bc857, 0x80080580, + 0x04020003, 0x497b281f, 0x497b2820, 0x5c000000, + 0x1c01f000, 0x4c000000, 0x59940023, 0x4803c857, + 0x480bc857, 0x80080580, 0x04020003, 0x497b2822, + 0x497b2823, 0x5c000000, 0x1c01f000, 0x4937c857, + 0x48ebc857, 0x59340203, 0x80e80480, 0x04001002, + 0x48ea6a03, 0x1c01f000, 0x5c03e000, 0x1c01f000, + 0x4d440000, 0x42007800, 0x00000010, 0x59968801, + 0x0201f800, 0x00020267, 0x04020012, 0x59341a03, + 0x800c1840, 0x0400100f, 0x59940027, 0x800c0480, + 0x04000003, 0x48026a03, 0x0402100a, 0x5934000f, + 0x497a6a03, 0x80000540, 0x04000006, 0x4c3c0000, + 0x5934140b, 0x0201f800, 0x00020275, 0x5c007800, + 0x81468800, 0x83440480, 0x00000800, 0x04021007, + 0x803c7840, 0x040207e7, 0x49472801, 0x5c028800, + 0x5c03e000, 0x1c01f000, 0x4a032800, 0x00000002, + 0x497b2801, 0x0401f7fa, 0x42007800, 0x00000010, + 0x59966002, 0x59300205, 0x80000d40, 0x04000006, + 0x59940027, 0x80040480, 0x48026205, 0x0400102d, + 0x0400002c, 0x59300206, 0x80000d40, 0x04000014, + 0x59b800e4, 0x8c000524, 0x04020011, 0x4a0370e4, + 0x00030000, 0x40000000, 0x59b800e4, 0x8c000524, + 0x04000004, 0x4a0370e4, 0x00020000, 0x0401f008, + 0x59940027, 0x80040480, 0x48026206, 0x4a0370e4, + 0x00020000, 0x0400101c, 0x0400001b, 0x83326400, + 0x00000024, 0x49332802, 0x41540000, 0x81300480, + 0x04021005, 0x803c7840, 0x040207db, 0x5c03e000, + 0x1c01f000, 0x59940026, 0x48032827, 0x4a032802, + 0x0010cfc0, 0x497b2826, 0x80000540, 0x0400000f, + 0x4a032800, 0x00000001, 0x5c03e000, 0x1c01f000, + 0x4c3c0000, 0x0201f800, 0x00108f92, 0x5c007800, + 0x0401f7d1, 0x4c3c0000, 0x0201f800, 0x00108b11, + 0x5c007800, 0x0401f7e2, 0x4a032800, 0x00000000, + 0x5c03e000, 0x1c01f000, 0x59a8086b, 0x8c040d30, + 0x04020029, 0x8c040d32, 0x0400000f, 0x59a80069, + 0x81640480, 0x04001019, 0x59a8000b, 0x81500580, + 0x04000005, 0x59a8006a, 0x59a81066, 0x80080580, + 0x04020012, 0x900411c0, 0x82081500, 0x00007000, + 0x0401f012, 0x82040500, 0x0000001f, 0x04000016, + 0x80040840, 0x82040500, 0x0000001f, 0x04000003, + 0x4807506b, 0x0401f010, 0x900401c0, 0x82000500, + 0x0000001f, 0x80040d40, 0x900401c0, 0x80040580, + 0x82001500, 0x00007000, 0x82040500, 0xffff8fff, + 0x80080540, 0x4803506b, 0x80081114, 0x0201f800, + 0x00100728, 0x1c01f000, 0x4a032807, 0x000007d0, + 0x4a032806, 0x0000000a, 0x1c01f000, 0x42000800, + 0x000007d0, 0x83180480, 0x00000005, 0x02021800, + 0x00100615, 0x83947c00, 0x00000009, 0x83180400, + 0x00105c7c, 0x50000000, 0x803c7c00, 0x48047801, + 0x4a007800, 0x0000000a, 0x1c01f000, 0x83180480, + 0x00000005, 0x02021800, 0x00100615, 0x83947c00, + 0x00000009, 0x83180400, 0x00105c7c, 0x50000000, + 0x803c7c00, 0x49787801, 0x1c01f000, 0x4807c857, + 0x480bc857, 0x59940025, 0x80040400, 0x02001800, + 0x00100615, 0x48032804, 0x480b2805, 0x4a032803, + 0x0000000a, 0x1c01f000, 0x4807c857, 0x480bc857, + 0x59940025, 0x80040400, 0x02001800, 0x00100615, + 0x4803281c, 0x480b281d, 0x4a03281b, 0x0000000a, + 0x1c01f000, 0x4c000000, 0x5994001d, 0x4803c857, + 0x480bc857, 0x80080580, 0x04020003, 0x4803281c, + 0x4803281d, 0x5c000000, 0x1c01f000, 0x4807c857, + 0x480bc857, 0x59940025, 0x80040400, 0x02001800, + 0x00100615, 0x48032822, 0x480b2823, 0x4a032821, + 0x0000000a, 0x1c01f000, 0x80e9d1c0, 0x0400000e, + 0x0401f832, 0x04025000, 0x4203e000, 0x80000000, + 0x40e81000, 0x41780800, 0x42000000, 0x00000064, + 0x0201f800, 0x001063ee, 0x59940024, 0x80080400, + 0x48032824, 0x1c01f000, 0x42001000, 0x00104d39, + 0x0401fee5, 0x42001000, 0x00104d2c, 0x0401ffd6, + 0x42001000, 0x00103f62, 0x0401fedf, 0x42001000, + 0x00103fe4, 0x0401fedc, 0x42001000, 0x00103f37, + 0x0401fed9, 0x42001000, 0x0010401b, 0x0401f6ea, + 0x4203e000, 0x70000000, 0x4203e000, 0xb0300000, + 0x40ebf800, 0x42000000, 0x0000003c, 0x04004004, + 0x80000040, 0x040207fe, 0x0401f007, 0x4203e000, + 0x70000000, 0x42000000, 0x0010b67d, 0x0201f800, + 0x0010a86e, 0x1c01f000, 0x4203e000, 0x80000000, + 0x4203e000, 0xb0400000, 0x40ebf800, 0x42000000, + 0x0000003c, 0x04005004, 0x80000040, 0x040207fe, + 0x0401f007, 0x4203e000, 0x80000000, 0x42000000, + 0x0010b67e, 0x0201f800, 0x0010a86e, 0x1c01f000, + 0x59a8000e, 0x82000480, 0x00000100, 0x599c0a02, + 0x800409c0, 0x04020002, 0x80040800, 0x80041480, + 0x04001002, 0x40000800, 0x48075067, 0x59a8100e, + 0x40040000, 0x800acc80, 0x4967500e, 0x49675069, + 0x59aaa80b, 0x41640800, 0x42001000, 0x00000024, + 0x0201f800, 0x001063cf, 0x8206a400, 0x0010cfc0, + 0x49535065, 0x4152b000, 0x42006000, 0x0010bc64, + 0x4a006004, 0x0000012c, 0x4a006005, 0xda10da10, + 0x4a006008, 0x00000011, 0x4a006009, 0x0010bc64, + 0x4a00600a, 0x00101108, 0x599c0014, 0x48006011, + 0x599c0015, 0x48006012, 0x42006000, 0x0010bc40, + 0x4a006203, 0x00000008, 0x4a006406, 0x00000006, + 0x4a006002, 0xffff0000, 0x4a006008, 0x0010bc64, + 0x4a006014, 0x0010bc64, 0x599c0014, 0x48006015, + 0x599c0015, 0x48006016, 0x599c0413, 0x48006017, + 0x49506018, 0x49546019, 0x59a80067, 0x4800601a, + 0x4a00601b, 0x0010b265, 0x4a00601c, 0x0010b266, + 0x4a00601d, 0x0010b26a, 0x42000000, 0xb0000000, + 0x42000800, 0x0010bc40, 0x0201f800, 0x00100bb2, + 0x1c01f000, 0x82000d00, 0x000000c0, 0x04000004, + 0x82040d80, 0x000000c0, 0x04020055, 0x82000d00, + 0x00002020, 0x59300414, 0x84000512, 0x82040d80, + 0x00002020, 0x0400000b, 0x8c000514, 0x0402000f, + 0x48026414, 0x813e79c0, 0x02020000, 0x00020804, + 0x42027000, 0x00000043, 0x0201f000, 0x000208d8, + 0x59326809, 0x59340a00, 0x8c040d0a, 0x040007f3, + 0x84000552, 0x0401f7f1, 0x84000514, 0x592c080d, + 0x48066015, 0x0401f7ef, 0x59326809, 0x59340a00, + 0x8c040d0a, 0x02000000, 0x00020817, 0x59300c14, + 0x84040d52, 0x48066414, 0x0201f000, 0x00020817, + 0x0201f800, 0x00020087, 0x813e79c0, 0x02020000, + 0x00020804, 0x0201f000, 0x00020825, 0x8c00051e, + 0x02000000, 0x00020831, 0x82000d00, 0x00002020, + 0x82040d80, 0x00002020, 0x04000014, 0x82000500, + 0x000000c0, 0x82000d80, 0x00000080, 0x04000008, + 0x813e79c0, 0x02020000, 0x00020804, 0x42027000, + 0x00000041, 0x0201f000, 0x000208d8, 0x813e79c0, + 0x02020000, 0x00020804, 0x42027000, 0x00000043, + 0x0201f000, 0x000208d8, 0x59326809, 0x59340a00, + 0x8c040d0a, 0x040007ea, 0x59300c14, 0x84040d52, + 0x48066414, 0x0401f7e6, 0x492fc857, 0x42000800, + 0x00000006, 0x0201f000, 0x0002082c, 0x492fc857, + 0x42000800, 0x00000004, 0x0201f000, 0x0002082c, + 0x4807c856, 0x59a80068, 0x800409c0, 0x04000003, + 0x80080540, 0x0401f002, 0x80080500, 0x48035068, + 0x1c01f000, 0x4a030800, 0x00000000, 0x4a030802, + 0x00000001, 0x497b0803, 0x497b0804, 0x1c01f000, + 0x59840002, 0x8c000500, 0x04000004, 0x84000500, + 0x4a030800, 0x00000001, 0x84000544, 0x84000506, + 0x48030802, 0x82000d00, 0x0fffffff, 0x42000000, + 0x90000000, 0x0201f800, 0x00100bde, 0x59a80069, + 0x82000480, 0x00000007, 0x48035069, 0x80000580, + 0x42000800, 0x0010b315, 0x48000800, 0x48000801, + 0x1c01f000, 0x59a80069, 0x82000400, 0x00000007, + 0x48035069, 0x1c01f000, 0x83640480, 0x00000008, + 0x0400101b, 0x58c80a03, 0x80000580, 0x82000400, + 0x00000008, 0x80040840, 0x040207fd, 0x815c0480, + 0x04001013, 0x4200b000, 0x00000007, 0x0201f800, + 0x00020892, 0x4a026203, 0x00000004, 0x4a026406, + 0x00000009, 0x4a026203, 0x00000004, 0x4a026007, + 0x00000101, 0x0401f809, 0x0401f880, 0x8058b040, + 0x040207f3, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x0401f7fd, 0x0201f800, 0x0010082a, + 0x492e6008, 0x58c80a03, 0x4a025a04, 0x0000002c, + 0x497a5800, 0x497a5801, 0x497a5c04, 0x497a5c06, + 0x497a5805, 0x4a025a08, 0x00000005, 0x4a025a07, + 0x00000002, 0x58c80201, 0x48025c04, 0x58c80202, + 0x48025c07, 0x58c80204, 0x48025c08, 0x4a02580d, + 0x0000ffff, 0x80040840, 0x0400000c, 0x412c2000, + 0x0201f800, 0x0010082a, 0x4a025a04, 0x0000000a, + 0x497a5c04, 0x48125800, 0x492c2001, 0x412c2000, + 0x80040840, 0x040207f7, 0x1c01f000, 0x4d7c0000, + 0x4202f800, 0x00000010, 0x4df00000, 0x4203e000, + 0x50000000, 0x59847803, 0x803c79c0, 0x0400001e, + 0x4c5c0000, 0x583cb808, 0x585c3408, 0x801831c0, + 0x0400000b, 0x0401f84a, 0x04000016, 0x42001000, + 0x0010b315, 0x0401f87f, 0x04000012, 0x0201f800, + 0x00100819, 0x0400000f, 0x492cb805, 0x585c0005, + 0x80000540, 0x02000800, 0x00100615, 0x0401f830, + 0x585c5408, 0x0401f80b, 0x5c00b800, 0x5c03e000, + 0x817ef840, 0x040207e1, 0x5c02f800, 0x1c01f000, + 0x5c00b800, 0x5c03e000, 0x5c02f800, 0x1c01f000, + 0x4803c856, 0x405c6000, 0x802851c0, 0x04000018, + 0x585c0204, 0x82000d00, 0x0000000f, 0x82040c00, + 0x0010110d, 0x50044000, 0x4c600000, 0x4c640000, + 0x4d040000, 0x4020c000, 0x40320800, 0x5984c804, + 0x4c280000, 0x0401f934, 0x5c005000, 0x40604000, + 0x41046000, 0x0201f800, 0x001010eb, 0x040207f6, + 0x5c020800, 0x5c00c800, 0x5c00c000, 0x58c80204, + 0x4800bc08, 0x0201f800, 0x00020087, 0x4a026007, + 0x00000101, 0x497a6009, 0x0401f055, 0x4803c856, + 0x59840003, 0x80026540, 0x04000003, 0x59300000, + 0x48030803, 0x1c01f000, 0x4803c856, 0x59840003, + 0x48026000, 0x49330803, 0x1c01f000, 0x58cc0805, + 0x40180000, 0x80040480, 0x0400100d, 0x82cc0580, + 0x0010b30a, 0x02020800, 0x00100615, 0x58c80205, + 0x80040480, 0x0400101d, 0x82000540, 0x00000001, + 0x1c01f000, 0x80003580, 0x0401f7fe, 0x82cc0580, + 0x0010b30a, 0x02020800, 0x00100615, 0x58c80400, + 0x8c000504, 0x040007f8, 0x58c8040b, 0x8c00051e, + 0x040007f5, 0x8c000500, 0x040207f3, 0x84000540, + 0x4801940b, 0x42000000, 0x0010b637, 0x0201f800, + 0x0010a86e, 0x42001000, 0x00008026, 0x0201f800, + 0x00103857, 0x0401f7e8, 0x58c8040b, 0x8c00051e, + 0x040007e2, 0x8c000502, 0x040207e0, 0x84000542, + 0x4801940b, 0x42000000, 0x0010b636, 0x0201f800, + 0x0010a86e, 0x42001000, 0x00008025, 0x42001800, + 0x00000000, 0x0201f800, 0x00103857, 0x0401f7d3, + 0x4803c856, 0x58080000, 0x42001800, 0x00000007, + 0x58080801, 0x80040480, 0x04020004, 0x400c0000, + 0x80000540, 0x0401f005, 0x04001003, 0x800c0480, + 0x0401f002, 0x80000080, 0x1c01f000, 0x4803c856, + 0x59300008, 0x80000d40, 0x02000800, 0x00100615, + 0x58040005, 0x80000540, 0x02000800, 0x00100615, + 0x59300007, 0x82000500, 0x00000101, 0x82000580, + 0x00000101, 0x02020800, 0x00100615, 0x42001000, + 0x0010b315, 0x58080801, 0x82040400, 0x0010b317, + 0x497a6414, 0x4a026015, 0x0000ffff, 0x45300000, + 0x80040800, 0x82040480, 0x00000008, 0x04001002, + 0x80000d80, 0x48041001, 0x82040400, 0x0010b317, + 0x45780000, 0x1c01f000, 0x4933c857, 0x59300808, + 0x800409c0, 0x02000800, 0x00100615, 0x4d2c0000, + 0x58065805, 0x812e59c0, 0x02020800, 0x0010083a, + 0x49780805, 0x40065800, 0x0201f800, 0x00100843, + 0x5c025800, 0x4d300000, 0x0201f800, 0x000208b4, + 0x5c026000, 0x1c01f000, 0x59300406, 0x82000580, + 0x00000009, 0x04020006, 0x59300007, 0x8c000510, + 0x04000003, 0x80000580, 0x1c01f000, 0x82000540, + 0x00000001, 0x1c01f000, 0x59840802, 0x8c040d04, + 0x1c01f000, 0x4803c856, 0x59840802, 0x84040d04, + 0x84040d40, 0x4a030800, 0x00000000, 0x48070802, + 0x82040d00, 0x0fffffff, 0x42000000, 0x90000000, + 0x0201f000, 0x00100bde, 0x4807c857, 0x4805980a, + 0x49799801, 0x49799803, 0x49799806, 0x49799807, + 0x49799808, 0x49799805, 0x49799809, 0x0401f8c8, + 0x0400000a, 0x0401f8ea, 0x04000008, 0x48359800, + 0x48359802, 0x48359806, 0x4a019804, 0x00000001, + 0x4a019807, 0x00000005, 0x1c01f000, 0x4807c857, + 0x58cc1007, 0x40040000, 0x80080480, 0x04021020, + 0x4c040000, 0x4c080000, 0x0401f8d9, 0x5c001000, + 0x5c000800, 0x0400001c, 0x58cc0006, 0x80006540, + 0x0402000b, 0x48359800, 0x48359802, 0x48359806, + 0x49799801, 0x49799803, 0x49786801, 0x49786800, + 0x49799804, 0x49799807, 0x0401f005, 0x48306801, + 0x48346000, 0x48359806, 0x49786800, 0x58cc0004, + 0x58cc1007, 0x80000000, 0x82081400, 0x00000005, + 0x48019804, 0x48099807, 0x0401f7df, 0x80000580, + 0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000, + 0x480bc857, 0x4c500000, 0x4c540000, 0x4c580000, + 0x40083000, 0x58cc0801, 0x82040480, 0x00000005, + 0x02021800, 0x00100615, 0x82040400, 0x00106150, + 0x50000000, 0x58cca800, 0x8054ac00, 0x42001800, + 0x00000005, 0x40040000, 0x800c0480, 0x80082480, + 0x04021002, 0x40080000, 0x8000b0c2, 0x8058b400, + 0x5450a800, 0x8050a000, 0x8054a800, 0x8058b040, + 0x040207fc, 0x40001000, 0x58cc2805, 0x58cc0807, + 0x58cc2001, 0x80142c00, 0x80040c80, 0x80102400, + 0x48159805, 0x48059807, 0x48119801, 0x82100580, + 0x00000005, 0x0400000c, 0x48119801, 0x40080000, + 0x80181480, 0x40083000, 0x04000003, 0x040217d6, + 0x80000580, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x1c01f000, 0x58cc0800, 0x800409c0, 0x02000800, + 0x00100615, 0x58040800, 0x48059800, 0x41782000, + 0x0401f7ee, 0x0401f812, 0x50600000, 0x81041c00, + 0x585c0204, 0x4803c857, 0x82000580, 0x0000002c, + 0x02020800, 0x00100615, 0x58040202, 0x800000e0, + 0x80640540, 0x48001802, 0x58040000, 0x48001800, + 0x58040001, 0x48001801, 0x1c01f000, 0x4807c856, + 0x58cc0005, 0x80000040, 0x02001800, 0x00100615, + 0x48019805, 0x58cc1003, 0x82080480, 0x00000005, + 0x02021800, 0x00100615, 0x82080400, 0x00106150, + 0x50000000, 0x58cc0802, 0x80040c00, 0x80081000, + 0x82080480, 0x00000005, 0x0402000f, 0x58cc2002, + 0x58100000, 0x80006d40, 0x04000009, 0x4c340000, + 0x0401f858, 0x5c006800, 0x49786801, 0x48359802, + 0x58cc0004, 0x80000040, 0x48019804, 0x49799803, + 0x0401f002, 0x48099803, 0x1c01f000, 0x4807c856, + 0x41781800, 0x58c80201, 0x80000540, 0x04000002, + 0x800c1800, 0x58c80c01, 0x80040c80, 0x0400100a, + 0x04000009, 0x800c1800, 0x58c80202, 0x80041480, + 0x04001005, 0x04000004, 0x800c1800, 0x40080800, + 0x0401f7fb, 0x480d9204, 0x400c0000, 0x42002000, + 0x00000001, 0x80000040, 0x04000007, 0x04001006, + 0x80102000, 0x82000480, 0x00000005, 0x04000002, + 0x040217fc, 0x48119203, 0x1c01f000, 0x4807c856, + 0x4d2c0000, 0x58cc000a, 0x80000540, 0x02000800, + 0x00100615, 0x82002400, 0x00000005, 0x0201f800, + 0x00100819, 0x04000012, 0x492d9809, 0x497a5800, + 0x497a5801, 0x0201f800, 0x00100819, 0x0400000c, + 0x58cc0009, 0x48025800, 0x497a5801, 0x492d9809, + 0x82102480, 0x00000005, 0x040217f7, 0x82000540, + 0x00000001, 0x5c025800, 0x1c01f000, 0x58cc0009, + 0x80025d40, 0x040007fc, 0x592c2000, 0x0201f800, + 0x0010083a, 0x40100000, 0x0401f7fa, 0x58cc0009, + 0x48cfc857, 0x80006d40, 0x04000005, 0x50340000, + 0x48019809, 0x49786800, 0x49786801, 0x1c01f000, + 0x4813c857, 0x58cc0009, 0x48002000, 0x48119809, + 0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0009, + 0x80025d40, 0x04000007, 0x592c0000, 0x4c000000, + 0x0201f800, 0x0010083a, 0x5c000000, 0x0401f7f9, + 0x5c025800, 0x1c01f000, 0x4807c856, 0x4d2c0000, + 0x58cc0002, 0x80025d40, 0x04000007, 0x592c0000, + 0x4c000000, 0x0201f800, 0x0010083a, 0x5c000000, + 0x0401f7f9, 0x49799800, 0x49799802, 0x49799801, + 0x49799803, 0x49799806, 0x49799807, 0x49799808, + 0x49799809, 0x4979980a, 0x5c025800, 0x1c01f000, + 0x00000003, 0x00000006, 0x00000009, 0x0000000c, + 0x0000000f, 0x00000012, 0x4803c856, 0x0401f857, + 0x4a00c204, 0x0000003c, 0x59301009, 0x82080580, + 0x0010b320, 0x04000013, 0x58080802, 0x82040d00, + 0x00ffffff, 0x58080403, 0x4804c005, 0x4800c406, + 0x4a00c207, 0x00000003, 0x59300811, 0x585c0404, + 0x4978c206, 0x4804c407, 0x80000540, 0x0400000d, + 0x58600206, 0x84000540, 0x4800c206, 0x0401f009, + 0x585c080a, 0x82040d00, 0x00ffffff, 0x4804c005, + 0x4a00c406, 0x000007ff, 0x4978c207, 0x0401f7ef, + 0x82603c00, 0x00000008, 0x58605404, 0x40282000, + 0x405c6000, 0x585c0a04, 0x82040d00, 0x0000000f, + 0x82040c00, 0x0010110d, 0x50044000, 0x80004d80, + 0x50200000, 0x80307400, 0x58380402, 0x8c244d00, + 0x04020003, 0x48003a00, 0x0401f003, 0x48003c00, + 0x801c3800, 0x80244800, 0x80102040, 0x04000006, + 0x0201f800, 0x001010eb, 0x02000800, 0x00100615, + 0x0401f7f0, 0x1c01f000, 0x4803c856, 0x4d340000, + 0x59300009, 0x80026d40, 0x02000800, 0x00100615, + 0x59340401, 0x80000540, 0x0400000e, 0x59840000, + 0x80000540, 0x0400000b, 0x836c0580, 0x00000003, + 0x04020008, 0x59341c03, 0x42002000, 0x00000004, + 0x42003000, 0x00000004, 0x0201f800, 0x001038c7, + 0x5c026800, 0x1c01f000, 0x4803c856, 0x80001580, + 0x58c80c01, 0x59300011, 0x80040c80, 0x48066011, + 0x58c80201, 0x80000540, 0x04000005, 0x80081000, + 0x80040c80, 0x04001007, 0x04000006, 0x58c80202, + 0x80081000, 0x80040c80, 0x04001002, 0x040207fd, + 0x4808bc08, 0x4808c404, 0x1c01f000, 0x4803c856, + 0x4a0370e5, 0x00020000, 0x59b800e5, 0x8c000524, + 0x040207fc, 0x4a0370e5, 0x00030000, 0x40000000, + 0x40000000, 0x59b800e5, 0x8c000524, 0x040207f5, + 0x5934000e, 0x80006d40, 0x04000010, 0x81300580, + 0x04020004, 0x58340000, 0x4802680e, 0x0401f00a, + 0x40347800, 0x58340000, 0x80006d40, 0x02000800, + 0x00100615, 0x81300580, 0x040207fa, 0x58340000, + 0x48007800, 0x497a6000, 0x4a0370e5, 0x00020000, + 0x1c01f000, 0x4803c856, 0x4d300000, 0x4d2c0000, + 0x42000800, 0x000003ff, 0x4a0370e5, 0x00020000, + 0x59b800e5, 0x8c000524, 0x04000005, 0x80040840, + 0x040207fa, 0x0201f800, 0x00100615, 0x4a0370e5, + 0x00030000, 0x40000000, 0x40000000, 0x59b800e5, + 0x8c000524, 0x040207f1, 0x5934000e, 0x80026540, + 0x0400000e, 0x4933c857, 0x59300000, 0x4802680e, + 0x4a026203, 0x00000004, 0x497a6206, 0x497a6009, + 0x4a026007, 0x00000101, 0x59325808, 0x497a5c08, + 0x0401fd82, 0x0401f7f1, 0x4a0370e5, 0x00020000, + 0x5c025800, 0x5c026000, 0x1c01f000, 0x4803c856, + 0x4c000000, 0x0201f800, 0x001059b9, 0x04020011, + 0x0201f800, 0x001043fc, 0x02020800, 0x00100615, + 0x5c000000, 0x48026802, 0x0201f800, 0x00020892, + 0x04000009, 0x49366009, 0x4a026406, 0x00000001, + 0x42027000, 0x00000001, 0x0201f000, 0x000208d8, + 0x5c000000, 0x1c01f000, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, + 0x0c01f001, 0x0010623b, 0x0010623b, 0x0010623b, + 0x0010623d, 0x0010629d, 0x0010623b, 0x0010623b, + 0x001062ef, 0x001062f0, 0x0010623b, 0x0010623b, + 0x0010623b, 0x0010623b, 0x0010623b, 0x0201f800, + 0x00100615, 0x493bc857, 0x83380480, 0x00000050, + 0x02021800, 0x00100615, 0x83380480, 0x00000049, + 0x02001800, 0x00100615, 0x0c01f001, 0x00106250, + 0x00106272, 0x0010624e, 0x0010624e, 0x0010624e, + 0x0010624e, 0x00106281, 0x0201f800, 0x00100615, + 0x4d2c0000, 0x59325808, 0x592c0206, 0x48025c06, + 0x4a025a06, 0x00000000, 0x4c5c0000, 0x592cbc0a, + 0x592c0000, 0x48026008, 0x0201f800, 0x00020385, + 0x59300008, 0x80000540, 0x04000008, 0x4a026203, + 0x00000007, 0x42027000, 0x00000043, 0x5c00b800, + 0x5c025800, 0x0401f08a, 0x8c5cbd08, 0x04020006, + 0x4a026203, 0x00000007, 0x497a6206, 0x497a6008, + 0x0401f003, 0x0201f800, 0x000208b4, 0x5c00b800, + 0x5c025800, 0x1c01f000, 0x0201f800, 0x001068c1, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00108df4, + 0x04000006, 0x4d400000, 0x42028000, 0x00000001, + 0x0401f90e, 0x5c028000, 0x5c025800, 0x0201f000, + 0x000208b4, 0x0201f800, 0x001068c1, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42003000, 0x00000014, 0x0201f800, 0x0010a766, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00108df4, + 0x04000006, 0x4d400000, 0x42028000, 0x00000029, + 0x0401f8f2, 0x5c028000, 0x5c025800, 0x0201f000, + 0x000208b4, 0x493bc857, 0x497a6206, 0x83380480, + 0x00000054, 0x02021800, 0x00100615, 0x83380480, + 0x00000047, 0x02001800, 0x00100615, 0x0c01f001, + 0x001062ee, 0x001062b7, 0x001062b5, 0x001062b5, + 0x001062b5, 0x001062b5, 0x001062b5, 0x001062b5, + 0x001062b5, 0x001062b5, 0x001062b5, 0x001062b5, + 0x001062bb, 0x0201f800, 0x00100615, 0x59300011, + 0x82000500, 0xffff0000, 0x04020034, 0x59840802, + 0x8c040d04, 0x04000025, 0x59300009, 0x80026d40, + 0x0400001f, 0x4c5c0000, 0x4c600000, 0x497a6206, + 0x5930b808, 0x585c0005, 0x8000c540, 0x02000800, + 0x00100615, 0x0401fe8d, 0x40625800, 0x0201f800, + 0x00020385, 0x4978b805, 0x0401fef5, 0x497a6009, + 0x585c3408, 0x0401fcbe, 0x0400000e, 0x42001000, + 0x0010b315, 0x0401fcf3, 0x0400000a, 0x0201f800, + 0x0010082a, 0x04000007, 0x492cb805, 0x585c5408, + 0x0401fc84, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x0401fcaa, 0x0401f7fc, 0x8c040d06, 0x040207fc, + 0x59300009, 0x80026d40, 0x04000006, 0x5934000e, + 0x80000540, 0x02020800, 0x00100615, 0x497a6009, + 0x0401fd0e, 0x0401f7f2, 0x0401f085, 0x4803c856, + 0x4803c856, 0x83380580, 0x00000043, 0x02020800, + 0x00100615, 0x4a026203, 0x00000003, 0x493a6403, + 0x59325808, 0x592c000f, 0x48026011, 0x497a6013, + 0x592c0406, 0x800000c2, 0x800010c4, 0x80081400, + 0x480a6206, 0x0201f800, 0x00100f9c, 0x42000800, + 0x80000060, 0x0401f161, 0x42000000, 0x0010b674, + 0x0201f800, 0x0010a86e, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, + 0x82000d80, 0x00000003, 0x04000006, 0x82000d80, + 0x00000004, 0x0400005b, 0x0201f800, 0x00100615, + 0x0201f800, 0x0010698c, 0x59300004, 0x8c00053e, + 0x04020007, 0x0201f800, 0x001068a3, 0x02020800, + 0x00100615, 0x0201f000, 0x00106982, 0x0401f9d3, + 0x0201f800, 0x00106982, 0x59325808, 0x42028000, + 0x00000006, 0x0401f861, 0x0201f000, 0x000208b4, + 0x4803c856, 0x59300203, 0x82000c80, 0x0000000e, + 0x02021800, 0x00100615, 0x82000d80, 0x00000002, + 0x04000009, 0x82000d80, 0x00000003, 0x04000019, + 0x82000d80, 0x00000004, 0x04000036, 0x0201f800, + 0x00100615, 0x4933c857, 0x4d2c0000, 0x59325808, + 0x812e59c0, 0x02000800, 0x00100615, 0x592c1a08, + 0x8c0c1d0e, 0x02000800, 0x00100615, 0x4d400000, + 0x42028000, 0x00000001, 0x0401f840, 0x0201f800, + 0x00107698, 0x5c028000, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x0201f800, 0x0010698c, 0x4df00000, + 0x59300004, 0x8c00053e, 0x04020006, 0x0201f800, + 0x00106cb4, 0x02020800, 0x00100615, 0x0401f010, + 0x0201f800, 0x00108a8a, 0x04020004, 0x0201f800, + 0x00106bb2, 0x0402000a, 0x0401f994, 0x02020800, + 0x00100615, 0x5c03e000, 0x02000800, 0x00106982, + 0x82000540, 0x00000001, 0x1c01f000, 0x5c03e000, + 0x02000800, 0x00106982, 0x80000580, 0x1c01f000, + 0x4933c857, 0x0201f800, 0x00100ee4, 0x4933c857, + 0x4c5c0000, 0x4d340000, 0x497a6206, 0x5930b808, + 0x59300009, 0x80026d40, 0x04020e49, 0x42001000, + 0x0010b315, 0x0401fc4b, 0x04000009, 0x58c80204, + 0x4800bc08, 0x41785000, 0x0201f800, 0x00105f60, + 0x5c026800, 0x5c00b800, 0x1c01f000, 0x4978bc08, + 0x0401fc02, 0x0401f7fb, 0x4803c856, 0x0201f800, + 0x00108df4, 0x0400000f, 0x592c0000, 0x80000d40, + 0x04000009, 0x497a5800, 0x49425a06, 0x4c040000, + 0x0201f800, 0x00020381, 0x5c000800, 0x40065800, + 0x0401f7f6, 0x49425a06, 0x0201f800, 0x00020381, + 0x1c01f000, 0x4933c857, 0x59300c06, 0x82040580, + 0x0000000e, 0x04000004, 0x82040580, 0x00000009, + 0x04020004, 0x0401ffe5, 0x497a6008, 0x80000580, + 0x1c01f000, 0x592e6009, 0x83300480, 0x0010cfc0, + 0x04001016, 0x41580000, 0x81300480, 0x04021013, + 0x40040000, 0x59300c06, 0x80040580, 0x04020012, + 0x59300a03, 0x82040580, 0x00000007, 0x02020800, + 0x00100615, 0x59300008, 0x80000540, 0x02020800, + 0x00100615, 0x0201f800, 0x000208b4, 0x42000000, + 0x00000000, 0x0401f009, 0x42000000, 0x00000008, + 0x0401f006, 0x82040580, 0x00000007, 0x040207fb, + 0x42000000, 0x00000005, 0x592c0a06, 0x48065c06, + 0x48025a06, 0x0201f000, 0x00020381, 0x4c0c0000, + 0x4c100000, 0x4c140000, 0x4c180000, 0x80001d80, + 0x80002580, 0x42003000, 0x00000020, 0x82040500, + 0x00000001, 0x04000003, 0x40080000, 0x800c1c00, + 0x400c2800, 0x800c1902, 0x80102102, 0x82140500, + 0x00000001, 0x04000003, 0x82102540, 0x80000000, + 0x80040902, 0x80183040, 0x040207f1, 0x40100800, + 0x400c0000, 0x5c003000, 0x5c002800, 0x5c002000, + 0x5c001800, 0x1c01f000, 0x4c580000, 0x4200b000, + 0x00000020, 0x80000540, 0x04000018, 0x80041c80, + 0x04021016, 0x800810c2, 0x80040982, 0x04001006, + 0x80041c80, 0x04021005, 0x8058b040, 0x040207fa, + 0x0401f006, 0x80041c80, 0x400c0800, 0x80081000, + 0x8058b040, 0x040207f4, 0x4c000000, 0x41f00000, + 0x82000500, 0xf7ffffff, 0x4003e000, 0x5c000000, + 0x5c00b000, 0x1c01f000, 0x4c000000, 0x41f00000, + 0x82000540, 0x08000000, 0x0401f7f8, 0x42007000, + 0x0010b33f, 0x4a007000, 0x00000005, 0x4a007401, + 0x00000000, 0x4a007202, 0x00000840, 0x4a0378e8, + 0x00000000, 0x4a03c821, 0x00000010, 0x4a03c823, + 0x00000004, 0x0401f81d, 0x4a0378e9, 0x00003a0d, + 0x4a0378e8, 0x00000001, 0x42000800, 0x00000005, + 0x4203a000, 0x00007600, 0x4a03a005, 0xd0000001, + 0x59d00006, 0x4a03a005, 0x90000001, 0x83d3a400, + 0x00000020, 0x80040840, 0x040207fa, 0x59e00003, + 0x82000500, 0xffffffe0, 0x82000540, 0x00008000, + 0x4803c003, 0x59c40006, 0x82000500, 0xfffcffff, + 0x48038806, 0x1c01f000, 0x4d900000, 0x4d180000, + 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6, 0xaaaaaaaa, + 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4, 0xaaaaaaaa, + 0x4a03781a, 0x0010b5d2, 0x4a03781b, 0x0010110d, + 0x4a03781c, 0x0010111d, 0x4a031800, 0x00000000, + 0x4a031801, 0x0010b342, 0x4a031802, 0x0010b349, + 0x42000800, 0x0010b5d5, 0x417a3000, 0x811b20c8, + 0x83932400, 0x0000bf32, 0x48072000, 0x4a032001, + 0x00000000, 0x83180400, 0x00106e41, 0x50000000, + 0x48032002, 0x82040c00, 0x00000003, 0x811a3000, + 0x83180480, 0x00000005, 0x040017f1, 0x5c023000, + 0x5c032000, 0x1c01f000, 0x48066004, 0x497a6000, + 0x497a6001, 0x59bc00ea, 0x8c000516, 0x040207fe, + 0x83300400, 0xa0000000, 0x480378e1, 0x1c01f000, + 0x4933c857, 0x59300804, 0x82040d00, 0x00000100, + 0x82040d40, 0x80000040, 0x48066004, 0x497a6000, + 0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400, + 0x60000000, 0x480378e1, 0x1c01f000, 0x0201f800, + 0x0010698c, 0x4df00000, 0x4d300000, 0x4d340000, + 0x4d2c0000, 0x4d180000, 0x4c5c0000, 0x4c600000, + 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, + 0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0, + 0x0400002c, 0x41302800, 0x4178c000, 0x59300000, + 0x4c000000, 0x59326809, 0x5930b801, 0x59300406, + 0x82000d80, 0x00000006, 0x04020003, 0x8d3e7d18, + 0x04000010, 0x8d3e7d06, 0x04000007, 0x82000580, + 0x00000003, 0x04020004, 0x59340200, 0x8c00050e, + 0x04020008, 0x0401f92d, 0x4c0c0000, 0x4c140000, + 0x0401fb59, 0x5c002800, 0x5c001800, 0x0401f005, + 0x41301800, 0x8060c1c0, 0x04020002, 0x400cc000, + 0x805cb9c0, 0x04000003, 0x405e6000, 0x0401f7e3, + 0x5c026000, 0x813261c0, 0x04000006, 0x8060c1c0, + 0x04000002, 0x40602800, 0x4178c000, 0x0401f7d8, + 0x417a3000, 0x0201f800, 0x00106e2f, 0x59926004, + 0x813261c0, 0x04000023, 0x59326809, 0x4130c000, + 0x59300001, 0x8000bd40, 0x04000016, 0x40026000, + 0x40602800, 0x5930b801, 0x59300406, 0x82000d80, + 0x00000006, 0x0400000e, 0x8d3e7d06, 0x04000007, + 0x82000580, 0x00000003, 0x04020004, 0x59340200, + 0x8c00050e, 0x04020006, 0x0401f8da, 0x4c140000, + 0x0401fb29, 0x5c002800, 0x0401f002, 0x41302800, + 0x405e6000, 0x813261c0, 0x040207eb, 0x8060c1c0, + 0x04000004, 0x40626000, 0x4178c000, 0x0401f7e7, + 0x811a3000, 0x83180480, 0x00000005, 0x040017d6, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x5c00c000, 0x5c00b800, 0x5c023000, 0x5c025800, + 0x5c026800, 0x5c026000, 0x5c03e000, 0x02000800, + 0x00106982, 0x1c01f000, 0x4933c857, 0x0201f800, + 0x0010698c, 0x4df00000, 0x4d340000, 0x4d180000, + 0x4d900000, 0x42003000, 0x0000bf2e, 0x59326809, + 0x58182001, 0x40102800, 0x801021c0, 0x04000016, + 0x41300000, 0x80100580, 0x04000011, 0x58100009, + 0x81340580, 0x0402000b, 0x40101800, 0x58102001, + 0x41300000, 0x801021c0, 0x0400000b, 0x80100d80, + 0x04000007, 0x40101800, 0x58102001, 0x0401f7fa, + 0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bb, + 0x0401f01a, 0x42032000, 0x0000bf32, 0x417a3000, + 0x59902004, 0x40102800, 0x801021c0, 0x0400000b, + 0x58100009, 0x81340580, 0x04020008, 0x41300000, + 0x80100580, 0x0400000c, 0x40102800, 0x58102001, + 0x801021c0, 0x040207fa, 0x811a3000, 0x83180480, + 0x00000005, 0x0402100d, 0x83932400, 0x00000010, + 0x0401f7ec, 0x0401f87f, 0x5c032000, 0x5c023000, + 0x5c026800, 0x5c03e000, 0x02000800, 0x00106982, + 0x80000580, 0x1c01f000, 0x5c032000, 0x5c023000, + 0x5c026800, 0x5c03e000, 0x02000800, 0x00106982, + 0x82000540, 0x00000001, 0x1c01f000, 0x0201f800, + 0x0010698c, 0x4df00000, 0x4d300000, 0x4d340000, + 0x4d180000, 0x4d2c0000, 0x4c5c0000, 0x4c600000, + 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, + 0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0, + 0x04000023, 0x41302800, 0x5930b800, 0x59326809, + 0x59340403, 0x81440580, 0x04000006, 0x805cb9c0, + 0x0400001b, 0x41302800, 0x405e6000, 0x0401f7f7, + 0x5930b801, 0x8d3e7d00, 0x04000003, 0x0401fb58, + 0x0402000e, 0x59300406, 0x82000580, 0x00000006, + 0x04020003, 0x8d3e7d18, 0x04000008, 0x0401f867, + 0x4c0c0000, 0x4c140000, 0x0401fa93, 0x5c002800, + 0x5c001800, 0x0401f002, 0x41301800, 0x405e6000, + 0x813261c0, 0x040207eb, 0x0401f02d, 0x417a3000, + 0x0201f800, 0x00106e2f, 0x59926004, 0x813261c0, + 0x04000005, 0x59326809, 0x59340403, 0x81440580, + 0x04000006, 0x811a3000, 0x83180480, 0x00000005, + 0x040017f4, 0x0401f01e, 0x4130c000, 0x59300001, + 0x8000bd40, 0x04000012, 0x40026000, 0x40602800, + 0x5930b801, 0x8d3e7d00, 0x04000003, 0x0401fb2c, + 0x0402000a, 0x59300406, 0x82000580, 0x00000006, + 0x04000006, 0x0401f81b, 0x4c140000, 0x0401fa6a, + 0x5c002800, 0x0401f002, 0x41302800, 0x405e6000, + 0x813261c0, 0x040207ef, 0x8060c1c0, 0x04000004, + 0x40626000, 0x4178c000, 0x0401f7eb, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c00c000, + 0x5c00b800, 0x5c025800, 0x5c023000, 0x5c026800, + 0x5c026000, 0x5c03e000, 0x04000bd4, 0x1c01f000, + 0x0401fbb9, 0x59900004, 0x81300580, 0x04020018, + 0x4c140000, 0x0201f800, 0x00106b13, 0x0401fba9, + 0x5c002800, 0x59300001, 0x800001c0, 0x04020003, + 0x497a680c, 0x1c01f000, 0x42003000, 0x0000bf2e, + 0x497a6001, 0x58180801, 0x800409c0, 0x04020004, + 0x48003000, 0x48003001, 0x1c01f000, 0x58180800, + 0x48000800, 0x48003000, 0x1c01f000, 0x59300001, + 0x48002801, 0x800001c0, 0x04020002, 0x4816680c, + 0x497a6001, 0x1c01f000, 0x0401fb97, 0x42003000, + 0x0000bf2e, 0x58180001, 0x81300580, 0x0402001c, + 0x59300801, 0x800409c0, 0x0400000e, 0x59300000, + 0x800001c0, 0x04020005, 0x48043001, 0x48043000, + 0x497a6001, 0x1c01f000, 0x59300000, 0x48000800, + 0x48043001, 0x497a6000, 0x497a6001, 0x1c01f000, + 0x59300800, 0x800409c0, 0x04020005, 0x49783001, + 0x49783000, 0x497a680c, 0x1c01f000, 0x48043001, + 0x497a6000, 0x497a680c, 0x1c01f000, 0x58180000, + 0x81300580, 0x0402000c, 0x59300001, 0x800001c0, + 0x04020005, 0x48143000, 0x49782800, 0x497a680c, + 0x1c01f000, 0x48003000, 0x48002800, 0x497a6001, + 0x1c01f000, 0x59300000, 0x800001c0, 0x04020008, + 0x59300001, 0x48001801, 0x800001c0, 0x04020002, + 0x480e680c, 0x497a6001, 0x1c01f000, 0x59300801, + 0x800409c0, 0x04020006, 0x59300800, 0x48042800, + 0x497a6000, 0x497a680c, 0x1c01f000, 0x59300000, + 0x48000800, 0x48042800, 0x497a6000, 0x497a6001, + 0x1c01f000, 0x0401fb73, 0x4df00000, 0x0401f83a, + 0x040208c7, 0x0402094a, 0x04020005, 0x5c03e000, + 0x04000b62, 0x80000580, 0x1c01f000, 0x5c03e000, + 0x04000b5e, 0x82000540, 0x00000001, 0x1c01f000, + 0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000, + 0x598e6009, 0x813261c0, 0x04000023, 0x59300406, + 0x82000580, 0x00000006, 0x04020004, 0x8d3e7d18, + 0x0402000c, 0x0401f019, 0x82040580, 0x00000005, + 0x04020008, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, + 0x04000004, 0x59300420, 0x8c000500, 0x0402000f, + 0x0401fa49, 0x59300000, 0x4c000000, 0x8d3e7d06, + 0x04000004, 0x0201f800, 0x0010909d, 0x04000005, + 0x0401f869, 0x4c180000, 0x0401f9b7, 0x5c003000, + 0x5c026000, 0x0401f7e0, 0x41303000, 0x59326000, + 0x0401f7dd, 0x5c026000, 0x5c026800, 0x5c025800, + 0x1c01f000, 0x4933c857, 0x4c5c0000, 0x813261c0, + 0x02000800, 0x00100615, 0x41300000, 0x598cb809, + 0x41783000, 0x805cb9c0, 0x04000013, 0x805c0d80, + 0x04000004, 0x405c3000, 0x5818b800, 0x0401f7fa, + 0x0401f84d, 0x598c000d, 0x81300580, 0x02000800, + 0x00106e10, 0x59300403, 0x82000580, 0x00000042, + 0x04020002, 0x497a6007, 0x80000580, 0x5c00b800, + 0x1c01f000, 0x82000540, 0x00000001, 0x5c00b800, + 0x1c01f000, 0x0401fb17, 0x4df00000, 0x4d2c0000, + 0x4d340000, 0x4d300000, 0x41783000, 0x598e6009, + 0x813261c0, 0x0400002e, 0x59300c06, 0x82040580, + 0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000c, + 0x0401f024, 0x82040580, 0x00000005, 0x04020008, + 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, + 0x59300420, 0x8c000500, 0x0402001a, 0x59326809, + 0x59340403, 0x81440580, 0x04020016, 0x8d3e7d00, + 0x04000006, 0x82040580, 0x00000003, 0x04020011, + 0x0401fa23, 0x0402000f, 0x0401f9ef, 0x59300000, + 0x4c000000, 0x8d3e7d06, 0x04000004, 0x0201f800, + 0x0010909d, 0x04000005, 0x0401f80f, 0x4c180000, + 0x0401f95d, 0x5c003000, 0x5c026000, 0x0401f7d5, + 0x41303000, 0x59326000, 0x0401f7d2, 0x5c026000, + 0x5c026800, 0x5c025800, 0x5c03e000, 0x04000ad3, + 0x1c01f000, 0x59300800, 0x497a6000, 0x0401fab6, + 0x801831c0, 0x04020009, 0x598c0008, 0x81300580, + 0x04020004, 0x48031808, 0x48031809, 0x0401f008, + 0x48071809, 0x0401f006, 0x48043000, 0x598c0008, + 0x81300580, 0x04020002, 0x481b1808, 0x0401f2b8, + 0x4d2c0000, 0x4d300000, 0x4d340000, 0x41783000, + 0x598e600b, 0x813261c0, 0x04000013, 0x8d3e7d06, + 0x04000005, 0x59326809, 0x59340200, 0x8c00050e, + 0x0402000a, 0x0401f9b8, 0x59300000, 0x4c000000, + 0x0401f853, 0x4c180000, 0x0401f92b, 0x5c003000, + 0x5c026000, 0x0401f7f0, 0x41303000, 0x59326000, + 0x0401f7ed, 0x0201f800, 0x001045c7, 0x5c026800, + 0x5c026000, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x4c5c0000, 0x813261c0, 0x02000800, 0x00100615, + 0x41300000, 0x598cb80b, 0x41783000, 0x805cb9c0, + 0x0400000f, 0x805c0d80, 0x04000004, 0x405c3000, + 0x5818b800, 0x0401f7fa, 0x0401f835, 0x598c000d, + 0x81300580, 0x02000800, 0x00106e10, 0x497a6007, + 0x80000580, 0x5c00b800, 0x1c01f000, 0x82000540, + 0x00000001, 0x5c00b800, 0x1c01f000, 0x0401fa8d, + 0x4df00000, 0x4d340000, 0x4d300000, 0x4d2c0000, + 0x0201f800, 0x00020267, 0x02020800, 0x00100615, + 0x41783000, 0x598e600b, 0x813261c0, 0x04000014, + 0x59300009, 0x81340580, 0x0402000e, 0x8d3e7d00, + 0x04000003, 0x0401f9aa, 0x0402000a, 0x0401f976, + 0x59300000, 0x4c000000, 0x0401f811, 0x4c180000, + 0x0401f8e9, 0x5c003000, 0x5c026000, 0x0401f7ef, + 0x41303000, 0x59326000, 0x0401f7ec, 0x0201f800, + 0x001045ea, 0x5c025800, 0x5c026000, 0x5c026800, + 0x5c03e000, 0x04000a5d, 0x1c01f000, 0x59300800, + 0x497a6000, 0x0401fa40, 0x801831c0, 0x04020009, + 0x598c000a, 0x81300580, 0x04020004, 0x4803180a, + 0x4803180b, 0x0401f008, 0x4807180b, 0x0401f006, + 0x48043000, 0x598c000a, 0x81300580, 0x04020002, + 0x481b180a, 0x0401f242, 0x0401fa52, 0x4df00000, + 0x4d300000, 0x4c5c0000, 0x4178b800, 0x8d3e7d18, + 0x04000004, 0x8d3e7d16, 0x04020002, 0x805cb800, + 0x598e6005, 0x813261c0, 0x0400001a, 0x59300000, + 0x4c000000, 0x805cb9c0, 0x0402000b, 0x59300c06, + 0x82040580, 0x00000011, 0x04000010, 0x82040580, + 0x00000004, 0x04020004, 0x59300420, 0x8c000500, + 0x0402000a, 0x0201f800, 0x00108f05, 0x02000800, + 0x00107da6, 0x0201f800, 0x001090ec, 0x0201f800, + 0x000208b4, 0x0401fa1e, 0x5c026000, 0x0401f7e6, + 0x497b1805, 0x497b1804, 0x5c00b800, 0x5c026000, + 0x5c03e000, 0x04000a1d, 0x1c01f000, 0x4933c857, + 0x4c5c0000, 0x4c600000, 0x813261c0, 0x02000800, + 0x00100615, 0x41300000, 0x598cb805, 0x405cc000, + 0x805cb9c0, 0x04000025, 0x805c0d80, 0x04000004, + 0x405cc000, 0x5860b800, 0x0401f7fa, 0x598c000d, + 0x81300580, 0x02000800, 0x00106e10, 0x0401f9ee, + 0x598c0005, 0x805c0580, 0x04020009, 0x585c0000, + 0x48031805, 0x4978b800, 0x598c0004, 0x805c0580, + 0x0402000d, 0x497b1804, 0x0401f00b, 0x598c0004, + 0x805c0580, 0x04020005, 0x48631804, 0x4978b800, + 0x4978c000, 0x0401f004, 0x585c0000, 0x4800c000, + 0x4978b800, 0x0401f9ea, 0x80000580, 0x5c00c000, + 0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001, + 0x5c00c000, 0x5c00b800, 0x1c01f000, 0x4933c857, + 0x0401f9f0, 0x4df00000, 0x4d2c0000, 0x4d340000, + 0x4d300000, 0x4c5c0000, 0x4178b800, 0x8d3e7d18, + 0x04000004, 0x8d3e7d16, 0x04020002, 0x805cb800, + 0x41783000, 0x598e6005, 0x813261c0, 0x04000029, + 0x59326809, 0x813669c0, 0x04000023, 0x59340403, + 0x81440580, 0x04020020, 0x805cb9c0, 0x0402000b, + 0x59300c06, 0x82040580, 0x00000011, 0x0400001a, + 0x82040580, 0x00000004, 0x04020004, 0x59300420, + 0x8c000500, 0x04020014, 0x0201f800, 0x00108df4, + 0x04000008, 0x0201f800, 0x00109360, 0x04020005, + 0x59300403, 0x82000580, 0x00000043, 0x0400000a, + 0x0401f8c1, 0x59300000, 0x4c000000, 0x0401f810, + 0x4c180000, 0x0401f834, 0x5c003000, 0x5c026000, + 0x0401f7da, 0x41303000, 0x59326000, 0x0401f7d7, + 0x5c00b800, 0x5c026000, 0x5c026800, 0x5c025800, + 0x5c03e000, 0x040009a9, 0x1c01f000, 0x59300800, + 0x497a6000, 0x0401f98c, 0x801831c0, 0x04020009, + 0x598c0004, 0x81300580, 0x04020004, 0x48031804, + 0x48031805, 0x0401f008, 0x48071805, 0x0401f006, + 0x48043000, 0x598c0004, 0x81300580, 0x04020002, + 0x481b1804, 0x0401f18e, 0x4943c857, 0x0401f99d, + 0x4df00000, 0x0401fe37, 0x0401fed2, 0x5c03e000, + 0x0400098e, 0x1c01f000, 0x4947c857, 0x0401f995, + 0x4df00000, 0x4d3c0000, 0x853e7d00, 0x0401fe7a, + 0x0401ff03, 0x5c027800, 0x5c03e000, 0x04000983, + 0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857, + 0x4d340000, 0x4d2c0000, 0x59326809, 0x59325808, + 0x59300406, 0x82000c80, 0x00000012, 0x02021800, + 0x00100615, 0x4933c857, 0x4943c857, 0x493fc857, + 0x4803c857, 0x0c01f804, 0x5c025800, 0x5c026800, + 0x1c01f000, 0x00106827, 0x00106829, 0x00106833, + 0x0010684d, 0x00106829, 0x0010683d, 0x00106865, + 0x00106827, 0x00106827, 0x00106878, 0x0010686f, + 0x00106827, 0x00106827, 0x00106827, 0x00106827, + 0x00106827, 0x0010687e, 0x0010687e, 0x0201f800, + 0x00100615, 0x0201f800, 0x00108ef1, 0x02000800, + 0x00101e1b, 0x0201f800, 0x001090ec, 0x0201f800, + 0x00107da6, 0x0201f000, 0x00107698, 0x812e59c0, + 0x02020800, 0x00100615, 0x5930021d, 0x82000580, + 0x00000003, 0x02000800, 0x00108ee7, 0x0201f000, + 0x00107698, 0x0201f800, 0x00108df4, 0x02000000, + 0x00107698, 0x592c1204, 0x82081500, 0x000000ff, + 0x82080580, 0x00000055, 0x02020800, 0x00100615, + 0x49425a06, 0x0201f800, 0x00020381, 0x0201f000, + 0x00107698, 0x59300004, 0x8400055c, 0x48026004, + 0x59300007, 0x8c000500, 0x02020800, 0x00100ee4, + 0x0201f800, 0x00108df4, 0x0400000d, 0x4a025a04, + 0x00000103, 0x49425a06, 0x497a5c09, 0x0201f800, + 0x00108f7d, 0x0201f800, 0x0010a4ae, 0x0201f800, + 0x00020381, 0x0201f800, 0x00108ee7, 0x0201f000, + 0x00107698, 0x59300007, 0x8c000500, 0x02020800, + 0x00100ee4, 0x0201f800, 0x00108df4, 0x02020800, + 0x0010a201, 0x0201f000, 0x00107698, 0x0201f800, + 0x00108df4, 0x04000005, 0x49425a06, 0x497a5c09, + 0x0201f800, 0x00020381, 0x0201f000, 0x00107698, + 0x0201f800, 0x00108df4, 0x02020800, 0x0010639d, + 0x0201f000, 0x00107698, 0x0201f800, 0x00108df4, + 0x04000004, 0x49425a06, 0x0201f800, 0x00020381, + 0x59325817, 0x0201f800, 0x00100843, 0x0201f000, + 0x00107698, 0x598c000d, 0x81300580, 0x04000003, + 0x497a6007, 0x1c01f000, 0x59c40004, 0x82000500, + 0x0000000c, 0x04000005, 0x4a038804, 0x0000000c, + 0x497b2807, 0x0401f00a, 0x0401fadb, 0x59300403, + 0x82000d80, 0x00000040, 0x04000004, 0x82000580, + 0x00000042, 0x04020002, 0x497a6007, 0x0201f800, + 0x00106e10, 0x80000580, 0x1c01f000, 0x59300804, + 0x8c040d20, 0x04020004, 0x82000540, 0x00000001, + 0x1c01f000, 0x4933c857, 0x4d380000, 0x59300804, + 0x84040d20, 0x48066004, 0x42027000, 0x00000049, + 0x59300203, 0x82000580, 0x00000003, 0x04000003, + 0x42027000, 0x00000013, 0x0201f800, 0x000208d8, + 0x80000580, 0x5c027000, 0x1c01f000, 0x59300017, + 0x81480580, 0x04020003, 0x59300018, 0x814c0580, + 0x1c01f000, 0x4d2c0000, 0x4d300000, 0x0401f8c9, + 0x4df00000, 0x0201f800, 0x00105d9b, 0x59900001, + 0x82000500, 0x00000003, 0x0c01f001, 0x001068f1, + 0x001068d1, 0x001068cf, 0x001068cf, 0x0201f800, + 0x00100615, 0x59926004, 0x0401f88e, 0x813261c0, + 0x0400001d, 0x59300004, 0x8c000516, 0x04000004, + 0x59325808, 0x497a5808, 0x497a5809, 0x0401f88e, + 0x59300001, 0x800001c0, 0x0400000e, 0x497a6001, + 0x42003000, 0x0000bf2e, 0x58180801, 0x800409c0, + 0x04020004, 0x48003001, 0x48003000, 0x0401f00a, + 0x58180800, 0x48000800, 0x48003000, 0x0401f006, + 0x59300809, 0x800409c0, 0x02000800, 0x00100615, + 0x4978080c, 0x5c03e000, 0x04000890, 0x5c026000, + 0x5c025800, 0x1c01f000, 0x4d300000, 0x497b2807, + 0x0401f894, 0x4df00000, 0x598c0000, 0x82000500, + 0x00000007, 0x4803c857, 0x0c01f001, 0x00106926, + 0x00106909, 0x00106912, 0x00106916, 0x00106921, + 0x00106926, 0x00106907, 0x00106907, 0x0201f800, + 0x00100615, 0x598c000d, 0x80026540, 0x04000004, + 0x0401f81e, 0x02020800, 0x00100615, 0x0201f800, + 0x00106e10, 0x0401f015, 0x0401f827, 0x0201f800, + 0x00106e10, 0x0401f011, 0x598c000d, 0x80026540, + 0x0400000e, 0x0401f838, 0x04000004, 0x0401f80f, + 0x04000002, 0x0401f81c, 0x0201f800, 0x00106e10, + 0x0401f006, 0x0401f830, 0x02020800, 0x00100615, + 0x0201f800, 0x00106e10, 0x5c03e000, 0x0400085b, + 0x5c026000, 0x1c01f000, 0x598c0009, 0x81300580, + 0x0402000c, 0x0401f84e, 0x0401f83b, 0x59300000, + 0x800001c0, 0x04000004, 0x48031809, 0x497a6000, + 0x0401f003, 0x497b1809, 0x497b1808, 0x80000580, + 0x1c01f000, 0x4d2c0000, 0x59300406, 0x82000580, + 0x00000003, 0x04020012, 0x598c000b, 0x81300580, + 0x0402000f, 0x0401f83a, 0x59325808, 0x497a5808, + 0x497a5809, 0x0401f824, 0x59300000, 0x800001c0, + 0x04000004, 0x4803180b, 0x497a6000, 0x0401f003, + 0x497b180a, 0x497b180b, 0x80000580, 0x5c025800, + 0x1c01f000, 0x598c0005, 0x81300580, 0x0402000c, + 0x0401f827, 0x0401f814, 0x59300000, 0x800001c0, + 0x04000004, 0x48031805, 0x497a6000, 0x0401f003, + 0x497b1805, 0x497b1804, 0x80000580, 0x1c01f000, + 0x4a032001, 0x00000000, 0x497b2004, 0x497b2005, + 0x59900006, 0x82000500, 0x0000ffff, 0x48032006, + 0x1c01f000, 0x4c040000, 0x59300004, 0x82000500, + 0x7ffeffff, 0x48026004, 0x59bc00e4, 0x8c000514, + 0x04000009, 0x42000800, 0x0000bf00, 0x58040012, + 0x81300580, 0x04020004, 0x49780812, 0x4a0378e4, + 0x00000800, 0x5c000800, 0x1c01f000, 0x4803c856, + 0x598c000c, 0x80000540, 0x04000003, 0x80000040, + 0x4803180c, 0x1c01f000, 0x59bc00ea, 0x82000500, + 0x00000007, 0x82000580, 0x00000003, 0x04020004, + 0x4803c856, 0x4a0378e8, 0x00000001, 0x1c01f000, + 0x59bc00ea, 0x82000500, 0x00000007, 0x82000580, + 0x00000001, 0x04020011, 0x4803c856, 0x42000800, + 0x00000000, 0x0401f80e, 0x42000800, 0x00001000, + 0x59bc00ea, 0x82000500, 0x00000007, 0x82000580, + 0x00000003, 0x04000005, 0x80040840, 0x040207f9, + 0x0201f800, 0x00100615, 0x1c01f000, 0x59bc00ea, + 0x82000500, 0x00000007, 0x82000580, 0x00000001, + 0x02020800, 0x00100615, 0x59bc00ea, 0x8c000516, + 0x040207fe, 0x480778e1, 0x1c01f000, 0x59bc00ea, + 0x8c000516, 0x040207fe, 0x480778e1, 0x59bc00ea, + 0x8c000516, 0x040207fe, 0x480b78e1, 0x1c01f000, + 0x4a0378e4, 0x00002000, 0x59a8006f, 0x82000500, + 0x0000000c, 0x04020008, 0x42007000, 0x0010b33f, + 0x58380401, 0x8c000506, 0x04020003, 0x4a0378e4, + 0x00080000, 0x1c01f000, 0x82000d00, 0x80000018, + 0x02020800, 0x0010060d, 0x0201f800, 0x00100615, + 0x001069dc, 0x00106a81, 0x00106a9b, 0x001069dc, + 0x001069de, 0x001069ff, 0x00106a1e, 0x00106a53, + 0x001069dc, 0x00106a7f, 0x001069dc, 0x001069dc, + 0x001069dc, 0x001069dc, 0x001069dc, 0x001069dc, + 0x0201f800, 0x00100615, 0x4d300000, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x0201f800, + 0x00106e2f, 0x59bc00ea, 0x8c000510, 0x040007fe, + 0x59be60e0, 0x59300004, 0x8c000520, 0x04000011, + 0x82000500, 0xfffefeff, 0x48026004, 0x4a026203, + 0x00000003, 0x0401ff9b, 0x0201f800, 0x0010101e, + 0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000, + 0x5c026000, 0x4a0378e4, 0x00000008, 0x0401f787, + 0x84000510, 0x48026004, 0x0401f7f6, 0x4d300000, + 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, + 0x0201f800, 0x00106e2f, 0x59bc00ea, 0x8c000510, + 0x040007fe, 0x59be60e0, 0x59300004, 0x8c000520, + 0x0400000f, 0x82000500, 0xfffefeff, 0x48026004, + 0x0401ff7c, 0x0201f800, 0x0010105c, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000, + 0x4a0378e4, 0x00000008, 0x0401f768, 0x84000510, + 0x48026004, 0x0401f7f6, 0x4d300000, 0x4d2c0000, + 0x4d340000, 0x4da40000, 0x4cd00000, 0x59bc00ea, + 0x8c000510, 0x040007fe, 0x59be60e0, 0x813261c0, + 0x02000800, 0x00100615, 0x59300004, 0x8c000520, + 0x0400001e, 0x82000500, 0xfffefeff, 0x48026004, + 0x59326809, 0x42034800, 0x0010b342, 0x04011000, + 0x4a03c840, 0x0010b349, 0x4a03c842, 0x00000012, + 0x04011000, 0x4a03c840, 0x0010b35b, 0x4a03c842, + 0x000000ff, 0x04011000, 0x4a03c840, 0x0010b45a, + 0x4a03c842, 0x000000ff, 0x0201f800, 0x00106e46, + 0x5c01a000, 0x5c034800, 0x5c026800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x84000510, 0x48026004, + 0x5c01a000, 0x5c034800, 0x5c026800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x1c01f000, 0x4d300000, + 0x4d2c0000, 0x4d340000, 0x4cd00000, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fbd4, + 0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0, + 0x813261c0, 0x02000800, 0x00100615, 0x59300004, + 0x8c000520, 0x0400000f, 0x82000500, 0xfffefeff, + 0x48026004, 0x0201f800, 0x001075b9, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x5c01a000, + 0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000, + 0x84000510, 0x48026004, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x5c01a000, 0x5c026800, + 0x5c025800, 0x5c026000, 0x1c01f000, 0x0201f800, + 0x00100615, 0x4d300000, 0x4d380000, 0x42000000, + 0x0010b6c3, 0x0201f800, 0x0010a86e, 0x0401ff05, + 0x598e600d, 0x59c40004, 0x8c000506, 0x04000004, + 0x0401f8e5, 0x4a038804, 0x00000008, 0x813261c0, + 0x04000006, 0x0401fb98, 0x42027000, 0x00000014, + 0x0201f800, 0x000208d8, 0x4a0378e4, 0x00000002, + 0x5c027000, 0x5c026000, 0x0401f6e8, 0x4d180000, + 0x4d300000, 0x4d380000, 0x4d900000, 0x4dd00000, + 0x4da40000, 0x4d140000, 0x0401feea, 0x417a3000, + 0x59c40804, 0x83180400, 0x00106df6, 0x50000000, + 0x80040500, 0x0400001b, 0x42000000, 0x0010b6c4, + 0x0201f800, 0x0010a86e, 0x0401fb81, 0x59926004, + 0x0401f863, 0x83180400, 0x00106df6, 0x50000000, + 0x48038804, 0x813261c0, 0x0400000a, 0x59300004, + 0x8c00050c, 0x04020003, 0x4a026203, 0x00000003, + 0x42027000, 0x0000004a, 0x0201f800, 0x000208d8, + 0x59c40004, 0x82000500, 0x00f80000, 0x04000005, + 0x811a3000, 0x83180480, 0x00000005, 0x040017dd, + 0x4a0378e4, 0x00000008, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x5c027000, 0x5c026000, + 0x5c023000, 0x0401f6b1, 0x4d2c0000, 0x4d340000, + 0x59326809, 0x598c0800, 0x82040580, 0x00000004, + 0x04020006, 0x838c1400, 0x00000005, 0x838c1c00, + 0x00000004, 0x0401f010, 0x82040580, 0x00000001, + 0x04020006, 0x838c1400, 0x00000009, 0x838c1c00, + 0x00000008, 0x0401f008, 0x82040580, 0x00000002, + 0x04020028, 0x838c1400, 0x0000000b, 0x838c1c00, + 0x0000000a, 0x41306800, 0x58340000, 0x80007d40, + 0x04000020, 0x583c0009, 0x81340580, 0x04020006, + 0x403c6800, 0x583c0000, 0x80007d40, 0x040207fa, + 0x0401f018, 0x4933c857, 0x483fc857, 0x583c0000, + 0x48006800, 0x49307800, 0x443c1000, 0x500c0000, + 0x803c0580, 0x04020002, 0x44341800, 0x80000580, + 0x4803180d, 0x4803180f, 0x598c0000, 0x82000580, + 0x00000003, 0x04000003, 0x4a031800, 0x00000000, + 0x80000580, 0x5c026800, 0x5c025800, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fb, 0x491bc857, + 0x59c80840, 0x82040540, 0x00000010, 0x48039040, + 0x59c41008, 0x82080500, 0xffffff7f, 0x48038808, + 0x4c040000, 0x4c080000, 0x0401fac2, 0x04020007, + 0x0401fac6, 0x04000022, 0x48038804, 0x0201f800, + 0x001010ca, 0x0401f042, 0x4a038803, 0x00000008, + 0x59c40003, 0x82000500, 0x00000003, 0x040007fd, + 0x8c000502, 0x04020007, 0x0401fab8, 0x04000014, + 0x48038804, 0x0201f800, 0x001010ca, 0x0401f034, + 0x59c80040, 0x8400056a, 0x48039040, 0x59c80040, + 0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500, + 0xc0000000, 0x04000006, 0x59c400a3, 0x84000540, + 0x480388a3, 0x4a038805, 0xc0000000, 0x0201f800, + 0x0010106b, 0x4a03a005, 0x30000000, 0x59d00006, + 0x4a03a005, 0x30000000, 0x59900006, 0x82000500, + 0xffff0000, 0x48032006, 0x59d00005, 0x8c000504, + 0x040207fe, 0x42000800, 0x00007600, 0x83180540, + 0x60000000, 0x480008a1, 0x811800dc, 0x59c80840, + 0x80040540, 0x48039040, 0x82000540, 0x00003000, + 0x48039040, 0x59c80040, 0x82000500, 0x00003000, + 0x040207fd, 0x0201f800, 0x001010b8, 0x83180400, + 0x00106df6, 0x50000000, 0x48038804, 0x80000580, + 0x4df00000, 0x0201f800, 0x00105d9b, 0x5c03e000, + 0x5c001000, 0x5c000800, 0x480b8808, 0x48079040, + 0x1c01f000, 0x4803c856, 0x59c80840, 0x82040540, + 0x00000010, 0x48039040, 0x59c41008, 0x82080500, + 0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000, + 0x59c40004, 0x82000500, 0x00000003, 0x04020010, + 0x59c40004, 0x82000500, 0x0000000c, 0x04000005, + 0x4a038804, 0x0000000c, 0x8c000504, 0x0401f025, + 0x59c80040, 0x8400056e, 0x48039040, 0x59c80040, + 0x8c00052e, 0x040207fe, 0x0401f01e, 0x4a038803, + 0x00000008, 0x59c40003, 0x82000500, 0x00000003, + 0x040007fd, 0x8c000502, 0x04020006, 0x59c40004, + 0x4a038804, 0x0000000c, 0x8c000504, 0x0401f011, + 0x59c80040, 0x8400056a, 0x48039040, 0x59c80040, + 0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500, + 0xc0000000, 0x04000007, 0x59c400a3, 0x84000540, + 0x480388a3, 0x4a038805, 0xc0000000, 0x80000580, + 0x497b2807, 0x5c001000, 0x5c000800, 0x480b8808, + 0x48079040, 0x1c01f000, 0x5c000000, 0x4c000000, + 0x4803c857, 0x491bc857, 0x4933c857, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdd1, + 0x4df00000, 0x0401fa72, 0x59900004, 0x800001c0, + 0x04000011, 0x81300580, 0x0402000f, 0x59300004, + 0x84000520, 0x48026004, 0x0401ff4d, 0x04020009, + 0x5c03e000, 0x04000db9, 0x80000580, 0x5c022800, + 0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000, + 0x0401fcf1, 0x42027000, 0x00000049, 0x59300004, + 0x84000520, 0x48026004, 0x8c00050c, 0x02020800, + 0x000208d8, 0x5c03e000, 0x04000da8, 0x82000540, + 0x00000001, 0x5c022800, 0x5c034800, 0x5c03a000, + 0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fda9, + 0x4df00000, 0x598c000d, 0x80026540, 0x04000012, + 0x59300004, 0x84000520, 0x48026004, 0x0401ff86, + 0x04000017, 0x0401fd09, 0x42027000, 0x00000013, + 0x59300004, 0x8c00050c, 0x02020800, 0x000208d8, + 0x5c03e000, 0x04000d8d, 0x82000540, 0x00000001, + 0x1c01f000, 0x836c1580, 0x00000001, 0x040007f9, + 0x836c1580, 0x00000004, 0x040007f6, 0x42001000, + 0x00103f62, 0x0201f800, 0x00105cc9, 0x5c03e000, + 0x04000d7e, 0x80000580, 0x1c01f000, 0x4d300000, + 0x4d180000, 0x4d3c0000, 0x0401fd82, 0x4df00000, + 0x4a0378e4, 0x0000000f, 0x0401fa02, 0x417a3000, + 0x59926004, 0x813261c0, 0x04000010, 0x417a7800, + 0x0201f800, 0x00104728, 0x0400000a, 0x59300c06, + 0x82040580, 0x00000003, 0x04000004, 0x82040580, + 0x00000006, 0x04020003, 0x42027800, 0x00000002, + 0x0201f800, 0x00108997, 0x811a3000, 0x83180480, + 0x00000005, 0x040017eb, 0x42000800, 0x00000040, + 0x0201f800, 0x00101395, 0x4a0378e4, 0x0000000a, + 0x5c03e000, 0x04000d55, 0x5c027800, 0x5c023000, + 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0401fd58, 0x4df00000, 0x59c80840, 0x82040540, + 0x00000010, 0x48039040, 0x59c41008, 0x82080500, + 0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000, + 0x42001000, 0x00000003, 0x0401f9c5, 0x598e600d, + 0x813261c0, 0x04020f9d, 0x040009ca, 0x497b2807, + 0x0401f80a, 0x5c001000, 0x5c000800, 0x480b8808, + 0x84040d74, 0x48079040, 0x5c03e000, 0x04000d33, + 0x5c026000, 0x1c01f000, 0x4d380000, 0x4d180000, + 0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000, + 0x4d140000, 0x59c41004, 0x480bc857, 0x82080500, + 0x00003ff0, 0x04000025, 0x417a3000, 0x4c080000, + 0x0201f800, 0x00105d9b, 0x5c001000, 0x82080500, + 0x00000210, 0x04020004, 0x811a3000, 0x80081102, + 0x0401f7f7, 0x0401f9c6, 0x59926004, 0x4933c857, + 0x813261c0, 0x04020005, 0x59c400a3, 0x8c00051a, + 0x02000800, 0x00100615, 0x0401fea1, 0x04000009, + 0x0401fc4d, 0x42027000, 0x00000049, 0x59300004, + 0x8c00050c, 0x02020800, 0x000208d8, 0x0401f007, + 0x42027000, 0x0000004a, 0x4a026203, 0x00000003, + 0x0201f800, 0x000208d8, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x5c026000, 0x5c023000, + 0x5c027000, 0x1c01f000, 0x4d300000, 0x4d180000, + 0x4d900000, 0x0401fcff, 0x42001000, 0x00000000, + 0x598c0000, 0x82000580, 0x00000005, 0x04000974, + 0x417a3000, 0x811b20c8, 0x83932400, 0x0000bf32, + 0x59900001, 0x82000580, 0x00000001, 0x0402000d, + 0x42000800, 0x000007d0, 0x59926004, 0x59300011, + 0x82000500, 0xfff00000, 0x80000540, 0x04000003, + 0x42000800, 0x00001b58, 0x0201f800, 0x00105d8d, + 0x811a3000, 0x83180480, 0x00000005, 0x040017ea, + 0x59c81040, 0x84081534, 0x480b9040, 0x0401fcd3, + 0x5c032000, 0x5c023000, 0x5c026000, 0x1c01f000, + 0x4933c857, 0x4d900000, 0x4dd00000, 0x4da40000, + 0x4d140000, 0x4d380000, 0x0401fcd2, 0x4df00000, + 0x59300004, 0x8c00053e, 0x04020007, 0x8c000520, + 0x04000026, 0x0201f800, 0x001068a3, 0x04000023, + 0x0401f02b, 0x598c000d, 0x81300580, 0x04000012, + 0x0201f800, 0x00108a8a, 0x04020025, 0x0401f91b, + 0x04000023, 0x48038804, 0x0401f961, 0x0201f800, + 0x001010ca, 0x0201f800, 0x001068c1, 0x42027000, + 0x00000049, 0x59300004, 0x8c00050c, 0x0402000d, + 0x0401f00e, 0x59c40004, 0x8c000504, 0x04000014, + 0x4a038804, 0x00000004, 0x0401fc18, 0x42027000, + 0x00000013, 0x59300004, 0x8c00050c, 0x04000003, + 0x0201f800, 0x000208d8, 0x5c03e000, 0x04000c9b, + 0x5c027000, 0x5c022800, 0x5c034800, 0x5c03a000, + 0x5c032000, 0x80000580, 0x1c01f000, 0x5c03e000, + 0x04000c92, 0x5c027000, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x82000540, 0x00000001, + 0x1c01f000, 0x497b2807, 0x0401fc92, 0x59c400af, + 0x800001c0, 0x04020004, 0x0401fc84, 0x0201f000, + 0x00101565, 0x598c000f, 0x82001480, 0x00000002, + 0x04021007, 0x80000000, 0x4803180f, 0x80000580, + 0x0201f800, 0x00105d86, 0x0400000e, 0x0401fed7, + 0x0402000c, 0x0401fdc5, 0x0400000a, 0x0201f800, + 0x0010a7ee, 0x0401f918, 0x4d380000, 0x42027000, + 0x00000014, 0x0201f800, 0x000208d8, 0x5c027000, + 0x0401fc6a, 0x0201f000, 0x00101565, 0x4d900000, + 0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000, + 0x0201f800, 0x00105d9b, 0x0401fc6a, 0x59c400af, + 0x800001c0, 0x04000027, 0x0401f909, 0x59926004, + 0x4933c857, 0x59300004, 0x8c000516, 0x0400000b, + 0x0401fe86, 0x0402001f, 0x0201f800, 0x001068c1, + 0x0401fc52, 0x42000800, 0x80000804, 0x0201f800, + 0x00106466, 0x0401f017, 0x42001800, 0x00007530, + 0x0401f8c3, 0x04020004, 0x0201f800, 0x00105d8b, + 0x0401f010, 0x0401fe75, 0x0402000e, 0x0201f800, + 0x0010a7ee, 0x59300004, 0x8c00050c, 0x04020003, + 0x4a026203, 0x00000003, 0x4d380000, 0x42027000, + 0x0000004a, 0x0201f800, 0x000208d8, 0x5c027000, + 0x0401fc36, 0x5c026000, 0x5c022800, 0x5c034800, + 0x5c03a000, 0x5c032000, 0x0201f000, 0x00101565, + 0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000, + 0x4d300000, 0x4d2c0000, 0x0401fc32, 0x0401f8d4, + 0x59926004, 0x4933c857, 0x0401f882, 0x04000016, + 0x0201f800, 0x00105d9b, 0x813261c0, 0x04000034, + 0x59325808, 0x812e59c0, 0x02000800, 0x00100615, + 0x0201f800, 0x00104e0d, 0x0402001d, 0x592c0208, + 0x84000550, 0x48025a08, 0x0201f800, 0x00104f29, + 0x04020027, 0x592c0208, 0x84000510, 0x48025a08, + 0x0401f023, 0x0201f800, 0x00105d8b, 0x0401f020, + 0x0201f800, 0x0010a7ee, 0x0401fd99, 0x592c0208, + 0x84000550, 0x48025a08, 0x4d380000, 0x42027000, + 0x0000004a, 0x4a026203, 0x00000003, 0x0201f800, + 0x000208d8, 0x5c027000, 0x0401f011, 0x59900006, + 0x82000500, 0xffff0000, 0x040207ee, 0x59c408af, + 0x82040480, 0x000003e8, 0x040217ea, 0x59900006, + 0x82000400, 0x00010000, 0x48032006, 0x0201f800, + 0x00105d8b, 0x0201f800, 0x00103f37, 0x5c025800, + 0x5c026000, 0x5c022800, 0x5c034800, 0x5c03a000, + 0x5c032000, 0x0201f000, 0x00106982, 0x4d300000, + 0x4d2c0000, 0x0201f800, 0x0010698c, 0x598e600d, + 0x4933c857, 0x59c41004, 0x8c081500, 0x04000007, + 0x0201f800, 0x00104e0d, 0x04020007, 0x0201f800, + 0x00104f29, 0x0402002f, 0x0201f800, 0x00105d86, + 0x0401f02c, 0x598c000f, 0x80000540, 0x04020011, + 0x59c408af, 0x82040480, 0x000003e8, 0x0402100d, + 0x598c080f, 0x80040800, 0x4807180f, 0x0201f800, + 0x00105d86, 0x42000000, 0x0010b650, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00103f37, 0x0401f019, + 0x0401fdad, 0x813261c0, 0x04020003, 0x0401f849, + 0x0401f014, 0x0201f800, 0x0010a7ee, 0x59300406, + 0x82000580, 0x00000003, 0x04020007, 0x59325808, + 0x812e59c0, 0x04000004, 0x592c0208, 0x84000550, + 0x48025a08, 0x0401f854, 0x4d380000, 0x42027000, + 0x00000014, 0x0201f800, 0x000208d8, 0x5c027000, + 0x5c025800, 0x5c026000, 0x0201f000, 0x00106982, + 0x59c40804, 0x83180400, 0x00106dec, 0x50000000, + 0x80040500, 0x1c01f000, 0x59c40804, 0x83180400, + 0x00106df1, 0x50000000, 0x80040500, 0x1c01f000, + 0x00000210, 0x00000420, 0x00000840, 0x00001080, + 0x00002100, 0x00004000, 0x00008000, 0x00010000, + 0x00020000, 0x00040000, 0x00080000, 0x00100000, + 0x00200000, 0x00400000, 0x00800000, 0x59900806, + 0x80040120, 0x800c0480, 0x04021004, 0x82000540, + 0x00000001, 0x0401f005, 0x82040c00, 0x00010000, + 0x48072006, 0x80000580, 0x1c01f000, 0x480bc857, + 0x0201f800, 0x0010698c, 0x4df00000, 0x480b1800, + 0x5c03e000, 0x02000800, 0x00106982, 0x1c01f000, + 0x4803c856, 0x0201f800, 0x0010698c, 0x4df00000, + 0x497b180d, 0x497b1803, 0x497b180e, 0x497b180f, + 0x497b1810, 0x598c0000, 0x82000580, 0x00000003, + 0x04000009, 0x836c0580, 0x00000002, 0x04020004, + 0x4a031800, 0x00000005, 0x0401f003, 0x4a031800, + 0x00000000, 0x5c03e000, 0x02000800, 0x00106982, + 0x1c01f000, 0x59300004, 0x8c00050c, 0x04020003, + 0x4a026203, 0x00000001, 0x1c01f000, 0x83180480, + 0x00000005, 0x02021800, 0x00100615, 0x491bc857, + 0x811b20c8, 0x83932400, 0x0000bf32, 0x811ba0ca, + 0x83d3a400, 0x00007600, 0x83180400, 0x00106e41, + 0x50034800, 0x811a28c2, 0x83162c00, 0x00006100, + 0x1c01f000, 0x0010b559, 0x0010b570, 0x0010b587, + 0x0010b59e, 0x0010b5b5, 0x4933c857, 0x59300406, + 0x82000c80, 0x00000012, 0x04021016, 0x4803c857, + 0x04011000, 0x0c01f001, 0x00106e60, 0x00106f03, + 0x00107249, 0x001072cf, 0x00106f03, 0x00107249, + 0x001072cf, 0x00106e60, 0x00106f03, 0x00106e60, + 0x00106e60, 0x00106e60, 0x00106e60, 0x00106e60, + 0x00106e60, 0x00106e60, 0x00106e66, 0x00106e66, + 0x0201f800, 0x0010698c, 0x0201f800, 0x001068f6, + 0x0201f000, 0x00106982, 0x42001000, 0x0010b5f4, + 0x50081000, 0x4930100c, 0x58080002, 0x82000580, + 0x00000100, 0x0402003e, 0x59325808, 0x812e59c0, + 0x02000800, 0x00100615, 0x59326809, 0x813669c0, + 0x04000025, 0x592c040b, 0x82000500, 0x0000e000, + 0x04000003, 0x0401fbc9, 0x0401f002, 0x0401fbb9, + 0x592c000d, 0x82000500, 0x00000003, 0x04000007, + 0x82000580, 0x00000003, 0x80000000, 0x58d00802, + 0x80040540, 0x4801a002, 0x42001000, 0x0010b5f4, + 0x50081000, 0x4930100b, 0x492c100a, 0x82d00400, + 0x00000006, 0x48001003, 0x592c000d, 0x82000400, + 0x00000003, 0x80000104, 0x48001004, 0x592c000e, + 0x48001007, 0x592c000f, 0x48001008, 0x0201f000, + 0x001008a1, 0x42026800, 0x0010bc0c, 0x592c080a, + 0x48066802, 0x82040500, 0x00ffff00, 0x04000007, + 0x497a6a12, 0x59a81010, 0x82081500, 0x00ffff00, + 0x80080580, 0x040207d0, 0x82040d00, 0x000000ff, + 0x800408d0, 0x48066a12, 0x0401f7cb, 0x1c01f000, + 0x4d2c0000, 0x4d300000, 0x4c580000, 0x4c540000, + 0x4c500000, 0x5832580a, 0x812e59c0, 0x02000800, + 0x00100615, 0x58300002, 0x4a006002, 0x00000100, + 0x82000580, 0x00000100, 0x04020020, 0x5830000b, + 0x5832600c, 0x81300580, 0x04020012, 0x0401f82f, + 0x04020014, 0x592c080d, 0x82040c00, 0x00000003, + 0x80040904, 0x4004b000, 0x4200a000, 0x0010b349, + 0x4050a800, 0x0201f800, 0x0010a94f, 0x42001000, + 0x0000dc00, 0x0201f800, 0x0010763b, 0x0401f005, + 0x4803c857, 0x4933c857, 0x0401f81c, 0x04000f93, + 0x5c00a000, 0x5c00a800, 0x5c00b000, 0x5c026000, + 0x5c025800, 0x1c01f000, 0x5830000b, 0x5832600c, + 0x4803c857, 0x4933c857, 0x81300580, 0x040207f1, + 0x0401f80e, 0x040207f3, 0x4803c857, 0x0201f800, + 0x00106619, 0x02020800, 0x00100615, 0x4a025a06, + 0x00000002, 0x0201f800, 0x00020381, 0x0201f800, + 0x00107698, 0x0401f7e7, 0x0201f800, 0x0010698c, + 0x4df00000, 0x598c000d, 0x81300580, 0x04020009, + 0x598c0005, 0x81300580, 0x04020006, 0x5c03e000, + 0x02000800, 0x00106982, 0x80000580, 0x1c01f000, + 0x4803c857, 0x5c03e000, 0x02000800, 0x00106982, + 0x82000540, 0x00000001, 0x1c01f000, 0x59300403, + 0x82000c80, 0x00000056, 0x02021800, 0x00100615, + 0x4803c857, 0x0c01f001, 0x0010707a, 0x00107095, + 0x001070a6, 0x001071a9, 0x00107169, 0x0010716d, + 0x0010717e, 0x00107192, 0x00107187, 0x00107192, + 0x001071cd, 0x00107192, 0x0010720f, 0x00107192, + 0x0010721d, 0x00107192, 0x00107187, 0x00107192, + 0x00107221, 0x00106f60, 0x00106f60, 0x00106f60, + 0x00106f60, 0x00106f60, 0x00106f60, 0x00106f60, + 0x00106f60, 0x00106f60, 0x00106f60, 0x00106f60, + 0x001072ed, 0x0010730c, 0x00107316, 0x00106f60, + 0x0010732c, 0x0010717e, 0x00106f60, 0x0010717e, + 0x00107192, 0x00106f60, 0x001070a6, 0x001071a9, + 0x00106f60, 0x0010737c, 0x00107192, 0x00106f60, + 0x0010738c, 0x00107192, 0x00106f60, 0x00107187, + 0x0010706b, 0x00106f62, 0x00106f60, 0x001073a3, + 0x001073dc, 0x00107456, 0x00106f60, 0x00107466, + 0x0010717c, 0x00107459, 0x00106f60, 0x00107338, + 0x0010747f, 0x00106f60, 0x001074b4, 0x00107507, + 0x00106f60, 0x00106f77, 0x00106fdd, 0x00106fea, + 0x00106f60, 0x0010717e, 0x00106f60, 0x00107031, + 0x0010703c, 0x00106f60, 0x00106f60, 0x00106f8b, + 0x00106fb0, 0x00107546, 0x00107587, 0x001075ad, + 0x00106f60, 0x00106f60, 0x00106f60, 0x0010757b, + 0x0201f800, 0x00100615, 0x0401fad2, 0x59325808, + 0x592c0009, 0x4801a006, 0x592c000a, 0x4801a007, + 0x592c000b, 0x4801a008, 0x592c000c, 0x4801a009, + 0x592c000d, 0x4801a00a, 0x4979a00b, 0x592c0809, + 0x82040d00, 0x00000fff, 0x80040904, 0x42001000, + 0x0000dc00, 0x0201f000, 0x0010763b, 0x4a026202, + 0x0000ffff, 0x0401fabb, 0x4d2c0000, 0x4a01a006, + 0x05000000, 0x59325808, 0x592c0009, 0x4801a007, + 0x592c000a, 0x4801a008, 0x592c000b, 0x4801a009, + 0x42000800, 0x00000004, 0x42001000, 0x0000dc00, + 0x5c025800, 0x0201f000, 0x0010763b, 0x4c580000, + 0x4c500000, 0x4c540000, 0x4d2c0000, 0x0401faa5, + 0x59325808, 0x5930040b, 0x800000c2, 0x4200a800, + 0x0010b349, 0x592cb205, 0x832ca400, 0x00000006, + 0x0201f800, 0x0010a93e, 0x40580000, 0x8054ac00, + 0x592c0001, 0x80000540, 0x04000003, 0x40025800, + 0x0401f7f5, 0x4200a000, 0x0010b349, 0x4050a800, + 0x5930b40b, 0x0201f800, 0x0010a94f, 0x59300c0b, + 0x42001000, 0x0000dc00, 0x5c025800, 0x5c00a800, + 0x5c00b000, 0x5c00a000, 0x0201f000, 0x0010763b, + 0x4c580000, 0x4c500000, 0x4c540000, 0x4d2c0000, + 0x42034800, 0x0010b342, 0x0401fa8c, 0x59325808, + 0x592c0802, 0x4807c857, 0x40041000, 0x80040904, + 0x82081500, 0x00000003, 0x04000008, 0x80040800, + 0x82081580, 0x00000003, 0x80081000, 0x58d00002, + 0x80080540, 0x4801a002, 0x4a025805, 0x02000000, + 0x82d0ac00, 0x00000006, 0x592cb011, 0x832ca400, + 0x00000005, 0x0201f800, 0x0010a93e, 0x40580000, + 0x8054ac00, 0x592e5801, 0x41780000, 0x812e5d40, + 0x040207f6, 0x42001000, 0x0000dc00, 0x5c025800, + 0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000, + 0x0010763b, 0x0401fa57, 0x4a01a006, 0x78000000, + 0x5930001c, 0x840001c0, 0x4801a407, 0x4979a207, + 0x42000800, 0x00000002, 0x42001000, 0x0000dc00, + 0x0201f000, 0x0010763b, 0x4c580000, 0x4c540000, + 0x4c500000, 0x0401fa55, 0x4a01a006, 0x02000000, + 0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009, + 0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b, + 0x5930001c, 0x82000d80, 0x0000e000, 0x04000016, + 0x82000d80, 0x0000df00, 0x04000006, 0x4a01a407, + 0x00000010, 0x42000800, 0x00000006, 0x0401f027, + 0x4a03c840, 0x0010b2e7, 0x4a03c842, 0x0000000d, + 0x42001800, 0x0010b2e7, 0x0201f800, 0x001007f5, + 0x42000000, 0x0000df00, 0x4200a000, 0x0010b2e7, + 0x0401f00d, 0x4a03c840, 0x0010b2f4, 0x4a03c842, + 0x0000000d, 0x42001800, 0x0010b2f4, 0x0201f800, + 0x001007f5, 0x42000000, 0x0000e000, 0x4200a000, + 0x0010b2f4, 0x82000540, 0x00000010, 0x4801a407, + 0x4a01a207, 0x00000034, 0x4200b000, 0x0000000d, + 0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010a93e, + 0x42000800, 0x00000013, 0x42001000, 0x0000dc00, + 0x5c00a000, 0x5c00a800, 0x5c00b000, 0x0201f000, + 0x0010763b, 0x0401fa03, 0x4a01a006, 0x63000028, + 0x5930001c, 0x4801a007, 0x42000800, 0x00000002, + 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, + 0x0401fa06, 0x41780000, 0x41780800, 0x42002000, + 0x00080000, 0x0c01f81b, 0x80000000, 0x80040800, + 0x42001000, 0x0000000c, 0x59841802, 0x8c0c1d00, + 0x04020008, 0x42002000, 0x00050000, 0x0c01f811, + 0x80000000, 0x80040800, 0x82081400, 0x00000004, + 0x82080540, 0x02000000, 0x4801a006, 0x800408e0, + 0x5930001c, 0x80040540, 0x4801a007, 0x80080904, + 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, + 0x00107061, 0x00107063, 0x00107065, 0x00107067, + 0x00107069, 0x4811a008, 0x1c01f000, 0x4811a009, + 0x1c01f000, 0x4811a00a, 0x1c01f000, 0x4811a00b, + 0x1c01f000, 0x4811a00c, 0x1c01f000, 0x4a026009, + 0x0010bc0c, 0x59a80010, 0x82000500, 0x000000ff, + 0x800000d0, 0x42026800, 0x0010bc0c, 0x48026a12, + 0x0401fa3c, 0x41780800, 0x42001000, 0x00005c00, + 0x0201f000, 0x0010763b, 0x0401f9ba, 0x4a01a006, + 0x52000000, 0x4979a007, 0x599c0017, 0x8c000500, + 0x04000005, 0x599c0402, 0x0201f800, 0x00101644, + 0x4805a007, 0x59a80002, 0x4801a008, 0x59a80003, + 0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001, + 0x4801a00b, 0x59a80010, 0x4801a00c, 0x42000800, + 0x00000007, 0x42001000, 0x0000dc00, 0x0201f000, + 0x0010763b, 0x4a026202, 0x0000ffff, 0x0401f99d, + 0x4a01a006, 0x05000000, 0x59a80010, 0x4801a007, + 0x59a80002, 0x59a80803, 0x4801a008, 0x4805a009, + 0x42000800, 0x00000004, 0x42001000, 0x0000dc00, + 0x0201f000, 0x0010763b, 0x4a026202, 0x0000ffff, + 0x0401f98c, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x00104745, 0x5c027800, 0x4a01a006, 0x03000000, + 0x59340403, 0x82000580, 0x000007fe, 0x0402006e, + 0x4a01a006, 0x04000000, 0x81a40800, 0x4a000800, + 0x22fffffe, 0x5934000a, 0x84000500, 0x4802680a, + 0x59c41002, 0x8408150c, 0x480b8802, 0x59a80026, + 0x8c000508, 0x04000010, 0x59a8002a, 0x4801a007, + 0x59a8002b, 0x82000500, 0xffff2000, 0x599c0818, + 0x8c040d16, 0x04000002, 0x8400056a, 0x4801a008, + 0x4a01a009, 0x00002710, 0x59a8002d, 0x4801a00a, + 0x0401f039, 0x59a8002a, 0x4801a007, 0x0201f800, + 0x00104e0d, 0x04020009, 0x497b8880, 0x82000500, + 0x0000ffff, 0x4c000000, 0x0201f800, 0x00101670, + 0x5c000000, 0x48038880, 0x59a8002b, 0x0201f800, + 0x00104e0d, 0x04020004, 0x82000500, 0x37ffffff, + 0x0401f003, 0x82000500, 0x3fffffff, 0x599c0818, + 0x8c040d16, 0x04000002, 0x8400056a, 0x59a80805, + 0x8c040d10, 0x04000019, 0x59300c03, 0x82041580, + 0x00000051, 0x04000015, 0x82041580, 0x00000031, + 0x04000012, 0x4c580000, 0x4c500000, 0x4c540000, + 0x4200b000, 0x00000004, 0x4200a000, 0x0010b6f9, + 0x82d0ac00, 0x0000001f, 0x4c000000, 0x0201f800, + 0x0010a93e, 0x5c000000, 0x5c00a800, 0x5c00a000, + 0x5c00b000, 0x8400057a, 0x4801a008, 0x4979a009, + 0x4979a00a, 0x59a80002, 0x59a80803, 0x4801a00b, + 0x4805a00c, 0x59a80000, 0x59a80801, 0x4801a00d, + 0x4805a00e, 0x4979a00f, 0x4979a010, 0x4979a011, + 0x4979a012, 0x4979a013, 0x4979a014, 0x4979a015, + 0x4979a016, 0x59a8002e, 0x84000576, 0x4801a017, + 0x59a8002f, 0x4801a018, 0x4979a019, 0x4979a01a, + 0x0401f043, 0x59a80026, 0x8c000508, 0x0400000d, + 0x59a8002a, 0x82000500, 0x0000ffff, 0x59c40880, + 0x80040d80, 0x04000007, 0x497b8880, 0x4c000000, + 0x0201f800, 0x00101670, 0x5c000000, 0x48038880, + 0x59a8002a, 0x4801a007, 0x4c640000, 0x4d2c0000, + 0x59a8c82b, 0x0201f800, 0x00108df4, 0x0400000d, + 0x0201f800, 0x00109360, 0x0402000a, 0x592c0207, + 0x8c00050e, 0x04000007, 0x8264cd00, 0x0000ffff, + 0x592c0009, 0x82000500, 0xffff0000, 0x8064cd40, + 0x4865a008, 0x5c025800, 0x5c00c800, 0x59a8002c, + 0x4801a009, 0x59a8002d, 0x4801a00a, 0x59a80002, + 0x59a80803, 0x4801a00b, 0x4805a00c, 0x59a80000, + 0x59a80801, 0x4801a00d, 0x4805a00e, 0x4979a00f, + 0x4979a010, 0x4979a011, 0x4979a012, 0x4979a013, + 0x4979a014, 0x4979a015, 0x4979a016, 0x59a8002e, + 0x4801a017, 0x59a8002f, 0x4801a018, 0x59a80030, + 0x4801a019, 0x59a80031, 0x4801a01a, 0x42000800, + 0x0000001d, 0x42001000, 0x0000dc00, 0x0201f000, + 0x0010763b, 0x0401f8cb, 0x4a01a006, 0x50000000, + 0x0401f7b5, 0x0401f8c7, 0x4a01a406, 0x21000010, + 0x4a01a206, 0x00000014, 0x4979a007, 0x4979a008, + 0x4979a009, 0x4979a00a, 0x42000800, 0x00000005, + 0x42001000, 0x0000dc00, 0x0201f000, 0x0010763b, + 0x0401f8bf, 0x0401f002, 0x0401f8c4, 0x4a01a006, + 0x02000000, 0x42000800, 0x00000001, 0x42001000, + 0x0000dc00, 0x0201f000, 0x0010763b, 0x0401f8bb, + 0x4a01a006, 0x02000000, 0x59300403, 0x82000580, + 0x00000031, 0x04020794, 0x81a40800, 0x4a000801, + 0x00fffffe, 0x0401f72b, 0x0401f8b0, 0x4a01a006, + 0x01000000, 0x5930041a, 0x80000540, 0x04000003, + 0x4801a407, 0x0401f003, 0x4a01a407, 0x00000003, + 0x5930021a, 0x80000540, 0x04000003, 0x4801a207, + 0x0401f003, 0x4a01a207, 0x00002a00, 0x42000800, + 0x00000002, 0x42001000, 0x0000dc00, 0x0201f000, + 0x0010763b, 0x4a026202, 0x0000ffff, 0x0401f889, + 0x4a01a406, 0x00002010, 0x4a01a206, 0x00000014, + 0x4a01a407, 0x00000800, 0x4a01a207, 0x00002000, + 0x80000580, 0x599c0817, 0x8c040d0a, 0x04020003, + 0x82000540, 0x00000020, 0x8c040d08, 0x04000003, + 0x82000540, 0x00000010, 0x82000540, 0x00000002, + 0x5934080a, 0x8c040d14, 0x04000005, 0x82040d00, + 0x00000380, 0x80040540, 0x0401f006, 0x599c0818, + 0x8c040d18, 0x04000003, 0x82000540, 0x00000380, + 0x0401f03c, 0x0401f875, 0x4a01a406, 0x00000210, + 0x4a01a206, 0x00000014, 0x4a01a407, 0x00000800, + 0x5934000a, 0x8c000516, 0x04000014, 0x59340c05, + 0x82040500, 0x00000030, 0x04000013, 0x59340a05, + 0x82040500, 0x0000c000, 0x04020009, 0x8c040d1a, + 0x04000004, 0x4a01a207, 0x00002100, 0x0401f00c, + 0x4a01a207, 0x00000100, 0x0401f009, 0x4a01a207, + 0x00000400, 0x0401f006, 0x4a01a207, 0x00000700, + 0x0401f003, 0x4a01a207, 0x00000800, 0x80000580, + 0x599c0817, 0x8c040d0a, 0x04020003, 0x82000540, + 0x00000020, 0x8c040d08, 0x04000003, 0x82000540, + 0x00000010, 0x82000540, 0x00000002, 0x59340a00, + 0x8c040d0e, 0x0400000b, 0x84000550, 0x599c1017, + 0x8c08150a, 0x04020004, 0x8c040d0a, 0x04000002, + 0x8400054e, 0x8c040d1c, 0x04000002, 0x84000552, + 0x4801a20a, 0x42000800, 0x00000005, 0x42001000, + 0x0000dc00, 0x0201f000, 0x0010763b, 0x0401f833, + 0x4a01a006, 0x02100014, 0x4a01a007, 0x01000000, + 0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800, + 0x00000005, 0x42001000, 0x0000dc00, 0x0201f000, + 0x0010763b, 0x0401f825, 0x4a01a006, 0x02000000, + 0x0401f65d, 0x4933c857, 0x0401f820, 0x4a01a006, + 0x01000000, 0x4a01a407, 0x0000000b, 0x42000800, + 0x00000002, 0x42001000, 0x0000dc00, 0x0201f000, + 0x0010763b, 0x42005000, 0x32000000, 0x42006000, + 0x08290000, 0x41786800, 0x41787800, 0x0401f3e6, + 0x42005000, 0x22000000, 0x42006000, 0x01290000, + 0x41786800, 0x41787800, 0x0401f3df, 0x42005000, + 0x33000000, 0x42006000, 0x08980000, 0x41786800, + 0x41787800, 0x0401f3d8, 0x42005000, 0x23000000, + 0x42006000, 0x01980000, 0x41786800, 0x41787800, + 0x0401f3d1, 0x59300403, 0x82000c80, 0x00000085, + 0x02001800, 0x00100615, 0x82000c80, 0x00000093, + 0x02021800, 0x00100615, 0x82000480, 0x00000085, + 0x0c01f001, 0x00107263, 0x00107265, 0x00107272, + 0x00107263, 0x00107263, 0x00107263, 0x00107263, + 0x00107263, 0x00107263, 0x00107263, 0x00107263, + 0x00107263, 0x00107263, 0x0010727f, 0x0201f800, + 0x00100615, 0x4933c857, 0x0401f851, 0x5930001c, + 0x4801a004, 0x4801a007, 0x4979a408, 0x4a01a208, + 0x0000ffff, 0x42000800, 0x00000003, 0x42001000, + 0x0000dc00, 0x0401f3ca, 0x4933c857, 0x0401f850, + 0x5930001c, 0x4801a004, 0x4a01a406, 0x00000003, + 0x4a01a206, 0x00000300, 0x42000800, 0x00000001, + 0x42001000, 0x0000dc00, 0x0401f3bd, 0x4d2c0000, + 0x59325808, 0x4933c857, 0x492fc857, 0x812e59c0, + 0x02000800, 0x00100615, 0x59340a12, 0x82040d00, + 0x0000ff00, 0x592c000a, 0x82000500, 0x000000ff, + 0x900001c0, 0x80040540, 0x82000540, 0x00000011, + 0x44034800, 0x81a5a000, 0x42001000, 0x00000009, + 0x42000800, 0x00000003, 0x592c0009, 0x82000500, + 0xff000000, 0x82001d80, 0x84000000, 0x04000009, + 0x82001d80, 0x85000000, 0x02020800, 0x00100615, + 0x42001000, 0x00000007, 0x42000800, 0x00000001, + 0x832c1c00, 0x00000009, 0x500c0000, 0x4401a000, + 0x800c1800, 0x80d1a000, 0x80081040, 0x040207fb, + 0x42001000, 0x0000dc00, 0x5c025800, 0x0401f38c, + 0x42005000, 0x81000000, 0x42006000, 0x00090000, + 0x41786800, 0x41787800, 0x0401f363, 0x42005000, + 0x84000000, 0x42006000, 0x00990000, 0x59300406, + 0x82000580, 0x00000005, 0x04000002, 0x8430652e, + 0x41786800, 0x41787800, 0x0401f357, 0x42005000, + 0x85000000, 0x42006000, 0x00990000, 0x59300406, + 0x82000580, 0x00000005, 0x04000002, 0x8430652e, + 0x41786800, 0x41787800, 0x0401f34b, 0x59300403, + 0x82000c80, 0x00000053, 0x02021800, 0x00100615, + 0x82000480, 0x0000004b, 0x02001800, 0x00100615, + 0x59326809, 0x59368c03, 0x4803c857, 0x0c01f001, + 0x00107353, 0x0010735b, 0x00107363, 0x0010736b, + 0x001072e4, 0x001072e4, 0x001072e4, 0x0010734b, + 0x0201f800, 0x00100615, 0x42005000, 0x06000000, + 0x42006000, 0x08290000, 0x41786800, 0x41787800, + 0x0401f32d, 0x4933c857, 0x0401ff46, 0x4a01a006, + 0x12000000, 0x59300406, 0x82000580, 0x00000004, + 0x04020003, 0x59340002, 0x0401f002, 0x59a80010, + 0x82000500, 0x00ffffff, 0x4801a007, 0x59300419, + 0x4801a408, 0x59300219, 0x4801a208, 0x4979a009, + 0x4979a00a, 0x4979a00b, 0x4979a00c, 0x4979a00d, + 0x4979a00e, 0x4979a00f, 0x4979a010, 0x42000800, + 0x0000000b, 0x42001000, 0x0000dc00, 0x0401f330, + 0x0401ff28, 0x4a01a006, 0x0f000000, 0x5930001c, + 0x4801a007, 0x42000800, 0x00000002, 0x42001000, + 0x0000dc00, 0x0401f326, 0x0401ff2c, 0x4a01a006, + 0x02000000, 0x59c40085, 0x48031004, 0x59880000, + 0x4801a007, 0x59880001, 0x4801a008, 0x59880002, + 0x4801a009, 0x59880003, 0x4801a00a, 0x59880004, + 0x4801a00b, 0x59880005, 0x4801a00c, 0x42000800, + 0x00000007, 0x42001000, 0x0000dc00, 0x0401f310, + 0x4a026202, 0x0000ffff, 0x0401ff06, 0x4a01a006, + 0x62000000, 0x5930001c, 0x4801a007, 0x42000800, + 0x00000002, 0x42001000, 0x0000dc00, 0x0401f304, + 0x0401fefc, 0x59300808, 0x4c500000, 0x4c540000, + 0x4c580000, 0x8204a400, 0x0000000a, 0x5930b01c, + 0x82d0ac00, 0x00000006, 0x0201f800, 0x0010a93e, + 0x5930081c, 0x42001000, 0x0000dc00, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x0401f2f1, 0x0401ff9b, + 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, + 0x4a01a008, 0x00001000, 0x0401f020, 0x0401ff93, + 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, + 0x4a01a008, 0x00004000, 0x0401f018, 0x0401ff8b, + 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, + 0x4a01a008, 0x00002000, 0x0401f010, 0x0401ff83, + 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, + 0x4a01a008, 0x00000400, 0x0401f008, 0x0401ff7b, + 0x59300017, 0x4801a006, 0x59300018, 0x4801a007, + 0x4a01a008, 0x00000200, 0x4979a009, 0x4979a00a, + 0x4979a00b, 0x4979a00c, 0x4979a00d, 0x42000800, + 0x00000008, 0x42001000, 0x0000dc00, 0x0401f2c0, + 0x0401fec6, 0x4a01a006, 0x02000014, 0x4979a407, + 0x4979a207, 0x59a8003a, 0x4801a008, 0x59a8003b, + 0x4801a009, 0x4a01a00a, 0x00047878, 0x42000800, + 0x00000005, 0x42001000, 0x0000dc00, 0x0401f2b0, + 0x0401feb6, 0x4a01a006, 0x02140018, 0x4a01a407, + 0x00000800, 0x5930001c, 0x82000d00, 0xff000000, + 0x900409c0, 0x4805a207, 0x82000500, 0x00ffffff, + 0x4801a00a, 0x4979a408, 0x4979a208, 0x4979a409, + 0x4979a209, 0x4979a00b, 0x42000800, 0x00000006, + 0x42001000, 0x0000dc00, 0x0401f299, 0x4933c857, + 0x4937c857, 0x4d380000, 0x4d1c0000, 0x42027000, + 0x00000035, 0x0201f800, 0x00109183, 0x04020022, + 0x0401fe88, 0x4a01a006, 0x13000000, 0x5932381e, + 0x591c0414, 0x8c000502, 0x02000800, 0x00100615, + 0x591c0019, 0x4801a005, 0x591c0406, 0x82000580, + 0x00000003, 0x04000007, 0x59300809, 0x58040002, + 0x82000500, 0x00ffffff, 0x4801a007, 0x0401f003, + 0x59a80010, 0x4801a007, 0x59300419, 0x4801a408, + 0x59300219, 0x4801a208, 0x42000800, 0x00000003, + 0x42001000, 0x0000dc00, 0x5c023800, 0x5c027000, + 0x0401f26f, 0x4803c856, 0x0201f800, 0x0010698c, + 0x598c000d, 0x81300580, 0x02020800, 0x00100615, + 0x0201f800, 0x001068f6, 0x0201f800, 0x000208b4, + 0x5c023800, 0x5c027000, 0x0201f000, 0x00106982, + 0x4803c856, 0x4d2c0000, 0x4d1c0000, 0x5932381e, + 0x811e39c0, 0x02000800, 0x00100615, 0x591c0c06, + 0x82040580, 0x00000006, 0x0400000d, 0x82040580, + 0x00000003, 0x04000036, 0x4a026403, 0x00000037, + 0x4a02641a, 0x00000003, 0x4a02621a, 0x00001700, + 0x5c023800, 0x5c025800, 0x0401f064, 0x0401f84b, + 0x42001000, 0x40000000, 0x591c0203, 0x591c0804, + 0x8c040d3e, 0x04020023, 0x82000c80, 0x0000000e, + 0x0c001003, 0x0201f800, 0x00100615, 0x00107410, + 0x0010741c, 0x00107412, 0x0010741c, 0x00107418, + 0x00107410, 0x00107410, 0x0010741c, 0x0010741c, + 0x00107410, 0x00107410, 0x00107410, 0x00107410, + 0x00107410, 0x0010741c, 0x00107410, 0x0010741c, + 0x0201f800, 0x00100615, 0x591c0414, 0x4803c857, + 0x8c000518, 0x04000003, 0x8c000512, 0x04000003, + 0x80001580, 0x0401f003, 0x42001000, 0x20000000, + 0x591c0015, 0x4801a00a, 0x0401f018, 0x0401f81f, + 0x591e5808, 0x812e59c0, 0x02000800, 0x00100615, + 0x592c100f, 0x591c0011, 0x80080480, 0x4801a00a, + 0x591c0203, 0x591c0804, 0x8c040d3e, 0x04020007, + 0x82000d80, 0x00000002, 0x04000007, 0x82000d80, + 0x00000004, 0x04000004, 0x42001000, 0x40000000, + 0x0401f002, 0x80001580, 0x4809a00b, 0x42000800, + 0x00000006, 0x42001000, 0x0000dc00, 0x5c023800, + 0x5c025800, 0x0401f1fe, 0x4803c856, 0x0401fe03, + 0x4a01a006, 0x02000000, 0x59300c19, 0x4805a407, + 0x59300a19, 0x4805a207, 0x59a81010, 0x59300809, + 0x58041802, 0x820c1d00, 0x00ffffff, 0x5930081e, + 0x58040406, 0x82000580, 0x00000003, 0x04020004, + 0x4809a008, 0x480da009, 0x0401f003, 0x480da008, + 0x4809a009, 0x1c01f000, 0x4803c856, 0x0401fdeb, + 0x0401f003, 0x4803c856, 0x0401fde1, 0x4a01a006, + 0x01000000, 0x5930041a, 0x4801a407, 0x5930021a, + 0x4801a207, 0x42000800, 0x00000002, 0x42001000, + 0x0000dc00, 0x0401f1d6, 0x4803c856, 0x4d1c0000, + 0x0401fdc5, 0x4a01a006, 0x14000000, 0x5932381e, + 0x591c0019, 0x4801a005, 0x59300419, 0x4801a407, + 0x59300219, 0x4801a207, 0x59300015, 0x4801a008, + 0x59300216, 0x82000500, 0x000000ff, 0x840001c0, + 0x4801a409, 0x42000800, 0x00000004, 0x42001000, + 0x0000dc00, 0x5c023800, 0x0401f1bd, 0x4803c856, + 0x0401f80b, 0x5930041a, 0x900001c0, 0x4801a005, + 0x0401f9f4, 0x41780800, 0x42001000, 0x00005c00, + 0x0401f9b3, 0x0201f000, 0x00105d86, 0x4803c856, + 0x59300817, 0x82041c00, 0x00000005, 0x46034800, + 0x00000021, 0x58040404, 0x82000500, 0x0000f000, + 0x82000580, 0x00003000, 0x04000003, 0x46034800, + 0x00000041, 0x81a5a000, 0x580c0001, 0x82000d00, + 0x00ffffff, 0x82040d40, 0xc2000000, 0x4805a000, + 0x580c0800, 0x82041500, 0x00ffffff, 0x82000500, + 0xff000000, 0x80080540, 0x4801a001, 0x580c0002, + 0x82000580, 0x00c00000, 0x82000500, 0x00fd0300, + 0x4801a002, 0x580c0003, 0x4801a003, 0x580c0404, + 0x4801a404, 0x580c0204, 0x4801a204, 0x1c01f000, + 0x4803c856, 0x59a80026, 0x82000500, 0x00000028, + 0x04020009, 0x59a80026, 0x82000500, 0x00000028, + 0x04000003, 0x497a6a12, 0x0401f003, 0x4a026a12, + 0x0000ff00, 0x42005000, 0x22000000, 0x42006000, + 0x01380000, 0x41786800, 0x41787800, 0x0401f952, + 0x59301008, 0x4a01a006, 0x54000000, 0x59a80010, + 0x82000500, 0x00ffffff, 0x58080c0a, 0x800408f0, + 0x80040540, 0x4801a007, 0x5808000a, 0x82000500, + 0xff000000, 0x4801a008, 0x59a80002, 0x4801a009, + 0x59a80003, 0x4801a00a, 0x59a80000, 0x4801a00b, + 0x59a80001, 0x4801a00c, 0x5808000c, 0x9c0001c0, + 0x4801a00d, 0x5808000d, 0x9c0001c0, 0x4801a00e, + 0x5808000e, 0x9c0001c0, 0x4801a00f, 0x5808000f, + 0x9c0001c0, 0x4801a010, 0x58080010, 0x9c0001c0, + 0x4801a011, 0x58080011, 0x9c0001c0, 0x4801a012, + 0x58080012, 0x9c0001c0, 0x4801a013, 0x58080013, + 0x9c0001c0, 0x4801a014, 0x58080010, 0x9c0001c0, + 0x4801a015, 0x58080011, 0x9c0001c0, 0x4801a016, + 0x58080012, 0x9c0001c0, 0x4801a017, 0x58080013, + 0x9c0001c0, 0x4801a018, 0x42000800, 0x00000013, + 0x42001000, 0x0000dc00, 0x0401f135, 0x4803c856, + 0x42005000, 0x22000000, 0x42006000, 0x01290000, + 0x41786800, 0x41787800, 0x0401f90b, 0x59301008, + 0x4a01a006, 0x55000000, 0x5808000b, 0x82000500, + 0x00ffffff, 0x58080c0a, 0x800408f0, 0x80040540, + 0x4801a007, 0x5808080a, 0x82040d00, 0xff000000, + 0x59a80010, 0x82000500, 0x00ffffff, 0x80040540, + 0x4801a008, 0x5808000c, 0x9c0001c0, 0x4801a009, + 0x5808000d, 0x9c0001c0, 0x4801a00a, 0x5808000e, + 0x9c0001c0, 0x4801a00b, 0x5808000f, 0x9c0001c0, + 0x4801a00c, 0x59a80002, 0x4801a00d, 0x59a80003, + 0x4801a00e, 0x59a80000, 0x4801a00f, 0x59a80001, + 0x4801a010, 0x58080010, 0x4801a011, 0x58080011, + 0x4801a012, 0x58080012, 0x4801a013, 0x58080013, + 0x4801a014, 0x4979a015, 0x4979a016, 0x4979a017, + 0x4979a018, 0x42000800, 0x00000013, 0x42001000, + 0x0000dc00, 0x0401f0f6, 0x0401fcfc, 0x5930001c, + 0x800001c0, 0x04000008, 0x4a01a006, 0x01000000, + 0x4a01a407, 0x00000003, 0x42000800, 0x00000002, + 0x0401f028, 0x4a01a006, 0x02000000, 0x41780800, + 0x836c0580, 0x00000004, 0x04020003, 0x84040d42, + 0x0401f00d, 0x0201f800, 0x00104e0d, 0x04020003, + 0x84040d4a, 0x0401f002, 0x84040d48, 0x59a80026, + 0x8c000506, 0x04020003, 0x8c00050a, 0x04000002, + 0x84040d46, 0x4805a207, 0x59c40085, 0x48031004, + 0x4c580000, 0x4c500000, 0x4c540000, 0x4200b000, + 0x00000006, 0x8388a400, 0x00000000, 0x82d0ac00, + 0x00000008, 0x0201f800, 0x0010a93e, 0x5c00a800, + 0x5c00a000, 0x5c00b000, 0x42000800, 0x00000008, + 0x42001000, 0x0000dc00, 0x0401f0c1, 0x0401fcb9, + 0x4a01a006, 0x56000000, 0x59340006, 0x4801a007, + 0x59340007, 0x4801a008, 0x42000800, 0x00000003, + 0x42001000, 0x0000dc00, 0x0401f0b5, 0x4803c856, + 0x0401fcba, 0x5930081c, 0x800409c0, 0x0400000e, + 0x82040580, 0x0000ffff, 0x04000004, 0x82040480, + 0x00000007, 0x04021008, 0x4a01a006, 0x01000000, + 0x4a01a407, 0x00000003, 0x42000800, 0x00000002, + 0x0401f012, 0x4a01a006, 0x0200001c, 0x4a01a007, + 0x00000001, 0x42001000, 0x0010b2ec, 0x50080000, + 0x9c0001c0, 0x4801a009, 0x59a80010, 0x4801a00a, + 0x59a80002, 0x59a80803, 0x4801a00b, 0x4805a00c, + 0x42000800, 0x00000007, 0x42001000, 0x0000dc00, + 0x0401f08f, 0x4d2c0000, 0x0401fc86, 0x59325808, + 0x592c0008, 0x82000500, 0x00ffffff, 0x4801a001, + 0x4a01a006, 0x51000000, 0x5c025800, 0x0201f000, + 0x001070bc, 0x4803c856, 0x59a80810, 0x82040d00, + 0x000000ff, 0x59325808, 0x59326809, 0x59a83026, + 0x8c18350a, 0x04020008, 0x8c00050e, 0x04020006, + 0x80001d80, 0x59a82010, 0x82102500, 0x000000ff, + 0x0401f001, 0x59300406, 0x4803c857, 0x82000d80, + 0x00000009, 0x04000006, 0x82000d80, 0x0000000a, + 0x0400002e, 0x0201f800, 0x00100615, 0x59300015, + 0x8c00051e, 0x04020020, 0x42005000, 0x04000000, + 0x42006000, 0x05000000, 0x592c040a, 0x82000500, + 0x00000030, 0x800000e0, 0x80306540, 0x5934000a, + 0x8c000508, 0x04000002, 0x84306546, 0x41786800, + 0x41787800, 0x0401f831, 0x59300c14, 0x80040000, + 0x48026414, 0x40040000, 0x800000d0, 0x82000540, + 0x00000020, 0x4801a403, 0x83180d40, 0x00000038, + 0x42001000, 0x0000c920, 0x0401f868, 0x0201f000, + 0x00105d8b, 0x59a80026, 0x82000500, 0x00000028, + 0x04000003, 0x497a6a12, 0x0401f7dc, 0x4a026a12, + 0x0000ff00, 0x0401f7d9, 0x42005000, 0x02000000, + 0x42006000, 0x20290000, 0x41786800, 0x41787800, + 0x0401f812, 0x83180d40, 0x00000038, 0x42001000, + 0x0000c9a0, 0x0401f851, 0x42000800, 0x000007d0, + 0x59300011, 0x82000500, 0xfff00000, 0x80000540, + 0x04000003, 0x42000800, 0x00001b58, 0x41781000, + 0x0201f000, 0x00105d8d, 0x4201a000, 0x00000000, + 0x0401f003, 0x4201a000, 0x00000011, 0x59340a12, + 0x82040d00, 0x0000ff00, 0x59a80010, 0x82000500, + 0x000000ff, 0x900001c0, 0x80040540, 0x80d00540, + 0x44034800, 0x81a5a000, 0x59340002, 0x82000500, + 0x00ffffff, 0x80280540, 0x4801a000, 0x59a80010, + 0x4801a001, 0x4831a002, 0x82340540, 0x00000000, + 0x4801a003, 0x59300402, 0x4801a404, 0x59300a02, + 0x4805a204, 0x8c30652e, 0x04000003, 0x4805a404, + 0x4801a204, 0x483da005, 0x1c01f000, 0x4807c857, + 0x4c040000, 0x0401f82a, 0x5c000800, 0x40040000, + 0x80081540, 0x800000c4, 0x82000540, 0x00002000, + 0x4803910a, 0x59b400f6, 0x82000500, 0x00000018, + 0x040207fd, 0x4a0368f0, 0x0010b342, 0x42001800, + 0x0010b343, 0x580c0000, 0x4803c857, 0x580c0002, + 0x4803c857, 0x580c0004, 0x4803c857, 0x4a0368f1, + 0x0010b349, 0x480b68f3, 0x4a0378e4, 0x00008000, + 0x0201f000, 0x00105d86, 0x4807c857, 0x480a2800, + 0x4c040000, 0x0401f80a, 0x5c000800, 0x59b400f6, + 0x8c00050a, 0x040207fe, 0x49a768f2, 0x480768f4, + 0x4a0378e4, 0x00008000, 0x1c01f000, 0x4a0378e4, + 0x0000c000, 0x59bc00e4, 0x8c000520, 0x0400000c, + 0x4a0378e4, 0x00008000, 0x42007000, 0x000003e8, + 0x59bc00e4, 0x8c000520, 0x040007f5, 0x80387040, + 0x02000800, 0x00100615, 0x0401f7fa, 0x1c01f000, + 0x82000500, 0xffff0000, 0x82000580, 0x01050000, + 0x0402000d, 0x599c0818, 0x8c040d10, 0x0400000a, + 0x59a80807, 0x8c040d0a, 0x04000007, 0x42001000, + 0x0000804f, 0x41781800, 0x41782000, 0x0201f800, + 0x00103857, 0x1c01f000, 0x41781000, 0x42026000, + 0x0010cfc0, 0x59a8180e, 0x480a6402, 0x4a026202, + 0x0000ffff, 0x80081000, 0x800c1840, 0x04000004, + 0x83326400, 0x00000024, 0x0401f7f8, 0x1c01f000, + 0x4933c857, 0x59300203, 0x82000580, 0x00000000, + 0x0400002c, 0x59300406, 0x4803c857, 0x82000d80, + 0x00000004, 0x04000011, 0x82000d80, 0x00000001, + 0x0400000e, 0x82000d80, 0x00000003, 0x04000006, + 0x82000d80, 0x00000006, 0x04020011, 0x0201f800, + 0x0010a3fa, 0x5930001c, 0x800001c0, 0x02020800, + 0x0010961a, 0x0401f00a, 0x5930081e, 0x4807c857, + 0x800409c0, 0x04000006, 0x5804001c, 0x4803c857, + 0x81300580, 0x04020002, 0x4978081c, 0x497a6008, + 0x4a026004, 0x00004000, 0x59a80037, 0x82000c80, + 0x00000051, 0x04001002, 0x80000102, 0x48026206, + 0x497a6205, 0x497a6009, 0x4a026406, 0x00000007, + 0x1c01f000, 0x8166c9c0, 0x0400001c, 0x41626000, + 0x41580000, 0x59300a03, 0x82040d80, 0x00000000, + 0x04000008, 0x83326400, 0x00000024, 0x81300c80, + 0x040017f9, 0x42026000, 0x0010cfc0, 0x0401f7f6, + 0x4933c857, 0x8166c840, 0x83300c00, 0x00000024, + 0x80040480, 0x04021006, 0x4006c000, 0x4a026203, + 0x00000008, 0x813261c0, 0x1c01f000, 0x4202c000, + 0x0010cfc0, 0x0401f7fa, 0x42000000, 0x0010b653, + 0x0201f800, 0x0010a86e, 0x4933c856, 0x417a6000, + 0x0401f7f5, 0x4933c857, 0x83380580, 0x00000013, + 0x0402000b, 0x59300004, 0x8c00053e, 0x04000007, + 0x0201f800, 0x0010698c, 0x0201f800, 0x001068f6, + 0x0201f800, 0x00106982, 0x1c01f000, 0x4933c857, + 0x59880053, 0x80000000, 0x48031053, 0x1c01f000, + 0x4933c857, 0x59300203, 0x82003480, 0x0000000e, + 0x02021800, 0x00100615, 0x4d2c0000, 0x0c01f803, + 0x5c025800, 0x1c01f000, 0x00107718, 0x00107c84, + 0x00107dd4, 0x00107718, 0x00107e3a, 0x0010787c, + 0x00107718, 0x00107718, 0x00107c1a, 0x00107718, + 0x00107718, 0x00107718, 0x00107718, 0x00107718, + 0x0201f800, 0x00100615, 0x4933c857, 0x59300203, + 0x82003480, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f001, 0x0010772f, 0x001087f0, 0x0010772f, + 0x0010772f, 0x0010772f, 0x0010772f, 0x0010772f, + 0x0010772f, 0x0010879a, 0x0010880c, 0x0010887a, + 0x0010880c, 0x0010887a, 0x0010772f, 0x0201f800, + 0x00100615, 0x0201f800, 0x00100615, 0x4933c857, + 0x4d2c0000, 0x59325808, 0x59300203, 0x82003480, + 0x0000000e, 0x02021800, 0x00100615, 0x0c01f803, + 0x5c025800, 0x1c01f000, 0x0010774c, 0x0010774c, + 0x0010774c, 0x00107768, 0x001077b4, 0x0010774c, + 0x0010774c, 0x0010774c, 0x0010774e, 0x0010774c, + 0x0010774c, 0x0010774c, 0x0010774c, 0x0010774c, + 0x0201f800, 0x00100615, 0x4933c857, 0x83380580, + 0x00000040, 0x02020800, 0x00100615, 0x4a026007, + 0x00082000, 0x4a026203, 0x00000003, 0x493a6403, + 0x4a025c08, 0x00000001, 0x592c000d, 0x48026011, + 0x497a6013, 0x592c0208, 0x800000c2, 0x800010c4, + 0x80081400, 0x480a6206, 0x0201f800, 0x00100f9c, + 0x42000800, 0x80000060, 0x0201f000, 0x00106466, + 0x4933c857, 0x83380480, 0x00000050, 0x02021800, + 0x00100615, 0x83380480, 0x00000049, 0x02001800, + 0x00100615, 0x0c01f001, 0x0010777b, 0x00107786, + 0x00107779, 0x00107779, 0x00107779, 0x00107779, + 0x00107791, 0x0201f800, 0x00100615, 0x4a026203, + 0x00000004, 0x4a025c08, 0x00000002, 0x592c0207, + 0x48025c09, 0x592c0209, 0x48025a07, 0x592c000c, + 0x4802580d, 0x1c01f000, 0x0201f800, 0x001068c1, + 0x0201f800, 0x00108df4, 0x04000005, 0x4a025a06, + 0x00000006, 0x0201f800, 0x00020381, 0x0201f000, + 0x000208b4, 0x0201f800, 0x001068c1, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42003000, 0x00000014, 0x41782800, 0x42002000, + 0x00000002, 0x4d400000, 0x4d440000, 0x59368c03, + 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, + 0x5c028800, 0x5c028000, 0x42000000, 0x0010b663, + 0x0201f800, 0x0010a86e, 0x0201f800, 0x00108df4, + 0x02000000, 0x000208b4, 0x4a025a06, 0x00000029, + 0x0201f800, 0x00020381, 0x0201f000, 0x000208b4, + 0x4933c857, 0x83380580, 0x00000048, 0x04000005, + 0x83380580, 0x00000053, 0x02020800, 0x00100615, + 0x592c0206, 0x82000580, 0x00000007, 0x04000009, + 0x59300011, 0x80000540, 0x04000006, 0x592c080c, + 0x80040480, 0x4802580c, 0x4a025a06, 0x00000015, + 0x592c0206, 0x80000540, 0x04020003, 0x4a025a06, + 0x00000000, 0x0201f800, 0x00020381, 0x0201f000, + 0x000208b4, 0x4933c857, 0x4d2c0000, 0x4c500000, + 0x4c540000, 0x4c580000, 0x0201f800, 0x0010082a, + 0x02000800, 0x00100615, 0x497a5a06, 0x59a8006e, + 0x82000500, 0x0000f000, 0x48025c07, 0x59a80816, + 0x82040c00, 0x00000018, 0x48065a07, 0x412c7800, + 0x4d2c0000, 0x41cca000, 0x42002800, 0x00000001, + 0x42001000, 0x0000002c, 0x82040480, 0x0000002d, + 0x04021006, 0x832cac00, 0x00000009, 0x0201f800, + 0x0010894a, 0x0401f02e, 0x40043000, 0x42000800, + 0x0000002c, 0x832cac00, 0x00000009, 0x0201f800, + 0x0010894a, 0x82183480, 0x0000002c, 0x0201f800, + 0x0010082a, 0x0400001a, 0x80142800, 0x4a025804, + 0x00000110, 0x492c7801, 0x82180c80, 0x0000003d, + 0x04021007, 0x40180800, 0x832cac00, 0x00000005, + 0x0201f800, 0x0010894a, 0x0401f015, 0x82081400, + 0x0000003c, 0x82183480, 0x0000003c, 0x42000800, + 0x0000003c, 0x412c7800, 0x832cac00, 0x00000005, + 0x0201f800, 0x0010894a, 0x0401f7e5, 0x5c025800, + 0x592c0206, 0x8400055e, 0x48025a06, 0x592c0407, + 0x80080540, 0x48025c07, 0x0401f002, 0x5c025800, + 0x813669c0, 0x04000003, 0x59343403, 0x0401f003, + 0x42003000, 0x0000ffff, 0x49325808, 0x481a5c06, + 0x82100580, 0x00000054, 0x04020002, 0x491e5813, + 0x841401c0, 0x80100540, 0x48025804, 0x592c0001, + 0x497a5801, 0x4c000000, 0x0201f800, 0x00020381, + 0x5c025800, 0x812e59c0, 0x040207f9, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000, + 0x4803c856, 0x4c5c0000, 0x4d2c0000, 0x4c500000, + 0x4c540000, 0x4c580000, 0x412cb800, 0x592c040b, + 0x8c000516, 0x04000003, 0x41cca000, 0x0401f003, + 0x83cca400, 0x00000006, 0x4008b000, 0x41781000, + 0x82580480, 0x00000012, 0x04001004, 0x4200b000, + 0x00000012, 0x40001000, 0x4c080000, 0x4d2c0000, + 0x0201f800, 0x0010082a, 0x04000023, 0x5c001800, + 0x492c1801, 0x485a5800, 0x832cac00, 0x00000002, + 0x0201f800, 0x0010a94f, 0x585c040b, 0x8c000500, + 0x0400000e, 0x832c1400, 0x00000002, 0x8c000516, + 0x04000003, 0x82081400, 0x00000006, 0x46001000, + 0x00000001, 0x80081000, 0x46001000, 0x00000900, + 0x84000500, 0x4800bc0b, 0x5c001000, 0x800811c0, + 0x040207da, 0x82000540, 0x00000001, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x5c025800, 0x5c00b800, + 0x1c01f000, 0x5c025800, 0x5c001000, 0x0401f7f8, + 0x4933c857, 0x83380d80, 0x00000015, 0x04020003, + 0x0201f000, 0x000208b4, 0x83380d80, 0x00000016, + 0x02020800, 0x00100615, 0x0201f000, 0x000208b4, + 0x4933c857, 0x4d2c0000, 0x4c500000, 0x4c540000, + 0x4c580000, 0x59325808, 0x83cca400, 0x00000006, + 0x59cc1806, 0x820c0580, 0x01000000, 0x04020004, + 0x4200b000, 0x00000002, 0x0401f00f, 0x4200b000, + 0x00000008, 0x832cac00, 0x00000005, 0x0201f800, + 0x0010a93e, 0x8c0c1d00, 0x0400000b, 0x4200b000, + 0x00000008, 0x592e5801, 0x812e59c0, 0x02000800, + 0x00100615, 0x832cac00, 0x00000005, 0x0201f800, + 0x0010a93e, 0x0401f816, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x4c500000, 0x4c540000, 0x4c580000, 0x83cca400, + 0x00000006, 0x5930a808, 0x8254ac00, 0x00000005, + 0x4200b000, 0x00000007, 0x0201f800, 0x0010a93e, + 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x4933c857, + 0x0201f800, 0x00108df4, 0x02000000, 0x000208b4, + 0x4d2c0000, 0x0201f800, 0x00109360, 0x0402000b, + 0x41780800, 0x4d400000, 0x42028000, 0x00000000, + 0x0201f800, 0x00109204, 0x5c028000, 0x5c025800, + 0x0201f000, 0x000208b4, 0x5931d821, 0x58ef400b, + 0x58ee580d, 0x4a025a04, 0x00000103, 0x58ec0009, + 0x0801f800, 0x5c025800, 0x0201f000, 0x000208b4, + 0x4933c857, 0x59cc1806, 0x820c0580, 0x02000000, + 0x04020014, 0x4a026802, 0x00fffffd, 0x5934000a, + 0x84000504, 0x4802680a, 0x59300808, 0x800409c0, + 0x02000000, 0x000208b4, 0x4a000a04, 0x00000103, + 0x480c0805, 0x5931d821, 0x58ef400b, 0x58ee580d, + 0x58ec0009, 0x0801f800, 0x0201f000, 0x000208b4, + 0x42000000, 0x0010b66b, 0x0201f800, 0x0010a86e, + 0x4c0c0000, 0x0401f804, 0x5c001800, 0x040207eb, + 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808, + 0x812e59c0, 0x04020009, 0x497a6206, 0x497a6205, + 0x4d380000, 0x42027000, 0x00000022, 0x0401fb77, + 0x5c027000, 0x80000580, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x4d2c0000, 0x4c500000, 0x4c540000, + 0x4c580000, 0x59325808, 0x592e5801, 0x832cac00, + 0x00000005, 0x83cca400, 0x00000006, 0x59a8086e, + 0x82040d00, 0x000003ff, 0x82041480, 0x0000000f, + 0x0400101b, 0x4200b000, 0x0000000f, 0x0201f800, + 0x0010a93e, 0x592e5801, 0x832cac00, 0x00000005, + 0x82080c80, 0x0000000f, 0x0400100d, 0x4200b000, + 0x0000000f, 0x0201f800, 0x0010a93e, 0x592e5801, + 0x832cac00, 0x00000005, 0x82041480, 0x0000000f, + 0x04001007, 0x42001000, 0x0000000f, 0x4008b000, + 0x0201f800, 0x0010a93e, 0x0401f004, 0x4004b000, + 0x0201f800, 0x0010a93e, 0x5931d821, 0x58ef400b, + 0x58ee580d, 0x4a025a04, 0x00000103, 0x592e5801, + 0x58ec0009, 0x0801f800, 0x0201f800, 0x000208b4, + 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800, + 0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000, + 0x4c540000, 0x4c580000, 0x59cc0006, 0x82000d80, + 0x01000000, 0x0400002c, 0x59cc0007, 0x9000b1c0, + 0x8258b500, 0x000000ff, 0x8058b104, 0x8258b400, + 0x00000002, 0x82580c80, 0x00000007, 0x04001003, + 0x4200b000, 0x00000006, 0x83cca400, 0x00000006, + 0x59301008, 0x800811c0, 0x02000800, 0x00100615, + 0x8208ac00, 0x00000005, 0x0201f800, 0x0010a93e, + 0x82000d00, 0xff000000, 0x800409c0, 0x04000019, + 0x8200b500, 0x000000ff, 0x8058b104, 0x82580c80, + 0x0000000e, 0x04001003, 0x4200b000, 0x0000000d, + 0x58081001, 0x800811c0, 0x02000800, 0x00100615, + 0x8208ac00, 0x00000005, 0x0201f800, 0x0010a93e, + 0x0401f008, 0x59301008, 0x800811c0, 0x02000800, + 0x00100615, 0x48001005, 0x59cc0007, 0x48001006, + 0x0401ff3b, 0x5c00b000, 0x5c00a800, 0x5c00a000, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x42000800, + 0x00000000, 0x59cc0006, 0x82000580, 0x02000000, + 0x04000003, 0x42000800, 0x00000001, 0x4d2c0000, + 0x59325808, 0x812e59c0, 0x02000800, 0x00100615, + 0x48065a06, 0x0201f800, 0x00020381, 0x5c025800, + 0x0201f000, 0x000208b4, 0x4933c857, 0x4d2c0000, + 0x4c500000, 0x4c540000, 0x4c580000, 0x4200b000, + 0x00000002, 0x59cc0806, 0x82040580, 0x01000000, + 0x04000004, 0x8204b500, 0x0000ffff, 0x8058b104, + 0x83cca400, 0x00000006, 0x59300008, 0x8200ac00, + 0x00000005, 0x0201f800, 0x0010a93e, 0x0401ff0c, + 0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800, + 0x1c01f000, 0x4933c857, 0x4803c857, 0x4807c857, + 0x480bc857, 0x480fc857, 0x4813c857, 0x481bc857, + 0x492fc857, 0x4d2c0000, 0x4c000000, 0x0201f800, + 0x00100819, 0x5c000000, 0x0400000f, 0x48025803, + 0x5c000000, 0x4802580a, 0x4c000000, 0x481a5801, + 0x48125809, 0x48065804, 0x480a5807, 0x480e5808, + 0x412c1000, 0x0201f800, 0x001008a1, 0x82000540, + 0x00000001, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x4d1c0000, 0x59cc0001, 0x82000500, 0x00ffffff, + 0x59341002, 0x82081500, 0x00ffffff, 0x80080580, + 0x0402001f, 0x497a6205, 0x4d380000, 0x42027000, + 0x00000035, 0x0201f800, 0x00109183, 0x5c027000, + 0x04020012, 0x591c001c, 0x800001c0, 0x0400000f, + 0x497a381c, 0x591c0414, 0x8c000502, 0x02000800, + 0x00100615, 0x84000502, 0x48023c14, 0x591c1406, + 0x82080580, 0x00000003, 0x04000006, 0x82080580, + 0x00000006, 0x04000005, 0x0401fc9e, 0x0401f004, + 0x0401f805, 0x0401f002, 0x0401f8c0, 0x5c023800, + 0x1c01f000, 0x4d2c0000, 0x591e5808, 0x4933c857, + 0x491fc857, 0x493bc857, 0x492fc857, 0x83380580, + 0x00000015, 0x040000b3, 0x83380580, 0x00000016, + 0x040200ae, 0x4d300000, 0x411e6000, 0x59cc0207, + 0x4803c857, 0x82000d00, 0x0000ff00, 0x82040580, + 0x00001700, 0x04000004, 0x82040580, 0x00000300, + 0x0402005b, 0x591c0203, 0x4803c857, 0x82000580, + 0x0000000d, 0x0400003f, 0x812e59c0, 0x0400009a, + 0x591c0202, 0x4803c857, 0x82000580, 0x0000ffff, + 0x0402007e, 0x592c020a, 0x4803c857, 0x82000500, + 0x00000003, 0x82000580, 0x00000002, 0x04020007, + 0x592c080f, 0x591c0011, 0x4803c857, 0x4807c857, + 0x80040580, 0x04020071, 0x591c0414, 0x4803c857, + 0x8c000500, 0x0402006d, 0x41780800, 0x591c1206, + 0x42000000, 0x0000000a, 0x0201f800, 0x001063ee, + 0x592c0406, 0x4803c857, 0x800001c0, 0x0400000c, + 0x80080c80, 0x04001004, 0x02020800, 0x00100615, + 0x80001040, 0x480a5c06, 0x800811c0, 0x04020004, + 0x0201f800, 0x00108b3c, 0x0401f06b, 0x0201f800, + 0x00108ee7, 0x591c0817, 0x591c0018, 0x48065808, + 0x48025809, 0x59300007, 0x8c000500, 0x02020800, + 0x00100ee4, 0x497a3808, 0x0201f800, 0x000201ee, + 0x0402004a, 0x411e6000, 0x0401fc3e, 0x0401f05a, + 0x0401fc6d, 0x04000013, 0x49366009, 0x4a026406, + 0x00000003, 0x492e6008, 0x591c0817, 0x591c1018, + 0x48066017, 0x480a6018, 0x4d380000, 0x591e7403, + 0x4d300000, 0x411e6000, 0x0401fc2e, 0x5c026000, + 0x0201f800, 0x000208d8, 0x5c027000, 0x0401f046, + 0x59a80039, 0x48023a05, 0x0401f043, 0x59cc0407, + 0x82000580, 0x0000000b, 0x04020025, 0x59340a00, + 0x84040d0e, 0x48066a00, 0x592c0a04, 0x82040d00, + 0x000000ff, 0x82040d80, 0x00000014, 0x04000003, + 0x4a02621d, 0x00000003, 0x59300007, 0x8c000500, + 0x02020800, 0x00100ee4, 0x4d400000, 0x42028000, + 0x00000003, 0x592c0a08, 0x0201f800, 0x00104bee, + 0x0201f800, 0x00020381, 0x5c028000, 0x497a6008, + 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, + 0x4a026406, 0x00000002, 0x42000800, 0x8000404b, + 0x0201f800, 0x00020855, 0x0401f01b, 0x59cc0207, + 0x82000580, 0x00002a00, 0x04020004, 0x59a80039, + 0x48023a05, 0x0401f014, 0x812e59c0, 0x02000800, + 0x00100615, 0x4a025a04, 0x00000103, 0x591c0007, + 0x8c000500, 0x02020800, 0x00100ee4, 0x591c0402, + 0x48025c06, 0x4a025a06, 0x00000003, 0x0201f800, + 0x00020381, 0x0201f800, 0x00107698, 0x0201f800, + 0x00104801, 0x5c026000, 0x0201f800, 0x000208b4, + 0x0401f002, 0x5c026000, 0x5c025800, 0x1c01f000, + 0x0401f819, 0x0401f7fd, 0x4933c857, 0x83380580, + 0x00000015, 0x04020004, 0x59a80039, 0x48023a05, + 0x0401f00d, 0x83380580, 0x00000016, 0x0402000d, + 0x4d300000, 0x411e6000, 0x0201f800, 0x0010a3fa, + 0x0201f800, 0x00020831, 0x0201f800, 0x000208b4, + 0x5c026000, 0x497a381c, 0x0201f800, 0x000208b4, + 0x1c01f000, 0x591c0414, 0x84000540, 0x48023c14, + 0x59cc100b, 0x4933c857, 0x491fc857, 0x492fc857, + 0x4803c857, 0x480bc857, 0x8c08153c, 0x04000006, + 0x59a80039, 0x48023a05, 0x497a381c, 0x0201f000, + 0x000208b4, 0x4d300000, 0x411e6000, 0x0201f800, + 0x0010898b, 0x5c026000, 0x591c0406, 0x82000580, + 0x00000000, 0x02000000, 0x000208b4, 0x591c0403, + 0x82000580, 0x00000050, 0x0402000d, 0x4d300000, + 0x411e6000, 0x4a026203, 0x00000001, 0x42000800, + 0x80000043, 0x0201f800, 0x00020855, 0x5c026000, + 0x497a381c, 0x0201f000, 0x000208b4, 0x591c0203, + 0x82000580, 0x0000000d, 0x04000014, 0x812e59c0, + 0x02000800, 0x00100615, 0x591c0203, 0x82000580, + 0x00000004, 0x04020011, 0x592c020a, 0x8c000502, + 0x0400000e, 0x4a023812, 0x0fffffff, 0x592c0208, + 0x8400051e, 0x48025a08, 0x42000000, 0x00000001, + 0x48023a14, 0x0401f021, 0x42000000, 0x00000007, + 0x48023a14, 0x0401f01d, 0x592c020a, 0x4803c857, + 0x8c000500, 0x0402000b, 0x8c000502, 0x040007f7, + 0x591c0414, 0x8c00051c, 0x040207eb, 0x591c0011, + 0x4803c857, 0x800001c0, 0x040007f0, 0x0401f7e6, + 0x8c08153a, 0x040207ed, 0x59cc000a, 0x592c180f, + 0x4803c857, 0x480fc857, 0x800c0580, 0x040007e7, + 0x59cc000a, 0x4803c857, 0x48023816, 0x42000000, + 0x00000005, 0x48023a14, 0x0201f000, 0x0010901b, + 0x4933c857, 0x4d1c0000, 0x59cc0001, 0x59341002, + 0x80080580, 0x82000500, 0x00ffffff, 0x04020041, + 0x59301419, 0x0201f800, 0x001091d9, 0x02000800, + 0x00100615, 0x591c1406, 0x82080580, 0x00000007, + 0x04000038, 0x82080580, 0x00000002, 0x04000035, + 0x82080580, 0x00000000, 0x04000032, 0x591c0202, + 0x82000d80, 0x0000ffff, 0x04000004, 0x59301a19, + 0x800c0580, 0x0402002b, 0x83380580, 0x00000015, + 0x04000026, 0x4d300000, 0x4d2c0000, 0x411e6000, + 0x59325808, 0x0201f800, 0x00108df4, 0x02000800, + 0x00100615, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000014, 0x04000003, 0x4a02621d, + 0x00000003, 0x42028000, 0x00000003, 0x592c0a08, + 0x0201f800, 0x00104bee, 0x0201f800, 0x00020381, + 0x5c025800, 0x497a6008, 0x4a026403, 0x00000085, + 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, + 0x42000800, 0x8000404b, 0x0201f800, 0x00020855, + 0x5c026000, 0x0401f003, 0x59a80039, 0x48023a05, + 0x497a381c, 0x0201f800, 0x000208b4, 0x5c023800, + 0x1c01f000, 0x4933c857, 0x4c580000, 0x4d2c0000, + 0x59325808, 0x83383580, 0x00000015, 0x04000010, + 0x59342200, 0x84102502, 0x48126a00, 0x0201f800, + 0x00108df4, 0x04000066, 0x0201f800, 0x00109360, + 0x04020005, 0x4200b000, 0x00000002, 0x0201f800, + 0x00109346, 0x0401fa0d, 0x0401f079, 0x83cc1400, + 0x00000008, 0x4200b000, 0x00000002, 0x83341c00, + 0x00000006, 0x0201f800, 0x001082ff, 0x04020015, + 0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, + 0x0402000c, 0x0201f800, 0x00101e1b, 0x59342200, + 0x59cc1007, 0x800811c0, 0x04000003, 0x480a6801, + 0x84102542, 0x8410251a, 0x48126a00, 0x0401f05f, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, + 0x0010a86e, 0x59340200, 0x84000558, 0x48026a00, + 0x4d300000, 0x0201f800, 0x00020892, 0x02000800, + 0x00100615, 0x49366009, 0x497a6008, 0x4a026406, + 0x00000001, 0x4a026403, 0x00000001, 0x42003000, + 0x00000003, 0x0201f800, 0x0010a766, 0x0201f800, + 0x0010393e, 0x04000011, 0x41782800, 0x42003000, + 0x00000001, 0x4d400000, 0x42028000, 0x00000029, + 0x0201f800, 0x0010a250, 0x5c028000, 0x4a026406, + 0x00000004, 0x4a026203, 0x00000007, 0x4a026420, + 0x00000001, 0x0401f009, 0x4a026203, 0x00000001, + 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, + 0x0201f800, 0x00106470, 0x5c026000, 0x0201f800, + 0x00108df4, 0x04000022, 0x0201f800, 0x00109360, + 0x04020022, 0x0401f9b1, 0x0401f01d, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, + 0x84000558, 0x48026a00, 0x42003000, 0x00000003, + 0x41782800, 0x42002000, 0x00000005, 0x4d400000, + 0x4d440000, 0x59368c03, 0x42028000, 0x00000029, + 0x0201f800, 0x0010962a, 0x5c028800, 0x5c028000, + 0x5c027800, 0x0201f800, 0x00101e1b, 0x0201f800, + 0x000208b4, 0x0401f002, 0x0401fca9, 0x5c025800, + 0x5c00b000, 0x1c01f000, 0x4933c857, 0x41380000, + 0x83383480, 0x00000056, 0x02021800, 0x00100615, + 0x0c01f001, 0x00107c7e, 0x00107c79, 0x00107c7e, + 0x00107c7e, 0x00107c7e, 0x00107c7e, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c7e, 0x00107c77, 0x00107c7e, 0x00107c7e, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c7e, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c7e, + 0x00107c7e, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, + 0x00107c77, 0x00107c7e, 0x00107c7e, 0x00107c77, + 0x00107c7e, 0x00107c7e, 0x00107c77, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c7e, 0x00107c77, + 0x00107c77, 0x00107c77, 0x00107c7e, 0x0201f800, + 0x00100615, 0x4a026203, 0x00000001, 0x493a6403, + 0x0201f000, 0x00106470, 0x4933c857, 0x4a026203, + 0x00000001, 0x493a6403, 0x0201f000, 0x00106470, + 0x59300403, 0x82003480, 0x00000056, 0x02021800, + 0x00100615, 0x83383580, 0x00000013, 0x04000096, + 0x83383580, 0x00000027, 0x0402004c, 0x4933c857, + 0x0201f800, 0x001068f6, 0x0201f800, 0x00108ef1, + 0x0400000b, 0x0201f800, 0x00108f05, 0x04000041, + 0x59300403, 0x82000d80, 0x00000022, 0x04020038, + 0x0401fc61, 0x0400003a, 0x0401f03a, 0x0201f800, + 0x00101e1b, 0x42000800, 0x00000007, 0x0201f800, + 0x001043c7, 0x0401f901, 0x4d440000, 0x59368c03, + 0x83440580, 0x000007fe, 0x04020008, 0x59a81026, + 0x84081540, 0x0201f800, 0x00104e0d, 0x04020002, + 0x8408154a, 0x480b5026, 0x42028000, 0x00000029, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x836c0580, 0x00000003, 0x0400000c, + 0x59326809, 0x59340008, 0x800001c0, 0x04020008, + 0x59368c03, 0x4933c857, 0x4937c857, 0x4947c857, + 0x0201f800, 0x00104451, 0x0401f00c, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x42003000, + 0x00000015, 0x41782800, 0x42002000, 0x00000003, + 0x0201f800, 0x0010962a, 0x5c028800, 0x0201f800, + 0x001090ec, 0x0201f000, 0x000208b4, 0x1c01f000, + 0x0401f8ce, 0x0401f7fa, 0x83380580, 0x00000014, + 0x0400000c, 0x4933c857, 0x0201f800, 0x00106cb4, + 0x02020000, 0x001076fb, 0x59300203, 0x82000580, + 0x00000002, 0x040000ef, 0x0201f800, 0x00100615, + 0x4933c857, 0x0201f800, 0x001068f6, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42003000, 0x00000016, 0x41782800, 0x4d400000, + 0x4d440000, 0x59368c03, 0x42002000, 0x00000009, + 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, + 0x5c028800, 0x5c028000, 0x42000000, 0x0010b663, + 0x0201f800, 0x0010a86e, 0x0201f800, 0x00108ef1, + 0x0402000c, 0x0201f800, 0x00101e1b, 0x0401f89f, + 0x59340c03, 0x82040580, 0x000007fe, 0x040207c8, + 0x59a80826, 0x84040d40, 0x48075026, 0x0401f7c4, + 0x0201f800, 0x00108f05, 0x04020003, 0x0401f893, + 0x0401f7bf, 0x59300403, 0x82000d80, 0x00000032, + 0x04020004, 0x0201f800, 0x001020b2, 0x0401f7b8, + 0x59300403, 0x82000d80, 0x00000022, 0x04000887, + 0x0401f7b3, 0x4933c857, 0x4803c857, 0x0c01f001, + 0x00107da0, 0x00107da0, 0x00107da0, 0x00107da0, + 0x00107da0, 0x00107da0, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d83, 0x00107da0, + 0x00107d7a, 0x00107da0, 0x00107da0, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107da0, 0x00107da0, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d7a, 0x00107d91, 0x00107da0, + 0x00107d7a, 0x00107d8a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107d8a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107da0, 0x00107d8d, 0x00107d7a, + 0x00107d7c, 0x00107da0, 0x00107d7a, 0x00107da0, + 0x00107da0, 0x00107d7a, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107da0, 0x00107d7a, 0x00107d7a, + 0x00107d7a, 0x00107da0, 0x0201f800, 0x00100615, + 0x4d2c0000, 0x59325808, 0x0201f800, 0x00020381, + 0x5c025800, 0x0201f000, 0x000208b4, 0x4a026203, + 0x00000005, 0x59a80039, 0x48026205, 0x59a80037, + 0x48026206, 0x1c01f000, 0x5930081e, 0x49780a05, + 0x0401f014, 0x0201f800, 0x001090ec, 0x0201f000, + 0x000208b4, 0x0201f800, 0x001020b2, 0x0201f800, + 0x0010698c, 0x04000005, 0x0201f800, 0x001068f6, + 0x0201f000, 0x000208b4, 0x0201f800, 0x001068f6, + 0x0201f800, 0x000208b4, 0x0201f000, 0x00106982, + 0x4933c857, 0x4a026203, 0x00000002, 0x59a80037, + 0x48026206, 0x1c01f000, 0x4933c857, 0x0201f800, + 0x00108df4, 0x0400002a, 0x4d2c0000, 0x0201f800, + 0x00109360, 0x0402000a, 0x4d400000, 0x42028000, + 0x00000031, 0x42000800, 0x00000004, 0x0201f800, + 0x00109204, 0x5c028000, 0x0401f01c, 0x59300c06, + 0x82040580, 0x00000010, 0x04000004, 0x82040580, + 0x00000011, 0x0402000a, 0x4a025a06, 0x00000031, + 0x4a02580d, 0x00000004, 0x4a02580e, 0x000000ff, + 0x0201f800, 0x00020381, 0x0401f00c, 0x592c0404, + 0x8c00051e, 0x04000009, 0x4a025a04, 0x00000103, + 0x4a025805, 0x01000000, 0x5931d821, 0x58ef400b, + 0x58ec0009, 0x0801f800, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x59340400, 0x82000500, 0x000000ff, + 0x82003480, 0x0000000c, 0x02021800, 0x00100615, + 0x59303403, 0x82180d80, 0x0000004d, 0x02000000, + 0x00109154, 0x82180d80, 0x00000033, 0x02000000, + 0x0010910f, 0x82180d80, 0x00000028, 0x02000000, + 0x00108f46, 0x82180d80, 0x00000029, 0x02000000, + 0x00108f5a, 0x82180d80, 0x0000001f, 0x02000000, + 0x001078af, 0x82180d80, 0x00000055, 0x02000000, + 0x00107888, 0x82180d80, 0x00000000, 0x0400058e, + 0x82180d80, 0x00000022, 0x02000000, 0x001078dc, + 0x82180d80, 0x00000035, 0x02000000, 0x001079d7, + 0x82180d80, 0x00000039, 0x04000536, 0x82180d80, + 0x0000003d, 0x02000000, 0x0010790c, 0x82180d80, + 0x00000044, 0x02000000, 0x00107949, 0x82180d80, + 0x00000049, 0x02000000, 0x0010799e, 0x82180d80, + 0x00000041, 0x02000000, 0x0010798a, 0x82180d80, + 0x00000043, 0x02000000, 0x001092a5, 0x82180d80, + 0x00000051, 0x02000000, 0x0010930b, 0x82180d80, + 0x00000004, 0x04020003, 0x42000000, 0x00000001, + 0x83380d80, 0x00000015, 0x04000006, 0x83380d80, + 0x00000016, 0x02020000, 0x001076fb, 0x0401f226, + 0x4d2c0000, 0x4d3c0000, 0x0c01f804, 0x5c027800, + 0x5c025800, 0x1c01f000, 0x00107e42, 0x00107e46, + 0x00107e42, 0x00107ebb, 0x00107e42, 0x00107fc7, + 0x00108060, 0x00107e42, 0x00107e42, 0x00108029, + 0x00107e42, 0x0010803b, 0x4933c857, 0x497a6007, + 0x59300808, 0x58040000, 0x4a000a04, 0x00000103, + 0x0201f000, 0x000208b4, 0x4933c857, 0x40000000, + 0x40000000, 0x1c01f000, 0x4933c857, 0x59a80016, + 0x82000580, 0x00000074, 0x0402005c, 0x0201f800, + 0x0010a0b1, 0x04020016, 0x0401f85c, 0x0201f800, + 0x00108df4, 0x0400000c, 0x0201f800, 0x00109360, + 0x04020009, 0x41780800, 0x4d400000, 0x42028000, + 0x00000000, 0x0201f800, 0x00109204, 0x5c028000, + 0x0401f003, 0x0201f800, 0x00101e1b, 0x0201f800, + 0x00104711, 0x0201f000, 0x000208b4, 0x0201f800, + 0x00108df4, 0x04000007, 0x0201f800, 0x00109360, + 0x04020004, 0x0401ff3d, 0x0201f000, 0x000208b4, + 0x417a7800, 0x0201f800, 0x00101de2, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, + 0x84000558, 0x48026a00, 0x42003000, 0x00000003, + 0x0201f800, 0x0010a766, 0x4d300000, 0x0201f800, + 0x00020892, 0x02000800, 0x00100615, 0x49366009, + 0x497a6008, 0x4a026406, 0x00000001, 0x4a026403, + 0x00000001, 0x0201f800, 0x0010393e, 0x04000011, + 0x4a026406, 0x00000004, 0x4a026203, 0x00000007, + 0x4a026420, 0x00000001, 0x42003000, 0x00000001, + 0x4d400000, 0x42028000, 0x00000029, 0x41782800, + 0x0201f800, 0x0010a250, 0x5c028000, 0x0401f009, + 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, + 0x4a026203, 0x00000001, 0x0201f800, 0x00106470, + 0x5c026000, 0x0401ff05, 0x0201f800, 0x00101e1b, + 0x0201f000, 0x000208b4, 0x0401ff00, 0x42000000, + 0x00000001, 0x0401f0de, 0x4933c857, 0x59340200, + 0x8c000500, 0x0400000d, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x001043bd, 0x5c027800, 0x0201f800, + 0x0010393e, 0x04000005, 0x42000800, 0x00000006, + 0x0201f800, 0x001043c7, 0x1c01f000, 0x4933c857, + 0x59a80816, 0x82040580, 0x00000074, 0x0400000e, + 0x4807c857, 0x82040580, 0x00000100, 0x040200b7, + 0x59cc0408, 0x4803c857, 0x8c000500, 0x040000b3, + 0x59341403, 0x82080580, 0x000007fe, 0x04000006, + 0x0401f0ae, 0x59341403, 0x82080580, 0x000007fe, + 0x0402001a, 0x59a80026, 0x8c000506, 0x04000015, + 0x59cc0000, 0x82000500, 0x000000ff, 0x59a80810, + 0x82040d00, 0x000000ff, 0x80040580, 0x0400000d, + 0x0201f800, 0x00101e1b, 0x0201f800, 0x000208b4, + 0x42000000, 0x0010b651, 0x0201f800, 0x0010a86e, + 0x4202d800, 0x00000001, 0x0201f000, 0x00103f37, + 0x0401fa9c, 0x0401f04c, 0x0201f800, 0x00104480, + 0x59341403, 0x82080580, 0x000007fc, 0x0402001f, + 0x4a026802, 0x00fffffc, 0x0201f800, 0x00108df4, + 0x04000012, 0x0201f800, 0x00109360, 0x0402000f, + 0x0401f8a9, 0x41780800, 0x4d400000, 0x42028000, + 0x00000000, 0x0201f800, 0x00109204, 0x5c028000, + 0x42000800, 0x00000004, 0x0201f800, 0x001043c7, + 0x0201f000, 0x000208b4, 0x42000800, 0x00000004, + 0x0201f800, 0x001043c7, 0x0201f800, 0x00101e1b, + 0x0201f000, 0x000208b4, 0x59a8006f, 0x8c000502, + 0x04000011, 0x0201f800, 0x00104e0d, 0x42001000, + 0x00000010, 0x04020009, 0x59340002, 0x82000500, + 0x00ff0000, 0x82000580, 0x00ff0000, 0x04000006, + 0x42001000, 0x00000008, 0x0201f800, 0x00104ada, + 0x0402005a, 0x0201f800, 0x00108df4, 0x0400005b, + 0x0201f800, 0x00109360, 0x04020005, 0x592c0404, + 0x8c00051c, 0x040207c9, 0x0401f877, 0x42000800, + 0x00000005, 0x0201f800, 0x001043c7, 0x4a026203, + 0x00000001, 0x4a026403, 0x00000003, 0x0201f000, + 0x00106470, 0x59cc0408, 0x8c000518, 0x04000010, + 0x0201f800, 0x001090ab, 0x0201f800, 0x00104e0d, + 0x04000004, 0x59cc0408, 0x8c000516, 0x040207b3, + 0x59a80026, 0x8400054a, 0x48035026, 0x59a80010, + 0x84000570, 0x48038832, 0x0401f7ac, 0x42001000, + 0x000000ef, 0x480b5010, 0x497b8830, 0x84081570, + 0x480b8832, 0x59c40802, 0x84040d4c, 0x48078802, + 0x0201f800, 0x001090d5, 0x59a80026, 0x84000548, + 0x48035026, 0x0201f800, 0x0010a1ec, 0x0402079b, + 0x59a80026, 0x8400054c, 0x48035026, 0x42000800, + 0x00000006, 0x0201f800, 0x001043c7, 0x417a7800, + 0x0201f800, 0x001043bd, 0x42000000, 0x000000e8, + 0x0201f800, 0x001059b9, 0x02000800, 0x001043fc, + 0x02020800, 0x00100615, 0x49366009, 0x59340200, + 0x8400051a, 0x48026a00, 0x42000800, 0x00000003, + 0x0201f800, 0x001043c7, 0x4a026406, 0x00000001, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000002, + 0x0201f000, 0x00106470, 0x0401fe2c, 0x42000000, + 0x00000001, 0x0401f00a, 0x599c0017, 0x8c00050a, + 0x040007ab, 0x42000800, 0x00000004, 0x0201f800, + 0x001043c7, 0x0201f000, 0x000208b4, 0x4933c857, + 0x80003540, 0x04000005, 0x42000800, 0x00000007, + 0x0201f800, 0x001043c7, 0x801831c0, 0x0402000e, + 0x59302008, 0x801021c0, 0x04000004, 0x58100404, + 0x8c00051e, 0x04020008, 0x59341c03, 0x42002000, + 0x00000004, 0x42003000, 0x00000012, 0x0201f800, + 0x001038c7, 0x0201f800, 0x00101e1b, 0x0201f000, + 0x000208b4, 0x4c5c0000, 0x4d2c0000, 0x59325808, + 0x0201f800, 0x00105439, 0x5c025800, 0x59cc0008, + 0x48002805, 0x59cc0009, 0x48002806, 0x49782807, + 0x49782808, 0x49782809, 0x4978280a, 0x59cc0013, + 0x8c00053e, 0x04000009, 0x59cc0414, 0x900001c0, + 0x59ccbc15, 0x805c0540, 0x48002807, 0x59cc0416, + 0x900001c0, 0x48002808, 0x59cc0017, 0x8c00053e, + 0x04000009, 0x59cc0418, 0x900001c0, 0x59ccbc19, + 0x805c0540, 0x48002809, 0x59cc041a, 0x900001c0, + 0x4800280a, 0x5c00b800, 0x1c01f000, 0x4933c857, + 0x59a80016, 0x82000580, 0x00000014, 0x04020048, + 0x59a8006f, 0x8c000502, 0x04000015, 0x0201f800, + 0x00104e0d, 0x42001000, 0x00000010, 0x04020009, + 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, + 0x00ff0000, 0x0400000a, 0x42001000, 0x00000008, + 0x0201f800, 0x00104ada, 0x04000005, 0x59a8006f, + 0x8400054c, 0x4803506f, 0x0401f031, 0x836c0580, + 0x00000003, 0x0402000b, 0x59300008, 0x80000540, + 0x04020008, 0x59341c03, 0x42002000, 0x00000006, + 0x42003000, 0x00000013, 0x0201f800, 0x001038c7, + 0x0201f800, 0x001044e1, 0x0401feb8, 0x0401fa1d, + 0x0402001f, 0x59340404, 0x80000540, 0x0400001c, + 0x42000800, 0x00000006, 0x0201f800, 0x001043c7, + 0x0201f800, 0x00108df4, 0x04000011, 0x0201f800, + 0x00109360, 0x0402000a, 0x41780800, 0x4d400000, + 0x42028000, 0x00000000, 0x0201f800, 0x00109204, + 0x5c028000, 0x0201f000, 0x000208b4, 0x4a025a04, + 0x00000103, 0x4a025805, 0x02000000, 0x0201f800, + 0x00101e1b, 0x0201f000, 0x000208b4, 0x0201f800, + 0x00104a83, 0x0201f800, 0x00108df4, 0x04000007, + 0x0201f800, 0x00109360, 0x04020004, 0x0401fd8b, + 0x0201f000, 0x000208b4, 0x0401fd88, 0x80000580, + 0x59a8006f, 0x8c00050c, 0x04000005, 0x8400050c, + 0x4803506f, 0x82000540, 0x00000001, 0x0401ff60, + 0x1c01f000, 0x4933c857, 0x59a80016, 0x82000580, + 0x00000014, 0x0402000b, 0x42000800, 0x0000000b, + 0x0201f800, 0x001043c7, 0x4a026203, 0x00000001, + 0x4a026403, 0x00000001, 0x0201f000, 0x00106470, + 0x42000000, 0x00000001, 0x0401f74d, 0x4933c857, + 0x40003000, 0x59a80016, 0x82000580, 0x00000004, + 0x0402000a, 0x82183580, 0x0000000b, 0x04020005, + 0x42000800, 0x00000007, 0x0201f800, 0x001043c7, + 0x0201f000, 0x000208b4, 0x42000000, 0x00000001, + 0x0401f73b, 0x4803c857, 0x4d2c0000, 0x4d3c0000, + 0x0c01f804, 0x5c027800, 0x5c025800, 0x1c01f000, + 0x00107e42, 0x0010806f, 0x00107e42, 0x001080c4, + 0x00107e42, 0x00108132, 0x00108060, 0x00107e42, + 0x00107e42, 0x00108152, 0x00107e42, 0x00108162, + 0x4933c857, 0x4d1c0000, 0x59301403, 0x82080580, + 0x00000003, 0x04000008, 0x82081580, 0x0000001e, + 0x04020003, 0x0201f800, 0x000208b4, 0x5c023800, + 0x1c01f000, 0x0401ff5a, 0x0401f7fd, 0x4933c857, + 0x0201f800, 0x00108df4, 0x0400000b, 0x0201f800, + 0x00109360, 0x04020008, 0x4200b000, 0x00000002, + 0x0201f800, 0x00109346, 0x0401fd2c, 0x0201f000, + 0x000208b4, 0x0401f8f5, 0x04020030, 0x417a7800, + 0x0201f800, 0x001043bd, 0x417a7800, 0x0201f800, + 0x00101de2, 0x42000000, 0x0010b663, 0x0201f800, + 0x0010a86e, 0x59340200, 0x84000558, 0x48026a00, + 0x4a026403, 0x00000002, 0x42003000, 0x00000003, + 0x0201f800, 0x0010a766, 0x0201f800, 0x0010393e, + 0x04000011, 0x4d400000, 0x41782800, 0x42003000, + 0x00000005, 0x42028000, 0x00000029, 0x0201f800, + 0x0010a250, 0x5c028000, 0x4a026203, 0x00000007, + 0x4a026406, 0x00000004, 0x4a026420, 0x00000001, + 0x1c01f000, 0x42000800, 0x00000003, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x0201f800, + 0x00106470, 0x0401f7f7, 0x59cc0407, 0x82000580, + 0x00000009, 0x0402000a, 0x59340412, 0x82000500, + 0x000000ff, 0x0400000c, 0x80000040, 0x48026c12, + 0x4a026206, 0x0000000a, 0x0401f7ea, 0x59cc0207, + 0x82000500, 0x0000ff00, 0x82000580, 0x00001900, + 0x040007c2, 0x0401fce5, 0x80000580, 0x0401f6c4, + 0x4933c857, 0x59a80032, 0x80000540, 0x04000015, + 0x59340403, 0x82000580, 0x000007fe, 0x04020011, + 0x59a80010, 0x80000000, 0x48035010, 0x417a7800, + 0x0201f800, 0x001043bd, 0x42000800, 0x00000003, + 0x0201f800, 0x001043c7, 0x4a026203, 0x00000001, + 0x4a026403, 0x00000002, 0x0201f000, 0x00106470, + 0x0201f800, 0x00108df4, 0x04000011, 0x0201f800, + 0x00109360, 0x0402000e, 0x4c580000, 0x4200b000, + 0x00000002, 0x0201f800, 0x00109346, 0x5c00b000, + 0x0401fcbe, 0x42000800, 0x00000007, 0x0201f800, + 0x001043c7, 0x0201f000, 0x000208b4, 0x0401fcb7, + 0x59cc3407, 0x82183500, 0x000000ff, 0x82180580, + 0x00000005, 0x0400001c, 0x82180580, 0x0000000b, + 0x04000016, 0x59cc0207, 0x82000500, 0x0000ff00, + 0x04020004, 0x82180580, 0x00000009, 0x04000012, + 0x82000580, 0x00001900, 0x0402000c, 0x82180580, + 0x00000009, 0x0400000c, 0x42000800, 0x00000004, + 0x0201f800, 0x001043c7, 0x0201f800, 0x00101e1b, + 0x0201f000, 0x000208b4, 0x42000000, 0x00000001, + 0x0401f677, 0x0201f800, 0x00108df4, 0x59325808, + 0x04000008, 0x592c0204, 0x82000580, 0x00000139, + 0x040007f6, 0x592c0404, 0x8c00051e, 0x040207f3, + 0x59340403, 0x82000580, 0x000007fe, 0x04020007, + 0x59a80026, 0x84000540, 0x48035026, 0x0201f800, + 0x00104059, 0x0401f7e9, 0x417a7800, 0x0201f800, + 0x00101de2, 0x42003000, 0x00000005, 0x0201f800, + 0x0010a766, 0x42000000, 0x0010b663, 0x0201f800, + 0x0010a86e, 0x0401f7dd, 0x4933c857, 0x0401f84d, + 0x0402000b, 0x42000800, 0x00000005, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000003, 0x0201f000, 0x00106470, 0x42000800, + 0x00000004, 0x0201f800, 0x001043c7, 0x0201f800, + 0x00109360, 0x0402000a, 0x4c580000, 0x4200b000, + 0x00000002, 0x0201f800, 0x00109346, 0x5c00b000, + 0x0401fc5a, 0x0201f000, 0x000208b4, 0x0401fc57, + 0x80000580, 0x0401f636, 0x4933c857, 0x0401f82d, + 0x0402000b, 0x42000800, 0x00000009, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000005, 0x0201f000, 0x00106470, 0x42000000, + 0x00000001, 0x0401f626, 0x4933c857, 0x0401f81d, + 0x0402000b, 0x42000800, 0x0000000b, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000001, 0x0201f000, 0x00106470, 0x42000000, + 0x00000001, 0x0401f616, 0x4933c857, 0x59cc0407, + 0x82000580, 0x00000003, 0x04020009, 0x59cc0207, + 0x82000500, 0x0000ff00, 0x82000d80, 0x00002a00, + 0x04000003, 0x82000d80, 0x00001e00, 0x1c01f000, + 0x4933c857, 0x82000540, 0x00000001, 0x1c01f000, + 0x4933c857, 0x4d400000, 0x4c580000, 0x59a80026, + 0x82000540, 0x00000003, 0x48035026, 0x0401f85c, + 0x04000038, 0x4d340000, 0x4d440000, 0x59a80026, + 0x84000552, 0x48035026, 0x0201f800, 0x0010393e, + 0x0400000c, 0x42028000, 0x0000002a, 0x42028800, + 0x0000ffff, 0x42003000, 0x00000002, 0x0201f800, + 0x0010a258, 0x59a80805, 0x84040d44, 0x48075005, + 0x42028000, 0x0000002a, 0x4d3c0000, 0x42027800, + 0x00000200, 0x0201f800, 0x00101d90, 0x5c027800, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x0201f800, 0x00101bf0, 0x4200b000, 0x00000010, + 0x42028800, 0x000007f0, 0x4d2c0000, 0x83440580, + 0x000007fe, 0x04000003, 0x0201f800, 0x00104451, + 0x81468800, 0x8058b040, 0x040207f9, 0x5c025800, + 0x59cc0408, 0x8c00051e, 0x04000004, 0x59a80026, + 0x84000512, 0x48035026, 0x5c028800, 0x5c026800, + 0x0201f800, 0x00104480, 0x4a026802, 0x00fffffe, + 0x59a80826, 0x84040d50, 0x59cc0013, 0x8c00053e, + 0x04000003, 0x8c000536, 0x04000004, 0x59cc0017, + 0x8c000536, 0x04020002, 0x84040d10, 0x48075026, + 0x59cc0800, 0x82040d00, 0x00ffffff, 0x48075010, + 0x80040110, 0x4803501d, 0x48038881, 0x0201f800, + 0x00104e0d, 0x04000007, 0x59cc0009, 0x48035035, + 0x59cc000a, 0x48035036, 0x0201f800, 0x001090ab, + 0x5c00b000, 0x5c028000, 0x1c01f000, 0x4933c857, + 0x4c580000, 0x59a80010, 0x82000500, 0x00ffff00, + 0x04000022, 0x59cc1000, 0x82081500, 0x00ffff00, + 0x80080580, 0x04000004, 0x42000000, 0x0010b639, + 0x0401f016, 0x83cc1400, 0x0000000b, 0x4200b000, + 0x00000002, 0x83341c00, 0x00000006, 0x0401f904, + 0x04000004, 0x42000000, 0x0010b63a, 0x0401f00b, + 0x83cc1400, 0x0000000d, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000008, 0x0401f8f9, 0x04000007, + 0x42000000, 0x0010b63b, 0x0201f800, 0x0010a86e, + 0x82000540, 0x00000001, 0x5c00b000, 0x1c01f000, + 0x4933c857, 0x59cc0206, 0x82000580, 0x00000014, + 0x04020016, 0x59cc0407, 0x82000580, 0x00000800, + 0x04020012, 0x59cc0207, 0x8c00051a, 0x0400000d, + 0x82000500, 0x00000f00, 0x82000580, 0x00000100, + 0x04020008, 0x59cc020a, 0x8c000508, 0x04020003, + 0x8c00050a, 0x04000003, 0x80000580, 0x1c01f000, + 0x82000540, 0x00000001, 0x1c01f000, 0x4933c857, + 0x4943c857, 0x493fc857, 0x4c5c0000, 0x4d300000, + 0x4d340000, 0x4d2c0000, 0x4d380000, 0x4130b800, + 0x42026000, 0x0010cfc0, 0x59a8000e, 0x81640480, + 0x040210c1, 0x8d3e7d12, 0x04000004, 0x405c0000, + 0x81300580, 0x040000b7, 0x59300406, 0x82000c80, + 0x00000012, 0x04021015, 0x59326809, 0x0c01f001, + 0x001082f4, 0x0010825f, 0x00108278, 0x00108283, + 0x00108258, 0x00108271, 0x001082ac, 0x001082f4, + 0x00108256, 0x001082c0, 0x001082cf, 0x00108256, + 0x00108256, 0x00108256, 0x00108256, 0x001082f4, + 0x001082e5, 0x001082dd, 0x0201f800, 0x00100615, + 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, + 0x59300420, 0x8c000500, 0x04020096, 0x59300403, + 0x82000580, 0x00000043, 0x04000092, 0x0201f800, + 0x00108ef1, 0x02000800, 0x00101e1b, 0x0201f800, + 0x00108f05, 0x02000800, 0x00107da6, 0x8d3e7d06, + 0x04000086, 0x0201f800, 0x0010909d, 0x04000085, + 0x0401f082, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, + 0x04000004, 0x59300420, 0x8c000500, 0x0402007d, + 0x59325808, 0x0201f800, 0x00108df4, 0x04000077, + 0x49425a06, 0x497a5c09, 0x0201f800, 0x00020381, + 0x0201f800, 0x00108ee7, 0x0401f070, 0x813669c0, + 0x02000800, 0x00100615, 0x8d3e7d06, 0x04000004, + 0x59340200, 0x8c00050e, 0x0402006a, 0x59300004, + 0x8400055c, 0x48026004, 0x59300203, 0x82000580, + 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, + 0x0201f800, 0x00108df4, 0x0400005c, 0x4a025a04, + 0x00000103, 0x59300402, 0x48025c06, 0x592c0408, + 0x8c000512, 0x04000006, 0x4d2c0000, 0x592e5809, + 0x0201f800, 0x00100843, 0x5c025800, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x00109365, 0x0201f800, + 0x00020381, 0x0201f800, 0x00108ee7, 0x0401f047, + 0x8c000518, 0x04000047, 0x59300203, 0x82000580, + 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, + 0x0201f800, 0x00108df4, 0x0400003c, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x0010a4ae, 0x0201f800, + 0x00109365, 0x0201f800, 0x00020381, 0x0401f033, + 0x0201f800, 0x0010600e, 0x04000032, 0x59300203, + 0x82000580, 0x00000004, 0x04020004, 0x0201f800, + 0x00100ee4, 0x0401f02b, 0x42027000, 0x00000047, + 0x0201f800, 0x000208d8, 0x0401f026, 0x59300203, + 0x82000580, 0x00000004, 0x02000800, 0x00100ee4, + 0x59325808, 0x0201f800, 0x00108df4, 0x0400001b, + 0x49425a06, 0x497a5c09, 0x0201f800, 0x00020381, + 0x0401f016, 0x833c0500, 0x00001800, 0x04000015, + 0x8d3e7d16, 0x04020013, 0x59325817, 0x0201f800, + 0x00100843, 0x59300203, 0x82000580, 0x00000004, + 0x02000800, 0x00100ee4, 0x59325808, 0x0201f800, + 0x00108df4, 0x04000005, 0x49425a06, 0x497a5c09, + 0x0201f800, 0x00020381, 0x0201f800, 0x00107698, + 0x83326400, 0x00000024, 0x41580000, 0x81300480, + 0x0400173e, 0x5c027000, 0x5c025800, 0x5c026800, + 0x5c026000, 0x5c00b800, 0x1c01f000, 0x5c000000, + 0x4c000000, 0x4803c857, 0x480bc857, 0x480fc857, + 0x485bc857, 0x50080800, 0x500c0000, 0x80042580, + 0x04020007, 0x80081000, 0x800c1800, 0x8058b040, + 0x040207f9, 0x80000580, 0x1c01f000, 0x4803c857, + 0x4807c857, 0x480bc857, 0x480fc857, 0x80040480, + 0x04001006, 0x42000000, 0x00000001, 0x82040d40, + 0x00000001, 0x1c01f000, 0x41780000, 0x0401f7fc, + 0x83380480, 0x00000053, 0x02021800, 0x00100615, + 0x83380480, 0x0000004b, 0x02001800, 0x00100615, + 0x0c01f001, 0x0010832f, 0x0010832f, 0x0010832f, + 0x0010832f, 0x0010832d, 0x0010832d, 0x0010832d, + 0x0010832f, 0x0201f800, 0x00100615, 0x493bc857, + 0x4a026203, 0x0000000d, 0x493a6403, 0x42000800, + 0x80000000, 0x0201f000, 0x00020855, 0x83380580, + 0x00000013, 0x04020008, 0x59300403, 0x82000580, + 0x00000050, 0x02020800, 0x00100615, 0x0201f000, + 0x000208b4, 0x4933c857, 0x83380580, 0x00000027, + 0x04020030, 0x4933c857, 0x0201f800, 0x001068f6, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, + 0x0010a86e, 0x4d2c0000, 0x59325808, 0x0201f800, + 0x00108df4, 0x492fc857, 0x0400000d, 0x4a025a04, + 0x00000103, 0x59300c02, 0x48065c06, 0x4a025a06, + 0x00000029, 0x497a5c09, 0x592c0c08, 0x84040d50, + 0x48065c08, 0x0201f800, 0x00020381, 0x5c025800, + 0x42003000, 0x00000015, 0x41782800, 0x42002000, + 0x00000003, 0x4d400000, 0x4d440000, 0x59368c03, + 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, + 0x5c028800, 0x5c028000, 0x0201f000, 0x000208b4, + 0x83380580, 0x00000014, 0x0402000d, 0x59300403, + 0x82000c80, 0x00000053, 0x02021800, 0x00100615, + 0x82000480, 0x00000040, 0x02001800, 0x00100615, + 0x4933c857, 0x4803c857, 0x0c01f00e, 0x83380580, + 0x00000053, 0x0400000a, 0x83380580, 0x00000048, + 0x02020800, 0x00100615, 0x59300403, 0x82000580, + 0x00000050, 0x02020800, 0x00100615, 0x1c01f000, + 0x001083a5, 0x001083a3, 0x001083a3, 0x001083a3, + 0x001083a3, 0x001083a3, 0x001083a3, 0x001083a3, + 0x001083a3, 0x001083a3, 0x001083a3, 0x001083bc, + 0x001083bc, 0x001083bc, 0x001083bc, 0x001083a3, + 0x001083bc, 0x001083a3, 0x001083bc, 0x0201f800, + 0x00100615, 0x4933c857, 0x0201f800, 0x001068f6, + 0x0201f800, 0x00108df4, 0x02000000, 0x000208b4, + 0x4d2c0000, 0x59325808, 0x4a025a04, 0x00000103, + 0x59300402, 0x48025c06, 0x4a025a06, 0x00000006, + 0x497a5c09, 0x0201f800, 0x00020381, 0x5c025800, + 0x0201f800, 0x00108ee7, 0x0201f000, 0x000208b4, + 0x4933c857, 0x0201f800, 0x001068f6, 0x0201f000, + 0x000208b4, 0x0201f800, 0x00100615, 0x5930001c, + 0x800001c0, 0x02020800, 0x0010961a, 0x59300004, + 0x8c00053e, 0x04020029, 0x59325808, 0x592c0c08, + 0x59cc2a08, 0x82141d00, 0x00000c00, 0x04000002, + 0x59cc1809, 0x84040d58, 0x48065c08, 0x82143500, + 0x00000fff, 0x04020027, 0x59340200, 0x8c00050e, + 0x04020080, 0x0201f800, 0x00020962, 0x04020006, + 0x4a025a06, 0x00000000, 0x59300811, 0x800409c0, + 0x04020951, 0x4a025a04, 0x00000103, 0x48065807, + 0x480e580a, 0x48165c09, 0x59300c02, 0x48065c06, + 0x0201f800, 0x00020381, 0x0201f800, 0x00104801, + 0x59cc0208, 0x8c000518, 0x02020000, 0x00108f88, + 0x0201f000, 0x000208b4, 0x0201f800, 0x00106cb4, + 0x040007d6, 0x4d3c0000, 0x42027800, 0x00000002, + 0x0201f800, 0x00108997, 0x5c027800, 0x0401f7cf, + 0x4817c857, 0x480fc857, 0x82180500, 0x000000ff, + 0x0400000e, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000048, 0x04020008, 0x592c0407, + 0x800001c0, 0x04000005, 0x0201f800, 0x0010950b, + 0x0201f000, 0x00109553, 0x82180d00, 0x00000c00, + 0x04000004, 0x59340200, 0x8c00050e, 0x04020032, + 0x4a025a06, 0x00000000, 0x41782000, 0x8c183510, + 0x04000007, 0x59cc000c, 0x82000500, 0x000000ff, + 0x04000002, 0x4803c857, 0x59cc200b, 0x4812580c, + 0x41780000, 0x8c183512, 0x04000002, 0x59cc000a, + 0x4802580b, 0x80100c00, 0x040007b8, 0x82041480, + 0x0000001d, 0x04001006, 0x592c0404, 0x8c00051e, + 0x0400000e, 0x42000800, 0x0000001c, 0x4c500000, + 0x4c540000, 0x83cca400, 0x0000000c, 0x832cac00, + 0x0000000d, 0x0201f800, 0x00108953, 0x5c00a800, + 0x5c00a000, 0x0401f7a5, 0x59300011, 0x59301402, + 0x480a5c06, 0x48025807, 0x480e580a, 0x48165c09, + 0x0201f800, 0x001088fc, 0x0201f800, 0x00108938, + 0x0401f7a6, 0x592c020a, 0x8c000502, 0x040007cd, + 0x592c0208, 0x8c00050e, 0x040207ca, 0x59300011, + 0x800c0d80, 0x040007c7, 0x4803c857, 0x480fc857, + 0x8c183514, 0x02000000, 0x00108fc6, 0x80000540, + 0x040007c0, 0x4807c856, 0x0201f000, 0x00108fc6, + 0x592c020a, 0x8c000502, 0x04000782, 0x59300011, + 0x800001c0, 0x0400077f, 0x592c0208, 0x8c00050e, + 0x0402077c, 0x0201f000, 0x00108fc6, 0x59cc2006, + 0x59cc2807, 0x0401f037, 0x0401f036, 0x1c01f000, + 0x4933c857, 0x5930001c, 0x800001c0, 0x02020800, + 0x0010961a, 0x59325808, 0x592c0c08, 0x41782800, + 0x41781800, 0x84040d58, 0x48065c08, 0x41783000, + 0x59340200, 0x8c00050e, 0x0402001a, 0x0201f800, + 0x00020962, 0x04020007, 0x4a025a06, 0x00000000, + 0x59300811, 0x4807c857, 0x800409c0, 0x040208b2, + 0x4a025a04, 0x00000103, 0x48065807, 0x480e580a, + 0x48165c09, 0x4933c857, 0x59300c02, 0x48065c06, + 0x0201f800, 0x00109365, 0x0201f800, 0x00020381, + 0x0201f800, 0x00104801, 0x0201f000, 0x000208b4, + 0x592c020a, 0x8c000502, 0x040007e8, 0x59300011, + 0x4803c857, 0x800001c0, 0x040007e4, 0x592c0208, + 0x8c00050e, 0x040207e1, 0x0201f000, 0x00108fc6, + 0x5930001c, 0x800001c0, 0x4c100000, 0x4c140000, + 0x02020800, 0x0010961a, 0x5c002800, 0x5c002000, + 0x4a026203, 0x00000002, 0x4a026403, 0x00000043, + 0x59325808, 0x592c020a, 0x8c000502, 0x0402001c, + 0x40100000, 0x592c080f, 0x80040c80, 0x40140000, + 0x80040480, 0x04001018, 0x59300004, 0x8c00053e, + 0x0402000a, 0x48126013, 0x48166011, 0x497a6205, + 0x0201f800, 0x00100fe1, 0x0402000d, 0x59300804, + 0x0201f000, 0x00106466, 0x4c100000, 0x4c140000, + 0x0201f800, 0x00106cb4, 0x5c002800, 0x5c002000, + 0x040007f1, 0x0201f000, 0x001076fb, 0x4933c857, + 0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7e7, + 0x83380480, 0x00000058, 0x04021005, 0x83380480, + 0x00000040, 0x04001002, 0x0c01f002, 0x1c01f000, + 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, + 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, + 0x001084ec, 0x001084ec, 0x001084ee, 0x001084ec, + 0x001084ec, 0x001084ec, 0x001084ec, 0x001084fb, + 0x001084ec, 0x001084ec, 0x001084ec, 0x001084ec, + 0x00108529, 0x001084ec, 0x001084ec, 0x001084ec, + 0x0201f800, 0x00100615, 0x4933c857, 0x0201f800, + 0x00106b13, 0x4a026203, 0x00000002, 0x59a80039, + 0x48026205, 0x59300011, 0x59300815, 0x80040c80, + 0x48066015, 0x0201f000, 0x001068c1, 0x4933c857, + 0x0201f800, 0x001068c1, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x00108df4, 0x04000010, 0x4d2c0000, 0x59325808, + 0x4a025a04, 0x00000103, 0x59300402, 0x48025c06, + 0x4a025a06, 0x00000029, 0x497a5c09, 0x592c0c08, + 0x84040d50, 0x48065c08, 0x0201f800, 0x00020381, + 0x5c025800, 0x42003000, 0x00000014, 0x41782800, + 0x4d400000, 0x4d440000, 0x59368c03, 0x42002000, + 0x00000002, 0x42028000, 0x00000029, 0x0201f800, + 0x0010962a, 0x5c028800, 0x5c028000, 0x0201f000, + 0x000208b4, 0x4933c857, 0x59300808, 0x49780c09, + 0x4978080a, 0x58041408, 0x84081558, 0x48080c08, + 0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020024, + 0x497a5a06, 0x5930001f, 0x80000540, 0x04000018, + 0x497a5a06, 0x4c040000, 0x4c080000, 0x4c0c0000, + 0x4c100000, 0x4c140000, 0x40002800, 0x58141003, + 0x40040000, 0x80081480, 0x48082803, 0x40140000, + 0x0201f800, 0x00100d9a, 0x5c002800, 0x5c002000, + 0x5c001800, 0x5c001000, 0x5c000800, 0x592c0206, + 0x80000540, 0x04020009, 0x0401f005, 0x592c0408, + 0x8c00051c, 0x04000002, 0x592c0803, 0x4807c857, + 0x4a025a06, 0x00000015, 0x1c01f000, 0x5930001f, + 0x80000540, 0x04000009, 0x4a025a06, 0x00000011, + 0x5930001f, 0x4c040000, 0x0201f800, 0x00100d9a, + 0x5c000800, 0x0401f7f5, 0x4807c856, 0x4a025a06, + 0x00000007, 0x1c01f000, 0x83380480, 0x00000058, + 0x04021007, 0x83380480, 0x00000040, 0x04001004, + 0x4d2c0000, 0x0c01f803, 0x5c025800, 0x1c01f000, + 0x00108588, 0x00108588, 0x00108588, 0x00108588, + 0x00108588, 0x0010858a, 0x00108588, 0x00108588, + 0x0010860d, 0x00108588, 0x00108588, 0x00108588, + 0x00108588, 0x00108588, 0x00108588, 0x00108588, + 0x00108588, 0x00108588, 0x00108588, 0x001086c5, + 0x001086ee, 0x001086cd, 0x00108588, 0x001086fa, + 0x0201f800, 0x00100615, 0x5930001c, 0x800001c0, + 0x02020800, 0x0010961a, 0x59300007, 0x8c00050e, + 0x0400007c, 0x8c000500, 0x0400006e, 0x8c00051c, + 0x04000009, 0x84000500, 0x48026007, 0x59325808, + 0x592c3c08, 0x841c3d58, 0x481e5c08, 0x0201f000, + 0x00020914, 0x59325808, 0x592c3c08, 0x841c3d58, + 0x59300007, 0x8c00051c, 0x040207f3, 0x481e5c08, + 0x42000000, 0x00000005, 0x40000000, 0x80000040, + 0x040207fe, 0x59300007, 0x8c00051c, 0x040207ea, + 0x59cc0a08, 0x592c0204, 0x82000500, 0x000000ff, + 0x82000580, 0x00000048, 0x0402000c, 0x497a580b, + 0x82040500, 0x000000ff, 0x04000008, 0x592c0407, + 0x800001c0, 0x04000005, 0x0201f800, 0x0010950b, + 0x0201f000, 0x00100ea1, 0x48065c09, 0x41782000, + 0x82040500, 0x00000c00, 0x04000002, 0x59cc2009, + 0x82043500, 0x00000fff, 0x04020027, 0x481e5c08, + 0x4a025a06, 0x00000000, 0x801831c0, 0x02000000, + 0x00100ea1, 0x41782000, 0x8c183510, 0x04000002, + 0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512, + 0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00, + 0x02001800, 0x00100615, 0x02000000, 0x00100ea1, + 0x82041480, 0x0000001d, 0x0402100c, 0x4c500000, + 0x4c540000, 0x83cca400, 0x0000000c, 0x832cac00, + 0x0000000d, 0x0401fb6e, 0x5c00a800, 0x5c00a000, + 0x0201f000, 0x00100ea1, 0x0401fb12, 0x0201f000, + 0x00100ea1, 0x412c7800, 0x0201f800, 0x0010082a, + 0x02000800, 0x00100615, 0x492c7809, 0x841c3d52, + 0x481c7c08, 0x4a025a04, 0x00000103, 0x4812580a, + 0x48065c09, 0x583c0404, 0x583c1005, 0x583c2208, + 0x48025c04, 0x480a5805, 0x48125a08, 0x0401f7c8, + 0x8c000524, 0x04000794, 0x59325808, 0x4c000000, + 0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003, + 0x4a026011, 0xffffffff, 0x84000524, 0x0401f78a, + 0x1c01f000, 0x59a80039, 0x48026205, 0x59325808, + 0x4a026203, 0x00000002, 0x592c2408, 0x59300807, + 0x4933c857, 0x4807c857, 0x592c0204, 0x82000500, + 0x000000ff, 0x82000580, 0x00000048, 0x04020004, + 0x8c102500, 0x02020000, 0x00109553, 0x4a025a06, + 0x00000000, 0x8c040d1e, 0x04000027, 0x41780800, + 0x497a5c09, 0x592c1c09, 0x59300011, 0x59341200, + 0x497a6205, 0x8c08150e, 0x0402006e, 0x4807c857, + 0x4806580a, 0x80000d40, 0x04020f03, 0x59300402, + 0x48025c06, 0x48065807, 0x4a025a04, 0x00000103, + 0x4c040000, 0x4c0c0000, 0x4c100000, 0x0201f800, + 0x00109365, 0x5c002000, 0x5c001800, 0x5c000800, + 0x8c102512, 0x0402001a, 0x4c0c0000, 0x0201f800, + 0x00020381, 0x0201f800, 0x00104801, 0x5c001800, + 0x8c0c1d18, 0x02000000, 0x000208b4, 0x0201f000, + 0x00108f88, 0x4813c857, 0x8c102518, 0x0400004b, + 0x41780800, 0x592c1c09, 0x820c0580, 0x00001000, + 0x040007d6, 0x8c102512, 0x040007d4, 0x592c7809, + 0x583c080a, 0x583c1c09, 0x0401f7d0, 0x4807c857, + 0x592c7809, 0x59300402, 0x592c1404, 0x8c08151e, + 0x0402000d, 0x592c1206, 0x48007c06, 0x48047807, + 0x48087a06, 0x84102512, 0x48107c08, 0x4c0c0000, + 0x0201f800, 0x00100843, 0x403e5800, 0x0401fad1, + 0x0401f7d9, 0x48025c06, 0x48065807, 0x583c080c, + 0x583c000b, 0x80040c00, 0x82041480, 0x0000001d, + 0x04001006, 0x583c1001, 0x480a5801, 0x49787801, + 0x42000800, 0x0000001c, 0x82040c00, 0x00000014, + 0x4c0c0000, 0x4c500000, 0x4c540000, 0x823ca400, + 0x00000008, 0x832cac00, 0x00000008, 0x4c100000, + 0x4c3c0000, 0x0401fad2, 0x5c007800, 0x5c002000, + 0x5c00a800, 0x5c00a000, 0x84102512, 0x48125c08, + 0x403e5800, 0x0201f800, 0x00100843, 0x42034000, + 0x0010b2a0, 0x59a1d81e, 0x80edd9c0, 0x02000800, + 0x00100615, 0x48efc857, 0x58ec0009, 0x4803c857, + 0x0801f800, 0x0401f7ac, 0x4933c857, 0x1c01f000, + 0x59301414, 0x480bc857, 0x8c08151c, 0x0402000e, + 0x80000540, 0x4803c857, 0x0400078d, 0x80042c80, + 0x0402178b, 0x8c081514, 0x04020005, 0x592c080f, + 0x4807c857, 0x80040480, 0x48026016, 0x8408155c, + 0x480a6414, 0x59301007, 0x8408151e, 0x480a6007, + 0x4c100000, 0x4c3c0000, 0x4d400000, 0x592e8206, + 0x4a025a06, 0x00000001, 0x0201f800, 0x00109365, + 0x49425a06, 0x5c028000, 0x5c007800, 0x5c002000, + 0x497a5c09, 0x8c102512, 0x04000006, 0x4d2c0000, + 0x403e5800, 0x0201f800, 0x00100843, 0x5c025800, + 0x82102500, 0xffffedff, 0x48125c08, 0x0201f000, + 0x00108fc6, 0x59325808, 0x592c0408, 0x8c000518, + 0x04000004, 0x412df800, 0x0201f000, 0x00100eba, + 0x1c01f000, 0x4933c857, 0x59325808, 0x497a5c09, + 0x4a025a06, 0x00000000, 0x4a025a04, 0x00000103, + 0x59300811, 0x4807c857, 0x800409c0, 0x0402000a, + 0x48065807, 0x59300c02, 0x48065c06, 0x0201f800, + 0x00020381, 0x0201f800, 0x00104801, 0x0201f000, + 0x000208b4, 0x59340200, 0x8c00050e, 0x04020005, + 0x59300811, 0x0401fe4c, 0x48065807, 0x0401f7f2, + 0x592c0208, 0x8c00050e, 0x040207fa, 0x4933c857, + 0x0201f000, 0x00108fc6, 0x4933c857, 0x59325808, + 0x812e59c0, 0x02000800, 0x00100615, 0x592c020a, + 0x8c000502, 0x02000800, 0x00100615, 0x4a026206, + 0x00000002, 0x1c01f000, 0x5930001c, 0x800001c0, + 0x02020800, 0x0010961a, 0x59300007, 0x4933c857, + 0x4803c857, 0x8c00050e, 0x04000037, 0x8c000500, + 0x04000029, 0x8c00051c, 0x0400000a, 0x84000500, + 0x48026007, 0x59325808, 0x592c3c08, 0x481fc857, + 0x841c3d58, 0x481e5c08, 0x0201f000, 0x00020914, + 0x59325808, 0x592c3c08, 0x841c3d58, 0x59300007, + 0x8c00051c, 0x040207f2, 0x481e5c08, 0x42000000, + 0x00000005, 0x40000000, 0x80000040, 0x040207fe, + 0x59300007, 0x8c00051c, 0x040207e9, 0x592c0204, + 0x82000500, 0x000000ff, 0x82000580, 0x00000048, + 0x04020003, 0x497a580b, 0x0401f002, 0x497a5c09, + 0x481e5c08, 0x4a025a06, 0x00000000, 0x0201f000, + 0x00100ea1, 0x8c000524, 0x040007d9, 0x59325808, + 0x4c000000, 0x592c0408, 0x8c00051c, 0x5c000000, + 0x04020003, 0x4a026011, 0xffffffff, 0x84000524, + 0x0401f7cf, 0x1c01f000, 0x4933c857, 0x41780800, + 0x83380480, 0x00000058, 0x0402100b, 0x83380480, + 0x00000040, 0x04001008, 0x4d2c0000, 0x59325808, + 0x812e59c0, 0x0c020806, 0x5c025800, 0x0201f000, + 0x000208b4, 0x493bc857, 0x1c01f000, 0x00108763, + 0x00108763, 0x00108763, 0x00108763, 0x00108763, + 0x00108765, 0x00108763, 0x00108763, 0x00108763, + 0x00108763, 0x00108763, 0x00108763, 0x00108763, + 0x00108763, 0x00108763, 0x00108763, 0x00108763, + 0x00108763, 0x00108763, 0x00108763, 0x0010876a, + 0x00108763, 0x00108763, 0x00108763, 0x0201f800, + 0x00100615, 0x59cc0a08, 0x497a5807, 0x4807c857, + 0x82040d00, 0x00000fff, 0x59300402, 0x48025c06, + 0x4a025a04, 0x00000103, 0x48065c09, 0x4a025a06, + 0x00000000, 0x800409c0, 0x02000000, 0x00020381, + 0x59cc0009, 0x4802580a, 0x82042500, 0x00000100, + 0x04000002, 0x59cc200b, 0x4812580c, 0x82040500, + 0x00000200, 0x04000002, 0x59cc000a, 0x4802580b, + 0x80100c00, 0x02001800, 0x00100615, 0x02000000, + 0x00020381, 0x82041480, 0x0000001d, 0x04001006, + 0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800, + 0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400, + 0x0000000c, 0x832cac00, 0x0000000d, 0x0401f9c0, + 0x5c00a800, 0x5c00a000, 0x0201f000, 0x00020381, + 0x0401f964, 0x0401f19f, 0x83380480, 0x00000093, + 0x02021800, 0x00100615, 0x83380480, 0x00000085, + 0x02001800, 0x00100615, 0x0c01f001, 0x001087b2, + 0x001087b0, 0x001087b0, 0x001087b9, 0x001087b0, + 0x001087b0, 0x001087b0, 0x001087b0, 0x001087b0, + 0x001087b0, 0x001087b0, 0x001087b0, 0x001087b0, + 0x0201f800, 0x00100615, 0x4a026203, 0x00000001, + 0x493a6403, 0x42000800, 0x80000040, 0x0201f000, + 0x00020855, 0x4933c857, 0x59cc1404, 0x0201f800, + 0x001091d9, 0x0400001b, 0x591c0203, 0x82000580, + 0x00000000, 0x04000017, 0x591c0009, 0x81340580, + 0x04020014, 0x4d300000, 0x4d1c0000, 0x411e6000, + 0x0401f9c3, 0x5c023800, 0x5c026000, 0x0400000b, + 0x59cc0005, 0x8c000500, 0x04020003, 0x0401f98d, + 0x0401f003, 0x4a023a03, 0x00000002, 0x4a026403, + 0x00000086, 0x0401f005, 0x0401f9a7, 0x040007f5, + 0x4a026403, 0x00000087, 0x4a026203, 0x00000001, + 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x59340200, 0x8c00050e, 0x0400000d, 0x59cc1404, + 0x0201f800, 0x001091d9, 0x04000009, 0x591c0414, + 0x8c00051a, 0x04000006, 0x4d300000, 0x411e6000, + 0x0201f800, 0x00108fdb, 0x5c026000, 0x1c01f000, + 0x83380580, 0x00000013, 0x0402000b, 0x59300403, + 0x4803c857, 0x82000d80, 0x00000086, 0x04000012, + 0x82000d80, 0x00000087, 0x02020800, 0x00100615, + 0x0401f00d, 0x83380580, 0x00000027, 0x04000005, + 0x83380580, 0x00000014, 0x02020800, 0x00100615, + 0x493bc857, 0x0201f800, 0x001068f6, 0x0201f000, + 0x00107698, 0x4933c857, 0x0201f000, 0x00107698, + 0x83380580, 0x00000013, 0x04020005, 0x59300403, + 0x82000480, 0x00000085, 0x0c01f04d, 0x83380580, + 0x00000027, 0x04020041, 0x4933c857, 0x0201f800, + 0x001068f6, 0x4d3c0000, 0x417a7800, 0x0201f800, + 0x00101de2, 0x5c027800, 0x42003000, 0x00000015, + 0x41782800, 0x42002000, 0x00000003, 0x42028000, + 0x00000029, 0x4d400000, 0x4d440000, 0x59368c03, + 0x0201f800, 0x0010962a, 0x5c028800, 0x5c028000, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x0201f800, 0x00108df4, 0x0400000c, 0x4d2c0000, + 0x59325808, 0x4a025a04, 0x00000103, 0x59300402, + 0x48025c06, 0x497a5c09, 0x49425a06, 0x0201f800, + 0x00020381, 0x5c025800, 0x0201f800, 0x00108ee7, + 0x0201f000, 0x000208b4, 0x83380580, 0x00000089, + 0x04000005, 0x83380580, 0x0000008a, 0x02020000, + 0x001076fb, 0x0201f800, 0x00106cb4, 0x02020000, + 0x001076fb, 0x59300a03, 0x82040580, 0x0000000a, + 0x0400002a, 0x82040580, 0x0000000c, 0x04000027, + 0x0201f800, 0x00100615, 0x83380580, 0x00000014, + 0x040207ea, 0x4933c857, 0x0201f800, 0x001068f6, + 0x42028000, 0x00000006, 0x0401f7d2, 0x0010886e, + 0x0010886c, 0x0010886c, 0x0010886c, 0x0010886c, + 0x0010886c, 0x00108874, 0x0010886c, 0x0010886c, + 0x0010886c, 0x0010886c, 0x0010886c, 0x0010886c, + 0x0201f800, 0x00100615, 0x4933c857, 0x59a80037, + 0x48026206, 0x4a026203, 0x0000000a, 0x1c01f000, + 0x4933c857, 0x59a80037, 0x48026206, 0x4a026203, + 0x0000000c, 0x1c01f000, 0x83380580, 0x00000089, + 0x04000008, 0x83380580, 0x0000008a, 0x04000032, + 0x4933c857, 0x493bc857, 0x0201f000, 0x001076fb, + 0x4933c857, 0x59325808, 0x59300a1d, 0x82040580, + 0x00000003, 0x04020004, 0x0201f800, 0x00104801, + 0x0401f00c, 0x5930021d, 0x82000580, 0x00000001, + 0x04020008, 0x59300c16, 0x82040580, 0x00000039, + 0x0400002c, 0x82040580, 0x00000035, 0x04000029, + 0x4c5c0000, 0x4130b800, 0x0201f800, 0x00020892, + 0x04000010, 0x4a026203, 0x00000001, 0x4a026403, + 0x0000001e, 0x59cc0c07, 0x48066419, 0x59cc0a07, + 0x48066219, 0x49366009, 0x4a026406, 0x00000001, + 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x405e6000, 0x0201f800, 0x000208b4, 0x5c00b800, + 0x1c01f000, 0x4933c857, 0x5930021d, 0x82000580, + 0x00000001, 0x04020040, 0x59300c16, 0x82040580, + 0x00000035, 0x04000007, 0x82040580, 0x0000001e, + 0x04000004, 0x82040580, 0x00000039, 0x04020036, + 0x4933c857, 0x4c500000, 0x4d1c0000, 0x4130a000, + 0x40067000, 0x0201f800, 0x00109183, 0x04020029, + 0x0201f800, 0x00020892, 0x04000026, 0x491fc857, + 0x4933c857, 0x83380580, 0x00000035, 0x04000004, + 0x83380580, 0x00000039, 0x04020002, 0x4932381c, + 0x493a6403, 0x4a026203, 0x00000001, 0x4a026406, + 0x00000001, 0x58500809, 0x4807c857, 0x48066009, + 0x58500c15, 0x4807c857, 0x48066415, 0x58500a15, + 0x4807c857, 0x48066215, 0x58500a16, 0x4807c857, + 0x48066216, 0x58500c19, 0x4807c857, 0x48066419, + 0x58500a19, 0x4807c857, 0x48066219, 0x491e601e, + 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x40526000, 0x5c023800, 0x5c00a000, 0x0201f000, + 0x000208b4, 0x5930021d, 0x82000580, 0x00000003, + 0x02000800, 0x00104801, 0x0201f000, 0x000208b4, + 0x4803c856, 0x4c500000, 0x4c540000, 0x412c7800, + 0x4c3c0000, 0x42002800, 0x00000001, 0x82040480, + 0x00000101, 0x04001003, 0x42000800, 0x00000100, + 0x40043000, 0x42000800, 0x0000001c, 0x83cca400, + 0x0000000c, 0x832cac00, 0x0000000d, 0x0401f844, + 0x82183480, 0x0000001c, 0x592e5801, 0x812e59c0, + 0x02020800, 0x00100843, 0x0201f800, 0x0010082a, + 0x04000017, 0x80142800, 0x4a025a04, 0x00000110, + 0x497a5c04, 0x492c7801, 0x82180c80, 0x0000003d, + 0x04021006, 0x40180800, 0x832cac00, 0x00000005, + 0x0401f82f, 0x0401f00a, 0x82183480, 0x0000003c, + 0x42000800, 0x0000003c, 0x412c7800, 0x832cac00, + 0x00000005, 0x0401f826, 0x0401f7e8, 0x5c007800, + 0x841429c0, 0x82142d40, 0x00000003, 0x48147a04, + 0x403e5800, 0x5c00a800, 0x5c00a000, 0x1c01f000, + 0x492fc857, 0x812e59c0, 0x0400000f, 0x4d2c0000, + 0x4c3c0000, 0x592c7801, 0x803c79c0, 0x04000006, + 0x497a5801, 0x0201f800, 0x00020381, 0x403e5800, + 0x0401f7f9, 0x5c007800, 0x0201f800, 0x00020381, + 0x5c025800, 0x1c01f000, 0x4803c856, 0x4c580000, + 0x82040c00, 0x00000003, 0x8004b104, 0x0201f800, + 0x0010a93e, 0x5c00b000, 0x1c01f000, 0x4803c856, + 0x4c580000, 0x82040c00, 0x00000003, 0x8004b104, + 0x0201f800, 0x0010a93e, 0x5c00b000, 0x1c01f000, + 0x591c0c06, 0x82040580, 0x00000003, 0x04000004, + 0x82040580, 0x00000002, 0x0402001a, 0x4d300000, + 0x4d2c0000, 0x411e6000, 0x59325808, 0x0201f800, + 0x00108df4, 0x0400000f, 0x4d400000, 0x42028000, + 0x00000013, 0x592c0a08, 0x84040d54, 0x0201f800, + 0x00104bee, 0x5c028000, 0x0201f800, 0x00109365, + 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, + 0x0201f800, 0x00107698, 0x5c025800, 0x5c026000, + 0x1c01f000, 0x59cc0005, 0x8c000500, 0x0402000b, + 0x591c0406, 0x82000580, 0x00000002, 0x04020007, + 0x591c0c03, 0x82040580, 0x00000085, 0x04000003, + 0x82040580, 0x0000008b, 0x1c01f000, 0x4933c857, + 0x4d3c0000, 0x42027800, 0x00000002, 0x59300406, + 0x82000c80, 0x00000012, 0x02021800, 0x00100615, + 0x0c01f80a, 0x5c027800, 0x1c01f000, 0x4933c857, + 0x59300406, 0x82000c80, 0x00000012, 0x02021800, + 0x00100615, 0x0c01f001, 0x001089b5, 0x001089b2, + 0x001089b2, 0x001089dd, 0x001089b0, 0x001089b2, + 0x001089ce, 0x001089b2, 0x001089b0, 0x0010632c, + 0x001089b2, 0x001089b2, 0x001089b2, 0x001089b0, + 0x001089b0, 0x001089b0, 0x00108aad, 0x001089b2, + 0x0201f800, 0x00100615, 0x4803c856, 0x80000580, + 0x1c01f000, 0x4803c856, 0x8d3e7d02, 0x04020016, + 0x0201f800, 0x00108df4, 0x0400000f, 0x59325808, + 0x41780800, 0x4d400000, 0x42028000, 0x00000005, + 0x0201f800, 0x00104bee, 0x5c028000, 0x0201f800, + 0x00109365, 0x0201f800, 0x00108f83, 0x0201f800, + 0x00020381, 0x0201f800, 0x00107698, 0x82000540, + 0x00000001, 0x1c01f000, 0x4933c857, 0x0201f800, + 0x00104728, 0x0402000c, 0x4d400000, 0x42028000, + 0x00000010, 0x0201f800, 0x00109fc0, 0x4a026406, + 0x00000006, 0x4a026203, 0x00000007, 0x5c028000, + 0x1c01f000, 0x4933c857, 0x0201f800, 0x0010698c, + 0x4df00000, 0x0401f8b8, 0x82000c80, 0x0000000e, + 0x02021800, 0x00100615, 0x0c01f001, 0x001089f7, + 0x00108a64, 0x00108a0e, 0x00108a77, 0x00108a5f, + 0x001089f5, 0x001089f7, 0x001089f7, 0x001089fb, + 0x001089f7, 0x001089f7, 0x001089f7, 0x001089f7, + 0x00108a0e, 0x0201f800, 0x00100615, 0x5c03e000, + 0x02000800, 0x00106982, 0x0401f7b8, 0x5c03e000, + 0x02000800, 0x00106982, 0x59300406, 0x82000580, + 0x00000003, 0x040207b4, 0x59300203, 0x82000580, + 0x0000000d, 0x040007b0, 0x8d3e7d02, 0x040207ae, + 0x4d340000, 0x59326809, 0x0201f800, 0x00104801, + 0x5c026800, 0x0401f7a8, 0x59300004, 0x8400055c, + 0x48026004, 0x0201f800, 0x00106982, 0x59300406, + 0x82000580, 0x00000006, 0x04000043, 0x8d3e7d02, + 0x04020041, 0x497a621d, 0x59300203, 0x82000580, + 0x0000000d, 0x04000003, 0x4a02621d, 0x00000003, + 0x0401fbd4, 0x04000024, 0x4d2c0000, 0x4d400000, + 0x59325808, 0x0201f800, 0x00108f83, 0x592c0408, + 0x8c000512, 0x04000009, 0x4d2c0000, 0x84000512, + 0x48025c08, 0x592c0809, 0x40065800, 0x0201f800, + 0x00100843, 0x5c025800, 0x4d400000, 0x42028000, + 0x00000005, 0x592c0a08, 0x8c040d0e, 0x04000004, + 0x42028000, 0x00000002, 0x0401f001, 0x0201f800, + 0x00104bee, 0x5c028000, 0x0201f800, 0x00109365, + 0x0201f800, 0x00020381, 0x497a6008, 0x5c028000, + 0x5c025800, 0x8d3e7d00, 0x04000009, 0x4d340000, + 0x59326809, 0x0201f800, 0x00104801, 0x5c026800, + 0x0201f800, 0x00107698, 0x0401f00b, 0x4a026403, + 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, + 0x00000002, 0x42000800, 0x8000404b, 0x0201f800, + 0x00020855, 0x5c03e000, 0x02020800, 0x0010698c, + 0x82000540, 0x00000001, 0x1c01f000, 0x0201f800, + 0x00106982, 0x0201f800, 0x00100ee4, 0x0401f7ab, + 0x598c000d, 0x81300580, 0x04020004, 0x0201f800, + 0x00106be2, 0x0402001b, 0x0201f800, 0x00106619, + 0x04020006, 0x59300c03, 0x82040580, 0x00000040, + 0x0400078b, 0x0401f79d, 0x0201f800, 0x001068a3, + 0x04000010, 0x0201f800, 0x00100615, 0x0401f813, + 0x04020004, 0x0201f800, 0x00106bb2, 0x04020009, + 0x0201f800, 0x001064f6, 0x040207f4, 0x59300c03, + 0x82040580, 0x00000040, 0x04000779, 0x0401f78b, + 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, + 0x00100615, 0x0c01f75e, 0x417a3000, 0x42032000, + 0x0000bf32, 0x59900004, 0x81300580, 0x04000009, + 0x83932400, 0x00000010, 0x811a3000, 0x83180480, + 0x00000005, 0x040017f8, 0x82000540, 0x00000001, + 0x1c01f000, 0x59300004, 0x8c00053e, 0x04000010, + 0x8c00050c, 0x0402000e, 0x8c000516, 0x04020006, + 0x82000d00, 0x0000001f, 0x82040580, 0x00000005, + 0x04020004, 0x42000000, 0x00000003, 0x0401f005, + 0x42000000, 0x00000001, 0x0401f002, 0x59300203, + 0x1c01f000, 0x4933c857, 0x0201f800, 0x0010698c, + 0x4df00000, 0x59300203, 0x82000c80, 0x0000000e, + 0x02021800, 0x00100615, 0x0c01f001, 0x00108ac7, + 0x00108ae4, 0x00108acb, 0x00108ac5, 0x00108ac5, + 0x00108ac5, 0x00108ac5, 0x00108ac5, 0x00108ac5, + 0x00108ac5, 0x00108ac5, 0x00108ac5, 0x00108ac5, + 0x00108ac5, 0x0201f800, 0x00100615, 0x5c03e000, + 0x02000800, 0x00106982, 0x0401f6e8, 0x5c03e000, + 0x02000800, 0x00106982, 0x4d2c0000, 0x59325808, + 0x59300403, 0x82000580, 0x00000052, 0x02000800, + 0x00101281, 0x0401fb1f, 0x02000800, 0x00100615, + 0x4a025a06, 0x00000005, 0x0201f800, 0x00020381, + 0x0201f800, 0x00104a83, 0x0201f800, 0x00107698, + 0x5c025800, 0x82000540, 0x00000001, 0x1c01f000, + 0x598c000d, 0x81300580, 0x0402001a, 0x59300004, + 0x8c000520, 0x04000004, 0x84000520, 0x48026004, + 0x0401f01a, 0x42001000, 0x0010b5f4, 0x50081000, + 0x58080002, 0x82000580, 0x00000100, 0x0400000a, + 0x5808000c, 0x81300580, 0x02020800, 0x00100615, + 0x0201f800, 0x00106619, 0x02020800, 0x00100615, + 0x0401f7cf, 0x0201f800, 0x00106be2, 0x0402000c, + 0x59300004, 0x8c000520, 0x04000004, 0x84000520, + 0x48026004, 0x0401f7c6, 0x0201f800, 0x00106619, + 0x040007c3, 0x0201f800, 0x00100615, 0x59300203, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f7a7, 0x59300406, 0x4933c857, 0x4803c857, + 0x82000c80, 0x00000012, 0x02021800, 0x00100615, + 0x0c01f001, 0x00108b30, 0x00108bfe, 0x00108d36, + 0x00108b3c, 0x00107698, 0x00108b30, 0x00109faf, + 0x000208b4, 0x00108bfe, 0x00106306, 0x00108d97, + 0x00108b2b, 0x00108b2b, 0x00108b2b, 0x00108b2b, + 0x00108b2b, 0x001094b7, 0x001094b7, 0x0201f800, + 0x00100615, 0x0401fbd8, 0x02000000, 0x00107da6, + 0x1c01f000, 0x0201f800, 0x0010698c, 0x0201f800, + 0x001068f6, 0x0201f800, 0x00106982, 0x0201f000, + 0x000208b4, 0x4a026206, 0x00000001, 0x1c01f000, + 0x42000000, 0x0010b671, 0x0201f800, 0x0010a86e, + 0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401fab1, + 0x04000007, 0x59325808, 0x592c0208, 0x8400054c, + 0x48025a08, 0x42028000, 0x00000006, 0x0201f800, + 0x0010698c, 0x0401ff4c, 0x4803c857, 0x82000c80, + 0x0000000e, 0x02021800, 0x00100615, 0x0c01f806, + 0x0201f800, 0x00106982, 0x5c028000, 0x5c025800, + 0x1c01f000, 0x00108bfd, 0x00108b69, 0x00108b79, + 0x00108ba0, 0x00108bce, 0x00108b67, 0x00108b30, + 0x00108b30, 0x00108b30, 0x00108b67, 0x00108b67, + 0x00108b67, 0x00108b67, 0x00108b79, 0x0201f800, + 0x00100615, 0x598c000d, 0x4803c857, 0x81300580, + 0x04020004, 0x0201f800, 0x00106be2, 0x0402003f, + 0x0201f800, 0x00106619, 0x04000043, 0x4803c856, + 0x0201f800, 0x001068a3, 0x04000038, 0x0201f800, + 0x00100615, 0x497a621d, 0x812e59c0, 0x02000800, + 0x00100615, 0x592c0204, 0x4803c857, 0x82000500, + 0x000000ff, 0x82000580, 0x00000014, 0x04000003, + 0x4a02621d, 0x00000003, 0x592c0a08, 0x0201f800, + 0x00104bee, 0x0201f800, 0x00109365, 0x0201f800, + 0x00020381, 0x497a6008, 0x4a026403, 0x00000085, + 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, + 0x59300804, 0x82040d00, 0x00000100, 0x82040d40, + 0x8000404b, 0x48066004, 0x0201f800, 0x00106982, + 0x42000800, 0x8000404b, 0x0201f000, 0x00020855, + 0x0401feea, 0x04020004, 0x0201f800, 0x00106bb2, + 0x0402000a, 0x0201f800, 0x001064f6, 0x040207cc, + 0x59300c03, 0x4807c857, 0x82040580, 0x00000040, + 0x04000009, 0x0401f7cc, 0x59300203, 0x4803c857, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f7a5, 0x0201f800, 0x00106982, 0x812e59c0, + 0x04000013, 0x592c0a08, 0x0201f800, 0x00104bee, + 0x0201f800, 0x00109365, 0x0201f800, 0x00020381, + 0x59300203, 0x82000580, 0x0000000d, 0x04000008, + 0x0201f800, 0x00106982, 0x4d340000, 0x59326809, + 0x0201f800, 0x00104801, 0x5c026800, 0x0201f800, + 0x00107698, 0x0401f030, 0x812e59c0, 0x02000800, + 0x00100615, 0x0201f800, 0x001091d3, 0x04020004, + 0x0201f800, 0x00100ee4, 0x0401f7a3, 0x0201f800, + 0x00106982, 0x592c0208, 0x8400050c, 0x48025a08, + 0x592c0406, 0x800000c2, 0x800008c4, 0x80040c00, + 0x48066206, 0x42000000, 0x10000000, 0x41300800, + 0x0201f800, 0x00100bde, 0x0400000d, 0x592c0208, + 0x8c00051c, 0x04020006, 0x8400055c, 0x48025a08, + 0x4a026206, 0x00000002, 0x0401f00f, 0x4d300000, + 0x0201f800, 0x00101335, 0x5c026000, 0x59300203, + 0x82000580, 0x00000004, 0x04020007, 0x4d380000, + 0x42027000, 0x00000048, 0x0201f800, 0x000208d8, + 0x5c027000, 0x1c01f000, 0x42000000, 0x0010b66d, + 0x0201f800, 0x0010a86e, 0x59300203, 0x82000c80, + 0x0000000e, 0x02021800, 0x00100615, 0x4803c857, + 0x0c01f001, 0x00108c17, 0x00108b39, 0x00108c19, + 0x00108c17, 0x00108c19, 0x00108c19, 0x00108b31, + 0x00108c17, 0x00108b2d, 0x00108c17, 0x00108c17, + 0x00108c17, 0x00108c17, 0x00108c17, 0x0201f800, + 0x00100615, 0x4d340000, 0x4d2c0000, 0x59326809, + 0x59340400, 0x82000500, 0x000000ff, 0x82000c80, + 0x0000000c, 0x02021800, 0x00100615, 0x59303403, + 0x82180d80, 0x00000004, 0x04020004, 0x42000000, + 0x00000001, 0x0401f006, 0x82180d80, 0x00000000, + 0x04020003, 0x42000000, 0x00000001, 0x4803c857, + 0x0c01f804, 0x5c025800, 0x5c026800, 0x1c01f000, + 0x00108c40, 0x00108cdf, 0x00108c42, 0x00108c77, + 0x00108c42, 0x00108cfc, 0x00108c42, 0x00108c4c, + 0x00108c40, 0x00108cfc, 0x00108c40, 0x00108c5b, + 0x0201f800, 0x00100615, 0x59300403, 0x82000d80, + 0x00000016, 0x0400002e, 0x82000d80, 0x00000004, + 0x0400002b, 0x82000d80, 0x00000002, 0x04000028, + 0x0401fab9, 0x04000079, 0x59300403, 0x82000d80, + 0x00000022, 0x040000ae, 0x82000d80, 0x00000039, + 0x040000b3, 0x82000d80, 0x00000035, 0x040000b0, + 0x82000d80, 0x0000001e, 0x0400001b, 0x0401f999, + 0x04000007, 0x0201f800, 0x00109360, 0x04020004, + 0x0201f800, 0x00104863, 0x0401f011, 0x59300403, + 0x82000d80, 0x00000001, 0x04020004, 0x0201f800, + 0x00104836, 0x0400000a, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x00107da6, 0x0201f000, 0x00107698, 0x0401f97d, + 0x04000004, 0x0201f800, 0x00109360, 0x040000a9, + 0x59300c03, 0x82040580, 0x00000016, 0x04000056, + 0x82040580, 0x00000002, 0x04020034, 0x59a80026, + 0x8c000502, 0x04020013, 0x0201f800, 0x00104e0d, + 0x04020010, 0x0201f800, 0x00104e23, 0x04020006, + 0x42000000, 0x00000001, 0x0201f800, 0x00104de5, + 0x0401f094, 0x4a035033, 0x00000001, 0x4202d800, + 0x00000001, 0x0201f800, 0x00104d76, 0x0401f08d, + 0x59340403, 0x82000580, 0x000007fc, 0x04000008, + 0x59a80026, 0x8c00050a, 0x04020084, 0x59340212, + 0x82000500, 0x0000ff00, 0x04000082, 0x59340412, + 0x82000500, 0x000000ff, 0x04000010, 0x80000040, + 0x48026c12, 0x497a6008, 0x4a026406, 0x00000007, + 0x4a026206, 0x00000398, 0x497a6205, 0x0201f800, + 0x00020892, 0x04000005, 0x49366009, 0x4a026406, + 0x00000001, 0x0401f020, 0x59300403, 0x82000d80, + 0x00000002, 0x0402000d, 0x59340403, 0x82000580, + 0x000007fe, 0x04020009, 0x59a80026, 0x84000540, + 0x48035026, 0x0201f800, 0x00104067, 0x0201f800, + 0x00107da6, 0x0401f00c, 0x0201f800, 0x00107da6, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x42000000, 0x0010b663, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x00101e1b, 0x0201f000, + 0x00107698, 0x42000800, 0x00000003, 0x0201f800, + 0x001043c7, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000002, 0x0201f000, 0x00106470, 0x0401f915, + 0x04020793, 0x0201f800, 0x00101e1b, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x42003000, 0x00000018, 0x41782800, 0x42002000, + 0x00000000, 0x4d400000, 0x4d440000, 0x59368c03, + 0x42028000, 0x00000029, 0x0201f800, 0x0010962a, + 0x5c028800, 0x5c028000, 0x0201f000, 0x00107698, + 0x0201f800, 0x00104863, 0x0401f7c8, 0x42000000, + 0x0010b66c, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x001078fd, 0x040207c1, 0x1c01f000, 0x4d380000, + 0x59327403, 0x0201f800, 0x00109183, 0x5c027000, + 0x02020000, 0x000208b4, 0x836c0580, 0x00000003, + 0x04000004, 0x4a026206, 0x00000002, 0x1c01f000, + 0x59300403, 0x48026416, 0x4a02621d, 0x00000001, + 0x4a026403, 0x00000085, 0x4a026203, 0x00000009, + 0x4a026406, 0x00000002, 0x42000800, 0x8000004b, + 0x0201f000, 0x00020855, 0x0201f800, 0x00101e1b, + 0x0201f800, 0x00107da6, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00101de2, 0x5c027800, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x497a6008, + 0x4a026406, 0x00000007, 0x4a026206, 0x00000398, + 0x497a6205, 0x1c01f000, 0x42000000, 0x0010b66f, + 0x0201f800, 0x0010a86e, 0x4d340000, 0x59326809, + 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, + 0x00100615, 0x4803c857, 0x0c01f803, 0x5c026800, + 0x1c01f000, 0x00108d53, 0x00108b39, 0x00108d53, + 0x00108d53, 0x00108d53, 0x00108d53, 0x00108d53, + 0x00108d53, 0x00108d53, 0x00108b39, 0x00108d55, + 0x00108b39, 0x00108d5d, 0x00108d53, 0x0201f800, + 0x00100615, 0x4a026403, 0x0000008b, 0x4a026203, + 0x0000000b, 0x42000800, 0x8000404b, 0x0201f000, + 0x00020855, 0x59300a1d, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00101de2, 0x5c027800, 0x42003000, + 0x00000011, 0x0201f800, 0x0010a766, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x41306800, + 0x0201f800, 0x00020892, 0x04000008, 0x49366009, + 0x4d300000, 0x40366000, 0x0201f800, 0x00107698, + 0x5c026000, 0x0401f002, 0x40366000, 0x497a6008, + 0x4a026406, 0x00000001, 0x4a026403, 0x00000001, + 0x0201f800, 0x0010393e, 0x04000011, 0x4a026406, + 0x00000004, 0x4a026203, 0x00000007, 0x4a026420, + 0x00000001, 0x42003000, 0x00000004, 0x4d400000, + 0x42028000, 0x00000029, 0x41782800, 0x0201f800, + 0x0010a250, 0x5c028000, 0x1c01f000, 0x42000800, + 0x0000000b, 0x0201f800, 0x001043c7, 0x4a026203, + 0x00000001, 0x0201f000, 0x00106470, 0x42000000, + 0x0010b675, 0x0201f800, 0x0010a86e, 0x59300203, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x4803c857, 0x0c01f001, 0x00108dc8, 0x00108db0, + 0x00108db4, 0x00108dc9, 0x00108db2, 0x00108db0, + 0x00108db0, 0x00108db0, 0x00108db0, 0x00108db0, + 0x00108db0, 0x00108db0, 0x00108db0, 0x00108db0, + 0x0201f800, 0x00100615, 0x0201f800, 0x00100ee4, + 0x4d2c0000, 0x59325808, 0x4a025a06, 0x00000006, + 0x0201f800, 0x00020381, 0x5c025800, 0x497a6008, + 0x4a02621d, 0x0000000a, 0x4a026403, 0x00000085, + 0x4a026203, 0x00000009, 0x4a026406, 0x00000002, + 0x42000800, 0x8000404b, 0x0201f000, 0x00020855, + 0x1c01f000, 0x0201f800, 0x0010698c, 0x4df00000, + 0x0401fcbe, 0x04020004, 0x0201f800, 0x00106bb2, + 0x0402000c, 0x0201f800, 0x001064f6, 0x04020005, + 0x5c03e000, 0x0201f800, 0x00106982, 0x0401f7dd, + 0x0201f800, 0x001068a3, 0x02020800, 0x00100615, + 0x5c03e000, 0x0201f800, 0x00106982, 0x59300203, + 0x82000d80, 0x00000003, 0x02000800, 0x00100615, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f7ba, 0x4803c856, 0x59a8000e, 0x59a80867, + 0x80040400, 0x80080480, 0x04021004, 0x82000540, + 0x00000001, 0x1c01f000, 0x80000580, 0x1c01f000, + 0x4803c856, 0x4c080000, 0x59301008, 0x82081500, + 0xfff00000, 0x5c001000, 0x1c01f000, 0x4803c856, + 0x4d300000, 0x0201f800, 0x00020892, 0x0400000a, + 0x0401f82f, 0x4d380000, 0x42027000, 0x0000004b, + 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, + 0x4d300000, 0x0201f800, 0x001076c9, 0x0400001b, + 0x0401f81f, 0x4d300000, 0x0201f800, 0x0010698c, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x001067f6, + 0x0201f800, 0x00106543, 0x5c027800, 0x0201f800, + 0x0010a0da, 0x0201f800, 0x00106982, 0x5c026000, + 0x8d3e7d3e, 0x0402000b, 0x4d380000, 0x42027000, + 0x0000004c, 0x0201f800, 0x000208d8, 0x5c027000, + 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, + 0x0201f800, 0x000208b4, 0x0401f7fa, 0x592c0407, + 0x494a6017, 0x494e6018, 0x49366009, 0x492e6008, + 0x4a026406, 0x00000003, 0x800000c2, 0x800008c4, + 0x80040400, 0x48026206, 0x1c01f000, 0x493bc857, + 0x4d300000, 0x0201f800, 0x00020892, 0x0400000d, + 0x0401ffef, 0x4d400000, 0x42028000, 0x00000005, + 0x0401f80d, 0x5c028000, 0x8d3e7d3e, 0x04020007, + 0x0201f800, 0x000208d8, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x0201f800, 0x000208b4, + 0x0401f7fa, 0x4803c856, 0x0201f800, 0x0010698c, + 0x4d3c0000, 0x4d440000, 0x59368c03, 0x42027800, + 0x00000001, 0x0201f800, 0x001066ff, 0x0201f800, + 0x00106675, 0x0201f800, 0x00106543, 0x0201f800, + 0x0010a0da, 0x5c028800, 0x5c027800, 0x0201f000, + 0x00106982, 0x4803c856, 0x4d300000, 0x0201f800, + 0x00020892, 0x0400000f, 0x481a601c, 0x48ee6021, + 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d380000, 0x42027000, 0x0000001f, 0x0201f800, + 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0201f800, 0x00020892, 0x0400000e, 0x48ee6021, + 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d380000, 0x42027000, 0x00000055, 0x0201f800, + 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0201f800, 0x00020892, 0x0400000f, 0x481a601c, + 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, + 0x492e6008, 0x4d380000, 0x42027000, 0x0000003d, + 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856, + 0x4d300000, 0x0201f800, 0x001076c9, 0x04000014, + 0x49366009, 0x492fc857, 0x4933c857, 0x592c0404, + 0x8c00051e, 0x04000003, 0x48efc857, 0x48ee6021, + 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, + 0x42027000, 0x00000000, 0x0201f800, 0x000208d8, + 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, + 0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800, + 0x00020892, 0x0400000f, 0x48ee6021, 0x481a601c, + 0x49366009, 0x4a026406, 0x00000001, 0x492e6008, + 0x4d380000, 0x42027000, 0x00000044, 0x0201f800, + 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000, + 0x0201f800, 0x00020892, 0x0400000f, 0x481a601c, + 0x48ee6021, 0x49366009, 0x4a026406, 0x00000001, + 0x492e6008, 0x4d380000, 0x42027000, 0x00000049, + 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x59300009, + 0x80001540, 0x02000800, 0x00100615, 0x5808040b, + 0x4803c856, 0x80000040, 0x04001002, 0x4800140b, + 0x1c01f000, 0x4803c856, 0x59300403, 0x82000d80, + 0x00000002, 0x0400000f, 0x82000d80, 0x00000003, + 0x0400000c, 0x82000d80, 0x00000004, 0x04000009, + 0x599c0819, 0x8c040d0e, 0x04000004, 0x82000d80, + 0x00000000, 0x04000003, 0x82000540, 0x00000001, + 0x1c01f000, 0x4803c856, 0x4c000000, 0x4d2c0000, + 0x59300406, 0x82000580, 0x00000004, 0x0400001d, + 0x59300008, 0x80025d40, 0x800001c0, 0x04000019, + 0x0201f800, 0x00109360, 0x04000014, 0x59300406, + 0x82004580, 0x00000010, 0x04000010, 0x82004580, + 0x00000011, 0x0400000d, 0x82004580, 0x00000003, + 0x0400000c, 0x82004580, 0x00000002, 0x04000009, + 0x82004580, 0x0000000a, 0x04000006, 0x592c0404, + 0x8c00051e, 0x04000003, 0x80000580, 0x0401f003, + 0x82000540, 0x00000001, 0x5c025800, 0x5c000000, + 0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800, + 0x001076c9, 0x04000013, 0x49366009, 0x48ee6021, + 0x4a026406, 0x00000001, 0x492e6008, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x4d380000, 0x42027000, 0x00000028, 0x0201f800, + 0x000208d8, 0x5c027000, 0x82000540, 0x00000001, + 0x5c026000, 0x1c01f000, 0x4803c856, 0x83380580, + 0x00000015, 0x0402000d, 0x59a80016, 0x82000580, + 0x00000074, 0x04020009, 0x0201f800, 0x00104480, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000029, + 0x0201f000, 0x00106470, 0x0201f800, 0x00107da6, + 0x0201f000, 0x000208b4, 0x4803c856, 0x83380580, + 0x00000016, 0x04020007, 0x42000800, 0x00000004, + 0x0201f800, 0x001043c7, 0x0201f000, 0x001078bf, + 0x83380580, 0x00000015, 0x04020013, 0x59a80016, + 0x82000580, 0x00000014, 0x0402000f, 0x0201f800, + 0x001044e1, 0x0201f800, 0x00108210, 0x0402000a, + 0x59340404, 0x80000540, 0x04000007, 0x42000800, + 0x00000006, 0x0201f800, 0x001043c7, 0x0201f000, + 0x001078bf, 0x0201f800, 0x00107da6, 0x0201f000, + 0x000208b4, 0x4803c856, 0x592c0206, 0x82000580, + 0x00000005, 0x04000002, 0x1c01f000, 0x4803c856, + 0x592c0208, 0x8400054a, 0x48025a08, 0x1c01f000, + 0x497a6205, 0x497a6008, 0x4a026203, 0x00000001, + 0x4a026403, 0x00000050, 0x42000800, 0x80000043, + 0x0201f000, 0x00020855, 0x4933c857, 0x4d340000, + 0x59326809, 0x59340200, 0x8c00050e, 0x04000006, + 0x59300406, 0x82000c80, 0x00000012, 0x04021004, + 0x0c01f806, 0x5c026800, 0x1c01f000, 0x0201f800, + 0x00108b30, 0x0401f7fc, 0x00108b30, 0x00108fb4, + 0x00108fb8, 0x00108fbb, 0x0010a2b9, 0x0010a2d6, + 0x0010a2da, 0x00108b30, 0x00108b30, 0x00108b30, + 0x00108b30, 0x00108b30, 0x00108b30, 0x00108b30, + 0x00108b30, 0x00108b30, 0x00108b30, 0x00108b30, + 0x4803c856, 0x40000000, 0x40000000, 0x1c01f000, + 0x40000000, 0x40000000, 0x1c01f000, 0x5930001c, + 0x4803c857, 0x59300414, 0x4933c857, 0x4803c857, + 0x8c000502, 0x04000005, 0x4803c857, 0x84000540, + 0x48026414, 0x1c01f000, 0x42000000, 0xd0000000, + 0x41300800, 0x0201f800, 0x00100bde, 0x0401f810, + 0x0402000e, 0x59300c14, 0x59300403, 0x82000580, + 0x00000040, 0x04000003, 0x84040d40, 0x0401f005, + 0x59a80037, 0x82000400, 0x0000000a, 0x48026205, + 0x84040d42, 0x48066414, 0x1c01f000, 0x4933c857, + 0x4d340000, 0x59326809, 0x59340200, 0x8c00050e, + 0x02000800, 0x00100615, 0x5930001c, 0x80000540, + 0x04020034, 0x59300403, 0x4803c857, 0x82000580, + 0x00000040, 0x04000004, 0x59a80021, 0x80000540, + 0x0402002a, 0x4d1c0000, 0x41323800, 0x0201f800, + 0x00020892, 0x04000023, 0x4932381c, 0x591c0414, + 0x84000542, 0x48023c14, 0x49366009, 0x591c0406, + 0x82000580, 0x00000003, 0x04000006, 0x591c0202, + 0x48026419, 0x591c0402, 0x48026219, 0x0401f005, + 0x591c0202, 0x48026219, 0x591c0402, 0x48026419, + 0x491e601e, 0x4a026406, 0x00000001, 0x4a026403, + 0x00000035, 0x4a026203, 0x00000001, 0x42000800, + 0x80000040, 0x0201f800, 0x00020855, 0x411e6000, + 0x5c023800, 0x80000580, 0x5c026800, 0x1c01f000, + 0x411e6000, 0x5c023800, 0x59a80039, 0x48026205, + 0x82000540, 0x00000001, 0x0401f7f8, 0x4933c857, + 0x4d2c0000, 0x4932381c, 0x4a026202, 0x0000ffff, + 0x591e5808, 0x591c0007, 0x8c00051e, 0x04000005, + 0x8400051e, 0x48023807, 0x497a5c09, 0x0401f018, + 0x592c0408, 0x8c000518, 0x04000015, 0x84000518, + 0x48025c08, 0x4d400000, 0x592e8206, 0x4a025a06, + 0x00000001, 0x0401fb34, 0x49425a06, 0x5c028000, + 0x497a5c09, 0x592c0408, 0x8c000512, 0x04000008, + 0x4d2c0000, 0x84000512, 0x48025c08, 0x592e5809, + 0x0201f800, 0x00100843, 0x5c025800, 0x59a80039, + 0x48026205, 0x591c0214, 0x48026216, 0x82000d80, + 0x00000001, 0x04000008, 0x4a023a03, 0x00000002, + 0x82000580, 0x00000005, 0x04000008, 0x497a6015, + 0x0401f01e, 0x591c0007, 0x84000540, 0x48023807, + 0x4a023a03, 0x00000004, 0x591c0414, 0x4803c857, + 0x8400051c, 0x84000554, 0x48023c14, 0x592c000f, + 0x40001000, 0x591c0816, 0x80040480, 0x040217f0, + 0x591c0016, 0x82000500, 0xfffffffc, 0x48026015, + 0x48023816, 0x591c0a14, 0x4807c857, 0x82040d80, + 0x00000005, 0x04020005, 0x480bc857, 0x4803c857, + 0x4a023812, 0xffffffff, 0x591c0402, 0x48026419, + 0x591c0202, 0x48026219, 0x591e6809, 0x49366009, + 0x4a026406, 0x00000001, 0x4a026403, 0x00000039, + 0x4a026203, 0x00000001, 0x42000800, 0x80000040, + 0x0201f800, 0x00020855, 0x5c025800, 0x1c01f000, + 0x4933c857, 0x59300414, 0x8c000514, 0x04000015, + 0x8c00051c, 0x04020012, 0x59300016, 0x80100480, + 0x04001006, 0x04000005, 0x59300414, 0x84000514, + 0x8400055c, 0x0401f009, 0x48126016, 0x48126012, + 0x40100000, 0x592c180f, 0x800c0480, 0x48026011, + 0x59300414, 0x84000514, 0x48026414, 0x1c01f000, + 0x4933c857, 0x8c00051c, 0x04020006, 0x59300012, + 0x48026016, 0x59300414, 0x8400055c, 0x48026414, + 0x1c01f000, 0x59300c03, 0x4933c857, 0x4807c857, + 0x82040480, 0x00000034, 0x04001006, 0x82040480, + 0x0000003c, 0x04021003, 0x80000580, 0x1c01f000, + 0x82000540, 0x00000001, 0x0401f7fd, 0x41780800, + 0x59a81035, 0x42000000, 0x00000032, 0x0201f800, + 0x001063ee, 0x800811c0, 0x04020003, 0x42001000, + 0x00000014, 0x480b5037, 0x59a81036, 0x480b502d, + 0x41780800, 0x42000000, 0x00000064, 0x0201f800, + 0x001063ee, 0x800811c0, 0x04020003, 0x42001000, + 0x00000014, 0x480b5038, 0x82081400, 0x0000000a, + 0x480b5039, 0x42000800, 0x00000001, 0x0201f800, + 0x001069af, 0x42000000, 0x30000000, 0x40080800, + 0x0201f800, 0x00100bb2, 0x42000800, 0x00000003, + 0x59a81010, 0x0201f800, 0x001069af, 0x0201f000, + 0x00104755, 0x4a035037, 0x00000028, 0x4a035038, + 0x00000014, 0x4a03502d, 0x000007d0, 0x42001000, + 0x0000001e, 0x480b5039, 0x42000800, 0x00000001, + 0x0201f800, 0x001069af, 0x42000000, 0x30000000, + 0x40080800, 0x0201f800, 0x00100bb2, 0x42000800, + 0x00000003, 0x59a81010, 0x0201f000, 0x001069af, + 0x4933c857, 0x4d2c0000, 0x59300403, 0x82000580, + 0x0000003e, 0x04020005, 0x59325817, 0x812e59c0, + 0x02020800, 0x0010083a, 0x5c025800, 0x1c01f000, + 0x4937c857, 0x4d300000, 0x0201f800, 0x00020892, + 0x04000011, 0x49366009, 0x4a026406, 0x00000001, + 0x492e6008, 0x42000800, 0x00000009, 0x0201f800, + 0x001043c7, 0x4d380000, 0x42027000, 0x00000033, + 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, + 0x4d2c0000, 0x4c580000, 0x4d3c0000, 0x59325808, + 0x83380580, 0x00000015, 0x04020025, 0x59a8b016, + 0x82580c80, 0x00000019, 0x04001003, 0x4200b000, + 0x00000018, 0x8058b104, 0x0401fa0a, 0x80000580, + 0x0401fa1a, 0x832cac00, 0x00000009, 0x83cca400, + 0x00000006, 0x0201f800, 0x0010a93e, 0x4c600000, + 0x4200c000, 0x00000001, 0x592c100a, 0x8c081518, + 0x04020006, 0x59a80010, 0x592c100d, 0x80080580, + 0x04020007, 0x4178c000, 0x59301009, 0x58081403, + 0x417a7800, 0x0201f800, 0x00101e48, 0x5c00c000, + 0x0201f800, 0x001078bf, 0x0401f008, 0x4200b000, + 0x00000002, 0x0401fa09, 0x0201f800, 0x00107da6, + 0x0201f800, 0x000208b4, 0x5c027800, 0x5c00b000, + 0x5c025800, 0x1c01f000, 0x4933c856, 0x49366009, + 0x4a026406, 0x00000001, 0x492e6008, 0x4d380000, + 0x42027000, 0x0000004d, 0x0201f800, 0x000208d8, + 0x5c027000, 0x82000540, 0x00000001, 0x1c01f000, + 0x4803c856, 0x4d2c0000, 0x83380580, 0x00000015, + 0x04020027, 0x59a80816, 0x59325808, 0x5930040b, + 0x800000c4, 0x80040580, 0x04020021, 0x4c500000, + 0x4c540000, 0x4c580000, 0x83cca400, 0x00000006, + 0x4050a800, 0x5930b40b, 0x0201f800, 0x0010a94f, + 0x83cca400, 0x00000006, 0x592cb205, 0x832cac00, + 0x00000006, 0x0201f800, 0x0010a93e, 0x592e5801, + 0x812e59c0, 0x040207f9, 0x5931d821, 0x58ef400b, + 0x58ee580d, 0x4a025a04, 0x00000103, 0x58ec0009, + 0x0801f800, 0x59300402, 0x5c00b000, 0x5c00a800, + 0x5c00a000, 0x5c025800, 0x1c01f000, 0x0201f800, + 0x00107da6, 0x5c025800, 0x1c01f000, 0x4933c857, + 0x83380580, 0x00000035, 0x04000005, 0x59301419, + 0x0401f851, 0x04000027, 0x0401f006, 0x4d300000, + 0x5932601e, 0x0401f856, 0x5c026000, 0x04000020, + 0x591c0c06, 0x82040580, 0x00000003, 0x04000004, + 0x82040580, 0x00000006, 0x0402001c, 0x591c0c02, + 0x59300419, 0x80040580, 0x04000009, 0x59300219, + 0x80040580, 0x04020015, 0x591c0a02, 0x59300419, + 0x80040580, 0x04020011, 0x0401f009, 0x59300a19, + 0x82040580, 0x0000ffff, 0x04000005, 0x591c0202, + 0x59300a19, 0x80040580, 0x04020008, 0x591c0009, + 0x59300809, 0x80040580, 0x1c01f000, 0x417a3800, + 0x82000540, 0x00000001, 0x1c01f000, 0x4803c856, + 0x59b800e4, 0x8c000538, 0x02020800, 0x00100615, + 0x42000800, 0x0000012c, 0x4a0370e4, 0x20000000, + 0x59b800e4, 0x80040840, 0x02000800, 0x00100615, + 0x8c00053c, 0x040207f9, 0x4a0370e4, 0x30000000, + 0x40000000, 0x40000000, 0x40000000, 0x59b800e4, + 0x8c00053c, 0x040207f1, 0x1c01f000, 0x4803c856, + 0x4a0370e4, 0x20000000, 0x40000000, 0x59b800e4, + 0x8c000538, 0x040207fb, 0x1c01f000, 0x59300807, + 0x8c040d1e, 0x592c0c08, 0x04020002, 0x8c040d18, + 0x1c01f000, 0x0401fc10, 0x04000008, 0x42000800, + 0x00000024, 0x0201f800, 0x001063cf, 0x82063c00, + 0x0010cfc0, 0x491fc857, 0x1c01f000, 0x83300480, + 0x0010cfc0, 0x0400100a, 0x59a8000b, 0x81300480, + 0x04021007, 0x59301402, 0x0401ffef, 0x04000007, + 0x411c0000, 0x81300580, 0x04000003, 0x81780500, + 0x0401f002, 0x81300540, 0x1c01f000, 0x4947c857, + 0x4d300000, 0x0201f800, 0x00020267, 0x0402000a, + 0x42026000, 0x0010bbe8, 0x49366009, 0x492e6008, + 0x0201f800, 0x00101de2, 0x80000580, 0x5c026000, + 0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fc, + 0x4933c857, 0x0201f800, 0x00108df4, 0x02000800, + 0x00100615, 0x4d2c0000, 0x4d340000, 0x4d440000, + 0x4c580000, 0x59325808, 0x59326809, 0x49425a06, + 0x0201f800, 0x00105439, 0x592e8c06, 0x592c4207, + 0x82200500, 0x0000000f, 0x0c01f806, 0x5c00b000, + 0x5c028800, 0x5c026800, 0x5c025800, 0x1c01f000, + 0x0010922f, 0x00109251, 0x00109258, 0x0010925c, + 0x00109265, 0x0010922c, 0x0010922c, 0x0010922c, + 0x00109269, 0x00109275, 0x00109275, 0x0010922c, + 0x0010922c, 0x0010922c, 0x0010922c, 0x0010922c, + 0x4803c857, 0x0201f800, 0x00100615, 0x814281c0, + 0x04020012, 0x41785800, 0x592c0404, 0x8c00051c, + 0x04020002, 0x59345c05, 0x442c2800, 0x59340008, + 0x48002802, 0x59340009, 0x48002801, 0x59340006, + 0x48002804, 0x59340007, 0x48002803, 0x4200b000, + 0x0000000b, 0x0401f037, 0x592c0207, 0x8c00051e, + 0x4200b000, 0x00000002, 0x04020032, 0x8204b540, + 0x00000000, 0x0400002f, 0x44042800, 0x59326809, + 0x59340400, 0x48002801, 0x4200b000, 0x00000002, + 0x0401f028, 0x814281c0, 0x04020030, 0x59345c05, + 0x442c2800, 0x4200b000, 0x00000001, 0x0401f021, + 0x8340b540, 0x00000000, 0x0400001e, 0x0401f027, + 0x814281c0, 0x04020025, 0x59340200, 0x44002800, + 0x59340001, 0x48002801, 0x4200b000, 0x00000002, + 0x0401f014, 0x8340b540, 0x00000000, 0x0402001b, + 0x0401f010, 0x8340b540, 0x00000000, 0x0400000d, + 0x0201f800, 0x00104871, 0x04000014, 0x8c20450e, + 0x04000002, 0x497a6009, 0x4178b000, 0x497a5a06, + 0x0401f004, 0x8340b540, 0x00000000, 0x0402000b, + 0x592c0404, 0x8400051c, 0x48025c04, 0x592c0207, + 0x8400051e, 0x48025a07, 0x0401f8aa, 0x497a6008, + 0x0201f000, 0x00020381, 0x592c0207, 0x8c00051e, + 0x4200b000, 0x00000002, 0x040207f2, 0x8204b540, + 0x00000000, 0x040007ef, 0x44042800, 0x4200b000, + 0x00000001, 0x0401f7eb, 0x4937c857, 0x4d300000, + 0x0201f800, 0x00020892, 0x04000011, 0x49366009, + 0x4a026406, 0x00000001, 0x492e6008, 0x42000800, + 0x0000000b, 0x0201f800, 0x001043c7, 0x4d380000, + 0x42027000, 0x00000043, 0x0201f800, 0x000208d8, + 0x5c027000, 0x82000540, 0x00000001, 0x5c026000, + 0x1c01f000, 0x4937c857, 0x4d2c0000, 0x59325808, + 0x83380580, 0x00000015, 0x04020025, 0x59a80016, + 0x82000580, 0x00000004, 0x04020021, 0x59a80010, + 0x592c1009, 0x80080580, 0x04020010, 0x4d440000, + 0x592e8c06, 0x592c0207, 0x4803c856, 0x82000500, + 0x00000080, 0x84000548, 0x4d3c0000, 0x42027800, + 0x00001000, 0x0201f800, 0x0010480a, 0x5c027800, + 0x5c028800, 0x0401f004, 0x4803c856, 0x0201f800, + 0x00104871, 0x0201f800, 0x00108df4, 0x04000017, + 0x4d400000, 0x42028000, 0x00000000, 0x41780800, + 0x0401ff38, 0x5c028000, 0x0401f00e, 0x0201f800, + 0x00104871, 0x040207f4, 0x0201f800, 0x00108df4, + 0x0400000a, 0x4c580000, 0x4200b000, 0x00000002, + 0x0401f86e, 0x5c00b000, 0x0201f800, 0x00107da6, + 0x0201f800, 0x000208b4, 0x5c025800, 0x1c01f000, + 0x4937c857, 0x4d300000, 0x0201f800, 0x00020892, + 0x04000012, 0x49366009, 0x4a026406, 0x00000001, + 0x4d3c0000, 0x4d380000, 0x417a7800, 0x0201f800, + 0x001043bd, 0x492e6008, 0x42027000, 0x00000004, + 0x0201f800, 0x000208d8, 0x5c027000, 0x5c027800, + 0x82000540, 0x00000001, 0x5c026000, 0x1c01f000, + 0x4937c857, 0x4d300000, 0x0201f800, 0x001076c9, + 0x0400000d, 0x49366009, 0x4a026406, 0x00000001, + 0x492e6008, 0x4d380000, 0x42027000, 0x00000051, + 0x0201f800, 0x000208d8, 0x5c027000, 0x82000540, + 0x00000001, 0x5c026000, 0x1c01f000, 0x4933c857, + 0x4c580000, 0x59325808, 0x83383580, 0x00000015, + 0x04020011, 0x592c0008, 0x82000500, 0x00ffffff, + 0x0402000a, 0x0201f800, 0x00105439, 0x59cc0000, + 0x82000500, 0x00ffffff, 0x44002800, 0x4200b000, + 0x00000001, 0x0401f80b, 0x0201f800, 0x001078bf, + 0x0401f006, 0x4200b000, 0x00000002, 0x0401f823, + 0x0201f800, 0x00107da6, 0x5c00b000, 0x1c01f000, + 0x492fc857, 0x4c580000, 0x4c000000, 0x8058b1c0, + 0x0400000b, 0x82580500, 0xfffffff0, 0x02020800, + 0x00100615, 0x8058b0d0, 0x592c0408, 0x82000500, + 0xfffff0ff, 0x80580540, 0x48025c08, 0x5c000000, + 0x5c00b000, 0x1c01f000, 0x492fc857, 0x4c000000, + 0x4c040000, 0x800000d8, 0x592c0c08, 0x82040d00, + 0xffff0fff, 0x80040540, 0x48025c08, 0x5c000800, + 0x5c000000, 0x1c01f000, 0x4933c857, 0x4d2c0000, + 0x59325808, 0x592c0207, 0x8400055e, 0x48025a07, + 0x4c500000, 0x4c540000, 0x4c580000, 0x0401ffd9, + 0x0201f800, 0x00105439, 0x46002800, 0x00000018, + 0x80142800, 0x8058b040, 0x83cca400, 0x00000007, + 0x4014a800, 0x0201f800, 0x0010a93e, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000, + 0x59325808, 0x592c0204, 0x82000580, 0x00000152, + 0x1c01f000, 0x5930001f, 0x80000540, 0x02020800, + 0x00100d9a, 0x1c01f000, 0x4d2c0000, 0x59325808, + 0x59300203, 0x4933c857, 0x492fc857, 0x493bc857, + 0x4803c857, 0x82003480, 0x0000000e, 0x02021800, + 0x00100615, 0x0c01f803, 0x5c025800, 0x1c01f000, + 0x00109386, 0x00109391, 0x001093cf, 0x00109386, + 0x00109386, 0x00109386, 0x00109386, 0x00109386, + 0x00109388, 0x00109386, 0x00109386, 0x00109386, + 0x00109386, 0x00109386, 0x0201f800, 0x00100615, + 0x83383480, 0x00000056, 0x02021800, 0x00100615, + 0x493a6403, 0x4a026203, 0x00000001, 0x0201f000, + 0x00106470, 0x83380580, 0x00000013, 0x04020010, + 0x4937c857, 0x592c000c, 0x800001c0, 0x04000006, + 0x4a026203, 0x00000002, 0x59a80037, 0x48026206, + 0x1c01f000, 0x4a025a06, 0x00000000, 0x0201f800, + 0x00020381, 0x0201f000, 0x000208b4, 0x83380580, + 0x00000027, 0x0400001b, 0x83380580, 0x00000014, + 0x04000012, 0x83380580, 0x00000015, 0x04000005, + 0x83380580, 0x00000016, 0x02020800, 0x00100615, + 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, + 0x59300203, 0x82000580, 0x00000002, 0x02020800, + 0x00100615, 0x0401f016, 0x4937c857, 0x0201f800, + 0x001068f6, 0x4a02580e, 0x00000011, 0x0401f006, + 0x4937c857, 0x0201f800, 0x001068f6, 0x4a02580e, + 0x00000010, 0x4a025a06, 0x00000031, 0x4a02580d, + 0x00000004, 0x0201f800, 0x00020381, 0x0201f800, + 0x00104a83, 0x0201f000, 0x00107698, 0x59341400, + 0x82081d00, 0x000000ff, 0x59300c03, 0x480bc857, + 0x4807c857, 0x82040580, 0x00000053, 0x0400002e, + 0x82040580, 0x00000002, 0x04000016, 0x82040580, + 0x00000001, 0x04000017, 0x82040580, 0x00000003, + 0x0400001c, 0x82040580, 0x00000005, 0x0400001d, + 0x82040580, 0x00000033, 0x0400001a, 0x82040580, + 0x00000000, 0x0400001b, 0x82040580, 0x00000004, + 0x02020800, 0x00100615, 0x0401f8a1, 0x0401f016, + 0x820c0580, 0x00000003, 0x0400084c, 0x0401f012, + 0x820c0580, 0x0000000b, 0x0402000f, 0x42000800, + 0x00000007, 0x0201f800, 0x001043c7, 0x0401f00a, + 0x820c0580, 0x00000005, 0x04000864, 0x0401f006, + 0x820c0580, 0x00000009, 0x04000889, 0x0401f002, + 0x0401f893, 0x4a026403, 0x00000052, 0x59a81016, + 0x592c040b, 0x8c000500, 0x04000003, 0x42001000, + 0x00000008, 0x592c040b, 0x8c000516, 0x04000003, + 0x82081400, 0x00000018, 0x592c000c, 0x497a580d, + 0x497a580e, 0x80080c80, 0x04000009, 0x04001005, + 0x4a025a06, 0x00000007, 0x40001000, 0x0401f006, + 0x4a025a06, 0x00000015, 0x0401f003, 0x4a025a06, + 0x00000000, 0x480a580c, 0x82081400, 0x00000003, + 0x80081104, 0x0201f800, 0x0010783c, 0x04000010, + 0x592c1001, 0x480a600b, 0x58080800, 0x82080400, + 0x00000002, 0x592c1011, 0x592c1812, 0x42003000, + 0x00000000, 0x42002000, 0x00101250, 0x0201f800, + 0x001079b9, 0x04000002, 0x1c01f000, 0x4a025a06, + 0x0000002c, 0x497a580c, 0x0201f800, 0x00020381, + 0x0201f000, 0x000208b4, 0x83380580, 0x00000015, + 0x0402000a, 0x59a8006f, 0x8c000502, 0x0402000b, + 0x0201f800, 0x00104480, 0x42000800, 0x00000004, + 0x0201f000, 0x001043c7, 0x42000800, 0x00000007, + 0x0201f000, 0x001043c7, 0x0201f800, 0x00104e0d, + 0x42001000, 0x00000010, 0x04020009, 0x59340002, + 0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000, + 0x040007ec, 0x42001000, 0x00000008, 0x0201f800, + 0x00104ada, 0x040007e7, 0x592c040b, 0x84000540, + 0x48025c0b, 0x0401f7e9, 0x83380580, 0x00000015, + 0x0402000f, 0x59a8006f, 0x8c000502, 0x04020010, + 0x0201f800, 0x001044e1, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x001043bd, 0x5c027800, 0x42000800, + 0x00000006, 0x0201f000, 0x001043c7, 0x42000800, + 0x00000004, 0x0201f000, 0x001043c7, 0x0201f800, + 0x00104e0d, 0x42001000, 0x00000010, 0x04020009, + 0x59340002, 0x82000500, 0x00ff0000, 0x82000580, + 0x00ff0000, 0x040007e7, 0x42001000, 0x00000008, + 0x0201f800, 0x00104ada, 0x040007e2, 0x592c040b, + 0x84000540, 0x48025c0b, 0x0401f7e9, 0x42000800, + 0x00000004, 0x0201f000, 0x001043c7, 0x83380580, + 0x00000015, 0x04020005, 0x0201f800, 0x0010a0b1, + 0x02000800, 0x00104711, 0x1c01f000, 0x83380580, + 0x00000015, 0x0402001d, 0x4c580000, 0x83cc1400, + 0x00000008, 0x4200b000, 0x00000002, 0x83341c00, + 0x00000006, 0x0201f800, 0x001082ff, 0x04020012, + 0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, + 0x04020009, 0x59342200, 0x59cc1007, 0x800811c0, + 0x04000003, 0x480a6801, 0x84102542, 0x8410251a, + 0x48126a00, 0x5c00b000, 0x1c01f000, 0x42000000, + 0x0010b67a, 0x0201f800, 0x0010a86e, 0x0201f800, + 0x0010698c, 0x59300203, 0x4933c857, 0x4803c857, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f803, 0x0201f000, 0x00106982, 0x001094d7, + 0x001094e6, 0x001094d8, 0x001094d5, 0x001094d5, + 0x001094d5, 0x001094d5, 0x001094d5, 0x001094d5, + 0x001094d5, 0x001094d5, 0x001094d5, 0x001094d5, + 0x001094d5, 0x0201f800, 0x00100615, 0x1c01f000, + 0x59300403, 0x82000580, 0x00000052, 0x02000000, + 0x00108b39, 0x0201f800, 0x00104a83, 0x59325808, + 0x4a025a06, 0x00000006, 0x0201f800, 0x00020381, + 0x0201f000, 0x00107698, 0x59301804, 0x840c0520, + 0x48026004, 0x598c000d, 0x81300580, 0x04020010, + 0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b5f4, + 0x50081000, 0x58080002, 0x82000580, 0x00000100, + 0x0400000e, 0x5808000c, 0x81300580, 0x02020800, + 0x00100615, 0x4978100c, 0x0401f003, 0x8c0c1d20, + 0x040207dc, 0x0201f800, 0x00106619, 0x040007d9, + 0x0201f800, 0x00100615, 0x0201f800, 0x00106be2, + 0x040007f9, 0x59300203, 0x82000c80, 0x0000000e, + 0x02021800, 0x00100615, 0x0c01f7bd, 0x4933c857, + 0x4c500000, 0x4c540000, 0x4c580000, 0x592c0c07, + 0x4806580a, 0x59cc0809, 0x48065807, 0x59cc0a08, + 0x4806580b, 0x59a8086e, 0x82040500, 0x000003ff, + 0x800010c4, 0x8c040d14, 0x04000005, 0x59cc0002, + 0x82000500, 0x00000003, 0x80081480, 0x82080480, + 0x000000f1, 0x02021800, 0x00100615, 0x480a621a, + 0x412c0800, 0x0201f800, 0x00100819, 0x02000800, + 0x00100615, 0x492c0809, 0x58040408, 0x84000552, + 0x84000540, 0x48000c08, 0x82081400, 0x00000003, + 0x80081104, 0x83cca400, 0x00000006, 0x832cac00, + 0x00000004, 0x42000800, 0x00000010, 0x82080480, + 0x00000010, 0x04021003, 0x40080800, 0x80000580, + 0x4004b000, 0x4c000000, 0x0201f800, 0x0010a94f, + 0x5c000000, 0x800001c0, 0x0400000d, 0x412c1000, + 0x4c000000, 0x0201f800, 0x00100819, 0x02000800, + 0x00100615, 0x492c1001, 0x832cac00, 0x00000004, + 0x5c000000, 0x40001000, 0x0401f7e9, 0x5c00b000, + 0x5c00a800, 0x5c00a000, 0x1c01f000, 0x4933c857, + 0x4d2c0000, 0x4c380000, 0x59325808, 0x5930021a, + 0x48025a08, 0x59301011, 0x800811c0, 0x04020008, + 0x4a025a06, 0x00000000, 0x592c000b, 0x82000500, + 0x00000c00, 0x0400000b, 0x0401f00b, 0x8c08153e, + 0x04000006, 0x4a025a06, 0x00000007, 0x80081080, + 0x80081000, 0x0401f003, 0x4a025a06, 0x00000015, + 0x480a5807, 0x42000000, 0x0010bcd8, 0x50007000, + 0x5838000b, 0x80000540, 0x04020008, 0x4930700c, + 0x4930700b, 0x58380002, 0x82000580, 0x00000000, + 0x04020809, 0x0401f005, 0x82001400, 0x00000000, + 0x45301000, 0x4930700b, 0x5c007000, 0x5c025800, + 0x1c01f000, 0x4933c857, 0x592c0009, 0x40001000, + 0x4800700a, 0x82080400, 0x00000004, 0x48007003, + 0x592c000d, 0x592c100e, 0x48007007, 0x48087008, + 0x592c000a, 0x592c1208, 0x80080c80, 0x04001002, + 0x40001000, 0x82081400, 0x00000003, 0x80081104, + 0x82080480, 0x00000010, 0x04021003, 0x80000580, + 0x0401f003, 0x42001000, 0x00000010, 0x4800700d, + 0x48087004, 0x800810c4, 0x48087005, 0x40381000, + 0x0201f800, 0x001008a1, 0x1c01f000, 0x4d2c0000, + 0x0201f800, 0x00100819, 0x02000800, 0x00100615, + 0x42000800, 0x0010bcd8, 0x452c0800, 0x497a580b, + 0x497a580c, 0x497a580d, 0x4a025809, 0x001095b6, + 0x4a025802, 0x00000100, 0x4a025801, 0x00000000, + 0x5c025800, 0x1c01f000, 0x4833c857, 0x4d300000, + 0x4d2c0000, 0x4c5c0000, 0x4030b800, 0x585c000a, + 0x80025d40, 0x04020004, 0x585c000c, 0x4c000000, + 0x0401f044, 0x585c0002, 0x82000580, 0x00000100, + 0x04020022, 0x592c0801, 0x4c040000, 0x0201f800, + 0x0010083a, 0x5c000800, 0x800409c0, 0x0400001c, + 0x4804b80a, 0x585c100d, 0x800811c0, 0x04020005, + 0x40065800, 0x0201f800, 0x00100843, 0x0401f014, + 0x82080480, 0x00000010, 0x04021003, 0x80000580, + 0x0401f003, 0x42001000, 0x00000010, 0x4800b80d, + 0x4808b804, 0x800810c4, 0x4808b805, 0x82040400, + 0x00000004, 0x4800b803, 0x405c1000, 0x0201f800, + 0x001008a1, 0x0401f025, 0x0401f828, 0x585c000c, + 0x80026540, 0x59300000, 0x80000d40, 0x04020002, + 0x4800b80b, 0x4800b80c, 0x497a6000, 0x4c000000, + 0x4978b80a, 0x59325808, 0x4a025a04, 0x00000103, + 0x59300402, 0x48025c06, 0x592c100b, 0x4c080000, + 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, + 0x5c001000, 0x8c081518, 0x04000004, 0x0201f800, + 0x00108f88, 0x0401f003, 0x0201f800, 0x000208b4, + 0x405c7000, 0x5c000000, 0x80026540, 0x04000003, + 0x59325808, 0x0401ff78, 0x5c00b800, 0x5c025800, + 0x5c026000, 0x1c01f000, 0x483bc857, 0x5838000a, + 0x40025800, 0x0201f800, 0x00100843, 0x5838000c, + 0x80026540, 0x59300008, 0x80025d40, 0x4a025a06, + 0x00000002, 0x1c01f000, 0x4803c857, 0x4d1c0000, + 0x497a601c, 0x41323800, 0x40026000, 0x4d3c0000, + 0x42027800, 0x00000005, 0x0401f840, 0x5c027800, + 0x411e6000, 0x59300414, 0x84000502, 0x48026414, + 0x5c023800, 0x1c01f000, 0x481bc857, 0x4933c857, + 0x4c5c0000, 0x4c600000, 0x4010b800, 0x4014c000, + 0x0201f800, 0x0010a766, 0x0201f800, 0x0010393e, + 0x04000008, 0x40602800, 0x405c3000, 0x0201f800, + 0x0010a258, 0x82000540, 0x00000001, 0x0401f002, + 0x80000580, 0x5c00c000, 0x5c00b800, 0x1c01f000, + 0x4803c856, 0x4d300000, 0x42026000, 0x0010cfc0, + 0x59a8000e, 0x81640580, 0x0400001a, 0x59300c06, + 0x82040580, 0x00000001, 0x0400000d, 0x82040580, + 0x00000004, 0x04000006, 0x82040580, 0x00000010, + 0x02000800, 0x00108aad, 0x0401f009, 0x59300203, + 0x82000d80, 0x00000007, 0x04000005, 0x4807c857, + 0x0201f800, 0x0010909d, 0x04020808, 0x83326400, + 0x00000024, 0x41580000, 0x81300480, 0x040017e5, + 0x5c026000, 0x1c01f000, 0x4933c857, 0x59300403, + 0x4803c857, 0x0201f800, 0x0010698c, 0x4df00000, + 0x59300406, 0x4803c857, 0x82000d80, 0x00000002, + 0x04000018, 0x82000d80, 0x00000001, 0x04000009, + 0x82000d80, 0x00000004, 0x04000006, 0x4933c856, + 0x5c03e000, 0x02000800, 0x00106982, 0x0401f03c, + 0x59300203, 0x82000d80, 0x00000001, 0x04000018, + 0x82000d80, 0x00000002, 0x04000026, 0x82000d80, + 0x00000005, 0x04000023, 0x0201f800, 0x00100615, + 0x59300203, 0x82000d80, 0x00000009, 0x0400000c, + 0x82000d80, 0x0000000b, 0x04000009, 0x82000d80, + 0x0000000a, 0x04000017, 0x82000d80, 0x0000000c, + 0x04000014, 0x0201f800, 0x00100615, 0x598c000d, + 0x81300580, 0x04020004, 0x0201f800, 0x00106be2, + 0x0402000c, 0x59300004, 0x4803c857, 0x8c000520, + 0x04000004, 0x84000520, 0x48026004, 0x0401f005, + 0x0201f800, 0x00106619, 0x02020800, 0x00100615, + 0x5c03e000, 0x02000800, 0x00106982, 0x59300406, + 0x82000d80, 0x00000002, 0x04000009, 0x0201f800, + 0x00104a83, 0x0201f800, 0x00108f05, 0x02000800, + 0x00107da6, 0x8d3e7d00, 0x04000003, 0x0201f000, + 0x00107698, 0x4a02621d, 0x00000001, 0x4a026403, + 0x00000085, 0x4a026203, 0x00000009, 0x4a026406, + 0x00000002, 0x42000800, 0x8000004b, 0x0201f000, + 0x00020855, 0x4933c857, 0x59368c03, 0x4c180000, + 0x59300203, 0x82003480, 0x0000000e, 0x02021800, + 0x00100615, 0x0c01f803, 0x5c003000, 0x1c01f000, + 0x001096da, 0x00109bb9, 0x00109cbd, 0x001096da, + 0x001096da, 0x001096da, 0x001096da, 0x001096da, + 0x001096fd, 0x001096da, 0x001096da, 0x001096da, + 0x001096da, 0x001096da, 0x0201f800, 0x00100615, + 0x4933c857, 0x42028800, 0x0000ffff, 0x813669c0, + 0x04000002, 0x59368c03, 0x4c180000, 0x59300203, + 0x82003480, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f803, 0x5c003000, 0x1c01f000, 0x001096f9, + 0x00109f70, 0x001096f9, 0x001096f9, 0x001096f9, + 0x001096f9, 0x001096f9, 0x0010a779, 0x00109edd, + 0x0010a34a, 0x0010a380, 0x0010a34a, 0x0010a380, + 0x001096f9, 0x0201f800, 0x00100615, 0x0201f800, + 0x00100615, 0x83383480, 0x00000051, 0x02021800, + 0x00100615, 0x41380000, 0x493bc857, 0x4d1c0000, + 0x4d400000, 0x0c01f804, 0x5c028000, 0x5c023800, + 0x1c01f000, 0x0010975a, 0x0010993d, 0x0010975a, + 0x0010975a, 0x0010975a, 0x00109948, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, + 0x0010977c, 0x001097ba, 0x001097d1, 0x0010982d, + 0x00109894, 0x001098d2, 0x00109902, 0x0010975a, + 0x0010975a, 0x00109950, 0x0010975a, 0x0010975a, + 0x0010995e, 0x00109967, 0x0010975a, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x001099e9, + 0x0010975a, 0x0010975a, 0x00109868, 0x0010975a, + 0x0010975a, 0x001099c0, 0x0010975a, 0x0010975a, + 0x0010975a, 0x001099f7, 0x0010975a, 0x0010975a, + 0x0010975a, 0x00109a40, 0x0010975a, 0x0010975a, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010975a, + 0x00109a8d, 0x0010975a, 0x00109ab9, 0x00109ac4, + 0x0010975a, 0x0010975a, 0x0010975c, 0x00109acf, + 0x0010975a, 0x0010975a, 0x0010975a, 0x0010976b, + 0x0010975a, 0x0010975a, 0x0010975a, 0x00109ad6, + 0x00109ade, 0x00109afc, 0x0201f800, 0x00100615, + 0x4933c857, 0x0201f800, 0x0010a3b0, 0x040203a8, + 0x0201f800, 0x00101eb0, 0x040203a5, 0x59cc0407, + 0x4802601c, 0x4a026403, 0x00000045, 0x4a026203, + 0x00000001, 0x0201f000, 0x00106470, 0x4933c857, + 0x0201f800, 0x0010a3b0, 0x04020399, 0x0201f800, + 0x00101eb0, 0x04020396, 0x0401fbd6, 0x0402019e, + 0x59cc0007, 0x4802601c, 0x4a026403, 0x0000004a, + 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, + 0x4933c857, 0x0201f800, 0x00101eb0, 0x04020009, + 0x0201f800, 0x0010473b, 0x04020006, 0x82000500, + 0x00000009, 0x82000580, 0x00000008, 0x04020008, + 0x4a026403, 0x00000009, 0x4a02641a, 0x00000009, + 0x4a02621a, 0x00000000, 0x0401f1b6, 0x0201f800, + 0x00104858, 0x04000018, 0x0201f800, 0x0010a041, + 0x0402001f, 0x42028000, 0x00000029, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x0201f800, 0x00104480, 0x4a026403, 0x00000008, + 0x42003000, 0x00000003, 0x0201f800, 0x0010393e, + 0x040001a0, 0x4a026203, 0x00000007, 0x41782800, + 0x0401f18b, 0x0201f800, 0x0010a1ec, 0x040207e7, + 0x4a026403, 0x00000009, 0x4a02641a, 0x0000000e, + 0x4a02621a, 0x00001900, 0x0401f192, 0x4a026403, + 0x00000009, 0x4a02641a, 0x00000003, 0x4a02621a, + 0x00000f00, 0x0401f18b, 0x4933c857, 0x0201f800, + 0x00101eb0, 0x0402034a, 0x0201f800, 0x0010473b, + 0x04020347, 0x493a6403, 0x0201f800, 0x0010a01c, + 0x04020006, 0x42003000, 0x00000005, 0x4a026403, + 0x00000006, 0x0401f7d9, 0x4a026403, 0x00000007, + 0x4a02641a, 0x00000009, 0x4a02621a, 0x00000000, + 0x0401f174, 0x4933c857, 0x0201f800, 0x0010473b, + 0x04020333, 0x0201f800, 0x0010a3b0, 0x02000800, + 0x00101eb0, 0x0402032e, 0x0201f800, 0x00104858, + 0x04020005, 0x42027800, 0x00000001, 0x0201f800, + 0x001043bd, 0x0201f800, 0x0010484b, 0x04020031, + 0x59cc0206, 0x82003500, 0x00000003, 0x04020034, + 0x82003480, 0x00000014, 0x04001031, 0x5934300a, + 0x84183516, 0x82000580, 0x00000014, 0x04020002, + 0x84183556, 0x481a680a, 0x59cc0406, 0x82000500, + 0x00000003, 0x04020026, 0x0201f800, 0x0010a08e, + 0x0402002e, 0x0201f800, 0x00104836, 0x04020007, + 0x4c600000, 0x4178c000, 0x417a7800, 0x0201f800, + 0x00101e48, 0x5c00c000, 0x836c0580, 0x00000003, + 0x04020009, 0x42003000, 0x00000006, 0x0201f800, + 0x0010a75e, 0x42000000, 0x0010b664, 0x0201f800, + 0x0010a86e, 0x0201f800, 0x001044e1, 0x4a026403, + 0x0000000a, 0x42003000, 0x00000020, 0x0401f78f, + 0x4a026403, 0x0000000b, 0x4a02641a, 0x00000009, + 0x4a02621a, 0x00001e00, 0x0401f12a, 0x42000000, + 0x0010b65f, 0x0201f800, 0x0010a86e, 0x4a026403, + 0x0000000b, 0x4a02641a, 0x00000007, 0x4a02621a, + 0x00000000, 0x0401f11f, 0x4a026403, 0x0000000b, + 0x4a02641a, 0x00000003, 0x4a02621a, 0x00000000, + 0x0401f118, 0x4933c857, 0x0201f800, 0x0010473b, + 0x040202d7, 0x0201f800, 0x0010a3b0, 0x040202d4, + 0x0201f800, 0x00101eb0, 0x040202d1, 0x59cc0206, + 0x82003500, 0x00000003, 0x04020020, 0x82003480, + 0x00000014, 0x0400101d, 0x59cc0406, 0x82000500, + 0x00000003, 0x04020019, 0x59340400, 0x82000580, + 0x00000707, 0x0400001c, 0x417a7800, 0x4c600000, + 0x4178c000, 0x0201f800, 0x00101e48, 0x5c00c000, + 0x42003000, 0x0000000a, 0x0201f800, 0x0010a75e, + 0x42000000, 0x0010b661, 0x0201f800, 0x0010a86e, + 0x4a026403, 0x0000000c, 0x41782800, 0x42003000, + 0x00000021, 0x0401f749, 0x4a026403, 0x0000000d, + 0x4a02641a, 0x00000007, 0x4a02621a, 0x00000000, + 0x0401f0e4, 0x4a026403, 0x0000000d, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f0dd, + 0x4933c857, 0x0201f800, 0x0010473b, 0x0402029c, + 0x0201f800, 0x0010a3b0, 0x04020299, 0x0201f800, + 0x00101eb0, 0x04020296, 0x0401fad6, 0x0402001a, + 0x493a6403, 0x4c5c0000, 0x0401fadc, 0x0402000e, + 0x4a026403, 0x0000002e, 0x4014b800, 0x0201f800, + 0x0010393e, 0x0400000e, 0x4a026203, 0x00000007, + 0x405c2800, 0x42003000, 0x00000024, 0x5c00b800, + 0x0401f0af, 0x4a026403, 0x0000000d, 0x4a02641a, + 0x00000007, 0x4a02621a, 0x00000000, 0x5c00b800, + 0x0401f0b8, 0x4a026403, 0x0000000d, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00001e00, 0x0401f0b1, + 0x4933c857, 0x0201f800, 0x0010473b, 0x040206f1, + 0x59a80026, 0x82000500, 0x00000009, 0x82000580, + 0x00000008, 0x040006eb, 0x0201f800, 0x0010484b, + 0x0402002d, 0x0201f800, 0x0010a096, 0x04020007, + 0x4a026403, 0x0000000e, 0x41782800, 0x42003000, + 0x00000052, 0x0401f6f9, 0x4933c857, 0x42003000, + 0x00000003, 0x0201f800, 0x0010a766, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x59340200, 0x84000558, 0x48026a00, 0x42000800, + 0x0000000b, 0x0201f800, 0x001043c7, 0x0201f800, + 0x0010393e, 0x0400007c, 0x42003000, 0x00000007, + 0x0401f061, 0x4933c857, 0x4a026403, 0x0000000f, + 0x4a02641a, 0x00000003, 0x4a02621a, 0x00001e00, + 0x0401f078, 0x59340400, 0x82000580, 0x00000703, + 0x040007f5, 0x0401f040, 0x4933c857, 0x0201f800, + 0x0010473b, 0x04020232, 0x59a80026, 0x82000500, + 0x00000009, 0x82000580, 0x00000008, 0x0400022c, + 0x0201f800, 0x00104842, 0x0402002f, 0x0201f800, + 0x0010a0b1, 0x02000800, 0x0010a041, 0x04020007, + 0x4a026403, 0x00000010, 0x41782800, 0x42003000, + 0x00000050, 0x0401f6b9, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x00101de2, 0x5c027800, 0x42003000, + 0x00000003, 0x0201f800, 0x0010a766, 0x42000000, + 0x0010b663, 0x0201f800, 0x0010a86e, 0x59340200, + 0x84000558, 0x48026a00, 0x0401f7c5, 0x4a026403, + 0x00000011, 0x4a02641a, 0x00000003, 0x4a02621a, + 0x00001e00, 0x0401f043, 0x4933c857, 0x0201f800, + 0x00101eb0, 0x02000800, 0x0010a3b0, 0x04020200, + 0x0401fa40, 0x04020008, 0x4a026403, 0x00000012, + 0x0401f038, 0x59340400, 0x82000580, 0x00000703, + 0x040007eb, 0x4d3c0000, 0x417a7800, 0x42028000, + 0x00000029, 0x0201f800, 0x00101de2, 0x5c027800, + 0x42003000, 0x00000017, 0x0201f800, 0x0010a766, + 0x42000000, 0x0010b663, 0x0201f800, 0x0010a86e, + 0x0201f800, 0x0010393e, 0x0400001b, 0x42003000, + 0x00000006, 0x42028000, 0x00000029, 0x4933c857, + 0x4a026403, 0x00000001, 0x4a026203, 0x00000007, + 0x4c180000, 0x0201f800, 0x0010a79b, 0x5c003000, + 0x41782800, 0x0201f000, 0x0010a250, 0x42028000, + 0x00000046, 0x4c140000, 0x4c180000, 0x0201f800, + 0x0010a79b, 0x5c003000, 0x5c002800, 0x0201f000, + 0x0010a250, 0x4933c857, 0x4a026403, 0x00000001, + 0x42000800, 0x0000000b, 0x0201f800, 0x001043c7, + 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, + 0x4933c857, 0x42000800, 0x00000009, 0x0201f800, + 0x001043c7, 0x4a026403, 0x00000005, 0x0401f7f5, + 0x0201f800, 0x0010a3b0, 0x040201b5, 0x0201f800, + 0x00101eb0, 0x040201b2, 0x0401f9f2, 0x040207ba, + 0x4a026403, 0x00000020, 0x4a026203, 0x00000001, + 0x0201f000, 0x00106470, 0x0201f800, 0x00101eb0, + 0x040201a7, 0x4a026403, 0x00000023, 0x4a026203, + 0x00000001, 0x0201f000, 0x00106470, 0x0201f800, + 0x0010a3b0, 0x02000800, 0x00101eb0, 0x0402019c, + 0x0401f9dc, 0x040207a4, 0x40300800, 0x59a81010, + 0x59cc0007, 0x82000500, 0x00ffffff, 0x80080580, + 0x04000019, 0x59cc1408, 0x0201f800, 0x00108de9, + 0x0400002d, 0x59cc0c08, 0x4d300000, 0x0201f800, + 0x00105b0f, 0x41323800, 0x5c026000, 0x04000026, + 0x591c0202, 0x82000580, 0x0000ffff, 0x04000005, + 0x59cc1208, 0x591c0202, 0x80080580, 0x0402001e, + 0x591c0406, 0x82000580, 0x00000007, 0x0402001a, + 0x0401f02c, 0x59cc1208, 0x82080580, 0x0000ffff, + 0x0400000c, 0x0201f800, 0x001091d9, 0x04000012, + 0x59cc1408, 0x591c0202, 0x80080580, 0x0402000e, + 0x591c0009, 0x81340580, 0x04000016, 0x0401f00a, + 0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a217, + 0x04020010, 0x59cc1208, 0x82080580, 0x0000ffff, + 0x04000019, 0x4a026403, 0x00000026, 0x4a02621a, + 0x00001700, 0x59cc1204, 0x82081580, 0x0000ffff, + 0x04020798, 0x4a026403, 0x00000025, 0x0401f795, + 0x591c0406, 0x82000580, 0x00000007, 0x040207f2, + 0x591c0403, 0x82000580, 0x00000024, 0x04020006, + 0x4d300000, 0x411e6000, 0x0201f800, 0x000208b4, + 0x5c026000, 0x4a026403, 0x00000025, 0x0401f785, + 0x4933c857, 0x4d3c0000, 0x42027800, 0x00000001, + 0x0201f800, 0x001043bd, 0x5c027800, 0x4c580000, + 0x4200b000, 0x00000002, 0x83a81c00, 0x00000002, + 0x83cc1400, 0x0000000b, 0x0201f800, 0x001082ff, + 0x5c00b000, 0x04000004, 0x4a026403, 0x00000031, + 0x0401f770, 0x0201f800, 0x00107698, 0x0201f800, + 0x00104e0d, 0x0402000f, 0x0201f800, 0x00104e1b, + 0x04020008, 0x4a035033, 0x00000001, 0x4202d800, + 0x00000001, 0x0201f800, 0x00104d76, 0x0401f005, + 0x42000000, 0x00000001, 0x0201f800, 0x00104de5, + 0x1c01f000, 0x0201f800, 0x00101eb0, 0x0402011c, + 0x0401f95c, 0x04020724, 0x493a6403, 0x0401f9ac, + 0x04020004, 0x4a026403, 0x0000002b, 0x0401f751, + 0x4a026403, 0x0000002c, 0x0401f74e, 0x4933c857, + 0x0201f800, 0x00101eb0, 0x0402010d, 0x0201f800, + 0x00104836, 0x04020740, 0x0201f800, 0x00104728, + 0x0400003c, 0x59cc0408, 0x48026419, 0x59cc0208, + 0x48026219, 0x59cc0807, 0x59340002, 0x82000500, + 0x00ffffff, 0x80040580, 0x04000012, 0x59a80010, + 0x80040580, 0x04020021, 0x59cc1408, 0x0201f800, + 0x001091d9, 0x04000023, 0x0201f800, 0x0010a2e8, + 0x04000020, 0x0201f800, 0x0010a745, 0x0400001d, + 0x491e601e, 0x4a026403, 0x00000036, 0x0401f0e6, + 0x59cc1208, 0x82080580, 0x0000ffff, 0x04000009, + 0x0201f800, 0x001091d9, 0x04000012, 0x591c0202, + 0x59cc0c08, 0x80040580, 0x0402000e, 0x0401f7eb, + 0x59cc1408, 0x41327800, 0x0201f800, 0x0010a217, + 0x04000008, 0x0401f7e5, 0x4803c856, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00001500, 0x0401f006, + 0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a, + 0x00001700, 0x4a026403, 0x00000037, 0x0401f0c6, + 0x4803c856, 0x4a026403, 0x00000012, 0x0401f0c2, + 0x4933c857, 0x0201f800, 0x00101eb0, 0x040200c4, + 0x0201f800, 0x00104836, 0x040206f7, 0x0201f800, + 0x00104728, 0x0400003e, 0x59cc0407, 0x48026419, + 0x59cc1207, 0x480a6219, 0x82080580, 0x0000ffff, + 0x04000005, 0x0201f800, 0x001091d9, 0x0400002c, + 0x0401f006, 0x59cc1407, 0x41327800, 0x0201f800, + 0x0010a217, 0x04000026, 0x59cc0c07, 0x591c0202, + 0x80040580, 0x04020022, 0x4d300000, 0x411e6000, + 0x0201f800, 0x0010898b, 0x5c026000, 0x59cc0c09, + 0x82040d00, 0x0000ff00, 0x840409c0, 0x0201f800, + 0x0010a745, 0x04000016, 0x82040580, 0x00000001, + 0x0400000a, 0x82040580, 0x00000005, 0x04000004, + 0x82040580, 0x00000007, 0x04020007, 0x591c0008, + 0x80000540, 0x04000004, 0x59cc2808, 0x0201f000, + 0x0010a2fc, 0x4803c856, 0x4a02641a, 0x00000009, + 0x4a02621a, 0x00002a00, 0x0401f006, 0x4803c856, + 0x4a02641a, 0x00000003, 0x4a02621a, 0x00000300, + 0x4a026403, 0x0000003b, 0x0401f07b, 0x4803c856, + 0x4a02641a, 0x0000000b, 0x4a02621a, 0x00000000, + 0x0401f7f8, 0x4c080000, 0x0201f800, 0x0010473b, + 0x04000026, 0x0201f800, 0x00104711, 0x0201f800, + 0x0010a41c, 0x0402001e, 0x59a80026, 0x82000540, + 0x00000003, 0x48035026, 0x59a8001d, 0x800000d0, + 0x59a80810, 0x82040d00, 0x000000ff, 0x80041540, + 0x480b5010, 0x42000800, 0x00000003, 0x0201f800, + 0x001069af, 0x497b5028, 0x0201f800, 0x0010393e, + 0x04000003, 0x4a032804, 0x000007d0, 0x8c00050a, + 0x0402000a, 0x0201f800, 0x000208b4, 0x0201f800, + 0x00101bf0, 0x5c001000, 0x1c01f000, 0x0201f800, + 0x0010a43e, 0x0401f7fc, 0x5c001000, 0x0201f000, + 0x000208b4, 0x0201f800, 0x00101eb0, 0x0402004c, + 0x0201f800, 0x0010a443, 0x4a026403, 0x00000047, + 0x4a026203, 0x00000001, 0x0201f000, 0x00106470, + 0x0201f800, 0x00101eb0, 0x04020041, 0x0201f800, + 0x0010a443, 0x4a026403, 0x00000047, 0x4a026203, + 0x00000001, 0x0201f000, 0x00106470, 0x0201f800, + 0x00101eb0, 0x04020036, 0x0201f800, 0x0010a443, + 0x0201f000, 0x000208b4, 0x0401f834, 0x04000030, + 0x4a026403, 0x0000004e, 0x4a026203, 0x00000001, + 0x0201f000, 0x00106470, 0x4a026403, 0x0000004f, + 0x497a601c, 0x59cc0a06, 0x82040d00, 0x000000ff, + 0x800409c0, 0x0400065f, 0x82040580, 0x00000001, + 0x04020005, 0x59cc0808, 0x59a80005, 0x80040580, + 0x04000658, 0x82040580, 0x00000002, 0x0402000a, + 0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000006, 0x0201f800, 0x001082ff, + 0x0400064c, 0x4a02601c, 0x00000001, 0x0401f649, + 0x4a026403, 0x00000050, 0x59cc0207, 0x4802601c, + 0x0401f644, 0x4a026203, 0x00000001, 0x42000800, + 0x80000040, 0x0201f000, 0x00020855, 0x4803c857, + 0x0201f000, 0x000208b4, 0x4d2c0000, 0x4c500000, + 0x4c580000, 0x4c540000, 0x59a80016, 0x82000c80, + 0x00000841, 0x0402102d, 0x0201f800, 0x00100819, + 0x0400002a, 0x492e6008, 0x59a80016, 0x48025802, + 0x82000400, 0x00000003, 0x80000104, 0x83cca400, + 0x00000006, 0x82000c80, 0x0000000b, 0x04001015, + 0x4a025811, 0x0000000b, 0x4200b000, 0x0000000b, + 0x832c0400, 0x00000005, 0x4000a800, 0x0201f800, + 0x0010a93e, 0x412c7000, 0x800409c0, 0x04020003, + 0x49787001, 0x0401f00e, 0x0201f800, 0x00100819, + 0x0400000e, 0x492c7001, 0x40040000, 0x0401f7ea, + 0x48025811, 0x4000b000, 0x832c0400, 0x00000005, + 0x4000a800, 0x0201f800, 0x0010a93e, 0x82000540, + 0x00000001, 0x0401f006, 0x497b5016, 0x59325808, + 0x0201f800, 0x00100843, 0x80000580, 0x5c00a800, + 0x5c00b000, 0x5c00a000, 0x5c025800, 0x1c01f000, + 0x4d340000, 0x59326809, 0x59343400, 0x4933c857, + 0x4937c857, 0x481bc857, 0x0201f800, 0x00104842, + 0x5c026800, 0x1c01f000, 0x4933c857, 0x4c600000, + 0x4c5c0000, 0x4d3c0000, 0x4d440000, 0x4d340000, + 0x0401f84f, 0x04020037, 0x59cc0207, 0x82000d00, + 0x0000ff00, 0x900411c0, 0x59cc000a, 0x82000500, + 0x00ffffff, 0x80081540, 0x480a601c, 0x8c040d18, + 0x04000011, 0x42003000, 0x00000008, 0x0201f800, + 0x0010a756, 0x42000000, 0x0010b662, 0x0201f800, + 0x0010a86e, 0x4200b800, 0x00000002, 0x4200c000, + 0x00000001, 0x417a7800, 0x0201f800, 0x00101e48, + 0x0401f01f, 0x4178b800, 0x8c040d1a, 0x04000019, + 0x59cc000a, 0x0201f800, 0x001059b9, 0x02000800, + 0x00020267, 0x04020013, 0x59300009, 0x4c000000, + 0x49366009, 0x42003000, 0x00000009, 0x0201f800, + 0x0010a75e, 0x42000000, 0x0010b662, 0x0201f800, + 0x0010a86e, 0x417a7800, 0x4178c000, 0x0201f800, + 0x00101e48, 0x5c000000, 0x48026009, 0x0401f004, + 0x82000540, 0x00000001, 0x0401f003, 0x405c2800, + 0x80000580, 0x5c026800, 0x5c028800, 0x5c027800, + 0x5c00b800, 0x5c00c000, 0x1c01f000, 0x4933c857, + 0x59cc0206, 0x82000480, 0x00000010, 0x04021006, + 0x4a02621a, 0x00000000, 0x82000540, 0x00000001, + 0x0401f002, 0x80000580, 0x1c01f000, 0x4933c857, + 0x4a02621a, 0x00000000, 0x59cc0407, 0x82000500, + 0x0000ff00, 0x82000580, 0x00000800, 0x04020009, + 0x59cc0006, 0x82000500, 0x00ff0000, 0x82000d80, + 0x00140000, 0x04000003, 0x82000d80, 0x00100000, + 0x1c01f000, 0x59300403, 0x82003480, 0x00000051, + 0x02021800, 0x00100615, 0x83383580, 0x00000013, + 0x04020003, 0x4803c857, 0x0c01f016, 0x4933c857, + 0x493bc857, 0x83383580, 0x00000027, 0x04000005, + 0x83383580, 0x00000014, 0x02020800, 0x00100615, + 0x493bc857, 0x4937c857, 0x0201f800, 0x00104711, + 0x42000800, 0x00000007, 0x0201f800, 0x001043c7, + 0x0201f800, 0x001068f6, 0x0201f000, 0x00107698, + 0x00109c29, 0x00109c32, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c32, 0x00109c3d, 0x00109cb0, + 0x00109c82, 0x00109cb0, 0x00109c9a, 0x00109cb0, + 0x00109ca1, 0x00109cb0, 0x00109ca9, 0x00109cb0, + 0x00109ca9, 0x00109cb0, 0x00109cb0, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c32, 0x00109c29, + 0x00109cb0, 0x00109c29, 0x00109c29, 0x00109cb0, + 0x00109c29, 0x00109cad, 0x00109cb0, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c29, 0x00109cb0, + 0x00109cb0, 0x00109c29, 0x00109ca6, 0x00109cb0, + 0x00109c29, 0x00109c37, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109cac, 0x00109cb0, + 0x00109c29, 0x00109c29, 0x00109cb0, 0x00109cb0, + 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c29, 0x00109c29, + 0x00109c29, 0x00109c2b, 0x00109c29, 0x00109c2b, + 0x00109c29, 0x00109c29, 0x00109c2b, 0x00109c29, + 0x00109c29, 0x00109c29, 0x00109c2b, 0x00109c2b, + 0x00109c2b, 0x0201f800, 0x00100615, 0x4d2c0000, + 0x59325808, 0x0201f800, 0x00100843, 0x5c025800, + 0x0201f000, 0x000208b4, 0x59a80037, 0x48026206, + 0x4a026203, 0x00000002, 0x1c01f000, 0x4d3c0000, + 0x417a7800, 0x0201f800, 0x001043bd, 0x5c027800, + 0x0401f074, 0x42000800, 0x00000007, 0x0201f800, + 0x001043c7, 0x59a80026, 0x8c000508, 0x04000012, + 0x59326809, 0x4c580000, 0x4200b000, 0x00000002, + 0x83a81c00, 0x00000002, 0x83341400, 0x00000006, + 0x0201f800, 0x001082ff, 0x80000540, 0x5c00b000, + 0x04020060, 0x59340200, 0x8400051a, 0x48026a00, + 0x0401f01b, 0x599c0017, 0x8c00050a, 0x04020059, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x001043bd, + 0x5c027800, 0x42000800, 0x00000007, 0x0201f800, + 0x001043c7, 0x59340212, 0x82000500, 0x0000ff00, + 0x0400004c, 0x599c0019, 0x8c00050e, 0x04020049, + 0x416c0000, 0x82000580, 0x00000002, 0x04020004, + 0x59a8001b, 0x80000000, 0x4803501b, 0x42000800, + 0x00000003, 0x0201f800, 0x001043c7, 0x4a026406, + 0x00000001, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000002, 0x0201f800, 0x00106470, 0x4ce80000, + 0x4201d000, 0x00000001, 0x0201f800, 0x00105ce7, + 0x5c01d000, 0x1c01f000, 0x0201f800, 0x00104842, + 0x0400002c, 0x0201f800, 0x00106196, 0x42000800, + 0x00000004, 0x0201f800, 0x001043c7, 0x0201f800, + 0x0010a791, 0x04020023, 0x42000800, 0x00000005, + 0x0201f800, 0x001043c7, 0x4a026406, 0x00000001, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000003, + 0x0201f000, 0x00106470, 0x0201f800, 0x0010484b, + 0x04020014, 0x42000800, 0x00000006, 0x0401f813, + 0x0401f010, 0x42000800, 0x00000004, 0x0201f800, + 0x001043c7, 0x0401f79c, 0x42000800, 0x00000004, + 0x0401f006, 0x0201f800, 0x00104711, 0x0401f005, + 0x0401f004, 0x0401f003, 0x0201f800, 0x001043c7, + 0x0201f000, 0x000208b4, 0x4933c857, 0x4807c857, + 0x0201f800, 0x001043c7, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x001043bd, 0x5c027800, 0x0201f000, + 0x00104711, 0x59340400, 0x4803c857, 0x80000110, + 0x82003480, 0x0000000c, 0x02021800, 0x00100615, + 0x83383580, 0x00000015, 0x04020002, 0x0c01f006, + 0x83383580, 0x00000016, 0x02020800, 0x00100615, + 0x0c01f00d, 0x00107e42, 0x00107e42, 0x00107e42, + 0x00107e42, 0x00107e42, 0x00107e42, 0x00109d11, + 0x00109ce5, 0x00107e42, 0x00107e42, 0x00107e42, + 0x00107e42, 0x00107e42, 0x00107e42, 0x00107e42, + 0x00107e42, 0x00107e42, 0x00107e42, 0x00109d11, + 0x00109d18, 0x00107e42, 0x00107e42, 0x00107e42, + 0x00107e42, 0x4933c857, 0x599c0017, 0x8c00050a, + 0x0402001b, 0x813669c0, 0x04000019, 0x59340212, + 0x82000500, 0x0000ff00, 0x04000015, 0x599c0019, + 0x8c00050e, 0x04020012, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x001043bd, 0x5c027800, 0x42000800, + 0x00000003, 0x0201f800, 0x001043c7, 0x4a026406, + 0x00000001, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000002, 0x0201f000, 0x00106470, 0x59cc0001, + 0x59340802, 0x80040580, 0x82000500, 0x00ffffff, + 0x02020000, 0x000208b4, 0x59345002, 0x0201f800, + 0x001040e4, 0x482a6802, 0x0201f000, 0x000208b4, + 0x1c01f000, 0x4933c857, 0x59303403, 0x82183580, + 0x0000001e, 0x02000000, 0x000208b4, 0x1c01f000, + 0x4933c857, 0x0201f800, 0x00108180, 0x02020000, + 0x000208b4, 0x4a026203, 0x00000001, 0x4a026403, + 0x00000001, 0x0201f000, 0x00106470, 0x493bc857, + 0x83380580, 0x00000051, 0x0402000b, 0x0201f800, + 0x00106cb4, 0x02020000, 0x001076fb, 0x59300203, + 0x82000580, 0x00000002, 0x0400006e, 0x0201f800, + 0x00100615, 0x83380580, 0x00000027, 0x04000014, + 0x83380580, 0x00000048, 0x04000006, 0x83380580, + 0x00000014, 0x0400000e, 0x02020800, 0x00100615, + 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, + 0x59300203, 0x82000580, 0x00000004, 0x02000000, + 0x000209a5, 0x0201f800, 0x00100615, 0x4933c857, + 0x59300403, 0x82000c80, 0x00000044, 0x02021800, + 0x00100615, 0x82000480, 0x00000040, 0x02001800, + 0x00100615, 0x40027000, 0x4803c857, 0x0c01f001, + 0x00109d58, 0x00109d5a, 0x00109d5a, 0x00109d75, + 0x0201f800, 0x00100615, 0x0201f800, 0x001068f6, + 0x59325808, 0x812e59c0, 0x04000016, 0x832c0500, + 0x00ff0000, 0x04000013, 0x4a026203, 0x00000002, + 0x59326809, 0x59340200, 0x8c00050e, 0x0402000d, + 0x42028000, 0x00000004, 0x0201f800, 0x0010a201, + 0x497a6008, 0x59300206, 0x80000540, 0x04020003, + 0x59a80038, 0x48026206, 0x4a026203, 0x00000007, + 0x1c01f000, 0x0201f800, 0x001068f6, 0x0201f800, + 0x00108df4, 0x02000000, 0x00107698, 0x59325808, + 0x0201f800, 0x0010083a, 0x0201f000, 0x00107698, + 0x0201f800, 0x00100615, 0x59325808, 0x592c040a, + 0x8c000502, 0x04000007, 0x4a026203, 0x00000007, + 0x42027000, 0x00000043, 0x0201f000, 0x000208d8, + 0x4a026203, 0x00000004, 0x1c01f000, 0x0201f800, + 0x0010a3b6, 0x02000000, 0x000209a3, 0x1c01f000, + 0x4a026203, 0x00000001, 0x4a026403, 0x00000041, + 0x42027800, 0x80002042, 0x0201f000, 0x00020855, + 0x83380580, 0x00000051, 0x04000006, 0x83380580, + 0x00000041, 0x02020800, 0x00100615, 0x1c01f000, + 0x0201f800, 0x00020831, 0x0201f800, 0x0010a3fa, + 0x0201f000, 0x000208b4, 0x83380480, 0x00000052, + 0x02021800, 0x00100615, 0x83380480, 0x00000049, + 0x02001800, 0x00100615, 0x0c01f001, 0x00109dbe, + 0x00109ddf, 0x00109dbc, 0x00109dbc, 0x00109dbc, + 0x00109dbc, 0x00109ddf, 0x00109dbc, 0x00109e01, + 0x0201f800, 0x00100615, 0x59325808, 0x592c040a, + 0x8c00051e, 0x0400000d, 0x82000d00, 0x000000c0, + 0x82040d80, 0x00000080, 0x0400000d, 0x59300804, + 0x8c040d18, 0x0402000a, 0x42027000, 0x00000041, + 0x0201f000, 0x000209c4, 0x4a026203, 0x00000007, + 0x497a6206, 0x0201f000, 0x00020831, 0x59325808, + 0x592c0c0a, 0x8c040d1a, 0x04020005, 0x0201f800, + 0x00020831, 0x0201f000, 0x000208b4, 0x0201f800, + 0x0010a3b6, 0x040007fa, 0x1c01f000, 0x0201f800, + 0x001068c1, 0x59325808, 0x59326809, 0x59340200, + 0x8c00050e, 0x0400000e, 0x592c040a, 0x82000500, + 0x000000c0, 0x82000580, 0x00000080, 0x04000005, + 0x592c000f, 0x59301815, 0x800c1c80, 0x480e6015, + 0x4a026203, 0x00000002, 0x0401f00e, 0x42028000, + 0x00000004, 0x0201f800, 0x0010a201, 0x59300206, + 0x80000540, 0x04020004, 0x59a80038, 0x800000c2, + 0x48026206, 0x497a6008, 0x4a026203, 0x00000007, + 0x1c01f000, 0x4933c857, 0x0201f800, 0x00106cb4, + 0x02020800, 0x00100615, 0x59300203, 0x82000580, + 0x00000002, 0x04000793, 0x0201f800, 0x00100615, + 0x4a026203, 0x00000007, 0x497a6206, 0x0201f000, + 0x00020831, 0x4a026203, 0x00000007, 0x497a6206, + 0x0201f000, 0x0002082c, 0x59300414, 0x8c00051c, + 0x02020000, 0x000209b5, 0x59325808, 0x592c200f, + 0x40080000, 0x80102480, 0x59300015, 0x80102400, + 0x48126015, 0x0201f000, 0x000209b5, 0x8c040d0e, + 0x0402000a, 0x4a026203, 0x00000006, 0x0401f823, + 0x5930001f, 0x80000540, 0x02020800, 0x00100dc4, + 0x0201f000, 0x0002082c, 0x4a026203, 0x00000002, + 0x1c01f000, 0x42000800, 0x00000001, 0x0201f800, + 0x00100dc4, 0x82040580, 0x00000001, 0x02000000, + 0x000209bc, 0x0401f7d8, 0x59300414, 0x8c00051c, + 0x04000006, 0x0201f800, 0x00100bad, 0x02000000, + 0x000209ae, 0x1c01f000, 0x59300011, 0x80000540, + 0x04020005, 0x0201f800, 0x00100bad, 0x02000000, + 0x000209ae, 0x1c01f000, 0x492fc857, 0x480bc857, + 0x8c08153e, 0x04000006, 0x80081080, 0x80081000, + 0x42000800, 0x00000009, 0x0401f003, 0x42000800, + 0x00000015, 0x480a580b, 0x1c01f000, 0x83380580, + 0x00000013, 0x04000005, 0x83380580, 0x00000014, + 0x02020800, 0x00100615, 0x59300414, 0x8c000516, + 0x02000800, 0x00100615, 0x1c01f000, 0x0201f800, + 0x00100615, 0x59300008, 0x80000540, 0x02020800, + 0x00100615, 0x1c01f000, 0x59300414, 0x8c000516, + 0x02000800, 0x00100615, 0x1c01f000, 0x4a026203, + 0x00000004, 0x493a6403, 0x42000800, 0x80002001, + 0x0201f000, 0x00020855, 0x4a026203, 0x00000003, + 0x493a6403, 0x0201f800, 0x000200ca, 0x59325808, + 0x592c040a, 0x8c00051e, 0x04000012, 0x82000500, + 0x000000c0, 0x82000580, 0x00000080, 0x04000011, + 0x59300414, 0x8c000512, 0x0402000a, 0x8c000510, + 0x04020008, 0x592c040c, 0x80000540, 0x04020005, + 0x82080d40, 0x80003065, 0x0201f000, 0x00106466, + 0x82080d40, 0x80002065, 0x0201f000, 0x00106466, + 0x82080d40, 0x80002042, 0x0201f000, 0x00106466, + 0x4933c857, 0x493bc857, 0x83380480, 0x00000044, + 0x02021800, 0x00100615, 0x83380480, 0x00000041, + 0x02001800, 0x00100615, 0x0c01f001, 0x00109ea6, + 0x00109eb6, 0x00109ecb, 0x59325808, 0x592c040a, + 0x8c00051e, 0x0400001d, 0x82001d00, 0x000000c0, + 0x820c1d80, 0x000000c0, 0x04000018, 0x4a026203, + 0x00000001, 0x493a6403, 0x42000800, 0x80002042, + 0x0201f000, 0x00020855, 0x59325808, 0x592c040a, + 0x8c00051e, 0x0400000d, 0x82001d00, 0x000000c0, + 0x820c1d80, 0x000000c0, 0x04000008, 0x4a026203, + 0x00000001, 0x493a6403, 0x42000800, 0x80002001, + 0x0201f000, 0x00020855, 0x497a6008, 0x497a6206, + 0x42028000, 0x00000004, 0x0401f337, 0x59325808, + 0x592c040a, 0x8c00051e, 0x040007f8, 0x82001d00, + 0x000000c0, 0x820c1d80, 0x000000c0, 0x040007f3, + 0x4a026203, 0x00000003, 0x493a6403, 0x0201f800, + 0x000200ca, 0x82080d40, 0x80002065, 0x0201f000, + 0x00106466, 0x4933c857, 0x493bc857, 0x83380580, + 0x00000085, 0x04000006, 0x83380580, 0x00000088, + 0x0400000a, 0x0201f800, 0x00100615, 0x4a026203, + 0x00000009, 0x493a6403, 0x42000800, 0x8000004b, + 0x0201f000, 0x00020855, 0x4d1c0000, 0x813669c0, + 0x04000004, 0x0201f800, 0x0010a3b0, 0x04020044, + 0x59cc1404, 0x0401f846, 0x04000018, 0x591c0406, + 0x82000500, 0x0000001f, 0x82002580, 0x00000006, + 0x04000007, 0x82002580, 0x00000004, 0x0400002e, + 0x82002580, 0x00000011, 0x0402000c, 0x497a3a05, + 0x42002000, 0x00000054, 0x0201f800, 0x001077d1, + 0x4a026203, 0x00000007, 0x493a6403, 0x0201f800, + 0x0010a79b, 0x0401f02c, 0x0201f800, 0x0010393e, + 0x04000004, 0x42023800, 0xffffffff, 0x0401f7f1, + 0x813669c0, 0x04020009, 0x59cc0001, 0x0201f800, + 0x001059b9, 0x0402001e, 0x0201f800, 0x001043fc, + 0x0402001b, 0x49366009, 0x4a026403, 0x00000087, + 0x59cc1204, 0x82081580, 0x0000ffff, 0x04020003, + 0x4a026403, 0x00000086, 0x4a026203, 0x00000001, + 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x0401f00d, 0x591c0203, 0x82000580, 0x00000007, + 0x040207de, 0x4d300000, 0x411e6000, 0x0201f800, + 0x00107698, 0x5c026000, 0x0401f7d8, 0x0201f800, + 0x00107698, 0x5c023800, 0x1c01f000, 0x4933c857, + 0x480bc857, 0x42002800, 0x0010cfc0, 0x41300000, + 0x80140580, 0x04000017, 0x58140203, 0x82000580, + 0x00000000, 0x04000013, 0x58140202, 0x80080580, + 0x04020010, 0x58141c06, 0x820c0580, 0x00000005, + 0x0400000c, 0x820c0580, 0x00000009, 0x0400001d, + 0x59302009, 0x58140009, 0x800001c0, 0x0400000b, + 0x801021c0, 0x04000003, 0x80100580, 0x04000010, + 0x82142c00, 0x00000024, 0x41540000, 0x80140480, + 0x0402100e, 0x0401f7e2, 0x5814001e, 0x801021c0, + 0x04000005, 0x58102002, 0x82102500, 0x00ffffff, + 0x0401f7f2, 0x5810201e, 0x0401f7f0, 0x40163800, + 0x81300540, 0x0401f002, 0x80000580, 0x1c01f000, + 0x58141807, 0x8c0c1d10, 0x040207ea, 0x0401f7e1, + 0x83380580, 0x00000013, 0x0402000e, 0x59300403, + 0x4803c857, 0x82000c80, 0x00000085, 0x02001800, + 0x00100615, 0x82000c80, 0x00000093, 0x02021800, + 0x00100615, 0x82000480, 0x00000085, 0x0c01f019, + 0x83380580, 0x00000027, 0x04000005, 0x83380580, + 0x00000014, 0x02020000, 0x001076fb, 0x493bc857, + 0x0201f800, 0x001068f6, 0x59325808, 0x812e59c0, + 0x02000000, 0x00107698, 0x4a025a06, 0x00000031, + 0x4a025811, 0x00000004, 0x4a025812, 0x000000ff, + 0x0201f800, 0x00020381, 0x0201f000, 0x00107698, + 0x00109fa6, 0x00109fad, 0x00109fad, 0x00109fa6, + 0x00109fa6, 0x00109fa6, 0x00109fa6, 0x00109fa6, + 0x00109fa6, 0x00109fa6, 0x00109fa6, 0x00109fa6, + 0x00109fa6, 0x00109fa8, 0x0201f800, 0x00100615, + 0x59325808, 0x4a025a06, 0x00000000, 0x0201f800, + 0x00020381, 0x0201f000, 0x000208b4, 0x4933c857, + 0x42000000, 0x0010b672, 0x0201f800, 0x0010a86e, + 0x0201f800, 0x0010a3fa, 0x497a6205, 0x42028000, + 0x0000000b, 0x0401f807, 0x4a026406, 0x00000006, + 0x4a026203, 0x00000007, 0x497a6206, 0x1c01f000, + 0x4933c857, 0x4943c857, 0x59300406, 0x82000580, + 0x00000007, 0x04020002, 0x1c01f000, 0x0201f800, + 0x0010698c, 0x4df00000, 0x0201f800, 0x00108a99, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f001, 0x00109ff4, 0x00109ff8, 0x00109fdf, + 0x0010a006, 0x0010a019, 0x00109fdf, 0x00109fdf, + 0x00109fdf, 0x00109fdf, 0x00109fdf, 0x00109fdf, + 0x00109fdf, 0x00109fdf, 0x00109fdf, 0x4d400000, + 0x5930001f, 0x80000540, 0x04000005, 0x41400800, + 0x0201f800, 0x00100dc4, 0x40068000, 0x4d2c0000, + 0x59325808, 0x0201f800, 0x00108df4, 0x04020a16, + 0x4c5c0000, 0x5930b809, 0x0201f800, 0x00107698, + 0x485e6009, 0x5c00b800, 0x5c025800, 0x5c028000, + 0x5c03e000, 0x02000000, 0x00106982, 0x1c01f000, + 0x598c000d, 0x81300580, 0x04020004, 0x0201f800, + 0x00106be2, 0x04020016, 0x0201f800, 0x00106619, + 0x040007df, 0x0201f800, 0x001068a3, 0x04000010, + 0x0201f800, 0x00100615, 0x0201f800, 0x00108a8a, + 0x04020004, 0x0201f800, 0x00106bb2, 0x04020008, + 0x0201f800, 0x001064f6, 0x040007d1, 0x0201f800, + 0x001068a3, 0x02020800, 0x00100615, 0x59300203, + 0x82000c80, 0x0000000e, 0x02021800, 0x00100615, + 0x0c01f7b9, 0x0201f800, 0x00100ee4, 0x0401f7c4, + 0x4933c857, 0x4d440000, 0x4d340000, 0x59cc0007, + 0x0201f800, 0x001059b9, 0x02000800, 0x00020267, + 0x0402001a, 0x59300009, 0x4c000000, 0x49366009, + 0x42003000, 0x0000000b, 0x0201f800, 0x0010a766, + 0x42000000, 0x0010b660, 0x0201f800, 0x0010a86e, + 0x4d3c0000, 0x4d400000, 0x42028000, 0x00000029, + 0x417a7800, 0x0201f800, 0x00101de2, 0x5c028000, + 0x5c027800, 0x5c000000, 0x48026009, 0x59cc0007, + 0x48026802, 0x80000580, 0x5c026800, 0x5c028800, + 0x1c01f000, 0x4933c857, 0x4c040000, 0x59a80016, + 0x82000580, 0x00000074, 0x04020040, 0x59cc0a08, + 0x82040480, 0x00000100, 0x04001033, 0x59cc0c08, + 0x82040500, 0x00008000, 0x04000035, 0x59a80032, + 0x80000540, 0x04020009, 0x59301009, 0x58080212, + 0x82000500, 0x0000ff00, 0x04000004, 0x82040500, + 0x00000800, 0x0400002a, 0x59cc0c09, 0x80040840, + 0x04001024, 0x59a80826, 0x8c040d06, 0x04000004, + 0x59cc0c0f, 0x8c040d1e, 0x04020012, 0x59cc0a17, + 0x800409c0, 0x04020012, 0x59cc0a18, 0x82040480, + 0x00000100, 0x04001014, 0x59cc0c18, 0x800409c0, + 0x0402000e, 0x59cc0c19, 0x80040840, 0x04001011, + 0x59cc0c1a, 0x80040840, 0x04001011, 0x0401f018, + 0x4a02621a, 0x00000100, 0x0401f012, 0x4a02621a, + 0x00000300, 0x0401f00f, 0x4a02621a, 0x00000500, + 0x0401f00c, 0x4a02621a, 0x00000700, 0x0401f009, + 0x4a02621a, 0x00000900, 0x0401f006, 0x4a02621a, + 0x00000f00, 0x0401f003, 0x4a02621a, 0x00002d00, + 0x82000540, 0x00000001, 0x0401f002, 0x80000580, + 0x5c000800, 0x1c01f000, 0x59cc0407, 0x4803c857, + 0x82000580, 0x00000800, 0x04000003, 0x4a02621a, + 0x00000000, 0x1c01f000, 0x4933c857, 0x4c580000, + 0x59cc000c, 0x59340802, 0x82040d00, 0x00ffffff, + 0x80040580, 0x04020012, 0x83cc1400, 0x00000008, + 0x4200b000, 0x00000002, 0x83341c00, 0x00000006, + 0x0201f800, 0x001082ff, 0x04020009, 0x83cc1400, + 0x0000000a, 0x4200b000, 0x00000002, 0x83341c00, + 0x00000008, 0x0201f800, 0x001082ff, 0x5c00b000, + 0x1c01f000, 0x4933c857, 0x4c580000, 0x83cc1400, + 0x0000000b, 0x4200b000, 0x00000002, 0x83341c00, + 0x00000006, 0x0201f800, 0x001082ff, 0x0402000c, + 0x83cc1400, 0x0000000d, 0x4200b000, 0x00000002, + 0x83341c00, 0x00000008, 0x0201f800, 0x001082ff, + 0x04000014, 0x4933c856, 0x4933c856, 0x4933c857, + 0x59340009, 0x4803c857, 0x5934000e, 0x4803c857, + 0x59340008, 0x4803c857, 0x5934000d, 0x4803c857, + 0x59340007, 0x4803c857, 0x5934000c, 0x4803c857, + 0x59340006, 0x4803c857, 0x5934000b, 0x4803c857, + 0x5c00b000, 0x1c01f000, 0x4933c857, 0x4947c857, + 0x4943c857, 0x4c600000, 0x0201f800, 0x0010698c, + 0x4df00000, 0x4d2c0000, 0x4d300000, 0x4d340000, + 0x0401f8d8, 0x4130c000, 0x42026000, 0x0010cfc0, + 0x59a8000e, 0x8060c1c0, 0x04000005, 0x82601580, + 0x0010bbe8, 0x04000002, 0x80000040, 0x81640480, + 0x040210c4, 0x40600000, 0x81300580, 0x040000bc, + 0x0401f9bc, 0x040200ba, 0x59326809, 0x59300406, + 0x82000c80, 0x00000012, 0x02021800, 0x00100615, + 0x0c01f001, 0x0010a1af, 0x0010a118, 0x0010a133, + 0x0010a13e, 0x0010a111, 0x0010a12c, 0x0010a169, + 0x0010a1af, 0x0010a10f, 0x0010a17c, 0x0010a190, + 0x0010a10f, 0x0010a10f, 0x0010a10f, 0x0010a10f, + 0x0010a1af, 0x0010a1a6, 0x0010a19e, 0x0201f800, + 0x00100615, 0x8d3e7d18, 0x04000003, 0x8d3e7d16, + 0x04000004, 0x59300420, 0x8c000500, 0x04020098, + 0x59300403, 0x82000580, 0x00000043, 0x04000094, + 0x0201f800, 0x00108ef1, 0x04000007, 0x0201f800, + 0x00108f05, 0x0402008c, 0x0201f800, 0x00107da6, + 0x0401f089, 0x0201f800, 0x00101e1b, 0x0201f800, + 0x00108f05, 0x02000800, 0x00107da6, 0x0401f082, + 0x8d3e7d18, 0x04000003, 0x8d3e7d16, 0x04000004, + 0x59300420, 0x8c000500, 0x0402007d, 0x59325808, + 0x0201f800, 0x00108df4, 0x04000077, 0x49425a06, + 0x497a5c09, 0x0201f800, 0x00020381, 0x0201f800, + 0x00108ee7, 0x0401f070, 0x8d3e7d00, 0x04000007, + 0x59300017, 0x81480580, 0x0402006d, 0x59300018, + 0x814c0580, 0x0402006a, 0x59300203, 0x82000580, + 0x00000004, 0x02000800, 0x00100ee4, 0x59325808, + 0x0201f800, 0x00108df4, 0x0400005f, 0x4a025a04, + 0x00000103, 0x59300004, 0x8400055c, 0x48026004, + 0x592c0408, 0x8c000512, 0x04000007, 0x4d2c0000, + 0x592c0009, 0x40025800, 0x0201f800, 0x00100843, + 0x5c025800, 0x49425a06, 0x497a5c09, 0x0401fb4f, + 0x0201f800, 0x00109365, 0x0201f800, 0x00108f7d, + 0x0201f800, 0x00020381, 0x0201f800, 0x00108ee7, + 0x0401f045, 0x8d3e7d18, 0x04000045, 0x59300203, + 0x82000580, 0x00000004, 0x02000800, 0x00100ee4, + 0x59325808, 0x0201f800, 0x00108df4, 0x0400003a, + 0x49425a06, 0x497a5c09, 0x0401fb38, 0x0201f800, + 0x00109365, 0x0201f800, 0x00020381, 0x0401f032, + 0x0201f800, 0x0010600e, 0x04000031, 0x59300203, + 0x82000580, 0x00000004, 0x0400002d, 0x59300203, + 0x82000580, 0x00000003, 0x04020029, 0x0201f800, + 0x001068c1, 0x59325808, 0x0201f800, 0x00108df4, + 0x04000021, 0x0201f800, 0x00020381, 0x0401f01e, + 0x59300203, 0x82000580, 0x00000004, 0x02000800, + 0x00100ee4, 0x59325808, 0x0201f800, 0x00108df4, + 0x04000015, 0x49425a06, 0x497a5c09, 0x0201f800, + 0x00020381, 0x0401f010, 0x833c0500, 0x00001800, + 0x0400000f, 0x8d3e7d16, 0x0402000d, 0x59325817, + 0x0201f800, 0x00100843, 0x59325808, 0x0201f800, + 0x00108df4, 0x04000004, 0x49425a06, 0x0201f800, + 0x00020381, 0x0201f800, 0x00107698, 0x83326400, + 0x00000024, 0x41580000, 0x81300480, 0x04001735, + 0x5c026800, 0x5c026000, 0x5c025800, 0x5c03e000, + 0x02000800, 0x00106982, 0x5c00c000, 0x1c01f000, + 0x4933c857, 0x813261c0, 0x0400002d, 0x83300d80, + 0x0010bbe8, 0x0400002a, 0x8d3e7d06, 0x04020028, + 0x59300c06, 0x82040580, 0x00000001, 0x0400000a, + 0x82040580, 0x00000002, 0x04020021, 0x5930021d, + 0x82000580, 0x00000001, 0x0402001d, 0x59300c16, + 0x0401f002, 0x59300c03, 0x82040580, 0x00000039, + 0x04000004, 0x82040580, 0x00000035, 0x04020014, + 0x4d300000, 0x4d1c0000, 0x5932601e, 0x4933c857, + 0x0201f800, 0x001091e3, 0x02000800, 0x00100615, + 0x591c001c, 0x497a381c, 0x591c0c14, 0x84040d02, + 0x48063c14, 0x5c023800, 0x5c026000, 0x81300580, + 0x02020800, 0x00100615, 0x497a601e, 0x1c01f000, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4d3c0000, + 0x42027800, 0x00000001, 0x0201f800, 0x001043bd, + 0x5c027800, 0x4c580000, 0x4200b000, 0x00000002, + 0x83a81c00, 0x00000002, 0x83cc1400, 0x0000000b, + 0x0201f800, 0x001082ff, 0x5c00b000, 0x80000540, + 0x1c01f000, 0x492fc857, 0x4943c857, 0x59a8000c, + 0x812c0480, 0x04001011, 0x59a8000d, 0x812c0480, + 0x0402100e, 0x592c0000, 0x80005d40, 0x04000008, + 0x497a5800, 0x49425a06, 0x4c2c0000, 0x0201f800, + 0x00020381, 0x5c025800, 0x0401f7f7, 0x49425a06, + 0x0201f000, 0x00020381, 0x1c01f000, 0x493fc857, + 0x4933c857, 0x480bc857, 0x0201f800, 0x0010393e, + 0x0400002e, 0x41502800, 0x813e79c0, 0x04020006, + 0x59a80066, 0x80000000, 0x59a8086a, 0x80040580, + 0x04000026, 0x41300000, 0x80140580, 0x0400001a, + 0x58140203, 0x82000580, 0x00000000, 0x04000016, + 0x58140202, 0x80080580, 0x04020013, 0x58141c06, + 0x820c0580, 0x00000005, 0x0400000f, 0x820c0580, + 0x00000009, 0x04000017, 0x59300009, 0x58142009, + 0x801021c0, 0x04020006, 0x5814201e, 0x59301809, + 0x580c0002, 0x82000500, 0x00ffffff, 0x80100580, + 0x04000007, 0x82142c00, 0x00000024, 0x41540000, + 0x80140480, 0x04021005, 0x0401f7df, 0x40163800, + 0x81300540, 0x0401f002, 0x80000580, 0x1c01f000, + 0x58141807, 0x8c0c1d10, 0x040207f3, 0x0401f7e7, + 0x42002000, 0x0000ffff, 0x59301009, 0x800811c0, + 0x04000002, 0x58082403, 0x41301000, 0x0401f007, + 0x41781000, 0x41442000, 0x0401f004, 0x41781000, + 0x42002000, 0x0000ffff, 0x5c000000, 0x4c000000, + 0x4803c857, 0x480bc857, 0x4813c857, 0x492fc857, + 0x4943c857, 0x4d2c0000, 0x4c080000, 0x4c100000, + 0x4c140000, 0x4c180000, 0x0201f800, 0x0010082a, + 0x02000800, 0x00100615, 0x5c003000, 0x5c002800, + 0x5c002000, 0x5c001000, 0x4a025a04, 0x0000010d, + 0x800811c0, 0x04000017, 0x83400580, 0x00000029, + 0x04020010, 0x82180580, 0x00000002, 0x0400000a, + 0x82180580, 0x00000003, 0x04000007, 0x82180580, + 0x00000008, 0x04000004, 0x82180580, 0x00000009, + 0x04020004, 0x4a025809, 0xffffffff, 0x0401f002, + 0x480a5809, 0x58080202, 0x48025c13, 0x0401f005, + 0x4a025809, 0xffffffff, 0x4a025c13, 0x0000ffff, + 0x49425a08, 0x48125a06, 0x82100580, 0x0000ffff, + 0x04000012, 0x4c140000, 0x4c180000, 0x4d440000, + 0x4d340000, 0x40128800, 0x0201f800, 0x00020267, + 0x02020800, 0x00100615, 0x59340002, 0x82000500, + 0x00ffffff, 0x48025812, 0x5c026800, 0x5c028800, + 0x5c003000, 0x5c002800, 0x497a5800, 0x497a5c04, + 0x83400580, 0x00000046, 0x04020002, 0x48165a07, + 0x481a5c08, 0x0401fbe0, 0x5c025800, 0x1c01f000, + 0x59300809, 0x800409c0, 0x04000004, 0x58040403, + 0x81440580, 0x1c01f000, 0x82000540, 0x00000001, + 0x0401f7fd, 0x4933c857, 0x4c040000, 0x59300403, + 0x82000d80, 0x0000001e, 0x04020016, 0x800000d0, + 0x59300a16, 0x82040d00, 0x000000ff, 0x80040540, + 0x4803c857, 0x48026416, 0x4a026403, 0x00000085, + 0x4a026203, 0x00000009, 0x4a026406, 0x00000005, + 0x4a02621d, 0x00000004, 0x59a80038, 0x48026206, + 0x42000800, 0x8000004b, 0x0201f800, 0x00020855, + 0x5c000800, 0x1c01f000, 0x4933c857, 0x40000000, + 0x40000000, 0x1c01f000, 0x59300414, 0x4933c857, + 0x4803c857, 0x8c000518, 0x04000009, 0x8c000512, + 0x02020000, 0x00108fdb, 0x0401f918, 0x0201f800, + 0x00020831, 0x0201f800, 0x000208b4, 0x1c01f000, + 0x591c0406, 0x4803c857, 0x82000c80, 0x00000009, + 0x0402100b, 0x0c01f001, 0x0010a2f7, 0x0010a2f7, + 0x0010a2f7, 0x0010a2f9, 0x0010a2f7, 0x0010a2f9, + 0x0010a2f9, 0x0010a2f7, 0x0010a2f9, 0x80000580, + 0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000, + 0x591c0406, 0x82000500, 0x0000001f, 0x82000580, + 0x00000006, 0x0400000e, 0x4803c857, 0x4a026403, + 0x0000003b, 0x4a02641a, 0x00000009, 0x4a02621a, + 0x00002a00, 0x4a026203, 0x00000001, 0x42000800, + 0x80000040, 0x0201f000, 0x00020855, 0x4803c856, + 0x4c040000, 0x4c140000, 0x4d300000, 0x411e6000, + 0x0401f8e6, 0x497a6205, 0x59300414, 0x4803c857, + 0x82000500, 0xffffadff, 0x48026414, 0x497a6405, + 0x5c026000, 0x0201f800, 0x0010082a, 0x02000800, + 0x00100615, 0x5c002800, 0x5c000800, 0x4a025a04, + 0x0000010d, 0x497a5800, 0x497a5c04, 0x4a025a08, + 0x00000045, 0x491e5809, 0x59300402, 0x48025c07, + 0x59300419, 0x48025c0b, 0x591c0414, 0x84000556, + 0x48023c14, 0x591c1809, 0x580c0403, 0x48025a06, + 0x4816580a, 0x48065a0b, 0x0401fb57, 0x4d400000, + 0x42028000, 0x00000045, 0x591c0202, 0x4c000000, + 0x4d300000, 0x411e6000, 0x0401fc82, 0x5c026000, + 0x5c000000, 0x48023a02, 0x5c028000, 0x4a023c06, + 0x00000006, 0x4a023a03, 0x00000007, 0x497a3a06, + 0x497a3a05, 0x1c01f000, 0x4933c857, 0x83380580, + 0x00000013, 0x0402000b, 0x59300403, 0x4803c857, + 0x82000d80, 0x00000085, 0x0400002b, 0x82000d80, + 0x0000008b, 0x04000028, 0x0201f800, 0x00100615, + 0x83380580, 0x00000027, 0x0402000c, 0x0201f800, + 0x001068f6, 0x4d2c0000, 0x4d400000, 0x59325808, + 0x42028000, 0x00000004, 0x0401fe9f, 0x5c028000, + 0x5c025800, 0x1c01f000, 0x83380580, 0x00000014, + 0x040007f3, 0x83380580, 0x00000089, 0x04000005, + 0x83380580, 0x0000008a, 0x02020000, 0x001076fb, + 0x0201f800, 0x00106cb4, 0x02020000, 0x001076fb, + 0x59300a03, 0x82040580, 0x0000000a, 0x04000009, + 0x82040580, 0x0000000c, 0x04000006, 0x0201f800, + 0x00100615, 0x4a026203, 0x0000000a, 0x1c01f000, + 0x83380480, 0x00000093, 0x0402100c, 0x83380480, + 0x00000085, 0x04001009, 0x83380580, 0x00000089, + 0x0400000a, 0x83380580, 0x0000008a, 0x04000022, + 0x0201f800, 0x00100615, 0x493bc857, 0x4933c857, + 0x0201f000, 0x001076fb, 0x4933c857, 0x4c340000, + 0x41306800, 0x0201f800, 0x00020892, 0x04000011, + 0x4a026203, 0x00000001, 0x4a026403, 0x0000001e, + 0x59cc0c07, 0x48066419, 0x59cc0a07, 0x48066219, + 0x58340809, 0x48066009, 0x4a026406, 0x00000004, + 0x42000800, 0x80000040, 0x0201f800, 0x00020855, + 0x40366000, 0x0201f800, 0x000208b4, 0x5c006800, + 0x1c01f000, 0x4933c857, 0x0201f000, 0x000208b4, + 0x59300809, 0x58040200, 0x8c00051a, 0x02020800, + 0x001006ba, 0x1c01f000, 0x0201f800, 0x0010472e, + 0x0400001e, 0x4a026203, 0x00000002, 0x59300414, + 0x84000558, 0x48026414, 0x8c000512, 0x04000004, + 0x59a80039, 0x48026205, 0x0401f007, 0x59a80839, + 0x59a80037, 0x80040400, 0x82000400, 0x0000001e, + 0x48026205, 0x59300009, 0x82000c00, 0x00000011, + 0x50040000, 0x80000540, 0x04000004, 0x82000c00, + 0x00000000, 0x0401f7fb, 0x45300800, 0x497a6000, + 0x82000540, 0x00000001, 0x1c01f000, 0x82100500, + 0xfffffeef, 0x0402001c, 0x4d2c0000, 0x4937c857, + 0x59340811, 0x83341400, 0x00000011, 0x800409c0, + 0x0400000e, 0x40040000, 0x81300580, 0x04000005, + 0x58040800, 0x82041400, 0x00000000, 0x0401f7f8, + 0x59300800, 0x497a6000, 0x44041000, 0x0201f800, + 0x00020831, 0x0401f002, 0x4933c857, 0x5c025800, + 0x492e6008, 0x0201f800, 0x00020831, 0x0201f000, + 0x000208b4, 0x492fc857, 0x4a025a06, 0x00000006, + 0x0201f000, 0x00020381, 0x4c340000, 0x59300009, + 0x800001c0, 0x04000010, 0x82006c00, 0x00000011, + 0x50340000, 0x80000540, 0x04000009, 0x81300580, + 0x04000005, 0x50340000, 0x82006c00, 0x00000000, + 0x0401f7f8, 0x59300000, 0x44006800, 0x5c006800, + 0x1c01f000, 0x59300c06, 0x82040580, 0x00000005, + 0x040007fb, 0x82040580, 0x00000011, 0x040007f8, + 0x82040580, 0x00000006, 0x040007f5, 0x82040580, + 0x00000001, 0x040007f2, 0x0201f800, 0x00100615, + 0x4933c857, 0x4c080000, 0x4c0c0000, 0x4c580000, + 0x59a8101d, 0x59cc1807, 0x820c1d00, 0x00ffffff, + 0x800c0110, 0x80083580, 0x04020014, 0x83cc1400, + 0x00000008, 0x4200b000, 0x00000002, 0x59300009, + 0x82001c00, 0x00000006, 0x0201f800, 0x001082ff, + 0x0402000a, 0x83cc1400, 0x0000000a, 0x4200b000, + 0x00000002, 0x59300009, 0x82001c00, 0x00000008, + 0x0201f800, 0x001082ff, 0x5c00b000, 0x5c001800, + 0x5c001000, 0x1c01f000, 0x4933c856, 0x0201f800, + 0x0010404b, 0x0201f000, 0x00101bf0, 0x493bc857, + 0x4d2c0000, 0x0201f800, 0x0010082a, 0x02000800, + 0x00100615, 0x832cac00, 0x00000005, 0x4c580000, + 0x4c540000, 0x4200b000, 0x00000006, 0x4578a800, + 0x8054a800, 0x8058b040, 0x040207fd, 0x83380580, + 0x00000046, 0x04020004, 0x4a025a04, 0x00000144, + 0x0401f008, 0x4a025a04, 0x00000146, 0x83380580, + 0x00000041, 0x04000003, 0x4a025a06, 0x00000001, + 0x59cc0007, 0x82000500, 0xff000000, 0x80000110, + 0x59cc1008, 0x82081500, 0xff000000, 0x80081540, + 0x480a580a, 0x83380580, 0x00000046, 0x04020006, + 0x59cc0007, 0x82000500, 0x00ffffff, 0x4802580b, + 0x0401f005, 0x59cc0008, 0x82000500, 0x00ffffff, + 0x4802580b, 0x83380580, 0x00000046, 0x04020004, + 0x83cc1400, 0x00000009, 0x0401f003, 0x83cc1400, + 0x0000000d, 0x50080000, 0x9c0001c0, 0x4802580c, + 0x80081000, 0x50080000, 0x9c0001c0, 0x4802580d, + 0x83380580, 0x00000046, 0x04020008, 0x59cc000b, + 0x9c0001c0, 0x4802580e, 0x59cc000c, 0x9c0001c0, + 0x4802580f, 0x0401f007, 0x59cc000f, 0x9c0001c0, + 0x4802580e, 0x59cc0010, 0x9c0001c0, 0x4802580f, + 0x83380580, 0x00000046, 0x04020004, 0x83cc1400, + 0x00000011, 0x0401f003, 0x83cc1400, 0x00000015, + 0x412c3000, 0x82183400, 0x00000010, 0x4200b000, + 0x00000004, 0x50080000, 0x9c0001c0, 0x44003000, + 0x80081000, 0x80183000, 0x8058b040, 0x040207fa, + 0x5c00a800, 0x5c00b000, 0x0201f800, 0x00020381, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x492fc857, + 0x59300809, 0x58040200, 0x8c00051e, 0x04000004, + 0x592c0208, 0x84000558, 0x48025a08, 0x1c01f000, + 0x59e0180f, 0x599c0413, 0x800c1000, 0x80080580, + 0x04020002, 0x41781000, 0x59e00010, 0x59e00810, + 0x80040d80, 0x040207fd, 0x80080580, 0x0400000b, + 0x4c080000, 0x599c0814, 0x599c1015, 0x800c00cc, + 0x80040c00, 0x82081440, 0x00000000, 0x5c001800, + 0x82000540, 0x00000001, 0x4803c857, 0x1c01f000, + 0x59300203, 0x4933c857, 0x4937c857, 0x493bc857, + 0x4803c857, 0x82003480, 0x0000000e, 0x02021800, + 0x00100615, 0x0c01f001, 0x0010a4e8, 0x0010a63a, + 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, + 0x0010a4e8, 0x0010a59f, 0x0010a4ea, 0x0010a4e8, + 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, 0x0010a4e8, + 0x0201f800, 0x00100615, 0x83380580, 0x0000004c, + 0x02020800, 0x00100615, 0x0201f800, 0x0010473b, + 0x04020020, 0x59a80826, 0x82040500, 0x00000009, + 0x82000580, 0x00000008, 0x0400001a, 0x8c040d12, + 0x0400003d, 0x59cc0806, 0x82040d00, 0xff000000, + 0x82040580, 0x03000000, 0x0400001f, 0x82040580, + 0x50000000, 0x04000005, 0x82040580, 0x52000000, + 0x02020000, 0x000208b4, 0x813669c0, 0x04000006, + 0x4d3c0000, 0x417a7800, 0x0201f800, 0x00101de2, + 0x5c027800, 0x4a026403, 0x00000001, 0x0401f014, + 0x59cc0806, 0x82040d00, 0xff000000, 0x82040580, + 0x03000000, 0x04000008, 0x82040580, 0x50000000, + 0x04000005, 0x82040580, 0x52000000, 0x02020000, + 0x000208b4, 0x4a026403, 0x00000009, 0x4a02641a, + 0x00000009, 0x4a02621a, 0x00000000, 0x813669c0, + 0x0402000b, 0x59cc0001, 0x0201f800, 0x001059b9, + 0x02020000, 0x000208b4, 0x0201f800, 0x001043fc, + 0x02020000, 0x000208b4, 0x49366009, 0x4a026406, + 0x00000004, 0x4a026203, 0x00000001, 0x0201f000, + 0x00106470, 0x0201f800, 0x0010393e, 0x04000023, + 0x59cc0806, 0x4807c857, 0x82040d00, 0xff000000, + 0x82040580, 0x03000000, 0x04000033, 0x82040580, + 0x20000000, 0x04000041, 0x82040580, 0x21000000, + 0x04000052, 0x82040580, 0x24000000, 0x0400004f, + 0x82040580, 0x50000000, 0x0400004c, 0x82040580, + 0x52000000, 0x04000049, 0x82040580, 0x05000000, + 0x0402000d, 0x59cc0806, 0x82040d00, 0xff000000, + 0x9c0431c0, 0x42028000, 0x00000046, 0x42002800, + 0x00000001, 0x0401fcf7, 0x0401f940, 0x02000800, + 0x00100615, 0x42002000, 0x00000051, 0x0201f800, + 0x001077d1, 0x59cc0000, 0x82000500, 0x00ffffff, + 0x82000580, 0x00ffffff, 0x04000005, 0x4a026203, + 0x00000007, 0x493a6403, 0x1c01f000, 0x59325817, + 0x812e59c0, 0x02020800, 0x00100843, 0x0201f000, + 0x000208b4, 0x813669c0, 0x040007df, 0x59340400, + 0x82000500, 0x000000ff, 0x82000580, 0x00000003, + 0x040207d9, 0x0401fc73, 0x040207d7, 0x4a026403, + 0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a, + 0x00001900, 0x0401f7a2, 0x813669c0, 0x0400000c, + 0x59340c00, 0x82040500, 0x000000ff, 0x82000580, + 0x00000009, 0x04000794, 0x82040500, 0x0000ff00, + 0x82000580, 0x00000700, 0x040207c3, 0x4a026403, + 0x00000009, 0x4a02641a, 0x00000009, 0x4a02621a, + 0x00001e00, 0x0401f78e, 0x813669c0, 0x040007f8, + 0x59340c00, 0x82040500, 0x0000ff00, 0x82000580, + 0x00000700, 0x040007f2, 0x0401f7b3, 0x4d2c0000, + 0x4c580000, 0x4c500000, 0x4c540000, 0x41385000, + 0x83380580, 0x00000054, 0x02020800, 0x00100615, + 0x59325808, 0x592c0c0b, 0x82040d00, 0x0000e000, + 0x82040580, 0x00002000, 0x04020076, 0x59300817, + 0x800409c0, 0x04000014, 0x58041404, 0x41cca800, + 0x8204a400, 0x00000005, 0x82080480, 0x00000010, + 0x04021004, 0x4008b000, 0x0401fb84, 0x0401f00a, + 0x40001000, 0x4200b000, 0x0000000f, 0x0401fb7f, + 0x58040801, 0x800409c0, 0x040207f2, 0x0201f800, + 0x00100615, 0x813669c0, 0x0400005e, 0x59344c00, + 0x592c0c09, 0x4807c857, 0x4827c857, 0x82040d00, + 0x000000ff, 0x82040580, 0x00000003, 0x0400002a, + 0x82040580, 0x00000005, 0x04000032, 0x82040580, + 0x00000020, 0x04000036, 0x82040580, 0x00000052, + 0x04000042, 0x82040580, 0x00000050, 0x04000042, + 0x82040580, 0x00000021, 0x04000004, 0x82040580, + 0x00000024, 0x04020043, 0x82240500, 0x0000ff00, + 0x82000580, 0x00000007, 0x04000008, 0x42000800, + 0x00000009, 0x0201f800, 0x001043c7, 0x42005000, + 0x0000000c, 0x0401f037, 0x4a025a06, 0x00000031, + 0x4a02580d, 0x00000009, 0x59340400, 0x4802580e, + 0x0201f800, 0x00020381, 0x0201f800, 0x00107698, + 0x0401f03d, 0x0201f800, 0x001040e4, 0x0201f800, + 0x00104480, 0x42000800, 0x00000003, 0x0201f800, + 0x001043c7, 0x42005000, 0x00000008, 0x0401f021, + 0x59cc0007, 0x0201f800, 0x00105c25, 0x0402001d, + 0x0201f800, 0x001040e4, 0x0401f01a, 0x82240500, + 0x0000ff00, 0x82000580, 0x00000007, 0x040007df, + 0x82240500, 0x000000ff, 0x82000580, 0x00000009, + 0x040007da, 0x0201f800, 0x001044e1, 0x42005000, + 0x0000000a, 0x0401f00b, 0x42005000, 0x0000000e, + 0x0401f003, 0x42005000, 0x00000010, 0x82240500, + 0x0000ff00, 0x82000580, 0x00000007, 0x040007cb, + 0x482a6403, 0x4a026203, 0x00000001, 0x592c000d, + 0x48026011, 0x497a6013, 0x59a80038, 0x48026206, + 0x417a7800, 0x0201f800, 0x00106470, 0x59325817, + 0x812e59c0, 0x04000004, 0x0201f800, 0x00100843, + 0x497a6017, 0x5c00a800, 0x5c00a000, 0x5c00b000, + 0x5c025800, 0x1c01f000, 0x4d2c0000, 0x59325808, + 0x83380580, 0x00000013, 0x0402002a, 0x492fc857, + 0x59300c03, 0x82040580, 0x00000054, 0x0400001e, + 0x82040580, 0x00000010, 0x04000018, 0x82040580, + 0x0000000e, 0x04000015, 0x82040580, 0x00000008, + 0x0400000d, 0x82040580, 0x0000000c, 0x0400000a, + 0x82040580, 0x0000000a, 0x02020800, 0x00100615, + 0x42000800, 0x00000006, 0x0201f800, 0x001043c7, + 0x0401f009, 0x42000800, 0x00000004, 0x0201f800, + 0x001043c7, 0x0401f004, 0x59340200, 0x8400051a, + 0x48026a00, 0x4a025a06, 0x00000000, 0x0201f800, + 0x00020381, 0x0201f800, 0x000208b4, 0x0401f024, + 0x83380580, 0x00000027, 0x0400000f, 0x83380580, + 0x00000014, 0x02020800, 0x00100615, 0x492fc857, + 0x0201f800, 0x001068f6, 0x42028000, 0x00000031, + 0x42000800, 0x00000004, 0x42001000, 0x000000ff, + 0x0401f00a, 0x492fc857, 0x0201f800, 0x001068f6, + 0x42028000, 0x00000031, 0x42000800, 0x00000004, + 0x42001000, 0x00000010, 0x49425a06, 0x4806580d, + 0x480a580e, 0x0201f800, 0x00020381, 0x0201f800, + 0x00104a83, 0x0201f800, 0x00107698, 0x5c025800, + 0x1c01f000, 0x492fc857, 0x42007000, 0x0010b5f6, + 0x58380807, 0x800409c0, 0x04020005, 0x492c7008, + 0x492c7007, 0x0201f000, 0x001008be, 0x492c0800, + 0x492c7007, 0x1c01f000, 0x4d2c0000, 0x4c580000, + 0x4c500000, 0x4c540000, 0x4933c857, 0x4937c857, + 0x59cc0806, 0x4807c857, 0x82040d00, 0xff000000, + 0x82040580, 0x03000000, 0x0400000d, 0x82040580, + 0x05000000, 0x0400000a, 0x82040580, 0x21000000, + 0x04000030, 0x82040580, 0x24000000, 0x0400002d, + 0x82040580, 0x20000000, 0x0402002f, 0x0201f800, + 0x0010082a, 0x0400002c, 0x492fc857, 0x492e6017, + 0x59a8b016, 0x8258b400, 0x0000001b, 0x8258b500, + 0xfffffffc, 0x8058b104, 0x485a5c04, 0x412c7800, + 0x41cca000, 0x82580480, 0x00000010, 0x04021005, + 0x832cac00, 0x00000005, 0x0401fa78, 0x0401f015, + 0x40580800, 0x4200b000, 0x0000000f, 0x832cac00, + 0x00000005, 0x0401fa71, 0x8204b480, 0x0000000f, + 0x0201f800, 0x0010082a, 0x04000004, 0x492c7801, + 0x412c7800, 0x0401f7ec, 0x59325817, 0x0201f800, + 0x00100843, 0x497a6017, 0x80000580, 0x0401f006, + 0x59340200, 0x84000554, 0x48026a00, 0x82000540, + 0x00000001, 0x5c00a800, 0x5c00a000, 0x5c00b000, + 0x5c025800, 0x1c01f000, 0x4933c857, 0x492fc857, + 0x4d2c0000, 0x4c5c0000, 0x5930bc06, 0x59300a03, + 0x82040580, 0x00000007, 0x0400003c, 0x82040580, + 0x00000001, 0x02020800, 0x00100615, 0x0201f800, + 0x0010698c, 0x4df00000, 0x598c000d, 0x81300580, + 0x04020019, 0x59300004, 0x8c000520, 0x04000004, + 0x84000520, 0x48026004, 0x0401f019, 0x825c0580, + 0x00000011, 0x0402000d, 0x42001000, 0x0010b5f4, + 0x50081000, 0x58080002, 0x82000580, 0x00000100, + 0x04000006, 0x5808000c, 0x81300580, 0x02020800, + 0x00100615, 0x0401f00a, 0x0201f800, 0x00106be2, + 0x04020027, 0x59300004, 0x8c000520, 0x04000004, + 0x84000520, 0x48026004, 0x0401f003, 0x0201f800, + 0x00106619, 0x5c03e000, 0x02000800, 0x00106982, + 0x0201f800, 0x00108df4, 0x02000800, 0x00100615, + 0x59325808, 0x4a025a06, 0x00000005, 0x0201f800, + 0x00020381, 0x825c0580, 0x00000005, 0x0400001b, + 0x0201f800, 0x00104a83, 0x825c0580, 0x00000005, + 0x04000016, 0x59325817, 0x812e59c0, 0x02020800, + 0x00100843, 0x0201f800, 0x00107698, 0x80000580, + 0x5c00b800, 0x5c025800, 0x1c01f000, 0x5c03e000, + 0x02000800, 0x00106982, 0x59300c06, 0x82040580, + 0x00000011, 0x040007ae, 0x82040580, 0x00000005, + 0x040007ab, 0x0401f7f3, 0x0201f800, 0x000208b4, + 0x0401f7ef, 0x4c040000, 0x59340200, 0x4803c857, + 0x8c00051c, 0x04000009, 0x59cc0805, 0x591c0019, + 0x4803c857, 0x80040580, 0x04000004, 0x80000580, + 0x4803c856, 0x0401f003, 0x82000540, 0x00000001, + 0x5c000800, 0x1c01f000, 0x4c000000, 0x4c0c0000, + 0x4c100000, 0x42001800, 0x0000ffff, 0x42002000, + 0x00000004, 0x0401f013, 0x4c000000, 0x4c0c0000, + 0x4c100000, 0x59302009, 0x58101c03, 0x42002000, + 0x00000004, 0x0401f00b, 0x4c000000, 0x4c0c0000, + 0x4c100000, 0x59302009, 0x801021c0, 0x02000800, + 0x00100615, 0x58101c03, 0x42002000, 0x00000007, + 0x480fc857, 0x4813c857, 0x481bc857, 0x0201f800, + 0x001038c7, 0x5c002000, 0x5c001800, 0x5c000000, + 0x1c01f000, 0x83380580, 0x00000092, 0x02020800, + 0x00100615, 0x42000800, 0x80000040, 0x4a026203, + 0x00000001, 0x493a6403, 0x0201f000, 0x00020855, + 0x4d400000, 0x0201f800, 0x0010393e, 0x04000008, + 0x59a80005, 0x84000544, 0x48035005, 0x42028000, + 0x0000002a, 0x0201f800, 0x0010a25b, 0x5c028000, + 0x1c01f000, 0x59a80026, 0x8c000508, 0x04000005, + 0x599c0017, 0x8c00050a, 0x04020002, 0x1c01f000, + 0x82000540, 0x00000001, 0x1c01f000, 0x59300420, + 0x84000540, 0x48026420, 0x1c01f000, 0x4817c857, + 0x4c000000, 0x4c040000, 0x8c142d2a, 0x04000004, + 0x598800b9, 0x80000000, 0x480310b9, 0x8c142d2e, + 0x04000004, 0x598800ba, 0x80000000, 0x480310ba, + 0x8c142d2c, 0x04000013, 0x40140000, 0x82000500, + 0x00070000, 0x82000d80, 0x00030000, 0x0400000d, + 0x82000d80, 0x00040000, 0x0400000a, 0x82000d80, + 0x00050000, 0x04000007, 0x59880005, 0x80000000, + 0x48031005, 0x598800bb, 0x80000000, 0x480310bb, + 0x5c000800, 0x5c000000, 0x1c01f000, 0x4817c857, + 0x4c000000, 0x4c040000, 0x8c142d2a, 0x04000004, + 0x598800bc, 0x80000000, 0x480310bc, 0x8c142d2e, + 0x04000004, 0x598800bd, 0x80000000, 0x480310bd, + 0x8c142d2c, 0x04000013, 0x40140000, 0x82000500, + 0x00070000, 0x82000d80, 0x00030000, 0x0400000d, + 0x82000d80, 0x00040000, 0x0400000a, 0x82000d80, + 0x00050000, 0x04000007, 0x59880005, 0x80000000, + 0x48031005, 0x598800be, 0x80000000, 0x480310be, + 0x5c000800, 0x5c000000, 0x1c01f000, 0x4c000000, + 0x59880001, 0x80000000, 0x4803c857, 0x48031001, + 0x5c000000, 0x1c01f000, 0x4c000000, 0x59880000, + 0x80000000, 0x4803c857, 0x48031000, 0x5c000000, + 0x1c01f000, 0x4c000000, 0x59880002, 0x80000000, + 0x4803c857, 0x48031002, 0x5c000000, 0x1c01f000, + 0x4807c857, 0x4c000000, 0x8c040d2c, 0x04000004, + 0x598800a7, 0x80000000, 0x480310a7, 0x8c040d2a, + 0x04000004, 0x598800a8, 0x80000000, 0x480310a8, + 0x8c040d28, 0x04000004, 0x598800a9, 0x80000000, + 0x480310a9, 0x8c040d26, 0x04000004, 0x598800aa, + 0x80000000, 0x480310aa, 0x8c040d24, 0x04000004, + 0x598800ab, 0x80000000, 0x480310ab, 0x8c040d22, + 0x04000004, 0x598800ac, 0x80000000, 0x480310ac, + 0x8c040d20, 0x04000004, 0x598800ad, 0x80000000, + 0x480310ad, 0x5c000000, 0x1c01f000, 0x4807c857, + 0x4c000000, 0x598800ae, 0x80000000, 0x480310ae, + 0x5c000000, 0x1c01f000, 0x4807c857, 0x4c000000, + 0x8c040d1c, 0x04000004, 0x598800af, 0x80000000, + 0x480310af, 0x8c040d1a, 0x04000004, 0x598800b0, + 0x80000000, 0x480310b0, 0x5c000000, 0x1c01f000, + 0x4807c857, 0x4c000000, 0x8c040d18, 0x04000004, + 0x598800b1, 0x80000000, 0x480310b1, 0x8c040d16, + 0x04000004, 0x598800b2, 0x80000000, 0x480310b2, + 0x8c040d14, 0x04000004, 0x598800b3, 0x80000000, + 0x480310b3, 0x5c000000, 0x1c01f000, 0x4807c857, + 0x4c000000, 0x8c040d10, 0x04000004, 0x598800b4, + 0x80000000, 0x480310b4, 0x8c040d0c, 0x04000004, + 0x598800b5, 0x80000000, 0x480310b5, 0x5c000000, + 0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d08, + 0x04000004, 0x598800b6, 0x80000000, 0x480310b6, + 0x8c040d04, 0x04000004, 0x598800b7, 0x80000000, + 0x480310b7, 0x5c000000, 0x1c01f000, 0x4807c856, + 0x4c000000, 0x59880080, 0x80000000, 0x48031080, + 0x5c000000, 0x1c01f000, 0x4803c857, 0x4c040000, + 0x50000800, 0x80040800, 0x4807c857, 0x44040000, + 0x5c000800, 0x1c01f000, 0x480fc857, 0x4c000000, + 0x820c0580, 0x00000000, 0x04020004, 0x42000000, + 0x0010b617, 0x0401f014, 0x820c0580, 0x00001001, + 0x04020004, 0x42000000, 0x0010b618, 0x0401f00e, + 0x820c0580, 0x00001002, 0x04020004, 0x42000000, + 0x0010b619, 0x0401f008, 0x820c0c80, 0x0000201c, + 0x02021800, 0x00100615, 0x820c0500, 0x0000001f, + 0x0c01f804, 0x0401ffdd, 0x5c000000, 0x1c01f000, + 0x0010a8b0, 0x0010a8b3, 0x0010a8b6, 0x0010a8b9, + 0x0010a8bc, 0x0010a8bf, 0x0010a8c2, 0x0010a8c5, + 0x0010a8c8, 0x0010a8cb, 0x0010a8ce, 0x0010a8d1, + 0x0010a8d4, 0x0010a8d7, 0x0010a8da, 0x0010a8dd, + 0x0010a8e0, 0x0010a8e3, 0x0010a8e6, 0x0010a8e9, + 0x0010a8ec, 0x0010a8ef, 0x0010a8f2, 0x0010a8f5, + 0x0010a8f8, 0x0010a8fb, 0x0010a8fe, 0x0010a901, + 0x42000000, 0x0010b61a, 0x1c01f000, 0x42000000, + 0x0010b61b, 0x1c01f000, 0x42000000, 0x0010b61c, + 0x1c01f000, 0x42000000, 0x0010b61d, 0x1c01f000, + 0x42000000, 0x0010b61e, 0x1c01f000, 0x42000000, + 0x0010b61f, 0x1c01f000, 0x42000000, 0x0010b620, + 0x1c01f000, 0x42000000, 0x0010b621, 0x1c01f000, + 0x42000000, 0x0010b622, 0x1c01f000, 0x42000000, + 0x0010b623, 0x1c01f000, 0x42000000, 0x0010b624, + 0x1c01f000, 0x42000000, 0x0010b625, 0x1c01f000, + 0x42000000, 0x0010b626, 0x1c01f000, 0x42000000, + 0x0010b627, 0x1c01f000, 0x42000000, 0x0010b628, + 0x1c01f000, 0x42000000, 0x0010b629, 0x1c01f000, + 0x42000000, 0x0010b62a, 0x1c01f000, 0x42000000, + 0x0010b62b, 0x1c01f000, 0x42000000, 0x0010b62c, + 0x1c01f000, 0x42000000, 0x0010b62d, 0x1c01f000, + 0x42000000, 0x0010b62e, 0x1c01f000, 0x42000000, + 0x0010b62f, 0x1c01f000, 0x42000000, 0x0010b630, + 0x1c01f000, 0x42000000, 0x0010b631, 0x1c01f000, + 0x42000000, 0x0010b632, 0x1c01f000, 0x42000000, + 0x0010b633, 0x1c01f000, 0x42000000, 0x0010b634, + 0x1c01f000, 0x42000000, 0x0010b635, 0x1c01f000, + 0x480fc857, 0x4c000000, 0x820c0580, 0x00000001, + 0x04020004, 0x42000000, 0x0010b60c, 0x0401f012, + 0x820c0580, 0x00000002, 0x04020004, 0x42000000, + 0x0010b60d, 0x0401f00c, 0x820c0580, 0x00000003, + 0x04020004, 0x42000000, 0x0010b60e, 0x0401f006, + 0x820c0580, 0x00000004, 0x04020004, 0x42000000, + 0x0010b60f, 0x0401ff51, 0x5c000000, 0x1c01f000, + 0x4c000000, 0x59a80026, 0x4803c857, 0x8c000502, + 0x04000010, 0x8c000506, 0x04000004, 0x42000000, + 0x0010b63f, 0x0401f012, 0x8c00050a, 0x04000004, + 0x42000000, 0x0010b63e, 0x0401f00d, 0x8c000508, + 0x04000004, 0x42000000, 0x0010b641, 0x0401f008, + 0x0201f800, 0x00104e0d, 0x04000006, 0x8c000506, + 0x04020004, 0x42000000, 0x0010b640, 0x0401ff33, + 0x5c000000, 0x1c01f000, 0x8058b1c0, 0x02000800, + 0x00100615, 0x5450a800, 0x8050a000, 0x8054a800, + 0x8058b040, 0x040207fc, 0x1c01f000, 0x8058b1c0, + 0x02000800, 0x00100615, 0x4450a800, 0x8054a800, + 0x8058b040, 0x040207fd, 0x1c01f000, 0x8058b1c0, + 0x02000800, 0x00100615, 0x50500000, 0x9c0001c0, + 0x4400a800, 0x8050a000, 0x8054a800, 0x8058b040, + 0x040207fa, 0x1c01f000, 0x4c000000, 0x59a80008, + 0x8c00051c, 0x5c000000, 0x1c01f000, 0x00000001, + 0x00000002, 0x00000004, 0x00000008, 0x00000010, + 0x00000020, 0x00000040, 0x00000080, 0x00000100, + 0x00000200, 0x00000400, 0x00000800, 0x00001000, + 0x00002000, 0x00004000, 0x00008000, 0x00010000, + 0xd2764e14 +}; + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_length01 = 0x0000a971 ; +#else +uint32_t risc_code_length01 = 0x0000a971 ; +#endif + + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_addr02 = 0x0010d000 ; +#else +uint32_t risc_code_addr02 = 0x0010d000 ; +#endif + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_code02[] = { +#else +uint32_t risc_code02[] = { +#endif + 0x00000000, 0x00000000, 0x0010d000, 0x0000165e, + 0x00000000, 0x00000000, 0x00020000, 0x000009f7, + 0x836c0580, 0x00000003, 0x02020000, 0x00100314, + 0x42000000, 0x0010b2b7, 0x50000000, 0x800001c0, + 0x0402098a, 0x0401f94d, 0x0201f800, 0x00020524, + 0x0401fbfe, 0x0201f800, 0x0002084c, 0x0201f800, + 0x000206af, 0x0401f7ef, 0x59b800ea, 0x82000d00, + 0xf0000038, 0x02020000, 0x00100ac3, 0x8c000510, + 0x02000000, 0x00100ac2, 0x59ba60e0, 0x81300182, + 0x0402104e, 0x04002030, 0x8532653e, 0x59300406, + 0x82000580, 0x00000003, 0x04020028, 0x59300203, + 0x82000580, 0x00000004, 0x04020024, 0x59325808, + 0x59300402, 0x4a025a04, 0x00000103, 0x900001c0, + 0x48025806, 0x497a5807, 0x497a5c09, 0x5930001f, + 0x80000540, 0x02020800, 0x00100d9a, 0x59300004, + 0x8c00053e, 0x04020010, 0x0401fb47, 0x59326809, + 0x0201f800, 0x000208b4, 0x5934000f, 0x5934140b, + 0x80081040, 0x04001002, 0x480a6c0b, 0x80000540, + 0x04020a31, 0x59b800ea, 0x8c000510, 0x040207d7, + 0x1c01f000, 0x0201f800, 0x00106cb4, 0x040007ef, + 0x0201f000, 0x00100aae, 0x42027000, 0x00000055, + 0x0401f027, 0x83326500, 0x3fffffff, 0x59300406, + 0x82000580, 0x00000003, 0x04020015, 0x59325808, + 0x59326809, 0x59301402, 0x4a025a04, 0x00000103, + 0x900811c0, 0x480a5806, 0x497a5c09, 0x497a5807, + 0x0401fb21, 0x0201f800, 0x000208b4, 0x5934000f, + 0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b, + 0x80000540, 0x04020a0c, 0x0401f7db, 0x42027000, + 0x00000054, 0x0401f00a, 0x83300500, 0x60000000, + 0x02000000, 0x00100ab1, 0x81326580, 0x8000013a, + 0x82000400, 0x00100ac9, 0x50027000, 0x59300c06, + 0x82040580, 0x00000002, 0x02000000, 0x00100aae, + 0x59300004, 0x8c00053e, 0x04020004, 0x0201f800, + 0x000208d8, 0x0401f7c4, 0x0201f800, 0x00106cb4, + 0x040007fb, 0x0201f000, 0x00100aae, 0x59325808, + 0x412c7000, 0x58380a04, 0x82040500, 0x0000000f, + 0x82000c00, 0x0010110d, 0x50044000, 0x0c01f001, + 0x00100e24, 0x00100e24, 0x000200a0, 0x00100e24, + 0x00100e24, 0x00100e24, 0x00100e24, 0x00100e24, + 0x000200b0, 0x00100e38, 0x00100e24, 0x00100e24, + 0x00100e26, 0x00100e24, 0x00100e24, 0x00100e24, + 0x5838040a, 0x8c000500, 0x02000800, 0x00100615, + 0x50200000, 0x80387c00, 0x583c1002, 0x583c2800, + 0x583c2001, 0x58380a07, 0x5838300f, 0x59303807, + 0x58384c08, 0x5838000d, 0x48026012, 0x0401f010, + 0x5838020a, 0x8c000502, 0x02000000, 0x00100e24, + 0x50200000, 0x80387c00, 0x583c2800, 0x583c2001, + 0x583c1002, 0x592c0a07, 0x592c4c08, 0x592c300f, + 0x59303807, 0x497a6012, 0x497a6013, 0x4816600e, + 0x4812600f, 0x480a6010, 0x481a6011, 0x80040840, + 0x4806600d, 0x02020000, 0x00100e65, 0x841c3d40, + 0x481e6007, 0x1c01f000, 0x41787800, 0x59325808, + 0x592c0c0a, 0x8c040d02, 0x02000000, 0x00100fda, + 0x592c000d, 0x592c100f, 0x592c0a04, 0x480a6011, + 0x48026012, 0x48026013, 0x412c3000, 0x82040500, + 0x0000000f, 0x82000400, 0x0010110d, 0x50003800, + 0x501c0000, 0x401c1000, 0x592c1a07, 0x4802600a, + 0x481a600b, 0x480a600c, 0x480e600d, 0x843c7d4a, + 0x403c1000, 0x1c01f000, 0x41787800, 0x497a6012, + 0x592c0a04, 0x412c3000, 0x592c1a07, 0x82040500, + 0x0000000f, 0x82000400, 0x0010110d, 0x50004000, + 0x50200000, 0x40201000, 0x4802600a, 0x481a600b, + 0x480a600c, 0x480e600d, 0x80000580, 0x483e6004, + 0x1c01f000, 0x0002014c, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x00020139, 0x00020139, 0x00020139, + 0x00020139, 0x4c000000, 0x4df00000, 0x4203e000, + 0xb0100000, 0x41f00000, 0x81fe1500, 0x8d0a1512, + 0x02020800, 0x00101468, 0x8d0a1518, 0x02020800, + 0x00020861, 0x8d0a151a, 0x04020ed0, 0x83080500, + 0x00000d00, 0x04020804, 0x5c03e000, 0x5c000000, + 0x1801f000, 0x8d0a1516, 0x02020800, 0x001012d9, + 0x8d0a1514, 0x02020800, 0x001011a5, 0x8d0a1508, + 0x02020800, 0x001011aa, 0x8d0a1500, 0x02020000, + 0x000207c8, 0x1c01f000, 0x42000000, 0x0010b2bd, + 0x50000000, 0x8c000504, 0x04000014, 0x42000000, + 0x0010b2bd, 0x50000000, 0x8c000502, 0x04020002, + 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, + 0x42034000, 0x0010b2a0, 0x59a0001d, 0x59a1d81e, + 0x84000502, 0x4803401d, 0x58ec0009, 0x0801f800, + 0x5c03e000, 0x1c01f000, 0x04027002, 0x04026002, + 0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000, + 0x0201f800, 0x0010082a, 0x0400001a, 0x412dd800, + 0x48efc857, 0x0201f800, 0x00103941, 0x42034000, + 0x0010b2a0, 0x49a1d80b, 0x48ef401e, 0x59a0001d, + 0x84000544, 0x4803401d, 0x59e00020, 0x4803c857, + 0x59e00021, 0x4803c857, 0x59e00022, 0x4803c857, + 0x59e00023, 0x4803c857, 0x59e00024, 0x4803c857, + 0x0201f800, 0x00101fbb, 0x0201f800, 0x00101fda, + 0x5c03e000, 0x1c01f000, 0x4da00000, 0x4df00000, + 0x4203e000, 0x50000000, 0x04006051, 0x42034000, + 0x0010b2a0, 0x59a01017, 0x59a01818, 0x800c19c0, + 0x04020008, 0x59a0381b, 0x801c39c0, 0x02000800, + 0x00100615, 0x59a0041c, 0x801c3c00, 0x0401f00c, + 0x59a00419, 0x82000400, 0x00000002, 0x48034419, + 0x82000c80, 0x00000013, 0x04001003, 0x497b4419, + 0x41780000, 0x59a03816, 0x801c3c00, 0x80081040, + 0x480b4017, 0x581c0200, 0x4803c021, 0x581c0401, + 0x4803c022, 0x581c0201, 0x4803c023, 0x581c0400, + 0x4803c020, 0x900001c0, 0x82000540, 0x00000012, + 0x4803c011, 0x59e00017, 0x8c000508, 0x04000003, + 0x4a03c017, 0x00000002, 0x4203e000, 0x30000001, + 0x800c19c0, 0x04000007, 0x800c1840, 0x480f4018, + 0x0402001f, 0x497b4419, 0x497b4219, 0x0401f01c, + 0x800811c0, 0x0402000b, 0x4d2c0000, 0x59a2581b, + 0x0201f800, 0x0010083a, 0x5c025800, 0x497b401b, + 0x497b401a, 0x497b441c, 0x497b421c, 0x0401f010, + 0x59a0041c, 0x82000400, 0x00000002, 0x82000c80, + 0x00000012, 0x4803441c, 0x04001009, 0x4d2c0000, + 0x59a2581b, 0x592c3813, 0x481f401b, 0x497b441c, + 0x0201f800, 0x0010083a, 0x5c025800, 0x5c03e000, + 0x5c034000, 0x1c01f000, 0x59a80005, 0x82000500, + 0x00000003, 0x02020000, 0x00104145, 0x59340400, + 0x82000580, 0x00000606, 0x02020000, 0x00104116, + 0x5934000d, 0x80027d40, 0x02020000, 0x00104151, + 0x0401f803, 0x80000580, 0x1c01f000, 0x5934000f, + 0x59341203, 0x80080540, 0x0402005d, 0x5934020b, + 0x5934140b, 0x80080480, 0x04021059, 0x0201f800, + 0x00020892, 0x04000052, 0x592c0406, 0x49366009, + 0x492e6008, 0x4a026406, 0x00000003, 0x4a026403, + 0x00000040, 0x80081000, 0x480a6c0b, 0x800000c2, + 0x800018c4, 0x800c0400, 0x48026206, 0x592c0808, + 0x592c1809, 0x592c020a, 0x48066017, 0x480e6018, + 0x8c000502, 0x0400002a, 0x4a026203, 0x00000004, + 0x592c0207, 0x80000040, 0x0402001a, 0x59a80070, + 0x80000040, 0x040207ff, 0x592c0204, 0x82000500, + 0x000000ff, 0x82000580, 0x00000018, 0x04020011, + 0x592c180f, 0x59300007, 0x82000540, 0x00000091, + 0x480e6011, 0x48026007, 0x42000000, 0x80000004, + 0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe, + 0x83300400, 0x20000000, 0x480378e1, 0x1c01f000, + 0x0401fe4b, 0x59300007, 0x8400054e, 0x48026007, + 0x592c1a04, 0x820c1d00, 0x000000ff, 0x820c0580, + 0x00000048, 0x04000012, 0x0401f7ec, 0x8c000500, + 0x04020e9e, 0x4a026203, 0x00000002, 0x59a80071, + 0x80000040, 0x040207ff, 0x592c1a04, 0x820c1d00, + 0x000000ff, 0x820c0580, 0x00000018, 0x040007df, + 0x820c0580, 0x00000048, 0x040207dc, 0x42000800, + 0x80000804, 0x0201f000, 0x00106466, 0x800811c0, + 0x04020003, 0x4a026a03, 0x00000001, 0x59340010, + 0x492e6810, 0x80000d40, 0x04020003, 0x492e680f, + 0x1c01f000, 0x492c0800, 0x1c01f000, 0x83440c80, + 0x00000800, 0x04021009, 0x83440400, 0x0010aa00, + 0x50000000, 0x80000540, 0x04000004, 0x40026800, + 0x80000580, 0x1c01f000, 0x82000540, 0x00000001, + 0x1c01f000, 0x59340203, 0x80000540, 0x0402004b, + 0x4d300000, 0x4d2c0000, 0x5934000f, 0x80025d40, + 0x04000044, 0x0201f800, 0x00020892, 0x0400003f, + 0x592c0000, 0x4802680f, 0x80000540, 0x04020002, + 0x48026810, 0x592c2a04, 0x80081000, 0x480a6c0b, + 0x49366009, 0x492e6008, 0x82142d00, 0x000000ff, + 0x82140580, 0x00000012, 0x04000035, 0x4a026406, + 0x00000003, 0x4a026403, 0x00000040, 0x592c0406, + 0x800000c2, 0x800018c4, 0x800c0400, 0x48026206, + 0x592c0808, 0x592c1809, 0x592c020a, 0x48066017, + 0x480e6018, 0x8c000502, 0x02000000, 0x001045a1, + 0x4a026203, 0x00000004, 0x592c0207, 0x80000040, + 0x02020000, 0x00104594, 0x82140580, 0x00000018, + 0x02020000, 0x00104594, 0x592c180f, 0x59300007, + 0x82000540, 0x00000091, 0x480e6011, 0x48026007, + 0x42000000, 0x80000004, 0x48026004, 0x59bc00ea, + 0x8c000516, 0x040207fe, 0x83300400, 0x20000000, + 0x480378e1, 0x5934020b, 0x5934140b, 0x80080480, + 0x040017be, 0x0401f003, 0x4a026a03, 0x00000001, + 0x5c025800, 0x5c026000, 0x1c01f000, 0x497a5800, + 0x49325809, 0x4a026406, 0x00000006, 0x4a026203, + 0x00000007, 0x0401f802, 0x0401f7ef, 0x59a80021, + 0x800001c0, 0x02020000, 0x001045c3, 0x59a80005, + 0x8c000504, 0x02020000, 0x001045bf, 0x59340200, + 0x8c000518, 0x02020000, 0x001045bb, 0x592c0a0c, + 0x48066202, 0x4a025a06, 0x00000000, 0x8c000508, + 0x02020000, 0x001045b7, 0x4d3c0000, 0x417a7800, + 0x0201f800, 0x000207ce, 0x5c027800, 0x1c01f000, + 0x59980026, 0x497a5800, 0x80000540, 0x04020067, + 0x59d80105, 0x82000d00, 0x00018780, 0x04020197, + 0x800000f6, 0x8000013c, 0x0c01f001, 0x000202f3, + 0x0002034e, 0x00020308, 0x00020326, 0x592c0001, + 0x492fb107, 0x80000d40, 0x04020805, 0x59940019, + 0x80000540, 0x04002085, 0x1c01f000, 0x497a5801, + 0x40065800, 0x592c0001, 0x496a5800, 0x815eb800, + 0x412ed000, 0x80000d40, 0x040207f9, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x1c01f000, + 0x492fb107, 0x592c0001, 0x80000d40, 0x04020ff0, + 0x59da5908, 0x835c0480, 0x00000020, 0x0400100d, + 0x0402b00b, 0x492fb007, 0x0400e7fa, 0x59d80105, + 0x82000500, 0x00018780, 0x0402016c, 0x59940019, + 0x80000540, 0x04002065, 0x1c01f000, 0x0400f009, + 0x496a5800, 0x412ed000, 0x815eb800, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x0401f7ef, + 0x492fa807, 0x0401f7ed, 0x59d81108, 0x45681000, + 0x400ad000, 0x815eb800, 0x0400e7fc, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x0402d009, + 0x592c0001, 0x492fb107, 0x80000d40, 0x04020fc8, + 0x59940019, 0x80000540, 0x04002048, 0x1c01f000, + 0x59d80105, 0x82000500, 0x00018780, 0x04020147, + 0x42000000, 0x0010b654, 0x0201f800, 0x0010a86e, + 0x59980026, 0x59980828, 0x80000000, 0x48033026, + 0x492f3028, 0x800409c0, 0x04000003, 0x492c0800, + 0x0401f002, 0x492f3029, 0x592c0001, 0x80000d40, + 0x04020faf, 0x0401f7e7, 0x59980026, 0x59980828, + 0x80000000, 0x48033026, 0x492f3028, 0x800409c0, + 0x04000003, 0x492c0800, 0x0401f002, 0x492f3029, + 0x592c0001, 0x80000d40, 0x04020fa1, 0x0402d00d, + 0x59980029, 0x80025d40, 0x0400000e, 0x59980026, + 0x80000040, 0x48033026, 0x04020002, 0x48033028, + 0x592c0000, 0x48033029, 0x492fb107, 0x0400d7f5, + 0x42000000, 0x0010b654, 0x0201f800, 0x0010a86e, + 0x0402e00a, 0x59da5908, 0x496a5800, 0x412ed000, + 0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540, + 0x00001200, 0x48039000, 0x59d80105, 0x82000500, + 0x00018780, 0x04020109, 0x59940019, 0x80000540, + 0x04002002, 0x1c01f000, 0x59980023, 0x48032819, + 0x1c01f000, 0x592c0404, 0x8c00051e, 0x02020000, + 0x00104b7b, 0x59980022, 0x80000540, 0x0402075d, + 0x59980026, 0x497a5800, 0x80000540, 0x02020000, + 0x00104ba6, 0x59d80105, 0x82000d00, 0x00018780, + 0x040200f2, 0x800000f6, 0x8000013c, 0x0c01f001, + 0x00020398, 0x00104ba6, 0x0002039d, 0x000203e6, + 0x592c0001, 0x492fb107, 0x80000d40, 0x04020760, + 0x1c01f000, 0x592c0001, 0x492fb107, 0x80000d40, + 0x04020f5b, 0x59da5908, 0x835c0480, 0x00000020, + 0x0400102b, 0x0402b033, 0x492fb007, 0x0400e7fa, + 0x59d80105, 0x82000500, 0x00018780, 0x040200d7, + 0x0400601f, 0x59d8010a, 0x59d8090a, 0x80040580, + 0x040207fd, 0x800408e0, 0x599c1017, 0x8c081508, + 0x04020028, 0x82040d40, 0x00000013, 0x5998002b, + 0x4807c011, 0x84000500, 0x4803302b, 0x59e00017, + 0x8c000508, 0x04020004, 0x4203e000, 0x30000001, + 0x1c01f000, 0x4a03c017, 0x00000003, 0x82040500, + 0x000000ff, 0x82000580, 0x0000001d, 0x040207f7, + 0x4a03c017, 0x0000000d, 0x0401f7f4, 0x5998082b, + 0x84040d40, 0x4807302b, 0x1c01f000, 0x496a5800, + 0x412ed000, 0x815eb800, 0x59c80000, 0x82000540, + 0x00001200, 0x48039000, 0x0400e7cb, 0x0401f7d1, + 0x0402f7f7, 0x492fa807, 0x0400e7c7, 0x0401f7cd, + 0x59e0000f, 0x59e0100f, 0x80081580, 0x040207fd, + 0x81281580, 0x040007d4, 0x40025000, 0x82040d40, + 0x0000001d, 0x0401f7d2, 0x59d80908, 0x45680800, + 0x4006d000, 0x815eb800, 0x0400e7fc, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x02006000, + 0x00104b8d, 0x59d8010a, 0x59d8090a, 0x80040d80, + 0x040207fd, 0x900001c0, 0x82000540, 0x00000013, + 0x4803c011, 0x5998002b, 0x84000500, 0x4803302b, + 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, + 0x00000003, 0x4203e000, 0x30000001, 0x59d80105, + 0x82000500, 0x00018780, 0x0402007c, 0x0202d000, + 0x00104b92, 0x592c0001, 0x492fb107, 0x80000d40, + 0x040206ef, 0x1c01f000, 0x59980020, 0x0c01f001, + 0x00020413, 0x00020414, 0x00020434, 0x1c01f000, + 0x4df00000, 0x4203e000, 0x50000000, 0x04026876, + 0x04006004, 0x599c0017, 0x8c000508, 0x040208f5, + 0x59980029, 0x80025d40, 0x0400000a, 0x0402d00b, + 0x59980026, 0x80000040, 0x48033026, 0x592c0000, + 0x492fb107, 0x48033029, 0x04020002, 0x48033028, + 0x5c03e000, 0x1c01f000, 0x59d80105, 0x82000500, + 0x00018780, 0x04020055, 0x42000000, 0x0010b654, + 0x0201f800, 0x0010a86e, 0x5c03e000, 0x1c01f000, + 0x4df00000, 0x4203e000, 0x50000000, 0x599cb817, + 0x59940019, 0x80000540, 0x04002023, 0x0400000e, + 0x59980022, 0x82000580, 0x00000005, 0x0400001e, + 0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08, + 0x04000007, 0x59a8006a, 0x59a80866, 0x80040580, + 0x04020015, 0x8c5cbd08, 0x0402002b, 0x59d8090b, + 0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e, + 0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040, + 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, + 0x00000002, 0x4203e000, 0x30000001, 0x4a032819, + 0xffff0000, 0x0400e879, 0x04006003, 0x8c5cbd08, + 0x0402088e, 0x59980029, 0x80025d40, 0x04020003, + 0x5c03e000, 0x1c01f000, 0x59d80105, 0x82000500, + 0x00018780, 0x04020019, 0x0202d000, 0x00104c06, + 0x59980826, 0x592c0000, 0x80040840, 0x48073026, + 0x492fb107, 0x48033029, 0x040207f2, 0x48033028, + 0x0401f7f0, 0x59e0000f, 0x59e0080f, 0x80040580, + 0x040207fd, 0x59e00010, 0x59e01010, 0x80081580, + 0x040207fd, 0x40065000, 0x80041580, 0x040007cc, + 0x040067e1, 0x0401f7cf, 0x4803c857, 0x485fc857, + 0x8c00050e, 0x02020800, 0x0010060d, 0x4203e000, + 0x50000000, 0x4200b800, 0x00008004, 0x0201f000, + 0x0010061a, 0x5998002b, 0x8c000500, 0x04020039, + 0x0400e006, 0x59d80105, 0x82000500, 0x00018780, + 0x040207ee, 0x1c01f000, 0x59da5908, 0x835c0c80, + 0x00000020, 0x04001003, 0x0400b028, 0x0400f02a, + 0x496a5800, 0x412ed000, 0x815eb800, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x0400e7f3, + 0x59d8010a, 0x59d8090a, 0x80040580, 0x040207fd, + 0x800408e0, 0x599c1017, 0x8c081508, 0x04020021, + 0x82040d40, 0x00000013, 0x4807c011, 0x59e00017, + 0x8c000508, 0x0400000a, 0x4a03c017, 0x00000003, + 0x82040500, 0x000000ff, 0x82000580, 0x0000001d, + 0x04020003, 0x4a03c017, 0x0000000d, 0x4203e000, + 0x30000001, 0x59d80105, 0x82000500, 0x00018780, + 0x040207c2, 0x1c01f000, 0x492fb007, 0x0400e7d3, + 0x0401f7e0, 0x492fa807, 0x0400e7d0, 0x0401f7dd, + 0x84000500, 0x4803302b, 0x0400e7cc, 0x0401f7d9, + 0x59e0000f, 0x59e0100f, 0x80081580, 0x040207fd, + 0x81281580, 0x040007db, 0x40025000, 0x82040d40, + 0x0000001d, 0x0401f7d9, 0x59da5908, 0x496a5800, + 0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x59d8090b, + 0x59980024, 0x48073024, 0x80040480, 0x04020004, + 0x59940019, 0x80000540, 0x04022003, 0x59980823, + 0x48072819, 0x59d80105, 0x82000500, 0x00018780, + 0x04020796, 0x1c01f000, 0x59981025, 0x59e00010, + 0x59e00810, 0x80041d80, 0x040207fd, 0x80080580, + 0x04000011, 0x48073025, 0x59e0000f, 0x59e0100f, + 0x80081d80, 0x040207fd, 0x81280580, 0x04000006, + 0x400a5000, 0x40080000, 0x80040580, 0x0402067f, + 0x1c01f000, 0x59940019, 0x80000540, 0x040227fa, + 0x1c01f000, 0x59e0000f, 0x59e0100f, 0x80081d80, + 0x040207fd, 0x81280580, 0x040007f6, 0x400a5000, + 0x59940019, 0x80000540, 0x040027ef, 0x1c01f000, + 0x59e0000f, 0x59e0100f, 0x80080d80, 0x040207fd, + 0x81280580, 0x04020002, 0x1c01f000, 0x400a5000, + 0x900811c0, 0x82081540, 0x0000001c, 0x480bc011, + 0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017, + 0x0000000c, 0x4203e000, 0x30000001, 0x1c01f000, + 0x41700000, 0x0c01f001, 0x001050f0, 0x0002052f, + 0x001050f0, 0x001050f1, 0x001050ee, 0x001050ee, + 0x001050ee, 0x001050ee, 0x00105594, 0x04010037, + 0x59980006, 0x80000540, 0x0402003c, 0x0402c01c, + 0x4202f800, 0x00000010, 0x4df00000, 0x4203e000, + 0x50000000, 0x49db3005, 0x59da5808, 0x592c0204, + 0x497a5800, 0x497a5801, 0x82000500, 0x000000ff, + 0x82000c80, 0x00000079, 0x04021036, 0x0c01f839, + 0x5c03e000, 0x817ef840, 0x04000009, 0x836c0580, + 0x00000003, 0x04020006, 0x83700580, 0x00000001, + 0x04020010, 0x0401001b, 0x0400c7e8, 0x0400f94b, + 0x0400b135, 0x59d40005, 0x82000500, 0x43018780, + 0x02020000, 0x00105523, 0x59d80005, 0x82000500, + 0x43018780, 0x02020000, 0x0010552a, 0x1c01f000, + 0x83700580, 0x00000003, 0x02000800, 0x001050f1, + 0x83700580, 0x00000001, 0x040207ed, 0x04010005, + 0x0400c7d2, 0x0401f7ea, 0x4202f800, 0x00000010, + 0x4df00000, 0x4203e000, 0x50000000, 0x49d73005, + 0x59d65808, 0x0401f7ce, 0x4df00000, 0x4203e000, + 0x50000000, 0x40025800, 0x592c0204, 0x497b3005, + 0x497b3006, 0x4202f800, 0x00000010, 0x0401f7c7, + 0x0201f800, 0x00105161, 0x5c03e000, 0x0401f7d4, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105207, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105171, 0x00105161, + 0x00105161, 0x00105161, 0x00105231, 0x00105161, + 0x00105161, 0x00105161, 0x00020623, 0x00105161, + 0x00105398, 0x00105161, 0x00105161, 0x00105161, + 0x000205f5, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105199, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x001054b7, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105502, 0x00105161, 0x0010518b, + 0x00105161, 0x0010547b, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105449, 0x00105161, 0x00105449, + 0x00105556, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105409, 0x00105539, + 0x00105161, 0x00105549, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x00105161, 0x00105161, 0x00105161, + 0x00105161, 0x592c0204, 0x80000110, 0x80000040, + 0x0400000b, 0x02001000, 0x00105169, 0x48033002, + 0x492f3003, 0x492f3004, 0x4a033008, 0x00020603, + 0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406, + 0x82000c80, 0x0000199a, 0x02021000, 0x00105179, + 0x59a80021, 0x80000540, 0x02020000, 0x001051a7, + 0x592e8a06, 0x83440c80, 0x000007f0, 0x02021000, + 0x00105179, 0x83440400, 0x0010aa00, 0x50000000, + 0x80026d40, 0x02000000, 0x001051bb, 0x59340002, + 0x592c0810, 0x80040580, 0x82000500, 0x00ffffff, + 0x02020000, 0x00105179, 0x0201f800, 0x000201ee, + 0x02020000, 0x001051be, 0x1c01f000, 0x592c0204, + 0x80000110, 0x02000000, 0x00105169, 0x80000040, + 0x0402000b, 0x592c040a, 0x8c000504, 0x04000010, + 0x592c0207, 0x82000c80, 0x00001001, 0x02021000, + 0x00105179, 0x0201f000, 0x0010556e, 0x48033002, + 0x492f3003, 0x492f3004, 0x4a033008, 0x0002063b, + 0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406, + 0x82000c80, 0x0000199a, 0x02021000, 0x00105179, + 0x592e8a06, 0x417a7800, 0x0401fc25, 0x02020000, + 0x0010533c, 0x59340002, 0x592c0808, 0x80040580, + 0x82000500, 0x00ffffff, 0x02020000, 0x00105179, + 0x497a5808, 0x592e6009, 0x83300580, 0xffffffff, + 0x02000000, 0x001052fc, 0x83300480, 0x0010cfc0, + 0x02001000, 0x00105359, 0x59a8000b, 0x81300480, + 0x02021000, 0x00105359, 0x592c240a, 0x49366009, + 0x8c10251c, 0x02020000, 0x001052ea, 0x59a80068, + 0x8c000510, 0x02020000, 0x00105372, 0x59a80821, + 0x800409c0, 0x02020000, 0x001052d0, 0x59a80805, + 0x8c040d04, 0x02020000, 0x00105363, 0x59340200, + 0x8c000518, 0x02020000, 0x00105354, 0x59300c06, + 0x82040580, 0x00000006, 0x02020000, 0x001052f4, + 0x59300414, 0x8c000516, 0x02020000, 0x0010535e, + 0x8c102508, 0x02020000, 0x0010a3d7, 0x59300808, + 0x4a025a06, 0x00000000, 0x800409c0, 0x02020000, + 0x001052cb, 0x592c0a0c, 0x48066202, 0x492e6008, + 0x0401f14a, 0x4df00000, 0x4203e000, 0x50000000, + 0x0402b00b, 0x835c0480, 0x00000020, 0x0400100d, + 0x815eb840, 0x416a5800, 0x592ed000, 0x492fb007, + 0x497a5800, 0x497a5801, 0x0400b7f7, 0x59d80005, + 0x82000500, 0x43018780, 0x02020000, 0x0010552a, + 0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000, + 0x50000000, 0x0402f00b, 0x835c0480, 0x00000020, + 0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000, + 0x492fa807, 0x497a5800, 0x497a5801, 0x0400f7f7, + 0x59d40005, 0x82000500, 0x43018780, 0x02020000, + 0x00105523, 0x5c03e000, 0x1c01f000, 0x4df00000, + 0x4203e000, 0x50000000, 0x59940024, 0x80000540, + 0x0400010f, 0x4c000000, 0x42000000, 0x00001000, + 0x50000000, 0x82000480, 0x24320001, 0x04020015, + 0x42000800, 0x00000064, 0x80040840, 0x04000007, + 0x4a030000, 0x00000001, 0x40000000, 0x59800000, + 0x8c000500, 0x040007f9, 0x04000008, 0x42000800, + 0x00007a01, 0x50040000, 0x8c000510, 0x04000003, + 0x84000510, 0x44000800, 0x4a030000, 0x00000000, + 0x59e00002, 0x8c00051e, 0x0402001b, 0x42000000, + 0x00001000, 0x50000000, 0x82000480, 0x24320002, + 0x04020015, 0x42000800, 0x00000064, 0x80040840, + 0x04000007, 0x4a030000, 0x00000001, 0x40000000, + 0x59800000, 0x8c000500, 0x040007f9, 0x04000008, + 0x42000800, 0x00007a17, 0x50040000, 0x8c00050e, + 0x04020003, 0x8400054e, 0x44000800, 0x4a030000, + 0x00000000, 0x5c000000, 0x5994781a, 0x48032825, + 0x803c0480, 0x04001004, 0x04000003, 0x4803281a, + 0x0401f022, 0x41787800, 0x803c7800, 0x82000400, + 0x000003e8, 0x040027fd, 0x4803281a, 0x59a80024, + 0x803c1400, 0x480b5024, 0x803c0040, 0x04000002, + 0x483fc857, 0x59e40852, 0x59a80025, 0x80040580, + 0x04000004, 0x480bc857, 0x59e40052, 0x48035025, + 0x59940026, 0x803c0400, 0x48032826, 0x0201f800, + 0x00105d5a, 0x59940000, 0x82000580, 0x00000000, + 0x04020006, 0x59940026, 0x48032827, 0x497b2826, + 0x4a032800, 0x00000001, 0x4c0c0000, 0x59940007, + 0x80000d40, 0x0400001d, 0x59941006, 0x59940025, + 0x80081c80, 0x04001004, 0x04000003, 0x480f2806, + 0x0401f016, 0x80040840, 0x48072807, 0x82040580, + 0x000003e8, 0x04020007, 0x4c040000, 0x4c0c0000, + 0x59940008, 0x0801f800, 0x5c001800, 0x5c000800, + 0x800409c0, 0x04020004, 0x59940008, 0x0801f800, + 0x0401f006, 0x400c0000, 0x820c1c00, 0x0000000a, + 0x040027ed, 0x480f2806, 0x5c001800, 0x4d180000, + 0x59c40008, 0x8c000534, 0x04020025, 0x417a3000, + 0x83947c00, 0x00000009, 0x583c0001, 0x80000d40, + 0x04020008, 0x823c7c00, 0x00000003, 0x811a3000, + 0x83180580, 0x00000005, 0x040207f8, 0x0401f018, + 0x583c1000, 0x59940025, 0x80080480, 0x04001005, + 0x04000004, 0x48007800, 0x80000040, 0x04021010, + 0x80040840, 0x48047801, 0x04000008, 0x82000400, + 0x0000000a, 0x48007800, 0x040027fa, 0x82040500, + 0x0000007f, 0x0401f7e8, 0x583c0002, 0x4c3c0000, + 0x0801f800, 0x5c007800, 0x0401f7e3, 0x5c023000, + 0x59940019, 0x80001540, 0x04000007, 0x04002006, + 0x59940025, 0x80080480, 0x04021002, 0x80000580, + 0x48032819, 0x5994001c, 0x80000d40, 0x04000013, + 0x5994101b, 0x59940025, 0x80080480, 0x04001005, + 0x04000004, 0x4803281b, 0x80000040, 0x0402100b, + 0x80040840, 0x4807281c, 0x04020004, 0x5994001d, + 0x0801f800, 0x0401f005, 0x82000400, 0x0000000a, + 0x4803281b, 0x040027f7, 0x59940004, 0x80000d40, + 0x04000013, 0x59941003, 0x59940025, 0x80080480, + 0x04001005, 0x04000004, 0x48032803, 0x80000040, + 0x0402100b, 0x80040840, 0x48072804, 0x04020004, + 0x59940005, 0x0801f800, 0x0401f005, 0x82000400, + 0x0000000a, 0x48032803, 0x040027f7, 0x5994001f, + 0x80000d40, 0x04000013, 0x5994101e, 0x59940025, + 0x80080480, 0x04001005, 0x04000004, 0x4803281e, + 0x80000040, 0x0402100b, 0x80040840, 0x4807281f, + 0x04020004, 0x59940020, 0x0801f800, 0x0401f005, + 0x82000400, 0x00000001, 0x4803281e, 0x040027f7, + 0x59940022, 0x80000d40, 0x04000013, 0x59941021, + 0x59940025, 0x80080480, 0x04001005, 0x04000004, + 0x48032821, 0x80000040, 0x0402100b, 0x80040840, + 0x48072822, 0x04020004, 0x59940023, 0x0801f800, + 0x0401f005, 0x82000400, 0x0000000a, 0x48032821, + 0x040027f7, 0x59940824, 0x59940025, 0x80040480, + 0x02001800, 0x00100615, 0x48032824, 0x59940000, + 0x0c01f001, 0x00105cee, 0x00105cf0, 0x00105d16, + 0x59940024, 0x80000000, 0x48032824, 0x4203e000, + 0x70000000, 0x1c01f000, 0x592c0406, 0x800000c2, + 0x800008c4, 0x80040c00, 0x592c040a, 0x48066206, + 0x82000d00, 0x00000003, 0x02000000, 0x00105e97, + 0x8c000500, 0x0402002c, 0x59a80872, 0x80040840, + 0x040207ff, 0x8c00051e, 0x02000000, 0x00105e72, + 0x82000d00, 0x000000c0, 0x02020000, 0x00105e68, + 0x82000d00, 0x00002020, 0x02020000, 0x00105e65, + 0x813e79c0, 0x02020000, 0x00105e65, 0x592c0c0c, + 0x800409c0, 0x02020000, 0x00105e65, 0x59300a03, + 0x82040d80, 0x00000007, 0x02020000, 0x00105e65, + 0x4a026203, 0x00000003, 0x4a026403, 0x00000043, + 0x0201f800, 0x000200ca, 0x82080d40, 0x80003465, + 0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516, + 0x040207fe, 0x83300400, 0xa0000000, 0x480378e1, + 0x1c01f000, 0x8c000502, 0x02020000, 0x00105eba, + 0x8c00051e, 0x0400000e, 0x82000d00, 0x000000c0, + 0x04000005, 0x82040d80, 0x000000c0, 0x02020000, + 0x00105ebf, 0x82000d00, 0x00002020, 0x82040d80, + 0x00002020, 0x02000000, 0x00105e86, 0x592c0207, + 0x80000040, 0x02020000, 0x00105e90, 0x592c180d, + 0x800c19c0, 0x02020000, 0x00105e90, 0x592c180f, + 0x59300007, 0x82000540, 0x00000011, 0x480e6011, + 0x48026007, 0x4a026203, 0x00000004, 0x4a026403, + 0x00000042, 0x42000800, 0x80002001, 0x0401f02a, + 0x5c000000, 0x4c000000, 0x4803c857, 0x4807c857, + 0x0401f003, 0x42000800, 0x00000001, 0x59325808, + 0x832c0500, 0x00ff0000, 0x0400000d, 0x592c0000, + 0x48065a06, 0x48026008, 0x592c040a, 0x8c000510, + 0x04020008, 0x0201f800, 0x00020381, 0x417a7800, + 0x59300008, 0x80025d40, 0x0402078c, 0x1c01f000, + 0x456a5800, 0x412ed000, 0x815eb800, 0x59c80000, + 0x82000540, 0x00001200, 0x48039000, 0x0401f7f4, + 0x59840000, 0x80000540, 0x04020002, 0x1c01f000, + 0x59840003, 0x80000540, 0x02020000, 0x00105f37, + 0x1c01f000, 0x59300004, 0x82000500, 0x00000100, + 0x80040d40, 0x48066004, 0x59bc00ea, 0x8c000516, + 0x040207fe, 0x83300400, 0x40000000, 0x480378e1, + 0x1c01f000, 0x59bc00ea, 0x82001500, 0xb0000018, + 0x02020000, 0x001069c6, 0x8c000510, 0x0400002a, + 0x59bc10e0, 0x82080500, 0xfffff000, 0x0402000a, + 0x80080108, 0x820a3500, 0x0000000f, 0x4803c857, + 0x1201f000, 0x001069cc, 0x84000510, 0x48026004, + 0x0401f016, 0x840a653e, 0x59300004, 0x8c000520, + 0x040007fa, 0x82000500, 0xfffefeff, 0x48026004, + 0x8c08153e, 0x04020005, 0x42027000, 0x00000013, + 0x0401f858, 0x0401f009, 0x59300004, 0x8c000514, + 0x04000003, 0x0401ffac, 0x0401f02e, 0x42027000, + 0x00000049, 0x0401f84f, 0x59bc00ea, 0x82001500, + 0xb0000018, 0x02020000, 0x001069c6, 0x8c000510, + 0x040207d8, 0x1c01f000, 0x83640480, 0x00000010, + 0x04001019, 0x41626000, 0x41580000, 0x59300a03, + 0x82040d80, 0x00000000, 0x04000008, 0x83326400, + 0x00000024, 0x81300c80, 0x040017f9, 0x42026000, + 0x0010cfc0, 0x0401f7f6, 0x4a026203, 0x00000008, + 0x8166c840, 0x8332c400, 0x00000024, 0x81600480, + 0x04021002, 0x1c01f000, 0x837ac540, 0x0010cfc0, + 0x1c01f000, 0x42000000, 0x0010b653, 0x0201f800, + 0x0010a86e, 0x4967c857, 0x80026580, 0x1c01f000, + 0x83300480, 0x0010cfc0, 0x02001800, 0x00100615, + 0x41580000, 0x81300480, 0x0402100c, 0x04011000, + 0x457a6000, 0x4a026202, 0x0000ffff, 0x83300400, + 0x00000003, 0x4803c840, 0x4a03c842, 0x00000021, + 0x8166c800, 0x1c01f000, 0x41540000, 0x81300480, + 0x02021800, 0x00100615, 0x04011000, 0x457a6000, + 0x4a026202, 0x0000ffff, 0x83300400, 0x00000003, + 0x4803c840, 0x4a03c842, 0x00000021, 0x59a80066, + 0x49335065, 0x80000000, 0x48035066, 0x1c01f000, + 0x4d340000, 0x59326809, 0x59300406, 0x82000500, + 0x0000001f, 0x0c01f803, 0x5c026800, 0x1c01f000, + 0x001076ed, 0x00107700, 0x0010771a, 0x00020900, + 0x001096c1, 0x001096dc, 0x00020975, 0x001076ed, + 0x00107700, 0x00106226, 0x00107733, 0x001076ed, + 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, + 0x0010936a, 0x0010a4d0, 0x001076ed, 0x001076ed, + 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, + 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, + 0x001076ed, 0x001076ed, 0x001076ed, 0x001076ed, + 0x59300203, 0x82000c80, 0x0000000e, 0x02021800, + 0x00100615, 0x0c01f001, 0x00107731, 0x00108337, + 0x00020914, 0x001084cc, 0x00108566, 0x00107731, + 0x00107731, 0x00107731, 0x0010831c, 0x00107731, + 0x00107731, 0x00107731, 0x00107731, 0x0010873a, + 0x83380480, 0x00000058, 0x04021007, 0x83380480, + 0x00000040, 0x04001004, 0x4d2c0000, 0x0c01f803, + 0x5c025800, 0x1c01f000, 0x001083c1, 0x001083c1, + 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c3, + 0x00108463, 0x001083c1, 0x001083c1, 0x001083c1, + 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c1, + 0x001083c1, 0x001083c1, 0x001083c1, 0x001083c1, + 0x001083c1, 0x00108467, 0x00020936, 0x001083c1, + 0x00108466, 0x00108468, 0x59325808, 0x59300811, + 0x59301402, 0x59340200, 0x8c00050e, 0x0402001c, + 0x0401f826, 0x04000005, 0x4a025a04, 0x00000103, + 0x497a5c09, 0x0401f009, 0x4a025a04, 0x00000103, + 0x4a025a06, 0x00000000, 0x497a5c09, 0x800409c0, + 0x02020800, 0x00108531, 0x48065807, 0x480a5c06, + 0x0201f800, 0x00020381, 0x5934000f, 0x5934140b, + 0x80081040, 0x04001002, 0x480a6c0b, 0x80000540, + 0x02020800, 0x00020275, 0x0401f75e, 0x592c020a, + 0x8c000502, 0x040007e9, 0x800409c0, 0x040007e7, + 0x592c0208, 0x8c00050e, 0x040207e4, 0x4933c857, + 0x0201f000, 0x00108fc6, 0x592c020a, 0x8c000500, + 0x04000010, 0x59300015, 0x592c380f, 0x801c3c80, + 0x0400000c, 0x4a025a06, 0x00000015, 0x8c1c3d3e, + 0x04000005, 0x4a025a06, 0x00000007, 0x801c3880, + 0x801c3800, 0x481fc857, 0x821c0d40, 0x00000000, + 0x1c01f000, 0x59300203, 0x82003480, 0x0000000e, + 0x02021800, 0x00100615, 0x0c01f001, 0x001096fb, + 0x00020989, 0x00109d9c, 0x00109daa, 0x000209a5, + 0x001096fb, 0x00109e98, 0x000209c4, 0x001096fb, + 0x001096fb, 0x001096fb, 0x001096fb, 0x001096fb, + 0x001096fb, 0x83380580, 0x00000013, 0x02020000, + 0x00109d23, 0x59300403, 0x82027480, 0x00000044, + 0x02021800, 0x00100615, 0x82000480, 0x00000040, + 0x02001800, 0x00100615, 0x0c01f001, 0x00109d80, + 0x0002099b, 0x00109d82, 0x00109d94, 0x59325808, + 0x832c0500, 0x00ff0000, 0x04000005, 0x592c0c0a, + 0x8c040d1a, 0x02020000, 0x00109d8f, 0x0401fe8e, + 0x0401f710, 0x83380580, 0x00000048, 0x04000007, + 0x83380580, 0x00000053, 0x02000000, 0x00109e3a, + 0x0201f800, 0x00100615, 0x5930001f, 0x59301011, + 0x59300809, 0x58040a00, 0x8c040d0e, 0x02020000, + 0x00109e16, 0x800811c0, 0x02020000, 0x00109e23, + 0x5930001f, 0x80000540, 0x02020000, 0x00109e31, + 0x59325808, 0x592c040a, 0x8c00051e, 0x02000000, + 0x00109e0c, 0x42027000, 0x00000041, 0x0401f001, + 0x83380480, 0x00000054, 0x02021800, 0x00100615, + 0x83380480, 0x00000040, 0x02001000, 0x00109e57, + 0x0c01f001, 0x00109e63, 0x000209e1, 0x00109e6f, + 0x00109e76, 0x00109e63, 0x00109e63, 0x00109e63, + 0x00109e63, 0x00109e65, 0x00109e6a, 0x00109e6a, + 0x00109e63, 0x00109e63, 0x00109e63, 0x00109e63, + 0x00109e6a, 0x00109e63, 0x00109e6a, 0x00109e63, + 0x00109e65, 0x4a026203, 0x00000001, 0x493a6403, + 0x42000800, 0x80002042, 0x0401f66f, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xa36ec441, 0x00000000, + 0x00000000, 0x00000000, 0x00000005, 0xfffffffb, + 0x02800004, 0x00000000, 0x0000c000, 0x0000071b, + 0x073fca5a, 0x0705a5a5, 0x01928009, 0x070ff0e1, + 0x03800006, 0x04958010, 0x05308000, 0x05008000, + 0x0600902f, 0x04a004dc, 0x0202f051, 0x042e4020, + 0x018f021b, 0x033e5000, 0x03020000, 0x078d0018, + 0x0493041a, 0x0092041c, 0x038a0305, 0x078b0303, + 0x048e8010, 0x0678aae5, 0x06000001, 0x07818174, + 0x040010e6, 0x0448e0e6, 0x04818010, 0x002fb008, + 0x0448e0e6, 0x04818010, 0x060ff0e6, 0x00580401, + 0x054880ff, 0x04818010, 0x022a5001, 0x030430d4, + 0x06780043, 0x030e0000, 0x030450ff, 0x06780043, + 0x03019000, 0x048185c4, 0x027c0045, 0x03020000, + 0x06810037, 0x027c0045, 0x03040000, 0x068100c7, + 0x027c0045, 0x03080000, 0x0681061c, 0x04908037, + 0x029105c2, 0x010410a6, 0x0379ff41, 0x037fffff, + 0x072d6000, 0x07601241, 0x050f80ff, 0x032fa009, + 0x05600400, 0x050f80ff, 0x056c04ff, 0x068105da, + 0x073fa009, 0x06000001, 0x0279ff02, 0x0700ffff, + 0x070ff0d1, 0x0179feff, 0x0700ffff, 0x045c0402, + 0x048185da, 0x060ff0d0, 0x0179feff, 0x0700ffff, + 0x057dfeff, 0x0700ffff, 0x068105bc, 0x05600e41, + 0x050f80ff, 0x032fa069, 0x07480000, 0x068105ce, + 0x06780043, 0x070000f0, 0x0781005f, 0x037c00ff, + 0x06000010, 0x0781005f, 0x038005ca, 0x0379ff00, + 0x070fffff, 0x06780043, 0x07f00000, 0x075a0000, + 0x020ef001, 0x038605cc, 0x05484000, 0x02a1819e, + 0x062d6001, 0x002fb001, 0x070ff069, 0x01868072, + 0x060ff079, 0x055c0441, 0x06810010, 0x012fb000, + 0x060560fb, 0x03800078, 0x060ff079, 0x02868198, + 0x070ff069, 0x055c0441, 0x06810010, 0x060560fb, + 0x0400d0d0, 0x062d6002, 0x0648300d, 0x06810086, + 0x070ff0d1, 0x062d6001, 0x045c040b, 0x06810089, + 0x05488000, 0x04818086, 0x072e500c, 0x00208001, + 0x05a004e1, 0x02800010, 0x062d6001, 0x07f00000, + 0x07f00000, 0x070ff0d1, 0x0179feff, 0x070000ff, + 0x055c040c, 0x058180bb, 0x0007b001, 0x03079041, + 0x0307a000, 0x06600a79, 0x050f80ff, 0x053fa80a, + 0x06000010, 0x072d5003, 0x078d0096, 0x0307c003, + 0x0007d004, 0x0107e005, 0x0307f006, 0x02080007, + 0x00081008, 0x01082009, 0x0308300a, 0x0008400b, + 0x0308500c, 0x068d00a1, 0x0678007a, 0x07f00000, + 0x010880ff, 0x03386000, 0x03010000, 0x072e6300, + 0x020ef07f, 0x02860010, 0x070ff07d, 0x0450047c, + 0x050f80ff, 0x002fa819, 0x068d00ae, 0x02080001, + 0x00081002, 0x0448807a, 0x068100b5, 0x0379ff03, + 0x070000ff, 0x01082003, 0x068d00b6, 0x02386004, + 0x03010000, 0x072e6c00, 0x02800010, 0x06780043, + 0x070000f0, 0x068105d5, 0x050020ff, 0x027c0002, + 0x06000010, 0x078100c3, 0x028005d5, 0x0700c0d1, + 0x0379ff0c, 0x070000ff, 0x0380008e, 0x0204a051, + 0x06780043, 0x070000f0, 0x037c00ff, 0x06000010, + 0x0781816a, 0x072d6000, 0x019485be, 0x050fb056, + 0x044880e6, 0x04818010, 0x060ff0d0, 0x0179feff, + 0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068105bc, + 0x05a00212, 0x0349c0e4, 0x0781811d, 0x070ff093, + 0x050010ff, 0x070ff093, 0x045c0401, 0x058180db, + 0x02046092, 0x04002046, 0x04600202, 0x00540401, + 0x048280e6, 0x04500425, 0x070060ff, 0x0730ffff, + 0x0700000f, 0x0742000f, 0x05810190, 0x06a005a4, + 0x0648a002, 0x048180e9, 0x00047089, 0x070ff047, + 0x045c0443, 0x077800ff, 0x07f00000, 0x0781818e, + 0x07780047, 0x0500e000, 0x048185ab, 0x070ff006, + 0x01860117, 0x0179fe47, 0x0700000f, 0x010480ff, + 0x056c7048, 0x06818102, 0x007a0d4a, 0x04003801, + 0x0220f001, 0x0180010f, 0x07608e48, 0x034a60ff, + 0x0700f0ff, 0x074b88ff, 0x037000ff, 0x07000600, + 0x05500448, 0x074d00ff, 0x045a044a, 0x0304a0ff, + 0x070ff00f, 0x01540406, 0x05820117, 0x04950120, + 0x05a001bd, 0x02868123, 0x0134bfff, 0x070fffff, + 0x0104102e, 0x050fd041, 0x00800126, 0x0595011d, + 0x05a001bd, 0x0186011d, 0x0202f00e, 0x052e4030, + 0x040fd02f, 0x070fc0ff, 0x05a00218, 0x02800010, + 0x0400e02f, 0x042e4020, 0x0202f051, 0x0004100e, + 0x0004b00e, 0x050fd041, 0x024a6c46, 0x04500423, + 0x050070ff, 0x03620024, 0x050080ff, 0x04004046, + 0x0700500f, 0x03206000, 0x05601048, 0x0700a0ff, + 0x0700900a, 0x070ff005, 0x04500446, 0x00540425, + 0x04820157, 0x05601622, 0x050f80ff, 0x063fa032, + 0x06000002, 0x03203000, 0x01204000, 0x03205000, + 0x0120b000, 0x0320c000, 0x07601441, 0x050f80ff, + 0x043fa852, 0x06000001, 0x070ff056, 0x056c02ff, + 0x050fb0ff, 0x070560ff, 0x03079041, 0x05600e41, + 0x050f80ff, 0x073fa011, 0x0600003d, 0x06780043, + 0x07f00000, 0x065a007a, 0x010880ff, 0x04a001b6, + 0x058d0150, 0x0208a04a, 0x0108b04b, 0x02386001, + 0x03010000, 0x072e6300, 0x028000a8, 0x0500d00a, + 0x05500405, 0x014a68ff, 0x070090ff, 0x0154040a, + 0x0700c0ff, 0x0600a023, 0x0500b024, 0x02206001, + 0x05601622, 0x050f80ff, 0x063fa04a, 0x06000002, + 0x05601022, 0x050f80ff, 0x043fa819, 0x06000001, + 0x0600a00d, 0x0180013c, 0x06780043, 0x070000f0, + 0x050010ff, 0x027c0001, 0x07000030, 0x078105b2, + 0x027c0001, 0x06000020, 0x078105b2, 0x038005ca, + 0x054880ff, 0x06810010, 0x070ff056, 0x050fb0ff, + 0x044880e5, 0x0581017d, 0x044880e6, 0x04818010, + 0x00800183, 0x056c02ff, 0x050fb0ff, 0x070560ff, + 0x072e5300, 0x044880e6, 0x04818010, 0x072d5003, + 0x06780043, 0x07f00000, 0x010880ff, 0x058d0187, + 0x03386005, 0x03010000, 0x033e6000, 0x0700000c, + 0x052e5200, 0x02800010, 0x0120918e, 0x018004e4, + 0x01209190, 0x018004e4, 0x00209192, 0x018004e4, + 0x03209000, 0x018004e4, 0x01209196, 0x018004e4, + 0x00209198, 0x018004e4, 0x02493075, 0x0681050b, + 0x0120919a, 0x018004e4, 0x06601e01, 0x050f80ff, + 0x063fa029, 0x06000008, 0x02015010, 0x02016051, + 0x00017051, 0x00011051, 0x05601a41, 0x050f80ff, + 0x053fa83a, 0x06000008, 0x05600e41, 0x050f80ff, + 0x01464000, 0x032fa00a, 0x07006011, 0x05007012, + 0x04008013, 0x07009014, 0x0600a015, 0x0400b016, + 0x0700c017, 0x07c00000, 0x072d5003, 0x06601479, + 0x050f80ff, 0x048d01b9, 0x063fa051, 0x0600003e, + 0x07c00000, 0x06005051, 0x0400e02c, 0x0660060e, + 0x050f80ff, 0x032fa009, 0x0379ff00, 0x070000ff, + 0x076c0000, 0x058101dd, 0x0660480e, 0x0500e0ff, + 0x034000ff, 0x01540427, 0x0582020a, 0x03400005, + 0x070ff005, 0x055c0428, 0x0481020e, 0x01680e05, + 0x056c0405, 0x068181bf, 0x040f8029, 0x053fa809, + 0x07000024, 0x06600649, 0x050f80ff, 0x032fa009, + 0x0379ff00, 0x070000ff, 0x076c0000, 0x068181bf, + 0x0400e049, 0x0340002d, 0x050f802b, 0x053fa80a, + 0x06000016, 0x0660480e, 0x0302c0ff, 0x034000ff, + 0x01540427, 0x0582020c, 0x072d6000, 0x0460040e, + 0x050f80ff, 0x0104e0d1, 0x0379ff4e, 0x0700ffff, + 0x062d6002, 0x032fa009, 0x0004d0d0, 0x074b004d, + 0x07780000, 0x07ffff00, 0x055a044d, 0x070000ff, + 0x00201008, 0x04002051, 0x06003051, 0x05304000, + 0x07000060, 0x03205009, 0x07006022, 0x0460040e, + 0x050f80ff, 0x032fa03a, 0x06603c0e, 0x050f80ff, + 0x073fa00a, 0x07000027, 0x050010d1, 0x0460320e, + 0x050f80ff, 0x012fa80a, 0x060ff00e, 0x055c042e, + 0x04810210, 0x07c00000, 0x0400e026, 0x008001cb, + 0x0202c026, 0x008001e6, 0x0500e02e, 0x008001e6, + 0x0400e051, 0x01800209, 0x0349c0e4, 0x04810215, + 0x07c00000, 0x013e4000, 0x070c0000, 0x07c00000, + 0x013e4000, 0x03080000, 0x07c00000, 0x009702f4, + 0x022a5002, 0x0790821d, 0x00910291, 0x030400a6, + 0x0678aae5, 0x06000001, 0x01a1860c, 0x06600c40, + 0x050f80ff, 0x032fa021, 0x074b0000, 0x076c0600, + 0x07818293, 0x05600403, 0x050f80ff, 0x073fa009, + 0x06000002, 0x0279ff04, 0x0700ffff, 0x010440d7, + 0x0179fe44, 0x0700ffff, 0x045c0404, 0x07818295, + 0x0349f044, 0x0681829e, 0x02495001, 0x06818297, + 0x060ff079, 0x045c0440, 0x0781823c, 0x0644f07a, + 0x002fb008, 0x060ff079, 0x045c0440, 0x07818241, + 0x0644f07a, 0x002fb008, 0x0648f001, 0x07818288, + 0x04600e40, 0x050f80ff, 0x06480001, 0x04810257, + 0x0448e001, 0x04810273, 0x02460001, 0x0644f001, + 0x012fa80a, 0x04008040, 0x05a004ee, 0x0286828c, + 0x05a004d8, 0x062da001, 0x013e4000, 0x06000080, + 0x06930013, 0x02920013, 0x02800010, 0x0644f001, + 0x012fa80a, 0x020ef002, 0x00860275, 0x04600840, + 0x050f80ff, 0x053fa809, 0x06000002, 0x05780105, + 0x00800440, 0x017c0105, 0x05000400, 0x06818275, + 0x06601e02, 0x050f80ff, 0x053fa809, 0x06000002, + 0x04602a40, 0x050f80ff, 0x070ff005, 0x053fa809, + 0x06000002, 0x055c0405, 0x06818275, 0x04008040, + 0x0045e008, 0x05a004d8, 0x00800251, 0x0644f001, + 0x012fa80a, 0x050020d8, 0x04600440, 0x050f80ff, + 0x073fa00a, 0x06000001, 0x06480001, 0x07818281, + 0x05308000, 0x03040000, 0x06009040, 0x04a004dc, + 0x00800251, 0x07a0060c, 0x054b0800, 0x056a0700, + 0x06600c40, 0x050f80ff, 0x032fa00a, 0x00800251, + 0x013e4000, 0x06000080, 0x01209288, 0x018004e4, + 0x06009008, 0x05308000, 0x05004000, 0x04a004dc, + 0x00800251, 0x02209002, 0x008002e5, 0x03209000, + 0x008002e5, 0x02209004, 0x008002e5, 0x04a002fd, + 0x062da001, 0x05308000, 0x05002000, 0x06009040, + 0x04a004dc, 0x00800252, 0x013e4000, 0x06000080, + 0x02495001, 0x078182db, 0x04600840, 0x050f80ff, + 0x053fa809, 0x06000001, 0x0721f000, 0x0349f003, + 0x058102aa, 0x0245f01f, 0x06000002, 0x018602db, + 0x07601400, 0x050f80ff, 0x012fa809, 0x06480001, + 0x058102db, 0x06602440, 0x050f80ff, 0x012fa809, + 0x020ef001, 0x038682db, 0x019b02db, 0x050020d8, + 0x062da001, 0x06303002, 0x05000430, 0x04600440, + 0x050f80ff, 0x073fa012, 0x06000001, 0x028f82bf, + 0x050040d8, 0x062da001, 0x07601e00, 0x050f80ff, + 0x073fa009, 0x06000001, 0x060ff004, 0x00540402, + 0x048202d9, 0x06005051, 0x06006051, 0x06602240, + 0x050f80ff, 0x063fa01a, 0x06000002, 0x06600a40, + 0x050f80ff, 0x073fa00a, 0x07000003, 0x060ff040, + 0x045a041f, 0x010eb0ff, 0x06930013, 0x02920013, + 0x02800010, 0x04004002, 0x018002c9, 0x04a002fd, + 0x062da001, 0x05308000, 0x07005000, 0x06009040, + 0x04a004dc, 0x050080d8, 0x05a004e1, 0x062da001, + 0x02800013, 0x050fd009, 0x050fd041, 0x013e4000, + 0x06000080, 0x05308000, 0x03013000, 0x04a004dc, + 0x010440d7, 0x0349f044, 0x048102f2, 0x062da001, + 0x008f02f2, 0x03e00000, 0x062da001, 0x02800013, + 0x0249c0e5, 0x06810013, 0x062da001, 0x07f00000, + 0x07f00000, 0x033e5000, 0x070c0000, 0x018f02f6, + 0x03800011, 0x050020d8, 0x04600440, 0x050f80ff, + 0x073fa00a, 0x06000001, 0x07c00000, 0x002fb001, + 0x03800306, 0x012fb000, 0x03075087, 0x068d0307, + 0x03386000, 0x03020000, 0x04482075, 0x06810352, + 0x0648a0e6, 0x07810347, 0x0642007f, 0x06810345, + 0x0340007e, 0x060ff038, 0x0154047e, 0x02d00334, + 0x0560027d, 0x050f80ff, 0x032fa009, 0x030ef000, + 0x02860504, 0x0107d000, 0x05600800, 0x050f80ff, + 0x032fa009, 0x03681e00, 0x04500420, 0x050f80ff, + 0x073fa009, 0x0700003f, 0x03800311, 0x070ff07d, + 0x0450047c, 0x050f80ff, 0x002fa819, 0x078d0327, + 0x02080001, 0x00081002, 0x0448807a, 0x0781032e, + 0x0379ff03, 0x070000ff, 0x01082003, 0x068d032f, + 0x02386004, 0x03010000, 0x072e6c00, 0x02800352, + 0x0380033a, 0x0380033c, 0x0280033e, 0x02800340, + 0x03800342, 0x03800344, 0x0727c005, 0x02800323, + 0x0627c008, 0x02800323, 0x0627c00b, 0x02800323, + 0x0627c00e, 0x02800323, 0x0727c011, 0x02800323, + 0x03800314, 0x052e6800, 0x02800352, 0x044880e6, + 0x06810531, 0x052e6200, 0x070ff088, 0x0179feff, + 0x070fffff, 0x04818501, 0x060ff083, 0x0086836d, + 0x033e6000, 0x07000003, 0x068d0352, 0x07286000, + 0x07f00000, 0x078d0355, 0x038c0306, 0x0648c0e6, + 0x05818372, 0x0448e0e6, 0x0781036a, 0x004920e6, + 0x07810365, 0x06a0056d, 0x05001088, 0x00700101, + 0x03100000, 0x00088001, 0x033e6000, 0x07000088, + 0x0280055e, 0x02386001, 0x07030000, 0x033e6000, + 0x06000008, 0x028003f1, 0x02799075, 0x0500040f, + 0x06810010, 0x06601479, 0x050080ff, 0x06309052, + 0x0600003e, 0x02800376, 0x06602279, 0x050080ff, + 0x05309812, 0x07000041, 0x0648007a, 0x0781037e, + 0x04488075, 0x0581837e, 0x040f8008, 0x070fa009, + 0x0049107a, 0x01a183f3, 0x00798075, 0x06000507, + 0x0481851c, 0x0448b075, 0x06810385, 0x02493075, + 0x07810509, 0x0249c0e6, 0x048183e0, 0x0648c0e6, + 0x0581839a, 0x068d0389, 0x02386001, 0x07030000, + 0x0049107a, 0x07810390, 0x020ef083, 0x0386039a, + 0x06483075, 0x068103ef, 0x0678007a, 0x07000035, + 0x03a184cf, 0x05308000, 0x07060000, 0x06009079, + 0x04a004dc, 0x028003ef, 0x0448807a, 0x0681039e, + 0x06483075, 0x058104f9, 0x0448d07a, 0x068103a2, + 0x06483075, 0x058104f9, 0x068d03a2, 0x02386001, + 0x07030000, 0x0444e07a, 0x0648307a, 0x048183c7, + 0x0448707a, 0x068103ea, 0x0648f07a, 0x078103b2, + 0x05a004cf, 0x04008079, 0x05a004ee, 0x008683c2, + 0x05a004d8, 0x028003ef, 0x0560107b, 0x050f80ff, + 0x032fa009, 0x0349c000, 0x058183c0, 0x04600e79, + 0x050f80ff, 0x073fa00a, 0x0600003d, 0x06600a79, + 0x050f80ff, 0x053fa80a, 0x06000010, 0x028003ef, + 0x0046e07a, 0x028003ea, 0x06009008, 0x05308000, + 0x05004000, 0x04a004dc, 0x028003ef, 0x0560167b, + 0x050f80ff, 0x032fa011, 0x070ff000, 0x04500401, + 0x030460ff, 0x060ff025, 0x00540446, 0x078203d1, + 0x030460ff, 0x04092046, 0x05a00218, 0x06600679, + 0x050f80ff, 0x00201007, 0x012fa80a, 0x0046047a, + 0x034630ff, 0x050020ff, 0x06003051, 0x04600e79, + 0x050f80ff, 0x073fa012, 0x06000001, 0x028003ef, + 0x033e6a00, 0x0202000e, 0x02079051, 0x07000088, + 0x078d03e4, 0x0744c000, 0x01088000, 0x03386006, + 0x03010000, 0x02800010, 0x05a004cf, 0x05308000, + 0x03020000, 0x06009079, 0x04a004dc, 0x033e6a00, + 0x0302000a, 0x02079051, 0x02800010, 0x04603e79, + 0x050f80ff, 0x032fa009, 0x070ff000, 0x0186040c, + 0x057dfeff, 0x07ffffff, 0x0581040c, 0x050f8000, + 0x012fa811, 0x0079fe02, 0x070000ff, 0x077d66ff, + 0x060000dc, 0x0781840c, 0x060ff001, 0x0286840d, + 0x064b0002, 0x06420002, 0x060ff002, 0x05500400, + 0x050f80ff, 0x05004084, 0x073fa00a, 0x06000002, + 0x07c00000, 0x04600201, 0x050f80ff, 0x073fa009, + 0x06000001, 0x0079fe02, 0x070000ff, 0x077d72ff, + 0x070000dd, 0x0781840c, 0x064b0002, 0x06420002, + 0x06000001, 0x01800406, 0x0605004c, 0x0180041e, + 0x0493041a, 0x04a004d5, 0x054bc450, 0x05810421, + 0x01d00422, 0x01800421, 0x00800432, 0x00800434, + 0x00800432, 0x008004a7, 0x0180043f, 0x00800434, + 0x01800471, 0x00800432, 0x00800432, 0x008004ab, + 0x00800432, 0x018004af, 0x008004c4, 0x01800488, + 0x00800432, 0x00800432, 0x00209432, 0x018004e4, + 0x0379ff50, 0x070fffff, 0x060ff079, 0x055c0450, + 0x048104a4, 0x002fb008, 0x060ff079, 0x055c0450, + 0x058104a3, 0x04a004c7, 0x0180049c, 0x0179fe50, + 0x070fffff, 0x070050ff, 0x060ff079, 0x055c0405, + 0x04810449, 0x002fb008, 0x060ff079, 0x055c0405, + 0x078184a0, 0x070ff087, 0x017980ff, 0x06000507, + 0x06818451, 0x02203040, 0x05002087, 0x0049d002, + 0x0481046b, 0x04930458, 0x01257000, 0x073c3fff, + 0x0700000f, 0x052e4003, 0x072e5030, 0x0304c050, + 0x02400057, 0x06740057, 0x06000002, 0x06820016, + 0x04002083, 0x07003084, 0x04004085, 0x06602279, + 0x050f80ff, 0x063fa01a, 0x06000001, 0x05a004cf, + 0x06a00576, 0x033e6a00, 0x0302000a, 0x062e5020, + 0x003e4002, 0x07000a00, 0x028003f1, 0x07420003, + 0x0781844e, 0x00798002, 0x06000507, 0x06818451, + 0x0180045c, 0x05930478, 0x01257000, 0x073c3fff, + 0x0700000f, 0x052e4003, 0x072e5030, 0x0304c050, + 0x067800e6, 0x07000041, 0x0581047d, 0x06a0057f, + 0x04818016, 0x002fb008, 0x067800e6, 0x07000041, + 0x04810483, 0x06a0057f, 0x04818016, 0x062e5020, + 0x003e4002, 0x07000a00, 0x03e00000, 0x02800010, + 0x0379ff50, 0x070fffff, 0x060ff079, 0x055c0450, + 0x0781848e, 0x0245507a, 0x002fb008, 0x060ff079, + 0x055c0450, 0x07818493, 0x0245507a, 0x002fb008, + 0x05600e50, 0x050f80ff, 0x012fa809, 0x02455001, + 0x05600e50, 0x050f80ff, 0x012fa80a, 0x0080049d, + 0x002fb008, 0x003e4002, 0x07000a00, 0x02800016, + 0x079384a3, 0x062e5020, 0x042e4002, 0x002fb008, + 0x013e4000, 0x05000e00, 0x02800016, 0x0179fe50, + 0x070fffff, 0x010210ff, 0x02800016, 0x0179fe50, + 0x070fffff, 0x050340ff, 0x0080049d, 0x0179fe50, + 0x070fffff, 0x0102e0ff, 0x0760282e, 0x050f80ff, + 0x05222000, 0x07223000, 0x05224000, 0x07225000, + 0x07226000, 0x05227000, 0x05228000, 0x07229000, + 0x0722a000, 0x0522b000, 0x063fa051, 0x07000011, + 0x0202c026, 0x0522d000, 0x052e400c, 0x02800016, + 0x030430d4, 0x062e5008, 0x00800176, 0x05600e50, + 0x050f80ff, 0x032fa009, 0x03460000, 0x018004d2, + 0x0246007a, 0x0045207a, 0x008004d0, 0x0246007a, + 0x0600007a, 0x04600e79, 0x050f80ff, 0x032fa00a, + 0x07c00000, 0x029284d5, 0x070500e1, 0x07c00000, + 0x0245f008, 0x048404d9, 0x020e0008, 0x07c00000, + 0x070ff009, 0x065a0008, 0x058404de, 0x020e0008, + 0x07c00000, 0x058404e1, 0x020e0008, 0x07c00000, + 0x05308000, 0x0500d000, 0x04a004dc, 0x04a004e9, + 0x02800010, 0x052e4300, 0x072e500c, 0x073c3fff, + 0x0700000f, 0x07c00000, 0x06602208, 0x050f80ff, + 0x032fa011, 0x076a0000, 0x068184f7, 0x066a0001, + 0x048104f7, 0x04002051, 0x07c00000, 0x00202001, + 0x07c00000, 0x0648307a, 0x01a18606, 0x05a004cc, + 0x05308000, 0x05001000, 0x06009079, 0x04a004dc, + 0x0280055e, 0x0249c0e6, 0x058104f9, 0x0280036d, + 0x0648307a, 0x07818196, 0x05a004cf, 0x02209504, + 0x018004e4, 0x02490075, 0x06810519, 0x04002089, + 0x04780102, 0x07f00000, 0x05001088, 0x06a0056d, + 0x04740101, 0x03100000, 0x060ff002, 0x045c0401, + 0x0481851a, 0x00088001, 0x033e6000, 0x070000c0, + 0x0380055a, 0x07f00000, 0x0220951a, 0x018004e4, + 0x040fd075, 0x040fd07a, 0x040fd079, 0x0648307a, + 0x06810525, 0x06780075, 0x06000007, 0x0481852c, + 0x07a00606, 0x06486075, 0x06818194, 0x02490075, + 0x0781819a, 0x04487075, 0x04818534, 0x0280053b, + 0x05308000, 0x03010000, 0x06009079, 0x04a004dc, + 0x02800010, 0x0448e0e6, 0x04818352, 0x00800192, + 0x05308000, 0x0500e000, 0x06009079, 0x04a004dc, + 0x04008089, 0x05a004e1, 0x0380055a, 0x05a004cc, + 0x05308000, 0x0700f000, 0x06009079, 0x07000088, + 0x06a00543, 0x04a004dc, 0x02800010, 0x03386000, + 0x07030000, 0x07f00000, 0x068d0546, 0x033e6a00, + 0x0202000e, 0x02079051, 0x0448b075, 0x06810551, + 0x02493075, 0x06810551, 0x05301005, 0x03010000, + 0x03800553, 0x05301006, 0x03010000, 0x05002087, + 0x06485002, 0x05818553, 0x0744c000, 0x01088000, + 0x02086001, 0x07c00000, 0x05001088, 0x06a0056d, + 0x0644c001, 0x00088001, 0x033e6a00, 0x0202000e, + 0x004920e6, 0x05818563, 0x02079051, 0x078d0563, + 0x060ff089, 0x034990ff, 0x0781056a, 0x03386005, + 0x03010000, 0x02800010, 0x03386006, 0x03010000, + 0x02800010, 0x068d056d, 0x03386000, 0x07030000, + 0x07f00000, 0x078d0571, 0x070ff087, 0x074850ff, + 0x05818572, 0x07c00000, 0x068d0576, 0x02386001, + 0x07030000, 0x07f00000, 0x068d057a, 0x070ff087, + 0x074850ff, 0x0581857b, 0x07c00000, 0x05002087, + 0x0049d002, 0x0581858e, 0x002fb008, 0x067800e6, + 0x07000041, 0x002fb008, 0x0581858e, 0x06a005a4, + 0x0448e002, 0x06810591, 0x0648a002, 0x0481859b, + 0x06486002, 0x07810595, 0x02400057, 0x056a02ff, + 0x07c00000, 0x06a005a4, 0x06788102, 0x06000004, + 0x0581858e, 0x04002089, 0x070ff0d4, 0x045c0402, + 0x077800ff, 0x07f00000, 0x0581858e, 0x00202010, + 0x038c058e, 0x07f00000, 0x06420002, 0x0581859c, + 0x06a00576, 0x033e6a00, 0x0302000a, 0x07c00000, + 0x07f00000, 0x060ff0a2, 0x050020ff, 0x060ff0a2, + 0x045c0402, 0x058185a5, 0x07c00000, 0x05a00218, + 0x03495047, 0x068105b0, 0x0320901d, 0x02800602, + 0x0220901f, 0x02800602, 0x014980e4, 0x04818010, + 0x013e4000, 0x07003000, 0x05600e35, 0x050f80ff, + 0x07a006fa, 0x01208003, 0x05a004e1, 0x038005ca, + 0x03209009, 0x02800602, 0x03209011, 0x02800602, + 0x02209007, 0x02800602, 0x03209003, 0x02800602, + 0x00498043, 0x048185bc, 0x00497043, 0x058185c0, + 0x02209001, 0x02800602, 0x0220900d, 0x02800602, + 0x0320900f, 0x02800602, 0x03493000, 0x068105d3, + 0x027c0045, 0x070a0000, 0x068105dc, 0x0220900b, + 0x02800602, 0x02209013, 0x05308000, 0x01012000, + 0x04a004dc, 0x00800183, 0x03209005, 0x02800602, + 0x072e500c, 0x00208002, 0x05a004e1, 0x02800010, + 0x02209015, 0x02800602, 0x072d6000, 0x05308000, + 0x05007000, 0x07f00000, 0x070090d1, 0x0379ff09, + 0x0700ffff, 0x04a004dc, 0x03209017, 0x02800602, + 0x033e5000, 0x06000080, 0x02209019, 0x02800602, + 0x072d6000, 0x033e5000, 0x06000080, 0x07f00000, + 0x060ff0d0, 0x0179feff, 0x0700ffff, 0x057dfeff, + 0x0700ffff, 0x04818010, 0x02400058, 0x00642058, + 0x06820010, 0x033e5000, 0x06000080, 0x04058051, + 0x0320901b, 0x02800602, 0x05308000, 0x01012000, + 0x04a004dc, 0x00800176, 0x05a00218, 0x05308000, + 0x05008000, 0x06009079, 0x04a004dc, 0x07c00000, + 0x034900e4, 0x04818616, 0x013e4000, 0x070000c0, + 0x07f00000, 0x034900e4, 0x05818614, 0x07c00000, + 0x013e4000, 0x06000080, 0x07f00000, 0x07f00000, + 0x07f00000, 0x034900e4, 0x0681060e, 0x02800616, + 0x072d6000, 0x00498043, 0x07810630, 0x060ff0d0, + 0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff, + 0x048185e0, 0x050f8030, 0x032fa009, 0x0379ff00, + 0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff, + 0x055c0400, 0x068105e0, 0x04004051, 0x03800678, + 0x06a006da, 0x062d6001, 0x020ef004, 0x038605e2, + 0x06600004, 0x050f80ff, 0x032fa009, 0x074b0000, + 0x05002000, 0x0769ff00, 0x01640800, 0x078205e2, + 0x01640e00, 0x058285e2, 0x070ff036, 0x045c0404, + 0x0581864b, 0x072d6000, 0x050f8030, 0x032fa009, + 0x0379ff00, 0x0700ffff, 0x070ff0d1, 0x0179feff, + 0x0700ffff, 0x055c0400, 0x068105e0, 0x04482034, + 0x068105fd, 0x06483034, 0x048185fd, 0x070ff0d4, + 0x077800ff, 0x070000f0, 0x037c00ff, 0x06000010, + 0x07810678, 0x07a006d4, 0x024900e5, 0x0681065b, + 0x033e5000, 0x06000080, 0x02800010, 0x04601c04, + 0x050f80ff, 0x053fa809, 0x06000020, 0x030ef041, + 0x028605ec, 0x062d6002, 0x05602a41, 0x050f80ff, + 0x012fa809, 0x060ff0d0, 0x074b00ff, 0x045c0401, + 0x04818676, 0x062d6001, 0x07602841, 0x050f80ff, + 0x053fa809, 0x06000001, 0x070ff0d1, 0x054b80ff, + 0x074b0003, 0x055c0403, 0x04818676, 0x033e5000, + 0x06000080, 0x0180070c, 0x07600041, 0x0380065c, + 0x07a006d4, 0x024900e5, 0x0781067e, 0x033e5000, + 0x06000080, 0x02800010, 0x07a006c0, 0x030ef041, + 0x038605f0, 0x04058051, 0x072d6000, 0x05601041, + 0x050f80ff, 0x012fa809, 0x0600a0d0, 0x0500b0d1, + 0x062d6001, 0x07f00000, 0x07f00000, 0x0600c0d0, + 0x0500d0d1, 0x062d6002, 0x0279ff0d, 0x07ff0000, + 0x044d800d, 0x060ff0d0, 0x074b00ff, 0x065a000d, + 0x06601201, 0x050f80ff, 0x073fa022, 0x07000005, + 0x0079fe0d, 0x070000ff, 0x050020ff, 0x05602a41, + 0x050f80ff, 0x073fa00a, 0x06000001, 0x020ef004, + 0x038606bd, 0x04601c04, 0x050f80ff, 0x053fa809, + 0x06000001, 0x050f80ff, 0x053fa80a, 0x06000020, + 0x07602841, 0x050f80ff, 0x073fa009, 0x06000001, + 0x0279ff02, 0x070000ff, 0x0678000d, 0x0700ff00, + 0x065a0002, 0x07602841, 0x050f80ff, 0x073fa00a, + 0x06000001, 0x07600041, 0x050f80ff, 0x053fa80a, + 0x06000001, 0x07601241, 0x050f80ff, 0x073fa00a, + 0x06000002, 0x033e5000, 0x06000080, 0x0180070c, + 0x040f8032, 0x073fa011, 0x06000001, 0x060ff002, + 0x055c0403, 0x048186c8, 0x00041051, 0x07c00000, + 0x04600402, 0x04500432, 0x050f80ff, 0x053fa809, + 0x06000020, 0x00400402, 0x01680eff, 0x070030ff, + 0x040f8032, 0x053fa80a, 0x06000001, 0x07c00000, + 0x024900e5, 0x078106d7, 0x07c00000, 0x033e5000, + 0x070000c0, 0x07c00000, 0x05004036, 0x060000d0, + 0x0179fe00, 0x0700ffff, 0x057dfeff, 0x0700ffff, + 0x078106f9, 0x070000d1, 0x0379ff00, 0x0700ffff, + 0x06005051, 0x060ff031, 0x05500405, 0x050f80ff, + 0x073fa009, 0x06000002, 0x020ef004, 0x038606f3, + 0x04600404, 0x050f80ff, 0x012fa809, 0x0079fe01, + 0x0700ffff, 0x055c0400, 0x078106f9, 0x01400405, + 0x070050ff, 0x057de0ff, 0x06000007, 0x048186e5, + 0x04004051, 0x07c00000, 0x072d6000, 0x07f00000, + 0x07f00000, 0x000110d0, 0x010120d1, 0x062d6001, + 0x07f00000, 0x07f00000, 0x020130d0, 0x010140d1, + 0x062d6002, 0x010170d4, 0x07f00000, 0x020150d0, + 0x030160d1, 0x053fa83a, 0x06000008, 0x07c00000, + 0x07600c41, 0x050f80ff, 0x073fa009, 0x06000001, + 0x04780102, 0x07ffff00, 0x046a0702, 0x050f80ff, + 0x073fa00a, 0x06000001, 0x05600e41, 0x050f80ff, + 0x032fa069, 0x03800053, 0xdb4ee9e2, 0x02800004, + 0x00000000, 0x00008000, 0x00000542, 0x040f801f, + 0x012fa8c9, 0x040f801f, 0x073fa081, 0x06000010, + 0x03200005, 0x07420000, 0x050fb000, 0x040f801f, + 0x073fa011, 0x06000038, 0x040f801f, 0x053fa859, + 0x0700003a, 0x050fe000, 0x0581800a, 0x0784003c, + 0x04958019, 0x030e0011, 0x072e4200, 0x03800014, + 0x0291001f, 0x050010c0, 0x04482001, 0x058180fa, + 0x06483001, 0x0681815d, 0x02920029, 0x068b0029, + 0x008a0162, 0x050010c0, 0x06780001, 0x050007c0, + 0x06818240, 0x06780001, 0x0500f800, 0x06818280, + 0x03910030, 0x040fe029, 0x03860030, 0x076c001d, + 0x058102b1, 0x076c0a1d, 0x048102da, 0x029200ab, + 0x040fe02f, 0x0386003c, 0x06000013, 0x050fb000, + 0x066c0073, 0x068103ec, 0x014920e4, 0x0581803c, + 0x03400000, 0x076c0a00, 0x04818034, 0x0696003e, + 0x03b900ca, 0x05908014, 0x010170e1, 0x07780017, + 0x03e00000, 0x06810091, 0x050010ff, 0x0179fe17, + 0x031fffff, 0x070000ff, 0x05600800, 0x050f80ff, + 0x073fa009, 0x06000001, 0x06780002, 0x02800040, + 0x037c00ff, 0x03800000, 0x0681005d, 0x0249f002, + 0x078100aa, 0x0448e002, 0x0681005d, 0x07600c00, + 0x050f80ff, 0x073fa009, 0x06000001, 0x06780002, + 0x07ffff00, 0x037c00ff, 0x05000200, 0x058180aa, + 0x064bd401, 0x03d0005f, 0x028000a8, 0x02800067, + 0x03800071, 0x0380007b, 0x02800085, 0x0280008f, + 0x028000a8, 0x028000a8, 0x050fe027, 0x0086806b, + 0x01028000, 0x0280006e, 0x07600027, 0x050f80ff, + 0x032fa00a, 0x01027000, 0x02400029, 0x038000aa, + 0x040fe025, 0x00868075, 0x03026000, 0x03800078, + 0x06600025, 0x050f80ff, 0x032fa00a, 0x03025000, + 0x02400029, 0x038000aa, 0x050fe021, 0x0086807f, + 0x01022000, 0x03800082, 0x07600021, 0x050f80ff, + 0x032fa00a, 0x01021000, 0x02400029, 0x038000aa, + 0x040fe023, 0x00868089, 0x01024000, 0x0280008c, + 0x06600023, 0x050f80ff, 0x032fa00a, 0x03023000, + 0x02400029, 0x038000aa, 0x06a000da, 0x038000aa, + 0x01640817, 0x048280a8, 0x070ff017, 0x03d00095, + 0x0280009d, 0x0380009f, 0x028000a2, 0x038000a5, + 0x028000a8, 0x028000a8, 0x028000a8, 0x028000a8, + 0x03e00000, 0x03800014, 0x0590809f, 0x030160e1, + 0x038000aa, 0x049080a2, 0x030150e1, 0x038000aa, + 0x059080a5, 0x010140e1, 0x038000aa, 0x060fc013, + 0x07a0053a, 0x03800014, 0x014940e4, 0x00a180ae, + 0x0380003c, 0x02681e0d, 0x050fb0ff, 0x04600876, + 0x050f80ff, 0x053fa809, 0x06000001, 0x05488003, + 0x058180bd, 0x0400800d, 0x0120d000, 0x013e4000, + 0x05000200, 0x06009076, 0x04002075, 0x06a00526, + 0x07c00000, 0x072e4800, 0x07000012, 0x028000cd, + 0x0747f000, 0x05600800, 0x050f80ff, 0x012fa809, + 0x0249f001, 0x068100cd, 0x01012000, 0x052e4c00, + 0x07c00000, 0x070000eb, 0x0349f000, 0x048180c1, + 0x05600800, 0x050f80ff, 0x012fa809, 0x0448e001, + 0x068100d3, 0x07c00000, 0x0079c101, 0x07ffffff, + 0x027a4b01, 0x03800000, 0x05600800, 0x050f80ff, + 0x012fa80a, 0x07600c00, 0x050f80ff, 0x012fa821, + 0x06780001, 0x07ffff00, 0x037c00ff, 0x05000700, + 0x068100ef, 0x06601804, 0x070030ff, 0x050f80ff, + 0x012fa809, 0x05002000, 0x050f8003, 0x073fa00a, + 0x06000001, 0x040fe001, 0x038600f0, 0x04600201, + 0x050f80ff, 0x032fa00a, 0x07c00000, 0x050fe02e, + 0x018680f5, 0x0102e000, 0x0302f000, 0x038000f9, + 0x0760002e, 0x050f80ff, 0x032fa00a, 0x0102e000, + 0x07c00000, 0x022c0004, 0x056c041d, 0x0481010e, + 0x056c021d, 0x04810125, 0x056c081d, 0x04810137, + 0x076c061d, 0x04810151, 0x0521d000, 0x0202c013, + 0x0202a013, 0x02020013, 0x0460021a, 0x050f80ff, + 0x053fa80a, 0x07000009, 0x03b600be, 0x0484801f, + 0x0380003c, 0x040fe02a, 0x00860104, 0x06000013, + 0x04001013, 0x0560102b, 0x050f80ff, 0x032fa012, + 0x06420029, 0x0660002a, 0x050f80ff, 0x053fa809, + 0x06000001, 0x050fe003, 0x01860122, 0x01028003, + 0x0660002a, 0x050f80ff, 0x053fa80a, 0x07000009, + 0x00800152, 0x00028013, 0x00027013, 0x00800152, + 0x040fe02a, 0x01860103, 0x06420029, 0x0660002a, + 0x050f80ff, 0x053fa809, 0x06000001, 0x050fe003, + 0x00860134, 0x03026003, 0x0660002a, 0x050f80ff, + 0x053fa80a, 0x07000009, 0x00800152, 0x02026013, + 0x02025013, 0x00800152, 0x040fe02a, 0x01860103, + 0x06420029, 0x0660002a, 0x050f80ff, 0x053fa809, + 0x06000001, 0x050fe003, 0x00860146, 0x01022003, + 0x0660002a, 0x050f80ff, 0x053fa80a, 0x07000009, + 0x01800148, 0x00022013, 0x00021013, 0x0647f020, + 0x007a0120, 0x04000101, 0x04a002a2, 0x0400802a, + 0x06a0051f, 0x03948103, 0x0521d005, 0x00800104, + 0x0180010c, 0x0647f020, 0x06486020, 0x06818157, + 0x04a002a2, 0x01800103, 0x007a0120, 0x04000101, + 0x04a002a2, 0x0400802a, 0x06a0051f, 0x01800103, + 0x040fd02a, 0x052e4003, 0x00208010, 0x06a0051f, + 0x0180010c, 0x00018098, 0x07480018, 0x06818173, + 0x05481018, 0x07818171, 0x05482018, 0x0781816f, + 0x07483018, 0x0681816d, 0x002fb004, 0x01800174, + 0x012fb003, 0x01800174, 0x002fb002, 0x01800174, + 0x002fb001, 0x01800174, 0x012fb000, 0x0179fe78, + 0x070000ff, 0x030190ff, 0x00017086, 0x058b0178, + 0x03385000, 0x03020000, 0x07780017, 0x00430407, + 0x07818200, 0x046c0419, 0x058101b4, 0x046c0219, + 0x05810184, 0x07219000, 0x00800198, 0x07219000, + 0x07483017, 0x0481019e, 0x05482017, 0x058101a5, + 0x0448b075, 0x06818198, 0x06601476, 0x050f80ff, + 0x073fa022, 0x0600003e, 0x06000080, 0x05001081, + 0x05002082, 0x06003083, 0x05004084, 0x04601c76, + 0x050f80ff, 0x022fa02a, 0x07219000, 0x07780078, + 0x07ffff00, 0x045a0419, 0x010780ff, 0x0484801f, + 0x0380003c, 0x040fe07f, 0x008601ad, 0x04a001cd, + 0x00920198, 0x040fe07f, 0x06a681cd, 0x00800198, + 0x0560107b, 0x050f80ff, 0x032fa009, 0x0744f000, + 0x0560107b, 0x050f80ff, 0x032fa00a, 0x0180018b, + 0x052e400c, 0x040080fb, 0x046aa108, 0x06009076, + 0x04002075, 0x06a00526, 0x00800198, 0x06219001, + 0x05482017, 0x048101c1, 0x058b01b7, 0x060ff086, + 0x0349f0ff, 0x07818177, 0x07483017, 0x058101be, + 0x050fd0ff, 0x040fe07f, 0x06a681cd, 0x00800198, + 0x05004084, 0x05a00222, 0x00920198, 0x070ff07d, + 0x0450047c, 0x056004ff, 0x050f80ff, 0x032fa009, + 0x070ff000, 0x00540479, 0x030790ff, 0x018001a5, + 0x060ff079, 0x0054047a, 0x058201f9, 0x058101f9, + 0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819, + 0x048b01d5, 0x02080001, 0x00081002, 0x01082003, + 0x048b01d9, 0x03385000, 0x03010000, 0x02400019, + 0x070ff003, 0x04500479, 0x030790ff, 0x0340007e, + 0x0642007f, 0x058101f9, 0x070ff07e, 0x050f80ff, + 0x032fa009, 0x050fe000, 0x028681f8, 0x070ff07d, + 0x056002ff, 0x050f80ff, 0x032fa009, 0x0107d000, + 0x018601fa, 0x0560087d, 0x050f80ff, 0x032fa009, + 0x03681e00, 0x0550041b, 0x050f80ff, 0x032fa009, + 0x0107e000, 0x070ff07e, 0x018001e4, 0x0307c000, + 0x07c00000, 0x052e400c, 0x040080fb, 0x046aa108, + 0x06009076, 0x04002075, 0x02800526, 0x040fd076, + 0x050fd017, 0x060ff086, 0x077800ff, 0x07000060, + 0x037c00ff, 0x07000060, 0x06818202, 0x07780078, + 0x07ffff00, 0x045a0419, 0x010780ff, 0x06601476, + 0x050f80ff, 0x073fa022, 0x0600003e, 0x052e400c, + 0x04600876, 0x050f80ff, 0x053fa809, 0x06000001, + 0x05488003, 0x0481021c, 0x0400d0fb, 0x066a810d, + 0x013e4000, 0x07000300, 0x02800029, 0x040080fb, + 0x066a8108, 0x06009076, 0x04002075, 0x06a00526, + 0x02800029, 0x0240007f, 0x0742007e, 0x050f807e, + 0x032fa009, 0x050fe000, 0x0386823c, 0x070ff07d, + 0x055c047b, 0x04810231, 0x0760007d, 0x050f80ff, + 0x032fa009, 0x050fe000, 0x02868231, 0x070ff07b, + 0x0107d0ff, 0x0560087d, 0x050f80ff, 0x032fa009, + 0x03681e00, 0x0450041c, 0x0107e0ff, 0x050f80ff, + 0x032fa009, 0x050fe000, 0x0086023e, 0x0307c000, + 0x07c00000, 0x040fd076, 0x0380053a, 0x010180c0, + 0x0548e018, 0x07818259, 0x0748f018, 0x07818255, + 0x03490018, 0x06818251, 0x01491018, 0x0781824d, + 0x073c0000, 0x06000040, 0x02200004, 0x0180025c, + 0x073c0000, 0x06000020, 0x03200003, 0x0180025c, + 0x073c0000, 0x06000010, 0x02200002, 0x0180025c, + 0x073c0000, 0x06000008, 0x02200001, 0x0180025c, + 0x073c0000, 0x06000004, 0x06000013, 0x050fb000, + 0x040fe076, 0x00860275, 0x046c0273, 0x04810285, + 0x066c0073, 0x05810266, 0x040fd076, 0x07a0053a, + 0x03800014, 0x040fd076, 0x01800269, 0x00452075, + 0x00077013, 0x0647f075, 0x06486075, 0x0781826f, + 0x04a002a8, 0x00800275, 0x007a0175, 0x04000101, + 0x04a002a8, 0x04008076, 0x0245f008, 0x06a0051f, + 0x07273000, 0x05600272, 0x050f80ff, 0x053fa80a, + 0x07000009, 0x0379ff78, 0x070000ff, 0x02076013, + 0x02075013, 0x0484801f, 0x0380003c, 0x070fc0ff, + 0x052e400c, 0x00208020, 0x06a0051f, 0x0180027e, + 0x04600276, 0x050010ff, 0x040f8001, 0x032fa009, + 0x040f8001, 0x053fa80a, 0x07000009, 0x070ff000, + 0x02868297, 0x06601276, 0x050f80ff, 0x073fa009, + 0x0700000c, 0x07601818, 0x050f80ff, 0x053fa80a, + 0x07000009, 0x00800298, 0x07a000f0, 0x0448b075, + 0x04810268, 0x06000013, 0x04001013, 0x0560107b, + 0x050f80ff, 0x032fa012, 0x0046b075, 0x03b600be, + 0x01800269, 0x06000020, 0x04001016, 0x0460082a, + 0x050f80ff, 0x032fa012, 0x07c00000, 0x06000075, + 0x040010a2, 0x044b0801, 0x060ff016, 0x065a0001, + 0x04600876, 0x050f80ff, 0x032fa012, 0x07c00000, + 0x050fe022, 0x008602bc, 0x0421d004, 0x0302a022, + 0x04a002e9, 0x04488020, 0x048102ce, 0x040fd02a, + 0x0521d000, 0x0202a013, 0x02020013, 0x040fe026, + 0x018602d4, 0x0421d001, 0x0202a026, 0x04a002e9, + 0x0202c013, 0x00683e20, 0x070060ff, 0x056c0206, + 0x0681031c, 0x056c0406, 0x06810332, 0x076c0606, + 0x078103a3, 0x04488020, 0x068182d0, 0x056c1606, + 0x078103b1, 0x06a00516, 0x018002e2, 0x040fd02a, + 0x0521d000, 0x0202a013, 0x02020013, 0x050fe028, + 0x018602e2, 0x0302a028, 0x0421d002, 0x04a002e9, + 0x018002f0, 0x050fe022, 0x018602e2, 0x0421d004, + 0x0302a022, 0x04a002e9, 0x04488020, 0x078182e4, + 0x06a00516, 0x05848030, 0x0380003c, 0x040fd02a, + 0x0521d000, 0x0202a013, 0x02020013, 0x018002e2, + 0x0460082a, 0x050f80ff, 0x022fa031, 0x03020000, + 0x0002b004, 0x01018005, 0x07c00000, 0x0400702a, + 0x07a003e4, 0x007a0101, 0x07060000, 0x07303000, + 0x07008290, 0x07600018, 0x050f80ff, 0x053fa809, + 0x07000003, 0x0448e007, 0x068182fe, 0x06006013, + 0x03800305, 0x02400010, 0x048102fe, 0x06006010, + 0x0460322a, 0x050f80ff, 0x073fa00a, 0x07000003, + 0x050f801e, 0x032fa03a, 0x063aa020, 0x06000002, + 0x013e4000, 0x07000030, 0x0298030b, 0x070ff0f6, + 0x036830ff, 0x0581830c, 0x070f001e, 0x0560102b, + 0x050f10ff, 0x063f3c08, 0x0600000d, 0x013e4000, + 0x06000020, 0x040f801a, 0x0320000a, 0x022017d0, + 0x032fa012, 0x0202c013, 0x018002e2, 0x04007013, + 0x07a003e4, 0x007a0101, 0x07050000, 0x07303000, + 0x07008890, 0x074d0005, 0x06006013, 0x050f801e, + 0x032fa03a, 0x05601a2b, 0x050f80ff, 0x022fa019, + 0x04001002, 0x04002013, 0x040f801f, 0x022fa01a, + 0x073aa00c, 0x06000002, 0x07300c03, 0x0600000d, + 0x038003d1, 0x04007013, 0x07a003e4, 0x007a0101, + 0x03070000, 0x0660282a, 0x050f80ff, 0x073fa009, + 0x06000004, 0x02499008, 0x0781033f, 0x07303000, + 0x07008890, 0x03800341, 0x07303000, 0x04008980, + 0x05007003, 0x074d0005, 0x06006013, 0x050f801e, + 0x032fa03a, 0x0760142b, 0x050f80ff, 0x032fa021, + 0x064b0002, 0x02499008, 0x0781034d, 0x0644c002, + 0x054b0400, 0x050040ff, 0x06698104, 0x04818362, + 0x06000013, 0x04001013, 0x04780102, 0x06000010, + 0x06003013, 0x04004013, 0x06005013, 0x06006013, + 0x04007013, 0x00644015, 0x0682035e, 0x04448002, + 0x02205008, 0x040f801f, 0x032fa042, 0x04008015, + 0x0280039b, 0x046c8004, 0x04818370, 0x01208018, + 0x06780002, 0x07000003, 0x04818373, 0x06003001, + 0x06000013, 0x04001013, 0x04004013, 0x06005013, + 0x040f801f, 0x022fa032, 0x0280039b, 0x040fd02a, + 0x07a0053a, 0x03800014, 0x0379ff03, 0x070000ff, + 0x04488002, 0x0681037a, 0x070ff003, 0x04500408, + 0x050080ff, 0x0379ff00, 0x070000ff, 0x06489002, + 0x07810381, 0x070ff000, 0x04500408, 0x050080ff, + 0x07005003, 0x05004000, 0x06003001, 0x06000013, + 0x04001013, 0x040f801f, 0x022fa032, 0x05601c2b, + 0x050f80ff, 0x022fa031, 0x06600c1f, 0x050f80ff, + 0x022fa032, 0x02680608, 0x0681039b, 0x016408ff, + 0x057dfeff, 0x07ffffff, 0x034000ff, 0x045a0407, + 0x070000ff, 0x0760061e, 0x050f80ff, 0x032fa00a, + 0x06600908, 0x0669f908, 0x027a0008, 0x06000020, + 0x070aa0ff, 0x014a20ff, 0x037a00ff, 0x060000dc, + 0x070000ff, 0x038003d1, 0x04007013, 0x07a003e4, + 0x007a0101, 0x07030000, 0x07303000, 0x07008190, + 0x06006013, 0x050f801e, 0x032fa03a, 0x073aa000, + 0x06000002, 0x07300c00, 0x07000005, 0x038003d1, + 0x04007013, 0x07a003e4, 0x007a0101, 0x07810000, + 0x07303000, 0x07000090, 0x06006013, 0x06600c2a, + 0x050f80ff, 0x053fa809, 0x07000003, 0x04780107, + 0x07ffff00, 0x007c0107, 0x07000500, 0x048183c4, + 0x07303000, 0x05000890, 0x074d0005, 0x0660282a, + 0x050f80ff, 0x053fa809, 0x07000003, 0x0049d007, + 0x068103cb, 0x02206001, 0x050f801e, 0x032fa03a, + 0x073aa000, 0x06000002, 0x07300c00, 0x07000005, + 0x013e4000, 0x07000030, 0x029803d3, 0x070ff0f6, + 0x036830ff, 0x058183d4, 0x070f001e, 0x040f101f, + 0x070f3000, 0x013e4000, 0x06000020, 0x040f801a, + 0x0320000a, 0x022017d0, 0x032fa012, 0x018002e2, + 0x03200000, 0x06006076, 0x028003e6, 0x03200011, + 0x0600602a, 0x04a0046b, 0x05600406, 0x050f80ff, + 0x053fa809, 0x06000002, 0x07c00000, 0x0207602f, + 0x04600876, 0x050f80ff, 0x022fa031, 0x03075000, + 0x0007b004, 0x01018005, 0x06600076, 0x050020ff, + 0x050f80ff, 0x012fa809, 0x0202f001, 0x018683fa, + 0x0002e013, 0x040f8002, 0x053fa80a, 0x07000009, + 0x06273001, 0x0448b075, 0x06818404, 0x04602076, + 0x050f80ff, 0x053fa811, 0x0700003c, 0x0179fe78, + 0x070000ff, 0x030190ff, 0x0386840c, 0x04a00420, + 0x00078019, 0x0092041f, 0x00800464, 0x040fd076, + 0x040fd019, 0x04600276, 0x050020ff, 0x050f80ff, + 0x032fa009, 0x040f8002, 0x053fa80a, 0x07000009, + 0x050fe000, 0x0286841c, 0x07601818, 0x050f80ff, + 0x053fa80a, 0x07000009, 0x0180041d, 0x07a000f0, + 0x07273000, 0x02076013, 0x0380003c, 0x048b0420, + 0x03385000, 0x07030000, 0x05600818, 0x050f80ff, + 0x032fa009, 0x054b0400, 0x0308a0ff, 0x0179fe00, + 0x070000ff, 0x010880ff, 0x0448b075, 0x0581043a, + 0x0760147b, 0x050f80ff, 0x002fa819, 0x064b0001, + 0x02080002, 0x01081003, 0x00082001, 0x02083001, + 0x02079001, 0x0207a001, 0x00084013, 0x0207f013, + 0x0180045c, 0x06485075, 0x04810452, 0x02465075, + 0x06601476, 0x050f80ff, 0x073fa021, 0x0600003e, + 0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819, + 0x048b0445, 0x02080001, 0x00081002, 0x01082003, + 0x03079003, 0x0208307a, 0x0340007e, 0x0642007f, + 0x04810457, 0x070ff07e, 0x05a001e4, 0x02928457, + 0x01800463, 0x048b0452, 0x06601476, 0x050f80ff, + 0x073fa041, 0x0600003e, 0x06602476, 0x050f80ff, + 0x073fa009, 0x06000007, 0x0008400e, 0x058b045c, + 0x03385000, 0x03010000, 0x06219001, 0x040fe07f, + 0x01860463, 0x008001cd, 0x07c00000, 0x00683e75, + 0x05810469, 0x0448d075, 0x0481048f, 0x018004bd, + 0x06a0051a, 0x0080041f, 0x02978476, 0x07602418, + 0x050f80ff, 0x012fa809, 0x06780001, 0x070000ff, + 0x075a0000, 0x070ff014, 0x0569feff, 0x054b08ff, + 0x075a0000, 0x05600418, 0x050f80ff, 0x012fa809, + 0x040fe007, 0x0386847d, 0x01204000, 0x0180048b, + 0x00700101, 0x03010000, 0x06780001, 0x07ff0000, + 0x076c00ff, 0x06818485, 0x00700101, 0x03010000, + 0x05600418, 0x050f80ff, 0x012fa80a, 0x06780001, + 0x07ff0000, 0x050040ff, 0x0279ff01, 0x0700ffff, + 0x05002014, 0x07c00000, 0x04007076, 0x0448b075, + 0x058104a9, 0x03200011, 0x06006076, 0x06a003e6, + 0x007a0101, 0x07060000, 0x07303000, 0x07008290, + 0x07600018, 0x050f80ff, 0x053fa809, 0x07000003, + 0x0448e007, 0x068184a1, 0x06006013, 0x018004b8, + 0x02400010, 0x048104a1, 0x06006010, 0x04603276, + 0x050f80ff, 0x073fa00a, 0x07000003, 0x018004b8, + 0x04602a76, 0x050f80ff, 0x032fa009, 0x060ff07a, + 0x05500400, 0x070000ff, 0x04602a76, 0x050f80ff, + 0x032fa00a, 0x07a003e1, 0x007a0101, 0x03010000, + 0x06303008, 0x05008000, 0x0600600e, 0x050f8074, + 0x032fa03a, 0x053079a0, 0x0700000c, 0x008004fd, + 0x00683e75, 0x076c0aff, 0x048104dc, 0x04007013, + 0x03200011, 0x06006076, 0x06a003e6, 0x007a0101, + 0x03070000, 0x06602876, 0x050f80ff, 0x053fa809, + 0x06000001, 0x03499003, 0x058104d1, 0x07303000, + 0x07008890, 0x053079a0, 0x0700000c, 0x008004d5, + 0x07303000, 0x04008980, 0x04307920, 0x0700000c, + 0x074d0005, 0x06006013, 0x050f8074, 0x032fa03a, + 0x04307920, 0x0700000c, 0x008004fd, 0x04602a76, + 0x050f80ff, 0x032fa009, 0x060ff07a, 0x05500400, + 0x070000ff, 0x04602a76, 0x050f80ff, 0x032fa00a, + 0x04007076, 0x07a003e1, 0x007a0101, 0x03010000, + 0x06303008, 0x07008800, 0x074d0005, 0x06600a76, + 0x050f80ff, 0x073fa009, 0x07000003, 0x054b0406, + 0x045a0404, 0x050040ff, 0x0600600e, 0x050f8074, + 0x032fa03a, 0x0648c075, 0x048104fb, 0x06307d20, + 0x0700000c, 0x008004fd, 0x04307920, 0x0700000c, + 0x013e4000, 0x07000030, 0x019804ff, 0x070ff0f6, + 0x074850ff, 0x05818500, 0x050f2074, 0x060a0007, + 0x040070fb, 0x046a7007, 0x050f40ff, 0x013e4000, + 0x06000020, 0x0678007a, 0x07fff000, 0x04818510, + 0x0320000a, 0x022017d0, 0x02800513, 0x0320000a, + 0x06301b58, 0x06000001, 0x050f8072, 0x032fa012, + 0x0080041f, 0x01208060, 0x0600902a, 0x04002020, + 0x02800526, 0x040080fb, 0x066ae108, 0x06009076, + 0x04002075, 0x02800526, 0x03201100, 0x05848524, + 0x06420001, 0x04818520, 0x0280053d, 0x020e0008, + 0x07c00000, 0x050fd009, 0x040fd008, 0x03201100, + 0x0584852d, 0x06420001, 0x04818529, 0x0280053d, + 0x007a0102, 0x04000101, 0x05600809, 0x050f80ff, + 0x073fa00a, 0x06000001, 0x020e0008, 0x06840537, + 0x030e0009, 0x07c00000, 0x01011009, 0x052e4300, + 0x07c00000, 0x052e400f, 0x01208090, 0x0280051f, + 0x070fc0ff, 0x040f8013, 0x032fa009, 0x02800540, + 0x6321d92e, 0xffef19a2 +}; + +#ifdef UNIQUE_FW_NAME +uint32_t fw2400_length02 = 0x0000165e ; +#else +uint32_t risc_code_length02 = 0x0000165e ; +#endif + diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index e96d58ded57c..fee0c493775b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -46,16 +46,22 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, case 0: if (ha->fw_dump_reading == 1) { qla_printk(KERN_INFO, ha, - "Firmware dump cleared on (%ld).\n", ha->host_no); + "Firmware dump cleared on (%ld).\n", + ha->host_no); vfree(ha->fw_dump_buffer); - ha->fw_dump_buffer = NULL; + if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + free_pages((unsigned long)ha->fw_dump, + ha->fw_dump_order); + ha->fw_dump_reading = 0; + ha->fw_dump_buffer = NULL; + ha->fw_dump = NULL; ha->fw_dumped = 0; } break; case 1: - if (ha->fw_dumped && !ha->fw_dump_reading) { + if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) { ha->fw_dump_reading = 1; if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index 74e54713aa7c..2d9b12ffe09c 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -28,7 +28,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) uint16_t __iomem *dmp_reg; unsigned long flags; struct qla2300_fw_dump *fw; - uint32_t data_ram_cnt; + uint32_t dump_size, data_ram_cnt; risc_address = data_ram_cnt = 0; mb0 = mb2 = 0; @@ -37,16 +37,23 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (!hardware_locked) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!ha->fw_dump) { + if (ha->fw_dump != NULL) { qla_printk(KERN_WARNING, ha, - "No buffer available for dump!!!\n"); + "Firmware has been previously dumped (%p) -- ignoring " + "request...\n", ha->fw_dump); goto qla2300_fw_dump_failed; } - if (ha->fw_dumped) { + /* Allocate (large) dump buffer. */ + dump_size = sizeof(struct qla2300_fw_dump); + dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); + ha->fw_dump_order = get_order(dump_size); + ha->fw_dump = (struct qla2300_fw_dump *) __get_free_pages(GFP_ATOMIC, + ha->fw_dump_order); + if (ha->fw_dump == NULL) { qla_printk(KERN_WARNING, ha, - "Firmware has been previously dumped (%p) -- ignoring " - "request...\n", ha->fw_dump); + "Unable to allocated memory for firmware dump (%d/%d).\n", + ha->fw_dump_order, dump_size); goto qla2300_fw_dump_failed; } fw = ha->fw_dump; @@ -351,16 +358,17 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) } } + if (rval != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "Failed to dump firmware (%x)!!!\n", rval); - ha->fw_dumped = 0; + free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); + ha->fw_dump = NULL; } else { qla_printk(KERN_INFO, ha, "Firmware dump saved to temp buffer (%ld/%p).\n", ha->host_no, ha->fw_dump); - ha->fw_dumped = 1; } qla2300_fw_dump_failed: @@ -579,16 +587,21 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (!hardware_locked) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!ha->fw_dump) { + if (ha->fw_dump != NULL) { qla_printk(KERN_WARNING, ha, - "No buffer available for dump!!!\n"); + "Firmware has been previously dumped (%p) -- ignoring " + "request...\n", ha->fw_dump); goto qla2100_fw_dump_failed; } - if (ha->fw_dumped) { + /* Allocate (large) dump buffer. */ + ha->fw_dump_order = get_order(sizeof(struct qla2100_fw_dump)); + ha->fw_dump = (struct qla2100_fw_dump *) __get_free_pages(GFP_ATOMIC, + ha->fw_dump_order); + if (ha->fw_dump == NULL) { qla_printk(KERN_WARNING, ha, - "Firmware has been previously dumped (%p) -- ignoring " - "request...\n", ha->fw_dump); + "Unable to allocated memory for firmware dump (%d/%Zd).\n", + ha->fw_dump_order, sizeof(struct qla2100_fw_dump)); goto qla2100_fw_dump_failed; } fw = ha->fw_dump; @@ -764,13 +777,13 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (rval != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "Failed to dump firmware (%x)!!!\n", rval); - ha->fw_dumped = 0; + free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); + ha->fw_dump = NULL; } else { qla_printk(KERN_INFO, ha, "Firmware dump saved to temp buffer (%ld/%p).\n", ha->host_no, ha->fw_dump); - ha->fw_dumped = 1; } qla2100_fw_dump_failed: @@ -975,7 +988,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (!hardware_locked) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!ha->fw_dump) { + if (!ha->fw_dump24) { qla_printk(KERN_WARNING, ha, "No buffer available for dump!!!\n"); goto qla24xx_fw_dump_failed; @@ -984,10 +997,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) if (ha->fw_dumped) { qla_printk(KERN_WARNING, ha, "Firmware has been previously dumped (%p) -- ignoring " - "request...\n", ha->fw_dump); + "request...\n", ha->fw_dump24); goto qla24xx_fw_dump_failed; } - fw = ha->fw_dump; + fw = (struct qla24xx_fw_dump *) ha->fw_dump24; rval = QLA_SUCCESS; fw->host_status = RD_REG_DWORD(®->host_status); @@ -1641,7 +1654,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) } else { qla_printk(KERN_INFO, ha, "Firmware dump saved to temp buffer (%ld/%p).\n", - ha->host_no, ha->fw_dump); + ha->host_no, ha->fw_dump24); ha->fw_dumped = 1; } @@ -1659,7 +1672,7 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) uint32_t ext_mem_cnt; uiter = ha->fw_dump_buffer; - fw = ha->fw_dump; + fw = ha->fw_dump24; qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", ha->fw_major_version, ha->fw_minor_version, @@ -1982,6 +1995,7 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) return; printk(" sp flags=0x%x\n", sp->flags); + printk(" state=%d\n", sp->state); } void diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index d6f6579cfd27..53508f3c4ae9 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -31,8 +31,6 @@ #include #include -#define QLA2XXX_DRIVER_NAME "qla2xxx" - /* * We have MAILBOX_REGISTER_COUNT sized arrays in a few places, * but that's fine as we don't look at the last 24 ones for @@ -191,13 +189,22 @@ typedef struct srb { struct scsi_cmnd *cmd; /* Linux SCSI command pkt */ + struct timer_list timer; /* Command timer */ + atomic_t ref_count; /* Reference count for this structure */ uint16_t flags; + /* Request state */ + uint16_t state; + /* Single transfer DMA context */ dma_addr_t dma_handle; uint32_t request_sense_length; uint8_t *request_sense_ptr; + + /* SRB magic number */ + uint16_t magic; +#define SRB_MAGIC 0x10CB } srb_t; /* @@ -218,6 +225,21 @@ typedef struct srb { #define SRB_IOCTL BIT_10 /* IOCTL command. */ #define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */ +/* + * SRB state definitions + */ +#define SRB_FREE_STATE 0 /* returned back */ +#define SRB_PENDING_STATE 1 /* queued in LUN Q */ +#define SRB_ACTIVE_STATE 2 /* in Active Array */ +#define SRB_DONE_STATE 3 /* queued in Done Queue */ +#define SRB_RETRY_STATE 4 /* in Retry Queue */ +#define SRB_SUSPENDED_STATE 5 /* in suspended state */ +#define SRB_NO_QUEUE_STATE 6 /* is in between states */ +#define SRB_ACTIVE_TIMEOUT_STATE 7 /* in Active Array but timed out */ +#define SRB_FAILOVER_STATE 8 /* in Failover Queue */ +#define SRB_SCSI_RETRY_STATE 9 /* in Scsi Retry Queue */ + + /* * ISP I/O Register Set structure definitions. */ @@ -248,8 +270,6 @@ struct device_reg_2xxx { #define NVR_SELECT BIT_1 #define NVR_CLOCK BIT_0 -#define NVR_WAIT_CNT 20000 - union { struct { uint16_t mailbox0; @@ -1493,6 +1513,62 @@ typedef struct { uint8_t port_name[WWN_SIZE]; } sw_info_t; +/* + * Inquiry command structure. + */ +#define INQ_DATA_SIZE 36 + +/* + * Inquiry mailbox IOCB packet definition. + */ +typedef struct { + union { + cmd_a64_entry_t cmd; + sts_entry_t rsp; + struct cmd_type_7 cmd24; + struct sts_entry_24xx rsp24; + } p; + uint8_t inq[INQ_DATA_SIZE]; +} inq_cmd_rsp_t; + +/* + * Report LUN command structure. + */ +#define CHAR_TO_SHORT(a, b) (uint16_t)((uint8_t)b << 8 | (uint8_t)a) + +typedef struct { + uint32_t len; + uint32_t rsrv; +} rpt_hdr_t; + +typedef struct { + struct { + uint8_t b : 6; + uint8_t address_method : 2; + } msb; + uint8_t lsb; + uint8_t unused[6]; +} rpt_lun_t; + +typedef struct { + rpt_hdr_t hdr; + rpt_lun_t lst[MAX_LUNS]; +} rpt_lun_lst_t; + +/* + * Report Lun mailbox IOCB packet definition. + */ +typedef struct { + union { + cmd_a64_entry_t cmd; + sts_entry_t rsp; + struct cmd_type_7 cmd24; + struct sts_entry_24xx rsp24; + } p; + rpt_lun_lst_t list; +} rpt_lun_cmd_rsp_t; + + /* * Fibre channel port type. */ @@ -1511,6 +1587,7 @@ typedef struct { typedef struct fc_port { struct list_head list; struct scsi_qla_host *ha; + struct scsi_qla_host *vis_ha; /* only used when suspending lun */ uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; @@ -1525,13 +1602,23 @@ typedef struct fc_port { unsigned int os_target_id; + uint16_t iodesc_idx_sent; + int port_login_retry_count; int login_retry; atomic_t port_down_timer; + uint8_t device_type; + uint8_t unused; + + uint8_t mp_byte; /* multi-path byte (not used) */ + uint8_t cur_path; /* current path id */ + spinlock_t rport_lock; struct fc_rport *rport, *drport; u32 supported_classes; + struct work_struct rport_add_work; + struct work_struct rport_del_work; } fc_port_t; /* @@ -1940,6 +2027,54 @@ struct sns_cmd_pkt { } p; }; +/* IO descriptors */ +#define MAX_IO_DESCRIPTORS 32 + +#define ABORT_IOCB_CB 0 +#define ADISC_PORT_IOCB_CB 1 +#define LOGOUT_PORT_IOCB_CB 2 +#define LOGIN_PORT_IOCB_CB 3 +#define LAST_IOCB_CB 4 + +#define IODESC_INVALID_INDEX 0xFFFF +#define IODESC_ADISC_NEEDED 0xFFFE +#define IODESC_LOGIN_NEEDED 0xFFFD + +struct io_descriptor { + uint16_t used:1; + uint16_t idx:11; + uint16_t cb_idx:4; + + struct timer_list timer; + + struct scsi_qla_host *ha; + + port_id_t d_id; + fc_port_t *remote_fcport; + + uint32_t signature; +}; + +struct qla_fw_info { + unsigned short addressing; /* addressing method used to load fw */ +#define FW_INFO_ADDR_NORMAL 0 +#define FW_INFO_ADDR_EXTENDED 1 +#define FW_INFO_ADDR_NOMORE 0xffff + unsigned short *fwcode; /* pointer to FW array */ + unsigned short *fwlen; /* number of words in array */ + unsigned short *fwstart; /* start address for F/W */ + unsigned long *lfwstart; /* start address (long) for F/W */ +}; + +struct qla_board_info { + char *drv_name; + + char isp_name[8]; + struct qla_fw_info *fw_info; + char *fw_fname; + struct scsi_host_template *sht; +}; + struct fw_blob { char *name; uint32_t segs[4]; @@ -2168,6 +2303,9 @@ typedef struct scsi_qla_host { uint32_t current_outstanding_cmd; srb_t *status_srb; /* Status continuation entry. */ + uint16_t revision; + uint8_t ports; + /* ISP configuration data. */ uint16_t loop_id; /* Host adapter loop id */ uint16_t fb_rev; @@ -2223,6 +2361,10 @@ typedef struct scsi_qla_host { /* Fibre Channel Device List. */ struct list_head fcports; + struct list_head rscn_fcports; + + struct io_descriptor io_descriptors[MAX_IO_DESCRIPTORS]; + uint16_t iodesc_signature; /* RSCN queue. */ uint32_t rscn_queue[MAX_RSCN_COUNT]; @@ -2253,6 +2395,9 @@ typedef struct scsi_qla_host { struct gid_list_info *gid_list; int gid_list_info_size; + dma_addr_t rlc_rsp_dma; + rpt_lun_cmd_rsp_t *rlc_rsp; + /* Small DMA pool allocations -- maximum 256 bytes in length. */ #define DMA_POOL_SIZE 256 struct dma_pool *s_dma_pool; @@ -2261,6 +2406,9 @@ typedef struct scsi_qla_host { init_cb_t *init_cb; int init_cb_size; + dma_addr_t iodesc_pd_dma; + port_database_t *iodesc_pd; + /* These are used by mailbox operations. */ volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; @@ -2287,16 +2435,13 @@ typedef struct scsi_qla_host { mbx_cmd_t mc; /* Basic firmware related information. */ + struct qla_board_info *brd_info; uint16_t fw_major_version; uint16_t fw_minor_version; uint16_t fw_subminor_version; uint16_t fw_attributes; uint32_t fw_memory_size; uint32_t fw_transfer_size; - uint32_t fw_srisc_address; -#define RISC_START_ADDRESS_2100 0x1000 -#define RISC_START_ADDRESS_2300 0x800 -#define RISC_START_ADDRESS_2400 0x100000 uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */ uint8_t fw_seriallink_options[4]; @@ -2304,11 +2449,15 @@ typedef struct scsi_qla_host { /* Firmware dump information. */ void *fw_dump; - int fw_dumped; + int fw_dump_order; int fw_dump_reading; char *fw_dump_buffer; int fw_dump_buffer_len; + int fw_dumped; + void *fw_dump24; + int fw_dump24_len; + uint8_t host_str[16]; uint32_t pci_attr; @@ -2354,6 +2503,8 @@ typedef struct scsi_qla_host { test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ atomic_read(&ha->loop_state) == LOOP_DOWN) +#define TGT_Q(ha, t) (ha->otgt[t]) + #define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata) #define qla_printk(level, ha, format, arg...) \ @@ -2386,6 +2537,19 @@ typedef struct scsi_qla_host { #define QLA_RSCNS_HANDLED 0x108 #define QLA_ALREADY_REGISTERED 0x109 +/* +* Stat info for all adpaters +*/ +struct _qla2x00stats { + unsigned long mboxtout; /* mailbox timeouts */ + unsigned long mboxerr; /* mailbox errors */ + unsigned long ispAbort; /* ISP aborts */ + unsigned long debugNo; + unsigned long loop_resync; + unsigned long outarray_full; + unsigned long retry_q_cnt; +}; + #define NVRAM_DELAY() udelay(10) #define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS+1) @@ -2401,6 +2565,12 @@ typedef struct scsi_qla_host { #include "qla_dbg.h" #include "qla_inline.h" +/* +* String arrays +*/ +#define LINESIZE 256 +#define MAXARGS 26 + #define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) #define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual) #define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual) diff --git a/trunk/drivers/scsi/qla2xxx/qla_fw.h b/trunk/drivers/scsi/qla2xxx/qla_fw.h index 3af478663be7..1ee58ad2f4dd 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_fw.h +++ b/trunk/drivers/scsi/qla2xxx/qla_fw.h @@ -7,6 +7,7 @@ #ifndef __QLA_FW_H #define __QLA_FW_H +#define RISC_SADDRESS 0x100000 #define MBS_CHECKSUM_ERROR 0x4010 /* @@ -462,7 +463,7 @@ struct sts_entry_24xx { uint16_t comp_status; /* Completion status. */ uint16_t ox_id; /* OX_ID used by the firmware. */ - uint32_t residual_len; /* FW calc residual transfer length. */ + uint32_t residual_len; /* Residual transfer length. */ uint16_t reserved_1; uint16_t state_flags; /* State flags. */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 164d53ccbfd0..91e83e2c1eb8 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -9,6 +9,9 @@ #include +extern void qla2x00_remove_one(struct pci_dev *); +extern int qla2x00_probe_one(struct pci_dev *, struct qla_board_info *); + /* * Global Function Prototypes in qla_init.c source file. */ @@ -61,11 +64,14 @@ extern int qlport_down_retry; extern int ql2xplogiabsentdevice; extern int ql2xloginretrycount; extern int ql2xfdmienable; +extern int ql2xprocessrscn; extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); +extern void qla2x00_cmd_timeout(srb_t *); + extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); @@ -279,6 +285,15 @@ extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern int qla2x00_fdmi_register(scsi_qla_host_t *); +/* + * Global Function Prototypes in qla_rscn.c source file. + */ +extern fc_port_t *qla2x00_alloc_rscn_fcport(scsi_qla_host_t *, gfp_t); +extern int qla2x00_handle_port_rscn(scsi_qla_host_t *, uint32_t, fc_port_t *, + int); +extern void qla2x00_process_iodesc(scsi_qla_host_t *, struct mbx_entry *); +extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *); + /* * Global Function Prototypes in qla_xioctl.c source file. */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 3d4487eac9b7..89a3fc0595bb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -194,6 +194,7 @@ qla2100_pci_config(scsi_qla_host_t *ha) mwi = 0; if (pci_set_mwi(ha->pdev)) mwi = PCI_COMMAND_INVALIDATE; + pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -231,6 +232,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) mwi = 0; if (pci_set_mwi(ha->pdev)) mwi = PCI_COMMAND_INVALIDATE; + pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -318,6 +320,7 @@ qla24xx_pci_config(scsi_qla_host_t *ha) mwi = 0; if (pci_set_mwi(ha->pdev)) mwi = PCI_COMMAND_INVALIDATE; + pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -383,7 +386,9 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "RISC CODE NOT loaded\n"); /* Verify checksum of loaded RISC code. */ - rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); + rval = qla2x00_verify_checksum(ha, + IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RISC_SADDRESS : + *ha->brd_info->fw_info[0].fwstart); } if (rval) { @@ -406,6 +411,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) unsigned long flags = 0; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; uint32_t cnt; + unsigned long mbx_flags = 0; uint16_t cmd; ha->isp_ops.disable_intrs(ha); @@ -513,8 +519,20 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) { for (cnt = 0; cnt < 30000; cnt++) { - if (RD_MAILBOX_REG(ha, reg, 0) != MBS_BUSY) + if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) + spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); + + if (RD_MAILBOX_REG(ha, reg, 0) != MBS_BUSY) { + if (!(test_bit(ABORT_ISP_ACTIVE, + &ha->dpc_flags))) + spin_unlock_irqrestore( + &ha->mbx_reg_lock, mbx_flags); break; + } + + if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) + spin_unlock_irqrestore(&ha->mbx_reg_lock, + mbx_flags); udelay(100); } @@ -773,26 +791,16 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) static void qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) { - uint32_t dump_size = 0; - ha->fw_dumped = 0; - if (IS_QLA2100(ha) || IS_QLA2200(ha)) { - dump_size = sizeof(struct qla2100_fw_dump); - } else if (IS_QLA23XX(ha)) { - dump_size = sizeof(struct qla2300_fw_dump); - dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { - dump_size = sizeof(struct qla24xx_fw_dump); - dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); - } - - ha->fw_dump = vmalloc(dump_size); - if (ha->fw_dump) + ha->fw_dump24_len = sizeof(struct qla24xx_fw_dump); + ha->fw_dump24_len += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); + ha->fw_dump24 = vmalloc(ha->fw_dump24_len); + if (ha->fw_dump24) qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware " - "dump...\n", dump_size / 1024); + "dump...\n", ha->fw_dump24_len / 1024); else qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " - "firmware dump!!!\n", dump_size / 1024); + "firmware dump!!!\n", ha->fw_dump24_len / 1024); } /** @@ -810,12 +818,13 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) dma_addr_t request_dma; request_t *request_ring; - qla2x00_alloc_fw_dump(ha); - /* Valid only on recent ISPs. */ if (IS_QLA2100(ha) || IS_QLA2200(ha)) return; + if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + qla2x00_alloc_fw_dump(ha); + /* Retrieve IOCB counts available to the firmware. */ rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt); if (rval) @@ -1536,12 +1545,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) while (cnt--) *dptr1++ = *dptr2++; - /* Use alternate WWN? */ - if (nv->host_p[1] & BIT_7) { - memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE); - memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE); - } - /* Prepare nodename */ if ((icb->firmware_options[1] & BIT_6) == 0) { /* @@ -1678,6 +1681,14 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) return (rval); } +static void +qla2x00_rport_add(void *data) +{ + fc_port_t *fcport = data; + + qla2x00_reg_remote_port(fcport->ha, fcport); +} + static void qla2x00_rport_del(void *data) { @@ -1715,10 +1726,13 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) fcport->ha = ha; fcport->port_type = FCT_UNKNOWN; fcport->loop_id = FC_NO_LOOP_ID; + fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; atomic_set(&fcport->state, FCS_UNCONFIGURED); fcport->flags = FCF_RLC_SUPPORT; fcport->supported_classes = FC_COS_UNSPECIFIED; spin_lock_init(&fcport->rport_lock); + INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); + INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); return (fcport); } @@ -1778,9 +1792,6 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) set_bit(RSCN_UPDATE, &flags); clear_bit(LOCAL_LOOP_UPDATE, &flags); - } else if (ha->current_topology == ISP_CFG_N) { - clear_bit(RSCN_UPDATE, &flags); - } else if (!ha->flags.online || (test_bit(ABORT_ISP_ACTIVE, &flags))) { @@ -2044,6 +2055,10 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) PORT_RETRY_TIME); fcport->flags &= ~FCF_LOGIN_NEEDED; + if (fcport->port_type == FCT_INITIATOR || + fcport->port_type == FCT_BROADCAST) + fcport->device_type = TYPE_PROCESSOR; + atomic_set(&fcport->state, FCS_ONLINE); if (ha->flags.init_done) @@ -2258,7 +2273,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) } /* Remove device from the new list and add it to DB */ - list_move_tail(&fcport->list, &ha->fcports); + list_del(&fcport->list); + list_add_tail(&fcport->list, &ha->fcports); /* Login and update database */ qla2x00_fabric_dev_login(ha, fcport, &next_loopid); @@ -2571,6 +2587,7 @@ static int qla2x00_device_resync(scsi_qla_host_t *ha) { int rval; + int rval2; uint32_t mask; fc_port_t *fcport; uint32_t rscn_entry; @@ -2626,6 +2643,17 @@ qla2x00_device_resync(scsi_qla_host_t *ha) switch (format) { case 0: + if (ql2xprocessrscn && + !IS_QLA2100(ha) && !IS_QLA2200(ha) && + !IS_QLA6312(ha) && !IS_QLA6322(ha) && + !IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + ha->flags.init_done) { + /* Handle port RSCN via asyncronous IOCBs */ + rval2 = qla2x00_handle_port_rscn(ha, rscn_entry, + NULL, 0); + if (rval2 == QLA_SUCCESS) + continue; + } mask = 0xffffff; break; case 1: @@ -2643,6 +2671,10 @@ qla2x00_device_resync(scsi_qla_host_t *ha) rval = QLA_SUCCESS; + /* Abort any outstanding IO descriptors. */ + if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) + qla2x00_cancel_io_descriptors(ha); + list_for_each_entry(fcport, &ha->fcports, list) { if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || (fcport->d_id.b24 & mask) != d_id.b24 || @@ -3351,14 +3383,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) } else strcpy(ha->model_number, "QLA2462"); - /* Use alternate WWN? */ - if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { - memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE); - memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE); - } - /* Prepare nodename */ - if ((icb->firmware_options_1 & __constant_cpu_to_le32(BIT_14)) == 0) { + if ((icb->firmware_options_1 & BIT_14) == 0) { /* * Firmware will apply the following mask if the nodename was * not provided. @@ -3374,8 +3400,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ha->flags.enable_target_reset = 1; ha->flags.enable_led_scheme = 0; - ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & - (BIT_6 | BIT_5 | BIT_4)) >> 4; + ha->operating_mode = + (icb->firmware_options_2 & (BIT_6 | BIT_5 | BIT_4)) >> 4; memcpy(ha->fw_seriallink_options24, nv->seriallink_options, sizeof(ha->fw_seriallink_options24)); @@ -3472,6 +3498,133 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) return (rval); } +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) + +int +qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) +{ + int rval, num, i; + uint32_t cnt; + uint16_t *risc_code; + uint32_t risc_addr, risc_size; + uint16_t *req_ring; + struct qla_fw_info *fw_iter; + + rval = QLA_SUCCESS; + + /* Load firmware sequences */ + fw_iter = ha->brd_info->fw_info; + *srisc_addr = *ha->brd_info->fw_info->fwstart; + while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) { + risc_code = fw_iter->fwcode; + risc_size = *fw_iter->fwlen; + if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) + risc_addr = *fw_iter->fwstart; + else + risc_addr = *fw_iter->lfwstart; + + num = 0; + rval = 0; + while (risc_size > 0 && !rval) { + cnt = (uint16_t)(ha->fw_transfer_size >> 1); + if (cnt > risc_size) + cnt = risc_size; + + DEBUG7(printk("scsi(%ld): Loading risc segment@ " + "addr %p, number of bytes 0x%x, offset 0x%lx.\n", + ha->host_no, risc_code, cnt, risc_addr)); + + req_ring = (uint16_t *)ha->request_ring; + for (i = 0; i < cnt; i++) + req_ring[i] = cpu_to_le16(risc_code[i]); + + rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr, + cnt); + if (rval) { + DEBUG(printk("scsi(%ld): [ERROR] Failed to " + "load segment %d of firmware\n", + ha->host_no, num)); + qla_printk(KERN_WARNING, ha, + "[ERROR] Failed to load segment %d of " + "firmware\n", num); + + qla2x00_dump_regs(ha); + break; + } + + risc_code += cnt; + risc_addr += cnt; + risc_size -= cnt; + num++; + } + + /* Next firmware sequence */ + fw_iter++; + } + return rval; +} + +int +qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) +{ + int rval, num, i; + uint32_t cnt; + uint32_t *risc_code; + uint32_t risc_addr, risc_size; + uint32_t *req_ring; + struct qla_fw_info *fw_iter; + + rval = QLA_SUCCESS; + + /* Load firmware sequences */ + fw_iter = ha->brd_info->fw_info; + *srisc_addr = *((uint32_t *)fw_iter->lfwstart); + while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) { + risc_code = (uint32_t *)fw_iter->fwcode; + risc_size = *((uint32_t *)fw_iter->fwlen); + risc_addr = *((uint32_t *)fw_iter->lfwstart); + + num = 0; + rval = 0; + while (risc_size > 0 && !rval) { + cnt = (uint32_t)(ha->fw_transfer_size >> 2); + if (cnt > risc_size) + cnt = risc_size; + + DEBUG7(printk("scsi(%ld): Loading risc segment@ " + "addr %p, number of bytes 0x%x, offset 0x%lx.\n", + ha->host_no, risc_code, cnt, risc_addr)); + + req_ring = (uint32_t *)ha->request_ring; + for (i = 0; i < cnt; i++) + req_ring[i] = cpu_to_le32(risc_code[i]); + + rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr, + cnt); + if (rval) { + DEBUG(printk("scsi(%ld): [ERROR] Failed to " + "load segment %d of firmware\n", + ha->host_no, num)); + qla_printk(KERN_WARNING, ha, + "[ERROR] Failed to load segment %d of " + "firmware\n", num); + + qla2x00_dump_regs(ha); + break; + } + + risc_code += cnt; + risc_addr += cnt; + risc_size -= cnt; + num++; + } + + /* Next firmware sequence */ + fw_iter++; + } + return rval; +} + int qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) { @@ -3554,7 +3707,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) return rval; } -#define QLA_FW_URL "ftp://ftp.qlogic.com/outgoing/linux/firmware/" +#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ int qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) @@ -3569,8 +3722,6 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(ha); if (!blob) { qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n"); - qla_printk(KERN_ERR, ha, "Firmware images can be retrieved " - "from: " QLA_FW_URL ".\n"); return QLA_FUNCTION_FAILED; } @@ -3672,13 +3823,7 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(ha); if (!blob) { qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n"); - qla_printk(KERN_ERR, ha, "Firmware images can be retrieved " - "from: " QLA_FW_URL ".\n"); - - /* Try to load RISC code from flash. */ - qla_printk(KERN_ERR, ha, "Attempting to load (potentially " - "outdated) firmware from flash.\n"); - return qla24xx_load_risc_flash(ha, srisc_addr); + return QLA_FUNCTION_FAILED; } rval = QLA_SUCCESS; @@ -3764,3 +3909,4 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) fail_fw_integrity: return QLA_FUNCTION_FAILED; } +#endif diff --git a/trunk/drivers/scsi/qla2xxx/qla_iocb.c b/trunk/drivers/scsi/qla2xxx/qla_iocb.c index 8c769cfaa14c..8f0f4a298357 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_iocb.c +++ b/trunk/drivers/scsi/qla2xxx/qla_iocb.c @@ -408,6 +408,7 @@ qla2x00_start_scsi(srb_t *sp) ha->request_ring_ptr++; sp->flags |= SRB_DMA_VALID; + sp->state = SRB_ACTIVE_STATE; /* Set chip new ring index. */ WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index); @@ -837,6 +838,7 @@ qla24xx_start_scsi(srb_t *sp) ha->request_ring_ptr++; sp->flags |= SRB_DMA_VALID; + sp->state = SRB_ACTIVE_STATE; /* Set chip new ring index. */ WRT_REG_DWORD(®->req_q_in, ha->req_ring_index); diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index b28ac0a27e25..2003dbb70579 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -514,6 +514,47 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_PORT_UPDATE: /* Port database update */ + /* + * If a single remote port just logged into (or logged out of) + * us, create a new entry in our rscn fcports list and handle + * the event like an RSCN. + */ + if (ql2xprocessrscn && + !IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) && + !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + ha->flags.init_done && mb[1] != 0xffff && + ((ha->operating_mode == P2P && mb[1] != 0) || + (ha->operating_mode != P2P && mb[1] != + SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) { + int rval; + fc_port_t *rscn_fcport; + + /* Create new fcport for login. */ + rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC); + if (rscn_fcport) { + DEBUG14(printk("scsi(%ld): Port Update -- " + "creating RSCN fcport %p for %x/%x/%x.\n", + ha->host_no, rscn_fcport, mb[1], mb[2], + mb[3])); + + rscn_fcport->loop_id = mb[1]; + rscn_fcport->d_id.b24 = INVALID_PORT_ID; + atomic_set(&rscn_fcport->state, + FCS_DEVICE_LOST); + list_add_tail(&rscn_fcport->list, + &ha->rscn_fcports); + + rval = qla2x00_handle_port_rscn(ha, 0, + rscn_fcport, 1); + if (rval == QLA_SUCCESS) + break; + } else { + DEBUG14(printk("scsi(%ld): Port Update -- " + "-- unable to allocate RSCN fcport " + "login.\n", ha->host_no)); + } + } + /* * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET * event etc. earlier indicating loop is down) then process @@ -712,6 +753,25 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) case MS_IOCB_TYPE: qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); break; + case MBX_IOCB_TYPE: + if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && + !IS_QLA6312(ha) && !IS_QLA6322(ha)) { + if (pkt->sys_define == SOURCE_ASYNC_IOCB) { + qla2x00_process_iodesc(ha, + (struct mbx_entry *)pkt); + } else { + /* MBX IOCB Type Not Supported. */ + DEBUG4(printk(KERN_WARNING + "scsi(%ld): Received unknown MBX " + "IOCB response pkt type=%x " + "source=%x entry status=%x.\n", + ha->host_no, pkt->entry_type, + pkt->sys_define, + pkt->entry_status)); + } + break; + } + /* Fallthrough. */ default: /* Type Not Supported. */ DEBUG4(printk(KERN_WARNING @@ -745,7 +805,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) uint16_t scsi_status; uint8_t lscsi_status; int32_t resid; - uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; + uint32_t sense_len, rsp_info_len, resid_len; uint8_t *rsp_info, *sense_data; sts = (sts_entry_t *) pkt; @@ -784,7 +844,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) cp = sp->cmd; if (cp == NULL) { DEBUG2(printk("scsi(%ld): Command already returned back to OS " - "pkt->handle=%d sp=%p.\n", ha->host_no, sts->handle, sp)); + "pkt->handle=%d sp=%p sp->state:%d\n", + ha->host_no, sts->handle, sp, sp->state)); qla_printk(KERN_WARNING, ha, "Command is NULL: already returned to OS (sp=%p)\n", sp); @@ -798,12 +859,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) fcport = sp->fcport; - sense_len = rsp_info_len = resid_len = fw_resid_len = 0; + sense_len = rsp_info_len = resid_len = 0; if (IS_QLA24XX(ha) || IS_QLA54XX(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); rsp_info = sts24->data; sense_data = sts24->data; host_to_fcp_swap(sts24->data, sizeof(sts24->data)); @@ -903,21 +963,14 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) case CS_DATA_UNDERRUN: resid = resid_len; - /* Use F/W calculated residual length. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) - resid = fw_resid_len; - if (scsi_status & SS_RESIDUAL_UNDER) { cp->resid = resid; CMD_RESID_LEN(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", ha->host_no, - cp->device->id, cp->device->lun, comp_status, - scsi_status, resid_len, resid, cp->cmnd[0], - cp->underflow)); + "0x%x-0x%x.\n", ha->host_no, cp->device->id, + cp->device->lun, comp_status, scsi_status)); } @@ -1128,7 +1181,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) cp = sp->cmd; if (cp == NULL) { DEBUG2(printk("%s(): Cmd already returned back to OS " - "sp=%p.\n", __func__, sp)); + "sp=%p sp->state:%d\n", __func__, sp, sp->state)); qla_printk(KERN_INFO, ha, "cmd is NULL: already returned to OS (sp=%p)\n", sp); diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index ccaad0b08d35..584fe5d8e507 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -54,6 +54,13 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xloginretrycount, "Specify an alternate value for the NVRAM login retry count."); +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) +int ql2xfwloadflash; +module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR); +MODULE_PARM_DESC(ql2xfwloadflash, + "Load ISP24xx firmware image from FLASH (onboard memory)."); +#endif + static void qla2x00_free_device(scsi_qla_host_t *); static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); @@ -64,6 +71,12 @@ MODULE_PARM_DESC(ql2xfdmienable, "Enables FDMI registratons " "Default is 0 - no FDMI. 1 - perfom FDMI."); +int ql2xprocessrscn; +module_param(ql2xprocessrscn, int, S_IRUGO|S_IRUSR); +MODULE_PARM_DESC(ql2xprocessrscn, + "Option to enable port RSCN handling via a series of less" + "fabric intrusive ADISCs and PLOGIs."); + /* * SCSI host template entry points */ @@ -86,7 +99,7 @@ static int qla2x00_change_queue_type(struct scsi_device *, int); static struct scsi_host_template qla2x00_driver_template = { .module = THIS_MODULE, - .name = QLA2XXX_DRIVER_NAME, + .name = "qla2xxx", .queuecommand = qla2x00_queuecommand, .eh_abort_handler = qla2xxx_eh_abort, @@ -115,7 +128,7 @@ static struct scsi_host_template qla2x00_driver_template = { static struct scsi_host_template qla24xx_driver_template = { .module = THIS_MODULE, - .name = QLA2XXX_DRIVER_NAME, + .name = "qla2xxx", .queuecommand = qla24xx_queuecommand, .eh_abort_handler = qla2xxx_eh_abort, @@ -327,6 +340,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, if (!sp) return sp; + atomic_set(&sp->ref_count, 1); sp->ha = ha; sp->fcport = fcport; sp->cmd = cmd; @@ -563,10 +577,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) while ((!atomic_read(&ha->loop_down_timer) && atomic_read(&ha->loop_state) == LOOP_DOWN) || atomic_read(&ha->loop_state) != LOOP_READY) { - if (atomic_read(&ha->loop_state) == LOOP_DEAD) { - return_status = QLA_FUNCTION_FAILED; - break; - } msleep(1000); if (time_after_eq(jiffies, loop_timeout)) { return_status = QLA_FUNCTION_FAILED; @@ -622,8 +632,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (sp->cmd != cmd) continue; - DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", - __func__, ha->host_no, sp, serial)); + DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld " + "sp->state=%x\n", __func__, ha->host_no, sp, serial, + sp->state)); DEBUG3(qla2x00_print_scsi_cmd(cmd);) spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -1146,22 +1157,18 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) case PCI_DEVICE_ID_QLOGIC_ISP2100: ha->device_type |= DT_ISP2100; ha->device_type &= ~DT_EXTENDED_IDS; - ha->fw_srisc_address = RISC_START_ADDRESS_2100; break; case PCI_DEVICE_ID_QLOGIC_ISP2200: ha->device_type |= DT_ISP2200; ha->device_type &= ~DT_EXTENDED_IDS; - ha->fw_srisc_address = RISC_START_ADDRESS_2100; break; case PCI_DEVICE_ID_QLOGIC_ISP2300: ha->device_type |= DT_ISP2300; ha->device_type |= DT_ZIO_SUPPORTED; - ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2312: ha->device_type |= DT_ISP2312; ha->device_type |= DT_ZIO_SUPPORTED; - ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2322: ha->device_type |= DT_ISP2322; @@ -1169,33 +1176,26 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) if (ha->pdev->subsystem_vendor == 0x1028 && ha->pdev->subsystem_device == 0x0170) ha->device_type |= DT_OEM_001; - ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP6312: ha->device_type |= DT_ISP6312; - ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP6322: ha->device_type |= DT_ISP6322; - ha->fw_srisc_address = RISC_START_ADDRESS_2300; break; case PCI_DEVICE_ID_QLOGIC_ISP2422: ha->device_type |= DT_ISP2422; ha->device_type |= DT_ZIO_SUPPORTED; - ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP2432: ha->device_type |= DT_ISP2432; ha->device_type |= DT_ZIO_SUPPORTED; - ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP5422: ha->device_type |= DT_ISP5422; - ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; case PCI_DEVICE_ID_QLOGIC_ISP5432: ha->device_type |= DT_ISP5432; - ha->fw_srisc_address = RISC_START_ADDRESS_2400; break; } } @@ -1242,7 +1242,7 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) goto iospace_error_exit; } - if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) { + if (pci_request_regions(ha->pdev, ha->brd_info->drv_name)) { qla_printk(KERN_WARNING, ha, "Failed to reserve PIO/MMIO regions (%s)\n", pci_name(ha->pdev)); @@ -1324,7 +1324,7 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) /* * PCI driver interface */ -static int qla2x00_probe_one(struct pci_dev *pdev) +int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) { int ret = -ENODEV; device_reg_t __iomem *reg; @@ -1358,7 +1358,8 @@ static int qla2x00_probe_one(struct pci_dev *pdev) ha->pdev = pdev; ha->host = host; ha->host_no = host->host_no; - sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); + ha->brd_info = brd_info; + sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); /* Set ISP-type information. */ qla2x00_set_isp_flags(ha); @@ -1375,6 +1376,7 @@ static int qla2x00_probe_one(struct pci_dev *pdev) spin_lock_init(&ha->hardware_lock); ha->prev_topology = 0; + ha->ports = MAX_BUSES; ha->init_cb_size = sizeof(init_cb_t); ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; ha->link_data_rate = LDR_UNKNOWN; @@ -1455,6 +1457,10 @@ static int qla2x00_probe_one(struct pci_dev *pdev) ha->isp_ops.nvram_config = qla24xx_nvram_config; ha->isp_ops.update_fw_options = qla24xx_update_fw_options; ha->isp_ops.load_risc = qla24xx_load_risc; +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) + if (ql2xfwloadflash) + ha->isp_ops.load_risc = qla24xx_load_risc_flash; +#endif ha->isp_ops.pci_info_str = qla24xx_pci_info_str; ha->isp_ops.fw_version_str = qla24xx_fw_version_str; ha->isp_ops.intr_handler = qla24xx_intr_handler; @@ -1488,6 +1494,7 @@ static int qla2x00_probe_one(struct pci_dev *pdev) INIT_LIST_HEAD(&ha->list); INIT_LIST_HEAD(&ha->fcports); + INIT_LIST_HEAD(&ha->rscn_fcports); /* * These locks are used to prevent more than one CPU @@ -1536,12 +1543,12 @@ static int qla2x00_probe_one(struct pci_dev *pdev) host->cmd_per_lun = 3; host->unique_id = ha->instance; host->max_cmd_len = MAX_CMDSZ; - host->max_channel = MAX_BUSES - 1; + host->max_channel = ha->ports - 1; host->max_lun = MAX_LUNS; host->transportt = qla2xxx_transport_template; ret = request_irq(pdev->irq, ha->isp_ops.intr_handler, - SA_INTERRUPT|SA_SHIRQ, QLA2XXX_DRIVER_NAME, ha); + SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); if (ret) { qla_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d already in use.\n", @@ -1639,8 +1646,9 @@ static int qla2x00_probe_one(struct pci_dev *pdev) probe_out: return ret; } +EXPORT_SYMBOL_GPL(qla2x00_probe_one); -static void qla2x00_remove_one(struct pci_dev *pdev) +void qla2x00_remove_one(struct pci_dev *pdev) { scsi_qla_host_t *ha; @@ -1658,10 +1666,15 @@ static void qla2x00_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +EXPORT_SYMBOL_GPL(qla2x00_remove_one); static void qla2x00_free_device(scsi_qla_host_t *ha) { + /* Abort any outstanding IO descriptors. */ + if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) + qla2x00_cancel_io_descriptors(ha); + /* Disable timer */ if (ha->timer_active) qla2x00_stop_timer(ha); @@ -1871,8 +1884,19 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) continue; } - snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME, - ha->host_no); + ha->rlc_rsp = dma_alloc_coherent(&ha->pdev->dev, + sizeof(rpt_lun_cmd_rsp_t), &ha->rlc_rsp_dma, GFP_KERNEL); + if (ha->rlc_rsp == NULL) { + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - rlc"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + + snprintf(name, sizeof(name), "qla2xxx_%ld", ha->host_no); ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev, DMA_POOL_SIZE, 8, 0); if (ha->s_dma_pool == NULL) { @@ -1899,6 +1923,21 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) } memset(ha->init_cb, 0, ha->init_cb_size); + /* Get consistent memory allocated for Get Port Database cmd */ + ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + &ha->iodesc_pd_dma); + if (ha->iodesc_pd == NULL) { + /* error */ + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - iodesc_pd\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE); + /* Allocate ioctl related memory. */ if (qla2x00_alloc_ioctl_mem(ha)) { qla_printk(KERN_WARNING, ha, @@ -2023,12 +2062,20 @@ qla2x00_mem_free(scsi_qla_host_t *ha) if (ha->ms_iocb) dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); + if (ha->iodesc_pd) + dma_pool_free(ha->s_dma_pool, ha->iodesc_pd, ha->iodesc_pd_dma); + if (ha->init_cb) dma_pool_free(ha->s_dma_pool, ha->init_cb, ha->init_cb_dma); if (ha->s_dma_pool) dma_pool_destroy(ha->s_dma_pool); + if (ha->rlc_rsp) + dma_free_coherent(&ha->pdev->dev, + sizeof(rpt_lun_cmd_rsp_t), ha->rlc_rsp, + ha->rlc_rsp_dma); + if (ha->gid_list) dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, ha->gid_list_dma); @@ -2049,11 +2096,15 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ha->ct_sns_dma = 0; ha->ms_iocb = NULL; ha->ms_iocb_dma = 0; + ha->iodesc_pd = NULL; + ha->iodesc_pd_dma = 0; ha->init_cb = NULL; ha->init_cb_dma = 0; ha->s_dma_pool = NULL; + ha->rlc_rsp = NULL; + ha->rlc_rsp_dma = 0; ha->gid_list = NULL; ha->gid_list_dma = 0; @@ -2071,10 +2122,15 @@ qla2x00_mem_free(scsi_qla_host_t *ha) } INIT_LIST_HEAD(&ha->fcports); - vfree(ha->fw_dump); + if (ha->fw_dump) + free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); + + vfree(ha->fw_dump24); + vfree(ha->fw_dump_buffer); ha->fw_dump = NULL; + ha->fw_dump24 = NULL; ha->fw_dumped = 0; ha->fw_dump_reading = 0; ha->fw_dump_buffer = NULL; @@ -2092,6 +2148,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) * * Context: * Kernel context. + * + * Note: Sets the ref_count for non Null sp to one. */ static int qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) @@ -2535,6 +2593,14 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) return -ETIMEDOUT; } +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) + +#define qla2x00_release_firmware() do { } while (0) +#define qla2x00_pci_module_init() (0) +#define qla2x00_pci_module_exit() do { } while (0) + +#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */ + /* Firmware interface routines. */ #define FW_BLOBS 5 @@ -2601,18 +2667,33 @@ qla2x00_release_firmware(void) up(&qla_fw_lock); } +static struct qla_board_info qla_board_tbl = { + .drv_name = "qla2xxx", +}; + static struct pci_device_id qla2xxx_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432, + PCI_ANY_ID, PCI_ANY_ID, }, { 0 }, }; MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); @@ -2620,7 +2701,7 @@ MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); static int __devinit qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { - return qla2x00_probe_one(pdev); + return qla2x00_probe_one(pdev, &qla_board_tbl); } static void __devexit @@ -2630,7 +2711,7 @@ qla2xxx_remove_one(struct pci_dev *pdev) } static struct pci_driver qla2xxx_pci_driver = { - .name = QLA2XXX_DRIVER_NAME, + .name = "qla2xxx", .driver = { .owner = THIS_MODULE, }, @@ -2651,6 +2732,8 @@ qla2x00_pci_module_exit(void) pci_unregister_driver(&qla2xxx_pci_driver); } +#endif + /** * qla2x00_module_init - Module initialization. **/ @@ -2670,6 +2753,9 @@ qla2x00_module_init(void) /* Derive version string. */ strcpy(qla2x00_version_str, QLA2XXX_VERSION); +#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) + strcat(qla2x00_version_str, "-fw"); +#endif #if DEBUG_QLA2100 strcat(qla2x00_version_str, "-debug"); #endif diff --git a/trunk/drivers/scsi/qla2xxx/qla_rscn.c b/trunk/drivers/scsi/qla2xxx/qla_rscn.c new file mode 100644 index 000000000000..b70bebe18c01 --- /dev/null +++ b/trunk/drivers/scsi/qla2xxx/qla_rscn.c @@ -0,0 +1,1426 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include "qla_def.h" + +/** + * IO descriptor handle definitions. + * + * Signature form: + * + * |31------28|27-------------------12|11-------0| + * | Type | Rolling Signature | Index | + * |----------|-----------------------|----------| + * + **/ + +#define HDL_TYPE_SCSI 0 +#define HDL_TYPE_ASYNC_IOCB 0x0A + +#define HDL_INDEX_BITS 12 +#define HDL_ITER_BITS 16 +#define HDL_TYPE_BITS 4 + +#define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1) +#define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1) +#define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1) + +#define HDL_INDEX_SHIFT 0 +#define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS) +#define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS) + +/* Local Prototypes. */ +static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t); +static inline uint16_t qla2x00_handle_to_idx(uint32_t); +static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *); +static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *, + uint32_t); + +static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *); +static inline void qla2x00_free_iodesc(struct io_descriptor *); +static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *); + +static void qla2x00_iodesc_timeout(unsigned long); +static inline void qla2x00_add_iodesc_timer(struct io_descriptor *); +static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *); + +static inline void qla2x00_update_login_fcport(scsi_qla_host_t *, + struct mbx_entry *, fc_port_t *); + +static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *, + uint32_t, int); +static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *, + struct mbx_entry *); + +static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *, + int); +static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *, + struct mbx_entry *); + +static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *, + int); +static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *, + struct io_descriptor *, struct mbx_entry *); + +static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *, + port_id_t *, int); +static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *, + struct mbx_entry *); + +/** + * Mailbox IOCB callback array. + **/ +static int (*iocb_function_cb_list[LAST_IOCB_CB]) + (scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = { + + qla2x00_send_abort_iocb_cb, + qla2x00_send_adisc_iocb_cb, + qla2x00_send_logout_iocb_cb, + qla2x00_send_login_iocb_cb, +}; + + +/** + * Generic IO descriptor handle routines. + **/ + +/** + * qla2x00_to_handle() - Create a descriptor handle. + * @type: descriptor type + * @iter: descriptor rolling signature + * @idx: index to the descriptor array + * + * Returns a composite handle based in the @type, @iter, and @idx. + */ +static inline uint32_t +qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx) +{ + return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) | + ((uint32_t)iter << HDL_ITER_SHIFT) | + ((uint32_t)idx << HDL_INDEX_SHIFT))); +} + +/** + * qla2x00_handle_to_idx() - Retrive the index for a given handle. + * @handle: descriptor handle + * + * Returns the index specified by the @handle. + */ +static inline uint16_t +qla2x00_handle_to_idx(uint32_t handle) +{ + return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK)); +} + +/** + * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle. + * @iodesc: io descriptor + * + * Returns a unique handle for @iodesc. + */ +static inline uint32_t +qla2x00_iodesc_to_handle(struct io_descriptor *iodesc) +{ + uint32_t handle; + + handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB, + ++iodesc->ha->iodesc_signature, iodesc->idx); + iodesc->signature = handle; + + return (handle); +} + +/** + * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle. + * @ha: HA context + * @handle: handle to io descriptor + * + * Returns a pointer to the io descriptor, or NULL, if the io descriptor does + * not exist or the io descriptors signature does not @handle. + */ +static inline struct io_descriptor * +qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle) +{ + uint16_t idx; + struct io_descriptor *iodesc; + + idx = qla2x00_handle_to_idx(handle); + iodesc = &ha->io_descriptors[idx]; + if (iodesc) + if (iodesc->signature != handle) + iodesc = NULL; + + return (iodesc); +} + + +/** + * IO descriptor allocation routines. + **/ + +/** + * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool. + * @ha: HA context + * + * Returns a pointer to the allocated io descriptor, or NULL, if none available. + */ +static inline struct io_descriptor * +qla2x00_alloc_iodesc(scsi_qla_host_t *ha) +{ + uint16_t iter; + struct io_descriptor *iodesc; + + iodesc = NULL; + for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) { + if (ha->io_descriptors[iter].used) + continue; + + iodesc = &ha->io_descriptors[iter]; + iodesc->used = 1; + iodesc->idx = iter; + init_timer(&iodesc->timer); + iodesc->ha = ha; + iodesc->signature = qla2x00_iodesc_to_handle(iodesc); + break; + } + + return (iodesc); +} + +/** + * qla2x00_free_iodesc() - Free an IO descriptor. + * @iodesc: io descriptor + * + * NOTE: The io descriptors timer *must* be stopped before it can be free'd. + */ +static inline void +qla2x00_free_iodesc(struct io_descriptor *iodesc) +{ + iodesc->used = 0; + iodesc->signature = 0; +} + +/** + * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor. + * @iodesc: io descriptor + */ +static inline void +qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc) +{ + if (iodesc->timer.function != NULL) { + del_timer_sync(&iodesc->timer); + iodesc->timer.data = (unsigned long) NULL; + iodesc->timer.function = NULL; + } +} + +/** + * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors. + * @ha: HA context + */ +static inline void +qla2x00_init_io_descriptors(scsi_qla_host_t *ha) +{ + uint16_t iter; + + for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) { + if (!ha->io_descriptors[iter].used) + continue; + + qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]); + qla2x00_free_iodesc(&ha->io_descriptors[iter]); + } +} + + +/** + * IO descriptor timer routines. + **/ + +/** + * qla2x00_iodesc_timeout() - Timeout IO descriptor handler. + * @data: io descriptor + */ +static void +qla2x00_iodesc_timeout(unsigned long data) +{ + struct io_descriptor *iodesc; + + iodesc = (struct io_descriptor *) data; + + DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x " + "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no, + iodesc->idx, iodesc->signature)); + + qla2x00_free_iodesc(iodesc); + + qla_printk(KERN_WARNING, iodesc->ha, + "IO descriptor timeout. Scheduling ISP abort.\n"); + set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags); +} + +/** + * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor. + * @iodesc: io descriptor + * + * NOTE: + * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in + * tenths of a second) after it hits the wire. But, if there are any request + * resource contraints (i.e. during heavy I/O), exchanges can be held off for + * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before + * scheduling a recovery (big hammer). + */ +static inline void +qla2x00_add_iodesc_timer(struct io_descriptor *iodesc) +{ + unsigned long timeout; + + timeout = (iodesc->ha->r_a_tov * 4) / 10; + init_timer(&iodesc->timer); + iodesc->timer.data = (unsigned long) iodesc; + iodesc->timer.expires = jiffies + (timeout * HZ); + iodesc->timer.function = + (void (*) (unsigned long)) qla2x00_iodesc_timeout; + add_timer(&iodesc->timer); +} + +/** + * IO descriptor support routines. + **/ + +/** + * qla2x00_update_login_fcport() - Update fcport data after login processing. + * @ha: HA context + * @mbxstat: Mailbox command status IOCB + * @fcport: port to update + */ +static inline void +qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat, + fc_port_t *fcport) +{ + if (le16_to_cpu(mbxstat->mb1) & BIT_0) { + fcport->port_type = FCT_INITIATOR; + } else { + fcport->port_type = FCT_TARGET; + if (le16_to_cpu(mbxstat->mb1) & BIT_1) { + fcport->flags |= FCF_TAPE_PRESENT; + } + } + fcport->login_retry = 0; + fcport->port_login_retry_count = ha->port_down_retry_count * + PORT_RETRY_TIME; + atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * + PORT_RETRY_TIME); + fcport->flags |= FCF_FABRIC_DEVICE; + fcport->flags &= ~FCF_FAILOVER_NEEDED; + fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; + atomic_set(&fcport->state, FCS_ONLINE); + schedule_work(&fcport->rport_add_work); +} + + +/** + * Mailbox IOCB commands. + **/ + +/** + * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue. + * @ha: HA context + * @handle: handle to io descriptor + * + * Returns a pointer to the reqest entry, or NULL, if none were available. + */ +static inline struct mbx_entry * +qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle) +{ + uint16_t cnt; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + struct mbx_entry *mbxentry; + + mbxentry = NULL; + + if (ha->req_q_cnt < 3) { + cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg)); + if (ha->req_ring_index < cnt) + ha->req_q_cnt = cnt - ha->req_ring_index; + else + ha->req_q_cnt = ha->request_q_length - + (ha->req_ring_index - cnt); + } + if (ha->req_q_cnt >= 3) { + mbxentry = (struct mbx_entry *)ha->request_ring_ptr; + + memset(mbxentry, 0, sizeof(struct mbx_entry)); + mbxentry->entry_type = MBX_IOCB_TYPE; + mbxentry->entry_count = 1; + mbxentry->sys_define1 = SOURCE_ASYNC_IOCB; + mbxentry->handle = handle; + } + return (mbxentry); +} + +/** + * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware. + * @ha: HA context + * @iodesc: io descriptor + * @handle_to_abort: firmware handle to abort + * @ha_locked: is function called with the hardware lock + * + * Returns QLA_SUCCESS if the IOCB was issued. + */ +static int +qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + uint32_t handle_to_abort, int ha_locked) +{ + unsigned long flags = 0; + struct mbx_entry *mbxentry; + + /* Send marker if required. */ + if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS) + return (QLA_FUNCTION_FAILED); + + if (!ha_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Build abort mailbox IOCB. */ + mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature); + if (mbxentry == NULL) { + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + return (QLA_FUNCTION_FAILED); + } + mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND); + mbxentry->mb1 = mbxentry->loop_id.extended = + cpu_to_le16(iodesc->remote_fcport->loop_id); + mbxentry->mb2 = LSW(handle_to_abort); + mbxentry->mb3 = MSW(handle_to_abort); + wmb(); + + qla2x00_add_iodesc_timer(iodesc); + + /* Issue command to ISP. */ + qla2x00_isp_cmd(ha); + + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting " + "%08x.\n", ha->host_no, iodesc->signature, + iodesc->remote_fcport->loop_id, handle_to_abort)); + + return (QLA_SUCCESS); +} + +/** + * qla2x00_send_abort_iocb_cb() - Abort IOCB callback. + * @ha: HA context + * @iodesc: io descriptor + * @mbxstat: mailbox status IOCB + * + * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc + * will be used for a retry. + */ +static int +qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + struct mbx_entry *mbxstat) +{ + DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], " + "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id, + iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa, + le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0))); + + return (QLA_SUCCESS); +} + + +/** + * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware. + * @ha: HA context + * @iodesc: io descriptor + * @ha_locked: is function called with the hardware lock + * + * Returns QLA_SUCCESS if the IOCB was issued. + */ +static int +qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + int ha_locked) +{ + unsigned long flags = 0; + struct mbx_entry *mbxentry; + + /* Send marker if required. */ + if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS) + return (QLA_FUNCTION_FAILED); + + if (!ha_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Build Get Port Database IOCB. */ + mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature); + if (mbxentry == NULL) { + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + return (QLA_FUNCTION_FAILED); + } + mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE); + mbxentry->mb1 = mbxentry->loop_id.extended = + cpu_to_le16(iodesc->remote_fcport->loop_id); + mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma))); + mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma))); + mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma))); + mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma))); + mbxentry->mb10 = __constant_cpu_to_le16(BIT_0); + wmb(); + + qla2x00_add_iodesc_timer(iodesc); + + /* Issue command to ISP. */ + qla2x00_isp_cmd(ha); + + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n", + ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id)); + + return (QLA_SUCCESS); +} + +/** + * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback. + * @ha: HA context + * @iodesc: io descriptor + * @mbxstat: mailbox status IOCB + * + * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc + * will be used for a retry. + */ +static int +qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + struct mbx_entry *mbxstat) +{ + fc_port_t *remote_fcport; + + remote_fcport = iodesc->remote_fcport; + + /* Ensure the port IDs are consistent. */ + if (remote_fcport->d_id.b24 != iodesc->d_id.b24) { + DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port " + "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n", + ha->host_no, remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa)); + + return (QLA_SUCCESS); + } + + /* Only process the last command. */ + if (remote_fcport->iodesc_idx_sent != iodesc->idx) { + DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to " + "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent, + iodesc->idx)); + + return (QLA_SUCCESS); + } + + if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) { + DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking " + "[%x/%02x%02x%02x] online.\n", ha->host_no, + remote_fcport->loop_id, remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa)); + + atomic_set(&remote_fcport->state, FCS_ONLINE); + } else { + DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking " + "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no, + remote_fcport->loop_id, remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa, + le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0))); + + if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD) + atomic_set(&remote_fcport->state, FCS_DEVICE_LOST); + } + remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; + + return (QLA_SUCCESS); +} + + +/** + * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware. + * @ha: HA context + * @iodesc: io descriptor + * @ha_locked: is function called with the hardware lock + * + * Returns QLA_SUCCESS if the IOCB was issued. + */ +static int +qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + int ha_locked) +{ + unsigned long flags = 0; + struct mbx_entry *mbxentry; + + /* Send marker if required. */ + if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS) + return (QLA_FUNCTION_FAILED); + + if (!ha_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Build fabric port logout mailbox IOCB. */ + mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature); + if (mbxentry == NULL) { + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + return (QLA_FUNCTION_FAILED); + } + mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT); + mbxentry->mb1 = mbxentry->loop_id.extended = + cpu_to_le16(iodesc->remote_fcport->loop_id); + wmb(); + + qla2x00_add_iodesc_timer(iodesc); + + /* Issue command to ISP. */ + qla2x00_isp_cmd(ha); + + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n", + ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id)); + + return (QLA_SUCCESS); +} + +/** + * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback. + * @ha: HA context + * @iodesc: io descriptor + * @mbxstat: mailbox status IOCB + * + * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc + * will be used for a retry. + */ +static int +qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + struct mbx_entry *mbxstat) +{ + DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], " + "status=%x mb0=%x mb1=%x.\n", ha->host_no, + iodesc->remote_fcport->loop_id, + iodesc->remote_fcport->d_id.b.domain, + iodesc->remote_fcport->d_id.b.area, + iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status), + le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1))); + + return (QLA_SUCCESS); +} + + +/** + * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware. + * @ha: HA context + * @iodesc: io descriptor + * @d_id: port id for device + * @ha_locked: is function called with the hardware lock + * + * Returns QLA_SUCCESS if the IOCB was issued. + */ +static int +qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + port_id_t *d_id, int ha_locked) +{ + unsigned long flags = 0; + struct mbx_entry *mbxentry; + + /* Send marker if required. */ + if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS) + return (QLA_FUNCTION_FAILED); + + if (!ha_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Build fabric port login mailbox IOCB. */ + mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature); + if (mbxentry == NULL) { + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + return (QLA_FUNCTION_FAILED); + } + mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT); + mbxentry->mb1 = mbxentry->loop_id.extended = + cpu_to_le16(iodesc->remote_fcport->loop_id); + mbxentry->mb2 = cpu_to_le16(d_id->b.domain); + mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa); + mbxentry->mb10 = __constant_cpu_to_le16(BIT_0); + wmb(); + + qla2x00_add_iodesc_timer(iodesc); + + /* Issue command to ISP. */ + qla2x00_isp_cmd(ha); + + if (!ha_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to " + "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature, + iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area, + d_id->b.al_pa)); + + return (QLA_SUCCESS); +} + +/** + * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback. + * @ha: HA context + * @iodesc: io descriptor + * @mbxstat: mailbox status IOCB + * + * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc + * will be used for a retry. + */ +static int +qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, + struct mbx_entry *mbxstat) +{ + int rval; + fc_port_t *fcport, *remote_fcport, *exist_fcport; + struct io_descriptor *abort_iodesc, *login_iodesc; + uint16_t status, mb[8]; + uint16_t reuse; + uint16_t remote_loopid; + port_id_t remote_did, inuse_did; + + remote_fcport = iodesc->remote_fcport; + + /* Only process the last command. */ + if (remote_fcport->iodesc_idx_sent != iodesc->idx) { + DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to " + "[%02x%02x%02x], expected %x, received %x.\n", + ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent, + iodesc->idx)); + + /* Free RSCN fcport resources. */ + if (remote_fcport->port_type == FCT_RSCN) { + DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN " + "fcport %p [%x/%02x%02x%02x] given ignored Login " + "IOCB.\n", ha->host_no, remote_fcport, + remote_fcport->loop_id, + remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa)); + + list_del(&remote_fcport->list); + kfree(remote_fcport); + } + return (QLA_SUCCESS); + } + + status = le16_to_cpu(mbxstat->status); + mb[0] = le16_to_cpu(mbxstat->mb0); + mb[1] = le16_to_cpu(mbxstat->mb1); + mb[2] = le16_to_cpu(mbxstat->mb2); + mb[6] = le16_to_cpu(mbxstat->mb6); + mb[7] = le16_to_cpu(mbxstat->mb7); + + /* Good status? */ + if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) && + mb[0] == MBS_COMMAND_COMPLETE) { + + DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn=" + "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status, + mb[1], mbxstat->port_name[0], mbxstat->port_name[1], + mbxstat->port_name[2], mbxstat->port_name[3], + mbxstat->port_name[4], mbxstat->port_name[5], + mbxstat->port_name[6], mbxstat->port_name[7])); + + memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE); + memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE); + + /* Is the device already in our fcports list? */ + if (remote_fcport->port_type != FCT_RSCN) { + DEBUG14(printk("scsi(%ld): Login IOCB -- marking " + "[%x/%02x%02x%02x] online.\n", ha->host_no, + remote_fcport->loop_id, + remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa)); + + qla2x00_update_login_fcport(ha, mbxstat, remote_fcport); + + return (QLA_SUCCESS); + } + + /* Does the RSCN portname already exist in our fcports list? */ + exist_fcport = NULL; + list_for_each_entry(fcport, &ha->fcports, list) { + if (memcmp(remote_fcport->port_name, fcport->port_name, + WWN_SIZE) == 0) { + exist_fcport = fcport; + break; + } + } + if (exist_fcport != NULL) { + DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN " + "fcport in fcports list [%p].\n", ha->host_no, + exist_fcport)); + + /* Abort any ADISC that could have been sent. */ + if (exist_fcport->iodesc_idx_sent != iodesc->idx && + exist_fcport->iodesc_idx_sent < + MAX_IO_DESCRIPTORS && + ha->io_descriptors[exist_fcport->iodesc_idx_sent]. + cb_idx == ADISC_PORT_IOCB_CB) { + + abort_iodesc = qla2x00_alloc_iodesc(ha); + if (abort_iodesc) { + DEBUG14(printk("scsi(%ld): Login IOCB " + "-- issuing abort to outstanding " + "Adisc [%x/%02x%02x%02x].\n", + ha->host_no, remote_fcport->loop_id, + exist_fcport->d_id.b.domain, + exist_fcport->d_id.b.area, + exist_fcport->d_id.b.al_pa)); + + abort_iodesc->cb_idx = ABORT_IOCB_CB; + abort_iodesc->d_id.b24 = + exist_fcport->d_id.b24; + abort_iodesc->remote_fcport = + exist_fcport; + exist_fcport->iodesc_idx_sent = + abort_iodesc->idx; + qla2x00_send_abort_iocb(ha, + abort_iodesc, ha->io_descriptors[ + exist_fcport->iodesc_idx_sent]. + signature, 1); + } else { + DEBUG14(printk("scsi(%ld): Login IOCB " + "-- unable to abort outstanding " + "Adisc [%x/%02x%02x%02x].\n", + ha->host_no, remote_fcport->loop_id, + exist_fcport->d_id.b.domain, + exist_fcport->d_id.b.area, + exist_fcport->d_id.b.al_pa)); + } + } + + /* + * If the existing fcport is waiting to send an ADISC + * or LOGIN, then reuse remote fcport (RSCN) to + * continue waiting. + */ + reuse = 0; + remote_loopid = remote_fcport->loop_id; + remote_did.b24 = remote_fcport->d_id.b24; + if (exist_fcport->iodesc_idx_sent == + IODESC_ADISC_NEEDED || + exist_fcport->iodesc_idx_sent == + IODESC_LOGIN_NEEDED) { + DEBUG14(printk("scsi(%ld): Login IOCB -- " + "existing fcport [%x/%02x%02x%02x] " + "waiting for IO descriptor, reuse RSCN " + "fcport.\n", ha->host_no, + exist_fcport->loop_id, + exist_fcport->d_id.b.domain, + exist_fcport->d_id.b.area, + exist_fcport->d_id.b.al_pa)); + + reuse++; + remote_fcport->iodesc_idx_sent = + exist_fcport->iodesc_idx_sent; + exist_fcport->iodesc_idx_sent = + IODESC_INVALID_INDEX; + remote_fcport->loop_id = exist_fcport->loop_id; + remote_fcport->d_id.b24 = + exist_fcport->d_id.b24; + } + + /* Logout the old loopid. */ + if (!reuse && + exist_fcport->loop_id != remote_fcport->loop_id && + exist_fcport->loop_id != FC_NO_LOOP_ID) { + login_iodesc = qla2x00_alloc_iodesc(ha); + if (login_iodesc) { + DEBUG14(printk("scsi(%ld): Login IOCB " + "-- issuing logout to free old " + "loop id [%x/%02x%02x%02x].\n", + ha->host_no, exist_fcport->loop_id, + exist_fcport->d_id.b.domain, + exist_fcport->d_id.b.area, + exist_fcport->d_id.b.al_pa)); + + login_iodesc->cb_idx = + LOGOUT_PORT_IOCB_CB; + login_iodesc->d_id.b24 = + exist_fcport->d_id.b24; + login_iodesc->remote_fcport = + exist_fcport; + exist_fcport->iodesc_idx_sent = + login_iodesc->idx; + qla2x00_send_logout_iocb(ha, + login_iodesc, 1); + } else { + /* Ran out of IO descriptiors. */ + DEBUG14(printk("scsi(%ld): Login IOCB " + "-- unable to logout to free old " + "loop id [%x/%02x%02x%02x].\n", + ha->host_no, exist_fcport->loop_id, + exist_fcport->d_id.b.domain, + exist_fcport->d_id.b.area, + exist_fcport->d_id.b.al_pa)); + + exist_fcport->iodesc_idx_sent = + IODESC_INVALID_INDEX; + } + + } + + /* Update existing fcport with remote fcport info. */ + DEBUG14(printk("scsi(%ld): Login IOCB -- marking " + "existing fcport [%x/%02x%02x%02x] online.\n", + ha->host_no, remote_loopid, remote_did.b.domain, + remote_did.b.area, remote_did.b.al_pa)); + + memcpy(exist_fcport->node_name, + remote_fcport->node_name, WWN_SIZE); + exist_fcport->loop_id = remote_loopid; + exist_fcport->d_id.b24 = remote_did.b24; + qla2x00_update_login_fcport(ha, mbxstat, exist_fcport); + + /* Finally, free the remote (RSCN) fcport. */ + if (!reuse) { + DEBUG14(printk("scsi(%ld): Login IOCB -- " + "Freeing RSCN fcport %p " + "[%x/%02x%02x%02x].\n", ha->host_no, + remote_fcport, remote_fcport->loop_id, + remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa)); + + list_del(&remote_fcport->list); + kfree(remote_fcport); + } + + return (QLA_SUCCESS); + } + + /* + * A new device has been added, move the RSCN fcport to our + * fcports list. + */ + DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport " + "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no, + remote_fcport->loop_id, remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa)); + + list_del(&remote_fcport->list); + remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED); + qla2x00_update_login_fcport(ha, mbxstat, remote_fcport); + list_add_tail(&remote_fcport->list, &ha->fcports); + set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags); + } else { + /* Handle login failure. */ + if (remote_fcport->login_retry != 0) { + if (mb[0] == MBS_LOOP_ID_USED) { + inuse_did.b.domain = LSB(mb[1]); + inuse_did.b.area = MSB(mb[2]); + inuse_did.b.al_pa = LSB(mb[2]); + + DEBUG14(printk("scsi(%ld): Login IOCB -- loop " + "id [%x] used by port id [%02x%02x%02x].\n", + ha->host_no, remote_fcport->loop_id, + inuse_did.b.domain, inuse_did.b.area, + inuse_did.b.al_pa)); + + if (remote_fcport->d_id.b24 == + INVALID_PORT_ID) { + /* + * Invalid port id means we are trying + * to login to a remote port with just + * a loop id without knowing about the + * port id. Copy the port id and try + * again. + */ + remote_fcport->d_id.b24 = inuse_did.b24; + iodesc->d_id.b24 = inuse_did.b24; + } else { + remote_fcport->loop_id++; + rval = qla2x00_find_new_loop_id(ha, + remote_fcport); + if (rval == QLA_FUNCTION_FAILED) { + /* No more loop ids. */ + return (QLA_SUCCESS); + } + } + } else if (mb[0] == MBS_PORT_ID_USED) { + /* + * Device has another loop ID. The firmware + * group recommends the driver perform an + * implicit login with the specified ID. + */ + DEBUG14(printk("scsi(%ld): Login IOCB -- port " + "id [%02x%02x%02x] already assigned to " + "loop id [%x].\n", ha->host_no, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa, mb[1])); + + remote_fcport->loop_id = mb[1]; + + } else { + /* Unable to perform login, try again. */ + DEBUG14(printk("scsi(%ld): Login IOCB -- " + "failed login [%x/%02x%02x%02x], status=%x " + "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n", + ha->host_no, remote_fcport->loop_id, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa, status, mb[0], mb[1], + mb[2], mb[6], mb[7])); + } + + /* Reissue Login with the same IO descriptor. */ + iodesc->signature = + qla2x00_iodesc_to_handle(iodesc); + iodesc->cb_idx = LOGIN_PORT_IOCB_CB; + iodesc->d_id.b24 = remote_fcport->d_id.b24; + remote_fcport->iodesc_idx_sent = iodesc->idx; + remote_fcport->login_retry--; + + DEBUG14(printk("scsi(%ld): Login IOCB -- retrying " + "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no, + remote_fcport->loop_id, + remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa, + remote_fcport->login_retry)); + + qla2x00_send_login_iocb(ha, iodesc, + &remote_fcport->d_id, 1); + + return (QLA_FUNCTION_FAILED); + } else { + /* No more logins, mark device dead. */ + DEBUG14(printk("scsi(%ld): Login IOCB -- failed " + "login [%x/%02x%02x%02x] after retries, status=%x " + "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n", + ha->host_no, remote_fcport->loop_id, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa, status, mb[0], mb[1], + mb[2], mb[6], mb[7])); + + atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD); + if (remote_fcport->port_type == FCT_RSCN) { + DEBUG14(printk("scsi(%ld): Login IOCB -- " + "Freeing dead RSCN fcport %p " + "[%x/%02x%02x%02x].\n", ha->host_no, + remote_fcport, remote_fcport->loop_id, + remote_fcport->d_id.b.domain, + remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa)); + + list_del(&remote_fcport->list); + kfree(remote_fcport); + } + } + } + + return (QLA_SUCCESS); +} + + +/** + * IO descriptor processing routines. + **/ + +/** + * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport. + * @ha: HA context + * @flags: allocation flags + * + * Returns a pointer to the allocated RSCN fcport, or NULL, if none available. + */ +fc_port_t * +qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, gfp_t flags) +{ + fc_port_t *fcport; + + fcport = qla2x00_alloc_fcport(ha, flags); + if (fcport == NULL) + return (fcport); + + /* Setup RSCN fcport structure. */ + fcport->port_type = FCT_RSCN; + + return (fcport); +} + +/** + * qla2x00_handle_port_rscn() - Handle port RSCN. + * @ha: HA context + * @rscn_entry: RSCN entry + * @fcport: fcport entry to updated + * + * Returns QLA_SUCCESS if the port RSCN was handled. + */ +int +qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry, + fc_port_t *known_fcport, int ha_locked) +{ + int rval; + port_id_t rscn_pid; + fc_port_t *fcport, *remote_fcport, *rscn_fcport; + struct io_descriptor *iodesc; + + remote_fcport = NULL; + rscn_fcport = NULL; + + /* Prepare port id based on incoming entries. */ + if (known_fcport) { + rscn_pid.b24 = known_fcport->d_id.b24; + remote_fcport = known_fcport; + + DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for " + "fcport [%02x%02x%02x].\n", ha->host_no, + remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area, + remote_fcport->d_id.b.al_pa)); + } else { + rscn_pid.b.domain = LSB(MSW(rscn_entry)); + rscn_pid.b.area = MSB(LSW(rscn_entry)); + rscn_pid.b.al_pa = LSB(LSW(rscn_entry)); + + DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for " + "port id [%02x%02x%02x].\n", ha->host_no, + rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa)); + + /* + * Search fcport lists for a known entry at the specified port + * ID. + */ + list_for_each_entry(fcport, &ha->fcports, list) { + if (rscn_pid.b24 == fcport->d_id.b24) { + remote_fcport = fcport; + break; + } + } + list_for_each_entry(fcport, &ha->rscn_fcports, list) { + if (rscn_pid.b24 == fcport->d_id.b24) { + rscn_fcport = fcport; + break; + } + } + if (remote_fcport == NULL) + remote_fcport = rscn_fcport; + } + + /* + * If the port is already in our fcport list and online, send an ADISC + * to see if it's still alive. Issue login if a new fcport or the known + * fcport is currently offline. + */ + if (remote_fcport) { + /* + * No need to send request if the remote fcport is currently + * waiting for an available io descriptor. + */ + if (known_fcport == NULL && + (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED || + remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) { + /* + * If previous waiting io descriptor is an ADISC, then + * the new RSCN may come from a new remote fcport being + * plugged into the same location. + */ + if (remote_fcport->port_type == FCT_RSCN) { + remote_fcport->iodesc_idx_sent = + IODESC_LOGIN_NEEDED; + } else if (remote_fcport->iodesc_idx_sent == + IODESC_ADISC_NEEDED) { + fc_port_t *new_fcport; + + remote_fcport->iodesc_idx_sent = + IODESC_INVALID_INDEX; + + /* Create new fcport for later login. */ + new_fcport = qla2x00_alloc_rscn_fcport(ha, + ha_locked ? GFP_ATOMIC: GFP_KERNEL); + if (new_fcport) { + DEBUG14(printk("scsi(%ld): Handle RSCN " + "-- creating RSCN fcport %p for " + "future login.\n", ha->host_no, + new_fcport)); + + new_fcport->d_id.b24 = + remote_fcport->d_id.b24; + new_fcport->iodesc_idx_sent = + IODESC_LOGIN_NEEDED; + + list_add_tail(&new_fcport->list, + &ha->rscn_fcports); + set_bit(IODESC_PROCESS_NEEDED, + &ha->dpc_flags); + } else { + DEBUG14(printk("scsi(%ld): Handle RSCN " + "-- unable to allocate RSCN fcport " + "for future login.\n", + ha->host_no)); + } + } + return (QLA_SUCCESS); + } + + /* Send ADISC if the fcport is online */ + if (atomic_read(&remote_fcport->state) == FCS_ONLINE || + remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) { + + atomic_set(&remote_fcport->state, FCS_DEVICE_LOST); + + iodesc = qla2x00_alloc_iodesc(ha); + if (iodesc == NULL) { + /* Mark fcport for later adisc processing */ + DEBUG14(printk("scsi(%ld): Handle RSCN -- not " + "enough IO descriptors for Adisc, flag " + "for later processing.\n", ha->host_no)); + + remote_fcport->iodesc_idx_sent = + IODESC_ADISC_NEEDED; + set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags); + + return (QLA_SUCCESS); + } + + iodesc->cb_idx = ADISC_PORT_IOCB_CB; + iodesc->d_id.b24 = rscn_pid.b24; + iodesc->remote_fcport = remote_fcport; + remote_fcport->iodesc_idx_sent = iodesc->idx; + qla2x00_send_adisc_iocb(ha, iodesc, ha_locked); + + return (QLA_SUCCESS); + } else if (remote_fcport->iodesc_idx_sent < + MAX_IO_DESCRIPTORS && + ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx == + ADISC_PORT_IOCB_CB) { + /* + * Receiving another RSCN while an ADISC is pending, + * abort the IOCB. Use the same descriptor for the + * abort. + */ + uint32_t handle_to_abort; + + iodesc = &ha->io_descriptors[ + remote_fcport->iodesc_idx_sent]; + qla2x00_remove_iodesc_timer(iodesc); + handle_to_abort = iodesc->signature; + iodesc->signature = qla2x00_iodesc_to_handle(iodesc); + iodesc->cb_idx = ABORT_IOCB_CB; + iodesc->d_id.b24 = remote_fcport->d_id.b24; + iodesc->remote_fcport = remote_fcport; + remote_fcport->iodesc_idx_sent = iodesc->idx; + + DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing " + "abort to outstanding Adisc [%x/%02x%02x%02x].\n", + ha->host_no, remote_fcport->loop_id, + iodesc->d_id.b.domain, iodesc->d_id.b.area, + iodesc->d_id.b.al_pa)); + + qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort, + ha_locked); + } + } + + /* We need to login to the remote port, find it. */ + if (known_fcport) { + remote_fcport = known_fcport; + } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID && + rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS && + ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx == + LOGIN_PORT_IOCB_CB) { + /* + * Ignore duplicate RSCN on fcport which has already + * initiated a login IOCB. + */ + DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login " + "already sent to [%02x%02x%02x].\n", ha->host_no, + rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area, + rscn_fcport->d_id.b.al_pa)); + + return (QLA_SUCCESS); + } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID && + rscn_fcport != remote_fcport) { + /* Reuse same rscn fcport. */ + DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport " + "[%02x%02x%02x].\n", ha->host_no, + rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area, + rscn_fcport->d_id.b.al_pa)); + + remote_fcport = rscn_fcport; + } else { + /* Create new fcport for later login. */ + remote_fcport = qla2x00_alloc_rscn_fcport(ha, + ha_locked ? GFP_ATOMIC: GFP_KERNEL); + list_add_tail(&remote_fcport->list, &ha->rscn_fcports); + } + if (remote_fcport == NULL) + return (QLA_SUCCESS); + + /* Prepare fcport for login. */ + atomic_set(&remote_fcport->state, FCS_DEVICE_LOST); + remote_fcport->login_retry = 3; /* ha->login_retry_count; */ + remote_fcport->d_id.b24 = rscn_pid.b24; + + iodesc = qla2x00_alloc_iodesc(ha); + if (iodesc == NULL) { + /* Mark fcport for later adisc processing. */ + DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO " + "descriptors for Login, flag for later processing.\n", + ha->host_no)); + + remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED; + set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags); + + return (QLA_SUCCESS); + } + + if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) { + remote_fcport->loop_id = ha->min_external_loopid; + + rval = qla2x00_find_new_loop_id(ha, remote_fcport); + if (rval == QLA_FUNCTION_FAILED) { + /* No more loop ids, failed. */ + DEBUG14(printk("scsi(%ld): Handle RSCN -- no available " + "loop id to perform Login, failed.\n", + ha->host_no)); + + return (rval); + } + } + + iodesc->cb_idx = LOGIN_PORT_IOCB_CB; + iodesc->d_id.b24 = rscn_pid.b24; + iodesc->remote_fcport = remote_fcport; + remote_fcport->iodesc_idx_sent = iodesc->idx; + + DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to " + "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id, + iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa)); + + qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked); + + return (QLA_SUCCESS); +} + +/** + * qla2x00_process_iodesc() - Complete IO descriptor processing. + * @ha: HA context + * @mbxstat: Mailbox IOCB status + */ +void +qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat) +{ + int rval; + uint32_t signature; + fc_port_t *fcport; + struct io_descriptor *iodesc; + + signature = mbxstat->handle; + + DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n", + ha->host_no, signature)); + + /* Retrieve proper IO descriptor. */ + iodesc = qla2x00_handle_to_iodesc(ha, signature); + if (iodesc == NULL) { + DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, " + "incorrect signature %08x.\n", ha->host_no, signature)); + + return; + } + + /* Stop IO descriptor timer. */ + qla2x00_remove_iodesc_timer(iodesc); + + /* Verify signature match. */ + if (iodesc->signature != signature) { + DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, " + "signature mismatch, sent %08x, received %08x.\n", + ha->host_no, iodesc->signature, signature)); + + return; + } + + /* Go with IOCB callback. */ + rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat); + if (rval != QLA_SUCCESS) { + /* IO descriptor reused by callback. */ + return; + } + + qla2x00_free_iodesc(iodesc); + + if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) { + /* Scan our fcports list for any RSCN requests. */ + list_for_each_entry(fcport, &ha->fcports, list) { + if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED || + fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) { + qla2x00_handle_port_rscn(ha, 0, fcport, 1); + return; + } + } + + /* Scan our RSCN fcports list for any RSCN requests. */ + list_for_each_entry(fcport, &ha->rscn_fcports, list) { + if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED || + fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) { + qla2x00_handle_port_rscn(ha, 0, fcport, 1); + return; + } + } + } + clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags); +} + +/** + * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors. + * @ha: HA context + * + * This routine will also delete any RSCN entries related to the outstanding + * IO descriptors. + */ +void +qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha) +{ + fc_port_t *fcport, *fcptemp; + + clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags); + + /* Abort all IO descriptors. */ + qla2x00_init_io_descriptors(ha); + + /* Reset all pending IO descriptors in fcports list. */ + list_for_each_entry(fcport, &ha->fcports, list) { + fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; + } + + /* Reset all pending IO descriptors in rscn fcports list. */ + list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) { + DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport " + "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport, + fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa)); + + list_del(&fcport->list); + kfree(fcport); + } +} diff --git a/trunk/drivers/scsi/qla2xxx/qla_settings.h b/trunk/drivers/scsi/qla2xxx/qla_settings.h index 249e4d90fdc5..363205c0e84f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_settings.h +++ b/trunk/drivers/scsi/qla2xxx/qla_settings.h @@ -16,6 +16,7 @@ /* Max time to wait for the loop to be in LOOP_READY state */ #define MAX_LOOP_TIMEOUT (60 * 5) +#define EH_ACTIVE 1 /* Error handler active */ /* * Some vendor subsystems do not recover properly after a device reset. Define diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index c71dbd5bd543..8b0121dceb01 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -97,7 +97,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data) { int count; uint16_t word; - uint32_t nv_cmd, wait_cnt; + uint32_t nv_cmd; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; qla2x00_nv_write(ha, NVR_DATA_OUT); @@ -127,13 +127,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data) /* Wait for NVRAM to become ready */ WRT_REG_WORD(®->nvram, NVR_SELECT); RD_REG_WORD(®->nvram); /* PCI Posting. */ - wait_cnt = NVR_WAIT_CNT; do { - if (!--wait_cnt) { - DEBUG9_10(printk("%s(%ld): NVRAM didn't go ready...\n", - __func__, ha->host_no)); - break; - } NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); } while ((word & NVR_DATA_IN) == 0); @@ -307,17 +301,16 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha) { int ret, stat; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; - uint32_t word, wait_cnt; + uint32_t word; uint16_t wprot, wprot_old; /* Clear NVRAM write protection. */ ret = QLA_FUNCTION_FAILED; - - wprot_old = cpu_to_le16(qla2x00_get_nvram_word(ha, ha->nvram_base)); - stat = qla2x00_write_nvram_word_tmo(ha, ha->nvram_base, + wprot_old = cpu_to_le16(qla2x00_get_nvram_word(ha, 0)); + stat = qla2x00_write_nvram_word_tmo(ha, 0, __constant_cpu_to_le16(0x1234), 100000); - wprot = cpu_to_le16(qla2x00_get_nvram_word(ha, ha->nvram_base)); - if (stat != QLA_SUCCESS || wprot != 0x1234) { + wprot = cpu_to_le16(qla2x00_get_nvram_word(ha, 0)); + if (stat != QLA_SUCCESS || wprot != __constant_cpu_to_le16(0x1234)) { /* Write enable. */ qla2x00_nv_write(ha, NVR_DATA_OUT); qla2x00_nv_write(ha, 0); @@ -348,22 +341,14 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha) /* Wait for NVRAM to become ready. */ WRT_REG_WORD(®->nvram, NVR_SELECT); RD_REG_WORD(®->nvram); /* PCI Posting. */ - wait_cnt = NVR_WAIT_CNT; do { - if (!--wait_cnt) { - DEBUG9_10(printk("%s(%ld): NVRAM didn't go " - "ready...\n", __func__, - ha->host_no)); - break; - } NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); } while ((word & NVR_DATA_IN) == 0); - if (wait_cnt) - ret = QLA_SUCCESS; + ret = QLA_SUCCESS; } else - qla2x00_write_nvram_word(ha, ha->nvram_base, wprot_old); + qla2x00_write_nvram_word(ha, 0, wprot_old); return ret; } @@ -372,7 +357,7 @@ static void qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat) { struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; - uint32_t word, wait_cnt; + uint32_t word; if (stat != QLA_SUCCESS) return; @@ -408,13 +393,7 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat) /* Wait for NVRAM to become ready. */ WRT_REG_WORD(®->nvram, NVR_SELECT); RD_REG_WORD(®->nvram); /* PCI Posting. */ - wait_cnt = NVR_WAIT_CNT; do { - if (!--wait_cnt) { - DEBUG9_10(printk("%s(%ld): NVRAM didn't go ready...\n", - __func__, ha->host_no)); - break; - } NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); } while ((word & NVR_DATA_IN) == 0); @@ -521,20 +500,6 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, ids = qla24xx_read_flash_dword(ha, flash_data_to_access_addr(0xd03ab)); *man_id = LSB(ids); *flash_id = MSB(ids); - - /* Check if man_id and flash_id are valid. */ - if (ids != 0xDEADDEAD && (*man_id == 0 || *flash_id == 0)) { - /* Read information using 0x9f opcode - * Device ID, Mfg ID would be read in the format: - * - * Example: ATMEL 0x00 01 45 1F - * Extract MFG and Dev ID from last two bytes. - */ - ids = qla24xx_read_flash_dword(ha, - flash_data_to_access_addr(0xd009f)); - *man_id = LSB(ids); - *flash_id = MSB(ids); - } } int @@ -543,8 +508,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, { int ret; uint32_t liter; - uint32_t sec_mask, rest_addr, conf_addr, sec_end_mask; - uint32_t fdata, findex ; + uint32_t sec_mask, rest_addr, conf_addr; + uint32_t fdata; uint8_t man_id, flash_id; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; @@ -554,7 +519,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, ha->host_no, man_id, flash_id)); - sec_end_mask = 0; conf_addr = flash_conf_to_access_addr(0x03d8); switch (man_id) { case 0xbf: /* STT flash. */ @@ -567,12 +531,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, rest_addr = 0x3fff; sec_mask = 0x3c000; break; - case 0x1f: // Atmel 26DF081A - rest_addr = 0x0fff; - sec_mask = 0xff000; - sec_end_mask = 0x003ff; - conf_addr = flash_conf_to_access_addr(0x0320); - break; default: /* Default to 64 kb sector size. */ rest_addr = 0x3fff; @@ -587,30 +545,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, /* Disable flash write-protection. */ qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); - /* Some flash parts need an additional zero-write to clear bits.*/ - qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); do { /* Loop once to provide quick error exit. */ for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { - if (man_id == 0x1f) { - findex = faddr << 2; - fdata = findex & sec_mask; - } else { - findex = faddr; - fdata = (findex & sec_mask) << 2; - } - /* Are we at the beginning of a sector? */ - if ((findex & rest_addr) == 0) { - /* - * Do sector unprotect at 4K boundry for Atmel - * part. - */ - if (man_id == 0x1f) - qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0339), - (fdata & 0xff00) | ((fdata << 16) & - 0xff0000) | ((fdata >> 16) & 0xff)); + if ((faddr & rest_addr) == 0) { fdata = (faddr & sec_mask) << 2; ret = qla24xx_write_flash_dword(ha, conf_addr, (fdata & 0xff00) |((fdata << 16) & @@ -631,14 +570,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, ha->host_no, faddr, *dwptr)); break; } - - /* Do sector protect at 4K boundry for Atmel part. */ - if (man_id == 0x1f && - ((faddr & sec_end_mask) == 0x3ff)) - qla24xx_write_flash_dword(ha, - flash_conf_to_access_addr(0x0336), - (fdata & 0xff00) | ((fdata << 16) & - 0xff0000) | ((fdata >> 16) & 0xff)); } } while (0); diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 6b315521bd89..d537192a1edb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.05-k2" +#define QLA2XXX_VERSION "8.01.04-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 -#define QLA_DRIVER_PATCH_VER 5 +#define QLA_DRIVER_PATCH_VER 4 #define QLA_DRIVER_BETA_VER 0 diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 329ead263714..7c27ecc6fb5d 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1,6 +1,6 @@ /* qlogicpti.c: Performance Technologies QlogicISP sbus card driver. * - * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) * * A lot of this driver was directly stolen from Erik H. Moe's PCI * Qlogic ISP driver. Mucho kudos to him for this code. @@ -43,9 +43,12 @@ #include #include #include +#include #include #include + + #define MAX_TARGETS 16 #define MAX_LUNS 8 /* 32 for 1.31 F/W */ @@ -55,6 +58,7 @@ static struct qlogicpti *qptichain = NULL; static DEFINE_SPINLOCK(qptichain_lock); +static int qptis_running = 0; #define PACKB(a, b) (((a)<<4)|(b)) @@ -128,7 +132,7 @@ static const u_char mbox_param[] = { PACKB(0, 0) /* 0x0042 */ }; -#define MAX_MBOX_COMMAND ARRAY_SIZE(mbox_param) +#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short)) /* queue length's _must_ be power of two: */ #define QUEUE_DEPTH(in, out, ql) ((in - out) & (ql)) @@ -812,6 +816,173 @@ static int __init qpti_map_queues(struct qlogicpti *qpti) return 0; } +/* Detect all PTI Qlogic ISP's in the machine. */ +static int __init qlogicpti_detect(struct scsi_host_template *tpnt) +{ + struct qlogicpti *qpti; + struct Scsi_Host *qpti_host; + struct sbus_bus *sbus; + struct sbus_dev *sdev; + int nqptis = 0, nqptis_in_use = 0; + + tpnt->proc_name = "qlogicpti"; + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + /* Is this a red snapper? */ + if (strcmp(sdev->prom_name, "ptisp") && + strcmp(sdev->prom_name, "PTI,ptisp") && + strcmp(sdev->prom_name, "QLGC,isp") && + strcmp(sdev->prom_name, "SUNW,isp")) + continue; + + /* Sometimes Antares cards come up not completely + * setup, and we get a report of a zero IRQ. + * Skip over them in such cases so we survive. + */ + if (sdev->irqs[0] == 0) { + printk("qpti%d: Adapter reports no interrupt, " + "skipping over this card.", nqptis); + continue; + } + + /* Yep, register and allocate software state. */ + qpti_host = scsi_register(tpnt, sizeof(struct qlogicpti)); + if (!qpti_host) { + printk("QPTI: Cannot register PTI Qlogic ISP SCSI host"); + continue; + } + qpti = (struct qlogicpti *) qpti_host->hostdata; + + /* We are wide capable, 16 targets. */ + qpti_host->max_id = MAX_TARGETS; + + /* Setup back pointers and misc. state. */ + qpti->qhost = qpti_host; + qpti->sdev = sdev; + qpti->qpti_id = nqptis++; + qpti->prom_node = sdev->prom_node; + prom_getstring(qpti->prom_node, "name", + qpti->prom_name, + sizeof(qpti->prom_name)); + + /* This is not correct, actually. There's a switch + * on the PTI cards that put them into "emulation" + * mode- i.e., report themselves as QLGC,isp + * instead of PTI,ptisp. The only real substantive + * difference between non-pti and pti cards is + * the tmon register. Which is possibly even + * there for Qlogic cards, but non-functional. + */ + qpti->is_pti = (strcmp (qpti->prom_name, "QLGC,isp") != 0); + + qpti_chain_add(qpti); + if (qpti_map_regs(qpti) < 0) + goto fail_unlink; + + if (qpti_register_irq(qpti) < 0) + goto fail_unmap_regs; + + qpti_get_scsi_id(qpti); + qpti_get_bursts(qpti); + qpti_get_clock(qpti); + + /* Clear out scsi_cmnd array. */ + memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots)); + + if (qpti_map_queues(qpti) < 0) + goto fail_free_irq; + + /* Load the firmware. */ + if (qlogicpti_load_firmware(qpti)) + goto fail_unmap_queues; + if (qpti->is_pti) { + /* Check the PTI status reg. */ + if (qlogicpti_verify_tmon(qpti)) + goto fail_unmap_queues; + } + + /* Reset the ISP and init res/req queues. */ + if (qlogicpti_reset_hardware(qpti_host)) + goto fail_unmap_queues; + + printk("(Firmware v%d.%d.%d)", qpti->fware_majrev, + qpti->fware_minrev, qpti->fware_micrev); + { + char buffer[60]; + + prom_getstring (qpti->prom_node, + "isp-fcode", buffer, 60); + if (buffer[0]) + printk("(Firmware %s)", buffer); + if (prom_getbool(qpti->prom_node, "differential")) + qpti->differential = 1; + } + + printk (" [%s Wide, using %s interface]\n", + (qpti->ultra ? "Ultra" : "Fast"), + (qpti->differential ? "differential" : "single ended")); + + nqptis_in_use++; + continue; + + fail_unmap_queues: +#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) + sbus_free_consistent(qpti->sdev, + QSIZE(RES_QUEUE_LEN), + qpti->res_cpu, qpti->res_dvma); + sbus_free_consistent(qpti->sdev, + QSIZE(QLOGICPTI_REQ_QUEUE_LEN), + qpti->req_cpu, qpti->req_dvma); +#undef QSIZE + fail_free_irq: + free_irq(qpti->irq, qpti); + + fail_unmap_regs: + sbus_iounmap(qpti->qregs, + qpti->sdev->reg_addrs[0].reg_size); + if (qpti->is_pti) + sbus_iounmap(qpti->sreg, sizeof(unsigned char)); + fail_unlink: + qpti_chain_del(qpti); + scsi_unregister(qpti->qhost); + } + } + if (nqptis) + printk("QPTI: Total of %d PTI Qlogic/ISP hosts found, %d actually in use.\n", + nqptis, nqptis_in_use); + qptis_running = nqptis_in_use; + return nqptis; +} + +static int qlogicpti_release(struct Scsi_Host *host) +{ + struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; + + /* Remove visibility from IRQ handlers. */ + qpti_chain_del(qpti); + + /* Shut up the card. */ + sbus_writew(0, qpti->qregs + SBUS_CTRL); + + /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */ + free_irq(qpti->irq, qpti); + +#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) + sbus_free_consistent(qpti->sdev, + QSIZE(RES_QUEUE_LEN), + qpti->res_cpu, qpti->res_dvma); + sbus_free_consistent(qpti->sdev, + QSIZE(QLOGICPTI_REQ_QUEUE_LEN), + qpti->req_cpu, qpti->req_dvma); +#undef QSIZE + + sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size); + if (qpti->is_pti) + sbus_iounmap(qpti->sreg, sizeof(unsigned char)); + + return 0; +} + const char *qlogicpti_info(struct Scsi_Host *host) { static char buf[80]; @@ -1381,9 +1552,9 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd) return return_status; } -static struct scsi_host_template qpti_template = { - .module = THIS_MODULE, - .name = "qlogicpti", +static struct scsi_host_template driver_template = { + .detect = qlogicpti_detect, + .release = qlogicpti_release, .info = qlogicpti_info, .queuecommand = qlogicpti_queuecommand_slow, .eh_abort_handler = qlogicpti_abort, @@ -1395,189 +1566,8 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match) -{ - static int nqptis; - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - struct device_node *dp = dev->node; - struct scsi_host_template *tpnt = match->data; - struct Scsi_Host *host; - struct qlogicpti *qpti; - char *fcode; - - /* Sometimes Antares cards come up not completely - * setup, and we get a report of a zero IRQ. - */ - if (sdev->irqs[0] == 0) - return -ENODEV; - - host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); - if (!host) - return -ENOMEM; - - qpti = (struct qlogicpti *) host->hostdata; - - host->max_id = MAX_TARGETS; - qpti->qhost = host; - qpti->sdev = sdev; - qpti->qpti_id = nqptis; - qpti->prom_node = sdev->prom_node; - strcpy(qpti->prom_name, sdev->ofdev.node->name); - qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp"); - - if (qpti_map_regs(qpti) < 0) - goto fail_unlink; - - if (qpti_register_irq(qpti) < 0) - goto fail_unmap_regs; - - qpti_get_scsi_id(qpti); - qpti_get_bursts(qpti); - qpti_get_clock(qpti); - - /* Clear out scsi_cmnd array. */ - memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots)); - - if (qpti_map_queues(qpti) < 0) - goto fail_free_irq; - - /* Load the firmware. */ - if (qlogicpti_load_firmware(qpti)) - goto fail_unmap_queues; - if (qpti->is_pti) { - /* Check the PTI status reg. */ - if (qlogicpti_verify_tmon(qpti)) - goto fail_unmap_queues; - } - - /* Reset the ISP and init res/req queues. */ - if (qlogicpti_reset_hardware(host)) - goto fail_unmap_queues; - - if (scsi_add_host(host, &dev->dev)) - goto fail_unmap_queues; - - printk("(Firmware v%d.%d.%d)", qpti->fware_majrev, - qpti->fware_minrev, qpti->fware_micrev); - - fcode = of_get_property(dp, "isp-fcode", NULL); - if (fcode && fcode[0]) - printk("(Firmware %s)", fcode); - if (of_find_property(dp, "differential", NULL) != NULL) - qpti->differential = 1; - - printk (" [%s Wide, using %s interface]\n", - (qpti->ultra ? "Ultra" : "Fast"), - (qpti->differential ? "differential" : "single ended")); - - dev_set_drvdata(&sdev->ofdev.dev, qpti); - - qpti_chain_add(qpti); - - scsi_scan_host(host); - nqptis++; - - return 0; - -fail_unmap_queues: -#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistent(qpti->sdev, - QSIZE(RES_QUEUE_LEN), - qpti->res_cpu, qpti->res_dvma); - sbus_free_consistent(qpti->sdev, - QSIZE(QLOGICPTI_REQ_QUEUE_LEN), - qpti->req_cpu, qpti->req_dvma); -#undef QSIZE - -fail_unmap_regs: - sbus_iounmap(qpti->qregs, - qpti->sdev->reg_addrs[0].reg_size); - if (qpti->is_pti) - sbus_iounmap(qpti->sreg, sizeof(unsigned char)); - -fail_free_irq: - free_irq(qpti->irq, qpti); - -fail_unlink: - scsi_host_put(host); - - return -ENODEV; -} - -static int __devexit qpti_sbus_remove(struct of_device *dev) -{ - struct qlogicpti *qpti = dev_get_drvdata(&dev->dev); - - qpti_chain_del(qpti); - - scsi_remove_host(qpti->qhost); - - /* Shut up the card. */ - sbus_writew(0, qpti->qregs + SBUS_CTRL); - - /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */ - free_irq(qpti->irq, qpti); - -#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - sbus_free_consistent(qpti->sdev, - QSIZE(RES_QUEUE_LEN), - qpti->res_cpu, qpti->res_dvma); - sbus_free_consistent(qpti->sdev, - QSIZE(QLOGICPTI_REQ_QUEUE_LEN), - qpti->req_cpu, qpti->req_dvma); -#undef QSIZE - - sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size); - if (qpti->is_pti) - sbus_iounmap(qpti->sreg, sizeof(unsigned char)); - - scsi_host_put(qpti->qhost); - - return 0; -} - -static struct of_device_id qpti_match[] = { - { - .name = "ptisp", - .data = &qpti_template, - }, - { - .name = "PTI,ptisp", - .data = &qpti_template, - }, - { - .name = "QLGC,isp", - .data = &qpti_template, - }, - { - .name = "SUNW,isp", - .data = &qpti_template, - }, - {}, -}; -MODULE_DEVICE_TABLE(of, qpti_match); - -static struct of_platform_driver qpti_sbus_driver = { - .name = "qpti", - .match_table = qpti_match, - .probe = qpti_sbus_probe, - .remove = __devexit_p(qpti_sbus_remove), -}; -static int __init qpti_init(void) -{ - return of_register_driver(&qpti_sbus_driver, &sbus_bus_type); -} - -static void __exit qpti_exit(void) -{ - of_unregister_driver(&qpti_sbus_driver); -} +#include "scsi_module.c" -MODULE_DESCRIPTION("QlogicISP SBUS driver"); -MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); MODULE_LICENSE("GPL"); -MODULE_VERSION("2.0"); -module_init(qpti_init); -module_exit(qpti_exit); diff --git a/trunk/drivers/scsi/raid_class.c b/trunk/drivers/scsi/raid_class.c index 327b33a57b0a..50c398aab557 100644 --- a/trunk/drivers/scsi/raid_class.c +++ b/trunk/drivers/scsi/raid_class.c @@ -131,7 +131,7 @@ static const char *raid_state_name(enum raid_state state) int i; char *name = NULL; - for (i = 0; i < ARRAY_SIZE(raid_states); i++) { + for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) { if (raid_states[i].value == state) { name = raid_states[i].name; break; @@ -161,7 +161,7 @@ static const char *raid_level_name(enum raid_level level) int i; char *name = NULL; - for (i = 0; i < ARRAY_SIZE(raid_levels); i++) { + for (i = 0; i < sizeof(raid_levels)/sizeof(raid_levels[0]); i++) { if (raid_levels[i].value == level) { name = raid_levels[i].name; break; diff --git a/trunk/drivers/scsi/sata_mv.c b/trunk/drivers/scsi/sata_mv.c index 4a71578df3c1..f16f92a6ec0f 100644 --- a/trunk/drivers/scsi/sata_mv.c +++ b/trunk/drivers/scsi/sata_mv.c @@ -93,7 +93,7 @@ enum { MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | - ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING), + ATA_FLAG_NO_ATAPI), MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, CRQB_FLAG_READ = (1 << 0), @@ -272,33 +272,33 @@ enum chip_type { /* Command ReQuest Block: 32B */ struct mv_crqb { - __le32 sg_addr; - __le32 sg_addr_hi; - __le16 ctrl_flags; - __le16 ata_cmd[11]; + u32 sg_addr; + u32 sg_addr_hi; + u16 ctrl_flags; + u16 ata_cmd[11]; }; struct mv_crqb_iie { - __le32 addr; - __le32 addr_hi; - __le32 flags; - __le32 len; - __le32 ata_cmd[4]; + u32 addr; + u32 addr_hi; + u32 flags; + u32 len; + u32 ata_cmd[4]; }; /* Command ResPonse Block: 8B */ struct mv_crpb { - __le16 id; - __le16 flags; - __le32 tmstmp; + u16 id; + u16 flags; + u32 tmstmp; }; /* EDMA Physical Region Descriptor (ePRD); A.K.A. SG */ struct mv_sg { - __le32 addr; - __le32 flags_size; - __le32 addr_hi; - __le32 reserved; + u32 addr; + u32 flags_size; + u32 addr_hi; + u32 reserved; }; struct mv_port_priv { @@ -390,7 +390,6 @@ static struct scsi_host_template mv_sht = { .proc_name = DRV_NAME, .dma_boundary = MV_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -407,7 +406,6 @@ static const struct ata_port_operations mv5_ops = { .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = mv_eng_timeout, @@ -435,7 +433,6 @@ static const struct ata_port_operations mv6_ops = { .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = mv_eng_timeout, @@ -686,7 +683,7 @@ static void mv_stop_dma(struct ata_port *ap) } if (EDMA_EN & reg) { - ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); + printk(KERN_ERR "ata%u: Unable to stop eDMA\n", ap->id); /* FIXME: Consider doing a reset here to recover */ } } @@ -1031,7 +1028,7 @@ static inline unsigned mv_inc_q_index(unsigned index) return (index + 1) & MV_MAX_Q_DEPTH_MASK; } -static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) +static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last) { u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS | (last ? CRQB_CMD_LAST : 0); @@ -1054,7 +1051,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct mv_port_priv *pp = ap->private_data; - __le16 *cw; + u16 *cw; struct ata_taskfile *tf; u16 flags = 0; unsigned in_index; @@ -1310,8 +1307,8 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); if (EDMA_ERR_SERR & edma_err_cause) { - sata_scr_read(ap, SCR_ERROR, &serr); - sata_scr_write_flush(ap, SCR_ERROR, serr); + serr = scr_read(ap, SCR_ERROR); + scr_write_flush(ap, SCR_ERROR, serr); } if (EDMA_ERR_SELF_DIS & edma_err_cause) { struct mv_port_priv *pp = ap->private_data; @@ -1380,7 +1377,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, /* Note that DEV_IRQ might happen spuriously during EDMA, * and should be ignored in such cases. * The cause of this is still under investigation. - */ + */ if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { /* EDMA: check for response queue interrupt */ if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { @@ -1401,7 +1398,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, } } - if (ap && (ap->flags & ATA_FLAG_DISABLED)) + if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) continue; err_mask = ac_err_mask(ata_status); @@ -1422,7 +1419,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ - if (!(qc->tf.flags & ATA_TFLAG_POLLING)) { + if (!(qc->tf.ctl & ATA_NIEN)) { qc->err_mask |= err_mask; ata_qc_complete(qc); } @@ -1952,16 +1949,15 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep) /* Issue COMRESET via SControl */ comreset_retry: - sata_scr_write_flush(ap, SCR_CONTROL, 0x301); + scr_write_flush(ap, SCR_CONTROL, 0x301); __msleep(1, can_sleep); - sata_scr_write_flush(ap, SCR_CONTROL, 0x300); + scr_write_flush(ap, SCR_CONTROL, 0x300); __msleep(20, can_sleep); timeout = jiffies + msecs_to_jiffies(200); do { - sata_scr_read(ap, SCR_STATUS, &sstatus); - sstatus &= 0x3; + sstatus = scr_read(ap, SCR_STATUS) & 0x3; if ((sstatus == 3) || (sstatus == 0)) break; @@ -1978,12 +1974,11 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep) "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); - if (ata_port_online(ap)) { + if (sata_dev_present(ap)) { ata_port_probe(ap); } else { - sata_scr_read(ap, SCR_STATUS, &sstatus); - ata_port_printk(ap, KERN_INFO, - "no device found (phy stat %08x)\n", sstatus); + printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n", + ap->id, scr_read(ap, SCR_STATUS)); ata_port_disable(ap); return; } @@ -2010,7 +2005,7 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep) tf.nsect = readb((void __iomem *) ap->ioaddr.nsect_addr); dev->class = ata_dev_classify(&tf); - if (!ata_dev_enabled(dev)) { + if (!ata_dev_present(dev)) { VPRINTK("Port disabled post-sig: No device present.\n"); ata_port_disable(ap); } @@ -2042,7 +2037,7 @@ static void mv_eng_timeout(struct ata_port *ap) struct ata_queued_cmd *qc; unsigned long flags; - ata_port_printk(ap, KERN_ERR, "Entering mv_eng_timeout\n"); + printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); DPRINTK("All regs @ start of eng_timeout\n"); mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, to_pci_dev(ap->host_set->dev)); diff --git a/trunk/drivers/scsi/sata_nv.c b/trunk/drivers/scsi/sata_nv.c index 5cc42c6054eb..9f553081b5e8 100644 --- a/trunk/drivers/scsi/sata_nv.c +++ b/trunk/drivers/scsi/sata_nv.c @@ -44,7 +44,7 @@ #include #define DRV_NAME "sata_nv" -#define DRV_VERSION "2.0" +#define DRV_VERSION "0.8" enum { NV_PORTS = 2, @@ -54,25 +54,40 @@ enum { NV_PORT0_SCR_REG_OFFSET = 0x00, NV_PORT1_SCR_REG_OFFSET = 0x40, - /* INT_STATUS/ENABLE */ NV_INT_STATUS = 0x10, - NV_INT_ENABLE = 0x11, NV_INT_STATUS_CK804 = 0x440, - NV_INT_ENABLE_CK804 = 0x441, - - /* INT_STATUS/ENABLE bits */ - NV_INT_DEV = 0x01, - NV_INT_PM = 0x02, - NV_INT_ADDED = 0x04, - NV_INT_REMOVED = 0x08, + NV_INT_STATUS_PDEV_INT = 0x01, + NV_INT_STATUS_PDEV_PM = 0x02, + NV_INT_STATUS_PDEV_ADDED = 0x04, + NV_INT_STATUS_PDEV_REMOVED = 0x08, + NV_INT_STATUS_SDEV_INT = 0x10, + NV_INT_STATUS_SDEV_PM = 0x20, + NV_INT_STATUS_SDEV_ADDED = 0x40, + NV_INT_STATUS_SDEV_REMOVED = 0x80, + NV_INT_STATUS_PDEV_HOTPLUG = (NV_INT_STATUS_PDEV_ADDED | + NV_INT_STATUS_PDEV_REMOVED), + NV_INT_STATUS_SDEV_HOTPLUG = (NV_INT_STATUS_SDEV_ADDED | + NV_INT_STATUS_SDEV_REMOVED), + NV_INT_STATUS_HOTPLUG = (NV_INT_STATUS_PDEV_HOTPLUG | + NV_INT_STATUS_SDEV_HOTPLUG), - NV_INT_PORT_SHIFT = 4, /* each port occupies 4 bits */ - - NV_INT_ALL = 0x0f, - NV_INT_MASK = NV_INT_DEV | - NV_INT_ADDED | NV_INT_REMOVED, + NV_INT_ENABLE = 0x11, + NV_INT_ENABLE_CK804 = 0x441, + NV_INT_ENABLE_PDEV_MASK = 0x01, + NV_INT_ENABLE_PDEV_PM = 0x02, + NV_INT_ENABLE_PDEV_ADDED = 0x04, + NV_INT_ENABLE_PDEV_REMOVED = 0x08, + NV_INT_ENABLE_SDEV_MASK = 0x10, + NV_INT_ENABLE_SDEV_PM = 0x20, + NV_INT_ENABLE_SDEV_ADDED = 0x40, + NV_INT_ENABLE_SDEV_REMOVED = 0x80, + NV_INT_ENABLE_PDEV_HOTPLUG = (NV_INT_ENABLE_PDEV_ADDED | + NV_INT_ENABLE_PDEV_REMOVED), + NV_INT_ENABLE_SDEV_HOTPLUG = (NV_INT_ENABLE_SDEV_ADDED | + NV_INT_ENABLE_SDEV_REMOVED), + NV_INT_ENABLE_HOTPLUG = (NV_INT_ENABLE_PDEV_HOTPLUG | + NV_INT_ENABLE_SDEV_HOTPLUG), - /* INT_CONFIG */ NV_INT_CONFIG = 0x12, NV_INT_CONFIG_METHD = 0x01, // 0 = INT, 1 = SMI @@ -82,27 +97,23 @@ enum { }; static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static void nv_ck804_host_stop(struct ata_host_set *host_set); -static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, - struct pt_regs *regs); -static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance, - struct pt_regs *regs); -static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance, - struct pt_regs *regs); +static irqreturn_t nv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs); static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); - -static void nv_nf2_freeze(struct ata_port *ap); -static void nv_nf2_thaw(struct ata_port *ap); -static void nv_ck804_freeze(struct ata_port *ap); -static void nv_ck804_thaw(struct ata_port *ap); -static void nv_error_handler(struct ata_port *ap); +static void nv_host_stop (struct ata_host_set *host_set); +static void nv_enable_hotplug(struct ata_probe_ent *probe_ent); +static void nv_disable_hotplug(struct ata_host_set *host_set); +static int nv_check_hotplug(struct ata_host_set *host_set); +static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent); +static void nv_disable_hotplug_ck804(struct ata_host_set *host_set); +static int nv_check_hotplug_ck804(struct ata_host_set *host_set); enum nv_host_type { GENERIC, NFORCE2, - NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ + NFORCE3, CK804 }; @@ -129,16 +140,6 @@ static const struct pci_device_id nv_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, - { PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC }, { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, @@ -148,6 +149,46 @@ static const struct pci_device_id nv_pci_tbl[] = { { 0, } /* terminate list */ }; +struct nv_host_desc +{ + enum nv_host_type host_type; + void (*enable_hotplug)(struct ata_probe_ent *probe_ent); + void (*disable_hotplug)(struct ata_host_set *host_set); + int (*check_hotplug)(struct ata_host_set *host_set); + +}; +static struct nv_host_desc nv_device_tbl[] = { + { + .host_type = GENERIC, + .enable_hotplug = NULL, + .disable_hotplug= NULL, + .check_hotplug = NULL, + }, + { + .host_type = NFORCE2, + .enable_hotplug = nv_enable_hotplug, + .disable_hotplug= nv_disable_hotplug, + .check_hotplug = nv_check_hotplug, + }, + { + .host_type = NFORCE3, + .enable_hotplug = nv_enable_hotplug, + .disable_hotplug= nv_disable_hotplug, + .check_hotplug = nv_check_hotplug, + }, + { .host_type = CK804, + .enable_hotplug = nv_enable_hotplug_ck804, + .disable_hotplug= nv_disable_hotplug_ck804, + .check_hotplug = nv_check_hotplug_ck804, + }, +}; + +struct nv_host +{ + struct nv_host_desc *host_desc; + unsigned long host_flags; +}; + static struct pci_driver nv_pci_driver = { .name = DRV_NAME, .id_table = nv_pci_tbl, @@ -169,119 +210,51 @@ static struct scsi_host_template nv_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; -static const struct ata_port_operations nv_generic_ops = { - .port_disable = ata_port_disable, - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .exec_command = ata_exec_command, - .check_status = ata_check_status, - .dev_select = ata_std_dev_select, - .bmdma_setup = ata_bmdma_setup, - .bmdma_start = ata_bmdma_start, - .bmdma_stop = ata_bmdma_stop, - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = nv_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, - .data_xfer = ata_pio_data_xfer, - .irq_handler = nv_generic_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .scr_read = nv_scr_read, - .scr_write = nv_scr_write, - .port_start = ata_port_start, - .port_stop = ata_port_stop, - .host_stop = ata_pci_host_stop, -}; - -static const struct ata_port_operations nv_nf2_ops = { +static const struct ata_port_operations nv_ops = { .port_disable = ata_port_disable, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .exec_command = ata_exec_command, .check_status = ata_check_status, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .freeze = nv_nf2_freeze, - .thaw = nv_nf2_thaw, - .error_handler = nv_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, - .data_xfer = ata_pio_data_xfer, - .irq_handler = nv_nf2_interrupt, + .eng_timeout = ata_eng_timeout, + .irq_handler = nv_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = nv_scr_read, .scr_write = nv_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, - .host_stop = ata_pci_host_stop, + .host_stop = nv_host_stop, }; -static const struct ata_port_operations nv_ck804_ops = { - .port_disable = ata_port_disable, - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .exec_command = ata_exec_command, - .check_status = ata_check_status, - .dev_select = ata_std_dev_select, - .bmdma_setup = ata_bmdma_setup, - .bmdma_start = ata_bmdma_start, - .bmdma_stop = ata_bmdma_stop, - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .freeze = nv_ck804_freeze, - .thaw = nv_ck804_thaw, - .error_handler = nv_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, - .data_xfer = ata_pio_data_xfer, - .irq_handler = nv_ck804_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .scr_read = nv_scr_read, - .scr_write = nv_scr_write, - .port_start = ata_port_start, - .port_stop = ata_port_stop, - .host_stop = nv_ck804_host_stop, -}; - -static struct ata_port_info nv_port_info[] = { - /* generic */ - { - .sht = &nv_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, - .pio_mask = NV_PIO_MASK, - .mwdma_mask = NV_MWDMA_MASK, - .udma_mask = NV_UDMA_MASK, - .port_ops = &nv_generic_ops, - }, - /* nforce2/3 */ - { - .sht = &nv_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, - .pio_mask = NV_PIO_MASK, - .mwdma_mask = NV_MWDMA_MASK, - .udma_mask = NV_UDMA_MASK, - .port_ops = &nv_nf2_ops, - }, - /* ck804 */ - { - .sht = &nv_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, - .pio_mask = NV_PIO_MASK, - .mwdma_mask = NV_MWDMA_MASK, - .udma_mask = NV_UDMA_MASK, - .port_ops = &nv_ck804_ops, - }, +/* FIXME: The hardware provides the necessary SATA PHY controls + * to support ATA_FLAG_SATA_RESET. However, it is currently + * necessary to disable that flag, to solve misdetection problems. + * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info. + * + * This problem really needs to be investigated further. But in the + * meantime, we avoid ATA_FLAG_SATA_RESET to get people working. + */ +static struct ata_port_info nv_port_info = { + .sht = &nv_sht, + .host_flags = ATA_FLAG_SATA | + /* ATA_FLAG_SATA_RESET | */ + ATA_FLAG_SRST | + ATA_FLAG_NO_LEGACY, + .pio_mask = NV_PIO_MASK, + .mwdma_mask = NV_MWDMA_MASK, + .udma_mask = NV_UDMA_MASK, + .port_ops = &nv_ops, }; MODULE_AUTHOR("NVIDIA"); @@ -290,10 +263,11 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, nv_pci_tbl); MODULE_VERSION(DRV_VERSION); -static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, - struct pt_regs *regs) +static irqreturn_t nv_interrupt (int irq, void *dev_instance, + struct pt_regs *regs) { struct ata_host_set *host_set = dev_instance; + struct nv_host *host = host_set->private_data; unsigned int i; unsigned int handled = 0; unsigned long flags; @@ -305,11 +279,11 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, ap = host_set->ports[i]; if (ap && - !(ap->flags & ATA_FLAG_DISABLED)) { + !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) + if (qc && (!(qc->tf.ctl & ATA_NIEN))) handled += ata_host_intr(ap, qc); else // No request pending? Clear interrupt status @@ -319,88 +293,14 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance, } - spin_unlock_irqrestore(&host_set->lock, flags); + if (host->host_desc->check_hotplug) + handled += host->host_desc->check_hotplug(host_set); - return IRQ_RETVAL(handled); -} - -static int nv_host_intr(struct ata_port *ap, u8 irq_stat) -{ - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - int handled; - - /* freeze if hotplugged */ - if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) { - ata_port_freeze(ap); - return 1; - } - - /* bail out if not our interrupt */ - if (!(irq_stat & NV_INT_DEV)) - return 0; - - /* DEV interrupt w/ no active qc? */ - if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { - ata_check_status(ap); - return 1; - } - - /* handle interrupt */ - handled = ata_host_intr(ap, qc); - if (unlikely(!handled)) { - /* spurious, clear it */ - ata_check_status(ap); - } - - return 1; -} - -static irqreturn_t nv_do_interrupt(struct ata_host_set *host_set, u8 irq_stat) -{ - int i, handled = 0; - - for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; - - if (ap && !(ap->flags & ATA_FLAG_DISABLED)) - handled += nv_host_intr(ap, irq_stat); - - irq_stat >>= NV_INT_PORT_SHIFT; - } + spin_unlock_irqrestore(&host_set->lock, flags); return IRQ_RETVAL(handled); } -static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance, - struct pt_regs *regs) -{ - struct ata_host_set *host_set = dev_instance; - u8 irq_stat; - irqreturn_t ret; - - spin_lock(&host_set->lock); - irq_stat = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS); - ret = nv_do_interrupt(host_set, irq_stat); - spin_unlock(&host_set->lock); - - return ret; -} - -static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance, - struct pt_regs *regs) -{ - struct ata_host_set *host_set = dev_instance; - u8 irq_stat; - irqreturn_t ret; - - spin_lock(&host_set->lock); - irq_stat = readb(host_set->mmio_base + NV_INT_STATUS_CK804); - ret = nv_do_interrupt(host_set, irq_stat); - spin_unlock(&host_set->lock); - - return ret; -} - static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) @@ -417,74 +317,23 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); } -static void nv_nf2_freeze(struct ata_port *ap) +static void nv_host_stop (struct ata_host_set *host_set) { - unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr; - int shift = ap->port_no * NV_INT_PORT_SHIFT; - u8 mask; + struct nv_host *host = host_set->private_data; - mask = inb(scr_addr + NV_INT_ENABLE); - mask &= ~(NV_INT_ALL << shift); - outb(mask, scr_addr + NV_INT_ENABLE); -} - -static void nv_nf2_thaw(struct ata_port *ap) -{ - unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr; - int shift = ap->port_no * NV_INT_PORT_SHIFT; - u8 mask; - - outb(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS); - - mask = inb(scr_addr + NV_INT_ENABLE); - mask |= (NV_INT_MASK << shift); - outb(mask, scr_addr + NV_INT_ENABLE); -} - -static void nv_ck804_freeze(struct ata_port *ap) -{ - void __iomem *mmio_base = ap->host_set->mmio_base; - int shift = ap->port_no * NV_INT_PORT_SHIFT; - u8 mask; - - mask = readb(mmio_base + NV_INT_ENABLE_CK804); - mask &= ~(NV_INT_ALL << shift); - writeb(mask, mmio_base + NV_INT_ENABLE_CK804); -} - -static void nv_ck804_thaw(struct ata_port *ap) -{ - void __iomem *mmio_base = ap->host_set->mmio_base; - int shift = ap->port_no * NV_INT_PORT_SHIFT; - u8 mask; + // Disable hotplug event interrupts. + if (host->host_desc->disable_hotplug) + host->host_desc->disable_hotplug(host_set); - writeb(NV_INT_ALL << shift, mmio_base + NV_INT_STATUS_CK804); + kfree(host); - mask = readb(mmio_base + NV_INT_ENABLE_CK804); - mask |= (NV_INT_MASK << shift); - writeb(mask, mmio_base + NV_INT_ENABLE_CK804); -} - -static int nv_hardreset(struct ata_port *ap, unsigned int *class) -{ - unsigned int dummy; - - /* SATA hardreset fails to retrieve proper device signature on - * some controllers. Don't classify on hardreset. For more - * info, see http://bugme.osdl.org/show_bug.cgi?id=3352 - */ - return sata_std_hardreset(ap, &dummy); -} - -static void nv_error_handler(struct ata_port *ap) -{ - ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, - nv_hardreset, ata_std_postreset); + ata_pci_host_stop(host_set); } static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version = 0; + struct nv_host *host; struct ata_port_info *ppi; struct ata_probe_ent *probe_ent; int pci_dev_busy = 0; @@ -521,15 +370,24 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) rc = -ENOMEM; - ppi = &nv_port_info[ent->driver_data]; + ppi = &nv_port_info; probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); if (!probe_ent) goto err_out_regions; + host = kmalloc(sizeof(struct nv_host), GFP_KERNEL); + if (!host) + goto err_out_free_ent; + + memset(host, 0, sizeof(struct nv_host)); + host->host_desc = &nv_device_tbl[ent->driver_data]; + + probe_ent->private_data = host; + probe_ent->mmio_base = pci_iomap(pdev, 5, 0); if (!probe_ent->mmio_base) { rc = -EIO; - goto err_out_free_ent; + goto err_out_free_host; } base = (unsigned long)probe_ent->mmio_base; @@ -537,27 +395,24 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET; probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; - /* enable SATA space for CK804 */ - if (ent->driver_data == CK804) { - u8 regval; - - pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); - regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN; - pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); - } - pci_set_master(pdev); rc = ata_device_add(probe_ent); if (rc != NV_PORTS) goto err_out_iounmap; + // Enable hotplug event interrupts. + if (host->host_desc->enable_hotplug) + host->host_desc->enable_hotplug(probe_ent); + kfree(probe_ent); return 0; err_out_iounmap: pci_iounmap(pdev, probe_ent->mmio_base); +err_out_free_host: + kfree(host); err_out_free_ent: kfree(probe_ent); err_out_regions: @@ -569,17 +424,127 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } -static void nv_ck804_host_stop(struct ata_host_set *host_set) +static void nv_enable_hotplug(struct ata_probe_ent *probe_ent) +{ + u8 intr_mask; + + outb(NV_INT_STATUS_HOTPLUG, + probe_ent->port[0].scr_addr + NV_INT_STATUS); + + intr_mask = inb(probe_ent->port[0].scr_addr + NV_INT_ENABLE); + intr_mask |= NV_INT_ENABLE_HOTPLUG; + + outb(intr_mask, probe_ent->port[0].scr_addr + NV_INT_ENABLE); +} + +static void nv_disable_hotplug(struct ata_host_set *host_set) +{ + u8 intr_mask; + + intr_mask = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE); + + intr_mask &= ~(NV_INT_ENABLE_HOTPLUG); + + outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE); +} + +static int nv_check_hotplug(struct ata_host_set *host_set) +{ + u8 intr_status; + + intr_status = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS); + + // Clear interrupt status. + outb(0xff, host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS); + + if (intr_status & NV_INT_STATUS_HOTPLUG) { + if (intr_status & NV_INT_STATUS_PDEV_ADDED) + printk(KERN_WARNING "nv_sata: " + "Primary device added\n"); + + if (intr_status & NV_INT_STATUS_PDEV_REMOVED) + printk(KERN_WARNING "nv_sata: " + "Primary device removed\n"); + + if (intr_status & NV_INT_STATUS_SDEV_ADDED) + printk(KERN_WARNING "nv_sata: " + "Secondary device added\n"); + + if (intr_status & NV_INT_STATUS_SDEV_REMOVED) + printk(KERN_WARNING "nv_sata: " + "Secondary device removed\n"); + + return 1; + } + + return 0; +} + +static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent) +{ + struct pci_dev *pdev = to_pci_dev(probe_ent->dev); + u8 intr_mask; + u8 regval; + + pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); + regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN; + pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); + + writeb(NV_INT_STATUS_HOTPLUG, probe_ent->mmio_base + NV_INT_STATUS_CK804); + + intr_mask = readb(probe_ent->mmio_base + NV_INT_ENABLE_CK804); + intr_mask |= NV_INT_ENABLE_HOTPLUG; + + writeb(intr_mask, probe_ent->mmio_base + NV_INT_ENABLE_CK804); +} + +static void nv_disable_hotplug_ck804(struct ata_host_set *host_set) { struct pci_dev *pdev = to_pci_dev(host_set->dev); + u8 intr_mask; u8 regval; - /* disable SATA space for CK804 */ + intr_mask = readb(host_set->mmio_base + NV_INT_ENABLE_CK804); + + intr_mask &= ~(NV_INT_ENABLE_HOTPLUG); + + writeb(intr_mask, host_set->mmio_base + NV_INT_ENABLE_CK804); + pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN; pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); +} - ata_pci_host_stop(host_set); +static int nv_check_hotplug_ck804(struct ata_host_set *host_set) +{ + u8 intr_status; + + intr_status = readb(host_set->mmio_base + NV_INT_STATUS_CK804); + + // Clear interrupt status. + writeb(0xff, host_set->mmio_base + NV_INT_STATUS_CK804); + + if (intr_status & NV_INT_STATUS_HOTPLUG) { + if (intr_status & NV_INT_STATUS_PDEV_ADDED) + printk(KERN_WARNING "nv_sata: " + "Primary device added\n"); + + if (intr_status & NV_INT_STATUS_PDEV_REMOVED) + printk(KERN_WARNING "nv_sata: " + "Primary device removed\n"); + + if (intr_status & NV_INT_STATUS_SDEV_ADDED) + printk(KERN_WARNING "nv_sata: " + "Secondary device added\n"); + + if (intr_status & NV_INT_STATUS_SDEV_REMOVED) + printk(KERN_WARNING "nv_sata: " + "Secondary device removed\n"); + + return 1; + } + + return 0; } static int __init nv_init(void) diff --git a/trunk/drivers/scsi/sata_promise.c b/trunk/drivers/scsi/sata_promise.c index b2b6ed5216e0..7eb67a6bdc64 100644 --- a/trunk/drivers/scsi/sata_promise.c +++ b/trunk/drivers/scsi/sata_promise.c @@ -76,8 +76,7 @@ enum { PDC_RESET = (1 << 11), /* HDMA reset */ PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | - ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | - ATA_FLAG_PIO_POLLING, + ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI, }; @@ -121,7 +120,6 @@ static struct scsi_host_template pdc_ata_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -138,7 +136,6 @@ static const struct ata_port_operations pdc_sata_ops = { .qc_prep = pdc_qc_prep, .qc_issue = pdc_qc_issue_prot, .eng_timeout = pdc_eng_timeout, - .data_xfer = ata_mmio_data_xfer, .irq_handler = pdc_interrupt, .irq_clear = pdc_irq_clear, @@ -161,7 +158,6 @@ static const struct ata_port_operations pdc_pata_ops = { .qc_prep = pdc_qc_prep, .qc_issue = pdc_qc_issue_prot, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = pdc_eng_timeout, .irq_handler = pdc_interrupt, .irq_clear = pdc_irq_clear, @@ -367,23 +363,12 @@ static void pdc_sata_phy_reset(struct ata_port *ap) sata_phy_reset(ap); } -static void pdc_pata_cbl_detect(struct ata_port *ap) -{ - u8 tmp; - void __iomem *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; - - tmp = readb(mmio); - - if (tmp & 0x01) { - ap->cbl = ATA_CBL_PATA40; - ap->udma_mask &= ATA_UDMA_MASK_40C; - } else - ap->cbl = ATA_CBL_PATA80; -} - static void pdc_pata_phy_reset(struct ata_port *ap) { - pdc_pata_cbl_detect(ap); + /* FIXME: add cable detect. Don't assume 40-pin cable */ + ap->cbl = ATA_CBL_PATA40; + ap->udma_mask &= ATA_UDMA_MASK_40C; + pdc_reset_port(ap); ata_port_probe(ap); ata_bus_reset(ap); @@ -450,7 +435,7 @@ static void pdc_eng_timeout(struct ata_port *ap) switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: - ata_port_printk(ap, KERN_ERR, "command timeout\n"); + printk(KERN_ERR "ata%u: command timeout\n", ap->id); drv_stat = ata_wait_idle(ap); qc->err_mask |= __ac_err_mask(drv_stat); break; @@ -458,9 +443,8 @@ static void pdc_eng_timeout(struct ata_port *ap) default: drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - ata_port_printk(ap, KERN_ERR, - "unknown timeout, cmd 0x%x stat 0x%x\n", - qc->tf.command, drv_stat); + printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", + ap->id, qc->tf.command, drv_stat); qc->err_mask |= ac_err_mask(drv_stat); break; @@ -549,11 +533,11 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r ap = host_set->ports[i]; tmp = mask & (1 << (i + 1)); if (tmp && ap && - !(ap->flags & ATA_FLAG_DISABLED)) { + !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) + if (qc && (!(qc->tf.ctl & ATA_NIEN))) handled += pdc_host_intr(ap, qc); } } @@ -692,6 +676,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* + * If this driver happens to only be useful on Apple's K2, then + * we should check that here as it has a normal Serverworks ID + */ rc = pci_enable_device(pdev); if (rc) return rc; diff --git a/trunk/drivers/scsi/sata_qstor.c b/trunk/drivers/scsi/sata_qstor.c index 98ddc25655f0..886f3447dd48 100644 --- a/trunk/drivers/scsi/sata_qstor.c +++ b/trunk/drivers/scsi/sata_qstor.c @@ -41,7 +41,7 @@ #include #define DRV_NAME "sata_qstor" -#define DRV_VERSION "0.06" +#define DRV_VERSION "0.05" enum { QS_PORTS = 4, @@ -142,7 +142,6 @@ static struct scsi_host_template qs_ata_sht = { .proc_name = DRV_NAME, .dma_boundary = QS_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -157,7 +156,6 @@ static const struct ata_port_operations qs_ata_ops = { .phy_reset = qs_phy_reset, .qc_prep = qs_qc_prep, .qc_issue = qs_qc_issue, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = qs_eng_timeout, .irq_handler = qs_intr, .irq_clear = qs_irq_clear, @@ -177,7 +175,7 @@ static const struct ata_port_info qs_port_info[] = { .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | //FIXME ATA_FLAG_SRST | - ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, + ATA_FLAG_MMIO, .pio_mask = 0x10, /* pio4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &qs_ata_ops, @@ -396,13 +394,14 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", sff1, sff0, port_no, sHST, sDST); handled = 1; - if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { + if (ap && !(ap->flags & + (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; struct qs_port_priv *pp = ap->private_data; if (!pp || pp->state != qs_state_pkt) continue; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { switch (sHST) { case 0: /* successful CPB */ case 3: /* device error */ @@ -429,13 +428,13 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) struct ata_port *ap; ap = host_set->ports[port_no]; if (ap && - !(ap->flags & ATA_FLAG_DISABLED)) { + !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; struct qs_port_priv *pp = ap->private_data; if (!pp || pp->state != qs_state_mmio) continue; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { /* check main status, clearing INTRQ */ u8 status = ata_check_status(ap); diff --git a/trunk/drivers/scsi/sata_sil.c b/trunk/drivers/scsi/sata_sil.c index 51d86d750e84..106627299d55 100644 --- a/trunk/drivers/scsi/sata_sil.c +++ b/trunk/drivers/scsi/sata_sil.c @@ -46,26 +46,23 @@ #include #define DRV_NAME "sata_sil" -#define DRV_VERSION "2.0" +#define DRV_VERSION "0.9" enum { /* * host flags */ - SIL_FLAG_NO_SATA_IRQ = (1 << 28), SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), - SIL_DFL_HOST_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_HRST_TO_RESUME, + ATA_FLAG_MMIO, /* * Controller IDs */ sil_3112 = 0, - sil_3112_no_sata_irq = 1, - sil_3512 = 2, - sil_3114 = 3, + sil_3512 = 1, + sil_3114 = 2, /* * Register offsets @@ -87,20 +84,6 @@ enum { /* BMDMA/BMDMA2 */ SIL_INTR_STEERING = (1 << 1), - SIL_DMA_ENABLE = (1 << 0), /* DMA run switch */ - SIL_DMA_RDWR = (1 << 3), /* DMA Rd-Wr */ - SIL_DMA_SATA_IRQ = (1 << 4), /* OR of all SATA IRQs */ - SIL_DMA_ACTIVE = (1 << 16), /* DMA running */ - SIL_DMA_ERROR = (1 << 17), /* PCI bus error */ - SIL_DMA_COMPLETE = (1 << 18), /* cmd complete / IRQ pending */ - SIL_DMA_N_SATA_IRQ = (1 << 6), /* SATA_IRQ for the next channel */ - SIL_DMA_N_ACTIVE = (1 << 24), /* ACTIVE for the next channel */ - SIL_DMA_N_ERROR = (1 << 25), /* ERROR for the next channel */ - SIL_DMA_N_COMPLETE = (1 << 26), /* COMPLETE for the next channel */ - - /* SIEN */ - SIL_SIEN_N = (1 << 16), /* triggered by SError.N */ - /* * Others */ @@ -113,10 +96,6 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_post_set_mode (struct ata_port *ap); -static irqreturn_t sil_interrupt(int irq, void *dev_instance, - struct pt_regs *regs); -static void sil_freeze(struct ata_port *ap); -static void sil_thaw(struct ata_port *ap); static const struct pci_device_id sil_pci_tbl[] = { @@ -125,8 +104,8 @@ static const struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, - { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, - { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, + { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { } /* terminate list */ }; @@ -176,7 +155,6 @@ static struct scsi_host_template sil_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -188,6 +166,7 @@ static const struct ata_port_operations sil_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .probe_reset = ata_std_probe_reset, .post_set_mode = sil_post_set_mode, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, @@ -195,12 +174,8 @@ static const struct ata_port_operations sil_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_mmio_data_xfer, - .freeze = sil_freeze, - .thaw = sil_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, - .irq_handler = sil_interrupt, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = sil_scr_read, .scr_write = sil_scr_write, @@ -219,16 +194,6 @@ static const struct ata_port_info sil_port_info[] = { .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, }, - /* sil_3112_no_sata_irq */ - { - .sht = &sil_sht, - .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE | - SIL_FLAG_NO_SATA_IRQ, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ - .port_ops = &sil_ops, - }, /* sil_3512 */ { .sht = &sil_sht, @@ -255,7 +220,6 @@ static const struct { unsigned long tf; /* ATA taskfile register block */ unsigned long ctl; /* ATA control/altstatus register block */ unsigned long bmdma; /* DMA register block */ - unsigned long bmdma2; /* DMA register block #2 */ unsigned long fifo_cfg; /* FIFO Valid Byte Count and Control */ unsigned long scr; /* SATA control register block */ unsigned long sien; /* SATA Interrupt Enable register */ @@ -263,10 +227,10 @@ static const struct { unsigned long sfis_cfg; /* SATA FIS reception config register */ } sil_port[] = { /* port 0 ... */ - { 0x80, 0x8A, 0x00, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c }, - { 0xC0, 0xCA, 0x08, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, - { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c }, - { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc }, + { 0x80, 0x8A, 0x00, 0x40, 0x100, 0x148, 0xb4, 0x14c }, + { 0xC0, 0xCA, 0x08, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, + { 0x280, 0x28A, 0x200, 0x240, 0x300, 0x348, 0x2b4, 0x34c }, + { 0x2C0, 0x2CA, 0x208, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc }, /* ... port 3 */ }; @@ -299,7 +263,7 @@ static void sil_post_set_mode (struct ata_port *ap) for (i = 0; i < 2; i++) { dev = &ap->device[i]; - if (!ata_dev_enabled(dev)) + if (!ata_dev_present(dev)) dev_mode[i] = 0; /* PIO0/1/2 */ else if (dev->flags & ATA_DFLAG_PIO) dev_mode[i] = 1; /* PIO3/4 */ @@ -350,156 +314,6 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) writel(val, mmio); } -static void sil_host_intr(struct ata_port *ap, u32 bmdma2) -{ - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - u8 status; - - if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) { - u32 serror; - - /* SIEN doesn't mask SATA IRQs on some 3112s. Those - * controllers continue to assert IRQ as long as - * SError bits are pending. Clear SError immediately. - */ - serror = sil_scr_read(ap, SCR_ERROR); - sil_scr_write(ap, SCR_ERROR, serror); - - /* Trigger hotplug and accumulate SError only if the - * port isn't already frozen. Otherwise, PHY events - * during hardreset makes controllers with broken SIEN - * repeat probing needlessly. - */ - if (!(ap->flags & ATA_FLAG_FROZEN)) { - ata_ehi_hotplugged(&ap->eh_info); - ap->eh_info.serror |= serror; - } - - goto freeze; - } - - if (unlikely(!qc || qc->tf.ctl & ATA_NIEN)) - goto freeze; - - /* Check whether we are expecting interrupt in this state */ - switch (ap->hsm_task_state) { - case HSM_ST_FIRST: - /* Some pre-ATAPI-4 devices assert INTRQ - * at this state when ready to receive CDB. - */ - - /* Check the ATA_DFLAG_CDB_INTR flag is enough here. - * The flag was turned on only for atapi devices. - * No need to check is_atapi_taskfile(&qc->tf) again. - */ - if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) - goto err_hsm; - break; - case HSM_ST_LAST: - if (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_DMA) { - /* clear DMA-Start bit */ - ap->ops->bmdma_stop(qc); - - if (bmdma2 & SIL_DMA_ERROR) { - qc->err_mask |= AC_ERR_HOST_BUS; - ap->hsm_task_state = HSM_ST_ERR; - } - } - break; - case HSM_ST: - break; - default: - goto err_hsm; - } - - /* check main status, clearing INTRQ */ - status = ata_chk_status(ap); - if (unlikely(status & ATA_BUSY)) - goto err_hsm; - - /* ack bmdma irq events */ - ata_bmdma_irq_clear(ap); - - /* kick HSM in the ass */ - ata_hsm_move(ap, qc, status, 0); - - return; - - err_hsm: - qc->err_mask |= AC_ERR_HSM; - freeze: - ata_port_freeze(ap); -} - -static irqreturn_t sil_interrupt(int irq, void *dev_instance, - struct pt_regs *regs) -{ - struct ata_host_set *host_set = dev_instance; - void __iomem *mmio_base = host_set->mmio_base; - int handled = 0; - int i; - - spin_lock(&host_set->lock); - - for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; - u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2); - - if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) - continue; - - /* turn off SATA_IRQ if not supported */ - if (ap->flags & SIL_FLAG_NO_SATA_IRQ) - bmdma2 &= ~SIL_DMA_SATA_IRQ; - - if (bmdma2 == 0xffffffff || - !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ))) - continue; - - sil_host_intr(ap, bmdma2); - handled = 1; - } - - spin_unlock(&host_set->lock); - - return IRQ_RETVAL(handled); -} - -static void sil_freeze(struct ata_port *ap) -{ - void __iomem *mmio_base = ap->host_set->mmio_base; - u32 tmp; - - /* global IRQ mask doesn't block SATA IRQ, turn off explicitly */ - writel(0, mmio_base + sil_port[ap->port_no].sien); - - /* plug IRQ */ - tmp = readl(mmio_base + SIL_SYSCFG); - tmp |= SIL_MASK_IDE0_INT << ap->port_no; - writel(tmp, mmio_base + SIL_SYSCFG); - readl(mmio_base + SIL_SYSCFG); /* flush */ -} - -static void sil_thaw(struct ata_port *ap) -{ - void __iomem *mmio_base = ap->host_set->mmio_base; - u32 tmp; - - /* clear IRQ */ - ata_chk_status(ap); - ata_bmdma_irq_clear(ap); - - /* turn on SATA IRQ if supported */ - if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) - writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); - - /* turn on IRQ */ - tmp = readl(mmio_base + SIL_SYSCFG); - tmp &= ~(SIL_MASK_IDE0_INT << ap->port_no); - writel(tmp, mmio_base + SIL_SYSCFG); -} - /** * sil_dev_config - Apply device/host-specific errata fixups * @ap: Port containing device to be examined @@ -546,16 +360,16 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) if (slow_down || ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE))) { - ata_dev_printk(dev, KERN_INFO, "applying Seagate errata fix " - "(mod15write workaround)\n"); + printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n", + ap->id, dev->devno); dev->max_sectors = 15; return; } /* limit to udma5 */ if (quirks & SIL_QUIRK_UDMA5MAX) { - ata_dev_printk(dev, KERN_INFO, - "applying Maxtor errata fix %s\n", model_num); + printk(KERN_INFO "ata%u(%u): applying Maxtor errata fix %s\n", + ap->id, dev->devno, model_num); dev->udma_mask &= ATA_UDMA5; return; } @@ -570,12 +384,16 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) int rc; unsigned int i; int pci_dev_busy = 0; - u32 tmp; + u32 tmp, irq_mask; u8 cls; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* + * If this driver happens to only be useful on Apple's K2, then + * we should check that here as it has a normal Serverworks ID + */ rc = pci_enable_device(pdev); if (rc) return rc; @@ -660,13 +478,31 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } if (ent->driver_data == sil_3114) { + irq_mask = SIL_MASK_4PORT; + /* flip the magic "make 4 ports work" bit */ tmp = readl(mmio_base + sil_port[2].bmdma); if ((tmp & SIL_INTR_STEERING) == 0) writel(tmp | SIL_INTR_STEERING, mmio_base + sil_port[2].bmdma); + + } else { + irq_mask = SIL_MASK_2PORT; } + /* make sure IDE0/1/2/3 interrupts are not masked */ + tmp = readl(mmio_base + SIL_SYSCFG); + if (tmp & irq_mask) { + tmp &= ~irq_mask; + writel(tmp, mmio_base + SIL_SYSCFG); + readl(mmio_base + SIL_SYSCFG); /* flush */ + } + + /* mask all SATA phy-related interrupts */ + /* TODO: unmask bit 6 (SError N bit) for hotplug */ + for (i = 0; i < probe_ent->n_ports; i++) + writel(0, mmio_base + sil_port[i].sien); + pci_set_master(pdev); /* FIXME: check ata_device_add return value */ diff --git a/trunk/drivers/scsi/sata_sil24.c b/trunk/drivers/scsi/sata_sil24.c index b5f8fa955679..cb9082fd7e2f 100644 --- a/trunk/drivers/scsi/sata_sil24.c +++ b/trunk/drivers/scsi/sata_sil24.c @@ -31,15 +31,15 @@ #include #define DRV_NAME "sata_sil24" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.23" /* * Port request block (PRB) 32 bytes */ struct sil24_prb { - __le16 ctrl; - __le16 prot; - __le32 rx_cnt; + u16 ctrl; + u16 prot; + u32 rx_cnt; u8 fis[6 * 4]; }; @@ -47,17 +47,17 @@ struct sil24_prb { * Scatter gather entry (SGE) 16 bytes */ struct sil24_sge { - __le64 addr; - __le32 cnt; - __le32 flags; + u64 addr; + u32 cnt; + u32 flags; }; /* * Port multiplier */ struct sil24_port_multiplier { - __le32 diag; - __le32 sactive; + u32 diag; + u32 sactive; }; enum { @@ -86,21 +86,12 @@ enum { /* HOST_SLOT_STAT bits */ HOST_SSTAT_ATTN = (1 << 31), - /* HOST_CTRL bits */ - HOST_CTRL_M66EN = (1 << 16), /* M66EN PCI bus signal */ - HOST_CTRL_TRDY = (1 << 17), /* latched PCI TRDY */ - HOST_CTRL_STOP = (1 << 18), /* latched PCI STOP */ - HOST_CTRL_DEVSEL = (1 << 19), /* latched PCI DEVSEL */ - HOST_CTRL_REQ64 = (1 << 20), /* latched PCI REQ64 */ - /* * Port registers * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2) */ PORT_REGS_SIZE = 0x2000, - - PORT_LRAM = 0x0000, /* 31 LRAM slots and PM regs */ - PORT_LRAM_SLOT_SZ = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */ + PORT_PRB = 0x0000, /* (32 bytes PRB + 16 bytes SGEs * 6) * 31 (3968 bytes) */ PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */ /* 32 bit regs */ @@ -151,16 +142,8 @@ enum { PORT_IRQ_PWR_CHG = (1 << 3), /* power management change */ PORT_IRQ_PHYRDY_CHG = (1 << 4), /* PHY ready change */ PORT_IRQ_COMWAKE = (1 << 5), /* COMWAKE received */ - PORT_IRQ_UNK_FIS = (1 << 6), /* unknown FIS received */ - PORT_IRQ_DEV_XCHG = (1 << 7), /* device exchanged */ - PORT_IRQ_8B10B = (1 << 8), /* 8b/10b decode error threshold */ - PORT_IRQ_CRC = (1 << 9), /* CRC error threshold */ - PORT_IRQ_HANDSHAKE = (1 << 10), /* handshake error threshold */ - PORT_IRQ_SDB_NOTIFY = (1 << 11), /* SDB notify received */ - - DEF_PORT_IRQ = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | - PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG | - PORT_IRQ_UNK_FIS, + PORT_IRQ_UNK_FIS = (1 << 6), /* Unknown FIS received */ + PORT_IRQ_SDB_FIS = (1 << 11), /* SDB FIS received */ /* bits[27:16] are unmasked (raw) */ PORT_IRQ_RAW_SHIFT = 16, @@ -191,7 +174,7 @@ enum { PORT_CERR_CMD_PCIPERR = 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */ PORT_CERR_XFR_UNDEF = 32, /* PSD ecode 00 - undefined */ PORT_CERR_XFR_TGTABRT = 33, /* PSD ecode 01 - target abort */ - PORT_CERR_XFR_MSTABRT = 34, /* PSD ecode 10 - master abort */ + PORT_CERR_XFR_MSGABRT = 34, /* PSD ecode 10 - master abort */ PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ @@ -219,19 +202,11 @@ enum { SGE_DRD = (1 << 29), /* discard data read (/dev/null) data address ignored */ - SIL24_MAX_CMDS = 31, - /* board id */ BID_SIL3124 = 0, BID_SIL3132 = 1, BID_SIL3131 = 2, - /* host flags */ - SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY, - SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ - IRQ_STAT_4PORTS = 0xf, }; @@ -251,58 +226,6 @@ union sil24_cmd_block { struct sil24_atapi_block atapi; }; -static struct sil24_cerr_info { - unsigned int err_mask, action; - const char *desc; -} sil24_cerr_db[] = { - [0] = { AC_ERR_DEV, ATA_EH_REVALIDATE, - "device error" }, - [PORT_CERR_DEV] = { AC_ERR_DEV, ATA_EH_REVALIDATE, - "device error via D2H FIS" }, - [PORT_CERR_SDB] = { AC_ERR_DEV, ATA_EH_REVALIDATE, - "device error via SDB FIS" }, - [PORT_CERR_DATA] = { AC_ERR_ATA_BUS, ATA_EH_SOFTRESET, - "error in data FIS" }, - [PORT_CERR_SEND] = { AC_ERR_ATA_BUS, ATA_EH_SOFTRESET, - "failed to transmit command FIS" }, - [PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "protocol mismatch" }, - [PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "data directon mismatch" }, - [PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "ran out of SGEs while writing" }, - [PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "ran out of SGEs while reading" }, - [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "invalid data directon for ATAPI CDB" }, - [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_SOFTRESET, - "SGT no on qword boundary" }, - [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI target abort while fetching SGT" }, - [PORT_CERR_SGT_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI master abort while fetching SGT" }, - [PORT_CERR_SGT_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI parity error while fetching SGT" }, - [PORT_CERR_CMD_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_SOFTRESET, - "PRB not on qword boundary" }, - [PORT_CERR_CMD_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI target abort while fetching PRB" }, - [PORT_CERR_CMD_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI master abort while fetching PRB" }, - [PORT_CERR_CMD_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI parity error while fetching PRB" }, - [PORT_CERR_XFR_UNDEF] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "undefined error while transferring data" }, - [PORT_CERR_XFR_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI target abort while transferring data" }, - [PORT_CERR_XFR_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI master abort while transferring data" }, - [PORT_CERR_XFR_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET, - "PCI parity error while transferring data" }, - [PORT_CERR_SENDSERVICE] = { AC_ERR_HSM, ATA_EH_SOFTRESET, - "FIS received while sending service FIS" }, -}; - /* * ap->private_data * @@ -326,14 +249,12 @@ static u8 sil24_check_status(struct ata_port *ap); static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); +static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes); static void sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static void sil24_irq_clear(struct ata_port *ap); +static void sil24_eng_timeout(struct ata_port *ap); static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static void sil24_freeze(struct ata_port *ap); -static void sil24_thaw(struct ata_port *ap); -static void sil24_error_handler(struct ata_port *ap); -static void sil24_post_internal_cmd(struct ata_queued_cmd *qc); static int sil24_port_start(struct ata_port *ap); static void sil24_port_stop(struct ata_port *ap); static void sil24_host_stop(struct ata_host_set *host_set); @@ -360,8 +281,7 @@ static struct scsi_host_template sil24_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, - .change_queue_depth = ata_scsi_change_queue_depth, - .can_queue = SIL24_MAX_CMDS, + .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, @@ -370,7 +290,6 @@ static struct scsi_host_template sil24_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -385,20 +304,19 @@ static const struct ata_port_operations sil24_ops = { .tf_read = sil24_tf_read, + .probe_reset = sil24_probe_reset, + .qc_prep = sil24_qc_prep, .qc_issue = sil24_qc_issue, + .eng_timeout = sil24_eng_timeout, + .irq_handler = sil24_interrupt, .irq_clear = sil24_irq_clear, .scr_read = sil24_scr_read, .scr_write = sil24_scr_write, - .freeze = sil24_freeze, - .thaw = sil24_thaw, - .error_handler = sil24_error_handler, - .post_internal_cmd = sil24_post_internal_cmd, - .port_start = sil24_port_start, .port_stop = sil24_port_stop, .host_stop = sil24_host_stop, @@ -415,8 +333,9 @@ static struct ata_port_info sil24_port_info[] = { /* sil_3124 */ { .sht = &sil24_sht, - .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | - SIL24_FLAG_PCIX_IRQ_WOC, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + SIL24_NPORTS2FLAG(4), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -425,7 +344,9 @@ static struct ata_port_info sil24_port_info[] = { /* sil_3132 */ { .sht = &sil24_sht, - .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + SIL24_NPORTS2FLAG(2), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -434,7 +355,9 @@ static struct ata_port_info sil24_port_info[] = { /* sil_3131/sil_3531 */ { .sht = &sil24_sht, - .host_flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + SIL24_NPORTS2FLAG(1), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -442,13 +365,6 @@ static struct ata_port_info sil24_port_info[] = { }, }; -static int sil24_tag(int tag) -{ - if (unlikely(ata_tag_internal(tag))) - return 0; - return tag; -} - static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) { void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; @@ -510,65 +426,56 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) *tf = pp->tf; } -static int sil24_init_port(struct ata_port *ap) -{ - void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - u32 tmp; - - writel(PORT_CS_INIT, port + PORT_CTRL_STAT); - ata_wait_register(port + PORT_CTRL_STAT, - PORT_CS_INIT, PORT_CS_INIT, 10, 100); - tmp = ata_wait_register(port + PORT_CTRL_STAT, - PORT_CS_RDY, 0, 10, 100); - - if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) - return -EIO; - return 0; -} - -static int sil24_softreset(struct ata_port *ap, unsigned int *class) +static int sil24_softreset(struct ata_port *ap, int verbose, + unsigned int *class) { void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; dma_addr_t paddr = pp->cmd_block_dma; - u32 mask, irq_stat; - const char *reason; + unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ; + u32 irq_enable, irq_stat; DPRINTK("ENTER\n"); - if (ata_port_offline(ap)) { + if (!sata_dev_present(ap)) { DPRINTK("PHY reports no device\n"); *class = ATA_DEV_NONE; goto out; } - /* put the port into known state */ - if (sil24_init_port(ap)) { - reason ="port not ready"; - goto err; - } + /* temporarily turn off IRQs during SRST */ + irq_enable = readl(port + PORT_IRQ_ENABLE_SET); + writel(irq_enable, port + PORT_IRQ_ENABLE_CLR); + + /* + * XXX: Not sure whether the following sleep is needed or not. + * The original driver had it. So.... + */ + msleep(10); - /* do SRST */ prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); prb->fis[1] = 0; /* no PM yet */ writel((u32)paddr, port + PORT_CMD_ACTIVATE); - writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); - mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; - irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, - 100, ATA_TMOUT_BOOT / HZ * 1000); + do { + irq_stat = readl(port + PORT_IRQ_STAT); + writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ + + irq_stat >>= PORT_IRQ_RAW_SHIFT; + if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR)) + break; - writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ - irq_stat >>= PORT_IRQ_RAW_SHIFT; + msleep(100); + } while (time_before(jiffies, timeout)); + + /* restore IRQs */ + writel(irq_enable, port + PORT_IRQ_ENABLE_SET); if (!(irq_stat & PORT_IRQ_COMPLETE)) { - if (irq_stat & PORT_IRQ_ERROR) - reason = "SRST command error"; - else - reason = "timeout"; - goto err; + DPRINTK("EXIT, srst failed\n"); + return -EIO; } sil24_update_tf(ap); @@ -580,57 +487,22 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class) out: DPRINTK("EXIT, class=%u\n", *class); return 0; - - err: - ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); - return -EIO; } -static int sil24_hardreset(struct ata_port *ap, unsigned int *class) +static int sil24_hardreset(struct ata_port *ap, int verbose, + unsigned int *class) { - void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - const char *reason; - int tout_msec, rc; - u32 tmp; + unsigned int dummy_class; - /* sil24 does the right thing(tm) without any protection */ - sata_set_spd(ap); - - tout_msec = 100; - if (ata_port_online(ap)) - tout_msec = 5000; - - writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT); - tmp = ata_wait_register(port + PORT_CTRL_STAT, - PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec); - - /* SStatus oscillates between zero and valid status after - * DEV_RST, debounce it. - */ - rc = sata_phy_debounce(ap, sata_deb_timing_before_fsrst); - if (rc) { - reason = "PHY debouncing failed"; - goto err; - } - - if (tmp & PORT_CS_DEV_RST) { - if (ata_port_offline(ap)) - return 0; - reason = "link not ready"; - goto err; - } - - /* Sil24 doesn't store signature FIS after hardreset, so we - * can't wait for BSY to clear. Some devices take a long time - * to get ready and those devices will choke if we don't wait - * for BSY clearance here. Tell libata to perform follow-up - * softreset. - */ - return -EAGAIN; + /* sil24 doesn't report device signature after hard reset */ + return sata_std_hardreset(ap, verbose, &dummy_class); +} - err: - ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason); - return -EIO; +static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) +{ + return ata_drive_probe_reset(ap, ata_std_probeinit, + sil24_softreset, sil24_hardreset, + ata_std_postreset, classes); } static inline void sil24_fill_sg(struct ata_queued_cmd *qc, @@ -656,20 +528,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct sil24_port_priv *pp = ap->private_data; - union sil24_cmd_block *cb; + union sil24_cmd_block *cb = pp->cmd_block + qc->tag; struct sil24_prb *prb; struct sil24_sge *sge; - u16 ctrl = 0; - - cb = &pp->cmd_block[sil24_tag(qc->tag)]; switch (qc->tf.protocol) { case ATA_PROT_PIO: case ATA_PROT_DMA: - case ATA_PROT_NCQ: case ATA_PROT_NODATA: prb = &cb->ata.prb; sge = cb->ata.sge; + prb->ctrl = 0; break; case ATA_PROT_ATAPI: @@ -682,10 +551,12 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { if (qc->tf.flags & ATA_TFLAG_WRITE) - ctrl = PRB_CTRL_PACKET_WRITE; + prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_WRITE); else - ctrl = PRB_CTRL_PACKET_READ; - } + prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_READ); + } else + prb->ctrl = 0; + break; default: @@ -694,7 +565,6 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) BUG(); } - prb->ctrl = cpu_to_le16(ctrl); ata_tf_to_fis(&qc->tf, prb->fis, 0); if (qc->flags & ATA_QCFLAG_DMAMAP) @@ -704,18 +574,11 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct sil24_port_priv *pp = ap->private_data; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - unsigned int tag = sil24_tag(qc->tag); - dma_addr_t paddr; - void __iomem *activate; - - paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block); - activate = port + PORT_CMD_ACTIVATE + tag * 8; - - writel((u32)paddr, activate); - writel((u64)paddr >> 32, activate + 4); + struct sil24_port_priv *pp = ap->private_data; + dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block); + writel((u32)paddr, port + PORT_CMD_ACTIVATE); return 0; } @@ -724,139 +587,162 @@ static void sil24_irq_clear(struct ata_port *ap) /* unused */ } -static void sil24_freeze(struct ata_port *ap) +static int __sil24_restart_controller(void __iomem *port) { - void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - - /* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear - * PORT_IRQ_ENABLE instead. - */ - writel(0xffff, port + PORT_IRQ_ENABLE_CLR); -} - -static void sil24_thaw(struct ata_port *ap) -{ - void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; u32 tmp; + int cnt; - /* clear IRQ */ - tmp = readl(port + PORT_IRQ_STAT); - writel(tmp, port + PORT_IRQ_STAT); + writel(PORT_CS_INIT, port + PORT_CTRL_STAT); - /* turn IRQ back on */ - writel(DEF_PORT_IRQ, port + PORT_IRQ_ENABLE_SET); + /* Max ~10ms */ + for (cnt = 0; cnt < 10000; cnt++) { + tmp = readl(port + PORT_CTRL_STAT); + if (tmp & PORT_CS_RDY) + return 0; + udelay(1); + } + + return -1; } -static void sil24_error_intr(struct ata_port *ap) +static void sil24_restart_controller(struct ata_port *ap) { - void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - struct ata_eh_info *ehi = &ap->eh_info; - int freeze = 0; - u32 irq_stat; - - /* on error, we need to clear IRQ explicitly */ - irq_stat = readl(port + PORT_IRQ_STAT); - writel(irq_stat, port + PORT_IRQ_STAT); - - /* first, analyze and record host port events */ - ata_ehi_clear_desc(ehi); + if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr)) + printk(KERN_ERR DRV_NAME + " ata%u: failed to restart controller\n", ap->id); +} - ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); +static int __sil24_reset_controller(void __iomem *port) +{ + int cnt; + u32 tmp; - if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { - ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, ", %s", - irq_stat & PORT_IRQ_PHYRDY_CHG ? - "PHY RDY changed" : "device exchanged"); - freeze = 1; - } + /* Reset controller state. Is this correct? */ + writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT); + readl(port + PORT_CTRL_STAT); /* sync */ - if (irq_stat & PORT_IRQ_UNK_FIS) { - ehi->err_mask |= AC_ERR_HSM; - ehi->action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi , ", unknown FIS"); - freeze = 1; + /* Max ~100ms */ + for (cnt = 0; cnt < 1000; cnt++) { + udelay(100); + tmp = readl(port + PORT_CTRL_STAT); + if (!(tmp & PORT_CS_DEV_RST)) + break; } - /* deal with command error */ - if (irq_stat & PORT_IRQ_ERROR) { - struct sil24_cerr_info *ci = NULL; - unsigned int err_mask = 0, action = 0; - struct ata_queued_cmd *qc; - u32 cerr; - - /* analyze CMD_ERR */ - cerr = readl(port + PORT_CMD_ERR); - if (cerr < ARRAY_SIZE(sil24_cerr_db)) - ci = &sil24_cerr_db[cerr]; - - if (ci && ci->desc) { - err_mask |= ci->err_mask; - action |= ci->action; - ata_ehi_push_desc(ehi, ", %s", ci->desc); - } else { - err_mask |= AC_ERR_OTHER; - action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, ", unknown command error %d", - cerr); - } + if (tmp & PORT_CS_DEV_RST) + return -1; - /* record error info */ - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc) { - sil24_update_tf(ap); - qc->err_mask |= err_mask; - } else - ehi->err_mask |= err_mask; + if (tmp & PORT_CS_RDY) + return 0; - ehi->action |= action; - } + return __sil24_restart_controller(port); +} - /* freeze or abort */ - if (freeze) - ata_port_freeze(ap); - else - ata_port_abort(ap); +static void sil24_reset_controller(struct ata_port *ap) +{ + printk(KERN_NOTICE DRV_NAME + " ata%u: resetting controller...\n", ap->id); + if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr)) + printk(KERN_ERR DRV_NAME + " ata%u: failed to reset controller\n", ap->id); } -static void sil24_finish_qc(struct ata_queued_cmd *qc) +static void sil24_eng_timeout(struct ata_port *ap) { - if (qc->flags & ATA_QCFLAG_RESULT_TF) - sil24_update_tf(qc->ap); + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->active_tag); + + printk(KERN_ERR "ata%u: command timeout\n", ap->id); + qc->err_mask |= AC_ERR_TIMEOUT; + ata_eh_qc_complete(qc); + + sil24_reset_controller(ap); } -static inline void sil24_host_intr(struct ata_port *ap) +static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) { + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); + struct sil24_port_priv *pp = ap->private_data; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; - u32 slot_stat, qc_active; - int rc; + u32 irq_stat, cmd_err, sstatus, serror; + unsigned int err_mask; - slot_stat = readl(port + PORT_SLOT_STAT); + irq_stat = readl(port + PORT_IRQ_STAT); + writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ - if (unlikely(slot_stat & HOST_SSTAT_ATTN)) { - sil24_error_intr(ap); + if (!(irq_stat & PORT_IRQ_ERROR)) { + /* ignore non-completion, non-error irqs for now */ + printk(KERN_WARNING DRV_NAME + "ata%u: non-error exception irq (irq_stat %x)\n", + ap->id, irq_stat); return; } - if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) - writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT); + cmd_err = readl(port + PORT_CMD_ERR); + sstatus = readl(port + PORT_SSTATUS); + serror = readl(port + PORT_SERROR); + if (serror) + writel(serror, port + PORT_SERROR); - qc_active = slot_stat & ~HOST_SSTAT_ATTN; - rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc); - if (rc > 0) - return; - if (rc < 0) { - struct ata_eh_info *ehi = &ap->eh_info; - ehi->err_mask |= AC_ERR_HSM; - ehi->action |= ATA_EH_SOFTRESET; - ata_port_freeze(ap); - return; + /* + * Don't log ATAPI device errors. They're supposed to happen + * and any serious errors will be logged using sense data by + * the SCSI layer. + */ + if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB) + printk("ata%u: error interrupt on port%d\n" + " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", + ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); + + if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) { + /* + * Device is reporting error, tf registers are valid. + */ + sil24_update_tf(ap); + err_mask = ac_err_mask(pp->tf.command); + sil24_restart_controller(ap); + } else { + /* + * Other errors. libata currently doesn't have any + * mechanism to report these errors. Just turn on + * ATA_ERR. + */ + err_mask = AC_ERR_OTHER; + sil24_reset_controller(ap); } - if (ata_ratelimit()) - ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(slot_stat 0x%x active_tag %d sactive 0x%x)\n", - slot_stat, ap->active_tag, ap->sactive); + if (qc) { + qc->err_mask |= err_mask; + ata_qc_complete(qc); + } +} + +static inline void sil24_host_intr(struct ata_port *ap) +{ + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; + u32 slot_stat; + + slot_stat = readl(port + PORT_SLOT_STAT); + if (!(slot_stat & HOST_SSTAT_ATTN)) { + struct sil24_port_priv *pp = ap->private_data; + /* + * !HOST_SSAT_ATTN guarantees successful completion, + * so reading back tf registers is unnecessary for + * most commands. TODO: read tf registers for + * commands which require these values on successful + * completion (EXECUTE DEVICE DIAGNOSTIC, CHECK POWER, + * DEVICE RESET and READ PORT MULTIPLIER (any more?). + */ + sil24_update_tf(ap); + + if (qc) { + qc->err_mask |= ac_err_mask(pp->tf.command); + ata_qc_complete(qc); + } + } else + sil24_error_intr(ap, slot_stat); } static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs) @@ -883,7 +769,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs * for (i = 0; i < host_set->n_ports; i++) if (status & (1 << i)) { struct ata_port *ap = host_set->ports[i]; - if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { + if (ap && !(ap->flags & ATA_FLAG_PORT_DISABLED)) { sil24_host_intr(host_set->ports[i]); handled++; } else @@ -896,35 +782,9 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs * return IRQ_RETVAL(handled); } -static void sil24_error_handler(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - - if (sil24_init_port(ap)) { - ata_eh_freeze_port(ap); - ehc->i.action |= ATA_EH_HARDRESET; - } - - /* perform recovery */ - ata_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset, - ata_std_postreset); -} - -static void sil24_post_internal_cmd(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - - /* make DMA engine forget about the failed command */ - if (qc->err_mask) - sil24_init_port(ap); -} - static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev) { - const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS; + const size_t cb_size = sizeof(*pp->cmd_block); dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); } @@ -934,7 +794,7 @@ static int sil24_port_start(struct ata_port *ap) struct device *dev = ap->host_set->dev; struct sil24_port_priv *pp; union sil24_cmd_block *cb; - size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS; + size_t cb_size = sizeof(*cb); dma_addr_t cb_dma; int rc = -ENOMEM; @@ -998,7 +858,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *host_base = NULL; void __iomem *port_base = NULL; int i, rc; - u32 tmp; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -1051,53 +910,37 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* * Configure the device */ - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { - rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (rc) { - rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "64-bit DMA enable failed\n"); - goto out_free; - } - } - } else { - rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "32-bit DMA enable failed\n"); - goto out_free; - } - rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - if (rc) { - dev_printk(KERN_ERR, &pdev->dev, - "32-bit consistent DMA enable failed\n"); - goto out_free; - } + /* + * FIXME: This device is certainly 64-bit capable. We just + * don't know how to use it. After fixing 32bit activation in + * this function, enable 64bit masks here. + */ + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit DMA enable failed\n"); + goto out_free; + } + rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit consistent DMA enable failed\n"); + goto out_free; } /* GPIO off */ writel(0, host_base + HOST_FLASH_CMD); - /* Apply workaround for completion IRQ loss on PCI-X errata */ - if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) { - tmp = readl(host_base + HOST_CTRL); - if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL)) - dev_printk(KERN_INFO, &pdev->dev, - "Applying completion IRQ loss on PCI-X " - "errata fix\n"); - else - probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; - } - - /* clear global reset & mask interrupts during initialization */ + /* Mask interrupts during initialization */ writel(0, host_base + HOST_CTRL); for (i = 0; i < probe_ent->n_ports; i++) { void __iomem *port = port_base + i * PORT_REGS_SIZE; unsigned long portu = (unsigned long)port; + u32 tmp; + int cnt; - probe_ent->port[i].cmd_addr = portu; + probe_ent->port[i].cmd_addr = portu + PORT_PRB; probe_ent->port[i].scr_addr = portu + PORT_SCONTROL; ata_std_ports(&probe_ent->port[i]); @@ -1109,20 +952,18 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tmp = readl(port + PORT_CTRL_STAT); if (tmp & PORT_CS_PORT_RST) { writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR); - tmp = ata_wait_register(port + PORT_CTRL_STAT, - PORT_CS_PORT_RST, - PORT_CS_PORT_RST, 10, 100); + readl(port + PORT_CTRL_STAT); /* sync */ + for (cnt = 0; cnt < 10; cnt++) { + msleep(10); + tmp = readl(port + PORT_CTRL_STAT); + if (!(tmp & PORT_CS_PORT_RST)) + break; + } if (tmp & PORT_CS_PORT_RST) dev_printk(KERN_ERR, &pdev->dev, "failed to clear port RST\n"); } - /* Configure IRQ WoC */ - if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) - writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); - else - writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); - /* Zero error counters. */ writel(0x8000, port + PORT_DECODE_ERR_THRESH); writel(0x8000, port + PORT_CRC_ERR_THRESH); @@ -1131,11 +972,26 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) writel(0x0000, port + PORT_CRC_ERR_CNT); writel(0x0000, port + PORT_HSHK_ERR_CNT); - /* Always use 64bit activation */ - writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR); + /* FIXME: 32bit activation? */ + writel(0, port + PORT_ACTIVATE_UPPER_ADDR); + writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_STAT); + + /* Configure interrupts */ + writel(0xffff, port + PORT_IRQ_ENABLE_CLR); + writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | PORT_IRQ_SDB_FIS, + port + PORT_IRQ_ENABLE_SET); + + /* Clear interrupts */ + writel(0x0fff0fff, port + PORT_IRQ_STAT); + writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); /* Clear port multiplier enable and resume bits */ writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR); + + /* Reset itself */ + if (__sil24_reset_controller(port)) + dev_printk(KERN_ERR, &pdev->dev, + "failed to reset controller\n"); } /* Turn on interrupts */ diff --git a/trunk/drivers/scsi/sata_sis.c b/trunk/drivers/scsi/sata_sis.c index 809d337ed641..728530df2e07 100644 --- a/trunk/drivers/scsi/sata_sis.c +++ b/trunk/drivers/scsi/sata_sis.c @@ -43,7 +43,7 @@ #include #define DRV_NAME "sata_sis" -#define DRV_VERSION "0.6" +#define DRV_VERSION "0.5" enum { sis_180 = 0, @@ -96,7 +96,6 @@ static struct scsi_host_template sis_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -107,17 +106,14 @@ static const struct ata_port_operations sis_ops = { .check_status = ata_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = sis_scr_read, @@ -129,7 +125,8 @@ static const struct ata_port_operations sis_ops = { static struct ata_port_info sis_port_info = { .sht = &sis_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x7, .udma_mask = 0x7f, diff --git a/trunk/drivers/scsi/sata_svw.c b/trunk/drivers/scsi/sata_svw.c index 7566c2cabaf7..53b0d5c0a61f 100644 --- a/trunk/drivers/scsi/sata_svw.c +++ b/trunk/drivers/scsi/sata_svw.c @@ -54,7 +54,7 @@ #endif /* CONFIG_PPC_OF */ #define DRV_NAME "sata_svw" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.07" enum { /* Taskfile registers offsets */ @@ -257,7 +257,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start, int len, index; /* Find the ata_port */ - ap = ata_shost_to_port(shost); + ap = (struct ata_port *) &shost->hostdata[0]; if (ap == NULL) return 0; @@ -299,7 +299,6 @@ static struct scsi_host_template k2_sata_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, #ifdef CONFIG_PPC_OF .proc_info = k2_sata_proc_info, #endif @@ -314,17 +313,14 @@ static const struct ata_port_operations k2_sata_ops = { .check_status = k2_stat_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, .bmdma_setup = k2_bmdma_setup_mmio, .bmdma_start = k2_bmdma_start_mmio, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_mmio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = k2_sata_scr_read, @@ -424,8 +420,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e writel(0x0, mmio_base + K2_SATA_SIM_OFFSET); probe_ent->sht = &k2_sata_sht; - probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; probe_ent->port_ops = &k2_sata_ops; probe_ent->n_ports = 4; probe_ent->irq = pdev->irq; diff --git a/trunk/drivers/scsi/sata_sx4.c b/trunk/drivers/scsi/sata_sx4.c index 7f864410f7c2..4139ad4b1df0 100644 --- a/trunk/drivers/scsi/sata_sx4.c +++ b/trunk/drivers/scsi/sata_sx4.c @@ -46,7 +46,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_sx4" -#define DRV_VERSION "0.9" +#define DRV_VERSION "0.8" enum { @@ -191,7 +191,6 @@ static struct scsi_host_template pdc_sata_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -205,7 +204,6 @@ static const struct ata_port_operations pdc_20621_ops = { .phy_reset = pdc_20621_phy_reset, .qc_prep = pdc20621_qc_prep, .qc_issue = pdc20621_qc_issue_prot, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = pdc_eng_timeout, .irq_handler = pdc20621_interrupt, .irq_clear = pdc20621_irq_clear, @@ -220,7 +218,7 @@ static const struct ata_port_info pdc_port_info[] = { .sht = &pdc_sata_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO | - ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, + ATA_FLAG_NO_ATAPI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -835,11 +833,11 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re tmp = mask & (1 << i); VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); if (tmp && ap && - !(ap->flags & ATA_FLAG_DISABLED)) { + !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) + if (qc && (!(qc->tf.ctl & ATA_NIEN))) handled += pdc20621_host_intr(ap, qc, (i > 4), mmio_base); } @@ -870,16 +868,15 @@ static void pdc_eng_timeout(struct ata_port *ap) switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: - ata_port_printk(ap, KERN_ERR, "command timeout\n"); + printk(KERN_ERR "ata%u: command timeout\n", ap->id); qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); break; default: drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - ata_port_printk(ap, KERN_ERR, - "unknown timeout, cmd 0x%x stat 0x%x\n", - qc->tf.command, drv_stat); + printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", + ap->id, qc->tf.command, drv_stat); qc->err_mask |= ac_err_mask(drv_stat); break; @@ -1378,6 +1375,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + /* + * If this driver happens to only be useful on Apple's K2, then + * we should check that here as it has a normal Serverworks ID + */ rc = pci_enable_device(pdev); if (rc) return rc; diff --git a/trunk/drivers/scsi/sata_uli.c b/trunk/drivers/scsi/sata_uli.c index 64f3c1aeed21..38b52bd3fa3f 100644 --- a/trunk/drivers/scsi/sata_uli.c +++ b/trunk/drivers/scsi/sata_uli.c @@ -37,7 +37,7 @@ #include #define DRV_NAME "sata_uli" -#define DRV_VERSION "1.0" +#define DRV_VERSION "0.5" enum { uli_5289 = 0, @@ -90,7 +90,6 @@ static struct scsi_host_template uli_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -103,18 +102,16 @@ static const struct ata_port_operations uli_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, + .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -129,7 +126,8 @@ static const struct ata_port_operations uli_ops = { static struct ata_port_info uli_port_info = { .sht = &uli_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &uli_ops, diff --git a/trunk/drivers/scsi/sata_via.c b/trunk/drivers/scsi/sata_via.c index 67c3d2999775..9e7ae4e0db32 100644 --- a/trunk/drivers/scsi/sata_via.c +++ b/trunk/drivers/scsi/sata_via.c @@ -47,7 +47,7 @@ #include #define DRV_NAME "sata_via" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.1" enum board_ids_enum { vt6420, @@ -103,7 +103,6 @@ static struct scsi_host_template svia_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -116,6 +115,8 @@ static const struct ata_port_operations svia_sata_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, + .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, @@ -123,12 +124,8 @@ static const struct ata_port_operations svia_sata_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -143,7 +140,7 @@ static const struct ata_port_operations svia_sata_ops = { static struct ata_port_info svia_port_info = { .sht = &svia_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, @@ -238,7 +235,8 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev) INIT_LIST_HEAD(&probe_ent->node); probe_ent->sht = &svia_sht; - probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY; + probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | + ATA_FLAG_NO_LEGACY; probe_ent->port_ops = &svia_sata_ops; probe_ent->n_ports = N_PORTS; probe_ent->irq = pdev->irq; diff --git a/trunk/drivers/scsi/sata_vsc.c b/trunk/drivers/scsi/sata_vsc.c index 616fd9634b4b..8a29ce340b47 100644 --- a/trunk/drivers/scsi/sata_vsc.c +++ b/trunk/drivers/scsi/sata_vsc.c @@ -47,7 +47,7 @@ #include #define DRV_NAME "sata_vsc" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.2" enum { /* Interrupt register offsets (from chip base address) */ @@ -221,21 +221,14 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, ap = host_set->ports[i]; - if (is_vsc_sata_int_err(i, int_status)) { - u32 err_status; - printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); - err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; - vsc_sata_scr_write(ap, SCR_ERROR, err_status); - handled++; - } - - if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { + if (ap && !(ap->flags & + (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) + if (qc && (!(qc->tf.ctl & ATA_NIEN))) { handled += ata_host_intr(ap, qc); - else if (is_vsc_sata_int_err(i, int_status)) { + } else if (is_vsc_sata_int_err(i, int_status)) { /* * On some chips (i.e. Intel 31244), an error * interrupt will sneak in at initialization @@ -279,7 +272,6 @@ static struct scsi_host_template vsc_sata_sht = { .proc_name = DRV_NAME, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -291,17 +283,14 @@ static const struct ata_port_operations vsc_sata_ops = { .exec_command = ata_exec_command, .check_status = ata_check_status, .dev_select = ata_std_dev_select, + .phy_reset = sata_phy_reset, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, + .eng_timeout = ata_eng_timeout, .irq_handler = vsc_sata_interrupt, .irq_clear = ata_bmdma_irq_clear, .scr_read = vsc_sata_scr_read, @@ -396,7 +385,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d probe_ent->sht = &vsc_sata_sht; probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO; + ATA_FLAG_MMIO | ATA_FLAG_SATA_RESET; probe_ent->port_ops = &vsc_sata_ops; probe_ent->n_ports = 4; probe_ent->irq = pdev->irq; @@ -443,12 +432,15 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d } +/* + * 0x1725/0x7174 is the Vitesse VSC-7174 + * 0x8086/0x3200 is the Intel 31244, which is supposed to be identical + * compatibility is untested as of yet + */ static const struct pci_device_id vsc_sata_pci_tbl[] = { - { PCI_VENDOR_ID_VITESSE, 0x7174, - PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, - { PCI_VENDOR_ID_INTEL, 0x3200, - PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, - { } /* terminate list */ + { 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, + { 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, + { } }; diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 2ab7df0dcfe8..73994e2ac2cb 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -63,6 +63,7 @@ #include #include #include +#include #include "scsi_priv.h" #include "scsi_logging.h" @@ -115,6 +116,79 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = { }; EXPORT_SYMBOL(scsi_device_types); +/* + * Function: scsi_allocate_request + * + * Purpose: Allocate a request descriptor. + * + * Arguments: device - device for which we want a request + * gfp_mask - allocation flags passed to kmalloc + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + * + * Returns: Pointer to request block. + */ +struct scsi_request *scsi_allocate_request(struct scsi_device *sdev, + gfp_t gfp_mask) +{ + const int offset = ALIGN(sizeof(struct scsi_request), 4); + const int size = offset + sizeof(struct request); + struct scsi_request *sreq; + + sreq = kzalloc(size, gfp_mask); + if (likely(sreq != NULL)) { + sreq->sr_request = (struct request *)(((char *)sreq) + offset); + sreq->sr_device = sdev; + sreq->sr_host = sdev->host; + sreq->sr_magic = SCSI_REQ_MAGIC; + sreq->sr_data_direction = DMA_BIDIRECTIONAL; + } + + return sreq; +} +EXPORT_SYMBOL(scsi_allocate_request); + +void __scsi_release_request(struct scsi_request *sreq) +{ + struct request *req = sreq->sr_request; + + /* unlikely because the tag was usually ended earlier by the + * mid-layer. However, for layering reasons ULD's don't end + * the tag of commands they generate. */ + if (unlikely(blk_rq_tagged(req))) { + unsigned long flags; + struct request_queue *q = req->q; + + spin_lock_irqsave(q->queue_lock, flags); + blk_queue_end_tag(q, req); + spin_unlock_irqrestore(q->queue_lock, flags); + } + + + if (likely(sreq->sr_command != NULL)) { + struct scsi_cmnd *cmd = sreq->sr_command; + + sreq->sr_command = NULL; + scsi_next_command(cmd); + } +} + +/* + * Function: scsi_release_request + * + * Purpose: Release a request descriptor. + * + * Arguments: sreq - request to release + * + * Lock status: No locks assumed to be held. This function is SMP-safe. + */ +void scsi_release_request(struct scsi_request *sreq) +{ + __scsi_release_request(sreq); + kfree(sreq); +} +EXPORT_SYMBOL(scsi_release_request); + struct scsi_host_cmd_pool { kmem_cache_t *slab; unsigned int users; @@ -572,29 +646,78 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) return rtn; } - /* - * Per-CPU I/O completion queue. - */ -static DEFINE_PER_CPU(struct list_head, scsi_done_q); - -/** - * scsi_req_abort_cmd -- Request command recovery for the specified command - * cmd: pointer to the SCSI command of interest + * Function: scsi_init_cmd_from_req + * + * Purpose: Queue a SCSI command + * Purpose: Initialize a struct scsi_cmnd from a struct scsi_request + * + * Arguments: cmd - command descriptor. + * sreq - Request from the queue. + * + * Lock status: None needed. * - * This function requests that SCSI Core start recovery for the - * command by deleting the timer and adding the command to the eh - * queue. It can be called by either LLDDs or SCSI Core. LLDDs who - * implement their own error recovery MAY ignore the timeout event if - * they generated scsi_req_abort_cmd. + * Returns: Nothing. + * + * Notes: Mainly transfer data from the request structure to the + * command structure. The request structure is allocated + * using the normal memory allocator, and requests can pile + * up to more or less any depth. The command structure represents + * a consumable resource, as these are allocated into a pool + * when the SCSI subsystem initializes. The preallocation is + * required so that in low-memory situations a disk I/O request + * won't cause the memory manager to try and write out a page. + * The request structure is generally used by ioctls and character + * devices. */ -void scsi_req_abort_cmd(struct scsi_cmnd *cmd) +void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq) { - if (!scsi_delete_timer(cmd)) - return; - scsi_times_out(cmd); + sreq->sr_command = cmd; + + cmd->cmd_len = sreq->sr_cmd_len; + cmd->use_sg = sreq->sr_use_sg; + + cmd->request = sreq->sr_request; + memcpy(cmd->data_cmnd, sreq->sr_cmnd, sizeof(cmd->data_cmnd)); + cmd->serial_number = 0; + cmd->bufflen = sreq->sr_bufflen; + cmd->buffer = sreq->sr_buffer; + cmd->retries = 0; + cmd->allowed = sreq->sr_allowed; + cmd->done = sreq->sr_done; + cmd->timeout_per_command = sreq->sr_timeout_per_command; + cmd->sc_data_direction = sreq->sr_data_direction; + cmd->sglist_len = sreq->sr_sglist_len; + cmd->underflow = sreq->sr_underflow; + cmd->sc_request = sreq; + memcpy(cmd->cmnd, sreq->sr_cmnd, sizeof(sreq->sr_cmnd)); + + /* + * Zero the sense buffer. Some host adapters automatically request + * sense on error. 0 is not a valid sense code. + */ + memset(cmd->sense_buffer, 0, sizeof(sreq->sr_sense_buffer)); + cmd->request_buffer = sreq->sr_buffer; + cmd->request_bufflen = sreq->sr_bufflen; + cmd->old_use_sg = cmd->use_sg; + if (cmd->cmd_len == 0) + cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); + cmd->old_cmd_len = cmd->cmd_len; + cmd->sc_old_data_direction = cmd->sc_data_direction; + cmd->old_underflow = cmd->underflow; + + /* + * Start the timer ticking. + */ + cmd->result = 0; + + SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n")); } -EXPORT_SYMBOL(scsi_req_abort_cmd); + +/* + * Per-CPU I/O completion queue. + */ +static DEFINE_PER_CPU(struct list_head, scsi_done_q); /** * scsi_done - Enqueue the finished SCSI command into the done queue. @@ -686,6 +809,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct Scsi_Host *shost = sdev->host; + struct scsi_request *sreq; scsi_device_unbusy(sdev); @@ -715,6 +839,21 @@ void scsi_finish_command(struct scsi_cmnd *cmd) * We can get here with use_sg=0, causing a panic in the upper level */ cmd->use_sg = cmd->old_use_sg; + + /* + * If there is an associated request structure, copy the data over + * before we call the completion function. + */ + sreq = cmd->sc_request; + if (sreq) { + sreq->sr_result = sreq->sr_command->result; + if (sreq->sr_result) { + memcpy(sreq->sr_sense_buffer, + sreq->sr_command->sense_buffer, + sizeof(sreq->sr_sense_buffer)); + } + } + cmd->done(cmd); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/trunk/drivers/scsi/scsi.h b/trunk/drivers/scsi/scsi.h index f51e466893e7..5ee5d80a9931 100644 --- a/trunk/drivers/scsi/scsi.h +++ b/trunk/drivers/scsi/scsi.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index fb5cb4c9ac65..62f8cb7b3d2b 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -159,8 +159,6 @@ static struct { {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, - {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, - {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ {"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */ {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 6a7a60fc0a4e..1c75646f9689 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -26,13 +26,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include "scsi_priv.h" #include "scsi_logging.h" @@ -57,28 +57,6 @@ void scsi_eh_wakeup(struct Scsi_Host *shost) } } -/** - * scsi_schedule_eh - schedule EH for SCSI host - * @shost: SCSI host to invoke error handling on. - * - * Schedule SCSI EH without scmd. - **/ -void scsi_schedule_eh(struct Scsi_Host *shost) -{ - unsigned long flags; - - spin_lock_irqsave(shost->host_lock, flags); - - if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 || - scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) { - shost->host_eh_scheduled++; - scsi_eh_wakeup(shost); - } - - spin_unlock_irqrestore(shost->host_lock, flags); -} -EXPORT_SYMBOL_GPL(scsi_schedule_eh); - /** * scsi_eh_scmd_add - add scsi cmd to error handling. * @scmd: scmd to run eh on. @@ -474,6 +452,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) (sdev->lun << 5 & 0xe0); shost->eh_action = &done; + scmd->request->rq_status = RQ_SCSI_BUSY; spin_lock_irqsave(shost->host_lock, flags); scsi_log_send(scmd); @@ -482,6 +461,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) timeleft = wait_for_completion_timeout(&done, timeout); + scmd->request->rq_status = RQ_SCSI_DONE; shost->eh_action = NULL; scsi_log_completion(scmd, SUCCESS); @@ -1537,7 +1517,7 @@ int scsi_error_handler(void *data) */ set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { - if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || + if (shost->host_failed == 0 || shost->host_failed != shost->host_busy) { SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d sleeping\n", @@ -1677,6 +1657,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->request = &req; memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout)); + scmd->request->rq_status = RQ_SCSI_BUSY; memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); @@ -1690,6 +1671,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->cmd_len = 0; scmd->sc_data_direction = DMA_BIDIRECTIONAL; + scmd->sc_request = NULL; + scmd->sc_magic = SCSI_CMND_MAGIC; init_timer(&scmd->eh_timeout); @@ -1786,6 +1769,14 @@ int scsi_normalize_sense(const u8 *sense_buffer, int sb_len, } EXPORT_SYMBOL(scsi_normalize_sense); +int scsi_request_normalize_sense(struct scsi_request *sreq, + struct scsi_sense_hdr *sshdr) +{ + return scsi_normalize_sense(sreq->sr_sense_buffer, + sizeof(sreq->sr_sense_buffer), sshdr); +} +EXPORT_SYMBOL(scsi_request_normalize_sense); + int scsi_command_normalize_sense(struct scsi_cmnd *cmd, struct scsi_sense_hdr *sshdr) { diff --git a/trunk/drivers/scsi/scsi_ioctl.c b/trunk/drivers/scsi/scsi_ioctl.c index a89c4115cfba..a89aff61d3d8 100644 --- a/trunk/drivers/scsi/scsi_ioctl.c +++ b/trunk/drivers/scsi/scsi_ioctl.c @@ -15,11 +15,11 @@ #include #include -#include #include #include #include #include +#include #include #include diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 3d04a9f386ac..faee4757c03a 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -19,18 +19,18 @@ #include #include -#include #include #include #include #include #include +#include #include "scsi_priv.h" #include "scsi_logging.h" -#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools) +#define SG_MEMPOOL_NR (sizeof(scsi_sg_pools)/sizeof(struct scsi_host_sg_pool)) #define SG_MEMPOOL_SIZE 32 struct scsi_host_sg_pool { @@ -83,7 +83,7 @@ static void scsi_unprep_request(struct request *req) struct scsi_cmnd *cmd = req->special; req->flags &= ~REQ_DONTPREP; - req->special = NULL; + req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL; scsi_put_command(cmd); } @@ -161,6 +161,72 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) return 0; } +/* + * Function: scsi_do_req + * + * Purpose: Queue a SCSI request + * + * Arguments: sreq - command descriptor. + * cmnd - actual SCSI command to be performed. + * buffer - data buffer. + * bufflen - size of data buffer. + * done - completion function to be run. + * timeout - how long to let it run before timeout. + * retries - number of retries we allow. + * + * Lock status: No locks held upon entry. + * + * Returns: Nothing. + * + * Notes: This function is only used for queueing requests for things + * like ioctls and character device requests - this is because + * we essentially just inject a request into the queue for the + * device. + * + * In order to support the scsi_device_quiesce function, we + * now inject requests on the *head* of the device queue + * rather than the tail. + */ +void scsi_do_req(struct scsi_request *sreq, const void *cmnd, + void *buffer, unsigned bufflen, + void (*done)(struct scsi_cmnd *), + int timeout, int retries) +{ + /* + * If the upper level driver is reusing these things, then + * we should release the low-level block now. Another one will + * be allocated later when this request is getting queued. + */ + __scsi_release_request(sreq); + + /* + * Our own function scsi_done (which marks the host as not busy, + * disables the timeout counter, etc) will be called by us or by the + * scsi_hosts[host].queuecommand() function needs to also call + * the completion function for the high level driver. + */ + memcpy(sreq->sr_cmnd, cmnd, sizeof(sreq->sr_cmnd)); + sreq->sr_bufflen = bufflen; + sreq->sr_buffer = buffer; + sreq->sr_allowed = retries; + sreq->sr_done = done; + sreq->sr_timeout_per_command = timeout; + + if (sreq->sr_cmd_len == 0) + sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]); + + /* + * head injection *required* here otherwise quiesce won't work + * + * Because users of this function are apt to reuse requests with no + * modification, we have to sanitise the request flags here + */ + sreq->sr_request->flags &= ~REQ_DONTPREP; + blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, + 1, sreq); +} +EXPORT_SYMBOL(scsi_do_req); + /** * scsi_execute - insert request and wait for the result * @sdev: scsi device @@ -500,7 +566,7 @@ void scsi_device_unbusy(struct scsi_device *sdev) spin_lock_irqsave(shost->host_lock, flags); shost->host_busy--; if (unlikely(scsi_host_in_recovery(shost) && - (shost->host_failed || shost->host_eh_scheduled))) + shost->host_failed)) scsi_eh_wakeup(shost); spin_unlock(shost->host_lock); spin_lock(sdev->request_queue->queue_lock); @@ -1234,7 +1300,15 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) * at request->cmd, as this tells us the real story. */ if (req->flags & REQ_SPECIAL && req->special) { - cmd = req->special; + struct scsi_request *sreq = req->special; + + if (sreq->sr_magic == SCSI_REQ_MAGIC) { + cmd = scsi_get_command(sreq->sr_device, GFP_ATOMIC); + if (unlikely(!cmd)) + goto defer; + scsi_init_cmd_from_req(cmd, sreq); + } else + cmd = req->special; } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) { @@ -2289,61 +2363,3 @@ scsi_target_unblock(struct device *dev) device_for_each_child(dev, NULL, target_unblock); } EXPORT_SYMBOL_GPL(scsi_target_unblock); - -/** - * scsi_kmap_atomic_sg - find and atomically map an sg-elemnt - * @sg: scatter-gather list - * @sg_count: number of segments in sg - * @offset: offset in bytes into sg, on return offset into the mapped area - * @len: bytes to map, on return number of bytes mapped - * - * Returns virtual address of the start of the mapped page - */ -void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, - size_t *offset, size_t *len) -{ - int i; - size_t sg_len = 0, len_complete = 0; - struct page *page; - - for (i = 0; i < sg_count; i++) { - len_complete = sg_len; /* Complete sg-entries */ - sg_len += sg[i].length; - if (sg_len > *offset) - break; - } - - if (unlikely(i == sg_count)) { - printk(KERN_ERR "%s: Bytes in sg: %zu, requested offset %zu, " - "elements %d\n", - __FUNCTION__, sg_len, *offset, sg_count); - WARN_ON(1); - return NULL; - } - - /* Offset starting from the beginning of first page in this sg-entry */ - *offset = *offset - len_complete + sg[i].offset; - - /* Assumption: contiguous pages can be accessed as "page + i" */ - page = nth_page(sg[i].page, (*offset >> PAGE_SHIFT)); - *offset &= ~PAGE_MASK; - - /* Bytes in this sg-entry from *offset to the end of the page */ - sg_len = PAGE_SIZE - *offset; - if (*len > sg_len) - *len = sg_len; - - return kmap_atomic(page, KM_BIO_SRC_IRQ); -} -EXPORT_SYMBOL(scsi_kmap_atomic_sg); - -/** - * scsi_kunmap_atomic_sg - atomically unmap a virtual address, previously - * mapped with scsi_kmap_atomic_sg - * @virt: virtual address to be unmapped - */ -void scsi_kunmap_atomic_sg(void *virt) -{ - kunmap_atomic(virt, KM_BIO_SRC_IRQ); -} -EXPORT_SYMBOL(scsi_kunmap_atomic_sg); diff --git a/trunk/drivers/scsi/scsi_logging.h b/trunk/drivers/scsi/scsi_logging.h index a3e2af6a846c..e1722ba94586 100644 --- a/trunk/drivers/scsi/scsi_logging.h +++ b/trunk/drivers/scsi/scsi_logging.h @@ -45,12 +45,10 @@ extern unsigned int scsi_logging_level; ((scsi_logging_level >> (SHIFT)) & ((1 << (BITS)) - 1)) #define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) \ -do { \ +{ \ if (unlikely((SCSI_LOG_LEVEL(SHIFT, BITS)) > (LEVEL))) \ - do { \ - CMD; \ - } while (0); \ -} while (0) + (CMD); \ +} #else #define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) #endif /* CONFIG_SCSI_LOGGING */ diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index a1727a0e1bdd..27c48274e8cb 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -8,9 +8,16 @@ struct request_queue; struct scsi_cmnd; struct scsi_device; struct scsi_host_template; +struct scsi_request; struct Scsi_Host; +/* + * Magic values for certain scsi structs. Shouldn't ever be used. + */ +#define SCSI_CMND_MAGIC 0xE25C23A5 +#define SCSI_REQ_MAGIC 0x75F6D354 + /* * Scsi Error Handler Flags */ @@ -27,6 +34,9 @@ extern void scsi_exit_hosts(void); extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); extern int scsi_setup_command_freelist(struct Scsi_Host *shost); extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); +extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, + struct scsi_request *sreq); +extern void __scsi_release_request(struct scsi_request *sreq); extern void __scsi_done(struct scsi_cmnd *cmd); extern int scsi_retry_command(struct scsi_cmnd *cmd); #ifdef CONFIG_SCSI_LOGGING diff --git a/trunk/drivers/scsi/scsi_proc.c b/trunk/drivers/scsi/scsi_proc.c index 55200e4fdf11..07be62bbaaea 100644 --- a/trunk/drivers/scsi/scsi_proc.c +++ b/trunk/drivers/scsi/scsi_proc.c @@ -266,6 +266,8 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, lun = simple_strtoul(p + 1, &p, 0); err = scsi_add_single_device(host, channel, id, lun); + if (err >= 0) + err = length; /* * Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi @@ -282,13 +284,6 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, err = scsi_remove_single_device(host, channel, id, lun); } - /* - * convert success returns so that we return the - * number of bytes consumed. - */ - if (!err) - err = length; - out: free_page((unsigned long)buffer); return err; diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 0f7e6f94d66b..1a5474bd11a1 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -33,11 +33,11 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -816,32 +816,6 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev) put_device(&sdev->sdev_gendev); } -#ifdef CONFIG_SCSI_LOGGING -/** - * scsi_inq_str - print INQUIRY data from min to max index, - * strip trailing whitespace - * @buf: Output buffer with at least end-first+1 bytes of space - * @inq: Inquiry buffer (input) - * @first: Offset of string into inq - * @end: Index after last character in inq - */ -static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq, - unsigned first, unsigned end) -{ - unsigned term = 0, idx; - - for (idx = 0; idx + first < end && idx + first < inq[4] + 5; idx++) { - if (inq[idx+first] > ' ') { - buf[idx] = inq[idx+first]; - term = idx+1; - } else { - buf[idx] = ' '; - } - } - buf[term] = 0; - return buf; -} -#endif /** * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it @@ -906,12 +880,10 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, if (scsi_probe_lun(sdev, result, result_len, &bflags)) goto out_free_result; - if (bflagsp) - *bflagsp = bflags; /* * result contains valid SCSI INQUIRY data. */ - if (((result[0] >> 5) == 3) && !(bflags & BLIST_ATTACH_PQ3)) { + if ((result[0] >> 5) == 3) { /* * For a Peripheral qualifier 3 (011b), the SCSI * spec says: The device server is not capable of @@ -922,22 +894,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * logical disk configured at sdev->lun, but there * is a target id responding. */ - SCSI_LOG_SCAN_BUS(2, sdev_printk(KERN_INFO, sdev, "scsi scan:" - " peripheral qualifier of 3, device not" - " added\n")) - if (lun == 0) { - SCSI_LOG_SCAN_BUS(1, { - unsigned char vend[9]; - unsigned char mod[17]; - - sdev_printk(KERN_INFO, sdev, - "scsi scan: consider passing scsi_mod." - "dev_flags=%s:%s:0x240 or 0x800240\n", - scsi_inq_str(vend, result, 8, 16), - scsi_inq_str(mod, result, 16, 32)); - }); - } - + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO + "scsi scan: peripheral qualifier of 3," + " no device added\n")); res = SCSI_SCAN_TARGET_PRESENT; goto out_free_result; } @@ -961,6 +920,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, sdev->lockable = 0; scsi_unlock_floptical(sdev, result); } + if (bflagsp) + *bflagsp = bflags; } out_free_result: @@ -985,6 +946,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * scsi_sequential_lun_scan - sequentially scan a SCSI target * @starget: pointer to target structure to scan * @bflags: black/white list flag for LUN 0 + * @lun0_res: result of scanning LUN 0 * * Description: * Generally, scan from LUN 1 (LUN 0 is assumed to already have been @@ -994,7 +956,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * Modifies sdevscan->lun. **/ static void scsi_sequential_lun_scan(struct scsi_target *starget, - int bflags, int scsi_level, int rescan) + int bflags, int lun0_res, int scsi_level, + int rescan) { unsigned int sparse_lun, lun, max_dev_lun; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -1014,6 +977,13 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, } else sparse_lun = 0; + /* + * If not sparse lun and no device attached at LUN 0 do not scan + * any further. + */ + if (!sparse_lun && (lun0_res != SCSI_SCAN_LUN_PRESENT)) + return; + /* * If less than SCSI_1_CSS, and no special lun scaning, stop * scanning; this matches 2.4 behaviour, but could just be a bug @@ -1425,7 +1395,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, * do a sequential scan. */ scsi_sequential_lun_scan(starget, bflags, - starget->scsi_level, rescan); + res, starget->scsi_level, rescan); } out_reap: @@ -1503,7 +1473,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, __FUNCTION__, channel, id, lun)); if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || - ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || + ((id != SCAN_WILD_CARD) && (id > shost->max_id)) || ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) return -EINVAL; diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 5ec7a4fb0145..a6fde52946d6 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -39,7 +39,7 @@ const char *scsi_device_state_name(enum scsi_device_state state) int i; char *name = NULL; - for (i = 0; i < ARRAY_SIZE(sdev_states); i++) { + for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) { if (sdev_states[i].value == state) { name = sdev_states[i].name; break; @@ -65,7 +65,7 @@ const char *scsi_host_state_name(enum scsi_host_state state) int i; char *name = NULL; - for (i = 0; i < ARRAY_SIZE(shost_states); i++) { + for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) { if (shost_states[i].value == state) { name = shost_states[i].name; break; @@ -160,7 +160,7 @@ store_shost_state(struct class_device *class_dev, const char *buf, size_t count) struct Scsi_Host *shost = class_to_shost(class_dev); enum scsi_host_state state = 0; - for (i = 0; i < ARRAY_SIZE(shost_states); i++) { + for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) { const int len = strlen(shost_states[i].name); if (strncmp(shost_states[i].name, buf, len) == 0 && buf[len] == '\n') { @@ -466,7 +466,7 @@ store_state_field(struct device *dev, struct device_attribute *attr, const char struct scsi_device *sdev = to_scsi_device(dev); enum scsi_device_state state = 0; - for (i = 0; i < ARRAY_SIZE(sdev_states); i++) { + for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) { const int len = strlen(sdev_states[i].name); if (strncmp(sdev_states[i].name, buf, len) == 0 && buf[len] == '\n') { diff --git a/trunk/drivers/scsi/scsi_transport_api.h b/trunk/drivers/scsi/scsi_transport_api.h deleted file mode 100644 index 934f0e62bb5c..000000000000 --- a/trunk/drivers/scsi/scsi_transport_api.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SCSI_TRANSPORT_API_H -#define _SCSI_TRANSPORT_API_H - -void scsi_schedule_eh(struct Scsi_Host *shost); - -#endif /* _SCSI_TRANSPORT_API_H */ diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index f2db7a41cf1d..95c5478dcdfd 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -50,7 +50,7 @@ static const char *get_fc_##title##_name(enum table_type table_key) \ int i; \ char *name = NULL; \ \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ if (table[i].value == table_key) { \ name = table[i].name; \ break; \ @@ -65,7 +65,7 @@ static int get_fc_##title##_match(const char *table_key, \ { \ int i; \ \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ if (strncmp(table_key, table[i].name, \ table[i].matchlen) == 0) { \ *value = table[i].value; \ @@ -140,7 +140,7 @@ get_fc_##title##_names(u32 table_key, char *buf) \ ssize_t len = 0; \ int i; \ \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ if (table[i].value & table_key) { \ len += sprintf(buf + len, "%s%s", \ prefix, table[i].name); \ diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 5569fdcfd621..2730d507e585 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -31,26 +31,31 @@ #include #include -#define ISCSI_SESSION_ATTRS 11 -#define ISCSI_CONN_ATTRS 11 -#define ISCSI_HOST_ATTRS 0 +#define ISCSI_SESSION_ATTRS 8 +#define ISCSI_CONN_ATTRS 6 struct iscsi_internal { - int daemon_pid; struct scsi_transport_template t; struct iscsi_transport *iscsi_transport; struct list_head list; - struct class_device cdev; + /* + * based on transport capabilities, at register time we set these + * bits to tell the transport class it wants attributes displayed + * in sysfs or that it can support different iSCSI Data-Path + * capabilities + */ + uint32_t param_mask; - struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; + struct class_device cdev; + /* + * We do not have any private or other attrs. + */ struct transport_container conn_cont; struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; struct transport_container session_cont; struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; }; -static int iscsi_session_nr; /* sysfs session id for next new session */ - /* * list of registered transports and lock that must * be held while accessing list. The iscsi_transport_lock must @@ -115,24 +120,6 @@ static struct attribute_group iscsi_transport_group = { .attrs = iscsi_transport_attrs, }; -static int iscsi_setup_host(struct transport_container *tc, struct device *dev, - struct class_device *cdev) -{ - struct Scsi_Host *shost = dev_to_shost(dev); - struct iscsi_host *ihost = shost->shost_data; - - memset(ihost, 0, sizeof(*ihost)); - INIT_LIST_HEAD(&ihost->sessions); - mutex_init(&ihost->mutex); - return 0; -} - -static DECLARE_TRANSPORT_CLASS(iscsi_host_class, - "iscsi_host", - iscsi_setup_host, - NULL, - NULL); - static DECLARE_TRANSPORT_CLASS(iscsi_session_class, "iscsi_session", NULL, @@ -146,6 +133,7 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, NULL); static struct sock *nls; +static int daemon_pid; static DEFINE_MUTEX(rx_queue_mutex); struct mempool_zone { @@ -177,23 +165,14 @@ static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); static DEFINE_SPINLOCK(connlock); -static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn) -{ - struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent); - return sess->sid; -} - -/* - * Returns the matching session to a given sid - */ -static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid) +static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle) { unsigned long flags; struct iscsi_cls_session *sess; spin_lock_irqsave(&sesslock, flags); list_for_each_entry(sess, &sesslist, sess_list) { - if (sess->sid == sid) { + if (sess == iscsi_ptr(handle)) { spin_unlock_irqrestore(&sesslock, flags); return sess; } @@ -202,17 +181,14 @@ static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid) return NULL; } -/* - * Returns the matching connection to a given sid / cid tuple - */ -static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) +static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle) { unsigned long flags; struct iscsi_cls_conn *conn; spin_lock_irqsave(&connlock, flags); list_for_each_entry(conn, &connlist, conn_list) { - if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) { + if (conn == iscsi_ptr(handle)) { spin_unlock_irqrestore(&connlock, flags); return conn; } @@ -233,7 +209,6 @@ static void iscsi_session_release(struct device *dev) shost = iscsi_session_to_shost(session); scsi_host_put(shost); - kfree(session->targetname); kfree(session); module_put(transport->owner); } @@ -243,95 +218,30 @@ static int iscsi_is_session_dev(const struct device *dev) return dev->release == iscsi_session_release; } -static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, - uint id, uint lun) -{ - struct iscsi_host *ihost = shost->shost_data; - struct iscsi_cls_session *session; - - mutex_lock(&ihost->mutex); - list_for_each_entry(session, &ihost->sessions, host_list) { - if ((channel == SCAN_WILD_CARD || - channel == session->channel) && - (id == SCAN_WILD_CARD || id == session->target_id)) - scsi_scan_target(&session->dev, session->channel, - session->target_id, lun, 1); - } - mutex_unlock(&ihost->mutex); - - return 0; -} - -static void session_recovery_timedout(void *data) -{ - struct iscsi_cls_session *session = data; - - dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed " - "out after %d secs\n", session->recovery_tmo); - - if (session->transport->session_recovery_timedout) - session->transport->session_recovery_timedout(session); - - scsi_target_unblock(&session->dev); -} - -void iscsi_unblock_session(struct iscsi_cls_session *session) -{ - if (!cancel_delayed_work(&session->recovery_work)) - flush_scheduled_work(); - scsi_target_unblock(&session->dev); -} -EXPORT_SYMBOL_GPL(iscsi_unblock_session); - -void iscsi_block_session(struct iscsi_cls_session *session) -{ - scsi_target_block(&session->dev); - schedule_delayed_work(&session->recovery_work, - session->recovery_tmo * HZ); -} -EXPORT_SYMBOL_GPL(iscsi_block_session); - /** * iscsi_create_session - create iscsi class session * @shost: scsi host * @transport: iscsi transport * - * This can be called from a LLD or iscsi_transport. + * This can be called from a LLD or iscsi_transport **/ struct iscsi_cls_session * -iscsi_create_session(struct Scsi_Host *shost, - struct iscsi_transport *transport, int channel) +iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport) { - struct iscsi_host *ihost; struct iscsi_cls_session *session; int err; if (!try_module_get(transport->owner)) return NULL; - session = kzalloc(sizeof(*session) + transport->sessiondata_size, - GFP_KERNEL); + session = kzalloc(sizeof(*session), GFP_KERNEL); if (!session) goto module_put; session->transport = transport; - session->recovery_tmo = 120; - INIT_WORK(&session->recovery_work, session_recovery_timedout, session); - INIT_LIST_HEAD(&session->host_list); - INIT_LIST_HEAD(&session->sess_list); - - if (transport->sessiondata_size) - session->dd_data = &session[1]; /* this is released in the dev's release function */ scsi_host_get(shost); - ihost = shost->shost_data; - - session->sid = iscsi_session_nr++; - session->channel = channel; - session->target_id = ihost->next_target_id++; - - snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", - session->sid); + snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no); session->dev.parent = &shost->shost_gendev; session->dev.release = iscsi_session_release; err = device_register(&session->dev); @@ -342,10 +252,6 @@ iscsi_create_session(struct Scsi_Host *shost, } transport_register_device(&session->dev); - mutex_lock(&ihost->mutex); - list_add(&session->host_list, &ihost->sessions); - mutex_unlock(&ihost->mutex); - return session; free_session: @@ -366,16 +272,6 @@ EXPORT_SYMBOL_GPL(iscsi_create_session); **/ int iscsi_destroy_session(struct iscsi_cls_session *session) { - struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; - - if (!cancel_delayed_work(&session->recovery_work)) - flush_scheduled_work(); - - mutex_lock(&ihost->mutex); - list_del(&session->host_list); - mutex_unlock(&ihost->mutex); - transport_unregister_device(&session->dev); device_unregister(&session->dev); return 0; @@ -388,7 +284,6 @@ static void iscsi_conn_release(struct device *dev) struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); struct device *parent = conn->dev.parent; - kfree(conn->persistent_address); kfree(conn); put_device(parent); } @@ -406,16 +301,12 @@ static int iscsi_is_conn_dev(const struct device *dev) * This can be called from a LLD or iscsi_transport. The connection * is child of the session so cid must be unique for all connections * on the session. - * - * Since we do not support MCS, cid will normally be zero. In some cases - * for software iscsi we could be trying to preallocate a connection struct - * in which case there could be two connection structs and cid would be - * non-zero. **/ struct iscsi_cls_conn * iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) { struct iscsi_transport *transport = session->transport; + struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_cls_conn *conn; int err; @@ -428,14 +319,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) INIT_LIST_HEAD(&conn->conn_list); conn->transport = transport; - conn->cid = cid; /* this is released in the dev's release function */ if (!get_device(&session->dev)) goto free_conn; - snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", - session->sid, cid); + shost->host_no, cid); conn->dev.parent = &session->dev; conn->dev.release = iscsi_conn_release; err = device_register(&conn->dev); @@ -471,6 +360,105 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn) EXPORT_SYMBOL_GPL(iscsi_destroy_conn); +/* + * These functions are used only by software iscsi_transports + * which do not allocate and more their scsi_hosts since this + * is initiated from userspace. + */ + +/* + * iSCSI Session's hostdata organization: + * + * *------------------* <== hostdata_session(host->hostdata) + * | ptr to class sess| + * |------------------| <== iscsi_hostdata(host->hostdata) + * | transport's data | + * *------------------* + */ + +#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \ + _t->hostdata_size % sizeof(unsigned long)) + +#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) + +/** + * iscsi_transport_create_session - create iscsi cls session and host + * scsit: scsi transport template + * transport: iscsi transport template + * + * This can be used by software iscsi_transports that allocate + * a session per scsi host. + **/ +struct Scsi_Host * +iscsi_transport_create_session(struct scsi_transport_template *scsit, + struct iscsi_transport *transport) +{ + struct iscsi_cls_session *session; + struct Scsi_Host *shost; + unsigned long flags; + + shost = scsi_host_alloc(transport->host_template, + hostdata_privsize(transport)); + if (!shost) { + printk(KERN_ERR "iscsi: can not allocate SCSI host for " + "session\n"); + return NULL; + } + + shost->max_id = 1; + shost->max_channel = 0; + shost->max_lun = transport->max_lun; + shost->max_cmd_len = transport->max_cmd_len; + shost->transportt = scsit; + shost->transportt->create_work_queue = 1; + + if (scsi_add_host(shost, NULL)) + goto free_host; + + session = iscsi_create_session(shost, transport); + if (!session) + goto remove_host; + + *(unsigned long*)shost->hostdata = (unsigned long)session; + spin_lock_irqsave(&sesslock, flags); + list_add(&session->sess_list, &sesslist); + spin_unlock_irqrestore(&sesslock, flags); + return shost; + +remove_host: + scsi_remove_host(shost); +free_host: + scsi_host_put(shost); + return NULL; +} + +EXPORT_SYMBOL_GPL(iscsi_transport_create_session); + +/** + * iscsi_transport_destroy_session - destroy session and scsi host + * shost: scsi host + * + * This can be used by software iscsi_transports that allocate + * a session per scsi host. + **/ +int iscsi_transport_destroy_session(struct Scsi_Host *shost) +{ + struct iscsi_cls_session *session; + unsigned long flags; + + scsi_remove_host(shost); + session = hostdata_session(shost->hostdata); + spin_lock_irqsave(&sesslock, flags); + list_del(&session->sess_list); + spin_unlock_irqrestore(&sesslock, flags); + iscsi_destroy_session(session); + /* ref from host alloc */ + scsi_host_put(shost); + return 0; +} + +EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session); + /* * iscsi interface functions */ @@ -572,13 +560,13 @@ mempool_zone_get_skb(struct mempool_zone *zone) } static int -iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) +iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) { unsigned long flags; int rc; skb_get(skb); - rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); + rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT); if (rc < 0) { mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); @@ -586,7 +574,6 @@ iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) } spin_lock_irqsave(&zone->freelock, flags); - INIT_LIST_HEAD(skb_to_lh(skb)); list_add(skb_to_lh(skb), &zone->freequeue); spin_unlock_irqrestore(&zone->freelock, flags); @@ -600,14 +587,9 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, struct sk_buff *skb; struct iscsi_uevent *ev; char *pdu; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + data_size); - priv = iscsi_if_transport_lookup(conn->transport); - if (!priv) - return -EINVAL; - mempool_zone_complete(conn->z_pdu); skb = mempool_zone_get_skb(conn->z_pdu); @@ -618,20 +600,19 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, return -ENOMEM; } - nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); ev = NLMSG_DATA(nlh); memset(ev, 0, sizeof(*ev)); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_RECV_PDU; if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) ev->iferror = -ENOMEM; - ev->r.recv_req.cid = conn->cid; - ev->r.recv_req.sid = iscsi_conn_get_sid(conn); + ev->r.recv_req.conn_handle = iscsi_handle(conn); pdu = (char*)ev + sizeof(*ev); memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); - return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid); + return iscsi_unicast_skb(conn->z_pdu, skb); } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); @@ -640,13 +621,8 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) struct nlmsghdr *nlh; struct sk_buff *skb; struct iscsi_uevent *ev; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev)); - priv = iscsi_if_transport_lookup(conn->transport); - if (!priv) - return; - mempool_zone_complete(conn->z_error); skb = mempool_zone_get_skb(conn->z_error); @@ -656,17 +632,16 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) return; } - nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); ev = NLMSG_DATA(nlh); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_CONN_ERROR; if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) ev->iferror = -ENOMEM; ev->r.connerror.error = error; - ev->r.connerror.cid = conn->cid; - ev->r.connerror.sid = iscsi_conn_get_sid(conn); + ev->r.connerror.conn_handle = iscsi_handle(conn); - iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid); + iscsi_unicast_skb(conn->z_error, skb); dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", error); @@ -696,7 +671,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); nlh->nlmsg_flags = flags; memcpy(NLMSG_DATA(nlh), payload, size); - return iscsi_unicast_skb(z_reply, skb, pid); + return iscsi_unicast_skb(z_reply, skb); } static int @@ -708,18 +683,13 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) struct iscsi_cls_conn *conn; struct nlmsghdr *nlhstat; struct iscsi_uevent *evstat; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_stats) + sizeof(struct iscsi_stats_custom) * ISCSI_STATS_CUSTOM_MAX); int err = 0; - priv = iscsi_if_transport_lookup(transport); - if (!priv) - return -EINVAL; - - conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid); + conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle); if (!conn) return -EEXIST; @@ -735,7 +705,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) return -ENOMEM; } - nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0, + nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0, (len - sizeof(*nlhstat)), 0); evstat = NLMSG_DATA(nlhstat); memset(evstat, 0, sizeof(*evstat)); @@ -743,10 +713,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) evstat->type = nlh->nlmsg_type; if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) evstat->iferror = -ENOMEM; - evstat->u.get_stats.cid = - ev->u.get_stats.cid; - evstat->u.get_stats.sid = - ev->u.get_stats.sid; + evstat->u.get_stats.conn_handle = + ev->u.get_stats.conn_handle; stats = (struct iscsi_stats *) ((char*)evstat + sizeof(*evstat)); memset(stats, 0, sizeof(*stats)); @@ -761,7 +729,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) skb_trim(skbstat, NLMSG_ALIGN(actual_size)); nlhstat->nlmsg_len = actual_size; - err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid); + err = iscsi_unicast_skb(conn->z_pdu, skbstat); } while (err < 0 && err != -ECONNREFUSED); return err; @@ -772,21 +740,16 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) { struct iscsi_transport *transport = priv->iscsi_transport; struct iscsi_cls_session *session; - unsigned long flags; - uint32_t hostno; + uint32_t sid; - session = transport->create_session(transport, &priv->t, + session = transport->create_session(&priv->t, ev->u.c_session.initial_cmdsn, - &hostno); + &sid); if (!session) return -ENOMEM; - spin_lock_irqsave(&sesslock, flags); - list_add(&session->sess_list, &sesslist); - spin_unlock_irqrestore(&sesslock, flags); - - ev->r.c_session_ret.host_no = hostno; - ev->r.c_session_ret.sid = session->sid; + ev->r.c_session_ret.session_handle = iscsi_handle(session); + ev->r.c_session_ret.sid = sid; return 0; } @@ -797,20 +760,13 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) struct iscsi_cls_session *session; unsigned long flags; - session = iscsi_session_lookup(ev->u.c_conn.sid); - if (!session) { - printk(KERN_ERR "iscsi: invalid session %d\n", - ev->u.c_conn.sid); + session = iscsi_session_lookup(ev->u.c_conn.session_handle); + if (!session) return -EINVAL; - } conn = transport->create_conn(session, ev->u.c_conn.cid); - if (!conn) { - printk(KERN_ERR "iscsi: couldn't create a new " - "connection for session %d\n", - session->sid); + if (!conn) return -ENOMEM; - } conn->z_pdu = mempool_zone_init(Z_MAX_PDU, NLMSG_SPACE(sizeof(struct iscsi_uevent) + @@ -832,8 +788,7 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) goto free_pdu_pool; } - ev->r.c_conn_ret.sid = session->sid; - ev->r.c_conn_ret.cid = conn->cid; + ev->r.handle = iscsi_handle(conn); spin_lock_irqsave(&connlock, flags); list_add(&conn->conn_list, &connlist); @@ -857,7 +812,7 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev struct iscsi_cls_conn *conn; struct mempool_zone *z_error, *z_pdu; - conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); + conn = iscsi_conn_lookup(ev->u.d_conn.conn_handle); if (!conn) return -EINVAL; spin_lock_irqsave(&connlock, flags); @@ -877,106 +832,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev return 0; } -static void -iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) -{ - if (ev->u.set_param.len != sizeof(uint32_t)) - BUG(); - memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), - ev->u.set_param.len)); -} - -static int -iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) -{ - char *data = (char*)ev + sizeof(*ev); - struct iscsi_cls_conn *conn; - struct iscsi_cls_session *session; - int err = 0; - uint32_t value = 0; - - session = iscsi_session_lookup(ev->u.set_param.sid); - conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); - if (!conn || !session) - return -EINVAL; - - switch (ev->u.set_param.param) { - case ISCSI_PARAM_SESS_RECOVERY_TMO: - iscsi_copy_param(ev, &value, data); - if (value != 0) - session->recovery_tmo = value; - break; - case ISCSI_PARAM_TARGET_NAME: - /* this should not change between logins */ - if (session->targetname) - return 0; - - session->targetname = kstrdup(data, GFP_KERNEL); - if (!session->targetname) - return -ENOMEM; - break; - case ISCSI_PARAM_TPGT: - iscsi_copy_param(ev, &value, data); - session->tpgt = value; - break; - case ISCSI_PARAM_PERSISTENT_PORT: - iscsi_copy_param(ev, &value, data); - conn->persistent_port = value; - break; - case ISCSI_PARAM_PERSISTENT_ADDRESS: - /* - * this is the address returned in discovery so it should - * not change between logins. - */ - if (conn->persistent_address) - return 0; - - conn->persistent_address = kstrdup(data, GFP_KERNEL); - if (!conn->persistent_address) - return -ENOMEM; - break; - default: - iscsi_copy_param(ev, &value, data); - err = transport->set_param(conn, ev->u.set_param.param, value); - } - - return err; -} - -static int -iscsi_if_transport_ep(struct iscsi_transport *transport, - struct iscsi_uevent *ev, int msg_type) -{ - struct sockaddr *dst_addr; - int rc = 0; - - switch (msg_type) { - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: - if (!transport->ep_connect) - return -EINVAL; - - dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); - rc = transport->ep_connect(dst_addr, - ev->u.ep_connect.non_blocking, - &ev->r.ep_connect_ret.handle); - break; - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - if (!transport->ep_poll) - return -EINVAL; - - ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle, - ev->u.ep_poll.timeout_ms); - break; - case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: - if (!transport->ep_disconnect) - return -EINVAL; - - transport->ep_disconnect(ev->u.ep_disconnect.ep_handle); - break; - } - return rc; -} - static int iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { @@ -986,7 +841,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct iscsi_internal *priv; struct iscsi_cls_session *session; struct iscsi_cls_conn *conn; - unsigned long flags; priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); if (!priv) @@ -996,21 +850,15 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!try_module_get(transport->owner)) return -EINVAL; - priv->daemon_pid = NETLINK_CREDS(skb)->pid; - switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: err = iscsi_if_create_session(priv, ev); break; case ISCSI_UEVENT_DESTROY_SESSION: - session = iscsi_session_lookup(ev->u.d_session.sid); - if (session) { - spin_lock_irqsave(&sesslock, flags); - list_del(&session->sess_list); - spin_unlock_irqrestore(&sesslock, flags); - + session = iscsi_session_lookup(ev->u.d_session.session_handle); + if (session) transport->destroy_session(session); - } else + else err = -EINVAL; break; case ISCSI_UEVENT_CREATE_CONN: @@ -1020,35 +868,41 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = iscsi_if_destroy_conn(transport, ev); break; case ISCSI_UEVENT_BIND_CONN: - session = iscsi_session_lookup(ev->u.b_conn.sid); - conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); + session = iscsi_session_lookup(ev->u.b_conn.session_handle); + conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle); if (session && conn) ev->r.retcode = transport->bind_conn(session, conn, - ev->u.b_conn.transport_eph, + ev->u.b_conn.transport_fd, ev->u.b_conn.is_leading); else err = -EINVAL; break; case ISCSI_UEVENT_SET_PARAM: - err = iscsi_set_param(transport, ev); + conn = iscsi_conn_lookup(ev->u.set_param.conn_handle); + if (conn) + ev->r.retcode = transport->set_param(conn, + ev->u.set_param.param, ev->u.set_param.value); + else + err = -EINVAL; break; case ISCSI_UEVENT_START_CONN: - conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid); + conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle); if (conn) ev->r.retcode = transport->start_conn(conn); else err = -EINVAL; + break; case ISCSI_UEVENT_STOP_CONN: - conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); + conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle); if (conn) transport->stop_conn(conn, ev->u.stop_conn.flag); else err = -EINVAL; break; case ISCSI_UEVENT_SEND_PDU: - conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); + conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle); if (conn) ev->r.retcode = transport->send_pdu(conn, (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), @@ -1060,11 +914,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case ISCSI_UEVENT_GET_STATS: err = iscsi_if_get_stats(transport, nlh); break; - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: - err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); - break; default: err = -EINVAL; break; @@ -1074,11 +923,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return err; } -/* - * Get message from skb (based on rtnetlink_rcv_skb). Each message is - * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or - * invalid creds are discarded silently. - */ +/* Get message from skb (based on rtnetlink_rcv_skb). Each message is + * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are + * or invalid creds discarded silently. */ static void iscsi_if_rx(struct sock *sk, int len) { @@ -1090,6 +937,7 @@ iscsi_if_rx(struct sock *sk, int len) skb_pull(skb, skb->len); goto free_skb; } + daemon_pid = NETLINK_CREDS(skb)->pid; while (skb->len >= NLMSG_SPACE(0)) { int err; @@ -1140,10 +988,6 @@ iscsi_if_rx(struct sock *sk, int len) #define iscsi_cdev_to_conn(_cdev) \ iscsi_dev_to_conn(_cdev->dev) -#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \ -struct class_device_attribute class_device_attr_##_prefix##_##_name = \ - __ATTR(_name,_mode,_show,_store) - /* * iSCSI connection attrs */ @@ -1161,8 +1005,7 @@ show_conn_int_param_##param(struct class_device *cdev, char *buf) \ #define iscsi_conn_int_attr(field, param, format) \ iscsi_conn_int_attr_show(param, format) \ -static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ - NULL); +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL); iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); @@ -1170,26 +1013,6 @@ iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); -iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); -iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); -iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); - -#define iscsi_conn_str_attr_show(param) \ -static ssize_t \ -show_conn_str_param_##param(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ - struct iscsi_transport *t = conn->transport; \ - return t->get_conn_str_param(conn, param, buf); \ -} - -#define iscsi_conn_str_attr(field, param) \ - iscsi_conn_str_attr_show(param) \ -static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ - NULL); - -iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); -iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); #define iscsi_cdev_to_session(_cdev) \ iscsi_dev_to_session(_cdev->dev) @@ -1211,8 +1034,7 @@ show_session_int_param_##param(struct class_device *cdev, char *buf) \ #define iscsi_session_int_attr(field, param, format) \ iscsi_session_int_attr_show(param, format) \ -static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ - NULL); +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL); iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); @@ -1222,89 +1044,18 @@ iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); -iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); - -#define iscsi_session_str_attr_show(param) \ -static ssize_t \ -show_session_str_param_##param(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ - struct iscsi_transport *t = session->transport; \ - return t->get_session_str_param(session, param, buf); \ -} - -#define iscsi_session_str_attr(field, param) \ - iscsi_session_str_attr_show(param) \ -static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ - NULL); - -iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); - -/* - * Private session and conn attrs. userspace uses several iscsi values - * to identify each session between reboots. Some of these values may not - * be present in the iscsi_transport/LLD driver becuase userspace handles - * login (and failback for login redirect) so for these type of drivers - * the class manages the attrs and values for the iscsi_transport/LLD - */ -#define iscsi_priv_session_attr_show(field, format) \ -static ssize_t \ -show_priv_session_##field(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ - return sprintf(buf, format"\n", session->field); \ -} - -#define iscsi_priv_session_attr(field, format) \ - iscsi_priv_session_attr_show(field, format) \ -static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ - NULL) -iscsi_priv_session_attr(targetname, "%s"); -iscsi_priv_session_attr(tpgt, "%d"); -iscsi_priv_session_attr(recovery_tmo, "%d"); - -#define iscsi_priv_conn_attr_show(field, format) \ -static ssize_t \ -show_priv_conn_##field(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ - return sprintf(buf, format"\n", conn->field); \ -} -#define iscsi_priv_conn_attr(field, format) \ - iscsi_priv_conn_attr_show(field, format) \ -static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ - NULL) -iscsi_priv_conn_attr(persistent_address, "%s"); -iscsi_priv_conn_attr(persistent_port, "%d"); - -#define SETUP_PRIV_SESSION_RD_ATTR(field) \ -do { \ - priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ - count++; \ -} while (0) - -#define SETUP_SESSION_RD_ATTR(field, param_flag) \ -do { \ - if (tt->param_mask & param_flag) { \ - priv->session_attrs[count] = &class_device_attr_sess_##field; \ +#define SETUP_SESSION_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->session_attrs[count] = &class_device_attr_##field;\ count++; \ - } \ -} while (0) - -#define SETUP_PRIV_CONN_RD_ATTR(field) \ -do { \ - priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ - count++; \ -} while (0) - -#define SETUP_CONN_RD_ATTR(field, param_flag) \ -do { \ - if (tt->param_mask & param_flag) { \ - priv->conn_attrs[count] = &class_device_attr_conn_##field; \ + } + +#define SETUP_CONN_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->conn_attrs[count] = &class_device_attr_##field; \ count++; \ - } \ -} while (0) + } static int iscsi_session_match(struct attribute_container *cont, struct device *dev) @@ -1353,24 +1104,6 @@ static int iscsi_conn_match(struct attribute_container *cont, return &priv->conn_cont.ac == cont; } -static int iscsi_host_match(struct attribute_container *cont, - struct device *dev) -{ - struct Scsi_Host *shost; - struct iscsi_internal *priv; - - if (!scsi_is_host_device(dev)) - return 0; - - shost = dev_to_shost(dev); - if (!shost->transportt || - shost->transportt->host_attrs.ac.class != &iscsi_host_class.class) - return 0; - - priv = to_iscsi_internal(shost->transportt); - return &priv->t.host_attrs.ac == cont; -} - struct scsi_transport_template * iscsi_register_transport(struct iscsi_transport *tt) { @@ -1389,7 +1122,6 @@ iscsi_register_transport(struct iscsi_transport *tt) return NULL; INIT_LIST_HEAD(&priv->list); priv->iscsi_transport = tt; - priv->t.user_scan = iscsi_user_scan; priv->cdev.class = &iscsi_transport_class; snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name); @@ -1401,13 +1133,18 @@ iscsi_register_transport(struct iscsi_transport *tt) if (err) goto unregister_cdev; - /* host parameters */ - priv->t.host_attrs.ac.attrs = &priv->host_attrs[0]; - priv->t.host_attrs.ac.class = &iscsi_host_class.class; - priv->t.host_attrs.ac.match = iscsi_host_match; - priv->t.host_size = sizeof(struct iscsi_host); - priv->host_attrs[0] = NULL; - transport_container_register(&priv->t.host_attrs); + /* setup parameters mask */ + priv->param_mask = 0xFFFFFFFF; + if (!(tt->caps & CAP_MULTI_R2T)) + priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T); + if (!(tt->caps & CAP_HDRDGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN); + if (!(tt->caps & CAP_DATADGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN); + if (!(tt->caps & CAP_MARKERS)) { + priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN); + priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN); + } /* connection parameters */ priv->conn_cont.ac.attrs = &priv->conn_attrs[0]; @@ -1415,25 +1152,12 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->conn_cont.ac.match = iscsi_conn_match; transport_container_register(&priv->conn_cont); - SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH); - SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH); - SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN); - SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN); - SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN); - SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN); - SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); - SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); - SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); - - if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) - SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); - else - SETUP_PRIV_CONN_RD_ATTR(persistent_address); - - if (tt->param_mask & ISCSI_PERSISTENT_PORT) - SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); - else - SETUP_PRIV_CONN_RD_ATTR(persistent_port); + SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); + SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); + SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN); + SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN); + SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN); + SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN); BUG_ON(count > ISCSI_CONN_ATTRS); priv->conn_attrs[count] = NULL; @@ -1445,25 +1169,14 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->session_cont.ac.match = iscsi_session_match; transport_container_register(&priv->session_cont); - SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN); - SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T); - SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN); - SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST); - SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST); - SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); - SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); - SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); - SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); - - if (tt->param_mask & ISCSI_TARGET_NAME) - SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); - else - SETUP_PRIV_SESSION_RD_ATTR(targetname); - - if (tt->param_mask & ISCSI_TPGT) - SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); - else - SETUP_PRIV_SESSION_RD_ATTR(tpgt); + SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); + SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); + SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN); + SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST); + SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST); + SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); + SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN) + SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL); BUG_ON(count > ISCSI_SESSION_ATTRS); priv->session_attrs[count] = NULL; @@ -1501,7 +1214,6 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) transport_container_unregister(&priv->conn_cont); transport_container_unregister(&priv->session_cont); - transport_container_unregister(&priv->t.host_attrs); sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group); class_device_unregister(&priv->cdev); @@ -1545,13 +1257,9 @@ static __init int iscsi_transport_init(void) if (err) return err; - err = transport_class_register(&iscsi_host_class); - if (err) - goto unregister_transport_class; - err = transport_class_register(&iscsi_connection_class); if (err) - goto unregister_host_class; + goto unregister_transport_class; err = transport_class_register(&iscsi_session_class); if (err) @@ -1580,8 +1288,6 @@ static __init int iscsi_transport_init(void) transport_class_unregister(&iscsi_session_class); unregister_conn_class: transport_class_unregister(&iscsi_connection_class); -unregister_host_class: - transport_class_unregister(&iscsi_host_class); unregister_transport_class: class_unregister(&iscsi_transport_class); return err; @@ -1594,7 +1300,6 @@ static void __exit iscsi_transport_exit(void) netlink_unregister_notifier(&iscsi_nl_notifier); transport_class_unregister(&iscsi_connection_class); transport_class_unregister(&iscsi_session_class); - transport_class_unregister(&iscsi_host_class); class_unregister(&iscsi_transport_class); } diff --git a/trunk/drivers/scsi/scsi_transport_sas.c b/trunk/drivers/scsi/scsi_transport_sas.c index 1fe6b2d01853..f3b16066387c 100644 --- a/trunk/drivers/scsi/scsi_transport_sas.c +++ b/trunk/drivers/scsi/scsi_transport_sas.c @@ -65,7 +65,7 @@ get_sas_##title##_names(u32 table_key, char *buf) \ ssize_t len = 0; \ int i; \ \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ if (table[i].value & table_key) { \ len += sprintf(buf + len, "%s%s", \ prefix, table[i].name); \ @@ -83,7 +83,7 @@ get_sas_##title##_names(u32 table_key, char *buf) \ ssize_t len = 0; \ int i; \ \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ if (table[i].value == table_key) { \ len += sprintf(buf + len, "%s", \ table[i].name); \ @@ -747,18 +747,6 @@ static void sas_end_device_release(struct device *dev) kfree(edev); } -/** - * sas_rphy_initialize - common rphy intialization - * @rphy: rphy to initialise - * - * Used by both sas_end_device_alloc() and sas_expander_alloc() to - * initialise the common rphy component of each. - */ -static void sas_rphy_initialize(struct sas_rphy *rphy) -{ - INIT_LIST_HEAD(&rphy->list); -} - /** * sas_end_device_alloc - allocate an rphy for an end device * @@ -783,7 +771,6 @@ struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d", shost->host_no, parent->port_identifier, parent->number); rdev->rphy.identify.device_type = SAS_END_DEVICE; - sas_rphy_initialize(&rdev->rphy); transport_setup_device(&rdev->rphy.dev); return &rdev->rphy; @@ -822,7 +809,6 @@ struct sas_rphy *sas_expander_alloc(struct sas_phy *parent, sprintf(rdev->rphy.dev.bus_id, "expander-%d:%d", shost->host_no, rdev->rphy.scsi_target_id); rdev->rphy.identify.device_type = type; - sas_rphy_initialize(&rdev->rphy); transport_setup_device(&rdev->rphy.dev); return &rdev->rphy; diff --git a/trunk/drivers/scsi/scsi_transport_spi.c b/trunk/drivers/scsi/scsi_transport_spi.c index ace49d5bd9c4..780aaedcbce9 100644 --- a/trunk/drivers/scsi/scsi_transport_spi.c +++ b/trunk/drivers/scsi/scsi_transport_spi.c @@ -146,7 +146,7 @@ static inline const char *spi_signal_to_string(enum spi_signal_type type) { int i; - for (i = 0; i < ARRAY_SIZE(signal_types); i++) { + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { if (type == signal_types[i].value) return signal_types[i].name; } @@ -156,7 +156,7 @@ static inline enum spi_signal_type spi_signal_to_value(const char *name) { int i, len; - for (i = 0; i < ARRAY_SIZE(signal_types); i++) { + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { len = strlen(signal_types[i].name); if (strncmp(name, signal_types[i].name, len) == 0 && (name[len] == '\n' || name[len] == '\0')) @@ -785,7 +785,6 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) { struct spi_internal *i = to_spi_internal(sdev->host->transportt); struct scsi_target *starget = sdev->sdev_target; - struct Scsi_Host *shost = sdev->host; int len = sdev->inquiry_len; /* first set us up for narrow async */ DV_SET(offset, 0); @@ -845,14 +844,6 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) if (spi_min_period(starget) == 8) DV_SET(pcomp_en, 1); } - /* now that we've done all this, actually check the bus - * signal type (if known). Some devices are stupid on - * a SE bus and still claim they can try LVD only settings */ - if (i->f->get_signalling) - i->f->get_signalling(shost); - if (spi_signalling(shost) == SPI_SIGNAL_SE || - spi_signalling(shost) == SPI_SIGNAL_HVD) - DV_SET(dt, 0); /* Do the read only INQUIRY tests */ spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, spi_dv_device_compare_inquiry); diff --git a/trunk/drivers/scsi/scsi_typedefs.h b/trunk/drivers/scsi/scsi_typedefs.h index 2ed4c5cb7088..29f038b42f60 100644 --- a/trunk/drivers/scsi/scsi_typedefs.h +++ b/trunk/drivers/scsi/scsi_typedefs.h @@ -1,2 +1,3 @@ typedef struct scsi_cmnd Scsi_Cmnd; +typedef struct scsi_request Scsi_Request; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 354199011246..c647d85d97d1 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -175,7 +175,7 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, * it's not worth the risk */ return -EINVAL; - for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { + for (i = 0; i < sizeof(sd_cache_types)/sizeof(sd_cache_types[0]); i++) { const int len = strlen(sd_cache_types[i]); if (strncmp(sd_cache_types[i], buf, len) == 0 && buf[len] == '\n') { @@ -891,7 +891,7 @@ static struct block_device_operations sd_fops = { static void sd_rw_intr(struct scsi_cmnd * SCpnt) { int result = SCpnt->result; - int this_count = SCpnt->request_bufflen; + int this_count = SCpnt->bufflen; int good_bytes = (result == 0 ? this_count : 0); sector_t block_sectors = 1; u64 first_err_block; diff --git a/trunk/drivers/scsi/seagate.c b/trunk/drivers/scsi/seagate.c index 7fa4da4ea64f..0ff83ddf13fe 100644 --- a/trunk/drivers/scsi/seagate.c +++ b/trunk/drivers/scsi/seagate.c @@ -312,7 +312,7 @@ static Signature __initdata signatures[] = { {"IBM F1 V1.2009/22/93", 5, 25, FD}, }; -#define NUM_SIGNATURES ARRAY_SIZE(signatures) +#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature)) #endif /* n OVERRIDE */ /* @@ -457,7 +457,7 @@ int __init seagate_st0x_detect (struct scsi_host_template * tpnt) * space for the on-board RAM instead. */ - for (i = 0; i < ARRAY_SIZE(seagate_bases); ++i) { + for (i = 0; i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i) { void __iomem *p = ioremap(seagate_bases[i], 0x2000); if (!p) continue; diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 98b9312ba8da..b098942445ec 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -2635,7 +2635,8 @@ static int sg_proc_init(void) { int k, mask; - int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr); + int num_leaves = + sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]); struct proc_dir_entry *pdep; struct sg_proc_leaf * leaf; @@ -2660,7 +2661,8 @@ static void sg_proc_cleanup(void) { int k; - int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr); + int num_leaves = + sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]); if (!sg_proc_sgp) return; diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index ebf6579ed698..7c80711e18ed 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -217,7 +217,7 @@ int sr_media_change(struct cdrom_device_info *cdi, int slot) static void rw_intr(struct scsi_cmnd * SCpnt) { int result = SCpnt->result; - int this_count = SCpnt->request_bufflen; + int this_count = SCpnt->bufflen; int good_bytes = (result == 0 ? this_count : 0); int block_sectors = 0; long error_sector; diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index b5218fc0ac86..56cb49006116 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -1193,7 +1193,7 @@ static int st_open(struct inode *inode, struct file *filp) /* Flush the tape buffer before close */ -static int st_flush(struct file *filp, fl_owner_t id) +static int st_flush(struct file *filp) { int result = 0, result2; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -2818,7 +2818,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon (cmdstatp->sense_hdr.sense_key == NO_SENSE || cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) && undone == 0) { - ioctl_result = 0; /* EOF written successfully at EOM */ + ioctl_result = 0; /* EOF written succesfully at EOM */ if (fileno >= 0) fileno++; STps->drv_file = fileno; @@ -3839,7 +3839,7 @@ static int __init st_setup(char *str) break; } } - if (i >= ARRAY_SIZE(parms)) + if (i >= sizeof(parms) / sizeof(struct st_dev_parm)) printk(KERN_WARNING "st: invalid parameter in '%s'\n", stp); stp = strchr(stp, ','); diff --git a/trunk/drivers/scsi/sun3x_esp.c b/trunk/drivers/scsi/sun3x_esp.c index 2e2c1eb15636..cc990bed9683 100644 --- a/trunk/drivers/scsi/sun3x_esp.c +++ b/trunk/drivers/scsi/sun3x_esp.c @@ -332,11 +332,11 @@ static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) struct scatterlist *sg = sp->SCp.buffer; while (sz >= 0) { - sg[sz].dma_address = dvma_map((unsigned long)page_address(sg[sz].page) + + sg[sz].dvma_address = dvma_map((unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); sz--; } - sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address); + sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address); } static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) @@ -350,14 +350,14 @@ static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) struct scatterlist *sg = (struct scatterlist *)sp->buffer; while(sz >= 0) { - dvma_unmap((char *)sg[sz].dma_address); + dvma_unmap((char *)sg[sz].dvma_address); sz--; } } static void dma_advance_sg (Scsi_Cmnd *sp) { - sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dma_address); + sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address); } static int sun3x_esp_release(struct Scsi_Host *instance) diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c index ea82d3df63af..7677fba2ceb5 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -150,7 +150,7 @@ static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) switch(SYM_UCMD_PTR(cmd)->data_mapped) { case 2: - pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir); + pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); break; case 1: pci_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping, @@ -180,7 +180,7 @@ static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) int use_sg; int dma_dir = cmd->sc_data_direction; - use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir); + use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir); if (use_sg > 0) { SYM_UCMD_PTR(cmd)->data_mapped = 2; SYM_UCMD_PTR(cmd)->data_mapping = use_sg; @@ -370,7 +370,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd if (!use_sg) segment = sym_scatter_no_sglist(np, cp, cmd); else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { - struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer; + struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; struct sym_tcb *tp = &np->target[cp->target]; struct sym_tblmove *data; diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c index 940fa1e6f994..a671bdc07450 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -1276,7 +1276,8 @@ static struct sym_chip sym_dev_table[] = { FE_RAM|FE_IO256|FE_LEDC} }; -#define sym_num_devs (ARRAY_SIZE(sym_dev_table)) +#define sym_num_devs \ + (sizeof(sym_dev_table) / sizeof(sym_dev_table[0])) /* * Look up the chip table. diff --git a/trunk/drivers/scsi/t128.c b/trunk/drivers/scsi/t128.c index a24f661b0270..21305fc91479 100644 --- a/trunk/drivers/scsi/t128.c +++ b/trunk/drivers/scsi/t128.c @@ -126,15 +126,15 @@ static struct override { unsigned long address; int irq; -} overrides +} overrides #ifdef T128_OVERRIDE [] __initdata = T128_OVERRIDE; #else - [4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, + [4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0 ,IRQ_AUTO}, {0, IRQ_AUTO}}; #endif -#define NO_OVERRIDES ARRAY_SIZE(overrides) +#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override)) static struct base { unsigned int address; @@ -143,7 +143,7 @@ static struct base { { 0xcc000, 0}, { 0xc8000, 0}, { 0xdc000, 0}, { 0xd8000, 0} }; -#define NO_BASES ARRAY_SIZE(bases) +#define NO_BASES (sizeof (bases) / sizeof (struct base)) static struct signature { const char *string; @@ -152,7 +152,7 @@ static struct signature { {"TSROM: SCSI BIOS, Version 1.12", 0x36}, }; -#define NO_SIGNATURES ARRAY_SIZE(signatures) +#define NO_SIGNATURES (sizeof (signatures) / sizeof (struct signature)) /* * Function : t128_setup(char *str, int *ints) diff --git a/trunk/drivers/scsi/wd33c93.c b/trunk/drivers/scsi/wd33c93.c index 27307fe5a4c8..d8a72609a31d 100644 --- a/trunk/drivers/scsi/wd33c93.c +++ b/trunk/drivers/scsi/wd33c93.c @@ -939,7 +939,6 @@ wd33c93_intr(struct Scsi_Host *instance) DB(DB_INTR, printk("%02x", cmd->SCp.Status)) if (hostdata->level2 >= L2_BASIC) { sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */ - udelay(7); hostdata->state = S_RUNNING_LEVEL2; write_wd33c93(regs, WD_COMMAND_PHASE, 0x50); write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER); @@ -956,7 +955,6 @@ wd33c93_intr(struct Scsi_Host *instance) msg = read_1_byte(regs); sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */ - udelay(7); hostdata->incoming_msg[hostdata->incoming_ptr] = msg; if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE) @@ -1360,7 +1358,6 @@ wd33c93_intr(struct Scsi_Host *instance) } else { /* Verify this is a change to MSG_IN and read the message */ sr = read_wd33c93(regs, WD_SCSI_STATUS); - udelay(7); if (sr == (CSR_ABORT | PHS_MESS_IN) || sr == (CSR_UNEXP | PHS_MESS_IN) || sr == (CSR_SRV_REQ | PHS_MESS_IN)) { @@ -1377,7 +1374,6 @@ wd33c93_intr(struct Scsi_Host *instance) asr); } sr = read_wd33c93(regs, WD_SCSI_STATUS); - udelay(7); if (sr != CSR_MSGIN) printk ("wd33c93: Not paused with ACK on RESEL (%02x)\n", @@ -1705,7 +1701,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) } #define MAX_WD33C93_HOSTS 4 -#define MAX_SETUP_ARGS ARRAY_SIZE(setup_args) +#define MAX_SETUP_ARGS ((int)(sizeof(setup_args) / sizeof(char *))) #define SETUP_BUFFER_SIZE 200 static char setup_buffer[SETUP_BUFFER_SIZE]; static char setup_used[MAX_SETUP_ARGS]; diff --git a/trunk/drivers/scsi/wd7000.c b/trunk/drivers/scsi/wd7000.c index 574955b78a24..fb54a87a80a3 100644 --- a/trunk/drivers/scsi/wd7000.c +++ b/trunk/drivers/scsi/wd7000.c @@ -267,7 +267,7 @@ static const long wd7000_biosaddr[] = { 0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000 }; -#define NUM_ADDRS ARRAY_SIZE(wd7000_biosaddr) +#define NUM_ADDRS (sizeof(wd7000_biosaddr)/sizeof(long)) static const unsigned short wd7000_iobase[] = { 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338, @@ -275,13 +275,13 @@ static const unsigned short wd7000_iobase[] = { 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8, 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8 }; -#define NUM_IOPORTS ARRAY_SIZE(wd7000_iobase) +#define NUM_IOPORTS (sizeof(wd7000_iobase)/sizeof(unsigned short)) static const short wd7000_irq[] = { 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; -#define NUM_IRQS ARRAY_SIZE(wd7000_irq) +#define NUM_IRQS (sizeof(wd7000_irq)/sizeof(short)) static const short wd7000_dma[] = { 5, 6, 7 }; -#define NUM_DMAS ARRAY_SIZE(wd7000_dma) +#define NUM_DMAS (sizeof(wd7000_dma)/sizeof(short)) /* * The following is set up by wd7000_detect, and used thereafter for @@ -317,7 +317,7 @@ static Config configs[] = { {7, 6, 0x350, BUS_ON, BUS_OFF}, /* My configuration (Zaga) */ {-1, -1, 0x0, BUS_ON, BUS_OFF} /* Empty slot */ }; -#define NUM_CONFIGS ARRAY_SIZE(configs) +#define NUM_CONFIGS (sizeof(configs)/sizeof(Config)) /* * The following list defines strings to look for in the BIOS that identify @@ -333,7 +333,7 @@ typedef struct signature { static const Signature signatures[] = { {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */ }; -#define NUM_SIGNATURES ARRAY_SIZE(signatures) +#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature)) /* @@ -1391,7 +1391,7 @@ static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, * */ -static __init int wd7000_detect(struct scsi_host_template *tpnt) +static int wd7000_detect(struct scsi_host_template *tpnt) { short present = 0, biosaddr_ptr, sig_ptr, i, pass; short biosptr[NUM_CONFIGS]; diff --git a/trunk/drivers/serial/8250_pnp.c b/trunk/drivers/serial/8250_pnp.c index 739bc84f91e9..b79ed0665d51 100644 --- a/trunk/drivers/serial/8250_pnp.c +++ b/trunk/drivers/serial/8250_pnp.c @@ -323,10 +323,8 @@ static const struct pnp_device_id pnp_dev_table[] = { { "USR9180", 0 }, /* U.S. Robotics 56K Voice INT PnP*/ { "USR9190", 0 }, - /* Wacom tablets */ - { "WACF004", 0 }, + /* HP Compaq Tablet PC tc1100 Wacom tablet */ { "WACF005", 0 }, - { "WACF006", 0 }, /* Rockwell's (PORALiNK) 33600 INT PNP */ { "WCI0003", 0 }, /* Unkown PnP modems */ diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index 5b48ac22c9c5..5ea778fc1caa 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -354,24 +354,21 @@ config SERIAL_CLPS711X_CONSOLE kernel at boot time.) config SERIAL_S3C2410 - tristate "Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support" + tristate "Samsung S3C2410 Serial port support" depends on ARM && ARCH_S3C2410 select SERIAL_CORE help - Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, + Support for the on-chip UARTs on the Samsung S3C2410X CPU, providing /dev/ttySAC0, 1 and 2 (note, some machines may not provide all of these ports, depending on how the serial port pins are configured. - Currently this driver supports the UARTS on the S3C2410, S3C2440, - S3C2442, S3C2412 and S3C2413 CPUs. - config SERIAL_S3C2410_CONSOLE bool "Support for console on S3C2410 serial port" depends on SERIAL_S3C2410=y select SERIAL_CORE_CONSOLE help - Allow selection of the S3C24XX on-board serial ports for use as + Allow selection of the S3C2410 on-board serial ports for use as an virtual console. Even if you say Y here, the currently visible virtual console @@ -940,23 +937,4 @@ config SERIAL_SGI_IOC3 If you have an SGI Altix with an IOC3 serial card, say Y or M. Otherwise, say N. -config SERIAL_NETX - bool "NetX serial port support" - depends on ARM && ARCH_NETX - select SERIAL_CORE - help - If you have a machine based on a Hilscher NetX SoC you - can enable its onboard serial port by enabling this option. - - To compile this driver as a module, choose M here: the - module will be called netx-serial. - -config SERIAL_NETX_CONSOLE - bool "Console on NetX serial port" - depends on SERIAL_NETX - select SERIAL_CORE_CONSOLE - help - If you have enabled the serial port on the Motorola IMX - CPU you can make it the console by answering Y to this option. - endmenu diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index 927faee0362e..0a71bf68a03f 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -55,4 +55,3 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o obj-$(CONFIG_SERIAL_AT91) += at91_serial.o -obj-$(CONFIG_SERIAL_NETX) += netx-serial.o diff --git a/trunk/drivers/serial/amba-pl010.c b/trunk/drivers/serial/amba-pl010.c index e920d196d0b1..1631414000a2 100644 --- a/trunk/drivers/serial/amba-pl010.c +++ b/trunk/drivers/serial/amba-pl010.c @@ -52,7 +52,7 @@ #include -#define UART_NR 8 +#define UART_NR 2 #define SERIAL_AMBA_MAJOR 204 #define SERIAL_AMBA_MINOR 16 diff --git a/trunk/drivers/serial/ioc4_serial.c b/trunk/drivers/serial/ioc4_serial.c index 717e47bbd784..c620209d7b9a 100644 --- a/trunk/drivers/serial/ioc4_serial.c +++ b/trunk/drivers/serial/ioc4_serial.c @@ -2646,10 +2646,7 @@ static int ioc4_serial_remove_one(struct ioc4_driver_data *idd) struct ioc4_port *port; struct ioc4_soft *soft; - /* If serial driver did not attach, don't try to detach */ control = idd->idd_serial_data; - if (!control) - return 0; for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) { for (port_type = UART_PORT_MIN; @@ -2781,12 +2778,6 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, idd->idd_pci_id)); - /* PCI-RT does not bring out serial connections. - * Do not attach to this particular IOC4. - */ - if (idd->idd_variant == IOC4_VARIANT_PCI_RT) - return 0; - /* request serial registers */ tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET; diff --git a/trunk/drivers/serial/mcfserial.c b/trunk/drivers/serial/mcfserial.c index 8ad242934368..8cbbb954df2c 100644 --- a/trunk/drivers/serial/mcfserial.c +++ b/trunk/drivers/serial/mcfserial.c @@ -60,11 +60,11 @@ struct timer_list mcfrs_timer_struct; #if defined(CONFIG_HW_FEITH) #define CONSOLE_BAUD_RATE 38400 #define DEFAULT_CBAUD B38400 -#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || defined(CONFIG_M5329EVB) +#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) #define CONSOLE_BAUD_RATE 115200 #define DEFAULT_CBAUD B115200 #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ - defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET) + defined(CONFIG_senTec) || defined(CONFIG_SNEHA) #define CONSOLE_BAUD_RATE 19200 #define DEFAULT_CBAUD B19200 #endif @@ -93,7 +93,7 @@ static struct tty_driver *mcfrs_serial_driver; #undef SERIAL_DEBUG_FLOW #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) #define IRQBASE (MCFINT_VECBASE+MCFINT_UART0) #else #define IRQBASE 73 @@ -1545,28 +1545,6 @@ static void mcfrs_irqinit(struct mcf_serial *info) *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2; } -#elif defined(CONFIG_M532x) - volatile unsigned char *uartp; - uartp = info->addr; - switch (info->line) { - case 0: - MCF_INTC0_ICR26 = 0x3; - MCF_INTC0_CIMR = 26; - /* GPIO initialization */ - MCF_GPIO_PAR_UART |= 0x000F; - break; - case 1: - MCF_INTC0_ICR27 = 0x3; - MCF_INTC0_CIMR = 27; - /* GPIO initialization */ - MCF_GPIO_PAR_UART |= 0x0FF0; - break; - case 2: - MCF_INTC0_ICR28 = 0x3; - MCF_INTC0_CIMR = 28; - /* GPIOs also must be initalized, depends on board */ - break; - } #else volatile unsigned char *icrp, *uartp; diff --git a/trunk/drivers/serial/netx-serial.c b/trunk/drivers/serial/netx-serial.c deleted file mode 100644 index c1adc9e4b239..000000000000 --- a/trunk/drivers/serial/netx-serial.c +++ /dev/null @@ -1,749 +0,0 @@ -/* - * drivers/serial/netx-serial.c - * - * Copyright (c) 2005 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#if defined(CONFIG_SERIAL_NETX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* We've been assigned a range on the "Low-density serial ports" major */ -#define SERIAL_NX_MAJOR 204 -#define MINOR_START 170 - -#ifdef CONFIG_SERIAL_NETX_CONSOLE - -enum uart_regs { - UART_DR = 0x00, - UART_SR = 0x04, - UART_LINE_CR = 0x08, - UART_BAUDDIV_MSB = 0x0c, - UART_BAUDDIV_LSB = 0x10, - UART_CR = 0x14, - UART_FR = 0x18, - UART_IIR = 0x1c, - UART_ILPR = 0x20, - UART_RTS_CR = 0x24, - UART_RTS_LEAD = 0x28, - UART_RTS_TRAIL = 0x2c, - UART_DRV_ENABLE = 0x30, - UART_BRM_CR = 0x34, - UART_RXFIFO_IRQLEVEL = 0x38, - UART_TXFIFO_IRQLEVEL = 0x3c, -}; - -#define SR_FE (1<<0) -#define SR_PE (1<<1) -#define SR_BE (1<<2) -#define SR_OE (1<<3) - -#define LINE_CR_BRK (1<<0) -#define LINE_CR_PEN (1<<1) -#define LINE_CR_EPS (1<<2) -#define LINE_CR_STP2 (1<<3) -#define LINE_CR_FEN (1<<4) -#define LINE_CR_5BIT (0<<5) -#define LINE_CR_6BIT (1<<5) -#define LINE_CR_7BIT (2<<5) -#define LINE_CR_8BIT (3<<5) -#define LINE_CR_BITS_MASK (3<<5) - -#define CR_UART_EN (1<<0) -#define CR_SIREN (1<<1) -#define CR_SIRLP (1<<2) -#define CR_MSIE (1<<3) -#define CR_RIE (1<<4) -#define CR_TIE (1<<5) -#define CR_RTIE (1<<6) -#define CR_LBE (1<<7) - -#define FR_CTS (1<<0) -#define FR_DSR (1<<1) -#define FR_DCD (1<<2) -#define FR_BUSY (1<<3) -#define FR_RXFE (1<<4) -#define FR_TXFF (1<<5) -#define FR_RXFF (1<<6) -#define FR_TXFE (1<<7) - -#define IIR_MIS (1<<0) -#define IIR_RIS (1<<1) -#define IIR_TIS (1<<2) -#define IIR_RTIS (1<<3) -#define IIR_MASK 0xf - -#define RTS_CR_AUTO (1<<0) -#define RTS_CR_RTS (1<<1) -#define RTS_CR_COUNT (1<<2) -#define RTS_CR_MOD2 (1<<3) -#define RTS_CR_RTS_POL (1<<4) -#define RTS_CR_CTS_CTR (1<<5) -#define RTS_CR_CTS_POL (1<<6) -#define RTS_CR_STICK (1<<7) - -#define UART_PORT_SIZE 0x40 -#define DRIVER_NAME "netx-uart" - -struct netx_port { - struct uart_port port; -}; - -static void netx_stop_tx(struct uart_port *port) -{ - unsigned int val; - val = readl(port->membase + UART_CR); - writel(val & ~CR_TIE, port->membase + UART_CR); -} - -static void netx_stop_rx(struct uart_port *port) -{ - unsigned int val; - val = readl(port->membase + UART_CR); - writel(val & ~CR_RIE, port->membase + UART_CR); -} - -static void netx_enable_ms(struct uart_port *port) -{ - unsigned int val; - val = readl(port->membase + UART_CR); - writel(val | CR_MSIE, port->membase + UART_CR); -} - -static inline void netx_transmit_buffer(struct uart_port *port) -{ - struct circ_buf *xmit = &port->info->xmit; - - if (port->x_char) { - writel(port->x_char, port->membase + UART_DR); - port->icount.tx++; - port->x_char = 0; - return; - } - - if (uart_tx_stopped(port) || uart_circ_empty(xmit)) { - netx_stop_tx(port); - return; - } - - do { - /* send xmit->buf[xmit->tail] - * out the port here */ - writel(xmit->buf[xmit->tail], port->membase + UART_DR); - xmit->tail = (xmit->tail + 1) & - (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (!(readl(port->membase + UART_FR) & FR_TXFF)); - - if (uart_circ_empty(xmit)) - netx_stop_tx(port); -} - -static void netx_start_tx(struct uart_port *port) -{ - writel( - readl(port->membase + UART_CR) | CR_TIE, port->membase + UART_CR); - - if (!(readl(port->membase + UART_FR) & FR_TXFF)) - netx_transmit_buffer(port); -} - -static unsigned int netx_tx_empty(struct uart_port *port) -{ - return readl(port->membase + UART_FR) & FR_BUSY ? 0 : TIOCSER_TEMT; -} - -static void netx_txint(struct uart_port *port) -{ - struct circ_buf *xmit = &port->info->xmit; - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - netx_stop_tx(port); - return; - } - - netx_transmit_buffer(port); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); -} - -static void netx_rxint(struct uart_port *port, struct pt_regs *regs) -{ - unsigned char rx, flg, status; - struct tty_struct *tty = port->info->tty; - - while (!(readl(port->membase + UART_FR) & FR_RXFE)) { - rx = readl(port->membase + UART_DR); - flg = TTY_NORMAL; - port->icount.rx++; - status = readl(port->membase + UART_SR); - if (status & SR_BE) { - writel(0, port->membase + UART_SR); - if (uart_handle_break(port)) - continue; - } - - if (unlikely(status & (SR_FE | SR_PE | SR_OE))) { - - if (status & SR_PE) - port->icount.parity++; - else if (status & SR_FE) - port->icount.frame++; - if (status & SR_OE) - port->icount.overrun++; - - status &= port->read_status_mask; - - if (status & SR_BE) - flg = TTY_BREAK; - else if (status & SR_PE) - flg = TTY_PARITY; - else if (status & SR_FE) - flg = TTY_FRAME; - } - - if (uart_handle_sysrq_char(port, rx, regs)) - continue; - - uart_insert_char(port, status, SR_OE, rx, flg); - } - - tty_flip_buffer_push(tty); - return; -} - -static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct uart_port *port = (struct uart_port *)dev_id; - unsigned long flags; - unsigned char status; - - spin_lock_irqsave(&port->lock,flags); - - status = readl(port->membase + UART_IIR) & IIR_MASK; - while (status) { - if (status & IIR_RIS) - netx_rxint(port, regs); - if (status & IIR_TIS) - netx_txint(port); - if (status & IIR_MIS) { - if (readl(port->membase + UART_FR) & FR_CTS) - uart_handle_cts_change(port, 1); - else - uart_handle_cts_change(port, 0); - } - writel(0, port->membase + UART_IIR); - status = readl(port->membase + UART_IIR) & IIR_MASK; - } - - spin_unlock_irqrestore(&port->lock,flags); - return IRQ_HANDLED; -} - -static unsigned int netx_get_mctrl(struct uart_port *port) -{ - unsigned int ret = TIOCM_DSR | TIOCM_CAR; - - if (readl(port->membase + UART_FR) & FR_CTS) - ret |= TIOCM_CTS; - - return ret; -} - -static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - unsigned int val; - - if (mctrl & TIOCM_RTS) { - val = readl(port->membase + UART_RTS_CR); - writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR); - } -} - -static void netx_break_ctl(struct uart_port *port, int break_state) -{ - unsigned int line_cr; - spin_lock_irq(&port->lock); - - line_cr = readl(port->membase + UART_LINE_CR); - if (break_state != 0) - line_cr |= LINE_CR_BRK; - else - line_cr &= ~LINE_CR_BRK; - writel(line_cr, port->membase + UART_LINE_CR); - - spin_unlock_irq(&port->lock); -} - -static int netx_startup(struct uart_port *port) -{ - int ret; - - ret = request_irq(port->irq, netx_int, 0, - DRIVER_NAME, port); - if (ret) { - dev_err(port->dev, "unable to grab irq%d\n",port->irq); - goto exit; - } - - writel(readl(port->membase + UART_LINE_CR) | LINE_CR_FEN, - port->membase + UART_LINE_CR); - - writel(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE | CR_UART_EN, - port->membase + UART_CR); - -exit: - return ret; -} - -static void netx_shutdown(struct uart_port *port) -{ - writel(0, port->membase + UART_CR) ; - - free_irq(port->irq, port); -} - -static void -netx_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned int baud, quot; - unsigned char old_cr; - unsigned char line_cr = LINE_CR_FEN; - unsigned char rts_cr = 0; - - switch (termios->c_cflag & CSIZE) { - case CS5: - line_cr |= LINE_CR_5BIT; - break; - case CS6: - line_cr |= LINE_CR_6BIT; - break; - case CS7: - line_cr |= LINE_CR_7BIT; - break; - case CS8: - line_cr |= LINE_CR_8BIT; - break; - } - - if (termios->c_cflag & CSTOPB) - line_cr |= LINE_CR_STP2; - - if (termios->c_cflag & PARENB) { - line_cr |= LINE_CR_PEN; - if (!(termios->c_cflag & PARODD)) - line_cr |= LINE_CR_EPS; - } - - if (termios->c_cflag & CRTSCTS) - rts_cr = RTS_CR_AUTO | RTS_CR_CTS_CTR | RTS_CR_RTS_POL; - - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = baud * 4096; - quot /= 1000; - quot *= 256; - quot /= 100000; - - spin_lock_irq(&port->lock); - - uart_update_timeout(port, termios->c_cflag, baud); - - old_cr = readl(port->membase + UART_CR); - - /* disable interrupts */ - writel(old_cr & ~(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE), - port->membase + UART_CR); - - /* drain transmitter */ - while (readl(port->membase + UART_FR) & FR_BUSY); - - /* disable UART */ - writel(old_cr & ~CR_UART_EN, port->membase + UART_CR); - - /* modem status interrupts */ - old_cr &= ~CR_MSIE; - if (UART_ENABLE_MS(port, termios->c_cflag)) - old_cr |= CR_MSIE; - - writel((quot>>8) & 0xff, port->membase + UART_BAUDDIV_MSB); - writel(quot & 0xff, port->membase + UART_BAUDDIV_LSB); - writel(line_cr, port->membase + UART_LINE_CR); - - writel(rts_cr, port->membase + UART_RTS_CR); - - /* - * Characters to ignore - */ - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= SR_PE; - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= SR_BE; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= SR_PE; - } - - port->read_status_mask = 0; - if (termios->c_iflag & (BRKINT | PARMRK)) - port->read_status_mask |= SR_BE; - if (termios->c_iflag & INPCK) - port->read_status_mask |= SR_PE | SR_FE; - - writel(old_cr, port->membase + UART_CR); - - spin_unlock_irq(&port->lock); -} - -static const char *netx_type(struct uart_port *port) -{ - return port->type == PORT_NETX ? "NETX" : NULL; -} - -static void netx_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, UART_PORT_SIZE); -} - -static int netx_request_port(struct uart_port *port) -{ - return request_mem_region(port->mapbase, UART_PORT_SIZE, - DRIVER_NAME) != NULL ? 0 : -EBUSY; -} - -static void netx_config_port(struct uart_port *port, int flags) -{ - if (flags & UART_CONFIG_TYPE && netx_request_port(port) == 0) - port->type = PORT_NETX; -} - -static int -netx_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - int ret = 0; - - if (ser->type != PORT_UNKNOWN && ser->type != PORT_NETX) - ret = -EINVAL; - - return ret; -} - -static struct uart_ops netx_pops = { - .tx_empty = netx_tx_empty, - .set_mctrl = netx_set_mctrl, - .get_mctrl = netx_get_mctrl, - .stop_tx = netx_stop_tx, - .start_tx = netx_start_tx, - .stop_rx = netx_stop_rx, - .enable_ms = netx_enable_ms, - .break_ctl = netx_break_ctl, - .startup = netx_startup, - .shutdown = netx_shutdown, - .set_termios = netx_set_termios, - .type = netx_type, - .release_port = netx_release_port, - .request_port = netx_request_port, - .config_port = netx_config_port, - .verify_port = netx_verify_port, -}; - -static struct netx_port netx_ports[] = { - { - .port = { - .type = PORT_NETX, - .iotype = UPIO_MEM, - .membase = (char __iomem *)io_p2v(NETX_PA_UART0), - .mapbase = NETX_PA_UART0, - .irq = NETX_IRQ_UART0, - .uartclk = 100000000, - .fifosize = 16, - .flags = UPF_BOOT_AUTOCONF, - .ops = &netx_pops, - .line = 0, - }, - }, { - .port = { - .type = PORT_NETX, - .iotype = UPIO_MEM, - .membase = (char __iomem *)io_p2v(NETX_PA_UART1), - .mapbase = NETX_PA_UART1, - .irq = NETX_IRQ_UART1, - .uartclk = 100000000, - .fifosize = 16, - .flags = UPF_BOOT_AUTOCONF, - .ops = &netx_pops, - .line = 1, - }, - }, { - .port = { - .type = PORT_NETX, - .iotype = UPIO_MEM, - .membase = (char __iomem *)io_p2v(NETX_PA_UART2), - .mapbase = NETX_PA_UART2, - .irq = NETX_IRQ_UART2, - .uartclk = 100000000, - .fifosize = 16, - .flags = UPF_BOOT_AUTOCONF, - .ops = &netx_pops, - .line = 2, - }, - } -}; - -static void netx_console_putchar(struct uart_port *port, int ch) -{ - while (readl(port->membase + UART_FR) & FR_BUSY); - writel(ch, port->membase + UART_DR); -} - -static void -netx_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_port *port = &netx_ports[co->index].port; - unsigned char cr_save; - - cr_save = readl(port->membase + UART_CR); - writel(cr_save | CR_UART_EN, port->membase + UART_CR); - - uart_console_write(port, s, count, netx_console_putchar); - - while (readl(port->membase + UART_FR) & FR_BUSY); - writel(cr_save, port->membase + UART_CR); -} - -static void __init -netx_console_get_options(struct uart_port *port, int *baud, - int *parity, int *bits, int *flow) -{ - unsigned char line_cr; - - *baud = (readl(port->membase + UART_BAUDDIV_MSB) << 8) | - readl(port->membase + UART_BAUDDIV_LSB); - *baud *= 1000; - *baud /= 4096; - *baud *= 1000; - *baud /= 256; - *baud *= 100; - - line_cr = readl(port->membase + UART_LINE_CR); - *parity = 'n'; - if (line_cr & LINE_CR_PEN) { - if (line_cr & LINE_CR_EPS) - *parity = 'e'; - else - *parity = 'o'; - } - - switch (line_cr & LINE_CR_BITS_MASK) { - case LINE_CR_8BIT: - *bits = 8; - break; - case LINE_CR_7BIT: - *bits = 7; - break; - case LINE_CR_6BIT: - *bits = 6; - break; - case LINE_CR_5BIT: - *bits = 5; - break; - } - - if (readl(port->membase + UART_RTS_CR) & RTS_CR_AUTO) - *flow = 'r'; -} - -static int __init -netx_console_setup(struct console *co, char *options) -{ - struct netx_port *sport; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index == -1 || co->index >= ARRAY_SIZE(netx_ports)) - co->index = 0; - sport = &netx_ports[co->index]; - - if (options) { - uart_parse_options(options, &baud, &parity, &bits, &flow); - } else { - /* if the UART is enabled, assume it has been correctly setup - * by the bootloader and get the options - */ - if (readl(sport->port.membase + UART_CR) & CR_UART_EN) { - netx_console_get_options(&sport->port, &baud, - &parity, &bits, &flow); - } - - } - - return uart_set_options(&sport->port, co, baud, parity, bits, flow); -} - -static struct uart_driver netx_reg; -static struct console netx_console = { - .name = "ttyNX", - .write = netx_console_write, - .device = uart_console_device, - .setup = netx_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &netx_reg, -}; - -static int __init netx_console_init(void) -{ - register_console(&netx_console); - return 0; -} -console_initcall(netx_console_init); - -#define NETX_CONSOLE &netx_console -#else -#define NETX_CONSOLE NULL -#endif - -static struct uart_driver netx_reg = { - .owner = THIS_MODULE, - .driver_name = DRIVER_NAME, - .dev_name = "ttyNX", - .major = SERIAL_NX_MAJOR, - .minor = MINOR_START, - .nr = ARRAY_SIZE(netx_ports), - .cons = NETX_CONSOLE, -}; - -static int serial_netx_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct netx_port *sport = platform_get_drvdata(pdev); - - if (sport) - uart_suspend_port(&netx_reg, &sport->port); - - return 0; -} - -static int serial_netx_resume(struct platform_device *pdev) -{ - struct netx_port *sport = platform_get_drvdata(pdev); - - if (sport) - uart_resume_port(&netx_reg, &sport->port); - - return 0; -} - -static int serial_netx_probe(struct platform_device *pdev) -{ - struct uart_port *port = &netx_ports[pdev->id].port; - - dev_info(&pdev->dev, "initialising\n"); - - port->dev = &pdev->dev; - - writel(1, port->membase + UART_RXFIFO_IRQLEVEL); - uart_add_one_port(&netx_reg, &netx_ports[pdev->id].port); - platform_set_drvdata(pdev, &netx_ports[pdev->id]); - - return 0; -} - -static int serial_netx_remove(struct platform_device *pdev) -{ - struct netx_port *sport = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (sport) - uart_remove_one_port(&netx_reg, &sport->port); - - return 0; -} - -static struct platform_driver serial_netx_driver = { - .probe = serial_netx_probe, - .remove = serial_netx_remove, - - .suspend = serial_netx_suspend, - .resume = serial_netx_resume, - - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init netx_serial_init(void) -{ - int ret; - - printk(KERN_INFO "Serial: NetX driver\n"); - - ret = uart_register_driver(&netx_reg); - if (ret) - return ret; - - ret = platform_driver_register(&serial_netx_driver); - if (ret != 0) - uart_unregister_driver(&netx_reg); - - return 0; -} - -static void __exit netx_serial_exit(void) -{ - platform_driver_unregister(&serial_netx_driver); - uart_unregister_driver(&netx_reg); -} - -module_init(netx_serial_init); -module_exit(netx_serial_exit); - -MODULE_AUTHOR("Sascha Hauer"); -MODULE_DESCRIPTION("NetX serial port driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/serial/pxa.c b/trunk/drivers/serial/pxa.c index ae3649568541..77d4568ccc3a 100644 --- a/trunk/drivers/serial/pxa.c +++ b/trunk/drivers/serial/pxa.c @@ -269,6 +269,7 @@ static unsigned int serial_pxa_get_mctrl(struct uart_port *port) unsigned char status; unsigned int ret; +return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; status = serial_in(up, UART_MSR); ret = 0; diff --git a/trunk/drivers/serial/s3c2410.c b/trunk/drivers/serial/s3c2410.c index 837b6da520b3..53c2465bad2d 100644 --- a/trunk/drivers/serial/s3c2410.c +++ b/trunk/drivers/serial/s3c2410.c @@ -872,8 +872,6 @@ static const char *s3c24xx_serial_type(struct uart_port *port) return "S3C2410"; case PORT_S3C2440: return "S3C2440"; - case PORT_S3C2412: - return "S3C2412"; default: return NULL; } @@ -1530,141 +1528,6 @@ static inline void s3c2440_serial_exit(void) #define s3c2440_uart_inf_at NULL #endif /* CONFIG_CPU_S3C2440 */ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) - -static int s3c2412_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - ucon &= ~S3C2412_UCON_CLKMASK; - - if (strcmp(clk->name, "uclk") == 0) - ucon |= S3C2440_UCON_UCLK; - else if (strcmp(clk->name, "pclk") == 0) - ucon |= S3C2440_UCON_PCLK; - else if (strcmp(clk->name, "usysclk") == 0) - ucon |= S3C2412_UCON_USYSCLK; - else { - printk(KERN_ERR "unknown clock source %s\n", clk->name); - return -EINVAL; - } - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - - -static int s3c2412_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - switch (ucon & S3C2412_UCON_CLKMASK) { - case S3C2412_UCON_UCLK: - clk->divisor = 1; - clk->name = "uclk"; - break; - - case S3C2412_UCON_PCLK: - case S3C2412_UCON_PCLK2: - clk->divisor = 1; - clk->name = "pclk"; - break; - - case S3C2412_UCON_USYSCLK: - clk->divisor = 1; - clk->name = "usysclk"; - break; - } - - return 0; -} - -static int s3c2412_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - dbg("%s: port=%p (%08lx), cfg=%p\n", - __FUNCTION__, port, port->mapbase, cfg); - - /* ensure we don't change the clock settings... */ - - ucon &= S3C2412_UCON_CLKMASK; - - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - return 0; -} - -static struct s3c24xx_uart_info s3c2412_uart_inf = { - .name = "Samsung S3C2412 UART", - .type = PORT_S3C2412, - .fifosize = 64, - .rx_fifomask = S3C2440_UFSTAT_RXMASK, - .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, - .rx_fifofull = S3C2440_UFSTAT_RXFULL, - .tx_fifofull = S3C2440_UFSTAT_TXFULL, - .tx_fifomask = S3C2440_UFSTAT_TXMASK, - .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .get_clksrc = s3c2412_serial_getsource, - .set_clksrc = s3c2412_serial_setsource, - .reset_port = s3c2412_serial_resetport, -}; - -/* device management */ - -static int s3c2412_serial_probe(struct platform_device *dev) -{ - dbg("s3c2440_serial_probe: dev=%p\n", dev); - return s3c24xx_serial_probe(dev, &s3c2440_uart_inf); -} - -static struct platform_driver s3c2412_serial_drv = { - .probe = s3c2412_serial_probe, - .remove = s3c24xx_serial_remove, - .suspend = s3c24xx_serial_suspend, - .resume = s3c24xx_serial_resume, - .driver = { - .name = "s3c2412-uart", - .owner = THIS_MODULE, - }, -}; - - -static inline int s3c2412_serial_init(void) -{ - return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf); -} - -static inline void s3c2412_serial_exit(void) -{ - platform_driver_unregister(&s3c2412_serial_drv); -} - -#define s3c2412_uart_inf_at &s3c2412_uart_inf -#else - -static inline int s3c2412_serial_init(void) -{ - return 0; -} - -static inline void s3c2412_serial_exit(void) -{ -} - -#define s3c2412_uart_inf_at NULL -#endif /* CONFIG_CPU_S3C2440 */ - - /* module initialisation code */ static int __init s3c24xx_serial_modinit(void) @@ -1679,7 +1542,6 @@ static int __init s3c24xx_serial_modinit(void) s3c2400_serial_init(); s3c2410_serial_init(); - s3c2412_serial_init(); s3c2440_serial_init(); return 0; @@ -1689,7 +1551,6 @@ static void __exit s3c24xx_serial_modexit(void) { s3c2400_serial_exit(); s3c2410_serial_exit(); - s3c2412_serial_exit(); s3c2440_serial_exit(); uart_unregister_driver(&s3c24xx_uart_drv); @@ -1912,8 +1773,6 @@ static int s3c24xx_serial_initconsole(void) info = s3c2410_uart_inf_at; } else if (strcmp(dev->name, "s3c2440-uart") == 0) { info = s3c2440_uart_inf_at; - } else if (strcmp(dev->name, "s3c2412-uart") == 0) { - info = s3c2412_uart_inf_at; } else { printk(KERN_ERR "s3c24xx: no driver for %s\n", dev->name); return 0; @@ -1937,4 +1796,4 @@ console_initcall(s3c24xx_serial_initconsole); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("Samsung S3C2410/S3C2440/S3C2412 Serial port driver"); +MODULE_DESCRIPTION("Samsung S3C2410/S3C2440 Serial port driver"); diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index ba22e256c6f7..f137804b3133 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -427,32 +427,31 @@ static int __init hv_console_compatible(char *buf, int len) static unsigned int __init get_interrupt(void) { - struct device_node *dev_node; - - dev_node = sun4v_vdev_root->child; - while (dev_node != NULL) { - struct property *prop; - - if (strcmp(dev_node->name, "console")) - goto next_sibling; + const char *cons_str = "console"; + const char *compat_str = "compatible"; + int node = prom_getchild(sun4v_vdev_root); + char buf[64]; + int err, len; + + node = prom_searchsiblings(node, cons_str); + if (!node) + return 0; - prop = of_find_property(dev_node, "compatible", NULL); - if (!prop) - goto next_sibling; + len = prom_getproplen(node, compat_str); + if (len == 0 || len == -1) + return 0; - if (hv_console_compatible(prop->value, prop->length)) - break; + err = prom_getproperty(node, compat_str, buf, 64); + if (err == -1) + return 0; - next_sibling: - dev_node = dev_node->sibling; - } - if (!dev_node) + if (!hv_console_compatible(buf, len)) return 0; /* Ok, the this is the OBP node for the sun4v hypervisor * console device. Decode the interrupt. */ - return sun4v_vdev_device_interrupt(dev_node); + return sun4v_vdev_device_interrupt(node); } static int __init sunhv_init(void) diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index e4c0fd2d6a9d..bfbe9dc90cca 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -984,19 +984,19 @@ static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device * for_each_ebus(ebus) { for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_node->name, "se")) { + if (!strcmp(edev->prom_name, "se")) { callback(edev, arg); continue; - } else if (!strcmp(edev->prom_node->name, "serial")) { - char *compat; + } else if (!strcmp(edev->prom_name, "serial")) { + char compat[32]; int clen; /* On RIO this can be an SE, check it. We could * just check ebus->is_rio, but this is more portable. */ - compat = of_get_property(edev->prom_node, - "compatible", &clen); - if (compat && clen > 0) { + clen = prom_getproperty(edev->prom_node, "compatible", + compat, sizeof(compat)); + if (clen > 0) { if (strncmp(compat, "sab82532", 8) == 0) { callback(edev, arg); continue; diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 0268b307c01e..4cdb610cdd37 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -1053,7 +1053,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) */ for_each_ebus(ebus) { for_each_ebusdev(dev, ebus) { - if (dev->prom_node->node == up->port_node) { + if (dev->prom_node == up->port_node) { /* * The EBus is broken on sparc; it delivers * virtual addresses in resources. Oh well... @@ -1073,7 +1073,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) #ifdef CONFIG_SPARC64 for_each_isa(isa_br) { for_each_isadev(isa_dev, isa_br) { - if (isa_dev->prom_node->node == up->port_node) { + if (isa_dev->prom_node == up->port_node) { /* Same on sparc64. Cool architecure... */ up->port.membase = (char *) isa_dev->resource.start; up->port.mapbase = isa_dev->resource.start; diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 76c9bac9271f..5b6569728a9c 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -1106,7 +1106,7 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode) + FHC_UREGS_ICLR; imap = central_bus->child->fhc_regs.uregs + FHC_UREGS_IMAP; - zilog_irq = build_irq(0, iclr, imap); + zilog_irq = build_irq(12, 0, iclr, imap); } else { err = prom_getproperty(zsnode, "interrupts", (char *) &sun4u_ino, diff --git a/trunk/drivers/sn/ioc3.c b/trunk/drivers/sn/ioc3.c index ed946311d3a4..501316b198e5 100644 --- a/trunk/drivers/sn/ioc3.c +++ b/trunk/drivers/sn/ioc3.c @@ -26,7 +26,7 @@ static DECLARE_RWSEM(ioc3_devices_rwsem); static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES]; static struct ioc3_submodule *ioc3_ethernet; -static DEFINE_RWLOCK(ioc3_submodules_lock); +static rwlock_t ioc3_submodules_lock = RW_LOCK_UNLOCKED; /* NIC probing code */ diff --git a/trunk/drivers/sn/ioc4.c b/trunk/drivers/sn/ioc4.c index 8256a97eb508..cdeff909403e 100644 --- a/trunk/drivers/sn/ioc4.c +++ b/trunk/drivers/sn/ioc4.c @@ -160,6 +160,9 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) writel(0, &idd->idd_misc_regs->int_out.raw); mmiowb(); + printk(KERN_INFO + "%s: Calibrating PCI bus speed " + "for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev)); /* Set up square wave */ int_out.raw = 0; int_out.fields.count = IOC4_CALIBRATE_COUNT; @@ -203,16 +206,11 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) /* Bounds check the result. */ if (period > IOC4_CALIBRATE_LOW_LIMIT || period < IOC4_CALIBRATE_HIGH_LIMIT) { - printk(KERN_INFO - "IOC4 %s: Clock calibration failed. Assuming" - "PCI clock is %d ns.\n", - pci_name(idd->idd_pdev), + printk("failed. Assuming PCI clock ticks are %d ns.\n", IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); period = IOC4_CALIBRATE_DEFAULT; } else { - printk(KERN_DEBUG - "IOC4 %s: PCI clock is %ld ns.\n", - pci_name(idd->idd_pdev), + printk("succeeded. PCI clock ticks are %ld ns.\n", period / IOC4_EXTINT_COUNT_DIVISOR); } @@ -224,51 +222,6 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) idd->count_period = period; } -/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT. - * Each brings out different combinations of IOC4 signals, thus. - * the IOC4 subdrivers need to know to which we're attached. - * - * We look for the presence of a SCSI (IO9) or SATA (IO10) controller - * on the same PCI bus at slot number 3 to differentiate IO9 from IO10. - * If neither is present, it's a PCI-RT. - */ -static unsigned int -ioc4_variant(struct ioc4_driver_data *idd) -{ - struct pci_dev *pdev = NULL; - int found = 0; - - /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */ - do { - pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC, - PCI_DEVICE_ID_QLOGIC_ISP12160, pdev); - if (pdev && - idd->idd_pdev->bus->number == pdev->bus->number && - 3 == PCI_SLOT(pdev->devfn)) - found = 1; - pci_dev_put(pdev); - } while (pdev && !found); - if (NULL != pdev) - return IOC4_VARIANT_IO9; - - /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */ - pdev = NULL; - do { - pdev = pci_get_device(PCI_VENDOR_ID_VITESSE, - PCI_DEVICE_ID_VITESSE_VSC7174, pdev); - if (pdev && - idd->idd_pdev->bus->number == pdev->bus->number && - 3 == PCI_SLOT(pdev->devfn)) - found = 1; - pci_dev_put(pdev); - } while (pdev && !found); - if (NULL != pdev) - return IOC4_VARIANT_IO10; - - /* PCI-RT: No SCSI/SATA controller will be present */ - return IOC4_VARIANT_PCI_RT; -} - /* Adds a new instance of an IOC4 card */ static int ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) @@ -333,13 +286,6 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) /* Failsafe portion of per-IOC4 initialization */ - /* Detect card variant */ - idd->idd_variant = ioc4_variant(idd); - printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev), - idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" : - idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" : - idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown"); - /* Initialize IOC4 */ pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd); pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index f6b2948ab288..5578a9dd04e8 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/drivers/telephony/ixj.c @@ -5712,7 +5712,7 @@ static int ixj_daa_write(IXJ *j) return 1; } -static int ixj_set_tone_off(unsigned short arg, IXJ *j) +int ixj_set_tone_off(unsigned short arg, IXJ *j) { j->tone_off_time = arg; if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */ diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index c7123bf71c58..9b7d9769fdcc 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -48,7 +48,6 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB_AUERSWALD) += misc/ -obj-$(CONFIG_USB_CY7C63) += misc/ obj-$(CONFIG_USB_CYTHERM) += misc/ obj-$(CONFIG_USB_EMI26) += misc/ obj-$(CONFIG_USB_EMI62) += misc/ @@ -62,7 +61,6 @@ obj-$(CONFIG_USB_TEST) += misc/ obj-$(CONFIG_USB_USS720) += misc/ obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ obj-$(CONFIG_USB_SISUSBVGA) += misc/ -obj-$(CONFIG_USB_APPLEDISPLAY) += misc/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index a38701c742c3..546249843b8e 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -1039,7 +1039,7 @@ static void usbatm_tasklet_schedule(unsigned long data) tasklet_schedule((struct tasklet_struct *) data); } -static void usbatm_init_channel(struct usbatm_channel *channel) +static inline void usbatm_init_channel(struct usbatm_channel *channel) { spin_lock_init(&channel->lock); INIT_LIST_HEAD(&channel->list); diff --git a/trunk/drivers/usb/atm/xusbatm.c b/trunk/drivers/usb/atm/xusbatm.c index 70125c6d3be4..42d6823b82b3 100644 --- a/trunk/drivers/usb/atm/xusbatm.c +++ b/trunk/drivers/usb/atm/xusbatm.c @@ -20,6 +20,7 @@ ******************************************************************************/ #include +#include /* FIXME: required by linux/etherdevice.h */ #include /* for random_ether_addr() */ #include "usbatm.h" diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index d41dc67ba4cc..6dd339f4c0fc 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include @@ -127,8 +127,8 @@ static int acm_wb_alloc(struct acm *acm) wb->use = 1; return wbn; } - wbn = (wbn + 1) % ACM_NW; - if (++i >= ACM_NW) + wbn = (wbn + 1) % ACM_NWB; + if (++i >= ACM_NWB) return -1; } } @@ -142,9 +142,10 @@ static int acm_wb_is_avail(struct acm *acm) { int i, n; - n = ACM_NW; - for (i = 0; i < ACM_NW; i++) { - n -= acm->wb[i].use; + n = 0; + for (i = 0; i < ACM_NWB; i++) { + if (!acm->wb[i].use) + n++; } return n; } @@ -166,7 +167,7 @@ static void acm_write_done(struct acm *acm) acm->write_ready = 1; wbn = acm->write_current; acm_wb_free(acm, wbn); - acm->write_current = (wbn + 1) % ACM_NW; + acm->write_current = (wbn + 1) % ACM_NWB; spin_unlock_irqrestore(&acm->write_lock, flags); } @@ -290,32 +291,22 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) struct acm_rb *buf; struct acm_ru *rcv = urb->context; struct acm *acm = rcv->instance; - int status = urb->status; dbg("Entering acm_read_bulk with status %d\n", urb->status); if (!ACM_READY(acm)) return; - if (status) - dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); + if (urb->status) + dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); buf = rcv->buffer; buf->size = urb->actual_length; - if (likely(status == 0)) { - spin_lock(&acm->read_lock); - list_add_tail(&rcv->list, &acm->spare_read_urbs); - list_add_tail(&buf->list, &acm->filled_read_bufs); - spin_unlock(&acm->read_lock); - } else { - /* we drop the buffer due to an error */ - spin_lock(&acm->read_lock); - list_add_tail(&rcv->list, &acm->spare_read_urbs); - list_add(&buf->list, &acm->spare_read_bufs); - spin_unlock(&acm->read_lock); - /* nevertheless the tasklet must be kicked unconditionally - so the queue cannot dry up */ - } + spin_lock(&acm->read_lock); + list_add_tail(&rcv->list, &acm->spare_read_urbs); + list_add_tail(&buf->list, &acm->filled_read_bufs); + spin_unlock(&acm->read_lock); + tasklet_schedule(&acm->urb_task); } @@ -473,10 +464,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) INIT_LIST_HEAD(&acm->spare_read_urbs); INIT_LIST_HEAD(&acm->spare_read_bufs); INIT_LIST_HEAD(&acm->filled_read_bufs); - for (i = 0; i < acm->rx_buflimit; i++) { + for (i = 0; i < ACM_NRU; i++) { list_add(&(acm->ru[i].list), &acm->spare_read_urbs); } - for (i = 0; i < acm->rx_buflimit; i++) { + for (i = 0; i < ACM_NRB; i++) { list_add(&(acm->rb[i].list), &acm->spare_read_bufs); } @@ -497,15 +488,14 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) static void acm_tty_unregister(struct acm *acm) { - int i,nr; + int i; - nr = acm->rx_buflimit; tty_unregister_device(acm_tty_driver, acm->minor); usb_put_intf(acm->control); acm_table[acm->minor] = NULL; usb_free_urb(acm->ctrlurb); usb_free_urb(acm->writeurb); - for (i = 0; i < nr; i++) + for (i = 0; i < ACM_NRU; i++) usb_free_urb(acm->ru[i].urb); kfree(acm); } @@ -513,19 +503,18 @@ static void acm_tty_unregister(struct acm *acm) static void acm_tty_close(struct tty_struct *tty, struct file *filp) { struct acm *acm = tty->driver_data; - int i,nr; + int i; if (!acm || !acm->used) return; - nr = acm->rx_buflimit; mutex_lock(&open_mutex); if (!--acm->used) { if (acm->dev) { acm_set_control(acm, acm->ctrlout = 0); usb_kill_urb(acm->ctrlurb); usb_kill_urb(acm->writeurb); - for (i = 0; i < nr; i++) + for (i = 0; i < ACM_NRU; i++) usb_kill_urb(acm->ru[i].urb); } else acm_tty_unregister(acm); @@ -587,7 +576,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) /* * This is inaccurate (overcounts), but it works. */ - return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize; + return (ACM_NWB - acm_wb_is_avail(acm)) * acm->writesize; } static void acm_tty_throttle(struct tty_struct *tty) @@ -723,7 +712,7 @@ static void acm_write_buffers_free(struct acm *acm) int i; struct acm_wb *wb; - for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { + for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); } } @@ -734,7 +723,7 @@ static int acm_write_buffers_alloc(struct acm *acm) int i; struct acm_wb *wb; - for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { + for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, &wb->dmah); if (!wb->buf) { @@ -771,14 +760,10 @@ static int acm_probe (struct usb_interface *intf, int call_interface_num = -1; int data_interface_num; unsigned long quirks; - int num_rx_buf; int i; - /* normal quirks */ - quirks = (unsigned long)id->driver_info; - num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; - /* handle quirks deadly to normal probing*/ + quirks = (unsigned long)id->driver_info; if (quirks == NO_UNION_NORMAL) { data_interface = usb_ifnum_to_if(usb_dev, 1); control_interface = usb_ifnum_to_if(usb_dev, 0); @@ -915,7 +900,7 @@ static int acm_probe (struct usb_interface *intf, } ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); - readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2); + readsize = le16_to_cpu(epread->wMaxPacketSize)*2; acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); acm->control = control_interface; acm->data = data_interface; @@ -924,7 +909,6 @@ static int acm_probe (struct usb_interface *intf, acm->ctrl_caps = ac_management_function; acm->ctrlsize = ctrlsize; acm->readsize = readsize; - acm->rx_buflimit = num_rx_buf; acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint, acm); @@ -951,7 +935,7 @@ static int acm_probe (struct usb_interface *intf, dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); goto alloc_fail5; } - for (i = 0; i < num_rx_buf; i++) { + for (i = 0; i < ACM_NRU; i++) { struct acm_ru *rcv = &(acm->ru[i]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { @@ -962,9 +946,10 @@ static int acm_probe (struct usb_interface *intf, rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = acm; } - for (i = 0; i < num_rx_buf; i++) { + for (i = 0; i < ACM_NRB; i++) { struct acm_rb *buf = &(acm->rb[i]); + // Using usb_buffer_alloc instead of kmalloc as Oliver suggested if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); goto alloc_fail7; @@ -1003,9 +988,9 @@ static int acm_probe (struct usb_interface *intf, return 0; alloc_fail7: - for (i = 0; i < num_rx_buf; i++) + for (i = 0; i < ACM_NRB; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); - for (i = 0; i < num_rx_buf; i++) + for (i = 0; i < ACM_NRU; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); alloc_fail5: @@ -1042,7 +1027,7 @@ static void acm_disconnect(struct usb_interface *intf) usb_kill_urb(acm->ctrlurb); usb_kill_urb(acm->writeurb); - for (i = 0; i < acm->rx_buflimit; i++) + for (i = 0; i < ACM_NRU; i++) usb_kill_urb(acm->ru[i].urb); INIT_LIST_HEAD(&acm->filled_read_bufs); @@ -1054,7 +1039,7 @@ static void acm_disconnect(struct usb_interface *intf) acm_write_buffers_free(acm); usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); - for (i = 0; i < acm->rx_buflimit; i++) + for (i = 0; i < ACM_NRB; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); @@ -1083,9 +1068,6 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, - { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */ - .driver_info = SINGLE_RX_URB, /* firmware bug */ - }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_ACM_PROTO_AT_V25TER) }, diff --git a/trunk/drivers/usb/class/cdc-acm.h b/trunk/drivers/usb/class/cdc-acm.h index 1bcaea32cfc1..fd2aaccdcbac 100644 --- a/trunk/drivers/usb/class/cdc-acm.h +++ b/trunk/drivers/usb/class/cdc-acm.h @@ -56,11 +56,11 @@ * in line disciplines. They ask for empty space amount, receive our URB size, * and proceed to issue several 1-character writes, assuming they will fit. * The very first write takes a complete URB. Fortunately, this only happens - * when processing onlcr, so we only need 2 buffers. These values must be - * powers of 2. + * when processing onlcr, so we only need 2 buffers. */ -#define ACM_NW 2 -#define ACM_NR 16 +#define ACM_NWB 2 +#define ACM_NRU 16 +#define ACM_NRB 16 struct acm_wb { unsigned char *buf; @@ -91,10 +91,9 @@ struct acm { struct urb *ctrlurb, *writeurb; /* urbs */ u8 *ctrl_buffer; /* buffers of urbs */ dma_addr_t ctrl_dma; /* dma handles of buffers */ - struct acm_wb wb[ACM_NW]; - struct acm_ru ru[ACM_NR]; - struct acm_rb rb[ACM_NR]; - int rx_buflimit; + struct acm_wb wb[ACM_NWB]; + struct acm_ru ru[ACM_NRU]; + struct acm_rb rb[ACM_NRB]; int rx_endpoint; spinlock_t read_lock; struct list_head spare_read_urbs; @@ -123,4 +122,3 @@ struct acm { /* constants describing various quirks and errors */ #define NO_UNION_NORMAL 1 -#define SINGLE_RX_URB 2 diff --git a/trunk/drivers/usb/core/Makefile b/trunk/drivers/usb/core/Makefile index ec510922af63..28329ddf187c 100644 --- a/trunk/drivers/usb/core/Makefile +++ b/trunk/drivers/usb/core/Makefile @@ -3,8 +3,7 @@ # usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ - config.o file.o buffer.o sysfs.o endpoint.o \ - devio.o notify.o + config.o file.o buffer.o sysfs.o devio.o notify.o ifeq ($(CONFIG_PCI),y) usbcore-objs += hcd-pci.o diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index bcbeaf7101d1..545da37afca7 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -515,19 +515,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig static struct usb_device *usbdev_lookup_minor(int minor) { - struct device *device; - struct usb_device *udev = NULL; + struct class_device *class_dev; + struct usb_device *dev = NULL; down(&usb_device_class->sem); - list_for_each_entry(device, &usb_device_class->devices, node) { - if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { - udev = device->platform_data; + list_for_each_entry(class_dev, &usb_device_class->children, node) { + if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { + dev = class_dev->class_data; break; } } up(&usb_device_class->sem); - return udev; + return dev; }; /* @@ -823,7 +823,8 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg) static int proc_resetdevice(struct dev_state *ps) { - return usb_reset_composite_device(ps->dev, NULL); + return usb_reset_device(ps->dev); + } static int proc_setintf(struct dev_state *ps, void __user *arg) @@ -922,8 +923,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) return -EINVAL; - /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ - if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) + /* min 8 byte setup packet, max arbitrary */ + if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE) return -EINVAL; if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) return -ENOMEM; @@ -981,8 +982,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EFAULT; } for (totlen = u = 0; u < uurb->number_of_packets; u++) { - /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */ - if (isopkt[u].length > 8192) { + if (isopkt[u].length > 1023) { kfree(isopkt); return -EINVAL; } @@ -1576,16 +1576,16 @@ static void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); - dev->usbfs_dev = device_create(usb_device_class, &dev->dev, - MKDEV(USB_DEVICE_MAJOR, minor), + dev->class_dev = class_device_create(usb_device_class, NULL, + MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, "usbdev%d.%d", dev->bus->busnum, dev->devnum); - dev->usbfs_dev->platform_data = dev; + dev->class_dev->class_data = dev; } static void usbdev_remove(struct usb_device *dev) { - device_unregister(dev->usbfs_dev); + class_device_unregister(dev->class_dev); } static int usbdev_notify(struct notifier_block *self, unsigned long action, diff --git a/trunk/drivers/usb/core/endpoint.c b/trunk/drivers/usb/core/endpoint.c deleted file mode 100644 index 247b5a4913a8..000000000000 --- a/trunk/drivers/usb/core/endpoint.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * drivers/usb/core/endpoint.c - * - * (C) Copyright 2002,2004,2006 Greg Kroah-Hartman - * (C) Copyright 2002,2004 IBM Corp. - * (C) Copyright 2006 Novell Inc. - * - * Endpoint sysfs stuff - * - */ - -#include -#include -#include "usb.h" - -/* endpoint stuff */ - -struct ep_device { - struct usb_endpoint_descriptor *desc; - struct usb_device *udev; - struct device dev; -}; -#define to_ep_device(_dev) \ - container_of(_dev, struct ep_device, dev) - -struct ep_attribute { - struct attribute attr; - ssize_t (*show)(struct usb_device *, - struct usb_endpoint_descriptor *, char *); -}; -#define to_ep_attribute(_attr) \ - container_of(_attr, struct ep_attribute, attr) - -#define usb_ep_attr(field, format_string) \ -static ssize_t show_ep_##field(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ep_device *ep = to_ep_device(dev); \ - return sprintf(buf, format_string, ep->desc->field); \ -} \ -static DEVICE_ATTR(field, S_IRUGO, show_ep_##field, NULL); - -usb_ep_attr(bLength, "%02x\n") -usb_ep_attr(bEndpointAddress, "%02x\n") -usb_ep_attr(bmAttributes, "%02x\n") -usb_ep_attr(bInterval, "%02x\n") - -static ssize_t show_ep_wMaxPacketSize(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ep_device *ep = to_ep_device(dev); - return sprintf(buf, "%04x\n", - le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff); -} -static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL); - -static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ep_device *ep = to_ep_device(dev); - char *type = "unknown"; - - switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_CONTROL: - type = "Control"; - break; - case USB_ENDPOINT_XFER_ISOC: - type = "Isoc"; - break; - case USB_ENDPOINT_XFER_BULK: - type = "Bulk"; - break; - case USB_ENDPOINT_XFER_INT: - type = "Interrupt"; - break; - } - return sprintf(buf, "%s\n", type); -} -static DEVICE_ATTR(type, S_IRUGO, show_ep_type, NULL); - -static ssize_t show_ep_interval(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ep_device *ep = to_ep_device(dev); - char unit; - unsigned interval = 0; - unsigned in; - - in = (ep->desc->bEndpointAddress & USB_DIR_IN); - - switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_CONTROL: - if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ - interval = ep->desc->bInterval; - break; - case USB_ENDPOINT_XFER_ISOC: - interval = 1 << (ep->desc->bInterval - 1); - break; - case USB_ENDPOINT_XFER_BULK: - if (ep->udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ - interval = ep->desc->bInterval; - break; - case USB_ENDPOINT_XFER_INT: - if (ep->udev->speed == USB_SPEED_HIGH) - interval = 1 << (ep->desc->bInterval - 1); - else - interval = ep->desc->bInterval; - break; - } - interval *= (ep->udev->speed == USB_SPEED_HIGH) ? 125 : 1000; - if (interval % 1000) - unit = 'u'; - else { - unit = 'm'; - interval /= 1000; - } - - return sprintf(buf, "%d%cs\n", interval, unit); -} -static DEVICE_ATTR(interval, S_IRUGO, show_ep_interval, NULL); - -static ssize_t show_ep_direction(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ep_device *ep = to_ep_device(dev); - char *direction; - - if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_CONTROL) - direction = "both"; - else if (ep->desc->bEndpointAddress & USB_DIR_IN) - direction = "in"; - else - direction = "out"; - return sprintf(buf, "%s\n", direction); -} -static DEVICE_ATTR(direction, S_IRUGO, show_ep_direction, NULL); - -static struct attribute *ep_dev_attrs[] = { - &dev_attr_bLength.attr, - &dev_attr_bEndpointAddress.attr, - &dev_attr_bmAttributes.attr, - &dev_attr_bInterval.attr, - &dev_attr_wMaxPacketSize.attr, - &dev_attr_interval.attr, - &dev_attr_type.attr, - &dev_attr_direction.attr, - NULL, -}; -static struct attribute_group ep_dev_attr_grp = { - .attrs = ep_dev_attrs, -}; - -static struct endpoint_class { - struct kref kref; - struct class *class; -} *ep_class; - -static int init_endpoint_class(void) -{ - int result = 0; - - if (ep_class != NULL) { - kref_get(&ep_class->kref); - goto exit; - } - - ep_class = kmalloc(sizeof(*ep_class), GFP_KERNEL); - if (!ep_class) { - result = -ENOMEM; - goto exit; - } - - kref_init(&ep_class->kref); - ep_class->class = class_create(THIS_MODULE, "usb_endpoint"); - if (IS_ERR(ep_class->class)) { - result = IS_ERR(ep_class->class); - kfree(ep_class); - ep_class = NULL; - goto exit; - } - -exit: - return result; -} - -static void release_endpoint_class(struct kref *kref) -{ - /* Ok, we cheat as we know we only have one ep_class */ - class_destroy(ep_class->class); - kfree(ep_class); - ep_class = NULL; -} - -static void destroy_endpoint_class(void) -{ - if (ep_class) - kref_put(&ep_class->kref, release_endpoint_class); -} - -static void ep_device_release(struct device *dev) -{ - struct ep_device *ep_dev = to_ep_device(dev); - - dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); - kfree(ep_dev); -} - -void usb_create_ep_files(struct device *parent, - struct usb_host_endpoint *endpoint, - struct usb_device *udev) -{ - char name[8]; - struct ep_device *ep_dev; - int minor; - int retval; - - retval = init_endpoint_class(); - if (retval) - goto exit; - - ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); - if (!ep_dev) { - retval = -ENOMEM; - goto exit; - } - - /* fun calculation to determine the minor of this endpoint */ - minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1); - - ep_dev->desc = &endpoint->desc; - ep_dev->udev = udev; - ep_dev->dev.devt = MKDEV(442, minor); // FIXME fake number... - ep_dev->dev.class = ep_class->class; - ep_dev->dev.parent = parent; - ep_dev->dev.release = ep_device_release; - snprintf(ep_dev->dev.bus_id, BUS_ID_SIZE, "usbdev%d.%d_ep%02x", - udev->bus->busnum, udev->devnum, - endpoint->desc.bEndpointAddress); - - retval = device_register(&ep_dev->dev); - if (retval) - goto error; - sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); - - endpoint->ep_dev = ep_dev; - - /* create the symlink to the old-style "ep_XX" directory */ - sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); - sysfs_create_link(&parent->kobj, &endpoint->ep_dev->dev.kobj, name); - -exit: - return; -error: - kfree(ep_dev); - return; -} - -void usb_remove_ep_files(struct usb_host_endpoint *endpoint) -{ - - if (endpoint->ep_dev) { - char name[8]; - - sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); - sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name); - sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp); - device_unregister(&endpoint->ep_dev->dev); - endpoint->ep_dev = NULL; - } - destroy_endpoint_class(); -} - - diff --git a/trunk/drivers/usb/core/file.c b/trunk/drivers/usb/core/file.c index f65b193cde3d..b263a54a13c0 100644 --- a/trunk/drivers/usb/core/file.c +++ b/trunk/drivers/usb/core/file.c @@ -61,66 +61,33 @@ static struct file_operations usb_fops = { .open = usb_open, }; -static struct usb_class { - struct kref kref; - struct class *class; -} *usb_class; - -static int init_usb_class(void) -{ - int result = 0; - - if (usb_class != NULL) { - kref_get(&usb_class->kref); - goto exit; - } - - usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL); - if (!usb_class) { - result = -ENOMEM; - goto exit; - } - - kref_init(&usb_class->kref); - usb_class->class = class_create(THIS_MODULE, "usb"); - if (IS_ERR(usb_class->class)) { - result = IS_ERR(usb_class->class); - err("class_create failed for usb devices"); - kfree(usb_class); - usb_class = NULL; - } - -exit: - return result; -} - -static void release_usb_class(struct kref *kref) -{ - /* Ok, we cheat as we know we only have one usb_class */ - class_destroy(usb_class->class); - kfree(usb_class); - usb_class = NULL; -} - -static void destroy_usb_class(void) -{ - if (usb_class) - kref_put(&usb_class->kref, release_usb_class); -} +static struct class *usb_class; int usb_major_init(void) { int error; error = register_chrdev(USB_MAJOR, "usb", &usb_fops); - if (error) + if (error) { err("unable to get major %d for usb devices", USB_MAJOR); + goto out; + } + usb_class = class_create(THIS_MODULE, "usb"); + if (IS_ERR(usb_class)) { + error = PTR_ERR(usb_class); + err("class_create failed for usb devices"); + unregister_chrdev(USB_MAJOR, "usb"); + goto out; + } + +out: return error; } void usb_major_cleanup(void) { + class_destroy(usb_class); unregister_chrdev(USB_MAJOR, "usb"); } @@ -179,10 +146,6 @@ int usb_register_dev(struct usb_interface *intf, } spin_unlock (&minor_lock); - if (retval) - goto exit; - - retval = init_usb_class(); if (retval) goto exit; @@ -195,13 +158,14 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->usb_dev = device_create(usb_class->class, &intf->dev, - MKDEV(USB_MAJOR, minor), "%s", temp); - if (IS_ERR(intf->usb_dev)) { + intf->class_dev = class_device_create(usb_class, NULL, + MKDEV(USB_MAJOR, minor), + &intf->dev, "%s", temp); + if (IS_ERR(intf->class_dev)) { spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - retval = PTR_ERR(intf->usb_dev); + retval = PTR_ERR(intf->class_dev); } exit: return retval; @@ -242,10 +206,9 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); - intf->usb_dev = NULL; + class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); + intf->class_dev = NULL; intf->minor = -1; - destroy_usb_class(); } EXPORT_SYMBOL(usb_deregister_dev); diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index e1731ff8af4d..90b8d43c6b33 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -432,22 +432,15 @@ static void hub_power_on(struct usb_hub *hub) { int port1; unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; - u16 wHubCharacteristics = - le16_to_cpu(hub->descriptor->wHubCharacteristics); - - /* Enable power on each port. Some hubs have reserved values - * of LPSM (> 2) in their descriptors, even though they are - * USB 2.0 hubs. Some hubs do not implement port-power switching - * but only emulate it. In all cases, the ports won't work - * unless we send these messages to the hub. - */ - if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) + u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); + + /* if hub supports power switching, enable power on each port */ + if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { dev_dbg(hub->intfdev, "enabling power on all ports\n"); - else - dev_dbg(hub->intfdev, "trying to enable port power on " - "non-switchable hub\n"); - for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) - set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); + for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) + set_port_feature(hub->hdev, port1, + USB_PORT_FEAT_POWER); + } /* Wait at least 100 msec for power to become stable */ msleep(max(pgood_delay, (unsigned) 100)); @@ -525,16 +518,15 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) /* caller has locked the hub device */ -static void hub_pre_reset(struct usb_interface *intf) +static void hub_pre_reset(struct usb_hub *hub, int disable_ports) { - struct usb_hub *hub = usb_get_intfdata(intf); struct usb_device *hdev = hub->hdev; int port1; for (port1 = 1; port1 <= hdev->maxchild; ++port1) { if (hdev->children[port1 - 1]) { usb_disconnect(&hdev->children[port1 - 1]); - if (hub->error == 0) + if (disable_ports) hub_port_disable(hub, port1, 0); } } @@ -542,10 +534,8 @@ static void hub_pre_reset(struct usb_interface *intf) } /* caller has locked the hub device */ -static void hub_post_reset(struct usb_interface *intf) +static void hub_post_reset(struct usb_hub *hub) { - struct usb_hub *hub = usb_get_intfdata(intf); - hub_activate(hub); hub_power_on(hub); } @@ -805,16 +795,15 @@ static void hub_disconnect(struct usb_interface *intf) struct usb_hub *hub = usb_get_intfdata (intf); struct usb_device *hdev; - /* Disconnect all children and quiesce the hub */ - hub->error = 0; - hub_pre_reset(intf); - usb_set_intfdata (intf, NULL); hdev = hub->hdev; if (hdev->speed == USB_SPEED_HIGH) highspeed_hubs--; + /* Disconnect all children and quiesce the hub */ + hub_pre_reset(hub, 1); + usb_free_urb(hub->urb); hub->urb = NULL; @@ -1180,7 +1169,6 @@ static int choose_configuration(struct usb_device *udev) { int i; int num_configs; - int insufficient_power = 0; struct usb_host_config *c, *best; best = NULL; @@ -1233,10 +1221,8 @@ static int choose_configuration(struct usb_device *udev) */ /* Rule out configs that draw too much bus current */ - if (c->desc.bMaxPower * 2 > udev->bus_mA) { - insufficient_power++; + if (c->desc.bMaxPower * 2 > udev->bus_mA) continue; - } /* If the first config's first interface is COMM/2/0xff * (MSFT RNDIS), rule it out unless Linux has host-side @@ -1245,7 +1231,7 @@ static int choose_configuration(struct usb_device *udev) && desc->bInterfaceClass == USB_CLASS_COMM && desc->bInterfaceSubClass == 2 && desc->bInterfaceProtocol == 0xff) { -#ifndef CONFIG_USB_NET_RNDIS_HOST +#ifndef CONFIG_USB_NET_RNDIS continue; #else best = c; @@ -1270,11 +1256,6 @@ static int choose_configuration(struct usb_device *udev) best = c; } - if (insufficient_power > 0) - dev_info(&udev->dev, "rejected %d configuration%s " - "due to insufficient available bus power\n", - insufficient_power, plural(insufficient_power)); - if (best) { i = best->desc.bConfigurationValue; dev_info(&udev->dev, @@ -2751,8 +2732,7 @@ static void hub_events(void) /* If the hub has died, clean up after it */ if (hdev->state == USB_STATE_NOTATTACHED) { - hub->error = -ENODEV; - hub_pre_reset(intf); + hub_pre_reset(hub, 0); goto loop; } @@ -2764,7 +2744,7 @@ static void hub_events(void) dev_dbg (hub_dev, "resetting for error %d\n", hub->error); - ret = usb_reset_composite_device(hdev, intf); + ret = usb_reset_device(hdev); if (ret) { dev_dbg (hub_dev, "error resetting hub: %d\n", ret); @@ -2933,8 +2913,6 @@ static struct usb_driver hub_driver = { .disconnect = hub_disconnect, .suspend = hub_suspend, .resume = hub_resume, - .pre_reset = hub_pre_reset, - .post_reset = hub_post_reset, .ioctl = hub_ioctl, .id_table = hub_id_table, }; @@ -3014,9 +2992,9 @@ static int config_descriptors_changed(struct usb_device *udev) * usb_reset_device - perform a USB port reset to reinitialize a device * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) * - * WARNING - don't use this routine to reset a composite device - * (one with multiple interfaces owned by separate drivers)! - * Use usb_reset_composite_device() instead. + * WARNING - don't reset any device unless drivers for all of its + * interfaces are expecting that reset! Maybe some driver->reset() + * method should eventually help ensure sufficient cooperation. * * Do a port reset, reassign the device's address, and establish its * former operating configuration. If the reset fails, or the device's @@ -3040,6 +3018,7 @@ int usb_reset_device(struct usb_device *udev) struct usb_device *parent_hdev = udev->parent; struct usb_hub *parent_hub; struct usb_device_descriptor descriptor = udev->descriptor; + struct usb_hub *hub = NULL; int i, ret = 0; int port1 = udev->portnum; @@ -3057,6 +3036,14 @@ int usb_reset_device(struct usb_device *udev) } parent_hub = hdev_to_hub(parent_hdev); + /* If we're resetting an active hub, take some special actions */ + if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 && + udev->actconfig->interface[0]->dev.driver == + &hub_driver.driver && + (hub = hdev_to_hub(udev)) != NULL) { + hub_pre_reset(hub, 0); + } + set_bit(port1, parent_hub->busy_bits); for (i = 0; i < SET_CONFIG_TRIES; ++i) { @@ -3115,87 +3102,11 @@ int usb_reset_device(struct usb_device *udev) } done: + if (hub) + hub_post_reset(hub); return 0; re_enumerate: hub_port_logical_disconnect(parent_hub, port1); return -ENODEV; } - -/** - * usb_reset_composite_device - warn interface drivers and perform a USB port reset - * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) - * @iface: interface bound to the driver making the request (optional) - * - * Warns all drivers bound to registered interfaces (using their pre_reset - * method), performs the port reset, and then lets the drivers know that - * the reset is over (using their post_reset method). - * - * Return value is the same as for usb_reset_device(). - * - * The caller must own the device lock. For example, it's safe to use - * this from a driver probe() routine after downloading new firmware. - * For calls that might not occur during probe(), drivers should lock - * the device using usb_lock_device_for_reset(). - * - * The interface locks are acquired during the pre_reset stage and released - * during the post_reset stage. However if iface is not NULL and is - * currently being probed, we assume that the caller already owns its - * lock. - */ -int usb_reset_composite_device(struct usb_device *udev, - struct usb_interface *iface) -{ - int ret; - struct usb_host_config *config = udev->actconfig; - - if (udev->state == USB_STATE_NOTATTACHED || - udev->state == USB_STATE_SUSPENDED) { - dev_dbg(&udev->dev, "device reset not allowed in state %d\n", - udev->state); - return -EINVAL; - } - - if (iface && iface->condition != USB_INTERFACE_BINDING) - iface = NULL; - - if (config) { - int i; - struct usb_interface *cintf; - struct usb_driver *drv; - - for (i = 0; i < config->desc.bNumInterfaces; ++i) { - cintf = config->interface[i]; - if (cintf != iface) - down(&cintf->dev.sem); - if (device_is_registered(&cintf->dev) && - cintf->dev.driver) { - drv = to_usb_driver(cintf->dev.driver); - if (drv->pre_reset) - (drv->pre_reset)(cintf); - } - } - } - - ret = usb_reset_device(udev); - - if (config) { - int i; - struct usb_interface *cintf; - struct usb_driver *drv; - - for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { - cintf = config->interface[i]; - if (device_is_registered(&cintf->dev) && - cintf->dev.driver) { - drv = to_usb_driver(cintf->dev.driver); - if (drv->post_reset) - (drv->post_reset)(cintf); - } - if (cintf != iface) - up(&cintf->dev.sem); - } - } - - return ret; -} diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index bfc9b28a7242..3cf945cc5b9a 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/drivers/usb/core/inode.c @@ -543,10 +543,10 @@ static void fs_remove_file (struct dentry *dentry) /* --------------------------------------------------------------------- */ -static int usb_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, struct vfsmount *mnt) +static struct super_block *usb_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) { - return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt); + return get_sb_single(fs_type, flags, data, usbfs_fill_super); } static struct file_system_type usb_fs_type = { @@ -569,7 +569,7 @@ static int create_special_files (void) ignore_mount = 1; /* create the devices special file */ - retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count); + retval = simple_pin_fs("usbfs", &usbfs_mount, &usbfs_mount_count); if (retval) { err ("Unable to get usbfs mount"); goto exit; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 8569600f3130..08fb20f06f3e 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -157,37 +157,6 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u } -/** - * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion - * @usb_dev: pointer to the usb device to send the message to - * @pipe: endpoint "pipe" to send the message to - * @data: pointer to the data to send - * @len: length in bytes of the data to send - * @actual_length: pointer to a location to put the actual length transferred in bytes - * @timeout: time in msecs to wait for the message to complete before - * timing out (if 0 the wait is forever) - * Context: !in_interrupt () - * - * This function sends a simple interrupt message to a specified endpoint and - * waits for the message to complete, or timeout. - * - * If successful, it returns 0, otherwise a negative error number. The number - * of actual bytes transferred will be stored in the actual_length paramater. - * - * Don't use this function from within an interrupt context, like a bottom half - * handler. If you need an asynchronous message, or need to send a message - * from within interrupt context, use usb_submit_urb() If a thread in your - * driver uses this call, make sure your disconnect() method can wait for it to - * complete. Since you don't have a handle on the URB used, you can't cancel - * the request. - */ -int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, - void *data, int len, int *actual_length, int timeout) -{ - return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout); -} -EXPORT_SYMBOL_GPL(usb_interrupt_msg); - /** * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to @@ -1411,12 +1380,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) return ret; } } - - i = dev->bus_mA - cp->desc.bMaxPower * 2; - if (i < 0) - dev_warn(&dev->dev, "new config #%d exceeds power " - "limit by %dmA\n", - configuration, -i); } /* if it's already configured, clear out old state first. @@ -1425,85 +1388,92 @@ int usb_set_configuration(struct usb_device *dev, int configuration) if (dev->state != USB_STATE_ADDRESS) usb_disable_device (dev, 1); // Skip ep0 + if (cp) { + i = dev->bus_mA - cp->desc.bMaxPower * 2; + if (i < 0) + dev_warn(&dev->dev, "new config #%d exceeds power " + "limit by %dmA\n", + configuration, -i); + } + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, 0, configuration, 0, - NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { - - /* All the old state is gone, so what else can we do? - * The device is probably useless now anyway. - */ - cp = NULL; - } + NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) + goto free_interfaces; dev->actconfig = cp; - if (!cp) { + if (!cp) usb_set_device_state(dev, USB_STATE_ADDRESS); - goto free_interfaces; - } - usb_set_device_state(dev, USB_STATE_CONFIGURED); - - /* Initialize the new interface structures and the - * hc/hcd/usbcore interface/endpoint state. - */ - for (i = 0; i < nintf; ++i) { - struct usb_interface_cache *intfc; - struct usb_interface *intf; - struct usb_host_interface *alt; - - cp->interface[i] = intf = new_interfaces[i]; - intfc = cp->intf_cache[i]; - intf->altsetting = intfc->altsetting; - intf->num_altsetting = intfc->num_altsetting; - kref_get(&intfc->ref); + else { + usb_set_device_state(dev, USB_STATE_CONFIGURED); - alt = usb_altnum_to_altsetting(intf, 0); - - /* No altsetting 0? We'll assume the first altsetting. - * We could use a GetInterface call, but if a device is - * so non-compliant that it doesn't have altsetting 0 - * then I wouldn't trust its reply anyway. + /* Initialize the new interface structures and the + * hc/hcd/usbcore interface/endpoint state. */ - if (!alt) - alt = &intf->altsetting[0]; - - intf->cur_altsetting = alt; - usb_enable_interface(dev, intf); - intf->dev.parent = &dev->dev; - intf->dev.driver = NULL; - intf->dev.bus = &usb_bus_type; - intf->dev.dma_mask = dev->dev.dma_mask; - intf->dev.release = release_interface; - device_initialize (&intf->dev); - mark_quiesced(intf); - sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", - dev->bus->busnum, dev->devpath, - configuration, alt->desc.bInterfaceNumber); - } - kfree(new_interfaces); + for (i = 0; i < nintf; ++i) { + struct usb_interface_cache *intfc; + struct usb_interface *intf; + struct usb_host_interface *alt; + + cp->interface[i] = intf = new_interfaces[i]; + intfc = cp->intf_cache[i]; + intf->altsetting = intfc->altsetting; + intf->num_altsetting = intfc->num_altsetting; + kref_get(&intfc->ref); + + alt = usb_altnum_to_altsetting(intf, 0); + + /* No altsetting 0? We'll assume the first altsetting. + * We could use a GetInterface call, but if a device is + * so non-compliant that it doesn't have altsetting 0 + * then I wouldn't trust its reply anyway. + */ + if (!alt) + alt = &intf->altsetting[0]; + + intf->cur_altsetting = alt; + usb_enable_interface(dev, intf); + intf->dev.parent = &dev->dev; + intf->dev.driver = NULL; + intf->dev.bus = &usb_bus_type; + intf->dev.dma_mask = dev->dev.dma_mask; + intf->dev.release = release_interface; + device_initialize (&intf->dev); + mark_quiesced(intf); + sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", + dev->bus->busnum, dev->devpath, + configuration, + alt->desc.bInterfaceNumber); + } + kfree(new_interfaces); - if (cp->string == NULL) - cp->string = usb_cache_string(dev, cp->desc.iConfiguration); + if (cp->string == NULL) + cp->string = usb_cache_string(dev, + cp->desc.iConfiguration); - /* Now that all the interfaces are set up, register them - * to trigger binding of drivers to interfaces. probe() - * routines may install different altsettings and may - * claim() any interfaces not yet bound. Many class drivers - * need that: CDC, audio, video, etc. - */ - for (i = 0; i < nintf; ++i) { - struct usb_interface *intf = cp->interface[i]; - - dev_dbg (&dev->dev, - "adding %s (config #%d, interface %d)\n", - intf->dev.bus_id, configuration, - intf->cur_altsetting->desc.bInterfaceNumber); - ret = device_add (&intf->dev); - if (ret != 0) { - dev_err(&dev->dev, "device_add(%s) --> %d\n", - intf->dev.bus_id, ret); - continue; + /* Now that all the interfaces are set up, register them + * to trigger binding of drivers to interfaces. probe() + * routines may install different altsettings and may + * claim() any interfaces not yet bound. Many class drivers + * need that: CDC, audio, video, etc. + */ + for (i = 0; i < nintf; ++i) { + struct usb_interface *intf = cp->interface[i]; + + dev_dbg (&dev->dev, + "adding %s (config #%d, interface %d)\n", + intf->dev.bus_id, configuration, + intf->cur_altsetting->desc.bInterfaceNumber); + ret = device_add (&intf->dev); + if (ret != 0) { + dev_err(&dev->dev, + "device_add(%s) --> %d\n", + intf->dev.bus_id, + ret); + continue; + } + usb_create_sysfs_intf_files (intf); } - usb_create_sysfs_intf_files (intf); } return 0; diff --git a/trunk/drivers/usb/core/sysfs.c b/trunk/drivers/usb/core/sysfs.c index 3f49bf51cff7..71d881327e88 100644 --- a/trunk/drivers/usb/core/sysfs.c +++ b/trunk/drivers/usb/core/sysfs.c @@ -15,6 +15,203 @@ #include #include "usb.h" +/* endpoint stuff */ +struct ep_object { + struct usb_endpoint_descriptor *desc; + struct usb_device *udev; + struct kobject kobj; +}; +#define to_ep_object(_kobj) \ + container_of(_kobj, struct ep_object, kobj) + +struct ep_attribute { + struct attribute attr; + ssize_t (*show)(struct usb_device *, + struct usb_endpoint_descriptor *, char *); +}; +#define to_ep_attribute(_attr) \ + container_of(_attr, struct ep_attribute, attr) + +#define EP_ATTR(_name) \ +struct ep_attribute ep_##_name = { \ + .attr = {.name = #_name, .owner = THIS_MODULE, \ + .mode = S_IRUGO}, \ + .show = show_ep_##_name} + +#define usb_ep_attr(field, format_string) \ +static ssize_t show_ep_##field(struct usb_device *udev, \ + struct usb_endpoint_descriptor *desc, \ + char *buf) \ +{ \ + return sprintf(buf, format_string, desc->field); \ +} \ +static EP_ATTR(field); + +usb_ep_attr(bLength, "%02x\n") +usb_ep_attr(bEndpointAddress, "%02x\n") +usb_ep_attr(bmAttributes, "%02x\n") +usb_ep_attr(bInterval, "%02x\n") + +static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) +{ + return sprintf(buf, "%04x\n", + le16_to_cpu(desc->wMaxPacketSize) & 0x07ff); +} +static EP_ATTR(wMaxPacketSize); + +static ssize_t show_ep_type(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) +{ + char *type = "unknown"; + + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + type = "Control"; + break; + case USB_ENDPOINT_XFER_ISOC: + type = "Isoc"; + break; + case USB_ENDPOINT_XFER_BULK: + type = "Bulk"; + break; + case USB_ENDPOINT_XFER_INT: + type = "Interrupt"; + break; + } + return sprintf(buf, "%s\n", type); +} +static EP_ATTR(type); + +static ssize_t show_ep_interval(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) +{ + char unit; + unsigned interval = 0; + unsigned in; + + in = (desc->bEndpointAddress & USB_DIR_IN); + + switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ + interval = desc->bInterval; + break; + case USB_ENDPOINT_XFER_ISOC: + interval = 1 << (desc->bInterval - 1); + break; + case USB_ENDPOINT_XFER_BULK: + if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ + interval = desc->bInterval; + break; + case USB_ENDPOINT_XFER_INT: + if (udev->speed == USB_SPEED_HIGH) + interval = 1 << (desc->bInterval - 1); + else + interval = desc->bInterval; + break; + } + interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; + if (interval % 1000) + unit = 'u'; + else { + unit = 'm'; + interval /= 1000; + } + + return sprintf(buf, "%d%cs\n", interval, unit); +} +static EP_ATTR(interval); + +static ssize_t show_ep_direction(struct usb_device *udev, + struct usb_endpoint_descriptor *desc, char *buf) +{ + char *direction; + + if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) + direction = "both"; + else if (desc->bEndpointAddress & USB_DIR_IN) + direction = "in"; + else + direction = "out"; + return sprintf(buf, "%s\n", direction); +} +static EP_ATTR(direction); + +static struct attribute *ep_attrs[] = { + &ep_bLength.attr, + &ep_bEndpointAddress.attr, + &ep_bmAttributes.attr, + &ep_bInterval.attr, + &ep_wMaxPacketSize.attr, + &ep_type.attr, + &ep_interval.attr, + &ep_direction.attr, + NULL, +}; + +static void ep_object_release(struct kobject *kobj) +{ + kfree(to_ep_object(kobj)); +} + +static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct ep_object *ep_obj = to_ep_object(kobj); + struct ep_attribute *ep_attr = to_ep_attribute(attr); + + return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf); +} + +static struct sysfs_ops ep_object_sysfs_ops = { + .show = ep_object_show, +}; + +static struct kobj_type ep_object_ktype = { + .release = ep_object_release, + .sysfs_ops = &ep_object_sysfs_ops, + .default_attrs = ep_attrs, +}; + +static void usb_create_ep_files(struct kobject *parent, + struct usb_host_endpoint *endpoint, + struct usb_device *udev) +{ + struct ep_object *ep_obj; + struct kobject *kobj; + + ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL); + if (!ep_obj) + return; + + ep_obj->desc = &endpoint->desc; + ep_obj->udev = udev; + + kobj = &ep_obj->kobj; + kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress); + kobj->parent = parent; + kobj->ktype = &ep_object_ktype; + + /* Don't use kobject_register, because it generates a hotplug event */ + kobject_init(kobj); + if (kobject_add(kobj) == 0) + endpoint->kobj = kobj; + else + kobject_put(kobj); +} + +static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) +{ + + if (endpoint->kobj) { + kobject_del(endpoint->kobj); + kobject_put(endpoint->kobj); + endpoint->kobj = NULL; + } +} + /* Active configuration fields */ #define usb_actconfig_show(field, multiplier, format_string) \ static ssize_t show_##field (struct device *dev, \ @@ -223,7 +420,7 @@ void usb_create_sysfs_dev_files (struct usb_device *udev) if (udev->serial) device_create_file (dev, &dev_attr_serial); device_create_file (dev, &dev_attr_configuration); - usb_create_ep_files(dev, &udev->ep0, udev); + usb_create_ep_files(&dev->kobj, &udev->ep0, udev); } void usb_remove_sysfs_dev_files (struct usb_device *udev) @@ -327,7 +524,7 @@ static inline void usb_create_intf_ep_files(struct usb_interface *intf, iface_desc = intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) - usb_create_ep_files(&intf->dev, &iface_desc->endpoint[i], + usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], udev); } diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index fb488c8a860c..b7fdc1cd134a 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -991,8 +991,6 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, static int verify_suspended(struct device *dev, void *unused) { - if (dev->driver == NULL) - return 0; return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; } @@ -1209,7 +1207,6 @@ EXPORT_SYMBOL(usb_ifnum_to_if); EXPORT_SYMBOL(usb_altnum_to_altsetting); EXPORT_SYMBOL(usb_reset_device); -EXPORT_SYMBOL(usb_reset_composite_device); EXPORT_SYMBOL(__usb_get_extra_descriptor); diff --git a/trunk/drivers/usb/core/usb.h b/trunk/drivers/usb/core/usb.h index 7a650c763a62..4647e1ebc68d 100644 --- a/trunk/drivers/usb/core/usb.h +++ b/trunk/drivers/usb/core/usb.h @@ -4,9 +4,6 @@ extern void usb_create_sysfs_dev_files (struct usb_device *dev); extern void usb_remove_sysfs_dev_files (struct usb_device *dev); extern void usb_create_sysfs_intf_files (struct usb_interface *intf); extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); -extern void usb_create_ep_files(struct device *parent, struct usb_host_endpoint *endpoint, - struct usb_device *udev); -extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); extern void usb_disable_interface (struct usb_device *dev, diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 078daa026718..9c4422ac9de4 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include @@ -101,9 +101,9 @@ static const char driver_desc [] = DRIVER_DESC; /* CDC and RNDIS support the same host-chosen outgoing packet filters. */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ - |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ - |USB_CDC_PACKET_TYPE_PROMISCUOUS \ - |USB_CDC_PACKET_TYPE_DIRECTED) + |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ + |USB_CDC_PACKET_TYPE_PROMISCUOUS \ + |USB_CDC_PACKET_TYPE_DIRECTED) /*-------------------------------------------------------------------------*/ @@ -318,7 +318,7 @@ static inline int rndis_active(struct eth_dev *dev) #define DEFAULT_QLEN 2 /* double buffering by default */ /* peak bulk transfer bits-per-second */ -#define HS_BPS (13 * 512 * 8 * 1000 * 8) +#define HS_BPS (13 * 512 * 8 * 1000 * 8) #define FS_BPS (19 * 64 * 1 * 1000 * 8) #ifdef CONFIG_USB_GADGET_DUALSPEED @@ -466,7 +466,7 @@ eth_config = { }; #ifdef CONFIG_USB_ETH_RNDIS -static struct usb_config_descriptor +static struct usb_config_descriptor rndis_config = { .bLength = sizeof rndis_config, .bDescriptorType = USB_DT_CONFIG, @@ -511,7 +511,7 @@ static const struct usb_interface_descriptor rndis_control_intf = { .bLength = sizeof rndis_control_intf, .bDescriptorType = USB_DT_INTERFACE, - + .bInterfaceNumber = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_COMM, @@ -545,20 +545,20 @@ static const struct usb_cdc_union_desc union_desc = { #ifdef CONFIG_USB_ETH_RNDIS static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = { - .bLength = sizeof call_mgmt_descriptor, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, + .bLength = sizeof call_mgmt_descriptor, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, - .bmCapabilities = 0x00, - .bDataInterface = 0x01, + .bmCapabilities = 0x00, + .bDataInterface = 0x01, }; static const struct usb_cdc_acm_descriptor acm_descriptor = { - .bLength = sizeof acm_descriptor, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = USB_CDC_ACM_TYPE, + .bLength = sizeof acm_descriptor, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_ACM_TYPE, - .bmCapabilities = 0x00, + .bmCapabilities = 0x00, }; #endif @@ -595,7 +595,7 @@ static const struct usb_cdc_ether_desc ether_desc = { * RNDIS requires the status endpoint, since it uses that encapsulation * mechanism for its funky RPC scheme. */ - + #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ #define STATUS_BYTECOUNT 16 /* 8 byte header + data */ @@ -978,7 +978,7 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) result = usb_ep_enable (dev->status_ep, dev->status); if (result != 0) { - DEBUG (dev, "enable %s --> %d\n", + DEBUG (dev, "enable %s --> %d\n", dev->status_ep->name, result); goto done; } @@ -1002,15 +1002,15 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) if (!cdc_active(dev)) { result = usb_ep_enable (dev->in_ep, dev->in); if (result != 0) { - DEBUG(dev, "enable %s --> %d\n", + DEBUG(dev, "enable %s --> %d\n", dev->in_ep->name, result); goto done; } result = usb_ep_enable (dev->out_ep, dev->out); if (result != 0) { - DEBUG (dev, "enable %s --> %d\n", - dev->out_ep->name, result); + DEBUG (dev, "enable %s --> %d\n", + dev->in_ep->name, result); goto done; } } @@ -1144,7 +1144,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags) #ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH: speed = "high"; break; #endif - default: speed = "?"; break; + default: speed = "?"; break; } dev->config = number; @@ -1206,7 +1206,7 @@ static void issue_start_status (struct eth_dev *dev) struct usb_request *req = dev->stat_req; struct usb_cdc_notification *event; int value; - + DEBUG (dev, "%s, flush old status first\n", __FUNCTION__); /* flush old status @@ -1268,7 +1268,7 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req) { struct eth_dev *dev = ep->driver_data; int status; - + /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ spin_lock(&dev->lock); status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); @@ -1472,7 +1472,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) #endif /* DEV_CONFIG_CDC */ -#ifdef CONFIG_USB_ETH_RNDIS +#ifdef CONFIG_USB_ETH_RNDIS /* RNDIS uses the CDC command encapsulation mechanism to implement * an RPC scheme, with much getting/setting of attributes by OID. */ @@ -1489,7 +1489,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->complete = rndis_command_complete; /* later, rndis_control_ack () sends a notification */ break; - + case USB_CDC_GET_ENCAPSULATED_RESPONSE: if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE) == ctrl->bRequestType @@ -1641,7 +1641,7 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) DEBUG (dev, "no rx skb\n"); goto enomem; } - + /* Some platforms perform better when IP packets are aligned, * but on at least one, checksumming fails otherwise. Note: * RNDIS headers involve variable numbers of LE32 values. @@ -1720,7 +1720,7 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) case -EOVERFLOW: dev->stats.rx_over_errors++; // FALLTHROUGH - + default: dev->stats.rx_errors++; DEBUG (dev, "rx status %d\n", status); @@ -1915,7 +1915,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) sizeof (struct rndis_packet_msg_type)); if (!skb_rndis) goto drop; - + dev_kfree_skb_any (skb); skb = skb_rndis; rndis_add_hdr (skb); @@ -2001,7 +2001,7 @@ static int rndis_control_ack (struct net_device *net) struct eth_dev *dev = netdev_priv(net); u32 length; struct usb_request *resp = dev->stat_req; - + /* in case RNDIS calls this after disconnect */ if (!dev->status) { DEBUG (dev, "status ENODEV\n"); @@ -2021,16 +2021,16 @@ static int rndis_control_ack (struct net_device *net) resp->length = 8; resp->complete = rndis_control_ack_complete; resp->context = dev; - + *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1); *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0); - + length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC); if (length < 0) { resp->status = 0; rndis_control_ack_complete (dev->status_ep, resp); } - + return 0; } @@ -2047,7 +2047,7 @@ static void eth_start (struct eth_dev *dev, gfp_t gfp_flags) /* fill the rx queue */ rx_fill (dev, gfp_flags); - /* and open the tx floodgates */ + /* and open the tx floodgates */ atomic_set (&dev->tx_qlen, 0); netif_wake_queue (dev->net); if (rndis_active(dev)) { @@ -2076,7 +2076,7 @@ static int eth_stop (struct net_device *net) netif_stop_queue (net); DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", - dev->stats.rx_packets, dev->stats.tx_packets, + dev->stats.rx_packets, dev->stats.tx_packets, dev->stats.rx_errors, dev->stats.tx_errors ); @@ -2095,7 +2095,7 @@ static int eth_stop (struct net_device *net) usb_ep_enable (dev->status_ep, dev->status); } } - + if (rndis_active(dev)) { rndis_set_param_medium (dev->rndis_config, NDIS_MEDIUM_802_3, 0); @@ -2301,7 +2301,7 @@ eth_bind (struct usb_gadget *gadget) return -ENODEV; } in_ep->driver_data = in_ep; /* claim */ - + out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc); if (!out_ep) goto autoconf_fail; @@ -2374,8 +2374,8 @@ eth_bind (struct usb_gadget *gadget) #endif } - net = alloc_etherdev (sizeof *dev); - if (!net) + net = alloc_etherdev (sizeof *dev); + if (!net) return status; dev = netdev_priv(net); spin_lock_init (&dev->lock); @@ -2454,7 +2454,7 @@ eth_bind (struct usb_gadget *gadget) dev->gadget = gadget; set_gadget_data (gadget, dev); gadget->ep0->driver_data = dev; - + /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" @@ -2462,8 +2462,8 @@ eth_bind (struct usb_gadget *gadget) netif_stop_queue (dev->net); netif_carrier_off (dev->net); - SET_NETDEV_DEV (dev->net, &gadget->dev); - status = register_netdev (dev->net); + SET_NETDEV_DEV (dev->net, &gadget->dev); + status = register_netdev (dev->net); if (status < 0) goto fail1; @@ -2488,7 +2488,7 @@ eth_bind (struct usb_gadget *gadget) u32 vendorID = 0; /* FIXME RNDIS vendor id == "vendor NIC code" == ? */ - + dev->rndis_config = rndis_register (rndis_control_ack); if (dev->rndis_config < 0) { fail0: @@ -2496,7 +2496,7 @@ eth_bind (struct usb_gadget *gadget) status = -ENODEV; goto fail; } - + /* these set up a lot of the OIDs that RNDIS needs */ rndis_set_host_mac (dev->rndis_config, dev->host_mac); if (rndis_set_param_dev (dev->rndis_config, dev->net, @@ -2556,7 +2556,7 @@ static struct usb_gadget_driver eth_driver = { .suspend = eth_suspend, .resume = eth_resume, - .driver = { + .driver = { .name = (char *) shortname, .owner = THIS_MODULE, }, diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index a43dc908ac59..6f887478b148 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -1906,6 +1906,7 @@ static int fsync_sub(struct lun *curlun) inode = filp->f_dentry->d_inode; mutex_lock(&inode->i_mutex); + current->flags |= PF_SYNCWRITE; rc = filemap_fdatawrite(inode->i_mapping); err = filp->f_op->fsync(filp, filp->f_dentry, 1); if (!rc) @@ -1913,6 +1914,7 @@ static int fsync_sub(struct lun *curlun) err = filemap_fdatawait(inode->i_mapping); if (!rc) rc = err; + current->flags &= ~PF_SYNCWRITE; mutex_unlock(&inode->i_mutex); VLDBG(curlun, "fdatasync -> %d\n", rc); return rc; diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index 3bdc5e3ba234..0eb010a3f5bc 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -528,7 +528,7 @@ struct kiocb_priv { struct usb_request *req; struct ep_data *epdata; void *buf; - char __user *ubuf; /* NULL for writes */ + char __user *ubuf; unsigned actual; }; @@ -566,6 +566,7 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb) status = priv->actual; kfree(priv->buf); kfree(priv); + aio_put_req(iocb); return status; } @@ -579,8 +580,8 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) spin_lock(&epdata->dev->lock); priv->req = NULL; priv->epdata = NULL; - if (priv->ubuf == NULL - || unlikely(req->actual == 0) + if (NULL == iocb->ki_retry + || unlikely(0 == req->actual) || unlikely(kiocbIsCancelled(iocb))) { kfree(req->buf); kfree(priv); @@ -617,7 +618,7 @@ ep_aio_rwtail( char __user *ubuf ) { - struct kiocb_priv *priv; + struct kiocb_priv *priv = (void *) &iocb->private; struct usb_request *req; ssize_t value; @@ -669,7 +670,7 @@ ep_aio_rwtail( kfree(priv); put_ep(epdata); } else - value = (ubuf ? -EIOCBRETRY : -EIOCBQUEUED); + value = -EIOCBQUEUED; return value; } @@ -1038,7 +1039,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) /* ep0 can't deliver events when STATE_SETUP */ for (i = 0; i < n; i++) { if (dev->event [i].type == GADGETFS_SETUP) { - len = i + 1; + len = n = i + 1; len *= sizeof (struct usb_gadgetfs_event); n = 0; break; @@ -1586,13 +1587,13 @@ gadgetfs_create_file (struct super_block *sb, char const *name, static int activate_ep_files (struct dev_data *dev) { struct usb_ep *ep; - struct ep_data *data; gadget_for_each_ep (ep, dev->gadget) { + struct ep_data *data; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) - goto enomem0; + goto enomem; data->state = STATE_EP_DISABLED; init_MUTEX (&data->lock); init_waitqueue_head (&data->wait); @@ -1607,23 +1608,21 @@ static int activate_ep_files (struct dev_data *dev) data->req = usb_ep_alloc_request (ep, GFP_KERNEL); if (!data->req) - goto enomem1; + goto enomem; data->inode = gadgetfs_create_file (dev->sb, data->name, data, &ep_config_operations, &data->dentry); - if (!data->inode) - goto enomem2; + if (!data->inode) { + usb_ep_free_request(ep, data->req); + kfree (data); + goto enomem; + } list_add_tail (&data->epfiles, &dev->epfiles); } return 0; -enomem2: - usb_ep_free_request (ep, data->req); -enomem1: - put_dev (dev); - kfree (data); -enomem0: +enomem: DBG (dev, "%s enomem\n", __FUNCTION__); destroy_ep_files (dev); return -ENOMEM; @@ -1794,7 +1793,7 @@ static struct usb_gadget_driver probe_driver = { * * After initialization, the device stays active for as long as that * $CHIP file is open. Events may then be read from that descriptor, - * such as configuration notifications. More complex drivers will handle + * such configuration notifications. More complex drivers will handle * some control requests in user space. */ @@ -2034,10 +2033,12 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) NULL, &simple_dir_operations, S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) - goto enomem0; + return -ENOMEM; inode->i_op = &simple_dir_inode_operations; - if (!(d = d_alloc_root (inode))) - goto enomem1; + if (!(d = d_alloc_root (inode))) { + iput (inode); + return -ENOMEM; + } sb->s_root = d; /* the ep0 file is named after the controller we expect; @@ -2045,36 +2046,29 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) */ dev = dev_new (); if (!dev) - goto enomem2; + return -ENOMEM; dev->sb = sb; - if (!gadgetfs_create_file (sb, CHIP, + if (!(inode = gadgetfs_create_file (sb, CHIP, dev, &dev_init_operations, - &dev->dentry)) - goto enomem3; + &dev->dentry))) { + put_dev(dev); + return -ENOMEM; + } /* other endpoint files are available after hardware setup, * from binding to a controller. */ the_device = dev; return 0; - -enomem3: - put_dev (dev); -enomem2: - dput (d); -enomem1: - iput (inode); -enomem0: - return -ENOMEM; } /* "mount -t gadgetfs path /dev/gadget" ends up here */ -static int +static struct super_block * gadgetfs_get_sb (struct file_system_type *t, int flags, - const char *path, void *opts, struct vfsmount *mnt) + const char *path, void *opts) { - return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt); + return get_sb_single (t, flags, opts, gadgetfs_fill_super); } static void diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 1facdea56a8a..020d3c42b1af 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -2966,22 +2966,6 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) return retval; } -/* make sure the board is quiescent; otherwise it will continue - * generating IRQs across the upcoming reboot. - */ - -static void net2280_shutdown (struct pci_dev *pdev) -{ - struct net2280 *dev = pci_get_drvdata (pdev); - - /* disable IRQs */ - writel (0, &dev->regs->pciirqenb0); - writel (0, &dev->regs->pciirqenb1); - - /* disable the pullup so the host will think we're gone */ - writel (0, &dev->usb->usbctl); -} - /*-------------------------------------------------------------------------*/ @@ -3011,7 +2995,6 @@ static struct pci_driver net2280_pci_driver = { .probe = net2280_probe, .remove = net2280_remove, - .shutdown = net2280_shutdown, /* FIXME add power management support */ }; diff --git a/trunk/drivers/usb/gadget/pxa2xx_udc.c b/trunk/drivers/usb/gadget/pxa2xx_udc.c index 269ce7f4ad66..680f7fc5b171 100644 --- a/trunk/drivers/usb/gadget/pxa2xx_udc.c +++ b/trunk/drivers/usb/gadget/pxa2xx_udc.c @@ -53,14 +53,12 @@ #include #include #include -#ifdef CONFIG_ARCH_PXA #include -#endif #include #include -#include +#include /* @@ -547,7 +545,6 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) count = req->req.length; done (ep, req, 0); ep0_idle(ep->dev); -#ifndef CONFIG_ARCH_IXP4XX #if 1 /* This seems to get rid of lost status irqs in some cases: * host responds quickly, or next request involves config @@ -567,7 +564,6 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) udelay(1); } while (count); } -#endif #endif } else if (ep->dev->req_pending) ep0start(ep->dev, 0, "IN"); @@ -1589,7 +1585,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) int retval; if (!driver - || driver->speed < USB_SPEED_FULL + || driver->speed != USB_SPEED_FULL || !driver->bind || !driver->unbind || !driver->disconnect @@ -2431,7 +2427,6 @@ static struct pxa2xx_udc memory = { #define PXA210_B1 0x00000123 #define PXA210_B0 0x00000122 #define IXP425_A0 0x000001c1 -#define IXP465_AD 0x00000200 /* * probe - binds to the platform device @@ -2468,8 +2463,6 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) break; #elif defined(CONFIG_ARCH_IXP4XX) case IXP425_A0: - case IXP465_AD: - dev->has_cfr = 1; out_dma = 0; break; #endif @@ -2582,12 +2575,10 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) free_irq(IRQ_USB, dev); dev->got_irq = 0; } -#ifdef CONFIG_ARCH_LUBBOCK if (machine_is_lubbock()) { free_irq(LUBBOCK_USB_DISC_IRQ, dev); free_irq(LUBBOCK_USB_IRQ, dev); } -#endif platform_set_drvdata(pdev, NULL); the_controller = NULL; return 0; diff --git a/trunk/drivers/usb/gadget/rndis.c b/trunk/drivers/usb/gadget/rndis.c index 3ff6db7828a0..6d6eaad73968 100644 --- a/trunk/drivers/usb/gadget/rndis.c +++ b/trunk/drivers/usb/gadget/rndis.c @@ -1,23 +1,23 @@ -/* +/* * RNDIS MSG parser - * + * * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $ - * + * * Authors: Benedikt Spranger, Pengutronix - * Robert Schwebel, Pengutronix - * + * Robert Schwebel, Pengutronix + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * + * version 2, as published by the Free Software Foundation. + * * This software was originally developed in conformance with * Microsoft's Remote NDIS Specification License Agreement. - * + * * 03/12/2004 Kai-Uwe Bloem * Fixed message length bug in init_response - * + * * 03/25/2004 Kai-Uwe Bloem - * Fixed rndis_rm_hdr length bug. + * Fixed rndis_rm_hdr length bug. * * Copyright (C) 2004 by David Brownell * updates to merge with Linux 2.6, better match RNDIS spec @@ -82,7 +82,7 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length); /* supported OIDs */ -static const u32 oid_supported_list [] = +static const u32 oid_supported_list [] = { /* the general stuff */ OID_GEN_SUPPORTED_LIST, @@ -103,7 +103,7 @@ static const u32 oid_supported_list [] = #if 0 OID_GEN_RNDIS_CONFIG_PARAMETER, #endif - + /* the statistical stuff */ OID_GEN_XMIT_OK, OID_GEN_RCV_OK, @@ -127,14 +127,14 @@ static const u32 oid_supported_list [] = OID_GEN_TRANSMIT_QUEUE_LENGTH, #endif /* RNDIS_OPTIONAL_STATS */ - /* mandatory 802.3 */ + /* mandatory 802.3 */ /* the general stuff */ OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, OID_802_3_MULTICAST_LIST, OID_802_3_MAC_OPTIONS, OID_802_3_MAXIMUM_LIST_SIZE, - + /* the statistical stuff */ OID_802_3_RCV_ERROR_ALIGNMENT, OID_802_3_XMIT_ONE_COLLISION, @@ -172,8 +172,8 @@ static int gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, rndis_resp_t *r) { - int retval = -ENOTSUPP; - u32 length = 4; /* usually */ + int retval = -ENOTSUPP; + u32 length = 4; /* usually */ __le32 *outbuf; int i, count; rndis_query_cmplt_type *resp; @@ -211,27 +211,27 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, outbuf[i] = cpu_to_le32 (oid_supported_list[i]); retval = 0; break; - + /* mandatory */ case OID_GEN_HARDWARE_STATUS: DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); - /* Bogus question! + /* Bogus question! * Hardware must be ready to receive high level protocols. - * BTW: + * BTW: * reddite ergo quae sunt Caesaris Caesari * et quae sunt Dei Deo! */ *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; - + /* mandatory */ case OID_GEN_MEDIA_SUPPORTED: DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; break; - + /* mandatory */ case OID_GEN_MEDIA_IN_USE: DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); @@ -239,7 +239,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); retval = 0; break; - + /* mandatory */ case OID_GEN_MAXIMUM_FRAME_SIZE: DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); @@ -249,7 +249,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_GEN_LINK_SPEED: if (rndis_debug > 1) @@ -272,7 +272,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_GEN_RECEIVE_BLOCK_SIZE: DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); @@ -282,7 +282,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_GEN_VENDOR_ID: DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); @@ -290,7 +290,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, rndis_per_dev_params [configNr].vendorID); retval = 0; break; - + /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); @@ -356,7 +356,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].stats->tx_packets - + rndis_per_dev_params [configNr].stats->tx_packets - rndis_per_dev_params [configNr].stats->tx_errors - rndis_per_dev_params [configNr].stats->tx_dropped); retval = 0; @@ -369,13 +369,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( - rndis_per_dev_params [configNr].stats->rx_packets - + rndis_per_dev_params [configNr].stats->rx_packets - rndis_per_dev_params [configNr].stats->rx_errors - rndis_per_dev_params [configNr].stats->rx_dropped); retval = 0; } break; - + /* mandatory */ case OID_GEN_XMIT_ERROR: if (rndis_debug > 1) @@ -386,7 +386,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_GEN_RCV_ERROR: if (rndis_debug > 1) @@ -397,7 +397,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_GEN_RCV_NO_BUFFER: DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); @@ -411,7 +411,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, #ifdef RNDIS_OPTIONAL_STATS case OID_GEN_DIRECTED_BYTES_XMIT: DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); - /* + /* * Aunt Tilly's size of shoes * minus antarctica count of penguins * divided by weight of Alpha Centauri @@ -419,7 +419,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( (rndis_per_dev_params [configNr] - .stats->tx_packets - + .stats->tx_packets - rndis_per_dev_params [configNr] .stats->tx_errors - rndis_per_dev_params [configNr] @@ -428,14 +428,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_DIRECTED_FRAMES_XMIT: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); /* dito */ if (rndis_per_dev_params [configNr].stats) { *outbuf = cpu_to_le32 ( (rndis_per_dev_params [configNr] - .stats->tx_packets - + .stats->tx_packets - rndis_per_dev_params [configNr] .stats->tx_errors - rndis_per_dev_params [configNr] @@ -444,7 +444,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_MULTICAST_BYTES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -453,7 +453,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_MULTICAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -462,7 +462,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_BROADCAST_BYTES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -471,7 +471,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_BROADCAST_FRAMES_XMIT: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -480,19 +480,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_DIRECTED_BYTES_RCV: DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; - + case OID_GEN_DIRECTED_FRAMES_RCV: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; - + case OID_GEN_MULTICAST_BYTES_RCV: DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -501,7 +501,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_MULTICAST_FRAMES_RCV: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -510,7 +510,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_BROADCAST_BYTES_RCV: DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -519,7 +519,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_BROADCAST_FRAMES_RCV: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -528,7 +528,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_RCV_CRC_ERROR: DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { @@ -537,7 +537,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + case OID_GEN_TRANSMIT_QUEUE_LENGTH: DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); *outbuf = __constant_cpu_to_le32 (0); @@ -558,7 +558,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_802_3_CURRENT_ADDRESS: DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); @@ -570,7 +570,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_802_3_MULTICAST_LIST: DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); @@ -578,7 +578,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, *outbuf = __constant_cpu_to_le32 (0xE0000000); retval = 0; break; - + /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); @@ -586,7 +586,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, *outbuf = __constant_cpu_to_le32 (1); retval = 0; break; - + case OID_802_3_MAC_OPTIONS: DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); break; @@ -602,56 +602,56 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, retval = 0; } break; - + /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; - + /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); *outbuf = __constant_cpu_to_le32 (0); retval = 0; break; - + #ifdef RNDIS_OPTIONAL_STATS case OID_802_3_XMIT_DEFERRED: DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_MAX_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_RCV_OVERRUN: DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_UNDERRUN: DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_HEARTBEAT_FAILURE: DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_TIMES_CRS_LOST: DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); /* TODO */ break; - + case OID_802_3_XMIT_LATE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); /* TODO */ - break; + break; #endif /* RNDIS_OPTIONAL_STATS */ #ifdef RNDIS_PM @@ -676,23 +676,23 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, #endif default: - printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", + printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", __FUNCTION__, OID); } if (retval < 0) length = 0; - + resp->InformationBufferLength = cpu_to_le32 (length); r->length = length + sizeof *resp; resp->MessageLength = cpu_to_le32 (r->length); return retval; } -static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, - rndis_resp_t *r) +static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, + rndis_resp_t *r) { rndis_set_cmplt_type *resp; - int i, retval = -ENOTSUPP; + int i, retval = -ENOTSUPP; struct rndis_params *params; if (!r) @@ -745,9 +745,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, netif_stop_queue (params->dev); } break; - + case OID_802_3_MULTICAST_LIST: - /* I think we can ignore this */ + /* I think we can ignore this */ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); retval = 0; break; @@ -796,29 +796,29 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, #endif /* RNDIS_PM */ default: - printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", + printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", __FUNCTION__, OID, buf_len); } - + return retval; } -/* - * Response Functions +/* + * Response Functions */ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) { - rndis_init_cmplt_type *resp; + rndis_init_cmplt_type *resp; rndis_resp_t *r; - + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; - + r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_init_cmplt_type *) r->buf; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_INITIALIZE_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (52); @@ -837,11 +837,11 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); resp->AFListOffset = __constant_cpu_to_le32 (0); resp->AFListSize = __constant_cpu_to_le32 (0); - + if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); - + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); + return 0; } @@ -849,10 +849,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) { rndis_query_cmplt_type *resp; rndis_resp_t *r; - + // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; - + /* * we need more memory: * gen_ndis_query_resp expects enough space for @@ -864,10 +864,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *) r->buf; - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - + if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), le32_to_cpu(buf->InformationBufferOffset) + 8 + (u8 *) buf, @@ -881,10 +881,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) resp->InformationBufferOffset = __constant_cpu_to_le32 (0); } else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } @@ -893,7 +893,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) u32 BufLength, BufOffset; rndis_set_cmplt_type *resp; rndis_resp_t *r; - + r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); if (!r) return -ENOMEM; @@ -906,27 +906,26 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); DEBUG("%s: InfoBuffer: ", __FUNCTION__); - + for (i = 0; i < BufLength; i++) { DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); } - + DEBUG ("\n"); #endif - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ - if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), - ((u8 *) buf) + 8 + BufOffset, BufLength, r)) - resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); - else - resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), + ((u8 *) buf) + 8 + BufOffset, BufLength, r)) + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); + else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); + if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); - + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); + return 0; } @@ -934,27 +933,27 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) { rndis_reset_cmplt_type *resp; rndis_resp_t *r; - + r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_reset_cmplt_type *) r->buf; - + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); /* resent information */ resp->AddressingReset = __constant_cpu_to_le32 (1); - + if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } static int rndis_keepalive_response (int configNr, - rndis_keepalive_msg_type *buf) + rndis_keepalive_msg_type *buf) { rndis_keepalive_cmplt_type *resp; rndis_resp_t *r; @@ -965,48 +964,48 @@ static int rndis_keepalive_response (int configNr, if (!r) return -ENOMEM; resp = (rndis_keepalive_cmplt_type *) r->buf; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_KEEPALIVE_CMPLT); resp->MessageLength = __constant_cpu_to_le32 (16); resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); - + if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); - + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); + return 0; } -/* - * Device to Host Comunication +/* + * Device to Host Comunication */ static int rndis_indicate_status_msg (int configNr, u32 status) { - rndis_indicate_status_msg_type *resp; + rndis_indicate_status_msg_type *resp; rndis_resp_t *r; - + if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) - return -ENOTSUPP; - - r = rndis_add_response (configNr, + return -ENOTSUPP; + + r = rndis_add_response (configNr, sizeof (rndis_indicate_status_msg_type)); if (!r) return -ENOMEM; resp = (rndis_indicate_status_msg_type *) r->buf; - + resp->MessageType = __constant_cpu_to_le32 ( REMOTE_NDIS_INDICATE_STATUS_MSG); resp->MessageLength = __constant_cpu_to_le32 (20); resp->Status = cpu_to_le32 (status); resp->StatusBufferLength = __constant_cpu_to_le32 (0); resp->StatusBufferOffset = __constant_cpu_to_le32 (0); - - if (rndis_per_dev_params [configNr].ack) - rndis_per_dev_params [configNr].ack ( - rndis_per_dev_params [configNr].dev); + + if (rndis_per_dev_params [configNr].ack) + rndis_per_dev_params [configNr].ack ( + rndis_per_dev_params [configNr].dev); return 0; } @@ -1014,7 +1013,7 @@ int rndis_signal_connect (int configNr) { rndis_per_dev_params [configNr].media_state = NDIS_MEDIA_STATE_CONNECTED; - return rndis_indicate_status_msg (configNr, + return rndis_indicate_status_msg (configNr, RNDIS_STATUS_MEDIA_CONNECT); } @@ -1046,26 +1045,26 @@ void rndis_set_host_mac (int configNr, const u8 *addr) rndis_per_dev_params [configNr].host_mac = addr; } -/* - * Message Parser +/* + * Message Parser */ int rndis_msg_parser (u8 configNr, u8 *buf) { u32 MsgType, MsgLength; __le32 *tmp; struct rndis_params *params; - + if (!buf) return -ENOMEM; - - tmp = (__le32 *) buf; + + tmp = (__le32 *) buf; MsgType = le32_to_cpup(tmp++); MsgLength = le32_to_cpup(tmp++); - + if (configNr >= RNDIS_MAX_CONFIGS) return -ENOTSUPP; params = &rndis_per_dev_params [configNr]; - + /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for * rx/tx statistics and link status, in addition to KEEPALIVE traffic * and normal HC level polling to see if there's any IN traffic. @@ -1074,12 +1073,12 @@ int rndis_msg_parser (u8 configNr, u8 *buf) /* For USB: responses may take up to 10 seconds */ switch (MsgType) { case REMOTE_NDIS_INITIALIZE_MSG: - DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", + DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __FUNCTION__ ); params->state = RNDIS_INITIALIZED; return rndis_init_response (configNr, - (rndis_init_msg_type *) buf); - + (rndis_init_msg_type *) buf); + case REMOTE_NDIS_HALT_MSG: DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", __FUNCTION__ ); @@ -1089,37 +1088,37 @@ int rndis_msg_parser (u8 configNr, u8 *buf) netif_stop_queue (params->dev); } return 0; - + case REMOTE_NDIS_QUERY_MSG: - return rndis_query_response (configNr, - (rndis_query_msg_type *) buf); - + return rndis_query_response (configNr, + (rndis_query_msg_type *) buf); + case REMOTE_NDIS_SET_MSG: - return rndis_set_response (configNr, - (rndis_set_msg_type *) buf); - + return rndis_set_response (configNr, + (rndis_set_msg_type *) buf); + case REMOTE_NDIS_RESET_MSG: - DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", + DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", __FUNCTION__ ); return rndis_reset_response (configNr, - (rndis_reset_msg_type *) buf); + (rndis_reset_msg_type *) buf); case REMOTE_NDIS_KEEPALIVE_MSG: /* For USB: host does this every 5 seconds */ if (rndis_debug > 1) - DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", + DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __FUNCTION__ ); return rndis_keepalive_response (configNr, - (rndis_keepalive_msg_type *) + (rndis_keepalive_msg_type *) buf); - - default: + + default: /* At least Windows XP emits some undefined RNDIS messages. * In one case those messages seemed to relate to the host * suspending itself. */ printk (KERN_WARNING - "%s: unknown RNDIS message 0x%08X len %d\n", + "%s: unknown RNDIS message 0x%08X len %d\n", __FUNCTION__ , MsgType, MsgLength); { unsigned i; @@ -1143,14 +1142,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf) } break; } - + return -ENOTSUPP; } int rndis_register (int (* rndis_control_ack) (struct net_device *)) { u8 i; - + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { if (!rndis_per_dev_params [i].used) { rndis_per_dev_params [i].used = 1; @@ -1160,32 +1159,32 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *)) } } DEBUG("failed\n"); - + return -1; } void rndis_deregister (int configNr) { DEBUG("%s: \n", __FUNCTION__ ); - + if (configNr >= RNDIS_MAX_CONFIGS) return; rndis_per_dev_params [configNr].used = 0; - + return; } -int rndis_set_param_dev (u8 configNr, struct net_device *dev, +int rndis_set_param_dev (u8 configNr, struct net_device *dev, struct net_device_stats *stats, u16 *cdc_filter) { DEBUG("%s:\n", __FUNCTION__ ); if (!dev || !stats) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].dev = dev; rndis_per_dev_params [configNr].stats = stats; rndis_per_dev_params [configNr].filter = cdc_filter; - + return 0; } @@ -1194,10 +1193,10 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr) DEBUG("%s:\n", __FUNCTION__ ); if (!vendorDescr) return -1; if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].vendorID = vendorID; rndis_per_dev_params [configNr].vendorDescr = vendorDescr; - + return 0; } @@ -1205,10 +1204,10 @@ int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed) { DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed); if (configNr >= RNDIS_MAX_CONFIGS) return -1; - + rndis_per_dev_params [configNr].medium = medium; rndis_per_dev_params [configNr].speed = speed; - + return 0; } @@ -1230,9 +1229,9 @@ void rndis_free_response (int configNr, u8 *buf) { rndis_resp_t *r; struct list_head *act, *tmp; - - list_for_each_safe (act, tmp, - &(rndis_per_dev_params [configNr].resp_queue)) + + list_for_each_safe (act, tmp, + &(rndis_per_dev_params [configNr].resp_queue)) { r = list_entry (act, rndis_resp_t, list); if (r && r->buf == buf) { @@ -1245,12 +1244,12 @@ void rndis_free_response (int configNr, u8 *buf) u8 *rndis_get_next_response (int configNr, u32 *length) { rndis_resp_t *r; - struct list_head *act, *tmp; - + struct list_head *act, *tmp; + if (!length) return NULL; - - list_for_each_safe (act, tmp, - &(rndis_per_dev_params [configNr].resp_queue)) + + list_for_each_safe (act, tmp, + &(rndis_per_dev_params [configNr].resp_queue)) { r = list_entry (act, rndis_resp_t, list); if (!r->send) { @@ -1259,24 +1258,24 @@ u8 *rndis_get_next_response (int configNr, u32 *length) return r->buf; } } - + return NULL; } static rndis_resp_t *rndis_add_response (int configNr, u32 length) { rndis_resp_t *r; - + /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC); if (!r) return NULL; - + r->buf = (u8 *) (r + 1); r->length = length; r->send = 0; - - list_add_tail (&r->list, - &(rndis_per_dev_params [configNr].resp_queue)); + + list_add_tail (&r->list, + &(rndis_per_dev_params [configNr].resp_queue)); return r; } @@ -1302,14 +1301,14 @@ int rndis_rm_hdr(struct sk_buff *skb) #ifdef CONFIG_USB_GADGET_DEBUG_FILES -static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, - void *data) +static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, + void *data) { char *out = page; int len; rndis_params *param = (rndis_params *) data; - - out += snprintf (out, count, + + out += snprintf (out, count, "Config Nr. %d\n" "used : %s\n" "state : %s\n" @@ -1317,8 +1316,8 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int "speed : %d\n" "cable : %s\n" "vendor ID : 0x%08X\n" - "vendor : %s\n", - param->confignr, (param->used) ? "y" : "n", + "vendor : %s\n", + param->confignr, (param->used) ? "y" : "n", ({ char *s = "?"; switch (param->state) { case RNDIS_UNINITIALIZED: @@ -1328,32 +1327,32 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int case RNDIS_DATA_INITIALIZED: s = "RNDIS_DATA_INITIALIZED"; break; }; s; }), - param->medium, - (param->media_state) ? 0 : param->speed*100, + param->medium, + (param->media_state) ? 0 : param->speed*100, (param->media_state) ? "disconnected" : "connected", - param->vendorID, param->vendorDescr); - + param->vendorID, param->vendorDescr); + len = out - page; len -= off; - + if (len < count) { *eof = 1; if (len <= 0) return 0; } else len = count; - + *start = page + off; return len; } -static int rndis_proc_write (struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int rndis_proc_write (struct file *file, const char __user *buffer, + unsigned long count, void *data) { rndis_params *p = data; u32 speed = 0; int i, fl_speed = 0; - + for (i = 0; i < count; i++) { char c; if (get_user(c, buffer)) @@ -1380,15 +1379,15 @@ static int rndis_proc_write (struct file *file, const char __user *buffer, case 'd': rndis_signal_disconnect(p->confignr); break; - default: + default: if (fl_speed) p->speed = speed; else DEBUG ("%c is not valid\n", c); break; } - + buffer++; } - + return count; } @@ -1409,7 +1408,7 @@ int __init rndis_init (void) sprintf (name, NAME_TEMPLATE, i); if (!(rndis_connect_state [i] - = create_proc_entry (name, 0660, NULL))) + = create_proc_entry (name, 0660, NULL))) { DEBUG ("%s :remove entries", __FUNCTION__); while (i) { @@ -1433,7 +1432,7 @@ int __init rndis_init (void) = NDIS_MEDIA_STATE_DISCONNECTED; INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue)); } - + return 0; } @@ -1442,7 +1441,7 @@ void rndis_exit (void) #ifdef CONFIG_USB_GADGET_DEBUG_FILES u8 i; char name [20]; - + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { sprintf (name, NAME_TEMPLATE, i); remove_proc_entry (name, NULL); diff --git a/trunk/drivers/usb/gadget/rndis.h b/trunk/drivers/usb/gadget/rndis.h index 2956608be751..95b4c6326100 100644 --- a/trunk/drivers/usb/gadget/rndis.h +++ b/trunk/drivers/usb/gadget/rndis.h @@ -1,15 +1,15 @@ -/* +/* * RNDIS Definitions for Remote NDIS - * + * * Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $ - * + * * Authors: Benedikt Spranger, Pengutronix - * Robert Schwebel, Pengutronix - * - * This program is free software; you can redistribute it and/or + * Robert Schwebel, Pengutronix + * + * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * + * version 2, as published by the Free Software Foundation. + * * This software was originally developed in conformance with * Microsoft's Remote NDIS Specification License Agreement. */ @@ -34,7 +34,7 @@ #define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ #define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ /* For all not specified status messages: - * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx + * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx */ /* Message Set for Connectionless (802.3) Devices */ @@ -69,7 +69,7 @@ #define OID_PNP_ENABLE_WAKE_UP 0xFD010106 -typedef struct rndis_init_msg_type +typedef struct rndis_init_msg_type { __le32 MessageType; __le32 MessageLength; @@ -234,12 +234,12 @@ typedef struct rndis_params const u8 *host_mac; u16 *filter; - struct net_device *dev; + struct net_device *dev; struct net_device_stats *stats; u32 vendorID; const char *vendorDescr; - int (*ack) (struct net_device *); + int (*ack) (struct net_device *); struct list_head resp_queue; } rndis_params; @@ -250,7 +250,7 @@ void rndis_deregister (int configNr); int rndis_set_param_dev (u8 configNr, struct net_device *dev, struct net_device_stats *stats, u16 *cdc_filter); -int rndis_set_param_vendor (u8 configNr, u32 vendorID, +int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr); int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); void rndis_add_hdr (struct sk_buff *skb); diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 9d6e1d295528..b992546c394d 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -45,16 +45,88 @@ #include #include -#include +#include #include #include "gadget_chips.h" +/* Wait Cond */ + +#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + spin_unlock_irqrestore(lock, flags); \ + schedule(); \ + spin_lock_irqsave(lock, flags); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_cond_interruptible(wq, condition, lock, flags) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __wait_cond_interruptible(wq, condition, lock, flags, \ + __ret); \ + __ret; \ +}) + +#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \ + timeout, ret) \ +do { \ + signed long __timeout = timeout; \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (__timeout == 0) \ + break; \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + spin_unlock_irqrestore(lock, flags); \ + __timeout = schedule_timeout(__timeout); \ + spin_lock_irqsave(lock, flags); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \ + timeout) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __wait_cond_interruptible_timeout(wq, condition, lock, \ + flags, timeout, __ret); \ + __ret; \ +}) + + /* Defines */ -#define GS_VERSION_STR "v2.2" -#define GS_VERSION_NUM 0x0202 +#define GS_VERSION_STR "v2.0" +#define GS_VERSION_NUM 0x0200 #define GS_LONG_NAME "Gadget Serial" #define GS_SHORT_NAME "g_serial" @@ -771,19 +843,9 @@ static int gs_open(struct tty_struct *tty, struct file *file) /* * gs_close */ - -#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \ -({ \ - int cond; \ - \ - spin_lock_irq(&(p)->port_lock); \ - cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \ - spin_unlock_irq(&(p)->port_lock); \ - cond; \ -}) - static void gs_close(struct tty_struct *tty, struct file *file) { + unsigned long flags; struct gs_port *port = tty->driver_data; struct semaphore *sem; @@ -797,7 +859,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) sem = &gs_open_close_sem[port->port_num]; down(sem); - spin_lock_irq(&port->port_lock); + spin_lock_irqsave(&port->port_lock, flags); if (port->port_open_count == 0) { printk(KERN_ERR @@ -825,11 +887,12 @@ static void gs_close(struct tty_struct *tty, struct file *file) /* wait for write buffer to drain, or */ /* at most GS_CLOSE_TIMEOUT seconds */ if (gs_buf_data_avail(port->port_write_buf) > 0) { - spin_unlock_irq(&port->port_lock); - wait_event_interruptible_timeout(port->port_write_wait, - GS_WRITE_FINISHED_EVENT_SAFELY(port), - GS_CLOSE_TIMEOUT * HZ); - spin_lock_irq(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); + wait_cond_interruptible_timeout(port->port_write_wait, + port->port_dev == NULL + || gs_buf_data_avail(port->port_write_buf) == 0, + &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); + spin_lock_irqsave(&port->port_lock, flags); } /* free disconnected port on final close */ @@ -849,7 +912,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) port->port_num, tty, file); exit: - spin_unlock_irq(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); up(sem); } diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index b93d71d28db7..e27b79a3c05f 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -47,29 +47,12 @@ config USB_EHCI_ROOT_HUB_TT controller is needed. It's safe to say "y" even if your controller doesn't support this feature. - This supports the EHCI implementation that's originally - from ARC, and has since changed hands a few times. - -config USB_EHCI_TT_NEWSCHED - bool "Improved Transaction Translator scheduling (EXPERIMENTAL)" - depends on USB_EHCI_HCD && EXPERIMENTAL - ---help--- - This changes the periodic scheduling code to fill more of the low - and full speed bandwidth available from the Transaction Translator - (TT) in USB 2.0 hubs. Without this, only one transfer will be - issued in each microframe, significantly reducing the number of - periodic low/fullspeed transfers possible. - - If you have multiple periodic low/fullspeed devices connected to a - highspeed USB hub which is connected to a highspeed USB Host - Controller, and some of those devices will not work correctly - (possibly due to "ENOSPC" or "-28" errors), say Y. - - If unsure, say N. + This supports the EHCI implementation from TransDimension Inc. config USB_ISP116X_HCD tristate "ISP116X HCD support" depends on USB + default N ---help--- The ISP1160 and ISP1161 chips are USB host controllers. Enable this option if your board has this chip. If unsure, say N. @@ -144,6 +127,7 @@ config USB_UHCI_HCD config USB_SL811_HCD tristate "SL811HS HCD support" depends on USB + default N help The SL811HS is a single-port USB controller that supports either host side or peripheral side roles. Enable this option if your @@ -156,6 +140,7 @@ config USB_SL811_HCD config USB_SL811_CS tristate "CF/PCMCIA support for SL811HS HCD" depends on USB_SL811_HCD && PCMCIA + default N help Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC REX-CFU1U CF card (often used with PDAs). If unsure, say N. diff --git a/trunk/drivers/usb/host/ehci-au1xxx.c b/trunk/drivers/usb/host/ehci-au1xxx.c index 9b4697add313..63eadeec1324 100644 --- a/trunk/drivers/usb/host/ehci-au1xxx.c +++ b/trunk/drivers/usb/host/ehci-au1xxx.c @@ -16,6 +16,10 @@ #include #include +#ifndef CONFIG_SOC_AU1200 +#error "this Alchemy chip doesn't have EHCI" +#else /* Au1200 */ + #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) #define USB_MCFG_PFEN (1<<31) #define USB_MCFG_RDCOMB (1<<30) @@ -268,8 +272,6 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev) return 0; } */ -MODULE_ALIAS("au1xxx-ehci"); -/* FIXME use "struct platform_driver" */ static struct device_driver ehci_hcd_au1xxx_driver = { .name = "au1xxx-ehci", .bus = &platform_bus_type, @@ -278,3 +280,18 @@ static struct device_driver ehci_hcd_au1xxx_driver = { /*.suspend = ehci_hcd_au1xxx_drv_suspend, */ /*.resume = ehci_hcd_au1xxx_drv_resume, */ }; + +static int __init ehci_hcd_au1xxx_init(void) +{ + pr_debug(DRIVER_INFO " (Au1xxx)\n"); + + return driver_register(&ehci_hcd_au1xxx_driver); +} + +static void __exit ehci_hcd_au1xxx_cleanup(void) +{ + driver_unregister(&ehci_hcd_au1xxx_driver); +} + +module_init(ehci_hcd_au1xxx_init); +module_exit(ehci_hcd_au1xxx_cleanup); diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index a49a689bf423..f985f121a245 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -324,12 +324,43 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev) return 0; } -MODULE_ALIAS("fsl-ehci"); +static struct platform_driver ehci_fsl_dr_driver = { + .probe = ehci_fsl_drv_probe, + .remove = ehci_fsl_drv_remove, + .driver = { + .name = "fsl-usb2-dr", + }, +}; -static struct platform_driver ehci_fsl_driver = { +static struct platform_driver ehci_fsl_mph_driver = { .probe = ehci_fsl_drv_probe, .remove = ehci_fsl_drv_remove, .driver = { - .name = "fsl-ehci", + .name = "fsl-usb2-mph", }, }; + +static int __init ehci_fsl_init(void) +{ + int retval; + + pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", + hcd_name, + sizeof(struct ehci_qh), sizeof(struct ehci_qtd), + sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); + + retval = platform_driver_register(&ehci_fsl_dr_driver); + if (retval) + return retval; + + return platform_driver_register(&ehci_fsl_mph_driver); +} + +static void __exit ehci_fsl_cleanup(void) +{ + platform_driver_unregister(&ehci_fsl_mph_driver); + platform_driver_unregister(&ehci_fsl_dr_driver); +} + +module_init(ehci_fsl_init); +module_exit(ehci_fsl_cleanup); diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 9b37e508ada3..79f2d8b9bfb6 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -889,59 +889,19 @@ MODULE_LICENSE ("GPL"); #ifdef CONFIG_PCI #include "ehci-pci.c" -#define PCI_DRIVER ehci_pci_driver +#define EHCI_BUS_GLUED #endif #ifdef CONFIG_PPC_83xx #include "ehci-fsl.c" -#define PLATFORM_DRIVER ehci_fsl_driver +#define EHCI_BUS_GLUED #endif -#ifdef CONFIG_SOC_AU1200 +#ifdef CONFIG_SOC_AU1X00 #include "ehci-au1xxx.c" -#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver +#define EHCI_BUS_GLUED #endif -#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) +#ifndef EHCI_BUS_GLUED #error "missing bus glue for ehci-hcd" #endif - -static int __init ehci_hcd_init(void) -{ - int retval = 0; - - pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", - hcd_name, - sizeof(struct ehci_qh), sizeof(struct ehci_qtd), - sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); - -#ifdef PLATFORM_DRIVER - retval = platform_driver_register(&PLATFORM_DRIVER); - if (retval < 0) - return retval; -#endif - -#ifdef PCI_DRIVER - retval = pci_register_driver(&PCI_DRIVER); - if (retval < 0) { -#ifdef PLATFORM_DRIVER - platform_driver_unregister(&PLATFORM_DRIVER); -#endif - } -#endif - - return retval; -} -module_init(ehci_hcd_init); - -static void __exit ehci_hcd_cleanup(void) -{ -#ifdef PLATFORM_DRIVER - platform_driver_unregister(&PLATFORM_DRIVER); -#endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -#endif -} -module_exit(ehci_hcd_cleanup); - diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index cadffacd945b..a1bd2bea6deb 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -76,30 +76,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); - /* ehci_init() causes memory for DMA transfers to be - * allocated. Thus, any vendor-specific workarounds based on - * limiting the type of memory used for DMA transfers must - * happen before ehci_init() is called. */ - switch (pdev->vendor) { - case PCI_VENDOR_ID_NVIDIA: - /* NVidia reports that certain chips don't handle - * QH, ITD, or SITD addresses above 2GB. (But TD, - * data buffer, and periodic schedule are normal.) - */ - switch (pdev->device) { - case 0x003c: /* MCP04 */ - case 0x005b: /* CK804 */ - case 0x00d8: /* CK8 */ - case 0x00e8: /* CK8S */ - if (pci_set_consistent_dma_mask(pdev, - DMA_31BIT_MASK) < 0) - ehci_warn(ehci, "can't enable NVidia " - "workaround for >2GB RAM\n"); - break; - } - break; - } - /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); @@ -112,6 +88,8 @@ static int ehci_pci_setup(struct usb_hcd *hcd) if (retval) return retval; + /* NOTE: only the parts below this line are PCI-specific */ + switch (pdev->vendor) { case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { @@ -129,6 +107,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd) break; case PCI_VENDOR_ID_NVIDIA: switch (pdev->device) { + /* NVidia reports that certain chips don't handle + * QH, ITD, or SITD addresses above 2GB. (But TD, + * data buffer, and periodic schedule are normal.) + */ + case 0x003c: /* MCP04 */ + case 0x005b: /* CK804 */ + case 0x00d8: /* CK8 */ + case 0x00e8: /* CK8S */ + if (pci_set_consistent_dma_mask(pdev, + DMA_31BIT_MASK) < 0) + ehci_warn(ehci, "can't enable NVidia " + "workaround for >2GB RAM\n"); + break; /* Some NForce2 chips have problems with selective suspend; * fixed in newer silicon. */ @@ -379,3 +370,23 @@ static struct pci_driver ehci_pci_driver = { .resume = usb_hcd_pci_resume, #endif }; + +static int __init ehci_hcd_pci_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", + hcd_name, + sizeof(struct ehci_qh), sizeof(struct ehci_qtd), + sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); + + return pci_register_driver(&ehci_pci_driver); +} +module_init(ehci_hcd_pci_init); + +static void __exit ehci_hcd_pci_cleanup(void) +{ + pci_unregister_driver(&ehci_pci_driver); +} +module_exit(ehci_hcd_pci_cleanup); diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 4859900bd135..5871944e6145 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -163,190 +163,6 @@ static int same_tt (struct usb_device *dev1, struct usb_device *dev2) return 1; } -#ifdef CONFIG_USB_EHCI_TT_NEWSCHED - -/* Which uframe does the low/fullspeed transfer start in? - * - * The parameter is the mask of ssplits in "H-frame" terms - * and this returns the transfer start uframe in "B-frame" terms, - * which allows both to match, e.g. a ssplit in "H-frame" uframe 0 - * will cause a transfer in "B-frame" uframe 0. "B-frames" lag - * "H-frames" by 1 uframe. See the EHCI spec sec 4.5 and figure 4.7. - */ -static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __le32 mask) -{ - unsigned char smask = QH_SMASK & le32_to_cpu(mask); - if (!smask) { - ehci_err(ehci, "invalid empty smask!\n"); - /* uframe 7 can't have bw so this will indicate failure */ - return 7; - } - return ffs(smask) - 1; -} - -static const unsigned char -max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; - -/* carryover low/fullspeed bandwidth that crosses uframe boundries */ -static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) -{ - int i; - for (i=0; i<7; i++) { - if (max_tt_usecs[i] < tt_usecs[i]) { - tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i]; - tt_usecs[i] = max_tt_usecs[i]; - } - } -} - -/* How many of the tt's periodic downstream 1000 usecs are allocated? - * - * While this measures the bandwidth in terms of usecs/uframe, - * the low/fullspeed bus has no notion of uframes, so any particular - * low/fullspeed transfer can "carry over" from one uframe to the next, - * since the TT just performs downstream transfers in sequence. - * - * For example two seperate 100 usec transfers can start in the same uframe, - * and the second one would "carry over" 75 usecs into the next uframe. - */ -static void -periodic_tt_usecs ( - struct ehci_hcd *ehci, - struct usb_device *dev, - unsigned frame, - unsigned short tt_usecs[8] -) -{ - __le32 *hw_p = &ehci->periodic [frame]; - union ehci_shadow *q = &ehci->pshadow [frame]; - unsigned char uf; - - memset(tt_usecs, 0, 16); - - while (q->ptr) { - switch (Q_NEXT_TYPE(*hw_p)) { - case Q_TYPE_ITD: - hw_p = &q->itd->hw_next; - q = &q->itd->itd_next; - continue; - case Q_TYPE_QH: - if (same_tt(dev, q->qh->dev)) { - uf = tt_start_uframe(ehci, q->qh->hw_info2); - tt_usecs[uf] += q->qh->tt_usecs; - } - hw_p = &q->qh->hw_next; - q = &q->qh->qh_next; - continue; - case Q_TYPE_SITD: - if (same_tt(dev, q->sitd->urb->dev)) { - uf = tt_start_uframe(ehci, q->sitd->hw_uframe); - tt_usecs[uf] += q->sitd->stream->tt_usecs; - } - hw_p = &q->sitd->hw_next; - q = &q->sitd->sitd_next; - continue; - // case Q_TYPE_FSTN: - default: - ehci_dbg(ehci, - "ignoring periodic frame %d FSTN\n", frame); - hw_p = &q->fstn->hw_next; - q = &q->fstn->fstn_next; - } - } - - carryover_tt_bandwidth(tt_usecs); - - if (max_tt_usecs[7] < tt_usecs[7]) - ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n", - frame, tt_usecs[7] - max_tt_usecs[7]); -} - -/* - * Return true if the device's tt's downstream bus is available for a - * periodic transfer of the specified length (usecs), starting at the - * specified frame/uframe. Note that (as summarized in section 11.19 - * of the usb 2.0 spec) TTs can buffer multiple transactions for each - * uframe. - * - * The uframe parameter is when the fullspeed/lowspeed transfer - * should be executed in "B-frame" terms, which is the same as the - * highspeed ssplit's uframe (which is in "H-frame" terms). For example - * a ssplit in "H-frame" 0 causes a transfer in "B-frame" 0. - * See the EHCI spec sec 4.5 and fig 4.7. - * - * This checks if the full/lowspeed bus, at the specified starting uframe, - * has the specified bandwidth available, according to rules listed - * in USB 2.0 spec section 11.18.1 fig 11-60. - * - * This does not check if the transfer would exceed the max ssplit - * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4, - * since proper scheduling limits ssplits to less than 16 per uframe. - */ -static int tt_available ( - struct ehci_hcd *ehci, - unsigned period, - struct usb_device *dev, - unsigned frame, - unsigned uframe, - u16 usecs -) -{ - if ((period == 0) || (uframe >= 7)) /* error */ - return 0; - - for (; frame < ehci->periodic_size; frame += period) { - unsigned short tt_usecs[8]; - - periodic_tt_usecs (ehci, dev, frame, tt_usecs); - - ehci_vdbg(ehci, "tt frame %d check %d usecs start uframe %d in" - " schedule %d/%d/%d/%d/%d/%d/%d/%d\n", - frame, usecs, uframe, - tt_usecs[0], tt_usecs[1], tt_usecs[2], tt_usecs[3], - tt_usecs[4], tt_usecs[5], tt_usecs[6], tt_usecs[7]); - - if (max_tt_usecs[uframe] <= tt_usecs[uframe]) { - ehci_vdbg(ehci, "frame %d uframe %d fully scheduled\n", - frame, uframe); - return 0; - } - - /* special case for isoc transfers larger than 125us: - * the first and each subsequent fully used uframe - * must be empty, so as to not illegally delay - * already scheduled transactions - */ - if (125 < usecs) { - int ufs = (usecs / 125) - 1; - int i; - for (i = uframe; i < (uframe + ufs) && i < 8; i++) - if (0 < tt_usecs[i]) { - ehci_vdbg(ehci, - "multi-uframe xfer can't fit " - "in frame %d uframe %d\n", - frame, i); - return 0; - } - } - - tt_usecs[uframe] += usecs; - - carryover_tt_bandwidth(tt_usecs); - - /* fail if the carryover pushed bw past the last uframe's limit */ - if (max_tt_usecs[7] < tt_usecs[7]) { - ehci_vdbg(ehci, - "tt unavailable usecs %d frame %d uframe %d\n", - usecs, frame, uframe); - return 0; - } - } - - return 1; -} - -#else - /* return true iff the device's transaction translator is available * for a periodic transfer starting at the specified frame, using * all the uframes in the mask. @@ -421,8 +237,6 @@ static int tt_no_collision ( return 1; } -#endif /* CONFIG_USB_EHCI_TT_NEWSCHED */ - /*-------------------------------------------------------------------------*/ static int enable_periodic (struct ehci_hcd *ehci) @@ -667,7 +481,7 @@ static int check_intr_schedule ( ) { int retval = -ENOSPC; - u8 mask = 0; + u8 mask; if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ goto done; @@ -680,24 +494,6 @@ static int check_intr_schedule ( goto done; } -#ifdef CONFIG_USB_EHCI_TT_NEWSCHED - if (tt_available (ehci, qh->period, qh->dev, frame, uframe, - qh->tt_usecs)) { - unsigned i; - - /* TODO : this may need FSTN for SSPLIT in uframe 5. */ - for (i=uframe+1; i<8 && iperiod, qh->c_usecs)) - goto done; - else - mask |= 1 << i; - - retval = 0; - - *c_maskp = cpu_to_le32 (mask << 8); - } -#else /* Make sure this tt's buffer is also available for CSPLITs. * We pessimize a bit; probably the typical full speed case * doesn't need the second CSPLIT. @@ -718,7 +514,6 @@ static int check_intr_schedule ( goto done; retval = 0; } -#endif done: return retval; } @@ -1252,21 +1047,12 @@ sitd_slot_ok ( frame = uframe >> 3; uf = uframe & 7; -#ifdef CONFIG_USB_EHCI_TT_NEWSCHED - /* The tt's fullspeed bus bandwidth must be available. - * tt_available scheduling guarantees 10+% for control/bulk. - */ - if (!tt_available (ehci, period_uframes << 3, - stream->udev, frame, uf, stream->tt_usecs)) - return 0; -#else /* tt must be idle for start(s), any gap, and csplit. * assume scheduling slop leaves 10+% for control/bulk. */ if (!tt_no_collision (ehci, period_uframes << 3, stream->udev, frame, mask)) return 0; -#endif /* check starts (OUT uses more than one) */ max_used = 100 - stream->usecs; diff --git a/trunk/drivers/usb/host/hc_crisv10.c b/trunk/drivers/usb/host/hc_crisv10.c index 4a22909518f5..2fe7fd19437b 100644 --- a/trunk/drivers/usb/host/hc_crisv10.c +++ b/trunk/drivers/usb/host/hc_crisv10.c @@ -411,7 +411,8 @@ static inline void urb_list_move_last(struct urb *urb, int epid) urb_entry_t *urb_entry = __urb_list_entry(urb, epid); assert(urb_entry); - list_move_tail(&urb_entry->list, &urb_list[epid]); + list_del(&urb_entry->list); + list_add_tail(&urb_entry->list, &urb_list[epid]); } /* Get the next urb in the list. */ diff --git a/trunk/drivers/usb/host/isp116x-hcd.c b/trunk/drivers/usb/host/isp116x-hcd.c index 14386254c870..e99210b7909b 100644 --- a/trunk/drivers/usb/host/isp116x-hcd.c +++ b/trunk/drivers/usb/host/isp116x-hcd.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include @@ -781,7 +781,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, if (ep->branch < PERIODIC_SIZE) break; - ep->branch = ret = balance(isp116x, ep->period, ep->load); + ret = ep->branch = balance(isp116x, ep->period, ep->load); if (ret < 0) goto fail; ret = 0; diff --git a/trunk/drivers/usb/host/sl811-hcd.c b/trunk/drivers/usb/host/sl811-hcd.c index 6b4bc3f2bd86..a92343052751 100644 --- a/trunk/drivers/usb/host/sl811-hcd.c +++ b/trunk/drivers/usb/host/sl811-hcd.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/usb/host/sl811_cs.c b/trunk/drivers/usb/host/sl811_cs.c index 54f554e0f0ad..302aa1ec312f 100644 --- a/trunk/drivers/usb/host/sl811_cs.c +++ b/trunk/drivers/usb/host/sl811_cs.c @@ -27,7 +27,7 @@ #include #include -#include +#include MODULE_AUTHOR("Botond Botyanszki"); MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); diff --git a/trunk/drivers/usb/host/uhci-debug.c b/trunk/drivers/usb/host/uhci-debug.c index 6637a0e49978..e1239319655c 100644 --- a/trunk/drivers/usb/host/uhci-debug.c +++ b/trunk/drivers/usb/host/uhci-debug.c @@ -98,7 +98,6 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) char *out = buf; struct uhci_td *td; int i, nactive, ninactive; - char *ptype; if (len < 200) return 0; @@ -111,15 +110,13 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); switch (usb_pipetype(urbp->urb->pipe)) { - case PIPE_ISOCHRONOUS: ptype = "ISO"; break; - case PIPE_INTERRUPT: ptype = "INT"; break; - case PIPE_BULK: ptype = "BLK"; break; - default: - case PIPE_CONTROL: ptype = "CTL"; break; + case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO"); break; + case PIPE_INTERRUPT: out += sprintf(out, "INT"); break; + case PIPE_BULK: out += sprintf(out, "BLK"); break; + case PIPE_CONTROL: out += sprintf(out, "CTL"); break; } - out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); - out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); + out += sprintf(out, "%s", (urbp->fsbr ? " FSBR" : "")); if (urbp->urb->status != -EINPROGRESS) out += sprintf(out, " Status=%d", urbp->urb->status); @@ -127,8 +124,7 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) i = nactive = ninactive = 0; list_for_each_entry(td, &urbp->td_list, list) { - if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC && - (++i <= 10 || debug > 2)) { + if (++i <= 10 || debug > 2) { out += sprintf(out, "%*s%d: ", space + 2, "", i); out += uhci_show_td(td, out, len - (out - buf), 0); } else { @@ -151,27 +147,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) char *out = buf; int i, nurbs; __le32 element = qh_element(qh); - char *qtype; /* Try to make sure there's enough memory */ - if (len < 80 * 7) + if (len < 80 * 6) return 0; - switch (qh->type) { - case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break; - case USB_ENDPOINT_XFER_INT: qtype = "INT"; break; - case USB_ENDPOINT_XFER_BULK: qtype = "BLK"; break; - case USB_ENDPOINT_XFER_CONTROL: qtype = "CTL"; break; - default: qtype = "Skel" ; break; - } - - out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n", - space, "", qh, qtype, - le32_to_cpu(qh->link), le32_to_cpu(element)); - if (qh->type == USB_ENDPOINT_XFER_ISOC) - out += sprintf(out, "%*s period %d frame %x desc [%p]\n", - space, "", qh->period, qh->iso_frame, - qh->iso_packet_desc); + out += sprintf(out, "%*s[%p] link (%08x) element (%08x)\n", space, "", + qh, le32_to_cpu(qh->link), le32_to_cpu(element)); if (element & UHCI_PTR_QH) out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); @@ -279,8 +261,7 @@ static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len) default: rh_state = "?"; break; } - out += sprintf(out, "Root-hub state: %s FSBR: %d\n", - rh_state, uhci->fsbr_is_on); + out += sprintf(out, "Root-hub state: %s\n", rh_state); return out - buf; } @@ -294,7 +275,7 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) unsigned short portsc1, portsc2; /* Try to make sure there's enough memory */ - if (len < 80 * 9) + if (len < 80 * 6) return 0; usbcmd = inw(io_addr + 0); @@ -333,10 +314,6 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) out += sprintf(out, " sof = %02x\n", sof); out += uhci_show_sc(1, portsc1, out, len - (out - buf)); out += uhci_show_sc(2, portsc2, out, len - (out - buf)); - out += sprintf(out, "Most recent frame: %x (%d) " - "Last ISO frame: %x (%d)\n", - uhci->frame_number, uhci->frame_number & 1023, - uhci->last_iso_frame, uhci->last_iso_frame & 1023); return out - buf; } diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index 7b48567622ef..d225e11f4055 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -13,7 +13,7 @@ * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) - * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu + * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu * * Intel documents this fairly well, and as far as I know there * are no royalties or anything like that, but even so there are @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,15 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); static void wakeup_rh(struct uhci_hcd *uhci); static void uhci_get_current_frame_number(struct uhci_hcd *uhci); +/* If a transfer is still active after this much time, turn off FSBR */ +#define IDLE_TIMEOUT msecs_to_jiffies(50) +#define FSBR_DELAY msecs_to_jiffies(50) + +/* When we timeout an idle transfer for FSBR, we'll switch it over to */ +/* depth first traversal. We'll do it in groups of this number of TDs */ +/* to make sure it doesn't hog all of the bandwidth */ +#define DEPTH_INTERVAL 5 + #include "uhci-debug.c" #include "uhci-q.c" #include "uhci-hub.c" @@ -110,29 +120,22 @@ static void finish_reset(struct uhci_hcd *uhci) uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->state = HC_STATE_HALT; uhci_to_hcd(uhci)->poll_rh = 0; - - uhci->dead = 0; /* Full reset resurrects the controller */ } /* * Last rites for a defunct/nonfunctional controller * or one we don't want to use any more. */ -static void uhci_hc_died(struct uhci_hcd *uhci) +static void hc_died(struct uhci_hcd *uhci) { - uhci_get_current_frame_number(uhci); uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); finish_reset(uhci); - uhci->dead = 1; - - /* The current frame may already be partway finished */ - ++uhci->frame_number; + uhci->hc_inaccessible = 1; } /* - * Initialize a controller that was newly discovered or has lost power - * or otherwise been reset while it was suspended. In none of these cases - * can we be sure of its previous state. + * Initialize a controller that was newly discovered or has just been + * resumed. In either case we can't be sure of its previous state. */ static void check_and_reset_hc(struct uhci_hcd *uhci) { @@ -152,8 +155,7 @@ static void configure_hc(struct uhci_hcd *uhci) outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); /* Set the current frame number */ - outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER, - uhci->io_addr + USBFRNUM); + outw(uhci->frame_number, uhci->io_addr + USBFRNUM); /* Mark controller as not halted before we enable interrupts */ uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; @@ -205,8 +207,7 @@ __acquires(uhci->lock) int int_enable; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); - dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, - "%s%s\n", __FUNCTION__, + dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__, (auto_stop ? " (auto-stop)" : "")); /* If we get a suspend request when we're already auto-stopped @@ -240,27 +241,27 @@ __acquires(uhci->lock) spin_unlock_irq(&uhci->lock); msleep(1); spin_lock_irq(&uhci->lock); - if (uhci->dead) + if (uhci->hc_inaccessible) /* Died */ return; } if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) - dev_warn(&uhci_to_hcd(uhci)->self.root_hub->dev, - "Controller not stopped yet!\n"); + dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n"); uhci_get_current_frame_number(uhci); + smp_wmb(); uhci->rh_state = new_state; uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->poll_rh = !int_enable; uhci_scan_schedule(uhci, NULL); - uhci_fsbr_off(uhci); } static void start_rh(struct uhci_hcd *uhci) { uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; uhci->is_stopped = 0; + smp_wmb(); /* Mark it configured and running with a 64-byte max packet. * All interrupts are enabled, even though RESUME won't do anything. @@ -277,8 +278,7 @@ static void wakeup_rh(struct uhci_hcd *uhci) __releases(uhci->lock) __acquires(uhci->lock) { - dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, - "%s%s\n", __FUNCTION__, + dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__, uhci->rh_state == UHCI_RH_AUTO_STOPPED ? " (auto-start)" : ""); @@ -293,7 +293,7 @@ __acquires(uhci->lock) spin_unlock_irq(&uhci->lock); msleep(20); spin_lock_irq(&uhci->lock); - if (uhci->dead) + if (uhci->hc_inaccessible) /* Died */ return; /* End Global Resume and wait for EOP to be sent */ @@ -345,7 +345,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) errbuf, ERRBUF_LEN); lprintk(errbuf); } - uhci_hc_died(uhci); + hc_died(uhci); /* Force a callback in case there are * pending unlinks */ @@ -368,21 +368,12 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) /* * Store the current frame number in uhci->frame_number if the controller - * is runnning. Expand from 11 bits (of which we use only 10) to a - * full-sized integer. - * - * Like many other parts of the driver, this code relies on being polled - * more than once per second as long as the controller is running. + * is runnning */ static void uhci_get_current_frame_number(struct uhci_hcd *uhci) { - if (!uhci->is_stopped) { - unsigned delta; - - delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) & - (UHCI_NUMFRAMES - 1); - uhci->frame_number += delta; - } + if (!uhci->is_stopped) + uhci->frame_number = inw(uhci->io_addr + USBFRNUM); } /* @@ -416,7 +407,7 @@ static void release_uhci(struct uhci_hcd *uhci) uhci->frame, uhci->frame_dma_handle); } -static int uhci_init(struct usb_hcd *hcd) +static int uhci_reset(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned io_size = (unsigned) hcd->rsrc_len; @@ -468,7 +459,7 @@ static void uhci_shutdown(struct pci_dev *pdev) { struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev); - uhci_hc_died(hcd_to_uhci(hcd)); + hc_died(hcd_to_uhci(hcd)); } /* @@ -496,10 +487,14 @@ static int uhci_start(struct usb_hcd *hcd) hcd->uses_new_polling = 1; + uhci->fsbr = 0; + uhci->fsbrtimeout = 0; + spin_lock_init(&uhci->lock); - setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout, - (unsigned long) uhci); + + INIT_LIST_HEAD(&uhci->td_remove_list); INIT_LIST_HEAD(&uhci->idle_qh_list); + init_waitqueue_head(&uhci->waitqh); if (DEBUG_CONFIGURED) { @@ -670,12 +665,11 @@ static void uhci_stop(struct usb_hcd *hcd) struct uhci_hcd *uhci = hcd_to_uhci(hcd); spin_lock_irq(&uhci->lock); - if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead) - uhci_hc_died(uhci); + if (!uhci->hc_inaccessible) + hc_died(uhci); uhci_scan_schedule(uhci, NULL); spin_unlock_irq(&uhci->lock); - del_timer_sync(&uhci->fsbr_timer); release_uhci(uhci); } @@ -683,15 +677,12 @@ static void uhci_stop(struct usb_hcd *hcd) static int uhci_rh_suspend(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - int rc = 0; spin_lock_irq(&uhci->lock); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) - rc = -ESHUTDOWN; - else if (!uhci->dead) + if (!uhci->hc_inaccessible) /* Not dead */ suspend_rh(uhci, UHCI_RH_SUSPENDED); spin_unlock_irq(&uhci->lock); - return rc; + return 0; } static int uhci_rh_resume(struct usb_hcd *hcd) @@ -700,10 +691,13 @@ static int uhci_rh_resume(struct usb_hcd *hcd) int rc = 0; spin_lock_irq(&uhci->lock); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n"); - rc = -ESHUTDOWN; - } else if (!uhci->dead) + if (uhci->hc_inaccessible) { + if (uhci->rh_state == UHCI_RH_SUSPENDED) { + dev_warn(uhci_dev(uhci), "HC isn't running!\n"); + rc = -ENODEV; + } + /* Otherwise the HC is dead */ + } else wakeup_rh(uhci); spin_unlock_irq(&uhci->lock); return rc; @@ -717,8 +711,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); spin_lock_irq(&uhci->lock); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) - goto done_okay; /* Already suspended or dead */ + if (uhci->hc_inaccessible) /* Dead or already suspended */ + goto done; if (uhci->rh_state > UHCI_RH_SUSPENDED) { dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); @@ -731,12 +725,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) */ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); mb(); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + uhci->hc_inaccessible = 1; hcd->poll_rh = 0; /* FIXME: Enable non-PME# remote wakeup? */ -done_okay: - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); done: spin_unlock_irq(&uhci->lock); return rc; @@ -749,22 +743,24 @@ static int uhci_resume(struct usb_hcd *hcd) dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); /* Since we aren't in D3 any more, it's safe to set this flag - * even if the controller was dead. + * even if the controller was dead. It might not even be dead + * any more, if the firmware or quirks code has reset it. */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); mb(); + if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ + return 0; spin_lock_irq(&uhci->lock); /* FIXME: Disable non-PME# remote wakeup? */ - /* The firmware or a boot kernel may have changed the controller - * settings during a system wakeup. Check it and reconfigure - * to avoid problems. + uhci->hc_inaccessible = 0; + + /* The BIOS may have changed the controller settings during a + * system wakeup. Check it and reconfigure to avoid problems. */ check_and_reset_hc(uhci); - - /* If the controller was dead before, it's back alive now */ configure_hc(uhci); if (uhci->rh_state == UHCI_RH_RESET) { @@ -814,15 +810,18 @@ static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd, static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - unsigned frame_number; - unsigned delta; + unsigned long flags; + int is_stopped; + int frame_number; /* Minimize latency by avoiding the spinlock */ - frame_number = uhci->frame_number; - barrier(); - delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) & - (UHCI_NUMFRAMES - 1); - return frame_number + delta; + local_irq_save(flags); + is_stopped = uhci->is_stopped; + smp_rmb(); + frame_number = (is_stopped ? uhci->frame_number : + inw(uhci->io_addr + USBFRNUM)); + local_irq_restore(flags); + return frame_number; } static const char hcd_name[] = "uhci_hcd"; @@ -837,7 +836,7 @@ static const struct hc_driver uhci_driver = { .flags = HCD_USB11, /* Basic lifecycle operations */ - .reset = uhci_init, + .reset = uhci_reset, .start = uhci_start, #ifdef CONFIG_PM .suspend = uhci_suspend, diff --git a/trunk/drivers/usb/host/uhci-hcd.h b/trunk/drivers/usb/host/uhci-hcd.h index 108e3de2dc26..d5c8f4d92823 100644 --- a/trunk/drivers/usb/host/uhci-hcd.h +++ b/trunk/drivers/usb/host/uhci-hcd.h @@ -84,13 +84,6 @@ #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames * can be scheduled */ -/* When no queues need Full-Speed Bandwidth Reclamation, - * delay this long before turning FSBR off */ -#define FSBR_OFF_DELAY msecs_to_jiffies(10) - -/* If a queue hasn't advanced after this much time, assume it is stuck */ -#define QH_WAIT_TIMEOUT msecs_to_jiffies(200) - /* * Queue Headers @@ -128,31 +121,21 @@ struct uhci_qh { __le32 element; /* Queue element (TD) pointer */ /* Software fields */ + dma_addr_t dma_handle; + struct list_head node; /* Node in the list of QHs */ struct usb_host_endpoint *hep; /* Endpoint information */ struct usb_device *udev; struct list_head queue; /* Queue of urbps for this QH */ struct uhci_qh *skel; /* Skeleton for this QH */ struct uhci_td *dummy_td; /* Dummy TD to end the queue */ - struct uhci_td *post_td; /* Last TD completed */ - struct usb_iso_packet_descriptor *iso_packet_desc; - /* Next urb->iso_frame_desc entry */ - unsigned long advance_jiffies; /* Time of last queue advance */ unsigned int unlink_frame; /* When the QH was unlinked */ - unsigned int period; /* For Interrupt and Isochronous QHs */ - unsigned int iso_frame; /* Frame # for iso_packet_desc */ - int iso_status; /* Status for Isochronous URBs */ - int state; /* QH_STATE_xxx; see above */ - int type; /* Queue type (control, bulk, etc) */ - - dma_addr_t dma_handle; unsigned int initial_toggle:1; /* Endpoint's current toggle value */ unsigned int needs_fixup:1; /* Must fix the TD toggle values */ - unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ - unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ + unsigned int is_stopped:1; /* Queue was stopped by an error */ } __attribute__((aligned(16))); /* @@ -243,6 +226,7 @@ struct uhci_td { dma_addr_t dma_handle; struct list_head list; + struct list_head remove_list; int frame; /* for iso: what frame? */ struct list_head fl_list; @@ -321,8 +305,38 @@ static inline u32 td_status(struct uhci_td *td) { #define skel_bulk_qh skelqh[12] #define skel_term_qh skelqh[13] -/* Find the skelqh entry corresponding to an interval exponent */ -#define UHCI_SKEL_INDEX(exponent) (9 - exponent) +/* + * Search tree for determining where fits in the skelqh[] + * skeleton. + * + * An interrupt request should be placed into the slowest skelqh[] + * which meets the interval/period/frequency requirement. + * An interrupt request is allowed to be faster than but not slower. + * + * For a given , this function returns the appropriate/matching + * skelqh[] index value. + */ +static inline int __interval_to_skel(int interval) +{ + if (interval < 16) { + if (interval < 4) { + if (interval < 2) + return 9; /* int1 for 0-1 ms */ + return 8; /* int2 for 2-3 ms */ + } + if (interval < 8) + return 7; /* int4 for 4-7 ms */ + return 6; /* int8 for 8-15 ms */ + } + if (interval < 64) { + if (interval < 32) + return 5; /* int16 for 16-31 ms */ + return 4; /* int32 for 32-63 ms */ + } + if (interval < 128) + return 3; /* int64 for 64-127 ms */ + return 2; /* int128 for 128-255 ms (Max.) */ +} /* @@ -382,32 +396,32 @@ struct uhci_hcd { __le32 *frame; void **frame_cpu; /* CPU's frame list */ + int fsbr; /* Full-speed bandwidth reclamation */ + unsigned long fsbrtimeout; /* FSBR delay */ + enum uhci_rh_state rh_state; unsigned long auto_stop_time; /* When to AUTO_STOP */ unsigned int frame_number; /* As of last check */ unsigned int is_stopped; #define UHCI_IS_STOPPED 9999 /* Larger than a frame # */ - unsigned int last_iso_frame; /* Frame of last scan */ - unsigned int cur_iso_frame; /* Frame for current scan */ unsigned int scan_in_progress:1; /* Schedule scan is running */ unsigned int need_rescan:1; /* Redo the schedule scan */ - unsigned int dead:1; /* Controller has died */ + unsigned int hc_inaccessible:1; /* HC is suspended or dead */ unsigned int working_RD:1; /* Suspended root hub doesn't need to be polled */ unsigned int is_initialized:1; /* Data structure is usable */ - unsigned int fsbr_is_on:1; /* FSBR is turned on */ - unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ - unsigned int fsbr_expiring:1; /* FSBR is timing out */ - - struct timer_list fsbr_timer; /* For turning off FBSR */ /* Support for port suspend/resume/reset */ unsigned long port_c_suspend; /* Bit-arrays of ports */ unsigned long resuming_ports; unsigned long ports_timeout; /* Time to stop signalling */ + /* List of TDs that are done, but waiting to be freed (race) */ + struct list_head td_remove_list; + unsigned int td_remove_age; /* Age in frames */ + struct list_head idle_qh_list; /* Where the idle QHs live */ int rh_numports; /* Number of root-hub ports */ @@ -428,9 +442,6 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) -/* Utility macro for comparing frame numbers */ -#define uhci_frame_before_eq(f1, f2) (0 <= (int) ((f2) - (f1))) - /* * Private per-URB data @@ -443,7 +454,9 @@ struct urb_priv { struct uhci_qh *qh; /* QH for this URB */ struct list_head td_list; - unsigned fsbr:1; /* URB wants FSBR */ + unsigned fsbr : 1; /* URB turned on FSBR */ + unsigned short_transfer : 1; /* URB got a short transfer, no + * need to rescan */ }; diff --git a/trunk/drivers/usb/host/uhci-hub.c b/trunk/drivers/usb/host/uhci-hub.c index c545ef92fe29..c8451d9578f1 100644 --- a/trunk/drivers/usb/host/uhci-hub.c +++ b/trunk/drivers/usb/host/uhci-hub.c @@ -171,8 +171,9 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) spin_lock_irqsave(&uhci->lock, flags); uhci_scan_schedule(uhci, NULL); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) + if (uhci->hc_inaccessible) goto done; + check_fsbr(uhci); uhci_check_ports(uhci); status = get_hub_status_data(uhci, buf); @@ -227,7 +228,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wPortChange, wPortStatus; unsigned long flags; - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) + if (uhci->hc_inaccessible) return -ETIMEDOUT; spin_lock_irqsave(&uhci->lock, flags); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index c9d72ac0a1d7..a06d84c19e13 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -13,9 +13,10 @@ * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) - * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu + * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu */ +static void uhci_free_pending_tds(struct uhci_hcd *uhci); /* * Technically, updating td->status here is a race, but it's not really a @@ -37,60 +38,6 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); } - -/* - * Full-Speed Bandwidth Reclamation (FSBR). - * We turn on FSBR whenever a queue that wants it is advancing, - * and leave it on for a short time thereafter. - */ -static void uhci_fsbr_on(struct uhci_hcd *uhci) -{ - uhci->fsbr_is_on = 1; - uhci->skel_term_qh->link = cpu_to_le32( - uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; -} - -static void uhci_fsbr_off(struct uhci_hcd *uhci) -{ - uhci->fsbr_is_on = 0; - uhci->skel_term_qh->link = UHCI_PTR_TERM; -} - -static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) -{ - struct urb_priv *urbp = urb->hcpriv; - - if (!(urb->transfer_flags & URB_NO_FSBR)) - urbp->fsbr = 1; -} - -static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp) -{ - if (urbp->fsbr) { - uhci->fsbr_is_wanted = 1; - if (!uhci->fsbr_is_on) - uhci_fsbr_on(uhci); - else if (uhci->fsbr_expiring) { - uhci->fsbr_expiring = 0; - del_timer(&uhci->fsbr_timer); - } - } -} - -static void uhci_fsbr_timeout(unsigned long _uhci) -{ - struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci; - unsigned long flags; - - spin_lock_irqsave(&uhci->lock, flags); - if (uhci->fsbr_expiring) { - uhci->fsbr_expiring = 0; - uhci_fsbr_off(uhci); - } - spin_unlock_irqrestore(&uhci->lock, flags); -} - - static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) { dma_addr_t dma_handle; @@ -104,6 +51,7 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) td->frame = -1; INIT_LIST_HEAD(&td->list); + INIT_LIST_HEAD(&td->remove_list); INIT_LIST_HEAD(&td->fl_list); return td; @@ -113,6 +61,8 @@ static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) { if (!list_empty(&td->list)) dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); + if (!list_empty(&td->remove_list)) + dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td); if (!list_empty(&td->fl_list)) dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); @@ -127,16 +77,6 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status, td->buffer = cpu_to_le32(buffer); } -static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp) -{ - list_add_tail(&td->list, &urbp->td_list); -} - -static void uhci_remove_td_from_urbp(struct uhci_td *td) -{ - list_del_init(&td->list); -} - /* * We insert Isochronous URBs directly into the frame list at the beginning */ @@ -198,24 +138,6 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, td->frame = -1; } -static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci, - unsigned int framenum) -{ - struct uhci_td *ftd, *ltd; - - framenum &= (UHCI_NUMFRAMES - 1); - - ftd = uhci->frame_cpu[framenum]; - if (ftd) { - ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); - uhci->frame[framenum] = ltd->link; - uhci->frame_cpu[framenum] = NULL; - - while (!list_empty(&ftd->fl_list)) - list_del_init(ftd->fl_list.prev); - } -} - /* * Remove all the TDs for an Isochronous URB from the frame list */ @@ -226,6 +148,7 @@ static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) list_for_each_entry(td, &urbp->td_list, list) uhci_remove_td_from_frame_list(uhci, td); + wmb(); } static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, @@ -238,7 +161,6 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, if (!qh) return NULL; - memset(qh, 0, sizeof(*qh)); qh->dma_handle = dma_handle; qh->element = UHCI_PTR_TERM; @@ -257,11 +179,10 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, qh->hep = hep; qh->udev = udev; hep->hcpriv = qh; - qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; } else { /* Skeleton QH */ qh->state = QH_STATE_ACTIVE; - qh->type = -1; + qh->udev = NULL; } return qh; } @@ -281,64 +202,35 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) } /* - * When a queue is stopped and a dequeued URB is given back, adjust - * the previous TD link (if the URB isn't first on the queue) or - * save its toggle value (if it is first and is currently executing). - * - * Returns 0 if the URB should not yet be given back, 1 otherwise. + * When the currently executing URB is dequeued, save its current toggle value */ -static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb) +static void uhci_save_toggle(struct uhci_qh *qh, struct urb *urb) { - struct urb_priv *urbp = urb->hcpriv; + struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; struct uhci_td *td; - int ret = 1; - - /* Isochronous pipes don't use toggles and their TD link pointers - * get adjusted during uhci_urb_dequeue(). But since their queues - * cannot truly be stopped, we have to watch out for dequeues - * occurring after the nominal unlink frame. */ - if (qh->type == USB_ENDPOINT_XFER_ISOC) { - ret = (uhci->frame_number + uhci->is_stopped != - qh->unlink_frame); - goto done; - } - - /* If the URB isn't first on its queue, adjust the link pointer - * of the last TD in the previous URB. The toggle doesn't need - * to be saved since this URB can't be executing yet. */ - if (qh->queue.next != &urbp->node) { - struct urb_priv *purbp; - struct uhci_td *ptd; - - purbp = list_entry(urbp->node.prev, struct urb_priv, node); - WARN_ON(list_empty(&purbp->td_list)); - ptd = list_entry(purbp->td_list.prev, struct uhci_td, - list); - td = list_entry(urbp->td_list.prev, struct uhci_td, - list); - ptd->link = td->link; - goto done; - } /* If the QH element pointer is UHCI_PTR_TERM then then currently * executing URB has already been unlinked, so this one isn't it. */ - if (qh_element(qh) == UHCI_PTR_TERM) - goto done; + if (qh_element(qh) == UHCI_PTR_TERM || + qh->queue.next != &urbp->node) + return; qh->element = UHCI_PTR_TERM; - /* Control pipes have to worry about toggles */ - if (qh->type == USB_ENDPOINT_XFER_CONTROL) - goto done; + /* Only bulk and interrupt pipes have to worry about toggles */ + if (!(usb_pipetype(urb->pipe) == PIPE_BULK || + usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) + return; - /* Save the next toggle value */ - WARN_ON(list_empty(&urbp->td_list)); - td = list_entry(urbp->td_list.next, struct uhci_td, list); - qh->needs_fixup = 1; - qh->initial_toggle = uhci_toggle(td_token(td)); + /* Find the first active TD; that's the device's toggle state */ + list_for_each_entry(td, &urbp->td_list, list) { + if (td_status(td) & TD_CTRL_ACTIVE) { + qh->needs_fixup = 1; + qh->initial_toggle = uhci_toggle(td_token(td)); + return; + } + } -done: - return ret; + WARN_ON(1); } /* @@ -413,10 +305,6 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) qh->element = cpu_to_le32(td->dma_handle); } - /* Treat the queue as if it has just advanced */ - qh->wait_expired = 0; - qh->advance_jiffies = jiffies; - if (qh->state == QH_STATE_ACTIVE) return; qh->state = QH_STATE_ACTIVE; @@ -482,12 +370,6 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) list_move(&qh->node, &uhci->idle_qh_list); qh->state = QH_STATE_IDLE; - /* Now that the QH is idle, its post_td isn't being used */ - if (qh->post_td) { - uhci_free_td(uhci, qh->post_td); - qh->post_td = NULL; - } - /* If anyone is waiting for a QH to become idle, wake them up */ if (uhci->num_waiting) wake_up_all(&uhci->waitqh); @@ -513,6 +395,21 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, return urbp; } +static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + + list_add_tail(&td->list, &urbp->td_list); +} + +static void uhci_remove_td_from_urb(struct uhci_td *td) +{ + if (list_empty(&td->list)) + return; + + list_del_init(&td->list); +} + static void uhci_free_urb_priv(struct uhci_hcd *uhci, struct urb_priv *urbp) { @@ -522,15 +419,48 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", urbp->urb); + uhci_get_current_frame_number(uhci); + if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) { + uhci_free_pending_tds(uhci); + uhci->td_remove_age = uhci->frame_number; + } + + /* Check to see if the remove list is empty. Set the IOC bit */ + /* to force an interrupt so we can remove the TDs. */ + if (list_empty(&uhci->td_remove_list)) + uhci_set_next_interrupt(uhci); + list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { - uhci_remove_td_from_urbp(td); - uhci_free_td(uhci, td); + uhci_remove_td_from_urb(td); + list_add(&td->remove_list, &uhci->td_remove_list); } urbp->urb->hcpriv = NULL; kmem_cache_free(uhci_up_cachep, urbp); } +static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + + if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) { + urbp->fsbr = 1; + if (!uhci->fsbr++ && !uhci->fsbrtimeout) + uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; + } +} + +static void uhci_dec_fsbr(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + + if ((!(urb->transfer_flags & URB_NO_FSBR)) && urbp->fsbr) { + urbp->fsbr = 0; + if (!--uhci->fsbr) + uhci->fsbrtimeout = jiffies + FSBR_DELAY; + } +} + /* * Map status to standard result codes * @@ -557,6 +487,7 @@ static int uhci_map_status(int status, int dir_out) return -ENOSR; if (status & TD_CTRL_STALLED) /* Stalled */ return -EPIPE; + WARN_ON(status & TD_CTRL_ACTIVE); /* Active */ return 0; } @@ -572,7 +503,6 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, int len = urb->transfer_buffer_length; dma_addr_t data = urb->transfer_dma; __le32 *plink; - struct urb_priv *urbp = urb->hcpriv; /* The "pipe" thing contains the destination in bits 8--18 */ destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; @@ -586,7 +516,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * Build the TD for the control request setup packet */ td = qh->dummy_td; - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(8), urb->setup_dma); plink = &td->link; @@ -618,7 +548,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, /* Alternate Data0/1 (start with Data1) */ destination ^= TD_TOKEN_TOGGLE; - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(pktsze), data); plink = &td->link; @@ -649,7 +579,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, status &= ~TD_CTRL_SPD; - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status | TD_CTRL_IOC, destination | uhci_explen(0), 0); plink = &td->link; @@ -676,18 +606,144 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, qh->skel = uhci->skel_ls_control_qh; else { qh->skel = uhci->skel_fs_control_qh; - uhci_add_fsbr(uhci, urb); + uhci_inc_fsbr(uhci, urb); } - - urb->actual_length = -8; /* Account for the SETUP packet */ return 0; nomem: /* Remove the dummy TD from the td_list so it doesn't get freed */ - uhci_remove_td_from_urbp(qh->dummy_td); + uhci_remove_td_from_urb(qh->dummy_td); return -ENOMEM; } +/* + * If control-IN transfer was short, the status packet wasn't sent. + * This routine changes the element pointer in the QH to point at the + * status TD. It's safe to do this even while the QH is live, because + * the hardware only updates the element pointer following a successful + * transfer. The inactive TD for the short packet won't cause an update, + * so the pointer won't get overwritten. The next time the controller + * sees this QH, it will send the status packet. + */ +static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb) +{ + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + struct uhci_td *td; + + urbp->short_transfer = 1; + + td = list_entry(urbp->td_list.prev, struct uhci_td, list); + urbp->qh->element = cpu_to_le32(td->dma_handle); + + return -EINPROGRESS; +} + + +static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) +{ + struct list_head *tmp, *head; + struct urb_priv *urbp = urb->hcpriv; + struct uhci_td *td; + unsigned int status; + int ret = 0; + + head = &urbp->td_list; + if (urbp->short_transfer) { + tmp = head->prev; + goto status_stage; + } + + urb->actual_length = 0; + + tmp = head->next; + td = list_entry(tmp, struct uhci_td, list); + + /* The first TD is the SETUP stage, check the status, but skip */ + /* the count */ + status = uhci_status_bits(td_status(td)); + if (status & TD_CTRL_ACTIVE) + return -EINPROGRESS; + + if (status) + goto td_error; + + /* The rest of the TDs (but the last) are data */ + tmp = tmp->next; + while (tmp != head && tmp->next != head) { + unsigned int ctrlstat; + + td = list_entry(tmp, struct uhci_td, list); + tmp = tmp->next; + + ctrlstat = td_status(td); + status = uhci_status_bits(ctrlstat); + if (status & TD_CTRL_ACTIVE) + return -EINPROGRESS; + + urb->actual_length += uhci_actual_length(ctrlstat); + + if (status) + goto td_error; + + /* Check to see if we received a short packet */ + if (uhci_actual_length(ctrlstat) < + uhci_expected_length(td_token(td))) { + if (urb->transfer_flags & URB_SHORT_NOT_OK) { + ret = -EREMOTEIO; + goto err; + } + + return usb_control_retrigger_status(uhci, urb); + } + } + +status_stage: + td = list_entry(tmp, struct uhci_td, list); + + /* Control status stage */ + status = td_status(td); + +#ifdef I_HAVE_BUGGY_APC_BACKUPS + /* APC BackUPS Pro kludge */ + /* It tries to send all of the descriptor instead of the amount */ + /* we requested */ + if (status & TD_CTRL_IOC && /* IOC is masked out by uhci_status_bits */ + status & TD_CTRL_ACTIVE && + status & TD_CTRL_NAK) + return 0; +#endif + + status = uhci_status_bits(status); + if (status & TD_CTRL_ACTIVE) + return -EINPROGRESS; + + if (status) + goto td_error; + + return 0; + +td_error: + ret = uhci_map_status(status, uhci_packetout(td_token(td))); + +err: + if ((debug == 1 && ret != -EPIPE) || debug > 1) { + /* Some debugging code */ + dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", + __FUNCTION__, status); + + if (errbuf) { + /* Print the chain for debugging purposes */ + uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); + lprintk(errbuf); + } + } + + /* Note that the queue has stopped */ + urbp->qh->element = UHCI_PTR_TERM; + urbp->qh->is_stopped = 1; + return ret; +} + /* * Common submit for bulk and interrupt */ @@ -700,7 +756,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, int len = urb->transfer_buffer_length; dma_addr_t data = urb->transfer_dma; __le32 *plink; - struct urb_priv *urbp = urb->hcpriv; unsigned int toggle; if (len < 0) @@ -738,7 +793,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, goto nomem; *plink = cpu_to_le32(td->dma_handle); } - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(pktsze) | (toggle << TD_TOKEN_TOGGLE_SHIFT), @@ -766,7 +821,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, goto nomem; *plink = cpu_to_le32(td->dma_handle); - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(0) | (toggle << TD_TOKEN_TOGGLE_SHIFT), @@ -796,7 +851,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, wmb(); qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); qh->dummy_td = td; - qh->period = urb->interval; usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle); @@ -804,178 +858,117 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, nomem: /* Remove the dummy TD from the td_list so it doesn't get freed */ - uhci_remove_td_from_urbp(qh->dummy_td); + uhci_remove_td_from_urb(qh->dummy_td); return -ENOMEM; } -static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) -{ - int ret; - - /* Can't have low-speed bulk transfers */ - if (urb->dev->speed == USB_SPEED_LOW) - return -EINVAL; - - qh->skel = uhci->skel_bulk_qh; - ret = uhci_submit_common(uhci, urb, qh); - if (ret == 0) - uhci_add_fsbr(uhci, urb); - return ret; -} - -static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, - struct uhci_qh *qh) -{ - int exponent; - - /* USB 1.1 interrupt transfers only involve one packet per interval. - * Drivers can submit URBs of any length, but longer ones will need - * multiple intervals to complete. - */ - - /* Figure out which power-of-two queue to use */ - for (exponent = 7; exponent >= 0; --exponent) { - if ((1 << exponent) <= urb->interval) - break; - } - if (exponent < 0) - return -EINVAL; - urb->interval = 1 << exponent; - - if (qh->period == 0) - qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; - else if (qh->period != urb->interval) - return -EINVAL; /* Can't change the period */ - - return uhci_submit_common(uhci, urb, qh); -} - /* - * Fix up the data structures following a short transfer - */ -static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, - struct uhci_qh *qh, struct urb_priv *urbp) -{ - struct uhci_td *td; - struct list_head *tmp; - int ret; - - td = list_entry(urbp->td_list.prev, struct uhci_td, list); - if (qh->type == USB_ENDPOINT_XFER_CONTROL) { - - /* When a control transfer is short, we have to restart - * the queue at the status stage transaction, which is - * the last TD. */ - WARN_ON(list_empty(&urbp->td_list)); - qh->element = cpu_to_le32(td->dma_handle); - tmp = td->list.prev; - ret = -EINPROGRESS; - - } else { - - /* When a bulk/interrupt transfer is short, we have to - * fix up the toggles of the following URBs on the queue - * before restarting the queue at the next URB. */ - qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1; - uhci_fixup_toggles(qh, 1); - - if (list_empty(&urbp->td_list)) - td = qh->post_td; - qh->element = td->link; - tmp = urbp->td_list.prev; - ret = 0; - } - - /* Remove all the TDs we skipped over, from tmp back to the start */ - while (tmp != &urbp->td_list) { - td = list_entry(tmp, struct uhci_td, list); - tmp = tmp->prev; - - uhci_remove_td_from_urbp(td); - uhci_free_td(uhci, td); - } - return ret; -} - -/* - * Common result for control, bulk, and interrupt + * Common result for bulk and interrupt */ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) { struct urb_priv *urbp = urb->hcpriv; - struct uhci_qh *qh = urbp->qh; - struct uhci_td *td, *tmp; - unsigned status; + struct uhci_td *td; + unsigned int status = 0; int ret = 0; - list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { - unsigned int ctrlstat; - int len; + urb->actual_length = 0; + + list_for_each_entry(td, &urbp->td_list, list) { + unsigned int ctrlstat = td_status(td); - ctrlstat = td_status(td); status = uhci_status_bits(ctrlstat); if (status & TD_CTRL_ACTIVE) return -EINPROGRESS; - len = uhci_actual_length(ctrlstat); - urb->actual_length += len; + urb->actual_length += uhci_actual_length(ctrlstat); - if (status) { - ret = uhci_map_status(status, - uhci_packetout(td_token(td))); - if ((debug == 1 && ret != -EPIPE) || debug > 1) { - /* Some debugging code */ - dev_dbg(&urb->dev->dev, - "%s: failed with status %x\n", - __FUNCTION__, status); - - if (debug > 1 && errbuf) { - /* Print the chain for debugging */ - uhci_show_qh(urbp->qh, errbuf, - ERRBUF_LEN, 0); - lprintk(errbuf); - } - } + if (status) + goto td_error; - } else if (len < uhci_expected_length(td_token(td))) { - - /* We received a short packet */ - if (urb->transfer_flags & URB_SHORT_NOT_OK) + if (uhci_actual_length(ctrlstat) < + uhci_expected_length(td_token(td))) { + if (urb->transfer_flags & URB_SHORT_NOT_OK) { ret = -EREMOTEIO; - else if (ctrlstat & TD_CTRL_SPD) - ret = 1; + goto err; + } + + /* + * This URB stopped short of its end. We have to + * fix up the toggles of the following URBs on the + * queue and restart the queue. + * + * Do this only the first time we encounter the + * short URB. + */ + if (!urbp->short_transfer) { + urbp->short_transfer = 1; + urbp->qh->initial_toggle = + uhci_toggle(td_token(td)) ^ 1; + uhci_fixup_toggles(urbp->qh, 1); + + td = list_entry(urbp->td_list.prev, + struct uhci_td, list); + urbp->qh->element = td->link; + } + break; } + } - uhci_remove_td_from_urbp(td); - if (qh->post_td) - uhci_free_td(uhci, qh->post_td); - qh->post_td = td; + return 0; + +td_error: + ret = uhci_map_status(status, uhci_packetout(td_token(td))); + + if ((debug == 1 && ret != -EPIPE) || debug > 1) { + /* Some debugging code */ + dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n", + __FUNCTION__, status); - if (ret != 0) - goto err; + if (debug > 1 && errbuf) { + /* Print the chain for debugging purposes */ + uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0); + lprintk(errbuf); + } } +err: + + /* Note that the queue has stopped and save the next toggle value */ + urbp->qh->element = UHCI_PTR_TERM; + urbp->qh->is_stopped = 1; + urbp->qh->needs_fixup = 1; + urbp->qh->initial_toggle = uhci_toggle(td_token(td)) ^ + (ret == -EREMOTEIO); return ret; +} -err: - if (ret < 0) { - /* In case a control transfer gets an error - * during the setup stage */ - urb->actual_length = max(urb->actual_length, 0); - - /* Note that the queue has stopped and save - * the next toggle value */ - qh->element = UHCI_PTR_TERM; - qh->is_stopped = 1; - qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); - qh->initial_toggle = uhci_toggle(td_token(td)) ^ - (ret == -EREMOTEIO); - - } else /* Short packet received */ - ret = uhci_fixup_short_transfer(uhci, qh, urbp); +static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, + struct uhci_qh *qh) +{ + int ret; + + /* Can't have low-speed bulk transfers */ + if (urb->dev->speed == USB_SPEED_LOW) + return -EINVAL; + + qh->skel = uhci->skel_bulk_qh; + ret = uhci_submit_common(uhci, urb, qh); + if (ret == 0) + uhci_inc_fsbr(uhci, urb); return ret; } +static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, + struct uhci_qh *qh) +{ + /* USB 1.1 interrupt transfers only involve one packet per interval. + * Drivers can submit URBs of any length, but longer ones will need + * multiple intervals to complete. + */ + qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)]; + return uhci_submit_common(uhci, urb, qh); +} + /* * Isochronous transfers */ @@ -987,57 +980,38 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, unsigned long destination, status; struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; - /* Values must not be too big (could overflow below) */ - if (urb->interval >= UHCI_NUMFRAMES || - urb->number_of_packets >= UHCI_NUMFRAMES) + if (urb->number_of_packets > 900) /* 900? Why? */ return -EFBIG; - /* Check the period and figure out the starting frame number */ - if (qh->period == 0) { - if (urb->transfer_flags & URB_ISO_ASAP) { - uhci_get_current_frame_number(uhci); - urb->start_frame = uhci->frame_number + 10; - } else { - i = urb->start_frame - uhci->last_iso_frame; - if (i <= 0 || i >= UHCI_NUMFRAMES) - return -EINVAL; - } - } else if (qh->period != urb->interval) { - return -EINVAL; /* Can't change the period */ + status = TD_CTRL_ACTIVE | TD_CTRL_IOS; + destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); - } else { /* Pick up where the last URB leaves off */ + /* Figure out the starting frame number */ + if (urb->transfer_flags & URB_ISO_ASAP) { if (list_empty(&qh->queue)) { - frame = qh->iso_frame; - } else { - struct urb *lurb; + uhci_get_current_frame_number(uhci); + urb->start_frame = (uhci->frame_number + 10); - lurb = list_entry(qh->queue.prev, + } else { /* Go right after the last one */ + struct urb *last_urb; + + last_urb = list_entry(qh->queue.prev, struct urb_priv, node)->urb; - frame = lurb->start_frame + - lurb->number_of_packets * - lurb->interval; + urb->start_frame = (last_urb->start_frame + + last_urb->number_of_packets * + last_urb->interval); } - if (urb->transfer_flags & URB_ISO_ASAP) - urb->start_frame = frame; - else if (urb->start_frame != frame) - return -EINVAL; + } else { + /* FIXME: Sanity check */ } - - /* Make sure we won't have to go too far into the future */ - if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES, - urb->start_frame + urb->number_of_packets * - urb->interval)) - return -EFBIG; - - status = TD_CTRL_ACTIVE | TD_CTRL_IOS; - destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); + urb->start_frame &= (UHCI_NUMFRAMES - 1); for (i = 0; i < urb->number_of_packets; i++) { td = uhci_alloc_td(uhci); if (!td) return -ENOMEM; - uhci_add_td_to_urbp(td, urbp); + uhci_add_td_to_urb(urb, td); uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length), urb->transfer_dma + @@ -1048,19 +1022,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); qh->skel = uhci->skel_iso_qh; - qh->period = urb->interval; /* Add the TDs to the frame list */ frame = urb->start_frame; list_for_each_entry(td, &urbp->td_list, list) { uhci_insert_td_in_frame_list(uhci, td, frame); - frame += qh->period; - } - - if (list_empty(&qh->queue)) { - qh->iso_packet_desc = &urb->iso_frame_desc[0]; - qh->iso_frame = urb->start_frame; - qh->iso_status = 0; + frame += urb->interval; } return 0; @@ -1068,44 +1035,37 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) { - struct uhci_td *td, *tmp; - struct urb_priv *urbp = urb->hcpriv; - struct uhci_qh *qh = urbp->qh; + struct uhci_td *td; + struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; + int status; + int i, ret = 0; - list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { - unsigned int ctrlstat; - int status; + urb->actual_length = urb->error_count = 0; + + i = 0; + list_for_each_entry(td, &urbp->td_list, list) { int actlength; + unsigned int ctrlstat = td_status(td); - if (uhci_frame_before_eq(uhci->cur_iso_frame, qh->iso_frame)) + if (ctrlstat & TD_CTRL_ACTIVE) return -EINPROGRESS; - uhci_remove_tds_from_frame(uhci, qh->iso_frame); - - ctrlstat = td_status(td); - if (ctrlstat & TD_CTRL_ACTIVE) { - status = -EXDEV; /* TD was added too late? */ - } else { - status = uhci_map_status(uhci_status_bits(ctrlstat), - usb_pipeout(urb->pipe)); - actlength = uhci_actual_length(ctrlstat); - - urb->actual_length += actlength; - qh->iso_packet_desc->actual_length = actlength; - qh->iso_packet_desc->status = status; - } + actlength = uhci_actual_length(ctrlstat); + urb->iso_frame_desc[i].actual_length = actlength; + urb->actual_length += actlength; + status = uhci_map_status(uhci_status_bits(ctrlstat), + usb_pipeout(urb->pipe)); + urb->iso_frame_desc[i].status = status; if (status) { urb->error_count++; - qh->iso_status = status; + ret = status; } - uhci_remove_td_from_urbp(td); - uhci_free_td(uhci, td); - qh->iso_frame += qh->period; - ++qh->iso_packet_desc; + i++; } - return qh->iso_status; + + return ret; } static int uhci_urb_enqueue(struct usb_hcd *hcd, @@ -1139,14 +1099,14 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, } urbp->qh = qh; - switch (qh->type) { - case USB_ENDPOINT_XFER_CONTROL: + switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: ret = uhci_submit_control(uhci, urb, qh); break; - case USB_ENDPOINT_XFER_BULK: + case PIPE_BULK: ret = uhci_submit_bulk(uhci, urb, qh); break; - case USB_ENDPOINT_XFER_INT: + case PIPE_INTERRUPT: if (list_empty(&qh->queue)) { bustime = usb_check_bandwidth(urb->dev, urb); if (bustime < 0) @@ -1165,8 +1125,7 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, ret = uhci_submit_interrupt(uhci, urb, qh); } break; - case USB_ENDPOINT_XFER_ISOC: - urb->error_count = 0; + case PIPE_ISOCHRONOUS: bustime = usb_check_bandwidth(urb->dev, urb); if (bustime < 0) { ret = bustime; @@ -1187,12 +1146,9 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, /* If the new URB is the first and only one on this QH then either * the QH is new and idle or else it's unlinked and waiting to - * become idle, so we can activate it right away. But only if the - * queue isn't stopped. */ - if (qh->queue.next == &urbp->node && !qh->is_stopped) { + * become idle, so we can activate it right away. */ + if (qh->queue.next == &urbp->node) uhci_activate_qh(uhci, qh); - uhci_urbp_wants_fsbr(uhci, urbp); - } goto done; err_submit_failed: @@ -1212,26 +1168,16 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long flags; struct urb_priv *urbp; - struct uhci_qh *qh; spin_lock_irqsave(&uhci->lock, flags); urbp = urb->hcpriv; if (!urbp) /* URB was never linked! */ goto done; - qh = urbp->qh; /* Remove Isochronous TDs from the frame list ASAP */ - if (qh->type == USB_ENDPOINT_XFER_ISOC) { + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) uhci_unlink_isochronous_tds(uhci, urb); - mb(); - - /* If the URB has already started, update the QH unlink time */ - uhci_get_current_frame_number(uhci); - if (uhci_frame_before_eq(urb->start_frame, uhci->frame_number)) - qh->unlink_frame = uhci->frame_number; - } - - uhci_unlink_qh(uhci, qh); + uhci_unlink_qh(uhci, urbp->qh); done: spin_unlock_irqrestore(&uhci->lock, flags); @@ -1248,17 +1194,22 @@ __acquires(uhci->lock) { struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; - /* When giving back the first URB in an Isochronous queue, - * reinitialize the QH's iso-related members for the next URB. */ - if (qh->type == USB_ENDPOINT_XFER_ISOC && - urbp->node.prev == &qh->queue && - urbp->node.next != &qh->queue) { - struct urb *nurb = list_entry(urbp->node.next, - struct urb_priv, node)->urb; - - qh->iso_packet_desc = &nurb->iso_frame_desc[0]; - qh->iso_frame = nurb->start_frame; - qh->iso_status = 0; + /* Isochronous TDs get unlinked directly from the frame list */ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + uhci_unlink_isochronous_tds(uhci, urb); + + /* If the URB isn't first on its queue, adjust the link pointer + * of the last TD in the previous URB. */ + else if (qh->queue.next != &urbp->node) { + struct urb_priv *purbp; + struct uhci_td *ptd, *ltd; + + purbp = list_entry(urbp->node.prev, struct urb_priv, node); + ptd = list_entry(purbp->td_list.prev, struct uhci_td, + list); + ltd = list_entry(urbp->td_list.prev, struct uhci_td, + list); + ptd->link = ltd->link; } /* Take the URB off the QH's queue. If the queue is now empty, @@ -1270,15 +1221,16 @@ __acquires(uhci->lock) qh->needs_fixup = 0; } + uhci_dec_fsbr(uhci, urb); /* Safe since it checks */ uhci_free_urb_priv(uhci, urbp); - switch (qh->type) { - case USB_ENDPOINT_XFER_ISOC: + switch (usb_pipetype(urb->pipe)) { + case PIPE_ISOCHRONOUS: /* Release bandwidth for Interrupt or Isoc. transfers */ if (urb->bandwidth) usb_release_bandwidth(urb->dev, urb, 1); break; - case USB_ENDPOINT_XFER_INT: + case PIPE_INTERRUPT: /* Release bandwidth for Interrupt or Isoc. transfers */ /* Make sure we don't release if we have a queued URB */ if (list_empty(&qh->queue) && urb->bandwidth) @@ -1300,7 +1252,6 @@ __acquires(uhci->lock) uhci_unlink_qh(uhci, qh); /* Bandwidth stuff not yet implemented */ - qh->period = 0; } } @@ -1322,10 +1273,17 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, urbp = list_entry(qh->queue.next, struct urb_priv, node); urb = urbp->urb; - if (qh->type == USB_ENDPOINT_XFER_ISOC) + switch (usb_pipetype(urb->pipe)) { + case PIPE_CONTROL: + status = uhci_result_control(uhci, urb); + break; + case PIPE_ISOCHRONOUS: status = uhci_result_isochronous(uhci, urb); - else + break; + default: /* PIPE_BULK or PIPE_INTERRUPT */ status = uhci_result_common(uhci, urb); + break; + } if (status == -EINPROGRESS) break; @@ -1333,43 +1291,31 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, if (urb->status == -EINPROGRESS) /* Not dequeued */ urb->status = status; else - status = ECONNRESET; /* Not -ECONNRESET */ + status = -ECONNRESET; spin_unlock(&urb->lock); /* Dequeued but completed URBs can't be given back unless * the QH is stopped or has finished unlinking. */ - if (status == ECONNRESET) { - if (QH_FINISHED_UNLINKING(qh)) - qh->is_stopped = 1; - else if (!qh->is_stopped) - return; - } + if (status == -ECONNRESET && + !(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) + return; uhci_giveback_urb(uhci, qh, urb, regs); - if (status < 0) + if (qh->is_stopped) break; } /* If the QH is neither stopped nor finished unlinking (normal case), * our work here is done. */ - if (QH_FINISHED_UNLINKING(qh)) - qh->is_stopped = 1; - else if (!qh->is_stopped) + restart: + if (!(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) return; /* Otherwise give back each of the dequeued URBs */ -restart: list_for_each_entry(urbp, &qh->queue, node) { urb = urbp->urb; if (urb->status != -EINPROGRESS) { - - /* Fix up the TD links and save the toggles for - * non-Isochronous queues. For Isochronous queues, - * test for too-recent dequeues. */ - if (!uhci_cleanup_queue(uhci, qh, urb)) { - qh->is_stopped = 0; - return; - } + uhci_save_toggle(qh, urb); uhci_giveback_urb(uhci, qh, urb, regs); goto restart; } @@ -1381,18 +1327,6 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, if (!list_empty(&qh->queue)) { if (qh->needs_fixup) uhci_fixup_toggles(qh, 0); - - /* If the first URB on the queue wants FSBR but its time - * limit has expired, set the next TD to interrupt on - * completion before reactivating the QH. */ - urbp = list_entry(qh->queue.next, struct urb_priv, node); - if (urbp->fsbr && qh->wait_expired) { - struct uhci_td *td = list_entry(urbp->td_list.next, - struct uhci_td, list); - - td->status |= __cpu_to_le32(TD_CTRL_IOC); - } - uhci_activate_qh(uhci, qh); } @@ -1402,84 +1336,15 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, uhci_make_qh_idle(uhci, qh); } -/* - * Check for queues that have made some forward progress. - * Returns 0 if the queue is not Isochronous, is ACTIVE, and - * has not advanced since last examined; 1 otherwise. - * - * Early Intel controllers have a bug which causes qh->element sometimes - * not to advance when a TD completes successfully. The queue remains - * stuck on the inactive completed TD. We detect such cases and advance - * the element pointer by hand. - */ -static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) +static void uhci_free_pending_tds(struct uhci_hcd *uhci) { - struct urb_priv *urbp = NULL; - struct uhci_td *td; - int ret = 1; - unsigned status; - - if (qh->type == USB_ENDPOINT_XFER_ISOC) - goto done; - - /* Treat an UNLINKING queue as though it hasn't advanced. - * This is okay because reactivation will treat it as though - * it has advanced, and if it is going to become IDLE then - * this doesn't matter anyway. Furthermore it's possible - * for an UNLINKING queue not to have any URBs at all, or - * for its first URB not to have any TDs (if it was dequeued - * just as it completed). So it's not easy in any case to - * test whether such queues have advanced. */ - if (qh->state != QH_STATE_ACTIVE) { - urbp = NULL; - status = 0; - - } else { - urbp = list_entry(qh->queue.next, struct urb_priv, node); - td = list_entry(urbp->td_list.next, struct uhci_td, list); - status = td_status(td); - if (!(status & TD_CTRL_ACTIVE)) { - - /* We're okay, the queue has advanced */ - qh->wait_expired = 0; - qh->advance_jiffies = jiffies; - goto done; - } - ret = 0; - } - - /* The queue hasn't advanced; check for timeout */ - if (qh->wait_expired) - goto done; - - if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { - - /* Detect the Intel bug and work around it */ - if (qh->post_td && qh_element(qh) == - cpu_to_le32(qh->post_td->dma_handle)) { - qh->element = qh->post_td->link; - qh->advance_jiffies = jiffies; - ret = 1; - goto done; - } - - qh->wait_expired = 1; + struct uhci_td *td, *tmp; - /* If the current URB wants FSBR, unlink it temporarily - * so that we can safely set the next TD to interrupt on - * completion. That way we'll know as soon as the queue - * starts moving again. */ - if (urbp && urbp->fsbr && !(status & TD_CTRL_IOC)) - uhci_unlink_qh(uhci, qh); + list_for_each_entry_safe(td, tmp, &uhci->td_remove_list, remove_list) { + list_del_init(&td->remove_list); - } else { - /* Unmoving but not-yet-expired queues keep FSBR alive */ - if (urbp) - uhci_urbp_wants_fsbr(uhci, urbp); + uhci_free_td(uhci, td); } - -done: - return ret; } /* @@ -1496,13 +1361,14 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) return; } uhci->scan_in_progress = 1; -rescan: + rescan: uhci->need_rescan = 0; - uhci->fsbr_is_wanted = 0; uhci_clear_next_interrupt(uhci); uhci_get_current_frame_number(uhci); - uhci->cur_iso_frame = uhci->frame_number; + + if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) + uhci_free_pending_tds(uhci); /* Go through all the QH queues and process the URBs in each one */ for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { @@ -1511,30 +1377,33 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) while ((qh = uhci->next_qh) != uhci->skelqh[i]) { uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, node); - - if (uhci_advance_check(uhci, qh)) { - uhci_scan_qh(uhci, qh, regs); - if (qh->state == QH_STATE_ACTIVE) { - uhci_urbp_wants_fsbr(uhci, - list_entry(qh->queue.next, struct urb_priv, node)); - } - } + uhci_scan_qh(uhci, qh, regs); } } - uhci->last_iso_frame = uhci->cur_iso_frame; if (uhci->need_rescan) goto rescan; uhci->scan_in_progress = 0; - if (uhci->fsbr_is_on && !uhci->fsbr_is_wanted && - !uhci->fsbr_expiring) { - uhci->fsbr_expiring = 1; - mod_timer(&uhci->fsbr_timer, jiffies + FSBR_OFF_DELAY); - } + /* If the controller is stopped, we can finish these off right now */ + if (uhci->is_stopped) + uhci_free_pending_tds(uhci); - if (list_empty(&uhci->skel_unlink_qh->node)) + if (list_empty(&uhci->td_remove_list) && + list_empty(&uhci->skel_unlink_qh->node)) uhci_clear_next_interrupt(uhci); else uhci_set_next_interrupt(uhci); } + +static void check_fsbr(struct uhci_hcd *uhci) +{ + /* For now, don't scan URBs for FSBR timeouts. + * Add it back in later... */ + + /* Really disable FSBR */ + if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { + uhci->fsbrtimeout = 0; + uhci->skel_term_qh->link = UHCI_PTR_TERM; + } +} diff --git a/trunk/drivers/usb/image/microtek.c b/trunk/drivers/usb/image/microtek.c index b2bafc37c414..2a0e18a48748 100644 --- a/trunk/drivers/usb/image/microtek.c +++ b/trunk/drivers/usb/image/microtek.c @@ -513,7 +513,7 @@ static void mts_do_sg (struct urb* transfer, struct pt_regs *regs) mts_transfer_cleanup(transfer); } - sg = context->srb->request_buffer; + sg = context->srb->buffer; context->fragment++; mts_int_submit_urb(transfer, context->data_pipe, @@ -549,19 +549,19 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) desc->context.fragment = 0; if (!srb->use_sg) { - if ( !srb->request_bufflen ){ + if ( !srb->bufflen ){ desc->context.data = NULL; desc->context.data_length = 0; return; } else { - desc->context.data = srb->request_buffer; - desc->context.data_length = srb->request_bufflen; + desc->context.data = srb->buffer; + desc->context.data_length = srb->bufflen; MTS_DEBUG("length = %d or %d\n", srb->request_bufflen, srb->bufflen); } } else { MTS_DEBUG("Using scatter/gather\n"); - sg = srb->request_buffer; + sg = srb->buffer; desc->context.data = page_address(sg[0].page) + sg[0].offset; desc->context.data_length = sg[0].length; } diff --git a/trunk/drivers/usb/input/acecad.c b/trunk/drivers/usb/input/acecad.c index 18c10e150ef3..df29b8078b54 100644 --- a/trunk/drivers/usb/input/acecad.c +++ b/trunk/drivers/usb/input/acecad.c @@ -27,9 +27,11 @@ #include #include +#include #include #include -#include +#include +#include /* * Version Information diff --git a/trunk/drivers/usb/input/aiptek.c b/trunk/drivers/usb/input/aiptek.c index b138dae2b055..a6693b0d1c4c 100644 --- a/trunk/drivers/usb/input/aiptek.c +++ b/trunk/drivers/usb/input/aiptek.c @@ -73,9 +73,11 @@ #include #include #include +#include #include #include -#include +#include +#include #include #include #include diff --git a/trunk/drivers/usb/input/appletouch.c b/trunk/drivers/usb/input/appletouch.c index 36855062eacc..c222ed13deab 100644 --- a/trunk/drivers/usb/input/appletouch.c +++ b/trunk/drivers/usb/input/appletouch.c @@ -1,5 +1,5 @@ /* - * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver + * Apple USB Touchpad (for post-February 2005 PowerBooks) driver * * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) @@ -7,7 +7,6 @@ * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) - * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) * * Thanks to Alex Harper for his inputs. * @@ -33,7 +32,9 @@ #include #include #include -#include +#include +#include +#include /* Apple has powerbooks which have the keyboard with different Product IDs */ #define APPLE_VENDOR_ID 0x05AC @@ -43,11 +44,6 @@ #define GEYSER_ISO_PRODUCT_ID 0x0215 #define GEYSER_JIS_PRODUCT_ID 0x0216 -/* MacBook devices */ -#define GEYSER3_ANSI_PRODUCT_ID 0x0217 -#define GEYSER3_ISO_PRODUCT_ID 0x0218 -#define GEYSER3_JIS_PRODUCT_ID 0x0219 - #define ATP_DEVICE(prod) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ USB_DEVICE_ID_MATCH_INT_CLASS | \ @@ -69,10 +65,6 @@ static struct usb_device_id atp_table [] = { { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) }, - /* Terminating entry */ { } }; @@ -109,13 +101,6 @@ MODULE_DEVICE_TABLE (usb, atp_table); */ #define ATP_THRESHOLD 5 -/* MacBook Pro (Geyser 3) initialization constants */ -#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1 -#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9 -#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300 -#define ATP_GEYSER3_MODE_REQUEST_INDEX 0 -#define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04 - /* Structure to hold all of our device specific stuff */ struct atp { char phys[64]; @@ -162,22 +147,13 @@ MODULE_PARM_DESC(debug, "Activate debugging output"); /* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ static inline int atp_is_geyser_2(struct atp *dev) { - u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); + int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct); return (productId == GEYSER_ANSI_PRODUCT_ID) || (productId == GEYSER_ISO_PRODUCT_ID) || (productId == GEYSER_JIS_PRODUCT_ID); } -static inline int atp_is_geyser_3(struct atp *dev) -{ - u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); - - return (productId == GEYSER3_ANSI_PRODUCT_ID) || - (productId == GEYSER3_ISO_PRODUCT_ID) || - (productId == GEYSER3_JIS_PRODUCT_ID); -} - static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, int *z, int *fingers) { @@ -243,33 +219,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) /* drop incomplete datasets */ if (dev->urb->actual_length != dev->datalen) { - dprintk("appletouch: incomplete data package" - " (first byte: %d, length: %d).\n", - dev->data[0], dev->urb->actual_length); + dprintk("appletouch: incomplete data package.\n"); goto exit; } /* reorder the sensors values */ - if (atp_is_geyser_3(dev)) { - memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); - - /* - * The values are laid out like this: - * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... - * '-' is an unused value. - */ - - /* read X values */ - for (i = 0, j = 19; i < 20; i += 2, j += 3) { - dev->xy_cur[i] = dev->data[j + 1]; - dev->xy_cur[i + 1] = dev->data[j + 2]; - } - /* read Y values */ - for (i = 0, j = 1; i < 9; i += 2, j += 3) { - dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; - dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; - } - } else if (atp_is_geyser_2(dev)) { + if (atp_is_geyser_2(dev)) { memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); /* @@ -312,9 +267,6 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) dev->x_old = dev->y_old = -1; memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); - if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */ - goto exit; - /* 17" Powerbooks have extra X sensors */ for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { if (!dev->xy_cur[i]) continue; @@ -462,50 +414,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id dev->udev = udev; dev->input = input_dev; dev->overflowwarn = 0; - if (atp_is_geyser_3(dev)) - dev->datalen = 64; - else if (atp_is_geyser_2(dev)) - dev->datalen = 64; - else - dev->datalen = 81; - - if (atp_is_geyser_3(dev)) { - /* - * By default Geyser 3 device sends standard USB HID mouse - * packets (Report ID 2). This code changes device mode, so it - * sends raw sensor reports (Report ID 5). - */ - char data[8]; - int size; - - size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - ATP_GEYSER3_MODE_READ_REQUEST_ID, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - - if (size != 8) { - err("Could not do mode read request from device" - " (Geyser 3 mode)"); - goto err_free_devs; - } - - /* Apply the mode switch */ - data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; - - size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - ATP_GEYSER3_MODE_WRITE_REQUEST_ID, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - - if (size != 8) { - err("Could not do mode write request to device" - " (Geyser 3 mode)"); - goto err_free_devs; - } - printk("appletouch Geyser 3 inited.\n"); - } + dev->datalen = (atp_is_geyser_2(dev)?64:81); dev->urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->urb) { @@ -538,15 +447,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id set_bit(EV_ABS, input_dev->evbit); - if (atp_is_geyser_3(dev)) { - /* - * MacBook have 20 X sensors, 10 Y sensors - */ - input_set_abs_params(input_dev, ABS_X, 0, - ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); - input_set_abs_params(input_dev, ABS_Y, 0, - ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); - } else if (atp_is_geyser_2(dev)) { + if (atp_is_geyser_2(dev)) { /* * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected * later. diff --git a/trunk/drivers/usb/input/ati_remote.c b/trunk/drivers/usb/input/ati_remote.c index 07c8c0e665dd..99f986cb6e95 100644 --- a/trunk/drivers/usb/input/ati_remote.c +++ b/trunk/drivers/usb/input/ati_remote.c @@ -92,7 +92,9 @@ #include #include #include -#include +#include +#include +#include #include #include diff --git a/trunk/drivers/usb/input/ati_remote2.c b/trunk/drivers/usb/input/ati_remote2.c index ea71de81ca6b..ab1a1ae24be9 100644 --- a/trunk/drivers/usb/input/ati_remote2.c +++ b/trunk/drivers/usb/input/ati_remote2.c @@ -8,7 +8,7 @@ * as published by the Free Software Foundation. */ -#include +#include #define DRIVER_DESC "ATI/Philips USB RF remote driver" #define DRIVER_VERSION "0.1" diff --git a/trunk/drivers/usb/input/fixp-arith.h b/trunk/drivers/usb/input/fixp-arith.h index ed3d2da0c485..b44d398de071 100644 --- a/trunk/drivers/usb/input/fixp-arith.h +++ b/trunk/drivers/usb/input/fixp-arith.h @@ -2,6 +2,8 @@ #define _FIXP_ARITH_H /* + * $$ + * * Simplistic fixed-point arithmetics. * Hmm, I'm probably duplicating some code :( * @@ -29,20 +31,20 @@ #include -/* The type representing fixed-point values */ +// The type representing fixed-point values typedef s16 fixp_t; #define FRAC_N 8 #define FRAC_MASK ((1<>= 1; diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index b9fb9687f926..435273e7c85c 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -944,28 +944,21 @@ static void hid_reset(void *_hid) dev_dbg(&hid->intf->dev, "resetting device\n"); rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); if (rc_lock >= 0) { - rc = usb_reset_composite_device(hid->dev, hid->intf); + rc = usb_reset_device(hid->dev); if (rc_lock) usb_unlock_device(hid->dev); } clear_bit(HID_RESET_PENDING, &hid->iofl); - switch (rc) { - case 0: - if (!test_bit(HID_IN_RUNNING, &hid->iofl)) + if (rc == 0) { + hid->retry_delay = 0; + if (hid_start_in(hid)) hid_io_error(hid); - break; - default: + } else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR)) err("can't reset device, %s-%s/input%d, status %d", hid->dev->bus->bus_name, hid->dev->devpath, hid->ifnum, rc); - /* FALLTHROUGH */ - case -EHOSTUNREACH: - case -ENODEV: - case -EINTR: - break; - } } /* Main I/O error handler */ @@ -1381,6 +1374,9 @@ void hid_close(struct hid_device *hid) #define USB_VENDOR_ID_PANJIT 0x134c +#define USB_VENDOR_ID_SILVERCREST 0x062a +#define USB_DEVICE_ID_SILVERCREST_KB 0x0201 + /* * Initialize all reports */ @@ -1465,6 +1461,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_ONTRAK 0x0a07 #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 +#define USB_VENDOR_ID_TANGTOP 0x0d3d +#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 + #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 @@ -1521,6 +1520,12 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a +#define USB_VENDOR_ID_CHICONY 0x04f2 +#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 + +#define USB_VENDOR_ID_BTC 0x046e +#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 + #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 @@ -1544,13 +1549,20 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 #define USB_VENDOR_ID_APPLE 0x05ac -#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 +#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 #define USB_VENDOR_ID_CHERRY 0x046a #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 -#define USB_VENDOR_ID_YEALINK 0x6993 -#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 +#define USB_VENDOR_ID_HP 0x03f0 +#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c + +#define USB_VENDOR_ID_IBM 0x04b3 +#define USB_DEVICE_ID_IBM_USBHUB_KB 0x3005 + +#define USB_VENDOR_ID_CREATIVELABS 0x062a +#define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201 + /* * Alphabetically sorted blacklist by quirk type. */ @@ -1659,7 +1671,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, @@ -1669,9 +1680,16 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, + { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, @@ -1693,9 +1711,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, @@ -1779,14 +1794,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) quirks = hid_blacklist[n].quirks; - /* Many keyboards and mice don't like to be polled for reports, - * so we will always set the HID_QUIRK_NOGET flag for them. */ - if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { - if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD || - interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) - quirks |= HID_QUIRK_NOGET; - } - if (quirks & HID_QUIRK_IGNORE) return NULL; @@ -2073,29 +2080,11 @@ static int hid_resume(struct usb_interface *intf) int status; clear_bit(HID_SUSPENDED, &hid->iofl); - hid->retry_delay = 0; status = hid_start_in(hid); dev_dbg(&intf->dev, "resume status %d\n", status); return status; } -/* Treat USB reset pretty much the same as suspend/resume */ -static void hid_pre_reset(struct usb_interface *intf) -{ - /* FIXME: What if the interface is already suspended? */ - hid_suspend(intf, PMSG_ON); -} - -static void hid_post_reset(struct usb_interface *intf) -{ - struct usb_device *dev = interface_to_usbdev (intf); - - hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); - /* FIXME: Any more reinitialization needed? */ - - hid_resume(intf); -} - static struct usb_device_id hid_usb_ids [] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, .bInterfaceClass = USB_INTERFACE_CLASS_HID }, @@ -2110,8 +2099,6 @@ static struct usb_driver hid_driver = { .disconnect = hid_disconnect, .suspend = hid_suspend, .resume = hid_resume, - .pre_reset = hid_pre_reset, - .post_reset = hid_post_reset, .id_table = hid_usb_ids, }; diff --git a/trunk/drivers/usb/input/hid-debug.h b/trunk/drivers/usb/input/hid-debug.h index f04d6d75c098..702c48c2f81b 100644 --- a/trunk/drivers/usb/input/hid-debug.h +++ b/trunk/drivers/usb/input/hid-debug.h @@ -563,7 +563,7 @@ static char *keys[KEY_MAX + 1] = { [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power", [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus", [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma", - [KEY_HANGUEL] = "Hangeul", [KEY_HANJA] = "Hanja", + [KEY_HANGUEL] = "Hanguel", [KEY_HANJA] = "Hanja", [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta", [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose", [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again", diff --git a/trunk/drivers/usb/input/hid-input.c b/trunk/drivers/usb/input/hid-input.c index 028e1ad89f5d..25bc85f8ce39 100644 --- a/trunk/drivers/usb/input/hid-input.c +++ b/trunk/drivers/usb/input/hid-input.c @@ -29,7 +29,9 @@ #include #include #include -#include +#include +#include +#include #undef DEBUG @@ -565,23 +567,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; } - if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { - if (usage->hid == HID_GD_Z) - map_rel(REL_HWHEEL); - else if (usage->code == BTN_1) - map_key(BTN_2); - else if (usage->code == BTN_2) - map_key(BTN_1); - } - - if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && - (usage->type == EV_REL) && (usage->code == REL_WHEEL)) - set_bit(REL_HWHEEL, bit); - - if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) - || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) - goto ignore; - set_bit(usage->type, input->evbit); while (usage->code <= max && test_and_set_bit(usage->code, bit)) @@ -590,6 +575,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel if (usage->code > max) goto ignore; + if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032))) + map_rel(REL_HWHEEL); + + if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && + (usage->type == EV_REL) && (usage->code == REL_WHEEL)) + set_bit(REL_HWHEEL, bit); + + if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) + || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) + goto ignore; if (usage->type == EV_ABS) { @@ -652,11 +647,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { - input_event(input, usage->type, usage->code, -value); - return; - } - if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { input_event(input, usage->type, REL_HWHEEL, value); return; diff --git a/trunk/drivers/usb/input/hid.h b/trunk/drivers/usb/input/hid.h index 778e575de352..9c62837b5b89 100644 --- a/trunk/drivers/usb/input/hid.h +++ b/trunk/drivers/usb/input/hid.h @@ -40,14 +40,6 @@ #define USB_INTERFACE_CLASS_HID 3 -/* - * USB HID interface subclass and protocol codes - */ - -#define USB_INTERFACE_SUBCLASS_BOOT 1 -#define USB_INTERFACE_PROTOCOL_KEYBOARD 1 -#define USB_INTERFACE_PROTOCOL_MOUSE 2 - /* * HID class requests */ @@ -255,11 +247,10 @@ struct hid_item { #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 -#define HID_QUIRK_MIGHTYMOUSE 0x00000400 +#define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400 #define HID_QUIRK_CYMOTION 0x00000800 #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 -#define HID_QUIRK_INVERT_HWHEEL 0x00004000 /* * This is the global environment of the parser. This information is diff --git a/trunk/drivers/usb/input/itmtouch.c b/trunk/drivers/usb/input/itmtouch.c index 5c570cc703f3..7618ae5c104f 100644 --- a/trunk/drivers/usb/input/itmtouch.c +++ b/trunk/drivers/usb/input/itmtouch.c @@ -42,9 +42,11 @@ #include #include #include +#include #include #include -#include +#include +#include /* only an 8 byte buffer necessary for a single packet */ #define ITM_BUFSIZE 8 diff --git a/trunk/drivers/usb/input/kbtab.c b/trunk/drivers/usb/input/kbtab.c index 604ade356ead..f6d5cead542b 100644 --- a/trunk/drivers/usb/input/kbtab.c +++ b/trunk/drivers/usb/input/kbtab.c @@ -1,9 +1,12 @@ #include #include +#include #include #include -#include +#include +#include #include +#include /* * Version Information diff --git a/trunk/drivers/usb/input/keyspan_remote.c b/trunk/drivers/usb/input/keyspan_remote.c index 70af985b5db9..3d911976f378 100644 --- a/trunk/drivers/usb/input/keyspan_remote.c +++ b/trunk/drivers/usb/input/keyspan_remote.c @@ -18,7 +18,9 @@ #include #include #include -#include +#include +#include +#include #define DRIVER_VERSION "v0.1" #define DRIVER_AUTHOR "Michael Downey " diff --git a/trunk/drivers/usb/input/mtouchusb.c b/trunk/drivers/usb/input/mtouchusb.c index 4fdee4db0729..f018953a5485 100644 --- a/trunk/drivers/usb/input/mtouchusb.c +++ b/trunk/drivers/usb/input/mtouchusb.c @@ -42,9 +42,11 @@ #include #include #include +#include #include #include -#include +#include +#include #define MTOUCHUSB_MIN_XC 0x0 #define MTOUCHUSB_MAX_RAW_XC 0x4000 diff --git a/trunk/drivers/usb/input/powermate.c b/trunk/drivers/usb/input/powermate.c index b3c0d0c3eae9..fdf0f788062c 100644 --- a/trunk/drivers/usb/input/powermate.c +++ b/trunk/drivers/usb/input/powermate.c @@ -30,10 +30,12 @@ #include #include +#include #include #include #include -#include +#include +#include #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ diff --git a/trunk/drivers/usb/input/touchkitusb.c b/trunk/drivers/usb/input/touchkitusb.c index da7b0bf51aff..697c5e573a11 100644 --- a/trunk/drivers/usb/input/touchkitusb.c +++ b/trunk/drivers/usb/input/touchkitusb.c @@ -27,9 +27,11 @@ #include #include #include +#include #include #include -#include +#include +#include #define TOUCHKIT_MIN_XC 0x0 #define TOUCHKIT_MAX_XC 0x07ff diff --git a/trunk/drivers/usb/input/usbkbd.c b/trunk/drivers/usb/input/usbkbd.c index 5067a6ae650f..2f3edc26cb50 100644 --- a/trunk/drivers/usb/input/usbkbd.c +++ b/trunk/drivers/usb/input/usbkbd.c @@ -29,8 +29,10 @@ #include #include #include +#include #include -#include +#include +#include /* * Version Information diff --git a/trunk/drivers/usb/input/usbmouse.c b/trunk/drivers/usb/input/usbmouse.c index 446935b671d9..af526135d210 100644 --- a/trunk/drivers/usb/input/usbmouse.c +++ b/trunk/drivers/usb/input/usbmouse.c @@ -28,9 +28,11 @@ #include #include +#include #include #include -#include +#include +#include /* * Version Information diff --git a/trunk/drivers/usb/input/usbtouchscreen.c b/trunk/drivers/usb/input/usbtouchscreen.c index 3b175aa482cd..e9a07c1e905b 100644 --- a/trunk/drivers/usb/input/usbtouchscreen.c +++ b/trunk/drivers/usb/input/usbtouchscreen.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #define DRIVER_VERSION "v0.3" diff --git a/trunk/drivers/usb/input/wacom.c b/trunk/drivers/usb/input/wacom.c index 369461a70b72..cf84c6096f29 100644 --- a/trunk/drivers/usb/input/wacom.c +++ b/trunk/drivers/usb/input/wacom.c @@ -69,10 +69,13 @@ #include #include +#include #include #include -#include +#include +#include #include +#include /* * Version Information diff --git a/trunk/drivers/usb/input/xpad.c b/trunk/drivers/usb/input/xpad.c index cfd4a4e04334..e278489a80c6 100644 --- a/trunk/drivers/usb/input/xpad.c +++ b/trunk/drivers/usb/input/xpad.c @@ -56,11 +56,13 @@ #include #include +#include #include #include #include #include -#include +#include +#include #define DRIVER_VERSION "v0.0.5" #define DRIVER_AUTHOR "Marko Friedemann " diff --git a/trunk/drivers/usb/input/yealink.c b/trunk/drivers/usb/input/yealink.c index 24aedbb20f03..37d2f0ba0319 100644 --- a/trunk/drivers/usb/input/yealink.c +++ b/trunk/drivers/usb/input/yealink.c @@ -48,11 +48,13 @@ #include #include +#include #include #include #include #include -#include +#include +#include #include "map_to_7segment.h" #include "yealink.h" diff --git a/trunk/drivers/usb/misc/Kconfig b/trunk/drivers/usb/misc/Kconfig index daa486dde8cf..8ba6a701e9c1 100644 --- a/trunk/drivers/usb/misc/Kconfig +++ b/trunk/drivers/usb/misc/Kconfig @@ -88,20 +88,6 @@ config USB_LED To compile this driver as a module, choose M here: the module will be called usbled. -config USB_CY7C63 - tristate "Cypress CY7C63xxx USB driver support" - depends on USB - help - Say Y here if you want to connect a Cypress CY7C63xxx - micro controller to your computer's USB port. This driver - supports the pre-programmed devices (incl. firmware) by - AK Modul-Bus Computer GmbH. - - Please see: http://www.ak-modul-bus.de/stat/mikrocontroller.html - - To compile this driver as a module, choose M here: the - module will be called cy7c63. - config USB_CYTHERM tristate "Cypress USB thermometer driver support" depends on USB @@ -151,15 +137,6 @@ config USB_IDMOUSE See also . -config USB_APPLEDISPLAY - tristate "Apple Cinema Display support" - depends on USB - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - help - Say Y here if you want to control the backlight of Apple Cinema - Displays over USB. This driver provides a sysfs interface. - source "drivers/usb/misc/sisusbvga/Kconfig" config USB_LD diff --git a/trunk/drivers/usb/misc/Makefile b/trunk/drivers/usb/misc/Makefile index f25a97227297..6c693bc68e2e 100644 --- a/trunk/drivers/usb/misc/Makefile +++ b/trunk/drivers/usb/misc/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_USB_AUERSWALD) += auerswald.o -obj-$(CONFIG_USB_CY7C63) += cy7c63.o obj-$(CONFIG_USB_CYTHERM) += cytherm.o obj-$(CONFIG_USB_EMI26) += emi26.o obj-$(CONFIG_USB_EMI62) += emi62.o @@ -18,7 +17,6 @@ obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o obj-$(CONFIG_USB_USS720) += uss720.o -obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c deleted file mode 100644 index bfde82f5d180..000000000000 --- a/trunk/drivers/usb/misc/appledisplay.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Apple Cinema Display driver - * - * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch) - * - * Thanks to Caskey L. Dickson for his work with acdctl. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APPLE_VENDOR_ID 0x05AC - -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_SET_REPORT 0x09 - -#define ACD_USB_TIMEOUT 250 - -#define ACD_USB_EDID 0x0302 -#define ACD_USB_BRIGHTNESS 0x0310 - -#define ACD_BTN_NONE 0 -#define ACD_BTN_BRIGHT_UP 3 -#define ACD_BTN_BRIGHT_DOWN 4 - -#define ACD_URB_BUFFER_LEN 2 -#define ACD_MSG_BUFFER_LEN 2 - -#define APPLEDISPLAY_DEVICE(prod) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_CLASS | \ - USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ - .idVendor = APPLE_VENDOR_ID, \ - .idProduct = (prod), \ - .bInterfaceClass = USB_CLASS_HID, \ - .bInterfaceProtocol = 0x00 - -/* table of devices that work with this driver */ -static struct usb_device_id appledisplay_table [] = { - { APPLEDISPLAY_DEVICE(0x9218) }, - { APPLEDISPLAY_DEVICE(0x9219) }, - { APPLEDISPLAY_DEVICE(0x921d) }, - - /* Terminating entry */ - { } -}; -MODULE_DEVICE_TABLE(usb, appledisplay_table); - -/* Structure to hold all of our device specific stuff */ -struct appledisplay { - struct usb_device *udev; /* usb device */ - struct urb *urb; /* usb request block */ - struct backlight_device *bd; /* backlight device */ - char *urbdata; /* interrupt URB data buffer */ - char *msgdata; /* control message data buffer */ - - struct work_struct work; - int button_pressed; - spinlock_t lock; -}; - -static atomic_t count_displays = ATOMIC_INIT(0); -static struct workqueue_struct *wq; - -static void appledisplay_complete(struct urb *urb, struct pt_regs *regs) -{ - struct appledisplay *pdata = urb->context; - unsigned long flags; - int retval; - - switch (urb->status) { - case 0: - /* success */ - break; - case -EOVERFLOW: - printk(KERN_ERR "appletouch: OVERFLOW with data " - "length %d, actual length is %d\n", - ACD_URB_BUFFER_LEN, pdata->urb->actual_length); - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* This urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __FUNCTION__, urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __FUNCTION__, urb->status); - goto exit; - } - - spin_lock_irqsave(&pdata->lock, flags); - - switch(pdata->urbdata[1]) { - case ACD_BTN_BRIGHT_UP: - case ACD_BTN_BRIGHT_DOWN: - pdata->button_pressed = 1; - queue_work(wq, &pdata->work); - break; - case ACD_BTN_NONE: - default: - pdata->button_pressed = 0; - break; - } - - spin_unlock_irqrestore(&pdata->lock, flags); - -exit: - retval = usb_submit_urb(pdata->urb, GFP_ATOMIC); - if (retval) { - err("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); - } -} - -static int appledisplay_bl_update_status(struct backlight_device *bd) -{ - struct appledisplay *pdata = class_get_devdata(&bd->class_dev); - int retval; - - pdata->msgdata[0] = 0x10; - pdata->msgdata[1] = bd->props->brightness; - - retval = usb_control_msg( - pdata->udev, - usb_sndctrlpipe(pdata->udev, 0), - USB_REQ_SET_REPORT, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ACD_USB_BRIGHTNESS, - 0, - pdata->msgdata, 2, - ACD_USB_TIMEOUT); - - return retval; -} - -static int appledisplay_bl_get_brightness(struct backlight_device *bd) -{ - struct appledisplay *pdata = class_get_devdata(&bd->class_dev); - int retval; - - retval = usb_control_msg( - pdata->udev, - usb_rcvctrlpipe(pdata->udev, 0), - USB_REQ_GET_REPORT, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ACD_USB_BRIGHTNESS, - 0, - pdata->msgdata, 2, - ACD_USB_TIMEOUT); - - if (retval < 0) - return retval; - else - return pdata->msgdata[1]; -} - -static struct backlight_properties appledisplay_bl_data = { - .owner = THIS_MODULE, - .get_brightness = appledisplay_bl_get_brightness, - .update_status = appledisplay_bl_update_status, - .max_brightness = 0xFF -}; - -static void appledisplay_work(void *private) -{ - struct appledisplay *pdata = private; - int retval; - - up(&pdata->bd->sem); - retval = appledisplay_bl_get_brightness(pdata->bd); - if (retval >= 0) - pdata->bd->props->brightness = retval; - down(&pdata->bd->sem); - - /* Poll again in about 125ms if there's still a button pressed */ - if (pdata->button_pressed) - schedule_delayed_work(&pdata->work, HZ / 8); -} - -static int appledisplay_probe(struct usb_interface *iface, - const struct usb_device_id *id) -{ - struct appledisplay *pdata; - struct usb_device *udev = interface_to_usbdev(iface); - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - int int_in_endpointAddr = 0; - int i, retval = -ENOMEM, brightness; - char bl_name[20]; - - /* set up the endpoint information */ - /* use only the first interrupt-in endpoint */ - iface_desc = iface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - endpoint = &iface_desc->endpoint[i].desc; - if (!int_in_endpointAddr && - (endpoint->bEndpointAddress & USB_DIR_IN) && - ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_INT)) { - /* we found an interrupt in endpoint */ - int_in_endpointAddr = endpoint->bEndpointAddress; - break; - } - } - if (!int_in_endpointAddr) { - err("Could not find int-in endpoint"); - return -EIO; - } - - /* allocate memory for our device state and initialize it */ - pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); - if (!pdata) { - retval = -ENOMEM; - err("Out of memory"); - goto error; - } - - pdata->udev = udev; - - spin_lock_init(&pdata->lock); - INIT_WORK(&pdata->work, appledisplay_work, pdata); - - /* Allocate buffer for control messages */ - pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); - if (!pdata->msgdata) { - retval = -ENOMEM; - err("appledisplay: Allocating buffer for control messages " - "failed"); - goto error; - } - - /* Allocate interrupt URB */ - pdata->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!pdata->urb) { - retval = -ENOMEM; - err("appledisplay: Allocating URB failed"); - goto error; - } - - /* Allocate buffer for interrupt data */ - pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN, - GFP_KERNEL, &pdata->urb->transfer_dma); - if (!pdata->urbdata) { - retval = -ENOMEM; - err("appledisplay: Allocating URB buffer failed"); - goto error; - } - - /* Configure interrupt URB */ - usb_fill_int_urb(pdata->urb, udev, - usb_rcvintpipe(udev, int_in_endpointAddr), - pdata->urbdata, ACD_URB_BUFFER_LEN, appledisplay_complete, - pdata, 1); - if (usb_submit_urb(pdata->urb, GFP_KERNEL)) { - retval = -EIO; - err("appledisplay: Submitting URB failed"); - goto error; - } - - /* Register backlight device */ - snprintf(bl_name, sizeof(bl_name), "appledisplay%d", - atomic_inc_return(&count_displays) - 1); - pdata->bd = backlight_device_register(bl_name, pdata, - &appledisplay_bl_data); - if (IS_ERR(pdata->bd)) { - err("appledisplay: Backlight registration failed"); - goto error; - } - - /* Try to get brightness */ - up(&pdata->bd->sem); - brightness = appledisplay_bl_get_brightness(pdata->bd); - down(&pdata->bd->sem); - - if (brightness < 0) { - retval = brightness; - err("appledisplay: Error while getting initial brightness: %d", retval); - goto error; - } - - /* Set brightness in backlight device */ - up(&pdata->bd->sem); - pdata->bd->props->brightness = brightness; - down(&pdata->bd->sem); - - /* save our data pointer in the interface device */ - usb_set_intfdata(iface, pdata); - - printk(KERN_INFO "appledisplay: Apple Cinema Display connected\n"); - - return 0; - -error: - if (pdata) { - if (pdata->urb) { - usb_kill_urb(pdata->urb); - if (pdata->urbdata) - usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN, - pdata->urbdata, pdata->urb->transfer_dma); - usb_free_urb(pdata->urb); - } - if (pdata->bd) - backlight_device_unregister(pdata->bd); - kfree(pdata->msgdata); - } - usb_set_intfdata(iface, NULL); - kfree(pdata); - return retval; -} - -static void appledisplay_disconnect(struct usb_interface *iface) -{ - struct appledisplay *pdata = usb_get_intfdata(iface); - - if (pdata) { - usb_kill_urb(pdata->urb); - cancel_delayed_work(&pdata->work); - backlight_device_unregister(pdata->bd); - usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN, - pdata->urbdata, pdata->urb->transfer_dma); - usb_free_urb(pdata->urb); - kfree(pdata->msgdata); - kfree(pdata); - } - - printk(KERN_INFO "appledisplay: Apple Cinema Display disconnected\n"); -} - -static struct usb_driver appledisplay_driver = { - .name = "appledisplay", - .probe = appledisplay_probe, - .disconnect = appledisplay_disconnect, - .id_table = appledisplay_table, -}; - -static int __init appledisplay_init(void) -{ - wq = create_singlethread_workqueue("appledisplay"); - if (!wq) { - err("Could not create work queue\n"); - return -ENOMEM; - } - - return usb_register(&appledisplay_driver); -} - -static void __exit appledisplay_exit(void) -{ - flush_workqueue(wq); - destroy_workqueue(wq); - usb_deregister(&appledisplay_driver); -} - -MODULE_AUTHOR("Michael Hanselmann"); -MODULE_DESCRIPTION("Apple Cinema Display driver"); -MODULE_LICENSE("GPL"); - -module_init(appledisplay_init); -module_exit(appledisplay_exit); diff --git a/trunk/drivers/usb/misc/cy7c63.c b/trunk/drivers/usb/misc/cy7c63.c deleted file mode 100644 index 8a1c10b89b76..000000000000 --- a/trunk/drivers/usb/misc/cy7c63.c +++ /dev/null @@ -1,244 +0,0 @@ -/* -* cy7c63.c -* -* Copyright (c) 2006 Oliver Bock (bock@fh-wolfenbuettel.de) -* -* This driver is based on the Cypress Thermometer USB Driver by -* Marcus Maul and the 2.0 version of Greg Kroah-Hartman's -* USB Skeleton driver. -* -* Is is a generic driver for the Cypress CY7C63000 family. -* For the time being it enables you to toggle the single I/O ports -* of the device. -* -* Supported vendors: AK Modul-Bus Computer GmbH -* Supported devices: CY7C63001A-PC (to be continued...) -* Supported functions: Read/Write Ports (to be continued...) -* -* Chipsets families: CY7C63000, CY7C63001, CY7C63100, CY7C63101 -* -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation, version 2. -*/ - -#include -#include -#include -#include - -#define DRIVER_AUTHOR "Oliver Bock (bock@fh-wolfenbuettel.de)" -#define DRIVER_DESC "Cypress CY7C63xxx USB driver" - -#define CY7C63_VENDOR_ID 0xa2c -#define CY7C63_PRODUCT_ID 0x8 - -#define CY7C63_READ_PORT 0x4 -#define CY7C63_WRITE_PORT 0x5 -#define CY7C63_READ_RAM 0x2 -#define CY7C63_WRITE_RAM 0x3 -#define CY7C63_READ_ROM 0x1 - -#define CY7C63_READ_PORT_ID0 0 -#define CY7C63_WRITE_PORT_ID0 0 -#define CY7C63_READ_PORT_ID1 0x2 -#define CY7C63_WRITE_PORT_ID1 1 - -#define CY7C63_MAX_REQSIZE 8 - - -/* table of devices that work with this driver */ -static struct usb_device_id cy7c63_table [] = { - { USB_DEVICE(CY7C63_VENDOR_ID, CY7C63_PRODUCT_ID) }, - { } -}; -MODULE_DEVICE_TABLE(usb, cy7c63_table); - -/* structure to hold all of our device specific stuff */ -struct cy7c63 { - struct usb_device * udev; - char port0; - char port1; -}; - -/* used to send usb control messages to device */ -int vendor_command(struct cy7c63 *dev, unsigned char request, - unsigned char address, unsigned char data) { - - int retval = 0; - unsigned int pipe; - unsigned char *iobuf; - - /* allocate some memory for the i/o buffer*/ - iobuf = kzalloc(CY7C63_MAX_REQSIZE, GFP_KERNEL); - if (!iobuf) { - dev_err(&dev->udev->dev, "Out of memory!\n"); - retval = -ENOMEM; - goto error; - } - - dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data); - - /* prepare usb control message and send it upstream */ - pipe = usb_rcvctrlpipe(dev->udev, 0); - retval = usb_control_msg(dev->udev, pipe, request, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, - address, data, iobuf, CY7C63_MAX_REQSIZE, - USB_CTRL_GET_TIMEOUT); - - /* store returned data (more READs to be added!) */ - switch (request) { - case CY7C63_READ_PORT: - if (address == CY7C63_READ_PORT_ID0) { - dev->port0 = iobuf[1]; - dev_dbg(&dev->udev->dev, - "READ_PORT0 returned: %d\n",dev->port0); - } - else if (address == CY7C63_READ_PORT_ID1) { - dev->port1 = iobuf[1]; - dev_dbg(&dev->udev->dev, - "READ_PORT1 returned: %d\n",dev->port1); - } - break; - } - - kfree(iobuf); -error: - return retval; -} - -#define get_set_port(num,read_id,write_id) \ -static ssize_t set_port##num(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) { \ - \ - int value; \ - int result = 0; \ - \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct cy7c63 *cyp = usb_get_intfdata(intf); \ - \ - dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", num); \ - \ - /* validate input data */ \ - if (sscanf(buf, "%d", &value) < 1) { \ - result = -EINVAL; \ - goto error; \ - } \ - if (value>255 || value<0) { \ - result = -EINVAL; \ - goto error; \ - } \ - \ - result = vendor_command(cyp, CY7C63_WRITE_PORT, write_id, \ - (unsigned char)value); \ - \ - dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n",result); \ -error: \ - return result < 0 ? result : count; \ -} \ - \ -static ssize_t get_port##num(struct device *dev, \ - struct device_attribute *attr, char *buf) { \ - \ - int result = 0; \ - \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct cy7c63 *cyp = usb_get_intfdata(intf); \ - \ - dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", num); \ - \ - result = vendor_command(cyp, CY7C63_READ_PORT, read_id, 0); \ - \ - dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result); \ - \ - return sprintf(buf, "%d", cyp->port##num); \ -} \ -static DEVICE_ATTR(port##num, S_IWUGO | S_IRUGO, get_port##num, set_port##num); - -get_set_port(0, CY7C63_READ_PORT_ID0, CY7C63_WRITE_PORT_ID0); -get_set_port(1, CY7C63_READ_PORT_ID1, CY7C63_WRITE_PORT_ID1); - -static int cy7c63_probe(struct usb_interface *interface, - const struct usb_device_id *id) { - - struct cy7c63 *dev = NULL; - int retval = -ENOMEM; - - /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&dev->udev->dev, "Out of memory!\n"); - goto error; - } - - dev->udev = usb_get_dev(interface_to_usbdev(interface)); - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); - - /* create device attribute files */ - device_create_file(&interface->dev, &dev_attr_port0); - device_create_file(&interface->dev, &dev_attr_port1); - - /* let the user know what node this device is now attached to */ - dev_info(&interface->dev, - "Cypress CY7C63xxx device now attached\n"); - - retval = 0; -error: - return retval; -} - -static void cy7c63_disconnect(struct usb_interface *interface) { - - struct cy7c63 *dev; - - dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - /* remove device attribute files */ - device_remove_file(&interface->dev, &dev_attr_port0); - device_remove_file(&interface->dev, &dev_attr_port1); - - usb_put_dev(dev->udev); - - dev_info(&interface->dev, - "Cypress CY7C63xxx device now disconnected\n"); - - kfree(dev); -} - -static struct usb_driver cy7c63_driver = { - .name = "cy7c63", - .probe = cy7c63_probe, - .disconnect = cy7c63_disconnect, - .id_table = cy7c63_table, -}; - -static int __init cy7c63_init(void) { - - int result; - - /* register this driver with the USB subsystem */ - result = usb_register(&cy7c63_driver); - if (result) { - err("Function usb_register failed! Error number: %d\n", result); - } - - return result; -} - -static void __exit cy7c63_exit(void) { - - /* deregister this driver with the USB subsystem */ - usb_deregister(&cy7c63_driver); -} - -module_init(cy7c63_init); -module_exit(cy7c63_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index 13aeea2026cc..997db5d8e35b 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -1,8 +1,7 @@ /* * USB PhidgetInterfaceKit driver 1.0 * - * Copyright (C) 2004, 2006 Sean Young - * Copyright (C) 2005 Daniel Saakes + * Copyright (C) 2004 Sean Young * Copyright (C) 2004 Greg Kroah-Hartman * * This program is free software; you can redistribute it and/or modify @@ -26,7 +25,6 @@ #define USB_VENDOR_ID_GLAB 0x06c2 #define USB_DEVICE_ID_INTERFACEKIT004 0x0040 -#define USB_DEVICE_ID_INTERFACEKIT01616 0x0044 #define USB_DEVICE_ID_INTERFACEKIT888 0x0045 #define USB_DEVICE_ID_INTERFACEKIT047 0x0051 #define USB_DEVICE_ID_INTERFACEKIT088 0x0053 @@ -34,9 +32,7 @@ #define USB_VENDOR_ID_WISEGROUP 0x0925 #define USB_DEVICE_ID_INTERFACEKIT884 0x8201 -#define MAX_INTERFACES 16 - -#define URB_INT_SIZE 8 +#define MAX_INTERFACES 8 struct driver_interfacekit { int sensors; @@ -56,24 +52,19 @@ ifkit(8, 8, 8, 0); ifkit(0, 4, 7, 1); ifkit(8, 8, 4, 0); ifkit(0, 8, 8, 1); -ifkit(0, 16, 16, 0); -struct interfacekit { +struct phidget_interfacekit { struct usb_device *udev; struct usb_interface *intf; struct driver_interfacekit *ifkit; - unsigned long outputs; - u8 inputs[MAX_INTERFACES]; - u16 sensors[MAX_INTERFACES]; + int outputs[MAX_INTERFACES]; + int inputs[MAX_INTERFACES]; + int sensors[MAX_INTERFACES]; u8 lcd_files_on; struct urb *irq; unsigned char *data; dma_addr_t data_dma; - - struct work_struct do_notify; - unsigned long input_events; - unsigned long sensor_events; }; static struct usb_device_id id_table[] = { @@ -85,33 +76,33 @@ static struct usb_device_id id_table[] = { .driver_info = (kernel_ulong_t)&ph_047}, {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), .driver_info = (kernel_ulong_t)&ph_088}, - {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616), - .driver_info = (kernel_ulong_t)&ph_01616}, {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), .driver_info = (kernel_ulong_t)&ph_884}, {} }; MODULE_DEVICE_TABLE(usb, id_table); -static int change_outputs(struct interfacekit *kit, int output_num, int enable) +static int change_outputs(struct phidget_interfacekit *kit, int output_num, int enable) { - u8 *buffer; + unsigned char *buffer; int retval; - - if (enable) - set_bit(output_num, &kit->outputs); - else - clear_bit(output_num, &kit->outputs); + int n; buffer = kzalloc(4, GFP_KERNEL); if (!buffer) { - dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); + dev_err(&kit->udev->dev, "%s - out of memory\n", + __FUNCTION__); return -ENOMEM; } - buffer[0] = (u8)kit->outputs; - buffer[1] = (u8)(kit->outputs >> 8); - dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs); + kit->outputs[output_num] = enable; + for (n=0; n<8; n++) { + if (kit->outputs[n]) { + buffer[0] |= 1 << n; + } + } + + dev_dbg(&kit->udev->dev, "sending data: %02x\n", buffer[0]); retval = usb_control_msg(kit->udev, usb_sndctrlpipe(kit->udev, 0), @@ -125,10 +116,10 @@ static int change_outputs(struct interfacekit *kit, int output_num, int enable) return retval < 0 ? retval : 0; } -static int change_string(struct interfacekit *kit, const char *display, unsigned char row) +static int change_string(struct phidget_interfacekit *kit, const char *display, unsigned char row) { unsigned char *buffer; - unsigned char *form_buffer; + unsigned char *form_buffer; int retval = -ENOMEM; int i,j, len, buf_ptr; @@ -184,7 +175,7 @@ static int change_string(struct interfacekit *kit, const char *display, unsigned static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ { \ struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ change_string(kit, buf, number - 1); \ return count; \ } \ @@ -195,7 +186,7 @@ set_lcd_line(2); static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_interface *intf = to_usb_interface(dev); - struct interfacekit *kit = usb_get_intfdata(intf); + struct phidget_interfacekit *kit = usb_get_intfdata(intf); int enabled; unsigned char *buffer; int retval = -ENOMEM; @@ -229,7 +220,7 @@ static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); -static void remove_lcd_files(struct interfacekit *kit) +static void remove_lcd_files(struct phidget_interfacekit *kit) { if (kit->lcd_files_on) { dev_dbg(&kit->udev->dev, "Removing lcd files\n"); @@ -242,7 +233,7 @@ static void remove_lcd_files(struct interfacekit *kit) static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct usb_interface *intf = to_usb_interface(dev); - struct interfacekit *kit = usb_get_intfdata(intf); + struct phidget_interfacekit *kit = usb_get_intfdata(intf); int enable; if (kit->ifkit->has_lcd == 0) @@ -272,10 +263,10 @@ static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) { - struct interfacekit *kit = urb->context; + struct phidget_interfacekit *kit = urb->context; unsigned char *buffer = kit->data; - int i, level, sensor; int status; + int n; switch (urb->status) { case 0: /* success */ @@ -289,63 +280,22 @@ static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) goto resubmit; } - /* digital inputs */ - if (kit->ifkit->inputs == 16) { - for (i=0; i < 8; i++) { - level = (buffer[0] >> i) & 1; - if (kit->inputs[i] != level) { - kit->inputs[i] = level; - set_bit(i, &kit->input_events); - } - level = (buffer[1] >> i) & 1; - if (kit->inputs[8 + i] != level) { - kit->inputs[8 + i] = level; - set_bit(8 + i, &kit->input_events); - } - } - } - else if (kit->ifkit->inputs == 8) { - for (i=0; i < 8; i++) { - level = (buffer[1] >> i) & 1; - if (kit->inputs[i] != level) { - kit->inputs[i] = level; - set_bit(i, &kit->input_events); - } - } + for (n=0; n<8; n++) { + kit->inputs[n] = buffer[1] & (1 << n) ? 1 : 0; } - /* analog inputs */ - if (kit->ifkit->sensors) { - sensor = (buffer[0] & 1) ? 4 : 0; - - level = buffer[2] + (buffer[3] & 0x0f) * 256; - if (level != kit->sensors[sensor]) { - kit->sensors[sensor] = level; - set_bit(sensor, &kit->sensor_events); - } - sensor++; - level = buffer[4] + (buffer[3] & 0xf0) * 16; - if (level != kit->sensors[sensor]) { - kit->sensors[sensor] = level; - set_bit(sensor, &kit->sensor_events); - } - sensor++; - level = buffer[5] + (buffer[6] & 0x0f) * 256; - if (level != kit->sensors[sensor]) { - kit->sensors[sensor] = level; - set_bit(sensor, &kit->sensor_events); - } - sensor++; - level = buffer[7] + (buffer[6] & 0xf0) * 16; - if (level != kit->sensors[sensor]) { - kit->sensors[sensor] = level; - set_bit(sensor, &kit->sensor_events); - } + if (buffer[0] & 1) { + kit->sensors[4] = buffer[2] + (buffer[3] & 0x0f) * 256; + kit->sensors[5] = buffer[4] + (buffer[3] & 0xf0) * 16; + kit->sensors[6] = buffer[5] + (buffer[6] & 0x0f) * 256; + kit->sensors[7] = buffer[7] + (buffer[6] & 0xf0) * 16; + } else { + kit->sensors[0] = buffer[2] + (buffer[3] & 0x0f) * 256; + kit->sensors[1] = buffer[4] + (buffer[3] & 0xf0) * 16; + kit->sensors[2] = buffer[5] + (buffer[6] & 0x0f) * 256; + kit->sensors[3] = buffer[7] + (buffer[6] & 0xf0) * 16; } - if (kit->input_events || kit->sensor_events) - schedule_work(&kit->do_notify); - resubmit: status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) @@ -354,40 +304,20 @@ static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) kit->udev->devpath, status); } -static void do_notify(void *data) -{ - struct interfacekit *kit = data; - int i; - char sysfs_file[8]; - - for (i=0; iifkit->inputs; i++) { - if (test_and_clear_bit(i, &kit->input_events)) { - sprintf(sysfs_file, "input%d", i + 1); - sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file); - } - } - - for (i=0; iifkit->sensors; i++) { - if (test_and_clear_bit(i, &kit->sensor_events)) { - sprintf(sysfs_file, "sensor%d", i + 1); - sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file); - } - } -} - #define show_set_output(value) \ -static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ +static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ size_t count) \ { \ struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ int enabled; \ int retval; \ \ - if (sscanf(buf, "%d", &enabled) < 1) \ + if (sscanf(buf, "%d", &enabled) < 1) { \ return -EINVAL; \ + } \ \ - retval = change_outputs(kit, value - 1, enabled); \ + retval = change_outputs(kit, value - 1, enabled ? 1 : 0); \ \ return retval ? retval : count; \ } \ @@ -395,9 +325,9 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ \ - return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ + return sprintf(buf, "%d\n", kit->outputs[value - 1]); \ } \ static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ show_output##value, set_output##value); @@ -408,23 +338,15 @@ show_set_output(4); show_set_output(5); show_set_output(6); show_set_output(7); -show_set_output(8); -show_set_output(9); -show_set_output(10); -show_set_output(11); -show_set_output(12); -show_set_output(13); -show_set_output(14); -show_set_output(15); -show_set_output(16); +show_set_output(8); /* should be MAX_INTERFACES - 1 */ #define show_input(value) \ static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ \ - return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ + return sprintf(buf, "%d\n", kit->inputs[value - 1]); \ } \ static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); @@ -435,23 +357,15 @@ show_input(4); show_input(5); show_input(6); show_input(7); -show_input(8); -show_input(9); -show_input(10); -show_input(11); -show_input(12); -show_input(13); -show_input(14); -show_input(15); -show_input(16); +show_input(8); /* should be MAX_INTERFACES - 1 */ #define show_sensor(value) \ static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct usb_interface *intf = to_usb_interface(dev); \ - struct interfacekit *kit = usb_get_intfdata(intf); \ + struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ \ - return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ + return sprintf(buf, "%d\n", kit->sensors[value - 1]); \ } \ static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); @@ -462,16 +376,16 @@ show_sensor(4); show_sensor(5); show_sensor(6); show_sensor(7); -show_sensor(8); +show_sensor(8); /* should be MAX_INTERFACES - 1 */ static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; - struct interfacekit *kit; + struct phidget_interfacekit *kit; struct driver_interfacekit *ifkit; - int pipe, maxp, rc = -ENOMEM; + int pipe, maxp; ifkit = (struct driver_interfacekit *)id->driver_info; if (!ifkit) @@ -491,23 +405,29 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); kit = kzalloc(sizeof(*kit), GFP_KERNEL); - if (!kit) - goto out; - + if (kit == NULL) { + dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__); + return -ENOMEM; + } kit->ifkit = ifkit; - kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma); - if (!kit->data) - goto out; + + kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma); + if (!kit->data) { + kfree(kit); + return -ENOMEM; + } kit->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!kit->irq) - goto out; + if (!kit->irq) { + usb_buffer_free(dev, 8, kit->data, kit->data_dma); + kfree(kit); + return -ENOMEM; + } kit->udev = usb_get_dev(dev); kit->intf = intf; - INIT_WORK(&kit->do_notify, do_notify, kit); usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, - maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, + (maxp > 8 ? 8 : maxp), interfacekit_irq, kit, endpoint->bInterval); kit->irq->transfer_dma = kit->data_dma; kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -515,8 +435,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic usb_set_intfdata(intf, kit); if (usb_submit_urb(kit->irq, GFP_KERNEL)) { - rc = -EIO; - goto out; + return -EIO; } if (ifkit->outputs >= 4) { @@ -525,22 +444,12 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic device_create_file(&intf->dev, &dev_attr_output3); device_create_file(&intf->dev, &dev_attr_output4); } - if (ifkit->outputs >= 8) { + if (ifkit->outputs == 8) { device_create_file(&intf->dev, &dev_attr_output5); device_create_file(&intf->dev, &dev_attr_output6); device_create_file(&intf->dev, &dev_attr_output7); device_create_file(&intf->dev, &dev_attr_output8); } - if (ifkit->outputs == 16) { - device_create_file(&intf->dev, &dev_attr_output9); - device_create_file(&intf->dev, &dev_attr_output10); - device_create_file(&intf->dev, &dev_attr_output11); - device_create_file(&intf->dev, &dev_attr_output12); - device_create_file(&intf->dev, &dev_attr_output13); - device_create_file(&intf->dev, &dev_attr_output14); - device_create_file(&intf->dev, &dev_attr_output15); - device_create_file(&intf->dev, &dev_attr_output16); - } if (ifkit->inputs >= 4) { device_create_file(&intf->dev, &dev_attr_input1); @@ -548,22 +457,12 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic device_create_file(&intf->dev, &dev_attr_input3); device_create_file(&intf->dev, &dev_attr_input4); } - if (ifkit->inputs >= 8) { + if (ifkit->inputs == 8) { device_create_file(&intf->dev, &dev_attr_input5); device_create_file(&intf->dev, &dev_attr_input6); device_create_file(&intf->dev, &dev_attr_input7); device_create_file(&intf->dev, &dev_attr_input8); } - if (ifkit->inputs == 16) { - device_create_file(&intf->dev, &dev_attr_input9); - device_create_file(&intf->dev, &dev_attr_input10); - device_create_file(&intf->dev, &dev_attr_input11); - device_create_file(&intf->dev, &dev_attr_input12); - device_create_file(&intf->dev, &dev_attr_input13); - device_create_file(&intf->dev, &dev_attr_input14); - device_create_file(&intf->dev, &dev_attr_input15); - device_create_file(&intf->dev, &dev_attr_input16); - } if (ifkit->sensors >= 4) { device_create_file(&intf->dev, &dev_attr_sensor1); @@ -576,8 +475,9 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic device_create_file(&intf->dev, &dev_attr_sensor6); device_create_file(&intf->dev, &dev_attr_sensor7); } - if (ifkit->sensors == 8) + if (ifkit->sensors == 8) { device_create_file(&intf->dev, &dev_attr_sensor8); + } if (ifkit->has_lcd) device_create_file(&intf->dev, &dev_attr_lcd); @@ -586,56 +486,29 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic ifkit->sensors, ifkit->inputs, ifkit->outputs); return 0; - -out: - if (kit) { - if (kit->irq) - usb_free_urb(kit->irq); - if (kit->data) - usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); - kfree(kit); - } - - return rc; } static void interfacekit_disconnect(struct usb_interface *interface) { - struct interfacekit *kit; + struct phidget_interfacekit *kit; kit = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); if (!kit) return; - usb_kill_urb(kit->irq); - usb_free_urb(kit->irq); - usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma); - - cancel_delayed_work(&kit->do_notify); - if (kit->ifkit->outputs >= 4) { device_remove_file(&interface->dev, &dev_attr_output1); device_remove_file(&interface->dev, &dev_attr_output2); device_remove_file(&interface->dev, &dev_attr_output3); device_remove_file(&interface->dev, &dev_attr_output4); } - if (kit->ifkit->outputs >= 8) { + if (kit->ifkit->outputs == 8) { device_remove_file(&interface->dev, &dev_attr_output5); device_remove_file(&interface->dev, &dev_attr_output6); device_remove_file(&interface->dev, &dev_attr_output7); device_remove_file(&interface->dev, &dev_attr_output8); } - if (kit->ifkit->outputs == 16) { - device_remove_file(&interface->dev, &dev_attr_output9); - device_remove_file(&interface->dev, &dev_attr_output10); - device_remove_file(&interface->dev, &dev_attr_output11); - device_remove_file(&interface->dev, &dev_attr_output12); - device_remove_file(&interface->dev, &dev_attr_output13); - device_remove_file(&interface->dev, &dev_attr_output14); - device_remove_file(&interface->dev, &dev_attr_output15); - device_remove_file(&interface->dev, &dev_attr_output16); - } if (kit->ifkit->inputs >= 4) { device_remove_file(&interface->dev, &dev_attr_input1); @@ -643,22 +516,12 @@ static void interfacekit_disconnect(struct usb_interface *interface) device_remove_file(&interface->dev, &dev_attr_input3); device_remove_file(&interface->dev, &dev_attr_input4); } - if (kit->ifkit->inputs >= 8) { + if (kit->ifkit->inputs == 8) { device_remove_file(&interface->dev, &dev_attr_input5); device_remove_file(&interface->dev, &dev_attr_input6); device_remove_file(&interface->dev, &dev_attr_input7); device_remove_file(&interface->dev, &dev_attr_input8); } - if (kit->ifkit->inputs == 16) { - device_remove_file(&interface->dev, &dev_attr_input9); - device_remove_file(&interface->dev, &dev_attr_input10); - device_remove_file(&interface->dev, &dev_attr_input11); - device_remove_file(&interface->dev, &dev_attr_input12); - device_remove_file(&interface->dev, &dev_attr_input13); - device_remove_file(&interface->dev, &dev_attr_input14); - device_remove_file(&interface->dev, &dev_attr_input15); - device_remove_file(&interface->dev, &dev_attr_input16); - } if (kit->ifkit->sensors >= 4) { device_remove_file(&interface->dev, &dev_attr_sensor1); @@ -671,15 +534,19 @@ static void interfacekit_disconnect(struct usb_interface *interface) device_remove_file(&interface->dev, &dev_attr_sensor6); device_remove_file(&interface->dev, &dev_attr_sensor7); } - if (kit->ifkit->sensors == 8) + if (kit->ifkit->sensors == 8) { device_remove_file(&interface->dev, &dev_attr_sensor8); - + } if (kit->ifkit->has_lcd) device_remove_file(&interface->dev, &dev_attr_lcd); dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); + usb_kill_urb(kit->irq); + usb_free_urb(kit->irq); + usb_buffer_free(kit->udev, 8, kit->data, kit->data_dma); + usb_put_dev(kit->udev); kfree(kit); } diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb.c b/trunk/drivers/usb/misc/sisusbvga/sisusb.c index 738bd7c7451f..196c8794a73c 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb.c @@ -37,7 +37,6 @@ */ #include -#include #include #include #include @@ -53,7 +52,6 @@ #include #include "sisusb.h" -#include "sisusb_init.h" #ifdef INCL_SISUSB_CON #include @@ -64,6 +62,36 @@ /* Forward declarations / clean-up routines */ #ifdef INCL_SISUSB_CON +int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); +int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data); +int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data); +int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data); +int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand, u8 myor); +int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor); +int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand); + +int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); +int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data); +int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data); +int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data); +int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, + u32 dest, int length, size_t *bytes_written); + +int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); + +extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); +extern int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); + +extern void sisusb_init_concode(void); +extern int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); +extern void sisusb_console_exit(struct sisusb_usb_data *sisusb); + +extern void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); + +extern int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, + u8 *arg, int cmapsz, int ch512, int dorecalc, + struct vc_data *c, int fh, int uplock); + static int sisusb_first_vc = 0; static int sisusb_last_vc = 0; module_param_named(first, sisusb_first_vc, int, 0); @@ -74,7 +102,7 @@ MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES static struct usb_driver sisusb_driver; -DEFINE_MUTEX(disconnect_mutex); +DECLARE_MUTEX(disconnect_sem); static void sisusb_free_buffers(struct sisusb_usb_data *sisusb) @@ -1331,6 +1359,9 @@ sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data) } #endif +#ifndef INCL_SISUSB_CON +static +#endif int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data) { @@ -1340,6 +1371,9 @@ sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data) return ret; } +#ifndef INCL_SISUSB_CON +static +#endif int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data) { @@ -1349,6 +1383,9 @@ sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data) return ret; } +#ifndef INCL_SISUSB_CON +static +#endif int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand, u8 myor) @@ -1378,12 +1415,18 @@ sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx, return ret; } +#ifndef INCL_SISUSB_CON +static +#endif int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor) { return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor)); } +#ifndef INCL_SISUSB_CON +static +#endif int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand) { @@ -1405,8 +1448,6 @@ sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); } -#if 0 - int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data) { @@ -1419,8 +1460,6 @@ sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data) return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); } -#endif /* 0 */ - int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, u32 dest, int length, size_t *bytes_written) @@ -2513,39 +2552,39 @@ sisusb_open(struct inode *inode, struct file *file) struct usb_interface *interface; int subminor = iminor(inode); - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { printk(KERN_ERR "sisusb[%d]: Failed to find interface\n", subminor); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } if (!(sisusb = usb_get_intfdata(interface))) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } - mutex_lock(&sisusb->lock); + down(&sisusb->lock); if (!sisusb->present || !sisusb->ready) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return -ENODEV; } if (sisusb->isopen) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return -EBUSY; } if (!sisusb->devinit) { if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { if (sisusb_init_gfxdevice(sisusb, 0)) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); printk(KERN_ERR "sisusbvga[%d]: Failed to initialize " "device\n", @@ -2553,8 +2592,8 @@ sisusb_open(struct inode *inode, struct file *file) return -EIO; } } else { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); printk(KERN_ERR "sisusbvga[%d]: Device not attached to " "USB 2.0 hub\n", @@ -2570,9 +2609,9 @@ sisusb_open(struct inode *inode, struct file *file) file->private_data = sisusb; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return 0; } @@ -2603,14 +2642,14 @@ sisusb_release(struct inode *inode, struct file *file) struct sisusb_usb_data *sisusb; int myminor; - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return -ENODEV; } - mutex_lock(&sisusb->lock); + down(&sisusb->lock); if (sisusb->present) { /* Wait for all URBs to finish if device still present */ @@ -2623,12 +2662,12 @@ sisusb_release(struct inode *inode, struct file *file) sisusb->isopen = 0; file->private_data = NULL; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); /* decrement the usage count on our device */ kref_put(&sisusb->kref, sisusb_delete); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return 0; } @@ -2646,11 +2685,11 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) return -ENODEV; - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Sanity check */ if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -ENODEV; } @@ -2745,7 +2784,7 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) { if (count != 4) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EINVAL; } @@ -2769,7 +2808,7 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) (*ppos) += bytes_read; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return errno ? errno : bytes_read; } @@ -2788,11 +2827,11 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count, if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) return -ENODEV; - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Sanity check */ if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -ENODEV; } @@ -2891,7 +2930,7 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count, (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + SISUSB_PCI_PCONFSIZE) { if (count != 4) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EINVAL; } @@ -2917,7 +2956,7 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count, (*ppos) += bytes_written; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return errno ? errno : bytes_written; } @@ -2931,11 +2970,11 @@ sisusb_lseek(struct file *file, loff_t offset, int orig) if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) return -ENODEV; - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Sanity check */ if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -ENODEV; } @@ -2955,7 +2994,7 @@ sisusb_lseek(struct file *file, loff_t offset, int orig) ret = -EINVAL; } - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return ret; } @@ -3097,7 +3136,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) return -ENODEV; - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Sanity check */ if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { @@ -3154,7 +3193,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } err_out: - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return retval; } @@ -3219,7 +3258,7 @@ static int sisusb_probe(struct usb_interface *intf, } kref_init(&sisusb->kref); - mutex_init(&(sisusb->lock)); + init_MUTEX(&(sisusb->lock)); /* Register device */ if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { @@ -3390,9 +3429,9 @@ static void sisusb_disconnect(struct usb_interface *intf) * protect all other routines from the disconnect * case, not the other way round. */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Wait for all URBs to complete and kill them in case (MUST do) */ if (!sisusb_wait_all_out_complete(sisusb)) @@ -3423,12 +3462,12 @@ static void sisusb_disconnect(struct usb_interface *intf) sisusb->present = 0; sisusb->ready = 0; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); /* decrement our usage count */ kref_put(&sisusb->kref, sisusb_delete); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor); } diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb.h b/trunk/drivers/usb/misc/sisusbvga/sisusb.h index 8e1120a64806..a716825d1f9b 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb.h +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb.h @@ -41,8 +41,6 @@ #define SISUSB_NEW_CONFIG_COMPAT #endif -#include - /* For older kernels, support for text consoles is by default * off. To ensable text console support, change the following: */ @@ -62,9 +60,11 @@ #define INCL_SISUSB_CON 1 #endif +#ifdef INCL_SISUSB_CON #include #include #include "sisusb_struct.h" +#endif /* USB related */ @@ -116,7 +116,7 @@ struct sisusb_usb_data { struct usb_interface *interface; struct kref kref; wait_queue_head_t wait_q; /* for syncind and timeouts */ - struct mutex lock; /* general race avoidance */ + struct semaphore lock; /* general race avoidance */ unsigned int ifnum; /* interface number of the USB device */ int minor; /* minor (for logging clarity) */ int isopen; /* !=0 if open */ diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c b/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c index fb48feca8353..be5c1a25ae21 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -48,7 +48,6 @@ */ #include -#include #include #include #include @@ -70,9 +69,27 @@ #include #include "sisusb.h" -#include "sisusb_init.h" #ifdef INCL_SISUSB_CON +extern int sisusb_setreg(struct sisusb_usb_data *, int, u8); +extern int sisusb_getreg(struct sisusb_usb_data *, int, u8 *); +extern int sisusb_setidxreg(struct sisusb_usb_data *, int, u8, u8); +extern int sisusb_getidxreg(struct sisusb_usb_data *, int, u8, u8 *); +extern int sisusb_setidxregor(struct sisusb_usb_data *, int, u8, u8); +extern int sisusb_setidxregand(struct sisusb_usb_data *, int, u8, u8); +extern int sisusb_setidxregandor(struct sisusb_usb_data *, int, u8, u8, u8); + +extern int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); +extern int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data); +extern int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data); +extern int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data); +extern int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, + u32 dest, int length, size_t *bytes_written); + +extern void sisusb_delete(struct kref *kref); +extern int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); + +extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); #define sisusbcon_writew(val, addr) (*(addr) = (val)) #define sisusbcon_readw(addr) (*(addr)) @@ -85,6 +102,8 @@ static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES]; /* Forward declaration */ static const struct consw sisusb_con; +extern struct semaphore disconnect_sem; + static inline void sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) { @@ -175,11 +194,11 @@ sisusb_get_sisusb_lock_and_check(unsigned short console) if (!(sisusb = sisusb_get_sisusb(console))) return NULL; - mutex_lock(&sisusb->lock); + down(&sisusb->lock); if (!sisusb_sisusb_valid(sisusb) || !sisusb->havethisconsole[console]) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return NULL; } @@ -217,18 +236,18 @@ sisusbcon_init(struct vc_data *c, int init) * are set up/restored. */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); if (!(sisusb = sisusb_get_sisusb(c->vc_num))) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return; } - mutex_lock(&sisusb->lock); + down(&sisusb->lock); if (!sisusb_sisusb_valid(sisusb)) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return; } @@ -265,9 +284,9 @@ sisusbcon_init(struct vc_data *c, int init) if (!*c->vc_uni_pagedir_loc) con_set_default_unimap(c); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); if (init) { c->vc_cols = cols; @@ -287,14 +306,14 @@ sisusbcon_deinit(struct vc_data *c) * and others, ie not under our control. */ - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); if (!(sisusb = sisusb_get_sisusb(c->vc_num))) { - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); return; } - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Clear ourselves in mysisusbs */ mysisusbs[c->vc_num] = NULL; @@ -313,12 +332,12 @@ sisusbcon_deinit(struct vc_data *c) } } - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); /* decrement the usage count on our sisusb */ kref_put(&sisusb->kref, sisusb_delete); - mutex_unlock(&disconnect_mutex); + up(&disconnect_sem); } /* interface routine */ @@ -398,7 +417,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) #endif if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -406,7 +425,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), (u32)SISUSB_HADDR(x, y), 2, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } /* Interface routine */ @@ -434,14 +453,14 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, sisusbcon_writew(sisusbcon_readw(s++), dest++); if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), (u32)SISUSB_HADDR(x, y), count * 2, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } /* Interface routine */ @@ -485,7 +504,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) } if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -495,7 +514,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), (u32)SISUSB_HADDR(x, y), length, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } /* Interface routine */ @@ -557,7 +576,7 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, #endif if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -567,7 +586,7 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), (u32)SISUSB_HADDR(dx, dy), length, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } /* interface routine */ @@ -590,7 +609,7 @@ sisusbcon_switch(struct vc_data *c) /* Don't write to screen if in gfx mode */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -599,7 +618,7 @@ sisusbcon_switch(struct vc_data *c) * as origin. */ if (c->vc_origin == (unsigned long)c->vc_screenbuf) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n"); return 0; } @@ -616,7 +635,7 @@ sisusbcon_switch(struct vc_data *c) (u32)SISUSB_HADDR(0, 0), length, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -638,7 +657,7 @@ sisusbcon_save_screen(struct vc_data *c) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -650,7 +669,7 @@ sisusbcon_save_screen(struct vc_data *c) sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } /* interface routine */ @@ -671,7 +690,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EINVAL; } @@ -686,7 +705,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table) break; } - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -709,7 +728,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) sisusb->is_gfx = blank ? 1 : 0; if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -758,7 +777,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) cr63 = 0x40; break; default: - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EINVAL; } @@ -769,7 +788,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) } - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return ret; } @@ -790,7 +809,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -830,7 +849,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines) sisusbcon_set_start_address(sisusb, c); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 1; } @@ -848,7 +867,7 @@ sisusbcon_cursor(struct vc_data *c, int mode) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -860,7 +879,7 @@ sisusbcon_cursor(struct vc_data *c, int mode) if (mode == CM_ERASE) { sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20); sisusb->sisusb_cursor_size_to = -1; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return; } @@ -900,7 +919,7 @@ sisusbcon_cursor(struct vc_data *c, int mode) sisusb->sisusb_cursor_size_to = to; } - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); } static int @@ -942,7 +961,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), (u32)SISUSB_HADDR(0, t), length, &written); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 1; } @@ -975,7 +994,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb)) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -1065,7 +1084,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines) c->vc_pos = c->vc_pos - oldorigin + c->vc_origin; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 1; } @@ -1087,7 +1106,7 @@ sisusbcon_set_origin(struct vc_data *c) /* sisusb->lock is down */ if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -1097,7 +1116,7 @@ sisusbcon_set_origin(struct vc_data *c) sisusb->con_rolled_over = 0; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 1; } @@ -1114,7 +1133,7 @@ sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows) fh = sisusb->current_font_height; - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); /* We are quite unflexible as regards resizing. The vt code * handles sizes where the line length isn't equal the pitch @@ -1148,7 +1167,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, if ((slot != 0 && slot != 2) || !fh) { if (uplock) - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EINVAL; } @@ -1308,7 +1327,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, } if (uplock) - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); if (dorecalc && c) { int i, rows = c->vc_scan_lines / fh; @@ -1332,7 +1351,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, font_op_error: if (uplock) - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -EIO; } @@ -1398,19 +1417,19 @@ sisusbcon_font_get(struct vc_data *c, struct console_font *font) font->charcount = 256; if (!font->data) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } if (!sisusb->font_backup) { - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return -ENODEV; } /* Copy 256 chars only, like vgacon */ memcpy(font->data, sisusb->font_backup, 256 * 32); - mutex_unlock(&sisusb->lock); + up(&sisusb->lock); return 0; } @@ -1467,7 +1486,7 @@ static int sisusbdummycon_dummy(void) #define SISUSBCONDUMMY (void *)sisusbdummycon_dummy -static const struct consw sisusb_dummy_con = { +const struct consw sisusb_dummy_con = { .owner = THIS_MODULE, .con_startup = sisusbdummycon_startup, .con_init = sisusbdummycon_init, @@ -1493,14 +1512,14 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) { int i, ret, minor = sisusb->minor; - mutex_lock(&disconnect_mutex); + down(&disconnect_sem); - mutex_lock(&sisusb->lock); + down(&sisusb->lock); /* Erm.. that should not happen */ if (sisusb->haveconsole || !sisusb->SiS_Pr) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return 1; } @@ -1510,15 +1529,15 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) if (first > last || first > MAX_NR_CONSOLES || last > MAX_NR_CONSOLES) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return 1; } /* If gfxcore not initialized or no consoles given, quit graciously */ if (!sisusb->gfxinit || first < 1 || last < 1) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); return 0; } @@ -1528,8 +1547,8 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) /* Set up text mode (and upload default font) */ if (sisusb_reset_text_mode(sisusb, 1)) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); printk(KERN_ERR "sisusbvga[%d]: Failed to set up text mode\n", minor); @@ -1552,16 +1571,16 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) /* Allocate screen buffer */ if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); printk(KERN_ERR "sisusbvga[%d]: Failed to allocate screen buffer\n", minor); return 1; } - mutex_unlock(&sisusb->lock); - mutex_unlock(&disconnect_mutex); + up(&sisusb->lock); + up(&disconnect_sem); /* Now grab the desired console(s) */ ret = take_over_console(&sisusb_con, first - 1, last - 1, 0); diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb_init.c b/trunk/drivers/usb/misc/sisusbvga/sisusb_init.c index 968f0d38cff7..044fa4482f9f 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -74,7 +74,6 @@ SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) /* HELPER: Get ModeID */ /*********************************************/ -#if 0 unsigned short SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) { @@ -158,7 +157,6 @@ SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) return ModeIndex; } -#endif /* 0 */ /*********************************************/ /* HELPER: SetReg, GetReg */ @@ -235,7 +233,7 @@ SiS_DisplayOn(struct SiS_Private *SiS_Pr) /* HELPER: Init Port Addresses */ /*********************************************/ -static void +void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) { SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb_init.h b/trunk/drivers/usb/misc/sisusbvga/sisusb_init.h index f05f83268af4..5b11577835c8 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb_init.h +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb_init.h @@ -690,7 +690,7 @@ static const struct SiS_CRT1Table SiSUSB_CRT1Table[] = 0x41}} /* 0x54 */ }; -static const struct SiS_VCLKData SiSUSB_VCLKData[] = +static struct SiS_VCLKData SiSUSB_VCLKData[] = { { 0x1b,0xe1, 25}, /* 0x00 */ { 0x4e,0xe4, 28}, /* 0x01 */ @@ -808,8 +808,8 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] = { 0x2b,0xc2, 35} /* 0x71 768@576@60 */ }; -extern struct mutex disconnect_mutex; - +void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr); +unsigned short SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth); int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); @@ -826,19 +826,5 @@ extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand); -void sisusb_delete(struct kref *kref); -int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); -int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data); -int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, - u32 dest, int length, size_t *bytes_written); -int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); -int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, - u8 *arg, int cmapsz, int ch512, int dorecalc, - struct vc_data *c, int fh, int uplock); -void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); -int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); -void sisusb_console_exit(struct sisusb_usb_data *sisusb); -void sisusb_init_concode(void); - #endif diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb_struct.h b/trunk/drivers/usb/misc/sisusbvga/sisusb_struct.h index f325ecb29a61..94edd4726c42 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb_struct.h +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb_struct.h @@ -161,7 +161,7 @@ struct SiS_Private const struct SiS_Ext *SiS_EModeIDTable; const struct SiS_Ext2 *SiS_RefIndex; const struct SiS_CRT1Table *SiS_CRT1Table; - const struct SiS_VCLKData *SiS_VCLKData; + struct SiS_VCLKData *SiS_VCLKData; const struct SiS_ModeResInfo *SiS_ModeResInfo; }; diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 81ba14c73dc7..ccc5e8238bd8 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -802,9 +802,7 @@ static void ctrl_complete (struct urb *urb, struct pt_regs *regs) if (u == urb || !u->dev) continue; - spin_unlock(&ctx->lock); status = usb_unlink_urb (u); - spin_lock(&ctx->lock); switch (status) { case -EINPROGRESS: case -EBUSY: @@ -1337,9 +1335,7 @@ struct iso_context { unsigned pending; spinlock_t lock; struct completion done; - int submit_error; unsigned long errors; - unsigned long packet_count; struct usbtest_dev *dev; }; @@ -1350,14 +1346,10 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs) spin_lock(&ctx->lock); ctx->count--; - ctx->packet_count += urb->number_of_packets; if (urb->error_count > 0) ctx->errors += urb->error_count; - else if (urb->status != 0) - ctx->errors += urb->number_of_packets; - if (urb->status == 0 && ctx->count > (ctx->pending - 1) - && !ctx->submit_error) { + if (urb->status == 0 && ctx->count > (ctx->pending - 1)) { int status = usb_submit_urb (urb, GFP_ATOMIC); switch (status) { case 0: @@ -1368,8 +1360,6 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs) status); /* FALLTHROUGH */ case -ENODEV: /* disconnected */ - case -ESHUTDOWN: /* endpoint disabled */ - ctx->submit_error = 1; break; } } @@ -1379,8 +1369,8 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs) if (ctx->pending == 0) { if (ctx->errors) dev_dbg (&ctx->dev->intf->dev, - "iso test, %lu errors out of %lu\n", - ctx->errors, ctx->packet_count); + "iso test, %lu errors\n", + ctx->errors); complete (&ctx->done); } done: @@ -1441,14 +1431,15 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, struct usb_device *udev; unsigned i; unsigned long packets = 0; - int status = 0; + int status; struct urb *urbs[10]; /* FIXME no limit */ if (param->sglen > 10) return -EDOM; - memset(&context, 0, sizeof context); context.count = param->iterations * param->sglen; + context.pending = param->sglen; + context.errors = 0; context.dev = dev; init_completion (&context.done); spin_lock_init (&context.lock); @@ -1480,7 +1471,6 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, spin_lock_irq (&context.lock); for (i = 0; i < param->sglen; i++) { - ++context.pending; status = usb_submit_urb (urbs [i], SLAB_ATOMIC); if (status < 0) { ERROR (dev, "submit iso[%d], error %d\n", i, status); @@ -1491,26 +1481,12 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, simple_free_urb (urbs [i]); context.pending--; - context.submit_error = 1; - break; } } spin_unlock_irq (&context.lock); wait_for_completion (&context.done); - - /* - * Isochronous transfers are expected to fail sometimes. As an - * arbitrary limit, we will report an error if any submissions - * fail or if the transfer failure rate is > 10%. - */ - if (status != 0) - ; - else if (context.submit_error) - status = -EACCES; - else if (context.errors > context.packet_count / 10) - status = -EIO; - return status; + return 0; fail: for (i = 0; i < param->sglen; i++) { diff --git a/trunk/drivers/usb/mon/mon_dma.c b/trunk/drivers/usb/mon/mon_dma.c index ddcfc01e77a0..0a1367b760a0 100644 --- a/trunk/drivers/usb/mon/mon_dma.c +++ b/trunk/drivers/usb/mon/mon_dma.c @@ -13,10 +13,7 @@ #include /* Only needed for declarations in usb_mon.h */ #include "usb_mon.h" -/* - * PC-compatibles, are, fortunately, sufficiently cache-coherent for this. - */ -#if defined(__i386__) || defined(__x86_64__) /* CONFIG_ARCH_I386 doesn't exit */ +#ifdef __i386__ /* CONFIG_ARCH_I386 does not exit */ #define MON_HAS_UNMAP 1 #define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT) diff --git a/trunk/drivers/usb/mon/mon_main.c b/trunk/drivers/usb/mon/mon_main.c index 275a66f83058..6ecc27302211 100644 --- a/trunk/drivers/usb/mon/mon_main.c +++ b/trunk/drivers/usb/mon/mon_main.c @@ -97,7 +97,6 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) if (mbus->nreaders == 0) goto out_locked; - mbus->cnt_events++; list_for_each (pos, &mbus->r_list) { r = list_entry(pos, struct mon_reader, r_link); r->rnf_submit(r->r_data, urb); @@ -114,32 +113,20 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) /* */ -static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) +static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int err) { struct mon_bus *mbus; - unsigned long flags; - struct list_head *pos; - struct mon_reader *r; mbus = ubus->mon_bus; if (mbus == NULL) goto out_unlocked; - spin_lock_irqsave(&mbus->lock, flags); - if (mbus->nreaders == 0) - goto out_locked; - - mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); - r->rnf_error(r->r_data, urb, error); - } + /* + * XXX Capture the error code and the 'E' event. + */ - spin_unlock_irqrestore(&mbus->lock, flags); return; -out_locked: - spin_unlock_irqrestore(&mbus->lock, flags); out_unlocked: return; } @@ -165,7 +152,6 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) } spin_lock_irqsave(&mbus->lock, flags); - mbus->cnt_events++; list_for_each (pos, &mbus->r_list) { r = list_entry(pos, struct mon_reader, r_link); r->rnf_complete(r->r_data, urb); @@ -177,6 +163,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) /* * Stop monitoring. + * Obviously this must be well locked, so no need to play with mb's. */ static void mon_stop(struct mon_bus *mbus) { diff --git a/trunk/drivers/usb/mon/mon_stat.c b/trunk/drivers/usb/mon/mon_stat.c index 1fe01d994a79..6e4b165d070a 100644 --- a/trunk/drivers/usb/mon/mon_stat.c +++ b/trunk/drivers/usb/mon/mon_stat.c @@ -31,8 +31,8 @@ static int mon_stat_open(struct inode *inode, struct file *file) mbus = inode->u.generic_ip; sp->slen = snprintf(sp->str, STAT_BUF_SIZE, - "nreaders %d events %u text_lost %u\n", - mbus->nreaders, mbus->cnt_events, mbus->cnt_text_lost); + "nreaders %d text_lost %u\n", + mbus->nreaders, mbus->cnt_text_lost); file->private_data = sp; return 0; diff --git a/trunk/drivers/usb/mon/mon_text.c b/trunk/drivers/usb/mon/mon_text.c index e02c1a30c4cd..ac043ec2b8dc 100644 --- a/trunk/drivers/usb/mon/mon_text.c +++ b/trunk/drivers/usb/mon/mon_text.c @@ -26,13 +26,10 @@ /* * This limit exists to prevent OOMs when the user process stops reading. - * If usbmon were available to unprivileged processes, it might be open - * to a local DoS. But we have to keep to root in order to prevent - * password sniffing from HID devices. */ -#define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text)) +#define EVENT_MAX 25 -#define PRINTF_DFL 160 +#define PRINTF_DFL 130 struct mon_event_text { struct list_head e_link; @@ -114,7 +111,7 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, * number of corner cases, but it seems that the following is * more or less safe. * - * We do not even try to look at transfer_buffer, because it can + * We do not even try to look transfer_buffer, because it can * contain non-NULL garbage in case the upper level promised to * set DMA for the HCD. */ @@ -182,32 +179,6 @@ static void mon_text_complete(void *data, struct urb *urb) mon_text_event(rp, urb, 'C'); } -static void mon_text_error(void *data, struct urb *urb, int error) -{ - struct mon_reader_text *rp = data; - struct mon_event_text *ep; - - if (rp->nevents >= EVENT_MAX || - (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) { - rp->r.m_bus->cnt_text_lost++; - return; - } - - ep->type = 'E'; - ep->pipe = urb->pipe; - ep->id = (unsigned long) urb; - ep->tstamp = 0; - ep->length = 0; - ep->status = error; - - ep->setup_flag = '-'; - ep->data_flag = 'E'; - - rp->nevents++; - list_add_tail(&ep->e_link, &rp->e_list); - wake_up(&rp->wait); -} - /* * Fetch next event from the circular buffer. */ @@ -261,7 +232,6 @@ static int mon_text_open(struct inode *inode, struct file *file) rp->r.m_bus = mbus; rp->r.r_data = rp; rp->r.rnf_submit = mon_text_submit; - rp->r.rnf_error = mon_text_error; rp->r.rnf_complete = mon_text_complete; snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, diff --git a/trunk/drivers/usb/mon/usb_mon.h b/trunk/drivers/usb/mon/usb_mon.h index 33678c24ebee..8e0613c350cc 100644 --- a/trunk/drivers/usb/mon/usb_mon.h +++ b/trunk/drivers/usb/mon/usb_mon.h @@ -27,7 +27,6 @@ struct mon_bus { struct kref ref; /* Under mon_lock */ /* Stats */ - unsigned int cnt_events; unsigned int cnt_text_lost; }; @@ -40,7 +39,6 @@ struct mon_reader { void *r_data; /* Use container_of instead? */ void (*rnf_submit)(void *data, struct urb *urb); - void (*rnf_error)(void *data, struct urb *urb, int error); void (*rnf_complete)(void *data, struct urb *urb); }; diff --git a/trunk/drivers/usb/net/asix.c b/trunk/drivers/usb/net/asix.c index 37111acec875..12b599a0b539 100644 --- a/trunk/drivers/usb/net/asix.c +++ b/trunk/drivers/usb/net/asix.c @@ -911,10 +911,6 @@ static const struct usb_device_id products [] = { // ASIX AX88772 10/100 USB_DEVICE (0x0b95, 0x7720), .driver_info = (unsigned long) &ax88772_info, -}, { - // ASIX AX88178 10/100/1000 - USB_DEVICE (0x0b95, 0x1780), - .driver_info = (unsigned long) &ax88772_info, }, { // Linksys USB200M Rev 2 USB_DEVICE (0x13b1, 0x0018), diff --git a/trunk/drivers/usb/net/cdc_ether.c b/trunk/drivers/usb/net/cdc_ether.c index efd195b5912c..63f1f3ba8e0b 100644 --- a/trunk/drivers/usb/net/cdc_ether.c +++ b/trunk/drivers/usb/net/cdc_ether.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "usbnet.h" @@ -455,18 +455,6 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, -/* Olympus has some models with a Zaurus-compatible option. - * R-1000 uses a FreeScale i.MXL cpu (ARMv4T) - */ -{ - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, - .idVendor = 0x07B4, - .idProduct = 0x0F02, /* R-1000 */ - ZAURUS_MASTER_INTERFACE, - .driver_info = 0, -}, - /* * WHITELIST!!! * diff --git a/trunk/drivers/usb/net/pegasus.c b/trunk/drivers/usb/net/pegasus.c index ab21f960d255..7683926a1b6f 100644 --- a/trunk/drivers/usb/net/pegasus.c +++ b/trunk/drivers/usb/net/pegasus.c @@ -163,8 +163,6 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, /* using ATOMIC, we'd never wake up if we slept */ if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) - netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", __FUNCTION__, ret); @@ -219,8 +217,6 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, set_current_state(TASK_UNINTERRUPTIBLE); if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) - netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", __FUNCTION__, ret); @@ -272,8 +268,6 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) set_current_state(TASK_UNINTERRUPTIBLE); if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) - netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", __FUNCTION__, ret); @@ -304,13 +298,10 @@ static int update_eth_regs_async(pegasus_t * pegasus) (char *) &pegasus->dr, pegasus->eth_regs, 3, ctrl_callback, pegasus); - if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) - netif_device_detach(pegasus->net); + if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", __FUNCTION__, ret); - } return ret; } @@ -701,10 +692,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); - rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); - if (rx_status == -ENODEV) - netif_device_detach(pegasus->net); - else if (rx_status) { + if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; goto tl_sched; } else { @@ -721,7 +709,6 @@ static void rx_fixup(unsigned long data) { pegasus_t *pegasus; unsigned long flags; - int status; pegasus = (pegasus_t *) data; if (pegasus->flags & PEGASUS_UNPLUG) @@ -747,10 +734,7 @@ static void rx_fixup(unsigned long data) pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); try_again: - status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); - if (status == -ENODEV) - netif_device_detach(pegasus->net); - else if (status) { + if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; tasklet_schedule(&pegasus->rx_tl); } else { @@ -852,8 +836,6 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs) } status = usb_submit_urb(urb, SLAB_ATOMIC); - if (status == -ENODEV) - netif_device_detach(pegasus->net); if (status && netif_msg_timer(pegasus)) printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", net->name, status); @@ -892,7 +874,6 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) /* cleanup should already have been scheduled */ break; case -ENODEV: /* disconnect() upcoming */ - netif_device_detach(pegasus->net); break; default: pegasus->stats.tx_errors++; @@ -1018,8 +999,6 @@ static int pegasus_open(struct net_device *net) pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { - if (res == -ENODEV) - netif_device_detach(pegasus->net); if (netif_msg_ifup(pegasus)) pr_debug("%s: failed rx_urb, %d", net->name, res); goto exit; @@ -1030,8 +1009,6 @@ static int pegasus_open(struct net_device *net) pegasus->intr_buff, sizeof (pegasus->intr_buff), intr_callback, pegasus, pegasus->intr_interval); if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { - if (res == -ENODEV) - netif_device_detach(pegasus->net); if (netif_msg_ifup(pegasus)) pr_debug("%s: failed intr_urb, %d\n", net->name, res); usb_kill_urb(pegasus->rx_urb); diff --git a/trunk/drivers/usb/net/rndis_host.c b/trunk/drivers/usb/net/rndis_host.c index f551546d7521..94ddfe16fdda 100644 --- a/trunk/drivers/usb/net/rndis_host.c +++ b/trunk/drivers/usb/net/rndis_host.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "usbnet.h" diff --git a/trunk/drivers/usb/net/zaurus.c b/trunk/drivers/usb/net/zaurus.c index 813e470d0600..f7ac9d6b9856 100644 --- a/trunk/drivers/usb/net/zaurus.c +++ b/trunk/drivers/usb/net/zaurus.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "usbnet.h" @@ -109,7 +109,7 @@ static const struct driver_info zaurus_sl5x00_info = { .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, - .tx_fixup = zaurus_tx_fixup, + .tx_fixup = zaurus_tx_fixup, }; #define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info) @@ -119,7 +119,7 @@ static const struct driver_info zaurus_pxa_info = { .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, - .tx_fixup = zaurus_tx_fixup, + .tx_fixup = zaurus_tx_fixup, }; #define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info) @@ -129,7 +129,7 @@ static const struct driver_info olympus_mxl_info = { .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, - .tx_fixup = zaurus_tx_fixup, + .tx_fixup = zaurus_tx_fixup, }; #define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info) @@ -228,11 +228,6 @@ static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf) detail->bDetailData[2]); goto bad_desc; } - - /* same extra framing as for non-BLAN mode */ - dev->net->hard_header_len += 6; - dev->rx_urb_size = dev->net->hard_header_len - + dev->net->mtu; break; } next_desc: @@ -263,7 +258,7 @@ static const struct driver_info bogus_mdlm_info = { .description = "pseudo-MDLM (BLAN) device", .flags = FLAG_FRAMING_Z, .check_connect = always_connected, - .tx_fixup = zaurus_tx_fixup, + .tx_fixup = zaurus_tx_fixup, .bind = blan_mdlm_bind, }; @@ -372,13 +367,13 @@ static struct usb_driver zaurus_driver = { static int __init zaurus_init(void) { - return usb_register(&zaurus_driver); + return usb_register(&zaurus_driver); } module_init(zaurus_init); static void __exit zaurus_exit(void) { - usb_deregister(&zaurus_driver); + usb_deregister(&zaurus_driver); } module_exit(zaurus_exit); diff --git a/trunk/drivers/usb/serial/Kconfig b/trunk/drivers/usb/serial/Kconfig index 8bd44fda5eaf..5c60be521561 100644 --- a/trunk/drivers/usb/serial/Kconfig +++ b/trunk/drivers/usb/serial/Kconfig @@ -417,7 +417,7 @@ config USB_SERIAL_MCT_U232 Magic Control Technology Corp. (U232 is one of the model numbers). This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB - BAY, Belkin F5U109, and Belkin F5U409 devices. + BAY devices. To compile this driver as a module, choose M here: the module will be called mct_u232. @@ -491,22 +491,16 @@ config USB_SERIAL_XIRCOM module will be called keyspan_pda. config USB_SERIAL_OPTION - tristate "USB driver for GSM modems" - depends on USB_SERIAL + tristate "USB Option PCMCIA serial driver" + depends on USB_SERIAL && USB_OHCI_HCD && PCCARD help - Say Y here if you have an "Option" GSM PCMCIA card - (or an OEM version: branded Huawei, Audiovox, or Novatel). - - These cards feature a built-in OHCI-USB adapter and an - internally-connected GSM modem. The USB bus is not - accessible externally. + Say Y here if you want to use an Option card. This is a + GSM card, controlled by three serial ports which are connected + via an OHCI adapter located on a PC card. To compile this driver as a module, choose M here: the module will be called option. - If this driver doesn't recognize your device, - it might be accessible via the FTDI_SIO driver. - config USB_SERIAL_OMNINET tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 94b9ba0ff875..694b205f9b73 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -16,11 +16,9 @@ #include "usb-serial.h" static struct usb_device_id id_table [] = { - { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/usb/serial/console.c b/trunk/drivers/usb/serial/console.c index f3404e10afb4..8023bb7279b1 100644 --- a/trunk/drivers/usb/serial/console.c +++ b/trunk/drivers/usb/serial/console.c @@ -202,7 +202,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun struct usb_serial *serial; int retval = -ENODEV; - if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) + if (!port) return; serial = port->serial; @@ -213,38 +213,17 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun if (!port->open_count) { dbg ("%s - port not opened", __FUNCTION__); - return; + goto exit; } - while (count) { - unsigned int i; - unsigned int lf; - /* search for LF so we can insert CR if necessary */ - for (i=0, lf=0 ; i < count ; i++) { - if (*(buf + i) == 10) { - lf = 1; - i++; - break; - } - } - /* pass on to the driver specific version of this function if it is available */ - if (serial->type->write) - retval = serial->type->write(port, buf, i); - else - retval = usb_serial_generic_write(port, buf, i); - dbg("%s - return value : %d", __FUNCTION__, retval); - if (lf) { - /* append CR after LF */ - unsigned char cr = 13; - if (serial->type->write) - retval = serial->type->write(port, &cr, 1); - else - retval = usb_serial_generic_write(port, &cr, 1); - dbg("%s - return value : %d", __FUNCTION__, retval); - } - buf += i; - count -= i; - } + /* pass on to the driver specific version of this function if it is available */ + if (serial->type->write) + retval = serial->type->write(port, buf, count); + else + retval = usb_serial_generic_write(port, buf, count); + +exit: + dbg("%s - return value (if we had one): %d", __FUNCTION__, retval); } static struct console usbcons = { @@ -255,14 +234,6 @@ static struct console usbcons = { .index = -1, }; -void usb_serial_console_disconnect(struct usb_serial *serial) -{ - if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) { - usb_serial_console_exit(); - usb_serial_put(serial); - } -} - void usb_serial_console_init (int serial_debug, int minor) { debug = serial_debug; @@ -288,11 +259,6 @@ void usb_serial_console_init (int serial_debug, int minor) void usb_serial_console_exit (void) { - if (usbcons_info.port) { - unregister_console(&usbcons); - if (usbcons_info.port->open_count) - usbcons_info.port->open_count--; - usbcons_info.port = NULL; - } + unregister_console(&usbcons); } diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index f8c0cb287736..e0c2acdb3f06 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -59,7 +59,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ - { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ diff --git a/trunk/drivers/usb/serial/cyberjack.c b/trunk/drivers/usb/serial/cyberjack.c index 1fd5c5a9f2ef..2357b1d102d7 100644 --- a/trunk/drivers/usb/serial/cyberjack.c +++ b/trunk/drivers/usb/serial/cyberjack.c @@ -469,7 +469,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs exit: spin_unlock(&priv->lock); - usb_serial_port_softint(port); + schedule_work(&port->work); } static int __init cyberjack_init (void) diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index 5de76efe1b37..7212fbe3b6f2 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -824,7 +824,7 @@ static void cypress_send(struct usb_serial_port *port) priv->bytes_out += count; /* do not count the line control and size bytes */ spin_unlock_irqrestore(&priv->lock, flags); - usb_serial_port_softint(port); + schedule_work(&port->work); } /* cypress_send */ diff --git a/trunk/drivers/usb/serial/empeg.c b/trunk/drivers/usb/serial/empeg.c index afca1eae5fb5..63f7c78a1152 100644 --- a/trunk/drivers/usb/serial/empeg.c +++ b/trunk/drivers/usb/serial/empeg.c @@ -335,7 +335,7 @@ static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - usb_serial_port_softint(port); + schedule_work(&port->work); } diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index b2bfea7c815a..986d7622273d 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -500,7 +500,6 @@ static struct usb_device_id id_table_combined [] = { { 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) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1262,6 +1261,7 @@ static void ftdi_shutdown (struct usb_serial *serial) static int ftdi_open (struct usb_serial_port *port, struct file *filp) { /* ftdi_open */ + struct termios tmp_termios; struct usb_device *dev = port->serial->dev; struct ftdi_private *priv = usb_get_serial_port_data(port); unsigned long flags; @@ -1271,8 +1271,8 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) dbg("%s", __FUNCTION__); - if (port->tty) - port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; /* No error checking for this (will get errors later anyway) */ /* See ftdi_sio.h for description of what is reset */ @@ -1286,8 +1286,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) This is same behaviour as serial.c/rs_open() - Kuba */ /* ftdi_set_termios will send usb control messages */ - if (port->tty) - ftdi_set_termios(port, NULL); + ftdi_set_termios(port, &tmp_termios); /* FIXME: Flow control might be enabled, so it should be checked - we have no control of defaults! */ @@ -1473,7 +1472,7 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - usb_serial_port_softint(port); + schedule_work(&port->work); } /* ftdi_write_bulk_callback */ @@ -1868,7 +1867,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ err("%s urb failed to set baudrate", __FUNCTION__); } /* Ensure RTS and DTR are raised when baudrate changed from 0 */ - if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) { + if ((old_termios->c_cflag & CBAUD) == B0) { set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } } diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index 6ab2ac845bd7..d69a917e768f 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -436,12 +436,6 @@ */ #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 */ - /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/trunk/drivers/usb/serial/garmin_gps.c b/trunk/drivers/usb/serial/garmin_gps.c index 04767759cf8a..5ec9bf5bac8d 100644 --- a/trunk/drivers/usb/serial/garmin_gps.c +++ b/trunk/drivers/usb/serial/garmin_gps.c @@ -1012,7 +1012,7 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) garmin_data_p->flags |= CLEAR_HALT_REQUIRED; } - usb_serial_port_softint(port); + schedule_work(&port->work); } diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index 07a478c59fb2..c62cc2876519 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -299,7 +299,9 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *re return; } - usb_serial_port_softint(port); + usb_serial_port_softint((void *)port); + + schedule_work(&port->work); } EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index b85d2156dfdc..b606c5968102 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -142,7 +142,7 @@ struct edgeport_port { /* This structure holds all of the individual device information */ struct edgeport_serial { - char name[MAX_NAME_LEN+2]; /* string name of this device */ + char name[MAX_NAME_LEN+1]; /* string name of this device */ struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ @@ -270,7 +270,7 @@ static void get_manufacturing_desc (struct edgeport_serial *edge_serial); static void get_boot_desc (struct edgeport_serial *edge_serial); static void load_application_firmware (struct edgeport_serial *edge_serial); -static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size); +static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size); // ************************************************************************ @@ -373,7 +373,7 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) * Get string descriptor from device * * * ************************************************************************/ -static int get_string (struct usb_device *dev, int Id, char *string, int buflen) +static int get_string (struct usb_device *dev, int Id, char *string) { struct usb_string_descriptor StringDesc; struct usb_string_descriptor *pStringDesc; @@ -395,7 +395,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) return 0; } - unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); + unicode_to_ascii(string, pStringDesc->wData, pStringDesc->bLength/2-1); kfree(pStringDesc); return strlen(string); @@ -2564,20 +2564,16 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio * ASCII range, but it's only for debugging... * NOTE: expects the unicode in LE format ****************************************************************************/ -static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size) +static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size) { int i; - if (buflen <= 0) /* never happens, but... */ + if (unicode_size <= 0) return; - --buflen; /* space for nul */ - for (i = 0; i < unicode_size; i++) { - if (i >= buflen) - break; + for (i = 0; i < unicode_size; ++i) string[i] = (char)(le16_to_cpu(unicode[i])); - } - string[i] = 0x00; + string[unicode_size] = 0x00; } @@ -2607,17 +2603,11 @@ static void get_manufacturing_desc (struct edgeport_serial *edge_serial) dbg(" BoardRev: %d", edge_serial->manuf_descriptor.BoardRev); dbg(" NumPorts: %d", edge_serial->manuf_descriptor.NumPorts); dbg(" DescDate: %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.SerialNumber, - edge_serial->manuf_descriptor.SerNumLength/2); + unicode_to_ascii (string, edge_serial->manuf_descriptor.SerialNumber, edge_serial->manuf_descriptor.SerNumLength/2-1); dbg(" SerialNumber: %s", string); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.AssemblyNumber, - edge_serial->manuf_descriptor.AssemblyNumLength/2); + unicode_to_ascii (string, edge_serial->manuf_descriptor.AssemblyNumber, edge_serial->manuf_descriptor.AssemblyNumLength/2-1); dbg(" AssemblyNumber: %s", string); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.OemAssyNumber, - edge_serial->manuf_descriptor.OemAssyNumLength/2); + unicode_to_ascii (string, edge_serial->manuf_descriptor.OemAssyNumber, edge_serial->manuf_descriptor.OemAssyNumLength/2-1); dbg(" OemAssyNumber: %s", string); dbg(" UartType: %d", edge_serial->manuf_descriptor.UartType); dbg(" IonPid: %d", edge_serial->manuf_descriptor.IonPid); @@ -2730,7 +2720,7 @@ static int edge_startup (struct usb_serial *serial) struct edgeport_serial *edge_serial; struct edgeport_port *edge_port; struct usb_device *dev; - int i, j; + int i; dev = serial->dev; @@ -2745,11 +2735,11 @@ static int edge_startup (struct usb_serial *serial) usb_set_serial_data(serial, edge_serial); /* get the name for the device from the device */ - i = get_string(dev, dev->descriptor.iManufacturer, - &edge_serial->name[0], MAX_NAME_LEN+1); - edge_serial->name[i++] = ' '; - get_string(dev, dev->descriptor.iProduct, - &edge_serial->name[i], MAX_NAME_LEN+2 - i); + if ( (i = get_string(dev, dev->descriptor.iManufacturer, &edge_serial->name[0])) != 0) { + edge_serial->name[i-1] = ' '; + } + + get_string(dev, dev->descriptor.iProduct, &edge_serial->name[i]); dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); @@ -2794,10 +2784,6 @@ static int edge_startup (struct usb_serial *serial) edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); if (edge_port == NULL) { dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); - for (j = 0; j < i; ++j) { - kfree (usb_get_serial_port_data(serial->port[j])); - usb_set_serial_port_data(serial->port[j], NULL); - } usb_set_serial_data(serial, NULL); kfree(edge_serial); return -ENOMEM; diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index 9da6d2a8f2b0..9a5c97989562 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -870,7 +870,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs) spin_unlock_irqrestore(&write_list_lock, flags); } - usb_serial_port_softint(port); + schedule_work(&port->work); } static int ipaq_write_room(struct usb_serial_port *port) diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index a4a0bfeaab00..e760a70242c1 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -376,7 +376,7 @@ static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs) if (urb->status) dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); - usb_serial_port_softint(port); + schedule_work(&port->work); } static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count) diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 9432c7302275..426182ddc42a 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -408,7 +408,7 @@ static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs) urb->actual_length, urb->transfer_buffer); - usb_serial_port_softint(port); + schedule_work(&port->work); } static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index 2cf6ade704e4..052b735c4fbd 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/drivers/usb/serial/keyspan.c @@ -481,7 +481,7 @@ static void usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs) dbg ("%s - urb %d", __FUNCTION__, urb == p_priv->out_urbs[1]); if (port->open_count) - usb_serial_port_softint(port); + schedule_work(&port->work); } static void usa26_inack_callback(struct urb *urb, struct pt_regs *regs) diff --git a/trunk/drivers/usb/serial/kl5kusb105.c b/trunk/drivers/usb/serial/kl5kusb105.c index 65d79f630fa4..78335a5f7743 100644 --- a/trunk/drivers/usb/serial/kl5kusb105.c +++ b/trunk/drivers/usb/serial/kl5kusb105.c @@ -569,7 +569,8 @@ static void klsi_105_write_bulk_callback ( struct urb *urb, struct pt_regs *regs return; } - usb_serial_port_softint(port); + /* from generic_write_bulk_callback */ + schedule_work(&port->work); } /* klsi_105_write_bulk_completion_callback */ diff --git a/trunk/drivers/usb/serial/omninet.c b/trunk/drivers/usb/serial/omninet.c index 6dcdb5f598b8..238033a87092 100644 --- a/trunk/drivers/usb/serial/omninet.c +++ b/trunk/drivers/usb/serial/omninet.c @@ -320,7 +320,7 @@ static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - usb_serial_port_softint(port); + schedule_work(&port->work); } diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index b0861b61bba7..5cf2b80add7a 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -1,5 +1,5 @@ /* - USB Driver for GSM modems + Option Card (PCMCIA to) USB to Serial Driver Copyright (C) 2005 Matthias Urlichs @@ -28,34 +28,15 @@ 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes wants to send >2000 bytes. - 2006-04-10 v0.5 fixed two array overrun errors :-/ - 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755 - 2006-05-15 v0.6 re-enable multi-port support - 2006-06-01 v0.6.1 add COBRA - 2006-06-01 v0.6.2 add backwards-compatibility stuff - 2006-06-01 v0.6.3 add Novatel Wireless - 2006-06-01 v0.7 Option => GSM + 2006-04-10 v0.4.2 fixed two array overrun errors :-/ Work sponsored by: Sigos GmbH, Germany - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - nonstandard flow (Option devices) and multiplex (Sierra) control - - controlling the baud rate doesn't make sense - - This driver is named "option" because the most common device it's - used for is a PC-Card (with an internal OHCI-USB interface, behind - which the GSM interface sits), made by Option Inc. - - Some of the "one port" devices actually exhibit multiple USB instances - on the USB bus. This is not a bug, these ports are used for different - device features. */ -#define DRIVER_VERSION "v0.7.0" +#define DRIVER_VERSION "v0.4" #define DRIVER_AUTHOR "Matthias Urlichs " -#define DRIVER_DESC "USB Driver for GSM modems" +#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" #include #include @@ -93,45 +74,22 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file, static int option_send_setup(struct usb_serial_port *port); /* Vendor and product IDs */ -#define OPTION_VENDOR_ID 0x0AF0 -#define HUAWEI_VENDOR_ID 0x12D1 -#define AUDIOVOX_VENDOR_ID 0x0F3D -#define SIERRAWIRELESS_VENDOR_ID 0x1199 -#define NOVATELWIRELESS_VENDOR_ID 0x1410 - -#define OPTION_PRODUCT_OLD 0x5000 -#define OPTION_PRODUCT_FUSION 0x6000 -#define OPTION_PRODUCT_FUSION2 0x6300 -#define OPTION_PRODUCT_COBRA 0x6500 -#define HUAWEI_PRODUCT_E600 0x1001 -#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 -#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802 -#define NOVATELWIRELESS_PRODUCT_U740 0x1400 +#define OPTION_VENDOR_ID 0x0AF0 +#define HUAWEI_VENDOR_ID 0x12D1 +#define AUDIOVOX_VENDOR_ID 0x0F3D + +#define OPTION_PRODUCT_OLD 0x5000 +#define OPTION_PRODUCT_FUSION 0x6000 +#define OPTION_PRODUCT_FUSION2 0x6300 +#define HUAWEI_PRODUCT_E600 0x1001 +#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, - { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, - { } /* Terminating entry */ -}; - -static struct usb_device_id option_ids1[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, - { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, - { } /* Terminating entry */ -}; -static struct usb_device_id option_ids3[] = { - { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, { } /* Terminating entry */ }; @@ -153,39 +111,12 @@ static struct usb_serial_driver option_3port_device = { .owner = THIS_MODULE, .name = "option", }, - .description = "GSM modem (3-port)", - .id_table = option_ids3, + .description = "Option 3G data card", + .id_table = option_ids, .num_interrupt_in = NUM_DONT_CARE, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, - .num_ports = 3, - .open = option_open, - .close = option_close, - .write = option_write, - .write_room = option_write_room, - .chars_in_buffer = option_chars_in_buffer, - .throttle = option_rx_throttle, - .unthrottle = option_rx_unthrottle, - .set_termios = option_set_termios, - .break_ctl = option_break_ctl, - .tiocmget = option_tiocmget, - .tiocmset = option_tiocmset, - .attach = option_startup, - .shutdown = option_shutdown, - .read_int_callback = option_instat_callback, -}; - -static struct usb_serial_driver option_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "option", - }, - .description = "GSM modem (1-port)", - .id_table = option_ids1, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, + .num_ports = 1, /* 3, but the card reports its ports separately */ .open = option_open, .close = option_close, .write = option_write, @@ -239,9 +170,6 @@ struct option_port_private { static int __init option_init(void) { int retval; - retval = usb_serial_register(&option_1port_device); - if (retval) - goto failed_1port_device_register; retval = usb_serial_register(&option_3port_device); if (retval) goto failed_3port_device_register; @@ -256,8 +184,6 @@ static int __init option_init(void) failed_driver_register: usb_serial_deregister (&option_3port_device); failed_3port_device_register: - usb_serial_deregister (&option_1port_device); -failed_1port_device_register: return retval; } @@ -265,7 +191,6 @@ static void __exit option_exit(void) { usb_deregister (&option_driver); usb_serial_deregister (&option_3port_device); - usb_serial_deregister (&option_1port_device); } module_init(option_init); @@ -440,7 +365,8 @@ static void option_outdat_callback(struct urb *urb, struct pt_regs *regs) port = (struct usb_serial_port *) urb->context; - usb_serial_port_softint(port); + if (port->open_count) + schedule_work(&port->work); } static void option_instat_callback(struct urb *urb, struct pt_regs *regs) @@ -647,30 +573,27 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, /* Setup urbs */ static void option_setup_urbs(struct usb_serial *serial) { - int i,j; + int j; struct usb_serial_port *port; struct option_port_private *portdata; dbg("%s", __FUNCTION__); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); + port = serial->port[0]; + portdata = usb_get_serial_port_data(port); /* Do indat endpoints first */ - for (j = 0; j < N_IN_URB; ++j) { - portdata->in_urbs[j] = option_setup_urb (serial, - port->bulk_in_endpointAddress, USB_DIR_IN, port, - portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); - } + for (j = 0; j < N_IN_URB; ++j) { + portdata->in_urbs[j] = option_setup_urb (serial, + port->bulk_in_endpointAddress, USB_DIR_IN, port, + portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); + } - /* outdat endpoints */ - for (j = 0; j < N_OUT_URB; ++j) { - portdata->out_urbs[j] = option_setup_urb (serial, - port->bulk_out_endpointAddress, USB_DIR_OUT, port, - portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); - } + /* outdat endpoints */ + for (j = 0; j < N_OUT_URB; ++j) { + portdata->out_urbs[j] = option_setup_urb (serial, + port->bulk_out_endpointAddress, USB_DIR_OUT, port, + portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); } } diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index d88704387202..c96714bb1cb8 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -314,7 +314,7 @@ static void pl2303_send(struct usb_serial_port *port) // TODO: reschedule pl2303_send } - usb_serial_port_softint(port); + schedule_work(&port->work); } static int pl2303_write_room(struct usb_serial_port *port) @@ -600,7 +600,7 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp) unsigned int c_cflag; int bps; long timeout; - wait_queue_t wait; + wait_queue_t wait; \ dbg("%s - port %d", __FUNCTION__, port->number); diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index a30135c7cfe6..9c36f0ece20f 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -162,19 +162,12 @@ static void destroy_serial(struct kref *kref) } } - flush_scheduled_work(); /* port->work */ - usb_put_dev(serial->dev); /* free up any memory that we allocated */ kfree (serial); } -void usb_serial_put(struct usb_serial *serial) -{ - kref_put(&serial->kref, destroy_serial); -} - /***************************************************************************** * Driver tty interface functions *****************************************************************************/ @@ -208,13 +201,13 @@ static int serial_open (struct tty_struct *tty, struct file * filp) ++port->open_count; - /* set up our port structure making the tty driver - * remember our port object, and us it */ - tty->driver_data = port; - port->tty = tty; - if (port->open_count == 1) { + /* set up our port structure making the tty driver + * remember our port object, and us it */ + tty->driver_data = port; + port->tty = tty; + /* lock this module before we call it * this may fail, which means we must bail out, * safe because we are called with BKL held */ @@ -237,11 +230,9 @@ static int serial_open (struct tty_struct *tty, struct file * filp) module_put(serial->type->driver.owner); bailout_mutex_unlock: port->open_count = 0; - tty->driver_data = NULL; - port->tty = NULL; mutex_unlock(&port->mutex); bailout_kref_put: - usb_serial_put(serial); + kref_put(&serial->kref, destroy_serial); return retval; } @@ -277,7 +268,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) } mutex_unlock(&port->mutex); - usb_serial_put(port->serial); + kref_put(&port->serial->kref, destroy_serial); } static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) @@ -285,7 +276,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int struct usb_serial_port *port = tty->driver_data; int retval = -EINVAL; - if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) + if (!port) goto exit; dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); @@ -305,7 +296,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int static int serial_write_room (struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; + int retval = -EINVAL; if (!port) goto exit; @@ -327,7 +318,7 @@ static int serial_write_room (struct tty_struct *tty) static int serial_chars_in_buffer (struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; + int retval = -EINVAL; if (!port) goto exit; @@ -482,7 +473,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int begin += length; length = 0; } - usb_serial_put(serial); + kref_put(&serial->kref, destroy_serial); } *eof = 1; done: @@ -497,18 +488,19 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file) struct usb_serial_port *port = tty->driver_data; if (!port) - return -ENODEV; + goto exit; dbg("%s - port %d", __FUNCTION__, port->number); if (!port->open_count) { dbg("%s - port not open", __FUNCTION__); - return -ENODEV; + goto exit; } if (port->serial->type->tiocmget) return port->serial->type->tiocmget(port, file); +exit: return -EINVAL; } @@ -518,32 +510,23 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file, struct usb_serial_port *port = tty->driver_data; if (!port) - return -ENODEV; + goto exit; dbg("%s - port %d", __FUNCTION__, port->number); if (!port->open_count) { dbg("%s - port not open", __FUNCTION__); - return -ENODEV; + goto exit; } if (port->serial->type->tiocmset) return port->serial->type->tiocmset(port, file, set, clear); +exit: return -EINVAL; } -/* - * We would be calling tty_wakeup here, but unfortunately some line - * disciplines have an annoying habit of calling tty->write from - * the write wakeup callback (e.g. n_hdlc.c). - */ -void usb_serial_port_softint(struct usb_serial_port *port) -{ - schedule_work(&port->work); -} - -static void usb_serial_port_work(void *private) +void usb_serial_port_softint(void *private) { struct usb_serial_port *port = private; struct tty_struct *tty; @@ -806,7 +789,7 @@ int usb_serial_probe(struct usb_interface *interface, port->serial = serial; spin_lock_init(&port->lock); mutex_init(&port->mutex); - INIT_WORK(&port->work, usb_serial_port_work, port); + INIT_WORK(&port->work, usb_serial_port_softint, port); serial->port[i] = port; } @@ -1002,7 +985,6 @@ void usb_serial_disconnect(struct usb_interface *interface) struct device *dev = &interface->dev; struct usb_serial_port *port; - usb_serial_console_disconnect(serial); dbg ("%s", __FUNCTION__); usb_set_intfdata (interface, NULL); @@ -1014,7 +996,7 @@ void usb_serial_disconnect(struct usb_interface *interface) } /* let the last holder of this object * cause it to be cleaned up */ - usb_serial_put(serial); + kref_put(&serial->kref, destroy_serial); } dev_info(dev, "device disconnected\n"); } diff --git a/trunk/drivers/usb/serial/usb-serial.h b/trunk/drivers/usb/serial/usb-serial.h index d53ea9b11e81..dc89d8710460 100644 --- a/trunk/drivers/usb/serial/usb-serial.h +++ b/trunk/drivers/usb/serial/usb-serial.h @@ -236,7 +236,7 @@ struct usb_serial_driver { extern int usb_serial_register(struct usb_serial_driver *driver); extern void usb_serial_deregister(struct usb_serial_driver *driver); -extern void usb_serial_port_softint(struct usb_serial_port *port); +extern void usb_serial_port_softint(void *private); extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); extern void usb_serial_disconnect(struct usb_interface *iface); @@ -248,16 +248,13 @@ extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit); #ifdef CONFIG_USB_SERIAL_CONSOLE extern void usb_serial_console_init (int debug, int minor); extern void usb_serial_console_exit (void); -extern void usb_serial_console_disconnect(struct usb_serial *serial); #else static inline void usb_serial_console_init (int debug, int minor) { } static inline void usb_serial_console_exit (void) { } -static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} #endif /* Functions needed by other parts of the usbserial core */ extern struct usb_serial *usb_serial_get_by_index (unsigned int minor); -extern void usb_serial_put(struct usb_serial *serial); extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); diff --git a/trunk/drivers/usb/serial/visor.c b/trunk/drivers/usb/serial/visor.c index 9e89b8d54f72..f5c3841d4843 100644 --- a/trunk/drivers/usb/serial/visor.c +++ b/trunk/drivers/usb/serial/visor.c @@ -480,7 +480,7 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs) --priv->outstanding_urbs; spin_unlock_irqrestore(&priv->lock, flags); - usb_serial_port_softint(port); + schedule_work(&port->work); } diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index 56ffc81302fc..f806553cd9a4 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -388,7 +388,7 @@ static int whiteheat_attach (struct usb_serial *serial) if (ret) { err("%s: Couldn't send command [%d]", serial->type->description, ret); goto no_firmware; - } else if (alen != 2) { + } else if (alen != sizeof(command)) { err("%s: Send command incomplete [%d]", serial->type->description, alen); goto no_firmware; } @@ -400,7 +400,7 @@ static int whiteheat_attach (struct usb_serial *serial) if (ret) { err("%s: Couldn't get results [%d]", serial->type->description, ret); goto no_firmware; - } else if (alen != sizeof(*hw_info) + 1) { + } else if (alen != sizeof(result)) { err("%s: Get results incomplete [%d]", serial->type->description, alen); goto no_firmware; } else if (result[0] != command[0]) { @@ -686,16 +686,19 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; usb_kill_urb(urb); - list_move(tmp, &info->rx_urbs_free); + list_del(tmp); + list_add(tmp, &info->rx_urbs_free); + } + list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { + list_del(tmp); + list_add(tmp, &info->rx_urbs_free); } - list_for_each_safe(tmp, tmp2, &info->rx_urb_q) - list_move(tmp, &info->rx_urbs_free); - list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) { wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; usb_kill_urb(urb); - list_move(tmp, &info->tx_urbs_free); + list_del(tmp); + list_add(tmp, &info->tx_urbs_free); } spin_unlock_irqrestore(&info->lock, flags); @@ -1077,7 +1080,8 @@ static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs) err("%s - Not my urb!", __FUNCTION__); return; } - list_move(&wrap->list, &info->tx_urbs_free); + list_del(&wrap->list); + list_add(&wrap->list, &info->tx_urbs_free); spin_unlock(&info->lock); if (urb->status) { @@ -1085,7 +1089,9 @@ static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs) return; } - usb_serial_port_softint(port); + usb_serial_port_softint((void *)port); + + schedule_work(&port->work); } @@ -1367,7 +1373,8 @@ static int start_port_read(struct usb_serial_port *port) wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); urb = wrap->urb; usb_kill_urb(urb); - list_move(tmp, &info->rx_urbs_free); + list_del(tmp); + list_add(tmp, &info->rx_urbs_free); } break; } diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 026a587eb8dd..55ee2d36d585 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -34,8 +34,9 @@ #include #include #include +#include #include -#include +#include #include "usb.h" #include "onetouch.h" #include "debug.h" diff --git a/trunk/drivers/usb/storage/scsiglue.c b/trunk/drivers/usb/storage/scsiglue.c index 5715291ba540..5f11e19eaae3 100644 --- a/trunk/drivers/usb/storage/scsiglue.c +++ b/trunk/drivers/usb/storage/scsiglue.c @@ -286,7 +286,11 @@ static int bus_reset(struct scsi_cmnd *srb) int result; US_DEBUGP("%s called\n", __FUNCTION__); + + mutex_lock(&(us->dev_mutex)); result = usb_stor_port_reset(us); + mutex_unlock(&us->dev_mutex); + return result < 0 ? FAILED : SUCCESS; } diff --git a/trunk/drivers/usb/storage/shuttle_usbat.c b/trunk/drivers/usb/storage/shuttle_usbat.c index 8fcec01dc622..f2bc5c9e23d5 100644 --- a/trunk/drivers/usb/storage/shuttle_usbat.c +++ b/trunk/drivers/usb/storage/shuttle_usbat.c @@ -131,30 +131,28 @@ static int usbat_write(struct us_data *us, * Convenience function to perform a bulk read */ static int usbat_bulk_read(struct us_data *us, - unsigned char *data, - unsigned int len, - int use_sg) + unsigned char *data, + unsigned int len) { if (len == 0) return USB_STOR_XFER_GOOD; US_DEBUGP("usbat_bulk_read: len = %d\n", len); - return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, data, len, use_sg, NULL); + return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, data, len, NULL); } /* * Convenience function to perform a bulk write */ static int usbat_bulk_write(struct us_data *us, - unsigned char *data, - unsigned int len, - int use_sg) + unsigned char *data, + unsigned int len) { if (len == 0) return USB_STOR_XFER_GOOD; US_DEBUGP("usbat_bulk_write: len = %d\n", len); - return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, data, len, use_sg, NULL); + return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, data, len, NULL); } /* @@ -319,8 +317,7 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) */ static int usbat_read_block(struct us_data *us, unsigned char *content, - unsigned short len, - int use_sg) + unsigned short len) { int result; unsigned char *command = us->iobuf; @@ -341,7 +338,7 @@ static int usbat_read_block(struct us_data *us, if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - result = usbat_bulk_read(us, content, len, use_sg); + result = usbat_bulk_read(us, content, len); return (result == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); } @@ -353,8 +350,7 @@ static int usbat_write_block(struct us_data *us, unsigned char access, unsigned char *content, unsigned short len, - int minutes, - int use_sg) + int minutes) { int result; unsigned char *command = us->iobuf; @@ -376,7 +372,7 @@ static int usbat_write_block(struct us_data *us, if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - result = usbat_bulk_write(us, content, len, use_sg); + result = usbat_bulk_write(us, content, len); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -469,7 +465,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, data[1+(j<<1)] = data_out[j]; } - result = usbat_bulk_write(us, data, num_registers*2, 0); + result = usbat_bulk_write(us, data, num_registers*2); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -587,7 +583,7 @@ static int usbat_multiple_write(struct us_data *us, } /* Send the data */ - result = usbat_bulk_write(us, data, num_registers*2, 0); + result = usbat_bulk_write(us, data, num_registers*2); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -610,9 +606,8 @@ static int usbat_multiple_write(struct us_data *us, * other related details) are defined beforehand with _set_shuttle_features(). */ static int usbat_read_blocks(struct us_data *us, - unsigned char *buffer, - int len, - int use_sg) + unsigned char *buffer, + int len) { int result; unsigned char *command = us->iobuf; @@ -632,7 +627,7 @@ static int usbat_read_blocks(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; /* Read the blocks we just asked for */ - result = usbat_bulk_read(us, buffer, len, use_sg); + result = usbat_bulk_read(us, buffer, len); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -653,8 +648,7 @@ static int usbat_read_blocks(struct us_data *us, */ static int usbat_write_blocks(struct us_data *us, unsigned char *buffer, - int len, - int use_sg) + int len) { int result; unsigned char *command = us->iobuf; @@ -674,7 +668,7 @@ static int usbat_write_blocks(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; /* Write the data */ - result = usbat_bulk_write(us, buffer, len, use_sg); + result = usbat_bulk_write(us, buffer, len); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -893,28 +887,22 @@ static int usbat_identify_device(struct us_data *us, * Set the transport function based on the device type */ static int usbat_set_transport(struct us_data *us, - struct usbat_info *info, - int devicetype) + struct usbat_info *info) { + int rc; - if (!info->devicetype) - info->devicetype = devicetype; - - if (!info->devicetype) - usbat_identify_device(us, info); - - switch (info->devicetype) { - default: - return USB_STOR_TRANSPORT_ERROR; + if (!info->devicetype) { + rc = usbat_identify_device(us, info); + if (rc != USB_STOR_TRANSPORT_GOOD) { + US_DEBUGP("usbat_set_transport: Could not identify device\n"); + return 1; + } + } - case USBAT_DEV_HP8200: + if (usbat_get_device_type(us) == USBAT_DEV_HP8200) us->transport = usbat_hp8200e_transport; - break; - - case USBAT_DEV_FLASH: + else if (usbat_get_device_type(us) == USBAT_DEV_FLASH) us->transport = usbat_flash_transport; - break; - } return 0; } @@ -959,7 +947,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, msleep(100); /* Read the device identification data */ - rc = usbat_read_block(us, reply, 512, 0); + rc = usbat_read_block(us, reply, 512); if (rc != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1043,7 +1031,7 @@ static int usbat_flash_read_data(struct us_data *us, goto leave; /* Read the data we just requested */ - result = usbat_read_blocks(us, buffer, len, 0); + result = usbat_read_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1137,7 +1125,7 @@ static int usbat_flash_write_data(struct us_data *us, goto leave; /* Write the data */ - result = usbat_write_blocks(us, buffer, len, 0); + result = usbat_write_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1322,7 +1310,7 @@ static int usbat_select_and_test_registers(struct us_data *us) /* * Initialize the USBAT processor and the storage device */ -static int init_usbat(struct us_data *us, int devicetype) +int init_usbat(struct us_data *us) { int rc; struct usbat_info *info; @@ -1404,7 +1392,7 @@ static int init_usbat(struct us_data *us, int devicetype) US_DEBUGP("INIT 9\n"); /* At this point, we need to detect which device we are using */ - if (usbat_set_transport(us, info, devicetype)) + if (usbat_set_transport(us, info)) return USB_STOR_TRANSPORT_ERROR; US_DEBUGP("INIT 10\n"); @@ -1515,10 +1503,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) * AT SPEED 4 IS UNRELIABLE!!! */ - if ((result = usbat_write_block(us, + if ( (result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12, - (srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) != - USB_STOR_TRANSPORT_GOOD)) { + srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) != + USB_STOR_TRANSPORT_GOOD) { return result; } @@ -1545,7 +1533,7 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) len = *status; - result = usbat_read_block(us, srb->request_buffer, len, srb->use_sg); + result = usbat_read_block(us, srb->request_buffer, len); /* Debug-print the first 32 bytes of the transfer */ @@ -1707,22 +1695,6 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) return USB_STOR_TRANSPORT_FAILED; } -int init_usbat_cd(struct us_data *us) -{ - return init_usbat(us, USBAT_DEV_HP8200); -} - - -int init_usbat_flash(struct us_data *us) -{ - return init_usbat(us, USBAT_DEV_FLASH); -} - -int init_usbat_probe(struct us_data *us) -{ - return init_usbat(us, 0); -} - /* * Default transport function. Attempts to detect which transport function * should be called, makes it the new default, and calls it. @@ -1736,8 +1708,9 @@ int usbat_transport(struct scsi_cmnd *srb, struct us_data *us) { struct usbat_info *info = (struct usbat_info*) (us->extra); - if (usbat_set_transport(us, info, 0)) + if (usbat_set_transport(us, info)) return USB_STOR_TRANSPORT_ERROR; return us->transport(srb, us); } + diff --git a/trunk/drivers/usb/storage/shuttle_usbat.h b/trunk/drivers/usb/storage/shuttle_usbat.h index 3ddf143a1dec..25e7d8b340b8 100644 --- a/trunk/drivers/usb/storage/shuttle_usbat.h +++ b/trunk/drivers/usb/storage/shuttle_usbat.h @@ -106,9 +106,7 @@ #define USBAT_FEAT_ET2 0x01 extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us); -extern int init_usbat_cd(struct us_data *us); -extern int init_usbat_flash(struct us_data *us); -extern int init_usbat_probe(struct us_data *us); +extern int init_usbat(struct us_data *us); struct usbat_info { int devicetype; diff --git a/trunk/drivers/usb/storage/transport.c b/trunk/drivers/usb/storage/transport.c index 19b25c5cafd4..7ca896a342e3 100644 --- a/trunk/drivers/usb/storage/transport.c +++ b/trunk/drivers/usb/storage/transport.c @@ -115,6 +115,19 @@ static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs) complete(urb_done_ptr); } + +/* This is the timeout handler which will cancel an URB when its timeout + * expires. + */ +static void timeout_handler(unsigned long us_) +{ + struct us_data *us = (struct us_data *) us_; + + if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) { + US_DEBUGP("Timeout -- cancelling URB\n"); + usb_unlink_urb(us->current_urb); + } +} /* This is the common part of the URB message submission code * @@ -125,7 +138,7 @@ static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs) static int usb_stor_msg_common(struct us_data *us, int timeout) { struct completion urb_done; - long timeleft; + struct timer_list to_timer; int status; /* don't submit URBs during abort/disconnect processing */ @@ -172,17 +185,22 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) } } + /* submit the timeout timer, if a timeout was requested */ + if (timeout > 0) { + init_timer(&to_timer); + to_timer.expires = jiffies + timeout; + to_timer.function = timeout_handler; + to_timer.data = (unsigned long) us; + add_timer(&to_timer); + } + /* wait for the completion of the URB */ - timeleft = wait_for_completion_interruptible_timeout( - &urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT); - + wait_for_completion(&urb_done); clear_bit(US_FLIDX_URB_ACTIVE, &us->flags); - - if (timeleft <= 0) { - US_DEBUGP("%s -- cancelling URB\n", - timeleft == 0 ? "Timeout" : "Signal"); - usb_unlink_urb(us->current_urb); - } + + /* clean up the timeout timer */ + if (timeout > 0) + del_timer_sync(&to_timer); /* return the URB status */ return us->current_urb->status; @@ -703,19 +721,16 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) * device reset. */ Handle_Errors: - /* Set the RESETTING bit, and clear the ABORTING bit so that - * the reset may proceed. */ + /* Let the SCSI layer know we are doing a reset, set the + * RESETTING bit, and clear the ABORTING bit so that the reset + * may proceed. */ scsi_lock(us_to_host(us)); + usb_stor_report_bus_reset(us); set_bit(US_FLIDX_RESETTING, &us->flags); clear_bit(US_FLIDX_ABORTING, &us->flags); scsi_unlock(us_to_host(us)); - /* We must release the device lock because the pre_reset routine - * will want to acquire it. */ - mutex_unlock(&us->dev_mutex); result = usb_stor_port_reset(us); - mutex_lock(&us->dev_mutex); - if (result < 0) { scsi_lock(us_to_host(us)); usb_stor_report_device_reset(us); @@ -1199,30 +1214,31 @@ int usb_stor_Bulk_reset(struct us_data *us) 0, us->ifnum, NULL, 0); } -/* Issue a USB port reset to the device. The caller must not hold - * us->dev_mutex. - */ +/* Issue a USB port reset to the device. But don't do anything if + * there's more than one interface in the device, so that other users + * are not affected. */ int usb_stor_port_reset(struct us_data *us) { - int result, rc_lock; + int result, rc; - result = rc_lock = - usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); - if (result < 0) - US_DEBUGP("unable to lock device for reset: %d\n", result); - else { - /* Were we disconnected while waiting for the lock? */ - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { - result = -EIO; - US_DEBUGP("No reset during disconnect\n"); - } else { - result = usb_reset_composite_device( - us->pusb_dev, us->pusb_intf); - US_DEBUGP("usb_reset_composite_device returns %d\n", + if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + result = -EIO; + US_DEBUGP("No reset during disconnect\n"); + } else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) { + result = -EBUSY; + US_DEBUGP("Refusing to reset a multi-interface device\n"); + } else { + result = rc = + usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); + if (result < 0) { + US_DEBUGP("unable to lock device for reset: %d\n", result); + } else { + result = usb_reset_device(us->pusb_dev); + if (rc) + usb_unlock_device(us->pusb_dev); + US_DEBUGP("usb_reset_device returns %d\n", result); } - if (rc_lock) - usb_unlock_device(us->pusb_dev); } return result; } diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 543244d421c1..aec5ea8682d5 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -78,12 +78,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, "HP", "CD-Writer+ 8200e", - US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, "HP", "CD-Writer+ CD-4e", - US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), #endif /* Reported by Sebastian Kapfer @@ -133,14 +133,6 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Jiri Slaby and - * Rene C. Castberg */ -UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100, - "Nokia", - "N80", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), - /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -224,14 +216,6 @@ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, "DVD-CAM DZ-MV100A Camcorder", US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN), -/* Patch for Nikon coolpix 2000 - * Submitted by Fabien Cosse */ -UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, - "NIKON", - "NIKON DSC E2000", - US_SC_DEVICE, US_PR_DEVICE,NULL, - US_FL_NOT_LOCKABLE ), - /* Reported by Andreas Bockhold */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -239,12 +223,13 @@ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), -/* Reported by Jamie Kitson */ -UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, +/* Patch for Nikon coolpix 2000 + * Submitted by Fabien Cosse */ +UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, "NIKON", - "NIKON DSC D70s", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), + "NIKON DSC E2000", + US_SC_DEVICE, US_PR_DEVICE,NULL, + US_FL_NOT_LOCKABLE ), /* BENQ DC5330 * Reported by Manuel Fombuena and @@ -408,7 +393,7 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, "Shuttle/SCM", "USBAT-02", - US_SC_SCSI, US_PR_USBAT, init_usbat_flash, + US_SC_SCSI, US_PR_USBAT, init_usbat, US_FL_SINGLE_LUN), #endif @@ -812,7 +797,7 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, "Sandisk", "ImageMate SDDR-05b", - US_SC_SCSI, US_PR_USBAT, init_usbat_flash, + US_SC_SCSI, US_PR_USBAT, init_usbat, US_FL_SINGLE_LUN ), #endif diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index e232c7c89909..dd108634348e 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -220,37 +220,6 @@ static int storage_resume(struct usb_interface *iface) #endif /* CONFIG_PM */ -/* - * The next two routines get called just before and just after - * a USB port reset, whether from this driver or a different one. - */ - -static void storage_pre_reset(struct usb_interface *iface) -{ - struct us_data *us = usb_get_intfdata(iface); - - US_DEBUGP("%s\n", __FUNCTION__); - - /* Make sure no command runs during the reset */ - mutex_lock(&us->dev_mutex); -} - -static void storage_post_reset(struct usb_interface *iface) -{ - struct us_data *us = usb_get_intfdata(iface); - - US_DEBUGP("%s\n", __FUNCTION__); - - /* Report the reset to the SCSI core */ - scsi_lock(us_to_host(us)); - usb_stor_report_bus_reset(us); - scsi_unlock(us_to_host(us)); - - /* FIXME: Notify the subdrivers that they need to reinitialize - * the device */ - mutex_unlock(&us->dev_mutex); -} - /* * fill_inquiry_response takes an unsigned char array (which must * be at least 36 characters) and populates the vendor name, @@ -624,15 +593,6 @@ static int get_transport(struct us_data *us) break; #endif -#ifdef CONFIG_USB_STORAGE_ALAUDA - case US_PR_ALAUDA: - us->transport_name = "Alauda Control/Bulk"; - us->transport = alauda_transport; - us->transport_reset = usb_stor_Bulk_reset; - us->max_lun = 1; - break; -#endif - default: return -EIO; } @@ -688,6 +648,15 @@ static int get_protocol(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_ALAUDA + case US_PR_ALAUDA: + us->transport_name = "Alauda Control/Bulk"; + us->transport = alauda_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + break; +#endif + default: return -EIO; } @@ -1033,8 +1002,6 @@ static struct usb_driver usb_storage_driver = { .suspend = storage_suspend, .resume = storage_resume, #endif - .pre_reset = storage_pre_reset, - .post_reset = storage_post_reset, .id_table = storage_usb_ids, }; diff --git a/trunk/drivers/usb/storage/usb.h b/trunk/drivers/usb/storage/usb.h index 5284abe1b5eb..009fb0953a56 100644 --- a/trunk/drivers/usb/storage/usb.h +++ b/trunk/drivers/usb/storage/usb.h @@ -160,10 +160,10 @@ struct us_data { }; /* Convert between us_data and the corresponding Scsi_Host */ -static inline struct Scsi_Host *us_to_host(struct us_data *us) { +static struct Scsi_Host inline *us_to_host(struct us_data *us) { return container_of((void *) us, struct Scsi_Host, hostdata); } -static inline struct us_data *host_to_us(struct Scsi_Host *host) { +static struct us_data inline *host_to_us(struct Scsi_Host *host) { return (struct us_data *) host->hostdata; } diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 17de4c84db69..5a2840aeb547 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -4,21 +4,6 @@ menu "Graphics support" -config FIRMWARE_EDID - bool "Enable firmware EDID" - default y - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - config FB tristate "Support for frame buffer devices" ---help--- @@ -85,10 +70,21 @@ config FB_MACMODES depends on FB default n -config FB_BACKLIGHT - bool +config FB_FIRMWARE_EDID + bool "Enable firmware EDID" depends on FB - default n + default y + ---help--- + This enables access to the EDID transferred from the firmware. + On the i386, this is from the Video BIOS. Enable this if DDC/I2C + transfers do not work for your driver and if you are using + nvidiafb, i810fb or savagefb. + + In general, choosing Y for this option is safe. If you + experience extremely long delays while booting before you get + something on your display, try setting this to N. Matrox cards in + combination with certain motherboards and monitors are known to + suffer from this problem. config FB_MODE_HELPERS bool "Enable Video Mode Handling Helpers" @@ -550,14 +546,10 @@ config FB_VESA You will get a boot time penguin logo at no additional cost. Please read . If unsure, say Y. -config FB_IMAC - bool "Intel-based Macintosh Framebuffer Support" - depends on (FB = y) && X86 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Intel-based Macintosh +config VIDEO_SELECT + bool + depends on FB_VESA + default y config FB_HGA tristate "Hercules mono graphics support" @@ -581,6 +573,12 @@ config FB_HGA_ACCEL This will compile the Hercules mono graphics with acceleration functions. + +config VIDEO_SELECT + bool + depends on (FB = y) && X86 + default y + config FB_SGIVW tristate "SGI Visual Workstation framebuffer support" depends on FB && X86_VISWS @@ -719,16 +717,6 @@ config FB_NVIDIA_I2C independently validate video mode parameters, you should say Y here. -config FB_NVIDIA_BACKLIGHT - bool "Support for backlight control" - depends on FB_NVIDIA && PPC_PMAC - select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default y - help - Say Y here if you want to control the backlight of your display. - config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI @@ -767,16 +755,6 @@ config FB_RIVA_DEBUG of debugging informations to provide to the maintainer when something goes wrong. -config FB_RIVA_BACKLIGHT - bool "Support for backlight control" - depends on FB_RIVA && PPC_PMAC - select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default y - help - Say Y here if you want to control the backlight of your display. - config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" depends on FB && EXPERIMENTAL && PCI && X86_32 @@ -1015,7 +993,6 @@ config FB_RADEON There is a product page at http://apps.ati.com/ATIcompare/ - config FB_RADEON_I2C bool "DDC/I2C for ATI Radeon support" depends on FB_RADEON @@ -1023,16 +1000,6 @@ config FB_RADEON_I2C help Say Y here if you want DDC/I2C support for your Radeon board. -config FB_RADEON_BACKLIGHT - bool "Support for backlight control" - depends on FB_RADEON && PPC_PMAC - select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default y - help - Say Y here if you want to control the backlight of your display. - config FB_RADEON_DEBUG bool "Lots of debug output from Radeon driver" depends on FB_RADEON @@ -1057,16 +1024,6 @@ config FB_ATY128 To compile this driver as a module, choose M here: the module will be called aty128fb. -config FB_ATY128_BACKLIGHT - bool "Support for backlight control" - depends on FB_ATY128 && PPC_PMAC - select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default y - help - Say Y here if you want to control the backlight of your display. - config FB_ATY tristate "ATI Mach64 display support" if PCI || ATARI depends on FB && !SPARC32 @@ -1109,16 +1066,6 @@ config FB_ATY_GX is at . -config FB_ATY_BACKLIGHT - bool "Support for backlight control" - depends on FB_ATY && PPC_PMAC - select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default y - help - Say Y here if you want to control the backlight of your display. - config FB_S3TRIO bool "S3 Trio display support" depends on (FB = y) && PPC && BROKEN diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index c335e9bc3b20..23de3b2c7856 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -4,15 +4,15 @@ # Each configuration option enables a list of files. +obj-$(CONFIG_VT) += console/ +obj-$(CONFIG_LOGO) += logo/ +obj-$(CONFIG_SYSFS) += backlight/ + obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o fb-objs := $(fb-y) -obj-$(CONFIG_VT) += console/ -obj-$(CONFIG_LOGO) += logo/ -obj-$(CONFIG_SYSFS) += backlight/ - obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o @@ -97,7 +97,6 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o -obj-$(CONFIG_FB_IMAC) += imacfb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o obj-$(CONFIG_FB_OF) += offb.o diff --git a/trunk/drivers/video/aty/Makefile b/trunk/drivers/video/aty/Makefile index a6cc0e9ec790..18521397a6e3 100644 --- a/trunk/drivers/video/aty/Makefile +++ b/trunk/drivers/video/aty/Makefile @@ -10,6 +10,5 @@ atyfb-objs := $(atyfb-y) radeonfb-y := radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o radeonfb-$(CONFIG_FB_RADEON_I2C) += radeon_i2c.o -radeonfb-$(CONFIG_FB_RADEON_BACKLIGHT) += radeon_backlight.o radeonfb-objs := $(radeonfb-y) diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index 11cf7fcb1d55..f7bbff4ddc6a 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #ifdef CONFIG_PPC_PMAC @@ -100,7 +99,7 @@ #ifndef CONFIG_PPC_PMAC /* default mode */ -static struct fb_var_screeninfo default_var __devinitdata = { +static struct fb_var_screeninfo default_var __initdata = { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 640, 480, 640, 480, 0, 0, 8, 0, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, @@ -123,7 +122,7 @@ static struct fb_var_screeninfo default_var = { /* default modedb mode */ /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ -static struct fb_videomode defaultmode __devinitdata = { +static struct fb_videomode defaultmode __initdata = { .refresh = 60, .xres = 640, .yres = 480, @@ -335,7 +334,7 @@ static const struct aty128_meminfo sdr_sgram = static const struct aty128_meminfo ddr_sgram = { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; -static struct fb_fix_screeninfo aty128fb_fix __devinitdata = { +static struct fb_fix_screeninfo aty128fb_fix __initdata = { .id = "ATY Rage128", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -345,15 +344,15 @@ static struct fb_fix_screeninfo aty128fb_fix __devinitdata = { .accel = FB_ACCEL_ATI_RAGE128, }; -static char *mode_option __devinitdata = NULL; +static char *mode_option __initdata = NULL; #ifdef CONFIG_PPC_PMAC -static int default_vmode __devinitdata = VMODE_1024_768_60; -static int default_cmode __devinitdata = CMODE_8; +static int default_vmode __initdata = VMODE_1024_768_60; +static int default_cmode __initdata = CMODE_8; #endif -static int default_crt_on __devinitdata = 0; -static int default_lcd_on __devinitdata = 1; +static int default_crt_on __initdata = 0; +static int default_lcd_on __initdata = 1; #ifdef CONFIG_MTRR static int mtrr = 1; @@ -445,9 +444,9 @@ static int aty128_encode_var(struct fb_var_screeninfo *var, static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par); #if 0 -static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, +static void __init aty128_get_pllinfo(struct aty128fb_par *par, void __iomem *bios); -static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); +static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); #endif static void aty128_timings(struct aty128fb_par *par); static void aty128_init_engine(struct aty128fb_par *par); @@ -481,6 +480,16 @@ static struct fb_ops aty128fb_ops = { .fb_imageblit = cfb_imageblit, }; +#ifdef CONFIG_PMAC_BACKLIGHT +static int aty128_set_backlight_enable(int on, int level, void* data); +static int aty128_set_backlight_level(int level, void* data); + +static struct backlight_controller aty128_backlight_controller = { + aty128_set_backlight_enable, + aty128_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ + /* * Functions to read from/write to the mmio registers * - endian conversions may possibly be avoided by @@ -573,7 +582,7 @@ static void aty_pll_writeupdate(const struct aty128fb_par *par) /* write to the scratch register to test r/w functionality */ -static int __devinit register_test(const struct aty128fb_par *par) +static int __init register_test(const struct aty128fb_par *par) { u32 val; int flag = 0; @@ -772,7 +781,7 @@ static u32 depth_to_dst(u32 depth) #ifndef __sparc__ -static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) +static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) { u16 dptr; u8 rom_type; @@ -856,7 +865,7 @@ static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, s return NULL; } -static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) +static void __init aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) { unsigned int bios_hdr; unsigned int bios_pll; @@ -903,7 +912,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par) #endif /* ndef(__sparc__) */ /* fill in known card constants if pll_block is not available */ -static void __devinit aty128_timings(struct aty128fb_par *par) +static void __init aty128_timings(struct aty128fb_par *par) { #ifdef CONFIG_PPC_OF /* instead of a table lookup, assume OF has properly @@ -1249,35 +1258,19 @@ static void aty128_set_crt_enable(struct aty128fb_par *par, int on) static void aty128_set_lcd_enable(struct aty128fb_par *par, int on) { u32 reg; -#ifdef CONFIG_FB_ATY128_BACKLIGHT - struct fb_info *info = pci_get_drvdata(par->pdev); -#endif if (on) { reg = aty_ld_le32(LVDS_GEN_CNTL); reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION; reg &= ~LVDS_DISPLAY_DIS; aty_st_le32(LVDS_GEN_CNTL, reg); -#ifdef CONFIG_FB_ATY128_BACKLIGHT - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - mutex_unlock(&info->bl_mutex); +#ifdef CONFIG_PMAC_BACKLIGHT + aty128_set_backlight_enable(get_backlight_enable(), + get_backlight_level(), par); #endif } else { -#ifdef CONFIG_FB_ATY128_BACKLIGHT - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->brightness = 0; - info->bl_dev->props->power = FB_BLANK_POWERDOWN; - info->bl_dev->props->update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - mutex_unlock(&info->bl_mutex); +#ifdef CONFIG_PMAC_BACKLIGHT + aty128_set_backlight_enable(0, 0, par); #endif reg = aty_ld_le32(LVDS_GEN_CNTL); reg |= LVDS_DISPLAY_DIS; @@ -1645,7 +1638,7 @@ static int aty128fb_sync(struct fb_info *info) } #ifndef MODULE -static int __devinit aty128fb_setup(char *options) +static int __init aty128fb_setup(char *options) { char *this_opt; @@ -1698,184 +1691,6 @@ static int __devinit aty128fb_setup(char *options) } #endif /* MODULE */ -/* Backlight */ -#ifdef CONFIG_FB_ATY128_BACKLIGHT -#define MAX_LEVEL 0xFF - -static struct backlight_properties aty128_bl_data; - -static int aty128_bl_get_level_brightness(struct aty128fb_par *par, - int level) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - int atylevel; - - /* Get and convert the value */ - mutex_lock(&info->bl_mutex); - atylevel = MAX_LEVEL - - (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL); - mutex_unlock(&info->bl_mutex); - - if (atylevel < 0) - atylevel = 0; - else if (atylevel > MAX_LEVEL) - atylevel = MAX_LEVEL; - - return atylevel; -} - -/* We turn off the LCD completely instead of just dimming the backlight. - * This provides greater power saving and the display is useless without - * backlight anyway - */ -#define BACKLIGHT_LVDS_OFF -/* That one prevents proper CRT output with LCD off */ -#undef BACKLIGHT_DAC_OFF - -static int aty128_bl_update_status(struct backlight_device *bd) -{ - struct aty128fb_par *par = class_get_devdata(&bd->class_dev); - unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); - int level; - - if (bd->props->power != FB_BLANK_UNBLANK || - bd->props->fb_blank != FB_BLANK_UNBLANK || - !par->lcd_on) - level = 0; - else - level = bd->props->brightness; - - reg |= LVDS_BL_MOD_EN | LVDS_BLON; - if (level > 0) { - reg |= LVDS_DIGION; - if (!(reg & LVDS_ON)) { - reg &= ~LVDS_BLON; - aty_st_le32(LVDS_GEN_CNTL, reg); - aty_ld_le32(LVDS_GEN_CNTL); - mdelay(10); - reg |= LVDS_BLON; - aty_st_le32(LVDS_GEN_CNTL, reg); - } - reg &= ~LVDS_BL_MOD_LEVEL_MASK; - reg |= (aty128_bl_get_level_brightness(par, level) << LVDS_BL_MOD_LEVEL_SHIFT); -#ifdef BACKLIGHT_LVDS_OFF - reg |= LVDS_ON | LVDS_EN; - reg &= ~LVDS_DISPLAY_DIS; -#endif - aty_st_le32(LVDS_GEN_CNTL, reg); -#ifdef BACKLIGHT_DAC_OFF - aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN)); -#endif - } else { - reg &= ~LVDS_BL_MOD_LEVEL_MASK; - reg |= (aty128_bl_get_level_brightness(par, 0) << LVDS_BL_MOD_LEVEL_SHIFT); -#ifdef BACKLIGHT_LVDS_OFF - reg |= LVDS_DISPLAY_DIS; - aty_st_le32(LVDS_GEN_CNTL, reg); - aty_ld_le32(LVDS_GEN_CNTL); - udelay(10); - reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION); -#endif - aty_st_le32(LVDS_GEN_CNTL, reg); -#ifdef BACKLIGHT_DAC_OFF - aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN); -#endif - } - - return 0; -} - -static int aty128_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props->brightness; -} - -static struct backlight_properties aty128_bl_data = { - .owner = THIS_MODULE, - .get_brightness = aty128_bl_get_brightness, - .update_status = aty128_bl_update_status, - .max_brightness = (FB_BACKLIGHT_LEVELS - 1), -}; - -static void aty128_bl_init(struct aty128fb_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - struct backlight_device *bd; - char name[12]; - - /* Could be extended to Rage128Pro LVDS output too */ - if (par->chip_gen != rage_M3) - return; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (!pmac_has_backlight_type("ati")) - return; -#endif - - snprintf(name, sizeof(name), "aty128bl%d", info->node); - - bd = backlight_device_register(name, par, &aty128_bl_data); - if (IS_ERR(bd)) { - info->bl_dev = NULL; - printk("aty128: Backlight registration failed\n"); - goto error; - } - - mutex_lock(&info->bl_mutex); - info->bl_dev = bd; - fb_bl_default_curve(info, 0, - 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, - 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); - mutex_unlock(&info->bl_mutex); - - up(&bd->sem); - bd->props->brightness = aty128_bl_data.max_brightness; - bd->props->power = FB_BLANK_UNBLANK; - bd->props->update_status(bd); - down(&bd->sem); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - if (!pmac_backlight) - pmac_backlight = bd; - mutex_unlock(&pmac_backlight_mutex); -#endif - - printk("aty128: Backlight initialized (%s)\n", name); - - return; - -error: - return; -} - -static void aty128_bl_exit(struct aty128fb_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); -#endif - - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { -#ifdef CONFIG_PMAC_BACKLIGHT - if (pmac_backlight == info->bl_dev) - pmac_backlight = NULL; -#endif - - backlight_device_unregister(info->bl_dev); - info->bl_dev = NULL; - - printk("aty128: Backlight unloaded\n"); - } - mutex_unlock(&info->bl_mutex); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_unlock(&pmac_backlight_mutex); -#endif -} -#endif /* CONFIG_FB_ATY128_BACKLIGHT */ /* * Initialisation @@ -1893,7 +1708,7 @@ static void aty128_early_resume(void *data) } #endif /* CONFIG_PPC_PMAC */ -static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info = pci_get_drvdata(pdev); struct aty128fb_par *par = info->par; @@ -2020,15 +1835,17 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i if (register_framebuffer(info) < 0) return 0; +#ifdef CONFIG_PMAC_BACKLIGHT + /* Could be extended to Rage128Pro LVDS output too */ + if (par->chip_gen == rage_M3) + register_backlight_controller(&aty128_backlight_controller, par, "ati"); +#endif /* CONFIG_PMAC_BACKLIGHT */ + par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); par->pdev = pdev; par->asleep = 0; par->lock_blank = 0; - -#ifdef CONFIG_FB_ATY128_BACKLIGHT - aty128_bl_init(par); -#endif - + printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", info->node, info->fix.id, video_card); @@ -2037,7 +1854,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i #ifdef CONFIG_PCI /* register a card ++ajoshi */ -static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long fb_addr, reg_addr; struct aty128fb_par *par; @@ -2164,10 +1981,6 @@ static void __devexit aty128_remove(struct pci_dev *pdev) par = info->par; -#ifdef CONFIG_FB_ATY128_BACKLIGHT - aty128_bl_exit(par); -#endif - unregister_framebuffer(info); #ifdef CONFIG_MTRR if (par->mtrr.vram_valid) @@ -2198,14 +2011,10 @@ static int aty128fb_blank(int blank, struct fb_info *fb) if (par->lock_blank || par->asleep) return 0; -#ifdef CONFIG_FB_ATY128_BACKLIGHT - if (machine_is(powermac) && blank) { - down(&fb->bl_dev->sem); - fb->bl_dev->props->power = FB_BLANK_POWERDOWN; - fb->bl_dev->props->update_status(fb->bl_dev); - up(&fb->bl_dev->sem); - } -#endif +#ifdef CONFIG_PMAC_BACKLIGHT + if (machine_is(powermac) && blank) + set_backlight_enable(0); +#endif /* CONFIG_PMAC_BACKLIGHT */ if (blank & FB_BLANK_VSYNC_SUSPEND) state |= 2; @@ -2220,14 +2029,10 @@ static int aty128fb_blank(int blank, struct fb_info *fb) aty128_set_crt_enable(par, par->crt_on && !blank); aty128_set_lcd_enable(par, par->lcd_on && !blank); } -#ifdef CONFIG_FB_ATY128_BACKLIGHT - if (machine_is(powermac) && !blank) { - down(&fb->bl_dev->sem); - fb->bl_dev->props->power = FB_BLANK_UNBLANK; - fb->bl_dev->props->update_status(fb->bl_dev); - up(&fb->bl_dev->sem); - } -#endif +#ifdef CONFIG_PMAC_BACKLIGHT + if (machine_is(powermac) && !blank) + set_backlight_enable(1); +#endif /* CONFIG_PMAC_BACKLIGHT */ return 0; } @@ -2333,6 +2138,73 @@ static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg) return -EINVAL; } +#ifdef CONFIG_PMAC_BACKLIGHT +static int backlight_conv[] = { + 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e, + 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24 +}; + +/* We turn off the LCD completely instead of just dimming the backlight. + * This provides greater power saving and the display is useless without + * backlight anyway + */ +#define BACKLIGHT_LVDS_OFF +/* That one prevents proper CRT output with LCD off */ +#undef BACKLIGHT_DAC_OFF + +static int aty128_set_backlight_enable(int on, int level, void *data) +{ + struct aty128fb_par *par = data; + unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); + + if (!par->lcd_on) + on = 0; + reg |= LVDS_BL_MOD_EN | LVDS_BLON; + if (on && level > BACKLIGHT_OFF) { + reg |= LVDS_DIGION; + if (!(reg & LVDS_ON)) { + reg &= ~LVDS_BLON; + aty_st_le32(LVDS_GEN_CNTL, reg); + (void)aty_ld_le32(LVDS_GEN_CNTL); + mdelay(10); + reg |= LVDS_BLON; + aty_st_le32(LVDS_GEN_CNTL, reg); + } + reg &= ~LVDS_BL_MOD_LEVEL_MASK; + reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT); +#ifdef BACKLIGHT_LVDS_OFF + reg |= LVDS_ON | LVDS_EN; + reg &= ~LVDS_DISPLAY_DIS; +#endif + aty_st_le32(LVDS_GEN_CNTL, reg); +#ifdef BACKLIGHT_DAC_OFF + aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN)); +#endif + } else { + reg &= ~LVDS_BL_MOD_LEVEL_MASK; + reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT); +#ifdef BACKLIGHT_LVDS_OFF + reg |= LVDS_DISPLAY_DIS; + aty_st_le32(LVDS_GEN_CNTL, reg); + (void)aty_ld_le32(LVDS_GEN_CNTL); + udelay(10); + reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION); +#endif + aty_st_le32(LVDS_GEN_CNTL, reg); +#ifdef BACKLIGHT_DAC_OFF + aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN); +#endif + } + + return 0; +} + +static int aty128_set_backlight_level(int level, void* data) +{ + return aty128_set_backlight_enable(1, level, data); +} +#endif /* CONFIG_PMAC_BACKLIGHT */ + #if 0 /* * Accelerated functions @@ -2556,7 +2428,7 @@ static int aty128_pci_resume(struct pci_dev *pdev) } -static int __devinit aty128fb_init(void) +static int __init aty128fb_init(void) { #ifndef MODULE char *option = NULL; diff --git a/trunk/drivers/video/aty/atyfb.h b/trunk/drivers/video/aty/atyfb.h index 43d2cb58af87..e9b7a64c1ac4 100644 --- a/trunk/drivers/video/aty/atyfb.h +++ b/trunk/drivers/video/aty/atyfb.h @@ -151,7 +151,6 @@ struct atyfb_par { int lock_blank; unsigned long res_start; unsigned long res_size; - struct pci_dev *pdev; #ifdef __sparc__ struct pci_mmap_map *mmap_map; u8 mmaped; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 22e720611bf6..d9d7d3c4cae2 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -66,7 +66,6 @@ #include #include #include -#include #include #include @@ -316,12 +315,12 @@ static int vram; static int pll; static int mclk; static int xclk; -static int comp_sync __devinitdata = -1; +static int comp_sync __initdata = -1; static char *mode; #ifdef CONFIG_PPC -static int default_vmode __devinitdata = VMODE_CHOOSE; -static int default_cmode __devinitdata = CMODE_CHOOSE; +static int default_vmode __initdata = VMODE_CHOOSE; +static int default_cmode __initdata = CMODE_CHOOSE; module_param_named(vmode, default_vmode, int, 0); MODULE_PARM_DESC(vmode, "int: video mode for mac"); @@ -330,10 +329,10 @@ MODULE_PARM_DESC(cmode, "int: color mode for mac"); #endif #ifdef CONFIG_ATARI -static unsigned int mach64_count __devinitdata = 0; -static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, }; -static unsigned long phys_size[FB_MAX] __devinitdata = { 0, }; -static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; +static unsigned int mach64_count __initdata = 0; +static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, }; +static unsigned long phys_size[FB_MAX] __initdata = { 0, }; +static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; #endif /* top -> down is an evolution of mach64 chipset, any corrections? */ @@ -583,7 +582,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p * Apple monitor sense */ -static int __devinit read_aty_sense(const struct atyfb_par *par) +static int __init read_aty_sense(const struct atyfb_par *par) { int sense, i; @@ -1281,14 +1280,6 @@ static int atyfb_set_par(struct fb_info *info) par->accel_flags = var->accel_flags; /* hack */ - if (var->accel_flags) { - info->fbops->fb_sync = atyfb_sync; - info->flags &= ~FBINFO_HWACCEL_DISABLED; - } else { - info->fbops->fb_sync = NULL; - info->flags |= FBINFO_HWACCEL_DISABLED; - } - if (par->blitter_may_be_busy) wait_for_idle(par); @@ -2124,144 +2115,47 @@ static int atyfb_pci_resume(struct pci_dev *pdev) #endif /* defined(CONFIG_PM) && defined(CONFIG_PCI) */ -/* Backlight */ -#ifdef CONFIG_FB_ATY_BACKLIGHT -#define MAX_LEVEL 0xFF - -static struct backlight_properties aty_bl_data; - -static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - int atylevel; - - /* Get and convert the value */ - mutex_lock(&info->bl_mutex); - atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; - mutex_unlock(&info->bl_mutex); +#ifdef CONFIG_PMAC_BACKLIGHT - if (atylevel < 0) - atylevel = 0; - else if (atylevel > MAX_LEVEL) - atylevel = MAX_LEVEL; + /* + * LCD backlight control + */ - return atylevel; -} +static int backlight_conv[] = { + 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d, + 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff +}; -static int aty_bl_update_status(struct backlight_device *bd) +static int aty_set_backlight_enable(int on, int level, void *data) { - struct atyfb_par *par = class_get_devdata(&bd->class_dev); + struct fb_info *info = (struct fb_info *) data; + struct atyfb_par *par = (struct atyfb_par *) info->par; unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); - int level; - - if (bd->props->power != FB_BLANK_UNBLANK || - bd->props->fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props->brightness; reg |= (BLMOD_EN | BIASMOD_EN); - if (level > 0) { + if (on && level > BACKLIGHT_OFF) { reg &= ~BIAS_MOD_LEVEL_MASK; - reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT); + reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT); } else { reg &= ~BIAS_MOD_LEVEL_MASK; - reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT); + reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT); } aty_st_lcd(LCD_MISC_CNTL, reg, par); - return 0; } -static int aty_bl_get_brightness(struct backlight_device *bd) +static int aty_set_backlight_level(int level, void *data) { - return bd->props->brightness; + return aty_set_backlight_enable(1, level, data); } -static struct backlight_properties aty_bl_data = { - .owner = THIS_MODULE, - .get_brightness = aty_bl_get_brightness, - .update_status = aty_bl_update_status, - .max_brightness = (FB_BACKLIGHT_LEVELS - 1), +static struct backlight_controller aty_backlight_controller = { + aty_set_backlight_enable, + aty_set_backlight_level }; +#endif /* CONFIG_PMAC_BACKLIGHT */ -static void aty_bl_init(struct atyfb_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - struct backlight_device *bd; - char name[12]; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (!pmac_has_backlight_type("ati")) - return; -#endif - - snprintf(name, sizeof(name), "atybl%d", info->node); - - bd = backlight_device_register(name, par, &aty_bl_data); - if (IS_ERR(bd)) { - info->bl_dev = NULL; - printk("aty: Backlight registration failed\n"); - goto error; - } - - mutex_lock(&info->bl_mutex); - info->bl_dev = bd; - fb_bl_default_curve(info, 0, - 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, - 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); - mutex_unlock(&info->bl_mutex); - - up(&bd->sem); - bd->props->brightness = aty_bl_data.max_brightness; - bd->props->power = FB_BLANK_UNBLANK; - bd->props->update_status(bd); - down(&bd->sem); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - if (!pmac_backlight) - pmac_backlight = bd; - mutex_unlock(&pmac_backlight_mutex); -#endif - - printk("aty: Backlight initialized (%s)\n", name); - - return; - -error: - return; -} - -static void aty_bl_exit(struct atyfb_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); -#endif - - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { -#ifdef CONFIG_PMAC_BACKLIGHT - if (pmac_backlight == info->bl_dev) - pmac_backlight = NULL; -#endif - - backlight_device_unregister(info->bl_dev); - - printk("aty: Backlight unloaded\n"); - } - mutex_unlock(&info->bl_mutex); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_unlock(&pmac_backlight_mutex); -#endif -} - -#endif /* CONFIG_FB_ATY_BACKLIGHT */ - -static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) +static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) { const int ragepro_tbl[] = { 44, 50, 55, 66, 75, 80, 100 @@ -2321,7 +2215,7 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par, } #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ -static int __devinit aty_init(struct fb_info *info, const char *name) +static int __init aty_init(struct fb_info *info, const char *name) { struct atyfb_par *par = (struct atyfb_par *) info->par; const char *ramname = NULL, *xtal; @@ -2402,15 +2296,12 @@ static int __devinit aty_init(struct fb_info *info, const char *name) break; } switch (clk_type) { -#ifdef CONFIG_ATARI case CLK_ATI18818_1: par->pll_ops = &aty_pll_ati18818_1; break; -#else case CLK_IBMRGB514: par->pll_ops = &aty_pll_ibm514; break; -#endif #if 0 /* dead code */ case CLK_STG1703: par->pll_ops = &aty_pll_stg1703; @@ -2615,24 +2506,16 @@ static int __devinit aty_init(struct fb_info *info, const char *name) info->fbops = &atyfb_ops; info->pseudo_palette = pseudo_palette; - info->flags = FBINFO_DEFAULT | - FBINFO_HWACCEL_IMAGEBLIT | - FBINFO_HWACCEL_FILLRECT | - FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_YPAN; + info->flags = FBINFO_FLAG_DEFAULT; #ifdef CONFIG_PMAC_BACKLIGHT if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { /* these bits let the 101 powerbook wake up from sleep -- paulus */ aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | (USE_F32KHZ | TRISTATE_MEM_EN), par); - } else -#endif - if (M64_HAS(MOBIL_BUS)) { -#ifdef CONFIG_FB_ATY_BACKLIGHT - aty_bl_init (par); -#endif - } + } else if (M64_HAS(MOBIL_BUS)) + register_backlight_controller(&aty_backlight_controller, info, "ati"); +#endif /* CONFIG_PMAC_BACKLIGHT */ memset(&var, 0, sizeof(var)); #ifdef CONFIG_PPC @@ -2748,7 +2631,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name) } #ifdef CONFIG_ATARI -static int __devinit store_video_par(char *video_str, unsigned char m64_num) +static int __init store_video_par(char *video_str, unsigned char m64_num) { char *p; unsigned long vmembase, size, guiregbase; @@ -2791,16 +2674,8 @@ static int atyfb_blank(int blank, struct fb_info *info) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank > FB_BLANK_NORMAL) { - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = FB_BLANK_POWERDOWN; - info->bl_dev->props->update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - mutex_unlock(&info->bl_mutex); - } + if (machine_is(powermac) && blank > FB_BLANK_NORMAL) + set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank > FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { @@ -2831,16 +2706,8 @@ static int atyfb_blank(int blank, struct fb_info *info) aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) { - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = FB_BLANK_UNBLANK; - info->bl_dev->props->update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - mutex_unlock(&info->bl_mutex); - } + if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) + set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank <= FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { @@ -3099,7 +2966,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, } pcp = pdev->sysdata; - if (node == pcp->prom_node->node) { + if (node == pcp->prom_node) { struct fb_var_screeninfo *var = &default_var; unsigned int N, P, Q, M, T, R; u32 v_total, h_total; @@ -3573,7 +3440,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi par->res_start = res_start; par->res_size = res_size; par->irq = pdev->irq; - par->pdev = pdev; /* Setup "info" structure */ #ifdef __sparc__ @@ -3705,11 +3571,6 @@ static void __devexit atyfb_remove(struct fb_info *info) aty_set_crtc(par, &saved_crtc); par->pll_ops->set_pll(info, &saved_pll); -#ifdef CONFIG_FB_ATY_BACKLIGHT - if (M64_HAS(MOBIL_BUS)) - aty_bl_exit(par); -#endif - unregister_framebuffer(info); #ifdef CONFIG_MTRR @@ -3779,7 +3640,7 @@ static struct pci_driver atyfb_driver = { #endif /* CONFIG_PCI */ #ifndef MODULE -static int __devinit atyfb_setup(char *options) +static int __init atyfb_setup(char *options) { char *this_opt; @@ -3851,7 +3712,7 @@ static int __devinit atyfb_setup(char *options) } #endif /* MODULE */ -static int __devinit atyfb_init(void) +static int __init atyfb_init(void) { #ifndef MODULE char *option = NULL; @@ -3861,9 +3722,7 @@ static int __devinit atyfb_init(void) atyfb_setup(option); #endif -#ifdef CONFIG_PCI pci_register_driver(&atyfb_driver); -#endif #ifdef CONFIG_ATARI atyfb_atari_probe(); #endif @@ -3872,9 +3731,7 @@ static int __devinit atyfb_init(void) static void __exit atyfb_exit(void) { -#ifdef CONFIG_PCI pci_unregister_driver(&atyfb_driver); -#endif } module_init(atyfb_init); diff --git a/trunk/drivers/video/aty/mach64_accel.c b/trunk/drivers/video/aty/mach64_accel.c index 1490e5e1c232..c98f4a442134 100644 --- a/trunk/drivers/video/aty/mach64_accel.c +++ b/trunk/drivers/video/aty/mach64_accel.c @@ -200,6 +200,8 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) if (!area->width || !area->height) return; if (!par->accel_flags) { + if (par->blitter_may_be_busy) + wait_for_idle(par); cfb_copyarea(info, area); return; } @@ -246,6 +248,8 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) if (!rect->width || !rect->height) return; if (!par->accel_flags) { + if (par->blitter_may_be_busy) + wait_for_idle(par); cfb_fillrect(info, rect); return; } @@ -284,10 +288,14 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) return; if (!par->accel_flags || (image->depth != 1 && info->var.bits_per_pixel != image->depth)) { + if (par->blitter_may_be_busy) + wait_for_idle(par); + cfb_imageblit(info, image); return; } + wait_for_idle(par); pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; @@ -417,6 +425,8 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) } } + wait_for_idle(par); + /* restore pix_width */ wait_for_fifo(1, par); aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); diff --git a/trunk/drivers/video/aty/mach64_cursor.c b/trunk/drivers/video/aty/mach64_cursor.c index 2a7f381c330f..ad8b7496f853 100644 --- a/trunk/drivers/video/aty/mach64_cursor.c +++ b/trunk/drivers/video/aty/mach64_cursor.c @@ -66,6 +66,11 @@ static const u8 cursor_bits_lookup[16] = { 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55 }; +static const u8 cursor_mask_lookup[16] = { + 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02, + 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00 +}; + static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct atyfb_par *par = (struct atyfb_par *) info->par; @@ -125,13 +130,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) fg_idx = cursor->image.fg_color; bg_idx = cursor->image.bg_color; - fg = ((info->cmap.red[fg_idx] & 0xff) << 24) | - ((info->cmap.green[fg_idx] & 0xff) << 16) | - ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff; + fg = (info->cmap.red[fg_idx] << 24) | + (info->cmap.green[fg_idx] << 16) | + (info->cmap.blue[fg_idx] << 8) | 15; - bg = ((info->cmap.red[bg_idx] & 0xff) << 24) | - ((info->cmap.green[bg_idx] & 0xff) << 16) | - ((info->cmap.blue[bg_idx] & 0xff) << 8); + bg = (info->cmap.red[bg_idx] << 24) | + (info->cmap.green[bg_idx] << 16) | + (info->cmap.blue[bg_idx] << 8); wait_for_fifo(2, par); aty_st_le32(CUR_CLR0, bg, par); @@ -161,17 +166,19 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: // Upper 4 bits of mask data - fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++); + fb_writeb(cursor_mask_lookup[m >> 4 ] | + cursor_bits_lookup[(b ^ m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f], - dst++); + fb_writeb(cursor_mask_lookup[m & 0x0f ] | + cursor_bits_lookup[(b ^ m) & 0x0f], dst++); break; case ROP_COPY: // Upper 4 bits of mask data - fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++); + fb_writeb(cursor_mask_lookup[m >> 4 ] | + cursor_bits_lookup[(b & m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_bits_lookup[(b & m) & 0x0f], - dst++); + fb_writeb(cursor_mask_lookup[m & 0x0f ] | + cursor_bits_lookup[(b & m) & 0x0f], dst++); break; } } @@ -187,7 +194,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) return 0; } -int __devinit aty_init_cursor(struct fb_info *info) +int __init aty_init_cursor(struct fb_info *info) { unsigned long addr; diff --git a/trunk/drivers/video/aty/radeon_backlight.c b/trunk/drivers/video/aty/radeon_backlight.c deleted file mode 100644 index 7de66b855d4e..000000000000 --- a/trunk/drivers/video/aty/radeon_backlight.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Backlight code for ATI Radeon based graphic cards - * - * Copyright (c) 2000 Ani Joshi - * Copyright (c) 2003 Benjamin Herrenschmidt - * Copyright (c) 2006 Michael Hanselmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include "radeonfb.h" -#include - -#ifdef CONFIG_PMAC_BACKLIGHT -#include -#endif - -#define MAX_RADEON_LEVEL 0xFF - -static struct backlight_properties radeon_bl_data; - -struct radeon_bl_privdata { - struct radeonfb_info *rinfo; - uint8_t negative; -}; - -static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, - int level) -{ - struct fb_info *info = pdata->rinfo->info; - int rlevel; - - mutex_lock(&info->bl_mutex); - - /* Get and convert the value */ - rlevel = pdata->rinfo->info->bl_curve[level] * - FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; - - mutex_unlock(&info->bl_mutex); - - if (pdata->negative) - rlevel = MAX_RADEON_LEVEL - rlevel; - - if (rlevel < 0) - rlevel = 0; - else if (rlevel > MAX_RADEON_LEVEL) - rlevel = MAX_RADEON_LEVEL; - - return rlevel; -} - -static int radeon_bl_update_status(struct backlight_device *bd) -{ - struct radeon_bl_privdata *pdata = class_get_devdata(&bd->class_dev); - struct radeonfb_info *rinfo = pdata->rinfo; - u32 lvds_gen_cntl, tmpPixclksCntl; - int level; - - if (rinfo->mon1_type != MT_LCD) - return 0; - - /* We turn off the LCD completely instead of just dimming the - * backlight. This provides some greater power saving and the display - * is useless without backlight anyway. - */ - if (bd->props->power != FB_BLANK_UNBLANK || - bd->props->fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props->brightness; - - del_timer_sync(&rinfo->lvds_timer); - radeon_engine_idle(); - - lvds_gen_cntl = INREG(LVDS_GEN_CNTL); - if (level > 0) { - lvds_gen_cntl &= ~LVDS_DISPLAY_DIS; - if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) { - lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON); - lvds_gen_cntl |= LVDS_BLON | LVDS_EN; - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= - (radeon_bl_get_level_brightness(pdata, level) << - LVDS_BL_MOD_LEVEL_SHIFT); - lvds_gen_cntl |= LVDS_ON; - lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN); - rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; - mod_timer(&rinfo->lvds_timer, - jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); - } else { - lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= - (radeon_bl_get_level_brightness(pdata, level) << - LVDS_BL_MOD_LEVEL_SHIFT); - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - } - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl - & LVDS_STATE_MASK; - } else { - /* Asic bug, when turning off LVDS_ON, we have to make sure - RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - tmpPixclksCntl = INPLL(PIXCLKS_CNTL); - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); - lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN); - lvds_gen_cntl |= (radeon_bl_get_level_brightness(pdata, 0) << - LVDS_BL_MOD_LEVEL_SHIFT); - lvds_gen_cntl |= LVDS_DISPLAY_DIS; - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - udelay(100); - lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN); - OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); - lvds_gen_cntl &= ~(LVDS_DIGON); - rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; - mod_timer(&rinfo->lvds_timer, - jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); - if (rinfo->is_mobility || rinfo->is_IGP) - OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl); - } - rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; - rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK); - - return 0; -} - -static int radeon_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props->brightness; -} - -static struct backlight_properties radeon_bl_data = { - .owner = THIS_MODULE, - .get_brightness = radeon_bl_get_brightness, - .update_status = radeon_bl_update_status, - .max_brightness = (FB_BACKLIGHT_LEVELS - 1), -}; - -void radeonfb_bl_init(struct radeonfb_info *rinfo) -{ - struct backlight_device *bd; - struct radeon_bl_privdata *pdata; - char name[12]; - - if (rinfo->mon1_type != MT_LCD) - return; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (!pmac_has_backlight_type("ati") && - !pmac_has_backlight_type("mnca")) - return; -#endif - - pdata = kmalloc(sizeof(struct radeon_bl_privdata), GFP_KERNEL); - if (!pdata) { - printk("radeonfb: Memory allocation failed\n"); - goto error; - } - - snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); - - bd = backlight_device_register(name, pdata, &radeon_bl_data); - if (IS_ERR(bd)) { - rinfo->info->bl_dev = NULL; - printk("radeonfb: Backlight registration failed\n"); - goto error; - } - - pdata->rinfo = rinfo; - - /* Pardon me for that hack... maybe some day we can figure out in what - * direction backlight should work on a given panel? - */ - pdata->negative = - (rinfo->family != CHIP_FAMILY_RV200 && - rinfo->family != CHIP_FAMILY_RV250 && - rinfo->family != CHIP_FAMILY_RV280 && - rinfo->family != CHIP_FAMILY_RV350); - -#ifdef CONFIG_PMAC_BACKLIGHT - pdata->negative = pdata->negative || - machine_is_compatible("PowerBook4,3") || - machine_is_compatible("PowerBook6,3") || - machine_is_compatible("PowerBook6,5"); -#endif - - mutex_lock(&rinfo->info->bl_mutex); - rinfo->info->bl_dev = bd; - fb_bl_default_curve(rinfo->info, 0, - 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, - 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); - mutex_unlock(&rinfo->info->bl_mutex); - - up(&bd->sem); - bd->props->brightness = radeon_bl_data.max_brightness; - bd->props->power = FB_BLANK_UNBLANK; - bd->props->update_status(bd); - down(&bd->sem); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - if (!pmac_backlight) - pmac_backlight = bd; - mutex_unlock(&pmac_backlight_mutex); -#endif - - printk("radeonfb: Backlight initialized (%s)\n", name); - - return; - -error: - kfree(pdata); - return; -} - -void radeonfb_bl_exit(struct radeonfb_info *rinfo) -{ -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); -#endif - - mutex_lock(&rinfo->info->bl_mutex); - if (rinfo->info->bl_dev) { - struct radeon_bl_privdata *pdata; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (pmac_backlight == rinfo->info->bl_dev) - pmac_backlight = NULL; -#endif - - pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev); - backlight_device_unregister(rinfo->info->bl_dev); - kfree(pdata); - rinfo->info->bl_dev = NULL; - - printk("radeonfb: Backlight unloaded\n"); - } - mutex_unlock(&rinfo->info->bl_mutex); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_unlock(&pmac_backlight_mutex); -#endif -} diff --git a/trunk/drivers/video/aty/radeon_base.c b/trunk/drivers/video/aty/radeon_base.c index 68b15645b893..387a18a47ac2 100644 --- a/trunk/drivers/video/aty/radeon_base.c +++ b/trunk/drivers/video/aty/radeon_base.c @@ -78,6 +78,10 @@ #include #include "../macmodes.h" +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif + #ifdef CONFIG_BOOTX_TEXT #include #endif @@ -273,6 +277,20 @@ static int nomtrr = 0; * prototypes */ + +#ifdef CONFIG_PPC_OF + +#ifdef CONFIG_PMAC_BACKLIGHT +static int radeon_set_backlight_enable(int on, int level, void *data); +static int radeon_set_backlight_level(int level, void *data); +static struct backlight_controller radeon_backlight_controller = { + radeon_set_backlight_enable, + radeon_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ + +#endif /* CONFIG_PPC_OF */ + static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) { if (!rinfo->bios_seg) @@ -1895,6 +1913,116 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) return 0; } + +#ifdef CONFIG_PMAC_BACKLIGHT + +/* TODO: Dbl check these tables, we don't go up to full ON backlight + * in these, possibly because we noticed MacOS doesn't, but I'd prefer + * having some more official numbers from ATI + */ +static int backlight_conv_m6[] = { + 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e, + 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24 +}; +static int backlight_conv_m7[] = { + 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81, + 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9 +}; + +#define BACKLIGHT_LVDS_OFF +#undef BACKLIGHT_DAC_OFF + +/* We turn off the LCD completely instead of just dimming the backlight. + * This provides some greater power saving and the display is useless + * without backlight anyway. + */ +static int radeon_set_backlight_enable(int on, int level, void *data) +{ + struct radeonfb_info *rinfo = (struct radeonfb_info *)data; + u32 lvds_gen_cntl, tmpPixclksCntl; + int* conv_table; + + if (rinfo->mon1_type != MT_LCD) + return 0; + + /* Pardon me for that hack... maybe some day we can figure + * out in what direction backlight should work on a given + * panel ? + */ + if ((rinfo->family == CHIP_FAMILY_RV200 || + rinfo->family == CHIP_FAMILY_RV250 || + rinfo->family == CHIP_FAMILY_RV280 || + rinfo->family == CHIP_FAMILY_RV350) && + !machine_is_compatible("PowerBook4,3") && + !machine_is_compatible("PowerBook6,3") && + !machine_is_compatible("PowerBook6,5")) + conv_table = backlight_conv_m7; + else + conv_table = backlight_conv_m6; + + del_timer_sync(&rinfo->lvds_timer); + radeon_engine_idle(); + + lvds_gen_cntl = INREG(LVDS_GEN_CNTL); + if (on && (level > BACKLIGHT_OFF)) { + lvds_gen_cntl &= ~LVDS_DISPLAY_DIS; + if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) { + lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON); + lvds_gen_cntl |= LVDS_BLON | LVDS_EN; + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; + lvds_gen_cntl |= (conv_table[level] << + LVDS_BL_MOD_LEVEL_SHIFT); + lvds_gen_cntl |= LVDS_ON; + lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN); + rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; + mod_timer(&rinfo->lvds_timer, + jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + } else { + lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; + lvds_gen_cntl |= (conv_table[level] << + LVDS_BL_MOD_LEVEL_SHIFT); + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + } + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl + & LVDS_STATE_MASK; + } else { + /* Asic bug, when turning off LVDS_ON, we have to make sure + RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + tmpPixclksCntl = INPLL(PIXCLKS_CNTL); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); + lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN); + lvds_gen_cntl |= (conv_table[0] << + LVDS_BL_MOD_LEVEL_SHIFT); + lvds_gen_cntl |= LVDS_DISPLAY_DIS; + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + udelay(100); + lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN); + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + lvds_gen_cntl &= ~(LVDS_DIGON); + rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; + mod_timer(&rinfo->lvds_timer, + jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl); + } + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK); + + return 0; +} + + +static int radeon_set_backlight_level(int level, void *data) +{ + return radeon_set_backlight_enable(1, level, data); +} +#endif /* CONFIG_PMAC_BACKLIGHT */ + + /* * This reconfigure the card's internal memory map. In theory, we'd like * to setup the card's memory at the same address as it's PCI bus address, @@ -2349,7 +2477,14 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, MTRR_TYPE_WRCOMB, 1); #endif - radeonfb_bl_init(rinfo); +#ifdef CONFIG_PMAC_BACKLIGHT + if (rinfo->mon1_type == MT_LCD) { + register_backlight_controller(&radeon_backlight_controller, + rinfo, "ati"); + register_backlight_controller(&radeon_backlight_controller, + rinfo, "mnca"); + } +#endif printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name); @@ -2379,6 +2514,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, err_release_fb: framebuffer_release(info); err_disable: + pci_disable_device(pdev); err_out: return ret; } @@ -2392,8 +2528,7 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) if (!rinfo) return; - - radeonfb_bl_exit(rinfo); + radeonfb_pm_exit(rinfo); if (rinfo->mon1_EDID) @@ -2435,6 +2570,7 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) #endif fb_dealloc_cmap(&info->cmap); framebuffer_release(info); + pci_disable_device(pdev); } diff --git a/trunk/drivers/video/aty/radeonfb.h b/trunk/drivers/video/aty/radeonfb.h index 1645943b1123..217e00ab4a2d 100644 --- a/trunk/drivers/video/aty/radeonfb.h +++ b/trunk/drivers/video/aty/radeonfb.h @@ -625,13 +625,4 @@ extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_ extern void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, int reg_only); -/* Backlight functions */ -#ifdef CONFIG_FB_RADEON_BACKLIGHT -extern void radeonfb_bl_init(struct radeonfb_info *rinfo); -extern void radeonfb_bl_exit(struct radeonfb_info *rinfo); -#else -static inline void radeonfb_bl_init(struct radeonfb_info *rinfo) {} -static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {} -#endif - #endif /* __RADEONFB_H__ */ diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index 9ef68cd83bb4..789450bb0bc9 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -7,8 +7,6 @@ * Karl Lessard * * - * PM support added by Rodolfo Giometti - * * Copyright 2002 MontaVista Software * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com @@ -604,52 +602,17 @@ int au1100fb_drv_remove(struct device *dev) return 0; } -#ifdef CONFIG_PM -static u32 sys_clksrc; -static struct au1100fb_regs fbregs; - int au1100fb_drv_suspend(struct device *dev, pm_message_t state) { - struct au1100fb_device *fbdev = dev_get_drvdata(dev); - - if (!fbdev) - return 0; - - /* Save the clock source state */ - sys_clksrc = au_readl(SYS_CLKSRC); - - /* Blank the LCD */ - au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); - - /* Stop LCD clocking */ - au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); - - memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); - + /* TODO */ return 0; } int au1100fb_drv_resume(struct device *dev) { - struct au1100fb_device *fbdev = dev_get_drvdata(dev); - - if (!fbdev) - return 0; - - memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); - - /* Restart LCD clocking */ - au_writel(sys_clksrc, SYS_CLKSRC); - - /* Unblank the LCD */ - au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); - + /* TODO */ return 0; } -#else -#define au1100fb_drv_suspend NULL -#define au1100fb_drv_resume NULL -#endif static struct device_driver au1100fb_driver = { .name = "au1100-lcd", @@ -743,7 +706,8 @@ void __exit au1100fb_cleanup(void) { driver_unregister(&au1100fb_driver); - kfree(drv_info.opt_mode); + if (drv_info.opt_mode) + kfree(drv_info.opt_mode); } module_init(au1100fb_init); diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 022f9d3473f5..b895eaaa73fd 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT && FB + depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of the LCD @@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT && FB + depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of LCD. @@ -50,14 +50,6 @@ config BACKLIGHT_CORGI If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the backlight driver. -config BACKLIGHT_LOCOMO - tristate "Sharp LOCOMO LCD/Backlight Driver" - depends on BACKLIGHT_DEVICE && SHARP_LOCOMO - default y - help - If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to - enable the LCD/backlight driver. - config BACKLIGHT_HP680 tristate "HP Jornada 680 Backlight Driver" depends on BACKLIGHT_DEVICE && SH_HP6XX diff --git a/trunk/drivers/video/backlight/Makefile b/trunk/drivers/video/backlight/Makefile index 65e5553fc849..744210c38e74 100644 --- a/trunk/drivers/video/backlight/Makefile +++ b/trunk/drivers/video/backlight/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o -obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o +obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o diff --git a/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index ffc72ae3ada8..a71e984c93d4 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -27,7 +27,7 @@ static int hp680bl_suspended; static int current_intensity = 0; -static DEFINE_SPINLOCK(bl_lock); +static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; static struct backlight_device *hp680_backlight_device; static void hp680bl_send_intensity(struct backlight_device *bd) diff --git a/trunk/drivers/video/backlight/locomolcd.c b/trunk/drivers/video/backlight/locomolcd.c index bd879b7ec119..60831bb23685 100644 --- a/trunk/drivers/video/backlight/locomolcd.c +++ b/trunk/drivers/video/backlight/locomolcd.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -27,10 +25,7 @@ #include "../../../arch/arm/mach-sa1100/generic.h" -static struct backlight_device *locomolcd_bl_device; static struct locomo_dev *locomolcd_dev; -static unsigned long locomolcd_flags; -#define LOCOMOLCD_SUSPENDED 0x01 static void locomolcd_on(int comadj) { @@ -94,10 +89,12 @@ void locomolcd_power(int on) } /* read comadj */ - if (comadj == -1 && machine_is_collie()) - comadj = 128; - if (comadj == -1 && machine_is_poodle()) - comadj = 118; + if (comadj == -1) { + if (machine_is_poodle()) + comadj = 118; + if (machine_is_collie()) + comadj = 128; + } if (on) locomolcd_on(comadj); @@ -108,100 +105,26 @@ void locomolcd_power(int on) } EXPORT_SYMBOL(locomolcd_power); - -static int current_intensity; - -static int locomolcd_set_intensity(struct backlight_device *bd) -{ - int intensity = bd->props->brightness; - - if (bd->props->power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props->fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - if (locomolcd_flags & LOCOMOLCD_SUSPENDED) - intensity = 0; - - switch (intensity) { - /* AC and non-AC are handled differently, but produce same results in sharp code? */ - case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break; - case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break; - case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break; - case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break; - case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break; - - default: - return -ENODEV; - } - current_intensity = intensity; - return 0; -} - -static int locomolcd_get_intensity(struct backlight_device *bd) -{ - return current_intensity; -} - -static struct backlight_properties locomobl_data = { - .owner = THIS_MODULE, - .get_brightness = locomolcd_get_intensity, - .update_status = locomolcd_set_intensity, - .max_brightness = 4, -}; - -#ifdef CONFIG_PM -static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state) -{ - locomolcd_flags |= LOCOMOLCD_SUSPENDED; - locomolcd_set_intensity(locomolcd_bl_device); - return 0; -} - -static int locomolcd_resume(struct locomo_dev *dev) -{ - locomolcd_flags &= ~LOCOMOLCD_SUSPENDED; - locomolcd_set_intensity(locomolcd_bl_device); - return 0; -} -#else -#define locomolcd_suspend NULL -#define locomolcd_resume NULL -#endif - -static int locomolcd_probe(struct locomo_dev *dev) +static int poodle_lcd_probe(struct locomo_dev *dev) { unsigned long flags; local_irq_save(flags); locomolcd_dev = dev; - locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0); - /* the poodle_lcd_power function is called for the first time * from fs_initcall, which is before locomo is activated. * We need to recall poodle_lcd_power here*/ - if (machine_is_poodle()) - locomolcd_power(1); - +#ifdef CONFIG_MACH_POODLE + locomolcd_power(1); +#endif local_irq_restore(flags); - - locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data); - - if (IS_ERR (locomolcd_bl_device)) - return PTR_ERR (locomolcd_bl_device); - - /* Set up frontlight so that screen is readable */ - locomobl_data.brightness = 2; - locomolcd_set_intensity(locomolcd_bl_device); - return 0; } -static int locomolcd_remove(struct locomo_dev *dev) +static int poodle_lcd_remove(struct locomo_dev *dev) { unsigned long flags; - - backlight_device_unregister(locomolcd_bl_device); local_irq_save(flags); locomolcd_dev = NULL; local_irq_restore(flags); @@ -213,33 +136,19 @@ static struct locomo_driver poodle_lcd_driver = { .name = "locomo-backlight", }, .devid = LOCOMO_DEVID_BACKLIGHT, - .probe = locomolcd_probe, - .remove = locomolcd_remove, - .suspend = locomolcd_suspend, - .resume = locomolcd_resume, + .probe = poodle_lcd_probe, + .remove = poodle_lcd_remove, }; - -static int __init locomolcd_init(void) +static int __init poodle_lcd_init(void) { int ret = locomo_driver_register(&poodle_lcd_driver); - if (ret) - return ret; + if (ret) return ret; #ifdef CONFIG_SA1100_COLLIE sa1100fb_lcd_power = locomolcd_power; #endif return 0; } +device_initcall(poodle_lcd_init); -static void __exit locomolcd_exit(void) -{ - locomo_driver_unregister(&poodle_lcd_driver); -} - -module_init(locomolcd_init); -module_exit(locomolcd_exit); - -MODULE_AUTHOR("John Lenz , Pavel Machek "); -MODULE_DESCRIPTION("Collie LCD driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/cfbimgblt.c b/trunk/drivers/video/cfbimgblt.c index ad8a89bf8eae..8ba6152db2fd 100644 --- a/trunk/drivers/video/cfbimgblt.c +++ b/trunk/drivers/video/cfbimgblt.c @@ -230,7 +230,6 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * tab = cfb_tab16; break; case 32: - default: tab = cfb_tab32; break; } diff --git a/trunk/drivers/video/chipsfb.c b/trunk/drivers/video/chipsfb.c index d76bbfac92cc..72ff6bf75e5e 100644 --- a/trunk/drivers/video/chipsfb.c +++ b/trunk/drivers/video/chipsfb.c @@ -148,24 +148,9 @@ static int chipsfb_set_par(struct fb_info *info) static int chipsfb_blank(int blank, struct fb_info *info) { #ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - - if (pmac_backlight) { - down(&pmac_backlight->sem); - - /* used to disable backlight only for blank > 1, but it seems - * useful at blank = 1 too (saves battery, extends backlight - * life) - */ - if (blank) - pmac_backlight->props->power = FB_BLANK_POWERDOWN; - else - pmac_backlight->props->power = FB_BLANK_UNBLANK; - pmac_backlight->props->update_status(pmac_backlight); - up(&pmac_backlight->sem); - } - - mutex_unlock(&pmac_backlight_mutex); + // used to disable backlight only for blank > 1, but it seems + // useful at blank = 1 too (saves battery, extends backlight life) + set_backlight_enable(!blank); #endif /* CONFIG_PMAC_BACKLIGHT */ return 1; /* get fb_blank to set the colormap to all black */ @@ -416,14 +401,7 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) #ifdef CONFIG_PMAC_BACKLIGHT /* turn on the backlight */ - mutex_lock(&pmac_backlight_mutex); - if (pmac_backlight) { - down(&pmac_backlight->sem); - pmac_backlight->props->power = FB_BLANK_UNBLANK; - pmac_backlight->props->update_status(pmac_backlight); - up(&pmac_backlight->sem); - } - mutex_unlock(&pmac_backlight_mutex); + set_backlight_enable(1); #endif /* CONFIG_PMAC_BACKLIGHT */ #ifdef CONFIG_PPC diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index dda240eb7360..1103010af54a 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -2227,6 +2227,7 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo) release_region(0x3C0, 32); pci_release_regions(pdev); framebuffer_release(cinfo->info); + pci_disable_device(pdev); } #endif /* CONFIG_PCI */ @@ -2457,6 +2458,7 @@ static int cirrusfb_pci_register (struct pci_dev *pdev, err_release_fb: framebuffer_release(info); err_disable: + pci_disable_device(pdev); err_out: return ret; } diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 5dc4083552d8..47ba1a79adcd 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -125,8 +125,6 @@ static int softback_lines; static int first_fb_vc; static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; -static int fbcon_has_exited; - /* font data */ static char fontname[40]; @@ -142,6 +140,7 @@ static const struct consw fb_con; #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) +static void fbcon_free_font(struct display *); static int fbcon_set_origin(struct vc_data *); #define CURSOR_DRAW_DELAY (1) @@ -195,9 +194,6 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, int line, int count, int dy); static void fbcon_modechanged(struct fb_info *info); static void fbcon_set_all_vcs(struct fb_info *info); -static void fbcon_start(void); -static void fbcon_exit(void); -static struct class_device *fbcon_class_device; #ifdef CONFIG_MAC /* @@ -256,7 +252,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) if (!ops || ops->currcon < 0 || rotate > 3) return; - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -393,18 +389,15 @@ static void fb_flashcursor(void *private) int c; int mode; - acquire_console_sem(); - if (ops && ops->currcon != -1) + if (ops->currcon != -1) vc = vc_cons[ops->currcon].d; if (!vc || !CON_IS_VISIBLE(vc) || fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info || - vc_cons[ops->currcon].d->vc_deccm != 1) { - release_console_sem(); + vc_cons[ops->currcon].d->vc_deccm != 1) return; - } - + acquire_console_sem(); p = &fb_display[vc->vc_num]; c = scr_readw((u16 *) vc->vc_pos); mode = (!ops->cursor_flash || ops->cursor_state.enable) ? @@ -535,7 +528,7 @@ static int search_fb_in_map(int idx) { int i, retval = 0; - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (con2fb_map[i] == idx) retval = 1; } @@ -546,7 +539,7 @@ static int search_for_mapped_con(void) { int i, retval = 0; - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (con2fb_map[i] != -1) retval = 1; } @@ -568,7 +561,6 @@ static int fbcon_takeover(int show_logo) err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); - if (err) { for (i = first_fb_vc; i <= last_fb_vc; i++) { con2fb_map[i] = -1; @@ -803,8 +795,8 @@ static int set_con2fb_map(int unit, int newidx, int user) if (oldidx == newidx) return 0; - if (!info || fbcon_has_exited) - return -EINVAL; + if (!info) + err = -EINVAL; if (!err && !search_for_mapped_con()) { info_idx = newidx; @@ -840,9 +832,6 @@ static int set_con2fb_map(int unit, int newidx, int user) con2fb_init_display(vc, info, unit, show_logo); } - if (!search_fb_in_map(info_idx)) - info_idx = newidx; - release_console_sem(); return err; } @@ -1045,7 +1034,6 @@ static const char *fbcon_startup(void) #endif /* CONFIG_MAC */ fbcon_add_cursor_timer(info); - fbcon_has_exited = 0; return display_desc; } @@ -1073,36 +1061,17 @@ static void fbcon_init(struct vc_data *vc, int init) /* If we are not the first console on this fb, copy the font from that console */ - t = &fb_display[fg_console]; - if (!p->fontdata) { - if (t->fontdata) { - struct vc_data *fvc = vc_cons[fg_console].d; - - vc->vc_font.data = (void *)(p->fontdata = - fvc->vc_font.data); - vc->vc_font.width = fvc->vc_font.width; - vc->vc_font.height = fvc->vc_font.height; - p->userfont = t->userfont; - - if (p->userfont) - REFCOUNT(p->fontdata)++; - } else { - const struct font_desc *font = NULL; - - if (!fontname[0] || !(font = find_font(fontname))) - font = get_default_font(info->var.xres, - info->var.yres); - vc->vc_font.width = font->width; - vc->vc_font.height = font->height; - vc->vc_font.data = (void *)(p->fontdata = font->data); - vc->vc_font.charcount = 256; /* FIXME Need to - support more fonts */ - } + t = &fb_display[svc->vc_num]; + if (!vc->vc_font.data) { + vc->vc_font.data = (void *)(p->fontdata = t->fontdata); + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; } - if (p->userfont) charcnt = FNTCHARCNT(p->fontdata); - vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -1176,47 +1145,13 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } -static void fbcon_free_font(struct display *p) -{ - if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) - kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); - p->fontdata = NULL; - p->userfont = 0; -} - static void fbcon_deinit(struct vc_data *vc) { struct display *p = &fb_display[vc->vc_num]; - struct fb_info *info; - struct fbcon_ops *ops; - int idx; + if (info_idx != -1) + return; fbcon_free_font(p); - idx = con2fb_map[vc->vc_num]; - - if (idx == -1) - goto finished; - - info = registered_fb[idx]; - - if (!info) - goto finished; - - ops = info->fbcon_par; - - if (!ops) - goto finished; - - if (CON_IS_VISIBLE(vc)) - fbcon_del_cursor_timer(info); - - ops->flags &= ~FBCON_FLAGS_INIT; -finished: - - if (!con_is_bound(&fb_con)) - fbcon_exit(); - - return; } /* ====================================================================== */ @@ -2164,11 +2099,12 @@ static int fbcon_switch(struct vc_data *vc) if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); - if (old_info != info) + if (old_info != info) { fbcon_del_cursor_timer(old_info); + fbcon_add_cursor_timer(info); + } } - fbcon_add_cursor_timer(info); set_blitting_type(vc, info); ops->cursor_reset = 1; @@ -2286,6 +2222,14 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) return 0; } +static void fbcon_free_font(struct display *p) +{ + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +} + static int fbcon_get_font(struct vc_data *vc, struct console_font *font) { u8 *fontdata = vc->vc_font.data; @@ -2499,7 +2443,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne FNTSUM(new_data) = csum; /* Check if the same font is on some other console already */ - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { struct vc_data *tmp = vc_cons[i].d; if (fb_display[i].userfont && @@ -2824,7 +2768,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) if (!ops || ops->currcon < 0) return; - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -2886,57 +2830,22 @@ static int fbcon_mode_deleted(struct fb_info *info, return found; } -static int fbcon_fb_unregistered(int idx) -{ - int i; - - for (i = first_fb_vc; i <= last_fb_vc; i++) { - if (con2fb_map[i] == idx) - con2fb_map[i] = -1; - } - - if (idx == info_idx) { - info_idx = -1; - - for (i = 0; i < FB_MAX; i++) { - if (registered_fb[i] != NULL) { - info_idx = i; - break; - } - } - } - - if (info_idx != -1) { - for (i = first_fb_vc; i <= last_fb_vc; i++) { - if (con2fb_map[i] == -1) - con2fb_map[i] = info_idx; - } - } - - if (!num_registered_fb) - unregister_con_driver(&fb_con); - - return 0; -} - static int fbcon_fb_registered(int idx) { int ret = 0, i; if (info_idx == -1) { - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (con2fb_map_boot[i] == idx) { info_idx = idx; break; } } - if (info_idx != -1) ret = fbcon_takeover(1); } else { - for (i = first_fb_vc; i <= last_fb_vc; i++) { - if (con2fb_map_boot[i] == idx && - con2fb_map[i] == -1) + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map_boot[i] == idx) set_con2fb_map(i, idx, 0); } } @@ -2973,7 +2882,7 @@ static void fbcon_new_modelist(struct fb_info *info) struct fb_var_screeninfo var; struct fb_videomode *mode; - for (i = first_fb_vc; i <= last_fb_vc; i++) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (registered_fb[con2fb_map[i]] != info) continue; if (!fb_display[i].mode) @@ -3001,14 +2910,6 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_con2fbmap *con2fb; int ret = 0; - /* - * ignore all events except driver registration and deregistration - * if fbcon is not active - */ - if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED || - action == FB_EVENT_FB_UNREGISTERED)) - goto done; - switch(action) { case FB_EVENT_SUSPEND: fbcon_suspended(info); @@ -3029,9 +2930,6 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info->node); break; - case FB_EVENT_FB_UNREGISTERED: - ret = fbcon_fb_unregistered(info->node); - break; case FB_EVENT_SET_CONSOLE_MAP: con2fb = event->data; ret = set_con2fb_map(con2fb->console - 1, @@ -3047,9 +2945,16 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_NEW_MODELIST: fbcon_new_modelist(info); break; + case FB_EVENT_SET_CON_ROTATE: + fbcon_rotate(info, *(int *)event->data); + break; + case FB_EVENT_GET_CON_ROTATE: + ret = fbcon_get_rotate(info); + break; + case FB_EVENT_SET_CON_ROTATE_ALL: + fbcon_rotate_all(info, *(int *)event->data); } -done: return ret; } @@ -3087,181 +2992,27 @@ static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; -static ssize_t store_rotate(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *info; - int rotate, idx; - char **last = NULL; - - if (fbcon_has_exited) - return count; - - acquire_console_sem(); - idx = con2fb_map[fg_console]; - - if (idx == -1 || registered_fb[idx] == NULL) - goto err; - - info = registered_fb[idx]; - rotate = simple_strtoul(buf, last, 0); - fbcon_rotate(info, rotate); -err: - release_console_sem(); - return count; -} - -static ssize_t store_rotate_all(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *info; - int rotate, idx; - char **last = NULL; - - if (fbcon_has_exited) - return count; - - acquire_console_sem(); - idx = con2fb_map[fg_console]; - - if (idx == -1 || registered_fb[idx] == NULL) - goto err; - - info = registered_fb[idx]; - rotate = simple_strtoul(buf, last, 0); - fbcon_rotate_all(info, rotate); -err: - release_console_sem(); - return count; -} - -static ssize_t show_rotate(struct class_device *class_device, char *buf) +static int __init fb_console_init(void) { - struct fb_info *info; - int rotate = 0, idx; - - if (fbcon_has_exited) - return 0; + int i; acquire_console_sem(); - idx = con2fb_map[fg_console]; - - if (idx == -1 || registered_fb[idx] == NULL) - goto err; - - info = registered_fb[idx]; - rotate = fbcon_get_rotate(info); -err: + fb_register_client(&fbcon_event_notifier); release_console_sem(); - return snprintf(buf, PAGE_SIZE, "%d\n", rotate); -} - -static struct class_device_attribute class_device_attrs[] = { - __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), - __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all), -}; - -static int fbcon_init_class_device(void) -{ - int i; - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(fbcon_class_device, - &class_device_attrs[i]); - return 0; -} + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; -static void fbcon_start(void) -{ if (num_registered_fb) { - int i; - - acquire_console_sem(); - for (i = 0; i < FB_MAX; i++) { if (registered_fb[i] != NULL) { info_idx = i; break; } } - - release_console_sem(); fbcon_takeover(0); } -} - -static void fbcon_exit(void) -{ - struct fb_info *info; - int i, j, mapped; - - if (fbcon_has_exited) - return; - -#ifdef CONFIG_ATARI - free_irq(IRQ_AUTO_4, fbcon_vbl_handler); -#endif -#ifdef CONFIG_MAC - if (MACH_IS_MAC && vbl_detected) - free_irq(IRQ_MAC_VBL, fbcon_vbl_handler); -#endif - - kfree((void *)softback_buf); - softback_buf = 0UL; - - for (i = 0; i < FB_MAX; i++) { - mapped = 0; - info = registered_fb[i]; - - if (info == NULL) - continue; - - for (j = first_fb_vc; j <= last_fb_vc; j++) { - if (con2fb_map[j] == i) - mapped = 1; - } - - if (mapped) { - if (info->fbops->fb_release) - info->fbops->fb_release(info, 0); - module_put(info->fbops->owner); - - if (info->fbcon_par) { - fbcon_del_cursor_timer(info); - kfree(info->fbcon_par); - info->fbcon_par = NULL; - } - if (info->queue.func == fb_flashcursor) - info->queue.func = NULL; - } - } - - fbcon_has_exited = 1; -} - -static int __init fb_console_init(void) -{ - int i; - - acquire_console_sem(); - fb_register_client(&fbcon_event_notifier); - fbcon_class_device = - class_device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon"); - - if (IS_ERR(fbcon_class_device)) { - printk(KERN_WARNING "Unable to create class_device " - "for fbcon; errno = %ld\n", - PTR_ERR(fbcon_class_device)); - fbcon_class_device = NULL; - } else - fbcon_init_class_device(); - - for (i = 0; i < MAX_NR_CONSOLES; i++) - con2fb_map[i] = -1; - - release_console_sem(); - fbcon_start(); return 0; } @@ -3269,24 +3020,12 @@ module_init(fb_console_init); #ifdef MODULE -static void __exit fbcon_deinit_class_device(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(fbcon_class_device, - &class_device_attrs[i]); -} - static void __exit fb_console_exit(void) { acquire_console_sem(); fb_unregister_client(&fbcon_event_notifier); - fbcon_deinit_class_device(); - class_device_destroy(fb_class, MKDEV(0, 0)); - fbcon_exit(); release_console_sem(); - unregister_con_driver(&fb_con); + give_up_console(&fb_con); } module_exit(fb_console_exit); diff --git a/trunk/drivers/video/console/fbcon.h b/trunk/drivers/video/console/fbcon.h index 3487a636370a..c38c3d8e7a74 100644 --- a/trunk/drivers/video/console/fbcon.h +++ b/trunk/drivers/video/console/fbcon.h @@ -175,7 +175,6 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); #endif extern void fbcon_set_bitops(struct fbcon_ops *ops); extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); -extern struct class *fb_class; #define FBCON_ATTRIBUTE_UNDERLINE 1 #define FBCON_ATTRIBUTE_REVERSE 2 diff --git a/trunk/drivers/video/console/mdacon.c b/trunk/drivers/video/console/mdacon.c index c89f90edf8ac..989e4d49e5bb 100644 --- a/trunk/drivers/video/console/mdacon.c +++ b/trunk/drivers/video/console/mdacon.c @@ -308,13 +308,13 @@ static void __init mda_initialize(void) outb_p(0x00, mda_gfx_port); } -static const char *mdacon_startup(void) +static const char __init *mdacon_startup(void) { mda_num_columns = 80; mda_num_lines = 25; + mda_vram_base = VGA_MAP_MEM(0xb0000); mda_vram_len = 0x01000; - mda_vram_base = VGA_MAP_MEM(0xb0000, mda_vram_len); mda_index_port = 0x3b4; mda_value_port = 0x3b5; diff --git a/trunk/drivers/video/console/newport_con.c b/trunk/drivers/video/console/newport_con.c index 03041311711b..e99fe30e568c 100644 --- a/trunk/drivers/video/console/newport_con.c +++ b/trunk/drivers/video/console/newport_con.c @@ -51,7 +51,6 @@ static int topscan; static int xcurs_correction = 29; static int newport_xsize; static int newport_ysize; -static int newport_has_init; static int newport_set_def_font(int unit, struct console_font *op); @@ -284,15 +283,6 @@ static void newport_get_revisions(void) xcurs_correction = 21; } -static void newport_exit(void) -{ - int i; - - /* free memory used by user font */ - for (i = 0; i < MAX_NR_CONSOLES; i++) - newport_set_def_font(i, NULL); -} - /* Can't be __init, take_over_console may call it later */ static const char *newport_startup(void) { @@ -300,10 +290,8 @@ static const char *newport_startup(void) if (!sgi_gfxaddr) return NULL; - - if (!npregs) - npregs = (struct newport_regs *)/* ioremap cannot fail */ - ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); + npregs = (struct newport_regs *) /* ioremap cannot fail */ + ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); npregs->cset.config = NPORT_CFG_GD0; if (newport_wait(npregs)) @@ -319,11 +307,11 @@ static const char *newport_startup(void) newport_reset(); newport_get_revisions(); newport_get_screensize(); - newport_has_init = 1; return "SGI Newport"; out_unmap: + iounmap((void *)npregs); return NULL; } @@ -336,10 +324,11 @@ static void newport_init(struct vc_data *vc, int init) static void newport_deinit(struct vc_data *c) { - if (!con_is_bound(&newport_con) && newport_has_init) { - newport_exit(); - newport_has_init = 0; - } + int i; + + /* free memory used by user font */ + for (i = 0; i < MAX_NR_CONSOLES; i++) + newport_set_def_font(i, NULL); } static void newport_clear(struct vc_data *vc, int sy, int sx, int height, @@ -739,23 +728,16 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { - - if (!sgi_gfxaddr) - return NULL; - - if (!npregs) - npregs = (struct newport_regs *)/* ioremap cannot fail */ - ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); - return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); } -module_init(newport_console_init); static void __exit newport_console_exit(void) { give_up_console(&newport_con); iounmap((void *)npregs); } + +module_init(newport_console_init); module_exit(newport_console_exit); #endif diff --git a/trunk/drivers/video/console/promcon.c b/trunk/drivers/video/console/promcon.c index d6e6ad537f9f..04f42fcaac59 100644 --- a/trunk/drivers/video/console/promcon.c +++ b/trunk/drivers/video/console/promcon.c @@ -109,7 +109,7 @@ promcon_end(struct vc_data *conp, char *b) return b - p; } -const char *promcon_startup(void) +const char __init *promcon_startup(void) { const char *display_desc = "PROM"; int node; @@ -133,7 +133,7 @@ const char *promcon_startup(void) return display_desc; } -static void +static void __init promcon_init_unimap(struct vc_data *conp) { mm_segment_t old_fs = get_fs(); diff --git a/trunk/drivers/video/console/sticon.c b/trunk/drivers/video/console/sticon.c index 45c4f227e56e..fd5940f41271 100644 --- a/trunk/drivers/video/console/sticon.c +++ b/trunk/drivers/video/console/sticon.c @@ -75,7 +75,7 @@ static inline void cursor_undrawn(void) cursor_drawn = 0; } -static const char *sticon_startup(void) +static const char *__init sticon_startup(void) { return "STI console"; } diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index f32b590730f2..d5a04b68c4d4 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -114,7 +114,6 @@ static int vga_512_chars; static int vga_video_font_height; static int vga_scan_lines; static unsigned int vga_rolled_over = 0; -static int vga_init_done; static int __init no_scroll(char *str) { @@ -191,7 +190,7 @@ static void vgacon_scrollback_init(int pitch) } } -static void vgacon_scrollback_startup(void) +static void __init vgacon_scrollback_startup(void) { vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024); @@ -356,7 +355,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) } #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ -static const char *vgacon_startup(void) +static const char __init *vgacon_startup(void) { const char *display_desc = NULL; u16 saved1, saved2; @@ -392,7 +391,7 @@ static const char *vgacon_startup(void) static struct resource ega_console_resource = { "ega", 0x3B0, 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; - vga_vram_size = 0x8000; + vga_vram_end = 0xb8000; display_desc = "EGA+"; request_resource(&ioport_resource, &ega_console_resource); @@ -402,7 +401,7 @@ static const char *vgacon_startup(void) static struct resource mda2_console_resource = { "mda", 0x3BF, 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; - vga_vram_size = 0x2000; + vga_vram_end = 0xb2000; display_desc = "*MDA"; request_resource(&ioport_resource, &mda1_console_resource); @@ -419,7 +418,7 @@ static const char *vgacon_startup(void) if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { int i; - vga_vram_size = 0x8000; + vga_vram_end = 0xc0000; if (!ORIG_VIDEO_ISVGA) { static struct resource ega_console_resource @@ -444,7 +443,7 @@ static const char *vgacon_startup(void) * and COE=1 isn't necessarily a good idea) */ vga_vram_base = 0xa0000; - vga_vram_size = 0x10000; + vga_vram_end = 0xb0000; outb_p(6, VGA_GFX_I); outb_p(6, VGA_GFX_D); #endif @@ -476,7 +475,7 @@ static const char *vgacon_startup(void) static struct resource cga_console_resource = { "cga", 0x3D4, 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; - vga_vram_size = 0x2000; + vga_vram_end = 0xba000; display_desc = "*CGA"; request_resource(&ioport_resource, &cga_console_resource); @@ -484,8 +483,9 @@ static const char *vgacon_startup(void) } } - vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size); - vga_vram_end = vga_vram_base + vga_vram_size; + vga_vram_base = VGA_MAP_MEM(vga_vram_base); + vga_vram_end = VGA_MAP_MEM(vga_vram_end); + vga_vram_size = vga_vram_end - vga_vram_base; /* * Find out if there is a graphics card present. @@ -524,12 +524,7 @@ static const char *vgacon_startup(void) vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; - - if (!vga_init_done) { - vgacon_scrollback_startup(); - vga_init_done = 1; - } - + vgacon_scrollback_startup(); return display_desc; } @@ -537,20 +532,10 @@ static void vgacon_init(struct vc_data *c, int init) { unsigned long p; - /* - * We cannot be loaded as a module, therefore init is always 1, - * but vgacon_init can be called more than once, and init will - * not be 1. - */ + /* We cannot be loaded as a module, therefore init is always 1 */ c->vc_can_do_color = vga_can_do_color; - - /* set dimensions manually if init != 0 since vc_resize() will fail */ - if (init) { - c->vc_cols = vga_video_num_columns; - c->vc_rows = vga_video_num_lines; - } else - vc_resize(c, vga_video_num_columns, vga_video_num_lines); - + c->vc_cols = vga_video_num_columns; + c->vc_rows = vga_video_num_lines; c->vc_scan_lines = vga_scan_lines; c->vc_font.height = vga_video_font_height; c->vc_complement_mask = 0x7700; @@ -1035,14 +1020,14 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) char *charmap; if (vga_video_type != VIDEO_TYPE_EGAM) { - charmap = (char *) VGA_MAP_MEM(colourmap, 0); + charmap = (char *) VGA_MAP_MEM(colourmap); beg = 0x0e; #ifdef VGA_CAN_DO_64KB if (vga_video_type == VIDEO_TYPE_VGAC) beg = 0x06; #endif } else { - charmap = (char *) VGA_MAP_MEM(blackwmap, 0); + charmap = (char *) VGA_MAP_MEM(blackwmap); beg = 0x0a; } diff --git a/trunk/drivers/video/epson1355fb.c b/trunk/drivers/video/epson1355fb.c index f0a621ecc288..082759447bf6 100644 --- a/trunk/drivers/video/epson1355fb.c +++ b/trunk/drivers/video/epson1355fb.c @@ -605,6 +605,11 @@ static void clearfb16(struct fb_info *info) fb_writeb(0, dst); } +static void epson1355fb_platform_release(struct device *device) +{ + dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); +} + static int epson1355fb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -728,7 +733,13 @@ static struct platform_driver epson1355fb_driver = { }, }; -static struct platform_device *epson1355fb_device; +static struct platform_device epson1355fb_device = { + .name = "epson1355fb", + .id = 0, + .dev = { + .release = epson1355fb_platform_release, + } +}; int __init epson1355fb_init(void) { @@ -738,21 +749,11 @@ int __init epson1355fb_init(void) return -ENODEV; ret = platform_driver_register(&epson1355fb_driver); - if (!ret) { - epson1355fb_device = platform_device_alloc("epson1355fb", 0); - - if (epson1355fb_device) - ret = platform_device_add(epson1355fb_device); - else - ret = -ENOMEM; - - if (ret) { - platform_device_put(epson1355fb_device); + ret = platform_device_register(&epson1355fb_device); + if (ret) platform_driver_unregister(&epson1355fb_driver); - } } - return ret; } @@ -761,7 +762,7 @@ module_init(epson1355fb_init); #ifdef MODULE static void __exit epson1355fb_exit(void) { - platform_device_unregister(epson1355fb_device); + platform_device_unregister(&epson1355fb_device); platform_driver_unregister(&epson1355fb_driver); } diff --git a/trunk/drivers/video/fbcvt.c b/trunk/drivers/video/fbcvt.c index b5498999c4ec..ac90883dc3aa 100644 --- a/trunk/drivers/video/fbcvt.c +++ b/trunk/drivers/video/fbcvt.c @@ -376,3 +376,4 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb) return 0; } +EXPORT_SYMBOL(fb_find_mode_cvt); diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 31143afe7c95..372aa1776827 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -34,6 +34,7 @@ #endif #include #include +#include #include #include @@ -161,6 +162,7 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size } #ifdef CONFIG_LOGO +#include static inline unsigned safe_shift(unsigned d, int n) { @@ -334,11 +336,11 @@ static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height) { - int i, j, h = height - 1; + int i, j, w = width - 1; for (i = 0; i < height; i++) for (j = 0; j < width; j++) - out[height * j + h - i] = *in++; + out[height * j + w - i] = *in++; } static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height) @@ -356,24 +358,24 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst, u32 tmp; if (rotate == FB_ROTATE_UD) { - fb_rotate_logo_ud(image->data, dst, image->width, - image->height); image->dx = info->var.xres - image->width; image->dy = info->var.yres - image->height; - } else if (rotate == FB_ROTATE_CW) { - fb_rotate_logo_cw(image->data, dst, image->width, + fb_rotate_logo_ud(image->data, dst, image->width, image->height); + } else if (rotate == FB_ROTATE_CW) { tmp = image->width; image->width = image->height; image->height = tmp; - image->dx = info->var.xres - image->width; + image->dx = info->var.xres - image->height; + fb_rotate_logo_cw(image->data, dst, image->width, + image->height); } else if (rotate == FB_ROTATE_CCW) { - fb_rotate_logo_ccw(image->data, dst, image->width, - image->height); tmp = image->width; image->width = image->height; image->height = tmp; - image->dy = info->var.yres - image->height; + image->dy = info->var.yres - image->width; + fb_rotate_logo_ccw(image->data, dst, image->width, + image->height); } image->data = dst; @@ -433,7 +435,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate) depth = info->var.green.length; } - if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { + if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { /* assume console colormap */ depth = 4; } @@ -1276,8 +1278,8 @@ static struct file_operations fb_fops = { #endif }; -struct class *fb_class; -EXPORT_SYMBOL(fb_class); +static struct class *fb_class; + /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1353,7 +1355,6 @@ register_framebuffer(struct fb_info *fb_info) int unregister_framebuffer(struct fb_info *fb_info) { - struct fb_event event; int i; i = fb_info->node; @@ -1361,17 +1362,13 @@ unregister_framebuffer(struct fb_info *fb_info) return -EINVAL; devfs_remove("fb/%d", i); - if (fb_info->pixmap.addr && - (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) + if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); registered_fb[i]=NULL; num_registered_fb--; fb_cleanup_class_device(fb_info); class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); - event.info = fb_info; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_FB_UNREGISTERED, &event); return 0; } @@ -1494,6 +1491,28 @@ int fb_new_modelist(struct fb_info *info) return err; } +/** + * fb_con_duit - user<->fbcon passthrough + * @info: struct fb_info + * @event: notification event to be passed to fbcon + * @data: private data + * + * DESCRIPTION + * This function is an fbcon-user event passing channel + * which bypasses fbdev. This is hopefully temporary + * until a user interface for fbcon is created + */ +int fb_con_duit(struct fb_info *info, int event, void *data) +{ + struct fb_event evnt; + + evnt.info = info; + evnt.data = data; + + return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt); +} +EXPORT_SYMBOL(fb_con_duit); + static char *video_options[FB_MAX]; static int ofonly; @@ -1603,5 +1622,6 @@ EXPORT_SYMBOL(fb_set_suspend); EXPORT_SYMBOL(fb_register_client); EXPORT_SYMBOL(fb_unregister_client); EXPORT_SYMBOL(fb_get_options); +EXPORT_SYMBOL(fb_new_modelist); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/fbmon.c b/trunk/drivers/video/fbmon.c index 3ccfff715a51..53beeb4a9998 100644 --- a/trunk/drivers/video/fbmon.c +++ b/trunk/drivers/video/fbmon.c @@ -29,9 +29,9 @@ #include #include #include -#include #include